notify the event loop that synthesized events are on the queue, wait for them to...
[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 CGPoint GetMousePosition()
58 {
59 int x, y;
60 wxGetMousePosition(&x, &y);
61
62 CGPoint pos;
63 pos.x = x;
64 pos.y = y;
65
66 return pos;
67 }
68
69 } // anonymous namespace
70
71 bool wxUIActionSimulator::MouseDown(int button)
72 {
73 CGEventType type = CGEventTypeForMouseButton(button, true);
74 wxCFRef<CGEventRef> event(
75 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), button));
76
77 if ( !event )
78 return false;
79
80 CGEventSetType(event, type);
81 CGEventPost(tap, event);
82 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
83 if (loop)
84 loop->SetShouldWaitForEvent(true);
85
86 return true;
87 }
88
89 bool wxUIActionSimulator::MouseDblClick(int button)
90 {
91 CGEventType downtype = CGEventTypeForMouseButton(button, true);
92 CGEventType uptype = CGEventTypeForMouseButton(button, false);
93 wxCFRef<CGEventRef> event(
94 CGEventCreateMouseEvent(NULL, downtype, GetMousePosition(), button));
95
96 if ( !event )
97 return false;
98
99 CGEventSetType(event,downtype);
100 CGEventPost(tap, event);
101
102 CGEventSetType(event, uptype);
103 CGEventPost(tap, event);
104
105 CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);
106 CGEventSetType(event, downtype);
107 CGEventPost(tap, event);
108
109 CGEventSetType(event, uptype);
110 CGEventPost(tap, event);
111 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
112 if (loop)
113 loop->SetShouldWaitForEvent(true);
114
115 return true;
116 }
117
118 bool wxUIActionSimulator::MouseMove(long x, long y)
119 {
120 CGPoint pos;
121 pos.x = x;
122 pos.y = y;
123
124 CGEventType type = kCGEventMouseMoved;
125 wxCFRef<CGEventRef> event(
126 CGEventCreateMouseEvent(NULL, type, pos, kCGMouseButtonLeft));
127
128 if ( !event )
129 return false;
130
131 CGEventSetType(event, type);
132 CGEventPost(tap, event);
133 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
134 if (loop)
135 loop->SetShouldWaitForEvent(true);
136
137 return true;
138 }
139
140 bool wxUIActionSimulator::MouseUp(int button)
141 {
142 CGEventType type = CGEventTypeForMouseButton(button, false);
143 wxCFRef<CGEventRef> event(
144 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), button));
145
146 if ( !event )
147 return false;
148
149 CGEventSetType(event, type);
150 CGEventPost(tap, event);
151 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
152 if (loop)
153 loop->SetShouldWaitForEvent(true);
154
155 return true;
156 }
157
158 bool
159 wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
160 {
161 CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode);
162
163 wxCFRef<CGEventRef>
164 event(CGEventCreateKeyboardEvent(NULL, cgcode, isDown));
165 if ( !event )
166 return false;
167
168 CGEventPost(kCGHIDEventTap, event);
169 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
170 if (loop)
171 loop->SetShouldWaitForEvent(true);
172
173 return true;
174 }
175
176 #endif // wxUSE_UIACTIONSIMULATOR
177