xserver-multidpi/mpx/extinit.c
Peter Hutterer 2a511492f9 Xi: adding MPX checks to ProcessOtherEvents
mpx:    adding QueryPointer request and reply
	adjusting names of requests to Xlib compatible naming (xMPX*** instead of
	mpx***)
2006-12-05 15:45:18 +10:30

300 lines
7.8 KiB
C

/* Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> */
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "inputstr.h"
#include "extnsionst.h" /* extension entry */
#include <X11/extensions/MPX.h>
#include <X11/extensions/MPXproto.h>
#include <X11/extensions/MPXconst.h>
#include "mpxglobals.h"
#include "mpxextinit.h"
#include "swaprep.h"
#include "getvers.h"
#include "listdev.h"
#include "selectev.h"
#include "getevbase.h"
#include "queryptr.h"
static Mask lastExtEventMask = 1;
int MPXEventIndex;
MPXExtEventInfo EventInfo[32];
/**
* MPX piggybacks on the X Input extension's event system. Each window has an
* array of event masks, from 0 to MAX_DEVICES. In XI, each device can have
* separate event masks. Before an event is delivered, the array at the index
* of the device is checked.
*
* Two things:
* -) core devices do not send input extension events
* -) MPX events are not device specific.
*
* Since the mask of the core pointer (index 1) is thus not used by XI, MPX
* can use it for the event mask. This also makes MPX less intrusive.
*/
int MPXmskidx = 1;
/*****************************************************************
*
* Externs defined elsewhere in the X server.
*
*/
extern MPXExtensionVersion AllExtensionVersions[];
Mask PropagateMask[MAX_DEVICES];
/*****************************************************************
*
* Globals referenced elsewhere in the server.
*
*/
int MPXReqCode = 0;
int MPXEventBase = 0;
int MPXErrorBase = 0;
int MPXButtonPress;
int MPXButtonRelease;
int MPXMotionNotify;
int MPXLastEvent;
/*****************************************************************
*
* Declarations of local routines.
*
*/
static MPXExtensionVersion thisversion = {
MPX_Major,
MPX_Minor
};
/**********************************************************************
*
* MPXExtensionInit - initialize the input extension.
*
* Called from InitExtensions in main() or from QueryExtension() if the
* extension is dynamically loaded.
*
* This extension has several events and errors.
*
*/
void
MPXExtensionInit(void)
{
ExtensionEntry *extEntry;
extEntry = AddExtension(MPXNAME, MPXEVENTS, MPXERRORS,
ProcMPXDispatch, SProcMPXDispatch,
MPXResetProc, StandardMinorOpcode);
if (extEntry) {
MPXReqCode = extEntry->base;
MPXEventBase = extEntry->eventBase;
MPXErrorBase = extEntry->errorBase;
AllExtensionVersions[MPXReqCode - 128] = thisversion;
MPXFixExtensionEvents(extEntry);
ReplySwapVector[MPXReqCode] = (ReplySwapPtr) SReplyMPXDispatch;
EventSwapVector[MPXButtonPress] = SEventMPXDispatch;
EventSwapVector[MPXButtonRelease] = SEventMPXDispatch;
EventSwapVector[MPXMotionNotify] = SEventMPXDispatch;
} else {
FatalError("MPXExtensionInit: AddExtensions failed\n");
}
}
/*************************************************************************
*
* ProcMPXDispatch - main dispatch routine for requests to this extension.
* This routine is used if server and client have the same byte ordering.
*
*/
int
ProcMPXDispatch(register ClientPtr client)
{
REQUEST(xReq);
if (stuff->data == X_MPXGetExtensionVersion)
return (ProcMPXGetExtensionVersion(client));
if (stuff->data == X_MPXListDevices)
return (ProcMPXListDevices(client));
if (stuff->data == X_MPXSelectEvents)
return (ProcMPXSelectEvents(client));
if (stuff->data == X_MPXGetEventBase)
return (ProcMPXGetEventBase(client));
if (stuff->data == X_MPXQueryPointer)
return (ProcMPXQueryPointer(client));
else {
SendErrorToClient(client, MPXReqCode, stuff->data, 0, BadRequest);
}
return (BadRequest);
}
/*******************************************************************************
*
* SProcMPXDispatch
*
* Main swapped dispatch routine for requests to this extension.
* This routine is used if server and client do not have the same byte ordering.
*
*/
int
SProcMPXDispatch(register ClientPtr client)
{
REQUEST(xReq);
if (stuff->data == X_MPXGetExtensionVersion)
return (SProcMPXGetExtensionVersion(client));
if (stuff->data == X_MPXListDevices)
return (SProcMPXListDevices(client));
if (stuff->data == X_MPXSelectEvents)
return (SProcMPXSelectEvents(client));
if (stuff->data == X_MPXGetEventBase)
return (SProcMPXGetEventBase(client));
if (stuff->data == X_MPXQueryPointer)
return (SProcMPXQueryPointer(client));
else {
SendErrorToClient(client, MPXReqCode, stuff->data, 0, BadRequest);
}
return (BadRequest);
}
/***********************************************************************
*
* MPXResetProc.
* Remove reply-swapping routine.
* Remove event-swapping routine.
*
*/
void
MPXResetProc(ExtensionEntry* unused)
{
ReplySwapVector[MPXReqCode] = ReplyNotSwappd;
EventSwapVector[MPXButtonPress] = NotImplemented;
EventSwapVector[MPXButtonRelease] = NotImplemented;
EventSwapVector[MPXMotionNotify] = NotImplemented;
MPXRestoreExtensionEvents();
}
void SReplyMPXDispatch(ClientPtr client, int len, xMPXGetExtensionVersionReply* rep)
{
if (rep->RepType == X_MPXGetExtensionVersion)
SRepMPXGetExtensionVersion(client, len,
(xMPXGetExtensionVersionReply*) rep);
if (rep->RepType == X_MPXListDevices)
SRepMPXListDevices(client, len,
(xMPXListDevicesReply*) rep);
else {
FatalError("MPX confused sending swapped reply");
}
}
void
SEventMPXDispatch(xEvent* from, xEvent* to)
{
int type = from->u.u.type & 0177;
if (type == MPXButtonPress) {
SKeyButtonPtrEvent(from, to);
to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
} else if (type == MPXButtonRelease) {
SKeyButtonPtrEvent(from, to);
to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
} else if (type == MPXMotionNotify) {
SKeyButtonPtrEvent(from, to);
to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
} else {
FatalError("XInputExtension: Impossible event!\n");
}
}
void
MPXFixExtensionEvents(ExtensionEntry* extEntry)
{
MPXButtonPress = extEntry->eventBase;
MPXButtonRelease = MPXButtonPress + 1;
MPXMotionNotify = MPXButtonRelease + 1;
MPXLastEvent = MPXMotionNotify + 1;
MPXSetMaskForExtEvent(MPXButtonPressMask, MPXButtonPress);
MPXSetMaskForExtEvent(MPXButtonReleaseMask, MPXButtonRelease);
MPXSetMaskForExtEvent(MPXPointerMotionMask, MPXMotionNotify);
}
/**************************************************************************
*
* Assign the specified mask to the specified event.
*
*/
void
MPXSetMaskForExtEvent(Mask mask, int event)
{
EventInfo[MPXEventIndex].mask = mask;
EventInfo[MPXEventIndex++].type = event;
if ((event < LASTEvent) || (event >= 128))
FatalError("MaskForExtensionEvent: bogus event number");
SetMaskForEvent(mask, event);
}
/************************************************************************
*
* This function restores extension event types and masks to their
* initial state.
*
*/
void
MPXRestoreExtensionEvents(void)
{
int i;
MPXReqCode = 0;
for (i = 0; i < MPXEventIndex - 1; i++) {
if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128))
SetMaskForEvent(0, EventInfo[i].type);
EventInfo[i].mask = 0;
EventInfo[i].type = 0;
}
MPXEventIndex = 0;
lastExtEventMask = 1;
MPXButtonPress = 0;
MPXButtonRelease = 1;
MPXMotionNotify = 2;
}
/**************************************************************************
*
* Allow the specified event to have its propagation suppressed.
* The default is to not allow suppression of propagation.
*
*/
void
MPXAllowPropagateSuppress(Mask mask)
{
int i;
for (i = 0; i < MAX_DEVICES; i++)
PropagateMask[i] |= mask;
}