WebEventFactory.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * Copyright (C) 2010 Apple Inc. All rights reserved.
  3. * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
  4. * Copyright (C) 2011 Igalia S.L.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  17. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  18. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  19. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  25. * THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "config.h"
  28. #include "WebEventFactory.h"
  29. #include "PlatformKeyboardEvent.h"
  30. #include "Scrollbar.h"
  31. #include "WindowsKeyboardCodes.h"
  32. #include <WebCore/GtkVersioning.h>
  33. #include <gdk/gdk.h>
  34. #include <gdk/gdkkeysyms.h>
  35. #include <wtf/ASCIICType.h>
  36. using namespace WebCore;
  37. namespace WebKit {
  38. static inline bool isGdkKeyCodeFromKeyPad(unsigned keyval)
  39. {
  40. return keyval >= GDK_KP_Space && keyval <= GDK_KP_9;
  41. }
  42. static inline WebEvent::Modifiers modifiersForEvent(const GdkEvent* event)
  43. {
  44. unsigned modifiers = 0;
  45. GdkModifierType state;
  46. // Check for a valid state in GdkEvent.
  47. if (!gdk_event_get_state(event, &state))
  48. return static_cast<WebEvent::Modifiers>(0);
  49. if (state & GDK_CONTROL_MASK)
  50. modifiers |= WebEvent::ControlKey;
  51. if (state & GDK_SHIFT_MASK)
  52. modifiers |= WebEvent::ShiftKey;
  53. if (state & GDK_MOD1_MASK)
  54. modifiers |= WebEvent::AltKey;
  55. if (state & GDK_META_MASK)
  56. modifiers |= WebEvent::MetaKey;
  57. return static_cast<WebEvent::Modifiers>(modifiers);
  58. }
  59. static inline WebMouseEvent::Button buttonForEvent(const GdkEvent* event)
  60. {
  61. unsigned button = 0;
  62. switch (event->type) {
  63. case GDK_MOTION_NOTIFY:
  64. button = WebMouseEvent::NoButton;
  65. if (event->motion.state & GDK_BUTTON1_MASK)
  66. button = WebMouseEvent::LeftButton;
  67. else if (event->motion.state & GDK_BUTTON2_MASK)
  68. button = WebMouseEvent::MiddleButton;
  69. else if (event->motion.state & GDK_BUTTON3_MASK)
  70. button = WebMouseEvent::RightButton;
  71. break;
  72. case GDK_BUTTON_PRESS:
  73. case GDK_2BUTTON_PRESS:
  74. case GDK_3BUTTON_PRESS:
  75. case GDK_BUTTON_RELEASE:
  76. if (event->button.button == 1)
  77. button = WebMouseEvent::LeftButton;
  78. else if (event->button.button == 2)
  79. button = WebMouseEvent::MiddleButton;
  80. else if (event->button.button == 3)
  81. button = WebMouseEvent::RightButton;
  82. break;
  83. default:
  84. ASSERT_NOT_REACHED();
  85. }
  86. return static_cast<WebMouseEvent::Button>(button);
  87. }
  88. WebMouseEvent WebEventFactory::createWebMouseEvent(const GdkEvent* event, int currentClickCount)
  89. {
  90. double x, y, xRoot, yRoot;
  91. gdk_event_get_coords(event, &x, &y);
  92. gdk_event_get_root_coords(event, &xRoot, &yRoot);
  93. WebEvent::Type type = static_cast<WebEvent::Type>(0);
  94. switch (event->type) {
  95. case GDK_MOTION_NOTIFY:
  96. type = WebEvent::MouseMove;
  97. break;
  98. case GDK_BUTTON_PRESS:
  99. case GDK_2BUTTON_PRESS:
  100. case GDK_3BUTTON_PRESS:
  101. type = WebEvent::MouseDown;
  102. break;
  103. case GDK_BUTTON_RELEASE:
  104. type = WebEvent::MouseUp;
  105. break;
  106. default :
  107. ASSERT_NOT_REACHED();
  108. }
  109. return WebMouseEvent(type,
  110. buttonForEvent(event),
  111. IntPoint(x, y),
  112. IntPoint(xRoot, yRoot),
  113. 0 /* deltaX */,
  114. 0 /* deltaY */,
  115. 0 /* deltaZ */,
  116. currentClickCount,
  117. modifiersForEvent(event),
  118. gdk_event_get_time(event));
  119. }
  120. WebWheelEvent WebEventFactory::createWebWheelEvent(const GdkEvent* event)
  121. {
  122. double x, y, xRoot, yRoot;
  123. gdk_event_get_coords(event, &x, &y);
  124. gdk_event_get_root_coords(event, &xRoot, &yRoot);
  125. FloatSize wheelTicks;
  126. switch (event->scroll.direction) {
  127. case GDK_SCROLL_UP:
  128. wheelTicks = FloatSize(0, 1);
  129. break;
  130. case GDK_SCROLL_DOWN:
  131. wheelTicks = FloatSize(0, -1);
  132. break;
  133. case GDK_SCROLL_LEFT:
  134. wheelTicks = FloatSize(1, 0);
  135. break;
  136. case GDK_SCROLL_RIGHT:
  137. wheelTicks = FloatSize(-1, 0);
  138. break;
  139. #if GTK_CHECK_VERSION(3, 3, 18)
  140. case GDK_SCROLL_SMOOTH: {
  141. double deltaX, deltaY;
  142. gdk_event_get_scroll_deltas(event, &deltaX, &deltaY);
  143. wheelTicks = FloatSize(-deltaX, -deltaY);
  144. }
  145. break;
  146. #endif
  147. default:
  148. ASSERT_NOT_REACHED();
  149. }
  150. // FIXME: [GTK] Add a setting to change the pixels per line used for scrolling
  151. // https://bugs.webkit.org/show_bug.cgi?id=54826
  152. float step = static_cast<float>(Scrollbar::pixelsPerLineStep());
  153. FloatSize delta(wheelTicks.width() * step, wheelTicks.height() * step);
  154. return WebWheelEvent(WebEvent::Wheel,
  155. IntPoint(x, y),
  156. IntPoint(xRoot, yRoot),
  157. delta,
  158. wheelTicks,
  159. WebWheelEvent::ScrollByPixelWheelEvent,
  160. modifiersForEvent(event),
  161. gdk_event_get_time(event));
  162. }
  163. WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(const GdkEvent* event, const WebCore::CompositionResults& compositionResults)
  164. {
  165. unsigned int keyValue = event->key.keyval;
  166. String text = compositionResults.simpleString.length() ?
  167. compositionResults.simpleString : PlatformKeyboardEvent::singleCharacterString(keyValue);
  168. int windowsVirtualKeyCode = compositionResults.compositionUpdated() ?
  169. VK_PROCESSKEY : PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(event->key.keyval);
  170. return WebKeyboardEvent((event->type == GDK_KEY_RELEASE) ? WebEvent::KeyUp : WebEvent::KeyDown,
  171. text,
  172. text,
  173. PlatformKeyboardEvent::keyIdentifierForGdkKeyCode(keyValue),
  174. windowsVirtualKeyCode,
  175. static_cast<int>(keyValue),
  176. 0 /* macCharCode */,
  177. false /* isAutoRepeat */,
  178. isGdkKeyCodeFromKeyPad(keyValue),
  179. false /* isSystemKey */,
  180. modifiersForEvent(event),
  181. gdk_event_get_time(event));
  182. }
  183. } // namespace WebKit