我目前正在为Linux进行延迟测试 . 为了最大限度地减少副作用,我尝试编写一个C程序,它直接使用XCB访问X-Server . 因为没有任何C语言经验,只有Java,也没有XCB,我遇到了一些困难 .
应用程序应该做的一切就是显示一个白框,如果在任何时候(窗口外)按下鼠标按钮,它应该瞬间变为黑色 . 测试应用程序不一定非常漂亮或安全,但只能快速反应 . 它仅用于这一项测试(请不要判断我的糟糕风格;-)) .
鼠标不能在同一窗口中,因为还有另一个独立的应用程序,它也需要处理事件(测量延迟的事件) .
阅读the XCB tutorial后,我修改了示例代码以打开一个窗口并在窗口内记录鼠标单击:
#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
变量更改为根窗口 . 但是我尝试的任何东西都会产生分段错误,或者根本不起作用 .
也许root的孩子(我的申请)没有足够的权利来获取它的父母的事件?但是 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);
How do I have to change the above code to react to all BUTTON_PRESS events on the whole X.Org-Server?
1 回答
因此,如果您想捕获所有按钮事件,我只有一个解决方案,但我不知道这是否适合您的需求 .
它像一个小窗口管理器这里是4个文件:
simple_window_manager.c
events.c
events.h
Makefile
simple_window_manager.c
events.c
events.h
Makefile文件
复制这4个文件,运行
然后在shell会话中尝试这个(我将解释为什么之后):
为了将所有事件都发送到根窗口,您必须配置根窗口,就像您的应用程序是窗口管理器一样 . 但它只能是一个窗口管理器,这就是为什么simple_window_manager不能在gnome或kde下运行的原因 . 你必须使用Xephyr进行测试 .
这是我知道获得所有活动的唯一方式 . 我不是专家,我希望这可以帮到你 .