X11 ได้รับการบันทึกไว้ค่อนข้างดีสำหรับ 'มาสก์เหตุการณ์'
https://tronche.com/gui/x/xlib/events/mask.html
หรือมี XQueryPointer เสมอ)..
// ลองใช้โปรแกรม C นี้เป็นพื้นฐานของสิ่งที่ต้องการทำ..
#รวม <stdio.h>
#รวม <assert.h>
#รวม <X11/Xlib.h>
#รวม <X11/extensions/XInput2.h>
int หลัก (int argc, ถ่าน ** argv)
{
จอแสดงผล *จอแสดงผล;
หน้าต่าง root_window;
/* Initialize (FIXME: ไม่มีการตรวจสอบข้อผิดพลาด) */
จอแสดงผล = XOpenDisplay(0);
root_window = XRootWindow (แสดง, 0);
/* ตรวจสอบ XInput */
int xi_opcode, เหตุการณ์, ข้อผิดพลาด;
ถ้า (!XQueryExtension(แสดงผล, "XInputExtension", &xi_opcode, &event, &error)) {
fprintf(stderr, "ข้อผิดพลาด: ไม่รองรับส่วนขยาย XInput!\n");
กลับ 1;
}
/* ตรวจสอบ XInput 2.0 */
int หลัก = 2;
int เล็กน้อย = 0;
int retval = XIQueryVersion(แสดง &หลัก &รอง);
ถ้า (retval != สำเร็จ) {
fprintf(stderr, "ข้อผิดพลาด: ไม่รองรับ XInput 2.0 (X11 โบราณ?)\n");
กลับ 1;
}
/*
* ตั้งหน้ากากเพื่อรับเหตุการณ์ XI_RawMotion เพราะมันดิบ
* ไม่รวมเหตุการณ์ XWarpPointer() คุณสามารถใช้ XI_Motion
* แทน.
*/
char mask_bytes ที่ไม่ได้ลงชื่อ [(XI_LASTEVENT + 7) / 8] = {0}; /* ต้องมีค่าเป็นศูนย์! */
XISetMask (mask_bytes, XI_RawMotion);
/* ตั้งค่าหน้ากากเพื่อรับเหตุการณ์จากอุปกรณ์หลักทั้งหมด */
XIEventMask evmasks[1];
/* คุณสามารถใช้ XIAllDevices สำหรับ XWarpPointer() */
evmasks[0].deviceid = XIAllMasterDevices;
evmasks[0].mask_len = sizeof(mask_bytes);
evmasks[0].mask = mask_bytes;
XISelectEvents (แสดง, root_window, evmasks, 1);
XEvent xเหตุการณ์;
ในขณะที่ (1) {
XNextEvent(แสดง, &xevent);
ถ้า (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;
int mask_return ที่ไม่ได้ลงนาม;
/*
* พวกเราต้องการ:
* child_return - หน้าต่างที่ใช้งานอยู่ใต้เคอร์เซอร์
* win_{x,y}_return - ตัวชี้ประสานงานกับหน้าต่างรูท
*/
int retval = XQueryPointer(จอแสดงผล, root_window, &root_return, &child_return,
&root_x_return, &root_y_return,
&win_x_return, &win_y_return,
&mask_return);
ถ้า (!retval) {
/* ตัวชี้ไม่อยู่ในหน้าจอเดียวกัน ไม่ต้องสนใจ */
ดำเนินต่อ;
}
/* เราใช้หน้าต่างรูทเป็นข้อมูลอ้างอิง ดังนั้นทั้งสองควรจะเหมือนกัน */
ยืนยัน (root_x_return == win_x_return);
ยืนยัน (root_y_return == win_y_return);
printf("รูท: x %d y %d\n", root_x_return, root_y_return);
ถ้า (child_return) {
int 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;
}