diff options
Diffstat (limited to 'xc/lib/dps/XDPS.c')
-rw-r--r-- | xc/lib/dps/XDPS.c | 2330 |
1 files changed, 0 insertions, 2330 deletions
diff --git a/xc/lib/dps/XDPS.c b/xc/lib/dps/XDPS.c deleted file mode 100644 index b945a4c8c..000000000 --- a/xc/lib/dps/XDPS.c +++ /dev/null @@ -1,2330 +0,0 @@ -/* - * XDPS.c -- implementation of low-level Xlib routines for XDPS extension - * - * (c) Copyright 1989-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 - */ - -#define NEED_EVENTS -#define NEED_REPLIES - -#include <stdio.h> -/* Include this first so that Xasync.h, included from Xlibint.h, can find - the definition of NOFILE */ -#include <sys/param.h> -#include <X11/Xlibint.h> -#include "cslibint.h" -#include "DPS/XDPS.h" -#include "DPS/XDPSproto.h" -#include "DPS/XDPSlib.h" -#include "DPS/dpsNXargs.h" -#include <X11/Xatom.h> -#include <X11/Xutil.h> -#include "dpsassert.h" -#include "DPSCAPClient.h" - -/* === DEFINITIONS === */ - -#ifndef _NFILE -#define DPSMAXDISPLAYS 128 -#else -#define DPSMAXDISPLAYS _NFILE -#endif /* _NFILE */ - -#define MajorOpCode(dpy) (Codes[DPY_NUMBER(dpy)] ? \ - Codes[DPY_NUMBER(dpy)]->major_opcode : \ - Punt()) - -#define DPSCAP_INITCTXTS 4 /* per display */ - -/* === TYPES === */ - -typedef Status (*PSCMProc)(); - -typedef struct { - char passEvents; - char wrapWaiting; - char syncMask; /* CSDPS only */ - char debugMask; /* CSDPS only */ -} DPSDisplayFlags; - -/* For now DPSDisplayFlags is no larger than a pointer. Revisit this if the - structure grows. */ - -typedef int (*GenericProcPtrReturnsInt)(); - -typedef struct _t_DPSCAPPausedContextData { - struct _t_DPSCAPPausedContextData *next; - Bool paused; - ContextXID cxid; - unsigned int seqnum; -} DPSCAPPausedContextData; - -typedef struct { - char showSmallSizes; - char pixMem; -} DPSCAPAgentArgs; - -typedef struct { - int (*Flush)(); - int (*Read)(); - int (*ReadPad)(); - Status (*Reply)(); - int (*Send)(); -} XDPSLIOProcs; - -/* === GLOBALS === */ - -/* For debugging, allows client to force the library to use an agent */ -int gForceCSDPS = 0; - -/* Force all DPS NX protocol requests to flush if CSDPS */ -int gAutoFlush = 1; - -/* Force all NX XDPSLGiveInputs to flush independent of gAutoFlush */ -int gForceFlush = 1; - -/* Quick check for any paused contexts */ -int gTotalPaused = 0; - -/* === LOCALS === */ - -/* Common stuff */ -static XExtCodes *Codes[DPSMAXDISPLAYS]; -static int version[DPSMAXDISPLAYS]; -static XDPSLEventHandler StatusProc[DPSMAXDISPLAYS]; -static DPSDisplayFlags displayFlags[DPSMAXDISPLAYS]; -static XDPSLEventHandler TextProc = NULL; -static XDPSLEventHandler ReadyProc[DPSMAXDISPLAYS]; /* L2-DPS/PROTO 9 */ -static int NumberType[DPSMAXDISPLAYS]; /* Garbage okay after dpy closed */ -static char *FloatingName[DPSMAXDISPLAYS]; /* Garbage okay after dpy closed */ - -/* CSDPS stuff */ -static Display *ShuntMap[DPSMAXDISPLAYS]; -static PSCMProc ClientMsgProc[DPSMAXDISPLAYS]; -static GenericProcPtrReturnsInt AfterProcs[DPSMAXDISPLAYS]; -static DPSCAPPausedContextData *PausedPerDisplay[DPSMAXDISPLAYS]; -static DPSCAPAgentArgs AgentArgs[DPSMAXDISPLAYS]; -static unsigned int LastXRequest[DPSMAXDISPLAYS]; -static int GCFlushMode[DPSMAXDISPLAYS]; - -#ifdef VMS -static Display *dpys[DPSMAXDISPLAYS]; -static nextDpy = 0; -#endif /* VMS */ - -static void DPSCAPInitGC(); -static Bool DPSCAPResumeWithIX(); -static Status DPSCAPClientMessageProc(); -static int DPSCAPAfterProc(); -static unsigned int DPSCAPSetPause(); -static Bool DPSCAPResumeContext(); -static Bool WaitForSyncProc(); - -static XDPSLIOProcs xlProcs = { /* Use these for DPS/X extension */ - _XFlush, - _XRead, - _XReadPad, - _XReply, - _XSend - }; - -static XDPSLIOProcs nxlProcs = { /* Use these for NX */ - N_XFlush, - N_XRead, - N_XReadPad, - N_XReply, - N_XSend - }; - -/* === MACROS === */ - -#define IFNXSETCALL(a, x) call = ((a) != (x)) ? &nxlProcs : &xlProcs - -/* === PRIVATE PROCS === */ - -static int Punt() -{ - DPSFatalProc(NULL, "Extension has not been initialized"); - exit(1); -} - -#ifdef VMS -/* This is a terribly inefficient way to find a per-display index, but we - need it till we get dpy->fd fixed in VMS%%%%%*/ -static int FindDpyNum(dpy) -{ -int i; -for (i=0; dpys[i] != dpy ; i++) - { - if (i == nextDpy) - { - dpys[nextDpy++]=dpy; - break; - } - } -return i; -} -#define DPY_NUMBER(dpy) FindDpyNum(dpy) -#else /* VMS */ -#define DPY_NUMBER(dpy) ((dpy)->fd) -#endif /* VMS */ - -/* === PROCEDURES === */ - -/* ARGSUSED */ -void -XDPSLSetTextEventHandler(dpy, proc) - Display *dpy; - XDPSLEventHandler proc; -{ - TextProc = proc; -} - -/* ARGSUSED */ -void -XDPSLCallOutputEventHandler(dpy, event) - Display *dpy; - XEvent *event; -{ - (*TextProc)(event); -} - -void -XDPSLSetStatusEventHandler(dpy, proc) - Display *dpy; - XDPSLEventHandler proc; -{ - StatusProc[DPY_NUMBER(dpy)] = proc; -} - -void -XDPSLCallStatusEventHandler(dpy, event) - Display *dpy; - XEvent *event; -{ - (*(StatusProc[DPY_NUMBER(dpy)]))(event); -} - -/* Added for L2-DPS/PROTO 9 */ -void -XDPSLSetReadyEventHandler(dpy, proc) - Display *dpy; - XDPSLEventHandler proc; -{ - ReadyProc[DPY_NUMBER(dpy)] = proc; -} - -/* Added for L2-DPS/PROTO 9 */ -void -XDPSLCallReadyEventHandler(dpy, event) - Display *dpy; - XEvent *event; -{ - (*(ReadyProc[DPY_NUMBER(dpy)]))(event); -} - -/* Added for L2-DPS/PROTO 9 */ -int -XDPSLGetVersion(dpy) - Display *dpy; -{ - return(version[DPY_NUMBER(dpy)]); -} -/* See CSDPS additions for XDPSLSetVersion */ - -void -XDPSLInitDisplayFlags(dpy) - Display *dpy; -{ - int d = DPY_NUMBER(dpy); - displayFlags[d].wrapWaiting = False; - - /* Instead of explicitly setting the pass-event flag, rely upon the fact - that it gets initialized to 0 by the compiler. This means that you - can set the event delivery mode on a display before creating any - contexts, which is a Good Thing */ -} - -XExtCodes *XDPSLGetCodes(dpy) - Display *dpy; -{ - return Codes[DPY_NUMBER(dpy)]; -} - -/* ARGSUSED */ -static int -CloseDisplayProc(dpy, codes) -Display *dpy; -XExtCodes *codes; -{ - extern void XDPSPrivZapDpy(); - - /* This proc is for native DPS/X only, not CSDPS */ - Codes[DPY_NUMBER(dpy)] = NULL; - /* Clear list */ - XDPSPrivZapDpy(dpy); -#ifdef VMS - dpys[DPY_NUMBER(dpy)] = NULL; - /*%%%%Temp till we fix dpy->fd*/ -#endif /* VMS */ -} - -Bool -XDPSLGetPassEventsFlag(dpy) - Display *dpy; -{ - return displayFlags[DPY_NUMBER(dpy)].passEvents; -} - -void -XDPSLSetPassEventsFlag(dpy, flag) - Display *dpy; - Bool flag; -{ - displayFlags[DPY_NUMBER(dpy)].passEvents = flag; -} - -Bool -XDPSLGetWrapWaitingFlag(dpy) - Display *dpy; -{ - return displayFlags[DPY_NUMBER(dpy)].wrapWaiting; -} - -void -XDPSLSetWrapWaitingFlag(dpy, flag) - Display *dpy; - Bool flag; -{ - displayFlags[DPY_NUMBER(dpy)].wrapWaiting = flag; -} - -static Status -ConvertOutputEvent(dpy, ce, we) - Display *dpy; - XEvent *ce; - xEvent *we; -{ - register PSOutputEvent *wireevent = (PSOutputEvent *) we; - register XDPSLOutputEvent *clientevent = (XDPSLOutputEvent *) ce; - - clientevent->type = wireevent->type & 0x7f; - clientevent->serial = _XSetLastRequestRead(dpy, - (xGenericReply *)wireevent); - clientevent->send_event = (wireevent->type & 0x80) != 0; - clientevent->display = dpy; - clientevent->cxid = wireevent->cxid; - clientevent->length = wireevent->length; - bcopy((char *) wireevent->data, clientevent->data, wireevent->length); - if (TextProc && !XDPSLGetPassEventsFlag(dpy)) { - (*TextProc)((XEvent *) clientevent); - return False; - } - return True; -} - -static Status -ConvertStatusEvent(dpy, ce, we) - Display *dpy; - XEvent *ce; - xEvent *we; -{ - register PSStatusEvent *wireevent = (PSStatusEvent *) we; - register XDPSLStatusEvent *clientevent = (XDPSLStatusEvent *) ce; - - clientevent->type = wireevent->type & 0x7f; - clientevent->serial = _XSetLastRequestRead(dpy, - (xGenericReply *)wireevent); - clientevent->send_event = (wireevent->type & 0x80) != 0; - clientevent->display = dpy; - clientevent->cxid = wireevent->cxid; - clientevent->status = wireevent->status; - if (StatusProc[DPY_NUMBER(dpy)] && !XDPSLGetPassEventsFlag(dpy)) { - (*(StatusProc[DPY_NUMBER(dpy)]))((XEvent *) clientevent); - return False; - } - return True; -} - -/* Added for L2-DPS/PROTO 9 */ -static Status -ConvertReadyEvent(dpy, ce, we) - Display *dpy; - XEvent *ce; - xEvent *we; -{ - register PSReadyEvent *wireevent = (PSReadyEvent *) we; - register XDPSLReadyEvent *clientevent = (XDPSLReadyEvent *) ce; - - clientevent->type = wireevent->type & 0x7f; - clientevent->serial = _XSetLastRequestRead(dpy, - (xGenericReply *)wireevent); - clientevent->send_event = (wireevent->type & 0x80) != 0; - clientevent->display = dpy; - clientevent->cxid = wireevent->cxid; - clientevent->val[0] = wireevent->val1; - clientevent->val[1] = wireevent->val2; - clientevent->val[2] = wireevent->val3; - clientevent->val[3] = wireevent->val4; - if (ReadyProc[DPY_NUMBER(dpy)] && !XDPSLGetPassEventsFlag(dpy)) { - (*(ReadyProc[DPY_NUMBER(dpy)]))((XEvent *) clientevent); - return False; - } - return True; -} - -/* Added for L2-DPS/PROTO 9 */ -/* ARGSUSED */ - -static int -CatchBadMatch(dpy, err, codes, ret_code) - Display *dpy; - xError *err; - XExtCodes *codes; - int *ret_code; -{ - if (err->errorCode == BadMatch) - { - *ret_code = 0; - return 1; /* suppress error */ - } - else - { - *ret_code = 1; - return 0; /* pass error along */ - } -} - - -int -XDPSLInit(dpy, numberType, floatingName) - Display *dpy; - int *numberType; /* RETURN */ - char **floatingName; /* RETURN: CALLER MUST NOT MODIFY OR FREE! */ -{ - XExtCodes *codes = (XExtCodes *)NULL; - register xPSInitReq *req; - xPSInitReply rep; - char *ptr; - int first_event; - - { - char *ddt; - extern char *getenv(); - - if ((ddt = getenv("DPSNXOVER")) != NULL) { - gForceCSDPS = (*ddt == 't' || *ddt == 'T'); - if (gForceCSDPS) - DPSWarnProc(NULL, "*** USING DPS NX ***"); - } - } - - if ((codes = Codes[DPY_NUMBER(dpy)]) != NULL) { - if (numberType) - *numberType = NumberType[DPY_NUMBER(dpy)]; - if (floatingName) - *floatingName = FloatingName[DPY_NUMBER(dpy)]; - return codes->first_event; - } else { - if (gForceCSDPS) - goto try_dps_nx; - codes = XInitExtension(dpy, DPSNAME); - if (codes == NULL) { - /* try DEC UWS 2.2 server */ - codes = XInitExtension(dpy, DECDPSNAME); -try_dps_nx: - if (codes == NULL) { - int myNumberType; - char *myFloatingName; - - first_event = CSDPSInit(dpy, &myNumberType, &myFloatingName); - NumberType[DPY_NUMBER(dpy)] = myNumberType; - FloatingName[DPY_NUMBER(dpy)] = myFloatingName; - if (numberType) - *numberType = myNumberType; - if (floatingName) - *floatingName = myFloatingName; - return first_event; - } - } - Codes[DPY_NUMBER(dpy)] = codes; - ShuntMap[DPY_NUMBER(dpy)] = dpy; - /* set procs for native DPS/X */ - XESetCloseDisplay(dpy, codes->extension, CloseDisplayProc); - XESetWireToEvent(dpy, codes->first_event + PSEVENTOUTPUT, - ConvertOutputEvent); - XESetWireToEvent(dpy, codes->first_event + PSEVENTSTATUS, - ConvertStatusEvent); - XESetWireToEvent(dpy, codes->first_event + PSEVENTREADY, - ConvertReadyEvent); - first_event = codes->first_event; - } - - /* We have to handle a BadMatch error, in the case where - the client has a later (higher) version of - the protocol than the server */ - { - int (*oldErrorProc)(); - int libVersion; - Bool doneIt; - - XSync(dpy, False); - LockDisplay(dpy); - oldErrorProc = XESetError(dpy, codes->extension, CatchBadMatch); - libVersion = DPSPROTOCOLVERSION; - doneIt = False; - while (libVersion >= DPSPROTO_OLDEST) - { - GetReq(PSInit, req); - req->reqType = MajorOpCode(dpy); - req->dpsReqType = X_PSInit; - req->libraryversion = libVersion; - if (_XReply(dpy, (xReply *) &rep, 0, xFalse)) - { - doneIt = True; - break; - } - /* otherwise, try previous version */ - --libVersion; - } - oldErrorProc = XESetError(dpy, codes->extension, oldErrorProc); - if (!doneIt) - { - DPSFatalProc(NULL, "Incompatible protocol versions"); - exit(1); - } - - /* NOTE ************************************************* - We made a boo-boo in the 1007.2 and earlier versions of - our X server glue code. Instead of sending a - BadMatch error if the client's version is newer (higher) - than the server's, it just replies with success. We - could test for that situation here by looking at - rep.serverversion, but it turns out that we don't need - to do anything special. Since rep.serverversion gets - assigned to our version[] array, it is as if we handled - the BadMatch correctly. Just for safety's sake, we'll - do some bulletproofing here instead. - Fixes 2ps_xdps BUG #6 */ - - else if (rep.serverversion < DPSPROTO_OLDEST - || rep.serverversion > DPSPROTOCOLVERSION) - { - DPSFatalProc(NULL, "Server replied with bogus version"); - exit(1); - } - } - - version[DPY_NUMBER(dpy)] = rep.serverversion; - NumberType[DPY_NUMBER(dpy)] = rep.preferredNumberFormat; - if (numberType) - *numberType = rep.preferredNumberFormat; - - ptr = (char *) Xmalloc(rep.floatingNameLength + 1); - _XReadPad(dpy, ptr, rep.floatingNameLength); - ptr[rep.floatingNameLength] = 0; - FloatingName[DPY_NUMBER(dpy)] = ptr; - if (floatingName) - *floatingName = ptr; - - UnlockDisplay(dpy); - SyncHandle(); - return first_event; -} - - - - -static void CopyColorMapsIntoCreateContextReq(req, colorcube, grayramp) - xPSCreateContextReq *req; - XStandardColormap *colorcube, *grayramp; -{ - req->cmap = 0; - if (colorcube != NULL) { - req->cmap = colorcube->colormap; - req->redmax = colorcube->red_max; - req->redmult = colorcube->red_mult; - req->greenmax = colorcube->green_max; - req->greenmult = colorcube->green_mult; - req->bluemax = colorcube->blue_max; - req->bluemult = colorcube->blue_mult; - req->colorbase = colorcube->base_pixel; - } - else { - req->redmult = 0; - /* The rest of this shouldn't be necessary, but there are some - servers out there that erroneously check the other fields - even when redmult is 0 */ - req->redmax = 0; - req->greenmult = 0; - req->greenmax = 0; - req->bluemult = 0; - req->bluemax = 0; - req->colorbase = 0; - } - - if (grayramp != NULL) { - req->cmap = grayramp->colormap; - req->graymax = grayramp->red_max; - req->graymult = grayramp->red_mult; - req->graybase = grayramp->base_pixel; - } - else req->graymult = 0; -} - - - - - - -/* ARGSUSED */ -ContextXID -XDPSLCreateContextAndSpace(xdpy, draw, gc, x, y, eventMask, grayRamp, - colorCube, actual, cpsid, sxid, - secure) - register Display *xdpy; - Drawable draw; - GC gc; - int x, y; - unsigned int eventMask; - XStandardColormap *grayRamp,*colorCube; - unsigned int actual; - ContextPSID *cpsid; /* RETURN */ - SpaceXID *sxid; /* RETURN */ - Bool secure; /* Added for L2-DPS/PROTO 9 */ -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - ContextXID cxid; - register xPSCreateContextReq *req; /* Same struct for CreateSecureContext */ - xPSCreateContextReply rep; - XStandardColormap defColorcube, defGrayramp; - XStandardColormap *requestCube, *requestRamp; - int index; - XDPSLIOProcs *call; - - if (grayRamp == NULL && colorCube == NULL) return(None); - - if (secure && version[dpyix] < DPSPROTO_V09) - return(None); /* No secure contexts before PROTO 9 */ - - /* Index gets encoded as follows: - * - * 0 grayRamp = Default, colorCube = Default - * 1 grayRamp = non-Default, colorcube = Default - * 2 grayRamp = Default, colorcube = non-Default - * 3 grayRamp = non-Default, colorcube = non-Default - * - */ - index = ((grayRamp == DefaultStdCMap || grayRamp == NULL) ? 0 : 1) + - (colorCube == DefaultStdCMap ? 0 : 2); - - switch (index) - { - case 0: /* Both are default */ - XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw, - &defColorcube, &defGrayramp); - requestCube = &defColorcube; - requestRamp = &defGrayramp; - break; - - case 1: /* gray specified, Color default */ - XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw, - &defColorcube, (XStandardColormap *) NULL); - requestCube = &defColorcube; - requestRamp = grayRamp; - break; - - case 2: /* gray default, Color specified */ - XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw, - (XStandardColormap *) NULL, &defGrayramp); - requestCube = colorCube; - requestRamp = &defGrayramp; - break; - - case 3: /* Both specified */ - requestCube = colorCube; - requestRamp = grayRamp; - break; - } - - if (gc != NULL) - XDPSLFlushGC(xdpy, gc); - if (dpy != xdpy) - { - int syncMask = displayFlags[dpyix].syncMask; - - /* Don't worry about pauses here, since we are just - now creating the context! */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSCreateContext, req); - CopyColorMapsIntoCreateContextReq(req, requestCube, requestRamp); - - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = (secure) ? X_PSCreateSecureContext : X_PSCreateContext; - req->x = x; - req->y = y; - req->drawable = draw; - req->gc = (gc != NULL) ? XGContextFromGC(gc) : None; - cxid = req->cxid = XAllocID(xdpy); - req->sxid = XAllocID(xdpy); - if (sxid) - *sxid = req->sxid; - req->eventmask = 0; /* %%% */ - req->actual = actual; - IFNXSETCALL(dpy, xdpy); - (void) (*call->Reply) (dpy, (xReply *)&rep, 0, xTrue); - - if (cpsid) - *cpsid = (int)rep.cpsid; - - UnlockDisplay(dpy); - /* If the context creation succeeded and we are CSDPS, send GC values */ - if (rep.cpsid && xdpy != dpy && gc != NULL) - { - DPSCAPInitGC(xdpy, dpy, gc); - } - SyncHandle(); - - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; - return (cxid); -} - - -/* ARGSUSED */ -ContextXID -XDPSLCreateContext(xdpy, sxid, draw, gc, x, y, eventMask, grayRamp, - colorCube, actual, cpsid, - secure) - register Display *xdpy; - SpaceXID sxid; - Drawable draw; - GC gc; - int x, y; - unsigned int eventMask; - XStandardColormap *grayRamp,*colorCube; - unsigned int actual; - ContextPSID *cpsid; /* RETURN */ - Bool secure; /* L2-DPS/PROTO 9 addition */ -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSCreateContextReq *req; - xPSCreateContextReply rep; - ContextXID cxid; /* RETURN */ - XStandardColormap defColorcube, defGrayramp; - XStandardColormap *requestCube, *requestRamp; - int index; - XDPSLIOProcs *call; - - if (secure && version[dpyix] < DPSPROTO_V09) - return(None); /* No secure contexts before PROTO 9 */ - - /* Index gets encoded as follows: - * - * 0 grayRamp = Default, colorCube = Default - * 1 grayRamp = non-Default, colorcube = Default - * 2 grayRamp = Default, colorcube = non-Default - * 3 grayRamp = non-Default, colorcube = non-Default - * - * Note that only the first or last case should ever happen. - */ - index = ((grayRamp == DefaultStdCMap) ? 0 : 1) + - ((colorCube == DefaultStdCMap) ? 0 : 2); - - switch (index) - { - case 0: /* Both are default */ - XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw, - &defColorcube, &defGrayramp); - requestCube = &defColorcube; - requestRamp = &defGrayramp; - break; - - case 1: /* gray specified, Color default */ - XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw, - &defColorcube, (XStandardColormap *) NULL); - requestCube = &defColorcube; - requestRamp = grayRamp; - break; - - case 2: /* gray default, Color specified */ - XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw, - (XStandardColormap *) NULL, &defGrayramp); - requestCube = colorCube; - requestRamp = &defGrayramp; - break; - - case 3: /* Both specified */ - requestCube = colorCube; - requestRamp = grayRamp; - break; - } - - - if (gc != NULL) - XDPSLFlushGC(xdpy, gc); - if (dpy != xdpy) - { - int syncMask = displayFlags[dpyix].syncMask; - - /* Don't worry about pauses here, since we are - just now creating this context! */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSCreateContext, req); - CopyColorMapsIntoCreateContextReq(req, requestCube, requestRamp); - - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = (secure) ? X_PSCreateSecureContext : X_PSCreateContext; - req->x = x; - req->y = y; - req->drawable = draw; - req->gc = (gc != NULL) ? XGContextFromGC(gc) : None; - cxid = req->cxid = XAllocID(xdpy); - req->sxid = sxid; - req->actual = actual; - - IFNXSETCALL(dpy, xdpy); - (void) (*call->Reply) (dpy, (xReply *)&rep, 0, xTrue); - if (cpsid) - *cpsid = (int)rep.cpsid; - - UnlockDisplay(dpy); - /* If the context creation succeeded and we are CSDPS, send GC values */ - if (rep.cpsid && xdpy != dpy && gc != NULL) - { - DPSCAPInitGC(xdpy, dpy, gc); - } - - SyncHandle(); - - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; - return cxid; -} - -SpaceXID -XDPSLCreateSpace(xdpy) - register Display *xdpy; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSCreateSpaceReq *req; - SpaceXID sxid; - - LockDisplay(dpy); - - NXMacroGetReq(PSCreateSpace, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSCreateSpace; - sxid = req->sxid = XAllocID(xdpy); - - UnlockDisplay(dpy); - SyncHandle(); - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; - return sxid; -} - - - -/* - * I'm not sure how portable my coalescing code is, so I've provided the - * below define. If it turns out this code just breaks somewhere, you - * can simply undefine COALESCEGIVEINPUT, and then everything will work - * (but slower). 6/16/89 (tw) - */ - -#define COALESCEGIVEINPUT - -void -XDPSLGiveInput(xdpy, cxid, data, length) -register Display *xdpy; -ContextXID cxid; -char *data; -int length; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSGiveInputReq *req; - int sendlen; - XDPSLIOProcs *call; - Bool didFlush = False; - - if (dpy != xdpy) - { - register int syncMask = displayFlags[dpyix].syncMask; - - if (syncMask & DPSCAP_SYNCMASK_RECONCILE) - { - XDPSLReconcileRequests(xdpy, cxid); - didFlush = True; - } - - /* If this context got paused, no matter how, ignore - mode and resume it */ - if (gTotalPaused && DPSCAPResumeContext(xdpy, cxid)) - { - /* xdpy was flushed by DPSCAPResumeContext */ - if (!didFlush) - { - N_XFlush(dpy); - didFlush = True; - } - } - else if (syncMask & DPSCAP_SYNCMASK_SYNC) - { - didFlush = True; - XSync(xdpy, False); - } - } - LockDisplay(dpy); - -#ifdef COALESCEGIVEINPUT - req = (xPSGiveInputReq *) dpy->last_req; - if (req->reqType == MajorOpCode(xdpy) - && req->dpsReqType == X_PSGiveInput - && req->cxid == cxid - && dpy->bufptr + length + 3 < dpy->bufmax) { - bcopy(data, ((char *) req) + sizeof(xPSGiveInputReq) + req->nunits, - length); - req->nunits += length; - req->length = (sizeof(xPSGiveInputReq) + req->nunits + 3) >> 2; - dpy->bufptr = dpy->last_req + sizeof(xPSGiveInputReq) + - ((req->nunits + 3) & ~3); - } else -#endif /* COALESCEGIVEINPUT */ - { - int flushOnce = 1; - int maxedOutLen = xdpy->max_request_size - sizeof(xPSGiveInputReq) - 4; - int nunits; - - /* We have the rare opportunity to chop up a buffer that is larger - than the max request size into separate requests, unlike - most other X requests (such as DrawText). The -4 is to - force these maxed out requests to be less than the maximum - padding that would ever be needed, and to minimize padding - in the case where the input buffer is several times - larger than max request length. */ - - nunits = maxedOutLen; - do { - if (length < maxedOutLen) - nunits = length; /* Normal size block */ - NXMacroGetReq(PSGiveInput, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSGiveInput; - req->cxid = cxid; - req->nunits = nunits; - req->length += ((nunits + 3) >> 2); - if (dpy != xdpy) { - if (flushOnce && !didFlush) { - LockDisplay(xdpy); - _XFlush(xdpy); - UnlockDisplay(xdpy); - flushOnce = 0; - } - NXProcData(dpy, (char *) data, nunits); - } else - {Data(dpy, (char *) data, nunits);} - data += nunits; - length -= nunits; - } while (length); - } - - /* In the NX case (didFlush is always False for the non-NX case), - the xdpy may have been flushed, but there is stuff left - buffered in dpy (NX connection). We can't leave the stuff - there, since we may never call a DPS routine again. Until - we can be notified about xdpy being flushed, we have to - clear out the dpy buffer after we cleared out the xdpy - buffer (didFlush == True). */ - - if (dpy != xdpy - && dpy->bufptr != dpy->buffer - && (gForceFlush || didFlush)) - N_XFlush(dpy); - - UnlockDisplay(dpy); - SyncHandle(); - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; -} - - -int -XDPSLGetStatus(xdpy, cxid) - register Display *xdpy; - ContextXID cxid; -{ - int dpyix; - Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSGetStatusReq *req; - xPSGetStatusReply rep; - XDPSLIOProcs *call; - - if (dpy != xdpy) - { - register int syncMask = displayFlags[dpyix].syncMask; - - /* ASSERT: There is no reason to pause the context for this - request, so just sync. */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSGetStatus, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSGetStatus; - req->cxid = cxid; - req->notifyIfChange = 0; - - IFNXSETCALL(dpy, xdpy); - if (! (*call->Reply)(dpy, (xReply *)&rep, 0, xTrue)) - rep.status = PSSTATUSERROR; - UnlockDisplay(dpy); - SyncHandle(); - /* For CSDPS, guarantee that status events arrive just like DPS/X */ - if (dpy != xdpy) - { - XDPSLSync(xdpy); - LastXRequest[dpyix] = XNextRequest(xdpy)-1; - } - return (int) rep.status; -} - -void -XDPSLDestroySpace( xdpy, sxid ) - Display *xdpy; - SpaceXID sxid; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSDestroySpaceReq *req; - - if (dpy != xdpy) - { - int syncMask = displayFlags[dpyix].syncMask; - - /* ASSERT: There is no reason to pause the context for this - request, so just sync. */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSDestroySpace, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSDestroySpace; - req->sxid = sxid; - - if (gAutoFlush && dpy != xdpy) - { - N_XFlush(dpy); - } - UnlockDisplay(dpy); - SyncHandle(); - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; -} - - -void -XDPSLReset( xdpy, cxid ) - Display *xdpy; - ContextXID cxid; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSResetReq *req; - - if (dpy != xdpy) - { - register int syncMask = displayFlags[dpyix].syncMask; - - /* ASSERT: There is no reason to pause the context for this - request, so just sync. */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSReset, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSReset; - req->cxid = cxid; - - if (gAutoFlush && dpy != xdpy) - { - N_XFlush(dpy); - } - UnlockDisplay(dpy); - SyncHandle(); - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; -} - -void -XDPSLNotifyContext( xdpy, cxid, ntype ) - Display *xdpy; - ContextXID cxid; - int ntype; /* should this be an enum?? %%% */ -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSNotifyContextReq *req; - - if (dpy != xdpy) - { - register int syncMask = displayFlags[dpyix].syncMask; - - /* ASSERT: There is no reason to pause the context for this - request, so just sync. */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSNotifyContext, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSNotifyContext; - req->cxid = cxid; - req->notifyType = ntype; - - if (dpy != xdpy) - { - N_XFlush(dpy); /* THIS IS CRITICAL TO AVOID HANGING! */ - } - - UnlockDisplay(dpy); - SyncHandle(); - - if (dpy != xdpy) - { - if (ntype == PSKILL) - XDPSLCleanContext(xdpy, cxid); - LastXRequest[dpyix] = XNextRequest(xdpy)-1; - } -} - - -ContextXID -XDPSLCreateContextFromID( xdpy, cpsid, sxid ) - Display *xdpy; - ContextPSID cpsid; - SpaceXID *sxid; /* RETURN */ -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSCreateContextFromIDReq *req; - xPSCreateContextFromIDReply rep; - ContextXID cxid; - XDPSLIOProcs *call; - - if (dpy != xdpy) - { - int syncMask = displayFlags[dpyix].syncMask; - - /* ASSERT: There is no reason to pause the context for this - request, so just sync. */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSCreateContextFromID, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSCreateContextFromID; - req->cpsid = cpsid; - cxid = req->cxid = XAllocID(xdpy); - - IFNXSETCALL(dpy, xdpy); - (void) (*call->Reply) (dpy, (xReply *)&rep, 0, xTrue); - if (sxid) - *sxid = (int)rep.sxid; - - UnlockDisplay(dpy); - SyncHandle(); - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; - return(cxid); -} - - -/* Returns 1 on success, 0 on failure (cpsid not a valid context). */ - -Status -XDPSLIDFromContext( xdpy, cpsid, cxid, sxid ) - Display *xdpy; - ContextPSID cpsid; - ContextXID *cxid; /* RETURN */ - SpaceXID *sxid; /* RETURN */ -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSXIDFromContextReq *req; - xPSXIDFromContextReply rep; - XDPSLIOProcs *call; - - if (dpy != xdpy) - { - int syncMask = displayFlags[dpyix].syncMask; - - /* ASSERT: There is no reason to pause the context for this - request, so just sync. */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSXIDFromContext, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSXIDFromContext; - req->cpsid = cpsid; - - IFNXSETCALL(dpy, xdpy); - (void) (*call->Reply) (dpy, (xReply *)&rep, 0, xTrue); - *sxid = (int)rep.sxid; - *cxid = (int)rep.cxid; - - UnlockDisplay(dpy); - SyncHandle(); - - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; - return((Status)(*sxid != None && *cxid != None)); -} - - -ContextPSID -XDPSLContextFromXID( xdpy, cxid ) - Display *xdpy; - ContextXID cxid; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSContextFromXIDReq *req; - xPSContextFromXIDReply rep; - XDPSLIOProcs *call; - - if (dpy != xdpy) - { - int syncMask = displayFlags[dpyix].syncMask; - - /* ASSERT: There is no reason to pause the context for this - request, so just sync. */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSContextFromXID, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSContextFromXID; - req->cxid = cxid; - - IFNXSETCALL(dpy, xdpy); - (void) (*call->Reply) (dpy, (xReply *)&rep, 0, xTrue); - - UnlockDisplay(dpy); - SyncHandle(); - - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; - return (int)rep.cpsid; -} - - -void -XDPSLSetStatusMask( xdpy, cxid, enableMask, disableMask, nextMask ) - Display *xdpy; - ContextXID cxid; - unsigned int enableMask, disableMask, nextMask; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSSetStatusMaskReq *req; - - if (dpy != xdpy) - { - register int syncMask = displayFlags[dpyix].syncMask; - - /* ASSERT: There is no reason to pause the context for this - request, so just sync. */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSSetStatusMask, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSSetStatusMask; - req->cxid = cxid; - req->enableMask = enableMask; - req->disableMask = disableMask; - req->nextMask = nextMask; - - if (gAutoFlush && dpy != xdpy) - { - N_XFlush(dpy); - } - UnlockDisplay(dpy); - SyncHandle(); - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; -} - - -#ifdef VMS -/* - * _XReadPad - Read bytes from the socket taking into account incomplete - * reads. If the number of bytes is not 0 mod 32, read additional pad - * bytes. This routine may have to be reworked if int < long. - */ - -/* This is really in xlib, but is not in the sharable image transfer vector - * so I am copying it here for now. BF - -The following notice applies only to the functions -_XReadPad and XFlush - -Copyright 1985, 1986, 1987, 1988, 1989 by the -Massachusetts Institute of Technology - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of M.I.T. not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. M.I.T. makes no representations about the -suitability of this software for any purpose. It is provided "as is" -without express or implied warranty. - -*/ - -_XReadPad (xdpy, data, size) - register Display *dpy; - register char *data; - register long size; -{ - static int padlength[4] = {0,3,2,1}; - register long bytes_read; - char pad[3]; - - CheckLock(dpy); - if (size == 0) return; - _XRead( dpy, data, size ); - if ( padlength[size & 3] ) { - _XRead( dpy, pad, padlength[size & 3] ); - } - -} -#endif /* VMS */ - -/* _____________ LEVEL 2 DPS/PROTOCOL 9 ADDITIONS _____________ */ - -void -XDPSLNotifyWhenReady( xdpy, cxid, val ) - Display *xdpy; - ContextXID cxid; - int val[4]; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xPSNotifyWhenReadyReq *req; - - if (version[dpyix] < DPSPROTO_V09) - { - DPSWarnProc(NULL, "Attempted use of XDPSLNotifyWhenReady with incompatible server ignored"); - return; /* PROTO 9 or later only */ - } - - if (dpy != xdpy) - { - register int syncMask = displayFlags[dpyix].syncMask; - - if (syncMask & DPSCAP_SYNCMASK_RECONCILE) - XDPSLReconcileRequests(xdpy, cxid); - - /* If this context got paused, no matter how, ignore - mode and resume it */ - if (gTotalPaused && DPSCAPResumeContext(xdpy, cxid)) - { - /* xdpy was flushed by DPSCAPResumeContext */ - if (gAutoFlush) - N_XFlush(dpy); - } - else if (syncMask & DPSCAP_SYNCMASK_SYNC) - XSync(xdpy, False); - } - LockDisplay(dpy); - - NXMacroGetReq(PSNotifyWhenReady, req); - req->reqType = MajorOpCode(xdpy); - req->dpsReqType = X_PSNotifyWhenReady; - req->cxid = cxid; - req->val1 = val[0]; - req->val2 = val[1]; - req->val3 = val[2]; - req->val4 = val[3]; - - if (gAutoFlush && dpy != xdpy) - { - N_XFlush(dpy); - } - UnlockDisplay(dpy); - SyncHandle(); - if (dpy != xdpy) - LastXRequest[dpyix] = XNextRequest(xdpy)-1; -} - -XDPSLPSErrors -XDPSLTestErrorCode(dpy, ecode) - Display *dpy; - int ecode; -{ - XExtCodes *c = XDPSLGetCodes(dpy); - - if (c == NULL) - return False; /* Not inited on that display; must be False */ - - switch (ecode - c->first_error) - { - case PSERRORBADCONTEXT: return(pserror_badcontext); - case PSERRORBADSPACE: return(pserror_badspace); - case PSERRORABORT: - if (version[DPY_NUMBER(dpy)] < DPSPROTO_V09) - return(not_pserror); - else - return(pserror_abort); - default: return(not_pserror); - } -} - -/* _____________ CLIENT SIDE DPS ADDITIONS _____________ */ - -/* === NEW HOOKS INTO XDPS === */ - -void -XDPSLSetVersion(dpy, ver) - Display *dpy; - unsigned ver; -{ - version[DPY_NUMBER(dpy)] = ver; -} - -void -XDPSLSetCodes(dpy, codes) - Display *dpy; - XExtCodes *codes; -{ - Codes[DPY_NUMBER(dpy)] = codes; -} - -Display * -XDPSLGetShunt(dpy_in) - register Display *dpy_in; -{ - return(ShuntMap[DPY_NUMBER(dpy_in)]); -} - -void -XDPSLSetShunt(dpy_in, dpy_out) - Display *dpy_in, *dpy_out; -{ - ShuntMap[DPY_NUMBER(dpy_in)] = dpy_out; -} - -int -XDPSLGetSyncMask(dpy) - Display *dpy; -{ - return (int)displayFlags[DPY_NUMBER(dpy)].syncMask; -} - -void -XDPSLSetSyncMask(dpy, mask) - Display *dpy; - int mask; -{ - displayFlags[DPY_NUMBER(dpy)].syncMask = (char)mask; - gForceFlush = (mask & DPSCAP_SYNCMASK_RECONCILE); -} - -void -XDPSLFlush(xdpy) - register Display *xdpy; -{ - register Display *dpy = ShuntMap[DPY_NUMBER(xdpy)]; - - _XFlush(xdpy); - if (dpy != xdpy) - N_XFlush(dpy); -} - -void -XDPSLSyncGCClip(xdpy, gc) - register Display *xdpy; - register GC gc; -{ - register unsigned long oldDirty; - register int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - extern int gNXSyncGCMode; - - /* We DON'T want to notice all gc changes, just the clip */ - oldDirty = gc->dirty; - gc->dirty = (GCClipXOrigin|GCClipYOrigin); - XDPSLFlushGC(xdpy, gc); - gc->dirty = oldDirty; - if (dpy == xdpy || gNXSyncGCMode != 1) /* 1 means sync always */ - { - /* For DPS NX and SLOW mode, flushing the gc cache has - the side-effect of synching agent and server connections. - So, to have consistent behavior, we sync for the DPS/X - or FAST cases too. */ - - if (GCFlushMode[dpyix] == XDPSNX_GC_UPDATES_FAST - || dpy == xdpy) - XDPSLSync(xdpy); - } -} - - -#ifdef VMS -void -XDPSLSetDisplay(dpy) - Display *dpy; -{ - dpys[DPY_NUMBER(dpy)] = dpy; -} -#endif /* VMS */ - -char * -XDPSLSetAgentName(dpy, name, deflt) - Display *dpy; - char *name; - int deflt; -{ - char *old; - - if (gCSDPS == NULL) - DPSCAPStartUp(); - if (deflt) - { - old = gCSDPS->defaultAgentName; - gCSDPS->defaultAgentName = name; - } - else - { - old = gCSDPS->map[DPY_NUMBER(dpy)]; - gCSDPS->map[DPY_NUMBER(dpy)] = name; - } - return(old); -} - - -void -XDPSLSetClientMessageHandler(dpy) - Display *dpy; -{ - if (dpy == NULL) return; - ClientMsgProc[DPY_NUMBER(dpy)] = XESetWireToEvent( - dpy, - ClientMessage, - DPSCAPClientMessageProc); -} - -void -XDPSLSetAfterProc(xdpy) - Display *xdpy; -{ - if (xdpy == NULL) return; - AfterProcs[DPY_NUMBER(xdpy)] = (GenericProcPtrReturnsInt) - XSetAfterFunction(xdpy, DPSCAPAfterProc); - /* +++ Consider using agent->synchandler to store old proc */ -} - - -CSDPSFakeEventTypes -XDPSLGetCSDPSFakeEventType(dpy, event) - Display *dpy; - XEvent *event; -{ - XExtCodes *codes = Codes[DPY_NUMBER(dpy)]; - XExtData *extData; - DPSCAPData my; - - if (event->type != ClientMessage || codes == NULL) - return(csdps_not); - extData = XFindOnExtensionList( - CSDPSHeadOfDpyExt(dpy), - codes->extension); - if (!extData) - return(csdps_not); - my = (DPSCAPData) extData->private_data; - - if (event->xclient.message_type == my->typePSOutput) - return(csdps_output); - if (event->xclient.message_type == my->typePSOutputWithLen) - return(csdps_output_with_len); - if (event->xclient.message_type == my->typePSStatus) - return(csdps_status); - if (event->xclient.message_type == my->typeNoop) - return(csdps_noop); - if (event->xclient.message_type == my->typePSReady) - return(csdps_ready); - return(csdps_not); -} - -Bool -XDPSLDispatchCSDPSFakeEvent(dpy, event, t) - Display *dpy; - XEvent *event; - CSDPSFakeEventTypes t; -{ - register XDPSLOutputEvent *oce; - register DPSCAPOutputEvent *oev; - XDPSLOutputEvent fakeOutput; - XExtCodes *codes = Codes[DPY_NUMBER(dpy)]; - - if (codes == NULL) - return(False); - - /* Fake up an event in the client's format. Bypasses - extension wire-to-event conversion */ - switch (t) - { - case csdps_output: - oce = &fakeOutput; - oev = (DPSCAPOutputEvent *)event->xclient.data.b; - oce->length = DPSCAP_BYTESPEROUTPUTEVENT; - goto samo_samo; - case csdps_output_with_len: - oce = &fakeOutput; - oev = (DPSCAPOutputEvent *)event->xclient.data.b; - oce->length = oev->data[DPSCAP_DATA_LEN]; -samo_samo: - oce->type = codes->first_event + PSEVENTOUTPUT; - oce->serial = event->xclient.serial; - oce->send_event = True; /* ??? */ - oce->display = dpy; - oce->cxid = oev->cxid; - bcopy((char *) oev->data, oce->data, oce->length); - XDPSLCallOutputEventHandler(dpy, (XEvent *) oce); - break; - case csdps_status: - { - register XDPSLStatusEvent *sce; - register DPSCAPStatusEvent *sev; - XDPSLStatusEvent fakeStatus; - - sev = (DPSCAPStatusEvent *)event->xclient.data.b; - sce = &fakeStatus; - sce->type = codes->first_event + PSEVENTSTATUS; - sce->serial = event->xclient.serial; - sce->send_event = True; /* ??? */ - sce->display = dpy; - sce->status = sev->status; - sce->cxid = sev->cxid; - XDPSLCallStatusEventHandler(dpy, (XEvent *) sce); - break; - } - case csdps_ready: /* L2-DPS/PROTO 9 addition */ - { - register XDPSLReadyEvent *rce; - XDPSLReadyEvent fakeReady; - - rce = &fakeReady; - rce->type = codes->first_event + PSEVENTREADY; - rce->serial = event->xclient.serial; - rce->send_event = True; - rce->display = dpy; - rce->cxid = event->xclient.data.l[0]; - rce->val[0] = event->xclient.data.l[1]; - rce->val[1] = event->xclient.data.l[2]; - rce->val[2] = event->xclient.data.l[3]; - rce->val[3] = event->xclient.data.l[4]; - XDPSLCallReadyEventHandler(dpy, (XEvent *) rce); - break; - } - default: - return(False); - } - return(True); -} - -extern struct _t_DPSContextRec *XDPSContextFromXID(); - -void -XDPSLGetCSDPSStatus(xdpy, event, ret_ctxt, ret_status) - Display *xdpy; - XEvent *event; - void **ret_ctxt; - int *ret_status; -{ - register DPSCAPStatusEvent *sev; - - /* Assert: event is ClientMessage with typePSStatus */ - sev = (DPSCAPStatusEvent *)event->xclient.data.b; - - if (ret_ctxt != NULL) - *ret_ctxt = XDPSContextFromXID(xdpy, sev->cxid); - if (ret_status != NULL) - *ret_status = sev->status; -} - -void -XDPSLGetCSDPSReady(xdpy, event, ret_ctxt, ret_val) - Display *xdpy; - XEvent *event; - void **ret_ctxt; - int *ret_val; -{ - /* Assert: event is ClientMessage with typePSReady */ - - if (ret_ctxt != NULL) - *ret_ctxt = - XDPSContextFromXID(xdpy, (ContextXID)event->xclient.data.l[0]); - if (ret_val != NULL) - { - ret_val[0] = event->xclient.data.l[1]; - ret_val[1] = event->xclient.data.l[2]; - ret_val[2] = event->xclient.data.l[3]; - ret_val[3] = event->xclient.data.l[4]; - } -} - -void -XDPSLCAPNotify(xdpy, cxid, ntype, data, extra) - Display *xdpy; - ContextXID cxid; - unsigned int ntype; /* should this be an enum?? %%% */ - unsigned int data; - unsigned int extra; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - register xCAPNotifyReq *req; - - if (dpy == xdpy) return; - - /* We _have_ to sync client and server here in order to guarantee - correct execution sequencing. We call this procedure alot - to keep track of GC's going away, so this is a major - performance hit. */ - if (ntype == DPSCAPNOTE_FREEGC) - XSync(xdpy, False); - - LockDisplay(dpy); - - NXMacroGetReq(CAPNotify, req); - req->reqType = DPSCAPOPCODEBASE; - req->type = X_CAPNotify; - req->cxid = cxid; - req->notification = ntype; - req->data = data; - req->extra = extra; - - if (gAutoFlush) - N_XFlush(dpy); - - UnlockDisplay(dpy); - SyncHandle(); - LastXRequest[dpyix] = XNextRequest(xdpy)-1; -} - -void -XDPSLSync(xdpy) - Display *xdpy; -{ - register Display *dpy = ShuntMap[DPY_NUMBER(xdpy)]; - - if (dpy == xdpy) - { - /* DPS/X */ - XSync(dpy, False); - } - else - { - /* CSDPS */ - XEvent event; - DPSCAPData my; - XExtData *extData; - void *next; - XExtCodes *codes = Codes[DPY_NUMBER(xdpy)]; - - if (codes == NULL) - return; - /* Get private data */ - extData = XFindOnExtensionList( - CSDPSHeadOfDpyExt(xdpy), - codes->extension); - if (!extData) - return; - my = (DPSCAPData) extData->private_data; - my->saveseq = XNextRequest(dpy)-1; - /* first send notification to agent */ - XDPSLCAPNotify(xdpy, 0, DPSCAPNOTE_SYNC, my->saveseq, 0); -#ifdef XXX -fprintf(stderr, "\nXDPSLSync(DPSCAPNOTE_SYNC) sending ... "); -#endif - _XFlush(xdpy); - N_XFlush(dpy); -#ifdef XXX -fprintf(stderr, "sent.\nWaiting for reply ... "); -#endif - /* agent should send a ClientMessage, so wait for it */ - XIfEvent(xdpy, &event, WaitForSyncProc, (char *) my); - -#ifdef XXX -fprintf(stderr, "received.\n"); -#endif - /* now client, agent, and server are synchronized */ - } -} - -void -XDPSLReconcileRequests(xdpy, cxid) - Display *xdpy; - ContextXID cxid; -{ - int dpyix; - unsigned int seqnum; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - - if (dpy == xdpy) - return; /* No-op for DPS/X */ - - /* Get the sequence number and set the pause flag - IFF we are sure that some X protocol has occurred - since the last time we did a DPS request. This - minimizes pause/resume requests */ - - if (LastXRequest[dpyix] == XNextRequest(xdpy)-1) - { - if (gAutoFlush) - N_XFlush(dpy); /* This is what XDPSLCAPNotify would do */ - return; - } - else - seqnum = DPSCAPSetPause(xdpy, cxid); - - /* Pause the context specified. */ - XDPSLCAPNotify(xdpy, cxid, DPSCAPNOTE_PAUSE, seqnum, 0); - - /* We don't even need to flush. All we have to do is make - sure that the notify request is queued before any - DPS requests that follow. */ -} - -Status -XDPSLSetAgentArg(xdpy, arg, val) - Display *xdpy; - int arg, val; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - CARD32 capArg; - register xCAPSetArgReq *req; - - if (dpy == xdpy) - return(Success); /* No-op for DPS/X */ - - /* dpy will be NIL if we haven't opened a connection yet, - but that's okay since we need to save the value anyway. */ - - if (dpy) - { - int syncMask = displayFlags[dpyix].syncMask; - - /* ASSERT: There is no reason to pause the context for this - request, so just sync. */ - if (syncMask & (DPSCAP_SYNCMASK_SYNC|DPSCAP_SYNCMASK_RECONCILE)) - XSync(xdpy, False); - } - - switch (arg) - { - case AGENT_ARG_SMALLFONTS: - AgentArgs[dpyix].showSmallSizes = val; - capArg = DPSCAP_ARG_SMALLFONTS; - break; - case AGENT_ARG_PIXMEM: - AgentArgs[dpyix].pixMem = val; - capArg = DPSCAP_ARG_PIXMEM; - break; - default: - return(!Success); - } - if (!dpy) - return(Success); - - LockDisplay(dpy); - - NXMacroGetReq(CAPSetArg, req); - req->reqType = DPSCAPOPCODEBASE; - req->type = X_CAPSetArg; - req->arg = capArg; - req->val = val; - - if (gAutoFlush) - N_XFlush(dpy); - - UnlockDisplay(dpy); - SyncHandle(); - LastXRequest[dpyix] = XNextRequest(xdpy)-1; - return(Success); -} - - -void -XDPSLCleanAll(xdpy) - register Display *xdpy; -{ - /* Clean up all state associated with dpy */ - register DPSCAPPausedContextData *slot; - int dpyix = DPY_NUMBER(xdpy); - - /* Clean up paused context list */ - for (slot = PausedPerDisplay[dpyix]; slot; slot = PausedPerDisplay[dpyix]) - { - PausedPerDisplay[dpyix] = slot->next; - Xfree(slot); - } - - /* Clear agent args */ - AgentArgs[dpyix].showSmallSizes = 0; - AgentArgs[dpyix].pixMem = 0; -} - -void -XDPSLUpdateAgentArgs(xdpy) - register Display *xdpy; -{ - int dpyix = DPY_NUMBER(xdpy); - - if (AgentArgs[dpyix].showSmallSizes) - XDPSLSetAgentArg(xdpy, AGENT_ARG_SMALLFONTS, AgentArgs[dpyix].showSmallSizes); - if (AgentArgs[dpyix].pixMem) - XDPSLSetAgentArg(xdpy, AGENT_ARG_PIXMEM, AgentArgs[dpyix].pixMem); -} - -void -XDPSLCleanContext(xdpy, cxid) - Display *xdpy; - ContextXID cxid; -{ - /* Clean up all state associated with cxid on this dpy */ - register DPSCAPPausedContextData *slot, *prev; - int dpyix = DPY_NUMBER(xdpy); - - /* If this is DPS/X, then slot will never have been initialized. - See XDPSLNotifyContext */ - - /* Clean up paused context list */ - prev = (DPSCAPPausedContextData *)NULL; - for (slot = PausedPerDisplay[dpyix]; slot; prev = slot, slot = slot->next) - { - if (slot->cxid != cxid) - continue; - if (!prev) - PausedPerDisplay[dpyix] = slot->next; - else - prev->next = slot->next; - Xfree(slot); - break; - } -} - -/* DPS NX 2.0 */ -void -XDPSLSetGCFlushMode(dpy, value) - Display *dpy; - int value; -{ - int dpyix; - register Display *agent = ShuntMap[dpyix = DPY_NUMBER(dpy)]; - - if (value != XDPSNX_GC_UPDATES_SLOW && value != XDPSNX_GC_UPDATES_FAST) - { - DPSWarnProc(NULL, "DPS NX: Bogus GC flush mode.\n"); - return; - } - /* 0 means no NX */ - GCFlushMode[dpyix] = (agent == dpy) ? 0 : value; -} - -int -XDPSLGetGCFlushMode(dpy) - Display *dpy; -{ - return(GCFlushMode[DPY_NUMBER(dpy)]); -} - -void -XDPSLFlushGC(xdpy, gc) - Display *xdpy; - GC gc; -{ - int dpyix; - register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)]; - - if (!gc->dirty) return; - - if (GCFlushMode[dpyix] == XDPSNX_GC_UPDATES_FAST) - { - XGCValues vals; - static unsigned long valuemask = DPSGCBITS & ~(GCClipMask); - - /* Okay to call Xlib, since dpy isn't locked */ - DPSAssertWarn(XGetGCValues(xdpy, gc, valuemask, &vals), - NULL, "DPS NX: XGetGCValues returned False\n"); - vals.clip_mask = gc->values.clip_mask; - LockDisplay(dpy); - DPSCAPChangeGC(dpy, gc, DPSGCBITS, &vals); - UnlockDisplay(dpy); - SyncHandle(); - } - /* Fall thru. Either the GCFlushMode is SLOW, which means - we will DPSCAPChangeGC as a side-effect of FlushGC when - the GC hook is called, or we just did it in the FAST case. */ - FlushGC(xdpy, gc); - XDPSLFlush(xdpy); -} - -/* === PRIVATE CSDPS PROCS === */ - -static Status -DPSCAPClientMessageProc(dpy, re, event) - Display *dpy; - XEvent *re; - register xEvent *event; -{ - register XDPSLOutputEvent *oce; - register DPSCAPOutputEvent *oev; - XDPSLOutputEvent fakeOutput; - XExtCodes *codes = Codes[DPY_NUMBER(dpy)]; - PSCMProc oldProc = ClientMsgProc[DPY_NUMBER(dpy)]; - - if (codes != NULL) - { - /* Get private data */ - XExtData *extData = XFindOnExtensionList( - CSDPSHeadOfDpyExt(dpy), - codes->extension); - DPSCAPData my; - - /* There's no extension, or there is an extension but we are - passing events uninterpreted, so just pass it along - unless it is a DPSCAP error. */ - - if (!extData) - goto pass_the_buck; - my = (DPSCAPData) extData->private_data; - if (XDPSLGetPassEventsFlag(dpy) && - (event->u.clientMessage.u.l.type != my->typeXError)) - goto pass_the_buck; - - /* Fake up a DPS extension event and handle it transparently, - without going through the Xlib event queue */ - - if (event->u.clientMessage.u.b.type == my->typePSOutput) - { - oce = &fakeOutput; - oce->length = DPSCAP_BYTESPEROUTPUTEVENT; - oev = (DPSCAPOutputEvent *)event->u.clientMessage.u.b.bytes; - goto common_stuff; - } - else if (event->u.clientMessage.u.b.type == my->typePSOutputWithLen) - { - oce = &fakeOutput; - oev = (DPSCAPOutputEvent *)event->u.clientMessage.u.b.bytes; - oce->length = oev->data[DPSCAP_DATA_LEN]; -common_stuff: - oce->type = codes->first_event + PSEVENTOUTPUT; - oce->serial = _XSetLastRequestRead(dpy, (xGenericReply *)event); - oce->send_event = True; /* ??? */ - oce->display = dpy; - oce->cxid = oev->cxid; - bcopy((char *) oev->data, oce->data, oce->length); - /* We've converted the event, give it to DPS */ - if (TextProc) - (*TextProc)((XEvent *) oce); - return(False); - } - else if (event->u.clientMessage.u.b.type == my->typePSStatus) - { - register XDPSLStatusEvent *sce; - register DPSCAPStatusEvent *sev; - XDPSLStatusEvent fakeStatus; - - sev = (DPSCAPStatusEvent *)event->u.clientMessage.u.b.bytes; - sce = &fakeStatus; - sce->type = codes->first_event + PSEVENTSTATUS; - sce->serial = _XSetLastRequestRead(dpy, (xGenericReply *)event); - sce->send_event = True; /* ??? */ - sce->display = dpy; - sce->cxid = sev->cxid; - sce->status = sev->status; - /* We've converted the event, give it to DPS */ - if (StatusProc[DPY_NUMBER(dpy)]) - (*(StatusProc[DPY_NUMBER(dpy)]))((XEvent *) sce); - return(False); - } - else if (event->u.clientMessage.u.l.type == my->typeXError) - { - xError err; - register xError *e = &err; - - e->type = X_Error; - e->errorCode = event->u.clientMessage.u.l.longs0; - e->sequenceNumber = event->u.u.sequenceNumber; - e->resourceID = event->u.clientMessage.u.l.longs3; - e->minorCode = event->u.clientMessage.u.l.longs2; - e->majorCode = event->u.clientMessage.u.l.longs1; - /* Smash the wire event here, before going off deep end */ - event->u.clientMessage.u.l.type = my->typeNoop; - /* Jump! */ - return(_XError(dpy, e)); - } - else if (event->u.clientMessage.u.l.type == my->typePSReady) - /* L2-DPS/PROTO 9 addition */ - { - register XDPSLReadyEvent *rce; - XDPSLReadyEvent fakeReady; - - rce = &fakeReady; - rce->type = codes->first_event + PSEVENTREADY; - rce->serial = _XSetLastRequestRead(dpy, (xGenericReply *)event); - rce->send_event = True; - rce->display = dpy; - rce->cxid = event->u.clientMessage.u.l.longs0; - rce->val[0] = event->u.clientMessage.u.l.longs1; - rce->val[1] = event->u.clientMessage.u.l.longs2; - rce->val[2] = event->u.clientMessage.u.l.longs3; - rce->val[3] = event->u.clientMessage.u.l.longs4; - XDPSLCallReadyEventHandler(dpy, (XEvent *) rce); - return(False); - } - } - - /* Put the event on the queue, so that Xlib is happy */ -pass_the_buck: - return(oldProc(dpy, re, event)); -} - - -static void -DPSCAPInitGC(dpy, agent, gc) - Display *dpy, *agent; - GC gc; -{ - XGCValues values; - unsigned long valuemask = DPSGCBITS & ~(GCClipMask); - - /* Okay to call Xlib, since dpy isn't locked */ - DPSAssertWarn(XGetGCValues(dpy, gc, valuemask, &values), - NULL, "DPS NX: XGetGCValues returned False\n"); - values.clip_mask = gc->values.clip_mask; - DPSCAPChangeGC(agent, gc, DPSGCBITS, &values); - SyncHandle(); - XDPSLSync(dpy); -} - - -/* ARGSUSED */ - -static Bool -WaitForSyncProc(xdpy, event, arg) - Display *xdpy; - XEvent *event; - char *arg; -{ - DPSCAPData my = (DPSCAPData)arg; - - if ((event->type & 0x7F) == ClientMessage - && event->xclient.message_type == my->typeSync - && event->xclient.data.l[0] == my->saveseq) { - return(True); - } else { - return(False); - } -} - - -static int -DPSCAPAfterProc(xdpy) - Display *xdpy; -{ - register Display *dpy = ShuntMap[DPY_NUMBER(xdpy)]; - GenericProcPtrReturnsInt proc; - - if (dpy != (Display *)NULL && dpy != xdpy) - { - LockDisplay(dpy); - N_XFlush(dpy); - UnlockDisplay(dpy); - LockDisplay(xdpy); - _XFlush(xdpy); - UnlockDisplay(xdpy); - } - if ((proc = AfterProcs[DPY_NUMBER(xdpy)]) != NULL) - return((*proc)(xdpy)); - else - return(0); -} - - -static unsigned int -DPSCAPSetPause(xdpy, cxid) - register Display *xdpy; - register ContextXID cxid; -{ - register DPSCAPPausedContextData *slot; - int dpyix; - unsigned int ret; - - /* Find or create slot */ - - slot = PausedPerDisplay[dpyix = DPY_NUMBER(xdpy)]; - if (!slot) - { - slot = (DPSCAPPausedContextData *) - Xcalloc(1, sizeof(DPSCAPPausedContextData)); - PausedPerDisplay[dpyix] = slot; - goto common_code; - /* IMPLICATION: it is okay to fall through common_code - and do test_ret. */ - } - while (1) - if (slot->cxid == cxid) - { - if (!slot->paused) - { - slot->paused = True; - ++gTotalPaused; - } - /* Back-to-back pauses get different sequence numbers */ - ret = ++slot->seqnum; - goto test_ret; - } - else if (slot->next) slot = slot->next; - else break; - /* cxid wasn't found, so add it */ - /* ASSERT: slot points to last record of the list */ - slot->next = (DPSCAPPausedContextData *) - Xcalloc(1, sizeof(DPSCAPPausedContextData)); - slot = slot->next; -common_code: - slot->paused = True; - ++gTotalPaused; - slot->cxid = cxid; - ret = ++slot->seqnum; -test_ret: - if (!ret) - { - DPSWarnProc(NULL, "Pause sequence wrapped around!"); - } - return(ret); -} - -static Bool -DPSCAPResumeContext(xdpy, cxid) - register Display *xdpy; - register ContextXID cxid; -{ - register DPSCAPPausedContextData *slot; - unsigned int ret; - int dpyix = DPY_NUMBER(xdpy); - - /* Try to match cxid to list of paused contexts */ - for (slot = PausedPerDisplay[dpyix]; slot; slot = slot->next) - if (slot->cxid == cxid && slot->paused) - { - /* Send resume event */ - register XClientMessageEvent *ee; - XEvent e; - XExtData *extData; - DPSCAPData my; - XExtCodes *codes = Codes[dpyix]; - - extData = XFindOnExtensionList( - CSDPSHeadOfDpyExt(xdpy), - codes->extension); - if (!extData) - return(False); - my = (DPSCAPData) extData->private_data; - - ee = &e.xclient; - ee->type = ClientMessage; - ee->display = xdpy; - ee->window = my->agentWindow; - ee->format = 32; - ee->message_type = my->typeResume; - ee->data.l[0] = cxid; - ee->data.l[1] = slot->seqnum; - (void) XSendEvent( - xdpy, - my->agentWindow, - False, - NoEventMask, - &e); - XFlush(xdpy); - /* Turn off flag */ - slot->paused = False; - --gTotalPaused; - return(True); - } - /* Fall thru */ - return(False); -} - - - - - - |