假设没有竞争条件;没有创建或销毁窗口或进程
如果您知道假设不成立,那么假设是不好的。幸运的是,您不需要这个假设。只需使用xcb_grab_server
和xcb_ungrab_server
围绕您的操作,这不会成为问题。
现在,至于XResQueryClientIds
,您实际上只需输入man xcb_res_query_client_ids
. XCB 只是提供了这个,不需要实际查询扩展。这是一个示例程序。编译它,gcc -lxcb -lxcb-res main.c
然后通过传递一个窗口 ID 作为唯一参数(例如,./a.out 0x2c00004
)来执行它。
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <xcb/res.h>
int main(int argc, char *argv[]) {
int screen;
xcb_connection_t *conn = xcb_connect(NULL, &screen);
xcb_res_client_id_spec_t spec = {0};
spec.client = strtol(argv[1], NULL, 0);
spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
xcb_generic_error_t *err = NULL;
xcb_res_query_client_ids_cookie_t cookie = xcb_res_query_client_ids(conn, 1, &spec);
xcb_res_query_client_ids_reply_t *reply = xcb_res_query_client_ids_reply(conn, cookie, &err);
if (reply == NULL) {
fprintf(stderr, "Uh-Oh! :(\n");
return -1;
}
uint32_t *pid = NULL;
xcb_res_client_id_value_iterator_t it = xcb_res_query_client_ids_ids_iterator(reply);
for (; it.rem; xcb_res_client_id_value_next(&it)) {
spec = it.data->spec;
if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
pid = xcb_res_client_id_value_value(it.data);
break;
}
}
free(reply);
xcb_disconnect(conn);
fprintf(stderr, "PID: %d\n", *pid);
}
为了给出正确的归属,我自己也不知道这些,我只是在谷歌上搜索了 XCB 函数名称并遇到了这个。要了解各个部分,我建议阅读它的 Xlib 文档。XCB 通常是……“文档不足”,正如您已经注意到的,但它实际上与 Xlib 相同,但在大多数情况下其他名称略有不同。