X11 довольно хорошо документирован для «Масок событий».
https://tronche.com/gui/x/xlib/events/mask.html
Или всегда есть XQueryPointer).
// Попробуйте эту программу C как основу того, что вы хотите сделать.
#include <stdio.h>
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/расширения/XInput2.h>
int main(int argc, char **argv)
{
Дисплей *дисплей;
Окно root_window;
/* Инициализировать (FIXME: без проверки ошибок). */
дисплей = XOpenDisplay (0);
root_window = XRootWindow (дисплей, 0);
/* проверка XInput */
int xi_opcode, событие, ошибка;
if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) {
fprintf(stderr, "Ошибка: расширение XInput не поддерживается!\n");
вернуть 1;
}
/* Проверка XInput 2.0 */
мажор = 2;
инт минор = 0;
int retval = XIQueryVersion(display, &major, &minor);
если (возвращение != успех) {
fprintf(stderr, "Ошибка: XInput 2.0 не поддерживается (древний X11?)\n");
вернуть 1;
}
/*
* Установите маску для получения событий XI_RawMotion. Потому что он сырой,
* События XWarpPointer() не включены, вы можете использовать XI_Motion
* вместо.
*/
unsigned char mask_bytes[(XI_LASTEVENT + 7)/8] = {0}; /* необходимо обнулить! */
XISetMask(mask_bytes, XI_RawMotion);
/* Установить маску для получения событий от всех ведущих устройств */
Маски XIEventMask[1];
/* Вы можете использовать XIAllDevices для XWarpPointer() */
evmasks[0].deviceid = XIAllMasterDevices;
evmasks[0].mask_len = sizeof(mask_bytes);
evmasks[0].mask = mask_bytes;
XISelectEvents(display, root_window, evmasks, 1);
XEvent xEvent;
в то время как (1) {
XNextEvent(отображение, &xevent);
if (xevent.xcookie.type != GenericEvent || xevent.xcookie.extension != xi_opcode) {
/* не событие XInput */
Продолжить;
}
XGetEventData(отображение, &xevent.xcookie);
если (xevent.xcookie.evtype != XI_RawMotion) {
/*
* Не является событием XI_RawMotion (вы можете обнаружить
* также XI_Motion, см. комментарии выше).
*/
XFreeEventData(отображение, &xevent.xcookie);
Продолжить;
}
XFreeEventData(отображение, &xevent.xcookie);
Окно root_return, child_return;
int root_x_return, root_y_return;
int win_x_return, win_y_return;
беззнаковое целое mask_return;
/*
* Нам нужно:
* child_return - активное окно под курсором
* win_{x,y}_return - координата указателя относительно корневого окна
*/
int retval = XQueryPointer(display, root_window, &root_return, &child_return,
&root_x_return, &root_y_return,
&win_x_return, &win_y_return,
&mask_return);
если (! ретвал) {
/* указатель не находится на том же экране, игнорировать */
Продолжить;
}
/* Мы использовали корневое окно в качестве ссылки, поэтому оба должны быть одинаковыми */
утверждать (root_x_return == win_x_return);
утверждать (root_y_return == win_y_return);
printf("root: x %d y %d\n", root_x_return, root_y_return);
если (дочерний_возврат) {
интервал local_x, local_y;
XTranslateCoordinates(дисплей, root_window, child_return,
root_x_return, root_y_return,
&local_x, &local_y, &child_return);
printf("local: x %d y %d\n\n", local_x, local_y);
}
}
XCloseDisplay (отображение);
вернуть 0;
}