#define NEED_EVENTS
#define NEED_REPLIES
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <X11/Xlibint.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include "DPS/XDPS.h"
#include "DPS/XDPSproto.h"
#include "DPS/XDPSlib.h"
#include "DPS/dpsNXargs.h"
#include "cslibint.h"
#include "dpsassert.h"
#include "DPSCAPClient.h"
#include "publictypes.h"
#include "dpsXpriv.h"
#ifndef _NFILE
#define DPSMAXDISPLAYS 128
#else
#define DPSMAXDISPLAYS _NFILE
#endif
#define MajorOpCode(dpy) (Codes[DPY_NUMBER(dpy)] ? \
Codes[DPY_NUMBER(dpy)]->major_opcode : \
Punt())
#define DPSCAP_INITCTXTS 4
typedef Status (*PSCMProc)(Display *, XEvent *, xEvent *);
typedef struct {
char passEvents;
char wrapWaiting;
char syncMask;
char debugMask;
} DPSDisplayFlags;
typedef int (*GenericProcPtrReturnsInt)(Display *);
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 {
void (*Flush)(Display *);
int (*Read)(Display*, char*, long);
void (*ReadPad)(Display*, char*, long);
Status (*Reply)(Display*, xReply*, int, Bool);
void (*Send)(Display*, _Xconst char*, long);
} XDPSLIOProcs;
int gForceCSDPS = 0;
int gAutoFlush = 1;
int gForceFlush = 1;
int gTotalPaused = 0;
static XExtCodes *Codes[DPSMAXDISPLAYS];
static int version[DPSMAXDISPLAYS];
static XDPSLEventHandler StatusProc[DPSMAXDISPLAYS];
static DPSDisplayFlags displayFlags[DPSMAXDISPLAYS];
static XDPSLEventHandler TextProc = NULL;
static XDPSLEventHandler ReadyProc[DPSMAXDISPLAYS];
static int NumberType[DPSMAXDISPLAYS];
static char *FloatingName[DPSMAXDISPLAYS];
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
static void DPSCAPInitGC(Display *dpy, Display *agent, GC gc);
static Status DPSCAPClientMessageProc(Display *dpy, XEvent *re, xEvent *event);
static int DPSCAPAfterProc(Display *xdpy);
static unsigned int DPSCAPSetPause(Display *xdpy, ContextXID cxid);
static Bool DPSCAPResumeContext(Display *xdpy, ContextXID cxid);
static Bool WaitForSyncProc(Display *xdpy, XEvent *event, char *arg);
static XDPSLIOProcs xlProcs = {
_XFlush,
_XRead,
_XReadPad,
_XReply,
_XSend
};
static XDPSLIOProcs nxlProcs = {
N_XFlush,
N_XRead,
N_XReadPad,
N_XReply,
N_XSend
};
#define IFNXSETCALL(a, x) call = ((a) != (x)) ? &nxlProcs : &xlProcs
static int Punt(void)
{
DPSFatalProc(NULL, "Extension has not been initialized");
exit(1);
}
#ifdef VMS
static int FindDpyNum(Display *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
#define DPY_NUMBER(dpy) ((dpy)->fd)
#endif
void
XDPSLSetTextEventHandler(Display *dpy, XDPSLEventHandler proc)
{
TextProc = proc;
}
void
XDPSLCallOutputEventHandler(Display *dpy, XEvent *event)
{
(*TextProc)(event);
}
void
XDPSLSetStatusEventHandler(Display *dpy, XDPSLEventHandler proc)
{
StatusProc[DPY_NUMBER(dpy)] = proc;
}
void
XDPSLCallStatusEventHandler(Display *dpy, XEvent *event)
{
(*(StatusProc[DPY_NUMBER(dpy)]))(event);
}
void
XDPSLSetReadyEventHandler(Display *dpy, XDPSLEventHandler proc)
{
ReadyProc[DPY_NUMBER(dpy)] = proc;
}
void
XDPSLCallReadyEventHandler(Display *dpy, XEvent *event)
{
(*(ReadyProc[DPY_NUMBER(dpy)]))(event);
}
int
XDPSLGetVersion(Display *dpy)
{
return(version[DPY_NUMBER(dpy)]);
}
void
XDPSLInitDisplayFlags(Display *dpy)
{
int d = DPY_NUMBER(dpy);
displayFlags[d].wrapWaiting = False;
}
XExtCodes *XDPSLGetCodes(Display *dpy)
{
return Codes[DPY_NUMBER(dpy)];
}
static int
CloseDisplayProc(Display *dpy, XExtCodes *codes)
{
Codes[DPY_NUMBER(dpy)] = NULL;
XDPSPrivZapDpy(dpy);
#ifdef VMS
dpys[DPY_NUMBER(dpy)] = NULL;
#endif
return 0;
}
Bool
XDPSLGetPassEventsFlag(Display *dpy)
{
return displayFlags[DPY_NUMBER(dpy)].passEvents;
}
void
XDPSLSetPassEventsFlag(Display *dpy, Bool flag)
{
displayFlags[DPY_NUMBER(dpy)].passEvents = flag;
}
Bool
XDPSLGetWrapWaitingFlag(Display *dpy)
{
return displayFlags[DPY_NUMBER(dpy)].wrapWaiting;
}
void
XDPSLSetWrapWaitingFlag(Display *dpy, Bool flag)
{
displayFlags[DPY_NUMBER(dpy)].wrapWaiting = flag;
}
static Status
ConvertOutputEvent(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(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;
}
static Status
ConvertReadyEvent(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;
}
static int
CatchBadMatch(Display *dpy, xError *err, XExtCodes *codes, int *ret_code)
{
if (err->errorCode == BadMatch)
{
*ret_code = 0;
return 1;
}
else
{
*ret_code = 1;
return 0;
}
}
int
XDPSLInit(
Display *dpy,
int *numberType,
char **floatingName)
{
XExtCodes *codes = (XExtCodes *)NULL;
register xPSInitReq *req;
xPSInitReply rep;
char *ptr;
int first_event;
{
char *ddt;
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) {
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;
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;
}
{
int (*oldErrorProc)(Display*, xError*, XExtCodes*, int*);
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;
}
--libVersion;
}
oldErrorProc = XESetError(dpy, codes->extension, oldErrorProc);
if (!doneIt)
{
DPSFatalProc(NULL, "Incompatible protocol versions");
exit(1);
}
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(
xPSCreateContextReq *req,
XStandardColormap *colorcube,
XStandardColormap *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;
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;
}
ContextXID
XDPSLCreateContextAndSpace(
register Display *xdpy,
Drawable draw,
GC gc,
int x, int y,
unsigned int eventMask,
XStandardColormap *grayRamp,
XStandardColormap *colorCube,
unsigned int actual,
ContextPSID *cpsid,
SpaceXID *sxid,
Bool secure)
{
int dpyix;
register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)];
ContextXID cxid;
register xPSCreateContextReq *req;
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);
index = ((grayRamp == DefaultStdCMap || grayRamp == NULL) ? 0 : 1) +
(colorCube == DefaultStdCMap ? 0 : 2);
switch (index)
{
default:
case 0:
XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw,
&defColorcube, &defGrayramp);
requestCube = &defColorcube;
requestRamp = &defGrayramp;
break;
case 1:
XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw,
&defColorcube, (XStandardColormap *) NULL);
requestCube = &defColorcube;
requestRamp = grayRamp;
break;
case 2:
XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw,
(XStandardColormap *) NULL, &defGrayramp);
requestCube = colorCube;
requestRamp = &defGrayramp;
break;
case 3:
requestCube = colorCube;
requestRamp = grayRamp;
break;
}
if (gc != NULL)
XDPSLFlushGC(xdpy, gc);
if (dpy != xdpy)
{
int syncMask = displayFlags[dpyix].syncMask;
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 (rep.cpsid && xdpy != dpy && gc != NULL)
{
DPSCAPInitGC(xdpy, dpy, gc);
}
SyncHandle();
if (dpy != xdpy)
LastXRequest[dpyix] = XNextRequest(xdpy)-1;
return (cxid);
}
ContextXID
XDPSLCreateContext(
register Display *xdpy,
SpaceXID sxid,
Drawable draw,
GC gc,
int x, int y,
unsigned int eventMask,
XStandardColormap *grayRamp,
XStandardColormap *colorCube,
unsigned int actual,
ContextPSID *cpsid,
Bool secure)
{
int dpyix;
register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)];
register xPSCreateContextReq *req;
xPSCreateContextReply rep;
ContextXID cxid;
XStandardColormap defColorcube, defGrayramp;
XStandardColormap *requestCube, *requestRamp;
int index;
XDPSLIOProcs *call;
if (secure && version[dpyix] < DPSPROTO_V09)
return(None);
index = ((grayRamp == DefaultStdCMap) ? 0 : 1) +
((colorCube == DefaultStdCMap) ? 0 : 2);
switch (index)
{
default:
case 0:
XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw,
&defColorcube, &defGrayramp);
requestCube = &defColorcube;
requestRamp = &defGrayramp;
break;
case 1:
XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw,
&defColorcube, (XStandardColormap *) NULL);
requestCube = &defColorcube;
requestRamp = grayRamp;
break;
case 2:
XDPSGetDefaultColorMaps(xdpy, (Screen *) NULL, draw,
(XStandardColormap *) NULL, &defGrayramp);
requestCube = colorCube;
requestRamp = &defGrayramp;
break;
case 3:
requestCube = colorCube;
requestRamp = grayRamp;
break;
}
if (gc != NULL)
XDPSLFlushGC(xdpy, gc);
if (dpy != xdpy)
{
int syncMask = displayFlags[dpyix].syncMask;
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 (rep.cpsid && xdpy != dpy && gc != NULL)
{
DPSCAPInitGC(xdpy, dpy, gc);
}
SyncHandle();
if (dpy != xdpy)
LastXRequest[dpyix] = XNextRequest(xdpy)-1;
return cxid;
}
SpaceXID
XDPSLCreateSpace(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;
}
#define COALESCEGIVEINPUT
void
XDPSLGiveInput(Display *xdpy, ContextXID cxid, char *data, int length)
{
int dpyix;
register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)];
register xPSGiveInputReq *req;
Bool didFlush = False;
if (dpy != xdpy)
{
register int syncMask = displayFlags[dpyix].syncMask;
if (syncMask & DPSCAP_SYNCMASK_RECONCILE)
{
XDPSLReconcileRequests(xdpy, cxid);
didFlush = True;
}
if (gTotalPaused && DPSCAPResumeContext(xdpy, cxid))
{
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
{
int flushOnce = 1;
int maxedOutLen = xdpy->max_request_size - sizeof(xPSGiveInputReq) - 4;
int nunits;
nunits = maxedOutLen;
do {
if (length < maxedOutLen)
nunits = length;
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);
}
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(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;
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();
if (dpy != xdpy)
{
XDPSLSync(xdpy);
LastXRequest[dpyix] = XNextRequest(xdpy)-1;
}
return (int) rep.status;
}
void
XDPSLDestroySpace(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;
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(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;
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(
Display *xdpy,
ContextXID cxid,
int ntype)
{
int dpyix;
register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)];
register xPSNotifyContextReq *req;
if (dpy != xdpy)
{
register int syncMask = displayFlags[dpyix].syncMask;
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);
}
UnlockDisplay(dpy);
SyncHandle();
if (dpy != xdpy)
{
if (ntype == PSKILL)
XDPSLCleanContext(xdpy, cxid);
LastXRequest[dpyix] = XNextRequest(xdpy)-1;
}
}
ContextXID
XDPSLCreateContextFromID(
Display *xdpy,
ContextPSID cpsid,
SpaceXID *sxid)
{
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;
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);
}
Status
XDPSLIDFromContext(
Display *xdpy,
ContextPSID cpsid,
ContextXID *cxid,
SpaceXID *sxid)
{
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;
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(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;
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(
Display *xdpy,
ContextXID cxid,
unsigned int enableMask,
unsigned int disableMask,
unsigned int nextMask)
{
int dpyix;
register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)];
register xPSSetStatusMaskReq *req;
if (dpy != xdpy)
{
register int syncMask = displayFlags[dpyix].syncMask;
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
void
_XReadPad (Display *dpy, char *data, 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
void
XDPSLNotifyWhenReady(
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;
}
if (dpy != xdpy)
{
register int syncMask = displayFlags[dpyix].syncMask;
if (syncMask & DPSCAP_SYNCMASK_RECONCILE)
XDPSLReconcileRequests(xdpy, cxid);
if (gTotalPaused && DPSCAPResumeContext(xdpy, cxid))
{
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(Display *dpy, int ecode)
{
XExtCodes *c = XDPSLGetCodes(dpy);
if (c == NULL)
return not_pserror;
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);
}
}
void
XDPSLSetVersion(Display *dpy, unsigned ver)
{
version[DPY_NUMBER(dpy)] = ver;
}
void
XDPSLSetCodes(Display *dpy, XExtCodes *codes)
{
Codes[DPY_NUMBER(dpy)] = codes;
}
Display *
XDPSLGetShunt(Display *dpy_in)
{
return(ShuntMap[DPY_NUMBER(dpy_in)]);
}
void
XDPSLSetShunt(Display *dpy_in, Display *dpy_out)
{
ShuntMap[DPY_NUMBER(dpy_in)] = dpy_out;
}
int
XDPSLGetSyncMask(Display *dpy)
{
return (int)displayFlags[DPY_NUMBER(dpy)].syncMask;
}
void
XDPSLSetSyncMask(Display *dpy, int mask)
{
displayFlags[DPY_NUMBER(dpy)].syncMask = (char)mask;
gForceFlush = (mask & DPSCAP_SYNCMASK_RECONCILE);
}
void
XDPSLFlush(Display *xdpy)
{
register Display *dpy = ShuntMap[DPY_NUMBER(xdpy)];
_XFlush(xdpy);
if (dpy != xdpy)
N_XFlush(dpy);
}
void
XDPSLSyncGCClip(Display *xdpy, GC gc)
{
register unsigned long oldDirty;
register int dpyix;
register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)];
oldDirty = gc->dirty;
gc->dirty = (GCClipXOrigin|GCClipYOrigin);
XDPSLFlushGC(xdpy, gc);
gc->dirty = oldDirty;
if (dpy == xdpy || gNXSyncGCMode != 1)
{
if (GCFlushMode[dpyix] == XDPSNX_GC_UPDATES_FAST
|| dpy == xdpy)
XDPSLSync(xdpy);
}
}
#ifdef VMS
void
XDPSLSetDisplay(Display *dpy)
{
dpys[DPY_NUMBER(dpy)] = dpy;
}
#endif
char *
XDPSLSetAgentName(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(Display *dpy)
{
if (dpy == NULL) return;
ClientMsgProc[DPY_NUMBER(dpy)] = XESetWireToEvent(
dpy,
ClientMessage,
DPSCAPClientMessageProc);
}
void
XDPSLSetAfterProc(Display *xdpy)
{
if (xdpy == NULL) return;
AfterProcs[DPY_NUMBER(xdpy)] = (GenericProcPtrReturnsInt)
XSetAfterFunction(xdpy, DPSCAPAfterProc);
}
CSDPSFakeEventTypes
XDPSLGetCSDPSFakeEventType(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(
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);
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:
{
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);
}
void
XDPSLGetCSDPSStatus(
Display *xdpy,
XEvent *event,
void **ret_ctxt,
int *ret_status)
{
register DPSCAPStatusEvent *sev;
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(
Display *xdpy,
XEvent *event,
void **ret_ctxt,
int *ret_val)
{
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(
Display *xdpy,
ContextXID cxid,
unsigned int ntype,
unsigned int data,
unsigned int extra)
{
int dpyix;
register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)];
register xCAPNotifyReq *req;
if (dpy == xdpy) return;
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(Display *xdpy)
{
register Display *dpy = ShuntMap[DPY_NUMBER(xdpy)];
if (dpy == xdpy)
{
XSync(dpy, False);
}
else
{
XEvent event;
DPSCAPData my;
XExtData *extData;
XExtCodes *codes = Codes[DPY_NUMBER(xdpy)];
if (codes == NULL)
return;
extData = XFindOnExtensionList(
CSDPSHeadOfDpyExt(xdpy),
codes->extension);
if (!extData)
return;
my = (DPSCAPData) extData->private_data;
my->saveseq = XNextRequest(dpy)-1;
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
XIfEvent(xdpy, &event, WaitForSyncProc, (char *) my);
#ifdef XXX
fprintf(stderr, "received.\n");
#endif
}
}
void
XDPSLReconcileRequests(Display *xdpy, ContextXID cxid)
{
int dpyix;
unsigned int seqnum;
register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)];
if (dpy == xdpy)
return;
if (LastXRequest[dpyix] == XNextRequest(xdpy)-1)
{
if (gAutoFlush)
N_XFlush(dpy);
return;
}
else
seqnum = DPSCAPSetPause(xdpy, cxid);
XDPSLCAPNotify(xdpy, cxid, DPSCAPNOTE_PAUSE, seqnum, 0);
}
Status
XDPSLSetAgentArg(Display *xdpy, int arg, int val)
{
int dpyix;
register Display *dpy = ShuntMap[dpyix = DPY_NUMBER(xdpy)];
CARD32 capArg;
register xCAPSetArgReq *req;
if (dpy == xdpy)
return(Success);
if (dpy)
{
int syncMask = displayFlags[dpyix].syncMask;
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;
{
register DPSCAPPausedContextData *slot;
int dpyix = DPY_NUMBER(xdpy);
for (slot = PausedPerDisplay[dpyix]; slot; slot = PausedPerDisplay[dpyix])
{
PausedPerDisplay[dpyix] = slot->next;
Xfree(slot);
}
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;
{
register DPSCAPPausedContextData *slot, *prev;
int dpyix = DPY_NUMBER(xdpy);
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;
}
}
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;
}
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);
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();
}
FlushGC(xdpy, gc);
XDPSLFlush(xdpy);
}
static Status
DPSCAPClientMessageProc(
Display *dpy,
XEvent *re,
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)
{
XExtData *extData = XFindOnExtensionList(
CSDPSHeadOfDpyExt(dpy),
codes->extension);
DPSCAPData my;
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;
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);
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;
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;
event->u.clientMessage.u.l.type = my->typeNoop;
return(_XError(dpy, e));
}
else if (event->u.clientMessage.u.l.type == my->typePSReady)
{
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);
}
}
pass_the_buck:
return(oldProc(dpy, re, event));
}
static void
DPSCAPInitGC(Display *dpy, Display *agent, GC gc)
{
XGCValues values;
unsigned long valuemask = DPSGCBITS & ~(GCClipMask);
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);
}
static Bool
WaitForSyncProc(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] == (long) my->saveseq) {
return(True);
} else {
return(False);
}
}
static int
DPSCAPAfterProc(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(Display *xdpy, ContextXID cxid)
{
register DPSCAPPausedContextData *slot;
int dpyix;
unsigned int ret;
slot = PausedPerDisplay[dpyix = DPY_NUMBER(xdpy)];
if (!slot)
{
slot = (DPSCAPPausedContextData *)
Xcalloc(1, sizeof(DPSCAPPausedContextData));
PausedPerDisplay[dpyix] = slot;
goto common_code;
}
while (1)
if (slot->cxid == cxid)
{
if (!slot->paused)
{
slot->paused = True;
++gTotalPaused;
}
ret = ++slot->seqnum;
goto test_ret;
}
else if (slot->next) slot = slot->next;
else break;
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(Display *xdpy, ContextXID cxid)
{
register DPSCAPPausedContextData *slot;
int dpyix = DPY_NUMBER(xdpy);
for (slot = PausedPerDisplay[dpyix]; slot; slot = slot->next)
if (slot->cxid == cxid && slot->paused)
{
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);
slot->paused = False;
--gTotalPaused;
return(True);
}
return(False);
}