1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/uiactionx11.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 /////////////////////////////////////////////////////////////////////////////
16 #if wxUSE_UIACTIONSIMULATOR
18 #include "wx/uiaction.h"
20 #include "wx/evtloop.h"
23 #include <X11/Xutil.h>
25 #include "wx/unix/utilsx11.h"
30 void SendButtonEvent(int button
, bool isDown
)
35 case wxMOUSE_BTN_LEFT
:
38 case wxMOUSE_BTN_MIDDLE
:
41 case wxMOUSE_BTN_RIGHT
:
45 wxFAIL_MSG("Unsupported button passed in.");
50 wxCHECK_RET(display
, "No display available!");
53 memset(&event
, 0x00, sizeof(event
));
55 event
.type
= isDown
? ButtonPress
: ButtonRelease
;
56 event
.xbutton
.button
= xbutton
;
57 event
.xbutton
.same_screen
= True
;
59 XQueryPointer(display
, display
.DefaultRoot(),
60 &event
.xbutton
.root
, &event
.xbutton
.window
,
61 &event
.xbutton
.x_root
, &event
.xbutton
.y_root
,
62 &event
.xbutton
.x
, &event
.xbutton
.y
, &event
.xbutton
.state
);
63 event
.xbutton
.subwindow
= event
.xbutton
.window
;
65 while (event
.xbutton
.subwindow
)
67 event
.xbutton
.window
= event
.xbutton
.subwindow
;
68 XQueryPointer(display
, event
.xbutton
.window
,
69 &event
.xbutton
.root
, &event
.xbutton
.subwindow
,
70 &event
.xbutton
.x_root
, &event
.xbutton
.y_root
,
71 &event
.xbutton
.x
, &event
.xbutton
.y
, &event
.xbutton
.state
);
74 XSendEvent(display
, PointerWindow
, True
, 0xfff, &event
);
77 } // anonymous namespace
79 bool wxUIActionSimulator::MouseDown(int button
)
81 SendButtonEvent(button
, true);
85 bool wxUIActionSimulator::MouseMove(long x
, long y
)
88 wxASSERT_MSG(display
, "No display available!");
90 Window root
= display
.DefaultRoot();
91 XWarpPointer(display
, None
, root
, 0, 0, 0, 0, x
, y
);
93 // At least with wxGTK we must always process the pending events before the
94 // mouse position change really takes effect, so just do it from here
95 // instead of forcing the client code using this function to always use
96 // wxYield() which is unnecessary under the other platforms.
97 if ( wxEventLoopBase
* const loop
= wxEventLoop::GetActive() )
99 loop
->YieldFor(wxEVT_CATEGORY_USER_INPUT
);
105 bool wxUIActionSimulator::MouseUp(int button
)
107 SendButtonEvent(button
, false);
111 bool wxUIActionSimulator::DoKey(int keycode
, int modifiers
, bool isDown
)
113 wxX11Display display
;
114 wxCHECK_MSG(display
, false, "No display available!");
126 mask
= KeyReleaseMask
;
129 WXKeySym xkeysym
= wxCharCodeWXToX(keycode
);
130 KeyCode xkeycode
= XKeysymToKeycode(display
, xkeysym
);
131 if ( xkeycode
== NoSymbol
)
136 XGetInputFocus(display
, &focus
, &revert
);
142 if (modifiers
& wxMOD_SHIFT
)
144 //Mod1 is alt in the vast majority of cases
145 if (modifiers
& wxMOD_ALT
)
147 if (modifiers
& wxMOD_CMD
)
151 event
.display
= display
;
152 event
.window
= focus
;
153 event
.root
= DefaultRootWindow(event
.display
);
154 event
.subwindow
= None
;
155 event
.time
= CurrentTime
;
160 event
.same_screen
= True
;
163 event
.keycode
= xkeycode
;
165 XSendEvent(event
.display
, event
.window
, True
, mask
, (XEvent
*) &event
);
170 #endif // wxUSE_UIACTIONSIMULATOR