OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 | 75 |
76 #if defined(HAVE_XINPUT2) | 76 #if defined(HAVE_XINPUT2) |
77 InitializeXInput2(); | 77 InitializeXInput2(); |
78 #endif | 78 #endif |
79 InitializeEventsToCapture(); | 79 InitializeEventsToCapture(); |
80 } | 80 } |
81 | 81 |
82 MessagePumpGlibX::~MessagePumpGlibX() { | 82 MessagePumpGlibX::~MessagePumpGlibX() { |
83 } | 83 } |
84 | 84 |
| 85 #if defined(HAVE_XINPUT2) |
| 86 void MessagePumpGlibX::SetupXInput2ForXWindow(Window xwindow) { |
| 87 Display* xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); |
| 88 |
| 89 // Setup mask for mouse events. |
| 90 unsigned char mask[(XI_LASTEVENT + 7)/8]; |
| 91 memset(mask, 0, sizeof(mask)); |
| 92 |
| 93 XISetMask(mask, XI_ButtonPress); |
| 94 XISetMask(mask, XI_ButtonRelease); |
| 95 XISetMask(mask, XI_Motion); |
| 96 |
| 97 // It is necessary to select only for the master devices. XInput2 provides |
| 98 // enough information to the event callback to decide which slave device |
| 99 // triggered the event, thus decide whether the 'pointer event' is a 'mouse |
| 100 // event' or a 'touch event'. So it is not necessary to select for the slave |
| 101 // devices here. |
| 102 XIEventMask evmasks[masters_.size()]; |
| 103 int count = 0; |
| 104 for (std::set<int>::const_iterator iter = masters_.begin(); |
| 105 iter != masters_.end(); |
| 106 ++iter, ++count) { |
| 107 evmasks[count].deviceid = *iter; |
| 108 evmasks[count].mask_len = sizeof(mask); |
| 109 evmasks[count].mask = mask; |
| 110 } |
| 111 |
| 112 XISelectEvents(xdisplay, xwindow, evmasks, masters_.size()); |
| 113 |
| 114 // TODO(sad): Setup masks for keyboard events. |
| 115 |
| 116 XFlush(xdisplay); |
| 117 } |
| 118 #endif // HAVE_XINPUT2 |
| 119 |
85 bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { | 120 bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { |
86 GdkDisplay* gdisp = gdk_display_get_default(); | 121 GdkDisplay* gdisp = gdk_display_get_default(); |
87 if (!gdisp) | 122 if (!gdisp) |
88 return MessagePumpForUI::RunOnce(context, block); | 123 return MessagePumpForUI::RunOnce(context, block); |
89 | 124 |
90 Display* display = GDK_DISPLAY_XDISPLAY(gdisp); | 125 Display* display = GDK_DISPLAY_XDISPLAY(gdisp); |
91 bool should_quit = false; | 126 bool should_quit = false; |
92 | 127 |
93 if (XPending(display)) { | 128 if (XPending(display)) { |
94 XEvent xev; | 129 XEvent xev; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 dispatching_event_ = false; | 194 dispatching_event_ = false; |
160 | 195 |
161 gdksource_->source_funcs->dispatch = cb; | 196 gdksource_->source_funcs->dispatch = cb; |
162 } else { | 197 } else { |
163 retvalue = g_main_context_iteration(context, block); | 198 retvalue = g_main_context_iteration(context, block); |
164 } | 199 } |
165 | 200 |
166 return retvalue; | 201 return retvalue; |
167 } | 202 } |
168 | 203 |
| 204 void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) { |
| 205 MessagePumpGlibX* pump_x = reinterpret_cast<MessagePumpGlibX*>(data); |
| 206 |
| 207 if (!pump_x->gdksource_) { |
| 208 pump_x->gdksource_ = g_main_current_source(); |
| 209 pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch; |
| 210 } else if (!pump_x->IsDispatchingEvent()) { |
| 211 if (event->type != GDK_NOTHING && |
| 212 pump_x->capture_gdk_events_[event->type]) { |
| 213 // TODO(sad): An X event is caught by the GDK handler. Put it back in the |
| 214 // X queue so that we catch it in the next iteration. When done, the |
| 215 // following DLOG statement will be removed. |
| 216 DLOG(WARNING) << "GDK received an event it shouldn't have"; |
| 217 } |
| 218 } |
| 219 |
| 220 pump_x->DispatchEvents(event); |
| 221 } |
| 222 |
169 void MessagePumpGlibX::InitializeEventsToCapture(void) { | 223 void MessagePumpGlibX::InitializeEventsToCapture(void) { |
170 // TODO(sad): Decide which events we want to capture and update the tables | 224 // TODO(sad): Decide which events we want to capture and update the tables |
171 // accordingly. | 225 // accordingly. |
172 capture_x_events_[KeyPress] = true; | 226 capture_x_events_[KeyPress] = true; |
173 capture_gdk_events_[GDK_KEY_PRESS] = true; | 227 capture_gdk_events_[GDK_KEY_PRESS] = true; |
174 | 228 |
175 capture_x_events_[KeyRelease] = true; | 229 capture_x_events_[KeyRelease] = true; |
176 capture_gdk_events_[GDK_KEY_RELEASE] = true; | 230 capture_gdk_events_[GDK_KEY_RELEASE] = true; |
177 | 231 |
178 capture_x_events_[ButtonPress] = true; | 232 capture_x_events_[ButtonPress] = true; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 // We do not need to care about XIFloatingSlave, because the callback for | 284 // We do not need to care about XIFloatingSlave, because the callback for |
231 // XI_HierarchyChanged event will take care of it. | 285 // XI_HierarchyChanged event will take care of it. |
232 } | 286 } |
233 XIFreeDeviceInfo(devices); | 287 XIFreeDeviceInfo(devices); |
234 | 288 |
235 // TODO(sad): Select on root for XI_HierarchyChanged so that slaves_ and | 289 // TODO(sad): Select on root for XI_HierarchyChanged so that slaves_ and |
236 // masters_ can be kept up-to-date. This is a relatively rare event, so we can | 290 // masters_ can be kept up-to-date. This is a relatively rare event, so we can |
237 // put it off for a later time. | 291 // put it off for a later time. |
238 // Note: It is not necessary to listen for XI_DeviceChanged events. | 292 // Note: It is not necessary to listen for XI_DeviceChanged events. |
239 } | 293 } |
240 | |
241 void MessagePumpGlibX::SetupXInput2ForXWindow(Window xwindow) { | |
242 Display* xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); | |
243 | |
244 // Setup mask for mouse events. | |
245 unsigned char mask[(XI_LASTEVENT + 7)/8]; | |
246 memset(mask, 0, sizeof(mask)); | |
247 | |
248 XISetMask(mask, XI_ButtonPress); | |
249 XISetMask(mask, XI_ButtonRelease); | |
250 XISetMask(mask, XI_Motion); | |
251 | |
252 // It is necessary to select only for the master devices. XInput2 provides | |
253 // enough information to the event callback to decide which slave device | |
254 // triggered the event, thus decide whether the 'pointer event' is a 'mouse | |
255 // event' or a 'touch event'. So it is not necessary to select for the slave | |
256 // devices here. | |
257 XIEventMask evmasks[masters_.size()]; | |
258 int count = 0; | |
259 for (std::set<int>::const_iterator iter = masters_.begin(); | |
260 iter != masters_.end(); | |
261 ++iter, ++count) { | |
262 evmasks[count].deviceid = *iter; | |
263 evmasks[count].mask_len = sizeof(mask); | |
264 evmasks[count].mask = mask; | |
265 } | |
266 | |
267 XISelectEvents(xdisplay, xwindow, evmasks, masters_.size()); | |
268 | |
269 // TODO(sad): Setup masks for keyboard events. | |
270 | |
271 XFlush(xdisplay); | |
272 } | |
273 | |
274 #endif // HAVE_XINPUT2 | 294 #endif // HAVE_XINPUT2 |
275 | 295 |
276 void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) { | |
277 MessagePumpGlibX* pump_x = reinterpret_cast<MessagePumpGlibX*>(data); | |
278 | |
279 if (!pump_x->gdksource_) { | |
280 pump_x->gdksource_ = g_main_current_source(); | |
281 pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch; | |
282 } else if (!pump_x->IsDispatchingEvent()) { | |
283 if (event->type != GDK_NOTHING && | |
284 pump_x->capture_gdk_events_[event->type]) { | |
285 // TODO(sad): An X event is caught by the GDK handler. Put it back in the | |
286 // X queue so that we catch it in the next iteration. When done, the | |
287 // following DLOG statement will be removed. | |
288 DLOG(WARNING) << "GDK received an event it shouldn't have"; | |
289 } | |
290 } | |
291 | |
292 pump_x->DispatchEvents(event); | |
293 } | |
294 | |
295 } // namespace base | 296 } // namespace base |
OLD | NEW |