|
|
1.1 ! root 1: #include "copyright.h" ! 2: #ifndef lint ! 3: static char *rcsid_xopendisplay_c = "$Header: XOpenDis.c,v 11.50 87/09/01 15:00:36 toddb Exp $"; ! 4: #endif ! 5: /* Copyright Massachusetts Institute of Technology 1985, 1986 */ ! 6: ! 7: /* Converted to V11 by jg */ ! 8: ! 9: #include <stdio.h> ! 10: #include "Xlibint.h" ! 11: #include <strings.h> ! 12: #include "Xatom.h" ! 13: ! 14: #ifndef lint ! 15: static int lock; /* get rid of ifdefs when locking implemented */ ! 16: #endif ! 17: ! 18: int _Xdebug = 0; ! 19: static xReq _dummy_request = { ! 20: 0, 0, 0 ! 21: }; ! 22: ! 23: /* head of the linked list of open displays */ ! 24: Display *_XHeadOfDisplayList = NULL; ! 25: ! 26: extern _XWireToEvent(); ! 27: extern _XUnknownNativeEvent(); ! 28: extern _XUnknownWireEvent(); ! 29: /* ! 30: * Connects to a server, creates a Display object and returns a pointer to ! 31: * the newly created Display back to the caller. ! 32: */ ! 33: Display *XOpenDisplay (display) ! 34: register char *display; ! 35: { ! 36: register Display *dpy; /* New Display object being created. */ ! 37: register int i; ! 38: int j, k; /* random iterator indexes */ ! 39: char *display_name; /* pointer to display name */ ! 40: int indian; /* to determine which indian. */ ! 41: xConnClientPrefix client; /* client information */ ! 42: xConnSetupPrefix prefix; /* prefix information */ ! 43: int vendorlen; /* length of vendor string */ ! 44: char *setup; /* memory allocated at startup */ ! 45: char displaybuf[256]; /* buffer to receive expanded name */ ! 46: int screen_num; /* screen number */ ! 47: union { ! 48: xConnSetup *setup; ! 49: char *failure; ! 50: char *vendor; ! 51: xPixmapFormat *sf; ! 52: xWindowRoot *rp; ! 53: xDepth *dp; ! 54: xVisualType *vp; ! 55: } u; ! 56: long setuplength; /* number of bytes in setup message */ ! 57: ! 58: extern int _XSendClientPrefix(); ! 59: extern int _XConnectDisplay(); ! 60: extern char *getenv(); ! 61: extern XID _XAllocID(); ! 62: ! 63: /* ! 64: * If the display specifier string supplied as an argument to this ! 65: * routine is NULL or a pointer to NULL, read the DISPLAY variable. ! 66: */ ! 67: if (display == NULL || *display == '\0') { ! 68: if ((display_name = getenv("DISPLAY")) == NULL) { ! 69: /* Oops! No DISPLAY environment variable - error. */ ! 70: return(NULL); ! 71: } ! 72: } ! 73: else { ! 74: /* Display is non-NULL, copy the pointer */ ! 75: display_name = display; ! 76: } ! 77: ! 78: /* ! 79: * Attempt to allocate a display structure. Return NULL if allocation fails. ! 80: */ ! 81: LockMutex(&lock); ! 82: if ((dpy = (Display *)Xcalloc(1, sizeof(Display))) == NULL) { ! 83: errno = ENOMEM; ! 84: UnlockMutex(&lock); ! 85: return(NULL); ! 86: } ! 87: ! 88: /* ! 89: * Call the Connect routine to get the network socket. If 0 is returned, the ! 90: * connection failed. The connect routine will return the expanded display ! 91: * name in displaybuf. ! 92: */ ! 93: ! 94: if ((dpy->fd = _XConnectDisplay(display_name, displaybuf, &screen_num)) ! 95: < 0) { ! 96: Xfree ((char *) dpy); ! 97: UnlockMutex(&lock); ! 98: return(NULL); /* errno set by XConnectDisplay */ ! 99: } ! 100: ! 101: /* ! 102: * First byte is the byte order byte. ! 103: * Authentication key is normally sent right after the connection. ! 104: * This (in MIT's case) will be kerberos. ! 105: */ ! 106: indian = 1; ! 107: if (*(char *) &indian) ! 108: client.byteOrder = 'l'; ! 109: else ! 110: client.byteOrder = 'B'; ! 111: client.majorVersion = X_PROTOCOL; ! 112: client.minorVersion = X_PROTOCOL_REVISION; ! 113: _XSendClientPrefix (dpy, &client); ! 114: /* ! 115: * Now see if connection was accepted... ! 116: */ ! 117: _XRead (dpy, (char *)&prefix,(long)sizeof(xConnSetupPrefix)); ! 118: ! 119: if (prefix.majorVersion < X_PROTOCOL) { ! 120: (void) fputs ("Warning: Client built for newer server!\n", stderr); ! 121: } ! 122: if (prefix.minorVersion != X_PROTOCOL_REVISION) { ! 123: (void) fputs ( ! 124: "Warning: Protocol rev. of client does not match server!\n", ! 125: stderr); ! 126: } ! 127: ! 128: setuplength = prefix.length << 2; ! 129: if ( (u.setup = (xConnSetup *)(setup = Xmalloc ((unsigned)setuplength))) ! 130: == NULL) { ! 131: errno = ENOMEM; ! 132: Xfree ((char *)dpy); ! 133: UnlockMutex(&lock); ! 134: return(NULL); ! 135: } ! 136: _XRead (dpy, (char *)u.setup, setuplength); ! 137: /* ! 138: * If the connection was not accepted by the server due to problems, ! 139: * give error message to the user.... ! 140: */ ! 141: if (prefix.success != xTrue) { ! 142: /* ! 143: (void) fwrite (u.failure, (int)*u.failure, sizeof(char), stderr); ! 144: */ ! 145: (void) fwrite (u.failure, sizeof(char), ! 146: (int)prefix.lengthReason, stderr); ! 147: (void) fwrite ("\n", sizeof(char), 1, stderr); ! 148: Xfree ((char *)dpy); ! 149: Xfree (setup); ! 150: UnlockMutex(&lock); ! 151: return (NULL); ! 152: } ! 153: ! 154: /* ! 155: * We succeeded at authorization, so let us move the data into ! 156: * the display structure. ! 157: */ ! 158: dpy->next = (Display *) NULL; ! 159: dpy->proto_major_version= prefix.majorVersion; ! 160: dpy->proto_minor_version= prefix.minorVersion; ! 161: dpy->release = u.setup->release; ! 162: dpy->resource_base = u.setup->ridBase; ! 163: dpy->resource_mask = u.setup->ridMask; ! 164: dpy->min_keycode = u.setup->minKeyCode; ! 165: dpy->max_keycode = u.setup->maxKeyCode; ! 166: dpy->keysyms = (KeySym *) NULL; ! 167: dpy->modifiermap = XNewModifiermap(0); ! 168: dpy->keysyms_per_keycode = 0; ! 169: dpy->current = None; ! 170: dpy->xdefaults = (char *)NULL; ! 171: dpy->scratch_length = 0L; ! 172: dpy->scratch_buffer = NULL; ! 173: dpy->motion_buffer = u.setup->motionBufferSize; ! 174: dpy->nformats = u.setup->numFormats; ! 175: dpy->nscreens = u.setup->numRoots; ! 176: dpy->byte_order = u.setup->imageByteOrder; ! 177: dpy->bitmap_unit = u.setup->bitmapScanlineUnit; ! 178: dpy->bitmap_pad = u.setup->bitmapScanlinePad; ! 179: dpy->bitmap_bit_order = u.setup->bitmapBitOrder; ! 180: dpy->max_request_size = u.setup->maxRequestSize; ! 181: dpy->ext_procs = (_XExtension *)NULL; ! 182: dpy->ext_data = (XExtData *)NULL; ! 183: dpy->ext_number = 0; ! 184: dpy->event_vec[X_Error] = _XUnknownWireEvent; ! 185: dpy->event_vec[X_Reply] = _XUnknownWireEvent; ! 186: dpy->wire_vec[X_Error] = _XUnknownNativeEvent; ! 187: dpy->wire_vec[X_Reply] = _XUnknownNativeEvent; ! 188: for (i = KeyPress; i < LASTEvent; i++) { ! 189: dpy->event_vec[i] = _XWireToEvent; ! 190: dpy->wire_vec[i] = NULL; ! 191: } ! 192: for (i = LASTEvent; i < 128; i++) { ! 193: dpy->event_vec[i] = _XUnknownWireEvent; ! 194: dpy->wire_vec[i] = _XUnknownNativeEvent; ! 195: } ! 196: dpy->resource_id = 0; ! 197: dpy->resource_shift = ffs(dpy->resource_mask) - 1; ! 198: dpy->db = (struct _XrmResourceDataBase *)NULL; ! 199: /* ! 200: * Initialize pointers to NULL so that XFreeDisplayStructure will ! 201: * work if we run out of memory ! 202: */ ! 203: ! 204: dpy->screens = NULL; ! 205: dpy->display_name = NULL; ! 206: dpy->buffer = NULL; ! 207: ! 208: /* ! 209: * now extract the vendor string... String must be null terminated, ! 210: * padded to multiple of 4 bytes. ! 211: */ ! 212: dpy->vendor = (char *) Xmalloc (u.setup->nbytesVendor + 1); ! 213: vendorlen = u.setup->nbytesVendor; ! 214: u.setup += 1; /* can't touch information in XConnSetup anymore..*/ ! 215: (void) strncpy(dpy->vendor, u.vendor, vendorlen); ! 216: u.vendor += (vendorlen + 3) & ~3; ! 217: /* ! 218: * Now iterate down setup information..... ! 219: */ ! 220: dpy->pixmap_format = ! 221: (ScreenFormat *)Xmalloc( ! 222: (unsigned) (dpy->nformats *sizeof(ScreenFormat))); ! 223: if (dpy->pixmap_format == NULL) { ! 224: OutOfMemory (dpy, setup); ! 225: UnlockMutex(&lock); ! 226: return(NULL); ! 227: } ! 228: /* ! 229: * First decode the Z axis Screen format information. ! 230: */ ! 231: for (i = 0; i < dpy->nformats; i++) { ! 232: register ScreenFormat *fmt = &dpy->pixmap_format[i]; ! 233: fmt->depth = u.sf->depth; ! 234: fmt->bits_per_pixel = u.sf->bitsPerPixel; ! 235: fmt->scanline_pad = u.sf->scanLinePad; ! 236: fmt->ext_data = NULL; ! 237: u.sf += 1; ! 238: } ! 239: ! 240: /* ! 241: * next the Screen structures. ! 242: */ ! 243: dpy->screens = ! 244: (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen)); ! 245: if (dpy->screens == NULL) { ! 246: OutOfMemory (dpy, setup); ! 247: UnlockMutex(&lock); ! 248: return(NULL); ! 249: } ! 250: /* ! 251: * Now go deal with each screen structure. ! 252: */ ! 253: for (i = 0; i < dpy->nscreens; i++) { ! 254: register Screen *sp = &dpy->screens[i]; ! 255: VisualID root_visualID = u.rp->rootVisualID; ! 256: sp->display = dpy; ! 257: sp->root = u.rp->windowId; ! 258: sp->cmap = u.rp->defaultColormap; ! 259: sp->white_pixel = u.rp->whitePixel; ! 260: sp->black_pixel = u.rp->blackPixel; ! 261: sp->root_input_mask = u.rp->currentInputMask; ! 262: sp->width = u.rp->pixWidth; ! 263: sp->height = u.rp->pixHeight; ! 264: sp->mwidth = u.rp->mmWidth; ! 265: sp->mheight = u.rp->mmHeight; ! 266: sp->min_maps = u.rp->minInstalledMaps; ! 267: sp->max_maps = u.rp->maxInstalledMaps; ! 268: sp->root_visual = NULL; /* filled in later, when we alloc Visuals */ ! 269: sp->backing_store= u.rp->backingStore; ! 270: sp->save_unders = u.rp->saveUnders; ! 271: sp->root_depth = u.rp->rootDepth; ! 272: sp->ndepths = u.rp->nDepths; ! 273: sp->ext_data = NULL; ! 274: u.rp += 1; ! 275: /* ! 276: * lets set up the depth structures. ! 277: */ ! 278: sp->depths = (Depth *)Xmalloc( ! 279: (unsigned)sp->ndepths*sizeof(Depth)); ! 280: if (sp->depths == NULL) { ! 281: OutOfMemory (dpy, setup); ! 282: UnlockMutex(&lock); ! 283: return(NULL); ! 284: } ! 285: /* ! 286: * for all depths on this screen. ! 287: */ ! 288: for (j = 0; j < sp->ndepths; j++) { ! 289: Depth *dp = &sp->depths[j]; ! 290: dp->depth = u.dp->depth; ! 291: dp->nvisuals = u.dp->nVisuals; ! 292: u.dp += 1; ! 293: dp->visuals = ! 294: (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual)); ! 295: if (dp->visuals == NULL) { ! 296: OutOfMemory (dpy, setup); ! 297: UnlockMutex(&lock); ! 298: return(NULL); ! 299: } ! 300: for (k = 0; k < dp->nvisuals; k++) { ! 301: register Visual *vp = &dp->visuals[k]; ! 302: if ((vp->visualid = u.vp->visualID) == root_visualID) ! 303: sp->root_visual = vp; ! 304: vp->class = u.vp->class; ! 305: vp->bits_per_rgb= u.vp->bitsPerRGB; ! 306: vp->map_entries = u.vp->colormapEntries; ! 307: vp->red_mask = u.vp->redMask; ! 308: vp->green_mask = u.vp->greenMask; ! 309: vp->blue_mask = u.vp->blueMask; ! 310: vp->ext_data = NULL; ! 311: u.vp += 1; ! 312: } ! 313: } ! 314: } ! 315: ! 316: ! 317: /* ! 318: * Setup other information in this display structure. ! 319: */ ! 320: dpy->vnumber = X_PROTOCOL; ! 321: dpy->resource_alloc = _XAllocID; ! 322: dpy->synchandler = NULL; ! 323: dpy->request = 0; ! 324: dpy->last_request_read = 0; ! 325: dpy->default_screen = screen_num; /* Value returned by ConnectDisplay */ ! 326: dpy->last_req = (char *)&_dummy_request; ! 327: ! 328: /* Salt away the host:display string for later use */ ! 329: if ((dpy->display_name = Xmalloc( ! 330: (unsigned) (strlen(displaybuf) + 1))) == NULL) { ! 331: OutOfMemory (dpy, setup); ! 332: UnlockMutex(&lock); ! 333: return(NULL); ! 334: } ! 335: (void) strcpy (dpy->display_name, displaybuf); ! 336: ! 337: /* Set up the output buffers. */ ! 338: if ((dpy->bufptr = dpy->buffer = Xmalloc(BUFSIZE)) == NULL) { ! 339: OutOfMemory (dpy, setup); ! 340: UnlockMutex(&lock); ! 341: return(NULL); ! 342: } ! 343: dpy->bufmax = dpy->buffer + BUFSIZE; ! 344: ! 345: /* Set up the input event queue and input event queue parameters. */ ! 346: dpy->head = dpy->tail = NULL; ! 347: dpy->qlen = 0; ! 348: ! 349: /* ! 350: * Now start talking to the server to setup all other information... ! 351: */ ! 352: ! 353: Xfree (setup); /* all finished with setup information */ ! 354: /* ! 355: * Set up other stuff clients are always going to use. ! 356: */ ! 357: for (i = 0; i < dpy->nscreens; i++) { ! 358: register Screen *sp = &dpy->screens[i]; ! 359: XGCValues values; ! 360: values.foreground = sp->white_pixel; ! 361: values.background = sp->black_pixel; ! 362: sp->default_gc = XCreateGC (dpy, sp->root, ! 363: GCForeground|GCBackground, &values); ! 364: } ! 365: /* ! 366: * call into synchronization routine so that all programs can be ! 367: * forced synchronize ! 368: */ ! 369: (void) XSynchronize(dpy, _Xdebug); ! 370: /* ! 371: * chain this stucture onto global list. ! 372: */ ! 373: dpy->next = _XHeadOfDisplayList; ! 374: _XHeadOfDisplayList = dpy; ! 375: UnlockDisplay(dpy); ! 376: UnlockMutex(&lock); ! 377: /* ! 378: * get the resource manager database off the root window. ! 379: */ ! 380: { ! 381: Atom actual_type; ! 382: int actual_format; ! 383: unsigned long nitems; ! 384: long leftover; ! 385: if (XGetWindowProperty(dpy, RootWindow(dpy, 0), ! 386: XA_RESOURCE_MANAGER, 0L, 100000000L, False, XA_STRING, ! 387: &actual_type, &actual_format, &nitems, &leftover, ! 388: &dpy->xdefaults) != Success) { ! 389: dpy->xdefaults = (char *) NULL; ! 390: } ! 391: else { ! 392: if ( (actual_type != XA_STRING) || (actual_format != 8) ) { ! 393: if (dpy->xdefaults != NULL) Xfree ( dpy->xdefaults ); ! 394: } ! 395: } ! 396: } ! 397: return(dpy); ! 398: } ! 399: ! 400: ! 401: /* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL ! 402: after this returns. */ ! 403: ! 404: static OutOfMemory (dpy, setup) ! 405: Display *dpy; ! 406: char *setup; ! 407: { ! 408: _XDisconnectDisplay (dpy->fd); ! 409: _XFreeDisplayStructure (dpy); ! 410: Xfree (setup); ! 411: errno = ENOMEM; ! 412: } ! 413: ! 414: ! 415: /* XFreeDisplayStructure frees all the storage associated with a ! 416: * Display. It is used by XOpenDisplay if it runs out of memory, ! 417: * and also by XCloseDisplay. It needs to check whether all pointers ! 418: * are non-NULL before dereferencing them, since it may be called ! 419: * by XOpenDisplay before the Display structure is fully formed. ! 420: * XOpenDisplay must be sure to initialize all the pointers to NULL ! 421: * before the first possible call on this. ! 422: */ ! 423: ! 424: _XFreeDisplayStructure(dpy) ! 425: register Display *dpy; ! 426: { ! 427: if (dpy->screens) { ! 428: register int i; ! 429: ! 430: for (i = 0; i < dpy->nscreens; i++) { ! 431: Screen *sp = &dpy->screens[i]; ! 432: ! 433: if (sp->depths) { ! 434: register int j; ! 435: ! 436: for (j = 0; j < sp->ndepths; j++) { ! 437: Depth *dp = &sp->depths[j]; ! 438: ! 439: if (dp->visuals) { ! 440: register int k; ! 441: ! 442: for (k = 0; k < dp->nvisuals; k++) ! 443: _XFreeExtData (dp->visuals[k].ext_data); ! 444: Xfree ((char *) dp->visuals); ! 445: } ! 446: } ! 447: ! 448: Xfree ((char *) sp->depths); ! 449: } ! 450: ! 451: _XFreeExtData (sp->ext_data); ! 452: } ! 453: ! 454: Xfree ((char *)dpy->screens); ! 455: } ! 456: ! 457: if (dpy->pixmap_format) { ! 458: register int i; ! 459: ! 460: for (i = 0; i < dpy->nformats; i++) ! 461: _XFreeExtData (dpy->pixmap_format[i].ext_data); ! 462: Xfree ((char *)dpy->pixmap_format); ! 463: } ! 464: ! 465: if (dpy->display_name) ! 466: Xfree (dpy->display_name); ! 467: ! 468: if (dpy->buffer) ! 469: Xfree (dpy->buffer); ! 470: if (dpy->keysyms) ! 471: Xfree ((char *) dpy->keysyms); ! 472: if (dpy->xdefaults) ! 473: Xfree (dpy->xdefaults); ! 474: ! 475: _XFreeExtData (dpy->ext_data); ! 476: ! 477: Xfree ((char *)dpy); ! 478: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.