X11 được ghi lại khá tốt cho 'Mặt nạ sự kiện'
https://tronche.com/gui/x/xlib/events/mask.html
Hoặc luôn có XQueryPulum)..
// Hãy thử chương trình C này làm cơ sở cho những gì bạn muốn làm..
#include <stdio.h>
#include <khẳng định.h>
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
int chính(int argc, char **argv)
{
Hiển thị * hiển thị;
Cửa sổ root_window;
/* Khởi tạo (FIXME: không kiểm tra lỗi). */
màn hình = XOpenDisplay(0);
root_window = XRootWindow(hiển thị, 0);
/* kiểm tra XInput */
int xi_opcode, sự kiện, lỗi;
if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) {
fprintf(stderr, "Lỗi: Phần mở rộng XInput không được hỗ trợ!\n");
trả lại 1;
}
/* Kiểm tra XInput 2.0 */
int chính = 2;
int nhỏ = 0;
int retval = XIQueryVersion(hiển thị, &chính, &phụ);
if (retval != Thành công) {
fprintf(stderr, "Lỗi: XInput 2.0 không được hỗ trợ (X11 cổ đại?)\n");
trả lại 1;
}
/*
* Đặt mặt nạ để nhận các sự kiện XI_RawMotion. Bởi vì nó là thô,
* Các sự kiện XWarpPulum() không được bao gồm, bạn có thể sử dụng XI_Motion
* thay thế.
*/
ký tự không dấu mask_bytes[(XI_LASTEVENT + 7) / 8] = {0}; /* phải bằng 0! */
XISetMask(mask_bytes, XI_RawMotion);
/* Đặt mặt nạ để nhận các sự kiện từ tất cả các thiết bị chính */
XIEventMask evmasks[1];
/* Bạn có thể sử dụng XIAllDevices cho XWarpPulum() */
evmasks[0].deviceid = XIAllMasterDevices;
evmasks[0].mask_len = sizeof(mask_bytes);
evmasks[0].mask = mask_bytes;
XISelectEvents(hiển thị, root_window, evmasks, 1);
XEvent xevent;
trong khi (1) {
XNextEvent(hiển thị, &xevent);
if (xevent.xcookie.type != GenericEvent || xevent.xcookie.extension != xi_opcode) {
/* không phải là sự kiện XInput */
tiếp tục;
}
XGetEventData(hiển thị, &xevent.xcookie);
if (xevent.xcookie.evtype != XI_RawMotion) {
/*
* Không phải sự kiện XI_RawMotion (bạn có thể muốn phát hiện
* XI_Motion cũng vậy, xem nhận xét ở trên).
*/
XFreeEventData(hiển thị, &xevent.xcookie);
tiếp tục;
}
XFreeEventData(hiển thị, &xevent.xcookie);
Cửa sổ root_return, child_return;
int root_x_return, root_y_return;
int win_x_return, win_y_return;
không dấu int mask_return;
/*
* Chúng tôi cần:
* child_return - cửa sổ đang hoạt động dưới con trỏ
* win_{x,y}_return - tọa độ con trỏ đối với cửa sổ gốc
*/
int retval = XQueryPulum(hiển thị, root_window, &root_return, &child_return,
&root_x_return, &root_y_return,
&win_x_return, &win_y_return,
&mask_return);
nếu (!retval) {
/* con trỏ không ở cùng màn hình, bỏ qua */
tiếp tục;
}
/* Chúng ta đã sử dụng cửa sổ gốc làm tham chiếu nên cả hai phải giống nhau */
khẳng định (root_x_return == win_x_return);
khẳng định (root_y_return == win_y_return);
printf("root: x %d y %d\n", root_x_return, root_y_return);
nếu (con_return) {
int local_x, local_y;
XTranslateCoordins(hiển thị, root_window, child_return,
root_x_return, root_y_return,
&local_x, &local_y, &child_return);
printf("cục bộ: x %d y %d\n\n", local_x, local_y);
}
}
XCloseDisplay(hiển thị);
trả về 0;
}