【问题标题】:XCB get all monitors ands their x, y coordinatesXCB 获取所有显示器及其 x、y 坐标
【发布时间】:2016-05-01 12:54:28
【问题描述】:

到目前为止,我已经拥有了所有显示器。监视器是屏幕。所以我所做的是:

xcb_connection_t *conn;

conn = xcb_connect(NULL, NULL);

if (xcb_connection_has_error(conn)) {
  printf("Error opening display.\n");
  exit(1);
}

const xcb_setup_t* setup;
xcb_screen_t* screen;

setup = xcb_get_setup(conn);
screen = xcb_setup_roots_iterator(setup).data;
printf("Screen dimensions: %d, %d\n", screen->width_in_pixels, screen->height_in_pixels);

这给了我宽度和高度。然而,我得到 x 和 y 是至关重要的。是在screen->root 上做xcb_get_window_attributes_cookie_t 获取x 和y 的方式吗?

我在这里阅读 - http://www.linuxhowtos.org/manpages/3/xcb_get_window_attributes_unchecked.htm - 但没有给出 x/y 坐标。

【问题讨论】:

    标签: xcb


    【解决方案1】:

    我假设您对显示器的几何形状感兴趣,即实际的物理设备,而不是 X 屏幕。

    在这种情况下,根窗口不是你感兴趣的。这里基本上有两个不同的事情需要考虑:

    要了解如何查询各种详细信息,我的建议是查看执行此操作的程序。一个规范的建议是支持多头设置的窗口管理器,例如 i3 窗口管理器,它实际上同时支持 Xinerama 和 RandR,因此您可以查看两者的源代码。

    您正在寻找的信息可以在src/randr.csrc/xinerama.c 中找到。必要的 RandR API 调用是

    • xcb_randr_get_screen_resources_current
    • xcb_randr_get_screen_resources_current_outputs
    • xcb_randr_get_output_info
    • xcb_randr_get_crtc_info

    后者将为您提供输出的 CRTC 信息,其中包括输出的位置和大小。

    RandR 实现的另一个来源是xedgewarp:src/randr.c*。我将在此处包含该源代码的一个大大缩短的摘录:

    xcb_randr_get_screen_resources_current_reply_t *reply = xcb_randr_get_screen_resources_current_reply(
            connection, xcb_randr_get_screen_resources_current(connection, root), NULL);
    
    xcb_timestamp_t timestamp = reply->config_timestamp;
    int len = xcb_randr_get_screen_resources_current_outputs_length(reply);
    xcb_randr_output_t *randr_outputs = xcb_randr_get_screen_resources_current_outputs(reply);
    for (int i = 0; i < len; i++) {
        xcb_randr_get_output_info_reply_t *output = xcb_randr_get_output_info_reply(
                connection, xcb_randr_get_output_info(connection, randr_outputs[i], timestamp), NULL);
        if (output == NULL)
            continue;
    
        if (output->crtc == XCB_NONE || output->connection == XCB_RANDR_CONNECTION_DISCONNECTED)
            continue;
    
        xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(connection,
                xcb_randr_get_crtc_info(connection, output->crtc, timestamp), NULL);
        fprintf(stderr, "x = %d | y = %d | w = %d | h = %d\n",
                crtc->x, crtc->y, crtc->width, crtc->height);
        FREE(crtc);
        FREE(output);
    }
    
    FREE(reply);
    

    *) 免责声明:我是该工具的作者。

    编辑:请注意,如果您有兴趣让您的信息保持最新,您还需要监听屏幕更改事件,然后再次查询输出。

    【讨论】:

    • 哇,谢谢!这就是我目前的做法,我在线程中使用 Xrandr,但我听说它不是线程安全的,所以我想将所有内容都切换到 xcb。这对我的帮助比你多很多! github.com/Noitidart/NativeShot/blob/master/modules/screenshot/… 我找不到关于这个 xcb 东西的文档,非常感谢!!
    • 是的,很遗憾,xcb 在很多领域都没有很好的文档记录。大多数时候,查看 Xlib 等价物的文档是非常好的,将信息传输到 xcb 通常是微不足道的。很高兴我能帮上忙!
    • @IngoBürk 现在 RandR 是否可以与 NVIDIA 和 AMD 专有驱动程序一起使用? (“最流行和广泛使用的闭源驱动程序的制造商,nVidia 和 AMD/ATI,拒绝支持 RandR。相反,他们更愿意提供自己的 RandR 不兼容的解决方案。”)linux-magazine.com/Issues/2009/106/Multi-heading-with-RandR
    • 是的,RandR 是事实上的标准。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 2021-07-10
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多