1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/uiactionx11.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 /////////////////////////////////////////////////////////////////////////////
15 #if wxUSE_UIACTIONSIMULATOR
17 #include "wx/uiaction.h"
19 #include "wx/evtloop.h"
22 #include <X11/Xutil.h>
24 #include "wx/unix/utilsx11.h"
29 void SendButtonEvent(int button
, bool isDown
)
34 case wxMOUSE_BTN_LEFT
:
37 case wxMOUSE_BTN_MIDDLE
:
40 case wxMOUSE_BTN_RIGHT
:
44 wxFAIL_MSG("Unsupported button passed in.");
49 wxCHECK_RET(display
, "No display available!");
52 memset(&event
, 0x00, sizeof(event
));
54 event
.type
= isDown
? ButtonPress
: ButtonRelease
;
55 event
.xbutton
.button
= xbutton
;
56 event
.xbutton
.same_screen
= True
;
58 XQueryPointer(display
, display
.DefaultRoot(),
59 &event
.xbutton
.root
, &event
.xbutton
.window
,
60 &event
.xbutton
.x_root
, &event
.xbutton
.y_root
,
61 &event
.xbutton
.x
, &event
.xbutton
.y
, &event
.xbutton
.state
);
62 event
.xbutton
.subwindow
= event
.xbutton
.window
;
64 while (event
.xbutton
.subwindow
)
66 event
.xbutton
.window
= event
.xbutton
.subwindow
;
67 XQueryPointer(display
, event
.xbutton
.window
,
68 &event
.xbutton
.root
, &event
.xbutton
.subwindow
,
69 &event
.xbutton
.x_root
, &event
.xbutton
.y_root
,
70 &event
.xbutton
.x
, &event
.xbutton
.y
, &event
.xbutton
.state
);
73 XSendEvent(display
, PointerWindow
, True
, 0xfff, &event
);
76 } // anonymous namespace
78 bool wxUIActionSimulator::MouseDown(int button
)
80 SendButtonEvent(button
, true);
84 bool wxUIActionSimulator::MouseMove(long x
, long y
)
87 wxASSERT_MSG(display
, "No display available!");
89 Window root
= display
.DefaultRoot();
90 XWarpPointer(display
, None
, root
, 0, 0, 0, 0, x
, y
);
92 // At least with wxGTK we must always process the pending events before the
93 // mouse position change really takes effect, so just do it from here
94 // instead of forcing the client code using this function to always use
95 // wxYield() which is unnecessary under the other platforms.
96 if ( wxEventLoopBase
* const loop
= wxEventLoop::GetActive() )
98 loop
->YieldFor(wxEVT_CATEGORY_USER_INPUT
);
104 bool wxUIActionSimulator::MouseUp(int button
)
106 SendButtonEvent(button
, false);
110 bool wxUIActionSimulator::DoKey(int keycode
, int modifiers
, bool isDown
)
112 wxX11Display display
;
113 wxCHECK_MSG(display
, false, "No display available!");
125 mask
= KeyReleaseMask
;
128 WXKeySym xkeysym
= wxCharCodeWXToX(keycode
);
129 KeyCode xkeycode
= XKeysymToKeycode(display
, xkeysym
);
130 if ( xkeycode
== NoSymbol
)
135 XGetInputFocus(display
, &focus
, &revert
);
141 if (modifiers
& wxMOD_SHIFT
)
143 //Mod1 is alt in the vast majority of cases
144 if (modifiers
& wxMOD_ALT
)
146 if (modifiers
& wxMOD_CMD
)
150 event
.display
= display
;
151 event
.window
= focus
;
152 event
.root
= DefaultRootWindow(event
.display
);
153 event
.subwindow
= None
;
154 event
.time
= CurrentTime
;
159 event
.same_screen
= True
;
162 event
.keycode
= xkeycode
;
164 XSendEvent(event
.display
, event
.window
, True
, mask
, (XEvent
*) &event
);
169 #endif // wxUSE_UIACTIONSIMULATOR