aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/dps/dpsXclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/lib/dps/dpsXclient.c')
-rw-r--r--nx-X11/lib/dps/dpsXclient.c1134
1 files changed, 1134 insertions, 0 deletions
diff --git a/nx-X11/lib/dps/dpsXclient.c b/nx-X11/lib/dps/dpsXclient.c
new file mode 100644
index 000000000..212030ecc
--- /dev/null
+++ b/nx-X11/lib/dps/dpsXclient.c
@@ -0,0 +1,1134 @@
+/*
+ * dpsXclient.c -- Implementation of the Display PostScript Client Library.
+ *
+ * (c) Copyright 1988-1994 Adobe Systems Incorporated.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sublicense this software
+ * and its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notices appear in all copies and that
+ * both those copyright notices and this permission notice appear in
+ * supporting documentation and that the name of Adobe Systems Incorporated
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. No trademark license
+ * to use the Adobe trademarks is hereby granted. If the Adobe trademark
+ * "Display PostScript"(tm) is used to describe this software, its
+ * functionality or for any other purpose, such use shall be limited to a
+ * statement that this software works in conjunction with the Display
+ * PostScript system. Proper trademark attribution to reflect Adobe's
+ * ownership of the trademark shall be given whenever any such reference to
+ * the Display PostScript system is made.
+ *
+ * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
+ * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
+ * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
+ * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
+ * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
+ *
+ * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
+ * Incorporated which may be registered in certain jurisdictions
+ *
+ * Author: Adobe Systems Incorporated
+ */
+/* $XFree86$ */
+
+#include <stdlib.h>
+#include <unistd.h> /* sleep() */
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef VMS
+/* Xlib does not like UNIX defined to any value under VMS. */
+#undef UNIX
+#include <decw$include/X.h>
+#include <decw$include/Xlib.h>
+
+#else /* VMS */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif /* VMS */
+
+#include "DPS/XDPSlib.h"
+#include "DPS/XDPS.h"
+
+#include "publictypes.h"
+#include "DPS/dpsclient.h"
+#include "dpsprivate.h"
+
+#include "dpsXpriv.h"
+#include "DPS/dpsXclient.h"
+
+#include "dpsdict.h"
+#include "DPS/dpsexcept.h"
+
+#include "dpsXint.h"
+
+static DPSPrivContext FindPrivContext (
+ Display * dpy,
+ long int cid)
+{
+ DPSPrivSpace ss;
+ DPSPrivContext cc;
+
+ for (ss = spaces; ss != NIL; ss = ss->next)
+ for (cc = ss->firstContext; cc != NIL; cc = cc->next)
+ if (cc->cid == cid && ((XDPSPrivContext) cc->wh)->dpy == dpy)
+ return (cc);
+ return (NIL);
+}
+
+DPSContext XDPSFindContext (
+ Display * dpy,
+ int cid)
+{
+ return ((DPSContext) FindPrivContext (dpy, cid));
+}
+
+DPSContext DPSContextFromContextID(
+ DPSContext ctxt,
+ int contextID,
+ DPSTextProc textProc,
+ DPSErrorProc errorProc)
+{
+ DPSPrivSpace ss;
+ Display *dpy = ((XDPSPrivContext) ((DPSPrivContext) ctxt)->wh)->dpy;
+ DPSPrivContext c, cc = FindPrivContext (dpy, contextID);
+ DPSPrivContext oldc = (DPSPrivContext)ctxt;
+
+ if (cc != NIL) return (DPSContext)cc;
+
+ c = (DPSPrivContext)DPScalloc(sizeof(DPSPrivContextRec), 1);
+ if (!c) return NIL;
+ *c = *oldc;
+ ss = (DPSPrivSpace)c->space;
+
+ if (textProc) c->textProc = textProc;
+ if (errorProc) c->errorProc = errorProc;
+
+ c->eofReceived = false;
+ c->cid = contextID;
+ c->buf = c->outBuf = c->objBuf = NIL;
+ c->chainParent = c->chainChild = NIL;
+
+ c->nBufChars = c->nOutBufChars = c->nObjBufChars = 0;
+
+ c->next = ss->firstContext;
+ DPSAssert(c->next != c);
+ ss->firstContext = c;
+
+ /* Note: there's no way to determine whether the new context id was obtained
+ ** as a result of a fork operation or from another application. so, it must
+ ** be assumed that the application is the creator of the new context.
+ ** Otherwise, it would have called the XDPSContextFromSharedID.
+ */
+ c->creator = true;
+ c->zombie = false;
+ c->numstringOffsets = NULL;
+
+ DPSIncludePrivContext(
+ (XDPSPrivContext) c->wh, (DPSContext)c, c->cid, ss->sid, DPSclientPrintProc);
+
+ return (DPSContext)c;
+}
+
+boolean DPSPrivateCheckWait(
+ DPSContext ctxt)
+{
+ DPSPrivContext cc = (DPSPrivContext) ctxt;
+
+ if (!cc->creator || cc->zombie) {
+ DPSSafeSetLastNameIndex(ctxt);
+ if (cc->errorProc != NIL) {
+ (*cc->errorProc) (ctxt, cc->zombie ? dps_err_deadContext :
+ dps_err_invalidAccess,
+ (unsigned long) ctxt, 0);
+ }
+ return true;
+ }
+ return false;
+}
+
+static void procFlushContext(
+ DPSContext ctxt)
+{
+ DPSPrivContext c = (DPSPrivContext) ctxt;
+ XDPSLFlush (((XDPSPrivContext) c->wh)->dpy);
+ if (ctxt->chainChild != NIL) DPSFlushContext(ctxt->chainChild);
+}
+
+/* ARGSUSED */
+static Bool FindDPSEvent(
+ Display *dpy,
+ XEvent *event,
+ char *arg)
+{
+ return XDPSIsDPSEvent(event);
+}
+
+static void procAwaitReturnValues(DPSContext ctxt)
+{
+ DPSPrivContext c = (DPSPrivContext)ctxt;
+
+ XDPSPrivContext xwh = (XDPSPrivContext) c->wh;
+ XEvent ev;
+
+ /* Output currently goes only to creator! */
+ if (!c->creator)
+ {
+ DPSSafeSetLastNameIndex(ctxt);
+ c->resultTable = NIL;
+ c->resultTableLength = 0;
+ if (c->errorProc != NIL)
+ (*c->errorProc) (ctxt, dps_err_invalidAccess, 0, 0);
+ return;
+ }
+ if (c->resultTable != NIL)
+ {
+ DPSCheckInitClientGlobals();
+
+ if (XDPSLGetWrapWaitingFlag(xwh->dpy)) {
+ DPSSafeSetLastNameIndex(ctxt);
+ c->resultTable = NIL;
+ c->resultTableLength = 0;
+ if (c->errorProc != NIL)
+ (*c->errorProc) (ctxt, dps_err_recursiveWait,
+ (unsigned long) xwh->dpy, 0);
+ return;
+ }
+ XDPSLSetWrapWaitingFlag(xwh->dpy, True);
+
+ DURING
+ DPSFlushContext(ctxt);
+ while (c->resultTable != NIL)
+ {
+ /* We may block indefinitely if the context is frozen or it
+ somehow needs more input. */
+ if (c->zombie)
+ {
+ DPSSafeSetLastNameIndex(ctxt);
+ c->resultTable = NIL;
+ c->resultTableLength = 0;
+ if (c->errorProc != NIL)
+ (*c->errorProc) (ctxt, dps_err_deadContext, (unsigned long) c, 0);
+ XDPSLSetWrapWaitingFlag(xwh->dpy, False);
+ E_RTRN_VOID;
+ }
+
+ /* Someone could conceivably change the event delivery mode in the
+ middle of this...best to check every time */
+
+ if (XDPSLGetPassEventsFlag(xwh->dpy)) {
+ XIfEvent(xwh->dpy, &ev, FindDPSEvent, (char *) NULL);
+ if (!XDPSDispatchEvent(&ev)) DPSCantHappen();
+ } else DPSSendPostScript((XDPSPrivContext) c->wh, DPSclientPrintProc,
+ c->cid, NIL, 0, NIL);
+ }
+ HANDLER
+ XDPSLSetWrapWaitingFlag(xwh->dpy, False);
+ RERAISE;
+ END_HANDLER
+
+ XDPSLSetWrapWaitingFlag(xwh->dpy, False);
+
+ }
+
+ /* update space's name map.
+ space->lastNameIndex is the highest index known to be known to the
+ server for this space.
+ c->lastNameIndex is the highest index sent so far to the context
+ */
+
+ if (((DPSPrivSpace)(c->space))->lastNameIndex < c->lastNameIndex)
+ ((DPSPrivSpace)(c->space))->lastNameIndex = c->lastNameIndex;
+}
+
+void DPSinnerProcWriteData(
+ DPSContext ctxt,
+ char *buf,
+ unsigned int count)
+{
+ DPSPrivContext c = (DPSPrivContext) ctxt;
+
+ /* ASSERT: safe to call with chain */
+
+ /* No local buffering */
+ DPSSendPostScript ((XDPSPrivContext) c->wh, DPSclientPrintProc,
+ c->cid, buf, count, NIL);
+} /* DPSinnerProcWriteData */
+
+static void procResetContext(DPSContext ctxt)
+{
+ DPSPrivContext c = (DPSPrivContext) ctxt;
+ int currStatus;
+ register XDPSPrivContext xwh = (XDPSPrivContext) c->wh;
+ int retries = 0;
+ int backoff = 2;
+
+ /* First make sure context isn't frozen, try to unfreeze. */
+
+#define DPS_SLEEP_SECS 2
+
+ while((currStatus = XDPSLGetStatus(xwh->dpy, xwh->cxid)) == PSFROZEN)
+ {
+ XDPSLNotifyContext(xwh->dpy, xwh->cxid, PSUNFREEZE);
+ sleep(DPS_SLEEP_SECS);
+ /* Okay if context is PSRUNNING, since the EOF will
+ be handled at the next PSNEEDSINPUT */
+ }
+
+ /* Remove events from Xlib Qs before sending the reset request. */
+ XDPSForceEvents (xwh->dpy);
+
+ if (currStatus == PSSTATUSERROR)
+ /* +++ report error? */;
+ else /* Didn't become zombie. */
+ {
+ currStatus = 0;
+ XDPSLReset(xwh->dpy, xwh->cxid);
+ XDPSLFlush(xwh->dpy);
+ /* Be optmistic for the first try. Assume the app set up a status mask
+ correctly, we should get a status event without asking the
+ server for status. */
+
+ XDPSForceEvents(xwh->dpy);
+ currStatus = c->statusFromEvent;
+
+ while (currStatus != PSNEEDSINPUT && currStatus != PSZOMBIE)
+ {
+ if (currStatus == PSFROZEN)
+ XDPSLNotifyContext(xwh->dpy, xwh->cxid, PSUNFREEZE);
+ if (retries > backoff)
+ {
+ /* Optimism failed. App probably didn't set up a status mask.
+ Ask the server for status. */
+ currStatus = XDPSLGetStatus(xwh->dpy, xwh->cxid);
+ retries = 0;
+ backoff = (backoff > 30) ? 2 : backoff + 1;
+ continue;
+ }
+ else
+ ++retries;
+ sleep(DPS_SLEEP_SECS);
+ XDPSForceEvents(xwh->dpy);
+ currStatus = c->statusFromEvent;
+ }
+ }
+
+ c->eofReceived = false;
+}
+
+void DPSPrivateDestroyContext(DPSContext ctxt)
+{
+ DPSPrivContext c = (DPSPrivContext)ctxt;
+ DPSPrivSpace s = (DPSPrivSpace) c->space;
+
+ if (c->creator)
+ DPSSendTerminate((XDPSPrivContext) c->wh, c->cid, DPSclientPrintProc);
+ else
+ XDPSSetStatusMask(ctxt, 0, XDPSL_ALL_EVENTS, 0); /* Stop status events */
+ /* Don't free the space's wh out from under it */
+ if (c->wh != s->wh) free(c->wh);
+}
+
+void DPSPrivateDestroySpace(DPSSpace space)
+{
+ DPSPrivSpace ss = (DPSPrivSpace) space;
+
+ if (ss->creator) DPSSendDestroySpace((XDPSPrivContext) ss->wh, ss->sid,
+ DPSclientPrintProc);
+
+ free (ss->wh);
+}
+
+boolean DPSCheckShared(DPSPrivContext ctxt)
+{
+ return ctxt->creator == false && ctxt->resultTable != NIL;
+ /* let procAwaitReturnValues generate error */
+}
+
+/* ARGSUSED */
+void DPSServicePostScript(boolean (*returnControl)(void))
+{
+} /* DPSServicePostScript */
+
+void DPSHandleBogusError(DPSContext ctxt, char *prefix, char *suffix)
+{
+ char *buf = "bogus error output from context";
+ DPSDefaultPrivateHandler(ctxt, dps_err_warning,
+ (long unsigned int)buf, 0, prefix, suffix);
+}
+
+void DPSDefaultPrivateHandler(
+ DPSContext ctxt,
+ DPSErrorCode errorCode,
+ long unsigned int arg1,
+ long unsigned int arg2,
+ char *prefix,
+ char *suffix)
+{
+
+ DPSTextProc textProc = DPSGetCurrentTextBackstop();
+
+ switch (errorCode) {
+ case dps_err_invalidAccess:
+ if (textProc != NIL)
+ {
+ char m[100];
+ (void) sprintf (m, "%sInvalid context access.%s", prefix, suffix);
+ (*textProc) (ctxt, m, strlen (m));
+ }
+ break;
+ case dps_err_encodingCheck:
+ if (textProc != NIL)
+ {
+ char m[100];
+ (void) sprintf (m, "%sInvalid name/program encoding: %d/%d.%s",
+ prefix, (int) arg1, (int) arg2, suffix);
+ (*textProc) (ctxt, m, strlen (m));
+ }
+ break;
+ case dps_err_closedDisplay:
+ if (textProc != NIL)
+ {
+ char m[100];
+ (void) sprintf (m, "%sBroken display connection %d.%s",
+ prefix, (int) arg1, suffix);
+ (*textProc) (ctxt, m, strlen (m));
+ }
+ break;
+ case dps_err_deadContext:
+ if (textProc != NIL)
+ {
+ char m[100];
+ (void) sprintf (m, "%sDead context 0x0%x.%s", prefix,
+ (int) arg1, suffix);
+ (*textProc) (ctxt, m, strlen (m));
+ }
+ break;
+ case dps_err_warning:
+ if (textProc != NIL)
+ {
+ char *warn = (char *)arg1;
+ char *msg = "%% DPS Client Library Warning:\n ";
+ (*textProc)(ctxt, msg, strlen(msg));
+ (*textProc)(ctxt, warn, strlen(warn));
+ msg = "\n";
+ (*textProc)(ctxt, msg, strlen(msg));
+ /* flush convention */
+ (*textProc)(ctxt, msg, 0);
+ }
+ break;
+ case dps_err_fatal:
+ if (textProc != NIL)
+ {
+ char *fatal = (char *)arg1;
+ char *msg = "%% DPS Client Library Fatal Internal Error:\n ";
+ (*textProc)(ctxt, msg, strlen(msg));
+ (*textProc)(ctxt, fatal, strlen(fatal));
+ msg = ".\nAborting ...\n";
+ (*textProc)(ctxt, msg, strlen(msg));
+ /* flush convention */
+ (*textProc)(ctxt, msg, 0);
+ abort();
+ }
+ break;
+ case dps_err_recursiveWait:
+ if (textProc != NIL)
+ {
+ char m[100];
+ (void) sprintf (m,
+ "%sRecursive wait for return values, display 0x%x.%s",
+ prefix, (int) arg1, suffix);
+ (*textProc) (ctxt, m, strlen (m));
+ }
+ break;
+ }
+}
+
+void DPSInitPrivateSpaceFields(DPSPrivSpace s)
+{
+ s->creator = true;
+}
+
+void DPSInitPrivateContextFields(DPSPrivContext c, DPSPrivSpace s)
+{
+ c->creator = true;
+ c->zombie = false;
+ if (!s->creator) {
+ c->procs = XDPSconvProcs;
+ c->nameEncoding = dps_strings;
+ }
+}
+
+void DPSInitPrivateTextContextFields(DPSPrivContext c, DPSPrivSpace s)
+{
+ c->creator = true;
+ c->zombie = false;
+ c->space = (DPSSpace) s;
+ c->next = s->firstContext;
+ s->firstContext = c;
+}
+
+long int DPSLastUserObjectIndex = 0;
+
+long int DPSNewUserObjectIndex (void)
+{
+ return (DPSLastUserObjectIndex++);
+}
+
+void XDPSSetProcs (void)
+{
+ DPSCheckInitClientGlobals ();
+ if (!textCtxProcs)
+ {
+ textCtxProcs = (DPSProcs) DPScalloc (sizeof (DPSProcsRec), 1);
+ DPSInitCommonTextContextProcs(textCtxProcs);
+ DPSInitSysNames();
+ }
+ if (!ctxProcs)
+ {
+ ctxProcs = (DPSProcs) DPScalloc (sizeof (DPSProcsRec), 1);
+ DPSInitCommonContextProcs(ctxProcs);
+ DPSInitPrivateContextProcs(ctxProcs);
+ }
+ if (!XDPSconvProcs)
+ XDPSconvProcs = (DPSProcs) DPScalloc (sizeof (DPSProcsRec), 1);
+ if (!XDPSrawProcs)
+ XDPSrawProcs = ctxProcs;
+ *XDPSconvProcs = *ctxProcs;
+ XDPSconvProcs->BinObjSeqWrite = textCtxProcs->BinObjSeqWrite;
+ XDPSconvProcs->WriteStringChars = textCtxProcs->WriteStringChars;
+ XDPSconvProcs->WritePostScript = textCtxProcs->WritePostScript;
+ XDPSconvProcs->WriteNumString = textCtxProcs->WriteNumString;
+}
+
+void DPSInitPrivateContextProcs(DPSProcs p)
+{
+ p->FlushContext = procFlushContext;
+ p->ResetContext = procResetContext;
+ p->AwaitReturnValues = procAwaitReturnValues;
+}
+
+DPSContext XDPSCreateSimpleContext (
+ Display *dpy,
+ Drawable draw,
+ GC gc,
+ int x,
+ int y,
+ DPSTextProc textProc,
+ DPSErrorProc errorProc,
+ DPSSpace space)
+{
+ XDPSPrivContext xwh = XDPSCreatePrivContextRec (dpy, draw, gc, x, y,
+ 0, DefaultStdCMap,
+ DefaultStdCMap, 0, false);
+ DPSContext newCtxt;
+
+ if (xwh == NIL)
+ return (NIL);
+ else
+ {
+ newCtxt = DPSCreateContext ((char *) xwh, textProc, errorProc, space);
+ if (newCtxt == NIL)
+ free ((char *) xwh);
+ return (newCtxt);
+ }
+}
+
+
+DPSContext XDPSCreateContext (
+ Display *dpy,
+ Drawable draw,
+ GC gc,
+ int x,
+ int y,
+ unsigned int eventmask,
+ XStandardColormap *grayramp,
+ XStandardColormap *ccube,
+ int actual,
+ DPSTextProc textProc,
+ DPSErrorProc errorProc,
+ DPSSpace space)
+{
+ XDPSPrivContext xwh = XDPSCreatePrivContextRec (dpy, draw, gc, x, y,
+ eventmask, grayramp,
+ ccube, actual, false);
+ DPSContext newCtxt;
+
+ if (xwh == NIL)
+ return (NIL);
+ else
+ {
+ newCtxt = DPSCreateContext ((char *) xwh, textProc, errorProc, space);
+ if (newCtxt == NIL)
+ free ((char *) xwh);
+ return (newCtxt);
+ }
+}
+
+DPSContext XDPSCreateSecureContext (
+ Display *dpy,
+ Drawable draw,
+ GC gc,
+ int x,
+ int y,
+ unsigned int eventmask,
+ XStandardColormap *grayramp,
+ XStandardColormap *ccube,
+ int actual,
+ DPSTextProc textProc,
+ DPSErrorProc errorProc,
+ DPSSpace space)
+{
+ XDPSPrivContext xwh = XDPSCreatePrivContextRec (dpy, draw, gc, x, y,
+ eventmask, grayramp,
+ ccube, actual, true);
+ DPSContext newCtxt;
+
+ if (xwh == NIL)
+ return (NIL);
+ else
+ {
+ newCtxt = DPSCreateContext ((char *) xwh, textProc, errorProc, space);
+ if (newCtxt == NIL)
+ free ((char *) xwh);
+ return (newCtxt);
+ }
+}
+
+
+DPSContext XDPSContextFromSharedID (dpy, cid, textProc, errorProc)
+ Display *dpy;
+ ContextPSID cid;
+ DPSTextProc textProc;
+ DPSErrorProc errorProc;
+{
+ DPSPrivContext c;
+ DPSPrivSpace s;
+ ContextXID cxid;
+ SpaceXID sxid;
+ XDPSPrivContext xwh;
+
+ if (DPSInitialize () != 0)
+ return (NIL);
+
+ c = FindPrivContext (dpy, cid);
+ if (c != NIL)
+ return ((DPSContext) c);
+
+ xwh = XDPSCreatePrivContextRec (dpy, 0, 0, 0, 0, 0, NIL, NIL, 0, false);
+ if (xwh == NIL)
+ return (NIL);
+ else if (XDPSLIDFromContext (dpy, cid, &cxid, &sxid) != 1)
+ {
+ free ((char *) xwh);
+ return (NIL);
+ }
+ xwh->cxid = cxid;
+
+ if (spaceProcs == NIL)
+ {
+ spaceProcs = (DPSSpaceProcs) DPScalloc (sizeof (DPSSpaceProcsRec), 1);
+ DPSInitCommonSpaceProcs(spaceProcs);
+ }
+
+ s = spaces;
+ while (s != NIL)
+ if ((SpaceXID)s->sid == sxid && ((XDPSPrivContext) s->wh)->dpy == dpy)
+ break;
+ else
+ s = s->next;
+
+ if (s == NIL) /* Create new space record. */
+ {
+ s = (DPSPrivSpace) DPScalloc (sizeof (DPSPrivSpaceRec), 1);
+ s->procs = spaceProcs;
+ s->lastNameIndex = -1;
+ s->sid = sxid;
+ s->wh = (char *) xwh;
+ s->creator = false;
+ s->next = spaces;
+ spaces = s;
+ }
+
+ c = (DPSPrivContext) DPScalloc (sizeof (DPSPrivContextRec), 1);
+ c->space = (DPSSpace) s;
+ c->procs = XDPSconvProcs;
+ c->textProc = textProc;
+ c->errorProc = errorProc;
+ c->programEncoding = DPSDefaultProgramEncoding;
+ c->nameEncoding = dps_strings;
+ c->next = s->firstContext;
+ s->firstContext = c;
+ c->lastNameIndex = s->lastNameIndex;
+ c->cid = cid;
+ c->numstringOffsets = NULL;
+ c->creator = false;
+ c->zombie = false;
+ c->numFormat = XDPSNumFormat (dpy);
+ c->wh = (char *) xwh;
+
+ xwh->ctxt = (DPSContext) c;
+
+ return ((DPSContext) c);
+}
+
+
+void DPSChangeEncoding (ctxt, newProgEncoding, newNameEncoding)
+ DPSContext ctxt;
+ DPSProgramEncoding newProgEncoding;
+ DPSNameEncoding newNameEncoding;
+{
+ if (ctxt->programEncoding != newProgEncoding ||
+ ctxt->nameEncoding != newNameEncoding)
+ {
+ DPSPrivContext cc = (DPSPrivContext) ctxt;
+ DPSPrivSpace ss = (DPSPrivSpace) (cc->space);
+
+ if ((!cc->creator || !ss->creator) && newNameEncoding != dps_strings)
+ {
+ DPSSafeSetLastNameIndex(ctxt);
+ if (cc->errorProc != NIL)
+ (*cc->errorProc) (ctxt, dps_err_encodingCheck,
+ (unsigned long) newNameEncoding,
+ (unsigned long) newProgEncoding);
+ return;
+ }
+ if (ctxt->procs == textCtxProcs)
+ {
+ ctxt->programEncoding = newProgEncoding;
+ ctxt->nameEncoding = newNameEncoding;
+ }
+ else
+ XDPSSetContextEncoding (ctxt, newProgEncoding, newNameEncoding);
+ }
+}
+
+
+DPSSpace XDPSSpaceFromSharedID (dpy, sid)
+ Display *dpy;
+ SpaceXID sid;
+{
+ DPSPrivSpace s;
+ XDPSPrivContext xwh;
+
+ if (DPSInitialize () != 0)
+ return (NIL);
+
+ if (spaceProcs == NIL)
+ {
+ spaceProcs = (DPSSpaceProcs) DPScalloc (sizeof (DPSSpaceProcsRec), 1);
+ DPSInitCommonSpaceProcs(spaceProcs);
+ }
+
+ s = spaces;
+ while (s != NIL)
+ if ((SpaceXID)s->sid == sid && ((XDPSPrivContext) s->wh)->dpy == dpy)
+ break;
+ else
+ s = s->next;
+
+ if (s == NIL) /* Create new space record. */
+ {
+ xwh = XDPSCreatePrivContextRec (dpy, 0, 0, 0, 0, 0, NIL, NIL, 0, false);
+ if (xwh == NIL)
+ return (NIL);
+
+ s = (DPSPrivSpace) DPScalloc (sizeof (DPSPrivSpaceRec), 1);
+ s->procs = spaceProcs;
+ s->lastNameIndex = -1;
+ s->sid = sid;
+ s->wh = (char *) xwh;
+ s->creator = false;
+ s->next = spaces;
+ spaces = s;
+ }
+
+ return ((DPSSpace) s);
+}
+
+
+void XDPSUnfreezeContext (ctxt)
+ DPSContext ctxt;
+{
+ XDPSPrivContext wh = (XDPSPrivContext) (((DPSPrivContext) ctxt)->wh);
+
+ if (wh != NIL && wh->cxid != 0)
+ XDPSSendUnfreeze (wh->dpy, wh->cxid);
+}
+
+
+ContextXID XDPSXIDFromContext (Pdpy, ctxt)
+ Display **Pdpy;
+ DPSContext ctxt;
+{
+ XDPSPrivContext xwh = (XDPSPrivContext) (((DPSPrivContext) ctxt)->wh);
+
+ if (xwh == NIL || xwh->cxid == 0)
+ {
+ *Pdpy = NULL;
+ return (0);
+ }
+ else
+ {
+ *Pdpy = xwh->dpy;
+ return (xwh->cxid);
+ }
+}
+
+
+SpaceXID XDPSXIDFromSpace (Pdpy, space)
+ Display **Pdpy;
+ DPSSpace space;
+{
+ DPSPrivSpace ss = (DPSPrivSpace) space;
+ XDPSPrivContext xwh = (XDPSPrivContext) ss->wh;
+
+ if (xwh != NIL && xwh->dpy != NULL)
+ {
+ *Pdpy = xwh->dpy;
+ return (ss->sid);
+ }
+ else
+ {
+ *Pdpy = NULL;
+ return (0);
+ }
+}
+
+
+DPSContext XDPSContextFromXID (dpy, cxid)
+ Display *dpy;
+ ContextXID cxid;
+{
+ DPSPrivContext c;
+ DPSPrivSpace ss;
+
+ for (ss = spaces; ss != NIL; ss = ss->next)
+ if (((XDPSPrivContext) ss->wh)->dpy == dpy)
+ for (c = ss->firstContext; c != NIL; c = c->next)
+ if (((XDPSPrivContext) c->wh)->cxid == cxid)
+ return ((DPSContext) c);
+
+ return (NIL);
+}
+
+
+DPSSpace XDPSSpaceFromXID (dpy, sxid)
+ Display *dpy;
+ SpaceXID sxid;
+{
+ DPSPrivSpace ss;
+
+ for (ss = spaces; ss != NIL; ss = ss->next)
+ if ((SpaceXID)ss->sid == sxid && ((XDPSPrivContext) ss->wh)->dpy == dpy)
+ return ((DPSSpace) ss);
+
+ return (NIL);
+}
+
+
+XDPSStatusProc XDPSRegisterStatusProc (ctxt, statusProc)
+ DPSContext ctxt;
+ XDPSStatusProc statusProc;
+{
+ DPSPrivContext c = (DPSPrivContext) ctxt;
+ XDPSStatusProc old = c->statusProc;
+
+ if (c->wh != NIL) c->statusProc = statusProc;
+ return old;
+}
+
+
+XDPSReadyProc XDPSRegisterReadyProc (ctxt, readyProc)
+ DPSContext ctxt;
+ XDPSReadyProc readyProc;
+{
+ DPSPrivContext c = (DPSPrivContext) ctxt;
+ XDPSReadyProc old = c->readyProc;
+
+ if (c->wh != NIL) c->readyProc = readyProc;
+ return old;
+}
+
+
+void XDPSSetStatusMask(ctxt, enableMask, disableMask, nextMask)
+ DPSContext ctxt;
+ unsigned long enableMask, disableMask, nextMask;
+{
+ XDPSPrivContext xwh = (XDPSPrivContext) (((DPSPrivContext) ctxt)->wh);
+
+ if (xwh != NIL && xwh->cxid != 0)
+ XDPSLSetStatusMask(xwh->dpy, xwh->cxid, enableMask, disableMask, nextMask);
+}
+
+
+int XDPSGetContextStatus(ctxt)
+ DPSContext ctxt;
+{
+ DPSPrivContext c = (DPSPrivContext) ctxt;
+ XDPSPrivContext xwh = (XDPSPrivContext) c->wh;
+
+ if (xwh != NIL && xwh->cxid != 0)
+ return (XDPSLGetStatus(xwh->dpy, xwh->cxid));
+ else
+ return (0);
+}
+
+void XDPSNotifyWhenReady(ctxt, i0, i1, i2, i3)
+ DPSContext ctxt;
+ int i0, i1, i2, i3;
+{
+ DPSPrivContext c = (DPSPrivContext) ctxt;
+ XDPSPrivContext xwh = (XDPSPrivContext) c->wh;
+ int i[4];
+
+ i[0] = i0;
+ i[1] = i1;
+ i[2] = i2;
+ i[3] = i3;
+
+ XDPSLNotifyWhenReady(xwh->dpy, xwh->cxid, i);
+}
+
+void XDPSStatusEventHandler (e)
+ XDPSLStatusEvent *e;
+{
+ DPSPrivContext c = (DPSPrivContext) XDPSContextFromXID(e->display, e->cxid);
+
+ if (c == NIL)
+ return;
+
+ c->statusFromEvent = e->status;
+ if (e->status == PSZOMBIE)
+ {
+ c->zombie = true;
+ if (c->resultTable != NIL) /* Currently waiting for results */
+ XDPSQuitBlocking = true;
+ }
+
+ if (c->statusProc != NIL)
+ (*(c->statusProc)) ((DPSContext) c, e->status);
+}
+
+void XDPSReadyEventHandler (e)
+ XDPSLReadyEvent *e;
+{
+ DPSPrivContext c = (DPSPrivContext) XDPSContextFromXID(e->display, e->cxid);
+
+ if (c == NIL)
+ return;
+
+ if (c->readyProc != NIL)
+ (*(c->readyProc)) ((DPSContext) c, e->val);
+}
+
+
+
+void DPSWarnProc(
+ DPSContext ctxt,
+ char *msg)
+{
+ DPSErrorProc ep;
+
+ if (DPSInitialize() != 0) return;
+ ep = DPSGetCurrentErrorBackstop();
+ if (ep == NULL) ep = DPSDefaultErrorProc;
+ (*ep)(ctxt, dps_err_warning, (long unsigned int)msg, 0);
+}
+
+void DPSFatalProc(
+ DPSContext ctxt,
+ char *msg)
+{
+ DPSErrorProc ep;
+
+ if (DPSInitialize() != 0) return;
+ ep = DPSGetCurrentErrorBackstop();
+ if (ep == NULL) ep = DPSDefaultErrorProc;
+ (*ep)(ctxt, dps_err_fatal, (long unsigned int)msg, 0);
+}
+
+void DPSCantHappen(void)
+{
+ static int locked = 0;
+ char *msg = "assertion failure or DPSCantHappen";
+ if (locked > 0) abort();
+ ++locked;
+ DPSFatalProc((DPSContext)NULL, msg);
+ /* Fatal proc shouldn't return, but client can override and do anything. */
+ --locked;
+}
+
+
+/* Procedures for delayed event dispatching */
+
+DPSEventDelivery XDPSSetEventDelivery(
+ Display *dpy,
+ DPSEventDelivery newMode)
+{
+ Bool old = XDPSLGetPassEventsFlag(dpy);
+
+ switch (newMode) {
+ case dps_event_pass_through:
+ XDPSLSetPassEventsFlag(dpy, True);
+ break;
+ case dps_event_internal_dispatch:
+ XDPSLSetPassEventsFlag(dpy, False);
+ break;
+ default:
+ break;
+ }
+
+ if (old) return dps_event_pass_through;
+ else return dps_event_internal_dispatch;
+}
+
+Bool XDPSIsStatusEvent(
+ XEvent *event,
+ DPSContext *ctxt,
+ int *status)
+{
+ Display *d = event->xany.display;
+ XExtCodes *c = XDPSLGetCodes(d);
+ XDPSLStatusEvent *se = (XDPSLStatusEvent *) event;
+
+ if (c == NULL) return False; /* Not inited on that display;
+ must be False */
+
+ if (!c->first_event) /* Check CSDPS first */
+ {
+ if (XDPSLGetCSDPSFakeEventType(d, event) == csdps_status)
+ { /* Check CSDPS first */
+ XDPSLGetCSDPSStatus(d, event, (void **)ctxt, status);
+ return True;
+ }
+ else
+ return False;
+ }
+
+ if (event->type != c->first_event + PSEVENTSTATUS) return False;
+
+ if (ctxt != NULL) *ctxt = XDPSContextFromXID(d, se->cxid);
+ if (status != NULL) *status = se->status;
+ return True;
+}
+
+Bool XDPSIsOutputEvent(
+ XEvent *event)
+{
+ Display *d = event->xany.display;
+ XExtCodes *c = XDPSLGetCodes(d);
+ CSDPSFakeEventTypes t;
+
+ if (c == NULL) return False; /* Not inited on that display;
+ must be False */
+
+ if (!c->first_event) /* Check CSDPS first */
+ {
+ if ((t = XDPSLGetCSDPSFakeEventType(d, event)) == csdps_output
+ || t == csdps_output_with_len)
+ return True;
+ else
+ return False;
+ }
+
+ return event->type == c->first_event + PSEVENTOUTPUT;
+}
+
+Bool XDPSIsDPSEvent(
+ XEvent *event)
+{
+ Display *d = event->xany.display;
+ XExtCodes *c = XDPSLGetCodes(d);
+
+ if (c == NULL) return False; /* Not inited on that display;
+ must be False */
+
+ if (!c->first_event) /* Check CSDPS first */
+ {
+ if (XDPSLGetCSDPSFakeEventType(d, event) != csdps_not)
+ return True;
+ else
+ return False;
+ }
+
+ return event->type >= c->first_event &&
+ event->type < c->first_event + NPSEVENTS;
+}
+
+Bool XDPSDispatchEvent(
+ XEvent *event)
+{
+ Display *d = event->xany.display;
+ XExtCodes *c = XDPSLGetCodes(d);
+ CSDPSFakeEventTypes t;
+
+ if (c == NULL) return False; /* Not inited on that display;
+ must be False */
+
+ if (!c->first_event) /* Check CSDPS first */
+ {
+ if ((t = XDPSLGetCSDPSFakeEventType(d, event)) != csdps_not)
+ return(XDPSLDispatchCSDPSFakeEvent(d, event, t));
+ else
+ return False;
+ }
+
+ if (event->type == c->first_event + PSEVENTSTATUS) {
+ XDPSLCallStatusEventHandler(d, event);
+ } else if (event->type == c->first_event + PSEVENTOUTPUT) {
+ XDPSLCallOutputEventHandler(d, event);
+ } else if (event->type == c->first_event + PSEVENTREADY) {
+ XDPSLCallReadyEventHandler(d, event);
+ } else return False;
+ return True;
+}
+
+/* L2-DPS/PROTO 9 addition */
+Bool XDPSIsReadyEvent(
+ XEvent *event,
+ DPSContext *ctxt,
+ int *val)
+{
+ Display *d = event->xany.display;
+ XExtCodes *c = XDPSLGetCodes(d);
+ XDPSLReadyEvent *re = (XDPSLReadyEvent *) event;
+
+ if (c == NULL) return False; /* Not inited on that display;
+ must be False */
+
+ if (!c->first_event) /* Check CSDPS first */
+ {
+ if (XDPSLGetCSDPSFakeEventType(d, event) == csdps_ready)
+ {
+ XDPSLGetCSDPSReady(d, event, (void **)ctxt, val);
+ return True;
+ }
+ else
+ return False;
+ }
+
+ if (event->type != c->first_event + PSEVENTREADY) return False;
+
+ if (ctxt != NULL) *ctxt = XDPSContextFromXID(d, re->cxid);
+ if (val != NULL) {
+ val[0] = re->val[0];
+ val[1] = re->val[1];
+ val[2] = re->val[2];
+ val[4] = re->val[3];
+ }
+ return True;
+}
+
+int XDPSGetProtocolVersion(
+ Display *dpy)
+{
+ return XDPSLGetVersion(dpy);
+}