| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   42   msgpump->SetupXInput2ForXWindow(GDK_WINDOW_XID(window)); |   42   msgpump->SetupXInput2ForXWindow(GDK_WINDOW_XID(window)); | 
|   43  |   43  | 
|   44   return true; |   44   return true; | 
|   45 } |   45 } | 
|   46  |   46  | 
|   47 // We need to capture all the GDK windows that get created, and start |   47 // We need to capture all the GDK windows that get created, and start | 
|   48 // listening for XInput2 events. So we setup a callback to the 'realize' |   48 // listening for XInput2 events. So we setup a callback to the 'realize' | 
|   49 // signal for GTK+ widgets, so that whenever the signal triggers for any |   49 // signal for GTK+ widgets, so that whenever the signal triggers for any | 
|   50 // GtkWidget, which means the GtkWidget should now have a GdkWindow, we can |   50 // GtkWidget, which means the GtkWidget should now have a GdkWindow, we can | 
|   51 // setup XInput2 events for the GdkWindow. |   51 // setup XInput2 events for the GdkWindow. | 
 |   52 static guint realize_signal_id = 0; | 
 |   53 static guint realize_hook_id = 0; | 
 |   54  | 
|   52 void SetupGtkWidgetRealizeNotifier(base::MessagePumpGlibX* msgpump) { |   55 void SetupGtkWidgetRealizeNotifier(base::MessagePumpGlibX* msgpump) { | 
|   53   guint signal_id; |  | 
|   54   gpointer klass = g_type_class_ref(GTK_TYPE_WIDGET); |   56   gpointer klass = g_type_class_ref(GTK_TYPE_WIDGET); | 
|   55  |   57  | 
|   56   g_signal_parse_name("realize", GTK_TYPE_WIDGET, &signal_id, NULL, FALSE); |   58   g_signal_parse_name("realize", GTK_TYPE_WIDGET, | 
|   57   g_signal_add_emission_hook(signal_id, 0, GtkWidgetRealizeCallback, |   59                       &realize_signal_id, NULL, FALSE); | 
|   58       static_cast<gpointer>(msgpump), NULL); |   60   realize_hook_id = g_signal_add_emission_hook(realize_signal_id, 0, | 
 |   61       GtkWidgetRealizeCallback, static_cast<gpointer>(msgpump), NULL); | 
|   59  |   62  | 
|   60   g_type_class_unref(klass); |   63   g_type_class_unref(klass); | 
|   61 } |   64 } | 
|   62  |   65  | 
 |   66 void RemoveGtkWidgetRealizeNotifier() { | 
 |   67   if (realize_signal_id != 0) | 
 |   68     g_signal_remove_emission_hook(realize_signal_id, realize_hook_id); | 
 |   69   realize_signal_id = 0; | 
 |   70   realize_hook_id = 0; | 
 |   71 } | 
 |   72  | 
|   63 #endif  // HAVE_XINPUT2 |   73 #endif  // HAVE_XINPUT2 | 
|   64  |   74  | 
|   65 }  // namespace |   75 }  // namespace | 
|   66  |   76  | 
|   67 namespace base { |   77 namespace base { | 
|   68  |   78  | 
|   69 MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(), |   79 MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(), | 
|   70 #if defined(HAVE_XINPUT2) |   80 #if defined(HAVE_XINPUT2) | 
|   71     xiopcode_(-1), |   81     xiopcode_(-1), | 
|   72     masters_(), |   82     masters_(), | 
|   73     slaves_(), |   83     slaves_(), | 
|   74 #endif |   84 #endif | 
|   75     gdksource_(NULL), |   85     gdksource_(NULL), | 
|   76     dispatching_event_(false), |   86     dispatching_event_(false), | 
|   77     capture_x_events_(0), |   87     capture_x_events_(0), | 
|   78     capture_gdk_events_(0) { |   88     capture_gdk_events_(0) { | 
|   79   gdk_event_handler_set(&EventDispatcherX, this, NULL); |   89   gdk_event_handler_set(&EventDispatcherX, this, NULL); | 
|   80  |   90  | 
|   81 #if defined(HAVE_XINPUT2) |   91 #if defined(HAVE_XINPUT2) | 
|   82   InitializeXInput2(); |   92   InitializeXInput2(); | 
|   83 #endif |   93 #endif | 
|   84   InitializeEventsToCapture(); |   94   InitializeEventsToCapture(); | 
|   85 } |   95 } | 
|   86  |   96  | 
|   87 MessagePumpGlibX::~MessagePumpGlibX() { |   97 MessagePumpGlibX::~MessagePumpGlibX() { | 
 |   98 #if defined(HAVE_XINPUT2) | 
 |   99   RemoveGtkWidgetRealizeNotifier(); | 
 |  100 #endif | 
|   88 } |  101 } | 
|   89  |  102  | 
|   90 #if defined(HAVE_XINPUT2) |  103 #if defined(HAVE_XINPUT2) | 
|   91 void MessagePumpGlibX::SetupXInput2ForXWindow(Window xwindow) { |  104 void MessagePumpGlibX::SetupXInput2ForXWindow(Window xwindow) { | 
|   92   Display* xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); |  105   Display* xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); | 
|   93  |  106  | 
|   94   // Setup mask for mouse events. |  107   // Setup mask for mouse events. | 
|   95   unsigned char mask[(XI_LASTEVENT + 7)/8]; |  108   unsigned char mask[(XI_LASTEVENT + 7)/8]; | 
|   96   memset(mask, 0, sizeof(mask)); |  109   memset(mask, 0, sizeof(mask)); | 
|   97  |  110  | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  117   XISelectEvents(xdisplay, xwindow, evmasks, masters_.size()); |  130   XISelectEvents(xdisplay, xwindow, evmasks, masters_.size()); | 
|  118  |  131  | 
|  119   // TODO(sad): Setup masks for keyboard events. |  132   // TODO(sad): Setup masks for keyboard events. | 
|  120  |  133  | 
|  121   XFlush(xdisplay); |  134   XFlush(xdisplay); | 
|  122 } |  135 } | 
|  123 #endif  // HAVE_XINPUT2 |  136 #endif  // HAVE_XINPUT2 | 
|  124  |  137  | 
|  125 bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { |  138 bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { | 
|  126   GdkDisplay* gdisp = gdk_display_get_default(); |  139   GdkDisplay* gdisp = gdk_display_get_default(); | 
|  127   if (!gdisp) |  140   if (!gdisp || !GetDispatcher()) | 
|  128     return MessagePumpForUI::RunOnce(context, block); |  141     return MessagePumpForUI::RunOnce(context, block); | 
|  129  |  142  | 
|  130   Display* display = GDK_DISPLAY_XDISPLAY(gdisp); |  143   Display* display = GDK_DISPLAY_XDISPLAY(gdisp); | 
|  131   bool should_quit = false; |  144   bool should_quit = false; | 
|  132  |  145  | 
|  133   if (XPending(display)) { |  146   if (XPending(display)) { | 
|  134     XEvent xev; |  147     XEvent xev; | 
|  135     XPeekEvent(display, &xev); |  148     XPeekEvent(display, &xev); | 
|  136     if (capture_x_events_[xev.type] |  149     if (capture_x_events_[xev.type] | 
|  137 #if defined(HAVE_XINPUT2) |  150 #if defined(HAVE_XINPUT2) | 
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  292   XIFreeDeviceInfo(devices); |  305   XIFreeDeviceInfo(devices); | 
|  293  |  306  | 
|  294   // TODO(sad): Select on root for XI_HierarchyChanged so that slaves_ and |  307   // TODO(sad): Select on root for XI_HierarchyChanged so that slaves_ and | 
|  295   // masters_ can be kept up-to-date. This is a relatively rare event, so we can |  308   // masters_ can be kept up-to-date. This is a relatively rare event, so we can | 
|  296   // put it off for a later time. |  309   // put it off for a later time. | 
|  297   // Note: It is not necessary to listen for XI_DeviceChanged events. |  310   // Note: It is not necessary to listen for XI_DeviceChanged events. | 
|  298 } |  311 } | 
|  299 #endif  // HAVE_XINPUT2 |  312 #endif  // HAVE_XINPUT2 | 
|  300  |  313  | 
|  301 }  // namespace base |  314 }  // namespace base | 
| OLD | NEW |