| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "webkit/glue/webinputevent.h" | 7 #include "webkit/glue/webinputevent.h" |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "webkit/glue/webinputevent_util.h" | 11 #include "webkit/glue/webinputevent_util.h" |
| 12 | 12 |
| 13 static const unsigned long kDefaultScrollLinesPerWheelDelta = 3; | 13 static const unsigned long kDefaultScrollLinesPerWheelDelta = 3; |
| 14 static const unsigned long kDefaultScrollCharsPerWheelDelta = 1; |
| 14 | 15 |
| 15 // WebMouseEvent -------------------------------------------------------------- | 16 // WebMouseEvent -------------------------------------------------------------- |
| 16 | 17 |
| 17 static LPARAM GetRelativeCursorPos(HWND hwnd) { | 18 static LPARAM GetRelativeCursorPos(HWND hwnd) { |
| 18 POINT pos = {-1, -1}; | 19 POINT pos = {-1, -1}; |
| 19 GetCursorPos(&pos); | 20 GetCursorPos(&pos); |
| 20 ScreenToClient(hwnd, &pos); | 21 ScreenToClient(hwnd, &pos); |
| 21 return MAKELPARAM(pos.x, pos.y); | 22 return MAKELPARAM(pos.x, pos.y); |
| 22 } | 23 } |
| 23 | 24 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 // TODO(pkasting): http://b/1117926 Instead of using GetTickCount() here, we | 106 // TODO(pkasting): http://b/1117926 Instead of using GetTickCount() here, we |
| 106 // should use GetMessageTime() on the original Windows message in the browser | 107 // should use GetMessageTime() on the original Windows message in the browser |
| 107 // process, and pass that in the WebMouseEvent. | 108 // process, and pass that in the WebMouseEvent. |
| 108 timestamp_sec = GetTickCount() / 1000.0; | 109 timestamp_sec = GetTickCount() / 1000.0; |
| 109 | 110 |
| 110 layout_test_click_count = 0; | 111 layout_test_click_count = 0; |
| 111 } | 112 } |
| 112 | 113 |
| 113 // WebMouseWheelEvent --------------------------------------------------------- | 114 // WebMouseWheelEvent --------------------------------------------------------- |
| 114 | 115 |
| 115 WebMouseWheelEvent::WebMouseWheelEvent(HWND hwnd, UINT message, WPARAM wparam, | 116 WebMouseWheelEvent::WebMouseWheelEvent(HWND hwnd, |
| 116 LPARAM lparam) { | 117 UINT message, |
| 118 WPARAM wparam, |
| 119 LPARAM lparam) |
| 120 : scroll_by_page(false) { |
| 117 type = MOUSE_WHEEL; | 121 type = MOUSE_WHEEL; |
| 118 button = BUTTON_NONE; | 122 button = BUTTON_NONE; |
| 119 | 123 |
| 120 // Add a simple workaround to scroll multiples units per page. | 124 // Get key state, coordinates, and wheel delta from event. |
| 121 // The right fix needs to extend webkit's implementation of | |
| 122 // wheel events and that's not something we want to do at | |
| 123 // this time. See bug# 928509 | |
| 124 // TODO(joshia): Implement the right fix for bug# 928509 | |
| 125 const int kPageScroll = 10; // 10 times wheel scroll | |
| 126 | |
| 127 UINT key_state = GET_KEYSTATE_WPARAM(wparam); | |
| 128 int wheel_delta = static_cast<int>(GET_WHEEL_DELTA_WPARAM(wparam)); | |
| 129 | |
| 130 typedef SHORT (WINAPI *GetKeyStateFunction)(int key); | 125 typedef SHORT (WINAPI *GetKeyStateFunction)(int key); |
| 131 GetKeyStateFunction get_key_state = GetKeyState; | 126 GetKeyStateFunction get_key_state; |
| 132 | 127 UINT key_state; |
| 133 // Synthesize mousewheel event from a scroll event. | 128 float wheel_delta; |
| 134 // This is needed to simulate middle mouse scrolling in some | 129 bool horizontal_scroll = false; |
| 135 // laptops (Thinkpads) | 130 if ((message == WM_VSCROLL) || (message == WM_HSCROLL)) { |
| 136 if ((WM_VSCROLL == message) || (WM_HSCROLL == message)) { | 131 // Synthesize mousewheel event from a scroll event. This is needed to |
| 132 // simulate middle mouse scrolling in some laptops. Use GetAsyncKeyState |
| 133 // for key state since we are synthesizing the input event. |
| 134 get_key_state = GetAsyncKeyState; |
| 135 key_state = 0; |
| 136 if (get_key_state(VK_SHIFT)) |
| 137 key_state |= MK_SHIFT; |
| 138 if (get_key_state(VK_CONTROL)) |
| 139 key_state |= MK_CONTROL; |
| 137 | 140 |
| 138 POINT cursor_position = {0}; | 141 POINT cursor_position = {0}; |
| 139 GetCursorPos(&cursor_position); | 142 GetCursorPos(&cursor_position); |
| 140 | |
| 141 global_x = cursor_position.x; | 143 global_x = cursor_position.x; |
| 142 global_y = cursor_position.y; | 144 global_y = cursor_position.y; |
| 143 | 145 |
| 144 key_state = 0; | |
| 145 | |
| 146 // Since we are synthesizing the wheel event, we have to | |
| 147 // use GetAsyncKeyState | |
| 148 if (GetAsyncKeyState(VK_SHIFT)) | |
| 149 key_state |= MK_SHIFT; | |
| 150 | |
| 151 if (GetAsyncKeyState(VK_CONTROL)) | |
| 152 key_state |= MK_CONTROL; | |
| 153 | |
| 154 switch (LOWORD(wparam)) { | 146 switch (LOWORD(wparam)) { |
| 155 case SB_LINEUP: // == SB_LINELEFT | 147 case SB_LINEUP: // == SB_LINELEFT |
| 156 wheel_delta = WHEEL_DELTA; | 148 wheel_delta = WHEEL_DELTA; |
| 157 break; | 149 break; |
| 158 case SB_LINEDOWN: // == SB_LINERIGHT | 150 case SB_LINEDOWN: // == SB_LINERIGHT |
| 159 wheel_delta = -WHEEL_DELTA; | 151 wheel_delta = -WHEEL_DELTA; |
| 160 break; | 152 break; |
| 161 case SB_PAGEUP: | 153 case SB_PAGEUP: |
| 162 wheel_delta = kPageScroll * WHEEL_DELTA; | 154 wheel_delta = 1; |
| 155 scroll_by_page = true; |
| 163 break; | 156 break; |
| 164 case SB_PAGEDOWN: | 157 case SB_PAGEDOWN: |
| 165 wheel_delta = -kPageScroll * WHEEL_DELTA; | 158 wheel_delta = -1; |
| 159 scroll_by_page = true; |
| 166 break; | 160 break; |
| 167 // TODO(joshia): Handle SB_THUMBPOSITION and SB_THUMBTRACK | 161 default: // We don't supoprt SB_THUMBPOSITION or SB_THUMBTRACK here. |
| 168 // for compeleteness | 162 wheel_delta = 0; |
| 169 default: | |
| 170 break; | 163 break; |
| 171 } | 164 } |
| 172 | 165 |
| 173 // Touchpads (or trackpoints) send the following messages in scrolling | 166 if (message == WM_HSCROLL) { |
| 174 // horizontally. | 167 horizontal_scroll = true; |
| 175 // * Scrolling left | |
| 176 // message == WM_HSCROLL, wparam == SB_LINELEFT (== SB_LINEUP). | |
| 177 // * Scrolling right | |
| 178 // message == WM_HSCROLL, wparam == SB_LINERIGHT (== SB_LINEDOWN). | |
| 179 if (WM_HSCROLL == message) { | |
| 180 key_state |= MK_SHIFT; | |
| 181 wheel_delta = -wheel_delta; | 168 wheel_delta = -wheel_delta; |
| 182 } | 169 } |
| 183 | |
| 184 // Use GetAsyncKeyState for key state since we are synthesizing | |
| 185 // the input | |
| 186 get_key_state = GetAsyncKeyState; | |
| 187 } else { | 170 } else { |
| 188 // TODO(hbono): we should add a new variable which indicates scroll | 171 // Non-synthesized event; we can just read data off the event. |
| 189 // direction and remove this key_state hack. | 172 get_key_state = GetKeyState; |
| 190 if (WM_MOUSEHWHEEL == message) | 173 key_state = GET_KEYSTATE_WPARAM(wparam); |
| 191 key_state |= MK_SHIFT; | |
| 192 | 174 |
| 193 global_x = static_cast<short>(LOWORD(lparam)); | 175 global_x = static_cast<short>(LOWORD(lparam)); |
| 194 global_y = static_cast<short>(HIWORD(lparam)); | 176 global_y = static_cast<short>(HIWORD(lparam)); |
| 177 |
| 178 wheel_delta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wparam)); |
| 179 if (((message == WM_MOUSEHWHEEL) || (key_state & MK_SHIFT)) && |
| 180 (wheel_delta != 0)) |
| 181 horizontal_scroll = true; |
| 195 } | 182 } |
| 196 | 183 |
| 197 POINT client_point = { global_x, global_y }; | 184 // Set modifiers based on key state. |
| 198 ScreenToClient(hwnd, &client_point); | |
| 199 x = client_point.x; | |
| 200 y = client_point.y; | |
| 201 | |
| 202 // compute the scroll delta based on Raymond Chen's algorithm: | |
| 203 // http://blogs.msdn.com/oldnewthing/archive/2003/08/07/54615.aspx | |
| 204 | |
| 205 static int carryover = 0; | |
| 206 static HWND last_window = NULL; | |
| 207 | |
| 208 if (hwnd != last_window) { | |
| 209 last_window = hwnd; | |
| 210 carryover = 0; | |
| 211 } | |
| 212 | |
| 213 unsigned long scroll_lines = kDefaultScrollLinesPerWheelDelta; | |
| 214 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scroll_lines, 0); | |
| 215 | |
| 216 int delta_lines = 0; | |
| 217 if (scroll_lines == WHEEL_PAGESCROLL) { | |
| 218 scroll_lines = kPageScroll; | |
| 219 } | |
| 220 | |
| 221 if (scroll_lines == 0) { | |
| 222 carryover = 0; | |
| 223 } else { | |
| 224 const int delta = carryover + wheel_delta; | |
| 225 | |
| 226 // see how many lines we should scroll. relies on round-toward-zero. | |
| 227 delta_lines = delta * static_cast<int>(scroll_lines) / WHEEL_DELTA; | |
| 228 | |
| 229 // record the unused portion as the next carryover. | |
| 230 carryover = | |
| 231 delta - delta_lines * WHEEL_DELTA / static_cast<int>(scroll_lines); | |
| 232 } | |
| 233 | |
| 234 // Scroll horizontally if shift is held. WebKit's WebKit/win/WebView.cpp | |
| 235 // does the equivalent. | |
| 236 // TODO(jackson): Support WM_MOUSEHWHEEL = 0x020E event as well. | |
| 237 // (Need a mouse with horizontal scrolling capabilities to test it.) | |
| 238 if (key_state & MK_SHIFT) { | |
| 239 // Scrolling up should move left, scrolling down should move right | |
| 240 delta_x = -delta_lines; | |
| 241 delta_y = 0; | |
| 242 } else { | |
| 243 delta_x = 0; | |
| 244 delta_y = delta_lines; | |
| 245 } | |
| 246 | |
| 247 if (key_state & MK_SHIFT) | 185 if (key_state & MK_SHIFT) |
| 248 modifiers |= SHIFT_KEY; | 186 modifiers |= SHIFT_KEY; |
| 249 if (key_state & MK_CONTROL) | 187 if (key_state & MK_CONTROL) |
| 250 modifiers |= CTRL_KEY; | 188 modifiers |= CTRL_KEY; |
| 251 | |
| 252 // Get any additional key states needed | |
| 253 if (get_key_state(VK_MENU) & 0x8000) | 189 if (get_key_state(VK_MENU) & 0x8000) |
| 254 modifiers |= (ALT_KEY | META_KEY); | 190 modifiers |= (ALT_KEY | META_KEY); |
| 191 |
| 192 // Set coordinates by translating event coordinates from screen to client. |
| 193 POINT client_point = { global_x, global_y }; |
| 194 MapWindowPoints(NULL, hwnd, &client_point, 1); |
| 195 x = client_point.x; |
| 196 y = client_point.y; |
| 197 |
| 198 // Convert wheel delta amount to a number of lines/chars to scroll. |
| 199 float scroll_delta = wheel_delta / WHEEL_DELTA; |
| 200 if (horizontal_scroll) { |
| 201 unsigned long scroll_chars = kDefaultScrollCharsPerWheelDelta; |
| 202 SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scroll_chars, 0); |
| 203 scroll_delta *= static_cast<float>(scroll_chars); |
| 204 } else { |
| 205 unsigned long scroll_lines = kDefaultScrollLinesPerWheelDelta; |
| 206 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scroll_lines, 0); |
| 207 if (scroll_lines == WHEEL_PAGESCROLL) |
| 208 scroll_by_page = true; |
| 209 if (!scroll_by_page) |
| 210 scroll_delta *= static_cast<float>(scroll_lines); |
| 211 } |
| 212 |
| 213 // Set scroll amount based on above calculations. |
| 214 if (horizontal_scroll) { |
| 215 // Scrolling up should move left, scrolling down should move right. This is |
| 216 // opposite Safari, but seems more consistent with vertical scrolling. |
| 217 delta_x = scroll_delta; |
| 218 delta_y = 0; |
| 219 } else { |
| 220 delta_x = 0; |
| 221 delta_y = scroll_delta; |
| 222 } |
| 255 } | 223 } |
| 256 | 224 |
| 257 // WebKeyboardEvent ----------------------------------------------------------- | 225 // WebKeyboardEvent ----------------------------------------------------------- |
| 258 | 226 |
| 259 bool IsKeyPad(WPARAM wparam, LPARAM lparam) { | 227 bool IsKeyPad(WPARAM wparam, LPARAM lparam) { |
| 260 bool keypad = false; | 228 bool keypad = false; |
| 261 switch (wparam) { | 229 switch (wparam) { |
| 262 case VK_RETURN: | 230 case VK_RETURN: |
| 263 keypad = (lparam >> 16) & KF_EXTENDED; | 231 keypad = (lparam >> 16) & KF_EXTENDED; |
| 264 break; | 232 break; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 modifiers |= CTRL_KEY; | 324 modifiers |= CTRL_KEY; |
| 357 if (GetKeyState(VK_MENU) & 0x8000) | 325 if (GetKeyState(VK_MENU) & 0x8000) |
| 358 modifiers |= (ALT_KEY | META_KEY); | 326 modifiers |= (ALT_KEY | META_KEY); |
| 359 | 327 |
| 360 if (LOWORD(lparam) > 1) | 328 if (LOWORD(lparam) > 1) |
| 361 modifiers |= IS_AUTO_REPEAT; | 329 modifiers |= IS_AUTO_REPEAT; |
| 362 if (IsKeyPad(wparam, lparam)) | 330 if (IsKeyPad(wparam, lparam)) |
| 363 modifiers |= IS_KEYPAD; | 331 modifiers |= IS_KEYPAD; |
| 364 } | 332 } |
| 365 | 333 |
| OLD | NEW |