我目前正在对Linux进行延迟测试。为了最小化副作用,我尝试编写一个直接使用XCB访问X-Server的C程序。
但是由于我没有C语言方面的经验,只有Java和XCB经验,因此遇到了一些困难。
应用程序需要做的就是显示一个白色框架,并且如果在任何时候按下鼠标按钮(窗口外),它应该立即变成黑色。测试应用程序不必美观或安全,只需快速响应。它仅用于此一次测试(请别嫌我的拙劣风格;-))。
另外,鼠标不能在同一个窗口内,因为还有另一个独立应用程序需要处理事件(测量延迟)。
阅读完XCB教程后,我已修改示例代码以打开一个窗口并记录窗口内的鼠标点击事件:
为了获取所有窗口的事件,我猜我必须将变量
应用程序需要做的就是显示一个白色框架,并且如果在任何时候按下鼠标按钮(窗口外),它应该立即变成黑色。测试应用程序不必美观或安全,只需快速响应。它仅用于此一次测试(请别嫌我的拙劣风格;-))。
另外,鼠标不能在同一个窗口内,因为还有另一个独立应用程序需要处理事件(测量延迟)。
阅读完XCB教程后,我已修改示例代码以打开一个窗口并记录窗口内的鼠标点击事件:
#include <stdio.h>
#include <xcb/xcb.h>
main ()
{
/* Open the connection to the X server */
xcb_connection_t *connection = xcb_connect (NULL, NULL);
/* Get the first screen */
xcb_screen_t *screen = xcb_setup_roots_iterator (xcb_get_setup (connection)).data;
/* Create black (foreground) graphic context */
xcb_drawable_t window;
uint32_t mask;
uint32_t values[2];
/* Create a window */
window = xcb_generate_id (connection);
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
values[0] = screen->white_pixel;
values[1] = XCB_EVENT_MASK_BUTTON_PRESS;
xcb_create_window (connection, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, 500, 500, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, values );
/* Map the window on the screen and flush*/
xcb_map_window (connection, window);
xcb_flush (connection);
/* Get XCB_EVENT_MASK_BUTTON_PRESS event */
xcb_generic_event_t *event;
while ((event = xcb_wait_for_event (connection))) {
switch (event ->response_type & ~0x80) {
case XCB_EVENT_MASK_BUTTON_PRESS:
printf("Button pressed!\n");
break;
default:
/* Unknown event type */
printf("Unknown event!\n");
break;
}
/* free (event); */
}
return 0;
}
为了获取所有窗口的事件,我猜我必须将变量
window
更改为根窗口。但是我尝试的任何事情都会产生分段错误或根本无法工作。也许根窗口的子窗口(我的应用程序)没有足够的权限来获取其父窗口的事件?但是xwininfo -root
是如何工作的呢?最好的尝试:xcb_connection_t *connection = xcb_connect (NULL, NULL);
xcb_screen_t *screen = xcb_setup_roots_iterator (xcb_get_setup (connection)).data;
xcb_drawable_t window = screen->root; /* !!! */
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t values[2];
values[0] = screen->white_pixel;
values[1] = XCB_EVENT_MASK_BUTTON_PRESS;
xcb_change_window_attributes (connection, window, mask, values); /* !!! */
xcb_map_window (connection, window);
xcb_flush (connection);
我应该如何更改上面的代码以响应整个 X.Org-Server 上的所有 BUTTON_PRESS 事件?
root
访问权限,可以直接访问/dev/input/*
(使用ioctl
)以获取每个窗口的信息。我能够打开一个event*
文件并读取键盘按键。鼠标可能有用的参考资料。 - SO_fix_the_vote_sorting_bugxinput --test-xi2 --root
所做的事情,但由于某种原因只能运行一个xinput
实例。这个链接有帮助吗? - jarno