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

Side by Side Diff: base/message_pump_x.cc

Issue 7983022: Reland 102005 and 102009: aura: Explicitly disable GTK. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 3 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_x.h ('k') | build/build_config.h » ('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) 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_x.h" 5 #include "base/message_pump_x.h"
6 6
7 #include <gdk/gdkx.h>
8 #include <X11/extensions/XInput2.h> 7 #include <X11/extensions/XInput2.h>
9 8
10 #include "base/basictypes.h" 9 #include "base/basictypes.h"
11 #include "base/message_loop.h" 10 #include "base/message_loop.h"
12 11
12 #if defined(TOOLKIT_USES_GTK)
13 #include <gdk/gdkx.h>
14 #endif
15
13 namespace { 16 namespace {
14 17
15 gboolean XSourcePrepare(GSource* source, gint* timeout_ms) { 18 gboolean XSourcePrepare(GSource* source, gint* timeout_ms) {
16 if (XPending(base::MessagePumpX::GetDefaultXDisplay())) 19 if (XPending(base::MessagePumpX::GetDefaultXDisplay()))
17 *timeout_ms = 0; 20 *timeout_ms = 0;
18 else 21 else
19 *timeout_ms = -1; 22 *timeout_ms = -1;
20 return FALSE; 23 return FALSE;
21 } 24 }
22 25
(...skipping 10 matching lines...) Expand all
33 return TRUE; 36 return TRUE;
34 } 37 }
35 38
36 GSourceFuncs XSourceFuncs = { 39 GSourceFuncs XSourceFuncs = {
37 XSourcePrepare, 40 XSourcePrepare,
38 XSourceCheck, 41 XSourceCheck,
39 XSourceDispatch, 42 XSourceDispatch,
40 NULL 43 NULL
41 }; 44 };
42 45
43 // A flag to disable GTK's message pump. This is intermediate step
44 // to remove gtk and will be removed once migration is complete.
45 bool use_gtk_message_pump = true;
46
47 // The opcode used for checking events. 46 // The opcode used for checking events.
48 int xiopcode = -1; 47 int xiopcode = -1;
49 48
50 // When the GTK/GDK event processing is disabled, the message-pump opens a 49 // When the GTK/GDK event processing is disabled, the message-pump opens a
51 // connection to the display and owns it. 50 // connection to the display and owns it.
52 Display* g_xdisplay = NULL; 51 Display* g_xdisplay = NULL;
53 52
53 #if defined(TOOLKIT_USES_GTK)
54 // A flag to disable GTK's message pump. This is intermediate step
55 // to remove gtk and will be removed once migration is complete.
56 bool use_gtk_message_pump = true;
57
54 gboolean PlaceholderDispatch(GSource* source, 58 gboolean PlaceholderDispatch(GSource* source,
55 GSourceFunc cb, 59 GSourceFunc cb,
56 gpointer data) { 60 gpointer data) {
57 return TRUE; 61 return TRUE;
58 } 62 }
63 #endif // defined(TOOLKIT_USES_GTK)
59 64
60 void InitializeXInput2(void) { 65 void InitializeXInput2(void) {
61 Display* display = base::MessagePumpX::GetDefaultXDisplay(); 66 Display* display = base::MessagePumpX::GetDefaultXDisplay();
62 if (!display) 67 if (!display)
63 return; 68 return;
64 69
65 int event, err; 70 int event, err;
66 71
67 if (!XQueryExtension(display, "XInputExtension", &xiopcode, &event, &err)) { 72 if (!XQueryExtension(display, "XInputExtension", &xiopcode, &event, &err)) {
68 VLOG(1) << "X Input extension not available."; 73 VLOG(1) << "X Input extension not available.";
69 xiopcode = -1; 74 xiopcode = -1;
70 return; 75 return;
71 } 76 }
72 77
73 int major = 2, minor = 0; 78 int major = 2, minor = 0;
74 if (XIQueryVersion(display, &major, &minor) == BadRequest) { 79 if (XIQueryVersion(display, &major, &minor) == BadRequest) {
75 VLOG(1) << "XInput2 not supported in the server."; 80 VLOG(1) << "XInput2 not supported in the server.";
76 xiopcode = -1; 81 xiopcode = -1;
77 return; 82 return;
78 } 83 }
79 } 84 }
80 85
81 } // namespace 86 } // namespace
82 87
83 namespace base { 88 namespace base {
84 89
85 MessagePumpX::MessagePumpX() : MessagePumpGlib(), 90 MessagePumpX::MessagePumpX() : MessagePumpGlib(),
86 x_source_(NULL), 91 #if defined(TOOLKIT_USES_GTK)
87 gdksource_(NULL), 92 gdksource_(NULL),
88 dispatching_event_(false), 93 dispatching_event_(false),
89 capture_x_events_(0), 94 capture_x_events_(0),
90 capture_gdk_events_(0) { 95 capture_gdk_events_(0),
96 #endif
97 x_source_(NULL) {
98 InitializeXInput2();
99 #if defined(TOOLKIT_USES_GTK)
91 if (use_gtk_message_pump) { 100 if (use_gtk_message_pump) {
92 gdk_window_add_filter(NULL, &GdkEventFilter, this); 101 gdk_window_add_filter(NULL, &GdkEventFilter, this);
93 gdk_event_handler_set(&EventDispatcherX, this, NULL); 102 gdk_event_handler_set(&EventDispatcherX, this, NULL);
94 } else { 103 } else {
95 GPollFD* x_poll = new GPollFD(); 104 InitXSource();
96 x_poll->fd = ConnectionNumber(g_xdisplay);
97 x_poll->events = G_IO_IN;
98
99 x_source_ = g_source_new(&XSourceFuncs, sizeof(GSource));
100 g_source_add_poll(x_source_, x_poll);
101 g_source_set_can_recurse(x_source_, FALSE);
102 g_source_attach(x_source_, g_main_context_default());
103 } 105 }
104
105 InitializeXInput2();
106 if (use_gtk_message_pump) 106 if (use_gtk_message_pump)
107 InitializeEventsToCapture(); 107 InitializeEventsToCapture();
108 #else
109 InitXSource();
110 #endif
108 } 111 }
109 112
110 MessagePumpX::~MessagePumpX() { 113 MessagePumpX::~MessagePumpX() {
114 #if defined(TOOLKIT_USES_GTK)
111 if (use_gtk_message_pump) { 115 if (use_gtk_message_pump) {
112 gdk_window_remove_filter(NULL, &GdkEventFilter, this); 116 gdk_window_remove_filter(NULL, &GdkEventFilter, this);
113 gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event), 117 gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event),
114 this, NULL); 118 this, NULL);
115 } else { 119 return;
116 g_source_destroy(x_source_);
117 g_source_unref(x_source_);
118 XCloseDisplay(g_xdisplay);
119 g_xdisplay = NULL;
120 } 120 }
121 #endif
122
123 g_source_destroy(x_source_);
124 g_source_unref(x_source_);
125 XCloseDisplay(g_xdisplay);
126 g_xdisplay = NULL;
127 }
128
129 #if defined(TOOLKIT_USES_GTK)
130 // static
131 void MessagePumpX::DisableGtkMessagePump() {
132 use_gtk_message_pump = false;
133 }
134 #endif
135
136 // static
137 Display* MessagePumpX::GetDefaultXDisplay() {
138 #if defined(TOOLKIT_USES_GTK)
139 if (use_gtk_message_pump) {
140 static GdkDisplay* display = gdk_display_get_default();
141 return display ? GDK_DISPLAY_XDISPLAY(display) : NULL;
142 }
143 #endif
144 if (!g_xdisplay)
145 g_xdisplay = XOpenDisplay(NULL);
146 return g_xdisplay;
121 } 147 }
122 148
123 // static 149 // static
124 void MessagePumpX::DisableGtkMessagePump() {
125 use_gtk_message_pump = false;
126 g_xdisplay = XOpenDisplay(NULL);
127 }
128
129 // static
130 Display* MessagePumpX::GetDefaultXDisplay() {
131 if (use_gtk_message_pump) {
132 static GdkDisplay* display = gdk_display_get_default();
133 return display ? GDK_DISPLAY_XDISPLAY(display) : NULL;
134 } else {
135 return g_xdisplay;
136 }
137 }
138
139 // static
140 bool MessagePumpX::HasXInput2() { 150 bool MessagePumpX::HasXInput2() {
141 return xiopcode != -1; 151 return xiopcode != -1;
142 } 152 }
143 153
154 void MessagePumpX::InitXSource() {
155 DCHECK(!x_source_);
156 GPollFD* x_poll = new GPollFD();
157 x_poll->fd = ConnectionNumber(g_xdisplay);
158 x_poll->events = G_IO_IN;
159
160 x_source_ = g_source_new(&XSourceFuncs, sizeof(GSource));
161 g_source_add_poll(x_source_, x_poll);
162 g_source_set_can_recurse(x_source_, FALSE);
163 g_source_attach(x_source_, g_main_context_default());
164 }
165
144 bool MessagePumpX::ShouldCaptureXEvent(XEvent* xev) { 166 bool MessagePumpX::ShouldCaptureXEvent(XEvent* xev) {
145 return (!use_gtk_message_pump || capture_x_events_[xev->type]) 167 return
146 && (xev->type != GenericEvent || xev->xcookie.extension == xiopcode); 168 #if defined(TOOLKIT_USES_GTK)
169 (!use_gtk_message_pump || capture_x_events_[xev->type]) &&
170 #endif
171 (xev->type != GenericEvent || xev->xcookie.extension == xiopcode);
147 } 172 }
148 173
149 bool MessagePumpX::ProcessXEvent(XEvent* xev) { 174 bool MessagePumpX::ProcessXEvent(XEvent* xev) {
150 bool should_quit = false; 175 bool should_quit = false;
151 176
152 bool have_cookie = false; 177 bool have_cookie = false;
153 if (xev->type == GenericEvent && 178 if (xev->type == GenericEvent &&
154 XGetEventData(xev->xgeneric.display, &xev->xcookie)) { 179 XGetEventData(xev->xgeneric.display, &xev->xcookie)) {
155 have_cookie = true; 180 have_cookie = true;
156 } 181 }
(...skipping 23 matching lines...) Expand all
180 return g_main_context_iteration(context, block); 205 return g_main_context_iteration(context, block);
181 206
182 if (XPending(display)) { 207 if (XPending(display)) {
183 XEvent xev; 208 XEvent xev;
184 XPeekEvent(display, &xev); 209 XPeekEvent(display, &xev);
185 210
186 if (ShouldCaptureXEvent(&xev)) { 211 if (ShouldCaptureXEvent(&xev)) {
187 XNextEvent(display, &xev); 212 XNextEvent(display, &xev);
188 if (ProcessXEvent(&xev)) 213 if (ProcessXEvent(&xev))
189 return true; 214 return true;
215 #if defined(TOOLKIT_USES_GTK)
190 } else if (use_gtk_message_pump && gdksource_) { 216 } else if (use_gtk_message_pump && gdksource_) {
191 // TODO(sad): A couple of extra events can still sneak in during this. 217 // TODO(sad): A couple of extra events can still sneak in during this.
192 // Those should be sent back to the X queue from the dispatcher 218 // Those should be sent back to the X queue from the dispatcher
193 // EventDispatcherX. 219 // EventDispatcherX.
194 gdksource_->source_funcs->dispatch = gdkdispatcher_; 220 gdksource_->source_funcs->dispatch = gdkdispatcher_;
195 g_main_context_iteration(context, FALSE); 221 g_main_context_iteration(context, FALSE);
222 #endif
196 } 223 }
197 } 224 }
198 225
199 bool retvalue; 226 bool retvalue;
227 #if defined(TOOLKIT_USES_GTK)
200 if (gdksource_ && use_gtk_message_pump) { 228 if (gdksource_ && use_gtk_message_pump) {
201 // Replace the dispatch callback of the GDK event source temporarily so that 229 // Replace the dispatch callback of the GDK event source temporarily so that
202 // it doesn't read events from X. 230 // it doesn't read events from X.
203 gboolean (*cb)(GSource*, GSourceFunc, void*) = 231 gboolean (*cb)(GSource*, GSourceFunc, void*) =
204 gdksource_->source_funcs->dispatch; 232 gdksource_->source_funcs->dispatch;
205 gdksource_->source_funcs->dispatch = PlaceholderDispatch; 233 gdksource_->source_funcs->dispatch = PlaceholderDispatch;
206 234
207 dispatching_event_ = true; 235 dispatching_event_ = true;
208 retvalue = g_main_context_iteration(context, block); 236 retvalue = g_main_context_iteration(context, block);
209 dispatching_event_ = false; 237 dispatching_event_ = false;
210 238
211 gdksource_->source_funcs->dispatch = cb; 239 gdksource_->source_funcs->dispatch = cb;
212 } else { 240 } else {
213 retvalue = g_main_context_iteration(context, block); 241 retvalue = g_main_context_iteration(context, block);
214 } 242 }
243 #else
244 retvalue = g_main_context_iteration(context, block);
245 #endif
215 246
216 return retvalue; 247 return retvalue;
217 } 248 }
218 249
250 bool MessagePumpX::WillProcessXEvent(XEvent* xevent) {
251 ObserverListBase<MessagePumpObserver>::Iterator it(observers());
252 MessagePumpObserver* obs;
253 while ((obs = it.GetNext()) != NULL) {
254 if (obs->WillProcessXEvent(xevent))
255 return true;
256 }
257 return false;
258 }
259
260 #if defined(TOOLKIT_USES_GTK)
219 GdkFilterReturn MessagePumpX::GdkEventFilter(GdkXEvent* gxevent, 261 GdkFilterReturn MessagePumpX::GdkEventFilter(GdkXEvent* gxevent,
220 GdkEvent* gevent, 262 GdkEvent* gevent,
221 gpointer data) { 263 gpointer data) {
222 MessagePumpX* pump = static_cast<MessagePumpX*>(data); 264 MessagePumpX* pump = static_cast<MessagePumpX*>(data);
223 XEvent* xev = static_cast<XEvent*>(gxevent); 265 XEvent* xev = static_cast<XEvent*>(gxevent);
224 266
225 if (pump->ShouldCaptureXEvent(xev) && pump->GetDispatcher()) { 267 if (pump->ShouldCaptureXEvent(xev) && pump->GetDispatcher()) {
226 pump->ProcessXEvent(xev); 268 pump->ProcessXEvent(xev);
227 return GDK_FILTER_REMOVE; 269 return GDK_FILTER_REMOVE;
228 } 270 }
229 CHECK(use_gtk_message_pump) << "GdkEvent:" << gevent->type; 271 CHECK(use_gtk_message_pump) << "GdkEvent:" << gevent->type;
230 return GDK_FILTER_CONTINUE; 272 return GDK_FILTER_CONTINUE;
231 } 273 }
232 274
233 bool MessagePumpX::WillProcessXEvent(XEvent* xevent) {
234 ObserverListBase<MessagePumpObserver>::Iterator it(observers());
235 MessagePumpObserver* obs;
236 while ((obs = it.GetNext()) != NULL) {
237 if (obs->WillProcessXEvent(xevent))
238 return true;
239 }
240 return false;
241 }
242
243 void MessagePumpX::EventDispatcherX(GdkEvent* event, gpointer data) { 275 void MessagePumpX::EventDispatcherX(GdkEvent* event, gpointer data) {
244 MessagePumpX* pump_x = reinterpret_cast<MessagePumpX*>(data); 276 MessagePumpX* pump_x = reinterpret_cast<MessagePumpX*>(data);
245 CHECK(use_gtk_message_pump) << "GdkEvent:" << event->type; 277 CHECK(use_gtk_message_pump) << "GdkEvent:" << event->type;
246 278
247 if (!pump_x->gdksource_) { 279 if (!pump_x->gdksource_) {
248 pump_x->gdksource_ = g_main_current_source(); 280 pump_x->gdksource_ = g_main_current_source();
249 if (pump_x->gdksource_) 281 if (pump_x->gdksource_)
250 pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch; 282 pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch;
251 } else if (!pump_x->IsDispatchingEvent()) { 283 } else if (!pump_x->IsDispatchingEvent()) {
252 if (event->type != GDK_NOTHING && 284 if (event->type != GDK_NOTHING &&
(...skipping 19 matching lines...) Expand all
272 304
273 capture_x_events_[ButtonRelease] = true; 305 capture_x_events_[ButtonRelease] = true;
274 capture_gdk_events_[GDK_BUTTON_RELEASE] = true; 306 capture_gdk_events_[GDK_BUTTON_RELEASE] = true;
275 307
276 capture_x_events_[MotionNotify] = true; 308 capture_x_events_[MotionNotify] = true;
277 capture_gdk_events_[GDK_MOTION_NOTIFY] = true; 309 capture_gdk_events_[GDK_MOTION_NOTIFY] = true;
278 310
279 capture_x_events_[GenericEvent] = true; 311 capture_x_events_[GenericEvent] = true;
280 } 312 }
281 313
314 COMPILE_ASSERT(XLASTEvent >= LASTEvent, XLASTEvent_too_small);
315
316 #endif // defined(TOOLKIT_USES_GTK)
317
282 MessagePumpObserver::EventStatus 318 MessagePumpObserver::EventStatus
283 MessagePumpObserver::WillProcessXEvent(XEvent* xev) { 319 MessagePumpObserver::WillProcessXEvent(XEvent* xev) {
284 return EVENT_CONTINUE; 320 return EVENT_CONTINUE;
285 } 321 }
286 322
287 COMPILE_ASSERT(XLASTEvent >= LASTEvent, XLASTEvent_too_small);
288
289 } // namespace base 323 } // namespace base
OLDNEW
« no previous file with comments | « base/message_pump_x.h ('k') | build/build_config.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698