Don't use uninitialized variable in wxCharCodeWXToOSX().
[wxWidgets.git] / src / osx / uiaction_osx.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/uiaction_osx.cpp
3 // Purpose: wxUIActionSimulator implementation
4 // Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
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
9 // (c) 2010 Steven Lamerton
10 // (c) 2010 Vadim Zeitlin
11 // Licence: wxWindows licence
12 /////////////////////////////////////////////////////////////////////////////
13
14 #include "wx/defs.h"
15
16 #if wxUSE_UIACTIONSIMULATOR
17
18 #include "wx/uiaction.h"
19
20 #include "wx/log.h"
21
22 #include "wx/osx/private.h"
23 #include "wx/osx/core/cfref.h"
24
25 namespace
26 {
27
28 CGEventTapLocation tap = kCGSessionEventTap;
29
30 CGEventType CGEventTypeForMouseButton(int button, bool isDown)
31 {
32 switch ( button )
33 {
34 case wxMOUSE_BTN_LEFT:
35 return isDown ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
36
37 case wxMOUSE_BTN_RIGHT:
38 return isDown ? kCGEventRightMouseDown : kCGEventRightMouseUp;
39
40 // All the other buttons use the constant OtherMouseDown but we still
41 // want to check for invalid parameters so assert first
42 default:
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;
48 }
49 }
50
51 CGPoint GetMousePosition()
52 {
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)
79 {
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
183 default:
184 wxLogDebug( "Unrecognised keycode %d", code );
185 keycode = -1;
186 }
187
188 return keycode;
189 }
190
191 } // anonymous namespace
192
193 bool wxUIActionSimulator::MouseDown(int button)
194 {
195 CGEventType type = CGEventTypeForMouseButton(button, true);
196 wxCFRef<CGEventRef> event(
197 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), button));
198
199 if ( !event )
200 return false;
201
202 CGEventSetType(event, type);
203 CGEventPost(tap, event);
204
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;
213
214 CGEventType type = kCGEventMouseMoved;
215 wxCFRef<CGEventRef> event(
216 CGEventCreateMouseEvent(NULL, type, pos, kCGMouseButtonLeft));
217
218 if ( !event )
219 return false;
220
221 CGEventSetType(event, type);
222 CGEventPost(tap, event);
223
224 return true;
225 }
226
227 bool wxUIActionSimulator::MouseUp(int button)
228 {
229 CGEventType type = CGEventTypeForMouseButton(button, false);
230 wxCFRef<CGEventRef> event(
231 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), button));
232
233 if ( !event )
234 return false;
235
236 CGEventSetType(event, type);
237 CGEventPost(tap, event);
238
239 return true;
240 }
241
242 bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown)
243 {
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 }
267
268 return true;
269 }
270
271 #endif // wxUSE_UIACTIONSIMULATOR
272