Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: base/message_pump_glib_x.cc

Issue 6724025: touch: Detect touch device, and listen for events on floating devices. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/message_pump_glib_x.h ('k') | views/touchui/touch_factory.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 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 "base/message_pump_glib_x.h" 5 #include "base/message_pump_glib_x.h"
6 6
7 #include <gdk/gdkx.h> 7 #include <gdk/gdkx.h>
8 #if defined(HAVE_XINPUT2) 8 #if defined(HAVE_XINPUT2)
9 #include <X11/extensions/XInput2.h> 9 #include <X11/extensions/XInput2.h>
10 #else 10 #else
11 #include <X11/Xlib.h> 11 #include <X11/Xlib.h>
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 #endif // HAVE_XINPUT2 73 #endif // HAVE_XINPUT2
74 74
75 } // namespace 75 } // namespace
76 76
77 namespace base { 77 namespace base {
78 78
79 MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(), 79 MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(),
80 #if defined(HAVE_XINPUT2) 80 #if defined(HAVE_XINPUT2)
81 xiopcode_(-1), 81 xiopcode_(-1),
82 masters_(), 82 masters_(),
83 slaves_(), 83 floats_(),
84 #endif 84 #endif
85 gdksource_(NULL), 85 gdksource_(NULL),
86 dispatching_event_(false), 86 dispatching_event_(false),
87 capture_x_events_(0), 87 capture_x_events_(0),
88 capture_gdk_events_(0) { 88 capture_gdk_events_(0) {
89 gdk_event_handler_set(&EventDispatcherX, this, NULL); 89 gdk_event_handler_set(&EventDispatcherX, this, NULL);
90 90
91 #if defined(HAVE_XINPUT2) 91 #if defined(HAVE_XINPUT2)
92 InitializeXInput2(); 92 InitializeXInput2();
93 #endif 93 #endif
(...skipping 11 matching lines...) Expand all
105 Display* xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); 105 Display* xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
106 106
107 // Setup mask for mouse events. 107 // Setup mask for mouse events.
108 unsigned char mask[(XI_LASTEVENT + 7)/8]; 108 unsigned char mask[(XI_LASTEVENT + 7)/8];
109 memset(mask, 0, sizeof(mask)); 109 memset(mask, 0, sizeof(mask));
110 110
111 XISetMask(mask, XI_ButtonPress); 111 XISetMask(mask, XI_ButtonPress);
112 XISetMask(mask, XI_ButtonRelease); 112 XISetMask(mask, XI_ButtonRelease);
113 XISetMask(mask, XI_Motion); 113 XISetMask(mask, XI_Motion);
114 114
115 // It is necessary to select only for the master devices. XInput2 provides 115 // It is not necessary to select for slave devices. XInput2 provides enough
116 // enough information to the event callback to decide which slave device 116 // information to the event callback to decide which slave device triggered
117 // triggered the event, thus decide whether the 'pointer event' is a 'mouse 117 // the event, thus decide whether the 'pointer event' is a 'mouse event' or a
118 // event' or a 'touch event'. So it is not necessary to select for the slave 118 // 'touch event'.
119 // devices here. 119 // If the touch device has 'GrabDevice' set and 'SendCoreEvents' unset (which
120 XIEventMask evmasks[masters_.size()]; 120 // is possible), then the device is detected as a floating device, and a
121 // floating device is not connected to a master device. So it is necessary to
122 // also select on the floating devices.
123 std::set<int> devices;
124 std::set_union(masters_.begin(), masters_.end(),
125 floats_.begin(), floats_.end(),
126 std::inserter(devices, devices.begin()));
127 XIEventMask evmasks[devices.size()];
121 int count = 0; 128 int count = 0;
122 for (std::set<int>::const_iterator iter = masters_.begin(); 129 for (std::set<int>::const_iterator iter = devices.begin();
123 iter != masters_.end(); 130 iter != devices.end();
124 ++iter, ++count) { 131 ++iter, ++count) {
125 evmasks[count].deviceid = *iter; 132 evmasks[count].deviceid = *iter;
126 evmasks[count].mask_len = sizeof(mask); 133 evmasks[count].mask_len = sizeof(mask);
127 evmasks[count].mask = mask; 134 evmasks[count].mask = mask;
128 } 135 }
129 136
130 XISelectEvents(xdisplay, xwindow, evmasks, masters_.size()); 137 XISelectEvents(xdisplay, xwindow, evmasks, devices.size());
131 138
132 // TODO(sad): Setup masks for keyboard events. 139 // TODO(sad): Setup masks for keyboard events.
133 140
134 XFlush(xdisplay); 141 XFlush(xdisplay);
135 } 142 }
136 #endif // HAVE_XINPUT2 143 #endif // HAVE_XINPUT2
137 144
138 bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { 145 bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) {
139 GdkDisplay* gdisp = gdk_display_get_default(); 146 GdkDisplay* gdisp = gdk_display_get_default();
140 if (!gdisp || !GetDispatcher()) 147 if (!gdisp || !GetDispatcher())
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 } 224 }
218 225
219 return retvalue; 226 return retvalue;
220 } 227 }
221 228
222 void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) { 229 void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) {
223 MessagePumpGlibX* pump_x = reinterpret_cast<MessagePumpGlibX*>(data); 230 MessagePumpGlibX* pump_x = reinterpret_cast<MessagePumpGlibX*>(data);
224 231
225 if (!pump_x->gdksource_) { 232 if (!pump_x->gdksource_) {
226 pump_x->gdksource_ = g_main_current_source(); 233 pump_x->gdksource_ = g_main_current_source();
227 pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch; 234 if (pump_x->gdksource_)
235 pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch;
228 } else if (!pump_x->IsDispatchingEvent()) { 236 } else if (!pump_x->IsDispatchingEvent()) {
229 if (event->type != GDK_NOTHING && 237 if (event->type != GDK_NOTHING &&
230 pump_x->capture_gdk_events_[event->type]) { 238 pump_x->capture_gdk_events_[event->type]) {
231 // TODO(sad): An X event is caught by the GDK handler. Put it back in the 239 // TODO(sad): An X event is caught by the GDK handler. Put it back in the
232 // X queue so that we catch it in the next iteration. When done, the 240 // X queue so that we catch it in the next iteration. When done, the
233 // following DLOG statement will be removed. 241 // following DLOG statement will be removed.
234 DLOG(WARNING) << "GDK received an event it shouldn't have"; 242 DLOG(WARNING) << "GDK received an event it shouldn't have";
235 } 243 }
236 } 244 }
237 245
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 // setup for XInput2 events. We need a way to listen for XInput2 events for X 295 // setup for XInput2 events. We need a way to listen for XInput2 events for X
288 // windows created by other means (e.g. for context menus). 296 // windows created by other means (e.g. for context menus).
289 SetupGtkWidgetRealizeNotifier(this); 297 SetupGtkWidgetRealizeNotifier(this);
290 298
291 // Instead of asking X for the list of devices all the time, let's maintain a 299 // Instead of asking X for the list of devices all the time, let's maintain a
292 // list of slave (physical) and master (virtual) pointer devices. 300 // list of slave (physical) and master (virtual) pointer devices.
293 int count = 0; 301 int count = 0;
294 XIDeviceInfo* devices = XIQueryDevice(xdisplay, XIAllDevices, &count); 302 XIDeviceInfo* devices = XIQueryDevice(xdisplay, XIAllDevices, &count);
295 for (int i = 0; i < count; i++) { 303 for (int i = 0; i < count; i++) {
296 XIDeviceInfo* devinfo = devices + i; 304 XIDeviceInfo* devinfo = devices + i;
297 if (devinfo->use == XISlavePointer) { 305 if (devinfo->use == XIFloatingSlave) {
298 slaves_.insert(devinfo->deviceid); 306 floats_.insert(devinfo->deviceid);
299 } else if (devinfo->use == XIMasterPointer) { 307 } else if (devinfo->use == XIMasterPointer) {
300 masters_.insert(devinfo->deviceid); 308 masters_.insert(devinfo->deviceid);
301 } 309 }
302 // We do not need to care about XIFloatingSlave, because the callback for
303 // XI_HierarchyChanged event will take care of it.
304 } 310 }
305 XIFreeDeviceInfo(devices); 311 XIFreeDeviceInfo(devices);
306 312
307 // TODO(sad): Select on root for XI_HierarchyChanged so that slaves_ and 313 // TODO(sad): Select on root for XI_HierarchyChanged so that floats_ and
308 // masters_ can be kept up-to-date. This is a relatively rare event, so we can 314 // masters_ can be kept up-to-date. This is a relatively rare event, so we can
309 // put it off for a later time. 315 // put it off for a later time.
310 // Note: It is not necessary to listen for XI_DeviceChanged events. 316 // Note: It is not necessary to listen for XI_DeviceChanged events.
311 } 317 }
312 #endif // HAVE_XINPUT2 318 #endif // HAVE_XINPUT2
313 319
314 } // namespace base 320 } // namespace base
OLDNEW
« no previous file with comments | « base/message_pump_glib_x.h ('k') | views/touchui/touch_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698