Make wxEventLoop::AddSourceForFD() static.
[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$
8 // Copyright: (c) Kevin Ollivier
9 // (c) 2010 Steven Lamerton
10 // (c) 2010 Vadim Zeitlin
11 // Licence: wxWindows licence
12 /////////////////////////////////////////////////////////////////////////////
13
14 #include "wx/wxprec.h"
15
16 #ifndef WX_PRECOMP
17 #include "wx/object.h"
18 #endif
19
20 #if wxUSE_UIACTIONSIMULATOR
21
22 #include "wx/uiaction.h"
23
24 #include "wx/log.h"
25
26 #include "wx/osx/private.h"
27 #include "wx/osx/core/cfref.h"
28
29 #include "wx/evtloop.h"
30
31 namespace
32 {
33
34 CGEventTapLocation tap = kCGSessionEventTap;
35
36 CGEventType CGEventTypeForMouseButton(int button, bool isDown)
37 {
38 switch ( button )
39 {
40 case wxMOUSE_BTN_LEFT:
41 return isDown ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
42
43 case wxMOUSE_BTN_RIGHT:
44 return isDown ? kCGEventRightMouseDown : kCGEventRightMouseUp;
45
46 // All the other buttons use the constant OtherMouseDown but we still
47 // want to check for invalid parameters so assert first
48 default:
49 wxFAIL_MSG("Unsupported button passed in.");
50 // fall back to the only known remaining case
51
52 case wxMOUSE_BTN_MIDDLE:
53 return isDown ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
54 }
55 }
56
57 CGEventType CGEventTypeForMouseDrag(int button)
58 {
59 switch ( button )
60 {
61 case wxMOUSE_BTN_LEFT:
62 return kCGEventLeftMouseDragged;
63 break;
64
65 case wxMOUSE_BTN_RIGHT:
66 return kCGEventRightMouseDragged;
67 break;
68
69 // All the other buttons use the constant OtherMouseDown but we still
70 // want to check for invalid parameters so assert first
71 default:
72 wxFAIL_MSG("Unsupported button passed in.");
73 // fall back to the only known remaining case
74
75 case wxMOUSE_BTN_MIDDLE:
76 return kCGEventOtherMouseDragged;
77 break;
78 }
79
80 }
81
82 CGMouseButton CGButtonForMouseButton(int button)
83 {
84 switch ( button )
85 {
86 case wxMOUSE_BTN_LEFT:
87 return kCGMouseButtonLeft;
88
89 case wxMOUSE_BTN_RIGHT:
90 return kCGMouseButtonRight;
91
92 // All the other buttons use the constant OtherMouseDown but we still
93 // want to check for invalid parameters so assert first
94 default:
95 wxFAIL_MSG("Unsupported button passed in.");
96 // fall back to the only known remaining case
97
98 case wxMOUSE_BTN_MIDDLE:
99 return kCGMouseButtonCenter;
100 }
101 }
102
103 CGPoint GetMousePosition()
104 {
105 int x, y;
106 wxGetMousePosition(&x, &y);
107
108 CGPoint pos;
109 pos.x = x;
110 pos.y = y;
111
112 return pos;
113 }
114
115 } // anonymous namespace
116
117 bool wxUIActionSimulator::MouseDown(int button)
118 {
119 CGEventType type = CGEventTypeForMouseButton(button, true);
120 wxCFRef<CGEventRef> event(
121 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), CGButtonForMouseButton(button)));
122
123 if ( !event )
124 return false;
125
126 CGEventSetType(event, type);
127 CGEventPost(tap, event);
128 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
129 if (loop)
130 loop->SetShouldWaitForEvent(true);
131
132 return true;
133 }
134
135 bool wxUIActionSimulator::MouseMove(long x, long y)
136 {
137 CGPoint pos;
138 pos.x = x;
139 pos.y = y;
140
141 CGEventType type = kCGEventMouseMoved;
142 wxCFRef<CGEventRef> event(
143 CGEventCreateMouseEvent(NULL, type, pos, kCGMouseButtonLeft));
144
145 if ( !event )
146 return false;
147
148 CGEventSetType(event, type);
149 CGEventPost(tap, event);
150
151 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
152 if (loop)
153 loop->SetShouldWaitForEvent(true);
154
155 return true;
156 }
157
158 bool wxUIActionSimulator::MouseUp(int button)
159 {
160 CGEventType type = CGEventTypeForMouseButton(button, false);
161 wxCFRef<CGEventRef> event(
162 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), CGButtonForMouseButton(button)));
163
164 if ( !event )
165 return false;
166
167 CGEventSetType(event, type);
168 CGEventPost(tap, event);
169 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
170 if (loop)
171 loop->SetShouldWaitForEvent(true);
172
173 return true;
174 }
175
176 bool wxUIActionSimulator::MouseDblClick(int button)
177 {
178 CGEventType downtype = CGEventTypeForMouseButton(button, true);
179 CGEventType uptype = CGEventTypeForMouseButton(button, false);
180 wxCFRef<CGEventRef> event(
181 CGEventCreateMouseEvent(NULL, downtype, GetMousePosition(), CGButtonForMouseButton(button)));
182
183 if ( !event )
184 return false;
185
186 CGEventSetType(event,downtype);
187 CGEventPost(tap, event);
188
189 CGEventSetType(event, uptype);
190 CGEventPost(tap, event);
191
192 CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);
193 CGEventSetType(event, downtype);
194 CGEventPost(tap, event);
195
196 CGEventSetType(event, uptype);
197 CGEventPost(tap, event);
198 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
199 if (loop)
200 loop->SetShouldWaitForEvent(true);
201
202 return true;
203 }
204
205 bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2,
206 int button)
207 {
208 CGPoint pos1,pos2;
209 pos1.x = x1;
210 pos1.y = y1;
211 pos2.x = x2;
212 pos2.y = y2;
213
214 CGEventType downtype = CGEventTypeForMouseButton(button, true);
215 CGEventType uptype = CGEventTypeForMouseButton(button, false);
216 CGEventType dragtype = CGEventTypeForMouseDrag(button) ;
217
218 wxCFRef<CGEventRef> event(
219 CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, pos1, CGButtonForMouseButton(button)));
220
221 if ( !event )
222 return false;
223
224 CGEventSetType(event,kCGEventMouseMoved);
225 CGEventPost(tap, event);
226
227 CGEventSetType(event,downtype);
228 CGEventPost(tap, event);
229
230
231 CGEventSetType(event, dragtype);
232 CGEventSetLocation(event,pos2);
233 CGEventPost(tap, event);
234
235 CGEventSetType(event, uptype);
236 CGEventPost(tap, event);
237 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
238 if (loop)
239 loop->SetShouldWaitForEvent(true);
240
241 return true;
242 }
243
244 bool
245 wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
246 {
247 CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode);
248
249 wxCFRef<CGEventRef>
250 event(CGEventCreateKeyboardEvent(NULL, cgcode, isDown));
251 if ( !event )
252 return false;
253
254 CGEventPost(kCGHIDEventTap, event);
255 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
256 if (loop)
257 loop->SetShouldWaitForEvent(true);
258
259 return true;
260 }
261
262 #endif // wxUSE_UIACTIONSIMULATOR
263