利用XCB编写X Window措施(一) 快速起步
当前位置:以往代写 > C/C++ 教程 >利用XCB编写X Window措施(一) 快速起步
2019-06-13

利用XCB编写X Window措施(一) 快速起步

利用XCB编写X Window措施(一) 快速起步

副标题#e#

预计此刻已经没有谁利用XCB这么底层的库写应用措施了,要用也是用颠末经心封装的Motif, LessTiff, GTK, Qt, EWL,  ETK可能Cairo等高条理的库。我之所以这么操心地去折腾XCB,其实主要也是为了进修。究竟,利用最靠近底层的UI库写代码是进修X协议及GUI编程道理的最好要领。

XCB的主要教程可以参考这里:http://xcb.freedesktop.org/tutorial/

和X协议有关的文档,在这里:http://www.x.org/releases/X11R7.7/doc/

在这里要继承吐槽freedesktop.org。没错,XCB的官网又是在freedesktop.org,并且正如我前几篇漫笔中提到的Xft、Freetype一样,文档极其不完善。不外在其XcbApi页面有这样的提示“Refactoring this page…please be patient…”,那就耐性期待吧。亏得代码是最好的文档,在Fedora 20中安装libxcb-devel软件包后,可以直接到/usr/include/xcb目次下查察XCB库的头文件,所以真要进修XCB也不是很难。如下图,我系统中的XCB库的头文件:

操作XCB编写X Window法子(一) 快速起步


#p#副标题#e#

下面是一个最简朴的XCB措施,它的成果是建设一个窗口。由于没有任何事件处理惩罚的机制,所以利用了pause()让措施暂停,要退出措施,必需得按Ctrl+C。

#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <xcb/xcb.h>
#include <stdio.h>
    
double get_time(){
    struct timeval timeval;
    gettimeofday(&timeval, NULL);
    return (double)timeval.tv_sec + (((double)timeval.tv_usec)/1000000);
}
    
int main(){
    double start_time = get_time();
    
    xcb_connection_t *connection = xcb_connect(NULL, NULL);
    const xcb_setup_t *setup = xcb_get_setup(connection);
    xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
    xcb_screen_t *screen = iter.data;
    
    xcb_window_t window = xcb_generate_id(connection);
    xcb_create_window(
            connection,
            XCB_COPY_FROM_PARENT,
            window,
            screen->root,
            100,100,
            400, 300,
            10,
            XCB_WINDOW_CLASS_INPUT_OUTPUT,
            screen->root_visual,
            0, NULL);
    xcb_map_window(connection, window);
    xcb_flush(connection);
    
    printf("耗费时间:%f秒。",get_time()-start_time);
    fflush(stdout);
    
    pause();
    xcb_disconnect(connection);
    return 0;
}

从这段代码可以看出,要建设一个简朴的窗口措施,必需颠末如下步调:

1、毗连到XServer的Display,通过xcb_connect()函数举办,返回一个xcb_connection_t的指针,在这一步中,同时可以获恰当前屏幕的Screen number;

2、得到xcb_setup,通过xcb_get_setup()函数举办。xcb_setup内里生存的是应用措施和XServer之间通讯时需要用到的信息,包罗协议的版本、字节的顺序等。一般环境下,我们不需要存眷这些细节;

3、得到Screen工具,这一步很重要,也很巨大。重要是因为只有得到一个Screen后,才气在屏幕上建设窗口,建设窗口时需要用到Screen中的一些信息。巨大是因为一个Display可以有多个Screen,所以通过xcb_setup_roots_iterator()函数返回的是一个迭代器,可以通过该迭代器对所有的Screen举办遍历。假如只有一个Screen,则返回的第一个迭代器中的data就指向该Screen。XCB中利用xcb_screen_t布局来生存Screen的信息;

4、建设窗口并显示窗口,这需要三步,第一步先利用xcb_generate_id()函数生成一个ID,第二步利用xcb_create_window()函数建设一个窗口,第三步利用xcb_map_window让窗口显示出来。

通过以上的代码,我还学到了一个能力,那就是利用gettimeofday()函数来获取一个准确到微秒的时间,用来查察应用措施的耗时。

措施运行如下图:

操作XCB编写X Window法子(一) 快速起步

#p#副标题#e#

这个新建设的窗口本身没有配景,所以它建设的时候屏幕上有什么,它窗口内里就有什么。对付措施顶用到的数据布局和列举的寄义,可以直接查察xcb的头文件,共同ctags和taglist.vim插件利用的话,只需要按Ctrl+]键,就可以自动跳转到这些数据布局的界说处(在Vim中利用taglist的要领见这里Linux江湖02:打造属于本身的Vim),如下两图:

操作XCB编写X Window法子(一) 快速起步

操作XCB编写X Window法子(一) 快速起步

#p#副标题#e#

最后,我对第一个简朴的措施举办适当的扩展,看看怎么获取Display中有几个Screen以及怎么遍历Screen,最后显示Screen的一些信息。措施如下:

 1 #include <stdlib.h>
2 #include <sys/time.h>
3 #include <unistd.h>
4 #include <xcb/xcb.h>
5 #include <stdio.h>
6
7 double get_time(){
8 struct timeval timeval;
9 gettimeofday(&timeval, NULL);
10 return (double)timeval.tv_sec + (((double)timeval.tv_usec)/1000000);
11 }
12
13 int main(){
14 double start_time = get_time();
15 int screen_number;
16
17 xcb_connection_t *connection = xcb_connect(NULL, &screen_number);
18 const xcb_setup_t *setup = xcb_get_setup(connection);
19 xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
20 printf("当前的Screen Number为:%d\n",screen_number);
21 printf("iter.rem = %d,下面开始遍历:\n",iter.rem);
22
23 xcb_screen_t *screen;
24 for(; iter.rem!=0; xcb_screen_next(&iter)){
25 screen = iter.data;
26 printf("*****看到几多行这个提示,就说明有几多个Screen。*****\n");
27 printf(" Screen->root:%d\n",screen->root);
28 printf(" Screen->root_depth:%d\n",screen->root_depth);
29 printf(" Screen->white_pixel:%d\n",screen->white_pixel);
30 printf(" Screen->black_pixel:%d\n",screen->black_pixel);
31 printf(" Screen->width_in_pixels:%d\n",screen->width_in_pixels);
32 printf(" Screen->height_in_pixels:%d\n",screen->height_in_pixels);
33 printf(" Screen->width_in_millimeters:%d\n",screen->width_in_millimeters);
34 printf(" Screen->height_in_millimeters:%d\n",screen->height_in_millimeters);
35 }
36
37
38 xcb_window_t window = xcb_generate_id(connection);
39 xcb_create_window(
40 connection,
41 XCB_COPY_FROM_PARENT,
42 window,
43 screen->root,
44 100,100,
45 400, 300,
46 10,
47 XCB_WINDOW_CLASS_INPUT_OUTPUT,
48 screen->root_visual,
49 0, NULL);
50 xcb_map_window(connection, window);
51 xcb_flush(connection);
52
53 printf("耗费时间:%f秒。",get_time()-start_time);
54 fflush(stdout);
55
56 pause();
57 xcb_disconnect(connection);
58 return 0;
59 }

最后运行结果如下图:

操作XCB编写X Window法子(一) 快速起步

作者:cnblogs 京山游侠

    关键字:

在线提交作业