summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-02-23 15:58:07 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-03-20 15:17:55 +1000
commit8b6a370058ad5a20e0a0e49ec9443daf03775de8 (patch)
tree9c681008defdd3226fbd50cd7c44aff392298ccf
parent38bba0c1b75b84e8bbdfa7975cf701a9414a3afd (diff)
Add XI2 masks and XISelectEvent() request handling.
XI2 event masks are simply stored in the OtherEventMasks as a separate field. This replaces the XiSelectEvent code.
-rw-r--r--Xi/Makefile.am4
-rw-r--r--Xi/exevents.c45
-rw-r--r--Xi/extinit.c6
-rw-r--r--Xi/xiselectev.c121
-rw-r--r--Xi/xiselectev.h (renamed from Xi/xiselev.h)17
-rw-r--r--Xi/xiselev.c79
-rw-r--r--include/exevents.h3
-rw-r--r--include/inputstr.h8
8 files changed, 184 insertions, 99 deletions
diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 10521fd7a..548300024 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -94,7 +94,7 @@ libXi_la_SOURCES = \
warpdevp.h \
xiproperty.c \
xiproperty.h \
- xiselev.c \
- xiselev.h
+ xiselectev.c \
+ xiselectev.h
EXTRA_DIST = stubs.c
diff --git a/Xi/exevents.c b/Xi/exevents.c
index fe11694b9..cee682300 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1499,15 +1499,20 @@ RecalculateDeviceDeliverableEvents(WindowPtr pWin)
InputClientsPtr others;
struct _OtherInputMasks *inputMasks; /* default: NULL */
WindowPtr pChild, tmp;
- int i;
+ int i, j;
pChild = pWin;
while (1) {
if ((inputMasks = wOtherInputMasks(pChild)) != 0) {
+ for (i = 0; i < EMASKSIZE; i++)
+ memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i]));
for (others = inputMasks->inputClients; others;
others = others->next) {
for (i = 0; i < EMASKSIZE; i++)
inputMasks->inputEvents[i] |= others->mask[i];
+ for (i = 0; i < EMASKSIZE; i++)
+ for (j = 0; j < XI2MASKSIZE; j++)
+ inputMasks->xi2mask[i][j] |= others->xi2mask[i][j];
}
for (i = 0; i < EMASKSIZE; i++)
inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
@@ -1955,3 +1960,41 @@ SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count)
}
}
+/**
+ * Set the XI2 mask for the given client on the given window.
+ * @param dev The device to set the mask for.
+ * @param win The window to set the mask on.
+ * @param client The client setting the mask.
+ * @param len Number of bytes in mask.
+ * @param mask Event mask in the form of (1 << eventtype)
+ */
+void
+XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
+ unsigned int len, unsigned char* mask)
+{
+ OtherInputMasks *masks;
+ InputClientsPtr others = NULL;
+
+ masks = wOtherInputMasks(win);
+ if (masks)
+ {
+ for (others = wOtherInputMasks(win)->inputClients; others;
+ others = others->next) {
+ if (SameClient(others, client)) {
+ memset(others->xi2mask[dev->id], 0,
+ sizeof(others->xi2mask[dev->id]));
+ break;
+ }
+ }
+ }
+
+ if (!others && len)
+ {
+ AddExtensionClient(win, client, 0, 0);
+ others= wOtherInputMasks(win)->inputClients;
+ }
+
+ memcpy(others->xi2mask[dev->id], mask, len);
+
+ RecalculateDeviceDeliverableEvents(win);
+}
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 5e87451f5..a83a20e22 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -119,7 +119,7 @@ SOFTWARE.
#include "ungrdevb.h"
#include "ungrdevk.h"
#include "warpdevp.h"
-#include "xiselev.h"
+#include "xiselectev.h"
#include "xiproperty.h"
@@ -237,7 +237,7 @@ static int (*ProcIVector[])(ClientPtr) = {
ProcXIChangeDeviceHierarchy, /* 43 */
ProcXISetClientPointer, /* 44 */
ProcXIGetClientPointer, /* 45 */
- ProcXiSelectEvent, /* 46 */
+ ProcXISelectEvent, /* 46 */
ProcXIQueryVersion, /* 47 */
ProcXIQueryDevice /* 48 */
};
@@ -290,7 +290,7 @@ static int (*SProcIVector[])(ClientPtr) = {
SProcXIChangeDeviceHierarchy, /* 43 */
SProcXISetClientPointer, /* 44 */
SProcXIGetClientPointer, /* 45 */
- SProcXiSelectEvent, /* 46 */
+ SProcXISelectEvent, /* 46 */
SProcXIQueryVersion, /* 47 */
SProcXIQueryDevice /* 48 */
};
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
new file mode 100644
index 000000000..87811dc2d
--- /dev/null
+++ b/Xi/xiselectev.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+
+#include "dixstruct.h"
+#include "windowstr.h"
+#include "exglobals.h"
+#include "exevents.h"
+#include <X11/extensions/XI2proto.h>
+
+#include "xiselectev.h"
+
+int
+SProcXISelectEvent(ClientPtr client)
+{
+ char n;
+ int i;
+ xXIDeviceEventMask* evmask;
+ uint16_t *evtype;
+
+ REQUEST(xXISelectEventsReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXISelectEventsReq);
+ swapl(&stuff->window, n);
+ swaps(&stuff->num_masks, n);
+
+ evmask = (xXIDeviceEventMask*)&stuff[1];
+ for (i = 0; i < stuff->num_masks; i++)
+ {
+ swaps(&evmask->deviceid, n);
+ swaps(&evmask->mask_len, n);
+ evmask = (xXIDeviceEventMask*)(((char*)evtype) + evmask->mask_len * 4);
+ }
+
+ return (ProcXISelectEvent(client));
+}
+
+int
+ProcXISelectEvent(ClientPtr client)
+{
+ int rc, num_masks, i;
+ WindowPtr win;
+ DeviceIntPtr dev;
+ xXIDeviceEventMask *evmask;
+ int *types = NULL;
+
+ REQUEST(xXISelectEventsReq);
+ REQUEST_AT_LEAST_SIZE(xXISelectEventsReq);
+
+ rc = dixLookupWindow(&win, stuff->window, client, DixReceiveAccess);
+ if (rc != Success)
+ return rc;
+
+ /* check request validity */
+ evmask = (xXIDeviceEventMask*)&stuff[1];
+ num_masks = stuff->num_masks;
+ while(num_masks--)
+ {
+ if (evmask->deviceid != AllDevices && evmask->deviceid != AllMasterDevices)
+ rc = dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess);
+ else {
+ /* XXX: XACE here? */
+ }
+ if (rc != Success)
+ return rc;
+
+
+ if ((evmask->mask_len * 4) > XI_LASTEVENT)
+ {
+ unsigned char *bits = (unsigned char*)&evmask[1];
+ for (i = XI_LASTEVENT; i < evmask->mask_len * 4; i++)
+ {
+ if (BitIsOn(bits, i))
+ return BadValue;
+ }
+ }
+
+ evmask = (xXIDeviceEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+ }
+
+ /* Set masks on window */
+ evmask = (xXIDeviceEventMask*)&stuff[1];
+ num_masks = stuff->num_masks;
+ while(num_masks--)
+ {
+ dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess);
+ XISetEventMask(dev, win, client, evmask->mask_len * 4, (unsigned char*)&evmask[1]);
+ evmask = (xXIDeviceEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+ }
+
+ RecalculateDeliverableEvents(win);
+
+ xfree(types);
+ return Success;
+}
diff --git a/Xi/xiselev.h b/Xi/xiselectev.h
index b751c5d1b..dc527122b 100644
--- a/Xi/xiselev.h
+++ b/Xi/xiselectev.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Peter Hutterer
+ * Copyright 2008 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,21 +20,12 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * Author: Peter Hutterer, University of South Australia, NICTA
+ * Author: Peter Hutterer
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
-#ifndef XISELEV_H
-#define XISELEV_H 1
-
-int SProcXiSelectEvent(ClientPtr /* client */
- );
-
-int ProcXiSelectEvent(ClientPtr /* client */
- );
-
-#endif /* XISELEV_H */
-
+int SProcXISelectEvent(ClientPtr client);
+int ProcXISelectEvent(ClientPtr client);
diff --git a/Xi/xiselev.c b/Xi/xiselev.c
deleted file mode 100644
index 229f2d1f6..000000000
--- a/Xi/xiselev.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2007-2008 Peter Hutterer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Author: Peter Hutterer, University of South Australia, NICTA
- */
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/extensions/XIproto.h>
-
-#include "dixstruct.h"
-#include "windowstr.h"
-
-#include "exglobals.h"
-#include "xiselev.h"
-#include "geext.h"
-
-int
-SProcXiSelectEvent(ClientPtr client)
-{
- char n;
-
- REQUEST(xXiSelectEventReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXiSelectEventReq);
- swapl(&stuff->window, n);
- swapl(&stuff->mask, n);
- return (ProcXiSelectEvent(client));
-}
-
-
-int
-ProcXiSelectEvent(ClientPtr client)
-{
- int rc;
- WindowPtr pWin;
- DeviceIntPtr pDev;
- REQUEST(xXiSelectEventReq);
- REQUEST_SIZE_MATCH(xXiSelectEventReq);
-
- rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
- if (rc != Success)
- return rc;
-
- if (stuff->deviceid & (0x1 << 7)) /* all devices */
- pDev = NULL;
- else {
- rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess);
- if (rc != Success)
- return rc;
- }
-
- /* XXX: THIS FUNCTION IS NOW DYSFUNCTIONAL */
-
- return Success;
-}
-
diff --git a/include/exevents.h b/include/exevents.h
index 4ee7084ef..fc1c23f27 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -254,4 +254,7 @@ extern void
XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master,
DeviceChangedEvent *dce);
+extern void XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
+ unsigned int len, unsigned char* mask);
+
#endif /* EXEVENTS_H */
diff --git a/include/inputstr.h b/include/inputstr.h
index 3edd33f7d..678c171c5 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -55,6 +55,7 @@ SOFTWARE.
#include "cursorstr.h"
#include "geext.h"
#include "privates.h"
+#include <X11/extensions/XI2proto.h>
#define BitIsOn(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))
#define SetBit(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7)))
@@ -63,7 +64,8 @@ SOFTWARE.
#define SameClient(obj,client) \
(CLIENT_BITS((obj)->resource) == (client)->clientAsMask)
-#define EMASKSIZE MAXDEVICES + 1
+#define EMASKSIZE MAXDEVICES + 2
+#define XI2MASKSIZE ((XI_LASTEVENT + 7)/8) /* no of bits for masks */
/**
* This struct stores the core event mask for each client except the client
@@ -98,6 +100,8 @@ typedef struct _InputClients {
InputClientsPtr next; /**< Pointer to the next mask */
XID resource; /**< id for putting into resource manager */
Mask mask[EMASKSIZE]; /**< Actual XI event mask, deviceid is index */
+ /** XI2 event masks. One per device, each bit is a mask of (1 << type) */
+ unsigned char xi2mask[EMASKSIZE][XI2MASKSIZE];
} InputClients;
/**
@@ -126,6 +130,8 @@ typedef struct _OtherInputMasks {
Mask dontPropagateMask[EMASKSIZE];
/** The clients that selected for events */
InputClientsPtr inputClients;
+ /* XI2 event masks. One per device, each bit is a mask of (1 << type) */
+ unsigned char xi2mask[EMASKSIZE][XI2MASKSIZE];
} OtherInputMasks;
/*