1
/* $Xorg: OpenDis.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */
4
Copyright 1985, 1986, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included in
13
all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
Except as contained in this notice, the name of The Open Group shall not be
23
used in advertising or otherwise to promote the sale, use or other dealings
24
in this Software without prior written authorization from The Open Group.
27
/* $XFree86: xc/lib/X11/OpenDis.c,v 3.12 2001/12/14 19:54:03 dawes Exp $ */
32
#include <X11/Xtrans.h>
33
#include <X11/Xatom.h>
34
#include "bigreqstr.h"
43
#define Size_t unsigned int
48
#define bignamelen (sizeof(XBigReqExtensionName) - 1)
56
int *_Xdebug_p = &_Xdebug;
61
int (*_XInitDisplayLock_fn)(Display *dpy) = NULL;
62
void (*_XFreeDisplayLock_fn)(Display *dpy) = NULL;
64
#define InitDisplayLock(d) (_XInitDisplayLock_fn ? (*_XInitDisplayLock_fn)(d) : Success)
65
#define FreeDisplayLock(d) if (_XFreeDisplayLock_fn) (*_XFreeDisplayLock_fn)(d)
67
#define InitDisplayLock(dis) Success
68
#define FreeDisplayLock(dis)
71
static xReq _dummy_request = {
75
static void OutOfMemory(Display *dpy, char *setup);
76
static Bool _XBigReqHandler(Display *dpy, xReply *rep, char *buf, int len,
80
* Connects to a server, creates a Display object and returns a pointer to
81
* the newly created Display back to the caller.
83
#if NeedFunctionPrototypes
84
Display *XOpenDisplay (
85
register _Xconst char *display)
87
Display *XOpenDisplay (display)
88
register char *display;
91
register Display *dpy; /* New Display object being created. */
93
int j, k; /* random iterator indexes */
94
char *display_name; /* pointer to display name */
95
int endian; /* to determine which endian. */
96
xConnClientPrefix client; /* client information */
97
xConnSetupPrefix prefix; /* prefix information */
98
int vendorlen; /* length of vendor string */
99
char *setup = NULL; /* memory allocated at startup */
100
char *fullname = NULL; /* expanded name of display */
101
int idisplay; /* display number */
102
int iscreen; /* screen number */
103
int prefixread = 0; /* setup prefix already read? */
112
} u; /* proto data returned from server */
113
long setuplength; /* number of bytes in setup message */
114
char *conn_auth_name, *conn_auth_data;
115
int conn_auth_namelen, conn_auth_datalen;
118
bzero((char *) &client, sizeof(client));
119
bzero((char *) &prefix, sizeof(prefix));
122
* If the display specifier string supplied as an argument to this
123
* routine is NULL or a pointer to NULL, read the DISPLAY variable.
125
if (display == NULL || *display == '\0') {
126
if ((display_name = getenv("DISPLAY")) == NULL) {
127
/* Oops! No DISPLAY environment variable - error. */
132
/* Display is non-NULL, copy the pointer */
133
display_name = (char *)display;
136
* Set the default error handlers. This allows the global variables to
137
* default to NULL for use with shared libraries.
139
if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL);
140
if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL);
143
* Attempt to allocate a display structure. Return NULL if allocation fails.
145
if ((dpy = (Display *)Xcalloc(1, sizeof(Display))) == NULL) {
150
* Call the Connect routine to get the transport connection object.
151
* If NULL is returned, the connection failed. The connect routine
152
* will set fullname to point to the expanded name.
155
if ((dpy->trans_conn = _X11TransConnectDisplay (
156
display_name, &fullname, &idisplay,
157
&iscreen, &conn_auth_name,
158
&conn_auth_namelen, &conn_auth_data,
159
&conn_auth_datalen)) == NULL) {
160
Xfree ((char *) dpy);
164
dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn);
166
/* Initialize as much of the display structure as we can.
167
* Initialize pointers to NULL so that XFreeDisplayStructure will
168
* work if we run out of memory before we finish initializing.
170
dpy->display_name = fullname;
171
dpy->keysyms = (KeySym *) NULL;
172
dpy->modifiermap = NULL;
173
dpy->lock_meaning = NoSymbol;
174
dpy->keysyms_per_keycode = 0;
175
dpy->xdefaults = (char *)NULL;
176
dpy->scratch_length = 0L;
177
dpy->scratch_buffer = NULL;
178
dpy->key_bindings = NULL;
179
dpy->ext_procs = (_XExtension *)NULL;
180
dpy->ext_data = (XExtData *)NULL;
182
dpy->event_vec[X_Error] = _XUnknownWireEvent;
183
dpy->event_vec[X_Reply] = _XUnknownWireEvent;
184
dpy->wire_vec[X_Error] = _XUnknownNativeEvent;
185
dpy->wire_vec[X_Reply] = _XUnknownNativeEvent;
186
for (i = KeyPress; i < LASTEvent; i++) {
187
dpy->event_vec[i] = _XWireToEvent;
188
dpy->wire_vec[i] = NULL;
190
for (i = LASTEvent; i < 128; i++) {
191
dpy->event_vec[i] = _XUnknownWireEvent;
192
dpy->wire_vec[i] = _XUnknownNativeEvent;
194
dpy->resource_id = 0;
195
dpy->db = (struct _XrmHashBucketRec *)NULL;
196
dpy->cursor_font = None;
198
dpy->async_handlers = NULL;
203
dpy->error_vec = NULL;
204
dpy->context_db = NULL;
205
dpy->free_funcs = NULL;
206
dpy->pixmap_format = NULL;
207
dpy->cms.clientCmaps = NULL;
208
dpy->cms.defaultCCCs = NULL;
209
dpy->cms.perVisualIntensityMaps = NULL;
210
dpy->im_filters = NULL;
211
dpy->bigreq_size = 0;
213
dpy->lock_fns = NULL;
215
dpy->next_event_serial_num = 1;
216
dpy->im_fd_info = NULL;
217
dpy->im_fd_length = 0;
218
dpy->conn_watchers = NULL;
219
dpy->watcher_count = 0;
222
dpy->xcmisc_opcode = 0;
223
dpy->xkb_info = NULL;
226
* Setup other information in this display structure.
228
dpy->vnumber = X_PROTOCOL;
229
dpy->resource_alloc = _XAllocID;
230
dpy->idlist_alloc = _XAllocIDs;
231
dpy->synchandler = NULL;
232
dpy->savedsynchandler = NULL;
234
dpy->last_request_read = 0;
235
dpy->default_screen = iscreen; /* Value returned by ConnectDisplay */
236
dpy->last_req = (char *)&_dummy_request;
238
/* Initialize the display lock */
239
if (InitDisplayLock(dpy) != 0) {
240
OutOfMemory (dpy, setup);
244
if (!_XPollfdCacheInit(dpy)) {
245
OutOfMemory (dpy, setup);
249
/* Set up the output buffers. */
250
if ((dpy->bufptr = dpy->buffer = Xcalloc(1, BUFSIZE)) == NULL) {
251
OutOfMemory (dpy, setup);
254
dpy->bufmax = dpy->buffer + BUFSIZE;
256
/* Set up the input event queue and input event queue parameters. */
257
dpy->head = dpy->tail = NULL;
260
/* Set up free-function record */
261
if ((dpy->free_funcs = (_XFreeFuncRec *)Xcalloc(1,
262
sizeof(_XFreeFuncRec)))
264
OutOfMemory (dpy, setup);
269
* The xConnClientPrefix describes the initial connection setup information
270
* and is followed by the authorization information. Sites that are interested
271
* in security are strongly encouraged to use an authentication and
272
* authorization system such as Kerberos.
275
if (*(char *) &endian)
276
client.byteOrder = '\154'; /* 'l' */
278
client.byteOrder = '\102'; /* 'B' */
279
client.majorVersion = X_PROTOCOL;
280
client.minorVersion = X_PROTOCOL_REVISION;
281
client.nbytesAuthProto = conn_auth_namelen;
282
client.nbytesAuthString = conn_auth_datalen;
283
prefixread = _XSendClientPrefix(dpy, &client,
284
conn_auth_name, conn_auth_data,
288
_XDisconnectDisplay (dpy->trans_conn);
292
if (conn_auth_name) Xfree(conn_auth_name);
293
if (conn_auth_data) Xfree(conn_auth_data);
295
* Now see if connection was accepted...
297
/* these internal functions expect the display to be locked */
301
_XRead (dpy, (char *)&prefix,(long)SIZEOF(xConnSetupPrefix));
303
/* an Authenticate reply we weren't expecting? */
304
if (prefix.success != xTrue && prefix.success != xFalse) {
306
"Xlib: unexpected connection setup reply from server, type %d.\r\n",
308
_XDisconnectDisplay (dpy->trans_conn);
313
if (prefix.majorVersion != X_PROTOCOL) {
314
/* XXX - printing messages marks a bad programming interface */
316
"Xlib: client uses different protocol version (%d) than server (%d)!\r\n",
317
X_PROTOCOL, prefix.majorVersion);
318
_XDisconnectDisplay (dpy->trans_conn);
323
setuplength = prefix.length << 2;
324
if ( (u.setup = (xConnSetup *)
325
(setup = Xmalloc ((unsigned) setuplength))) == NULL) {
326
_XDisconnectDisplay (dpy->trans_conn);
330
_XRead (dpy, (char *)u.setup, setuplength);
332
* If the connection was not accepted by the server due to problems,
333
* give error message to the user....
335
if (prefix.success != xTrue) {
336
/* XXX - printing messages marks a bad programming interface */
338
"Xlib: connection to \"%s\" refused by server\r\nXlib: ",
340
(void) fwrite (u.failure, (Size_t)sizeof(char),
341
(Size_t)prefix.lengthReason, stderr);
342
(void) fwrite ("\r\n", sizeof(char), 2, stderr);
343
OutOfMemory(dpy, setup);
348
* We succeeded at authorization, so let us move the data into
349
* the display structure.
351
dpy->proto_major_version= prefix.majorVersion;
352
dpy->proto_minor_version= prefix.minorVersion;
353
dpy->release = u.setup->release;
354
dpy->resource_base = u.setup->ridBase;
355
dpy->resource_mask = u.setup->ridMask;
356
dpy->min_keycode = u.setup->minKeyCode;
357
dpy->max_keycode = u.setup->maxKeyCode;
358
dpy->motion_buffer = u.setup->motionBufferSize;
359
dpy->nformats = u.setup->numFormats;
360
dpy->nscreens = u.setup->numRoots;
361
dpy->byte_order = u.setup->imageByteOrder;
362
dpy->bitmap_unit = u.setup->bitmapScanlineUnit;
363
dpy->bitmap_pad = u.setup->bitmapScanlinePad;
364
dpy->bitmap_bit_order = u.setup->bitmapBitOrder;
365
dpy->max_request_size = u.setup->maxRequestSize;
366
mask = dpy->resource_mask;
367
dpy->resource_shift = 0;
370
fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n",
372
OutOfMemory(dpy, setup);
376
while (!(mask & 1)) {
377
dpy->resource_shift++;
380
dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5;
382
* now extract the vendor string... String must be null terminated,
383
* padded to multiple of 4 bytes.
385
/* Check for a sane vendor string length */
386
if (u.setup->nbytesVendor > 256) {
387
OutOfMemory(dpy, setup);
390
dpy->vendor = (char *) Xmalloc((unsigned) (u.setup->nbytesVendor + 1));
391
if (dpy->vendor == NULL) {
392
OutOfMemory(dpy, setup);
395
vendorlen = u.setup->nbytesVendor;
396
u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup);
397
(void) strncpy(dpy->vendor, u.vendor, vendorlen);
398
dpy->vendor[vendorlen] = '\0';
399
vendorlen = (vendorlen + 3) & ~3; /* round up */
401
* validate setup length
403
if ((int) setuplength - sz_xConnSetup - vendorlen < 0) {
404
OutOfMemory(dpy, setup);
407
memmove (setup, u.vendor + vendorlen,
408
(int) setuplength - sz_xConnSetup - vendorlen);
411
* Now iterate down setup information.....
414
(ScreenFormat *)Xmalloc(
415
(unsigned) (dpy->nformats *sizeof(ScreenFormat)));
416
if (dpy->pixmap_format == NULL) {
417
OutOfMemory (dpy, setup);
421
* First decode the Z axis Screen format information.
423
for (i = 0; i < dpy->nformats; i++) {
424
register ScreenFormat *fmt = &dpy->pixmap_format[i];
425
fmt->depth = u.sf->depth;
426
fmt->bits_per_pixel = u.sf->bitsPerPixel;
427
fmt->scanline_pad = u.sf->scanLinePad;
428
fmt->ext_data = NULL;
429
u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat);
433
* next the Screen structures.
436
(Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen));
437
if (dpy->screens == NULL) {
438
OutOfMemory (dpy, setup);
442
* Now go deal with each screen structure.
444
for (i = 0; i < dpy->nscreens; i++) {
445
register Screen *sp = &dpy->screens[i];
446
VisualID root_visualID = u.rp->rootVisualID;
448
sp->root = u.rp->windowId;
449
sp->cmap = u.rp->defaultColormap;
450
sp->white_pixel = u.rp->whitePixel;
451
sp->black_pixel = u.rp->blackPixel;
452
sp->root_input_mask = u.rp->currentInputMask;
453
sp->width = u.rp->pixWidth;
454
sp->height = u.rp->pixHeight;
455
sp->mwidth = u.rp->mmWidth;
456
sp->mheight = u.rp->mmHeight;
457
sp->min_maps = u.rp->minInstalledMaps;
458
sp->max_maps = u.rp->maxInstalledMaps;
459
sp->backing_store= u.rp->backingStore;
460
sp->save_unders = u.rp->saveUnders;
461
sp->root_depth = u.rp->rootDepth;
462
sp->ndepths = u.rp->nDepths;
464
u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot);
466
* lets set up the depth structures.
468
sp->depths = (Depth *)Xmalloc(
469
(unsigned)sp->ndepths*sizeof(Depth));
470
if (sp->depths == NULL) {
471
OutOfMemory (dpy, setup);
475
* for all depths on this screen.
477
for (j = 0; j < sp->ndepths; j++) {
478
Depth *dp = &sp->depths[j];
479
dp->depth = u.dp->depth;
480
dp->nvisuals = u.dp->nVisuals;
481
u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth);
482
if (dp->nvisuals > 0) {
484
(Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual));
485
if (dp->visuals == NULL) {
486
OutOfMemory (dpy, setup);
489
for (k = 0; k < dp->nvisuals; k++) {
490
register Visual *vp = &dp->visuals[k];
491
vp->visualid = u.vp->visualID;
492
vp->class = u.vp->class;
493
vp->bits_per_rgb= u.vp->bitsPerRGB;
494
vp->map_entries = u.vp->colormapEntries;
495
vp->red_mask = u.vp->redMask;
496
vp->green_mask = u.vp->greenMask;
497
vp->blue_mask = u.vp->blueMask;
499
u.vp = (xVisualType *) (((char *) u.vp) +
503
dp->visuals = (Visual *) NULL;
506
sp->root_visual = _XVIDtoVisual(dpy, root_visualID);
511
* Now start talking to the server to setup all other information...
514
Xfree (setup); /* all finished with setup information */
517
* Make sure default screen is legal.
519
if (iscreen >= dpy->nscreens) {
520
OutOfMemory(dpy, (char *) NULL);
525
* finished calling internal routines, now unlock for external routines
530
* Set up other stuff clients are always going to use.
532
for (i = 0; i < dpy->nscreens; i++) {
533
register Screen *sp = &dpy->screens[i];
535
values.foreground = sp->black_pixel;
536
values.background = sp->white_pixel;
537
if ((sp->default_gc = XCreateGC (dpy, sp->root,
538
GCForeground|GCBackground,
540
OutOfMemory(dpy, (char *) NULL);
545
* call into synchronization routine so that all programs can be
548
(void) XSynchronize(dpy, _Xdebug);
551
* get availability of large requests, and
552
* get the resource manager database off the root window.
556
_XAsyncHandler async;
557
_XBigReqState async_state;
558
xQueryExtensionReq *qreq;
559
xGetPropertyReply reply;
560
xGetPropertyReq *req;
561
xBigReqEnableReq *breq;
562
xBigReqEnableReply brep;
564
GetReq(QueryExtension, qreq);
565
async_state.seq = dpy->request;
566
async_state.opcode = 0;
567
async.next = dpy->async_handlers;
568
async.handler = _XBigReqHandler;
569
async.data = (XPointer)&async_state;
570
dpy->async_handlers = &async;
571
qreq->nbytes = bignamelen;
572
qreq->length += (bignamelen+3)>>2;
573
Data(dpy, XBigReqExtensionName, bignamelen);
575
GetReq (GetProperty, req);
576
req->window = RootWindow(dpy, 0);
577
req->property = XA_RESOURCE_MANAGER;
578
req->type = XA_STRING;
581
req->longLength = 100000000L;
583
if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) {
584
if (reply.format == 8 && reply.propertyType == XA_STRING &&
585
(reply.nItems + 1 > 0) &&
586
(reply.nItems <= req->longLength * 4) &&
587
(dpy->xdefaults = Xmalloc (reply.nItems + 1))) {
588
_XReadPad (dpy, dpy->xdefaults, reply.nItems);
589
dpy->xdefaults[reply.nItems] = '\0';
591
else if (reply.propertyType != None)
592
_XEatData(dpy, reply.nItems * (reply.format >> 3));
594
DeqAsyncHandler(dpy, &async);
595
if (async_state.opcode) {
596
GetReq(BigReqEnable, breq);
597
breq->reqType = async_state.opcode;
598
breq->brReqType = X_BigReqEnable;
599
if (_XReply(dpy, (xReply *)&brep, 0, xFalse))
600
dpy->bigreq_size = brep.max_request_size;
607
extern Display *_XHeadOfDisplayList;
608
_XHeadOfDisplayList = dpy;
612
XkbUseExtension(dpy,NULL,NULL);
615
* and return successfully
621
_XBigReqHandler(dpy, rep, buf, len, data)
622
register Display *dpy;
623
register xReply *rep;
628
_XBigReqState *state;
629
xQueryExtensionReply replbuf;
630
xQueryExtensionReply *repl;
632
state = (_XBigReqState *)data;
633
if (dpy->last_request_read != state->seq)
635
if (rep->generic.type == X_Error)
637
repl = (xQueryExtensionReply *)
638
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
639
(SIZEOF(xQueryExtensionReply) - SIZEOF(xReply)) >> 2,
642
state->opcode = repl->major_opcode;
647
/* XFreeDisplayStructure frees all the storage associated with a
648
* Display. It is used by XOpenDisplay if it runs out of memory,
649
* and also by XCloseDisplay. It needs to check whether all pointers
650
* are non-NULL before dereferencing them, since it may be called
651
* by XOpenDisplay before the Display structure is fully formed.
652
* XOpenDisplay must be sure to initialize all the pointers to NULL
653
* before the first possible call on this.
656
void _XFreeDisplayStructure(dpy)
657
register Display *dpy;
659
while (dpy->ext_procs) {
660
_XExtension *ext = dpy->ext_procs;
661
dpy->ext_procs = ext->next;
667
(*dpy->free_funcs->im_filters)(dpy);
668
if (dpy->cms.clientCmaps)
669
(*dpy->free_funcs->clientCmaps)(dpy);
670
if (dpy->cms.defaultCCCs)
671
(*dpy->free_funcs->defaultCCCs)(dpy);
672
if (dpy->cms.perVisualIntensityMaps)
673
(*dpy->free_funcs->intensityMaps)(dpy);
675
(*dpy->free_funcs->atoms)(dpy);
676
if (dpy->modifiermap)
677
(*dpy->free_funcs->modifiermap)(dpy->modifiermap);
678
if (dpy->key_bindings)
679
(*dpy->free_funcs->key_bindings)(dpy);
681
(*dpy->free_funcs->context_db)(dpy);
683
(*dpy->free_funcs->xkb)(dpy);
688
for (i = 0; i < dpy->nscreens; i++) {
689
Screen *sp = &dpy->screens[i];
694
for (j = 0; j < sp->ndepths; j++) {
695
Depth *dp = &sp->depths[j];
700
for (k = 0; k < dp->nvisuals; k++)
701
_XFreeExtData (dp->visuals[k].ext_data);
702
Xfree ((char *) dp->visuals);
706
Xfree ((char *) sp->depths);
709
_XFreeExtData (sp->ext_data);
712
Xfree ((char *)dpy->screens);
715
if (dpy->pixmap_format) {
718
for (i = 0; i < dpy->nformats; i++)
719
_XFreeExtData (dpy->pixmap_format[i].ext_data);
720
Xfree ((char *)dpy->pixmap_format);
723
if (dpy->display_name)
724
Xfree (dpy->display_name);
731
Xfree ((char *) dpy->keysyms);
733
Xfree (dpy->xdefaults);
735
Xfree ((char *)dpy->error_vec);
737
_XFreeExtData (dpy->ext_data);
739
Xfree ((char *)dpy->free_funcs);
740
if (dpy->scratch_buffer)
741
Xfree (dpy->scratch_buffer);
742
FreeDisplayLock(dpy);
745
register _XQEvent *qelt = dpy->qfree;
748
register _XQEvent *qnxt = qelt->next;
749
Xfree ((char *) qelt);
753
while (dpy->im_fd_info) {
754
struct _XConnectionInfo *conni = dpy->im_fd_info;
755
dpy->im_fd_info = conni->next;
756
if (conni->watch_data)
757
Xfree (conni->watch_data);
760
if (dpy->conn_watchers) {
761
struct _XConnWatchInfo *watcher = dpy->conn_watchers;
762
dpy->conn_watchers = watcher->next;
766
Xfree (dpy->filedes);
771
/* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL
772
after this returns. */
774
static void OutOfMemory (dpy, setup)
778
_XDisconnectDisplay (dpy->trans_conn);
779
_XFreeDisplayStructure (dpy);
780
if (setup) Xfree (setup);