OpenDis.c revision b4ee4795
1/* 2 3Copyright 1985, 1986, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25*/ 26 27#define NEED_REPLIES 28#define NEED_EVENTS 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include "Xlibint.h" 33#if USE_XCB 34#include "Xxcbint.h" 35#else /* !USE_XCB */ 36#include <X11/Xtrans/Xtrans.h> 37#include <X11/extensions/bigreqstr.h> 38#endif /* USE_XCB */ 39#include <X11/Xatom.h> 40#include <X11/Xresource.h> 41#include <stdio.h> 42#include "Xintconn.h" 43 44#ifdef XKB 45#include "XKBlib.h" 46#endif /* XKB */ 47 48#if !USE_XCB 49#ifdef X_NOT_POSIX 50#define Size_t unsigned int 51#else 52#define Size_t size_t 53#endif 54 55#define bignamelen (sizeof(XBigReqExtensionName) - 1) 56 57typedef struct { 58 unsigned long seq; 59 int opcode; 60} _XBigReqState; 61#endif /* !USE_XCB */ 62 63#ifdef XTHREADS 64#include "locking.h" 65int (*_XInitDisplayLock_fn)(Display *dpy) = NULL; 66void (*_XFreeDisplayLock_fn)(Display *dpy) = NULL; 67 68#define InitDisplayLock(d) (_XInitDisplayLock_fn ? (*_XInitDisplayLock_fn)(d) : Success) 69#define FreeDisplayLock(d) if (_XFreeDisplayLock_fn) (*_XFreeDisplayLock_fn)(d) 70#else 71#define InitDisplayLock(dis) Success 72#define FreeDisplayLock(dis) 73#endif /* XTHREADS */ 74 75static xReq _dummy_request = { 76 0, 0, 0 77}; 78 79static void OutOfMemory(Display *dpy, char *setup); 80#if !USE_XCB 81static Bool _XBigReqHandler(Display *dpy, xReply *rep, char *buf, int len, 82 XPointer data); 83#endif /* !USE_XCB */ 84 85/* 86 * Connects to a server, creates a Display object and returns a pointer to 87 * the newly created Display back to the caller. 88 */ 89Display * 90XOpenDisplay ( 91 register _Xconst char *display) 92{ 93 register Display *dpy; /* New Display object being created. */ 94 register int i; 95 int j, k; /* random iterator indexes */ 96#if !USE_XCB 97 char *display_name; /* pointer to display name */ 98 int endian; /* to determine which endian. */ 99 xConnClientPrefix client; /* client information */ 100 int idisplay; /* display number */ 101 int prefixread = 0; /* setup prefix already read? */ 102 char *conn_auth_name, *conn_auth_data; 103 int conn_auth_namelen, conn_auth_datalen; 104#endif /* !USE_XCB */ 105 char *setup = NULL; /* memory allocated at startup */ 106 char *fullname = NULL; /* expanded name of display */ 107 int iscreen; /* screen number */ 108 xConnSetupPrefix prefix; /* prefix information */ 109 int vendorlen; /* length of vendor string */ 110 union { 111 xConnSetup *setup; 112 char *failure; 113 char *vendor; 114 xPixmapFormat *sf; 115 xWindowRoot *rp; 116 xDepth *dp; 117 xVisualType *vp; 118 } u; /* proto data returned from server */ 119 long setuplength; /* number of bytes in setup message */ 120 long usedbytes = 0; /* number of bytes we have processed */ 121 unsigned long mask; 122 long int conn_buf_size; 123 char *xlib_buffer_size; 124 125#if !USE_XCB 126 bzero((char *) &client, sizeof(client)); 127 bzero((char *) &prefix, sizeof(prefix)); 128 129 /* 130 * If the display specifier string supplied as an argument to this 131 * routine is NULL or a pointer to NULL, read the DISPLAY variable. 132 */ 133 if (display == NULL || *display == '\0') { 134 if ((display_name = getenv("DISPLAY")) == NULL) { 135 /* Oops! No DISPLAY environment variable - error. */ 136 return(NULL); 137 } 138 } 139 else { 140 /* Display is non-NULL, copy the pointer */ 141 display_name = (char *)display; 142 } 143#endif /* !USE_XCB */ 144 145/* 146 * Set the default error handlers. This allows the global variables to 147 * default to NULL for use with shared libraries. 148 */ 149 if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL); 150 if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL); 151 152/* 153 * Attempt to allocate a display structure. Return NULL if allocation fails. 154 */ 155 if ((dpy = (Display *)Xcalloc(1, sizeof(Display))) == NULL) { 156 return(NULL); 157 } 158 159/* 160 * Call the Connect routine to get the transport connection object. 161 * If NULL is returned, the connection failed. The connect routine 162 * will set fullname to point to the expanded name. 163 */ 164 165#if USE_XCB 166 if(!_XConnectXCB(dpy, display, &fullname, &iscreen)) { 167 dpy->display_name = fullname; 168 OutOfMemory(dpy, NULL); 169 return NULL; 170 } 171#else /* !USE_XCB */ 172 if ((dpy->trans_conn = _X11TransConnectDisplay ( 173 display_name, &fullname, &idisplay, 174 &iscreen, &conn_auth_name, 175 &conn_auth_namelen, &conn_auth_data, 176 &conn_auth_datalen)) == NULL) { 177 Xfree ((char *) dpy); 178 return(NULL); 179 } 180 181 dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn); 182#endif /* USE_XCB */ 183 184 /* Initialize as much of the display structure as we can. 185 * Initialize pointers to NULL so that XFreeDisplayStructure will 186 * work if we run out of memory before we finish initializing. 187 */ 188 dpy->display_name = fullname; 189 dpy->keysyms = (KeySym *) NULL; 190 dpy->modifiermap = NULL; 191 dpy->lock_meaning = NoSymbol; 192 dpy->keysyms_per_keycode = 0; 193 dpy->xdefaults = (char *)NULL; 194 dpy->scratch_length = 0L; 195 dpy->scratch_buffer = NULL; 196 dpy->key_bindings = NULL; 197 dpy->ext_procs = (_XExtension *)NULL; 198 dpy->ext_data = (XExtData *)NULL; 199 dpy->ext_number = 0; 200 dpy->event_vec[X_Error] = _XUnknownWireEvent; 201 dpy->event_vec[X_Reply] = _XUnknownWireEvent; 202 dpy->wire_vec[X_Error] = _XUnknownNativeEvent; 203 dpy->wire_vec[X_Reply] = _XUnknownNativeEvent; 204 for (i = KeyPress; i < LASTEvent; i++) { 205 dpy->event_vec[i] = _XWireToEvent; 206 dpy->wire_vec[i] = NULL; 207 } 208 for (i = LASTEvent; i < 128; i++) { 209 dpy->event_vec[i] = _XUnknownWireEvent; 210 dpy->wire_vec[i] = _XUnknownNativeEvent; 211 } 212 dpy->resource_id = 0; 213 dpy->db = (struct _XrmHashBucketRec *)NULL; 214 dpy->cursor_font = None; 215 dpy->flags = 0; 216 dpy->async_handlers = NULL; 217 dpy->screens = NULL; 218 dpy->vendor = NULL; 219 dpy->buffer = NULL; 220 dpy->atoms = NULL; 221 dpy->error_vec = NULL; 222 dpy->context_db = NULL; 223 dpy->free_funcs = NULL; 224 dpy->pixmap_format = NULL; 225 dpy->cms.clientCmaps = NULL; 226 dpy->cms.defaultCCCs = NULL; 227 dpy->cms.perVisualIntensityMaps = NULL; 228 dpy->im_filters = NULL; 229 dpy->bigreq_size = 0; 230 dpy->lock = NULL; 231 dpy->lock_fns = NULL; 232 dpy->qfree = NULL; 233 dpy->next_event_serial_num = 1; 234 dpy->im_fd_info = NULL; 235 dpy->im_fd_length = 0; 236 dpy->conn_watchers = NULL; 237 dpy->watcher_count = 0; 238 dpy->filedes = NULL; 239 dpy->flushes = NULL; 240 dpy->xcmisc_opcode = 0; 241 dpy->xkb_info = NULL; 242 243/* 244 * Setup other information in this display structure. 245 */ 246 dpy->vnumber = X_PROTOCOL; 247 dpy->resource_alloc = _XAllocID; 248 dpy->idlist_alloc = _XAllocIDs; 249 dpy->synchandler = NULL; 250 dpy->savedsynchandler = NULL; 251 dpy->request = 0; 252 dpy->last_request_read = 0; 253 dpy->default_screen = iscreen; /* Value returned by ConnectDisplay */ 254 dpy->last_req = (char *)&_dummy_request; 255 256 /* Initialize the display lock */ 257 if (InitDisplayLock(dpy) != 0) { 258 OutOfMemory (dpy, setup); 259 return(NULL); 260 } 261 262 if (!_XPollfdCacheInit(dpy)) { 263 OutOfMemory (dpy, setup); 264 return(NULL); 265 } 266 267 /* Set up the output buffers. */ 268#ifndef XLIBDEFAULTBUFSIZE 269#define XLIBDEFAULTBUFSIZE 16384 /* 16k */ 270#endif 271#ifndef XLIBMINBUFSIZE 272#define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */ 273#endif 274 xlib_buffer_size = getenv("XLIBBUFFERSIZE"); 275 276#ifdef __sun /* Backwards compatibility for old Solaris libX11 name */ 277 if (xlib_buffer_size == NULL) 278 xlib_buffer_size = getenv("XSUNBUFFERSIZE"); 279#endif 280 281 if (xlib_buffer_size == NULL) 282 conn_buf_size = XLIBDEFAULTBUFSIZE; 283 else 284 conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10); 285 if (conn_buf_size < XLIBMINBUFSIZE) 286 conn_buf_size = XLIBMINBUFSIZE; 287 288 if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) { 289 OutOfMemory (dpy, setup); 290 return(NULL); 291 } 292 dpy->bufmax = dpy->buffer + conn_buf_size; 293#if USE_XCB 294 dpy->xcb->real_bufmax = dpy->bufmax; 295 dpy->bufmax = dpy->buffer; 296#endif 297 298 /* Set up the input event queue and input event queue parameters. */ 299 dpy->head = dpy->tail = NULL; 300 dpy->qlen = 0; 301 302 /* Set up free-function record */ 303 if ((dpy->free_funcs = (_XFreeFuncRec *)Xcalloc(1, 304 sizeof(_XFreeFuncRec))) 305 == NULL) { 306 OutOfMemory (dpy, setup); 307 return(NULL); 308 } 309 310#if !USE_XCB 311/* 312 * The xConnClientPrefix describes the initial connection setup information 313 * and is followed by the authorization information. Sites that are interested 314 * in security are strongly encouraged to use an authentication and 315 * authorization system such as Kerberos. 316 */ 317 endian = 1; 318 if (*(char *) &endian) 319 client.byteOrder = '\154'; /* 'l' */ 320 else 321 client.byteOrder = '\102'; /* 'B' */ 322 client.majorVersion = X_PROTOCOL; 323 client.minorVersion = X_PROTOCOL_REVISION; 324 client.nbytesAuthProto = conn_auth_namelen; 325 client.nbytesAuthString = conn_auth_datalen; 326 prefixread = _XSendClientPrefix(dpy, &client, 327 conn_auth_name, conn_auth_data, 328 &prefix); 329 if (prefixread < 0) 330 { 331 _XDisconnectDisplay (dpy->trans_conn); 332 Xfree ((char *)dpy); 333 return(NULL); 334 } 335 if (conn_auth_name) Xfree(conn_auth_name); 336 if (conn_auth_data) Xfree(conn_auth_data); 337/* 338 * Now see if connection was accepted... 339 */ 340 /* these internal functions expect the display to be locked */ 341 LockDisplay(dpy); 342 343 if (prefixread == 0) 344 _XRead (dpy, (char *)&prefix,(long)SIZEOF(xConnSetupPrefix)); 345 346 /* an Authenticate reply we weren't expecting? */ 347 if (prefix.success != xTrue && prefix.success != xFalse) { 348 fprintf (stderr, 349 "Xlib: unexpected connection setup reply from server, type %d.\r\n", 350 prefix.success); 351 _XDisconnectDisplay (dpy->trans_conn); 352 Xfree ((char *)dpy); 353 return(NULL); 354 } 355 356 if (prefix.majorVersion != X_PROTOCOL) { 357 /* XXX - printing messages marks a bad programming interface */ 358 fprintf (stderr, 359 "Xlib: client uses different protocol version (%d) than server (%d)!\r\n", 360 X_PROTOCOL, prefix.majorVersion); 361 _XDisconnectDisplay (dpy->trans_conn); 362 Xfree ((char *)dpy); 363 return(NULL); 364 } 365#endif /* !USE_XCB */ 366 367#if USE_XCB 368 { 369 const struct xcb_setup_t *xcbsetup = xcb_get_setup(dpy->xcb->connection); 370 memcpy(&prefix, xcbsetup, sizeof(prefix)); 371 setuplength = prefix.length << 2; 372 setup = (char *) xcbsetup; 373 setup += SIZEOF(xConnSetupPrefix); 374 u.setup = (xConnSetup *) setup; 375 } 376#else /* !USE_XCB */ 377 setuplength = prefix.length << 2; 378 if ( (u.setup = (xConnSetup *) 379 (setup = Xmalloc ((unsigned) setuplength))) == NULL) { 380 _XDisconnectDisplay (dpy->trans_conn); 381 Xfree ((char *)dpy); 382 return(NULL); 383 } 384 _XRead (dpy, (char *)u.setup, setuplength); 385 386/* 387 * If the connection was not accepted by the server due to problems, 388 * give error message to the user.... 389 */ 390 if (prefix.success != xTrue) { 391 /* XXX - printing messages marks a bad programming interface */ 392 fprintf (stderr, 393 "Xlib: connection to \"%s\" refused by server\r\nXlib: ", 394 fullname); 395 396 if (prefix.lengthReason > setuplength) { 397 fprintf (stderr, "Xlib: Broken initial reply: length of reason > length of packet\r\n"); 398 }else{ 399 (void) fwrite (u.failure, (Size_t)sizeof(char), 400 (Size_t)prefix.lengthReason, stderr); 401 (void) fwrite ("\r\n", sizeof(char), 2, stderr); 402 } 403 404 OutOfMemory(dpy, setup); 405 return (NULL); 406 } 407#endif /* USE_XCB */ 408 409/* 410 * Check if the reply was long enough to get any information out of it. 411 */ 412 usedbytes = sz_xConnSetup; 413 if (setuplength < usedbytes ) { 414 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 415 OutOfMemory(dpy, setup); 416 return (NULL); 417 } 418 419/* 420 * We succeeded at authorization, so let us move the data into 421 * the display structure. 422 */ 423 dpy->proto_major_version= prefix.majorVersion; 424 dpy->proto_minor_version= prefix.minorVersion; 425 dpy->release = u.setup->release; 426 dpy->resource_base = u.setup->ridBase; 427 dpy->resource_mask = u.setup->ridMask; 428 dpy->min_keycode = u.setup->minKeyCode; 429 dpy->max_keycode = u.setup->maxKeyCode; 430 dpy->motion_buffer = u.setup->motionBufferSize; 431 dpy->nformats = u.setup->numFormats; 432 dpy->nscreens = u.setup->numRoots; 433 dpy->byte_order = u.setup->imageByteOrder; 434 dpy->bitmap_unit = u.setup->bitmapScanlineUnit; 435 dpy->bitmap_pad = u.setup->bitmapScanlinePad; 436 dpy->bitmap_bit_order = u.setup->bitmapBitOrder; 437 dpy->max_request_size = u.setup->maxRequestSize; 438 mask = dpy->resource_mask; 439 dpy->resource_shift = 0; 440 if (!mask) 441 { 442 fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n", 443 fullname); 444 OutOfMemory(dpy, setup); 445 return (NULL); 446 } 447 448 while (!(mask & 1)) { 449 dpy->resource_shift++; 450 mask = mask >> 1; 451 } 452 dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5; 453/* 454 * now extract the vendor string... String must be null terminated, 455 * padded to multiple of 4 bytes. 456 */ 457 /* Check for a sane vendor string length */ 458 if (u.setup->nbytesVendor > 256) { 459 OutOfMemory(dpy, setup); 460 return (NULL); 461 } 462 463 dpy->vendor = (char *) Xmalloc((unsigned) (u.setup->nbytesVendor + 1)); 464 if (dpy->vendor == NULL) { 465 OutOfMemory(dpy, setup); 466 return (NULL); 467 } 468 vendorlen = u.setup->nbytesVendor; 469 470/* 471 * validate setup length 472 */ 473 usedbytes += (vendorlen + 3) & ~3; 474 if (setuplength < usedbytes) { 475 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 476 OutOfMemory(dpy, setup); 477 return (NULL); 478 } 479 480 u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup); 481 (void) strncpy(dpy->vendor, u.vendor, vendorlen); 482 dpy->vendor[vendorlen] = '\0'; 483 vendorlen = (vendorlen + 3) & ~3; /* round up */ 484 u.vendor += vendorlen; 485 486/* 487 * Now iterate down setup information..... 488 */ 489 dpy->pixmap_format = 490 (ScreenFormat *)Xmalloc( 491 (unsigned) (dpy->nformats *sizeof(ScreenFormat))); 492 if (dpy->pixmap_format == NULL) { 493 OutOfMemory (dpy, setup); 494 return(NULL); 495 } 496/* 497 * First decode the Z axis Screen format information. 498 */ 499 usedbytes += dpy->nformats * sz_xPixmapFormat; 500 501 if (setuplength < usedbytes) { 502 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 503 OutOfMemory (dpy, setup); 504 return(NULL); 505 } 506 507 for (i = 0; i < dpy->nformats; i++) { 508 register ScreenFormat *fmt = &dpy->pixmap_format[i]; 509 fmt->depth = u.sf->depth; 510 fmt->bits_per_pixel = u.sf->bitsPerPixel; 511 fmt->scanline_pad = u.sf->scanLinePad; 512 fmt->ext_data = NULL; 513 u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat); 514 } 515 516/* 517 * next the Screen structures. 518 */ 519 dpy->screens = 520 (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen)); 521 if (dpy->screens == NULL) { 522 OutOfMemory (dpy, setup); 523 return(NULL); 524 } 525 526/* 527 * Now go deal with each screen structure. 528 */ 529 for (i = 0; i < dpy->nscreens; i++) { 530 register Screen *sp = &dpy->screens[i]; 531 VisualID root_visualID; 532 533 usedbytes += sz_xWindowRoot; 534 if (setuplength < usedbytes) { 535 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 536 OutOfMemory (dpy, setup); 537 return(NULL); 538 } 539 540 root_visualID = u.rp->rootVisualID; 541 sp->display = dpy; 542 sp->root = u.rp->windowId; 543 sp->cmap = u.rp->defaultColormap; 544 sp->white_pixel = u.rp->whitePixel; 545 sp->black_pixel = u.rp->blackPixel; 546 sp->root_input_mask = u.rp->currentInputMask; 547 sp->width = u.rp->pixWidth; 548 sp->height = u.rp->pixHeight; 549 sp->mwidth = u.rp->mmWidth; 550 sp->mheight = u.rp->mmHeight; 551 sp->min_maps = u.rp->minInstalledMaps; 552 sp->max_maps = u.rp->maxInstalledMaps; 553 sp->backing_store= u.rp->backingStore; 554 sp->save_unders = u.rp->saveUnders; 555 sp->root_depth = u.rp->rootDepth; 556 sp->ndepths = u.rp->nDepths; 557 sp->ext_data = NULL; 558 u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot); 559/* 560 * lets set up the depth structures. 561 */ 562 sp->depths = (Depth *)Xmalloc( 563 (unsigned)sp->ndepths*sizeof(Depth)); 564 if (sp->depths == NULL) { 565 OutOfMemory (dpy, setup); 566 return(NULL); 567 } 568 /* 569 * for all depths on this screen. 570 */ 571 for (j = 0; j < sp->ndepths; j++) { 572 Depth *dp = &sp->depths[j]; 573 574 usedbytes += sz_xDepth; 575 if (setuplength < usedbytes) { 576 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 577 OutOfMemory (dpy, setup); 578 return(NULL); 579 } 580 581 dp->depth = u.dp->depth; 582 dp->nvisuals = u.dp->nVisuals; 583 u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth); 584 if (dp->nvisuals > 0) { 585 dp->visuals = 586 (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual)); 587 if (dp->visuals == NULL) { 588 OutOfMemory (dpy, setup); 589 return(NULL); 590 } 591 for (k = 0; k < dp->nvisuals; k++) { 592 register Visual *vp = &dp->visuals[k]; 593 594 usedbytes += sz_xVisualType; 595 if (setuplength < usedbytes) { 596 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 597 OutOfMemory (dpy, setup); 598 return(NULL); 599 } 600 601 vp->visualid = u.vp->visualID; 602 vp->class = u.vp->class; 603 vp->bits_per_rgb= u.vp->bitsPerRGB; 604 vp->map_entries = u.vp->colormapEntries; 605 vp->red_mask = u.vp->redMask; 606 vp->green_mask = u.vp->greenMask; 607 vp->blue_mask = u.vp->blueMask; 608 vp->ext_data = NULL; 609 u.vp = (xVisualType *) (((char *) u.vp) + 610 sz_xVisualType); 611 } 612 if (dp->depth == 32 && getenv ("XLIB_SKIP_ARGB_VISUALS")) 613 { 614 Xfree (dp->visuals); 615 dp->visuals = NULL; 616 dp->nvisuals = 0; 617 } 618 } else { 619 dp->visuals = (Visual *) NULL; 620 } 621 } 622 sp->root_visual = _XVIDtoVisual(dpy, root_visualID); 623 } 624 625 if(usedbytes != setuplength){ 626 /* Sanity check, shouldn't happen. */ 627 fprintf(stderr, "Xlib: Did not parse entire setup message: " 628 "parsed: %ld, message: %ld\n", 629 usedbytes, setuplength); 630 OutOfMemory(dpy, setup); 631 return(NULL); 632 } 633 634/* 635 * Now start talking to the server to setup all other information... 636 */ 637 638#if !USE_XCB 639 Xfree (setup); /* all finished with setup information */ 640#endif /* !USE_XCB */ 641 642/* 643 * Make sure default screen is legal. 644 */ 645 if (iscreen >= dpy->nscreens) { 646 OutOfMemory(dpy, (char *) NULL); 647 return(NULL); 648 } 649 650#if !USE_XCB 651/* 652 * finished calling internal routines, now unlock for external routines 653 */ 654 UnlockDisplay(dpy); 655#endif /* !USE_XCB */ 656 657#if USE_XCB 658 dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection); 659 if(dpy->bigreq_size <= dpy->max_request_size) 660 dpy->bigreq_size = 0; 661#endif /* USE_XCB */ 662 663/* 664 * Set up other stuff clients are always going to use. 665 */ 666 for (i = 0; i < dpy->nscreens; i++) { 667 register Screen *sp = &dpy->screens[i]; 668 XGCValues values; 669 values.foreground = sp->black_pixel; 670 values.background = sp->white_pixel; 671 if ((sp->default_gc = XCreateGC (dpy, sp->root, 672 GCForeground|GCBackground, 673 &values)) == NULL) { 674 OutOfMemory(dpy, (char *) NULL); 675 return (NULL); 676 } 677 } 678/* 679 * call into synchronization routine so that all programs can be 680 * forced synchronous 681 */ 682 (void) XSynchronize(dpy, _Xdebug); 683 684/* 685 * get availability of large requests, and 686 * get the resource manager database off the root window. 687 */ 688 LockDisplay(dpy); 689 { 690 xGetPropertyReply reply; 691 xGetPropertyReq *req; 692#if !USE_XCB 693 _XAsyncHandler async; 694 _XBigReqState async_state; 695 xQueryExtensionReq *qreq; 696 xBigReqEnableReq *breq; 697 xBigReqEnableReply brep; 698 699 GetReq(QueryExtension, qreq); 700 async_state.seq = dpy->request; 701 async_state.opcode = 0; 702 async.next = dpy->async_handlers; 703 async.handler = _XBigReqHandler; 704 async.data = (XPointer)&async_state; 705 dpy->async_handlers = &async; 706 qreq->nbytes = bignamelen; 707 qreq->length += (bignamelen+3)>>2; 708 Data(dpy, XBigReqExtensionName, bignamelen); 709#endif /* !USE_XCB */ 710 711 GetReq (GetProperty, req); 712 req->window = RootWindow(dpy, 0); 713 req->property = XA_RESOURCE_MANAGER; 714 req->type = XA_STRING; 715 req->delete = False; 716 req->longOffset = 0; 717 req->longLength = 100000000L; 718 719 if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) { 720 if (reply.format == 8 && reply.propertyType == XA_STRING && 721 (reply.nItems + 1 > 0) && 722 (reply.nItems <= req->longLength * 4) && 723 (dpy->xdefaults = Xmalloc (reply.nItems + 1))) { 724 _XReadPad (dpy, dpy->xdefaults, reply.nItems); 725 dpy->xdefaults[reply.nItems] = '\0'; 726 } 727 else if (reply.propertyType != None) 728 _XEatData(dpy, reply.nItems * (reply.format >> 3)); 729 } 730#if !USE_XCB 731 DeqAsyncHandler(dpy, &async); 732 if (async_state.opcode) { 733 GetReq(BigReqEnable, breq); 734 breq->reqType = async_state.opcode; 735 breq->brReqType = X_BigReqEnable; 736 if (_XReply(dpy, (xReply *)&brep, 0, xFalse)) 737 dpy->bigreq_size = brep.max_request_size; 738 } 739#endif /* !USE_XCB */ 740 } 741 UnlockDisplay(dpy); 742 743#ifdef MOTIFBC 744 { 745 extern Display *_XHeadOfDisplayList; 746 _XHeadOfDisplayList = dpy; 747 } 748#endif 749#ifdef XKB 750 XkbUseExtension(dpy,NULL,NULL); 751#endif 752/* 753 * and return successfully 754 */ 755 return(dpy); 756} 757 758#if !USE_XCB 759static Bool 760_XBigReqHandler( 761 register Display *dpy, 762 register xReply *rep, 763 char *buf, 764 int len, 765 XPointer data) 766{ 767 _XBigReqState *state; 768 xQueryExtensionReply replbuf; 769 xQueryExtensionReply *repl; 770 771 state = (_XBigReqState *)data; 772 if (dpy->last_request_read != state->seq) 773 return False; 774 if (rep->generic.type == X_Error) 775 return True; 776 repl = (xQueryExtensionReply *) 777 _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, 778 (SIZEOF(xQueryExtensionReply) - SIZEOF(xReply)) >> 2, 779 True); 780 if (repl->present) 781 state->opcode = repl->major_opcode; 782 return True; 783} 784#endif /* !USE_XCB */ 785 786 787/* XFreeDisplayStructure frees all the storage associated with a 788 * Display. It is used by XOpenDisplay if it runs out of memory, 789 * and also by XCloseDisplay. It needs to check whether all pointers 790 * are non-NULL before dereferencing them, since it may be called 791 * by XOpenDisplay before the Display structure is fully formed. 792 * XOpenDisplay must be sure to initialize all the pointers to NULL 793 * before the first possible call on this. 794 */ 795 796void _XFreeDisplayStructure(Display *dpy) 797{ 798 /* move all cookies in the EQ to the jar, then free them. */ 799 if (dpy->qfree) { 800 _XQEvent *qelt = dpy->qfree; 801 while (qelt) { 802 if (_XIsEventCookie(dpy, &qelt->event)) 803 _XStoreEventCookie(dpy, &qelt->event); 804 qelt = qelt->next; 805 } 806 } 807 if (dpy->cookiejar) 808 _XFreeEventCookies(dpy); 809 while (dpy->ext_procs) { 810 _XExtension *ext = dpy->ext_procs; 811 dpy->ext_procs = ext->next; 812 if (ext->name) 813 Xfree (ext->name); 814 Xfree ((char *)ext); 815 } 816 if (dpy->im_filters) 817 (*dpy->free_funcs->im_filters)(dpy); 818 if (dpy->cms.clientCmaps) 819 (*dpy->free_funcs->clientCmaps)(dpy); 820 if (dpy->cms.defaultCCCs) 821 (*dpy->free_funcs->defaultCCCs)(dpy); 822 if (dpy->cms.perVisualIntensityMaps) 823 (*dpy->free_funcs->intensityMaps)(dpy); 824 if (dpy->atoms) 825 (*dpy->free_funcs->atoms)(dpy); 826 if (dpy->modifiermap) 827 (*dpy->free_funcs->modifiermap)(dpy->modifiermap); 828 if (dpy->key_bindings) 829 (*dpy->free_funcs->key_bindings)(dpy); 830 if (dpy->context_db) 831 (*dpy->free_funcs->context_db)(dpy); 832 if (dpy->xkb_info) 833 (*dpy->free_funcs->xkb)(dpy); 834 835 /* if RM database was allocated by XGetDefault() free it */ 836 if (dpy->db && (dpy->flags & XlibDisplayDfltRMDB)) 837 XrmDestroyDatabase(dpy->db); 838 839 if (dpy->screens) { 840 register int i; 841 842 for (i = 0; i < dpy->nscreens; i++) { 843 Screen *sp = &dpy->screens[i]; 844 845 if (sp->depths) { 846 register int j; 847 848 for (j = 0; j < sp->ndepths; j++) { 849 Depth *dp = &sp->depths[j]; 850 851 if (dp->visuals) { 852 register int k; 853 854 for (k = 0; k < dp->nvisuals; k++) 855 _XFreeExtData (dp->visuals[k].ext_data); 856 Xfree ((char *) dp->visuals); 857 } 858 } 859 860 Xfree ((char *) sp->depths); 861 } 862 863 _XFreeExtData (sp->ext_data); 864 } 865 866 Xfree ((char *)dpy->screens); 867 } 868 869 if (dpy->pixmap_format) { 870 register int i; 871 872 for (i = 0; i < dpy->nformats; i++) 873 _XFreeExtData (dpy->pixmap_format[i].ext_data); 874 Xfree ((char *)dpy->pixmap_format); 875 } 876 877 if (dpy->display_name) 878 Xfree (dpy->display_name); 879 if (dpy->vendor) 880 Xfree (dpy->vendor); 881 882 if (dpy->buffer) 883 Xfree (dpy->buffer); 884 if (dpy->keysyms) 885 Xfree ((char *) dpy->keysyms); 886 if (dpy->xdefaults) 887 Xfree (dpy->xdefaults); 888 if (dpy->error_vec) 889 Xfree ((char *)dpy->error_vec); 890 891 _XFreeExtData (dpy->ext_data); 892 if (dpy->free_funcs) 893 Xfree ((char *)dpy->free_funcs); 894 if (dpy->scratch_buffer) 895 Xfree (dpy->scratch_buffer); 896 FreeDisplayLock(dpy); 897 898 if (dpy->qfree) { 899 register _XQEvent *qelt = dpy->qfree; 900 901 while (qelt) { 902 register _XQEvent *qnxt = qelt->next; 903 Xfree ((char *) qelt); 904 qelt = qnxt; 905 } 906 } 907 while (dpy->im_fd_info) { 908 struct _XConnectionInfo *conni = dpy->im_fd_info; 909 dpy->im_fd_info = conni->next; 910 if (conni->watch_data) 911 Xfree (conni->watch_data); 912 Xfree (conni); 913 } 914 if (dpy->conn_watchers) { 915 struct _XConnWatchInfo *watcher = dpy->conn_watchers; 916 dpy->conn_watchers = watcher->next; 917 Xfree (watcher); 918 } 919 if (dpy->filedes) 920 Xfree (dpy->filedes); 921 922#if USE_XCB 923 _XFreeX11XCBStructure(dpy); 924#endif /* USE_XCB */ 925 926 Xfree ((char *)dpy); 927} 928 929/* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL 930 after this returns. */ 931 932static void OutOfMemory(Display *dpy, char *setup) 933{ 934#if USE_XCB 935 if(dpy->xcb->connection) 936 xcb_disconnect(dpy->xcb->connection); 937#else /* !USE_XCB */ 938 _XDisconnectDisplay (dpy->trans_conn); 939#endif /* USE_XCB */ 940 _XFreeDisplayStructure (dpy); 941#if !USE_XCB 942 if (setup) Xfree (setup); 943#endif /* !USE_XCB */ 944} 945