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 +#endif + + +#include "dixstruct.h" +#include "windowstr.h" +#include "exglobals.h" +#include "exevents.h" +#include + +#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 similarity index 81% rename from Xi/xiselev.h rename to 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 #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 -#endif - -#include - -#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 #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; /*