diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:57 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:57 +0000 |
commit | 9508a382f8a9f241dab097d921b6d290c1c3a776 (patch) | |
tree | fa456480bae7040c3f971a70b390f2d091c680b5 /XTrap | |
parent | ded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff) |
Initial revision
Diffstat (limited to 'XTrap')
-rw-r--r-- | XTrap/xtrapddmi.c | 184 | ||||
-rw-r--r-- | XTrap/xtrapdi.c | 2147 | ||||
-rw-r--r-- | XTrap/xtrapdiswp.c | 1006 | ||||
-rw-r--r-- | XTrap/xtrapditbl.c | 238 |
4 files changed, 3575 insertions, 0 deletions
diff --git a/XTrap/xtrapddmi.c b/XTrap/xtrapddmi.c new file mode 100644 index 000000000..170726bff --- /dev/null +++ b/XTrap/xtrapddmi.c @@ -0,0 +1,184 @@ +/* $XFree86: xc/programs/Xserver/XTrap/xtrapddmi.c,v 1.2 2002/01/23 03:31:39 dawes Exp $ */ +/***************************************************************************** +Copyright 1987, 1988, 1989, 1990, 1991 by Digital Equipment Corp., Maynard, MA + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*****************************************************************************/ +/* + * ABSTRACT: + * + * This module is the platform-specific but conditionally independent + * code for the XTrap extension (usually I/O or platform setup). + * This is shared code and is subject to change only by team approval. + * + * CONTRIBUTORS: + * + * Dick Annicchiarico + * Robert Chesler + * Gene Durso + * Marc Evans + * Alan Jamison + * Mark Henry + * Ken Miller + * + */ + +#ifndef EXTMODULE +#include <errno.h> +#include <X11/Xos.h> +#ifdef PC +# include "fcntl.h" +# include "io.h" +# define O_NDELAY 0L +#endif +#else +#include "xf86_ansic.h" +#endif + +#define NEED_REPLIES +#define NEED_EVENTS +#include <X11/X.h> /* From library include environment */ +#include "input.h" /* From server include env. (must be before Xlib.h!) */ +#ifdef PC +# include "scrintst.h" /* Screen struct */ +# include "extnsist.h" +#else +# include "extnsionst.h" /* Server ExtensionEntry definitions */ +# include "scrnintstr.h" /* Screen struct */ +#endif + +#include <X11/extensions/xtrapdi.h> +#include <X11/extensions/xtrapddmi.h> +#include <X11/extensions/xtrapproto.h> + +extern int XETrapErrorBase; +extern xXTrapGetAvailReply XETrap_avail; +extern DevicePtr XETrapKbdDev; +extern DevicePtr XETrapPtrDev; + +/* + * DESCRIPTION: + * + * This function performs the platform specific setup for server + * extension implementations. + */ +void XETrapPlatformSetup() +{ +} + + +#if !defined _XINPUT +/* + * DESCRIPTION: + * + * This routine processes the simulation of some input event. + * + */ +int XETrapSimulateXEvent(register xXTrapInputReq *request, + register ClientPtr client) +{ + ScreenPtr pScr = NULL; + int status = Success; + xEvent xev; + register int x = request->input.x; + register int y = request->input.y; + DevicePtr keydev = LookupKeyboardDevice(); + DevicePtr ptrdev = LookupPointerDevice(); + + if (request->input.screen < screenInfo.numScreens) + { + pScr = screenInfo.screens[request->input.screen]; + } + else + { /* Trying to play bogus events to this WS! */ +#ifdef VERBOSE + ErrorF("%s: Trying to send events to screen %d!\n", XTrapExtName, + request->input.screen); +#endif + status = XETrapErrorBase + BadScreen; + } + /* Fill in the event structure with the information + * Note: root, event, child, eventX, eventY, state, and sameScreen + * are all updated by FixUpEventFromWindow() when the events + * are delivered via DeliverDeviceEvents() or whatever. XTrap + * needs to only concern itself with type, detail, time, rootX, + * and rootY. + */ + if (status == Success) + { + xev.u.u.type = request->input.type; + xev.u.u.detail = request->input.detail; + xev.u.keyButtonPointer.time = GetTimeInMillis(); + xev.u.keyButtonPointer.rootX = x; + xev.u.keyButtonPointer.rootY = y; + + if (request->input.type == MotionNotify) + { /* Set new cursor position on screen */ + XETrap_avail.data.cur_x = x; + XETrap_avail.data.cur_y = y; + NewCurrentScreen (pScr, x, y); /* fix from amnonc@mercury.co.il */ + if (!(*pScr->SetCursorPosition)(pScr, x, y, xFalse)) + { + status = BadImplementation; + } + } + } + if (status == Success) + { + switch(request->input.type) + { /* Now process the event appropriately */ + case KeyPress: + case KeyRelease: + (*XETrapKbdDev->realInputProc)(&xev,(DeviceIntPtr)keydev, 1L); + break; + case MotionNotify: + case ButtonPress: + case ButtonRelease: + (*XETrapPtrDev->realInputProc)(&xev,(DeviceIntPtr)ptrdev, 1L); + break; + default: + status = BadValue; + break; + } + } + return(status); +} +#endif /* _XINPUT */ + +#if defined vms && !defined LINKED_IN +/* Used by swapping code not visible from VMS (from main.c) */ +#ifndef BLADE +void +NotImplemented() +{ + FatalError("Not implemented"); +} +#endif + +int +#ifdef __STDC__ +ProcBadRequest( ClientPtr client) +#else +ProcBadRequest(client) + ClientPtr client; +#endif +{ + return (BadRequest); +} + +#endif /* vms && ! LINKED_IN */ diff --git a/XTrap/xtrapdi.c b/XTrap/xtrapdi.c new file mode 100644 index 000000000..6aae14be2 --- /dev/null +++ b/XTrap/xtrapdi.c @@ -0,0 +1,2147 @@ +/* $XFree86: xc/programs/Xserver/XTrap/xtrapdi.c,v 1.5 2002/09/18 17:11:47 tsi Exp $ */ +/***************************************************************************** +Copyright 1987, 1988, 1989, 1990, 1991 by Digital Equipment Corp., Maynard, MA +X11R6 Changes Copyright (c) 1994 by Robert Chesler of Absol-Puter, Hudson, NH. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL AND ABSOL-PUTER DISCLAIM ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL DIGITAL OR ABSOL-PUTER BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +*****************************************************************************/ +/* + * ABSTRACT: + * + * This module is the main module for extension initialization and setup. + * It is called by the server and by clients using the extension. + * This is shared code and is subject to change only by team approval. + * + * CONTRIBUTORS: + * + * Dick Annicchiarico + * Robert Chesler + * Gene Durso + * Marc Evans + * Alan Jamison + * Mark Henry + * Ken Miller + * + * CHANGES: + * + * Robert Chesler - grab-impreviousness patch to improve grab behavior + * Robert Chesler - add client arg to swapping routines for X11R6 port + * + */ + +/*-----------------* + * Include Files * + *-----------------*/ + +#define NEED_REPLIES +#define NEED_EVENTS +#ifndef EXTMODULE +#include <stdio.h> +#include <errno.h> +#include <X11/Xos.h> +#else +#include "xf86_ansic.h" +#endif +#include <X11/X.h> +#include <X11/Xproto.h> +#include "input.h" /* Server DevicePtr definitions */ +#include "misc.h" /* Server swapping macros */ +#include "dixstruct.h" /* Server ClientRec definitions */ +#include "resource.h" /* Used with the MakeAtom call */ +#ifdef PC +# include "scrintst.h" /* Screen struct */ +# include "extnsist.h" +#else +# include "extnsionst.h" /* Server ExtensionEntry definitions */ +# include "scrnintstr.h" /* Screen struct */ +#endif +#include "pixmapstr.h" /* DrawableRec */ +#include "windowstr.h" /* Drawable Lookup structures */ +#include <X11/extensions/xtrapdi.h> +#include <X11/extensions/xtrapddmi.h> +#include <X11/extensions/xtrapproto.h> +#include "colormapst.h" +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#include "cursor.h" +#endif + + +/*----------------------------* + * Global Data Declarations * + *----------------------------*/ + +DevicePtr XETrapKbdDev = NULL; +DevicePtr XETrapPtrDev = NULL; +int XETrapErrorBase = 0L; +xXTrapGetAvailReply XETrap_avail; /* What's available to clients */ + +globalref int_function XETrapDispatchVector[10L]; /* Vector of XTrap Rtns */ +globalref int_function XETSwDispatchVector[10L]; /* Swapped XTrap Rtns */ + +globalref int_function XETrapProcVector[256L]; /* The "shadowed" ProcVector */ + /* The "real" EventVector (XTrap creates it till events + * truly become vectored + */ +#ifndef VECTORED_EVENTS +globalref int_function EventProcVector[XETrapCoreEvents]; +#else +extern WindowPtr GetCurrentRootWindow(); +globalref int_function EventProcVector[128L]; +#endif +static int_function keybd_process_inp = NULL; /* Used for VECTORED_EVENTS */ + /* The "shadowed" Event Vector */ +globalref int_function XETrapEventProcVector[XETrapCoreEvents]; + +globalref void_function XETSwProcVector[256L];/* Vector of Req swapping rtns */ + +/* This macro returns a true/false indicator based on whether it changes the + * environment state bits local to the server extension. This is based on the + * idea that if a valid flag is set and the corresponding data bit is not in + * the same state as desired, then true is returned, otherwise false is + * returned. + */ +#define _CheckChangeBit(valid,data,local,bit) \ + (BitIsFalse(valid,bit) ? 0L : \ + (((BitIsTrue(data,bit) && BitIsTrue(local,bit)) || \ + (BitIsFalse(data,bit) && BitIsFalse(local,bit))) ? 0L : \ + (BitToggle(local,bit), 1L))) + +/* This macro is designed to return the number of elements in an + * automatically allocated array. + */ +#ifndef ASIZE +#define ASIZE(array) (sizeof(array)/sizeof(array[0L])) +#endif + +/* This macro is designed to return the number of long words beyond + * XETrapMinRepSize contained in a data structure. + */ +#ifndef XEXTRA +#define XEXTRA(s) \ + ((sizeof(s)+(sizeof(CARD32)-1L)-XETrapMinRepSize)/sizeof(CARD32)) +#endif + +/* Static Declarations known to XTrap Only + * All XTrap clients refer to these single copies! + */ +/* This carries all of the information XTrap uses for internal information */ +static XETrapEnv *XETenv[MAXCLIENTS] = {NULL}; +#ifndef RESTYPE +#define RESTYPE unsigned long +#endif +static RESTYPE XETrapClass = 0L; /* Resource class for this extension */ +static RESTYPE XETrapType = 0L; /* Resource type for this extension */ +static Bool gate_closed = False; /* The global "gatekeeper" */ +static Bool key_ignore = False; /* The global "keymaster" */ +static Bool ignore_grabs = False; +static CARD8 next_key = XEKeyIsClear; /* Echo, Clear, or Other */ +static INT16 current_screen = -1L; /* Current screen for events */ +static INT16 vectored_requests[256L] = {0L}; /* cnt of vectoring clients */ +static INT16 vectored_events[KeyPress+MotionNotify] = {0L}; +typedef struct _client_list +{ + struct _client_list *next; + ClientPtr client; +} ClientList; +static ClientList io_clients; /* Linked-list of clients currently doing I/O */ +static ClientList stats_clients; /* Linked-list of clients collecting stats */ +static ClientList cmd_clients; /* Linked-list of clients using command key */ + +/*----------------------------* + * Forward Declarations + *----------------------------*/ +static void _SwapProc (int (**f1 )(), int (**f2 )()); +static void sXETrapEvent (xETrapDataEvent *from , xETrapDataEvent *to ); +static int add_accelerator_node (ClientPtr client , ClientList *accel ); +static void remove_accelerator_node (ClientPtr client , ClientList *accel ); +static void update_protocol (xXTrapGetReq *reqptr , ClientPtr client ); +#ifdef COLOR_REPLIES +static void GetSendColorRep (ClientPtr client , xResourceReq *req ); +static void GetSendNamedColorRep (ClientPtr client , xResourceReq *req ); +static void GetSendColorCellsRep (ClientPtr client , xResourceReq *req ); +static void GetSendColorPlanesRep (ClientPtr client , xResourceReq *req ); +#endif + +/* + * DESCRIPTION: + * + * This routine is called by the server when a given client + * goes away (as identified by the first argument). All + * memory allocations, misc. values specific to a given + * client would be reset here. + * + */ +int XETrapDestroyEnv(pointer value, XID id) +{ + xXTrapReq request; + XETrapEnv *penv = XETenv[(long)value]; + + XETrapReset(&request,penv->client); + /* Free any memory malloc'd for a particular client here */ + /* In case stop I/O wasn't received for this client */ + if (penv->stats) + { /* Remove from client accelerator list */ + remove_accelerator_node(penv->client, &stats_clients); + Xfree(penv->stats); /* Free the stats buckets */ + } + if (cmd_clients.next == NULL) + { /* No more command key clients! Let's reset the gate */ + gate_closed = False; + key_ignore = False; + next_key = XEKeyIsClear; + } + + + current_screen = -1L; /* Invalidate current screen */ + +#ifdef VERBOSE + ErrorF("%s: Client '%d' Disconnected\n", XTrapExtName, + penv->client->index); +#endif + + Xfree(penv); + XETenv[(long)value] = NULL; + + return 0; +} + +/* + * DESCRIPTION: + * + * This routine is called by the server when the last client + * (the session manager in most cases) goes away. This is server + * reset. When the server comes back up, this extension will not + * be loaded unless this routine makes the proper arrangements. + * + * The real concern here is to unload the extension + * and possibly make arragements to be called upon + * server restart. + * + */ +void XETrapCloseDown(ExtensionEntry *extEntry) +{ + long i; + + for (i=0L; i<MAXCLIENTS; i++) + { + if (XETenv[i] != NULL) + { + XETrapDestroyEnv((pointer)i,0L); + } + } + ignore_grabs = False; + return; +} + +/* + * + * DESCRIPTION: + * + * This routine has been created because of the initialization + * order that X uses, such that extensions are initialized before + * devices. This means that this extension must perform a second + * level of initialization to obtain the device references at some + * point after they have been initialized. It is assumed that when + * a client establishes communication with the extension that the + * devices havae been initialized, and therefore this function can + * obtain the information it needs. + * + * In obtaining the information, this function also places its own + * functions in place of the *standard* functions. The original + * functions are retained for vectoring purposes. + */ + +Bool XETrapRedirectDevices() +{ + Bool retval = True; + + /* Do we need to redirect the keyboard device? */ + if (XETrapKbdDev == NULL) + { + if ((XETrapKbdDev = LookupKeyboardDevice()) == NULL) + { + retval = False; + } + else + { + EventProcVector[KeyPress] = + (int_function)XETrapKbdDev->realInputProc; + EventProcVector[KeyRelease] = + (int_function)XETrapKbdDev->realInputProc; + } +#ifdef VECTORED_EVENTS + keybd_process_inp = EventProcVector[KeyPress]; + EventProcVector[KeyPress] = EventProcVector[KeyRelease] = NULL; + XETrapEventProcVector[KeyPress] = XETrapEventVector; + XETrapEventProcVector[KeyRelease] = XETrapEventVector; +#else /* !VECTORED_EVENTS */ + XETrapEventProcVector[KeyPress] = XETrapKeyboard; + XETrapEventProcVector[KeyRelease] = XETrapKeyboard; +#endif /* !VECTORED_EVENTS */ + } + /* Do we need to redirect the pointer device? */ +#ifndef VECTORED_EVENTS + if (XETrapPtrDev == NULL) + { + if ((XETrapPtrDev = LookupPointerDevice()) == 0L) + { + retval = False; + } + else + { + EventProcVector[ButtonPress] = + (int_function)XETrapPtrDev->realInputProc; + EventProcVector[ButtonRelease] = + (int_function)XETrapPtrDev->realInputProc; + EventProcVector[MotionNotify] = + (int_function)XETrapPtrDev->realInputProc; + } + XETrapEventProcVector[ButtonPress] = XETrapPointer; + XETrapEventProcVector[ButtonRelease] = XETrapPointer; + XETrapEventProcVector[MotionNotify] = XETrapPointer; + } +#endif /* !VECTORED_EVENTS */ + return(retval); +} + +/* + * + * DESCRIPTION: + * + * This routine is the main entry point for the Xtrap extension. It is + * called by the server to inititalize the Xtrap extension. Once the + * extension is initialized, life is controlled by the XtrapDispatch + * routine by the requests it will handle. + * + * Initializes all the XTrap data structures with the proper + * addresses of defined routines that will help control the extension. + * It is vital that the extension state be kept accurate so that only + * one call to this routine be made. + * + */ + +void DEC_XTRAPInit() +{ + register ExtensionEntry *extEntry; + unsigned int i; + Atom a; + + /* Make the extension known to the server. Must be done every time + * DEC_XTRAPInit is called, else server will think it failed. + */ + if ((extEntry = AddExtension(XTrapExtName,XETrapNumEvents, + XETrapNumErrors,XETrapDispatch,sXETrapDispatch,XETrapCloseDown + ,StandardMinorOpcode)) == NULL) + { + ErrorF("%s: AddExtension Failed!\n", XTrapExtName); + return; + } +#ifdef VERBOSE + ErrorF("%s: AddExtension assigned Major Opcode '%d'\n", + XTrapExtName, extEntry->base); +#endif + XETrap_avail.data.major_opcode = extEntry->base; + XETrapErrorBase = extEntry->errorBase; + XETrap_avail.data.event_base = extEntry->eventBase; + + /* Set up our swapped reply vector */ + ReplySwapVector[XETrap_avail.data.major_opcode] = + (void_function) sReplyXTrapDispatch; + + /* Set up our swapped event vector */ + EventSwapVector[extEntry->eventBase + XETrapData] = + (EventSwapPtr) sXETrapEvent; + + /* make an atom saying that the extension is present. The + * adding of the resource occurs during XETrapCreateEnv(). + */ + if ((a = MakeAtom(XTrapExtName,strlen(XTrapExtName),1L)) == None || + (XETrapType = CreateNewResourceType(XETrapDestroyEnv)) == 0L) + { + ErrorF("%s: Setup can't create new resource type (%d,%d,%d)\n", + XTrapExtName, a,XETrapClass,XETrapType); + return; + } + /* initialize the GetAvailable info reply here */ + XETrap_avail.hdr.type = X_Reply; + XETrap_avail.hdr.length = XEXTRA(xXTrapGetAvailReply); + XETrap_avail.data.xtrap_release = XETrapRelease; + XETrap_avail.data.xtrap_version = XETrapVersion; + XETrap_avail.data.xtrap_revision = XETrapRevision; + XETrap_avail.data.pf_ident = XETrapPlatform; + XETrap_avail.data.max_pkt_size = 0xFFFF; /* very large number */ + for (i=0L; i<ASIZE(XETrap_avail.data.valid); i++) + { + XETrap_avail.data.valid[i] = 0L; /* Clear bits initially */ + } + BitTrue(XETrap_avail.data.valid,XETrapTimestamp); + BitTrue(XETrap_avail.data.valid,XETrapCmd); + BitTrue(XETrap_avail.data.valid,XETrapCmdKeyMod); + BitTrue(XETrap_avail.data.valid,XETrapRequest); + BitTrue(XETrap_avail.data.valid,XETrapEvent); + BitTrue(XETrap_avail.data.valid,XETrapMaxPacket); + BitTrue(XETrap_avail.data.valid,XETrapStatistics); + BitTrue(XETrap_avail.data.valid,XETrapWinXY); + /* Not yet implemented */ + BitFalse(XETrap_avail.data.valid,XETrapCursor); +#ifndef _XINPUT + BitFalse(XETrap_avail.data.valid,XETrapXInput); +#else + BitTrue(XETrap_avail.data.valid,XETrapXInput); +#endif +#ifndef VECTORED_EVENTS + BitFalse(XETrap_avail.data.valid,XETrapVectorEvents); +#else + BitTrue(XETrap_avail.data.valid,XETrapVectorEvents); +#endif /* VECTORED_EVENTS */ +#ifndef COLOR_REPLIES + BitFalse(XETrap_avail.data.valid,XETrapColorReplies); +#else + BitTrue(XETrap_avail.data.valid,XETrapColorReplies); +#endif /* COLOR_REPLIES */ + BitTrue(XETrap_avail.data.valid,XETrapGrabServer); + /* initialize multi-client accelerator lists */ + io_clients.next = NULL; + stats_clients.next = NULL; + cmd_clients.next = NULL; + for (i=0L; i<256L; i++) + { + vectored_requests[i] = 0L; + } + for (i=KeyPress; i<=MotionNotify; i++) + { + vectored_events[i] = 0L; + } + gate_closed = False; + key_ignore = False; + next_key = XEKeyIsClear; + + XETrapPlatformSetup(); + /* Initialize any local memory we use */ + for (i=0L; i<ASIZE(EventProcVector); i++) + { + EventProcVector[i] = NULL; +#ifndef VECTORED_EVENTS + XETrapEventProcVector[i] = NULL; +#else + XETrapEventProcVector[i] = XETrapEventVector; +#endif + } + XETrapKbdDev = NULL; + XETrapPtrDev = NULL; + for (i=0L; i<ASIZE(XETrapProcVector); i++) + { + XETrapProcVector[i] = XETrapRequestVector; + } + for (i=128L; i<=255L; i++) + { /* Extension "swapped" requests are not implemented */ + XETSwProcVector[i] = NotImplemented; + } +#ifdef VERBOSE + ErrorF("%s: Vers. %d.%d-%d successfully loaded\n", XTrapExtName, + XETrap_avail.data.xtrap_release, + XETrap_avail.data.xtrap_version, + XETrap_avail.data.xtrap_revision); +#endif + + return; +} + +/* + * DESCRIPTION: + * + * This procedure is called upon dispatch to allocate an + * environment structure for a new XTrap client. The XETenv[] + * entry is allocated and initialized with default values. + * XETrapDestroyEnv() is responsible for deallocating this memory + * upon client termination. + * + * Note: the status of this routine is returned to the caller of + * the Dispatch routine which will in turn SendErrorToClient if + * necessary. + * + */ + +int XETrapCreateEnv(ClientPtr client) +{ + XETrapEnv *penv = NULL; + int status = Success; + + if (client->index > MAXCLIENTS) + { + status = BadImplementation; + } + else if ((XETenv[client->index] = (XETrapEnv *)Xcalloc(sizeof(XETrapEnv))) + == NULL) + { + status = BadAlloc; + } + if (status == Success) + { + penv = XETenv[client->index]; + penv->client = client; + penv->protocol = 31; /* default to backwards compatibility */ + /* prep for client's departure (for memory dealloc, cleanup) */ + AddResource(FakeClientID(client->index),XETrapType, + (pointer)(long)(client->index)); + if (XETrapRedirectDevices() == False) + { + status = XETrapErrorBase + BadDevices; + } + /* Initialize the current state */ + if (status == Success) + { + status = XETrapReset(NULL, penv->client); + } + } + + current_screen = -1L; /* Invalidate current screen */ + +#ifdef VERBOSE + if (status == Success) + { + ErrorF("%s: Client '%d' Connection Accepted\n", XTrapExtName, + penv->client->index); + } +#endif + + return(status); +} + +/* + * DESCRIPTION: + * + * This procedure is defined for the call to AddExtension() + * in which it is expected to be a parameter of the call. + * + * This routine will be called by the server dispatcher + * when a client makes a request that is handled + * by the extension and the byte ordering of the client is the + * SAME as that of the extension. + * + * Note: the status of the requests is returned to the caller of + * the Dispatch routine which will in turn SendErrorToClient if + * necessary. + */ + +int XETrapDispatch(ClientPtr client) +{ + + REQUEST(xXTrapReq); + register int status = Success; + + REQUEST_AT_LEAST_SIZE(xXTrapReq); + + /* Have we seen this client before? */ + if (XETenv[client->index] == NULL) + { + status = XETrapCreateEnv(client); + } + /* Do we have a valid request? */ + if (status == Success) + { + if (stuff->minor_opcode < ASIZE(XETrapDispatchVector)) + { + /* Then vector to the pointed to function */ + status = + (*(XETrapDispatchVector[stuff->minor_opcode]))(stuff,client); + } + else + { + status = BadRequest; + } + } + return(status); +} + +/* + * DESCRIPTION: + * + * This procedure is defined for the call to AddExtension() + * in which it is expected to be a parameter of the call. + * + * This routine would ordinarily be called by the server + * dispatcher when a client makes a request that is handled + * by the extension and the byte ordering of the client is + * DIFFERENT than that of the extension. + */ + +int sXETrapDispatch(ClientPtr client) +{ + + REQUEST(xXTrapReq); + register int status = Success; + + REQUEST_AT_LEAST_SIZE(xXTrapReq); + + /* Have we seen this client before? */ + if (XETenv[client->index] == NULL) + { + status = XETrapCreateEnv(client); + } + /* Do we have a valid request? */ + if (status == Success) + { + if (stuff->minor_opcode < ASIZE(XETSwDispatchVector)) + { + /* Then vector to the pointed to function */ + status = + (*(XETSwDispatchVector[stuff->minor_opcode]))(stuff,client); + } + else + { + status = BadRequest; + } + } + return(status); +} + +/* + * DESCRIPTION: + * + * This routine will place the extension in a steady and known + * state. Any current state will be reset. This is called either + * by a client request (dispatched) or when a new client environment + * is created. + * + */ +int XETrapReset(xXTrapReq *request, ClientPtr client) +{ + static xXTrapConfigReq DummyReq; + register int i; + register int status = Success; + XETrapEnv *penv = XETenv[client->index]; + + /* in case any i/o's pending */ + (void)XETrapStopTrap((xXTrapReq *)NULL, client); + penv->cur.hdr.type = X_Reply; + penv->cur.hdr.length = XEXTRA(xXTrapGetCurReply); + /* Fill in a dummy config request to clear all elements */ + for (i=0L; i<ASIZE(DummyReq.config_flags_valid); i++) + { + DummyReq.config_flags_valid[i] = 0xFFL; /* set all the valid flags */ + DummyReq.config_flags_data[i] = 0L; /* clear all data flags */ + } + /* Don't reset grab server arbitrarily, it must be explicitly + * de-configured. + */ + BitSet(DummyReq.config_flags_data, XETrapGrabServer, ignore_grabs); + for (i=0L; i< ASIZE(DummyReq.config_flags_req); i++) + { + DummyReq.config_flags_req[i] = 0xFF; /* Clear all protocol requests */ + } + for (i=0L; i< ASIZE(DummyReq.config_flags_event); i++) + { + DummyReq.config_flags_event[i] = 0xFF; /* Clear all protocol events */ + } + /* Call config routine to clear all configurable fields */ + status = XETrapConfig(&DummyReq, client); + /* reset the environment */ + for (i=0L; i<ASIZE(penv->cur.data_state_flags); i++) + { + penv->cur.data_state_flags[i] = 0L; /* Clear all env flags */ + } + penv->cur.data_config_max_pkt_size = XETrap_avail.data.max_pkt_size; + + return(status); +} + +/* + * DESCRIPTION: + * + * This function sends a reply back to the requesting client indicating + * the available states of the extension can be configured for. + */ +int XETrapGetAvailable(xXTrapGetReq *request, ClientPtr client) +{ + XETrapEnv *penv = XETenv[client->index]; + update_protocol(request, client); + /* Initialize the reply as needed */ + XETrap_avail.data.xtrap_protocol = penv->protocol; + XETrap_avail.hdr.detail = XETrap_GetAvailable; + XETrap_avail.hdr.sequenceNumber = client->sequence; + WriteReplyToClient(client, sizeof(xXTrapGetAvailReply), &XETrap_avail); + return(Success); +} + +/* + * DESCRIPTION: + * + * This function sends a reply back to the requesting client indicating + * the current state of the extension. + */ +int XETrapGetCurrent(xXTrapReq *request, ClientPtr client) +{ + XETrapEnv *penv = XETenv[client->index]; + int rep_size = (penv->protocol == 31 ? 284 : sz_xXTrapGetCurReply); + penv->cur.hdr.length = (rep_size - 32L) / SIZEOF(CARD32); + + /* Initialize the reply as needed */ + penv->cur.hdr.detail = XETrap_GetCurrent; + penv->cur.hdr.sequenceNumber = client->sequence; + WriteReplyToClient(client, rep_size, &(penv->cur)); + + return(Success); +} + +/* + * DESCRIPTION: + * + * This function sends a reply back to the requesting client dumping + * statistics (counts) of requests and events. If stat's isn't + * configured, return failure. + */ +int XETrapGetStatistics(xXTrapReq *request, ClientPtr client) +{ + int status = Success; + XETrapEnv *penv = XETenv[client->index]; + + if ((BitIsTrue(penv->cur.data_config_flags_data, XETrapStatistics)) && + (penv->stats)) + { + /* Initialize the reply as needed */ + int rep_size = sizeof(xXTrapGetStatsReply); + penv->stats->detail = XETrap_GetStatistics; + penv->stats->sequenceNumber = client->sequence; + if (penv->protocol == 31) + { + xXTrapGetStatsReply rep_stats; + rep_stats = *penv->stats; +#ifndef VECTORED_EVENTS + rep_size = 1060; +#else + rep_size = 1544; +#endif + rep_stats.length = (rep_size - 32L) / SIZEOF(CARD32); + /* + * Now we need to shift the data *into* the header area + * for bug compatibility. + */ + memcpy(&(rep_stats.pad0),&(penv->stats->data), + sizeof(XETrapGetStatsRep)); + WriteReplyToClient(client, rep_size, &rep_stats); + } + else + { + WriteReplyToClient(client, rep_size, penv->stats); + } + } + else + { + status = XETrapErrorBase + BadStatistics; + } + return(status); +} + +/* + * DESCRIPTION: + * + * This function is dispatched when a client requests the extension to + * be configured in some manner. + */ +int XETrapConfig(xXTrapConfigReq *request, ClientPtr client) +{ + UByteP vflags = request->config_flags_valid; + UByteP dflags = request->config_flags_data; + UByteP req_flags = request->config_flags_req; + UByteP event_flags = request->config_flags_event; + XETrapEnv *penv = XETenv[client->index]; + UByteP bit_flags = penv->cur.data_config_flags_data; + int status = Success; + CARD32 i = 0L; + + /* Check events and swap if desired */ + if (BitIsTrue(vflags,XETrapEvent)) + { /* Loop through all of the events */ + for (i=0L; i<ASIZE(EventProcVector); i++) + { + if (BitIsTrue(event_flags,i) && /* Do we care about this one? */ + (BitValue(dflags,XETrapEvent) ^ /* Exclusive Or */ + (BitValue(penv->cur.data_config_flags_event,i)))) + { /* At this point we *know* there's a change. The + * only question remaining is are there any more + * clients interested in this specific event. If + * so, *don't* swap this process! + */ + if (BitIsTrue(dflags,XETrapEvent)) + { /* Client wants the XTrap rtn */ + if (++(vectored_events[i]) <= 1L) + { /* first client, so do it */ + _SwapProc(&(XETrapEventProcVector[i]), + &(EventProcVector[i])); + } + } + else + { /* Client wants the *real* rtn */ + if (--(vectored_events[i]) <= 0L) + { /* No more clients using, so do it */ + _SwapProc(&(XETrapEventProcVector[i]), + &(EventProcVector[i])); + } + } + switch(i) + { + case KeyPress: /* needed for command key processing */ + case KeyRelease: + XETrapKbdDev->processInputProc = + (void_function)(EventProcVector[i] ? + (void_function)EventProcVector[i] : + (void_function)keybd_process_inp); + XETrapKbdDev->realInputProc = + (void_function)(EventProcVector[i] ? + (void_function)EventProcVector[i] : + (void_function)keybd_process_inp); + break; +#ifndef VECTORED_EVENTS + case ButtonPress: /* hack until events become vectored */ + case ButtonRelease: + case MotionNotify: + XETrapPtrDev->processInputProc = + (void_function)EventProcVector[i]; + XETrapPtrDev->realInputProc = + (void_function)EventProcVector[i]; + break; + default: + status = BadImplementation; + break; +#endif /* !VECTORED_EVENTS */ + } + BitToggle(penv->cur.data_config_flags_event,i); + } + } + } + if ((status == Success) && + (_CheckChangeBit(vflags,dflags,bit_flags,XETrapCmd))) + { + if (BitIsTrue(dflags, XETrapCmd)) + { /* Add accelerator entry to cmd_clients list iff necessary */ + penv->cur.data_config_cmd_key = request->config_cmd_key; + status = add_accelerator_node(penv->client, &cmd_clients); + } + else + { + penv->cur.data_config_cmd_key = 0L; /* default no KeyCode */ + remove_accelerator_node(penv->client, &cmd_clients); + } + } + if ((status == Success) && + (_CheckChangeBit(vflags,dflags,bit_flags,XETrapMaxPacket))) + { + if (BitIsTrue(dflags,XETrapMaxPacket)) + { /* Set size to what's passed in */ + if (request->config_max_pkt_size < XETrapMinPktSize) + { /* Tell them the value is too small */ + status = BadValue; + } + else + { + penv->cur.data_config_max_pkt_size = + request->config_max_pkt_size; + } + } + else + { /* Set it to the default (a *very* big number) */ + penv->cur.data_config_max_pkt_size = 0xFFFF; + } + } + /* If the valid flag is set for requests, then each of the + * requests is swapped if it's different from current state. + */ + if (BitIsTrue(vflags,XETrapRequest) && status == Success) + { /* Loop through all of the core requests */ + for (i=0L; i<ASIZE(XETrapProcVector); i++) + { + if (BitIsTrue(req_flags,i) && /* Do we care about this one? */ + (BitValue(dflags,XETrapRequest) ^ /* Exclusive Or */ + (BitValue(penv->cur.data_config_flags_req,i)))) + { /* At this point we *know* there's a change. The + * only question remaining is are there any more + * clients interested in this specific request. If + * so, *don't* swap this process! + */ + if (BitIsTrue(dflags,XETrapRequest)) + { /* Client wants the XTrap rtn */ + if (++(vectored_requests[i]) <= 1L) + { /* first client, so do it */ + _SwapProc(&(XETrapProcVector[i]), &(ProcVector[i])); + } + } + else + { /* Client wants the *real* rtn */ + if (--(vectored_requests[i]) <= 0L) + { /* No more clients using, so do it */ + _SwapProc(&(XETrapProcVector[i]), &(ProcVector[i])); + } + } + if (status == Success) + { + BitToggle(penv->cur.data_config_flags_req,i); + } + } + } + } + /* Check & Set the boolean flags */ + if (status == Success) + { + _CheckChangeBit(vflags,dflags,bit_flags,XETrapCmdKeyMod); + _CheckChangeBit(vflags,dflags,bit_flags,XETrapTimestamp); + _CheckChangeBit(vflags,dflags,bit_flags,XETrapWinXY); +/* _CheckChangeBit(vflags,dflags,bit_flags,XETrapCursor); */ +#ifdef COLOR_REPLIES + _CheckChangeBit(vflags,dflags,bit_flags,XETrapColorReplies); +#endif /* COLOR_REPLIES */ + if (_CheckChangeBit(vflags,dflags,bit_flags,XETrapGrabServer)) + { /* Let any client uncoditionally set/clear Grabs */ + ignore_grabs = BitValue(dflags, XETrapGrabServer); + } + } + /* The statistics vflag/dflag mechanism is a little different + * from most. The dflag is initially set to 0 to indicate no + * statistics. When a config request comes in to request + * statistics, memory's allocated and the dflag is set. + * Thereafter, whenever a client wants to clear the counters, he + * simply sets the vflag and clears the dflag. Multiple requests + * for statistics configuration are ignored, and the stats memory is + * free'd only when the client disconnects. + */ + if (status == Success) + { + if (_CheckChangeBit(vflags,dflags,bit_flags,XETrapStatistics)) + { + if (BitIsTrue(dflags,XETrapStatistics)) + { /* Do we need to allocate memory? */ + if (penv->stats == NULL && (penv->stats = + (xXTrapGetStatsReply *)Xcalloc(sizeof(xXTrapGetStatsReply))) + != NULL) + { /* Set up the reply header */ + penv->stats->type = X_Reply; + penv->stats->length = XEXTRA(xXTrapGetStatsReply); + /* add accelerator node for stats clients list */ + status = add_accelerator_node(penv->client, &stats_clients); + } + else if (penv->stats == NULL) + { /* No Memory! */ + status = BadAlloc; + } + } + else + { /* Zero out counters */ + (void)memset(penv->stats->data.requests, 0L, + sizeof(penv->stats->data.requests)); + (void)memset(penv->stats->data.events, 0L, + sizeof(penv->stats->data.events)); + /* Re-cock the Stat's flag so that it'll + * sense a change for next zero'ing out + * of the counters. + */ + BitTrue(penv->cur.data_config_flags_data, XETrapStatistics); + } + } + } + return(status); +} + +/* + * DESCRIPTION: + * + * This function sets the XETrapTrapActive bit to indicate that Trapping + * of requests and/or core events to the client may take place. + * + */ +int XETrapStartTrap(xXTrapReq *request, ClientPtr client) +{ + XETrapEnv *penv = XETenv[client->index]; + int status = add_accelerator_node(penv->client, &io_clients); + if (status == Success) + { + BitTrue(penv->cur.data_state_flags, XETrapTrapActive); + } + return(status); +} +/* + * DESCRIPTION: + * + * This function clears the XETrapTrapActive bit to indicate that Trapping + * of requests and/or core events to the client may *not* take place. + * + */ +int XETrapStopTrap(xXTrapReq *request, ClientPtr client) +{ + XETrapEnv *penv = XETenv[client->index]; + + remove_accelerator_node(penv->client, &io_clients); + BitFalse(penv->cur.data_state_flags, XETrapTrapActive); + return(Success); +} + +/* + * DESCRIPTION: + * + * This function sends a reply back to the requesting client indicating + * the specific XTrap version of this extension. + */ +int XETrapGetVersion(xXTrapGetReq *request, ClientPtr client) +{ + xXTrapGetVersReply ver_rep; + XETrapEnv *penv = XETenv[client->index]; + + update_protocol(request,client); /* to agree on protocol version */ + /* Initialize the reply as needed */ + ver_rep.hdr.type = X_Reply; + ver_rep.hdr.detail = XETrap_GetVersion; + ver_rep.hdr.sequenceNumber = client->sequence; + ver_rep.hdr.length = XEXTRA(xXTrapGetVersReply); + ver_rep.data.xtrap_release = XETrap_avail.data.xtrap_release; + ver_rep.data.xtrap_version = XETrap_avail.data.xtrap_version; + ver_rep.data.xtrap_revision = XETrap_avail.data.xtrap_revision; + ver_rep.data.xtrap_protocol = penv->protocol; /* return agreed protocol */ + WriteReplyToClient(client, sizeof(xXTrapGetVersReply), &ver_rep); + return(Success); +} + +/* + * DESCRIPTION: + * + * This function sends a reply back to the requesting client indicating + * the specific XTrap version of this extension. + */ +int XETrapGetLastInpTime(xXTrapReq *request, ClientPtr client) +{ + xXTrapGetLITimReply tim_rep; + XETrapEnv *penv = XETenv[client->index]; + + /* Initialize the reply as needed */ + tim_rep.hdr.type = X_Reply; + tim_rep.hdr.detail = XETrap_GetLastInpTime; + tim_rep.hdr.sequenceNumber = client->sequence; + tim_rep.hdr.length = XEXTRA(xXTrapGetLITimReply); + tim_rep.data_last_time = penv->last_input_time; + WriteReplyToClient(client, sizeof(xXTrapGetLITimReply), &tim_rep); + return(Success); +} + +/* + * DESCRIPTION: + * + * This routine is swapped in for the server's output request vectors. + * After writing the request to one (or more) XTrap client(s), this + * routine ALWAYS returns by calling the REAL output request vector rtn. + * + * Note: Swapped Requests are handled automatically since the unswapped + * vectored routine is called after the request has been swapped. + * IOW, all requests are directed through ProcVector eventually and are + * "unswapped" at that point. It is necessary to swap the data + * back if writing to a swapped client, however, and this is done + * by calling the appropriate XETSwProcVector[] routine. + */ +int XETrapRequestVector(ClientPtr client) +{ + int status = True; + XETrapDatum *pdata, *spdata = NULL; + REQUEST(xResourceReq); + WindowPtr window_ptr; + XETrapEnv *penv; + BYTE *tptr; + ClientList *ioc = &io_clients; + ClientList *stc = &stats_clients; + INT32 asize = sizeof(pdata->hdr) + stuff->length * sizeof(CARD32); + INT32 size = MAX(asize,XETrapMinPktSize); /* Must be at least */ + INT32 csize; /* size of request to send to the XTrap client */ + + /* Get memory for the data to be sent */ + if ((pdata = (XETrapDatum *)Xcalloc(size)) == NULL) + { /* Can't do anything accept set a flag since we don't + * know who to send the error to yet. + */ + status = False; + } + + while (ioc->next != NULL) + { + ioc = ioc->next; + penv = XETenv[ioc->client->index]; + if (status == False) + { /* We didn't get the memory! Complain */ + SendErrorToClient(penv->client,XETrap_avail.data.major_opcode, + stuff->reqType, 0L, BadAlloc); + break; + } + if (BitIsTrue(penv->cur.data_config_flags_req,stuff->reqType)) + { /* This particular client is interested in *this* request */ + pdata->hdr.client = client->index; /* stuff client index in hdr */ + if (BitIsTrue(penv->cur.data_config_flags_data,XETrapWinXY)) + { + window_ptr = (WindowPtr) LookupDrawable(stuff->id, client); + if (window_ptr == 0L) + { /* Failed...invalidate the X and Y coordinate data. */ + pdata->hdr.win_x = -1L; + pdata->hdr.win_y = -1L; + } + else + { + pdata->hdr.screen = window_ptr->drawable.pScreen->myNum; + pdata->hdr.win_x = window_ptr->drawable.x; + pdata->hdr.win_y = window_ptr->drawable.y; + } + } + if (BitIsTrue(penv->cur.data_config_flags_data,XETrapTimestamp)) + { + pdata->hdr.timestamp = GetTimeInMillis(); + } + /* Copy the information to a location we can write it from */ + (void) memcpy(&(pdata->u.req),stuff,stuff->length*sizeof(CARD32)); + pdata->hdr.count = MIN(penv->cur.data_config_max_pkt_size,asize); + XETrapSetHeaderRequest(&(pdata->hdr)); + + /* Perform any needed byte/word swapping. NOTE: This is not + * the "normal" technique that should be used to perform the + * swapping. The reason that we do it here is to be sure to + * do it only once in a controlled manner, which we can not + * guarentee in the case of the Xlib transport. Notice that + * we don't swap the XTRAP EVENT information. This is done + * in the XETrapWriteXLib() routine. + */ + + if (penv->client->swapped) + { /* need to deal with swapped clients */ + if (spdata == NULL) + { /* Get memory for the swapped data to be sent */ + if ((spdata = (XETrapDatum *)Xcalloc(size)) == NULL) + { + SendErrorToClient(penv->client, + XETrap_avail.data.major_opcode, + stuff->reqType, 0L, BadAlloc); + break; + } + + memcpy(spdata,pdata,size); /* fill in the info */ + /* Now call the request-specific rtn to swap the request */ + if (stuff->reqType < 128) + { /* a core request, good */ + (*XETSwProcVector[stuff->reqType])(&(spdata->u.req), + penv->client); /* RTC X11R6 */ + } + else if (penv->cur.data_config_max_pkt_size == + XETrapMinPktSize) + { /* Minimum size, so swap it as an ResourceReq */ + XETSwResourceReq(&(spdata->u.req)); + } + else + { /* trying to swap an extension request! */ + SendErrorToClient(penv->client, + XETrap_avail.data.major_opcode, + stuff->reqType, 0L, XETrapErrorBase + BadSwapReq); + } + } + /* need to stow in the latest header (count) */ + memcpy(spdata,pdata,SIZEOF(XETrapHeader)); + sXETrapHeader(&(spdata->hdr)); /* swap the XTrap Header */ + } + /* Write as many bytes of information as the client wants */ + tptr = (BYTE *)(penv->client->swapped ? spdata : pdata); + csize = MAX(pdata->hdr.count, XETrapMinPktSize); + if (XETrapWriteXLib(penv, tptr, csize) != csize) + { + SendErrorToClient(penv->client,XETrap_avail.data.major_opcode, + stuff->reqType, 0L, XETrapErrorBase + BadIO); + } +#ifdef COLOR_REPLIES + /* Process Color Replies, if desired, and applicable */ + if (BitIsTrue(penv->cur.data_config_flags_data,XETrapColorReplies)) + { /* wants color replies */ + switch(stuff->reqType) + { + case X_AllocColor: + GetSendColorRep(client, stuff); + break; + case X_AllocNamedColor: + GetSendNamedColorRep(client, stuff); + break; + case X_AllocColorCells: + GetSendColorCellsRep(client, stuff); + break; + case X_AllocColorPlanes: + GetSendColorPlanesRep(client, stuff); + break; + default: + break; + } + } +#endif /* COLOR_REPLIES */ + } + } + while (stc->next != NULL) + { /* increment appropriate stats bucket for each interested client */ + stc = stc->next; + penv = XETenv[stc->client->index]; + if (BitIsTrue(penv->cur.data_config_flags_req,stuff->reqType)) + { /* This particular client would like this particular stat */ + penv->stats->data.requests[stuff->reqType]++; + } + } + + if (pdata) + { + Xfree(pdata); + } + if (spdata) + { + Xfree(spdata); + } + if (ignore_grabs == True && + (stuff->reqType == X_GrabServer || stuff->reqType == X_UngrabServer)) + { /* doesn't want Grab's! Note: this is a "last configured" setting */ +#ifndef NO_NEW_XTRAP + int status; + + if (stuff->reqType == X_GrabServer) + { + ClientList *pclient; + + /* first call grab server procedure */ + status = (*XETrapProcVector[stuff->reqType])(client); + + /* then add XTrap controlling clients */ + for (pclient = &io_clients; pclient; pclient = pclient->next) + if (pclient->client) + MakeClientGrabImpervious(pclient->client); + } + else + { + ClientList *pclient; + + /* first drop XTrap controlling clients */ + for (pclient = &io_clients; pclient; pclient = pclient->next) + if (pclient->client) + MakeClientGrabPervious(pclient->client); + + /* then call ungrab server procedure */ + status = (*XETrapProcVector[stuff->reqType])(client); + } + return status; +#else /* NO_NEW_XTRAP */ + return(Success); +#endif /* NO_NEW_XTRAP */ + } + else + { + return((*XETrapProcVector[stuff->reqType])(client)); + } +} +/* + * + * DESCRIPTION: + * + * This routine intercepts input xEvents from the keyboard. + * if XETrapTrapActive, will write record to client(s) + * and then pass the event to the server iff not command + * key and gate is open. If it's a command key, then twiddle + * the gate state as required (optional, see below). + * + * This routine implements an optional user specified command key + * that can be used to close the input pipe into the server + * while a client command is generated. The keypress of the + * command key places this routine in command mode, the keyrelease + * exits command mode. + * + * A keypress of the command key followed by the + * optionally specified lock key will place this routine in continuous + * command mode until the command key and lock key are pressed again + * to exit command mode. In the locked state, the client interprets + * keystrokes as it wishes, as commands or as input to a prior command. + * + * Both mechanisms can be used alternately. + * + * IMPLICIT INPUTS : + * + * penv->cur.data_config_cmd_key : + * This is the keycode of the key that is used to stop + * and restart the transmission of intercepted input + * events to the server. If specified, the gate_state + * flag will be set or cleared depending on the state of + * the command_key. + * + * penv->cur.data_config_flags_data.XETrapCmdKeyMod: + * This is the value of the mode in which the command_key + * will operate. It currently has two values: MODIFIER and + * COMMAND_LOCK. MODIFIER mode clears gate_state on + * keypress, and sets gate_state on keyrelease. + * COMMAND_LOCK mode toggles gate_state on + * or off. + * + * gate_closed: + * A flag that is set/cleared in the xtrap_keyboard + * routine that indicates whether intercepted input + * should be passed to the server at any particular + * instance. + * + * + * next_key: + * This variable tracks the state of the next key to be + * pressed or released. It allows the checking of double + * presses of the command key to be sent to the server and + * keeps good state order when the command key is used. + * + * key_ignore: + * This variable indicates whether or not the specific + * key should be ignored for subsequent server processing. + * + */ +int XETrapKeyboard(xEvent *x_event, DevicePtr keybd, int count) +{ + register BYTE type = x_event->u.u.type; + register BYTE detail = x_event->u.u.detail; + XETrapEnv *penv; + ClientList *stc = &stats_clients; + ClientList *cmc = &cmd_clients; + int_function cur_func = XETrapKeyboard; + +#ifdef VERBOSE + if (count != 1L) + { /* We haven't coded for this situation yet! */ + ErrorF("Warning! Event count != 1 (%d)\n", count); + } +#endif + while (stc->next != NULL) + { /* increment appropriate stats bucket for each interested client */ + stc = stc->next; + penv = XETenv[stc->client->index]; + if (BitIsTrue(penv->cur.data_config_flags_event,type)) + { /* This particular client would like this particular stat */ + penv->stats->data.events[type]++; + } + } +#ifndef VECTORED_EVENTS + /* We *only* StampAndMail command keys with vectored events since + * we get much more data by waiting till we get called in XETrapEventVector + */ + XETrapStampAndMail(x_event); /* send to XTrap client if necessry */ +#endif + while (cmc->next != NULL) + { + cmc = cmc->next; + penv = XETenv[cmc->client->index]; + key_ignore = False; + if (detail == penv->cur.data_config_cmd_key) + { + if (BitIsTrue(penv->cur.data_config_flags_data, XETrapCmdKeyMod)) + { + switch (type) + { + case KeyPress: + if (next_key == XEKeyIsEcho) + { + break; + } + gate_closed = True; + next_key = XEKeyIsClear; + break; + + case KeyRelease: + if (next_key == XEKeyIsEcho) + { + next_key = XEKeyIsClear; + break; + } + if (next_key == XEKeyIsClear) + { + next_key = XEKeyIsEcho; + } + else + { /* it's Other, so Clear it */ + next_key = XEKeyIsClear; + } + gate_closed = False; + key_ignore = True; + break; + + default: break; + } + } + else + { + switch (type) + { + case KeyPress: + if (next_key == XEKeyIsEcho) + { + gate_closed = False; + break; + } + /* Open gate on cmd key release */ + if ((next_key == XEKeyIsOther) && + gate_closed == True) + { + break; + } + gate_closed = True; + next_key = XEKeyIsClear; + break; + + case KeyRelease: + if (next_key == XEKeyIsClear) + { + next_key = XEKeyIsEcho; + break; + } + + if (next_key == XEKeyIsEcho) + { + next_key = XEKeyIsClear; + break; + } + + gate_closed = False; + key_ignore = True; + next_key = XEKeyIsClear; + break; + + default: + break; + } + } + } + else + { + next_key = XEKeyIsOther; + } + } + + /* + * If the gate to the server is open, + * and we are not ignoring a keyrelease, + * pass the event to the server for normal processing. + */ +#ifndef VECTORED_EVENTS + if ((gate_closed == False) && (key_ignore == False)) + { + if (XETrapEventProcVector[type] != cur_func) + { /* to protect us from infinite loops */ + (void)(*XETrapEventProcVector[type])(x_event,keybd,count); + } + else + { + (void)(*EventProcVector[type])(x_event,keybd,count); + } + } +#else /* VECTORED_EVENTS */ + if ((gate_closed == False) && (key_ignore == False)) + { /* send event on to server to be trapped again in XETrapEventVector */ + (void)(*keybd_process_inp)(x_event,keybd,count); + } + else + { + XETrapStampAndMail(x_event); /* send to XTrap client if necessry */ + } +#endif + key_ignore = False; /* reset for next time around */ + return 0; +} + +/* + * DESCRIPTION: + * + * This routine intercepts input xEvents from the pointer device + * and passes the input event back to the server for normal processing. + * + * This routine is sensitive to whether input is being passed + * up to the server or not. This state is set by the keyboard + * input routine. + * + * + */ +#ifndef VECTORED_EVENTS +int XETrapPointer(xEvent *x_event, DevicePtr ptrdev, int count) +{ + XETrapEnv *penv; + ClientList *stc = &stats_clients; + int_function cur_func = XETrapPointer; + +#ifdef VERBOSE + if (count != 1L) + { /* We haven't coded for this situation yet! */ + ErrorF("Warning! Event count != 1 (%d)\n", count); + } +#endif + while (stc->next != NULL) + { /* increment appropriate stats bucket for each interested client */ + stc = stc->next; + penv = XETenv[stc->client->index]; + if (BitIsTrue(penv->cur.data_config_flags_event,x_event->u.u.type)) + { /* This particular client would like this particular stat */ + penv->stats->data.events[x_event->u.u.type]++; + } + } + XETrapStampAndMail(x_event); /* send to XTrap client if necessry */ + /* + * If the gate to the server is open, + * pass the event up like nothing has happened. + */ + if (gate_closed == False) + { + if (XETrapEventProcVector[x_event->u.u.type] != cur_func) + { /* to protect us from infinite loops */ + (void)(*XETrapEventProcVector[x_event->u.u.type])(x_event,ptrdev, + count); + } + else + { + (void)(*EventProcVector[x_event->u.u.type])(x_event,ptrdev,count); + } + } + return 0; +} +#endif /* !VECTORED_EVENTS */ + + +/* + * DESCRIPTION: + * + * This routine determines whether it needs to send event data + * to the XTrap Client(s). If so, it timestamps it appropriately + * and writes out both the header and detail information. + * + */ +void XETrapStampAndMail(xEvent *x_event) +{ + XETrapDatum data; + register CARD32 size; + XETrapEnv *penv; + ClientList *ioc = &io_clients; + + /* Currently, we're intercepting core events *before* most + * of the event information's filled in. Specifically, the + * only fields that are valid at this level are: type, detail, + * time, rootX, rootY, and state. + */ + /* Loop through all clients wishing I/O */ + while (ioc->next != NULL) + { + ioc = ioc->next; + penv = XETenv[ioc->client->index]; + /* Do we have a valid fd? Do we care about this event? */ + if (BitIsTrue(penv->cur.data_config_flags_event, x_event->u.u.type)) + { + XETrapSetHeaderEvent(&(data.hdr)); + data.hdr.win_x = data.hdr.win_y = -1L; /* Invalidate req draw */ + data.hdr.screen = 0L; /* not till Events are vectored! */ + data.hdr.client = 0L; /* not till Events are vectored! */ + if (BitIsTrue(penv->cur.data_config_flags_data, + XETrapTimestamp)) + { + data.hdr.timestamp = GetTimeInMillis(); + } + size = data.hdr.count = XETrapMinPktSize; /* Always for evts */ + penv->last_input_time = x_event->u.keyButtonPointer.time; + /* Copy the event information into our local memory */ + (void)memcpy(&(data.u.event),x_event,sizeof(xEvent)); + +#ifdef PANORAMIX + if (!noPanoramiXExtension && + (data.u.event.u.u.type == MotionNotify || + data.u.event.u.u.type == ButtonPress || + data.u.event.u.u.type == ButtonRelease || + data.u.event.u.u.type == KeyPress || + data.u.event.u.u.type == KeyRelease)) { + int scr = XineramaGetCursorScreen(); + data.u.event.u.keyButtonPointer.rootX += + panoramiXdataPtr[scr].x - panoramiXdataPtr[0].x; + data.u.event.u.keyButtonPointer.rootY += + panoramiXdataPtr[scr].y - panoramiXdataPtr[0].y; + } +#endif + + if (penv->client->swapped) + { /* + * Notice that we don't swap the XTRAP EVENT information. + * This is done in the XETrapWriteXLib() routine. + */ + xEvent ToEvent; + (*EventSwapVector[data.u.event.u.u.type & 0177]) + (&data.u.event,&ToEvent); + (void)memcpy(&(data.u.event),&ToEvent,sizeof(ToEvent)); + sXETrapHeader(&(data.hdr)); /* swap the XTrap Header */ + } + /* From this point on, the contents of data is swapped and + * therefore we should not refer to it for information. + */ + if (XETrapWriteXLib(penv, (BYTE *)&data, size) != size) + { + SendErrorToClient(penv->client, + XETrap_avail.data.major_opcode, + x_event->u.u.type, 0L, XETrapErrorBase + BadIO); + } + } + } + return; +} +#ifdef VECTORED_EVENTS +int XETrapEventVector(ClientPtr client, xEvent *x_event) +{ + XETrapDatum data; + register CARD32 size; + XETrapEnv *penv; + ClientList *ioc = &io_clients; + + /* Loop through all clients wishing I/O */ + while (ioc->next != NULL) + { + ioc = ioc->next; + penv = XETenv[ioc->client->index]; + /* Do we care about this event? */ + if (BitIsTrue(penv->cur.data_config_flags_event, x_event->u.u.type)) + { + XETrapSetHeaderEvent(&(data.hdr)); + data.hdr.client = client->index; + data.hdr.win_x = data.hdr.win_y = -1L; /* Invalidate req draw */ + if ((current_screen < 0L) || ((x_event->u.u.type >= KeyPress) && + (x_event->u.u.type <= MotionNotify) && + (!x_event->u.keyButtonPointer.sameScreen))) + { /* we've moved/warped to another screen */ + WindowPtr root_win = GetCurrentRootWindow(); + current_screen = root_win->drawable.pScreen->myNum; + } + data.hdr.screen = current_screen; + if (BitIsTrue(penv->cur.data_config_flags_data, + XETrapTimestamp)) + { + data.hdr.timestamp = GetTimeInMillis(); + } + size = data.hdr.count = XETrapMinPktSize; /* Always for evts */ + penv->last_input_time = x_event->u.keyButtonPointer.time; + /* Copy the event information into our local memory */ + (void)memcpy(&(data.u.event),x_event,sizeof(xEvent)); + + if (penv->client->swapped) + { + xEvent ToEvent; + (*EventSwapVector[data.u.event.u.u.type & 0177]) + (&data.u.event,&ToEvent); + (void)memcpy(&(data.u.event),&ToEvent,sizeof(ToEvent)); + sXETrapHeader(&(data.hdr)); /* swap the XTrap Header */ + } + /* From this point on, the contents of pdata is swapped and + * therefore we should not refer to it for information. + */ + if (XETrapWriteXLib(penv, (BYTE *)&data, size) != size) + { + SendErrorToClient(penv->client, + XETrap_avail.data.major_opcode, + x_event->u.u.type, 0L, XETrapErrorBase + BadIO); + } + } + } + return; +} +#endif /* VECTORED_EVENTS */ +void sReplyXTrapDispatch(ClientPtr client, int size, char *reply) +{ + register XETrapRepHdr *rep = (XETrapRepHdr *)reply; + + switch(rep->detail) + { + case XETrap_GetAvailable: + { + xXTrapGetAvailReply lrep; + (void)memcpy((char *)&lrep,reply,sizeof(lrep)); + sReplyXETrapGetAvail(client,size,(char *)&lrep); + } + break; + case XETrap_GetCurrent: + { + xXTrapGetCurReply lrep; + (void)memcpy((char *)&lrep,reply,sizeof(lrep)); + sReplyXETrapGetCur(client,size,(char *)&lrep); + } + break; + case XETrap_GetStatistics: + { + xXTrapGetStatsReply lrep; + (void)memcpy((char *)&lrep,reply,sizeof(lrep)); + sReplyXETrapGetStats(client,size,(char *)&lrep); + } + break; + case XETrap_GetVersion: + { + xXTrapGetVersReply lrep; + (void)memcpy((char *)&lrep,reply,sizeof(lrep)); + sReplyXETrapGetVers(client,size,(char *)&lrep); + } + break; + case XETrap_GetLastInpTime: + { + xXTrapGetLITimReply lrep; + (void)memcpy((char *)&lrep,reply,sizeof(lrep)); + sReplyXETrapGetLITim(client,size,(char *)&lrep); + } + break; + default: + SendErrorToClient(client,XETrap_avail.data.major_opcode, + rep->detail, 0L, BadImplementation); + break; + } + return; +} + +/* + * XLib communications routines + */ + +/* + * DESCRIPTION: + * + * This function performs the transport specific functions required + * for writing data back to an XTrap client over XLib. The trick is + * packaging the data into <=32 byte packets to conform to the sizeof + * an X Event. nbytes must be at least equal to XETrapMinPktSize + * + */ +int XETrapWriteXLib(XETrapEnv *penv, BYTE *data, CARD32 nbytes) +{ + CARD32 size, total = 0L; + xETrapDataEvent event; + + /* Initialize the detail field to show the beginning of a datum */ + event.detail = XETrapDataStart; + event.idx = 0L; + + /* This loop could be optimized by not calling Write until after all + * of the events are packaged. However, this would require memory + * games, and may not therefore be a win. + */ + while (nbytes > 0L) + { /* How many bytes can we send in this packet */ + size = (nbytes > sz_EventData) ? sz_EventData : nbytes; + + /* Initialize the event */ + event.type = XETrapData + XETrap_avail.data.event_base; + event.sequenceNumber = penv->client->sequence; + + /* Copy the data we are sending */ + (void)memcpy(event.data,data,size); + if (size < sz_EventData) + (void)memset(event.data+size,0L,sz_EventData-size); + data += size; + nbytes -= size; + total += size; + + /* Set the detail field to show the continuation of datum */ + if (total != size) + { /* this is not the first one */ + event.detail = (nbytes > 0) ? XETrapDataContinued : XETrapDataLast; + } + + /* Send this part to the client */ + WriteEventsToClient(penv->client, 1L, (xEvent *) &event); + event.idx++; /* Bump the index for the next event */ + } + return(total); +} + +/*----------------------------* + * Static Functions + *----------------------------*/ + +static void update_protocol(xXTrapGetReq *reqptr, ClientPtr client) +{ + XETrapEnv *penv = XETenv[client->index]; + /* update protocol number */ + switch (reqptr->protocol) + { + /* known acceptable protocols */ + case 31: + case XETrapProtocol: + penv->protocol = reqptr->protocol; + break; + /* all else */ + default: /* stay backwards compatible */ + penv->protocol = 31; + break; + } +} + +/* Swap 2 functions. This is a function instead of a macro to help to keep + * lint from complaining about mixed types. It seems to work, but I would + * probably classify this as a hack. + */ +static void _SwapProc( register int (**f1)(), register int (**f2)()) +{ + register int (*t1)() = *f1; + *f1 = *f2; + *f2 = t1; + + return; +} + +/* + * DESCRIPTION: + * + * This function swaps the byte order of fields within + * the XTrap Event Header. It assumes the data will be + * swapped by code in XETrapRequestVector(). + * + */ +static void sXETrapEvent(xETrapDataEvent *from, xETrapDataEvent *to) +{ + to->type = from->type; + to->detail = from->detail; + cpswaps(from->sequenceNumber,to->sequenceNumber); + cpswapl(from->idx,to->idx); + /* Assumes that the data's already been swapped by XETrapRequestVector */ + memcpy(to->data, from->data, SIZEOF(EventData)); +} + +/* + * DESCRIPTION: + * + * This function adds a node from an accelerator linked-list + * (either io_clients, stats_clients, or cmd_clients). + * + */ +static int add_accelerator_node(ClientPtr client, ClientList *accel) +{ + Bool found = False; + int status = Success; + + while (accel->next != NULL) + { + if (accel->client == client) + { + found = True; /* Client's already known */ + break; + } + else + { + accel = accel->next; + } + } + if (found == False) + { + if ((accel->next = (ClientList *)Xcalloc(sizeof(ClientList))) == NULL) + { + status = BadAlloc; + } + else + { /* fill in the node */ + accel = accel->next; + accel->next = NULL; + accel->client = client; + } + } + return(status); +} +/* + * DESCRIPTION: + * + * This function removes a node from an accelerator linked-list + * (either io_clients, stats_clients, or cmd_clients). + * + */ +static void remove_accelerator_node(ClientPtr client, ClientList *accel) +{ + while (accel->next != NULL) + { + if (accel->next->client == client) + { + ClientList *tmp = accel->next->next; + Xfree(accel->next); + accel->next = tmp; + break; + } + else + { + accel = accel->next; + } + } + + return; +} + +#ifdef COLOR_REPLIES +static void GetSendColorRep(ClientPtr client, xResourceReq *req) +{ /* adapted from ProcAllocColor() in dispatch.c */ + XETrapDatum data; + int retval; + XETrapEnv *penv = XETenv[client->index]; + xAllocColorReply *crep = (xAllocColorReply *)&(data.u.reply); + xAllocColorReq *creq = (xAllocColorReq *)req; + ColormapPtr pmap = (ColormapPtr )LookupIDByType(creq->cmap, RT_COLORMAP); + + /* Fill in the header fields */ + data.hdr.count = XETrapMinPktSize; /* The color replies are 32 bytes */ + XETrapSetHeaderReply(&(data.hdr)); + /* Hack alert: + * We need to pass the "reply" type in the header since replies don't + * contain the id's themselves. However, we're not changing the + * protocol to support this until we decide exactly how we want to + * do *all* replies (e.g. not just ColorReplies). So until then, stow + * the reply id in the screen field which wouldn't normally be used in + * this context. + */ + data.hdr.screen = req->reqType; + if (!pmap) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, BadColor); + return; + } + crep->red = creq->red; + crep->green = creq->green; + crep->blue = creq->blue; + crep->pixel = 0; + if ((retval = AllocColor(pmap, &(crep->red), &(crep->green), + &(crep->blue), &(crep->pixel), client->index)) != Success) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, retval); + return; + } + /* Swap data if necessary */ + if (client->swapped) + { + INT32 n; + swaps(&(crep->red), n); + swaps(&(crep->green), n); + swaps(&(crep->blue), n); + swapl(&(crep->pixel), n); + } + /* Send data to client */ + if (XETrapWriteXLib(penv, (BYTE *)&data, XETrapMinPktSize) + != XETrapMinPktSize) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, XETrapErrorBase + BadIO); + } +} + +static void GetSendNamedColorRep(ClientPtr client, xResourceReq *req) +{ /* adapted from ProcAllocNamedColor() in dispatch.c */ + XETrapDatum data; + XETrapEnv *penv = XETenv[client->index]; + int retval; + xAllocNamedColorReply *nrep = (xAllocNamedColorReply *)&(data.u.reply); + xAllocNamedColorReq *nreq = (xAllocNamedColorReq *)req; + ColormapPtr pcmp = (ColormapPtr )LookupIDByType(nreq->cmap, RT_COLORMAP); + + data.hdr.count = XETrapMinPktSize; /* The color replies are 32 bytes */ + XETrapSetHeaderReply(&(data.hdr)); + /* Hack alert: + * We need to pass the "reply" type in the header since replies don't + * contain the id's themselves. However, we're not changing the + * protocol to support this until we decide exactly how we want to + * do *all* replies (e.g. not just ColorReplies). So until then, stow + * the reply id in the screen field which wouldn't normally be used in + * this context. + */ + data.hdr.screen = req->reqType; + if (!pcmp) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, BadColor); + return; + } + if (!OsLookupColor(pcmp->pScreen->myNum, (char *)&nreq[1], + nreq->nbytes, &(nrep->exactRed), &(nrep->exactGreen), + &(nrep->exactBlue))) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, BadName); + return; + } + nrep->screenRed = nrep->exactRed; + nrep->screenGreen = nrep->exactGreen; + nrep->screenBlue = nrep->exactBlue; + nrep->pixel = 0; + if ((retval = AllocColor(pcmp, &(nrep->screenRed), + &(nrep->screenGreen), &(nrep->screenBlue), &(nrep->pixel), + client->index)) != Success) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, retval); + return; + } + /* Swap data if necessary */ + if (client->swapped) + { + INT32 n; + swapl(&(nrep->pixel), n); + swaps(&(nrep->exactRed), n); + swaps(&(nrep->exactGreen), n); + swaps(&(nrep->exactBlue), n); + swaps(&(nrep->screenRed), n); + swaps(&(nrep->screenGreen), n); + swaps(&(nrep->screenBlue), n); + } + + /* Send data to client */ + if (XETrapWriteXLib(penv, (BYTE *)&data, XETrapMinPktSize) + != XETrapMinPktSize) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, XETrapErrorBase + BadIO); + } +} + +static void GetSendColorCellsRep(ClientPtr client, xResourceReq *req) +{ /* adapted from ProcAllocColorCells() in dispatch.c */ + int retval; + int npixels, nmasks; + unsigned long *ppixels, *pmasks; + long length; + XETrapDatum *data; + XETrapEnv *penv = XETenv[client->index]; + xAllocColorCellsReply *crep; + xAllocColorCellsReq *creq = (xAllocColorCellsReq *)req; + ColormapPtr pmap = (ColormapPtr )LookupIDByType(creq->cmap, RT_COLORMAP); + + if (!pmap) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, BadColor); + return; + } + npixels = creq->colors; + if (!npixels) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, BadValue); + return; + } + nmasks = creq->planes; + length = ((long)npixels + (long)nmasks) * sizeof(Pixel); + data = (XETrapDatum *)ALLOCATE_LOCAL(sizeof(XETrapDatum)+length); + if (!data) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, BadAlloc); + return; + } + data->hdr.count = MIN(penv->cur.data_config_max_pkt_size, + sizeof(XETrapDatum)+length); + XETrapSetHeaderReply(&(data->hdr)); + data->hdr.screen = req->reqType; /* hack! but necessary */ + ppixels = (unsigned long *)((char *)data + sizeof(XETrapDatum)); + pmasks = ppixels + npixels; + if ((retval = AllocColorCells(client->index, pmap, npixels, + nmasks, (Bool)creq->contiguous, ppixels, pmasks)) != Success) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, retval); + DEALLOCATE_LOCAL(data); + return; + } + crep = (xAllocColorCellsReply *)&(data->u.reply); + crep->nPixels = npixels; + crep->nMasks = nmasks; + /* Swap data if necessary */ + if (client->swapped) + { + INT32 n, i, *ptr; + ptr=(INT32 *)ppixels; + swaps(&(crep->nPixels), n); + swaps(&(crep->nMasks), n); + for (i=0; i<length; i++) + { + swapl(&(ptr[i]), n); + } + } + /* Send data to client */ + if (XETrapWriteXLib(penv, (BYTE *)&data, data->hdr.count) + != data->hdr.count) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, XETrapErrorBase + BadIO); + } + DEALLOCATE_LOCAL(data); +} +static void GetSendColorPlanesRep(ClientPtr client, xResourceReq *req) +{ /* adapted from ProcAllocColorPlanes() in dispatch.c */ + int retval; + int npixels, nmasks; + unsigned long *ppixels, *pmasks; + long length; + XETrapDatum *data; + XETrapEnv *penv = XETenv[client->index]; + xAllocColorPlanesReply *crep; + xAllocColorPlanesReq *creq = (xAllocColorPlanesReq *)req; + ColormapPtr pmap = (ColormapPtr )LookupIDByType(creq->cmap, RT_COLORMAP); + + if (!pmap) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, BadColor); + return; + } + npixels = creq->colors; + if (!npixels) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, BadValue); + return; + } + length = (long)npixels * sizeof(Pixel); + data = (XETrapDatum *)ALLOCATE_LOCAL(sizeof(XETrapDatum)+length); + if (!data) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, BadAlloc); + return; + } + data->hdr.count = MIN(penv->cur.data_config_max_pkt_size, + sizeof(XETrapDatum)+length); + XETrapSetHeaderReply(&(data->hdr)); + data->hdr.screen = req->reqType; /* hack! but necessary */ + ppixels = (unsigned long *)((char *)data + sizeof(XETrapDatum)); + crep = (xAllocColorPlanesReply *)&(data->u.reply); + if ((retval = AllocColorPlanes(client->index, pmap, npixels, + (int)creq->red, (int)creq->green, (int)creq->blue, + (int)creq->contiguous, ppixels, &(crep->redMask), &(crep->greenMask), + &(crep->blueMask))) != Success) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, retval); + DEALLOCATE_LOCAL(data); + return; + } + crep->nPixels = npixels; + /* Swap data if necessary */ + if (client->swapped) + { + INT32 n, i, *ptr; + ptr=(INT32 *)ppixels; + swaps(&(crep->nPixels), n); + swapl(&(crep->redMask), n); + swapl(&(crep->greenMask), n); + swapl(&(crep->blueMask), n); + for (i=0; i<length; i++) + { + swapl(&(ptr[i]), n); + } + } + /* Send data to client */ + if (XETrapWriteXLib(penv, (BYTE *)&data, data->hdr.count) + != data->hdr.count) + { + SendErrorToClient(penv->client, XETrap_avail.data.major_opcode, + req->reqType, 0L, XETrapErrorBase + BadIO); + } + DEALLOCATE_LOCAL(data); +} +#endif /* COLOR_REPLIES */ diff --git a/XTrap/xtrapdiswp.c b/XTrap/xtrapdiswp.c new file mode 100644 index 000000000..435ca71f6 --- /dev/null +++ b/XTrap/xtrapdiswp.c @@ -0,0 +1,1006 @@ +/* $XFree86: xc/programs/Xserver/XTrap/xtrapdiswp.c,v 1.1 2001/11/02 23:29:29 dawes Exp $ */ +/**************************************************************************** +Copyright 1987, 1988, 1989, 1990, 1991, 1992 by + + Digital Equipment Corp., Maynard, MA + +X11R6 Changes Copyright (c) 1994 by Robert Chesler of Absol-Puter, Hudson, NH. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL AND ABSOL-PUTER DISCLAIM ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL DIGITAL OR ABSOL-PUTER BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +*****************************************************************************/ +/* + * ABSTRACT: + * + * This module is the device independent module responsible for all + * routines required for proper communication in a heterogeneous + * networking environment (i.e. client & server on different endian + * machines). The bulk of this module is patterned after X11/R4's + * server/dix/swapreq.c ; however, they infact swap fields + * in the exact opposite order since XTrap requires "unswapped" data + * to become "swapped" before sending it to a "swapped" client. + * + * CONTRIBUTORS: + * + * Ken Miller + * Marc Evans + * + * CHANGES: + * + * Robert Chesler - added client arg for X11R6 port in many spots + * + */ + +#include <X11/X.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include <X11/Xproto.h> +#include <X11/Xprotostr.h> +#include <X11/extensions/xtrapdi.h> +#include "input.h" /* Server DevicePtr definitions */ +#include "misc.h" +#include "dixstruct.h" +#ifdef PC +# include "extnsist.h" +#else +# include "extnsionst.h" /* Server ExtensionEntry definitions */ +#endif +# include "swapreq.h" /* Server SwapColorItem definition */ +#include <X11/extensions/xtrapddmi.h> +#include <X11/extensions/xtrapproto.h> + +/* In-coming XTrap requests needing to be swapped to native format */ + +int sXETrapReset(xXTrapReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->length),n); + return(XETrapReset(request,client)); +} + +int sXETrapGetAvailable(xXTrapGetReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->length),n); + swaps(&(request->protocol),n); + return(XETrapGetAvailable(request,client)); +} + +int sXETrapConfig(xXTrapConfigReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->length),n); + swaps(&(request->config_max_pkt_size),n); + return(XETrapConfig(request,client)); +} + +int sXETrapStartTrap(xXTrapReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->length),n); + return(XETrapStartTrap(request,client)); +} + +int sXETrapStopTrap(xXTrapReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->length),n); + return(XETrapStopTrap(request,client)); +} + +int sXETrapGetCurrent(xXTrapReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->length),n); + return(XETrapGetCurrent(request,client)); +} + +int sXETrapGetStatistics(xXTrapReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->length),n); + return(XETrapGetStatistics(request,client)); +} + +#ifndef _XINPUT +int sXETrapSimulateXEvent(xXTrapInputReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->input.x),n); + swaps(&(request->input.y),n); + return(XETrapSimulateXEvent(request,client)); +} +#endif + +int sXETrapGetVersion(xXTrapGetReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->length),n); + swaps(&(request->protocol),n); + return(XETrapGetVersion(request,client)); +} + +int sXETrapGetLastInpTime(xXTrapReq *request, ClientPtr client) +{ + register char n; + swaps(&(request->length),n); + return(XETrapGetLastInpTime(request,client)); +} + + +/* Out-going XTrap replies needing to be swapped *from* native format */ + +void sReplyXETrapGetAvail(ClientPtr client, int size, char *reply) +{ + xXTrapGetAvailReply *rep = (xXTrapGetAvailReply *)reply; + register char n; + swaps(&(rep->hdr.sequenceNumber),n); + swapl(&(rep->hdr.length),n); + swapl(&(rep->data.pf_ident),n); + swaps(&(rep->data.xtrap_release),n); + swaps(&(rep->data.xtrap_version),n); + swaps(&(rep->data.xtrap_revision),n); + swaps(&(rep->data.max_pkt_size),n); + swapl(&(rep->data.major_opcode),n); + swapl(&(rep->data.event_base),n); + swaps(&(rep->data.cur_x),n); + swaps(&(rep->data.cur_y),n); + (void)WriteToClient(client,size,reply); + return; +} +void sReplyXETrapGetVers(ClientPtr client, int size, char *reply) +{ + xXTrapGetVersReply *rep = (xXTrapGetVersReply *)reply; + register char n; + swaps(&(rep->hdr.sequenceNumber),n); + swapl(&(rep->hdr.length),n); + swaps(&(rep->data.xtrap_release),n); + swaps(&(rep->data.xtrap_version),n); + swaps(&(rep->data.xtrap_revision),n); + (void)WriteToClient(client,size,reply); + return; +} +void sReplyXETrapGetLITim(ClientPtr client, int size, char *reply) +{ + xXTrapGetLITimReply *rep = (xXTrapGetLITimReply *)reply; + register char n; + swaps(&(rep->hdr.sequenceNumber),n); + swapl(&(rep->hdr.length),n); + swapl(&(rep->data_last_time),n); + (void)WriteToClient(client,size,reply); + return; +} +void sReplyXETrapGetCur(ClientPtr client, int size, char *reply) +{ + xXTrapGetCurReply *rep = (xXTrapGetCurReply *)reply; + register char n; + swaps(&(rep->hdr.sequenceNumber),n); + swapl(&(rep->hdr.length),n); + swaps(&(rep->data_config_max_pkt_size),n); + (void)WriteToClient(client,size,reply); + return; +} +void sReplyXETrapGetStats(ClientPtr client, int size, char *reply) +{ + xXTrapGetStatsReply *rep = (xXTrapGetStatsReply *)reply; + register char n; + register int i; + long *p; + + swaps(&(rep->sequenceNumber),n); + swapl(&(rep->length),n); + for (i=0L, p = (long *)rep->data.requests; i<256L; i++, p++) + { + swapl(p,n); + } + for (i=0L, p = (long *)rep->data.events; i<XETrapCoreEvents; i++, p++) + { + swapl(p,n); + } + (void)WriteToClient(client,size,reply); + return; +} + +/* Out-going XTrap I/O header needing to be swapped *from* native format */ + +void sXETrapHeader(XETrapHeader *hdr) +{ + register char n; + + swapl(&(hdr->count), n); + swapl(&(hdr->timestamp), n); + swaps(&(hdr->win_x), n); + swaps(&(hdr->win_y), n); + swaps(&(hdr->client), n); +} + + /* Out-going requests needing to be swapped *from* native format + * aka swapreq.c "equivalents" + */ + +/* The following is used for all requests that have + no fields to be swapped (except "length") */ +void XETSwSimpleReq(register xReq *data) +{ + register char n; + swaps(&(data->length), n); +} + +/* The following is used for all requests that have + only a single 32-bit field to be swapped, coming + right after the "length" field */ + +void XETSwResourceReq(register xResourceReq *data) +{ + register char n; + + swaps(&(data->length), n); + swapl(&(data->id), n); +} + +void XETSwCreateWindow(register xCreateWindowReq *data,ClientPtr client) +{ + register char n; + + swapl(&(data->wid), n); + swapl(&(data->parent), n); + swaps(&(data->x), n); + swaps(&(data->y), n); + swaps(&(data->width), n); + swaps(&(data->height), n); + swaps(&(data->borderWidth), n); + swaps(&(data->class), n); + swapl(&(data->visual), n); + swapl(&(data->mask), n); + SwapRestL(data); + swaps(&(data->length), n); +} + +void XETSwChangeWindowAttributes(register xChangeWindowAttributesReq *data, +ClientPtr client) +{ + register char n; + + swapl(&(data->window), n); + swapl(&(data->valueMask), n); + SwapRestL(data); + swaps(&(data->length), n); +} + +void XETSwReparentWindow(register xReparentWindowReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->window), n); + swapl(&(data->parent), n); + swaps(&(data->x), n); + swaps(&(data->y), n); +} + +void XETSwConfigureWindow(xConfigureWindowReq *data, ClientPtr client) +{ + register char n; + swapl(&(data->window), n); + swaps(&(data->mask), n); + SwapRestL(data); + swaps(&(data->length), n); +} + + +void XETSwInternAtom(register xInternAtomReq *data) +{ + register char n; + swaps(&(data->length), n); + swaps(&(data->nbytes), n); +} + +void XETSwChangeProperty(register xChangePropertyReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->window), n); + swapl(&(data->property), n); + swapl(&(data->type), n); + switch ( data->format ) { + case 8L : break; + case 16L: + SwapShorts((short *)(data + 1), data->nUnits); + break; + case 32L: + SwapLongs((CARD32 *)(data + 1), data->nUnits); + break; + } + swapl(&(data->nUnits), n); +} + +void XETSwDeleteProperty(register xDeletePropertyReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->window), n); + swapl(&(data->property), n); + +} +void XETSwGetProperty(register xGetPropertyReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->window), n); + swapl(&(data->property), n); + swapl(&(data->type), n); + swapl(&(data->longOffset), n); + swapl(&(data->longLength), n); +} + +void XETSwSetSelectionOwner(register xSetSelectionOwnerReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->window), n); + swapl(&(data->selection), n); + swapl(&(data->time), n); +} + +void XETSwConvertSelection(register xConvertSelectionReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->requestor), n); + swapl(&(data->selection), n); + swapl(&(data->target), n); + swapl(&(data->property), n); + swapl(&(data->time), n); +} + +void XETSwSendEvent(register xSendEventReq *data) +{ + register char n; + xEvent eventT; + void (*proc)(); + swapl(&(data->destination), n); + swapl(&(data->eventMask), n); + + /* Swap event */ + proc = EventSwapVector[data->event.u.u.type & 0177]; + if (!proc || (int (*)()) proc == (int (*)()) NotImplemented) + (*proc)(&(data->event), &eventT); + data->event = eventT; + swaps(&(data->length), n); +} + +void XETSwGrabPointer(register xGrabPointerReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->grabWindow), n); + swaps(&(data->eventMask), n); + swapl(&(data->confineTo), n); + swapl(&(data->cursor), n); + swapl(&(data->time), n); +} + +void XETSwGrabButton(register xGrabButtonReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->grabWindow), n); + swaps(&(data->eventMask), n); + swapl(&(data->confineTo), n); + swapl(&(data->cursor), n); + swaps(&(data->modifiers), n); +} + +void XETSwUngrabButton(register xUngrabButtonReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->grabWindow), n); + swaps(&(data->modifiers), n); +} + +void XETSwChangeActivePointerGrab(register xChangeActivePointerGrabReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->cursor), n); + swapl(&(data->time), n); + swaps(&(data->eventMask), n); +} + +void XETSwGrabKeyboard(register xGrabKeyboardReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->grabWindow), n); + swapl(&(data->time), n); +} + +void XETSwGrabKey(register xGrabKeyReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->grabWindow), n); + swaps(&(data->modifiers), n); +} + +void XETSwUngrabKey(register xUngrabKeyReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->grabWindow), n); + swaps(&(data->modifiers), n); +} + +void XETSwGetMotionEvents(register xGetMotionEventsReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->window), n); + swapl(&(data->start), n); + swapl(&(data->stop), n); +} + +void XETSwTranslateCoords(register xTranslateCoordsReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->srcWid), n); + swapl(&(data->dstWid), n); + swaps(&(data->srcX), n); + swaps(&(data->srcY), n); +} + +void XETSwWarpPointer(register xWarpPointerReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->srcWid), n); + swapl(&(data->dstWid), n); + swaps(&(data->srcX), n); + swaps(&(data->srcY), n); + swaps(&(data->srcWidth), n); + swaps(&(data->srcHeight), n); + swaps(&(data->dstX), n); + swaps(&(data->dstY), n); +} + +void XETSwSetInputFocus(register xSetInputFocusReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->focus), n); + swapl(&(data->time), n); +} + +void XETSwOpenFont(register xOpenFontReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->fid), n); + swaps(&(data->nbytes), n); +} + +void XETSwListFonts(register xListFontsReq *data) +{ + register char n; + swaps(&(data->length), n); + swaps(&(data->maxNames), n); + swaps(&(data->nbytes), n); +} + +void XETSwListFontsWithInfo(register xListFontsWithInfoReq *data) +{ + register char n; + swaps(&(data->length), n); + swaps(&(data->maxNames), n); + swaps(&(data->nbytes), n); +} + +void XETSwSetFontPath(register xSetFontPathReq *data) +{ + register char n; + swaps(&(data->length), n); + swaps(&(data->nFonts), n); +} + +void XETSwCreatePixmap(register xCreatePixmapReq *data) +{ + register char n; + + swaps(&(data->length), n); + swapl(&(data->pid), n); + swapl(&(data->drawable), n); + swaps(&(data->width), n); + swaps(&(data->height), n); +} + +void XETSwCreateGC(register xCreateGCReq *data, ClientPtr client) +{ + register char n; + swapl(&(data->gc), n); + swapl(&(data->drawable), n); + swapl(&(data->mask), n); + SwapRestL(data); + swaps(&(data->length), n); +} + +void XETSwChangeGC(register xChangeGCReq *data, ClientPtr client) +{ + register char n; + swapl(&(data->gc), n); + swapl(&(data->mask), n); + SwapRestL(data); + swaps(&(data->length), n); +} + +void XETSwCopyGC(register xCopyGCReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->srcGC), n); + swapl(&(data->dstGC), n); + swapl(&(data->mask), n); +} + +void XETSwSetDashes(register xSetDashesReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->gc), n); + swaps(&(data->dashOffset), n); + swaps(&(data->nDashes), n); +} + +void XETSwSetClipRectangles(register xSetClipRectanglesReq *data, ClientPtr +client) +{ + register char n; + swapl(&(data->gc), n); + swaps(&(data->xOrigin), n); + swaps(&(data->yOrigin), n); + SwapRestS(data); + swaps(&(data->length), n); +} + +void XETSwClearToBackground(register xClearAreaReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->window), n); + swaps(&(data->x), n); + swaps(&(data->y), n); + swaps(&(data->width), n); + swaps(&(data->height), n); +} + +void XETSwCopyArea(register xCopyAreaReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->srcDrawable), n); + swapl(&(data->dstDrawable), n); + swapl(&(data->gc), n); + swaps(&(data->srcX), n); + swaps(&(data->srcY), n); + swaps(&(data->dstX), n); + swaps(&(data->dstY), n); + swaps(&(data->width), n); + swaps(&(data->height), n); +} + +void XETSwCopyPlane(register xCopyPlaneReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->srcDrawable), n); + swapl(&(data->dstDrawable), n); + swapl(&(data->gc), n); + swaps(&(data->srcX), n); + swaps(&(data->srcY), n); + swaps(&(data->dstX), n); + swaps(&(data->dstY), n); + swaps(&(data->width), n); + swaps(&(data->height), n); + swapl(&(data->bitPlane), n); +} + +/* The following routine is used for all Poly drawing requests + (except FillPoly, which uses a different request format) */ +void XETSwPoly(register xPolyPointReq *data, ClientPtr client) +{ + register char n; + + swapl(&(data->drawable), n); + swapl(&(data->gc), n); + SwapRestS(data); + swaps(&(data->length), n); +} + /* cannot use XETSwPoly for this one, because xFillPolyReq + * is longer than xPolyPointReq, and we don't want to swap + * the difference as shorts! + */ +void XETSwFillPoly(register xFillPolyReq *data, ClientPtr client) +{ + register char n; + + swapl(&(data->drawable), n); + swapl(&(data->gc), n); + SwapRestS(data); + swaps(&(data->length), n); +} + +void XETSwPutImage(register xPutImageReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->drawable), n); + swapl(&(data->gc), n); + swaps(&(data->width), n); + swaps(&(data->height), n); + swaps(&(data->dstX), n); + swaps(&(data->dstY), n); + /* Image should already be swapped */ +} + +void XETSwGetImage(register xGetImageReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->drawable), n); + swaps(&(data->x), n); + swaps(&(data->y), n); + swaps(&(data->width), n); + swaps(&(data->height), n); + swapl(&(data->planeMask), n); +} + +/* ProcPolyText used for both PolyText8 and PolyText16 */ + +void XETSwPolyText(register xPolyTextReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->drawable), n); + swapl(&(data->gc), n); + swaps(&(data->x), n); + swaps(&(data->y), n); +} + +/* ProcImageText used for both ImageText8 and ImageText16 */ + +void XETSwImageText(register xImageTextReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->drawable), n); + swapl(&(data->gc), n); + swaps(&(data->x), n); + swaps(&(data->y), n); +} + +void XETSwCreateColormap(register xCreateColormapReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->mid), n); + swapl(&(data->window), n); + swapl(&(data->visual), n); +} + + +void XETSwCopyColormapAndFree(register xCopyColormapAndFreeReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->mid), n); + swapl(&(data->srcCmap), n); + +} + +void XETSwAllocColor (register xAllocColorReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->cmap), n); + swaps(&(data->red), n); + swaps(&(data->green), n); + swaps(&(data->blue), n); +} + +void XETSwAllocNamedColor (register xAllocNamedColorReq *data) +{ + register char n; + + swaps(&(data->length), n); + swapl(&(data->cmap), n); + swaps(&(data->nbytes), n); +} + +void XETSwAllocColorCells (register xAllocColorCellsReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->cmap), n); + swaps(&(data->colors), n); + swaps(&(data->planes), n); +} + +void XETSwAllocColorPlanes(register xAllocColorPlanesReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->cmap), n); + swaps(&(data->colors), n); + swaps(&(data->red), n); + swaps(&(data->green), n); + swaps(&(data->blue), n); +} + +void XETSwFreeColors (register xFreeColorsReq *data, ClientPtr +client) +{ + register char n; + swapl(&(data->cmap), n); + swapl(&(data->planeMask), n); + SwapRestL(data); + swaps(&(data->length), n); + +} + +void XETSwStoreColors (register xStoreColorsReq *data,ClientPtr +client) +{ + register char n; + unsigned long count; + xColorItem *pItem; + + swapl(&(data->cmap), n); + pItem = (xColorItem *) &(data[1]); + for(count = LengthRestB(data)/sizeof(xColorItem); count != 0; count--) + SwapColorItem(pItem++); + swaps(&(data->length), n); +} + +void XETSwStoreNamedColor (register xStoreNamedColorReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->cmap), n); + swapl(&(data->pixel), n); + swaps(&(data->nbytes), n); +} + +void XETSwQueryColors(register xQueryColorsReq *data, ClientPtr client) +{ + register char n; + swapl(&(data->cmap), n); + SwapRestL(data); + swaps(&(data->length), n); +} + +void XETSwLookupColor(register xLookupColorReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->cmap), n); + swaps(&(data->nbytes), n); +} + +void XETSwCreateCursor(register xCreateCursorReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->cid), n); + swapl(&(data->source), n); + swapl(&(data->mask), n); + swaps(&(data->foreRed), n); + swaps(&(data->foreGreen), n); + swaps(&(data->foreBlue), n); + swaps(&(data->backRed), n); + swaps(&(data->backGreen), n); + swaps(&(data->backBlue), n); + swaps(&(data->x), n); + swaps(&(data->y), n); +} + +void XETSwCreateGlyphCursor(register xCreateGlyphCursorReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->cid), n); + swapl(&(data->source), n); + swapl(&(data->mask), n); + swaps(&(data->sourceChar), n); + swaps(&(data->maskChar), n); + swaps(&(data->foreRed), n); + swaps(&(data->foreGreen), n); + swaps(&(data->foreBlue), n); + swaps(&(data->backRed), n); + swaps(&(data->backGreen), n); + swaps(&(data->backBlue), n); +} + + +void XETSwRecolorCursor(register xRecolorCursorReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->cursor), n); + swaps(&(data->foreRed), n); + swaps(&(data->foreGreen), n); + swaps(&(data->foreBlue), n); + swaps(&(data->backRed), n); + swaps(&(data->backGreen), n); + swaps(&(data->backBlue), n); +} + +void XETSwQueryBestSize (register xQueryBestSizeReq *data) +{ + register char n; + swaps(&(data->length), n); + swapl(&(data->drawable), n); + swaps(&(data->width), n); + swaps(&(data->height), n); + +} + +void XETSwQueryExtension (register xQueryExtensionReq *data) +{ + register char n; + swaps(&(data->length), n); + swaps(&(data->nbytes), n); +} + +void XETSwChangeKeyboardMapping (register xChangeKeyboardMappingReq *data) +{ + register char n; + register long *p; + register int i, count; + + swaps(&(data->length), n); + p = (long *)&(data[1]); + count = data->keyCodes * data->keySymsPerKeyCode; + for(i = 0; i < count; i++) + { + swapl(p, n); + p++; + } +} + + +void XETSwChangeKeyboardControl (register xChangeKeyboardControlReq *data, + ClientPtr client) +{ + register char n; + swapl(&(data->mask), n); + SwapRestL(data); + swaps(&(data->length), n); +} + +void XETSwChangePointerControl (register xChangePointerControlReq *data) +{ + register char n; + swaps(&(data->length), n); + swaps(&(data->accelNum), n); + swaps(&(data->accelDenum), n); + swaps(&(data->threshold), n); +} + + +void XETSwSetScreenSaver (register xSetScreenSaverReq *data) +{ + register char n; + swaps(&(data->length), n); + swaps(&(data->timeout), n); + swaps(&(data->interval), n); +} + +void XETSwChangeHosts(register xChangeHostsReq *data) +{ + register char n; + + swaps(&(data->length), n); + swaps(&(data->hostLength), n); + +} +void XETSwRotateProperties(register xRotatePropertiesReq *data, ClientPtr client) +{ + register char n; + swapl(&(data->window), n); + swaps(&(data->nAtoms), n); + swaps(&(data->nPositions), n); + SwapRestL(data); + swaps(&(data->length), n); +} + +/*ARGSUSED*/ +void XETSwNoOperation(xReq *data) +{ + /* noop -- don't do anything */ +} + +/* Byte swap a list of longs */ +#if defined vms && !defined MITR5 +#ifndef LINKED_IN +void SwapLongs ( register long *list, register unsigned long count) +{ + register char n; + + while (count >= 8) { + swapl(list+0, n); + swapl(list+1, n); + swapl(list+2, n); + swapl(list+3, n); + swapl(list+4, n); + swapl(list+5, n); + swapl(list+6, n); + swapl(list+7, n); + list += 8; + count -= 8; + } + if (count != 0) { + do { + swapl(list, n); + list++; + } while (--count != 0); + } +} + +/* Byte swap a list of shorts */ + +void SwapShorts (register short *list, register unsigned long count) +{ + register char n; + + while (count >= 16) { + swaps(list+0, n); + swaps(list+1, n); + swaps(list+2, n); + swaps(list+3, n); + swaps(list+4, n); + swaps(list+5, n); + swaps(list+6, n); + swaps(list+7, n); + swaps(list+8, n); + swaps(list+9, n); + swaps(list+10, n); + swaps(list+11, n); + swaps(list+12, n); + swaps(list+13, n); + swaps(list+14, n); + swaps(list+15, n); + list += 16; + count -= 16; + } + if (count != 0) { + do { + swaps(list, n); + list++; + } while (--count != 0); + } +} + +SwapColorItem(xColorItem *pItem) +{ + register char n; + swapl(&pItem->pixel, n); + swaps(&pItem->red, n); + swaps(&pItem->green, n); + swaps(&pItem->blue, n); +} +#endif /* LINKED_IN */ +#endif /* vms */ diff --git a/XTrap/xtrapditbl.c b/XTrap/xtrapditbl.c new file mode 100644 index 000000000..db06e1cc2 --- /dev/null +++ b/XTrap/xtrapditbl.c @@ -0,0 +1,238 @@ +/* $XFree86: xc/programs/Xserver/XTrap/xtrapditbl.c,v 1.1 2001/11/02 23:29:29 dawes Exp $ */ +/**************************************************************************** +Copyright 1987, 1988, 1989, 1990, 1991 by Digital Equipment Corp., Maynard, MA + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*****************************************************************************/ +/* + * ABSTRACT: + * + * This module is contains Vector tables used for swapping and general + * dispatch by the XTrap server extension. + * + * CONTRIBUTORS: + * + * Ken Miller + * Marc Evans + * + */ + +/*-----------------* + * Include Files * + *-----------------*/ +#include <X11/X.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include <X11/Xproto.h> +#include <X11/Xprotostr.h> +#include <X11/extensions/xtrapdi.h> +#include "input.h" /* Server DevicePtr definitions */ +#include "misc.h" +#include "dixstruct.h" +#ifdef PC +# include "extnsist.h" +#else +# include "extnsionst.h" /* Server ExtensionEntry definitions */ +#endif +#include <X11/extensions/xtrapddmi.h> +#include <X11/extensions/xtrapproto.h> + +globaldef void_function XETSwProcVector[256L] = +{ + (void_function)ProcBadRequest, + XETSwCreateWindow, + XETSwChangeWindowAttributes, + XETSwResourceReq, /* GetWindowAttributes */ + XETSwResourceReq, /* DestroyWindow */ + XETSwResourceReq, /* 5 DestroySubwindows */ + XETSwResourceReq, /* XETSwChangeSaveSet, */ + XETSwReparentWindow, + XETSwResourceReq, /* MapWindow */ + XETSwResourceReq, /* MapSubwindows */ + XETSwResourceReq, /* 10 UnmapWindow */ + XETSwResourceReq, /* UnmapSubwindows */ + XETSwConfigureWindow, + XETSwResourceReq, /* XETSwCirculateWindow, */ + XETSwResourceReq, /* GetGeometry */ + XETSwResourceReq, /* 15 QueryTree */ + XETSwInternAtom, + XETSwResourceReq, /* XETSwGetAtomName, */ + XETSwChangeProperty, + XETSwDeleteProperty, + XETSwGetProperty, /* 20 */ + XETSwResourceReq, /* XETSwListProperties, */ + XETSwSetSelectionOwner, + XETSwResourceReq, /* XETSwGetSelectionOwner, */ + XETSwConvertSelection, + XETSwSendEvent, /* 25 */ + XETSwGrabPointer, + XETSwResourceReq, /* XETSwUngrabPointer, */ + XETSwGrabButton, + XETSwUngrabButton, + XETSwChangeActivePointerGrab, /* 30 */ + XETSwGrabKeyboard, + XETSwResourceReq, /* XETSwUngrabKeyboard, */ + XETSwGrabKey, + XETSwUngrabKey, + XETSwResourceReq, /* 35 XETSwAllowEvents, */ + XETSwSimpleReq, /* XETSwGrabServer, */ + XETSwSimpleReq, /* XETSwUngrabServer, */ + XETSwResourceReq, /* XETSwQueryPointer, */ + XETSwGetMotionEvents, + XETSwTranslateCoords, /*40 */ + XETSwWarpPointer, + XETSwSetInputFocus, + XETSwSimpleReq, /* XETSwGetInputFocus, */ + XETSwSimpleReq, /* QueryKeymap, */ + XETSwOpenFont, /* 45 */ + XETSwResourceReq, /* XETSwCloseFont, */ + XETSwResourceReq, /* XETSwQueryFont, */ + XETSwResourceReq, /* XETSwQueryTextExtents, */ + XETSwListFonts, + XETSwListFontsWithInfo, /* 50 */ + XETSwSetFontPath, + XETSwSimpleReq, /* GetFontPath, */ + XETSwCreatePixmap, + XETSwResourceReq, /* XETSwFreePixmap, */ + XETSwCreateGC, /* 55 */ + XETSwChangeGC, + XETSwCopyGC, + XETSwSetDashes, + XETSwSetClipRectangles, + XETSwResourceReq, /* 60 XETSwFreeGC, */ + XETSwClearToBackground, + XETSwCopyArea, + XETSwCopyPlane, + XETSwPoly, /* PolyPoint, */ + XETSwPoly, /* 65 PolyLine */ + XETSwPoly, /* PolySegment, */ + XETSwPoly, /* PolyRectangle, */ + XETSwPoly, /* PolyArc, */ + XETSwFillPoly, + XETSwPoly, /* 70 PolyFillRectangle */ + XETSwPoly, /* PolyFillArc, */ + XETSwPutImage, + XETSwGetImage, + XETSwPolyText, + XETSwPolyText, /* 75 */ + XETSwImageText, + XETSwImageText, + XETSwCreateColormap, + XETSwResourceReq, /* XETSwFreeColormap, */ + XETSwCopyColormapAndFree, /* 80 */ + XETSwResourceReq, /* XETSwInstallColormap, */ + XETSwResourceReq, /* XETSwUninstallColormap, */ + XETSwResourceReq, /* XETSwListInstalledColormaps, */ + XETSwAllocColor, + XETSwAllocNamedColor, /* 85 */ + XETSwAllocColorCells, + XETSwAllocColorPlanes, + XETSwFreeColors, + XETSwStoreColors, + XETSwStoreNamedColor, /* 90 */ + XETSwQueryColors, + XETSwLookupColor, + XETSwCreateCursor, + XETSwCreateGlyphCursor, + XETSwResourceReq, /* 95 XETSwFreeCursor, */ + XETSwRecolorCursor, + XETSwQueryBestSize, + XETSwQueryExtension, + XETSwSimpleReq, /* ListExtensions, */ + XETSwChangeKeyboardMapping, /* 100 */ + XETSwSimpleReq, /* GetKeyboardMapping, */ + XETSwChangeKeyboardControl, + XETSwSimpleReq, /* GetKeyboardControl, */ + XETSwSimpleReq, /* Bell, */ + XETSwChangePointerControl, /* 105 */ + XETSwSimpleReq, /* GetPointerControl, */ + XETSwSetScreenSaver, + XETSwSimpleReq, /* GetScreenSaver, */ + XETSwChangeHosts, + XETSwSimpleReq, /* 110 ListHosts, */ + XETSwSimpleReq, /* XETSwChangeAccessControl, */ + XETSwSimpleReq, /* XETSwChangeCloseDownMode, */ + XETSwResourceReq, /* XETSwKillClient, */ + XETSwRotateProperties, + XETSwSimpleReq, /* 115 ForceScreenSaver */ + XETSwSimpleReq, /* SetPointerMapping, */ + XETSwSimpleReq, /* GetPointerMapping, */ + XETSwSimpleReq, /* SetModifierMapping, */ + XETSwSimpleReq, /* GetModifierMapping, */ + NotImplemented, /* 120 */ + NotImplemented, + NotImplemented, + NotImplemented, + NotImplemented, + NotImplemented, /* 125 */ + NotImplemented, + XETSwNoOperation +}; + +/* NOTE: This array must align with the values of the constants used + * as minor_opcode values in the request structure. Failure to do this + * could result in random code paths. + */ +globaldef int_function XETrapDispatchVector[10L] = +{ + XETrapReset, /* 0 XETrap_Reset */ + XETrapGetAvailable, /* 1 XETrap_GetAvailable */ + XETrapConfig, /* 2 XETrap_Config */ + XETrapStartTrap, /* 3 XETrap_StartTrap */ + XETrapStopTrap, /* 4 XETrap_StopTrap */ + XETrapGetCurrent, /* 5 XETrap_GetCurrent */ + XETrapGetStatistics, /* 6 XETrap_GetStatistics */ +#ifndef _XINPUT + XETrapSimulateXEvent, /* 7 XETrap_SimulateXEvent */ +#endif + XETrapGetVersion, /* 8 XETrap_GetVersion */ + XETrapGetLastInpTime, /* 9 XETrap_GetLastInpTime */ +}; + +/* NOTE: This array must align with the values of the constants used + * as minor_opcode values in the request structure. Failure to do this + * could result in random code paths. + */ +globaldef int_function XETSwDispatchVector[10L] = +{ + sXETrapReset, /* 0 XETrap_Reset */ + sXETrapGetAvailable, /* 1 XETrap_GetAvailable */ + sXETrapConfig, /* 2 XETrap_Config */ + sXETrapStartTrap, /* 3 XETrap_StartTrap */ + sXETrapStopTrap, /* 4 XETrap_StopTrap */ + sXETrapGetCurrent, /* 5 XETrap_GetCurrent */ + sXETrapGetStatistics, /* 6 XETrap_GetStatistics */ +#ifndef _XINPUT + sXETrapSimulateXEvent, /* 7 XETrap_SimulateXEvent */ +#endif + sXETrapGetVersion, /* 8 XETrap_GetVersion */ + sXETrapGetLastInpTime, /* 9 XETrap_GetLastInpTime */ +}; + +/* ProcVector shadow vector */ +globaldef int_function XETrapProcVector[256L] = {XETrapRequestVector}; +/* + * Events are faked as if they're vectored since that's + * the way it'll eventually be (X11 R5?). + */ +#ifndef VECTORED_EVENTS +globaldef int_function EventProcVector[XETrapCoreEvents] = {NULL}; +#endif +globaldef int_function XETrapEventProcVector[XETrapCoreEvents] = {NULL}; + + |