第二章 X Programming 的第一步

Index:
基本步骤
建立一个 display至 X Server
取得 display的相关资料
建立视窗
和视窗管理程式(Window Manager)沟通
显示视窗
关闭(destroy)视窗
关闭 display



--------------------------------------------------------------------------------
一个 X 的程式的几个基本步骤:
main() {
        建立一个 display 至 X Server;
        取得 display 的相关资料;
        设定视窗(window)特性(Attributes);
        建立视窗(window);
        和视窗管理程式(window manager)进行沟通;
        显示(map)视窗;
        ......  ......
        ... 程式处理 ...
        .............
        关闭(destroy)视窗;
        关闭 display;
}


1. 建立一个 display 至 X Server


在程式开始向 X Server 进行任何的动作之前,程式必需先和 X Server 之间建立一个连线(connection),我们称之为 display。 XOpenDisplay 即为 Xlib 提供给我建立 display 的函数。
--------------------------------------------------------------------------------
Display *XOpenDisplay(display_name)
char *display_name;

 指定要连接之 server。如果 display_name 设定为NULL,则内定使用环境变量(environment variable)DISPLAY 的内容为连接对像。
--------------------------------------------------------------------------------
呼叫 XOpenDisplay 之後,会传回一个 Display 结构。 Display 结构存放着一些关於 display 的资讯。
虽然我们可以直接存取 Display 结构,但我们不该迳自改变其内容。 Xlib 有提供一系列的函数和巨集 (macro),我应该透过这些函数
和巨集(macro)存取 Display 的内容。 以维持 Xlib 的正常运作。

display_name 或是 DISPLAY 环境变数(environment variable)的格式 如下:
--------------------------------------------------------------------------------
        hostname:number.screen_number
hostname
        设定 display 所在主机(host)之名称,在主机名称之後紧接着的是单
        个冒号(:)或是双冒号(::)。
number        指定主机上,display server 的编号。一台主机(host)上可能同时存
        有多个 server,每个 server 都会给与一个编号,这个编号从零开始
        。在 server 的编号後面有一个句点(.),这个依你是否设定後面的
        screen_number 而决定是否该加。
screen_number
        每一个 server 可能同时管理着多个显示幕,而每一个显示幕我们也给
        与一个从零开始的编号。screen_number 也就是设定着这个编号,做为
        default 的 screen。当你使用 DefaultScreen 巨集或是
        XDefaultScreen 函数时,即会存取到这个值。
--------------------------------------------------------------------------------
举例:
        Display *display;
        display = XOpenDisplay("cnpa.yzu.edu.tw:0");
建立与 cnpa.yzu.edu.tw 上第零个 server 的 display。


2. 取得 display 的相关资料

 

 

 

在我们建立视窗之前,我们必需对目标 display 和萤幕(screen)的属性状况有所了解。 我们可以透过 Xlib 所提供的巨集
(macro)和函数 (function)取得指定 display 和萤幕(screen)的资料,利用这些资料 以设定视窗参数,以应不同的萤幕建
构合适的视窗。
建立视窗,我们必需设定多种和目标萤幕(screen)相关的参数。我们就 这些参数设定的需要,介绍如何利用 Xlib 来取得关於 display 的资 料。
--------------------------------------------------------------------------------
DefaultRootWindow(display)
Window XDefaultRootWindow(display)
        Display *display;
        display                指定至 X server 的连结(connection),即XOpenDisplay 所传回之结构。
--------------------------------------------------------------------------------
传回预定萤幕(default screen)的根(root)视窗。每一个视窗都有父视窗(parent window),当你要在程式开启一个最上层的视窗(top window);不是程式其它视窗的子视窗。那麽,由於己没有其它更上层 的视窗可以当父视窗,所以必需设根视窗(root window)为该视窗的父视窗 (parent window)。我们使用 DefaultRootWindow 取得预定萤幕的根视窗(root window),可以在建立新视窗时,以任一根视窗(root window) 做为新视窗的父视窗(parent window)。透过指定父视窗(root window) ,我们也指定了负责显示新视窗的萤幕(screen)。
--------------------------------------------------------------------------------
DefaultDepth(display, screen_number)
int XDefaultDepth(display, screen_number)
                Display *display;
                int screen_number;
        display                指定连至 X Server 的连接(connection)。
        screen_number        指定萤幕的编号。
--------------------------------------------------------------------------------
传回指定萤幕根视窗(root window)的预定深度(depth)。每个视窗都有自己的深度(depth),深度影着该视窗所能显示的颜色数。当一个视窗的深度大,则其同时能显示的颜色总数也会随之增加。但,深度( depth)并非无限量的增加,会受限於硬的限制。一般我们会参考根视窗(root window)的设定。
--------------------------------------------------------------------------------
        DefaultScreenOfDisplay(display)
        Screen *XDefaultScreenOfDisplay(display)
                Display *display;
        display                指定一个 X Server 的连结(connection)
--------------------------------------------------------------------------------
传回指向预定萤幕(default screen)的指针。预定萤幕(default screen)即建立 display 时,在 display name 指定的 screen number。
--------------------------------------------------------------------------------
        DefaultVisualOfScreen(screen)
        Visual *XDefaultVisualOfScreen(screen)
                Screen *screen;
        screen                指定适当的 Screen 结构。
--------------------------------------------------------------------------------
传回预定萤幕(default screen)的预定视觉(default visual)。在某些显示设备上,允许同时以多种不同的方式理颜色的显示。我们可以任意 的方式,将深度(depth)为 8-bits 的图素(pixel)对映到显示的颜色。 也可以将深度(depth)为 24-bits 的图素(pixel),以红、黄、蓝各为 8-bits 的方式对映到实际的颜色。图素(pixel)指的是画面上的一个点 ,这指的是代表该点颜色的一个编号。

 

 

例如,我们可能以 7 做为RGB 值为 0x9f7071 的颜色的编码,则任何图素(pixel)为 7 的点,其颜色 则为
RGB 0x7f7071。


3. 建立视窗

 

 

 

我现在开始建立新视窗(window)。视窗(window)建立之後,并不会马上 在我们指定的显示器(screen)上显示出来。我们要经过
一道 map 的手 序後,视窗(window)才会正式在显示器上显示出来。在我们建立视窗( window)之後,在 map 之前,我们可以对新视
窗(window)做一些设定的 动作,以设定视窗(window)的行为特性。

 

 


建立新视窗(window)要透过 Xlib 所提供的 XCreateWindow 函数或者 XCreateSimpleWindow 函数,XCreateSimpleWindow 是 XCreateWindow 的简化版。这两个函数可用来建立新的子视窗。
--------------------------------------------------------------------------------
        Window XCreateWindow(display, parent, x, y, width, height,
                border_width, depth, class, visual, valuemask, attributes)


                Display *display;
                Window parent;
                int x, y;
                unsigned int width, height;
                unsigned int border_width;
                int depth;
                unsigned int class;
                Visual *visual;
                unigned long valuemask;
                XSetWindowAttributes *attributes;


        display                指定到 X Server 的连结。
        parent                指定父视窗(parent window)。
        x, y                     指定视窗边框(border)的左上角相对於父视窗(parentwindow的座标。也就是以父视窗(parent window)内部的左上角做为原点所求得的相对座标。此座标用来指定视窗的显示位子。
        width, height      视窗内部尺寸的宽度和高度,高度和宽度并不包括边框(border)的部分。这些尺寸不能为度,否则会造成
                                   BadValue 的错误结果。
        border_width      设定视窗边框(border)的宽度,其单位为图素(pixels),也就是指定其边框的宽度是几个图素(pixels)。
        depth                  设定新视窗的颜色深度(depth),若指定 depth 的值为CopyFromParent,则深度(depth)将会从父视窗(parent window)取得。
        class                    指定视窗的类别(class)。你可以指定为 InputOutput,InputOnly 或 CopyFromParent 其中一种。若指为
                                   CopyFromParent 则表示将由父视窗(parent window)取得。
        visual                  设定视觉(visual)的种类。设为 CopyFromParent 则会取自父视窗。
        valuemask          用以设定在 attributes 参数设定了那些视窗属性
                                  (attribut)的遮罩(mask)。在这个遮罩(mask),每一
                                   bit 代表着一项属性(attribut),我们以 OR 位元运算
                                  ,将代表各项属性的遮罩(mask)组合起来。若为零,则会乎略 attributes 参数。
        attributes        这是一个存放视窗属性(attribut)的结构(structure),配合设定正确的遮罩(mask),用以设定视窗的属性。
--------------------------------------------------------------------------------


/* Values */
typedef struct {
        Pixmap background_pixmap;
        unsigned long background_pixel;
        Pixmap border_pixmap;
        unsigned long border_pixel;
        int bit_gravity;
        int win_gravity;
        int backing__store;
        unsigned long backing_planes;
        unsigned long backing_pixel;
        Bool save_under;
        long event_mask;
        long do_not_propagate_mask;
        Bool override_redirect;
        long event_mask;
        long do_not_propagate_mask;
        Bool override_redirect;
        Colormap colormap;
        Cursor cursor;
} XSetWindowAttributes;


/* Window attribute value mask bits */
#define CWBackPixmap                (1L
#include
#include
#include
main() {
        Display *display;
        Window window;
        XSetWindowAttributes attr;
        XSizeHints *sz;
       
        /* 建立一个 display 的 connection */
        display = XOpenDisplay("0:0");
        /* 建立和设定 window 的属性 */
        window = XCreateWindow(display, XDefaultRootWindow(display),
                100, 100, 300, 300, 2, XDefaultDepth(display, 0),
                InputOutput, CopyFromParent, 0, &attr);
        /* 和 Window Manager 进行沟通 */
        XStoreName(display, window, "hello!! world!!");
        sz = XAllocSizeHints();
        sz->x = 100;
        sz->y = 100;
        sz->width = 300;
        sz->height = 300;
        sz->flags = USPosition | USSize;
        XSetNormalHints(display, window, sz);
        /* Mapping Window  正式影射到显示器画面*/
        printf("Map window/n");
        XMapWindow(display, window);
        getchar();        /* 至此,视窗已执行 Map 的动作了,但
                           显示器上,却可能看不到。*/
       
        printf("XFlush/n");
        XFlush(display);
        getchar();        /* 这,你应该就看到显示器上的变化了 */
       
        /*
           .................
           .... 程式处理部分 ..
           ....................
        */
        /* 关闭视窗 */
        printf("Destory Window/n");
        XDestroyWindow(display, window);
        getchar();
       
        printf("XFlush/n");
        XFlush(display);
        getchar();
        /* 关闭 display */
        printf("close display/n");
        XCloseDisplay(display);
        getchar();
}
--------------------------------------------------------------------------------
        gcc -o Xtest Xtest.c -L/usr/X11R6/lib -lX11
--------------------------------------------------------------------------------
上面是一个简单的例程式和 compile 的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值