Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: Source/web/WebInputEventFactoryWin.cpp

Issue 27532002: Revert "Remove web/{android, gtk, win}" (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/web/WebInputEventFactoryGtk.cpp ('k') | Source/web/android/WebInputEventFactory.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2006-2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "WebInputEventFactory.h"
33
34 #include "WebInputEvent.h"
35
36 #include "wtf/Assertions.h"
37
38 namespace WebKit {
39
40 static const unsigned long defaultScrollLinesPerWheelDelta = 3;
41 static const unsigned long defaultScrollCharsPerWheelDelta = 1;
42
43 // WebKeyboardEvent -----------------------------------------------------------
44
45 static bool isKeyDown(WPARAM wparam)
46 {
47 return GetKeyState(wparam) & 0x8000;
48 }
49
50 static int getLocationModifier(WPARAM wparam, LPARAM lparam)
51 {
52 int modifier = 0;
53 switch (wparam) {
54 case VK_RETURN:
55 if ((lparam >> 16) & KF_EXTENDED)
56 modifier = WebInputEvent::IsKeyPad;
57 break;
58 case VK_INSERT:
59 case VK_DELETE:
60 case VK_HOME:
61 case VK_END:
62 case VK_PRIOR:
63 case VK_NEXT:
64 case VK_UP:
65 case VK_DOWN:
66 case VK_LEFT:
67 case VK_RIGHT:
68 if (!((lparam >> 16) & KF_EXTENDED))
69 modifier = WebInputEvent::IsKeyPad;
70 break;
71 case VK_NUMPAD0:
72 case VK_NUMPAD1:
73 case VK_NUMPAD2:
74 case VK_NUMPAD3:
75 case VK_NUMPAD4:
76 case VK_NUMPAD5:
77 case VK_NUMPAD6:
78 case VK_NUMPAD7:
79 case VK_NUMPAD8:
80 case VK_NUMPAD9:
81 case VK_DIVIDE:
82 case VK_MULTIPLY:
83 case VK_SUBTRACT:
84 case VK_ADD:
85 case VK_DECIMAL:
86 case VK_CLEAR:
87 modifier = WebInputEvent::IsKeyPad;
88 break;
89 case VK_SHIFT:
90 if (isKeyDown(VK_LSHIFT))
91 modifier = WebInputEvent::IsLeft;
92 else if (isKeyDown(VK_RSHIFT))
93 modifier = WebInputEvent::IsRight;
94 break;
95 case VK_CONTROL:
96 if (isKeyDown(VK_LCONTROL))
97 modifier = WebInputEvent::IsLeft;
98 else if (isKeyDown(VK_RCONTROL))
99 modifier = WebInputEvent::IsRight;
100 break;
101 case VK_MENU:
102 if (isKeyDown(VK_LMENU))
103 modifier = WebInputEvent::IsLeft;
104 else if (isKeyDown(VK_RMENU))
105 modifier = WebInputEvent::IsRight;
106 break;
107 case VK_LWIN:
108 modifier = WebInputEvent::IsLeft;
109 break;
110 case VK_RWIN:
111 modifier = WebInputEvent::IsRight;
112 break;
113 }
114
115 ASSERT(!modifier
116 || modifier == WebInputEvent::IsKeyPad
117 || modifier == WebInputEvent::IsLeft
118 || modifier == WebInputEvent::IsRight);
119 return modifier;
120 }
121
122 // Loads the state for toggle keys into the event.
123 static void SetToggleKeyState(WebInputEvent* event)
124 {
125 // Low bit set from GetKeyState indicates "toggled".
126 if (::GetKeyState(VK_NUMLOCK) & 1)
127 event->modifiers |= WebInputEvent::NumLockOn;
128 if (::GetKeyState(VK_CAPITAL) & 1)
129 event->modifiers |= WebInputEvent::CapsLockOn;
130 }
131
132 WebKeyboardEvent WebInputEventFactory::keyboardEvent(HWND hwnd, UINT message,
133 WPARAM wparam, LPARAM lpara m)
134 {
135 WebKeyboardEvent result;
136
137 // TODO(pkasting): http://b/1117926 Are we guaranteed that the message that
138 // GetMessageTime() refers to is the same one that we're passed in? Perhaps
139 // one of the construction parameters should be the time passed by the
140 // caller, who would know for sure.
141 result.timeStampSeconds = GetMessageTime() / 1000.0;
142
143 result.windowsKeyCode = static_cast<int>(wparam);
144 // Record the scan code (along with other context bits) for this key event.
145 result.nativeKeyCode = static_cast<int>(lparam);
146
147 switch (message) {
148 case WM_SYSKEYDOWN:
149 result.isSystemKey = true;
150 case WM_KEYDOWN:
151 result.type = WebInputEvent::RawKeyDown;
152 break;
153 case WM_SYSKEYUP:
154 result.isSystemKey = true;
155 case WM_KEYUP:
156 result.type = WebInputEvent::KeyUp;
157 break;
158 case WM_IME_CHAR:
159 result.type = WebInputEvent::Char;
160 break;
161 case WM_SYSCHAR:
162 result.isSystemKey = true;
163 result.type = WebInputEvent::Char;
164 case WM_CHAR:
165 result.type = WebInputEvent::Char;
166 break;
167 default:
168 ASSERT_NOT_REACHED();
169 }
170
171 if (result.type == WebInputEvent::Char || result.type == WebInputEvent::RawK eyDown) {
172 result.text[0] = result.windowsKeyCode;
173 result.unmodifiedText[0] = result.windowsKeyCode;
174 }
175 if (result.type != WebInputEvent::Char)
176 result.setKeyIdentifierFromWindowsKeyCode();
177
178 if (GetKeyState(VK_SHIFT) & 0x8000)
179 result.modifiers |= WebInputEvent::ShiftKey;
180 if (GetKeyState(VK_CONTROL) & 0x8000)
181 result.modifiers |= WebInputEvent::ControlKey;
182 if (GetKeyState(VK_MENU) & 0x8000)
183 result.modifiers |= WebInputEvent::AltKey;
184 // NOTE: There doesn't seem to be a way to query the mouse button state in
185 // this case.
186
187 if (LOWORD(lparam) > 1)
188 result.modifiers |= WebInputEvent::IsAutoRepeat;
189
190 result.modifiers |= getLocationModifier(wparam, lparam);
191
192 SetToggleKeyState(&result);
193 return result;
194 }
195
196 // WebMouseEvent --------------------------------------------------------------
197
198 static int gLastClickCount;
199 static double gLastClickTime;
200
201 static LPARAM GetRelativeCursorPos(HWND hwnd)
202 {
203 POINT pos = {-1, -1};
204 GetCursorPos(&pos);
205 ScreenToClient(hwnd, &pos);
206 return MAKELPARAM(pos.x, pos.y);
207 }
208
209 void WebInputEventFactory::resetLastClickState()
210 {
211 gLastClickTime = gLastClickCount = 0;
212 }
213
214 WebMouseEvent WebInputEventFactory::mouseEvent(HWND hwnd, UINT message,
215 WPARAM wparam, LPARAM lparam)
216 {
217 WebMouseEvent result; //(WebInputEvent::Uninitialized());
218
219 switch (message) {
220 case WM_MOUSEMOVE:
221 result.type = WebInputEvent::MouseMove;
222 if (wparam & MK_LBUTTON)
223 result.button = WebMouseEvent::ButtonLeft;
224 else if (wparam & MK_MBUTTON)
225 result.button = WebMouseEvent::ButtonMiddle;
226 else if (wparam & MK_RBUTTON)
227 result.button = WebMouseEvent::ButtonRight;
228 else
229 result.button = WebMouseEvent::ButtonNone;
230 break;
231 case WM_MOUSELEAVE:
232 result.type = WebInputEvent::MouseLeave;
233 result.button = WebMouseEvent::ButtonNone;
234 // set the current mouse position (relative to the client area of the
235 // current window) since none is specified for this event
236 lparam = GetRelativeCursorPos(hwnd);
237 break;
238 case WM_LBUTTONDOWN:
239 case WM_LBUTTONDBLCLK:
240 result.type = WebInputEvent::MouseDown;
241 result.button = WebMouseEvent::ButtonLeft;
242 break;
243 case WM_MBUTTONDOWN:
244 case WM_MBUTTONDBLCLK:
245 result.type = WebInputEvent::MouseDown;
246 result.button = WebMouseEvent::ButtonMiddle;
247 break;
248 case WM_RBUTTONDOWN:
249 case WM_RBUTTONDBLCLK:
250 result.type = WebInputEvent::MouseDown;
251 result.button = WebMouseEvent::ButtonRight;
252 break;
253 case WM_LBUTTONUP:
254 result.type = WebInputEvent::MouseUp;
255 result.button = WebMouseEvent::ButtonLeft;
256 break;
257 case WM_MBUTTONUP:
258 result.type = WebInputEvent::MouseUp;
259 result.button = WebMouseEvent::ButtonMiddle;
260 break;
261 case WM_RBUTTONUP:
262 result.type = WebInputEvent::MouseUp;
263 result.button = WebMouseEvent::ButtonRight;
264 break;
265 default:
266 ASSERT_NOT_REACHED();
267 }
268
269 // TODO(pkasting): http://b/1117926 Are we guaranteed that the message that
270 // GetMessageTime() refers to is the same one that we're passed in? Perhaps
271 // one of the construction parameters should be the time passed by the
272 // caller, who would know for sure.
273 result.timeStampSeconds = GetMessageTime() / 1000.0;
274
275 // set position fields:
276
277 result.x = static_cast<short>(LOWORD(lparam));
278 result.y = static_cast<short>(HIWORD(lparam));
279 result.windowX = result.x;
280 result.windowY = result.y;
281
282 POINT globalPoint = { result.x, result.y };
283 ClientToScreen(hwnd, &globalPoint);
284
285 result.globalX = globalPoint.x;
286 result.globalY = globalPoint.y;
287
288 // calculate number of clicks:
289
290 // This differs slightly from the WebKit code in WebKit/win/WebView.cpp
291 // where their original code looks buggy.
292 static int lastClickPositionX;
293 static int lastClickPositionY;
294 static WebMouseEvent::Button lastClickButton = WebMouseEvent::ButtonLeft;
295
296 double currentTime = result.timeStampSeconds;
297 bool cancelPreviousClick =
298 (abs(lastClickPositionX - result.x) > (GetSystemMetrics(SM_CXDOUBLECLK) / 2))
299 || (abs(lastClickPositionY - result.y) > (GetSystemMetrics(SM_CYDOUBLECL K) / 2))
300 || ((currentTime - gLastClickTime) * 1000.0 > GetDoubleClickTime());
301
302 if (result.type == WebInputEvent::MouseDown) {
303 if (!cancelPreviousClick && (result.button == lastClickButton))
304 ++gLastClickCount;
305 else {
306 gLastClickCount = 1;
307 lastClickPositionX = result.x;
308 lastClickPositionY = result.y;
309 }
310 gLastClickTime = currentTime;
311 lastClickButton = result.button;
312 } else if (result.type == WebInputEvent::MouseMove
313 || result.type == WebInputEvent::MouseLeave) {
314 if (cancelPreviousClick) {
315 gLastClickCount = 0;
316 lastClickPositionX = 0;
317 lastClickPositionY = 0;
318 gLastClickTime = 0;
319 }
320 }
321 result.clickCount = gLastClickCount;
322
323 // set modifiers:
324
325 if (wparam & MK_CONTROL)
326 result.modifiers |= WebInputEvent::ControlKey;
327 if (wparam & MK_SHIFT)
328 result.modifiers |= WebInputEvent::ShiftKey;
329 if (GetKeyState(VK_MENU) & 0x8000)
330 result.modifiers |= WebInputEvent::AltKey;
331 if (wparam & MK_LBUTTON)
332 result.modifiers |= WebInputEvent::LeftButtonDown;
333 if (wparam & MK_MBUTTON)
334 result.modifiers |= WebInputEvent::MiddleButtonDown;
335 if (wparam & MK_RBUTTON)
336 result.modifiers |= WebInputEvent::RightButtonDown;
337
338 SetToggleKeyState(&result);
339 return result;
340 }
341
342 // WebMouseWheelEvent ---------------------------------------------------------
343
344 WebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(HWND hwnd, UINT message ,
345 WPARAM wparam, LPARAM l param)
346 {
347 WebMouseWheelEvent result; //(WebInputEvent::Uninitialized());
348
349 result.type = WebInputEvent::MouseWheel;
350
351 // TODO(pkasting): http://b/1117926 Are we guaranteed that the message that
352 // GetMessageTime() refers to is the same one that we're passed in? Perhaps
353 // one of the construction parameters should be the time passed by the
354 // caller, who would know for sure.
355 result.timeStampSeconds = GetMessageTime() / 1000.0;
356
357 result.button = WebMouseEvent::ButtonNone;
358
359 // Get key state, coordinates, and wheel delta from event.
360 typedef SHORT (WINAPI *GetKeyStateFunction)(int key);
361 GetKeyStateFunction getKeyState;
362 UINT keyState;
363 float wheelDelta;
364 bool horizontalScroll = false;
365 if ((message == WM_VSCROLL) || (message == WM_HSCROLL)) {
366 // Synthesize mousewheel event from a scroll event. This is needed to
367 // simulate middle mouse scrolling in some laptops. Use GetAsyncKeyStat e
368 // for key state since we are synthesizing the input event.
369 getKeyState = GetAsyncKeyState;
370 keyState = 0;
371 if (getKeyState(VK_SHIFT))
372 keyState |= MK_SHIFT;
373 if (getKeyState(VK_CONTROL))
374 keyState |= MK_CONTROL;
375 // NOTE: There doesn't seem to be a way to query the mouse button state
376 // in this case.
377
378 POINT cursorPosition = {0};
379 GetCursorPos(&cursorPosition);
380 result.globalX = cursorPosition.x;
381 result.globalY = cursorPosition.y;
382
383 switch (LOWORD(wparam)) {
384 case SB_LINEUP: // == SB_LINELEFT
385 wheelDelta = WHEEL_DELTA;
386 break;
387 case SB_LINEDOWN: // == SB_LINERIGHT
388 wheelDelta = -WHEEL_DELTA;
389 break;
390 case SB_PAGEUP:
391 wheelDelta = 1;
392 result.scrollByPage = true;
393 break;
394 case SB_PAGEDOWN:
395 wheelDelta = -1;
396 result.scrollByPage = true;
397 break;
398 default: // We don't supoprt SB_THUMBPOSITION or SB_THUMBTRACK here.
399 wheelDelta = 0;
400 break;
401 }
402
403 if (message == WM_HSCROLL)
404 horizontalScroll = true;
405 } else {
406 // Non-synthesized event; we can just read data off the event.
407 getKeyState = GetKeyState;
408 keyState = GET_KEYSTATE_WPARAM(wparam);
409
410 result.globalX = static_cast<short>(LOWORD(lparam));
411 result.globalY = static_cast<short>(HIWORD(lparam));
412
413 wheelDelta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wparam));
414 if (message == WM_MOUSEHWHEEL) {
415 horizontalScroll = true;
416 wheelDelta = -wheelDelta; // Windows is <- -/+ ->, WebKit <- +/- -> .
417 }
418 }
419 if (keyState & MK_SHIFT)
420 horizontalScroll = true;
421
422 // Set modifiers based on key state.
423 if (keyState & MK_SHIFT)
424 result.modifiers |= WebInputEvent::ShiftKey;
425 if (keyState & MK_CONTROL)
426 result.modifiers |= WebInputEvent::ControlKey;
427 if (getKeyState(VK_MENU) & 0x8000)
428 result.modifiers |= WebInputEvent::AltKey;
429 if (keyState & MK_LBUTTON)
430 result.modifiers |= WebInputEvent::LeftButtonDown;
431 if (keyState & MK_MBUTTON)
432 result.modifiers |= WebInputEvent::MiddleButtonDown;
433 if (keyState & MK_RBUTTON)
434 result.modifiers |= WebInputEvent::RightButtonDown;
435
436 SetToggleKeyState(&result);
437
438 // Set coordinates by translating event coordinates from screen to client.
439 POINT clientPoint = { result.globalX, result.globalY };
440 MapWindowPoints(0, hwnd, &clientPoint, 1);
441 result.x = clientPoint.x;
442 result.y = clientPoint.y;
443 result.windowX = result.x;
444 result.windowY = result.y;
445
446 // Convert wheel delta amount to a number of pixels to scroll.
447 //
448 // How many pixels should we scroll per line? Gecko uses the height of the
449 // current line, which means scroll distance changes as you go through the
450 // page or go to different pages. IE 8 is ~60 px/line, although the value
451 // seems to vary slightly by page and zoom level. Also, IE defaults to
452 // smooth scrolling while Firefox doesn't, so it can get away with somewhat
453 // larger scroll values without feeling as jerky. Here we use 100 px per
454 // three lines (the default scroll amount is three lines per wheel tick).
455 // Even though we have smooth scrolling, we don't make this as large as IE
456 // because subjectively IE feels like it scrolls farther than you want while
457 // reading articles.
458 static const float scrollbarPixelsPerLine = 100.0f / 3.0f;
459 wheelDelta /= WHEEL_DELTA;
460 float scrollDelta = wheelDelta;
461 if (horizontalScroll) {
462 unsigned long scrollChars = defaultScrollCharsPerWheelDelta;
463 SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0);
464 // TODO(pkasting): Should probably have a different multiplier
465 // scrollbarPixelsPerChar here.
466 scrollDelta *= static_cast<float>(scrollChars) * scrollbarPixelsPerLine;
467 } else {
468 unsigned long scrollLines = defaultScrollLinesPerWheelDelta;
469 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
470 if (scrollLines == WHEEL_PAGESCROLL)
471 result.scrollByPage = true;
472 if (!result.scrollByPage)
473 scrollDelta *= static_cast<float>(scrollLines) * scrollbarPixelsPerL ine;
474 }
475
476 // Set scroll amount based on above calculations. WebKit expects positive
477 // deltaY to mean "scroll up" and positive deltaX to mean "scroll left".
478 if (horizontalScroll) {
479 result.deltaX = scrollDelta;
480 result.wheelTicksX = wheelDelta;
481 } else {
482 result.deltaY = scrollDelta;
483 result.wheelTicksY = wheelDelta;
484 }
485
486 return result;
487 }
488
489 } // namespace WebKit
OLDNEW
« no previous file with comments | « Source/web/WebInputEventFactoryGtk.cpp ('k') | Source/web/android/WebInputEventFactory.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698