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

Side by Side Diff: base/message_pump_x.cc

Issue 10441028: aura/cros: Rename MessagePump{X => AuraX11} and move the atom cache into it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compile error in file added in the interim Created 8 years, 6 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') | chrome/browser/chromeos/system_key_event_listener.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/message_pump_x.h"
6
7 #include <X11/extensions/XInput2.h>
8
9 #include "base/basictypes.h"
10 #include "base/message_loop.h"
11
12 namespace {
13
14 gboolean XSourcePrepare(GSource* source, gint* timeout_ms) {
15 if (XPending(base::MessagePumpX::GetDefaultXDisplay()))
16 *timeout_ms = 0;
17 else
18 *timeout_ms = -1;
19 return FALSE;
20 }
21
22 gboolean XSourceCheck(GSource* source) {
23 return XPending(base::MessagePumpX::GetDefaultXDisplay());
24 }
25
26 gboolean XSourceDispatch(GSource* source,
27 GSourceFunc unused_func,
28 gpointer data) {
29 base::MessagePumpX* pump = static_cast<base::MessagePumpX*>(data);
30 return pump->DispatchXEvents();
31 }
32
33 GSourceFuncs XSourceFuncs = {
34 XSourcePrepare,
35 XSourceCheck,
36 XSourceDispatch,
37 NULL
38 };
39
40 // The message-pump opens a connection to the display and owns it.
41 Display* g_xdisplay = NULL;
42
43 // The default dispatcher to process native events when no dispatcher
44 // is specified.
45 base::MessagePumpDispatcher* g_default_dispatcher = NULL;
46
47 bool InitializeXInput2Internal() {
48 Display* display = base::MessagePumpX::GetDefaultXDisplay();
49 if (!display)
50 return false;
51
52 int event, err;
53
54 int xiopcode;
55 if (!XQueryExtension(display, "XInputExtension", &xiopcode, &event, &err)) {
56 DVLOG(1) << "X Input extension not available.";
57 return false;
58 }
59
60 #if defined(USE_XI2_MT)
61 // USE_XI2_MT also defines the required XI2 minor minimum version.
62 int major = 2, minor = USE_XI2_MT;
63 #else
64 int major = 2, minor = 0;
65 #endif
66 if (XIQueryVersion(display, &major, &minor) == BadRequest) {
67 DVLOG(1) << "XInput2 not supported in the server.";
68 return false;
69 }
70 #if defined(USE_XI2_MT)
71 if (major < 2 || (major == 2 && minor < USE_XI2_MT)) {
72 DVLOG(1) << "XI version on server is " << major << "." << minor << ". "
73 << "But 2." << USE_XI2_MT << " is required.";
74 return false;
75 }
76 #endif
77
78 return true;
79 }
80
81 bool InitializeXInput2() {
82 static bool xinput2_supported = InitializeXInput2Internal();
83 return xinput2_supported;
84 }
85
86 } // namespace
87
88 namespace base {
89
90 MessagePumpX::MessagePumpX() : MessagePumpGlib(),
91 x_source_(NULL) {
92 InitializeXInput2();
93 InitXSource();
94 }
95
96 // static
97 Display* MessagePumpX::GetDefaultXDisplay() {
98 if (!g_xdisplay)
99 g_xdisplay = XOpenDisplay(NULL);
100 return g_xdisplay;
101 }
102
103 // static
104 bool MessagePumpX::HasXInput2() {
105 return InitializeXInput2();
106 }
107
108 // static
109 void MessagePumpX::SetDefaultDispatcher(MessagePumpDispatcher* dispatcher) {
110 DCHECK(!g_default_dispatcher || !dispatcher);
111 g_default_dispatcher = dispatcher;
112 }
113
114 gboolean MessagePumpX::DispatchXEvents() {
115 Display* display = GetDefaultXDisplay();
116 DCHECK(display);
117 MessagePumpDispatcher* dispatcher =
118 GetDispatcher() ? GetDispatcher() : g_default_dispatcher;
119
120 // In the general case, we want to handle all pending events before running
121 // the tasks. This is what happens in the message_pump_glib case.
122 while (XPending(display)) {
123 XEvent xev;
124 XNextEvent(display, &xev);
125 if (dispatcher && ProcessXEvent(dispatcher, &xev))
126 return TRUE;
127 }
128 return TRUE;
129 }
130
131 MessagePumpX::~MessagePumpX() {
132 g_source_destroy(x_source_);
133 g_source_unref(x_source_);
134 XCloseDisplay(g_xdisplay);
135 g_xdisplay = NULL;
136 }
137
138 void MessagePumpX::InitXSource() {
139 // CHECKs are to help track down crbug.com/113106.
140 CHECK(!x_source_);
141 Display* display = GetDefaultXDisplay();
142 CHECK(display) << "Unable to get connection to X server";
143 x_poll_.reset(new GPollFD());
144 CHECK(x_poll_.get());
145 x_poll_->fd = ConnectionNumber(display);
146 x_poll_->events = G_IO_IN;
147
148 x_source_ = g_source_new(&XSourceFuncs, sizeof(GSource));
149 g_source_add_poll(x_source_, x_poll_.get());
150 g_source_set_can_recurse(x_source_, TRUE);
151 g_source_set_callback(x_source_, NULL, this, NULL);
152 g_source_attach(x_source_, g_main_context_default());
153 }
154
155 bool MessagePumpX::ProcessXEvent(MessagePumpDispatcher* dispatcher,
156 XEvent* xev) {
157 bool should_quit = false;
158
159 bool have_cookie = false;
160 if (xev->type == GenericEvent &&
161 XGetEventData(xev->xgeneric.display, &xev->xcookie)) {
162 have_cookie = true;
163 }
164
165 if (!WillProcessXEvent(xev)) {
166 if (!dispatcher->Dispatch(xev)) {
167 should_quit = true;
168 Quit();
169 }
170 DidProcessXEvent(xev);
171 }
172
173 if (have_cookie) {
174 XFreeEventData(xev->xgeneric.display, &xev->xcookie);
175 }
176
177 return should_quit;
178 }
179
180 bool MessagePumpX::WillProcessXEvent(XEvent* xevent) {
181 if (!observers().might_have_observers())
182 return false;
183 ObserverListBase<MessagePumpObserver>::Iterator it(observers());
184 MessagePumpObserver* obs;
185 while ((obs = it.GetNext()) != NULL) {
186 if (obs->WillProcessEvent(xevent))
187 return true;
188 }
189 return false;
190 }
191
192 void MessagePumpX::DidProcessXEvent(XEvent* xevent) {
193 FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(xevent));
194 }
195
196 } // namespace base
OLDNEW
« no previous file with comments | « base/message_pump_x.h ('k') | chrome/browser/chromeos/system_key_event_listener.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698