Chromium Code Reviews| 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 "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 15 matching lines...) Expand all Loading... | |
| 26 namespace base { | 26 namespace base { |
| 27 | 27 |
| 28 MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(), | 28 MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(), |
| 29 #if defined(HAVE_XINPUT2) | 29 #if defined(HAVE_XINPUT2) |
| 30 xiopcode_(-1), | 30 xiopcode_(-1), |
| 31 #endif | 31 #endif |
| 32 gdksource_(NULL), | 32 gdksource_(NULL), |
| 33 dispatching_event_(false), | 33 dispatching_event_(false), |
| 34 capture_x_events_(0), | 34 capture_x_events_(0), |
| 35 capture_gdk_events_(0) { | 35 capture_gdk_events_(0) { |
| 36 gdk_window_add_filter(NULL, GdkEventFilter, this); | |
|
sadrul
2011/05/24 15:34:18
To keep with the existing code, '&GdkEventFilter'
Yufeng Shen (Slow to review)
2011/05/24 18:30:50
Done.
| |
| 36 gdk_event_handler_set(&EventDispatcherX, this, NULL); | 37 gdk_event_handler_set(&EventDispatcherX, this, NULL); |
| 37 | 38 |
| 38 #if defined(HAVE_XINPUT2) | 39 #if defined(HAVE_XINPUT2) |
| 39 InitializeXInput2(); | 40 InitializeXInput2(); |
| 40 #endif | 41 #endif |
| 41 InitializeEventsToCapture(); | 42 InitializeEventsToCapture(); |
| 42 } | 43 } |
| 43 | 44 |
| 44 MessagePumpGlibX::~MessagePumpGlibX() { | 45 MessagePumpGlibX::~MessagePumpGlibX() { |
| 45 } | 46 } |
| 46 | 47 |
| 48 bool MessagePumpGlibX::ShouldCaptureXEvent(XEvent* xev) { | |
| 49 return capture_x_events_[xev->type] | |
| 50 #if defined(HAVE_XINPUT2) | |
| 51 && (xev->type != GenericEvent || xev->xcookie.extension == xiopcode_) | |
| 52 #endif | |
| 53 ; | |
| 54 } | |
| 55 | |
| 56 | |
| 57 bool MessagePumpGlibX::ProcessXEvent(XEvent* xev) { | |
| 58 bool should_quit = false; | |
| 59 | |
| 60 #if defined(HAVE_XINPUT2) | |
| 61 bool have_cookie = false; | |
| 62 if (xev->type == GenericEvent && | |
| 63 XGetEventData(xev->xgeneric.display, &xev->xcookie)) { | |
| 64 have_cookie = true; | |
| 65 } | |
| 66 #endif | |
| 67 | |
| 68 if (!WillProcessXEvent(xev)) { | |
| 69 MessagePumpGlibXDispatcher::DispatchStatus status = | |
| 70 static_cast<MessagePumpGlibXDispatcher*> | |
| 71 (GetDispatcher())->DispatchX(xev); | |
| 72 | |
| 73 if (status == MessagePumpGlibXDispatcher::EVENT_QUIT) { | |
| 74 should_quit = true; | |
| 75 Quit(); | |
| 76 } else if (status == MessagePumpGlibXDispatcher::EVENT_IGNORED) { | |
| 77 DLOG(WARNING) << "Event (" << xev->type << ") not handled."; | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 #if defined(HAVE_XINPUT2) | |
| 82 if (have_cookie) { | |
| 83 XFreeEventData(xev->xgeneric.display, &xev->xcookie); | |
| 84 } | |
| 85 #endif | |
| 86 | |
| 87 return should_quit; | |
| 88 } | |
| 89 | |
| 47 bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { | 90 bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { |
| 48 GdkDisplay* gdisp = gdk_display_get_default(); | 91 GdkDisplay* gdisp = gdk_display_get_default(); |
| 49 if (!gdisp || !GetDispatcher()) | 92 if (!gdisp || !GetDispatcher()) |
| 50 return MessagePumpForUI::RunOnce(context, block); | 93 return MessagePumpForUI::RunOnce(context, block); |
| 51 | 94 |
| 52 Display* display = GDK_DISPLAY_XDISPLAY(gdisp); | 95 Display* display = GDK_DISPLAY_XDISPLAY(gdisp); |
| 53 bool should_quit = false; | 96 bool should_quit = false; |
| 54 | 97 |
| 55 if (XPending(display)) { | 98 if (XPending(display)) { |
| 56 XEvent xev; | 99 XEvent xev; |
| 57 XPeekEvent(display, &xev); | 100 XPeekEvent(display, &xev); |
| 58 if (capture_x_events_[xev.type] | 101 |
| 59 #if defined(HAVE_XINPUT2) | 102 if (ShouldCaptureXEvent(&xev)) { |
| 60 && (xev.type != GenericEvent || xev.xcookie.extension == xiopcode_) | |
| 61 #endif | |
| 62 ) { | |
| 63 XNextEvent(display, &xev); | 103 XNextEvent(display, &xev); |
| 64 | 104 should_quit = ProcessXEvent(&xev); |
|
sadrul
2011/05/24 15:34:18
Using should_quit isn't necessary anymore:
if (
Yufeng Shen (Slow to review)
2011/05/24 18:30:50
Done.
| |
| 65 #if defined(HAVE_XINPUT2) | |
| 66 bool have_cookie = false; | |
| 67 if (xev.type == GenericEvent && | |
| 68 XGetEventData(xev.xgeneric.display, &xev.xcookie)) { | |
| 69 have_cookie = true; | |
| 70 } | |
| 71 #endif | |
| 72 | |
| 73 if (!WillProcessXEvent(&xev)) { | |
| 74 MessagePumpGlibXDispatcher::DispatchStatus status = | |
| 75 static_cast<MessagePumpGlibXDispatcher*> | |
| 76 (GetDispatcher())->DispatchX(&xev); | |
| 77 | |
| 78 if (status == MessagePumpGlibXDispatcher::EVENT_QUIT) { | |
| 79 should_quit = true; | |
| 80 Quit(); | |
| 81 } else if (status == MessagePumpGlibXDispatcher::EVENT_IGNORED) { | |
| 82 DLOG(WARNING) << "Event (" << xev.type << ") not handled."; | |
| 83 } | |
| 84 } | |
| 85 | |
| 86 #if defined(HAVE_XINPUT2) | |
| 87 if (have_cookie) { | |
| 88 XFreeEventData(xev.xgeneric.display, &xev.xcookie); | |
| 89 } | |
| 90 #endif | |
| 91 } else { | 105 } else { |
| 92 // TODO(sad): A couple of extra events can still sneak in during this. | 106 // TODO(sad): A couple of extra events can still sneak in during this. |
| 93 // Those should be sent back to the X queue from the dispatcher | 107 // Those should be sent back to the X queue from the dispatcher |
| 94 // EventDispatcherX. | 108 // EventDispatcherX. |
| 95 if (gdksource_) | 109 if (gdksource_) |
| 96 gdksource_->source_funcs->dispatch = gdkdispatcher_; | 110 gdksource_->source_funcs->dispatch = gdkdispatcher_; |
| 97 g_main_context_iteration(context, FALSE); | 111 g_main_context_iteration(context, FALSE); |
| 98 } | 112 } |
| 99 } | 113 } |
| 100 | 114 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 114 dispatching_event_ = false; | 128 dispatching_event_ = false; |
| 115 | 129 |
| 116 gdksource_->source_funcs->dispatch = cb; | 130 gdksource_->source_funcs->dispatch = cb; |
| 117 } else { | 131 } else { |
| 118 retvalue = g_main_context_iteration(context, block); | 132 retvalue = g_main_context_iteration(context, block); |
| 119 } | 133 } |
| 120 | 134 |
| 121 return retvalue; | 135 return retvalue; |
| 122 } | 136 } |
| 123 | 137 |
| 138 GdkFilterReturn MessagePumpGlibX::GdkEventFilter(GdkXEvent* gxevent, | |
| 139 GdkEvent* gevent, | |
| 140 gpointer data) { | |
| 141 MessagePumpGlibX* pump = static_cast<MessagePumpGlibX*>(data); | |
| 142 XEvent* xev = static_cast<XEvent*>(gxevent); | |
| 143 | |
| 144 if (pump->ShouldCaptureXEvent(xev) && pump->GetDispatcher()) { | |
| 145 pump->ProcessXEvent(xev); | |
|
sadrul
2011/05/24 15:34:18
This looks good as is. But should this do anything
Yufeng Shen (Slow to review)
2011/05/24 18:30:50
Since it is in the GDK's message processing loop,
| |
| 146 return GDK_FILTER_REMOVE; | |
| 147 } | |
| 148 | |
| 149 return GDK_FILTER_CONTINUE; | |
| 150 } | |
| 151 | |
| 152 | |
|
sadrul
2011/05/24 15:34:18
Too many new lines!
Yufeng Shen (Slow to review)
2011/05/24 18:30:50
Done.
| |
| 153 | |
| 124 bool MessagePumpGlibX::WillProcessXEvent(XEvent* xevent) { | 154 bool MessagePumpGlibX::WillProcessXEvent(XEvent* xevent) { |
| 125 ObserverListBase<Observer>::Iterator it(observers()); | 155 ObserverListBase<Observer>::Iterator it(observers()); |
| 126 Observer* obs; | 156 Observer* obs; |
| 127 while ((obs = it.GetNext()) != NULL) { | 157 while ((obs = it.GetNext()) != NULL) { |
| 128 MessagePumpXObserver* xobs = | 158 MessagePumpXObserver* xobs = |
| 129 static_cast<MessagePumpXObserver*>(obs); | 159 static_cast<MessagePumpXObserver*>(obs); |
| 130 if (xobs->WillProcessXEvent(xevent)) | 160 if (xobs->WillProcessXEvent(xevent)) |
| 131 return true; | 161 return true; |
| 132 } | 162 } |
| 133 return false; | 163 return false; |
| 134 } | 164 } |
| 135 | 165 |
| 136 void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) { | 166 void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) { |
| 137 MessagePumpGlibX* pump_x = reinterpret_cast<MessagePumpGlibX*>(data); | 167 MessagePumpGlibX* pump_x = reinterpret_cast<MessagePumpGlibX*>(data); |
| 138 | 168 |
| 139 if (!pump_x->gdksource_) { | 169 if (!pump_x->gdksource_) { |
| 140 pump_x->gdksource_ = g_main_current_source(); | 170 pump_x->gdksource_ = g_main_current_source(); |
| 141 if (pump_x->gdksource_) | 171 if (pump_x->gdksource_) |
| 142 pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch; | 172 pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch; |
| 143 } else if (!pump_x->IsDispatchingEvent()) { | 173 } else if (!pump_x->IsDispatchingEvent()) { |
| 144 if (event->type != GDK_NOTHING && | 174 if (event->type != GDK_NOTHING && |
| 145 pump_x->capture_gdk_events_[event->type]) { | 175 pump_x->capture_gdk_events_[event->type]) { |
| 146 // TODO(sad): An X event is caught by the GDK handler. Put it back in the | 176 // TODO(sad): An X event is caught by the GDK handler. Put it back in the |
| 147 // X queue so that we catch it in the next iteration. When done, the | 177 // X queue so that we catch it in the next iteration. When done, the |
| 148 // following DLOG statement will be removed. | 178 // following DLOG statement will be removed. |
| 149 DLOG(WARNING) << "GDK received an event it shouldn't have"; | 179 DLOG(WARNING) << "GDK received an event it shouldn't have"; |
|
sadrul
2011/05/24 15:34:18
Can you please replace the DLOG with a NOTREACHED
Yufeng Shen (Slow to review)
2011/05/24 18:30:50
Done.
| |
| 150 } | 180 } |
| 151 } | 181 } |
| 152 | 182 |
| 153 pump_x->DispatchEvents(event); | 183 pump_x->DispatchEvents(event); |
| 154 } | 184 } |
| 155 | 185 |
| 156 void MessagePumpGlibX::InitializeEventsToCapture(void) { | 186 void MessagePumpGlibX::InitializeEventsToCapture(void) { |
| 157 // TODO(sad): Decide which events we want to capture and update the tables | 187 // TODO(sad): Decide which events we want to capture and update the tables |
| 158 // accordingly. | 188 // accordingly. |
| 159 capture_x_events_[KeyPress] = true; | 189 capture_x_events_[KeyPress] = true; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 return; | 228 return; |
| 199 } | 229 } |
| 200 } | 230 } |
| 201 #endif // HAVE_XINPUT2 | 231 #endif // HAVE_XINPUT2 |
| 202 | 232 |
| 203 bool MessagePumpXObserver::WillProcessXEvent(XEvent* xev) { | 233 bool MessagePumpXObserver::WillProcessXEvent(XEvent* xev) { |
| 204 return false; | 234 return false; |
| 205 } | 235 } |
| 206 | 236 |
| 207 } // namespace base | 237 } // namespace base |
| OLD | NEW |