Upstream version 10.38.220.0
[platform/framework/web/crosswalk.git] / src / ui / events / test / events_test_utils_x11.cc
index 210216b..28558a2 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "base/logging.h"
 #include "ui/events/event_constants.h"
+#include "ui/events/event_utils.h"
 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
 #include "ui/events/x/touch_factory_x11.h"
 
@@ -23,6 +24,10 @@ unsigned int XEventState(int flags) {
       ((flags & ui::EF_CONTROL_DOWN) ? ControlMask : 0) |
       ((flags & ui::EF_ALT_DOWN) ? Mod1Mask : 0) |
       ((flags & ui::EF_CAPS_LOCK_DOWN) ? LockMask : 0) |
+      ((flags & ui::EF_ALTGR_DOWN) ? Mod5Mask : 0) |
+      ((flags & ui::EF_COMMAND_DOWN) ? Mod4Mask : 0) |
+      ((flags & ui::EF_MOD3_DOWN) ? Mod3Mask : 0) |
+      ((flags & ui::EF_NUMPAD_KEY) ? Mod2Mask : 0) |
       ((flags & ui::EF_LEFT_MOUSE_BUTTON) ? Button1Mask: 0) |
       ((flags & ui::EF_MIDDLE_MOUSE_BUTTON) ? Button2Mask: 0) |
       ((flags & ui::EF_RIGHT_MOUSE_BUTTON) ? Button3Mask: 0);
@@ -40,32 +45,32 @@ int XKeyEventType(ui::EventType type) {
   }
 }
 
-// Converts EventType to XButtonEvent type.
-int XButtonEventType(ui::EventType type) {
+// Converts EventType to XI2 event type.
+int XIKeyEventType(ui::EventType type) {
+  switch (type) {
+    case ui::ET_KEY_PRESSED:
+      return XI_KeyPress;
+    case ui::ET_KEY_RELEASED:
+      return XI_KeyRelease;
+    default:
+      return 0;
+  }
+}
+
+int XIButtonEventType(ui::EventType type) {
   switch (type) {
     case ui::ET_MOUSEWHEEL:
     case ui::ET_MOUSE_PRESSED:
       // The button release X events for mouse wheels are dropped by Aura.
-      return ButtonPress;
+      return XI_ButtonPress;
     case ui::ET_MOUSE_RELEASED:
-      return ButtonRelease;
+      return XI_ButtonRelease;
     default:
+      NOTREACHED();
       return 0;
   }
 }
 
-// Converts KeyboardCode to XKeyEvent keycode.
-unsigned int XKeyEventKeyCode(ui::KeyboardCode key_code,
-                              int flags,
-                              XDisplay* display) {
-  const int keysym = XKeysymForWindowsKeyCode(key_code,
-                                              flags & ui::EF_SHIFT_DOWN);
-  // Tests assume the keycode for XK_less is equal to the one of XK_comma,
-  // but XKeysymToKeycode returns 94 for XK_less while it returns 59 for
-  // XK_comma. Here we convert the value for XK_less to the value for XK_comma.
-  return (keysym == XK_less) ? 59 : XKeysymToKeycode(display, keysym);
-}
-
 // Converts Aura event type and flag to X button event.
 unsigned int XButtonEventButton(ui::EventType type,
                                 int flags) {
@@ -74,20 +79,18 @@ unsigned int XButtonEventButton(ui::EventType type,
   if (type == ui::ET_MOUSEWHEEL)
     return Button4;
 
-  switch (flags) {
-    case ui::EF_LEFT_MOUSE_BUTTON:
-      return Button1;
-    case ui::EF_MIDDLE_MOUSE_BUTTON:
-      return Button2;
-    case ui::EF_RIGHT_MOUSE_BUTTON:
-      return Button3;
-  }
+  if (flags & ui::EF_LEFT_MOUSE_BUTTON)
+    return Button1;
+  if (flags & ui::EF_MIDDLE_MOUSE_BUTTON)
+    return Button2;
+  if (flags & ui::EF_RIGHT_MOUSE_BUTTON)
+    return Button3;
 
   return 0;
 }
 
 void InitValuatorsForXIDeviceEvent(XIDeviceEvent* xiev) {
-  int valuator_count = ui::DeviceDataManager::DT_LAST_ENTRY;
+  int valuator_count = ui::DeviceDataManagerX11::DT_LAST_ENTRY;
   xiev->valuators.mask_len = (valuator_count / 8) + 1;
   xiev->valuators.mask = new unsigned char[xiev->valuators.mask_len];
   memset(xiev->valuators.mask, 0, xiev->valuators.mask_len);
@@ -111,7 +114,12 @@ XEvent* CreateXInput2Event(int deviceid,
   xiev->detail = tracking_id;
   xiev->event_x = location.x();
   xiev->event_y = location.y();
-
+  xiev->event = DefaultRootWindow(gfx::GetXDisplay());
+  if (evtype == XI_ButtonPress || evtype == XI_ButtonRelease) {
+    xiev->buttons.mask_len = 8;
+    xiev->buttons.mask = new unsigned char[xiev->buttons.mask_len];
+    memset(xiev->buttons.mask, 0, xiev->buttons.mask_len);
+  }
   return event;
 }
 
@@ -119,15 +127,28 @@ XEvent* CreateXInput2Event(int deviceid,
 
 namespace ui {
 
-ScopedXI2Event::ScopedXI2Event() {}
-ScopedXI2Event::~ScopedXI2Event() {
-  Cleanup();
+// XInput2 events contain additional data that need to be explicitly freed (see
+// |CreateXInput2Event()|.
+void XEventDeleter::operator()(XEvent* event) {
+  if (event->type == GenericEvent) {
+    XIDeviceEvent* xiev =
+        static_cast<XIDeviceEvent*>(event->xcookie.data);
+    if (xiev) {
+      delete[] xiev->valuators.mask;
+      delete[] xiev->valuators.values;
+      delete[] xiev->buttons.mask;
+      delete xiev;
+    }
+  }
+  delete event;
 }
 
+ScopedXI2Event::ScopedXI2Event() {}
+ScopedXI2Event::~ScopedXI2Event() {}
+
 void ScopedXI2Event::InitKeyEvent(EventType type,
                                   KeyboardCode key_code,
                                   int flags) {
-  Cleanup();
   XDisplay* display = gfx::GetXDisplay();
   event_.reset(new XEvent);
   memset(event_.get(), 0, sizeof(XEvent));
@@ -145,39 +166,49 @@ void ScopedXI2Event::InitKeyEvent(EventType type,
   event_->xkey.x_root = 0;
   event_->xkey.y_root = 0;
   event_->xkey.state = XEventState(flags);
-  event_->xkey.keycode = XKeyEventKeyCode(key_code, flags, display);
+  event_->xkey.keycode = XKeyCodeForWindowsKeyCode(key_code, flags, display);
   event_->xkey.same_screen = 1;
 }
 
-void ScopedXI2Event::InitButtonEvent(EventType type,
-                                     int flags) {
-  Cleanup();
-  event_.reset(new XEvent);
-  memset(event_.get(), 0, sizeof(XEvent));
-  event_->type = XButtonEventType(type);
-  CHECK_NE(0, event_->type);
-  event_->xbutton.serial = 0;
-  event_->xbutton.send_event = 0;
-  event_->xbutton.display = gfx::GetXDisplay();
-  event_->xbutton.time = 0;
-  event_->xbutton.window = 0;
-  event_->xbutton.root = 0;
-  event_->xbutton.subwindow = 0;
-  event_->xbutton.x = 0;
-  event_->xbutton.y = 0;
-  event_->xbutton.x_root = 0;
-  event_->xbutton.y_root = 0;
-  event_->xbutton.state = XEventState(flags);
-  event_->xbutton.button = XButtonEventButton(type, flags);
-  event_->xbutton.same_screen = 1;
+void ScopedXI2Event::InitGenericKeyEvent(int deviceid,
+                                         int sourceid,
+                                         EventType type,
+                                         KeyboardCode key_code,
+                                         int flags) {
+  event_.reset(
+      CreateXInput2Event(deviceid, XIKeyEventType(type), 0, gfx::Point()));
+  XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event_->xcookie.data);
+  CHECK_NE(0, xievent->evtype);
+  XDisplay* display = gfx::GetXDisplay();
+  event_->xgeneric.display = display;
+  xievent->display = display;
+  xievent->mods.effective = XEventState(flags);
+  xievent->detail = XKeyCodeForWindowsKeyCode(key_code, flags, display);
+  xievent->sourceid = sourceid;
 }
 
-void ScopedXI2Event::InitMouseWheelEvent(int wheel_delta,
-                                         int flags) {
-  InitButtonEvent(ui::ET_MOUSEWHEEL, flags);
-  // MouseWheelEvents are not taking horizontal scrolls into account
-  // at the moment.
-  event_->xbutton.button = wheel_delta > 0 ? Button4 : Button5;
+void ScopedXI2Event::InitGenericButtonEvent(int deviceid,
+                                            EventType type,
+                                            const gfx::Point& location,
+                                            int flags) {
+  event_.reset(CreateXInput2Event(deviceid,
+                                  XIButtonEventType(type), 0, gfx::Point()));
+  XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event_->xcookie.data);
+  xievent->mods.effective = XEventState(flags);
+  xievent->detail = XButtonEventButton(type, flags);
+  xievent->event_x = location.x();
+  xievent->event_y = location.y();
+  XISetMask(xievent->buttons.mask, xievent->detail);
+  // Setup an empty valuator list for generic button events.
+  SetUpValuators(std::vector<Valuator>());
+}
+
+void ScopedXI2Event::InitGenericMouseWheelEvent(int deviceid,
+                                                int wheel_delta,
+                                                int flags) {
+  InitGenericButtonEvent(deviceid, ui::ET_MOUSEWHEEL, gfx::Point(), flags);
+  XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event_->xcookie.data);
+  xievent->detail = wheel_delta > 0 ? Button4 : Button5;
 }
 
 void ScopedXI2Event::InitScrollEvent(int deviceid,
@@ -186,15 +217,14 @@ void ScopedXI2Event::InitScrollEvent(int deviceid,
                                      int x_offset_ordinal,
                                      int y_offset_ordinal,
                                      int finger_count) {
-  Cleanup();
   event_.reset(CreateXInput2Event(deviceid, XI_Motion, 0, gfx::Point()));
 
   Valuator valuators[] = {
-    Valuator(DeviceDataManager::DT_CMT_SCROLL_X, x_offset),
-    Valuator(DeviceDataManager::DT_CMT_SCROLL_Y, y_offset),
-    Valuator(DeviceDataManager::DT_CMT_ORDINAL_X, x_offset_ordinal),
-    Valuator(DeviceDataManager::DT_CMT_ORDINAL_Y, y_offset_ordinal),
-    Valuator(DeviceDataManager::DT_CMT_FINGER_COUNT, finger_count)
+    Valuator(DeviceDataManagerX11::DT_CMT_SCROLL_X, x_offset),
+    Valuator(DeviceDataManagerX11::DT_CMT_SCROLL_Y, y_offset),
+    Valuator(DeviceDataManagerX11::DT_CMT_ORDINAL_X, x_offset_ordinal),
+    Valuator(DeviceDataManagerX11::DT_CMT_ORDINAL_Y, y_offset_ordinal),
+    Valuator(DeviceDataManagerX11::DT_CMT_FINGER_COUNT, finger_count)
   };
   SetUpValuators(
       std::vector<Valuator>(valuators, valuators + arraysize(valuators)));
@@ -206,15 +236,14 @@ void ScopedXI2Event::InitFlingScrollEvent(int deviceid,
                                           int x_velocity_ordinal,
                                           int y_velocity_ordinal,
                                           bool is_cancel) {
-  Cleanup();
   event_.reset(CreateXInput2Event(deviceid, XI_Motion, deviceid, gfx::Point()));
 
   Valuator valuators[] = {
-    Valuator(DeviceDataManager::DT_CMT_FLING_STATE, is_cancel ? 1 : 0),
-    Valuator(DeviceDataManager::DT_CMT_FLING_Y, y_velocity),
-    Valuator(DeviceDataManager::DT_CMT_ORDINAL_Y, y_velocity_ordinal),
-    Valuator(DeviceDataManager::DT_CMT_FLING_X, x_velocity),
-    Valuator(DeviceDataManager::DT_CMT_ORDINAL_X, x_velocity_ordinal)
+    Valuator(DeviceDataManagerX11::DT_CMT_FLING_STATE, is_cancel ? 1 : 0),
+    Valuator(DeviceDataManagerX11::DT_CMT_FLING_Y, y_velocity),
+    Valuator(DeviceDataManagerX11::DT_CMT_ORDINAL_Y, y_velocity_ordinal),
+    Valuator(DeviceDataManagerX11::DT_CMT_FLING_X, x_velocity),
+    Valuator(DeviceDataManagerX11::DT_CMT_ORDINAL_X, x_velocity_ordinal)
   };
 
   SetUpValuators(
@@ -226,22 +255,23 @@ void ScopedXI2Event::InitTouchEvent(int deviceid,
                                     int tracking_id,
                                     const gfx::Point& location,
                                     const std::vector<Valuator>& valuators) {
-  Cleanup();
   event_.reset(CreateXInput2Event(deviceid, evtype, tracking_id, location));
-  SetUpValuators(valuators);
-}
 
-void ScopedXI2Event::Cleanup() {
-  if (event_.get() && event_->type == GenericEvent) {
-    XIDeviceEvent* xiev =
-        static_cast<XIDeviceEvent*>(event_->xcookie.data);
-    if (xiev) {
-      delete[] xiev->valuators.mask;
-      delete[] xiev->valuators.values;
-      delete xiev;
+  // If a timestamp was specified, setup the event.
+  for (size_t i = 0; i < valuators.size(); ++i) {
+    if (valuators[i].data_type ==
+        DeviceDataManagerX11::DT_TOUCH_RAW_TIMESTAMP) {
+      SetUpValuators(valuators);
+      return;
     }
   }
-  event_.reset();
+
+  // No timestamp was specified. Use |ui::EventTimeForNow()|.
+  std::vector<Valuator> valuators_with_time = valuators;
+  valuators_with_time.push_back(
+      Valuator(DeviceDataManagerX11::DT_TOUCH_RAW_TIMESTAMP,
+               (ui::EventTimeForNow()).InMicroseconds()));
+  SetUpValuators(valuators_with_time);
 }
 
 void ScopedXI2Event::SetUpValuators(const std::vector<Valuator>& valuators) {
@@ -249,25 +279,25 @@ void ScopedXI2Event::SetUpValuators(const std::vector<Valuator>& valuators) {
   CHECK_EQ(GenericEvent, event_->type);
   XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(event_->xcookie.data);
   InitValuatorsForXIDeviceEvent(xiev);
-  ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
+  ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
   for (size_t i = 0; i < valuators.size(); ++i) {
     manager->SetValuatorDataForTest(xiev, valuators[i].data_type,
                                     valuators[i].value);
   }
 }
 
-void SetUpScrollDeviceForTest(unsigned int deviceid) {
+void SetUpTouchPadForTest(unsigned int deviceid) {
   std::vector<unsigned int> device_list;
   device_list.push_back(deviceid);
 
   TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
-  ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
+  ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
   manager->SetDeviceListForTest(std::vector<unsigned int>(), device_list);
 }
 
 void SetUpTouchDevicesForTest(const std::vector<unsigned int>& devices) {
   TouchFactory::GetInstance()->SetTouchDeviceForTest(devices);
-  ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
+  ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
   manager->SetDeviceListForTest(devices, std::vector<unsigned int>());
 }