]>
Commit | Line | Data |
---|---|---|
a02a5cfc KO |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: src/osx/uiaction_osx.cpp | |
3 | // Purpose: wxUIActionSimulator implementation | |
571d991b | 4 | // Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin |
a02a5cfc KO |
5 | // Modified by: |
6 | // Created: 2010-03-06 | |
7 | // RCS-ID: $Id: menu.cpp 54129 2008-06-11 19:30:52Z SC $ | |
8 | // Copyright: (c) Kevin Ollivier | |
571d991b VZ |
9 | // (c) 2010 Steven Lamerton |
10 | // (c) 2010 Vadim Zeitlin | |
a02a5cfc KO |
11 | // Licence: wxWindows licence |
12 | ///////////////////////////////////////////////////////////////////////////// | |
13 | ||
9b7e0226 VZ |
14 | #include "wx/defs.h" |
15 | ||
16 | #if wxUSE_UIACTIONSIMULATOR | |
17 | ||
18 | #include "wx/uiaction.h" | |
a02a5cfc | 19 | |
571d991b VZ |
20 | #include "wx/log.h" |
21 | ||
22 | #include "wx/osx/private.h" | |
23 | #include "wx/osx/core/cfref.h" | |
24 | ||
25 | namespace | |
26 | { | |
a02a5cfc KO |
27 | |
28 | CGEventTapLocation tap = kCGSessionEventTap; | |
29 | ||
30 | CGEventType CGEventTypeForMouseButton(int button, bool isDown) | |
31 | { | |
571d991b | 32 | switch ( button ) |
a02a5cfc KO |
33 | { |
34 | case wxMOUSE_BTN_LEFT: | |
571d991b | 35 | return isDown ? kCGEventLeftMouseDown : kCGEventLeftMouseUp; |
9b7e0226 | 36 | |
571d991b VZ |
37 | case wxMOUSE_BTN_RIGHT: |
38 | return isDown ? kCGEventRightMouseDown : kCGEventRightMouseUp; | |
9b7e0226 | 39 | |
571d991b VZ |
40 | // All the other buttons use the constant OtherMouseDown but we still |
41 | // want to check for invalid parameters so assert first | |
a02a5cfc | 42 | default: |
571d991b VZ |
43 | wxFAIL_MSG("Unsupported button passed in."); |
44 | // fall back to the only known remaining case | |
45 | ||
46 | case wxMOUSE_BTN_MIDDLE: | |
47 | return isDown ? kCGEventOtherMouseDown : kCGEventOtherMouseUp; | |
a02a5cfc KO |
48 | } |
49 | } | |
50 | ||
571d991b | 51 | CGPoint GetMousePosition() |
a02a5cfc | 52 | { |
571d991b VZ |
53 | int x, y; |
54 | wxGetMousePosition(&x, &y); | |
55 | ||
56 | CGPoint pos; | |
57 | pos.x = x; | |
58 | pos.y = y; | |
59 | ||
60 | return pos; | |
61 | } | |
62 | ||
63 | bool SendCharCode(CGKeyCode keycode, bool isDown) | |
64 | { | |
65 | wxCFRef<CGEventRef> | |
66 | event(CGEventCreateKeyboardEvent(NULL, keycode, isDown)); | |
67 | if ( !event ) | |
68 | return false; | |
69 | ||
70 | CGEventPost(kCGHIDEventTap, event); | |
71 | return true; | |
72 | } | |
73 | ||
74 | CGKeyCode wxCharCodeWXToOSX(wxKeyCode code) | |
75 | { | |
76 | CGKeyCode keycode; | |
77 | ||
78 | switch (code) | |
a02a5cfc | 79 | { |
571d991b VZ |
80 | case 'a': case 'A': keycode = kVK_ANSI_A; break; |
81 | case 'b': case 'B': keycode = kVK_ANSI_B; break; | |
82 | case 'c': case 'C': keycode = kVK_ANSI_C; break; | |
83 | case 'd': case 'D': keycode = kVK_ANSI_D; break; | |
84 | case 'e': case 'E': keycode = kVK_ANSI_E; break; | |
85 | case 'f': case 'F': keycode = kVK_ANSI_F; break; | |
86 | case 'g': case 'G': keycode = kVK_ANSI_G; break; | |
87 | case 'h': case 'H': keycode = kVK_ANSI_H; break; | |
88 | case 'i': case 'I': keycode = kVK_ANSI_I; break; | |
89 | case 'j': case 'J': keycode = kVK_ANSI_J; break; | |
90 | case 'k': case 'K': keycode = kVK_ANSI_K; break; | |
91 | case 'l': case 'L': keycode = kVK_ANSI_L; break; | |
92 | case 'm': case 'M': keycode = kVK_ANSI_M; break; | |
93 | case 'n': case 'N': keycode = kVK_ANSI_N; break; | |
94 | case 'o': case 'O': keycode = kVK_ANSI_O; break; | |
95 | case 'p': case 'P': keycode = kVK_ANSI_P; break; | |
96 | case 'q': case 'Q': keycode = kVK_ANSI_Q; break; | |
97 | case 'r': case 'R': keycode = kVK_ANSI_R; break; | |
98 | case 's': case 'S': keycode = kVK_ANSI_S; break; | |
99 | case 't': case 'T': keycode = kVK_ANSI_T; break; | |
100 | case 'u': case 'U': keycode = kVK_ANSI_U; break; | |
101 | case 'v': case 'V': keycode = kVK_ANSI_V; break; | |
102 | case 'w': case 'W': keycode = kVK_ANSI_W; break; | |
103 | case 'x': case 'X': keycode = kVK_ANSI_X; break; | |
104 | case 'y': case 'Y': keycode = kVK_ANSI_Y; break; | |
105 | case 'z': case 'Z': keycode = kVK_ANSI_Z; break; | |
106 | ||
107 | case '0': keycode = kVK_ANSI_0; break; | |
108 | case '1': keycode = kVK_ANSI_1; break; | |
109 | case '2': keycode = kVK_ANSI_2; break; | |
110 | case '3': keycode = kVK_ANSI_3; break; | |
111 | case '4': keycode = kVK_ANSI_4; break; | |
112 | case '5': keycode = kVK_ANSI_5; break; | |
113 | case '6': keycode = kVK_ANSI_6; break; | |
114 | case '7': keycode = kVK_ANSI_7; break; | |
115 | case '8': keycode = kVK_ANSI_8; break; | |
116 | case '9': keycode = kVK_ANSI_9; break; | |
117 | ||
118 | case WXK_BACK: keycode = kVK_Delete; break; | |
119 | case WXK_TAB: keycode = kVK_Tab; break; | |
120 | case WXK_RETURN: keycode = kVK_Return; break; | |
121 | case WXK_ESCAPE: keycode = kVK_Escape; break; | |
122 | case WXK_SPACE: keycode = kVK_Space; break; | |
123 | case WXK_DELETE: keycode = kVK_Delete; break; | |
124 | ||
125 | case WXK_SHIFT: keycode = kVK_Shift; break; | |
126 | case WXK_ALT: keycode = kVK_Option; break; | |
127 | case WXK_CONTROL: keycode = kVK_Control; break; | |
128 | case WXK_COMMAND: keycode = kVK_Command; break; | |
129 | ||
130 | case WXK_CAPITAL: keycode = kVK_CapsLock; break; | |
131 | case WXK_END: keycode = kVK_End; break; | |
132 | case WXK_HOME: keycode = kVK_Home; break; | |
133 | case WXK_LEFT: keycode = kVK_LeftArrow; break; | |
134 | case WXK_UP: keycode = kVK_UpArrow; break; | |
135 | case WXK_RIGHT: keycode = kVK_RightArrow; break; | |
136 | case WXK_DOWN: keycode = kVK_DownArrow; break; | |
137 | ||
138 | case WXK_HELP: keycode = kVK_Help; break; | |
139 | ||
140 | ||
141 | case WXK_NUMPAD0: keycode = kVK_ANSI_Keypad0; break; | |
142 | case WXK_NUMPAD1: keycode = kVK_ANSI_Keypad1; break; | |
143 | case WXK_NUMPAD2: keycode = kVK_ANSI_Keypad2; break; | |
144 | case WXK_NUMPAD3: keycode = kVK_ANSI_Keypad3; break; | |
145 | case WXK_NUMPAD4: keycode = kVK_ANSI_Keypad4; break; | |
146 | case WXK_NUMPAD5: keycode = kVK_ANSI_Keypad5; break; | |
147 | case WXK_NUMPAD6: keycode = kVK_ANSI_Keypad6; break; | |
148 | case WXK_NUMPAD7: keycode = kVK_ANSI_Keypad7; break; | |
149 | case WXK_NUMPAD8: keycode = kVK_ANSI_Keypad8; break; | |
150 | case WXK_NUMPAD9: keycode = kVK_ANSI_Keypad9; break; | |
151 | case WXK_F1: keycode = kVK_F1; break; | |
152 | case WXK_F2: keycode = kVK_F2; break; | |
153 | case WXK_F3: keycode = kVK_F3; break; | |
154 | case WXK_F4: keycode = kVK_F4; break; | |
155 | case WXK_F5: keycode = kVK_F5; break; | |
156 | case WXK_F6: keycode = kVK_F6; break; | |
157 | case WXK_F7: keycode = kVK_F7; break; | |
158 | case WXK_F8: keycode = kVK_F8; break; | |
159 | case WXK_F9: keycode = kVK_F9; break; | |
160 | case WXK_F10: keycode = kVK_F10; break; | |
161 | case WXK_F11: keycode = kVK_F11; break; | |
162 | case WXK_F12: keycode = kVK_F12; break; | |
163 | case WXK_F13: keycode = kVK_F13; break; | |
164 | case WXK_F14: keycode = kVK_F14; break; | |
165 | case WXK_F15: keycode = kVK_F15; break; | |
166 | case WXK_F16: keycode = kVK_F16; break; | |
167 | case WXK_F17: keycode = kVK_F17; break; | |
168 | case WXK_F18: keycode = kVK_F18; break; | |
169 | case WXK_F19: keycode = kVK_F19; break; | |
170 | case WXK_F20: keycode = kVK_F20; break; | |
171 | ||
172 | case WXK_PAGEUP: keycode = kVK_PageUp; break; | |
173 | case WXK_PAGEDOWN: keycode = kVK_PageDown; break; | |
174 | ||
175 | case WXK_NUMPAD_DELETE: keycode = kVK_ANSI_KeypadClear; break; | |
176 | case WXK_NUMPAD_EQUAL: keycode = kVK_ANSI_KeypadEquals; break; | |
177 | case WXK_NUMPAD_MULTIPLY: keycode = kVK_ANSI_KeypadMultiply; break; | |
178 | case WXK_NUMPAD_ADD: keycode = kVK_ANSI_KeypadPlus; break; | |
179 | case WXK_NUMPAD_SUBTRACT: keycode = kVK_ANSI_KeypadMinus; break; | |
180 | case WXK_NUMPAD_DECIMAL: keycode = kVK_ANSI_KeypadDecimal; break; | |
181 | case WXK_NUMPAD_DIVIDE: keycode = kVK_ANSI_KeypadDivide; break; | |
182 | ||
453296e7 VZ |
183 | default: |
184 | wxLogDebug( "Unrecognised keycode %d", code ); | |
185 | keycode = -1; | |
a02a5cfc | 186 | } |
571d991b VZ |
187 | |
188 | return keycode; | |
a02a5cfc KO |
189 | } |
190 | ||
571d991b VZ |
191 | } // anonymous namespace |
192 | ||
a02a5cfc KO |
193 | bool wxUIActionSimulator::MouseDown(int button) |
194 | { | |
a02a5cfc | 195 | CGEventType type = CGEventTypeForMouseButton(button, true); |
571d991b VZ |
196 | wxCFRef<CGEventRef> event( |
197 | CGEventCreateMouseEvent(NULL, type, GetMousePosition(), button)); | |
198 | ||
199 | if ( !event ) | |
200 | return false; | |
201 | ||
a02a5cfc | 202 | CGEventSetType(event, type); |
571d991b | 203 | CGEventPost(tap, event); |
9b7e0226 | 204 | |
a02a5cfc KO |
205 | return true; |
206 | } | |
207 | ||
208 | bool wxUIActionSimulator::MouseMove(long x, long y) | |
209 | { | |
210 | CGPoint pos; | |
211 | pos.x = x; | |
212 | pos.y = y; | |
571d991b | 213 | |
a02a5cfc | 214 | CGEventType type = kCGEventMouseMoved; |
571d991b VZ |
215 | wxCFRef<CGEventRef> event( |
216 | CGEventCreateMouseEvent(NULL, type, pos, kCGMouseButtonLeft)); | |
9b7e0226 | 217 | |
571d991b VZ |
218 | if ( !event ) |
219 | return false; | |
220 | ||
221 | CGEventSetType(event, type); | |
222 | CGEventPost(tap, event); | |
9b7e0226 | 223 | |
a02a5cfc KO |
224 | return true; |
225 | } | |
226 | ||
227 | bool wxUIActionSimulator::MouseUp(int button) | |
228 | { | |
a02a5cfc | 229 | CGEventType type = CGEventTypeForMouseButton(button, false); |
571d991b VZ |
230 | wxCFRef<CGEventRef> event( |
231 | CGEventCreateMouseEvent(NULL, type, GetMousePosition(), button)); | |
9b7e0226 | 232 | |
571d991b VZ |
233 | if ( !event ) |
234 | return false; | |
235 | ||
236 | CGEventSetType(event, type); | |
237 | CGEventPost(tap, event); | |
a02a5cfc KO |
238 | |
239 | return true; | |
240 | } | |
241 | ||
571d991b | 242 | bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown) |
a02a5cfc | 243 | { |
571d991b VZ |
244 | if (isDown) |
245 | { | |
246 | if (modifiers & wxMOD_SHIFT) | |
247 | SendCharCode(kVK_Shift, true); | |
248 | if (modifiers & wxMOD_ALT) | |
249 | SendCharCode(kVK_Option, true); | |
250 | if (modifiers & wxMOD_CMD) | |
251 | SendCharCode(kVK_Command, true); | |
252 | } | |
253 | ||
254 | CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode); | |
255 | if ( !SendCharCode(cgcode, isDown) ) | |
256 | return false; | |
257 | ||
258 | if(!isDown) | |
259 | { | |
260 | if (modifiers & wxMOD_SHIFT) | |
261 | SendCharCode(kVK_Shift, false); | |
262 | if (modifiers & wxMOD_ALT) | |
263 | SendCharCode(kVK_Option, false); | |
264 | if (modifiers & wxMOD_CMD) | |
265 | SendCharCode(kVK_Command, false); | |
266 | } | |
9b7e0226 | 267 | |
a02a5cfc KO |
268 | return true; |
269 | } | |
270 | ||
9b7e0226 | 271 | #endif // wxUSE_UIACTIONSIMULATOR |
a02a5cfc | 272 |