【问题标题】:python: PID to X11 Window ID using XResQueryClientIdspython:使用 XResQueryClientIds 将 PID 转换为 X11 窗口 ID
【发布时间】:2016-09-13 23:17:01
【问题描述】:

注意:这是来自 unix.stackexchange 对What process created this X11 window? 的回答的延续。该答案从X-Resource v1.2 extension 中提到了XResQueryClientIds。我想知道怎么用。

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

我对 X11 了解不多,XCB API documentation 似乎不完整,auto-generated xcffib python bindings 没有记录。根据我收集到的信息,我需要:

  1. 创建连接:xcb_connect
  2. 获取扩展名:?undocumented?
  3. 查询扩展:?xcb_get_extension_data 提到“?QueryExtension requests”
  4. 获取查询响应:xcb_get_extension_data
  5. 使用extension documentationprotocol stub API 解压缩响应。

【问题讨论】:

  • 如果我的回答对您有帮助,请将其标记为已接受。我注意到您一直在关注 SO,但尚未对我的回答提供任何反馈。

标签: python x11 xcb


【解决方案1】:

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

如果您知道假设不成立,那么假设就是不好的。幸运的是,您不需要这个假设。只需在您的操作中使用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 函数名称并遇到了this。要了解各个部分,我建议阅读它的 Xlib 文档。正如您所注意到的,XCB 通常是……“文档不足”,但它实际上与 Xlib 相同,但大多数情况下其他名称略有不同。

【讨论】:

  • 不是我想要的,但很有帮助。 xcffib 有很多问题: 1] 0.1 (fedora 23) 连接被破坏,即使手动 xauth 2] 尝试手动打包结构,这是 错误的方式 3] 很多方法来做同样的事情,其中大多数是错误的方式 4] 没有文档 5] 0.4.2(当前)的更改破坏了与 xlib 的兼容性(应该在下一个版本中修复)。从字面上看,我尝试过的每一行都有问题,无论是我自己(文档)、旧版本、坏补丁还是坏协议。
  • 无论如何,我打算切换到 libxcb (c),但由于 X-Resource protocol doesn't match the specificationxcb_res_query_client_ids_reply_t 充满了垃圾(越界读取)。该补丁修复了所有绑定的问题,所以现在 xcffib 可以完美运行,现在我知道自己在做什么了。
  • 我看到您在调试方面付出了相当多的努力。酷!
  • 这太棒了。自己搞定这些东西可能很容易花费我好几天的时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-22
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 2020-10-11
相关资源
最近更新 更多