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

Side by Side Diff: base/message_pump_aurax11.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: Created 8 years, 7 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
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_pump_x.h" 5 #include "base/message_pump_aurax11.h"
6 6
7 #include <X11/extensions/XInput2.h> 7 #include <X11/extensions/XInput2.h>
8 8
9 #include <map>
10
9 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/lazy_instance.h"
10 #include "base/message_loop.h" 13 #include "base/message_loop.h"
11 14
12 namespace { 15 namespace {
13 16
14 gboolean XSourcePrepare(GSource* source, gint* timeout_ms) { 17 gboolean XSourcePrepare(GSource* source, gint* timeout_ms) {
15 if (XPending(base::MessagePumpX::GetDefaultXDisplay())) 18 if (XPending(base::MessagePumpAuraX11::GetDefaultXDisplay()))
16 *timeout_ms = 0; 19 *timeout_ms = 0;
17 else 20 else
18 *timeout_ms = -1; 21 *timeout_ms = -1;
19 return FALSE; 22 return FALSE;
20 } 23 }
21 24
22 gboolean XSourceCheck(GSource* source) { 25 gboolean XSourceCheck(GSource* source) {
23 return XPending(base::MessagePumpX::GetDefaultXDisplay()); 26 return XPending(base::MessagePumpAuraX11::GetDefaultXDisplay());
24 } 27 }
25 28
26 gboolean XSourceDispatch(GSource* source, 29 gboolean XSourceDispatch(GSource* source,
27 GSourceFunc unused_func, 30 GSourceFunc unused_func,
28 gpointer data) { 31 gpointer data) {
29 base::MessagePumpX* pump = static_cast<base::MessagePumpX*>(data); 32 base::MessagePumpAuraX11* pump = static_cast<base::MessagePumpAuraX11*>(data);
30 return pump->DispatchXEvents(); 33 return pump->DispatchXEvents();
31 } 34 }
32 35
33 GSourceFuncs XSourceFuncs = { 36 GSourceFuncs XSourceFuncs = {
34 XSourcePrepare, 37 XSourcePrepare,
35 XSourceCheck, 38 XSourceCheck,
36 XSourceDispatch, 39 XSourceDispatch,
37 NULL 40 NULL
38 }; 41 };
39 42
40 // The message-pump opens a connection to the display and owns it. 43 // The message-pump opens a connection to the display and owns it.
41 Display* g_xdisplay = NULL; 44 Display* g_xdisplay = NULL;
42 45
43 // The default dispatcher to process native events when no dispatcher 46 // The default dispatcher to process native events when no dispatcher
44 // is specified. 47 // is specified.
45 base::MessagePumpDispatcher* g_default_dispatcher = NULL; 48 base::MessagePumpDispatcher* g_default_dispatcher = NULL;
46 49
50 // A cache of Atoms tied to the lifetime of |g_xdisplay|. Cleared when
51 // |g_xdisplay| is destroyed.
52 typedef std::map<base::atom::Name, ::Atom> AtomMap;
53 base::LazyInstance<AtomMap> g_cached_atoms = LAZY_INSTANCE_INITIALIZER;
54
55 // A list of atoms that we'll intern on host creation to save roundtrips to the
56 // X11 server. Must be kept in sync with base::atom::Name
57 struct AtomInfo {
58 base::atom::Name id;
59 const char* name;
60 } const kAtomList[] = {
61 { base::atom::WM_DELETE_WINDOW, "WM_DELETE_WINDOW" },
62 { base::atom::_NET_WM_MOVERESIZE, "_NET_WM_MOVERESIZE" },
63 { base::atom::_NET_WM_PING, "_NET_WM_PING" },
64 { base::atom::_NET_WM_PID, "_NET_WM_PID" },
65 { base::atom::WM_S0, "WM_S0" },
66 { base::atom::_MOTIF_WM_HINTS, "_MOTIF_WM_HINTS" }
67 };
68
69 // Our lists need to stay in sync here.
70 COMPILE_ASSERT(arraysize(kAtomList) == base::atom::ATOM_COUNT,
71 atom_lists_are_same_size);
72
47 bool InitializeXInput2Internal() { 73 bool InitializeXInput2Internal() {
48 Display* display = base::MessagePumpX::GetDefaultXDisplay(); 74 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
49 if (!display) 75 if (!display)
50 return false; 76 return false;
51 77
52 int event, err; 78 int event, err;
53 79
54 int xiopcode; 80 int xiopcode;
55 if (!XQueryExtension(display, "XInputExtension", &xiopcode, &event, &err)) { 81 if (!XQueryExtension(display, "XInputExtension", &xiopcode, &event, &err)) {
56 DVLOG(1) << "X Input extension not available."; 82 DVLOG(1) << "X Input extension not available.";
57 return false; 83 return false;
58 } 84 }
(...skipping 21 matching lines...) Expand all
80 106
81 bool InitializeXInput2() { 107 bool InitializeXInput2() {
82 static bool xinput2_supported = InitializeXInput2Internal(); 108 static bool xinput2_supported = InitializeXInput2Internal();
83 return xinput2_supported; 109 return xinput2_supported;
84 } 110 }
85 111
86 } // namespace 112 } // namespace
87 113
88 namespace base { 114 namespace base {
89 115
90 MessagePumpX::MessagePumpX() : MessagePumpGlib(), 116 MessagePumpAuraX11::MessagePumpAuraX11() : MessagePumpGlib(),
91 x_source_(NULL) { 117 x_source_(NULL) {
92 InitializeXInput2(); 118 InitializeXInput2();
93 InitXSource(); 119 InitXSource();
94 } 120 }
95 121
96 // static 122 // static
97 Display* MessagePumpX::GetDefaultXDisplay() { 123 Display* MessagePumpAuraX11::GetDefaultXDisplay() {
98 if (!g_xdisplay) 124 if (!g_xdisplay)
99 g_xdisplay = XOpenDisplay(NULL); 125 g_xdisplay = XOpenDisplay(NULL);
100 return g_xdisplay; 126 return g_xdisplay;
101 } 127 }
102 128
103 // static 129 // static
104 bool MessagePumpX::HasXInput2() { 130 ::Atom MessagePumpAuraX11::GetAtom(atom::Name name) {
131 AtomMap& cached_atom_map = g_cached_atoms.Get();
132 if (cached_atom_map.empty()) {
133 // First time we're trying to use a cached atom. Intern all our atom data.
134 const char* all_names[atom::ATOM_COUNT];
135 ::Atom cached_atoms[atom::ATOM_COUNT];
136
137 for (int i = 0; i < atom::ATOM_COUNT; ++i)
138 all_names[i] = kAtomList[i].name;
139
140 // Grab all the atoms we need now to minimize roundtrips to the X11 server.
141 XInternAtoms(base::MessagePumpAuraX11::GetDefaultXDisplay(),
142 const_cast<char**>(all_names), atom::ATOM_COUNT, False,
143 cached_atoms);
144
145 for (int i = 0; i < atom::ATOM_COUNT; ++i)
146 cached_atom_map.insert(std::make_pair(kAtomList[i].id, cached_atoms[i]));
147 }
148
149 AtomMap::const_iterator it = cached_atom_map.find(name);
150 DCHECK(it != cached_atom_map.end());
151 return it->second;
152 }
153
154 // static
155 bool MessagePumpAuraX11::HasXInput2() {
105 return InitializeXInput2(); 156 return InitializeXInput2();
106 } 157 }
107 158
108 // static 159 // static
109 void MessagePumpX::SetDefaultDispatcher(MessagePumpDispatcher* dispatcher) { 160 void MessagePumpAuraX11::SetDefaultDispatcher(
161 MessagePumpDispatcher* dispatcher) {
110 DCHECK(!g_default_dispatcher || !dispatcher); 162 DCHECK(!g_default_dispatcher || !dispatcher);
111 g_default_dispatcher = dispatcher; 163 g_default_dispatcher = dispatcher;
112 } 164 }
113 165
114 gboolean MessagePumpX::DispatchXEvents() { 166 gboolean MessagePumpAuraX11::DispatchXEvents() {
115 Display* display = GetDefaultXDisplay(); 167 Display* display = GetDefaultXDisplay();
116 DCHECK(display); 168 DCHECK(display);
117 MessagePumpDispatcher* dispatcher = 169 MessagePumpDispatcher* dispatcher =
118 GetDispatcher() ? GetDispatcher() : g_default_dispatcher; 170 GetDispatcher() ? GetDispatcher() : g_default_dispatcher;
119 171
120 // In the general case, we want to handle all pending events before running 172 // 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. 173 // the tasks. This is what happens in the message_pump_glib case.
122 while (XPending(display)) { 174 while (XPending(display)) {
123 XEvent xev; 175 XEvent xev;
124 XNextEvent(display, &xev); 176 XNextEvent(display, &xev);
125 if (dispatcher && ProcessXEvent(dispatcher, &xev)) 177 if (dispatcher && ProcessXEvent(dispatcher, &xev))
126 return TRUE; 178 return TRUE;
127 } 179 }
128 return TRUE; 180 return TRUE;
129 } 181 }
130 182
131 MessagePumpX::~MessagePumpX() { 183 MessagePumpAuraX11::~MessagePumpAuraX11() {
132 g_source_destroy(x_source_); 184 g_source_destroy(x_source_);
133 g_source_unref(x_source_); 185 g_source_unref(x_source_);
134 XCloseDisplay(g_xdisplay); 186 XCloseDisplay(g_xdisplay);
135 g_xdisplay = NULL; 187 g_xdisplay = NULL;
188 g_cached_atoms.Get().clear();
136 } 189 }
137 190
138 void MessagePumpX::InitXSource() { 191 void MessagePumpAuraX11::InitXSource() {
139 // CHECKs are to help track down crbug.com/113106. 192 // CHECKs are to help track down crbug.com/113106.
140 CHECK(!x_source_); 193 CHECK(!x_source_);
141 Display* display = GetDefaultXDisplay(); 194 Display* display = GetDefaultXDisplay();
142 CHECK(display) << "Unable to get connection to X server"; 195 CHECK(display) << "Unable to get connection to X server";
143 x_poll_.reset(new GPollFD()); 196 x_poll_.reset(new GPollFD());
144 CHECK(x_poll_.get()); 197 CHECK(x_poll_.get());
145 x_poll_->fd = ConnectionNumber(display); 198 x_poll_->fd = ConnectionNumber(display);
146 x_poll_->events = G_IO_IN; 199 x_poll_->events = G_IO_IN;
147 200
148 x_source_ = g_source_new(&XSourceFuncs, sizeof(GSource)); 201 x_source_ = g_source_new(&XSourceFuncs, sizeof(GSource));
149 g_source_add_poll(x_source_, x_poll_.get()); 202 g_source_add_poll(x_source_, x_poll_.get());
150 g_source_set_can_recurse(x_source_, TRUE); 203 g_source_set_can_recurse(x_source_, TRUE);
151 g_source_set_callback(x_source_, NULL, this, NULL); 204 g_source_set_callback(x_source_, NULL, this, NULL);
152 g_source_attach(x_source_, g_main_context_default()); 205 g_source_attach(x_source_, g_main_context_default());
153 } 206 }
154 207
155 bool MessagePumpX::ProcessXEvent(MessagePumpDispatcher* dispatcher, 208 bool MessagePumpAuraX11::ProcessXEvent(MessagePumpDispatcher* dispatcher,
156 XEvent* xev) { 209 XEvent* xev) {
157 bool should_quit = false; 210 bool should_quit = false;
158 211
159 bool have_cookie = false; 212 bool have_cookie = false;
160 if (xev->type == GenericEvent && 213 if (xev->type == GenericEvent &&
161 XGetEventData(xev->xgeneric.display, &xev->xcookie)) { 214 XGetEventData(xev->xgeneric.display, &xev->xcookie)) {
162 have_cookie = true; 215 have_cookie = true;
163 } 216 }
164 217
165 if (!WillProcessXEvent(xev)) { 218 if (!WillProcessXEvent(xev)) {
166 if (!dispatcher->Dispatch(xev)) { 219 if (!dispatcher->Dispatch(xev)) {
167 should_quit = true; 220 should_quit = true;
168 Quit(); 221 Quit();
169 } 222 }
170 DidProcessXEvent(xev); 223 DidProcessXEvent(xev);
171 } 224 }
172 225
173 if (have_cookie) { 226 if (have_cookie) {
174 XFreeEventData(xev->xgeneric.display, &xev->xcookie); 227 XFreeEventData(xev->xgeneric.display, &xev->xcookie);
175 } 228 }
176 229
177 return should_quit; 230 return should_quit;
178 } 231 }
179 232
180 bool MessagePumpX::WillProcessXEvent(XEvent* xevent) { 233 bool MessagePumpAuraX11::WillProcessXEvent(XEvent* xevent) {
181 if (!observers().might_have_observers()) 234 if (!observers().might_have_observers())
182 return false; 235 return false;
183 ObserverListBase<MessagePumpObserver>::Iterator it(observers()); 236 ObserverListBase<MessagePumpObserver>::Iterator it(observers());
184 MessagePumpObserver* obs; 237 MessagePumpObserver* obs;
185 while ((obs = it.GetNext()) != NULL) { 238 while ((obs = it.GetNext()) != NULL) {
186 if (obs->WillProcessEvent(xevent)) 239 if (obs->WillProcessEvent(xevent))
187 return true; 240 return true;
188 } 241 }
189 return false; 242 return false;
190 } 243 }
191 244
192 void MessagePumpX::DidProcessXEvent(XEvent* xevent) { 245 void MessagePumpAuraX11::DidProcessXEvent(XEvent* xevent) {
193 FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(xevent)); 246 FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(xevent));
194 } 247 }
195 248
196 } // namespace base 249 } // namespace base
OLDNEW
« base/base.gypi ('K') | « base/message_pump_aurax11.h ('k') | base/message_pump_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698