5#include <QLoggingCategory>
10#include <X11/extensions/XTest.h>
12#include "InputDeviceXLib.h"
14Q_LOGGING_CATEGORY(LogInput,
"Device.Input")
26CInputDeviceXLib::~CInputDeviceXLib()
28 qDebug(LogInput) <<
"CInputDeviceXLib::~CInputDeviceXLib()";
32KeyCode CInputDeviceXLib::XkbKeysymToKeycode(Display* dpy, KeySym keysym) {
38 xkb = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
42 XkbGetState(dpy, XkbUseCoreKbd, &state);
45 mods = XkbBuildCoreState(XkbStateMods(&state), state.group);
47 for (keycode = xkb->min_key_code;
48 keycode <= xkb->max_key_code;
51 unsigned int out_mods;
52 XkbTranslateKeyCode(xkb, keycode, mods, &out_mods, &cursym);
57 if (keycode > xkb->max_key_code)
60 XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
64 if ((keycode == 0) && (keysym == XK_Tab) && (mods & ShiftMask))
65 return XkbKeysymToKeycode(dpy, XK_ISO_Left_Tab);
71int CInputDeviceXLib::KeyEvent(quint32 keysym, quint32 xtcode,
bool down)
78 Display *display = XOpenDisplay(NULL);
81 if (codeMap && rawKeyboard && xtcode < codeMapLen)
82 keycode = codeMap[xtcode];
85 if (pressedKeys.find(keysym) != pressedKeys.end())
86 keycode = pressedKeys[keysym];
90 keycode = XkbKeysymToKeycode(display, keysym);
95 qCritical(LogInput) <<
"Could not map key event to X11 key code";
101 pressedKeys[keysym] = keycode;
103 pressedKeys.erase(keysym);
105 qDebug(LogInput,
"%d %s", keycode, down ?
"down" :
"up");
107 XTestFakeKeyEvent(display, keycode, down, CurrentTime);
109 XCloseDisplay(display);
116void click(Display *display,
int button,
bool press)
119 XTestFakeButtonEvent(display, button, press, CurrentTime);
123 memset (&event, 0,
sizeof (event));
124 event.xbutton.button = button;
125 event.xbutton.same_screen = True;
126 event.xbutton.subwindow = DefaultRootWindow (display);
127 while (event.xbutton.subwindow)
129 event.xbutton.window =
event.xbutton.subwindow;
130 XQueryPointer (display, event.xbutton.window,
131 &event.xbutton.root, &event.xbutton.subwindow,
132 &event.xbutton.x_root, &event.xbutton.y_root,
133 &event.xbutton.x, &event.xbutton.y,
134 &event.xbutton.state);
139 event.type = ButtonPress;
140 if (XSendEvent (display, PointerWindow, True, ButtonPressMask, &event) == 0)
141 fprintf (stderr,
"Error to send the event!\n");
143 if (XSendEvent (display, PointerWindow, True, ButtonReleaseMask, &event) == 0)
144 fprintf (stderr,
"Error to send the event!\n");
152void coords (Display *display,
int *x,
int *y)
155 XQueryPointer (display, DefaultRootWindow (display),
156 &event.xbutton.root, &event.xbutton.window,
157 &event.xbutton.x_root, &event.xbutton.y_root,
158 &event.xbutton.x, &event.xbutton.y,
159 &event.xbutton.state);
160 *x =
event.xbutton.x;
161 *y =
event.xbutton.y;
165void move (Display *display,
int x,
int y)
167 XWarpPointer (display, None, None, 0,0,0,0, x, y);
173void move_to (Display *display,
int x,
int y)
176 coords (display, &cur_x, &cur_y);
177 XWarpPointer (display, None, None, 0,0,0,0, -cur_x, -cur_y);
178 XWarpPointer (display, None, None, 0,0,0,0, x, y);
192int CInputDeviceXLib::MouseEvent(MouseButtons buttons, QPoint pos)
194 Display *display = XOpenDisplay(NULL);
197 qCritical(LogInput) <<
"Open display fail";
200 Window root = DefaultRootWindow(display);
203 if (m_LastPostion != pos)
205 XTestFakeMotionEvent(display, DefaultScreen(display),
210 XWarpPointer (display, root, root, 0, 0, 0, 0, pos.x(), pos.y());
214 if((m_LastButtons & LeftButton) != (LeftButton & buttons))
216 if(buttons & LeftButton)
217 click(display, Button1,
true);
219 click(display, Button1,
false);
223 if((m_LastButtons & MiddleButton) != (MiddleButton & buttons))
225 if(buttons & MiddleButton)
226 click(display, Button2,
true);
228 click(display, Button2,
false);
232 if((m_LastButtons & RightButton) != (RightButton & buttons))
234 if(buttons & RightButton)
235 click(display, Button3,
true);
237 click(display, Button3,
false);
239 m_LastButtons = buttons;
240 XCloseDisplay(display);
244int CInputDeviceXLib::MouseEvent(MouseButtons buttons,
int x,
int y)
246 return MouseEvent(buttons, QPoint(x, y));