2003-11-14 16:54:54 +01:00
|
|
|
/* $Xorg: xtest1di.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
|
|
|
|
/*
|
|
|
|
* File: xtest1di.c
|
|
|
|
*
|
|
|
|
* This file contains the device independent parts of the input
|
|
|
|
* synthesis extension.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
|
|
Copyright 1986, 1987, 1988, 1998 The Open Group
|
|
|
|
|
|
|
|
Permission to use, copy, modify, distribute, and sell this software and its
|
|
|
|
documentation for any purpose is hereby granted without fee, provided that
|
|
|
|
the above copyright notice appear in all copies and that both that
|
|
|
|
copyright notice and this permission notice appear in supporting
|
|
|
|
documentation.
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
|
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
Except as contained in this notice, the name of The Open Group shall not be
|
|
|
|
used in advertising or otherwise to promote the sale, use or other dealings
|
|
|
|
in this Software without prior written authorization from The Open Group.
|
|
|
|
|
|
|
|
|
|
|
|
Copyright 1986, 1987, 1988 by Hewlett-Packard Corporation
|
|
|
|
|
|
|
|
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 Hewlett-Packard not be used in
|
|
|
|
advertising or publicity pertaining to distribution of the
|
|
|
|
software without specific, written prior permission.
|
|
|
|
|
|
|
|
Hewlett-Packard makes no representations about the
|
|
|
|
suitability of this software for any purpose. It is provided
|
|
|
|
"as is" without express or implied warranty.
|
|
|
|
|
|
|
|
This software is not subject to any license of the American
|
|
|
|
Telephone and Telegraph Company or of the Regents of the
|
|
|
|
University of California.
|
|
|
|
|
|
|
|
*/
|
2003-11-14 17:49:22 +01:00
|
|
|
/* $XFree86: xc/programs/Xserver/Xext/xtest1di.c,v 3.3 2001/12/14 19:58:52 dawes Exp $ */
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* include files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#define NEED_EVENTS
|
|
|
|
#define NEED_REPLIES
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "X.h"
|
|
|
|
#include "Xproto.h"
|
|
|
|
#include "misc.h"
|
|
|
|
#include "os.h"
|
|
|
|
#include "gcstruct.h"
|
|
|
|
#include "extnsionst.h"
|
|
|
|
#include "dixstruct.h"
|
|
|
|
#include "opaque.h"
|
|
|
|
#define XTestSERVER_SIDE
|
|
|
|
#include "xtestext1.h"
|
|
|
|
|
2003-11-14 17:49:22 +01:00
|
|
|
#include "xtest1dd.h"
|
|
|
|
|
2003-11-14 16:54:54 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* defines
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* externals
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* id of client using XTestGetInput
|
|
|
|
*
|
|
|
|
* defined in xtest1dd.c
|
|
|
|
*/
|
|
|
|
extern ClientPtr current_xtest_client;
|
|
|
|
/*
|
|
|
|
* id of client using XTestFakeInput
|
|
|
|
*
|
|
|
|
* defined in xtest1dd.c
|
|
|
|
*/
|
|
|
|
extern ClientPtr playback_client;
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* variables
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Holds the request type code for this extension. The request type code
|
|
|
|
* for this extension may vary depending on how many extensions are installed
|
|
|
|
* already, so the initial value given below will be added to the base request
|
|
|
|
* code that is aquired when this extension is installed.
|
|
|
|
*/
|
|
|
|
static int XTestReqCode = 0;
|
|
|
|
/*
|
|
|
|
* Holds the two event type codes for this extension. The event type codes
|
|
|
|
* for this extension may vary depending on how many extensions are installed
|
|
|
|
* already, so the initial values given below will be added to the base event
|
|
|
|
* code that is aquired when this extension is installed.
|
|
|
|
*/
|
|
|
|
int XTestInputActionType = 0;
|
|
|
|
int XTestFakeAckType = 1;
|
|
|
|
/*
|
|
|
|
* true => monitor stealing input
|
|
|
|
*/
|
|
|
|
int on_steal_input = FALSE;
|
|
|
|
/*
|
|
|
|
* true => monitor alone getting input
|
|
|
|
*/
|
|
|
|
int exclusive_steal = FALSE;
|
|
|
|
/*
|
|
|
|
* holds the resource type assigned to this extension
|
|
|
|
*/
|
|
|
|
static RESTYPE XTestType;
|
|
|
|
/*
|
|
|
|
* holds the resource ID for the client currently using XTestGetInput
|
|
|
|
*/
|
|
|
|
static XID current_client_id;
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* function declarations
|
|
|
|
****************************************************************************/
|
|
|
|
|
2003-11-14 17:49:22 +01:00
|
|
|
static DISPATCH_PROC(ProcXTestDispatch);
|
|
|
|
static DISPATCH_PROC(SProcXTestDispatch);
|
|
|
|
static DISPATCH_PROC(ProcTestFakeInput);
|
|
|
|
static DISPATCH_PROC(SProcTestFakeInput);
|
|
|
|
static DISPATCH_PROC(ProcTestGetInput);
|
|
|
|
static DISPATCH_PROC(SProcTestGetInput);
|
|
|
|
static DISPATCH_PROC(ProcTestStopInput);
|
|
|
|
static DISPATCH_PROC(SProcTestStopInput);
|
|
|
|
static DISPATCH_PROC(ProcTestReset);
|
|
|
|
static DISPATCH_PROC(SProcTestReset);
|
|
|
|
static DISPATCH_PROC(ProcTestQueryInputSize);
|
|
|
|
static DISPATCH_PROC(SProcTestQueryInputSize);
|
|
|
|
|
|
|
|
static void XTestResetProc(
|
|
|
|
#if NeedFunctionPrototypes
|
|
|
|
ExtensionEntry * /* unused */
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
static void SReplyXTestDispatch(
|
|
|
|
#if NeedFunctionPrototypes
|
|
|
|
ClientPtr /* client_ptr */,
|
|
|
|
int /* size */,
|
|
|
|
char * /* reply_ptr */
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
static void SEventXTestDispatch(
|
|
|
|
#if NeedFunctionPrototypes
|
|
|
|
xEvent * /* from */,
|
|
|
|
xEvent * /* to */
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
|
|
|
|
static int XTestCurrentClientGone(
|
|
|
|
#if NeedFunctionPrototypes
|
|
|
|
pointer /* value */,
|
|
|
|
XID /* id */
|
|
|
|
#endif
|
|
|
|
);
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* XTestExtension1Init
|
|
|
|
*
|
|
|
|
* Called from InitExtensions in main() or from QueryExtension() if the
|
|
|
|
* extension is dynamically loaded.
|
|
|
|
*
|
|
|
|
* XTestExtension1Init has no events or errors
|
|
|
|
* (other than the core errors).
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
XTestExtension1Init()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* holds the pointer to the extension entry structure
|
|
|
|
*/
|
|
|
|
ExtensionEntry *extEntry;
|
|
|
|
|
|
|
|
extEntry = AddExtension(XTestEXTENSION_NAME,
|
|
|
|
XTestEVENT_COUNT,
|
|
|
|
0,
|
|
|
|
ProcXTestDispatch,
|
|
|
|
SProcXTestDispatch,
|
|
|
|
XTestResetProc,
|
|
|
|
StandardMinorOpcode);
|
|
|
|
if (extEntry)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* remember the request code assigned to this extension
|
|
|
|
*/
|
|
|
|
XTestReqCode = extEntry->base;
|
|
|
|
/*
|
|
|
|
* make an atom saying that this extension is present
|
|
|
|
*/
|
|
|
|
(void) MakeAtom(XTestEXTENSION_NAME,
|
|
|
|
strlen(XTestEXTENSION_NAME),
|
|
|
|
TRUE);
|
|
|
|
/*
|
|
|
|
* remember the event codes assigned to this extension
|
|
|
|
*/
|
|
|
|
XTestInputActionType += extEntry->eventBase;
|
|
|
|
XTestFakeAckType += extEntry->eventBase;
|
|
|
|
/*
|
|
|
|
* install the routine to handle byte-swapping the replies
|
|
|
|
* for this extension in the ReplySwapVector table
|
|
|
|
*/
|
2003-11-14 17:49:22 +01:00
|
|
|
ReplySwapVector[XTestReqCode] = (ReplySwapPtr) SReplyXTestDispatch;
|
2003-11-14 16:54:54 +01:00
|
|
|
/*
|
|
|
|
* install the routine to handle byte-swapping the events
|
|
|
|
* for this extension in the EventSwapVector table
|
|
|
|
*/
|
|
|
|
EventSwapVector[XTestInputActionType] = SEventXTestDispatch;
|
|
|
|
EventSwapVector[XTestFakeAckType] = SEventXTestDispatch;
|
|
|
|
/*
|
|
|
|
* get the resource type for this extension
|
|
|
|
*/
|
|
|
|
XTestType = CreateNewResourceType(XTestCurrentClientGone);
|
|
|
|
if (XTestType == 0)
|
|
|
|
{
|
|
|
|
FatalError("XTestExtension1Init: CreateNewResourceType failed\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FatalError("XTestExtension1Init: AddExtensions failed\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* ProcXTestDispatch
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ProcXTestDispatch(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
REQUEST(xReq);
|
|
|
|
if (stuff->data == X_TestFakeInput)
|
|
|
|
{
|
|
|
|
return(ProcTestFakeInput(client));
|
|
|
|
}
|
|
|
|
else if (stuff->data == X_TestGetInput)
|
|
|
|
{
|
|
|
|
return(ProcTestGetInput(client));
|
|
|
|
}
|
|
|
|
else if (stuff->data == X_TestStopInput)
|
|
|
|
{
|
|
|
|
return(ProcTestStopInput(client));
|
|
|
|
}
|
|
|
|
else if (stuff->data == X_TestReset)
|
|
|
|
{
|
|
|
|
return(ProcTestReset(client));
|
|
|
|
}
|
|
|
|
else if (stuff->data == X_TestQueryInputSize)
|
|
|
|
{
|
|
|
|
return(ProcTestQueryInputSize(client));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SendErrorToClient(client,
|
|
|
|
XTestReqCode,
|
|
|
|
stuff->data,
|
|
|
|
None,
|
|
|
|
BadRequest);
|
|
|
|
return(BadRequest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* SProcXTestDispatch
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
SProcXTestDispatch(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
REQUEST(xReq);
|
|
|
|
if (stuff->data == X_TestFakeInput)
|
|
|
|
{
|
|
|
|
return(SProcTestFakeInput(client));
|
|
|
|
}
|
|
|
|
else if (stuff->data == X_TestGetInput)
|
|
|
|
{
|
|
|
|
return(SProcTestGetInput(client));
|
|
|
|
}
|
|
|
|
else if (stuff->data == X_TestStopInput)
|
|
|
|
{
|
|
|
|
return(SProcTestStopInput(client));
|
|
|
|
}
|
|
|
|
else if (stuff->data == X_TestReset)
|
|
|
|
{
|
|
|
|
return(SProcTestReset(client));
|
|
|
|
}
|
|
|
|
else if (stuff->data == X_TestQueryInputSize)
|
|
|
|
{
|
|
|
|
return(SProcTestQueryInputSize(client));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SendErrorToClient(client,
|
|
|
|
XTestReqCode,
|
|
|
|
stuff->data,
|
|
|
|
None,
|
|
|
|
BadRequest);
|
|
|
|
return(BadRequest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* SProcTestFakeInput
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
SProcTestFakeInput(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* used in the swaps and swapl macros for temporary storage space
|
|
|
|
*/
|
|
|
|
register char n;
|
|
|
|
/*
|
|
|
|
* index counter
|
|
|
|
*/
|
|
|
|
int i;
|
|
|
|
/*
|
|
|
|
* pointer to the next input action in the request
|
|
|
|
*/
|
|
|
|
CARD8 *input_action_ptr;
|
|
|
|
/*
|
|
|
|
* holds the type of the next input action in the request
|
|
|
|
*/
|
|
|
|
int input_action_type;
|
|
|
|
|
|
|
|
REQUEST(xTestFakeInputReq);
|
|
|
|
/*
|
|
|
|
* byte-swap the fields in the request
|
|
|
|
*/
|
|
|
|
swaps(&stuff->length, n);
|
|
|
|
swapl(&stuff->ack, n);
|
|
|
|
/*
|
|
|
|
* have to parse and then byte-swap the input action list here
|
|
|
|
*/
|
|
|
|
for (i = 0; i < XTestMAX_ACTION_LIST_SIZE;)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* point to the next input action in the request
|
|
|
|
*/
|
|
|
|
input_action_ptr = &(((xTestFakeInputReq *) stuff)->action_list[i]);
|
|
|
|
/*
|
|
|
|
* figure out what type of input action it is
|
|
|
|
*/
|
|
|
|
input_action_type = (*input_action_ptr) & XTestACTION_TYPE_MASK;
|
|
|
|
/*
|
|
|
|
* byte-swap the input action according to it's type
|
|
|
|
*/
|
|
|
|
switch (input_action_type)
|
|
|
|
{
|
|
|
|
case XTestKEY_ACTION:
|
|
|
|
/*
|
|
|
|
* byte-swap the delay_time field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestKeyInfo *) input_action_ptr)->delay_time), n);
|
|
|
|
/*
|
|
|
|
* advance to the next input action
|
|
|
|
*/
|
|
|
|
i += sizeof(XTestKeyInfo);
|
|
|
|
break;
|
|
|
|
case XTestMOTION_ACTION:
|
|
|
|
/*
|
|
|
|
* byte-swap the delay_time field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestMotionInfo *) input_action_ptr)->delay_time), n);
|
|
|
|
/*
|
|
|
|
* advance to the next input action
|
|
|
|
*/
|
|
|
|
i += sizeof(XTestMotionInfo);
|
|
|
|
break;
|
|
|
|
case XTestJUMP_ACTION:
|
|
|
|
/*
|
|
|
|
* byte-swap the jumpx field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpx), n);
|
|
|
|
/*
|
|
|
|
* byte-swap the jumpy field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpy), n);
|
|
|
|
/*
|
|
|
|
* byte-swap the delay_time field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestJumpInfo *) input_action_ptr)->delay_time), n);
|
|
|
|
/*
|
|
|
|
* advance to the next input action
|
|
|
|
*/
|
|
|
|
i += sizeof(XTestJumpInfo);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/*
|
|
|
|
* if this is a delay input action, then byte-swap it,
|
|
|
|
* otherwise we have reached the end of the input
|
|
|
|
* actions in this request
|
|
|
|
*/
|
|
|
|
if (XTestUnpackDeviceID(*input_action_ptr) ==
|
|
|
|
XTestDELAY_DEVICE_ID)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* byte-swap the delay_time field
|
|
|
|
*/
|
|
|
|
swapl(&(((XTestDelayInfo *) input_action_ptr)->delay_time), n);
|
|
|
|
/*
|
|
|
|
* advance to the next input action
|
|
|
|
*/
|
|
|
|
i += sizeof(XTestDelayInfo);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* if the input action header byte is 0 or
|
|
|
|
* ill-formed, then there are no more input
|
|
|
|
* actions in this request
|
|
|
|
*/
|
|
|
|
i = XTestMAX_ACTION_LIST_SIZE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(ProcTestFakeInput(client));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* SProcTestGetInput
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
SProcTestGetInput(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* used in the swaps and swapl macros for temporary storage space
|
|
|
|
*/
|
|
|
|
register char n;
|
|
|
|
|
|
|
|
REQUEST(xTestGetInputReq);
|
|
|
|
/*
|
|
|
|
* byte-swap the fields in the request
|
|
|
|
*/
|
|
|
|
swaps(&stuff->length, n);
|
|
|
|
swapl(&stuff->mode, n);
|
|
|
|
return(ProcTestGetInput(client));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* SProcTestStopInput
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
SProcTestStopInput(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* used in the swaps and swapl macros for temporary storage space
|
|
|
|
*/
|
|
|
|
register char n;
|
|
|
|
|
|
|
|
REQUEST(xTestStopInputReq);
|
|
|
|
/*
|
|
|
|
* byte-swap the length field in the request
|
|
|
|
*/
|
|
|
|
swaps(&stuff->length, n);
|
|
|
|
return(ProcTestStopInput(client));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* SProcTestReset
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
SProcTestReset(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* used in the swaps and swapl macros for temporary storage space
|
|
|
|
*/
|
|
|
|
register char n;
|
|
|
|
|
|
|
|
REQUEST(xTestResetReq);
|
|
|
|
/*
|
|
|
|
* byte-swap the length field in the request
|
|
|
|
*/
|
|
|
|
swaps(&stuff->length, n);
|
|
|
|
return(ProcTestReset(client));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* SProcTestQueryInputSize
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
SProcTestQueryInputSize(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* used in the swaps and swapl macros for temporary storage space
|
|
|
|
*/
|
|
|
|
register char n;
|
|
|
|
|
|
|
|
REQUEST(xTestQueryInputSizeReq);
|
|
|
|
/*
|
|
|
|
* byte-swap the length field in the request
|
|
|
|
*/
|
|
|
|
swaps(&stuff->length, n);
|
|
|
|
return(ProcTestQueryInputSize(client));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* ProcTestFakeInput
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ProcTestFakeInput(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
REQUEST(xTestFakeInputReq);
|
|
|
|
REQUEST_SIZE_MATCH(xTestFakeInputReq);
|
|
|
|
|
|
|
|
if (playback_client == NULL)
|
|
|
|
{
|
|
|
|
playback_client = client;
|
|
|
|
current_client_id = FakeClientID(client->index);
|
|
|
|
AddResource(current_client_id,
|
|
|
|
XTestType,
|
|
|
|
0);
|
|
|
|
MakeClientGrabImpervious(client);
|
|
|
|
}
|
|
|
|
if (playback_client == client)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* This extension does not need to clean up any
|
|
|
|
* server state when a client using this function
|
|
|
|
* "goes away". The server will just process any
|
|
|
|
* input actions that have already been sent to it,
|
|
|
|
* and will then reset its association with a client.
|
|
|
|
*/
|
|
|
|
parse_fake_input(client, (char *)stuff);
|
|
|
|
return(Success);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* this is a request by another client to send fake
|
|
|
|
* input while the server is still being used
|
|
|
|
*/
|
|
|
|
SendErrorToClient(client,
|
|
|
|
XTestReqCode,
|
|
|
|
X_TestFakeInput,
|
|
|
|
None,
|
|
|
|
BadAccess);
|
|
|
|
return(BadAccess);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* ProcTestGetInput
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ProcTestGetInput(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
REQUEST(xTestGetInputReq);
|
|
|
|
REQUEST_SIZE_MATCH(xTestGetInputReq);
|
|
|
|
if (on_steal_input)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* this is a request by another client to get fake input
|
|
|
|
* while the server is still sending input to the first client
|
|
|
|
*/
|
|
|
|
SendErrorToClient(client,
|
|
|
|
XTestReqCode,
|
|
|
|
X_TestGetInput,
|
|
|
|
None,
|
|
|
|
BadAccess);
|
|
|
|
return(BadAccess);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Set up a resource associated with the client using this
|
|
|
|
* function so that this extension gets called when the
|
|
|
|
* client "goes away". This allows this extension to
|
|
|
|
* clean up the server state.
|
|
|
|
*/
|
|
|
|
current_client_id = FakeClientID(client->index);
|
|
|
|
AddResource(current_client_id,
|
|
|
|
XTestType,
|
|
|
|
0);
|
|
|
|
/*
|
|
|
|
* indicate that a client is stealing input
|
|
|
|
*/
|
|
|
|
on_steal_input = TRUE;
|
|
|
|
if ((stuff->mode & XTestEXCLUSIVE) == 0)
|
|
|
|
{
|
|
|
|
exclusive_steal = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
exclusive_steal = TRUE;
|
|
|
|
}
|
|
|
|
steal_input(client, stuff->mode);
|
|
|
|
return(Success);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* ProcTestStopInput
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ProcTestStopInput(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
REQUEST_SIZE_MATCH(xTestStopInputReq);
|
|
|
|
if (on_steal_input && (current_xtest_client == client))
|
|
|
|
{
|
|
|
|
on_steal_input = FALSE;
|
|
|
|
exclusive_steal = FALSE;
|
|
|
|
stop_stealing_input();
|
|
|
|
/*
|
|
|
|
* remove the resource associated with this client
|
|
|
|
*/
|
|
|
|
FreeResource(current_client_id, RT_NONE);
|
|
|
|
return(Success);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* this is a request to stop fake input when fake input has
|
|
|
|
* never been started or from a client that hasn't started
|
|
|
|
* fake input
|
|
|
|
*/
|
|
|
|
SendErrorToClient(client,
|
|
|
|
XTestReqCode,
|
|
|
|
X_TestStopInput,
|
|
|
|
None,
|
|
|
|
BadAccess);
|
|
|
|
return(BadAccess);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* ProcTestReset
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ProcTestReset(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
REQUEST_SIZE_MATCH(xTestResetReq);
|
|
|
|
on_steal_input = FALSE;
|
|
|
|
exclusive_steal = FALSE;
|
|
|
|
/*
|
|
|
|
* defined in xtest1dd.c
|
|
|
|
*/
|
|
|
|
stop_stealing_input();
|
|
|
|
/*
|
|
|
|
* defined in xtest1dd.c
|
|
|
|
*/
|
|
|
|
abort_play_back();
|
|
|
|
return(Success);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* ProcTestQueryInputSize
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ProcTestQueryInputSize(client)
|
|
|
|
register ClientPtr client;
|
|
|
|
{
|
|
|
|
REQUEST_SIZE_MATCH(xTestQueryInputSizeReq);
|
|
|
|
/*
|
|
|
|
* defined in xtest1dd.c
|
|
|
|
*/
|
|
|
|
return_input_array_size(client);
|
|
|
|
return(Success);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* XTestResetProc
|
|
|
|
*
|
|
|
|
* This function is called by the server when the server has no clients
|
|
|
|
* connected to it. It must put eveything back the way it was before
|
|
|
|
* this extension was installed.
|
|
|
|
*/
|
2003-11-14 17:49:22 +01:00
|
|
|
/*ARGSUSED*/
|
2003-11-14 16:54:54 +01:00
|
|
|
static void
|
2003-11-14 17:49:22 +01:00
|
|
|
XTestResetProc(unused)
|
|
|
|
ExtensionEntry * unused;
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* remove the routine to handle byte-swapping the replies
|
|
|
|
* for this extension in the ReplySwapVector table
|
|
|
|
*/
|
2003-11-14 17:49:22 +01:00
|
|
|
ReplySwapVector[XTestReqCode] = ReplyNotSwappd;
|
2003-11-14 16:54:54 +01:00
|
|
|
/*
|
|
|
|
* remove the routine to handle byte-swapping the events
|
|
|
|
* for this extension in the EventSwapVector table
|
|
|
|
*/
|
|
|
|
EventSwapVector[XTestInputActionType] = NotImplemented;
|
|
|
|
EventSwapVector[XTestFakeAckType] = NotImplemented;
|
|
|
|
/*
|
|
|
|
* reset the variables initialized just once at load time
|
|
|
|
*/
|
|
|
|
XTestReqCode = 0;
|
|
|
|
XTestInputActionType = 0;
|
|
|
|
XTestFakeAckType = 1;
|
|
|
|
on_steal_input = FALSE;
|
|
|
|
exclusive_steal = FALSE;
|
|
|
|
playback_client = 0; /* Don't really need this but it looks nice */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
2003-11-14 17:49:22 +01:00
|
|
|
* PXTestCurrentClientGone
|
2003-11-14 16:54:54 +01:00
|
|
|
*
|
|
|
|
* This routine is called when a client that has asked for input actions
|
|
|
|
* to be sent to it "goes away". This routine must clean up the
|
|
|
|
* server state.
|
|
|
|
*/
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
|
|
|
XTestCurrentClientGone(value, id)
|
|
|
|
pointer value;
|
|
|
|
XID id;
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* defined in xtest1dd.c
|
|
|
|
*/
|
|
|
|
on_steal_input = FALSE;
|
|
|
|
exclusive_steal = FALSE;
|
|
|
|
/*
|
|
|
|
* defined in xtestdd.c
|
|
|
|
*/
|
|
|
|
playback_client = 0;
|
|
|
|
abort_play_back();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* SReplyXTestDispatch
|
|
|
|
*
|
|
|
|
* Swap any replies defined in this extension.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
SReplyXTestDispatch(client_ptr, size, reply_ptr)
|
|
|
|
ClientPtr client_ptr;
|
|
|
|
int size;
|
|
|
|
char *reply_ptr;
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* used in the swaps and swapl macros for temporary storage space
|
|
|
|
*/
|
|
|
|
register char n;
|
|
|
|
/*
|
|
|
|
* pointer to xTestQueryInputSizeReply
|
|
|
|
*/
|
|
|
|
xTestQueryInputSizeReply *rep_ptr;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* there is only one reply in this extension, so byte-swap it
|
|
|
|
*/
|
|
|
|
rep_ptr = (xTestQueryInputSizeReply *) reply_ptr;
|
|
|
|
swaps(&(rep_ptr->sequenceNumber), n);
|
|
|
|
swapl(&(rep_ptr->length), n);
|
|
|
|
swapl(&(rep_ptr->size_return), n);
|
|
|
|
/*
|
|
|
|
* now write the swapped reply to the client
|
|
|
|
*/
|
|
|
|
WriteToClient(client_ptr, size, reply_ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* SEventXTestDispatch
|
|
|
|
*
|
|
|
|
* Swap any events defined in this extension.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
SEventXTestDispatch(from, to)
|
|
|
|
xEvent *from;
|
|
|
|
xEvent *to;
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* used in the swaps and swapl macros for temporary storage space
|
|
|
|
*/
|
|
|
|
register char n;
|
|
|
|
/*
|
|
|
|
* index counter
|
|
|
|
*/
|
|
|
|
int i;
|
|
|
|
/*
|
|
|
|
* pointer to the next input action in the event
|
|
|
|
*/
|
|
|
|
CARD8 *input_action_ptr;
|
|
|
|
/*
|
|
|
|
* holds the type of the next input action in the event
|
|
|
|
*/
|
|
|
|
int input_action_type;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* copy the type information from the "from" event to the "to" event
|
|
|
|
*/
|
|
|
|
((xTestInputActionEvent *) to)->type =
|
|
|
|
((xTestInputActionEvent *) from)->type;
|
|
|
|
/*
|
|
|
|
* copy the sequence number information from the "from" event to the
|
|
|
|
* "to" event
|
|
|
|
*/
|
|
|
|
((xTestInputActionEvent *) to)->sequenceNumber =
|
|
|
|
((xTestInputActionEvent *) from)->sequenceNumber;
|
|
|
|
/*
|
|
|
|
* byte-swap the sequence number in the "to" event
|
|
|
|
*/
|
|
|
|
swaps(&(((xTestInputActionEvent *) to)->sequenceNumber), n);
|
|
|
|
/*
|
|
|
|
* If the event is an xTestInputActionEvent, then it needs more
|
|
|
|
* processing. Otherwise, it is an xTestFakeAckEvent, which
|
|
|
|
* has no other information in it.
|
|
|
|
*/
|
|
|
|
if ((((xTestInputActionEvent *) to)->type & 0x7f) ==
|
|
|
|
XTestInputActionType)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* copy the input actions from the "from" event
|
|
|
|
* to the "to" event
|
|
|
|
*/
|
|
|
|
for (i = 0; i < XTestACTIONS_SIZE; i++)
|
|
|
|
{
|
|
|
|
((xTestInputActionEvent *) to)->actions[i] =
|
|
|
|
((xTestInputActionEvent *) from)->actions[i];
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* byte-swap the input actions in the "to" event
|
|
|
|
*/
|
|
|
|
for (i = 0; i < XTestACTIONS_SIZE; i++)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* point to the next input action in the event
|
|
|
|
*/
|
|
|
|
input_action_ptr = &(((xTestInputActionEvent *) to)->actions[i]);
|
|
|
|
/*
|
|
|
|
* figure out what type of input action it is
|
|
|
|
*/
|
|
|
|
input_action_type = (*input_action_ptr) &
|
|
|
|
XTestACTION_TYPE_MASK;
|
|
|
|
/*
|
|
|
|
* byte-swap the input action according to it's type
|
|
|
|
*/
|
|
|
|
switch (input_action_type)
|
|
|
|
{
|
|
|
|
case XTestKEY_ACTION:
|
|
|
|
/*
|
|
|
|
* byte-swap the delay_time field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestKeyInfo *) input_action_ptr)->delay_time), n);
|
|
|
|
/*
|
|
|
|
* advance to the next input action
|
|
|
|
*/
|
|
|
|
i += sizeof(XTestKeyInfo);
|
|
|
|
break;
|
|
|
|
case XTestMOTION_ACTION:
|
|
|
|
/*
|
|
|
|
* byte-swap the delay_time field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestMotionInfo *) input_action_ptr)->delay_time), n);
|
|
|
|
/*
|
|
|
|
* advance to the next input action
|
|
|
|
*/
|
|
|
|
i += sizeof(XTestMotionInfo);
|
|
|
|
break;
|
|
|
|
case XTestJUMP_ACTION:
|
|
|
|
/*
|
|
|
|
* byte-swap the jumpx field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpx), n);
|
|
|
|
/*
|
|
|
|
* byte-swap the jumpy field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpy), n);
|
|
|
|
/*
|
|
|
|
* byte-swap the delay_time field
|
|
|
|
*/
|
|
|
|
swaps(&(((XTestJumpInfo *) input_action_ptr)->delay_time), n);
|
|
|
|
/*
|
|
|
|
* advance to the next input action
|
|
|
|
*/
|
|
|
|
i += sizeof(XTestJumpInfo);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/*
|
|
|
|
* if this is a delay input action, then
|
|
|
|
* byte-swap it, otherwise we have reached the
|
|
|
|
* end of the input actions in this event
|
|
|
|
*/
|
|
|
|
if (XTestUnpackDeviceID(*input_action_ptr) ==
|
|
|
|
XTestDELAY_DEVICE_ID)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* byte-swap the delay_time field
|
|
|
|
*/
|
|
|
|
swapl(&(((XTestDelayInfo *) input_action_ptr)->delay_time), n);
|
|
|
|
/*
|
|
|
|
* advance to the next input action
|
|
|
|
*/
|
|
|
|
i += sizeof(XTestDelayInfo);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* if the input action header byte is 0
|
|
|
|
* or ill-formed, then there are no
|
|
|
|
* more input actions in this event
|
|
|
|
*/
|
|
|
|
i = XTestACTIONS_SIZE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|