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