Skip to content

Latest commit

 

History

History
182 lines (144 loc) · 9.76 KB

3.13.md

File metadata and controls

182 lines (144 loc) · 9.76 KB

3.13使用体会


XCreateWindow

X中存在着两种创建窗口的方式,分别是XCreateWindowXCreateSimpleWindow

函数原型如下

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

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

XCreateWindow

  • 第一个参数display指向对Server的连接用于与服务器的通信
  • 第二个参数parent用于指定新窗口的父窗口
  • 第三个参数和第四个参数x,y分别指定了窗口相对于父窗口的位置偏移(也就是父窗口左上角的起始位置但是并不包括边界)
  • 第五个和第六个参数width,height用于指定窗口的宽和高,单位是像素
  • 第七个参数border_width指定了边界的宽度
  • 第八个参数depth指定该窗口的深度(深度就是窗口能够支持的颜色的位数,以比特位的不同来表现不同的颜色,比如8位的色深只能有256种颜色)
  • 第九个参数class用于说明窗口的类,分别是InputOutput,InputOnly,CopyFromParent(分别表示能够接受输入输出,只能接受输入以及和父窗口类型相同)InputOnly不允许有边界值(也就是边界值为0)
  • 第十个参数visual采用了窗口显示的视觉效果,视觉效果用于指定对图形的渲染效果例如红绿蓝的色深和偏移,透明度和标志位以及包含了对下一个视觉效果的指针
  • 最后两个参数valuemask、attributes分别指定了属性的掩码和属性的各个值,valuemask可以采用位运算,但是需要注意的是,在掩码中比特位最低的将被优先处理,也就是说,属性列表必须服从比特位在各个属性中的位置

XCreateSimpleWindow产生与前者类似的效果,不同的是在未指定的参数在XCreateSimpleWindow如色深depth,类别class,视觉效果visual,但是对于背景和边界都有自己默认的值

一个window的attribute的结构如下

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;

新创建的窗口将默认不会被映射,需要使用映射函数进行映射XMapWindow,同时需要保证其父窗口也已经被映射且没有遮挡(这个过程是递归向上直到顶级窗口的),此处还有映射所有子窗口的函数XMapSubWindows

新增一个新创建的窗口本身不是一个能够被绘制的实体,它是一个抽象概念,除非使用backing store

你可以对同一个父窗口创建诸多子窗口,他们之间的存在着堆栈顺序,一个窗口是否被兄弟窗口遮掩取决于堆栈的相对位置,如果一个窗口位于其他的兄弟窗口之上,那么就可以遮挡住其下所有的兄弟窗口,子窗口无法超过父窗口的边界

你可以使用XCirculateWindowXConfigureWindowXRestackWindow函数来重置对窗口的堆栈顺序

根据窗口的类型,如果是一个不可见窗口,那么对其进行进行绘图操作不会产生任何影响,当一个窗口被遮挡时,将会擦除所有的显示效果,等到重新暴露的时候,就会重新进行绘图操作。窗口的显示效果是可以被保存的,但是通常不会自动,需要进行指定


图形上下文

通常在绘图时,使用图形上下文GC进行保存绘制格式

上下文的拥有诸多属性,通常采用XCreateGC来创建,例如

GC gc = XCreateGC(con, window, GCForeground | GCBackground | GCCapStyle | GCJoinStyle,
                      (XGCValues[]){{.foreground = XWhitePixelOfScreen(screen),
                                     .background = XBlackPixelOfScreen(screen),
                                     .cap_style = CapButt,
                                     .join_style = JoinBevel,
                                     .fill_style = FillSolid}});

以下是GC的常用函数的原型

GC XCreateGC(Display *display, Drawable d, unsigned long valuemask, XGCValues *values);
int XCopyGC(Display *display, GC src, unsigned long valuemask, GC dest);
int XChangeGC(Display *display, GC gc, unsigned long valuemask, XGCValues *values);
Status XGetGCValues(Display *display, GC gc, unsigned long valuemask, XGCValues *values_return);
int XFreeGC(Display *display, GC gc);
GContext XGContextFromGC(GC gc);

一个GC结构体包含的成员

typedef struct {
int function;
/* logical operation */
unsigned long plane_mask;/* plane mask */
unsigned long foreground;/* foreground pixel */
unsigned long background;/* background pixel */
int line_width;
/* line width (in pixels) */
int line_style;
/* LineSolid, LineOnOffDash, LineDoubleDash */
int cap_style;
/* CapNotLast, CapButt, CapRound, CapProjecting */
int join_style;
/* JoinMiter, JoinRound, JoinBevel */
int fill_style;
/* FillSolid, FillTiled, FillStippled FillOpaqueStippled*/
int fill_rule;
/* EvenOddRule, WindingRule */
int arc_mode;
/* ArcChord, ArcPieSlice */
Pixmap tile;
/* tile pixmap for tiling operations */
Pixmap stipple;
/* stipple 1 plane pixmap for stippling */
int ts_x_origin;
/* offset for tile or stipple operations */
int ts_y_origin;
Font font;
/* default text font for text operations */
int subwindow_mode;
/* ClipByChildren, IncludeInferiors */
Bool graphics_exposures;
/* boolean, should exposures be generated */
int clip_x_origin;
/* origin for clipping */
int clip_y_origin;
Pixmap clip_mask;
/* bitmap clipping; other calls for rects */
int dash_offset;
/* patterned/dashed line information */
char dashes;
} XGCValues;
  • foreground 和 background: 这两个成员分别指定了绘制图形时的前景色和背景色。例如,在绘制文本时,前景色指定了文本的颜色,而背景色指定了文本背后的颜色。
  • function: 该成员指定了绘制图形时的逻辑操作。不同的函数可以产生不同的效果,例如 XOR 可以用于绘制交互式图形,AND 可以用于擦除等。
  • line_width: 该成员指定了绘制线条时的宽度。线条宽度的不同会影响线条的粗细,从而改变绘制出的图形的外观。
  • line_style: 该成员指定了绘制线条时的样式。不同的线条样式可以产生不同的效果,例如虚线、点线等。
  • cap_style 和 join_style: 这两个成员分别指定了线条端点的样式和线条连接点的样式。不同的样式可以产生不同的线条外观。
  • fill_style 和 fill_rule: 这两个成员分别指定了填充图形时的样式和规则。不同的填充样式和规则会影响图形填充的方式和效果。
  • arc_mode: 该成员指定了绘制圆弧时的模式,可以是扇形模式或弦模式。
  • tile 和 stipple: 这两个成员分别指定了填充图案和阴影图案。通过设置不同的图案,可以产生不同的填充效果。
  • ts_x_origin 和 ts_y_origin: 这两个成员指定了平铺图案的起点坐标。通过调整这些值,可以改变填充图案的起始位置。
  • font: 该成员指定了绘制文本时使用的字体。不同的字体会影响文本的外观。
  • subwindow_mode: 该成员指定了子窗口模式,影响绘制时是否考虑子窗口。

除了使用XChangeGC方式可以修改GC,同时我们也可以采用set系列的函数来对某一特定的属性进行修改。


像素映射图

像window一样,像素映射图同样是可以用来容纳绘制的图形。但是区别于window的是,像素图在没有被映射的情况下进行绘图操作仍然能够正常执行,window在未映射或被遮掩的情况下不会进行有效操作(除非window设置了backing store属性),但是像素图是不会显示在屏幕中,需要被拷贝到所需要显示的屏幕,这对系统的性能带来了挑战性,同时如果保存了大量的像素图将会导致服务器内存压力骤增,因此不应该在应用程序中大量使用像素图。

window和像素图都被称之为一个可绘制对象,绘制操作可以发生在二者上,但是在将绘制像素图复制到window上时,应该注意window的色深应当和像素图一致,使用函数

nt XCopyArea(Display *display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned int width, unsigned height, int dest_x, int dest_y);

int XCopyPlane(Display *display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned width, int height, int dest_x, int dest_y, unsigned long plane);

可以将像素图复制到所需绘制目标中

第一个函数会将每一层都复制到目标中但是第二层只会将某一层的值拷贝到目标中

像素图色深为1的就是传统意义上的位图,拥有两个维度分别表示黑色和白色,在当今的显示器中没有什么作用,但是可以用来表示一些元素例如光标,字符(包括不同的字体)等