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

Side by Side Diff: ui/aura/ui_controls_x11.cc

Issue 9390038: Move automation/ui_controls to ui/ui_controls (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: win_aura fix, sync Created 8 years, 9 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 | « ui/aura/ui_controls_win.cc ('k') | ui/base/gtk/gtk_screen_util.h » ('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 <X11/keysym.h>
6 #include <X11/Xlib.h>
7
8 // X macro fail.
9 #if defined(RootWindow)
10 #undef RootWindow
11 #endif
12
13 #include "base/logging.h"
14 #include "base/message_pump_x.h"
15 #include "ui/aura/root_window.h"
16 #include "ui/aura/ui_controls_aura.h"
17 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
18 #include "ui/ui_controls/ui_controls_aura.h"
19
20 namespace aura {
21 namespace {
22
23 // Mask of the buttons currently down.
24 unsigned button_down_mask = 0;
25
26 // Event waiter executes the specified closure|when a matching event
27 // is found.
28 // TODO(oshima): Move this to base.
29 class EventWaiter : public MessageLoopForUI::Observer {
30 public:
31 typedef bool (*EventWaiterMatcher)(const base::NativeEvent& event);
32
33 EventWaiter(const base::Closure& closure, EventWaiterMatcher matcher)
34 : closure_(closure),
35 matcher_(matcher) {
36 MessageLoopForUI::current()->AddObserver(this);
37 }
38
39 virtual ~EventWaiter() {
40 MessageLoopForUI::current()->RemoveObserver(this);
41 }
42
43 // MessageLoop::Observer implementation:
44 virtual base::EventStatus WillProcessEvent(
45 const base::NativeEvent& event) OVERRIDE {
46 if ((*matcher_)(event)) {
47 MessageLoop::current()->PostTask(FROM_HERE, closure_);
48 delete this;
49 }
50 return base::EVENT_CONTINUE;
51 }
52
53 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE {
54 }
55
56 private:
57 base::Closure closure_;
58 EventWaiterMatcher matcher_;
59 DISALLOW_COPY_AND_ASSIGN(EventWaiter);
60 };
61
62 // Latest mouse pointer location set by SendMouseMoveNotifyWhenDone.
63 int g_current_x = -1000;
64 int g_current_y = -1000;
65
66 // Returns atom that indidates that the XEvent is marker event.
67 Atom MarkerEventAtom() {
68 return XInternAtom(base::MessagePumpX::GetDefaultXDisplay(),
69 "marker_event",
70 False);
71 }
72
73 // Returns true when the event is a marker event.
74 bool Matcher(const base::NativeEvent& event) {
75 return event->xany.type == ClientMessage &&
76 event->xclient.message_type == MarkerEventAtom();
77 }
78
79 class UIControlsX11 : public ui_controls::UIControlsAura {
80 public:
81 UIControlsX11(RootWindow* root_window) : root_window_(root_window) {
82 }
83
84 virtual bool SendKeyPress(gfx::NativeWindow window,
85 ui::KeyboardCode key,
86 bool control,
87 bool shift,
88 bool alt,
89 bool command) {
90 DCHECK(!command); // No command key on Aura
91 return SendKeyPressNotifyWhenDone(
92 window, key, control, shift, alt, command, base::Closure());
93 }
94 virtual bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window,
95 ui::KeyboardCode key,
96 bool control,
97 bool shift,
98 bool alt,
99 bool command,
100 const base::Closure& closure) {
101 DCHECK(!command); // No command key on Aura
102 XEvent xevent = {0};
103 xevent.xkey.type = KeyPress;
104 if (control)
105 SetKeycodeAndSendThenMask(&xevent, XK_Control_L, ControlMask);
106 if (shift)
107 SetKeycodeAndSendThenMask(&xevent, XK_Shift_L, ShiftMask);
108 if (alt)
109 SetKeycodeAndSendThenMask(&xevent, XK_Alt_L, Mod1Mask);
110 xevent.xkey.keycode =
111 XKeysymToKeycode(base::MessagePumpX::GetDefaultXDisplay(),
112 ui::XKeysymForWindowsKeyCode(key, shift));
113 root_window_->PostNativeEvent(&xevent);
114
115 // Send key release events.
116 xevent.xkey.type = KeyRelease;
117 root_window_->PostNativeEvent(&xevent);
118 if (alt)
119 UnmaskAndSetKeycodeThenSend(&xevent, Mod1Mask, XK_Alt_L);
120 if (shift)
121 UnmaskAndSetKeycodeThenSend(&xevent, ShiftMask, XK_Shift_L);
122 if (control)
123 UnmaskAndSetKeycodeThenSend(&xevent, ControlMask, XK_Control_L);
124 DCHECK(!xevent.xkey.state);
125 RunClosureAfterAllPendingUIEvents(closure);
126 return true;
127 }
128
129 // Simulate a mouse move. (x,y) are absolute screen coordinates.
130 virtual bool SendMouseMove(long x, long y) {
131 return SendMouseMoveNotifyWhenDone(x, y, base::Closure());
132 }
133 virtual bool SendMouseMoveNotifyWhenDone(long x,
134 long y,
135 const base::Closure& closure) {
136 XEvent xevent = {0};
137 XMotionEvent* xmotion = &xevent.xmotion;
138 xmotion->type = MotionNotify;
139 g_current_x = xmotion->x = x;
140 g_current_y = xmotion->y = y;
141 xmotion->state = button_down_mask;
142 xmotion->same_screen = True;
143 // RootWindow will take care of other necessary fields.
144 root_window_->PostNativeEvent(&xevent);
145 RunClosureAfterAllPendingUIEvents(closure);
146 return true;
147 }
148 virtual bool SendMouseEvents(ui_controls::MouseButton type, int state) {
149 return SendMouseEventsNotifyWhenDone(type, state, base::Closure());
150 }
151 virtual bool SendMouseEventsNotifyWhenDone(ui_controls::MouseButton type,
152 int state,
153 const base::Closure& closure) {
154 XEvent xevent = {0};
155 XButtonEvent* xbutton = &xevent.xbutton;
156 DCHECK_NE(g_current_x, -1000);
157 DCHECK_NE(g_current_y, -1000);
158 xbutton->x = g_current_x;
159 xbutton->y = g_current_y;
160 xbutton->same_screen = True;
161 switch (type) {
162 case ui_controls::LEFT:
163 xbutton->button = Button1;
164 xbutton->state = Button1Mask;
165 break;
166 case ui_controls::MIDDLE:
167 xbutton->button = Button2;
168 xbutton->state = Button2Mask;
169 break;
170 case ui_controls::RIGHT:
171 xbutton->button = Button3;
172 xbutton->state = Button3Mask;
173 break;
174 }
175 // RootWindow will take care of other necessary fields.
176 if (state & ui_controls::DOWN) {
177 xevent.xbutton.type = ButtonPress;
178 root_window_->PostNativeEvent(&xevent);
179 button_down_mask |= xbutton->state;
180 }
181 if (state & ui_controls::UP) {
182 xevent.xbutton.type = ButtonRelease;
183 root_window_->PostNativeEvent(&xevent);
184 button_down_mask = (button_down_mask | xbutton->state) ^ xbutton->state;
185 }
186 RunClosureAfterAllPendingUIEvents(closure);
187 return true;
188 }
189 virtual bool SendMouseClick(ui_controls::MouseButton type) {
190 return SendMouseEvents(type, ui_controls::UP | ui_controls::DOWN);
191 }
192 virtual void RunClosureAfterAllPendingUIEvents(const base::Closure& closure) {
193 if (closure.is_null())
194 return;
195 static XEvent* marker_event = NULL;
196 if (!marker_event) {
197 marker_event = new XEvent();
198 marker_event->xclient.type = ClientMessage;
199 marker_event->xclient.display = NULL;
200 marker_event->xclient.window = None;
201 marker_event->xclient.format = 8;
202 }
203 marker_event->xclient.message_type = MarkerEventAtom();
204 root_window_->PostNativeEvent(marker_event);
205 new EventWaiter(closure, &Matcher);
206 }
207 private:
208 void SetKeycodeAndSendThenMask(XEvent* xevent,
209 KeySym keysym,
210 unsigned int mask) {
211 xevent->xkey.keycode =
212 XKeysymToKeycode(base::MessagePumpX::GetDefaultXDisplay(),
213 keysym);
214 root_window_->PostNativeEvent(xevent);
215 xevent->xkey.state |= mask;
216 }
217
218 void UnmaskAndSetKeycodeThenSend(XEvent* xevent,
219 unsigned int mask,
220 KeySym keysym) {
221 xevent->xkey.state ^= mask;
222 xevent->xkey.keycode =
223 XKeysymToKeycode(base::MessagePumpX::GetDefaultXDisplay(),
224 keysym);
225 root_window_->PostNativeEvent(xevent);
226 }
227
228 RootWindow* root_window_;
229 DISALLOW_COPY_AND_ASSIGN(UIControlsX11);
230 };
231
232 } // namespace
233
234 ui_controls::UIControlsAura* CreateUIControlsAura(RootWindow* root_window) {
235 return new UIControlsX11(root_window);
236 }
237
238 } // namespace aura
OLDNEW
« no previous file with comments | « ui/aura/ui_controls_win.cc ('k') | ui/base/gtk/gtk_screen_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698