Update V8 to version 4.7.16.
[chromium-blink-merge.git] / ui / events / test / events_test_utils_x11.cc
blobcfb28b1a4593d99f3b20f5e07cdf6439899cfea4
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/events/test/events_test_utils_x11.h"
7 #include <X11/extensions/XI2.h>
8 #include <X11/keysym.h>
9 #include <X11/X.h>
10 #include <X11/Xlib.h>
12 #include "base/logging.h"
13 #include "ui/events/devices/x11/touch_factory_x11.h"
14 #include "ui/events/event_constants.h"
15 #include "ui/events/event_utils.h"
16 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
18 namespace {
20 // Converts ui::EventType to state for X*Events.
21 unsigned int XEventState(int flags) {
22 return
23 ((flags & ui::EF_SHIFT_DOWN) ? ShiftMask : 0) |
24 ((flags & ui::EF_CONTROL_DOWN) ? ControlMask : 0) |
25 ((flags & ui::EF_ALT_DOWN) ? Mod1Mask : 0) |
26 ((flags & ui::EF_CAPS_LOCK_DOWN) ? LockMask : 0) |
27 ((flags & ui::EF_ALTGR_DOWN) ? Mod5Mask : 0) |
28 ((flags & ui::EF_COMMAND_DOWN) ? Mod4Mask : 0) |
29 ((flags & ui::EF_MOD3_DOWN) ? Mod3Mask : 0) |
30 ((flags & ui::EF_LEFT_MOUSE_BUTTON) ? Button1Mask: 0) |
31 ((flags & ui::EF_MIDDLE_MOUSE_BUTTON) ? Button2Mask: 0) |
32 ((flags & ui::EF_RIGHT_MOUSE_BUTTON) ? Button3Mask: 0);
35 // Converts EventType to XKeyEvent type.
36 int XKeyEventType(ui::EventType type) {
37 switch (type) {
38 case ui::ET_KEY_PRESSED:
39 return KeyPress;
40 case ui::ET_KEY_RELEASED:
41 return KeyRelease;
42 default:
43 return 0;
47 // Converts EventType to XI2 event type.
48 int XIKeyEventType(ui::EventType type) {
49 switch (type) {
50 case ui::ET_KEY_PRESSED:
51 return XI_KeyPress;
52 case ui::ET_KEY_RELEASED:
53 return XI_KeyRelease;
54 default:
55 return 0;
59 int XIButtonEventType(ui::EventType type) {
60 switch (type) {
61 case ui::ET_MOUSEWHEEL:
62 case ui::ET_MOUSE_PRESSED:
63 // The button release X events for mouse wheels are dropped by Aura.
64 return XI_ButtonPress;
65 case ui::ET_MOUSE_RELEASED:
66 return XI_ButtonRelease;
67 default:
68 NOTREACHED();
69 return 0;
73 // Converts Aura event type and flag to X button event.
74 unsigned int XButtonEventButton(ui::EventType type,
75 int flags) {
76 // Aura events don't keep track of mouse wheel button, so just return
77 // the first mouse wheel button.
78 if (type == ui::ET_MOUSEWHEEL)
79 return Button4;
81 if (flags & ui::EF_LEFT_MOUSE_BUTTON)
82 return Button1;
83 if (flags & ui::EF_MIDDLE_MOUSE_BUTTON)
84 return Button2;
85 if (flags & ui::EF_RIGHT_MOUSE_BUTTON)
86 return Button3;
88 return 0;
91 void InitValuatorsForXIDeviceEvent(XIDeviceEvent* xiev) {
92 int valuator_count = ui::DeviceDataManagerX11::DT_LAST_ENTRY;
93 xiev->valuators.mask_len = (valuator_count / 8) + 1;
94 xiev->valuators.mask = new unsigned char[xiev->valuators.mask_len];
95 memset(xiev->valuators.mask, 0, xiev->valuators.mask_len);
96 xiev->valuators.values = new double[valuator_count];
99 XEvent* CreateXInput2Event(int deviceid,
100 int evtype,
101 int tracking_id,
102 const gfx::Point& location) {
103 XEvent* event = new XEvent;
104 memset(event, 0, sizeof(*event));
105 event->type = GenericEvent;
106 event->xcookie.data = new XIDeviceEvent;
107 XIDeviceEvent* xiev =
108 static_cast<XIDeviceEvent*>(event->xcookie.data);
109 memset(xiev, 0, sizeof(XIDeviceEvent));
110 xiev->deviceid = deviceid;
111 xiev->sourceid = deviceid;
112 xiev->evtype = evtype;
113 xiev->detail = tracking_id;
114 xiev->event_x = location.x();
115 xiev->event_y = location.y();
116 xiev->event = DefaultRootWindow(gfx::GetXDisplay());
117 if (evtype == XI_ButtonPress || evtype == XI_ButtonRelease) {
118 xiev->buttons.mask_len = 8;
119 xiev->buttons.mask = new unsigned char[xiev->buttons.mask_len];
120 memset(xiev->buttons.mask, 0, xiev->buttons.mask_len);
122 return event;
125 } // namespace
127 namespace ui {
129 // XInput2 events contain additional data that need to be explicitly freed (see
130 // |CreateXInput2Event()|.
131 void XEventDeleter::operator()(XEvent* event) {
132 if (event->type == GenericEvent) {
133 XIDeviceEvent* xiev =
134 static_cast<XIDeviceEvent*>(event->xcookie.data);
135 if (xiev) {
136 delete[] xiev->valuators.mask;
137 delete[] xiev->valuators.values;
138 delete[] xiev->buttons.mask;
139 delete xiev;
142 delete event;
145 ScopedXI2Event::ScopedXI2Event() {}
146 ScopedXI2Event::~ScopedXI2Event() {}
148 void ScopedXI2Event::InitKeyEvent(EventType type,
149 KeyboardCode key_code,
150 int flags) {
151 XDisplay* display = gfx::GetXDisplay();
152 event_.reset(new XEvent);
153 memset(event_.get(), 0, sizeof(XEvent));
154 event_->type = XKeyEventType(type);
155 CHECK_NE(0, event_->type);
156 event_->xkey.serial = 0;
157 event_->xkey.send_event = 0;
158 event_->xkey.display = display;
159 event_->xkey.time = 0;
160 event_->xkey.window = 0;
161 event_->xkey.root = 0;
162 event_->xkey.subwindow = 0;
163 event_->xkey.x = 0;
164 event_->xkey.y = 0;
165 event_->xkey.x_root = 0;
166 event_->xkey.y_root = 0;
167 event_->xkey.state = XEventState(flags);
168 event_->xkey.keycode = XKeyCodeForWindowsKeyCode(key_code, flags, display);
169 event_->xkey.same_screen = 1;
172 void ScopedXI2Event::InitMotionEvent(const gfx::Point& location,
173 const gfx::Point& root_location,
174 int flags) {
175 XDisplay* display = gfx::GetXDisplay();
176 event_.reset(new XEvent);
177 memset(event_.get(), 0, sizeof(XEvent));
178 event_->type = MotionNotify;
179 event_->xmotion.serial = 0;
180 event_->xmotion.send_event = 0;
181 event_->xmotion.display = display;
182 event_->xmotion.time = 0;
183 event_->xmotion.window = 0;
184 event_->xmotion.root = 0;
185 event_->xkey.subwindow = 0;
186 event_->xmotion.x = location.x();
187 event_->xmotion.y = location.y();
188 event_->xmotion.x_root = root_location.x();
189 event_->xmotion.y_root = root_location.y();
190 event_->xmotion.state = XEventState(flags);
191 event_->xmotion.same_screen = 1;
194 void ScopedXI2Event::InitGenericKeyEvent(int deviceid,
195 int sourceid,
196 EventType type,
197 KeyboardCode key_code,
198 int flags) {
199 event_.reset(
200 CreateXInput2Event(deviceid, XIKeyEventType(type), 0, gfx::Point()));
201 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event_->xcookie.data);
202 CHECK_NE(0, xievent->evtype);
203 XDisplay* display = gfx::GetXDisplay();
204 event_->xgeneric.display = display;
205 xievent->display = display;
206 xievent->mods.effective = XEventState(flags);
207 xievent->detail = XKeyCodeForWindowsKeyCode(key_code, flags, display);
208 xievent->sourceid = sourceid;
211 void ScopedXI2Event::InitGenericButtonEvent(int deviceid,
212 EventType type,
213 const gfx::Point& location,
214 int flags) {
215 event_.reset(CreateXInput2Event(deviceid,
216 XIButtonEventType(type), 0, gfx::Point()));
217 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event_->xcookie.data);
218 xievent->mods.effective = XEventState(flags);
219 xievent->detail = XButtonEventButton(type, flags);
220 xievent->event_x = location.x();
221 xievent->event_y = location.y();
222 XISetMask(xievent->buttons.mask, xievent->detail);
223 // Setup an empty valuator list for generic button events.
224 SetUpValuators(std::vector<Valuator>());
227 void ScopedXI2Event::InitGenericMouseWheelEvent(int deviceid,
228 int wheel_delta,
229 int flags) {
230 InitGenericButtonEvent(deviceid, ui::ET_MOUSEWHEEL, gfx::Point(), flags);
231 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event_->xcookie.data);
232 xievent->detail = wheel_delta > 0 ? Button4 : Button5;
235 void ScopedXI2Event::InitScrollEvent(int deviceid,
236 int x_offset,
237 int y_offset,
238 int x_offset_ordinal,
239 int y_offset_ordinal,
240 int finger_count) {
241 event_.reset(CreateXInput2Event(deviceid, XI_Motion, 0, gfx::Point()));
243 Valuator valuators[] = {
244 Valuator(DeviceDataManagerX11::DT_CMT_SCROLL_X, x_offset),
245 Valuator(DeviceDataManagerX11::DT_CMT_SCROLL_Y, y_offset),
246 Valuator(DeviceDataManagerX11::DT_CMT_ORDINAL_X, x_offset_ordinal),
247 Valuator(DeviceDataManagerX11::DT_CMT_ORDINAL_Y, y_offset_ordinal),
248 Valuator(DeviceDataManagerX11::DT_CMT_FINGER_COUNT, finger_count)
250 SetUpValuators(
251 std::vector<Valuator>(valuators, valuators + arraysize(valuators)));
254 void ScopedXI2Event::InitFlingScrollEvent(int deviceid,
255 int x_velocity,
256 int y_velocity,
257 int x_velocity_ordinal,
258 int y_velocity_ordinal,
259 bool is_cancel) {
260 event_.reset(CreateXInput2Event(deviceid, XI_Motion, deviceid, gfx::Point()));
262 Valuator valuators[] = {
263 Valuator(DeviceDataManagerX11::DT_CMT_FLING_STATE, is_cancel ? 1 : 0),
264 Valuator(DeviceDataManagerX11::DT_CMT_FLING_Y, y_velocity),
265 Valuator(DeviceDataManagerX11::DT_CMT_ORDINAL_Y, y_velocity_ordinal),
266 Valuator(DeviceDataManagerX11::DT_CMT_FLING_X, x_velocity),
267 Valuator(DeviceDataManagerX11::DT_CMT_ORDINAL_X, x_velocity_ordinal)
270 SetUpValuators(
271 std::vector<Valuator>(valuators, valuators + arraysize(valuators)));
274 void ScopedXI2Event::InitTouchEvent(int deviceid,
275 int evtype,
276 int tracking_id,
277 const gfx::Point& location,
278 const std::vector<Valuator>& valuators) {
279 event_.reset(CreateXInput2Event(deviceid, evtype, tracking_id, location));
281 // If a timestamp was specified, setup the event.
282 for (size_t i = 0; i < valuators.size(); ++i) {
283 if (valuators[i].data_type ==
284 DeviceDataManagerX11::DT_TOUCH_RAW_TIMESTAMP) {
285 SetUpValuators(valuators);
286 return;
290 // No timestamp was specified. Use |ui::EventTimeForNow()|.
291 std::vector<Valuator> valuators_with_time = valuators;
292 valuators_with_time.push_back(
293 Valuator(DeviceDataManagerX11::DT_TOUCH_RAW_TIMESTAMP,
294 (ui::EventTimeForNow()).InMicroseconds()));
295 SetUpValuators(valuators_with_time);
298 void ScopedXI2Event::SetUpValuators(const std::vector<Valuator>& valuators) {
299 CHECK(event_.get());
300 CHECK_EQ(GenericEvent, event_->type);
301 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(event_->xcookie.data);
302 InitValuatorsForXIDeviceEvent(xiev);
303 ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
304 for (size_t i = 0; i < valuators.size(); ++i) {
305 manager->SetValuatorDataForTest(xiev, valuators[i].data_type,
306 valuators[i].value);
310 void SetUpTouchPadForTest(int deviceid) {
311 std::vector<int> device_list;
312 device_list.push_back(deviceid);
314 TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
315 ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
316 manager->SetDeviceListForTest(std::vector<int>(), device_list,
317 std::vector<int>());
320 void SetUpTouchDevicesForTest(const std::vector<int>& devices) {
321 TouchFactory::GetInstance()->SetTouchDeviceForTest(devices);
322 ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
323 manager->SetDeviceListForTest(devices, std::vector<int>(),
324 std::vector<int>());
327 void SetUpPointerDevicesForTest(const std::vector<int>& devices) {
328 TouchFactory::GetInstance()->SetPointerDeviceForTest(devices);
329 ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
330 manager->SetDeviceListForTest(std::vector<int>(), std::vector<int>(),
331 devices);
334 } // namespace ui