15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstring>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <X11/extensions/XInput2.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/Xlib.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generically-named #defines from Xlib that conflict with symbols in GTest.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef Bool
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef None
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event_constants.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event_utils.h"
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/base/touch/touch_factory_x11.h"
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/base/x/device_data_manager.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes the passed-in Xlib event.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitButtonEvent(XEvent* event,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     bool is_press,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const gfx::Point& location,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int button,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int state) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(event, 0, sizeof(*event));
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't bother setting fields that the event code doesn't use, such as
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // x_root/y_root and window/root/subwindow.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XButtonEvent* button_event = &(event->xbutton);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  button_event->type = is_press ? ButtonPress : ButtonRelease;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  button_event->x = location.x();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  button_event->y = location.y();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  button_event->button = button;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  button_event->state = state;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(USE_XI2_MT)
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int kValuatorNum = 3;
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int kTouchValuatorMap[kValuatorNum][4] = {
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // { valuator_index, valuator_type, min_val, max_val }
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  { 0, DeviceDataManager::DT_TOUCH_MAJOR, 0, 1000},
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  { 1, DeviceDataManager::DT_TOUCH_ORIENTATION, 0, 1.0},
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  { 2, DeviceDataManager::DT_TOUCH_PRESSURE, 0, 1000},
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)struct Valuator {
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Valuator(DeviceDataManager::DataType type, double v)
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      : data_type(type), value(v) {}
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DeviceDataManager::DataType data_type;
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  double value;
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)XEvent* CreateTouchEvent(int deviceid,
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         int evtype,
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         int tracking_id,
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         const gfx::Point& location,
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         const std::vector<Valuator>& valuators) {
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  XEvent* event = new XEvent;
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  memset(event, 0, sizeof(*event));
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  event->type = GenericEvent;
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  event->xcookie.data = new XIDeviceEvent;
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  XIDeviceEvent* xiev =
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      static_cast<XIDeviceEvent*>(event->xcookie.data);
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  xiev->deviceid = deviceid;
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  xiev->sourceid = deviceid;
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  xiev->evtype = evtype;
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  xiev->detail = tracking_id;
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  xiev->event_x = location.x();
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  xiev->event_y = location.y();
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  xiev->valuators.mask_len = (valuators.size() / 8) + 1;
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  xiev->valuators.mask = new unsigned char[xiev->valuators.mask_len];
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  memset(xiev->valuators.mask, 0, xiev->valuators.mask_len);
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  xiev->valuators.values = new double[valuators.size()];
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int val_count = 0;
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (int i = 0; i < kValuatorNum; i++) {
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for(size_t j = 0; j < valuators.size(); j++) {
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (valuators[j].data_type == kTouchValuatorMap[i][1]) {
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        XISetMask(xiev->valuators.mask, kTouchValuatorMap[i][0]);
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        xiev->valuators.values[val_count++] = valuators[j].value;
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      }
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return event;
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DestroyTouchEvent(XEvent* event) {
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  XIDeviceEvent* xiev =
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      static_cast<XIDeviceEvent*>(event->xcookie.data);
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (xiev) {
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    delete[] xiev->valuators.mask;
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    delete[] xiev->valuators.values;
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    delete xiev;
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  delete event;
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void SetupTouchFactory(const std::vector<unsigned int>& devices) {
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TouchFactory* factory = TouchFactory::GetInstance();
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  factory->SetTouchDeviceForTest(devices);
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void SetupDeviceDataManager(const std::vector<unsigned int>& devices) {
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  manager->SetDeviceListForTest(devices);
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (size_t i = 0; i < devices.size(); i++) {
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for (int j = 0; j < kValuatorNum; j++) {
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      manager->SetDeviceValuatorForTest(
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          devices[i],
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          kTouchValuatorMap[j][0],
120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          static_cast<DeviceDataManager::DataType>(kTouchValuatorMap[j][1]),
121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          kTouchValuatorMap[j][2],
122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          kTouchValuatorMap[j][3]);
123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(EventsXTest, ButtonEvents) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XEvent event;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point location(5, 10);
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Vector2d offset;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitButtonEvent(&event, true, location, 1, 0);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(&event));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, ui::EventFlagsFromNative(&event));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ui::IsMouseEvent(&event));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitButtonEvent(&event, true, location, 2, Button1Mask | ShiftMask);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(&event));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON |
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ui::EF_SHIFT_DOWN,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ui::EventFlagsFromNative(&event));
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ui::IsMouseEvent(&event));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitButtonEvent(&event, false, location, 3, 0);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSE_RELEASED, ui::EventTypeFromNative(&event));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, ui::EventFlagsFromNative(&event));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ui::IsMouseEvent(&event));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Scroll up.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitButtonEvent(&event, true, location, 4, 0);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ui::EventFlagsFromNative(&event));
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ui::IsMouseEvent(&event));
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  offset = ui::GetMouseWheelOffset(&event);
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_GT(offset.y(), 0);
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, offset.x());
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Scroll down.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitButtonEvent(&event, true, location, 5, 0);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ui::EventFlagsFromNative(&event));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ui::IsMouseEvent(&event));
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  offset = ui::GetMouseWheelOffset(&event);
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_LT(offset.y(), 0);
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, offset.x());
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Scroll left, typically.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitButtonEvent(&event, true, location, 6, 0);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ui::EventFlagsFromNative(&event));
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ui::IsMouseEvent(&event));
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  offset = ui::GetMouseWheelOffset(&event);
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, offset.y());
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, offset.x());
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Scroll right, typically.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitButtonEvent(&event, true, location, 7, 0);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ui::EventFlagsFromNative(&event));
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ui::IsMouseEvent(&event));
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  offset = ui::GetMouseWheelOffset(&event);
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, offset.y());
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, offset.x());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(derat): Test XInput code.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(EventsXTest, AvoidExtraEventsOnWheelRelease) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XEvent event;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point location(5, 10);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitButtonEvent(&event, true, location, 4, 0);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should return ET_UNKNOWN for the release event instead of returning
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ET_MOUSEWHEEL; otherwise we'll scroll twice for each scrollwheel step.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitButtonEvent(&event, false, location, 4, 0);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_UNKNOWN, ui::EventTypeFromNative(&event));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(derat): Test XInput code.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(EventsXTest, EnterLeaveEvent) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XEvent event;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.type = EnterNotify;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.x = 10;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.y = 20;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.x_root = 110;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.y_root = 120;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Mouse enter events are converted to mouse move events to be consistent with
221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // the way views handle mouse enter. See comments for EnterNotify case in
222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // ui::EventTypeFromNative for more details.
223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSE_MOVED, ui::EventTypeFromNative(&event));
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10,20", ui::EventLocationFromNative(&event).ToString());
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("110,120", ui::EventSystemLocationFromNative(&event).ToString());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.type = LeaveNotify;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.x = 30;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.y = 40;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.x_root = 230;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.xcrossing.y_root = 240;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSE_EXITED, ui::EventTypeFromNative(&event));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("30,40", ui::EventLocationFromNative(&event).ToString());
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("230,240", ui::EventSystemLocationFromNative(&event).ToString());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(USE_XI2_MT)
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST(EventsXTest, TouchEventBasic) {
239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::vector<unsigned int> devices;
240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  devices.push_back(0);
241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SetupTouchFactory(devices);
242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SetupDeviceDataManager(devices);
243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  XEvent* event = NULL;
244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::vector<Valuator> valuators;
245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Init touch begin with tracking id 5, touch id 0.
247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.push_back(Valuator(DeviceDataManager::DT_TOUCH_MAJOR, 20));
248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.push_back(Valuator(DeviceDataManager::DT_TOUCH_ORIENTATION, 0.3f));
249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.push_back(Valuator(DeviceDataManager::DT_TOUCH_PRESSURE, 100));
250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  event = CreateTouchEvent(0, XI_TouchBegin, 5, gfx::Point(10, 10), valuators);
251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ("10,10", ui::EventLocationFromNative(event).ToString());
252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchId(event), 0);
253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchRadiusX(event), 10);
254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchAngle(event), 0.15f);
255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchForce(event), 0.1f);
256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DestroyTouchEvent(event);
257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Touch update, with new orientation info.
259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.clear();
260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.push_back(Valuator(DeviceDataManager::DT_TOUCH_ORIENTATION, 0.5f));
261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  event = CreateTouchEvent(0, XI_TouchUpdate, 5, gfx::Point(20, 20), valuators);
262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ("20,20", ui::EventLocationFromNative(event).ToString());
263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchId(event), 0);
264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchRadiusX(event), 10);
265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchAngle(event), 0.25f);
266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchForce(event), 0.1f);
267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DestroyTouchEvent(event);
268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Another touch with tracking id 6, touch id 1.
270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.clear();
271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.push_back(Valuator(DeviceDataManager::DT_TOUCH_MAJOR, 100));
272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.push_back(Valuator(DeviceDataManager::DT_TOUCH_ORIENTATION, 0.9f));
273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.push_back(Valuator(DeviceDataManager::DT_TOUCH_PRESSURE, 500));
274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  event = CreateTouchEvent(
275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0, XI_TouchBegin, 6, gfx::Point(200, 200), valuators);
276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ("200,200", ui::EventLocationFromNative(event).ToString());
277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchId(event), 1);
278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchRadiusX(event), 50);
279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchAngle(event), 0.45f);
280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchForce(event), 0.5f);
281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DestroyTouchEvent(event);
282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Touch with tracking id 5 should have old radius/angle value and new pressue
284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // value.
285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.clear();
286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.push_back(Valuator(DeviceDataManager::DT_TOUCH_PRESSURE, 50));
287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  event = CreateTouchEvent(0, XI_TouchEnd, 5, gfx::Point(30, 30), valuators);
288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ("30,30", ui::EventLocationFromNative(event).ToString());
289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchId(event), 0);
290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchRadiusX(event), 10);
291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchAngle(event), 0.25f);
292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchForce(event), 0.05f);
293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DestroyTouchEvent(event);
294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Touch with tracking id 6 should have old angle/pressure value and new
296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // radius value.
297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.clear();
298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  valuators.push_back(Valuator(DeviceDataManager::DT_TOUCH_MAJOR, 50));
299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  event = CreateTouchEvent(0, XI_TouchEnd, 6, gfx::Point(200, 200), valuators);
300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ("200,200", ui::EventLocationFromNative(event).ToString());
301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchId(event), 1);
302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(GetTouchRadiusX(event), 25);
303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchAngle(event), 0.45f);
304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FLOAT_EQ(GetTouchForce(event), 0.5f);
305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DestroyTouchEvent(event);
306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
309