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

« back to all changes in this revision

Viewing changes to unix/xc/lib/dps/dpsXclient.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
/*
 
2
 * dpsXclient.c -- Implementation of the Display PostScript Client Library.
 
3
 *
 
4
 * (c) Copyright 1988-1994 Adobe Systems Incorporated.
 
5
 * All rights reserved.
 
6
 * 
 
7
 * Permission to use, copy, modify, distribute, and sublicense this software
 
8
 * and its documentation for any purpose and without fee is hereby granted,
 
9
 * provided that the above copyright notices appear in all copies and that
 
10
 * both those copyright notices and this permission notice appear in
 
11
 * supporting documentation and that the name of Adobe Systems Incorporated
 
12
 * not be used in advertising or publicity pertaining to distribution of the
 
13
 * software without specific, written prior permission.  No trademark license
 
14
 * to use the Adobe trademarks is hereby granted.  If the Adobe trademark
 
15
 * "Display PostScript"(tm) is used to describe this software, its
 
16
 * functionality or for any other purpose, such use shall be limited to a
 
17
 * statement that this software works in conjunction with the Display
 
18
 * PostScript system.  Proper trademark attribution to reflect Adobe's
 
19
 * ownership of the trademark shall be given whenever any such reference to
 
20
 * the Display PostScript system is made.
 
21
 * 
 
22
 * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
 
23
 * ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
 
24
 * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 
25
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
26
 * NON- INFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL ADOBE BE LIABLE
 
27
 * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
 
28
 * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
 
29
 * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
 
30
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  ADOBE WILL NOT
 
31
 * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
 
32
 * 
 
33
 * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
 
34
 * Incorporated which may be registered in certain jurisdictions
 
35
 * 
 
36
 * Author:  Adobe Systems Incorporated
 
37
 */
 
38
/* $XFree86: xc/lib/dps/dpsXclient.c,v 1.3 2000/09/26 15:56:59 tsi Exp $ */
 
39
 
 
40
#include <stdlib.h>
 
41
#include <unistd.h>     /* sleep() */
 
42
#include <stdio.h>
 
43
#include <string.h>
 
44
#include <ctype.h>
 
45
 
 
46
#ifdef VMS
 
47
/* Xlib does not like UNIX defined to any value under VMS. */
 
48
#undef UNIX
 
49
#include <decw$include/X.h>
 
50
#include <decw$include/Xlib.h>
 
51
 
 
52
#else /* VMS */
 
53
#include <X11/Xlib.h>
 
54
#include <X11/Xutil.h>
 
55
#endif /* VMS */
 
56
 
 
57
#include "DPS/XDPSlib.h"
 
58
#include "DPS/XDPS.h"
 
59
 
 
60
#include "publictypes.h"
 
61
#include "DPS/dpsclient.h"
 
62
#include "dpsprivate.h"
 
63
 
 
64
#include "dpsXpriv.h"
 
65
#include "DPS/dpsXclient.h"
 
66
 
 
67
#include "dpsdict.h"
 
68
#include "DPS/dpsexcept.h"
 
69
 
 
70
#include "dpsXint.h"
 
71
 
 
72
static DPSPrivContext FindPrivContext (
 
73
  Display  *    dpy,
 
74
  long int      cid)
 
75
{
 
76
  DPSPrivSpace ss;
 
77
  DPSPrivContext cc;
 
78
 
 
79
  for (ss = spaces;  ss != NIL;  ss = ss->next)
 
80
    for (cc = ss->firstContext;  cc != NIL;  cc = cc->next)
 
81
      if (cc->cid == cid && ((XDPSPrivContext) cc->wh)->dpy == dpy)
 
82
        return (cc);
 
83
  return (NIL);
 
84
}
 
85
 
 
86
DPSContext XDPSFindContext (
 
87
  Display  *    dpy,
 
88
  int           cid)
 
89
{
 
90
  return ((DPSContext) FindPrivContext (dpy, cid));
 
91
}
 
92
 
 
93
DPSContext DPSContextFromContextID(
 
94
  DPSContext ctxt,
 
95
  int contextID,
 
96
  DPSTextProc textProc,
 
97
  DPSErrorProc errorProc)
 
98
{
 
99
  DPSPrivSpace ss;
 
100
  Display *dpy = ((XDPSPrivContext) ((DPSPrivContext) ctxt)->wh)->dpy;
 
101
  DPSPrivContext c, cc = FindPrivContext (dpy, contextID);
 
102
  DPSPrivContext oldc = (DPSPrivContext)ctxt;
 
103
  
 
104
  if (cc != NIL) return (DPSContext)cc;
 
105
 
 
106
  c = (DPSPrivContext)DPScalloc(sizeof(DPSPrivContextRec), 1);
 
107
  if (!c) return NIL;
 
108
  *c = *oldc;
 
109
  ss = (DPSPrivSpace)c->space;
 
110
  
 
111
  if (textProc) c->textProc = textProc;
 
112
  if (errorProc) c->errorProc = errorProc;
 
113
 
 
114
  c->eofReceived = false;
 
115
  c->cid = contextID;
 
116
  c->buf = c->outBuf = c->objBuf = NIL;
 
117
  c->chainParent = c->chainChild = NIL;
 
118
  
 
119
  c->nBufChars = c->nOutBufChars = c->nObjBufChars = 0;
 
120
 
 
121
  c->next = ss->firstContext;
 
122
  DPSAssert(c->next != c);
 
123
  ss->firstContext = c;
 
124
 
 
125
  /* Note: there's no way to determine whether the new context id was obtained
 
126
  ** as a result of a fork operation or from another application.  so, it must
 
127
  ** be assumed that the application is the creator of the new context.
 
128
  ** Otherwise, it would have called the XDPSContextFromSharedID.
 
129
  */
 
130
  c->creator = true;
 
131
  c->zombie = false;
 
132
  c->numstringOffsets = NULL;
 
133
 
 
134
  DPSIncludePrivContext(
 
135
    (XDPSPrivContext) c->wh, (DPSContext)c, c->cid, ss->sid, DPSclientPrintProc);
 
136
 
 
137
  return (DPSContext)c;
 
138
}
 
139
 
 
140
boolean DPSPrivateCheckWait(
 
141
    DPSContext ctxt)
 
142
{
 
143
    DPSPrivContext cc = (DPSPrivContext) ctxt;
 
144
 
 
145
    if (!cc->creator || cc->zombie) {
 
146
        DPSSafeSetLastNameIndex(ctxt);
 
147
        if (cc->errorProc != NIL) {
 
148
            (*cc->errorProc) (ctxt, cc->zombie ? dps_err_deadContext :
 
149
                                                 dps_err_invalidAccess,
 
150
                              (unsigned long) ctxt, 0);
 
151
        }
 
152
        return true;
 
153
    }
 
154
    return false;
 
155
}
 
156
 
 
157
static void procFlushContext(
 
158
  DPSContext ctxt)
 
159
{
 
160
  DPSPrivContext c = (DPSPrivContext) ctxt;
 
161
  XDPSLFlush (((XDPSPrivContext) c->wh)->dpy);
 
162
  if (ctxt->chainChild != NIL) DPSFlushContext(ctxt->chainChild);
 
163
}
 
164
 
 
165
/* ARGSUSED */
 
166
static Bool FindDPSEvent(
 
167
  Display *dpy,
 
168
  XEvent *event,
 
169
  char *arg)
 
170
{
 
171
  return XDPSIsDPSEvent(event);
 
172
}
 
173
 
 
174
static void procAwaitReturnValues(DPSContext ctxt)
 
175
{
 
176
  DPSPrivContext c = (DPSPrivContext)ctxt;
 
177
 
 
178
  XDPSPrivContext xwh = (XDPSPrivContext) c->wh;
 
179
  XEvent ev;
 
180
 
 
181
  /* Output currently goes only to creator! */
 
182
  if (!c->creator)
 
183
    {
 
184
    DPSSafeSetLastNameIndex(ctxt);
 
185
    c->resultTable = NIL;
 
186
    c->resultTableLength = 0;
 
187
    if (c->errorProc != NIL)
 
188
      (*c->errorProc) (ctxt, dps_err_invalidAccess, 0, 0);
 
189
    return;
 
190
    }
 
191
  if (c->resultTable != NIL)
 
192
    {
 
193
    DPSCheckInitClientGlobals();
 
194
 
 
195
    if (XDPSLGetWrapWaitingFlag(xwh->dpy)) {
 
196
        DPSSafeSetLastNameIndex(ctxt);
 
197
        c->resultTable = NIL;
 
198
        c->resultTableLength = 0;
 
199
        if (c->errorProc != NIL)
 
200
                (*c->errorProc) (ctxt, dps_err_recursiveWait,
 
201
                                 (unsigned long) xwh->dpy, 0);
 
202
        return;
 
203
    }
 
204
    XDPSLSetWrapWaitingFlag(xwh->dpy, True);
 
205
 
 
206
  DURING
 
207
    DPSFlushContext(ctxt);
 
208
    while (c->resultTable != NIL)
 
209
      {
 
210
      /* We may block indefinitely if the context is frozen or it
 
211
         somehow needs more input. */
 
212
      if (c->zombie)
 
213
        {
 
214
        DPSSafeSetLastNameIndex(ctxt);
 
215
        c->resultTable = NIL;
 
216
        c->resultTableLength = 0;
 
217
        if (c->errorProc != NIL)
 
218
          (*c->errorProc) (ctxt, dps_err_deadContext, (unsigned long) c, 0);
 
219
        XDPSLSetWrapWaitingFlag(xwh->dpy, False);
 
220
        E_RTRN_VOID;
 
221
        }
 
222
      
 
223
      /* Someone could conceivably change the event delivery mode in the
 
224
         middle of this...best to check every time */
 
225
 
 
226
      if (XDPSLGetPassEventsFlag(xwh->dpy)) {
 
227
          XIfEvent(xwh->dpy, &ev, FindDPSEvent, (char *) NULL);
 
228
          if (!XDPSDispatchEvent(&ev)) DPSCantHappen();
 
229
      } else DPSSendPostScript((XDPSPrivContext) c->wh, DPSclientPrintProc,
 
230
                               c->cid, NIL, 0, NIL);
 
231
    }
 
232
  HANDLER
 
233
    XDPSLSetWrapWaitingFlag(xwh->dpy, False);
 
234
    RERAISE;
 
235
  END_HANDLER
 
236
 
 
237
  XDPSLSetWrapWaitingFlag(xwh->dpy, False);
 
238
 
 
239
  }
 
240
 
 
241
 /* update space's name map.
 
242
       space->lastNameIndex is the highest index known to be known to the
 
243
         server for this space.
 
244
       c->lastNameIndex is the highest index sent so far to the context
 
245
 */
 
246
 
 
247
  if (((DPSPrivSpace)(c->space))->lastNameIndex < c->lastNameIndex)
 
248
    ((DPSPrivSpace)(c->space))->lastNameIndex = c->lastNameIndex;
 
249
}
 
250
 
 
251
void DPSinnerProcWriteData(
 
252
  DPSContext ctxt,
 
253
  char *buf,
 
254
  unsigned int count)
 
255
{
 
256
  DPSPrivContext c = (DPSPrivContext) ctxt;
 
257
  
 
258
  /* ASSERT: safe to call with chain */
 
259
 
 
260
  /* No local buffering */
 
261
  DPSSendPostScript ((XDPSPrivContext) c->wh, DPSclientPrintProc,
 
262
                     c->cid, buf, count, NIL);
 
263
} /* DPSinnerProcWriteData */
 
264
 
 
265
static void procResetContext(DPSContext ctxt)
 
266
{
 
267
  DPSPrivContext c = (DPSPrivContext) ctxt;
 
268
  int currStatus;
 
269
  register XDPSPrivContext xwh = (XDPSPrivContext) c->wh;
 
270
  int retries = 0;
 
271
  int backoff = 2;
 
272
  
 
273
  /* First make sure context isn't frozen, try to unfreeze. */
 
274
 
 
275
#define DPS_SLEEP_SECS 2
 
276
 
 
277
  while((currStatus = XDPSLGetStatus(xwh->dpy, xwh->cxid)) == PSFROZEN)
 
278
    {
 
279
    XDPSLNotifyContext(xwh->dpy, xwh->cxid, PSUNFREEZE);
 
280
    sleep(DPS_SLEEP_SECS);
 
281
      /* Okay if context is PSRUNNING, since the EOF will
 
282
         be handled at the next PSNEEDSINPUT */
 
283
    }
 
284
 
 
285
  /* Remove events from Xlib Qs before sending the reset request. */
 
286
  XDPSForceEvents (xwh->dpy);
 
287
  
 
288
  if (currStatus == PSSTATUSERROR)
 
289
    /* +++ report error? */;
 
290
  else  /* Didn't become zombie. */
 
291
    {
 
292
    currStatus = 0;
 
293
    XDPSLReset(xwh->dpy, xwh->cxid);
 
294
    XDPSLFlush(xwh->dpy);
 
295
    /* Be optmistic for the first try. Assume the app set up a status mask
 
296
       correctly, we should get a status event without asking the
 
297
       server for status. */
 
298
    
 
299
    XDPSForceEvents(xwh->dpy);
 
300
    currStatus = c->statusFromEvent;
 
301
 
 
302
    while (currStatus != PSNEEDSINPUT && currStatus != PSZOMBIE)
 
303
      {
 
304
      if (currStatus == PSFROZEN)
 
305
          XDPSLNotifyContext(xwh->dpy, xwh->cxid, PSUNFREEZE);
 
306
      if (retries > backoff)
 
307
        {
 
308
        /* Optimism failed.  App probably didn't set up a status mask.
 
309
           Ask the server for status. */
 
310
        currStatus = XDPSLGetStatus(xwh->dpy, xwh->cxid);
 
311
        retries = 0;
 
312
        backoff = (backoff > 30) ? 2 : backoff + 1;
 
313
        continue;
 
314
        }
 
315
      else
 
316
        ++retries;
 
317
      sleep(DPS_SLEEP_SECS);
 
318
      XDPSForceEvents(xwh->dpy);
 
319
      currStatus = c->statusFromEvent;
 
320
      }
 
321
    }
 
322
  
 
323
  c->eofReceived = false;
 
324
}
 
325
 
 
326
void DPSPrivateDestroyContext(DPSContext ctxt)
 
327
{
 
328
  DPSPrivContext c = (DPSPrivContext)ctxt;
 
329
  DPSPrivSpace s = (DPSPrivSpace) c->space;
 
330
 
 
331
  if (c->creator)
 
332
    DPSSendTerminate((XDPSPrivContext) c->wh, c->cid, DPSclientPrintProc);
 
333
  else 
 
334
    XDPSSetStatusMask(ctxt, 0, XDPSL_ALL_EVENTS, 0);  /* Stop status events */
 
335
  /* Don't free the space's wh out from under it */
 
336
  if (c->wh != s->wh) free(c->wh);
 
337
}
 
338
 
 
339
void DPSPrivateDestroySpace(DPSSpace space)
 
340
{
 
341
    DPSPrivSpace ss = (DPSPrivSpace) space;
 
342
 
 
343
    if (ss->creator) DPSSendDestroySpace((XDPSPrivContext) ss->wh, ss->sid,
 
344
                                         DPSclientPrintProc);
 
345
 
 
346
    free (ss->wh);
 
347
}
 
348
 
 
349
boolean DPSCheckShared(DPSPrivContext ctxt)
 
350
{
 
351
  return ctxt->creator == false && ctxt->resultTable != NIL;
 
352
  /* let procAwaitReturnValues generate error */
 
353
}
 
354
 
 
355
/* ARGSUSED */
 
356
void DPSServicePostScript(boolean (*returnControl)(void))
 
357
{
 
358
} /* DPSServicePostScript */
 
359
 
 
360
void DPSHandleBogusError(DPSContext ctxt, char *prefix, char *suffix)
 
361
{
 
362
    char *buf = "bogus error output from context";
 
363
    DPSDefaultPrivateHandler(ctxt, dps_err_warning,
 
364
                             (long unsigned int)buf, 0, prefix, suffix);
 
365
}
 
366
 
 
367
void DPSDefaultPrivateHandler(
 
368
  DPSContext ctxt,
 
369
  DPSErrorCode errorCode,
 
370
  long unsigned int arg1,
 
371
  long unsigned int arg2,
 
372
  char *prefix,
 
373
  char *suffix)
 
374
{
 
375
 
 
376
  DPSTextProc textProc = DPSGetCurrentTextBackstop();
 
377
 
 
378
  switch (errorCode) {
 
379
    case dps_err_invalidAccess:
 
380
      if (textProc != NIL)
 
381
        {
 
382
        char m[100];
 
383
        (void) sprintf (m, "%sInvalid context access.%s", prefix, suffix);
 
384
        (*textProc) (ctxt, m, strlen (m));
 
385
        }
 
386
        break;
 
387
    case dps_err_encodingCheck:
 
388
      if (textProc != NIL)
 
389
        {
 
390
        char m[100];
 
391
        (void) sprintf (m, "%sInvalid name/program encoding: %d/%d.%s",
 
392
                        prefix, (int) arg1, (int) arg2, suffix);
 
393
        (*textProc) (ctxt, m, strlen (m));
 
394
        }
 
395
        break;
 
396
    case dps_err_closedDisplay:
 
397
      if (textProc != NIL)
 
398
        {
 
399
        char m[100];
 
400
        (void) sprintf (m, "%sBroken display connection %d.%s",
 
401
                        prefix, (int) arg1, suffix);
 
402
        (*textProc) (ctxt, m, strlen (m));
 
403
        }
 
404
        break;
 
405
    case dps_err_deadContext:
 
406
      if (textProc != NIL)
 
407
        {
 
408
        char m[100];
 
409
        (void) sprintf (m, "%sDead context 0x0%x.%s", prefix,
 
410
                        (int) arg1, suffix);
 
411
        (*textProc) (ctxt, m, strlen (m));
 
412
        }
 
413
        break;
 
414
    case dps_err_warning:
 
415
      if (textProc != NIL)
 
416
        {
 
417
        char *warn = (char *)arg1;
 
418
        char *msg = "%% DPS Client Library Warning:\n   ";
 
419
        (*textProc)(ctxt, msg, strlen(msg));
 
420
        (*textProc)(ctxt, warn, strlen(warn));
 
421
        msg = "\n";
 
422
        (*textProc)(ctxt, msg, strlen(msg));
 
423
        /* flush convention */
 
424
        (*textProc)(ctxt, msg, 0);
 
425
        }
 
426
        break;
 
427
    case dps_err_fatal:
 
428
      if (textProc != NIL)
 
429
        {
 
430
        char *fatal = (char *)arg1;
 
431
        char *msg = "%% DPS Client Library Fatal Internal Error:\n   ";
 
432
        (*textProc)(ctxt, msg, strlen(msg));
 
433
        (*textProc)(ctxt, fatal, strlen(fatal));
 
434
        msg = ".\nAborting ...\n";
 
435
        (*textProc)(ctxt, msg, strlen(msg));
 
436
        /* flush convention */
 
437
        (*textProc)(ctxt, msg, 0);
 
438
        abort();
 
439
        }
 
440
        break;
 
441
    case dps_err_recursiveWait:
 
442
      if (textProc != NIL)
 
443
        {
 
444
        char m[100];
 
445
        (void) sprintf (m,
 
446
                        "%sRecursive wait for return values, display 0x%x.%s",
 
447
                        prefix, (int) arg1, suffix);
 
448
        (*textProc) (ctxt, m, strlen (m));
 
449
        }
 
450
        break;
 
451
  }
 
452
}
 
453
 
 
454
void DPSInitPrivateSpaceFields(DPSPrivSpace s)
 
455
{
 
456
    s->creator = true;
 
457
}
 
458
 
 
459
void DPSInitPrivateContextFields(DPSPrivContext c, DPSPrivSpace s)
 
460
{
 
461
    c->creator = true;
 
462
    c->zombie = false;
 
463
    if (!s->creator) {
 
464
        c->procs = XDPSconvProcs;
 
465
        c->nameEncoding = dps_strings;
 
466
    }
 
467
}
 
468
 
 
469
void  DPSInitPrivateTextContextFields(DPSPrivContext c, DPSPrivSpace s)
 
470
{
 
471
    c->creator = true;
 
472
    c->zombie = false;
 
473
    c->space = (DPSSpace) s;
 
474
    c->next = s->firstContext;
 
475
    s->firstContext = c;
 
476
}
 
477
  
 
478
long int DPSLastUserObjectIndex = 0;
 
479
 
 
480
long int DPSNewUserObjectIndex (void)
 
481
{
 
482
  return (DPSLastUserObjectIndex++);
 
483
}
 
484
 
 
485
void XDPSSetProcs (void)
 
486
{
 
487
  DPSCheckInitClientGlobals ();
 
488
  if (!textCtxProcs)
 
489
    {
 
490
    textCtxProcs = (DPSProcs) DPScalloc (sizeof (DPSProcsRec), 1);
 
491
    DPSInitCommonTextContextProcs(textCtxProcs);
 
492
    DPSInitSysNames();
 
493
    }
 
494
  if (!ctxProcs)
 
495
    {
 
496
    ctxProcs = (DPSProcs) DPScalloc (sizeof (DPSProcsRec), 1);
 
497
    DPSInitCommonContextProcs(ctxProcs);
 
498
    DPSInitPrivateContextProcs(ctxProcs);
 
499
    }
 
500
  if (!XDPSconvProcs)
 
501
    XDPSconvProcs = (DPSProcs) DPScalloc (sizeof (DPSProcsRec), 1);
 
502
  if (!XDPSrawProcs)
 
503
    XDPSrawProcs = ctxProcs;
 
504
  *XDPSconvProcs = *ctxProcs;
 
505
  XDPSconvProcs->BinObjSeqWrite = textCtxProcs->BinObjSeqWrite;
 
506
  XDPSconvProcs->WriteStringChars = textCtxProcs->WriteStringChars;
 
507
  XDPSconvProcs->WritePostScript = textCtxProcs->WritePostScript;
 
508
  XDPSconvProcs->WriteNumString = textCtxProcs->WriteNumString;
 
509
}
 
510
 
 
511
void DPSInitPrivateContextProcs(DPSProcs p)
 
512
{
 
513
    p->FlushContext = procFlushContext;
 
514
    p->ResetContext = procResetContext;
 
515
    p->AwaitReturnValues = procAwaitReturnValues;
 
516
}
 
517
 
 
518
DPSContext XDPSCreateSimpleContext (
 
519
  Display       *dpy,
 
520
  Drawable      draw,
 
521
  GC            gc,
 
522
  int           x,
 
523
  int           y,
 
524
  DPSTextProc   textProc,
 
525
  DPSErrorProc  errorProc,
 
526
  DPSSpace      space)
 
527
{
 
528
  XDPSPrivContext xwh = XDPSCreatePrivContextRec (dpy, draw, gc, x, y,
 
529
                                                  0, DefaultStdCMap,
 
530
                                                  DefaultStdCMap, 0, false);
 
531
  DPSContext newCtxt;
 
532
  
 
533
  if (xwh == NIL)
 
534
    return (NIL);
 
535
  else
 
536
    {
 
537
    newCtxt = DPSCreateContext ((char *) xwh, textProc, errorProc, space);
 
538
    if (newCtxt == NIL)
 
539
      free ((char *) xwh);
 
540
    return (newCtxt);
 
541
    }
 
542
}
 
543
 
 
544
 
 
545
DPSContext XDPSCreateContext (
 
546
  Display               *dpy,
 
547
  Drawable              draw,
 
548
  GC                    gc,
 
549
  int                   x,
 
550
  int                   y,
 
551
  unsigned int          eventmask,
 
552
  XStandardColormap     *grayramp,
 
553
  XStandardColormap     *ccube,
 
554
  int                   actual,
 
555
  DPSTextProc           textProc,
 
556
  DPSErrorProc          errorProc,
 
557
  DPSSpace              space)
 
558
{
 
559
  XDPSPrivContext xwh = XDPSCreatePrivContextRec (dpy, draw, gc, x, y,
 
560
                                                  eventmask, grayramp,
 
561
                                                  ccube, actual, false);
 
562
  DPSContext newCtxt;
 
563
  
 
564
  if (xwh == NIL)
 
565
    return (NIL);
 
566
  else
 
567
    {
 
568
    newCtxt = DPSCreateContext ((char *) xwh, textProc, errorProc, space);
 
569
    if (newCtxt == NIL)
 
570
      free ((char *) xwh);
 
571
    return (newCtxt);
 
572
    }
 
573
}
 
574
 
 
575
DPSContext XDPSCreateSecureContext (
 
576
  Display               *dpy,
 
577
  Drawable              draw,
 
578
  GC                    gc,
 
579
  int                   x,
 
580
  int                   y,
 
581
  unsigned int          eventmask,
 
582
  XStandardColormap     *grayramp,
 
583
  XStandardColormap     *ccube,
 
584
  int                   actual,
 
585
  DPSTextProc           textProc,
 
586
  DPSErrorProc          errorProc,
 
587
  DPSSpace              space)
 
588
{
 
589
  XDPSPrivContext xwh = XDPSCreatePrivContextRec (dpy, draw, gc, x, y,
 
590
                                                  eventmask, grayramp,
 
591
                                                  ccube, actual, true);
 
592
  DPSContext newCtxt;
 
593
  
 
594
  if (xwh == NIL)
 
595
    return (NIL);
 
596
  else
 
597
    {
 
598
    newCtxt = DPSCreateContext ((char *) xwh, textProc, errorProc, space);
 
599
    if (newCtxt == NIL)
 
600
      free ((char *) xwh);
 
601
    return (newCtxt);
 
602
    }
 
603
}
 
604
 
 
605
 
 
606
DPSContext XDPSContextFromSharedID (dpy, cid, textProc, errorProc)
 
607
  Display         *dpy;
 
608
  ContextPSID     cid;
 
609
  DPSTextProc     textProc;
 
610
  DPSErrorProc    errorProc;
 
611
{
 
612
  DPSPrivContext        c;
 
613
  DPSPrivSpace          s; 
 
614
  ContextXID            cxid;
 
615
  SpaceXID              sxid;
 
616
  XDPSPrivContext       xwh;
 
617
 
 
618
  if (DPSInitialize () != 0)
 
619
    return (NIL);
 
620
 
 
621
  c = FindPrivContext (dpy, cid);
 
622
  if (c != NIL)
 
623
    return ((DPSContext) c);
 
624
 
 
625
  xwh = XDPSCreatePrivContextRec (dpy, 0, 0, 0, 0, 0, NIL, NIL, 0, false);
 
626
  if (xwh == NIL)
 
627
    return (NIL);
 
628
  else if (XDPSLIDFromContext (dpy, cid, &cxid, &sxid) != 1)
 
629
    {
 
630
    free ((char *) xwh);
 
631
    return (NIL);
 
632
    }
 
633
  xwh->cxid = cxid;
 
634
 
 
635
  if (spaceProcs == NIL)
 
636
    {
 
637
    spaceProcs = (DPSSpaceProcs) DPScalloc (sizeof (DPSSpaceProcsRec), 1);
 
638
    DPSInitCommonSpaceProcs(spaceProcs);
 
639
    }
 
640
 
 
641
  s = spaces;
 
642
  while (s != NIL)
 
643
    if ((SpaceXID)s->sid == sxid && ((XDPSPrivContext) s->wh)->dpy == dpy)
 
644
      break;
 
645
    else
 
646
      s = s->next;
 
647
 
 
648
  if (s == NIL)   /* Create new space record. */
 
649
    {
 
650
    s = (DPSPrivSpace) DPScalloc (sizeof (DPSPrivSpaceRec), 1);
 
651
    s->procs = spaceProcs;
 
652
    s->lastNameIndex = -1;
 
653
    s->sid = sxid;
 
654
    s->wh = (char *) xwh;
 
655
    s->creator = false;
 
656
    s->next = spaces;
 
657
    spaces = s;
 
658
    }
 
659
 
 
660
  c = (DPSPrivContext) DPScalloc (sizeof (DPSPrivContextRec), 1);
 
661
  c->space = (DPSSpace) s;
 
662
  c->procs = XDPSconvProcs;
 
663
  c->textProc = textProc;
 
664
  c->errorProc = errorProc;
 
665
  c->programEncoding = DPSDefaultProgramEncoding;
 
666
  c->nameEncoding = dps_strings;
 
667
  c->next = s->firstContext;
 
668
  s->firstContext = c;
 
669
  c->lastNameIndex = s->lastNameIndex;
 
670
  c->cid = cid;
 
671
  c->numstringOffsets = NULL;
 
672
  c->creator = false;
 
673
  c->zombie = false;
 
674
  c->numFormat = XDPSNumFormat (dpy);
 
675
  c->wh = (char *) xwh;
 
676
  
 
677
  xwh->ctxt = (DPSContext) c;
 
678
 
 
679
  return ((DPSContext) c);
 
680
}
 
681
 
 
682
 
 
683
void DPSChangeEncoding (ctxt, newProgEncoding, newNameEncoding)
 
684
  DPSContext         ctxt;
 
685
  DPSProgramEncoding newProgEncoding;
 
686
  DPSNameEncoding    newNameEncoding;
 
687
{
 
688
  if (ctxt->programEncoding != newProgEncoding ||
 
689
      ctxt->nameEncoding != newNameEncoding)
 
690
    {
 
691
      DPSPrivContext cc = (DPSPrivContext) ctxt;
 
692
      DPSPrivSpace   ss = (DPSPrivSpace) (cc->space);
 
693
      
 
694
      if ((!cc->creator || !ss->creator) && newNameEncoding != dps_strings)
 
695
        {
 
696
        DPSSafeSetLastNameIndex(ctxt);
 
697
        if (cc->errorProc != NIL)
 
698
          (*cc->errorProc) (ctxt, dps_err_encodingCheck,
 
699
                            (unsigned long) newNameEncoding,
 
700
                            (unsigned long) newProgEncoding);
 
701
        return;
 
702
        }
 
703
      if (ctxt->procs == textCtxProcs)
 
704
        {
 
705
        ctxt->programEncoding = newProgEncoding;
 
706
        ctxt->nameEncoding = newNameEncoding;
 
707
        }
 
708
      else
 
709
        XDPSSetContextEncoding (ctxt, newProgEncoding, newNameEncoding);
 
710
    }
 
711
}
 
712
 
 
713
 
 
714
DPSSpace XDPSSpaceFromSharedID (dpy, sid)
 
715
  Display       *dpy;
 
716
  SpaceXID      sid;
 
717
{
 
718
  DPSPrivSpace          s;
 
719
  XDPSPrivContext       xwh;
 
720
 
 
721
  if (DPSInitialize () != 0)
 
722
    return (NIL);
 
723
 
 
724
  if (spaceProcs == NIL)
 
725
    {
 
726
    spaceProcs = (DPSSpaceProcs) DPScalloc (sizeof (DPSSpaceProcsRec), 1);
 
727
    DPSInitCommonSpaceProcs(spaceProcs);
 
728
    }
 
729
 
 
730
  s = spaces;
 
731
  while (s != NIL)
 
732
    if ((SpaceXID)s->sid == sid && ((XDPSPrivContext) s->wh)->dpy == dpy)
 
733
      break;
 
734
    else
 
735
      s = s->next;
 
736
 
 
737
  if (s == NIL)   /* Create new space record. */
 
738
    {
 
739
    xwh = XDPSCreatePrivContextRec (dpy, 0, 0, 0, 0, 0, NIL, NIL, 0, false);
 
740
    if (xwh == NIL)
 
741
      return (NIL);
 
742
 
 
743
    s = (DPSPrivSpace) DPScalloc (sizeof (DPSPrivSpaceRec), 1);
 
744
    s->procs = spaceProcs;
 
745
    s->lastNameIndex = -1;
 
746
    s->sid = sid;
 
747
    s->wh = (char *) xwh;
 
748
    s->creator = false;
 
749
    s->next = spaces;
 
750
    spaces = s;
 
751
    }
 
752
 
 
753
  return ((DPSSpace) s);
 
754
}
 
755
 
 
756
 
 
757
void XDPSUnfreezeContext (ctxt)
 
758
  DPSContext ctxt;
 
759
{
 
760
  XDPSPrivContext wh = (XDPSPrivContext) (((DPSPrivContext) ctxt)->wh);
 
761
  
 
762
  if (wh != NIL && wh->cxid != 0)
 
763
    XDPSSendUnfreeze (wh->dpy, wh->cxid);
 
764
}
 
765
 
 
766
 
 
767
ContextXID XDPSXIDFromContext (Pdpy, ctxt)
 
768
  Display    **Pdpy;
 
769
  DPSContext ctxt;
 
770
{
 
771
  XDPSPrivContext  xwh = (XDPSPrivContext) (((DPSPrivContext) ctxt)->wh);
 
772
  
 
773
  if (xwh == NIL || xwh->cxid == 0)
 
774
    {
 
775
    *Pdpy = NULL;
 
776
    return (0);
 
777
    }
 
778
  else
 
779
    {
 
780
    *Pdpy = xwh->dpy;
 
781
    return (xwh->cxid);
 
782
    }
 
783
}
 
784
 
 
785
 
 
786
SpaceXID XDPSXIDFromSpace (Pdpy, space)
 
787
  Display    **Pdpy;
 
788
  DPSSpace   space;
 
789
{
 
790
  DPSPrivSpace     ss = (DPSPrivSpace) space;
 
791
  XDPSPrivContext  xwh = (XDPSPrivContext) ss->wh;
 
792
  
 
793
  if (xwh != NIL && xwh->dpy != NULL)
 
794
    {
 
795
    *Pdpy = xwh->dpy;
 
796
    return (ss->sid);
 
797
    }
 
798
  else
 
799
    {
 
800
    *Pdpy = NULL;
 
801
    return (0);
 
802
    }
 
803
}
 
804
 
 
805
 
 
806
DPSContext XDPSContextFromXID (dpy, cxid)
 
807
  Display    *dpy;
 
808
  ContextXID cxid;
 
809
{
 
810
  DPSPrivContext c;
 
811
  DPSPrivSpace   ss;
 
812
  
 
813
  for (ss = spaces;  ss != NIL;  ss = ss->next)
 
814
    if (((XDPSPrivContext) ss->wh)->dpy == dpy)
 
815
      for (c = ss->firstContext;  c != NIL;  c = c->next)
 
816
        if (((XDPSPrivContext) c->wh)->cxid == cxid)
 
817
          return ((DPSContext) c);
 
818
 
 
819
  return (NIL);
 
820
}
 
821
 
 
822
 
 
823
DPSSpace XDPSSpaceFromXID (dpy, sxid)
 
824
  Display    *dpy;
 
825
  SpaceXID   sxid;
 
826
{
 
827
  DPSPrivSpace  ss;
 
828
  
 
829
  for (ss = spaces;  ss != NIL;  ss = ss->next)
 
830
    if ((SpaceXID)ss->sid == sxid && ((XDPSPrivContext) ss->wh)->dpy == dpy)
 
831
      return ((DPSSpace) ss);
 
832
 
 
833
  return (NIL);
 
834
}
 
835
 
 
836
 
 
837
XDPSStatusProc XDPSRegisterStatusProc (ctxt, statusProc)
 
838
  DPSContext     ctxt;
 
839
  XDPSStatusProc statusProc;
 
840
{
 
841
  DPSPrivContext c = (DPSPrivContext) ctxt;
 
842
  XDPSStatusProc old = c->statusProc;
 
843
  
 
844
  if (c->wh != NIL) c->statusProc = statusProc;
 
845
  return old;
 
846
}
 
847
 
 
848
 
 
849
XDPSReadyProc XDPSRegisterReadyProc (ctxt, readyProc)
 
850
  DPSContext     ctxt;
 
851
  XDPSReadyProc readyProc;
 
852
{
 
853
  DPSPrivContext c = (DPSPrivContext) ctxt;
 
854
  XDPSReadyProc old = c->readyProc;
 
855
  
 
856
  if (c->wh != NIL) c->readyProc = readyProc;
 
857
  return old;
 
858
}
 
859
 
 
860
 
 
861
void XDPSSetStatusMask(ctxt, enableMask, disableMask, nextMask)
 
862
  DPSContext ctxt;
 
863
  unsigned long enableMask, disableMask, nextMask;
 
864
{
 
865
  XDPSPrivContext xwh = (XDPSPrivContext) (((DPSPrivContext) ctxt)->wh);
 
866
  
 
867
  if (xwh != NIL && xwh->cxid != 0)
 
868
    XDPSLSetStatusMask(xwh->dpy, xwh->cxid, enableMask, disableMask, nextMask);
 
869
}
 
870
 
 
871
 
 
872
int XDPSGetContextStatus(ctxt)
 
873
  DPSContext ctxt;
 
874
{
 
875
  DPSPrivContext  c = (DPSPrivContext) ctxt;
 
876
  XDPSPrivContext xwh = (XDPSPrivContext) c->wh;
 
877
  
 
878
  if (xwh != NIL && xwh->cxid != 0)
 
879
    return (XDPSLGetStatus(xwh->dpy, xwh->cxid));
 
880
  else
 
881
    return (0);
 
882
}
 
883
 
 
884
void XDPSNotifyWhenReady(ctxt, i0, i1, i2, i3)
 
885
    DPSContext ctxt;
 
886
    int i0, i1, i2, i3;
 
887
{
 
888
    DPSPrivContext  c = (DPSPrivContext) ctxt;
 
889
    XDPSPrivContext xwh = (XDPSPrivContext) c->wh;
 
890
    int i[4];
 
891
 
 
892
    i[0] = i0;
 
893
    i[1] = i1;
 
894
    i[2] = i2;
 
895
    i[3] = i3;
 
896
    
 
897
    XDPSLNotifyWhenReady(xwh->dpy, xwh->cxid, i);
 
898
}
 
899
 
 
900
void XDPSStatusEventHandler (e)
 
901
  XDPSLStatusEvent *e;
 
902
{
 
903
  DPSPrivContext  c = (DPSPrivContext) XDPSContextFromXID(e->display, e->cxid);
 
904
  
 
905
  if (c == NIL)
 
906
    return;
 
907
  
 
908
  c->statusFromEvent = e->status;
 
909
  if (e->status == PSZOMBIE)
 
910
    {
 
911
    c->zombie = true;
 
912
    if (c->resultTable != NIL)  /* Currently waiting for results */
 
913
      XDPSQuitBlocking = true;
 
914
    }
 
915
  
 
916
  if (c->statusProc != NIL)
 
917
    (*(c->statusProc)) ((DPSContext) c, e->status);
 
918
}
 
919
 
 
920
void XDPSReadyEventHandler (e)
 
921
  XDPSLReadyEvent *e;
 
922
{
 
923
  DPSPrivContext  c = (DPSPrivContext) XDPSContextFromXID(e->display, e->cxid);
 
924
  
 
925
  if (c == NIL)
 
926
    return;
 
927
  
 
928
  if (c->readyProc != NIL)
 
929
    (*(c->readyProc)) ((DPSContext) c, e->val);
 
930
}
 
931
 
 
932
 
 
933
 
 
934
void DPSWarnProc(
 
935
    DPSContext ctxt,
 
936
    char *msg)
 
937
{
 
938
    DPSErrorProc ep;
 
939
 
 
940
    if (DPSInitialize() != 0) return;
 
941
    ep = DPSGetCurrentErrorBackstop();
 
942
    if (ep == NULL) ep = DPSDefaultErrorProc;
 
943
    (*ep)(ctxt, dps_err_warning, (long unsigned int)msg, 0);
 
944
}
 
945
 
 
946
void DPSFatalProc(
 
947
    DPSContext ctxt,
 
948
    char *msg)
 
949
{
 
950
    DPSErrorProc ep;
 
951
 
 
952
    if (DPSInitialize() != 0) return;
 
953
    ep = DPSGetCurrentErrorBackstop();
 
954
    if (ep == NULL) ep = DPSDefaultErrorProc;
 
955
    (*ep)(ctxt, dps_err_fatal, (long unsigned int)msg, 0);
 
956
}
 
957
 
 
958
void DPSCantHappen(void)
 
959
{
 
960
  static int locked = 0;
 
961
  char *msg = "assertion failure or DPSCantHappen";
 
962
  if (locked > 0) abort();
 
963
  ++locked;
 
964
  DPSFatalProc((DPSContext)NULL, msg);
 
965
  /* Fatal proc shouldn't return, but client can override and do anything. */
 
966
  --locked;
 
967
}
 
968
 
 
969
 
 
970
/* Procedures for delayed event dispatching */
 
971
 
 
972
DPSEventDelivery XDPSSetEventDelivery(
 
973
    Display *dpy,
 
974
    DPSEventDelivery newMode)
 
975
{
 
976
    Bool old = XDPSLGetPassEventsFlag(dpy);
 
977
 
 
978
    switch (newMode) {
 
979
        case dps_event_pass_through:
 
980
            XDPSLSetPassEventsFlag(dpy, True);
 
981
            break;
 
982
        case dps_event_internal_dispatch:
 
983
            XDPSLSetPassEventsFlag(dpy, False);
 
984
            break;
 
985
        default:
 
986
            break;
 
987
    }
 
988
 
 
989
    if (old) return dps_event_pass_through;
 
990
    else return dps_event_internal_dispatch;
 
991
}
 
992
 
 
993
Bool XDPSIsStatusEvent(
 
994
    XEvent *event,
 
995
    DPSContext *ctxt,
 
996
    int *status)
 
997
{
 
998
    Display *d = event->xany.display;
 
999
    XExtCodes *c = XDPSLGetCodes(d);
 
1000
    XDPSLStatusEvent *se = (XDPSLStatusEvent *) event;
 
1001
 
 
1002
    if (c == NULL) return False;        /* Not inited on that display;
 
1003
                                           must be False */
 
1004
 
 
1005
    if (!c->first_event)                /* Check CSDPS first */
 
1006
        {
 
1007
        if (XDPSLGetCSDPSFakeEventType(d, event) == csdps_status)
 
1008
            {                           /* Check CSDPS first */
 
1009
            XDPSLGetCSDPSStatus(d, event, (void **)ctxt, status);
 
1010
            return True;
 
1011
            }
 
1012
        else
 
1013
            return False;
 
1014
        }
 
1015
 
 
1016
    if (event->type != c->first_event + PSEVENTSTATUS) return False;
 
1017
 
 
1018
    if (ctxt != NULL) *ctxt = XDPSContextFromXID(d, se->cxid);
 
1019
    if (status != NULL) *status = se->status;
 
1020
    return True;
 
1021
}
 
1022
 
 
1023
Bool XDPSIsOutputEvent(
 
1024
    XEvent *event)
 
1025
{
 
1026
    Display *d = event->xany.display;
 
1027
    XExtCodes *c = XDPSLGetCodes(d);
 
1028
    CSDPSFakeEventTypes t;
 
1029
 
 
1030
    if (c == NULL) return False;        /* Not inited on that display;
 
1031
                                           must be False */
 
1032
 
 
1033
    if (!c->first_event)                /* Check CSDPS first */
 
1034
        {
 
1035
        if ((t = XDPSLGetCSDPSFakeEventType(d, event)) == csdps_output
 
1036
          || t == csdps_output_with_len)
 
1037
            return True;
 
1038
        else
 
1039
            return False;
 
1040
        }
 
1041
 
 
1042
    return event->type == c->first_event + PSEVENTOUTPUT;
 
1043
}
 
1044
 
 
1045
Bool XDPSIsDPSEvent(
 
1046
    XEvent *event)
 
1047
{
 
1048
    Display *d = event->xany.display;
 
1049
    XExtCodes *c = XDPSLGetCodes(d);
 
1050
 
 
1051
    if (c == NULL) return False;        /* Not inited on that display;
 
1052
                                           must be False */
 
1053
 
 
1054
    if (!c->first_event)                /* Check CSDPS first */
 
1055
        {
 
1056
        if (XDPSLGetCSDPSFakeEventType(d, event) != csdps_not)
 
1057
            return True;
 
1058
        else
 
1059
            return False;
 
1060
        }
 
1061
 
 
1062
    return event->type >= c->first_event &&
 
1063
           event->type <  c->first_event + NPSEVENTS;
 
1064
}
 
1065
 
 
1066
Bool XDPSDispatchEvent(
 
1067
    XEvent *event)
 
1068
{
 
1069
    Display *d = event->xany.display;
 
1070
    XExtCodes *c = XDPSLGetCodes(d);
 
1071
    CSDPSFakeEventTypes t;
 
1072
 
 
1073
    if (c == NULL) return False;        /* Not inited on that display;
 
1074
                                           must be False */
 
1075
 
 
1076
    if (!c->first_event)                /* Check CSDPS first */
 
1077
        {
 
1078
        if ((t = XDPSLGetCSDPSFakeEventType(d, event)) != csdps_not) 
 
1079
            return(XDPSLDispatchCSDPSFakeEvent(d, event, t));
 
1080
        else
 
1081
            return False;
 
1082
        }
 
1083
 
 
1084
    if (event->type == c->first_event + PSEVENTSTATUS) {
 
1085
        XDPSLCallStatusEventHandler(d, event);
 
1086
    } else if (event->type == c->first_event + PSEVENTOUTPUT) {
 
1087
        XDPSLCallOutputEventHandler(d, event);
 
1088
    } else if (event->type == c->first_event + PSEVENTREADY) {
 
1089
        XDPSLCallReadyEventHandler(d, event);
 
1090
    } else return False;
 
1091
    return True;
 
1092
}
 
1093
 
 
1094
/* L2-DPS/PROTO 9 addition */
 
1095
Bool XDPSIsReadyEvent(
 
1096
    XEvent *event,
 
1097
    DPSContext *ctxt,
 
1098
    int *val)
 
1099
{
 
1100
    Display *d = event->xany.display;
 
1101
    XExtCodes *c = XDPSLGetCodes(d);
 
1102
    XDPSLReadyEvent *re = (XDPSLReadyEvent *) event;
 
1103
 
 
1104
    if (c == NULL) return False;        /* Not inited on that display;
 
1105
                                           must be False */
 
1106
 
 
1107
    if (!c->first_event)                /* Check CSDPS first */
 
1108
        {
 
1109
        if (XDPSLGetCSDPSFakeEventType(d, event) == csdps_ready)
 
1110
            {
 
1111
            XDPSLGetCSDPSReady(d, event, (void **)ctxt, val);
 
1112
            return True;
 
1113
            }
 
1114
        else
 
1115
            return False;
 
1116
        }
 
1117
 
 
1118
    if (event->type != c->first_event + PSEVENTREADY) return False;
 
1119
 
 
1120
    if (ctxt != NULL) *ctxt = XDPSContextFromXID(d, re->cxid);
 
1121
    if (val != NULL) {
 
1122
        val[0] = re->val[0];
 
1123
        val[1] = re->val[1];
 
1124
        val[2] = re->val[2];
 
1125
        val[4] = re->val[3];
 
1126
    }
 
1127
    return True;
 
1128
}
 
1129
 
 
1130
int XDPSGetProtocolVersion(
 
1131
    Display *dpy)
 
1132
{
 
1133
    return XDPSLGetVersion(dpy);
 
1134
}