3

注意:这是对What process created this X11 window的回答的延续?来自 unix.stackexchange。该答案提到XResQueryClientIdsX-Resource v1.2 extension。我想知道如何使用它。

如何使用python 的 xcffib 模块查找与提供的 PID 关联的所有 X11 窗口 ID(假设没有竞争条件;没有创建或销毁窗口或进程)。

我对 X11 了解不多,XCB API 文档似乎不完整,并且自动生成的 xcffib python 绑定没有文档记录。根据我收集的信息,我需要:

  1. 创建连接:xcb_connect
  2. 获取扩展名: ?undocumented?
  3. 查询分机:? xcb_get_extension_data提到“?QueryExtension 请求”
  4. 获取查询响应:xcb_get_extension_data
  5. 使用扩展文档协议存根 API来解压响应。
4

1 回答 1

4

假设没有竞争条件;没有创建或销毁窗口或进程

如果您知道假设不成立,那么假设是不好的。幸运的是,您不需要这个假设。只需使用xcb_grab_serverxcb_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 相同,但在大多数情况下其他名称略有不同。

于 2016-05-18T20:11:14.633 回答