OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "ui/aura/desktop_host.h" | 5 #include "ui/aura/desktop_host.h" |
6 | 6 |
7 #include <X11/cursorfont.h> | 7 #include <X11/cursorfont.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 | 9 |
10 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. | 10 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. |
(...skipping 15 matching lines...) Expand all Loading... | |
26 #include <X11/extensions/XInput2.h> | 26 #include <X11/extensions/XInput2.h> |
27 #include <X11/Xlib.h> | 27 #include <X11/Xlib.h> |
28 | 28 |
29 using std::max; | 29 using std::max; |
30 using std::min; | 30 using std::min; |
31 | 31 |
32 namespace aura { | 32 namespace aura { |
33 | 33 |
34 namespace { | 34 namespace { |
35 | 35 |
36 // The events reported for slave devices can have incorrect information for some | |
37 // fields. This utility function is used to check for such inconsistencies. | |
38 void CheckXEventForConsistency(XEvent* xevent) { | |
39 static bool expect_master_event = false; | |
40 static XIDeviceEvent slave_event; | |
41 static gfx::Point slave_location; | |
42 | |
43 if (xevent->type != GenericEvent) { | |
44 expect_master_event = false; | |
45 return; | |
46 } | |
47 | |
48 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); | |
49 if (xievent->evtype != XI_Motion && | |
50 xievent->evtype != XI_ButtonPress && | |
51 xievent->evtype != XI_ButtonRelease) { | |
52 expect_master_event = false; | |
53 return; | |
54 } | |
55 | |
56 if (xievent->sourceid == xievent->deviceid) { | |
57 // This is a slave event. We shouldn't have been expecting a master event. | |
58 CHECK(!expect_master_event); | |
Rick Byers
2011/11/25 18:17:05
This CHECK fails when using the Acer touch screen
| |
59 slave_event = *xievent; | |
60 slave_location = ui::EventLocationFromNative(xevent); | |
61 expect_master_event = true; | |
62 } else if (expect_master_event) { | |
63 CHECK_EQ(slave_location.x(), ui::EventLocationFromNative(xevent).x()); | |
64 CHECK_EQ(slave_location.y(), ui::EventLocationFromNative(xevent).y()); | |
65 | |
66 CHECK_EQ(slave_event.type, xievent->type); | |
67 CHECK_EQ(slave_event.evtype, xievent->evtype); | |
68 CHECK_EQ(slave_event.detail, xievent->detail); | |
69 CHECK_EQ(slave_event.flags, xievent->flags); | |
70 CHECK_EQ(slave_event.buttons.mask_len, xievent->buttons.mask_len); | |
71 CHECK_EQ(slave_event.valuators.mask_len, xievent->valuators.mask_len); | |
72 CHECK_EQ(slave_event.mods.base, xievent->mods.base); | |
73 CHECK_EQ(slave_event.mods.latched, xievent->mods.latched); | |
74 CHECK_EQ(slave_event.mods.locked, xievent->mods.locked); | |
75 CHECK_EQ(slave_event.mods.effective, xievent->mods.effective); | |
76 | |
77 expect_master_event = false; | |
78 } | |
79 } | |
80 | |
36 // Returns X font cursor shape from an Aura cursor. | 81 // Returns X font cursor shape from an Aura cursor. |
37 int CursorShapeFromNative(gfx::NativeCursor native_cursor) { | 82 int CursorShapeFromNative(gfx::NativeCursor native_cursor) { |
38 switch (native_cursor) { | 83 switch (native_cursor) { |
39 case aura::kCursorNull: | 84 case aura::kCursorNull: |
40 return XC_left_ptr; | 85 return XC_left_ptr; |
41 case aura::kCursorPointer: | 86 case aura::kCursorPointer: |
42 return XC_left_ptr; | 87 return XC_left_ptr; |
43 case aura::kCursorCross: | 88 case aura::kCursorCross: |
44 return XC_crosshair; | 89 return XC_crosshair; |
45 case aura::kCursorHand: | 90 case aura::kCursorHand: |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 | 179 |
135 // If we can't get the cookie, abort the check. | 180 // If we can't get the cookie, abort the check. |
136 if (!XGetEventData(next_event.xgeneric.display, &next_event.xcookie)) | 181 if (!XGetEventData(next_event.xgeneric.display, &next_event.xcookie)) |
137 return num_coalesed; | 182 return num_coalesed; |
138 | 183 |
139 // If this isn't from a valid device, throw the event away, as | 184 // If this isn't from a valid device, throw the event away, as |
140 // that's what the message pump would do. Device events come in pairs | 185 // that's what the message pump would do. Device events come in pairs |
141 // with one from the master and one from the slave so there will | 186 // with one from the master and one from the slave so there will |
142 // always be at least one pending. | 187 // always be at least one pending. |
143 if (!ui::TouchFactory::GetInstance()->ShouldProcessXI2Event(&next_event)) { | 188 if (!ui::TouchFactory::GetInstance()->ShouldProcessXI2Event(&next_event)) { |
189 CheckXEventForConsistency(&next_event); | |
144 XFreeEventData(display, &next_event.xcookie); | 190 XFreeEventData(display, &next_event.xcookie); |
145 XNextEvent(display, &next_event); | 191 XNextEvent(display, &next_event); |
146 continue; | 192 continue; |
147 } | 193 } |
148 | 194 |
149 if (next_event.type == GenericEvent && | 195 if (next_event.type == GenericEvent && |
150 next_event.xgeneric.evtype == XI_Motion) { | 196 next_event.xgeneric.evtype == XI_Motion) { |
151 XIDeviceEvent* next_xievent = | 197 XIDeviceEvent* next_xievent = |
152 static_cast<XIDeviceEvent*>(next_event.xcookie.data); | 198 static_cast<XIDeviceEvent*>(next_event.xcookie.data); |
153 // Confirm that the motion event is targeted at the same window | 199 // Confirm that the motion event is targeted at the same window |
154 // and that no buttons or modifiers have changed. | 200 // and that no buttons or modifiers have changed. |
155 if (xievent->event == next_xievent->event && | 201 if (xievent->event == next_xievent->event && |
156 xievent->child == next_xievent->child && | 202 xievent->child == next_xievent->child && |
157 xievent->buttons.mask_len == next_xievent->buttons.mask_len && | 203 xievent->buttons.mask_len == next_xievent->buttons.mask_len && |
158 (memcmp(xievent->buttons.mask, | 204 (memcmp(xievent->buttons.mask, |
159 next_xievent->buttons.mask, | 205 next_xievent->buttons.mask, |
160 xievent->buttons.mask_len) == 0) && | 206 xievent->buttons.mask_len) == 0) && |
161 xievent->mods.base == next_xievent->mods.base && | 207 xievent->mods.base == next_xievent->mods.base && |
162 xievent->mods.latched == next_xievent->mods.latched && | 208 xievent->mods.latched == next_xievent->mods.latched && |
163 xievent->mods.locked == next_xievent->mods.locked && | 209 xievent->mods.locked == next_xievent->mods.locked && |
164 xievent->mods.effective == next_xievent->mods.effective) { | 210 xievent->mods.effective == next_xievent->mods.effective) { |
165 XFreeEventData(display, &next_event.xcookie); | 211 XFreeEventData(display, &next_event.xcookie); |
166 // Free the previous cookie. | 212 // Free the previous cookie. |
167 if (num_coalesed > 0) | 213 if (num_coalesed > 0) |
168 XFreeEventData(display, &last_event->xcookie); | 214 XFreeEventData(display, &last_event->xcookie); |
169 // Get the event and its cookie data. | 215 // Get the event and its cookie data. |
170 XNextEvent(display, last_event); | 216 XNextEvent(display, last_event); |
171 XGetEventData(display, &last_event->xcookie); | 217 XGetEventData(display, &last_event->xcookie); |
218 CheckXEventForConsistency(last_event); | |
172 ++num_coalesed; | 219 ++num_coalesed; |
173 continue; | 220 continue; |
174 } else { | 221 } else { |
175 // This isn't an event we want so free its cookie data. | 222 // This isn't an event we want so free its cookie data. |
176 XFreeEventData(display, &next_event.xcookie); | 223 XFreeEventData(display, &next_event.xcookie); |
177 } | 224 } |
178 } | 225 } |
179 break; | 226 break; |
180 } | 227 } |
181 return num_coalesed; | 228 return num_coalesed; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 xwindow_(0), | 316 xwindow_(0), |
270 current_cursor_(aura::kCursorNull), | 317 current_cursor_(aura::kCursorNull), |
271 bounds_(bounds) { | 318 bounds_(bounds) { |
272 xwindow_ = XCreateSimpleWindow(xdisplay_, DefaultRootWindow(xdisplay_), | 319 xwindow_ = XCreateSimpleWindow(xdisplay_, DefaultRootWindow(xdisplay_), |
273 bounds.x(), bounds.y(), | 320 bounds.x(), bounds.y(), |
274 bounds.width(), bounds.height(), | 321 bounds.width(), bounds.height(), |
275 0, 0, 0); | 322 0, 0, 0); |
276 | 323 |
277 long event_mask = ButtonPressMask | ButtonReleaseMask | | 324 long event_mask = ButtonPressMask | ButtonReleaseMask | |
278 KeyPressMask | KeyReleaseMask | | 325 KeyPressMask | KeyReleaseMask | |
326 EnterWindowMask | LeaveWindowMask | | |
279 ExposureMask | VisibilityChangeMask | | 327 ExposureMask | VisibilityChangeMask | |
280 StructureNotifyMask | PropertyChangeMask | | 328 StructureNotifyMask | PropertyChangeMask | |
281 PointerMotionMask; | 329 PointerMotionMask; |
282 XSelectInput(xdisplay_, xwindow_, event_mask); | 330 XSelectInput(xdisplay_, xwindow_, event_mask); |
283 XFlush(xdisplay_); | 331 XFlush(xdisplay_); |
284 | 332 |
285 // TODO(sadrul): reenable once 103981 is fixed. | |
286 #if defined(TOUCH_UI) | |
287 if (base::MessagePumpForUI::HasXInput2()) | 333 if (base::MessagePumpForUI::HasXInput2()) |
288 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); | 334 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); |
289 #endif | |
290 } | 335 } |
291 | 336 |
292 DesktopHostLinux::~DesktopHostLinux() { | 337 DesktopHostLinux::~DesktopHostLinux() { |
293 XDestroyWindow(xdisplay_, xwindow_); | 338 XDestroyWindow(xdisplay_, xwindow_); |
294 | 339 |
295 // Clears XCursorCache. | 340 // Clears XCursorCache. |
296 ui::GetXCursor(ui::kCursorClearXCursorCache); | 341 ui::GetXCursor(ui::kCursorClearXCursorCache); |
297 } | 342 } |
298 | 343 |
299 base::MessagePumpDispatcher::DispatchStatus DesktopHostLinux::Dispatch( | 344 base::MessagePumpDispatcher::DispatchStatus DesktopHostLinux::Dispatch( |
300 XEvent* xev) { | 345 XEvent* xev) { |
301 bool handled = false; | 346 bool handled = false; |
347 | |
348 CheckXEventForConsistency(xev); | |
349 | |
302 switch (xev->type) { | 350 switch (xev->type) { |
303 case Expose: | 351 case Expose: |
304 desktop_->Draw(); | 352 desktop_->Draw(); |
305 handled = true; | 353 handled = true; |
306 break; | 354 break; |
307 case KeyPress: { | 355 case KeyPress: { |
308 KeyEvent keydown_event(xev, false); | 356 KeyEvent keydown_event(xev, false); |
309 handled = desktop_->DispatchKeyEvent(&keydown_event); | 357 handled = desktop_->DispatchKeyEvent(&keydown_event); |
310 if (ShouldSendCharEventForKeyboardCode(keydown_event.key_code())) { | 358 if (ShouldSendCharEventForKeyboardCode(keydown_event.key_code())) { |
311 KeyEvent char_event(xev, true); | 359 KeyEvent char_event(xev, true); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 return new DesktopHostLinux(bounds); | 582 return new DesktopHostLinux(bounds); |
535 } | 583 } |
536 | 584 |
537 // static | 585 // static |
538 gfx::Size DesktopHost::GetNativeDisplaySize() { | 586 gfx::Size DesktopHost::GetNativeDisplaySize() { |
539 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); | 587 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); |
540 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 588 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
541 } | 589 } |
542 | 590 |
543 } // namespace aura | 591 } // namespace aura |
OLD | NEW |