OLD | NEW |
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 "chrome/browser/automation/ui_controls.h" | 5 #include "chrome/browser/automation/ui_controls.h" |
6 | 6 |
7 #include <X11/keysym.h> | 7 #include <X11/keysym.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 | 9 |
10 // X macro fail. | 10 // X macro fail. |
11 #if defined(RootWindow) | 11 #if defined(RootWindow) |
12 #undef RootWindow | 12 #undef RootWindow |
13 #endif | 13 #endif |
14 | 14 |
15 #include "base/callback.h" | 15 #include "base/callback.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/message_pump_x.h" | 17 #include "base/message_pump_x.h" |
18 #include "chrome/browser/automation/ui_controls_internal.h" | 18 #include "chrome/browser/automation/ui_controls_internal.h" |
19 #include "ui/aura/root_window.h" | 19 #include "ui/aura/root_window.h" |
20 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 20 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
21 #include "ui/views/view.h" | 21 #include "ui/views/view.h" |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
| 25 // Mask of the buttons currently down. |
| 26 unsigned button_down_mask = 0; |
| 27 |
25 // Event waiter executes the specified closure|when a matching event | 28 // Event waiter executes the specified closure|when a matching event |
26 // is found. | 29 // is found. |
27 // TODO(oshima): Move this to base. | 30 // TODO(oshima): Move this to base. |
28 class EventWaiter : public MessageLoopForUI::Observer { | 31 class EventWaiter : public MessageLoopForUI::Observer { |
29 public: | 32 public: |
30 typedef bool (*EventWaiterMatcher)(const base::NativeEvent& event); | 33 typedef bool (*EventWaiterMatcher)(const base::NativeEvent& event); |
31 | 34 |
32 EventWaiter(const base::Closure& closure, EventWaiterMatcher matcher) | 35 EventWaiter(const base::Closure& closure, EventWaiterMatcher matcher) |
33 : closure_(closure), | 36 : closure_(closure), |
34 matcher_(matcher) { | 37 matcher_(matcher) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 bool SendMouseMove(long x, long y) { | 151 bool SendMouseMove(long x, long y) { |
149 return SendMouseMoveNotifyWhenDone(x, y, base::Closure()); | 152 return SendMouseMoveNotifyWhenDone(x, y, base::Closure()); |
150 } | 153 } |
151 | 154 |
152 bool SendMouseMoveNotifyWhenDone(long x, long y, const base::Closure& closure) { | 155 bool SendMouseMoveNotifyWhenDone(long x, long y, const base::Closure& closure) { |
153 XEvent xevent = {0}; | 156 XEvent xevent = {0}; |
154 XMotionEvent* xmotion = &xevent.xmotion; | 157 XMotionEvent* xmotion = &xevent.xmotion; |
155 xmotion->type = MotionNotify; | 158 xmotion->type = MotionNotify; |
156 g_current_x = xmotion->x = x; | 159 g_current_x = xmotion->x = x; |
157 g_current_y = xmotion->y = y; | 160 g_current_y = xmotion->y = y; |
| 161 xmotion->state = button_down_mask; |
158 xmotion->same_screen = True; | 162 xmotion->same_screen = True; |
159 // RootWindow will take care of other necessary fields. | 163 // RootWindow will take care of other necessary fields. |
160 aura::RootWindow::GetInstance()->PostNativeEvent(&xevent); | 164 aura::RootWindow::GetInstance()->PostNativeEvent(&xevent); |
161 RunClosureAfterAllPendingUIEvents(closure); | 165 RunClosureAfterAllPendingUIEvents(closure); |
162 return true; | 166 return true; |
163 } | 167 } |
164 | 168 |
165 bool SendMouseEvents(MouseButton type, int state) { | 169 bool SendMouseEvents(MouseButton type, int state) { |
166 return SendMouseEventsNotifyWhenDone(type, state, base::Closure()); | 170 return SendMouseEventsNotifyWhenDone(type, state, base::Closure()); |
167 } | 171 } |
(...skipping 21 matching lines...) Expand all Loading... |
189 xbutton->button = Button3; | 193 xbutton->button = Button3; |
190 xbutton->state = Button3Mask; | 194 xbutton->state = Button3Mask; |
191 break; | 195 break; |
192 } | 196 } |
193 // RootWindow will take care of other necessary fields. | 197 // RootWindow will take care of other necessary fields. |
194 | 198 |
195 aura::RootWindow* root_window = aura::RootWindow::GetInstance(); | 199 aura::RootWindow* root_window = aura::RootWindow::GetInstance(); |
196 if (state & DOWN) { | 200 if (state & DOWN) { |
197 xevent.xbutton.type = ButtonPress; | 201 xevent.xbutton.type = ButtonPress; |
198 root_window->PostNativeEvent(&xevent); | 202 root_window->PostNativeEvent(&xevent); |
| 203 button_down_mask |= xbutton->state; |
199 } | 204 } |
200 if (state & UP) { | 205 if (state & UP) { |
201 xevent.xbutton.type = ButtonRelease; | 206 xevent.xbutton.type = ButtonRelease; |
202 root_window->PostNativeEvent(&xevent); | 207 root_window->PostNativeEvent(&xevent); |
| 208 button_down_mask = (button_down_mask | xbutton->state) ^ xbutton->state; |
203 } | 209 } |
204 RunClosureAfterAllPendingUIEvents(closure); | 210 RunClosureAfterAllPendingUIEvents(closure); |
205 return true; | 211 return true; |
206 } | 212 } |
207 | 213 |
208 bool SendMouseClick(MouseButton type) { | 214 bool SendMouseClick(MouseButton type) { |
209 return SendMouseEvents(type, UP | DOWN); | 215 return SendMouseEvents(type, UP | DOWN); |
210 } | 216 } |
211 | 217 |
212 void MoveMouseToCenterAndPress(views::View* view, MouseButton button, | 218 void MoveMouseToCenterAndPress(views::View* view, MouseButton button, |
(...skipping 16 matching lines...) Expand all Loading... |
229 marker_event->xclient.display = NULL; | 235 marker_event->xclient.display = NULL; |
230 marker_event->xclient.window = None; | 236 marker_event->xclient.window = None; |
231 marker_event->xclient.format = 8; | 237 marker_event->xclient.format = 8; |
232 } | 238 } |
233 marker_event->xclient.message_type = MarkerEventAtom(); | 239 marker_event->xclient.message_type = MarkerEventAtom(); |
234 aura::RootWindow::GetInstance()->PostNativeEvent(marker_event); | 240 aura::RootWindow::GetInstance()->PostNativeEvent(marker_event); |
235 new EventWaiter(closure, &Matcher); | 241 new EventWaiter(closure, &Matcher); |
236 } | 242 } |
237 | 243 |
238 } // namespace ui_controls | 244 } // namespace ui_controls |
OLD | NEW |