|
|
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.