XOpenDisplay函数对应的源码在src/OpenDis.c中。完整源码请参见:
X11 Xlib截屏问题及深入分析二 —— 源码实现1_蓝天居士的博客-CSDN博客
XOpenDisplay函数很长,有500行左右。在此为了便于分析,列出函数名和前边变量定义的部分。代码如下:
- /*
- * Connects to a server, creates a Display object and returns a pointer to
- * the newly created Display back to the caller.
- */
- Display *
- XOpenDisplay (
- register _Xconst char *display)
- {
- register Display *dpy; /* New Display object being created. */
- register int i;
- int j, k; /* random iterator indexes */
- char *display_name; /* pointer to display name */
- char *setup = NULL; /* memory allocated at startup */
- int iscreen; /* screen number */
- xConnSetupPrefix prefix; /* prefix information */
- int vendorlen; /* length of vendor string */
- union {
- xConnSetup *setup;
- char *failure;
- char *vendor;
- xPixmapFormat *sf;
- xWindowRoot *rp;
- xDepth *dp;
- xVisualType *vp;
- } u; /* proto data returned from server */
- long setuplength; /* number of bytes in setup message */
- long usedbytes = 0; /* number of bytes we have processed */
- unsigned long mask;
- long int conn_buf_size;
- char *xlib_buffer_size;
-
- ……
- }
余下的代码分块来进行分析。
- /*
- * If the display specifier string supplied as an argument to this
- * routine is NULL or a pointer to NULL, read the DISPLAY variable.
- */
- if (display == NULL || *display == '\0') {
- if ((display_name = getenv("DISPLAY")) == NULL) {
- /* Oops! No DISPLAY environment variable - error. */
- return(NULL);
- }
- }
- else {
- /* Display is non-NULL, copy the pointer */
- display_name = (char *)display;
- }
如果XOpenDisplay函数的输入参数display为空或者字符串结束符,则默认从环境变量中获取对应的值,赋给char *display_name;否则直接将display赋值给display_name。笔者环境变量DISPLAY对应的值为:
- $ echo $DISPLAY
- :0
在例程(同样参见《X11 Xlib截屏问题及深入分析二》)中是如此调用的XOpenDisplay:
Display *display = XOpenDisplay(NULL);
综上,最终得到display_name的值为":0"。
- /*
- * Set the default error handlers. This allows the global variables to
- * default to NULL for use with shared libraries.
- */
- if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL);
- if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL);
这部分代码比较好理解,设置默认的错误处理函数和IO错误处理函数。
_XErrorFunction和_XIOErrorFunction是函数指针,在include/X11/Xlibint.h中定义:
- extern int (*_XIOErrorFunction)(
- Display* /* dpy */
- );
- extern int (*_XErrorFunction)(
- Display* /* dpy */,
- XErrorEvent* /* error_event */
- );
- /*
- * Attempt to allocate a display structure. Return NULL if allocation fails.
- */
- if ((dpy = Xcalloc(1, sizeof(Display))) == NULL) {
- return(NULL);
- }
-
- if ((dpy->display_name = strdup(display_name)) == NULL) {
- OutOfMemory(dpy);
- return(NULL);
- }
这段代码也好理解,动态分配Display对象,赋给register Display *dpy;并且将dpy->display_name的值赋为":0"。
Display结构的定义在include/X11/Xlib.h中:
- /*
- * Display datatype maintaining display specific data.
- * The contents of this structure are implementation dependent.
- * A Display should be treated as opaque by application code.
- */
- #ifndef XLIB_ILLEGAL_ACCESS
- typedef struct _XDisplay Display;
- #endif
-
- struct _XPrivate; /* Forward declare before use for C++ */
- struct _XrmHashBucketRec;
-
- typedef struct
- #ifdef XLIB_ILLEGAL_ACCESS
- _XDisplay
- #endif
- {
- XExtData *ext_data; /* hook for extension to hang data */
- struct _XPrivate *private1;
- int fd; /* Network socket. */
- int private2;
- int proto_major_version;/* major version of server's X protocol */
- int proto_minor_version;/* minor version of servers X protocol */
- char *vendor; /* vendor of the server hardware */
- XID private3;
- XID private4;
- XID private5;
- int private6;
- XID (*resource_alloc)( /* allocator function */
- struct _XDisplay*
- );
- int byte_order; /* screen byte order, LSBFirst, MSBFirst */
- int bitmap_unit; /* padding and data requirements */
- int bitmap_pad; /* padding requirements on bitmaps */
- int bitmap_bit_order; /* LeastSignificant or MostSignificant */
- int nformats; /* number of pixmap formats in list */
- ScreenFormat *pixmap_format; /* pixmap format list */
- int private8;
- int release; /* release of the server */
- struct _XPrivate *private9, *private10;
- int qlen; /* Length of input event queue */
- unsigned long last_request_read; /* seq number of last event read */
- unsigned long request; /* sequence number of last request. */
- XPointer private11;
- XPointer private12;
- XPointer private13;
- XPointer private14;
- unsigned max_request_size; /* maximum number 32 bit words in request*/
- struct _XrmHashBucketRec *db;
- int (*private15)(
- struct _XDisplay*
- );
- char *display_name; /* "host:display" string used on this connect*/
- int default_screen; /* default screen for operations */
- int nscreens; /* number of screens on this server*/
- Screen *screens; /* pointer to list of screens */
- unsigned long motion_buffer; /* size of motion buffer */
- unsigned long private16;
- int min_keycode; /* minimum defined keycode */
- int max_keycode; /* maximum defined keycode */
- XPointer private17;
- XPointer private18;
- int private19;
- char *xdefaults; /* contents of defaults from server */
- /* there is more to this structure, but it is private to Xlib */
- }
Display结构中有很多成员,后边用到哪个的时候再针对于哪个进行详细说明。
为了便于理解,本文对于XOpenDisplay函数就分析到第3部分代码,接来下的文章继续分析其余部分。