初级X编程2

这篇博客探讨了X编程中窗口的组织体系,包括根窗口、父窗口和子窗口的关系,以及事件传递机制。文章介绍了如何与窗口管理器交互,设置窗口属性、名字和图标,并详细阐述了如何通过分配和释放颜色映射来使用颜色。此外,还讲解了X Bitmaps和Pixmaps的使用,以及如何改变鼠标光标。通过示例代码展示了如何创建、映射和操作窗口,以及使用颜色和光标。
摘要由CSDN通过智能技术生成

窗口们的组织体系

当窗口们被显示在X服务器上时,它们通常按照一定组织体系来排序 - 每个窗口可以有子窗口,每个子窗口又可以有自己的子窗口。让我们来查看这个组织体系的一些特性,看看它们是如何来影响例如绘画和事件等处理。


根窗口,父窗口和子窗口

每一个屏幕上都有一个根窗口。根窗口总是占据整个屏幕尺寸。这个窗口无法被销毁,改变尺寸或者图标化。当一个应用程序创建了一些窗口,它先创建至少一个顶层窗口。在被映射到屏幕上后,这个窗口成为一个根窗口的直接子窗口。这个窗口在被映射到屏幕上之前,窗口管理器被告知什么发生了,然后,窗口管理器获得特权成为新顶层窗口的"父亲"。这通常被用来增加一个会包含新窗口的窗口和绘制框架,标题栏,系统菜单等。

一旦一个顶层窗口(当然它实际上不是一个顶层窗口,因为窗口管理器已经成为它的父窗口了)被创建了,应用程序可以在它里面创建它的子窗口。一个子窗口只能在它的父窗口里显示 - 如果试图把它移动到外面,出去的部分将被父窗口的边框给切掉。任何窗口都可以包含一个以上的子窗口,在这种情况下,这些子窗口将被放置在应用的内部栈上。当一个顶层窗口被打开 - 它的所有子窗口也将随着它被打开。

以下例子演示如何在一个给定的叫"win"的窗口里打开一个子窗口。

Lets see how to create a child window inside a given window 'win'.


/* this variable will store the handle of the newly created child window. */
Window child_win;

/* these variables will store the window's width and height. */
int child_win_width = 50;
int child_win_height = 30;

/* these variables will store the window's location.         */
/* position of the child window is top-left corner of the    */
/* parent window. - 0,0.                                     */
int child_win_x = 0;
int child_win_y = 0;

/* create the window, as specified earlier. */
child_win = XCreateSimpleWindow(display,
                                win,
                                child_win_x, child_win_y,
                                child_win_width, child_win_height,
                                child_win_border_width,
                                BlackPixel(display, screen_num),
                                WhitePixel(display, screen_num));


事件传递

先前我们已经讨论了事件传递 - 如果一个窗口收到了一个它不处理的事件 - 它就把该事件发到它的父窗口去。如果那个父窗口也不处理该事件 - 那个父窗口就把该事件发到它的父窗口上去,接下来依此类推。这种行为对一个简单的Xlib程序是没什么用的,但对于抽象级更高的绘图库是有用的。这些抽象级更高的绘图库通常把某个特定窗口的事件联系到一个函数上去。在这种情况下,发送事件到特定的窗口并用适当的函数来处理就非常有用。


与窗口管理器进行交互

在我们察看了如何创建和绘制窗口之后,我们回过头来看一下我们的窗口是如何与它们的环境 - 整个屏幕和其它窗口进行交互的。首先,我们的程序需要与窗口管理器进行交互。窗口管理器有责任装饰被绘制的窗口(例如增加框架,一个图标化的按钮,一个系统菜单,一个标题栏),同时在窗口被图标化时绘制图标。它还管理屏幕里的窗口排列顺序以及其它可管理的任务。我们需要给它各种提示以让它以我们需要的方式来对待我们的窗口。


窗口属性

许多与窗口管理器交流的参数都通过叫"properties"的数据来传递。X服务器把这些属性贴到各种窗口上,同时把它们存储成一种可以被各种架构的系统所能读取的格式(记住,一个X客户程序可能运行在一台远程主机上)。属性可以是各种类型 - 数字,字符串,等等。大部分的窗口管理器提示函数使用文本属性。一个叫XStringListToTextProperty()的函数可以把C语言的字符串转换成X文本属性,转换后的结果就可以传给各色Xlib函数。以下是一个例子:


/* This variable will store the newly created property. */
XTextProperty window_title_property;

/* This is the string to be translated into a property. */
char* window_title = "hello, world";

/* translate the given string into an X property. */
int rc = XStringListToTextProperty(&window_title,
                                   1,
                                   &window_title_property);
/* check the success of the translation. */
if (rc == 0) {
    fprintf(stderr, "XStringListToTextProperty - out of memory/n");
    exit(1);
}

函数XStringListToTextProperty()接收一个C字符串矩阵(在我们的例子里只有一个)和一个指向XTextProperty型变量的指针为参数,合并C字符串里的属性把值传到XTextProperty型变量里。成功时它返回一个非0值,失败时返回0(例如,没有足够的内存来完成操作)。


设置窗口名字和图标名字

我们需要做的第一件事就是给我们的窗口设置名字。使用函数XSetWMName()。窗口管理器也许会把这个名字显示在窗口标题栏或是在任务栏上。该函数接受3个参数:一个指向显示的指针,一个窗口句柄,和一个包含有我们设置的名字的XTextProperty变量。下面是我们如何做的:


/* assume that window_title_property is our XTextProperty, and is */
/* defined to contain the desired window title.                   */
XSetWMName(display, win, &window_title_property);

为了设置我们的窗口的图标化名字,我们将用相同的方式使用函数XSetWMIconName()。


/* this time we assume that icon_name_property is an initialized */
/* XTextProperty variable containing the desired icon name.      */
XSetWMIconName(display, win, &icon_name_property);

设置满意的窗口尺寸

在各种情况下,我们希望让窗口管理器知道我们指定的窗口尺寸以及只允许用户在我们的限定下改变窗口尺寸。例如,一个终端窗口(像xterm),我们总是要求我们的窗口可以包含全部的行和列,因此我们就不能从中间截断我们的显示。在其它情况下,我们不希望我们的窗口可以被改变尺寸(像绝大部分的对话框窗口),等等。我们可以依赖窗口管理器的这个尺寸信息,虽然它可能被简单的忽视掉。我们首先需要创建一个数据结构来包含该信息,填充必要的数据,然后使用函数XSetWMNormalHints()。下面是如何操作:


/* pointer to the size hints structure. */
XSizeHints* win_size_hints = XAllocSizeHints();
if (!win_size_hints) {
    fprintf(stderr, "XAllocSizeHints - out of memory/n");
    exit(1);
}

/* initialize the structure appropriately. */
/* first, specify which size hints we want to fill in. */
/* in our case - setting the minimal size as well as the initial size. */
win_size_hints->flags = PSize | PMinSize;
/* next, specify the desired limits.                             */
/* in our case - make the window's size at least 300x200 pixels. */
/* and make its initial size 400x250.                            */
win_size_hints->min_width = 300;
win_size_hints->min_height = 200;
win_size_hints->base_width = 400;
win_size_hints->base_height = 250;

/* pass the size hints to the window manager. */
XSetWMNormalHints(display, win, win_size_hints);

/* finally, we can free the size hints structure. */
XFree(win_size_hints);

请查看你的手册来获取尺寸提示的完整信息。


设置各种窗口管理器提示

使用函数XSetWMHints()还可以设置许多其它的窗口管理器提示。该函数使用一个XWMHints结构来传递参数给窗口管理器。下面是例子:


/* pointer to the WM hints structure. */
XWMHints* win_hints = XAllocWMHints();
if (!win_hints) {
    fprintf(stderr, "XAllocWMHints - out of memory/n");
    exit(1);
}

/* initialize the structure appropriately. */
/* first, s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值