c-如何通过xcb-RandR扩展获得RandR输出的分辨率



我正在处理一个已经在使用xcb的项目,需要获得单个输出的分辨率,而不是组合屏幕的分辨率。我可以使用xcb的RandR扩展吗?如果是,我如何使用我的xcb_connection_t对象来执行此操作。

我也在寻找答案。我不知道你是否成功了,但由于你还没有回答这个问题,我想你还没有。

对于那些正在研究如何做到这一点的人来说,你必须了解XCB通常是如何工作的。这对于RandR XCB扩展来说尤其重要。正如您可能知道的那样,要从X服务器获取一些信息,您需要首先通过请求对其进行查询。在发送请求后发生XCB的情况下,您将获得一个cookie,该cookie存储已发送请求的ID。你为什么需要这样的饼干?原因很简单,也很明显-要从X服务器获得回复,我们需要用我们发送的请求的ID来询问它(这样服务器就知道你想要哪个请求的答案)。

为了更清楚地说明这一点,这里有一个日常生活中的简单例子——想象一个记忆力极短的酒保,它是这样的:

client   : "I'd like to order a beer."
bartender: "OK, I'll get you a beer."
*bartender handles a ticket with an ID of the beer order to the client*
*client waits and waits and then he approaches bartender*
client   : "Dude, give me my beer finally, here's your damn ticket"
*client handles the ticket to bartender, who looks for the order from the 
ticket in his order book and when he finds it he replies*
bartender: "Here's your beer, enjoy."

好吧,那么XCB为什么不简单地发送一个请求并一次性得到答案呢?好吧,这正是Xlib的工作原理,事实证明,在某些条件下,XCB的速度高达117倍。如果你想了解更多,请阅读XCB教程中的基本XCB注意事项。

回到问题上来——如何获得输出(或者更确切地说是CRTC)的分辨率?以下是我如何做到这一点的最小化版本:

#include <cstdio>
#include <xcb/xcb.h>
#include <xcb/randr.h>
int main()
{
//Open connection to X server
xcb_connection_t* XConnection = xcb_connect(0, 0);
//Get the first X screen
xcb_screen_t* XFirstScreen = xcb_setup_roots_iterator(
xcb_get_setup(XConnection)).data;
//Generate ID for the X window
xcb_window_t XWindowDummy = xcb_generate_id(XConnection);
//Create dummy X window
xcb_create_window(XConnection, 0, XWindowDummy, XFirstScreen->root,
0, 0, 1, 1, 0, 0, 0, 0, 0);
//Flush pending requests to the X server
xcb_flush(XConnection);
//Send a request for screen resources to the X server
xcb_randr_get_screen_resources_cookie_t screenResCookie = {};
screenResCookie = xcb_randr_get_screen_resources(XConnection, 
XWindowDummy);
//Receive reply from X server
xcb_randr_get_screen_resources_reply_t* screenResReply = {};
screenResReply = xcb_randr_get_screen_resources_reply(XConnection,
screenResCookie, 0);
int crtcs_num = 0;
xcb_randr_crtc_t* firstCRTC;
//Get a pointer to the first CRTC and number of CRTCs
//It is crucial to notice that you are in fact getting
//an array with firstCRTC being the first element of
//this array and crtcs_length - length of this array
if(screenResReply)
{
crtcs_num = xcb_randr_get_screen_resources_crtcs_length(screenResReply);
firstCRTC = xcb_randr_get_screen_resources_crtcs(screenResReply);
}
else
return -1;
//Array of requests to the X server for CRTC info
xcb_randr_get_crtc_info_cookie_t* crtcResCookie = new   
xcb_randr_get_crtc_info_cookie_t[crtcs_num];
for(int i = 0; i < crtcs_num; i++)
crtcResCookie[i] = xcb_randr_get_crtc_info(XConnection, 
*(firstCRTC+i), 0);
//Array of pointers to replies from X server
xcb_randr_get_crtc_info_reply_t** crtcResReply = new 
xcb_randr_get_crtc_info_reply_t*[crtcs_num];
for(int i = 0; i < crtcs_num; i++)
crtcResReply[i] = xcb_randr_get_crtc_info_reply(XConnection,
crtcResCookie[i], 0);
//Self-explanatory
for(int i = 0; i < crtcs_num; i++)
{
if(crtcResReply[i])
{
printf("CRTC[%i] INFO:n", i);
printf("x-offt: %in", crtcResReply[i]->x);
printf("y-offt: %in", crtcResReply[i]->y);
printf("widtht: %in", crtcResReply[i]->width);
printf("heightt: %inn", crtcResReply[i]->height);
}
}
xcb_disconnect(XConnection);
return 0;
}

示例输出:

CRTC[0] INFO:
x-off   : 1920
y-off   : 0
width   : 1920
height  : 1200
CRTC[1] INFO:
x-off   : 0
y-off   : 0
width   : 1920
height  : 1200
CRTC[2] INFO:
x-off   : 0
y-off   : 0
width   : 0
height  : 0
CRTC[3] INFO:
x-off   : 0
y-off   : 0
width   : 0
height  : 0

如果你愿意,你可以用矢量之类的东西来提高代码的可读性,而不是用指针来动态分配,但我认为这并不难理解。

我还是XCB编程的新手,可能有更好的方法,但这种方法看起来一点也不坏。我花了大量的时间试图理解这一点,所以我希望它能帮助到一些人。

有用的链接:

  • XCB教程(建议您自行查找)
  • XCB API(非常有用,在这种情况下尤其是RandR API)

相关内容

  • 没有找到相关文章

最新更新