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