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