1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/uiaction_osx.cpp
3 // Purpose: wxUIActionSimulator implementation
4 // Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
7 // Copyright: (c) Kevin Ollivier
8 // (c) 2010 Steven Lamerton
9 // (c) 2010 Vadim Zeitlin
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
13 #include "wx/wxprec.h"
16 #include "wx/object.h"
19 #if wxUSE_UIACTIONSIMULATOR
21 #include "wx/uiaction.h"
25 #include "wx/osx/private.h"
26 #include "wx/osx/core/cfref.h"
28 #include "wx/evtloop.h"
33 CGEventTapLocation tap
= kCGSessionEventTap
;
35 CGEventType
CGEventTypeForMouseButton(int button
, bool isDown
)
39 case wxMOUSE_BTN_LEFT
:
40 return isDown
? kCGEventLeftMouseDown
: kCGEventLeftMouseUp
;
42 case wxMOUSE_BTN_RIGHT
:
43 return isDown
? kCGEventRightMouseDown
: kCGEventRightMouseUp
;
45 // All the other buttons use the constant OtherMouseDown but we still
46 // want to check for invalid parameters so assert first
48 wxFAIL_MSG("Unsupported button passed in.");
49 // fall back to the only known remaining case
51 case wxMOUSE_BTN_MIDDLE
:
52 return isDown
? kCGEventOtherMouseDown
: kCGEventOtherMouseUp
;
56 CGEventType
CGEventTypeForMouseDrag(int button
)
60 case wxMOUSE_BTN_LEFT
:
61 return kCGEventLeftMouseDragged
;
64 case wxMOUSE_BTN_RIGHT
:
65 return kCGEventRightMouseDragged
;
68 // All the other buttons use the constant OtherMouseDown but we still
69 // want to check for invalid parameters so assert first
71 wxFAIL_MSG("Unsupported button passed in.");
72 // fall back to the only known remaining case
74 case wxMOUSE_BTN_MIDDLE
:
75 return kCGEventOtherMouseDragged
;
81 CGMouseButton
CGButtonForMouseButton(int button
)
85 case wxMOUSE_BTN_LEFT
:
86 return kCGMouseButtonLeft
;
88 case wxMOUSE_BTN_RIGHT
:
89 return kCGMouseButtonRight
;
91 // All the other buttons use the constant OtherMouseDown but we still
92 // want to check for invalid parameters so assert first
94 wxFAIL_MSG("Unsupported button passed in.");
95 // fall back to the only known remaining case
97 case wxMOUSE_BTN_MIDDLE
:
98 return kCGMouseButtonCenter
;
102 CGPoint
GetMousePosition()
105 wxGetMousePosition(&x
, &y
);
114 } // anonymous namespace
116 bool wxUIActionSimulator::MouseDown(int button
)
118 CGEventType type
= CGEventTypeForMouseButton(button
, true);
119 wxCFRef
<CGEventRef
> event(
120 CGEventCreateMouseEvent(NULL
, type
, GetMousePosition(), CGButtonForMouseButton(button
)));
125 CGEventSetType(event
, type
);
126 CGEventPost(tap
, event
);
127 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
129 loop
->SetShouldWaitForEvent(true);
134 bool wxUIActionSimulator::MouseMove(long x
, long y
)
140 CGEventType type
= kCGEventMouseMoved
;
141 wxCFRef
<CGEventRef
> event(
142 CGEventCreateMouseEvent(NULL
, type
, pos
, kCGMouseButtonLeft
));
147 CGEventSetType(event
, type
);
148 CGEventPost(tap
, event
);
150 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
152 loop
->SetShouldWaitForEvent(true);
157 bool wxUIActionSimulator::MouseUp(int button
)
159 CGEventType type
= CGEventTypeForMouseButton(button
, false);
160 wxCFRef
<CGEventRef
> event(
161 CGEventCreateMouseEvent(NULL
, type
, GetMousePosition(), CGButtonForMouseButton(button
)));
166 CGEventSetType(event
, type
);
167 CGEventPost(tap
, event
);
168 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
170 loop
->SetShouldWaitForEvent(true);
175 bool wxUIActionSimulator::MouseDblClick(int button
)
177 CGEventType downtype
= CGEventTypeForMouseButton(button
, true);
178 CGEventType uptype
= CGEventTypeForMouseButton(button
, false);
179 wxCFRef
<CGEventRef
> event(
180 CGEventCreateMouseEvent(NULL
, downtype
, GetMousePosition(), CGButtonForMouseButton(button
)));
185 CGEventSetType(event
,downtype
);
186 CGEventPost(tap
, event
);
188 CGEventSetType(event
, uptype
);
189 CGEventPost(tap
, event
);
191 CGEventSetIntegerValueField(event
, kCGMouseEventClickState
, 2);
192 CGEventSetType(event
, downtype
);
193 CGEventPost(tap
, event
);
195 CGEventSetType(event
, uptype
);
196 CGEventPost(tap
, event
);
197 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
199 loop
->SetShouldWaitForEvent(true);
204 bool wxUIActionSimulator::MouseDragDrop(long x1
, long y1
, long x2
, long y2
,
213 CGEventType downtype
= CGEventTypeForMouseButton(button
, true);
214 CGEventType uptype
= CGEventTypeForMouseButton(button
, false);
215 CGEventType dragtype
= CGEventTypeForMouseDrag(button
) ;
217 wxCFRef
<CGEventRef
> event(
218 CGEventCreateMouseEvent(NULL
, kCGEventMouseMoved
, pos1
, CGButtonForMouseButton(button
)));
223 CGEventSetType(event
,kCGEventMouseMoved
);
224 CGEventPost(tap
, event
);
226 CGEventSetType(event
,downtype
);
227 CGEventPost(tap
, event
);
230 CGEventSetType(event
, dragtype
);
231 CGEventSetLocation(event
,pos2
);
232 CGEventPost(tap
, event
);
234 CGEventSetType(event
, uptype
);
235 CGEventPost(tap
, event
);
236 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
238 loop
->SetShouldWaitForEvent(true);
244 wxUIActionSimulator::DoKey(int keycode
, int WXUNUSED(modifiers
), bool isDown
)
246 CGKeyCode cgcode
= wxCharCodeWXToOSX((wxKeyCode
)keycode
);
249 event(CGEventCreateKeyboardEvent(NULL
, cgcode
, isDown
));
253 CGEventPost(kCGHIDEventTap
, event
);
254 wxCFEventLoop
* loop
= dynamic_cast<wxCFEventLoop
*>(wxEventLoop::GetActive());
256 loop
->SetShouldWaitForEvent(true);
261 #endif // wxUSE_UIACTIONSIMULATOR