Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1631180
  • 博文数量: 584
  • 博客积分: 13857
  • 博客等级: 上将
  • 技术积分: 11883
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-16 09:34

分类: LINUX

2010-06-25 14:55:34

Index:
Create windows/Destroy windows 
    Class 
    Visual Types 
    Depth 
    Create 
    Destroy 
Map windows/Unmap windows 
    Events 
    SubstructureRedirectMask 
    Mapping/UnMapping Fuctions 
Configure windows 
    XWindowChanges 
    Convenient functions 
Change the stacking order 
Change window attributes 
    background 
    border 
    bit-gravity 
    win-gravity 
    backing-store 
    save-under 
    event-mask 
    do-not-propagate-mask 
    override-redirect 
    colormap 
    cursor 

--------------------------------------------------------------------------------


Create windows/Destroy windows
Class
X Window 系统的视窗可分为两类(两种 Class),InputOnly 和 InputOutput。 InputOnly 的视 窗,
顾名思意就是只能做为 Input 使用,也就是 client 程式只能透过这个视窗来收取 event,但是不
能在这个视 窗做任何的输出。而 InputOutput 视窗则不只可以接受输入而己, 而且也可以使用该
视窗做输出。你可以在 InputOutput 视窗上输出 文字图形,却不能在 InputOnly 视窗上这麽做。
InputOnly 视窗 由於并没有输出的能力,所以并不会出现在画面上。虽然如此,实 际上它还是存在
的。其主要功能是用来做输入的控制,例如让 标进入其区域时,立即变成另一种的形式。这样的可
以让使用者感 觉到标在 parent 视窗的某个区域采用不同的标。既然 InputOnly 没有输出的能力,
所以 InputOnly 视窗也不能做为 drawable 使用。

Visual
在有些硬体上可能提供多种颜色的对映方式。例如有些硬体可能提供 了 16bits 的模式,也就是显示
出来的每个点使用 16bits 长度的 pixel 值表示。同时也可能提供 8bits 的模式,每个点的颜色使用
 8bits 长度的 pixel 值表示。这种 pixel 值的大小称 depth,例如 使用 8bits 来表示颜色,则其 
 depth 为 8。除了表示的位元数不同外 ,颜色和 pixel 值之间的对映方式也不同。像一般以 RGB 为
 基础的 硬,如果采用 8bits 的模式可能 3bits 对映为 red,3bits 对映 为 green,2bits 对映为 
 blue。这种对映的方式称为 visual。

Xlib 使用 Visual 这个结构存放对映的 visual 资料,而 Visual 实际内容被包装起来,不让使用者
直接接触。Xlib 提供一些应用的 函数和巨集,让 programmer 透过这些功能来操作 Visual 结构。 
下面是所有的 visual 种类及其对 colormap 和 RGB 的影。 
PseudoColor 
pixel 值对映到 colormap 而产生 RGB 值,RGB 值可以随时更改而不 影到已输出的点。 
GrayScale 
和 PseudoColor 差不多,主要的不同在 RGB 值不能更改,否则会影 到已输出的点的颜色。 
DirectColor 
pixel 被分成 R,G,B 三个部分,这三个部分分别对映 colormap 得到 三个值。从 colormap 得到的
三个值,可以组合成对映的颜色值。 colormap 的 RGB 值可以随时更换,并且不会因而影项到已输出 
的点之颜色。 
TrueColor 
和 DirectColor 近似,但是 colormap 内的 RGB 值是内定的,而且不能更改。不同的硬所提供的 
colormap 不尽相同,但在 RGB 各个原色的 colormap 中,大多会提供线性或接进线性变化的 RGB 值。 
StaticColor 
和 PseudoColor 的不同在於其 colormap 的 RGB 值是预定的,无法修改的。 
StaticGray 
和 StaticColor 相似,但任何单一点的 RGB 值都一样,其实就是单色的意思。 
Depth
depth 就如先前所说的,用以表示对映颜色的资料长度。以 8bits 的 pixel 值表示对映颜色,则 
depth 为 8。 
Create
Xlib 提供 XCreateWindow 建立 unmapped 的视窗: 
--------------------------------------------------------------------------------

     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
           unsigned long valuemask;
           XSetWindowAttributes *attributes;


--------------------------------------------------------------------------------
如果成功建立视窗的话,XCreateWindow 会传回一 Window ID,用以 往後指定视窗,并且产生 
CreateNotify event。新建立的视窗,会是 parent 参数所指定之视窗的子 视窗(subwindow)。x 和 y 
则指定视窗左上角相对於 parent 视窗左 上角的座标。width 和 hieght 指定视窗的宽和高。border_width 
和 depth 分别是视窗边框的宽度和视窗的 depth,depth 并不需要和 parent 一样。视窗的 class 为 
InputOnly ,border_width 和 depth 必需指定为零,否则会产生 BadMatch error。 InputOutput 视窗的 
parent 规定必需也是 InputOutput,否则会产生 BadMatch error,InputOnly 则无这种限 制。 visual 
必需设为硬体有提供的 visual。valuemask 和 attributes 则合力指定视窗的属性,在後面会谈到。

XCreateSimpleWindow 则是简易版,用於建立 InputOutput 视窗: 
--------------------------------------------------------------------------------

     Window XCreateSimpleWindow(display, parent, x, y, width, height,
      border_width, border, background)
           Display *display;
           Window parent;
           int x, y;
           unsigned int width, height;
           unsigned int border_width;
           unsigned long border;
           unsigned long background;


--------------------------------------------------------------------------------
参数的指定和 XCreateWindow 都差不多,border 是指定边框的 pixel 值,background 指定背景的 
pixel 值。

Destroy
任何一个视窗被关掉(移除; destroy)都会产生 DestroyNotify event。 parent 视窗被关掉,子视窗也
会因而被关掉,而且会 parent 视窗关 掉之前先自动关掉子视窗。这时,任何被关掉的视窗,包括子视窗
和 parent 视窗,都会产生 DestroyNotify event。

XDestroyWindow 是用以关闭指定之视窗及其子视窗。 
--------------------------------------------------------------------------------

  XDestroyWindow(display, w)
        Display *display;
        Window w;


--------------------------------------------------------------------------------


XDestroySubwindows 关闭指定视窗的所有子视窗,但不包括指定 之视窗。 
--------------------------------------------------------------------------------

  XDestroySubwindows(display, w)
        Display *display;
        Window w;


--------------------------------------------------------------------------------

Map windows/Unmap windows
Events
视窗被建立之後,并不会立即出现在萤幕上,在显示之前还要经过一个 称为 mapping 的动作。map 一个
子视窗後,如果其任何一个 ancest 视窗(先视窗)是在 unmapped 状态(未曾被 map, 或者曾被 map 但又
 被 unmap 了)则子视窗还是不会显示出来,我们称之为 unviewable。 子视窗必需等到其所有 ancest 
 视窗都在 mapped 的状态下时,才会从 unviewable 的状态进入到 viewable 状况。视窗只有在 viewable 
 的状 态下才会被显示。将视窗 unmap 会使的视窗和其子视窗都隐形起来。任 何一个视窗只要有任何一个
  ancest 视窗被 unmap,都会使该视窗从显 示器上消失(隐形起来),也就是进入 unviewable 的状态。

当视窗被 map 时,X Server 会产生 MapNotify evnet。而 unmap 时,会 产 件 UnmapNotify event。当视
窗由 unviewable 进入 viewable 状态, 并且没有全部被其它视窗遮住,则 X Server 会产 生 Expose event。
 任何时候,只要视窗的任何一部分从在显示上看不到 的状态变成看的到的状态,就会产生 Expose evnet。

SubstructureRedirectMask
如果有 client 程式对 parent 视窗设定 SubstructureRedirectMask,则其它的 client 对子视窗 发出的
 Map request 都会被转送给设定 SubstructureRedirectMask 的 client,而且 该 Map request 并不会被
 进行。Window Manager 就是采用这个方式,对 root 视窗设定 SubstructureRedirectMask ,因而 能攫取
 其它 client 对 root 视窗的子视窗(top window)所送 出的 Map request,而收 到 MapRequest Event。
 透过这样的方式, Window Manager 能控制视窗的外观和行为。但,事情并不完全这样 的,如果子视窗
 (child window)的 override-redirect flag 被设为 True,会使这种转送(redirect)机制失 效,其它视窗
 所产生的 Map request 将不再被转送给在父视窗设定 SubstructureRedirectMask 的 client。

类似於 SubstructureRedirectMask 的情形也发生在 ResizeRedirectMask。如果 有 client 对 parent window
 设定 ResizeRedirectMask,则其它 client 对 child window 的 Resize request 同样 也会被转送给对 
 parent window 设定 ResizeRedirectMask 的 client。如 果 child window 的 override-redirect flag 被
 设为 True,同样的,这种转送机制 也会失效。

Mapping/UnMapping Fuctions

--------------------------------------------------------------------------------

  XMapWindow(display, w)
        Display *display;
        Window w;

  XMapRaised(display, w)
        Display *display;
        Window w;

  XMapSubwindows(display, w)
        Display *display;
        Window w;


--------------------------------------------------------------------------------
XMapRaised() 除了 map 指定的视窗之外,还会使的视窗上到 window stack 的最上面,使的视窗出现在画面
的最上面,不会被 其它的视窗挡住。而 XMapSubwindows() 则是 map 指定视窗的所 有子视窗。

Configure windows
XWindowChanges

--------------------------------------------------------------------------------

     /* Configure window value mask bits */
     #define   CWX                         (1<<0)
     #define   CWY                         (1<<1)
     #define   CWWidth                     (1<<2)
     #define   CWHeight                    (1<<3)
     #define   CWBorderWidth               (1<<4)
     #define   CWSibling                   (1<<5)
     #define   CWStackMode                 (1<<6)
     /* Values */

     typedef struct {
          int x, y;
          int width, height;
          int border_width;
          Window sibling;
          int stack_mode;
     } XWindowChanges;


--------------------------------------------------------------------------------

x,y 
顾名思意, x,y 栏位设定视窗的左上角位置. 
width,height 
视窗的宽(width)和高(height) 
border_width 
视窗边框的宽度 
sibling,stack_mode 
sibling 和 stack_mode 是相关的, 在 sibling 设定一个 window ID, 此视窗和 欲设定其属性的视窗
为兄弟(sibling;同一个 parent window). stack_mode 指定 视窗重叠顺序如何调整. 
我们可以使用 XConfigureWindow 来对视窗设定一些属性. 
--------------------------------------------------------------------------------

     XConfigureWindow(display, w, value_mask, values)
           Display *display;
           Window w;
           unsigned int value_mask;
           XWindowChanges *values;


--------------------------------------------------------------------------------
values 传入一些视窗的属性, 是一个 (XWindowChanges *)的指标. XWindowChanges 请参考上表. 
value_mask 用以表示被修改的 属性部分. 若指 定 values->sibling 和 values->stack_mode, 则 w 
视窗的重叠次序会如下改变: 
Above 
w 视窗的重叠次序会重新排在 sibling 的上面. 
Below 
w 视窗的重叠次序会重新排在 sibling 的下面. 
TopIf 
若 sibling 视窗完全盖住 w 视窗, 则 w 视窗的次序会重新排在最上面. 
ButtomIf 
若 w 视窗完全盖住 sibling 视窗, 则 w 视窗的次序会重新排在最下面. 
Opposite 
若 sibling 视窗完全盖住 w 视窗, 则 w 视窗的次序会重新排在最上面. 若 w 视窗完全盖住 sibling
 视窗, 则 w 视窗的次序会重新排在最下面. 
若只指定 values->stack_mode, 而未指定 values->sibling, 则 w 视窗的重叠次序会如下改 变: 
Above 
w 视窗的重叠次序会重新排在任何其它兄弟视窗的上面(最上面;top). 
Below 
w 视窗的重叠次序会重新排在任何其它兄弟视窗的下面(最下面;buttom). 
TopIf 
若有任何其它兄弟视窗盖住 w, 则 w 的重叠次序会重新排在最上面. 
ButtomIf 
若 w 盖住任何其它兄弟视窗, 则 w 的重叠次序会重新排在最下面. 
Opposite 
若有任可其它兄弟视窗盖住 w, 则 w 的重叠次序会重新排在最上面. 若 w 盖住任何其它兄弟视窗, 
则 w 的重叠次序会重新排在最下面. 

--------------------------------------------------------------------------------

#include 
#include 
#include 
#include 
#include 


Display *display;
Window window;
GC gc;


void
draw()
{
XDrawRectangle(display, window, gc, 10, 10, 100, 100);

XDrawLine(display, window, gc, 200, 10, 200, 290);
}


main()
{
XSetWindowAttributes attr;
Colormap colormap;
XColor color1, color2;
XGCValues gcvalue;
XSizeHints *sz;
unsigned int vmask;
XWindowChanges values;

display = XOpenDisplay("0:0");

colormap = DefaultColormap(display, DefaultScreen(display));
color1.red = color1.blue = 0xffff;
color1.green = 0;
color2.red = color2.green = color2.blue = 0xff;
color1.flags = color2.flags = DoRed | DoGreen | DoBlue; 
XAllocColor(display, colormap, &color1);
XAllocColor(display, colormap, &color2);

attr.background_pixel = color2.pixel;
window = XCreateWindow(display, XDefaultRootWindow(display),
50, 100, 400, 300, 2, XDefaultDepth(display, 0),
InputOutput, CopyFromParent, CWBackPixel, &attr);

XStoreName(display, window, "hello!! world!!");
sz = XAllocSizeHints();
sz->x = 50;
sz->y = 100;
sz->width = 400;
sz->height = 300;
sz->flags = USPosition | USSize;
XSetNormalHints(display, window, sz);
XMapWindow(display, window);
XFlush(display);

gc = XCreateGC(display, window, 0, &gcvalue);
XSetLineAttributes(display, gc, 5, LineOnOffDash,
CapButt, JoinRound);
XSetForeground(display, gc, color1.pixel);
XSetBackground(display, gc, color2.pixel);
XFlush(display);
sleep(2);
draw();
XFlush(display);
sleep(3);

printf("XConfigureWindow()\n");
values.x = 100;
values.y = 50;
values.width = 300;
values.height = 200;
vmask = CWX | CWY | CWWidth | CWHeight;
XConfigureWindow(display, window, vmask, &values);
XFlush(display);
sleep(2);
draw();
XFlush(display);
sleep(3);

XDestroyWindow(display, window);
XFlush(display);

XCloseDisplay(display);
}


--------------------------------------------------------------------------------
上例是改变视窗的位置和大小, 位置在萤幕上 (100, 50) 的位置, 大小为宽高各为 300 和 200. 
Convenient functions

--------------------------------------------------------------------------------

     XMoveWindow(display, w, x, y)
           Display *display;
           Window w;
           int x, y;

     XResizeWindow(display, w, width, height)
           Display *display;
           Window w;
           unsigned int width, height;

     XMoveResizeWindow(display, w, x, y, width, height)
           Display *display;
           Window w;
           int x, y;
           unsigned int width, height;

     XSetWindowBorderWidth(display, w, width)
           Display *display;
           Window w;
           unsigned int width;


--------------------------------------------------------------------------------

XMoveWindow, XResizeWindow, XMoveResizeWindow, XSetWindowBorderWidth, 分 别为移动视窗, 
改变视窗大小, 移动并改变视窗大小, 和设定视窗的外框的 宽度, 是一些简单方便的函数, 可以简
化 XConfigureWindow 的使用. 
Change the stacking order
在 X 的 window 常因为相互重叠, 而使的视窗部方的画面被其它视窗挡 住. 这种视窗重叠的上下次
序称为 stack order. 
--------------------------------------------------------------------------------

  XRaiseWindow(display, w)
        Display *display;
        Window w;

  XLowerWindow(display, w)
        Display *display;
        Window w;


--------------------------------------------------------------------------------
上面两个函数正是把视窗在 stack 的顺序移至最上面(raise)和 最下面(lower). 
--------------------------------------------------------------------------------

  XCirculateSubwindows(display, w, direction)
        Display *display;
        Window w;
        int direction;


--------------------------------------------------------------------------------
XCirculateSubwindows 改变有子视窗的 stack order, 'direction ' 为 移动的方 向, RaiseLowest 把
所有视窗往上移动一个位子, 最上面的视窗 则回到 stack 的最下面, LowerHighest 则反之. 
--------------------------------------------------------------------------------

  XCirculateSubwindowsUp(display, w)
        Display *display;
        Window w;

  XCirculateSubwindowsDown(display, w)
        Display *display;
        Window w;


--------------------------------------------------------------------------------
和 XCirculateSubwindows 功能重, 但比较易於使用. 
--------------------------------------------------------------------------------

  XRestackWindows(display, windows, nwindows);
        Display *display;
        Window windows[];
        int nwindows;


--------------------------------------------------------------------------------
透过 XRestackWindows 可以直接指定 stack order. windows 传入 依次序存放的 Window 阵列, 
nwindows 则是阵列的长度. 
Change window attributes
视窗除了位置和大小之外, 还有其它不同的属性, 控制视窗的外观和行为. 
--------------------------------------------------------------------------------

     /* Window attribute value mask bits */
     #define   CWBackPixmap                (1L<<0)
     #define   CWBackPixel                 (1L<<1)
     #define   CWBorderPixmap              (1L<<2)
     #define   CWBorderPixel               (1L<<3)
     #define   CWBitGravity                (1L<<4)
     #define   CWWinGravity                (1L<<5)
     #define   CWBackingStore              (1L<<6)
     #define   CWBackingPlanes             (1L<<7)
     #define   CWBackingPixel              (1L<<8)
     #define   CWOverrideRedirect          (1L<<9)
     #define   CWSaveUnder                 (1L<<10)
     #define   CWEventMask                 (1L<<11)
     #define   CWDontPropagate             (1L<<12)
     #define   CWColormap                  (1L<<13)
     #define   CWCursor                    (1L<<14)
     /* Values */

  typedef struct {
       Pixmap background_pixmap;/* background, None, or ParentRelative */
       unsigned long background_pixel;/* background pixel */
       Pixmap border_pixmap;    /* border of the window or CopyFromParent */
       unsigned long border_pixel;/* border pixel value */
       int bit_gravity;         /* one of bit gravity values */
       int win_gravity;         /* one of the window gravity values */
       int backing_store;       /* NotUseful, WhenMapped, Always */
       unsigned long backing_planes;/* planes to be preserved if possible */
       unsigned long backing_pixel;/* value to use in restoring planes */
       Bool save_under;         /* should bits under be saved? (popups) */
       long event_mask;         /* set of events that should be saved */
       long do_not_propagate_mask;/* set of events that should not propagate */
       Bool override_redirect;  /* boolean value for override_redirect */
       Colormap colormap;       /* color map to be associated with window */
       Cursor cursor;           /* cursor to be displayed (or None) */
  } XSetWindowAttributes;


  XChangeWindowAttributes(display, w, valuemask, attributes)
        Display *display;
        Window w;
        unsigned long valuemask;
        XSetWindowAttributes *attributes;


--------------------------------------------------------------------------------
XChangeWindowAttributes 设定视窗的各种属性, 各种属性的意义在後面 的小节会一一介绍. 'valuemask' 
是根据设定的 attributes 栏位而 定, 把有设定的栏位的对应 mask 做 OR 运算. 
--------------------------------------------------------------------------------

Display *d;
Window w;
XSetWindowAttributes attr;
unsigned long vmask;

...............
........

attr.save_under = True;
attr.override_redirect = False;
vmask = CWOverrideRedirect | CWSaveUnder;
XChangeWindowAttributes(d, w, vmask, &attr);


--------------------------------------------------------------------------------

background
视窗的背景可以涂上单一颜色, 或者是贴上不同的图案. 
--------------------------------------------------------------------------------

  XSetWindowBackground(display, w, background_pixel)
        Display *display;
        Window w;
        unsigned long background_pixel;

  XSetWindowBackgroundPixmap(display, w, background_pixmap)
        Display *display;
        Window w;
        Pixmap background_pixmap;


--------------------------------------------------------------------------------
XSetWindowBackground 用以设定背景颜色, 'background_pixel' 则为 背景的颜色. 功能和设定 
XSetWindowAttributes 中的 background_pixel 栏位的功能相 同. XSetWindowBackgroundPixmap 
则是设定背景为一张图 (pixmap), 相当於设定 background_pixmap 栏位. 
border
设定视窗的外框颜色或图形. 
--------------------------------------------------------------------------------

  XSetWindowBorder(display, w, border_pixel)
        Display *display;
        Window w;
        unsigned long border_pixel;

  XSetWindowBorderPixmap(display, w, border_pixmap)
        Display *display;
        Window w;
        Pixmap border_pixmap;


--------------------------------------------------------------------------------

bit-gravity
设定视窗的 bit-gravity, bit-gravity 控制 InputOutput 视窗 resize 时, 视窗的内容如何维 持. 
当视窗的大小改变时, 视窗的内容不会改变, 但是会因为视窗大小的改变而移动其在视窗内的相对位置
(相对於左上角). 当视窗的宽和高改变了 w 和 h, 则任何一点(x,y)的位置会如下改变: 
NorthWestGravity (0,0) 
NorthGravity (w/2,0) 
NorthEastGravity (w,0) 
WestGravity (0,h/2) 
CenterGravity (w/2,h/2) 
EastGravity (w,h/2) 
SouthWestGravity (0,h) 
SouthGravity (w/2,h) 
SouthEastGravity (w,h) 

win-gravity
win-gravity 和 bit-gravity 类似, 但控制的对像是视窗内的子视窗的位置. 
backing-store
有些 X Server 会帮视窗储存其内容, 当视窗的内容 lost 而需要重绘时, Server 会使用先前储存的
内容自动补回去, 这样的动作称为 backing store. backing-store 控制这项功能是否作用, 其状态可
为 NotUseful (default), WhenMapped, Always.

backing-store 为 NotUseful, 则议 X Server 不要进行 backing store. 但这只是 议, X Server 可能
还是选择进行 backing store. WhenMapped 则议 X Server 在视窗映射时(mapped)进 行 backing store,
 同样的, 这也只是议, 并不保 X Server 一定会进行, 所以 client 还是得 注 意 Expose evnet.Always
  则是议随时都进行 backing store, 不论是 映射(mapped)或未映射. 
save-under
save under 和 backing store 类似, 但其处理的对象是被指定视窗盖住 的其它视窗内容. save-under 
可为 True 或 False(default), 为 True, X Server 会自动维护被该视窗盖到的其它视窗内容, 在该部分
重新 Expose 时, 自动回补. 
event-mask
do-not-propagate-mask
do-not-propagate-mask 是一 个 KeyPress, KeyRelease, ButtonPress, ButtonRelease, PointerMotion, 
Button1Motion, Button2Motion, Button3Motion, Button4Motion, Buttton5Motion, ButtonMotion 的 
bitwise inclusive or. 当视窗产生或从子视窗 propagate 一个 被 mask 的 event, 该 event 将不会继续
往 parent propagate. 
override-redirect
将使的 parent 上设定 SubstructureRedirectMask 失效. 
colormap

--------------------------------------------------------------------------------

  XSetWindowColormap(display, w, colormap)
        Display *display;
        Window w;
        Colormap colormap;


--------------------------------------------------------------------------------

cursor
cursor 指定标进入视窗後所使用的指标, 指标可用 XCreatePixmapCursor 建立. 
--------------------------------------------------------------------------------

  Cursor XCreatePixmapCursor(display, source, mask,
  foreground_color, background_color, x, y)
Display *display;
Pixmap source;
Pixmap mask;
XColor *foreground_color;
XColor *background_color;
unsigned int x, y;


--------------------------------------------------------------------------------
XCreatePixmapCursor 可由 pixmap 建立一个新的标, source 是标的 图案, mask 则是图形 的 mask, 用以 
mask 标的图形, 以定义图形内那 一部分属於标图形(设为1), 那一部分不属於(设为0), 建立不规则形状的 
标. 
阅读(1587) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~