1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/uiaction_osx.cpp
3 // Purpose: wxUIActionSimulator implementation
4 // Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
8 // Copyright: (c) Kevin Ollivier
9 // (c) 2010 Steven Lamerton
10 // (c) 2010 Vadim Zeitlin
11 // Licence: wxWindows licence
12 /////////////////////////////////////////////////////////////////////////////
14 #include "wx/wxprec.h"
17 #include "wx/object.h"
20 #if wxUSE_UIACTIONSIMULATOR
22 #include "wx/uiaction.h"
26 #include "wx/osx/private.h"
27 #include "wx/osx/core/cfref.h"
29 #include "wx/evtloop.h"
34 CGEventTapLocation tap
= kCGSessionEventTap
;
36 CGEventType
CGEventTypeForMouseButton(int button
, bool isDown
)
40 case wxMOUSE_BTN_LEFT
:
41 return isDown
? kCGEventLeftMouseDown
: kCGEventLeftMouseUp
;
43 case wxMOUSE_BTN_RIGHT
:
44 return isDown
? kCGEventRightMouseDown
: kCGEventRightMouseUp
;
46 // All the other buttons use the constant OtherMouseDown but we still
47 // want to check for invalid parameters so assert first
49 wxFAIL_MSG("Unsupported button passed in.");
50 // fall back to the only known remaining case
52 case wxMOUSE_BTN_MIDDLE
:
53 return isDown
? kCGEventOtherMouseDown
: kCGEventOtherMouseUp
;
57 CGEventType
CGEventTypeForMouseDrag(int button
)
61 case wxMOUSE_BTN_LEFT
:
62 return kCGEventLeftMouseDragged
;
65 case wxMOUSE_BTN_RIGHT
:
66 return kCGEventRightMouseDragged
;
69 // All the other buttons use the constant OtherMouseDown but we still
70 // want to check for invalid parameters so assert first
72 wxFAIL_MSG("Unsupported button passed in.");
73 // fall back to the only known remaining case
75 case wxMOUSE_BTN_MIDDLE
:
76 return kCGEventOtherMouseDragged
;
82 CGMouseButton
CGButtonForMouseButton(int button
)
86 case wxMOUSE_BTN_LEFT
:
87 return kCGMouseButtonLeft
;
89 case wxMOUSE_BTN_RIGHT
:
90 return kCGMouseButtonRight
;
92 // All the other buttons use the constant OtherMouseDown but we still
93 // want to check for invalid parameters so assert first
95 wxFAIL_MSG("Unsupported button passed in.");
96 // fall back to the only known remaining case
98 case wxMOUSE_BTN_MIDDLE
:
99 return kCGMouseButtonCenter
;
103 CGPoint
GetMousePosition()
106 wxGetMousePosition(&x
, &y
);
115 } // anonymous namespace
117 bool wxUIActionSimulator::MouseDown(int button
)
119 CGEventType type
= CGEventTypeForMouseButton(button
, true);
120 wxCFRef
<CGEventRef
> event(
121 CGEventCreateMouseEvent(NULL
, type
, GetMousePosition(), CGButtonForMouseButton(button
)));
126 CGEventSetType(event
, type
);
127 CGEventPost(tap
, event
);
128 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
130 loop
->SetShouldWaitForEvent(true);
135 bool wxUIActionSimulator::MouseMove(long x
, long y
)
141 CGEventType type
= kCGEventMouseMoved
;
142 wxCFRef
<CGEventRef
> event(
143 CGEventCreateMouseEvent(NULL
, type
, pos
, kCGMouseButtonLeft
));
148 CGEventSetType(event
, type
);
149 CGEventPost(tap
, event
);
151 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
153 loop
->SetShouldWaitForEvent(true);
158 bool wxUIActionSimulator::MouseUp(int button
)
160 CGEventType type
= CGEventTypeForMouseButton(button
, false);
161 wxCFRef
<CGEventRef
> event(
162 CGEventCreateMouseEvent(NULL
, type
, GetMousePosition(), CGButtonForMouseButton(button
)));
167 CGEventSetType(event
, type
);
168 CGEventPost(tap
, event
);
169 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
171 loop
->SetShouldWaitForEvent(true);
176 bool wxUIActionSimulator::MouseDblClick(int button
)
178 CGEventType downtype
= CGEventTypeForMouseButton(button
, true);
179 CGEventType uptype
= CGEventTypeForMouseButton(button
, false);
180 wxCFRef
<CGEventRef
> event(
181 CGEventCreateMouseEvent(NULL
, downtype
, GetMousePosition(), CGButtonForMouseButton(button
)));
186 CGEventSetType(event
,downtype
);
187 CGEventPost(tap
, event
);
189 CGEventSetType(event
, uptype
);
190 CGEventPost(tap
, event
);
192 CGEventSetIntegerValueField(event
, kCGMouseEventClickState
, 2);
193 CGEventSetType(event
, downtype
);
194 CGEventPost(tap
, event
);
196 CGEventSetType(event
, uptype
);
197 CGEventPost(tap
, event
);
198 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
200 loop
->SetShouldWaitForEvent(true);
205 bool wxUIActionSimulator::MouseDragDrop(long x1
, long y1
, long x2
, long y2
,
214 CGEventType downtype
= CGEventTypeForMouseButton(button
, true);
215 CGEventType uptype
= CGEventTypeForMouseButton(button
, false);
216 CGEventType dragtype
= CGEventTypeForMouseDrag(button
) ;
218 wxCFRef
<CGEventRef
> event(
219 CGEventCreateMouseEvent(NULL
, kCGEventMouseMoved
, pos1
, CGButtonForMouseButton(button
)));
224 CGEventSetType(event
,kCGEventMouseMoved
);
225 CGEventPost(tap
, event
);
227 CGEventSetType(event
,downtype
);
228 CGEventPost(tap
, event
);
231 CGEventSetType(event
, dragtype
);
232 CGEventSetLocation(event
,pos2
);
233 CGEventPost(tap
, event
);
235 CGEventSetType(event
, uptype
);
236 CGEventPost(tap
, event
);
237 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
239 loop
->SetShouldWaitForEvent(true);
245 wxUIActionSimulator::DoKey(int keycode
, int WXUNUSED(modifiers
), bool isDown
)
247 CGKeyCode cgcode
= wxCharCodeWXToOSX((wxKeyCode
)keycode
);
250 event(CGEventCreateKeyboardEvent(NULL
, cgcode
, isDown
));
254 CGEventPost(kCGHIDEventTap
, event
);
255 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
257 loop
->SetShouldWaitForEvent(true);
262 #endif // wxUSE_UIACTIONSIMULATOR