~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/X11/OpenDis.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: OpenDis.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */
 
2
/*
 
3
 
 
4
Copyright 1985, 1986, 1998  The Open Group
 
5
 
 
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
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
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.
 
21
 
 
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.
 
25
 
 
26
*/
 
27
/* $XFree86: xc/lib/X11/OpenDis.c,v 3.12 2001/12/14 19:54:03 dawes Exp $ */
 
28
 
 
29
#define NEED_REPLIES
 
30
#define NEED_EVENTS
 
31
#include "Xlibint.h"
 
32
#include <X11/Xtrans.h>
 
33
#include <X11/Xatom.h>
 
34
#include "bigreqstr.h"
 
35
#include <stdio.h>
 
36
#include "Xintconn.h"
 
37
 
 
38
#ifdef XKB
 
39
#include "XKBlib.h"
 
40
#endif /* XKB */
 
41
 
 
42
#ifdef X_NOT_POSIX
 
43
#define Size_t unsigned int
 
44
#else
 
45
#define Size_t size_t
 
46
#endif
 
47
 
 
48
#define bignamelen (sizeof(XBigReqExtensionName) - 1)
 
49
 
 
50
typedef struct {
 
51
    unsigned long seq;
 
52
    int opcode;
 
53
} _XBigReqState;
 
54
 
 
55
#ifdef WIN32
 
56
int *_Xdebug_p = &_Xdebug;
 
57
#endif
 
58
 
 
59
#ifdef XTHREADS
 
60
#include "locking.h"
 
61
int  (*_XInitDisplayLock_fn)(Display *dpy) = NULL;
 
62
void (*_XFreeDisplayLock_fn)(Display *dpy) = NULL;
 
63
 
 
64
#define InitDisplayLock(d)      (_XInitDisplayLock_fn ? (*_XInitDisplayLock_fn)(d) : Success)
 
65
#define FreeDisplayLock(d)      if (_XFreeDisplayLock_fn) (*_XFreeDisplayLock_fn)(d)
 
66
#else
 
67
#define InitDisplayLock(dis) Success
 
68
#define FreeDisplayLock(dis)
 
69
#endif /* XTHREADS */
 
70
 
 
71
static xReq _dummy_request = {
 
72
        0, 0, 0
 
73
};
 
74
 
 
75
static void OutOfMemory(Display *dpy, char *setup);
 
76
static Bool _XBigReqHandler(Display *dpy, xReply *rep, char *buf, int len,
 
77
                                XPointer data);
 
78
 
 
79
/* 
 
80
 * Connects to a server, creates a Display object and returns a pointer to
 
81
 * the newly created Display back to the caller.
 
82
 */
 
83
#if NeedFunctionPrototypes
 
84
Display *XOpenDisplay (
 
85
        register _Xconst char *display)
 
86
#else
 
87
Display *XOpenDisplay (display)
 
88
        register char *display;
 
89
#endif
 
90
{
 
91
        register Display *dpy;          /* New Display object being created. */
 
92
        register int i;
 
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? */
 
104
        union {
 
105
                xConnSetup *setup;
 
106
                char *failure;
 
107
                char *vendor;
 
108
                xPixmapFormat *sf;
 
109
                xWindowRoot *rp;
 
110
                xDepth *dp;
 
111
                xVisualType *vp;
 
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;
 
116
        unsigned long mask;
 
117
 
 
118
        bzero((char *) &client, sizeof(client));
 
119
        bzero((char *) &prefix, sizeof(prefix));
 
120
 
 
121
        /*
 
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.
 
124
         */
 
125
        if (display == NULL || *display == '\0') {
 
126
                if ((display_name = getenv("DISPLAY")) == NULL) {
 
127
                        /* Oops! No DISPLAY environment variable - error. */
 
128
                        return(NULL);
 
129
                }
 
130
        }
 
131
        else {
 
132
                /* Display is non-NULL, copy the pointer */
 
133
                display_name = (char *)display;
 
134
        }
 
135
/*
 
136
 * Set the default error handlers.  This allows the global variables to
 
137
 * default to NULL for use with shared libraries.
 
138
 */
 
139
        if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL);
 
140
        if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL);
 
141
 
 
142
/*
 
143
 * Attempt to allocate a display structure. Return NULL if allocation fails.
 
144
 */
 
145
        if ((dpy = (Display *)Xcalloc(1, sizeof(Display))) == NULL) {
 
146
                return(NULL);
 
147
        }
 
148
 
 
149
/*
 
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.
 
153
 */
 
154
 
 
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);
 
161
                return(NULL);
 
162
        }
 
163
 
 
164
        dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn);
 
165
 
 
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.
 
169
         */
 
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;
 
181
        dpy->ext_number         = 0;
 
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;
 
189
        }
 
190
        for (i = LASTEvent; i < 128; i++) {
 
191
            dpy->event_vec[i]   = _XUnknownWireEvent;
 
192
            dpy->wire_vec[i]    = _XUnknownNativeEvent;
 
193
        }
 
194
        dpy->resource_id        = 0;
 
195
        dpy->db                 = (struct _XrmHashBucketRec *)NULL;
 
196
        dpy->cursor_font        = None;
 
197
        dpy->flags              = 0;
 
198
        dpy->async_handlers     = NULL;
 
199
        dpy->screens            = NULL;
 
200
        dpy->vendor             = NULL;
 
201
        dpy->buffer             = NULL;
 
202
        dpy->atoms              = 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;
 
212
        dpy->lock               = NULL;
 
213
        dpy->lock_fns           = NULL;
 
214
        dpy->qfree              = 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;
 
220
        dpy->filedes            = NULL;
 
221
        dpy->flushes            = NULL;
 
222
        dpy->xcmisc_opcode      = 0;
 
223
        dpy->xkb_info           = NULL;
 
224
 
 
225
/*
 
226
 * Setup other information in this display structure.
 
227
 */
 
228
        dpy->vnumber = X_PROTOCOL;
 
229
        dpy->resource_alloc = _XAllocID;
 
230
        dpy->idlist_alloc = _XAllocIDs;
 
231
        dpy->synchandler = NULL;
 
232
        dpy->savedsynchandler = NULL;
 
233
        dpy->request = 0;
 
234
        dpy->last_request_read = 0;
 
235
        dpy->default_screen = iscreen;  /* Value returned by ConnectDisplay */
 
236
        dpy->last_req = (char *)&_dummy_request;
 
237
 
 
238
        /* Initialize the display lock */
 
239
        if (InitDisplayLock(dpy) != 0) {
 
240
                OutOfMemory (dpy, setup);
 
241
                return(NULL);
 
242
        }
 
243
 
 
244
        if (!_XPollfdCacheInit(dpy)) {
 
245
                OutOfMemory (dpy, setup);
 
246
                return(NULL);
 
247
        }       
 
248
 
 
249
        /* Set up the output buffers. */
 
250
        if ((dpy->bufptr = dpy->buffer = Xcalloc(1, BUFSIZE)) == NULL) {
 
251
                OutOfMemory (dpy, setup);
 
252
                return(NULL);
 
253
        }
 
254
        dpy->bufmax = dpy->buffer + BUFSIZE;
 
255
 
 
256
        /* Set up the input event queue and input event queue parameters. */
 
257
        dpy->head = dpy->tail = NULL;
 
258
        dpy->qlen = 0;
 
259
 
 
260
        /* Set up free-function record */
 
261
        if ((dpy->free_funcs = (_XFreeFuncRec *)Xcalloc(1,
 
262
                                                        sizeof(_XFreeFuncRec)))
 
263
            == NULL) {
 
264
            OutOfMemory (dpy, setup);
 
265
            return(NULL);
 
266
        }
 
267
 
 
268
/*
 
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.
 
273
 */
 
274
        endian = 1;
 
275
        if (*(char *) &endian)
 
276
            client.byteOrder = '\154'; /* 'l' */
 
277
        else
 
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,
 
285
                                        &prefix);
 
286
        if (prefixread < 0)
 
287
        {
 
288
            _XDisconnectDisplay (dpy->trans_conn);
 
289
            Xfree ((char *)dpy);
 
290
            return(NULL);
 
291
        }
 
292
        if (conn_auth_name) Xfree(conn_auth_name);
 
293
        if (conn_auth_data) Xfree(conn_auth_data);
 
294
/*
 
295
 * Now see if connection was accepted...
 
296
 */
 
297
        /* these internal functions expect the display to be locked */
 
298
        LockDisplay(dpy);
 
299
 
 
300
        if (prefixread == 0)
 
301
            _XRead (dpy, (char *)&prefix,(long)SIZEOF(xConnSetupPrefix));
 
302
 
 
303
        /* an Authenticate reply we weren't expecting? */
 
304
        if (prefix.success != xTrue && prefix.success != xFalse) {
 
305
            fprintf (stderr,
 
306
      "Xlib: unexpected connection setup reply from server, type %d.\r\n",
 
307
                     prefix.success);
 
308
            _XDisconnectDisplay (dpy->trans_conn);
 
309
            Xfree ((char *)dpy);
 
310
            return(NULL);
 
311
        }
 
312
 
 
313
        if (prefix.majorVersion != X_PROTOCOL) {
 
314
            /* XXX - printing messages marks a bad programming interface */
 
315
            fprintf (stderr,
 
316
     "Xlib: client uses different protocol version (%d) than server (%d)!\r\n",
 
317
                     X_PROTOCOL, prefix.majorVersion);
 
318
            _XDisconnectDisplay (dpy->trans_conn);
 
319
            Xfree ((char *)dpy);
 
320
            return(NULL);
 
321
        }
 
322
 
 
323
        setuplength = prefix.length << 2;
 
324
        if ( (u.setup = (xConnSetup *)
 
325
              (setup =  Xmalloc ((unsigned) setuplength))) == NULL) {
 
326
                _XDisconnectDisplay (dpy->trans_conn);
 
327
                Xfree ((char *)dpy);
 
328
                return(NULL);
 
329
        }
 
330
        _XRead (dpy, (char *)u.setup, setuplength);
 
331
/*
 
332
 * If the connection was not accepted by the server due to problems,
 
333
 * give error message to the user....
 
334
 */
 
335
        if (prefix.success != xTrue) {
 
336
                /* XXX - printing messages marks a bad programming interface */
 
337
                fprintf (stderr, 
 
338
                      "Xlib: connection to \"%s\" refused by server\r\nXlib: ",
 
339
                         fullname);
 
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);
 
344
                return (NULL);
 
345
        }
 
346
 
 
347
/*
 
348
 * We succeeded at authorization, so let us move the data into
 
349
 * the display structure.
 
350
 */
 
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;
 
368
        if (!mask)
 
369
        {
 
370
            fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n",
 
371
                     fullname);
 
372
            OutOfMemory(dpy, setup);
 
373
            return (NULL);
 
374
        }
 
375
    
 
376
        while (!(mask & 1)) {
 
377
            dpy->resource_shift++;
 
378
            mask = mask >> 1;
 
379
        }
 
380
        dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5;
 
381
/*
 
382
 * now extract the vendor string...  String must be null terminated,
 
383
 * padded to multiple of 4 bytes.
 
384
 */
 
385
        /* Check for a sane vendor string length */
 
386
        if (u.setup->nbytesVendor > 256) {
 
387
            OutOfMemory(dpy, setup);
 
388
            return (NULL);
 
389
        }
 
390
        dpy->vendor = (char *) Xmalloc((unsigned) (u.setup->nbytesVendor + 1));
 
391
        if (dpy->vendor == NULL) {
 
392
            OutOfMemory(dpy, setup);
 
393
            return (NULL);
 
394
        }
 
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 */
 
400
/*
 
401
 * validate setup length
 
402
 */
 
403
        if ((int) setuplength - sz_xConnSetup - vendorlen < 0) {
 
404
            OutOfMemory(dpy, setup);
 
405
            return (NULL);
 
406
        }
 
407
        memmove (setup, u.vendor + vendorlen,
 
408
                 (int) setuplength - sz_xConnSetup - vendorlen);
 
409
        u.vendor = setup;
 
410
/*
 
411
 * Now iterate down setup information.....
 
412
 */
 
413
        dpy->pixmap_format = 
 
414
            (ScreenFormat *)Xmalloc(
 
415
                (unsigned) (dpy->nformats *sizeof(ScreenFormat)));
 
416
        if (dpy->pixmap_format == NULL) {
 
417
                OutOfMemory (dpy, setup);
 
418
                return(NULL);
 
419
        }
 
420
/*
 
421
 * First decode the Z axis Screen format information.
 
422
 */
 
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);
 
430
        }
 
431
 
 
432
/*
 
433
 * next the Screen structures.
 
434
 */
 
435
        dpy->screens = 
 
436
            (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen));
 
437
        if (dpy->screens == NULL) {
 
438
                OutOfMemory (dpy, setup);
 
439
                return(NULL);
 
440
        }
 
441
/*
 
442
 * Now go deal with each screen structure.
 
443
 */
 
444
        for (i = 0; i < dpy->nscreens; i++) {
 
445
            register Screen *sp = &dpy->screens[i];
 
446
            VisualID root_visualID = u.rp->rootVisualID;
 
447
            sp->display     = dpy;
 
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;
 
463
            sp->ext_data   = NULL;
 
464
            u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot);
 
465
/*
 
466
 * lets set up the depth structures.
 
467
 */
 
468
            sp->depths = (Depth *)Xmalloc(
 
469
                        (unsigned)sp->ndepths*sizeof(Depth));
 
470
            if (sp->depths == NULL) {
 
471
                OutOfMemory (dpy, setup);
 
472
                return(NULL);
 
473
            }
 
474
            /*
 
475
             * for all depths on this screen.
 
476
             */
 
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) {
 
483
                    dp->visuals = 
 
484
                      (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual));
 
485
                    if (dp->visuals == NULL) {
 
486
                        OutOfMemory (dpy, setup);
 
487
                        return(NULL);
 
488
                    }
 
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;
 
498
                        vp->ext_data    = NULL;
 
499
                        u.vp = (xVisualType *) (((char *) u.vp) +
 
500
                                                sz_xVisualType);
 
501
                    }
 
502
                } else {
 
503
                    dp->visuals = (Visual *) NULL;
 
504
                }
 
505
            }
 
506
            sp->root_visual = _XVIDtoVisual(dpy, root_visualID);
 
507
        }
 
508
                
 
509
 
 
510
/*
 
511
 * Now start talking to the server to setup all other information...
 
512
 */
 
513
 
 
514
        Xfree (setup);  /* all finished with setup information */
 
515
 
 
516
/*
 
517
 * Make sure default screen is legal.
 
518
 */
 
519
        if (iscreen >= dpy->nscreens) {
 
520
            OutOfMemory(dpy, (char *) NULL);
 
521
            return(NULL);
 
522
        }
 
523
 
 
524
/*
 
525
 * finished calling internal routines, now unlock for external routines
 
526
 */
 
527
        UnlockDisplay(dpy);
 
528
 
 
529
/*
 
530
 * Set up other stuff clients are always going to use.
 
531
 */
 
532
        for (i = 0; i < dpy->nscreens; i++) {
 
533
            register Screen *sp = &dpy->screens[i];
 
534
            XGCValues values;
 
535
            values.foreground = sp->black_pixel;
 
536
            values.background = sp->white_pixel;
 
537
            if ((sp->default_gc = XCreateGC (dpy, sp->root,
 
538
                                             GCForeground|GCBackground,
 
539
                                             &values)) == NULL) {
 
540
                OutOfMemory(dpy, (char *) NULL);
 
541
                return (NULL);
 
542
            }
 
543
        }
 
544
/*
 
545
 * call into synchronization routine so that all programs can be
 
546
 * forced synchronous
 
547
 */
 
548
        (void) XSynchronize(dpy, _Xdebug);
 
549
 
 
550
/*
 
551
 * get availability of large requests, and
 
552
 * get the resource manager database off the root window.
 
553
 */
 
554
        LockDisplay(dpy);
 
555
        {
 
556
            _XAsyncHandler async;
 
557
            _XBigReqState async_state;
 
558
            xQueryExtensionReq *qreq;
 
559
            xGetPropertyReply reply;
 
560
            xGetPropertyReq *req;
 
561
            xBigReqEnableReq *breq;
 
562
            xBigReqEnableReply brep;
 
563
 
 
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);
 
574
 
 
575
            GetReq (GetProperty, req);
 
576
            req->window = RootWindow(dpy, 0);
 
577
            req->property = XA_RESOURCE_MANAGER;
 
578
            req->type = XA_STRING;
 
579
            req->delete = False;
 
580
            req->longOffset = 0;
 
581
            req->longLength = 100000000L;
 
582
 
 
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';
 
590
                }
 
591
                else if (reply.propertyType != None)
 
592
                    _XEatData(dpy, reply.nItems * (reply.format >> 3));
 
593
            }
 
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;
 
601
            }
 
602
        }
 
603
        UnlockDisplay(dpy);
 
604
 
 
605
#ifdef MOTIFBC
 
606
        {
 
607
            extern Display *_XHeadOfDisplayList;
 
608
            _XHeadOfDisplayList = dpy;
 
609
        }
 
610
#endif
 
611
#ifdef XKB
 
612
        XkbUseExtension(dpy,NULL,NULL);
 
613
#endif
 
614
/*
 
615
 * and return successfully
 
616
 */
 
617
        return(dpy);
 
618
}
 
619
 
 
620
static Bool
 
621
_XBigReqHandler(dpy, rep, buf, len, data)
 
622
    register Display *dpy;
 
623
    register xReply *rep;
 
624
    char *buf;
 
625
    int len;
 
626
    XPointer data;
 
627
{
 
628
    _XBigReqState *state;
 
629
    xQueryExtensionReply replbuf;
 
630
    xQueryExtensionReply *repl;
 
631
 
 
632
    state = (_XBigReqState *)data;
 
633
    if (dpy->last_request_read != state->seq)
 
634
        return False;
 
635
    if (rep->generic.type == X_Error)
 
636
        return True;
 
637
    repl = (xQueryExtensionReply *)
 
638
        _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
 
639
                        (SIZEOF(xQueryExtensionReply) - SIZEOF(xReply)) >> 2,
 
640
                        True);
 
641
    if (repl->present)
 
642
        state->opcode = repl->major_opcode;
 
643
    return True;
 
644
}
 
645
 
 
646
 
 
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.
 
654
 */
 
655
 
 
656
void _XFreeDisplayStructure(dpy)
 
657
        register Display *dpy;
 
658
{
 
659
        while (dpy->ext_procs) {
 
660
            _XExtension *ext = dpy->ext_procs;
 
661
            dpy->ext_procs = ext->next;
 
662
            if (ext->name)
 
663
                Xfree (ext->name);
 
664
            Xfree ((char *)ext);
 
665
        }
 
666
        if (dpy->im_filters)
 
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);
 
674
        if (dpy->atoms)
 
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);
 
680
        if (dpy->context_db)
 
681
           (*dpy->free_funcs->context_db)(dpy);
 
682
        if (dpy->xkb_info)
 
683
           (*dpy->free_funcs->xkb)(dpy);
 
684
 
 
685
        if (dpy->screens) {
 
686
            register int i;
 
687
 
 
688
            for (i = 0; i < dpy->nscreens; i++) {
 
689
                Screen *sp = &dpy->screens[i];
 
690
 
 
691
                if (sp->depths) {
 
692
                   register int j;
 
693
 
 
694
                   for (j = 0; j < sp->ndepths; j++) {
 
695
                        Depth *dp = &sp->depths[j];
 
696
 
 
697
                        if (dp->visuals) {
 
698
                           register int k;
 
699
 
 
700
                           for (k = 0; k < dp->nvisuals; k++)
 
701
                             _XFreeExtData (dp->visuals[k].ext_data);
 
702
                           Xfree ((char *) dp->visuals);
 
703
                           }
 
704
                        }
 
705
 
 
706
                   Xfree ((char *) sp->depths);
 
707
                   }
 
708
 
 
709
                _XFreeExtData (sp->ext_data);
 
710
                }
 
711
 
 
712
            Xfree ((char *)dpy->screens);
 
713
            }
 
714
        
 
715
        if (dpy->pixmap_format) {
 
716
            register int i;
 
717
 
 
718
            for (i = 0; i < dpy->nformats; i++)
 
719
              _XFreeExtData (dpy->pixmap_format[i].ext_data);
 
720
            Xfree ((char *)dpy->pixmap_format);
 
721
            }
 
722
 
 
723
        if (dpy->display_name)
 
724
           Xfree (dpy->display_name);
 
725
        if (dpy->vendor)
 
726
           Xfree (dpy->vendor);
 
727
 
 
728
        if (dpy->buffer)
 
729
           Xfree (dpy->buffer);
 
730
        if (dpy->keysyms)
 
731
           Xfree ((char *) dpy->keysyms);
 
732
        if (dpy->xdefaults)
 
733
           Xfree (dpy->xdefaults);
 
734
        if (dpy->error_vec)
 
735
            Xfree ((char *)dpy->error_vec);
 
736
 
 
737
        _XFreeExtData (dpy->ext_data);
 
738
        if (dpy->free_funcs)
 
739
            Xfree ((char *)dpy->free_funcs);
 
740
        if (dpy->scratch_buffer)
 
741
            Xfree (dpy->scratch_buffer);
 
742
        FreeDisplayLock(dpy);
 
743
 
 
744
        if (dpy->qfree) {
 
745
            register _XQEvent *qelt = dpy->qfree;
 
746
 
 
747
            while (qelt) {
 
748
                register _XQEvent *qnxt = qelt->next;
 
749
                Xfree ((char *) qelt);
 
750
                qelt = qnxt;
 
751
            }
 
752
        }
 
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);
 
758
            Xfree (conni);
 
759
        }
 
760
        if (dpy->conn_watchers) {
 
761
            struct _XConnWatchInfo *watcher = dpy->conn_watchers;
 
762
            dpy->conn_watchers = watcher->next;
 
763
            Xfree (watcher);
 
764
        }
 
765
        if (dpy->filedes)
 
766
            Xfree (dpy->filedes);
 
767
 
 
768
        Xfree ((char *)dpy);
 
769
}
 
770
 
 
771
/* OutOfMemory is called if malloc fails.  XOpenDisplay returns NULL
 
772
   after this returns. */
 
773
 
 
774
static void OutOfMemory (dpy, setup)
 
775
    Display *dpy;
 
776
    char *setup;
 
777
{
 
778
    _XDisconnectDisplay (dpy->trans_conn);
 
779
    _XFreeDisplayStructure (dpy);
 
780
    if (setup) Xfree (setup);
 
781
}