OLD | NEW |
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_x.h" |
6 | 6 |
7 #include <X11/extensions/XInput2.h> | 7 #include <X11/extensions/XInput2.h> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 } // namespace | 86 } // namespace |
87 | 87 |
88 namespace base { | 88 namespace base { |
89 | 89 |
90 MessagePumpX::MessagePumpX() : MessagePumpGlib(), | 90 MessagePumpX::MessagePumpX() : MessagePumpGlib(), |
91 x_source_(NULL) { | 91 x_source_(NULL) { |
92 InitializeXInput2(); | 92 InitializeXInput2(); |
93 InitXSource(); | 93 InitXSource(); |
94 } | 94 } |
95 | 95 |
96 MessagePumpX::~MessagePumpX() { | |
97 g_source_destroy(x_source_); | |
98 g_source_unref(x_source_); | |
99 XCloseDisplay(g_xdisplay); | |
100 g_xdisplay = NULL; | |
101 } | |
102 | |
103 // static | 96 // static |
104 Display* MessagePumpX::GetDefaultXDisplay() { | 97 Display* MessagePumpX::GetDefaultXDisplay() { |
105 if (!g_xdisplay) | 98 if (!g_xdisplay) |
106 g_xdisplay = XOpenDisplay(NULL); | 99 g_xdisplay = XOpenDisplay(NULL); |
107 return g_xdisplay; | 100 return g_xdisplay; |
108 } | 101 } |
109 | 102 |
110 // static | 103 // static |
111 bool MessagePumpX::HasXInput2() { | 104 bool MessagePumpX::HasXInput2() { |
112 return InitializeXInput2(); | 105 return InitializeXInput2(); |
113 } | 106 } |
114 | 107 |
115 // static | 108 // static |
116 void MessagePumpX::SetDefaultDispatcher(MessagePumpDispatcher* dispatcher) { | 109 void MessagePumpX::SetDefaultDispatcher(MessagePumpDispatcher* dispatcher) { |
117 DCHECK(!g_default_dispatcher || !dispatcher); | 110 DCHECK(!g_default_dispatcher || !dispatcher); |
118 g_default_dispatcher = dispatcher; | 111 g_default_dispatcher = dispatcher; |
119 } | 112 } |
120 | 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 |
121 void MessagePumpX::InitXSource() { | 138 void MessagePumpX::InitXSource() { |
122 // CHECKs are to help track down crbug.com/113106. | 139 // CHECKs are to help track down crbug.com/113106. |
123 CHECK(!x_source_); | 140 CHECK(!x_source_); |
124 Display* display = GetDefaultXDisplay(); | 141 Display* display = GetDefaultXDisplay(); |
125 CHECK(display) << "Unable to get connection to X server"; | 142 CHECK(display) << "Unable to get connection to X server"; |
126 x_poll_.reset(new GPollFD()); | 143 x_poll_.reset(new GPollFD()); |
127 CHECK(x_poll_.get()); | 144 CHECK(x_poll_.get()); |
128 x_poll_->fd = ConnectionNumber(display); | 145 x_poll_->fd = ConnectionNumber(display); |
129 x_poll_->events = G_IO_IN; | 146 x_poll_->events = G_IO_IN; |
130 | 147 |
(...skipping 22 matching lines...) Expand all Loading... |
153 DidProcessXEvent(xev); | 170 DidProcessXEvent(xev); |
154 } | 171 } |
155 | 172 |
156 if (have_cookie) { | 173 if (have_cookie) { |
157 XFreeEventData(xev->xgeneric.display, &xev->xcookie); | 174 XFreeEventData(xev->xgeneric.display, &xev->xcookie); |
158 } | 175 } |
159 | 176 |
160 return should_quit; | 177 return should_quit; |
161 } | 178 } |
162 | 179 |
163 gboolean MessagePumpX::DispatchXEvents() { | |
164 Display* display = GetDefaultXDisplay(); | |
165 DCHECK(display); | |
166 MessagePumpDispatcher* dispatcher = | |
167 GetDispatcher() ? GetDispatcher() : g_default_dispatcher; | |
168 | |
169 // In the general case, we want to handle all pending events before running | |
170 // the tasks. This is what happens in the message_pump_glib case. | |
171 while (XPending(display)) { | |
172 XEvent xev; | |
173 XNextEvent(display, &xev); | |
174 if (dispatcher && ProcessXEvent(dispatcher, &xev)) | |
175 return TRUE; | |
176 } | |
177 return TRUE; | |
178 } | |
179 | |
180 bool MessagePumpX::WillProcessXEvent(XEvent* xevent) { | 180 bool MessagePumpX::WillProcessXEvent(XEvent* xevent) { |
181 if (!observers().might_have_observers()) | 181 if (!observers().might_have_observers()) |
182 return false; | 182 return false; |
183 ObserverListBase<MessagePumpObserver>::Iterator it(observers()); | 183 ObserverListBase<MessagePumpObserver>::Iterator it(observers()); |
184 MessagePumpObserver* obs; | 184 MessagePumpObserver* obs; |
185 while ((obs = it.GetNext()) != NULL) { | 185 while ((obs = it.GetNext()) != NULL) { |
186 if (obs->WillProcessEvent(xevent)) | 186 if (obs->WillProcessEvent(xevent)) |
187 return true; | 187 return true; |
188 } | 188 } |
189 return false; | 189 return false; |
190 } | 190 } |
191 | 191 |
192 void MessagePumpX::DidProcessXEvent(XEvent* xevent) { | 192 void MessagePumpX::DidProcessXEvent(XEvent* xevent) { |
193 FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(xevent)); | 193 FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(xevent)); |
194 } | 194 } |
195 | 195 |
196 } // namespace base | 196 } // namespace base |
OLD | NEW |