当前位置:天才代写 > tutorial > C语言/C++ 教程 > 利用XCB编写X Window措施(二) 在窗口中画图

利用XCB编写X Window措施(二) 在窗口中画图

2017-11-02 08:00 星期四 所属: C语言/C++ 教程 浏览:742

副标题#e#

在上一篇中,我展示了怎么毗连X处事器以及怎么建设一个窗口。建设窗口是编写GUI措施的基础。在GUI编程中尚有别的两个重点,其一是事件处理惩罚,其二是在窗口中画图。这一篇中,将展示如何利用XCB在窗口中举办画图。

先看一个示例代码及其运行结果,代码如下:

#include <stdlib.h>
    #include <stdio.h>
    
    #include <xcb/xcb.h>
    
    int
    main ()
    {
        /* geometric objects */
        xcb_point_t          points[] = {
            {40, 40},
            {40, 80},
            {80, 40},
            {80, 80}};
    
        xcb_point_t          polyline[] = {
            {200, 40},
            { 20, 80},     /* rest of points are relative */
            {100,-80},
            {40, 40}};
    
        xcb_segment_t        segments[] = {
            {400, 40, 560, 120},
            {440, 100, 520, 240}};
    
        xcb_rectangle_t      rectangles[] = {
            { 40, 200, 160, 80},
            { 320, 200, 40, 160}};
    
        xcb_arc_t            arcs[] = {
            {40, 400, 240, 160, 0, 90 << 6},
            {360, 400, 220, 160, 0, 270 << 6}};
    
    
        /* Open the connection to the X server */
        xcb_connection_t *connection = xcb_connect (NULL, NULL);
    
        /* Get the first screen */
        xcb_screen_t *screen = xcb_setup_roots_iterator (xcb_get_setup (connection)).data;
    
        /* Create black (foreground) graphic context */
        xcb_drawable_t  window     = screen->root;
        xcb_gcontext_t  gc = xcb_generate_id (connection);
        uint32_t        mask       = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
        uint32_t        values[2]  = {screen->black_pixel, 0};
    
        xcb_create_gc (connection, gc, window, mask, values);
    
    
        /* Create a window */
        window = xcb_generate_id (connection);
    
        mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
        values[0] = screen->white_pixel;
        values[1] = XCB_EVENT_MASK_EXPOSURE;
    
        xcb_create_window (connection,                    /* connection          */
                           XCB_COPY_FROM_PARENT,          /* depth               */
                           window,                        /* window Id           */
                           screen->root,                  /* parent window       */
                           0, 0,                          /* x, y                */
                           800, 600,                      /* width, height       */
                           10,                            /* border_width        */
                           XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
                           screen->root_visual,           /* visual              */
                           mask, values );                /* masks */
    
    
        /* Map the window on the screen and flush*/
        xcb_map_window (connection, window);
        xcb_flush (connection);
    
    
        /* draw primitives */
        xcb_generic_event_t *event;
        while ((event = xcb_wait_for_event (connection))) {
            switch (event->response_type & ~0x80) {
            case XCB_EXPOSE:
                /* We draw the points */
                xcb_poly_point (connection, XCB_COORD_MODE_ORIGIN, window, gc, 4, points);
    
                /* We draw the polygonal line */
                xcb_poly_line (connection, XCB_COORD_MODE_PREVIOUS, window, gc, 4, polyline);
    
                /* We draw the segments */
                xcb_poly_segment (connection, window, gc, 2, segments);
    
                /* draw the rectangles */
                xcb_poly_rectangle (connection, window, gc, 2, rectangles);
    
                /* draw the arcs */
                xcb_poly_arc (connection, window, gc, 2, arcs);
    
                /* flush the request */
                xcb_flush (connection);
    
                break;
            default: 
                /* Unknown event type, ignore it */
                break;
            }

    
            free (event);
        }
    
        return 0;
    }


#p#副标题#e#

运行结果如下图:

操作XCB编写X Window法子(二) 在窗口中绘图

下面,对以上GUI画图的措施举办阐明:

1、任何画图措施,无论利用的是Win32 API,照旧Java Swing,都离不开GC和DC的观念,利用XCB编写窗口措施也是如此。这两个观念,一个代表了图怎么绘,一个代表了图绘在那边。由于画图时需要指定太多的信息,好比画笔的粗细、线型、前景致、配景致等等,假如把这些信息统统作为参数通报给画图函数,就会发生两个问题:一是挪用这些函数太巨大,二是效率太低。所以,今朝所有主流的GUI库都回收了一致的做法,那就是把这些信息组织成一个context,我们称之为graphic context,可简称gcontext或GC。DC可以认为是画图时所用的画布,我们可以直接把图绘到屏幕上,也可以把图绘到窗口中,虽然,也可以绘到控件中(因为控件的本质也是窗口)。在面向工具的编程语言中,可以画图的组件往往都担任自Drawable。在XCB中,从画图函数的签名可以看出,它仍然将画图的方针称为drawable,固然它只是一个id。

#p#分页标题#e#

2、什么时候画图。理论上讲,任何时候都可以挪用画图函数。可是从实践上来讲,所有的GUI措施都是在窗口重绘的事件中挪用画图函数。窗口重绘事件,有的叫onPaint,有的叫onDraw,XCB中较量奇怪,叫EXPOSE。不管叫什么,其原理是一样的。那就是当窗口初次显示、从埋没到显示或窗口内容需要刷新时,城市触发该事件,所以在处理惩罚该事件的代码中挪用画图函数是最好的,既可以担保我们看到画图的功效,又分身效率(窗口不行见时画图函数不消执行,窗口稳定革时画图函数也不消执行)。MVC模式也是构建在这样的基本之上,将数据与显示疏散,数据可以随时被操纵,可是画图只在窗口重绘时举办。

#p#副标题#e#

3、挪用画图函数。这个不需要多讲,因为险些所有的画图函数都是自表明的,看到函数名,就知道它要举办什么操纵。

在XCB中,建设GC可以通过xcb_create_gc()函数举办,建设窗口可以通过xcb_create_window()函数举办。在这两个函数中,都有一个较量奇怪的模式,那就是通过一个mask和value数组来设定GC和窗口的详细信息。在上一篇中,建设的窗口没有配景,而这一篇中,窗口具有白色配景,就是因为这里挪用xcb_create_window时,在其mask参数中指定了XCB_CW_BACK_PIXEL。

借助于ctags和Vim的taglist.vim插件,可以很是利便地查察这些mask的取值及其意义,只需按下Ctrl+]就可以跳到相应的界说处。如下两图,是enum xcb_gc_t中界说的一系列XCB_GC_***:

操作XCB编写X Window法子(二) 在窗口中绘图

操作XCB编写X Window法子(二) 在窗口中绘图

#p#副标题#e#

再下面两个图,是建设窗口是可以用到的mask值:

操作XCB编写X Window法子(二) 在窗口中绘图

操作XCB编写X Window法子(二) 在窗口中绘图

这些列举都有很具体的注释,所以我就不在这里烦琐了。libxcb的头文件中的注释,自己就是一种很好的进修资料,不是吗?

作者:cnblogs 京山游侠

 

    关键字:

天才代写-代写联系方式