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

Side by Side Diff: base/message_loop/message_pump_x11.cc

Issue 23880006: gtk: Allow building both the X11 and Gtk message-pumps for gtk. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tot-merge Created 7 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_loop/message_pump_x11.h ('k') | chromeos/display/output_util.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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_loop/message_pump_aurax11.h" 5 #include "base/message_loop/message_pump_x11.h"
6 6
7 #include <glib.h> 7 #include <glib.h>
8 #include <X11/X.h> 8 #include <X11/X.h>
9 #include <X11/extensions/XInput2.h> 9 #include <X11/extensions/XInput2.h>
10 #include <X11/XKBlib.h> 10 #include <X11/XKBlib.h>
11 11
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 14
15 namespace base { 15 namespace base {
16 16
17 namespace { 17 namespace {
18 18
19 gboolean XSourcePrepare(GSource* source, gint* timeout_ms) { 19 gboolean XSourcePrepare(GSource* source, gint* timeout_ms) {
20 if (XPending(MessagePumpAuraX11::GetDefaultXDisplay())) 20 if (XPending(MessagePumpX11::GetDefaultXDisplay()))
21 *timeout_ms = 0; 21 *timeout_ms = 0;
22 else 22 else
23 *timeout_ms = -1; 23 *timeout_ms = -1;
24 return FALSE; 24 return FALSE;
25 } 25 }
26 26
27 gboolean XSourceCheck(GSource* source) { 27 gboolean XSourceCheck(GSource* source) {
28 return XPending(MessagePumpAuraX11::GetDefaultXDisplay()); 28 return XPending(MessagePumpX11::GetDefaultXDisplay());
29 } 29 }
30 30
31 gboolean XSourceDispatch(GSource* source, 31 gboolean XSourceDispatch(GSource* source,
32 GSourceFunc unused_func, 32 GSourceFunc unused_func,
33 gpointer data) { 33 gpointer data) {
34 MessagePumpAuraX11* pump = static_cast<MessagePumpAuraX11*>(data); 34 MessagePumpX11* pump = static_cast<MessagePumpX11*>(data);
35 return pump->DispatchXEvents(); 35 return pump->DispatchXEvents();
36 } 36 }
37 37
38 GSourceFuncs XSourceFuncs = { 38 GSourceFuncs XSourceFuncs = {
39 XSourcePrepare, 39 XSourcePrepare,
40 XSourceCheck, 40 XSourceCheck,
41 XSourceDispatch, 41 XSourceDispatch,
42 NULL 42 NULL
43 }; 43 };
44 44
45 // The connection is essentially a global that's accessed through a static 45 // The connection is essentially a global that's accessed through a static
46 // method and destroyed whenever ~MessagePumpAuraX11() is called. We do this 46 // method and destroyed whenever ~MessagePumpX11() is called. We do this
47 // for historical reasons so user code can call 47 // for historical reasons so user code can call
48 // MessagePumpForUI::GetDefaultXDisplay() where MessagePumpForUI is a typedef 48 // MessagePumpForUI::GetDefaultXDisplay() where MessagePumpForUI is a typedef
49 // to whatever type in the current build. 49 // to whatever type in the current build.
50 // 50 //
51 // TODO(erg): This can be changed to something more sane like 51 // TODO(erg): This can be changed to something more sane like
52 // MessagePumpAuraX11::Current()->display() once MessagePumpGtk goes away. 52 // MessagePumpX11::Current()->display() once MessagePumpGtk goes away.
53 Display* g_xdisplay = NULL; 53 Display* g_xdisplay = NULL;
54 int g_xinput_opcode = -1; 54 int g_xinput_opcode = -1;
55 55
56 bool InitializeXInput2Internal() { 56 bool InitializeXInput2Internal() {
57 Display* display = MessagePumpAuraX11::GetDefaultXDisplay(); 57 Display* display = MessagePumpX11::GetDefaultXDisplay();
58 if (!display) 58 if (!display)
59 return false; 59 return false;
60 60
61 int event, err; 61 int event, err;
62 62
63 int xiopcode; 63 int xiopcode;
64 if (!XQueryExtension(display, "XInputExtension", &xiopcode, &event, &err)) { 64 if (!XQueryExtension(display, "XInputExtension", &xiopcode, &event, &err)) {
65 DVLOG(1) << "X Input extension not available."; 65 DVLOG(1) << "X Input extension not available.";
66 return false; 66 return false;
67 } 67 }
(...skipping 28 matching lines...) Expand all
96 } 96 }
97 return target; 97 return target;
98 } 98 }
99 99
100 bool InitializeXInput2() { 100 bool InitializeXInput2() {
101 static bool xinput2_supported = InitializeXInput2Internal(); 101 static bool xinput2_supported = InitializeXInput2Internal();
102 return xinput2_supported; 102 return xinput2_supported;
103 } 103 }
104 104
105 bool InitializeXkb() { 105 bool InitializeXkb() {
106 Display* display = MessagePumpAuraX11::GetDefaultXDisplay(); 106 Display* display = MessagePumpX11::GetDefaultXDisplay();
107 if (!display) 107 if (!display)
108 return false; 108 return false;
109 109
110 int opcode, event, error; 110 int opcode, event, error;
111 int major = XkbMajorVersion; 111 int major = XkbMajorVersion;
112 int minor = XkbMinorVersion; 112 int minor = XkbMinorVersion;
113 if (!XkbQueryExtension(display, &opcode, &event, &error, &major, &minor)) { 113 if (!XkbQueryExtension(display, &opcode, &event, &error, &major, &minor)) {
114 DVLOG(1) << "Xkb extension not available."; 114 DVLOG(1) << "Xkb extension not available.";
115 return false; 115 return false;
116 } 116 }
117 117
118 // Ask the server not to send KeyRelease event when the user holds down a key. 118 // Ask the server not to send KeyRelease event when the user holds down a key.
119 // crbug.com/138092 119 // crbug.com/138092
120 Bool supported_return; 120 Bool supported_return;
121 if (!XkbSetDetectableAutoRepeat(display, True, &supported_return)) { 121 if (!XkbSetDetectableAutoRepeat(display, True, &supported_return)) {
122 DVLOG(1) << "XKB not supported in the server."; 122 DVLOG(1) << "XKB not supported in the server.";
123 return false; 123 return false;
124 } 124 }
125 125
126 return true; 126 return true;
127 } 127 }
128 128
129 } // namespace 129 } // namespace
130 130
131 MessagePumpAuraX11::MessagePumpAuraX11() : MessagePumpGlib(), 131 MessagePumpX11::MessagePumpX11() : MessagePumpGlib(),
132 x_source_(NULL) { 132 x_source_(NULL) {
133 InitializeXInput2(); 133 InitializeXInput2();
134 InitializeXkb(); 134 InitializeXkb();
135 InitXSource(); 135 InitXSource();
136 136
137 // Can't put this in the initializer list because g_xdisplay may not exist 137 // Can't put this in the initializer list because g_xdisplay may not exist
138 // until after InitXSource(). 138 // until after InitXSource().
139 x_root_window_ = DefaultRootWindow(g_xdisplay); 139 x_root_window_ = DefaultRootWindow(g_xdisplay);
140 } 140 }
141 141
142 MessagePumpAuraX11::~MessagePumpAuraX11() { 142 MessagePumpX11::~MessagePumpX11() {
143 g_source_destroy(x_source_); 143 g_source_destroy(x_source_);
144 g_source_unref(x_source_); 144 g_source_unref(x_source_);
145 XCloseDisplay(g_xdisplay); 145 XCloseDisplay(g_xdisplay);
146 g_xdisplay = NULL; 146 g_xdisplay = NULL;
147 } 147 }
148 148
149 // static 149 // static
150 Display* MessagePumpAuraX11::GetDefaultXDisplay() { 150 Display* MessagePumpX11::GetDefaultXDisplay() {
151 if (!g_xdisplay) 151 if (!g_xdisplay)
152 g_xdisplay = XOpenDisplay(NULL); 152 g_xdisplay = XOpenDisplay(NULL);
153 return g_xdisplay; 153 return g_xdisplay;
154 } 154 }
155 155
156 // static 156 // static
157 bool MessagePumpAuraX11::HasXInput2() { 157 bool MessagePumpX11::HasXInput2() {
158 return InitializeXInput2(); 158 return InitializeXInput2();
159 } 159 }
160 160
161 #if !defined(TOOLKIT_GTK)
161 // static 162 // static
162 MessagePumpAuraX11* MessagePumpAuraX11::Current() { 163 MessagePumpX11* MessagePumpX11::Current() {
163 MessageLoopForUI* loop = MessageLoopForUI::current(); 164 MessageLoopForUI* loop = MessageLoopForUI::current();
164 return static_cast<MessagePumpAuraX11*>(loop->pump_ui()); 165 return static_cast<MessagePumpX11*>(loop->pump_ui());
165 } 166 }
167 #endif
166 168
167 void MessagePumpAuraX11::AddDispatcherForWindow( 169 void MessagePumpX11::AddDispatcherForWindow(
168 MessagePumpDispatcher* dispatcher, 170 MessagePumpDispatcher* dispatcher,
169 unsigned long xid) { 171 unsigned long xid) {
170 dispatchers_.insert(std::make_pair(xid, dispatcher)); 172 dispatchers_.insert(std::make_pair(xid, dispatcher));
171 } 173 }
172 174
173 void MessagePumpAuraX11::RemoveDispatcherForWindow(unsigned long xid) { 175 void MessagePumpX11::RemoveDispatcherForWindow(unsigned long xid) {
174 dispatchers_.erase(xid); 176 dispatchers_.erase(xid);
175 } 177 }
176 178
177 void MessagePumpAuraX11::AddDispatcherForRootWindow( 179 void MessagePumpX11::AddDispatcherForRootWindow(
178 MessagePumpDispatcher* dispatcher) { 180 MessagePumpDispatcher* dispatcher) {
179 root_window_dispatchers_.AddObserver(dispatcher); 181 root_window_dispatchers_.AddObserver(dispatcher);
180 } 182 }
181 183
182 void MessagePumpAuraX11::RemoveDispatcherForRootWindow( 184 void MessagePumpX11::RemoveDispatcherForRootWindow(
183 MessagePumpDispatcher* dispatcher) { 185 MessagePumpDispatcher* dispatcher) {
184 root_window_dispatchers_.RemoveObserver(dispatcher); 186 root_window_dispatchers_.RemoveObserver(dispatcher);
185 } 187 }
186 188
187 void MessagePumpAuraX11::AddObserver(MessagePumpObserver* observer) { 189 void MessagePumpX11::AddObserver(MessagePumpObserver* observer) {
188 observers_.AddObserver(observer); 190 observers_.AddObserver(observer);
189 } 191 }
190 192
191 void MessagePumpAuraX11::RemoveObserver(MessagePumpObserver* observer) { 193 void MessagePumpX11::RemoveObserver(MessagePumpObserver* observer) {
192 observers_.RemoveObserver(observer); 194 observers_.RemoveObserver(observer);
193 } 195 }
194 196
195 bool MessagePumpAuraX11::DispatchXEvents() { 197 bool MessagePumpX11::DispatchXEvents() {
196 Display* display = GetDefaultXDisplay(); 198 Display* display = GetDefaultXDisplay();
197 DCHECK(display); 199 DCHECK(display);
198 MessagePumpDispatcher* dispatcher = 200 MessagePumpDispatcher* dispatcher =
199 GetDispatcher() ? GetDispatcher() : this; 201 GetDispatcher() ? GetDispatcher() : this;
200 202
201 // In the general case, we want to handle all pending events before running 203 // In the general case, we want to handle all pending events before running
202 // the tasks. This is what happens in the message_pump_glib case. 204 // the tasks. This is what happens in the message_pump_glib case.
203 while (XPending(display)) { 205 while (XPending(display)) {
204 XEvent xev; 206 XEvent xev;
205 XNextEvent(display, &xev); 207 XNextEvent(display, &xev);
206 if (dispatcher && ProcessXEvent(dispatcher, &xev)) 208 if (dispatcher && ProcessXEvent(dispatcher, &xev))
207 return TRUE; 209 return TRUE;
208 } 210 }
209 return TRUE; 211 return TRUE;
210 } 212 }
211 213
212 void MessagePumpAuraX11::BlockUntilWindowMapped(unsigned long xid) { 214 void MessagePumpX11::BlockUntilWindowMapped(unsigned long xid) {
213 XEvent event; 215 XEvent event;
214 216
215 Display* display = GetDefaultXDisplay(); 217 Display* display = GetDefaultXDisplay();
216 DCHECK(display); 218 DCHECK(display);
217 219
218 MessagePumpDispatcher* dispatcher = 220 MessagePumpDispatcher* dispatcher =
219 GetDispatcher() ? GetDispatcher() : this; 221 GetDispatcher() ? GetDispatcher() : this;
220 222
221 do { 223 do {
222 // Block until there's a message of |event_mask| type on |w|. Then remove 224 // Block until there's a message of |event_mask| type on |w|. Then remove
223 // it from the queue and stuff it in |event|. 225 // it from the queue and stuff it in |event|.
224 XWindowEvent(display, xid, StructureNotifyMask, &event); 226 XWindowEvent(display, xid, StructureNotifyMask, &event);
225 ProcessXEvent(dispatcher, &event); 227 ProcessXEvent(dispatcher, &event);
226 } while (event.type != MapNotify); 228 } while (event.type != MapNotify);
227 } 229 }
228 230
229 void MessagePumpAuraX11::InitXSource() { 231 void MessagePumpX11::InitXSource() {
230 // CHECKs are to help track down crbug.com/113106. 232 // CHECKs are to help track down crbug.com/113106.
231 CHECK(!x_source_); 233 CHECK(!x_source_);
232 Display* display = GetDefaultXDisplay(); 234 Display* display = GetDefaultXDisplay();
233 CHECK(display) << "Unable to get connection to X server"; 235 CHECK(display) << "Unable to get connection to X server";
234 x_poll_.reset(new GPollFD()); 236 x_poll_.reset(new GPollFD());
235 CHECK(x_poll_.get()); 237 CHECK(x_poll_.get());
236 x_poll_->fd = ConnectionNumber(display); 238 x_poll_->fd = ConnectionNumber(display);
237 x_poll_->events = G_IO_IN; 239 x_poll_->events = G_IO_IN;
238 240
239 x_source_ = g_source_new(&XSourceFuncs, sizeof(GSource)); 241 x_source_ = g_source_new(&XSourceFuncs, sizeof(GSource));
240 g_source_add_poll(x_source_, x_poll_.get()); 242 g_source_add_poll(x_source_, x_poll_.get());
241 g_source_set_can_recurse(x_source_, TRUE); 243 g_source_set_can_recurse(x_source_, TRUE);
242 g_source_set_callback(x_source_, NULL, this, NULL); 244 g_source_set_callback(x_source_, NULL, this, NULL);
243 g_source_attach(x_source_, g_main_context_default()); 245 g_source_attach(x_source_, g_main_context_default());
244 } 246 }
245 247
246 bool MessagePumpAuraX11::ProcessXEvent(MessagePumpDispatcher* dispatcher, 248 bool MessagePumpX11::ProcessXEvent(MessagePumpDispatcher* dispatcher,
247 XEvent* xev) { 249 XEvent* xev) {
248 bool should_quit = false; 250 bool should_quit = false;
249 251
250 bool have_cookie = false; 252 bool have_cookie = false;
251 if (xev->type == GenericEvent && 253 if (xev->type == GenericEvent &&
252 XGetEventData(xev->xgeneric.display, &xev->xcookie)) { 254 XGetEventData(xev->xgeneric.display, &xev->xcookie)) {
253 have_cookie = true; 255 have_cookie = true;
254 } 256 }
255 257
256 if (!WillProcessXEvent(xev)) { 258 if (!WillProcessXEvent(xev)) {
257 if (!dispatcher->Dispatch(xev)) { 259 if (!dispatcher->Dispatch(xev)) {
258 should_quit = true; 260 should_quit = true;
259 Quit(); 261 Quit();
260 } 262 }
261 DidProcessXEvent(xev); 263 DidProcessXEvent(xev);
262 } 264 }
263 265
264 if (have_cookie) { 266 if (have_cookie) {
265 XFreeEventData(xev->xgeneric.display, &xev->xcookie); 267 XFreeEventData(xev->xgeneric.display, &xev->xcookie);
266 } 268 }
267 269
268 return should_quit; 270 return should_quit;
269 } 271 }
270 272
271 bool MessagePumpAuraX11::WillProcessXEvent(XEvent* xevent) { 273 bool MessagePumpX11::WillProcessXEvent(XEvent* xevent) {
272 if (!observers().might_have_observers()) 274 if (!observers().might_have_observers())
273 return false; 275 return false;
274 ObserverListBase<MessagePumpObserver>::Iterator it(observers()); 276 ObserverListBase<MessagePumpObserver>::Iterator it(observers());
275 MessagePumpObserver* obs; 277 MessagePumpObserver* obs;
276 while ((obs = it.GetNext()) != NULL) { 278 while ((obs = it.GetNext()) != NULL) {
277 if (obs->WillProcessEvent(xevent)) 279 if (obs->WillProcessEvent(xevent))
278 return true; 280 return true;
279 } 281 }
280 return false; 282 return false;
281 } 283 }
282 284
283 void MessagePumpAuraX11::DidProcessXEvent(XEvent* xevent) { 285 void MessagePumpX11::DidProcessXEvent(XEvent* xevent) {
284 FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(xevent)); 286 FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(xevent));
285 } 287 }
286 288
287 MessagePumpDispatcher* MessagePumpAuraX11::GetDispatcherForXEvent( 289 MessagePumpDispatcher* MessagePumpX11::GetDispatcherForXEvent(
288 const NativeEvent& xev) const { 290 const NativeEvent& xev) const {
289 ::Window x_window = FindEventTarget(xev); 291 ::Window x_window = FindEventTarget(xev);
290 DispatchersMap::const_iterator it = dispatchers_.find(x_window); 292 DispatchersMap::const_iterator it = dispatchers_.find(x_window);
291 return it != dispatchers_.end() ? it->second : NULL; 293 return it != dispatchers_.end() ? it->second : NULL;
292 } 294 }
293 295
294 bool MessagePumpAuraX11::Dispatch(const NativeEvent& xev) { 296 bool MessagePumpX11::Dispatch(const NativeEvent& xev) {
295 // MappingNotify events (meaning that the keyboard or pointer buttons have 297 // MappingNotify events (meaning that the keyboard or pointer buttons have
296 // been remapped) aren't associated with a window; send them to all 298 // been remapped) aren't associated with a window; send them to all
297 // dispatchers. 299 // dispatchers.
298 if (xev->type == MappingNotify) { 300 if (xev->type == MappingNotify) {
299 for (DispatchersMap::const_iterator it = dispatchers_.begin(); 301 for (DispatchersMap::const_iterator it = dispatchers_.begin();
300 it != dispatchers_.end(); ++it) { 302 it != dispatchers_.end(); ++it) {
301 it->second->Dispatch(xev); 303 it->second->Dispatch(xev);
302 } 304 }
303 return true; 305 return true;
304 } 306 }
305 307
306 if (FindEventTarget(xev) == x_root_window_) { 308 if (FindEventTarget(xev) == x_root_window_) {
307 FOR_EACH_OBSERVER(MessagePumpDispatcher, root_window_dispatchers_, 309 FOR_EACH_OBSERVER(MessagePumpDispatcher, root_window_dispatchers_,
308 Dispatch(xev)); 310 Dispatch(xev));
309 return true; 311 return true;
310 } 312 }
311 MessagePumpDispatcher* dispatcher = GetDispatcherForXEvent(xev); 313 MessagePumpDispatcher* dispatcher = GetDispatcherForXEvent(xev);
312 return dispatcher ? dispatcher->Dispatch(xev) : true; 314 return dispatcher ? dispatcher->Dispatch(xev) : true;
313 } 315 }
314 316
315 } // namespace base 317 } // namespace base
OLDNEW
« no previous file with comments | « base/message_loop/message_pump_x11.h ('k') | chromeos/display/output_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698