X11 este destul de bine documentat pentru „măști de eveniment”
https://tronche.com/gui/x/xlib/events/mask.html
Sau există întotdeauna XQueryPointer)..
// Încercați acest program C ca bază pentru ceea ce doriți să faceți..
#include <stdio.h>
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
int main(int argc, char **argv)
{
Display *afisaj;
Fereastra root_window;
/* Inițializare (FIXME: nicio verificare a erorilor). */
display = XOpenDisplay(0);
root_window = XRootWindow(afisare, 0);
/* verifica XInput */
int xi_opcode, eveniment, eroare;
dacă (!XQueryExtension(afișare, „XInputExtension”, &xi_opcode, &eveniment, &eroare)) {
fprintf(stderr, „Eroare: extensia XInput nu este acceptată!\n”);
întoarcere 1;
}
/* Verificați XInput 2.0 */
int major = 2;
int minor = 0;
int retval = XIQueryVersion(afișare, &major, &minor);
if (retval != Succes) {
fprintf(stderr, „Eroare: XInput 2.0 nu este acceptat (antic X11?)\n”);
întoarcere 1;
}
/*
* Setați masca pentru a primi evenimente XI_RawMotion. Pentru că este crudă,
* Evenimentele XWarpPointer() nu sunt incluse, puteți utiliza XI_Motion
* in schimb.
*/
unsigned char mask_bytes[(XI_LASTEVENT + 7) / 8] = {0}; /* trebuie pus la zero! */
XISetMask(mask_bytes, XI_RawMotion);
/* Setați masca pentru a primi evenimente de pe toate dispozitivele principale */
XIEventMask evmasks[1];
/* Puteți folosi XIAllDevices pentru XWarpPointer() */
evmasks[0].deviceid = XIAllMasterDevices;
evmasks[0].mask_len = sizeof(mask_bytes);
evmasks[0].mask = mask_bytes;
XISelectEvents(afișare, fereastră_rădăcină, evmasks, 1);
XEvent xevent;
în timp ce (1) {
XNextEvent(afișare, &xevent);
if (xevent.xcookie.type != GenericEvent || xevent.xcookie.extension != xi_opcode) {
/* nu este un eveniment XInput */
continua;
}
XGetEventData(afișare, &xevent.xcookie);
dacă (xevent.xcookie.evtype != XI_RawMotion) {
/*
* Nu este un eveniment XI_RawMotion (poate dori să detectați
* XI_Motion, de asemenea, vezi comentariile de mai sus).
*/
XFreeEventData(afișare, &xevent.xcookie);
continua;
}
XFreeEventData(afișare, &xevent.xcookie);
Fereastra root_return, child_return;
int root_x_return, root_y_return;
int win_x_return, win_y_return;
unsigned int mask_return;
/*
* Avem nevoie:
* child_return - fereastra activă sub cursor
* win_{x,y}_return - coordona indicatorului în raport cu fereastra rădăcină
*/
int retval = XQueryPointer(afișare, fereastră_rădăcină, &root_return, &child_return,
&root_x_return, &root_y_return,
&win_x_return, &win_y_return,
&mask_return);
dacă (!retval) {
/* indicatorul nu este în același ecran, ignorați */
continua;
}
/* Am folosit fereastra rădăcină ca referință, așa că ambele ar trebui să fie la fel */
assert(root_x_return == win_x_return);
assert(root_y_return == win_y_return);
printf("rădăcină: x %d y %d\n", root_x_return, root_y_return);
if (child_return) {
int local_x, local_y;
XTranslateCoordinates(display, 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(afișare);
întoarce 0;
}