diff options
Diffstat (limited to 'xorg-server/Xi')
-rw-r--r-- | xorg-server/Xi/chgdctl.c | 476 | ||||
-rw-r--r-- | xorg-server/Xi/exevents.c | 4288 | ||||
-rw-r--r-- | xorg-server/Xi/exglobals.h | 168 | ||||
-rw-r--r-- | xorg-server/Xi/extinit.c | 2620 | ||||
-rw-r--r-- | xorg-server/Xi/getdctl.c | 482 | ||||
-rw-r--r-- | xorg-server/Xi/getprop.c | 374 | ||||
-rw-r--r-- | xorg-server/Xi/getselev.c | 356 | ||||
-rw-r--r-- | xorg-server/Xi/stubs.c | 292 | ||||
-rw-r--r-- | xorg-server/Xi/xichangehierarchy.c | 992 | ||||
-rw-r--r-- | xorg-server/Xi/xipassivegrab.c | 630 | ||||
-rw-r--r-- | xorg-server/Xi/xiquerydevice.c | 1012 | ||||
-rw-r--r-- | xorg-server/Xi/xiquerypointer.c | 458 | ||||
-rw-r--r-- | xorg-server/Xi/xiqueryversion.c | 250 | ||||
-rw-r--r-- | xorg-server/Xi/xiwarppointer.c | 406 |
14 files changed, 6402 insertions, 6402 deletions
diff --git a/xorg-server/Xi/chgdctl.c b/xorg-server/Xi/chgdctl.c index b5580803b..4c4aebac6 100644 --- a/xorg-server/Xi/chgdctl.c +++ b/xorg-server/Xi/chgdctl.c @@ -1,238 +1,238 @@ -/************************************************************
-
-Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California.
-
- All Rights Reserved
-
-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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-HEWLETT-PACKARD 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.
-
-********************************************************/
-
-/********************************************************************
- *
- * Change Device control attributes for an extension device.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "inputstr.h" /* DeviceIntPtr */
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h> /* control constants */
-#include "XIstubs.h"
-
-#include "exglobals.h"
-#include "exevents.h"
-
-#include "chgdctl.h"
-
-/***********************************************************************
- *
- * This procedure changes the control attributes for an extension device,
- * for clients on machines with a different byte ordering than the server.
- *
- */
-
-int
-SProcXChangeDeviceControl(ClientPtr client)
-{
- char n;
- xDeviceCtl *ctl;
-
- REQUEST(xChangeDeviceControlReq);
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
- swaps(&stuff->control, n);
- ctl = (xDeviceCtl*)&stuff[1];
- swaps(&ctl->control, n);
- swaps(&ctl->length, n);
- switch(stuff->control) {
- case DEVICE_ABS_CALIB:
- case DEVICE_ABS_AREA:
- case DEVICE_CORE:
- case DEVICE_ENABLE:
- case DEVICE_RESOLUTION:
- /* hmm. beer. *drool* */
- break;
-
- }
- return (ProcXChangeDeviceControl(client));
-}
-
-/***********************************************************************
- *
- * Change the control attributes.
- *
- */
-
-int
-ProcXChangeDeviceControl(ClientPtr client)
-{
- unsigned len;
- int i, status, ret = BadValue;
- DeviceIntPtr dev;
- xDeviceResolutionCtl *r;
- xChangeDeviceControlReply rep;
- AxisInfoPtr a;
- CARD32 *resolution;
- xDeviceEnableCtl *e;
- devicePresenceNotify dpn;
-
- REQUEST(xChangeDeviceControlReq);
- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
-
- len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq));
- ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
- if (ret != Success)
- goto out;
-
- rep.repType = X_Reply;
- rep.RepType = X_ChangeDeviceControl;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- switch (stuff->control) {
- case DEVICE_RESOLUTION:
- r = (xDeviceResolutionCtl *) & stuff[1];
- if ((len < bytes_to_int32(sizeof(xDeviceResolutionCtl))) ||
- (len != bytes_to_int32(sizeof(xDeviceResolutionCtl)) + r->num_valuators)) {
- ret = BadLength;
- goto out;
- }
- if (!dev->valuator) {
- ret = BadMatch;
- goto out;
- }
- if ((dev->deviceGrab.grab) && !SameClient(dev->deviceGrab.grab, client)) {
- rep.status = AlreadyGrabbed;
- ret = Success;
- goto out;
- }
- resolution = (CARD32 *) (r + 1);
- if (r->first_valuator + r->num_valuators > dev->valuator->numAxes) {
- ret = BadValue;
- goto out;
- }
- status = ChangeDeviceControl(client, dev, (xDeviceCtl *) r);
- if (status == Success) {
- a = &dev->valuator->axes[r->first_valuator];
- for (i = 0; i < r->num_valuators; i++)
- if (*(resolution + i) < (a + i)->min_resolution ||
- *(resolution + i) > (a + i)->max_resolution)
- return BadValue;
- for (i = 0; i < r->num_valuators; i++)
- (a++)->resolution = *resolution++;
-
- ret = Success;
- } else if (status == DeviceBusy) {
- rep.status = DeviceBusy;
- ret = Success;
- } else {
- ret = BadMatch;
- }
- break;
- case DEVICE_ABS_CALIB:
- case DEVICE_ABS_AREA:
- /* Calibration is now done through properties, and never had any effect
- * on anything (in the open-source world). Thus, be honest. */
- ret = BadMatch;
- break;
- case DEVICE_CORE:
- /* Sorry, no device core switching no more. If you want a device to
- * send core events, attach it to a master device */
- ret = BadMatch;
- break;
- case DEVICE_ENABLE:
- e = (xDeviceEnableCtl *)&stuff[1];
-
- status = ChangeDeviceControl(client, dev, (xDeviceCtl *) e);
-
- if (status == Success) {
- if (e->enable)
- EnableDevice(dev, TRUE);
- else
- DisableDevice(dev, TRUE);
- ret = Success;
- } else if (status == DeviceBusy) {
- rep.status = DeviceBusy;
- ret = Success;
- } else {
- ret = BadMatch;
- }
-
- break;
- default:
- ret = BadValue;
- }
-
-out:
- if (ret == Success) {
- dpn.type = DevicePresenceNotify;
- dpn.time = currentTime.milliseconds;
- dpn.devchange = DeviceControlChanged;
- dpn.deviceid = dev->id;
- dpn.control = stuff->control;
- SendEventToAllWindows(dev, DevicePresenceNotifyMask,
- (xEvent *) &dpn, 1);
-
- WriteReplyToClient(client, sizeof(xChangeDeviceControlReply), &rep);
- }
-
- return ret;
-}
-
-/***********************************************************************
- *
- * This procedure writes the reply for the xChangeDeviceControl function,
- * if the client and server have a different byte ordering.
- *
- */
-
-void
-SRepXChangeDeviceControl(ClientPtr client, int size,
- xChangeDeviceControlReply * rep)
-{
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- WriteToClient(client, size, (char *)rep);
-}
+/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + All Rights Reserved + +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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/******************************************************************** + * + * Change Device control attributes for an extension device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> /* control constants */ +#include "XIstubs.h" + +#include "exglobals.h" +#include "exevents.h" + +#include "chgdctl.h" + +/*********************************************************************** + * + * This procedure changes the control attributes for an extension device, + * for clients on machines with a different byte ordering than the server. + * + */ + +int +SProcXChangeDeviceControl(ClientPtr client) +{ + char n; + xDeviceCtl *ctl; + + REQUEST(xChangeDeviceControlReq); + swaps(&stuff->length, n); + REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq); + swaps(&stuff->control, n); + ctl = (xDeviceCtl*)&stuff[1]; + swaps(&ctl->control, n); + swaps(&ctl->length, n); + switch(stuff->control) { + case DEVICE_ABS_CALIB: + case DEVICE_ABS_AREA: + case DEVICE_CORE: + case DEVICE_ENABLE: + case DEVICE_RESOLUTION: + /* hmm. beer. *drool* */ + break; + + } + return (ProcXChangeDeviceControl(client)); +} + +/*********************************************************************** + * + * Change the control attributes. + * + */ + +int +ProcXChangeDeviceControl(ClientPtr client) +{ + unsigned len; + int i, status, ret = BadValue; + DeviceIntPtr dev; + xDeviceResolutionCtl *r; + xChangeDeviceControlReply rep; + AxisInfoPtr a; + CARD32 *resolution; + xDeviceEnableCtl *e; + devicePresenceNotify dpn; + + REQUEST(xChangeDeviceControlReq); + REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq); + + len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq)); + ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess); + if (ret != Success) + goto out; + + rep.repType = X_Reply; + rep.RepType = X_ChangeDeviceControl; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + switch (stuff->control) { + case DEVICE_RESOLUTION: + r = (xDeviceResolutionCtl *) & stuff[1]; + if ((len < bytes_to_int32(sizeof(xDeviceResolutionCtl))) || + (len != bytes_to_int32(sizeof(xDeviceResolutionCtl)) + r->num_valuators)) { + ret = BadLength; + goto out; + } + if (!dev->valuator) { + ret = BadMatch; + goto out; + } + if ((dev->deviceGrab.grab) && !SameClient(dev->deviceGrab.grab, client)) { + rep.status = AlreadyGrabbed; + ret = Success; + goto out; + } + resolution = (CARD32 *) (r + 1); + if (r->first_valuator + r->num_valuators > dev->valuator->numAxes) { + ret = BadValue; + goto out; + } + status = ChangeDeviceControl(client, dev, (xDeviceCtl *) r); + if (status == Success) { + a = &dev->valuator->axes[r->first_valuator]; + for (i = 0; i < r->num_valuators; i++) + if (*(resolution + i) < (a + i)->min_resolution || + *(resolution + i) > (a + i)->max_resolution) + return BadValue; + for (i = 0; i < r->num_valuators; i++) + (a++)->resolution = *resolution++; + + ret = Success; + } else if (status == DeviceBusy) { + rep.status = DeviceBusy; + ret = Success; + } else { + ret = BadMatch; + } + break; + case DEVICE_ABS_CALIB: + case DEVICE_ABS_AREA: + /* Calibration is now done through properties, and never had any effect + * on anything (in the open-source world). Thus, be honest. */ + ret = BadMatch; + break; + case DEVICE_CORE: + /* Sorry, no device core switching no more. If you want a device to + * send core events, attach it to a master device */ + ret = BadMatch; + break; + case DEVICE_ENABLE: + e = (xDeviceEnableCtl *)&stuff[1]; + + status = ChangeDeviceControl(client, dev, (xDeviceCtl *) e); + + if (status == Success) { + if (e->enable) + EnableDevice(dev, TRUE); + else + DisableDevice(dev, TRUE); + ret = Success; + } else if (status == DeviceBusy) { + rep.status = DeviceBusy; + ret = Success; + } else { + ret = BadMatch; + } + + break; + default: + ret = BadValue; + } + +out: + if (ret == Success) { + dpn.type = DevicePresenceNotify; + dpn.time = currentTime.milliseconds; + dpn.devchange = DeviceControlChanged; + dpn.deviceid = dev->id; + dpn.control = stuff->control; + SendEventToAllWindows(dev, DevicePresenceNotifyMask, + (xEvent *) &dpn, 1); + + WriteReplyToClient(client, sizeof(xChangeDeviceControlReply), &rep); + } + + return ret; +} + +/*********************************************************************** + * + * This procedure writes the reply for the xChangeDeviceControl function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXChangeDeviceControl(ClientPtr client, int size, + xChangeDeviceControlReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index baecb8147..3d4889361 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -1,2144 +1,2144 @@ -/************************************************************
-
-Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California.
-
- All Rights Reserved
-
-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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-HEWLETT-PACKARD 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.
-
-********************************************************/
-
-/********************************************************************
- *
- * Routines to register and initialize extension input devices.
- * This also contains ProcessOtherEvent, the routine called from DDX
- * to route extension events.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#else
-#define XINPUT
-#endif
-
-#include "inputstr.h"
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include <X11/extensions/XI2proto.h>
-#include <X11/extensions/geproto.h>
-#include "windowstr.h"
-#include "miscstruct.h"
-#include "region.h"
-#include "exevents.h"
-#include "extnsionst.h"
-#include "exglobals.h"
-#include "dixevents.h" /* DeliverFocusedEvent */
-#include "dixgrabs.h" /* CreateGrab() */
-#include "scrnintstr.h"
-#include "listdev.h" /* for CopySwapXXXClass */
-#include "xace.h"
-#include "xiquerydevice.h" /* For List*Info */
-#include "eventconvert.h"
-#include "eventstr.h"
-#include "inpututils.h"
-
-#include <X11/extensions/XKBproto.h>
-#include "xkbsrv.h"
-
-#define WID(w) ((w) ? ((w)->drawable.id) : 0)
-#define AllModifiersMask ( \
- ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
- Mod3Mask | Mod4Mask | Mod5Mask )
-#define AllButtonsMask ( \
- Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
-
-Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
- Bool /* ignoreSelectedEvents */
- );
-static Bool MakeInputMasks(WindowPtr /* pWin */
- );
-
-/*
- * Only let the given client know of core events which will affect its
- * interpretation of input events, if the client's ClientPointer (or the
- * paired keyboard) is the current device.
- */
-int
-XIShouldNotify(ClientPtr client, DeviceIntPtr dev)
-{
- DeviceIntPtr current_ptr = PickPointer(client);
- DeviceIntPtr current_kbd = GetPairedDevice(current_ptr);
-
- if (dev == current_kbd || dev == current_ptr)
- return 1;
-
- return 0;
-}
-
-Bool
-IsPointerEvent(InternalEvent* event)
-{
- switch(event->any.type)
- {
- case ET_ButtonPress:
- case ET_ButtonRelease:
- case ET_Motion:
- /* XXX: enter/leave ?? */
- return TRUE;
- default:
- break;
- }
- return FALSE;
-}
-
-/**
- * @return the device matching the deviceid of the device set in the event, or
- * NULL if the event is not an XInput event.
- */
-DeviceIntPtr
-XIGetDevice(xEvent* xE)
-{
- DeviceIntPtr pDev = NULL;
-
- if (xE->u.u.type == DeviceButtonPress ||
- xE->u.u.type == DeviceButtonRelease ||
- xE->u.u.type == DeviceMotionNotify ||
- xE->u.u.type == ProximityIn ||
- xE->u.u.type == ProximityOut ||
- xE->u.u.type == DevicePropertyNotify)
- {
- int rc;
- int id;
-
- id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS;
-
- rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess);
- if (rc != Success)
- ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc);
- }
- return pDev;
-}
-
-
-/**
- * Copy the device->key into master->key and send a mapping notify to the
- * clients if appropriate.
- * master->key needs to be allocated by the caller.
- *
- * Device is the slave device. If it is attached to a master device, we may
- * need to send a mapping notify to the client because it causes the MD
- * to change state.
- *
- * Mapping notify needs to be sent in the following cases:
- * - different slave device on same master
- * - different master
- *
- * XXX: They way how the code is we also send a map notify if the slave device
- * stays the same, but the master changes. This isn't really necessary though.
- *
- * XXX: this gives you funny behaviour with the ClientPointer. When a
- * MappingNotify is sent to the client, the client usually responds with a
- * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard
- * mapping, regardless of which keyboard sent the last mapping notify request.
- * So depending on the CP setting, your keyboard may change layout in each
- * app...
- *
- * This code is basically the old SwitchCoreKeyboard.
- */
-
-void
-CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
-{
- KeyClassPtr mk = master->key;
-
- if (device == master)
- return;
-
- mk->sourceid = device->id;
-
-
- if (!XkbCopyDeviceKeymap(master, device))
- FatalError("Couldn't pivot keymap from device to core!\n");
-}
-
-/**
- * Copies the feedback classes from device "from" into device "to". Classes
- * are duplicated (not just flipping the pointers). All feedback classes are
- * linked lists, the full list is duplicated.
- */
-static void
-DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
-{
- ClassesPtr classes;
-
-
- if (from->intfeed)
- {
- IntegerFeedbackPtr *i, it;
-
- if (!to->intfeed)
- {
- classes = to->unused_classes;
- to->intfeed = classes->intfeed;
- classes->intfeed = NULL;
- }
-
- i = &to->intfeed;
- for (it = from->intfeed; it; it = it->next)
- {
- if (!(*i))
- {
- *i = calloc(1, sizeof(IntegerFeedbackClassRec));
- if (!(*i))
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*i)->CtrlProc = it->CtrlProc;
- (*i)->ctrl = it->ctrl;
-
- i = &(*i)->next;
- }
- } else if (to->intfeed && !from->intfeed)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->intfeed = to->intfeed;
- to->intfeed = NULL;
- }
-
- if (from->stringfeed)
- {
- StringFeedbackPtr *s, it;
-
- if (!to->stringfeed)
- {
- classes = to->unused_classes;
- to->stringfeed = classes->stringfeed;
- classes->stringfeed = NULL;
- }
-
- s = &to->stringfeed;
- for (it = from->stringfeed; it; it = it->next)
- {
- if (!(*s))
- {
- *s = calloc(1, sizeof(StringFeedbackClassRec));
- if (!(*s))
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*s)->CtrlProc = it->CtrlProc;
- (*s)->ctrl = it->ctrl;
-
- s = &(*s)->next;
- }
- } else if (to->stringfeed && !from->stringfeed)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->stringfeed = to->stringfeed;
- to->stringfeed = NULL;
- }
-
- if (from->bell)
- {
- BellFeedbackPtr *b, it;
-
- if (!to->bell)
- {
- classes = to->unused_classes;
- to->bell = classes->bell;
- classes->bell = NULL;
- }
-
- b = &to->bell;
- for (it = from->bell; it; it = it->next)
- {
- if (!(*b))
- {
- *b = calloc(1, sizeof(BellFeedbackClassRec));
- if (!(*b))
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*b)->BellProc = it->BellProc;
- (*b)->CtrlProc = it->CtrlProc;
- (*b)->ctrl = it->ctrl;
-
- b = &(*b)->next;
- }
- } else if (to->bell && !from->bell)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->bell = to->bell;
- to->bell = NULL;
- }
-
- if (from->leds)
- {
- LedFeedbackPtr *l, it;
-
- if (!to->leds)
- {
- classes = to->unused_classes;
- to->leds = classes->leds;
- classes->leds = NULL;
- }
-
- l = &to->leds;
- for (it = from->leds; it; it = it->next)
- {
- if (!(*l))
- {
- *l = calloc(1, sizeof(LedFeedbackClassRec));
- if (!(*l))
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*l)->CtrlProc = it->CtrlProc;
- (*l)->ctrl = it->ctrl;
- if ((*l)->xkb_sli)
- XkbFreeSrvLedInfo((*l)->xkb_sli);
- (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l);
-
- l = &(*l)->next;
- }
- } else if (to->leds && !from->leds)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->leds = to->leds;
- to->leds = NULL;
- }
-}
-
-static void
-DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
-{
- ClassesPtr classes;
-
- /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the
- * kbdfeed to be set up properly, so let's do the feedback classes first.
- */
- if (from->kbdfeed)
- {
- KbdFeedbackPtr *k, it;
-
- if (!to->kbdfeed)
- {
- classes = to->unused_classes;
-
- to->kbdfeed = classes->kbdfeed;
- if (!to->kbdfeed)
- InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
- classes->kbdfeed = NULL;
- }
-
- k = &to->kbdfeed;
- for(it = from->kbdfeed; it; it = it->next)
- {
- if (!(*k))
- {
- *k = calloc(1, sizeof(KbdFeedbackClassRec));
- if (!*k)
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*k)->BellProc = it->BellProc;
- (*k)->CtrlProc = it->CtrlProc;
- (*k)->ctrl = it->ctrl;
- if ((*k)->xkb_sli)
- XkbFreeSrvLedInfo((*k)->xkb_sli);
- (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
-
- k = &(*k)->next;
- }
- } else if (to->kbdfeed && !from->kbdfeed)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->kbdfeed = to->kbdfeed;
- to->kbdfeed = NULL;
- }
-
- if (from->key)
- {
- if (!to->key)
- {
- classes = to->unused_classes;
- to->key = classes->key;
- if (!to->key)
- InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
- else
- classes->key = NULL;
- }
-
- CopyKeyClass(from, to);
- } else if (to->key && !from->key)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->key = to->key;
- to->key = NULL;
- }
-
- /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps
- * pointer point into the xkbInfo->desc struct. XkbCopySrvLedInfo
- * didn't update the pointers so we need to do it manually here.
- */
- if (to->kbdfeed)
- {
- KbdFeedbackPtr k;
-
- for (k = to->kbdfeed; k; k = k->next)
- {
- if (!k->xkb_sli)
- continue;
- if (k->xkb_sli->flags & XkbSLI_IsDefault)
- {
- k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators;
- k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps;
- }
- }
- }
-
- /* We can't just copy over the focus class. When an app sets the focus,
- * it'll do so on the master device. Copying the SDs focus means losing
- * the focus.
- * So we only copy the focus class if the device didn't have one,
- * otherwise we leave it as it is.
- */
- if (from->focus)
- {
- if (!to->focus)
- {
- WindowPtr *oldTrace;
-
- classes = to->unused_classes;
- to->focus = classes->focus;
- if (!to->focus)
- {
- to->focus = calloc(1, sizeof(FocusClassRec));
- if (!to->focus)
- FatalError("[Xi] no memory for class shift.\n");
- } else
- classes->focus = NULL;
-
- oldTrace = to->focus->trace;
- memcpy(to->focus, from->focus, sizeof(FocusClassRec));
- to->focus->trace = realloc(oldTrace,
- to->focus->traceSize * sizeof(WindowPtr));
- if (!to->focus->trace && to->focus->traceSize)
- FatalError("[Xi] no memory for trace.\n");
- memcpy(to->focus->trace, from->focus->trace,
- from->focus->traceSize * sizeof(WindowPtr));
- to->focus->sourceid = from->id;
- }
- } else if (to->focus)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->focus = to->focus;
- to->focus = NULL;
- }
-
-}
-
-static void
-DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
-{
- ClassesPtr classes;
-
- /* Feedback classes must be copied first */
- if (from->ptrfeed)
- {
- PtrFeedbackPtr *p, it;
- if (!to->ptrfeed)
- {
- classes = to->unused_classes;
- to->ptrfeed = classes->ptrfeed;
- classes->ptrfeed = NULL;
- }
-
- p = &to->ptrfeed;
- for (it = from->ptrfeed; it; it = it->next)
- {
- if (!(*p))
- {
- *p = calloc(1, sizeof(PtrFeedbackClassRec));
- if (!*p)
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*p)->CtrlProc = it->CtrlProc;
- (*p)->ctrl = it->ctrl;
-
- p = &(*p)->next;
- }
- } else if (to->ptrfeed && !from->ptrfeed)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->ptrfeed = to->ptrfeed;
- to->ptrfeed = NULL;
- }
-
- if (from->valuator)
- {
- ValuatorClassPtr v;
-
- if (!to->valuator)
- {
- classes = to->unused_classes;
- to->valuator = classes->valuator;
- if (to->valuator)
- classes->valuator = NULL;
- }
-
- v = AllocValuatorClass(to->valuator, from->valuator->numAxes);
-
- if (!v)
- FatalError("[Xi] no memory for class shift.\n");
-
- to->valuator = v;
- memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo));
-
- v->sourceid = from->id;
- } else if (to->valuator && !from->valuator)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->valuator = to->valuator;
- to->valuator = NULL;
- }
-
- if (from->button)
- {
- if (!to->button)
- {
- classes = to->unused_classes;
- to->button = classes->button;
- if (!to->button)
- {
- to->button = calloc(1, sizeof(ButtonClassRec));
- if (!to->button)
- FatalError("[Xi] no memory for class shift.\n");
- } else
- classes->button = NULL;
- }
-
- if (from->button->xkb_acts)
- {
- if (!to->button->xkb_acts)
- {
- to->button->xkb_acts = calloc(1, sizeof(XkbAction));
- if (!to->button->xkb_acts)
- FatalError("[Xi] not enough memory for xkb_acts.\n");
- }
- memcpy(to->button->xkb_acts, from->button->xkb_acts,
- sizeof(XkbAction));
- } else
- free(to->button->xkb_acts);
-
- memcpy(to->button->labels, from->button->labels,
- from->button->numButtons * sizeof(Atom));
- to->button->sourceid = from->id;
- } else if (to->button && !from->button)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->button = to->button;
- to->button = NULL;
- }
-
- if (from->proximity)
- {
- if (!to->proximity)
- {
- classes = to->unused_classes;
- to->proximity = classes->proximity;
- if (!to->proximity)
- {
- to->proximity = calloc(1, sizeof(ProximityClassRec));
- if (!to->proximity)
- FatalError("[Xi] no memory for class shift.\n");
- } else
- classes->proximity = NULL;
- }
- memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec));
- to->proximity->sourceid = from->id;
- } else if (to->proximity)
- {
- ClassesPtr classes;
- classes = to->unused_classes;
- classes->proximity = to->proximity;
- to->proximity = NULL;
- }
-}
-
-/**
- * Copies the CONTENT of the classes of device from into the classes in device
- * to. From and to are identical after finishing.
- *
- * If to does not have classes from currenly has, the classes are stored in
- * to's devPrivates system. Later, we recover it again from there if needed.
- * Saves a few memory allocations.
- */
-void
-DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce)
-{
- /* generic feedback classes, not tied to pointer and/or keyboard */
- DeepCopyFeedbackClasses(from, to);
-
- if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT))
- DeepCopyKeyboardClasses(from, to);
- if ((dce->flags & DEVCHANGE_POINTER_EVENT))
- DeepCopyPointerClasses(from, to);
-}
-
-
-/**
- * Send an XI2 DeviceChangedEvent to all interested clients.
- */
-void
-XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce)
-{
- xXIDeviceChangedEvent *dcce;
- int rc;
-
- rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce);
- if (rc != Success)
- {
- ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc);
- return;
- }
-
- /* we don't actually swap if there's a NullClient, swapping is done
- * later when event is delivered. */
- SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1);
- free(dcce);
-}
-
-static void
-ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
-{
- DeviceIntPtr slave;
- int rc;
-
- /* For now, we don't have devices that change physically. */
- if (!IsMaster(device))
- return;
-
- rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess);
-
- if (rc != Success)
- return; /* Device has disappeared */
-
- if (IsMaster(slave))
- return;
-
- if (IsFloating(slave))
- return; /* set floating since the event */
-
- if (GetMaster(slave, MASTER_ATTACHED)->id != dce->masterid)
- return; /* not our slave anymore, don't care */
-
- /* FIXME: we probably need to send a DCE for the new slave now */
-
- device->public.devicePrivate = slave->public.devicePrivate;
-
- /* FIXME: the classes may have changed since we generated the event. */
- DeepCopyDeviceClasses(slave, device, dce);
- XISendDeviceChangedEvent(slave, device, dce);
-}
-
-/**
- * Update the device state according to the data in the event.
- *
- * return values are
- * DEFAULT ... process as normal
- * DONT_PROCESS ... return immediately from caller
- */
-#define DEFAULT 0
-#define DONT_PROCESS 1
-int
-UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
-{
- int i;
- int key = 0,
- bit = 0,
- last_valuator;
-
- KeyClassPtr k = NULL;
- ButtonClassPtr b = NULL;
- ValuatorClassPtr v = NULL;
-
- /* This event is always the first we get, before the actual events with
- * the data. However, the way how the DDX is set up, "device" will
- * actually be the slave device that caused the event.
- */
- switch(event->type)
- {
- case ET_DeviceChanged:
- ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event);
- return DONT_PROCESS; /* event has been sent already */
- case ET_Motion:
- case ET_ButtonPress:
- case ET_ButtonRelease:
- case ET_KeyPress:
- case ET_KeyRelease:
- case ET_ProximityIn:
- case ET_ProximityOut:
- break;
- default:
- /* other events don't update the device */
- return DEFAULT;
- }
-
- k = device->key;
- v = device->valuator;
- b = device->button;
-
- key = event->detail.key;
- bit = 1 << (key & 7);
-
- /* Update device axis */
- /* Check valuators first */
- last_valuator = -1;
- for (i = 0; i < MAX_VALUATORS; i++)
- {
- if (BitIsOn(&event->valuators.mask, i))
- {
- if (!v)
- {
- ErrorF("[Xi] Valuators reported for non-valuator device '%s'. "
- "Ignoring event.\n", device->name);
- return DONT_PROCESS;
- } else if (v->numAxes < i)
- {
- ErrorF("[Xi] Too many valuators reported for device '%s'. "
- "Ignoring event.\n", device->name);
- return DONT_PROCESS;
- }
- last_valuator = i;
- }
- }
-
- for (i = 0; i <= last_valuator && i < v->numAxes; i++)
- {
- if (BitIsOn(&event->valuators.mask, i))
- {
- /* XXX: Relative/Absolute mode */
- v->axisVal[i] = event->valuators.data[i];
- v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16));
- }
- }
-
- if (event->type == ET_KeyPress) {
- if (!k)
- return DONT_PROCESS;
-
- /* don't allow ddx to generate multiple downs, but repeats are okay */
- if (key_is_down(device, key, KEY_PROCESSED) && !event->key_repeat)
- return DONT_PROCESS;
-
- if (device->valuator)
- device->valuator->motionHintWindow = NullWindow;
- set_key_down(device, key, KEY_PROCESSED);
- } else if (event->type == ET_KeyRelease) {
- if (!k)
- return DONT_PROCESS;
-
- if (!key_is_down(device, key, KEY_PROCESSED)) /* guard against duplicates */
- return DONT_PROCESS;
- if (device->valuator)
- device->valuator->motionHintWindow = NullWindow;
- set_key_up(device, key, KEY_PROCESSED);
- } else if (event->type == ET_ButtonPress) {
- Mask mask;
- if (!b)
- return DONT_PROCESS;
-
- if (button_is_down(device, key, BUTTON_PROCESSED))
- return DONT_PROCESS;
-
- set_button_down(device, key, BUTTON_PROCESSED);
- if (device->valuator)
- device->valuator->motionHintWindow = NullWindow;
- if (!b->map[key])
- return DONT_PROCESS;
- b->buttonsDown++;
- b->motionMask = DeviceButtonMotionMask;
- if (b->map[key] <= 5)
- b->state |= (Button1Mask >> 1) << b->map[key];
-
- /* Add state and motionMask to the filter for this event */
- mask = DevicePointerMotionMask | b->state | b->motionMask;
- SetMaskForEvent(device->id, mask, DeviceMotionNotify);
- mask = PointerMotionMask | b->state | b->motionMask;
- SetMaskForEvent(device->id, mask, MotionNotify);
- } else if (event->type == ET_ButtonRelease) {
- Mask mask;
- if (!b)
- return DONT_PROCESS;
-
- if (!button_is_down(device, key, BUTTON_PROCESSED))
- return DONT_PROCESS;
- if (IsMaster(device)) {
- DeviceIntPtr sd;
-
- /*
- * Leave the button down if any slave has the
- * button still down. Note that this depends on the
- * event being delivered through the slave first
- */
- for (sd = inputInfo.devices; sd; sd = sd->next) {
- if (IsMaster(sd) || GetMaster(sd, MASTER_POINTER) != device)
- continue;
- if (!sd->button)
- continue;
- for (i = 1; i <= sd->button->numButtons; i++)
- if (sd->button->map[i] == key &&
- button_is_down(sd, i, BUTTON_PROCESSED))
- return DONT_PROCESS;
- }
- }
- set_button_up(device, key, BUTTON_PROCESSED);
- if (device->valuator)
- device->valuator->motionHintWindow = NullWindow;
- if (!b->map[key])
- return DONT_PROCESS;
- if (b->buttonsDown >= 1 && !--b->buttonsDown)
- b->motionMask = 0;
- if (b->map[key] <= 5)
- b->state &= ~((Button1Mask >> 1) << b->map[key]);
-
- /* Add state and motionMask to the filter for this event */
- mask = DevicePointerMotionMask | b->state | b->motionMask;
- SetMaskForEvent(device->id, mask, DeviceMotionNotify);
- mask = PointerMotionMask | b->state | b->motionMask;
- SetMaskForEvent(device->id, mask, MotionNotify);
- } else if (event->type == ET_ProximityIn)
- device->proximity->in_proximity = TRUE;
- else if (event->type == ET_ProximityOut)
- device->proximity->in_proximity = FALSE;
-
- return DEFAULT;
-}
-
-/**
- * Main device event processing function.
- * Called from when processing the events from the event queue.
- *
- */
-void
-ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
-{
- GrabPtr grab;
- Bool deactivateDeviceGrab = FALSE;
- int key = 0, rootX, rootY;
- ButtonClassPtr b;
- KeyClassPtr k;
- ValuatorClassPtr v;
- int ret = 0;
- int state, i;
- DeviceIntPtr mouse = NULL, kbd = NULL;
- DeviceEvent *event = &ev->device_event;
-
- verify_internal_event(ev);
-
- if (ev->any.type == ET_RawKeyPress ||
- ev->any.type == ET_RawKeyRelease ||
- ev->any.type == ET_RawButtonPress ||
- ev->any.type == ET_RawButtonRelease ||
- ev->any.type == ET_RawMotion)
- {
- DeliverRawEvent(&ev->raw_event, device);
- return;
- }
-
- if (IsPointerDevice(device))
- {
- kbd = GetPairedDevice(device);
- mouse = device;
- if (kbd && !kbd->key) /* can happen with floating SDs */
- kbd = NULL;
- } else
- {
- mouse = GetPairedDevice(device);
- kbd = device;
- if (!mouse->valuator || !mouse->button) /* may be float. SDs */
- mouse = NULL;
- }
-
- /* State needs to be assembled BEFORE the device is updated. */
- state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
- state |= (mouse && mouse->button) ? (mouse->button->state) : 0;
-
- for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
- if (BitIsOn(mouse->button->down, i))
- SetBit(event->buttons, i);
-
- if (kbd && kbd->key)
- {
- XkbStatePtr state;
- /* we need the state before the event happens */
- if (event->type == ET_KeyPress || event->type == ET_KeyRelease)
- state = &kbd->key->xkbInfo->prev_state;
- else
- state = &kbd->key->xkbInfo->state;
-
- event->mods.base = state->base_mods;
- event->mods.latched = state->latched_mods;
- event->mods.locked = state->locked_mods;
- event->mods.effective = state->mods;
-
- event->group.base = state->base_group;
- event->group.latched = state->latched_group;
- event->group.locked = state->locked_group;
- event->group.effective = state->group;
- }
-
- ret = UpdateDeviceState(device, event);
- if (ret == DONT_PROCESS)
- return;
-
- v = device->valuator;
- b = device->button;
- k = device->key;
-
- if (IsMaster(device) || IsFloating(device))
- CheckMotion(event, device);
-
- switch (event->type)
- {
- case ET_Motion:
- case ET_ButtonPress:
- case ET_ButtonRelease:
- case ET_KeyPress:
- case ET_KeyRelease:
- case ET_ProximityIn:
- case ET_ProximityOut:
- if (!device->spriteInfo->sprite)
- return;
- GetSpritePosition(device, &rootX, &rootY);
- event->root_x = rootX;
- event->root_y = rootY;
- NoticeEventTime((InternalEvent*)event);
- event->corestate = state;
- key = event->detail.key;
- break;
- default:
- break;
- }
-
- if (DeviceEventCallback && !syncEvents.playingEvents) {
- DeviceEventInfoRec eventinfo;
- SpritePtr pSprite = device->spriteInfo->sprite;
-
- /* see comment in EnqueueEvents regarding the next three lines */
- if (ev->any.type == ET_Motion)
- ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id;
-
- eventinfo.device = device;
- eventinfo.event = ev;
- CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
- }
-
- grab = device->deviceGrab.grab;
-
- switch(event->type)
- {
- case ET_KeyPress:
- if (!grab && CheckDeviceGrabs(device, event, 0))
- return;
- break;
- case ET_KeyRelease:
- if (grab && device->deviceGrab.fromPassiveGrab &&
- (key == device->deviceGrab.activatingKey) &&
- (device->deviceGrab.grab->type == KeyPress ||
- device->deviceGrab.grab->type == DeviceKeyPress ||
- device->deviceGrab.grab->type == XI_KeyPress))
- deactivateDeviceGrab = TRUE;
- break;
- case ET_ButtonPress:
- event->detail.button = b->map[key];
- if (!event->detail.button) { /* there's no button 0 */
- event->detail.button = key;
- return;
- }
- if (!grab && CheckDeviceGrabs(device, event, 0))
- {
- /* if a passive grab was activated, the event has been sent
- * already */
- return;
- }
- break;
- case ET_ButtonRelease:
- event->detail.button = b->map[key];
- if (!event->detail.button) { /* there's no button 0 */
- event->detail.button = key;
- return;
- }
- if (grab && !b->buttonsDown &&
- device->deviceGrab.fromPassiveGrab &&
- (device->deviceGrab.grab->type == ButtonPress ||
- device->deviceGrab.grab->type == DeviceButtonPress ||
- device->deviceGrab.grab->type == XI_ButtonPress))
- deactivateDeviceGrab = TRUE;
- default:
- break;
- }
-
-
- if (grab)
- DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab);
- else if (device->focus && !IsPointerEvent((InternalEvent*)ev))
- DeliverFocusedEvent(device, (InternalEvent*)event,
- GetSpriteWindow(device));
- else
- DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event,
- NullGrab, NullWindow, device);
-
- if (deactivateDeviceGrab == TRUE)
- (*device->deviceGrab.DeactivateGrab) (device);
- event->detail.key = key;
-}
-
-int
-InitProximityClassDeviceStruct(DeviceIntPtr dev)
-{
- ProximityClassPtr proxc;
-
- proxc = (ProximityClassPtr) malloc(sizeof(ProximityClassRec));
- if (!proxc)
- return FALSE;
- proxc->sourceid = dev->id;
- proxc->in_proximity = TRUE;
- dev->proximity = proxc;
- return TRUE;
-}
-
-/**
- * Initialise the device's valuators. The memory must already be allocated,
- * this function merely inits the matching axis (specified through axnum) to
- * sane values.
- *
- * It is a condition that (minval < maxval).
- *
- * @see InitValuatorClassDeviceStruct
- */
-void
-InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
- int resolution, int min_res, int max_res, int mode)
-{
- AxisInfoPtr ax;
-
- if (!dev || !dev->valuator || minval > maxval)
- return;
- if (axnum >= dev->valuator->numAxes)
- return;
-
- ax = dev->valuator->axes + axnum;
-
- ax->min_value = minval;
- ax->max_value = maxval;
- ax->resolution = resolution;
- ax->min_resolution = min_res;
- ax->max_resolution = max_res;
- ax->label = label;
- ax->mode = mode;
-
- if (mode & OutOfProximity)
- dev->proximity->in_proximity = FALSE;
-}
-
-static void
-FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
- ButtonClassPtr b, ValuatorClassPtr v, int first)
-{
- ev->type = DeviceStateNotify;
- ev->deviceid = dev->id;
- ev->time = currentTime.milliseconds;
- ev->classes_reported = 0;
- ev->num_keys = 0;
- ev->num_buttons = 0;
- ev->num_valuators = 0;
-
- if (b) {
- ev->classes_reported |= (1 << ButtonClass);
- ev->num_buttons = b->numButtons;
- memcpy((char*)ev->buttons, (char*)b->down, 4);
- } else if (k) {
- ev->classes_reported |= (1 << KeyClass);
- ev->num_keys = k->xkbInfo->desc->max_key_code -
- k->xkbInfo->desc->min_key_code;
- memmove((char *)&ev->keys[0], (char *)k->down, 4);
- }
- if (v) {
- int nval = v->numAxes - first;
-
- ev->classes_reported |= (1 << ValuatorClass);
- ev->classes_reported |= valuator_get_mode(dev, 0) << ModeBitsShift;
- ev->num_valuators = nval < 3 ? nval : 3;
- switch (ev->num_valuators) {
- case 3:
- ev->valuator2 = v->axisVal[first + 2];
- case 2:
- ev->valuator1 = v->axisVal[first + 1];
- case 1:
- ev->valuator0 = v->axisVal[first];
- break;
- }
- }
-}
-
-static void
-FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
- int first)
-{
- int nval = v->numAxes - first;
-
- ev->type = DeviceValuator;
- ev->deviceid = dev->id;
- ev->num_valuators = nval < 3 ? nval : 3;
- ev->first_valuator = first;
- switch (ev->num_valuators) {
- case 3:
- ev->valuator2 = v->axisVal[first + 2];
- case 2:
- ev->valuator1 = v->axisVal[first + 1];
- case 1:
- ev->valuator0 = v->axisVal[first];
- break;
- }
- first += ev->num_valuators;
-}
-
-static void
-DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
-{
- int evcount = 1;
- deviceStateNotify *ev, *sev;
- deviceKeyStateNotify *kev;
- deviceButtonStateNotify *bev;
-
- KeyClassPtr k;
- ButtonClassPtr b;
- ValuatorClassPtr v;
- int nval = 0, nkeys = 0, nbuttons = 0, first = 0;
-
- if (!(wOtherInputMasks(win)) ||
- !(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask))
- return;
-
- if ((b = dev->button) != NULL) {
- nbuttons = b->numButtons;
- if (nbuttons > 32)
- evcount++;
- }
- if ((k = dev->key) != NULL) {
- nkeys = k->xkbInfo->desc->max_key_code -
- k->xkbInfo->desc->min_key_code;
- if (nkeys > 32)
- evcount++;
- if (nbuttons > 0) {
- evcount++;
- }
- }
- if ((v = dev->valuator) != NULL) {
- nval = v->numAxes;
-
- if (nval > 3)
- evcount++;
- if (nval > 6) {
- if (!(k && b))
- evcount++;
- if (nval > 9)
- evcount += ((nval - 7) / 3);
- }
- }
-
- sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent));
- FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
-
- if (b != NULL) {
- FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
- first += 3;
- nval -= 3;
- if (nbuttons > 32) {
- (ev - 1)->deviceid |= MORE_EVENTS;
- bev = (deviceButtonStateNotify *) ev++;
- bev->type = DeviceButtonStateNotify;
- bev->deviceid = dev->id;
- memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4);
- }
- if (nval > 0) {
- (ev - 1)->deviceid |= MORE_EVENTS;
- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
- first += 3;
- nval -= 3;
- }
- }
-
- if (k != NULL) {
- FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
- first += 3;
- nval -= 3;
- if (nkeys > 32) {
- (ev - 1)->deviceid |= MORE_EVENTS;
- kev = (deviceKeyStateNotify *) ev++;
- kev->type = DeviceKeyStateNotify;
- kev->deviceid = dev->id;
- memmove((char *)&kev->keys[0], (char *)&k->down[4], 28);
- }
- if (nval > 0) {
- (ev - 1)->deviceid |= MORE_EVENTS;
- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
- first += 3;
- nval -= 3;
- }
- }
-
- while (nval > 0) {
- FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
- first += 3;
- nval -= 3;
- if (nval > 0) {
- (ev - 1)->deviceid |= MORE_EVENTS;
- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
- first += 3;
- nval -= 3;
- }
- }
-
- DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
- DeviceStateNotifyMask, NullGrab);
- free(sev);
-}
-
-void
-DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
- WindowPtr pWin)
-{
- deviceFocus event;
- xXIFocusInEvent *xi2event;
- DeviceIntPtr mouse;
- int btlen, len, i;
-
- mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER);
-
- /* XI 2 event */
- btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
- btlen = bytes_to_int32(btlen);
- len = sizeof(xXIFocusInEvent) + btlen * 4;
-
- xi2event = calloc(1, len);
- xi2event->type = GenericEvent;
- xi2event->extension = IReqCode;
- xi2event->evtype = type;
- xi2event->length = bytes_to_int32(len - sizeof(xEvent));
- xi2event->buttons_len = btlen;
- xi2event->detail = detail;
- xi2event->time = currentTime.milliseconds;
- xi2event->deviceid = dev->id;
- xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */
- xi2event->mode = mode;
- xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0);
- xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0);
-
- for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
- if (BitIsOn(mouse->button->down, i))
- SetBit(&xi2event[1], i);
-
- if (dev->key)
- {
- xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods;
- xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods;
- xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods;
- xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods;
-
- xi2event->group.base_group = dev->key->xkbInfo->state.base_group;
- xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group;
- xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group;
- xi2event->group.effective_group = dev->key->xkbInfo->state.group;
- }
-
- FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent*)xi2event, pWin,
- None, FALSE);
-
- DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1,
- GetEventFilter(dev, (xEvent*)xi2event), NullGrab);
-
- free(xi2event);
-
- /* XI 1.x event */
- event.deviceid = dev->id;
- event.mode = mode;
- event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut;
- event.detail = detail;
- event.window = pWin->drawable.id;
- event.time = currentTime.milliseconds;
-
- DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
- DeviceFocusChangeMask, NullGrab);
-
- if (event.type == DeviceFocusIn)
- DeliverStateNotifyEvent(dev, pWin);
-}
-
-int
-CheckGrabValues(ClientPtr client, GrabParameters* param)
-{
- if (param->grabtype != GRABTYPE_CORE &&
- param->grabtype != GRABTYPE_XI &&
- param->grabtype != GRABTYPE_XI2)
- {
- ErrorF("[Xi] grabtype is invalid. This is a bug.\n");
- return BadImplementation;
- }
-
- if ((param->this_device_mode != GrabModeSync) &&
- (param->this_device_mode != GrabModeAsync)) {
- client->errorValue = param->this_device_mode;
- return BadValue;
- }
- if ((param->other_devices_mode != GrabModeSync) &&
- (param->other_devices_mode != GrabModeAsync)) {
- client->errorValue = param->other_devices_mode;
- return BadValue;
- }
-
- if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) &&
- (param->modifiers & ~AllModifiersMask)) {
- client->errorValue = param->modifiers;
- return BadValue;
- }
-
- if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) {
- client->errorValue = param->ownerEvents;
- return BadValue;
- }
- return Success;
-}
-
-int
-GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
- int button, GrabParameters *param, GrabType grabtype,
- GrabMask *mask)
-{
- WindowPtr pWin, confineTo;
- CursorPtr cursor;
- GrabPtr grab;
- int rc, type = -1;
- Mask access_mode = DixGrabAccess;
-
- rc = CheckGrabValues(client, param);
- if (rc != Success)
- return rc;
- if (param->confineTo == None)
- confineTo = NullWindow;
- else {
- rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess);
- if (rc != Success)
- return rc;
- }
- if (param->cursor == None)
- cursor = NullCursor;
- else {
- rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
- RT_CURSOR, client, DixUseAccess);
- if (rc != Success)
- {
- client->errorValue = param->cursor;
- return rc;
- }
- access_mode |= DixForceAccess;
- }
- if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
- access_mode |= DixFreezeAccess;
- rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
- if (rc != Success)
- return rc;
- rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
- if (rc != Success)
- return rc;
-
- if (grabtype == GRABTYPE_XI)
- type = DeviceButtonPress;
- else if (grabtype == GRABTYPE_XI2)
- type = XI_ButtonPress;
-
- grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
- mask, param, type, button, confineTo, cursor);
- if (!grab)
- return BadAlloc;
- return AddPassiveGrabToList(client, grab);
-}
-
-/**
- * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If
- * grabtype is GRABTYPE_XI2, the key is a keysym.
- */
-int
-GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
- int key, GrabParameters *param, GrabType grabtype, GrabMask *mask)
-{
- WindowPtr pWin;
- GrabPtr grab;
- KeyClassPtr k = dev->key;
- Mask access_mode = DixGrabAccess;
- int rc, type = -1;
-
- rc = CheckGrabValues(client, param);
- if (rc != Success)
- return rc;
- if (k == NULL)
- return BadMatch;
- if (grabtype == GRABTYPE_XI)
- {
- if ((key > k->xkbInfo->desc->max_key_code ||
- key < k->xkbInfo->desc->min_key_code)
- && (key != AnyKey)) {
- client->errorValue = key;
- return BadValue;
- }
- type = DeviceKeyPress;
- } else if (grabtype == GRABTYPE_XI2)
- type = XI_KeyPress;
-
- rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
- if (rc != Success)
- return rc;
- if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
- access_mode |= DixFreezeAccess;
- rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
- if (rc != Success)
- return rc;
-
- grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
- mask, param, type, key, NULL, NULL);
- if (!grab)
- return BadAlloc;
- return AddPassiveGrabToList(client, grab);
-}
-
-/* Enter/FocusIn grab */
-int
-GrabWindow(ClientPtr client, DeviceIntPtr dev, int type,
- GrabParameters *param, GrabMask *mask)
-{
- WindowPtr pWin;
- CursorPtr cursor;
- GrabPtr grab;
- Mask access_mode = DixGrabAccess;
- int rc;
-
- rc = CheckGrabValues(client, param);
- if (rc != Success)
- return rc;
-
- rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
- if (rc != Success)
- return rc;
- if (param->cursor == None)
- cursor = NullCursor;
- else {
- rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
- RT_CURSOR, client, DixUseAccess);
- if (rc != Success)
- {
- client->errorValue = param->cursor;
- return rc;
- }
- access_mode |= DixForceAccess;
- }
- if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
- access_mode |= DixFreezeAccess;
- rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
- if (rc != Success)
- return rc;
-
- grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2,
- mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn,
- 0, NULL, cursor);
-
- if (!grab)
- return BadAlloc;
-
- return AddPassiveGrabToList(client, grab);
-}
-
-int
-SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client,
- Mask mask, Mask exclusivemasks)
-{
- int mskidx = dev->id;
- int i, ret;
- Mask check;
- InputClientsPtr others;
-
- check = (mask & exclusivemasks);
- if (wOtherInputMasks(pWin)) {
- if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different
- * clients to select on any of the
- * events for maskcheck. However,
- * it is OK, for some client to
- * continue selecting on one of those
- * events. */
- for (others = wOtherInputMasks(pWin)->inputClients; others;
- others = others->next) {
- if (!SameClient(others, client) && (check &
- others->mask[mskidx]))
- return BadAccess;
- }
- }
- for (others = wOtherInputMasks(pWin)->inputClients; others;
- others = others->next) {
- if (SameClient(others, client)) {
- check = others->mask[mskidx];
- others->mask[mskidx] = mask;
- if (mask == 0) {
- for (i = 0; i < EMASKSIZE; i++)
- if (i != mskidx && others->mask[i] != 0)
- break;
- if (i == EMASKSIZE) {
- RecalculateDeviceDeliverableEvents(pWin);
- if (ShouldFreeInputMasks(pWin, FALSE))
- FreeResource(others->resource, RT_NONE);
- return Success;
- }
- }
- goto maskSet;
- }
- }
- }
- check = 0;
- if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success)
- return ret;
- maskSet:
- if (dev->valuator)
- if ((dev->valuator->motionHintWindow == pWin) &&
- (mask & DevicePointerMotionHintMask) &&
- !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab)
- dev->valuator->motionHintWindow = NullWindow;
- RecalculateDeviceDeliverableEvents(pWin);
- return Success;
-}
-
-int
-AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx)
-{
- InputClientsPtr others;
-
- if (!pWin->optional && !MakeWindowOptional(pWin))
- return BadAlloc;
- others = calloc(1, sizeof(InputClients));
- if (!others)
- return BadAlloc;
- if (!pWin->optional->inputMasks && !MakeInputMasks(pWin))
- goto bail;
- others->mask[mskidx] = mask;
- others->resource = FakeClientID(client->index);
- others->next = pWin->optional->inputMasks->inputClients;
- pWin->optional->inputMasks->inputClients = others;
- if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin))
- goto bail;
- return Success;
-
-bail:
- free(others);
- return BadAlloc;
-}
-
-static Bool
-MakeInputMasks(WindowPtr pWin)
-{
- struct _OtherInputMasks *imasks;
-
- imasks = calloc(1, sizeof(struct _OtherInputMasks));
- if (!imasks)
- return FALSE;
- pWin->optional->inputMasks = imasks;
- return TRUE;
-}
-
-void
-RecalculateDeviceDeliverableEvents(WindowPtr pWin)
-{
- InputClientsPtr others;
- struct _OtherInputMasks *inputMasks; /* default: NULL */
- WindowPtr pChild, tmp;
- 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];
- for (tmp = pChild->parent; tmp; tmp = tmp->parent)
- if (wOtherInputMasks(tmp))
- for (i = 0; i < EMASKSIZE; i++)
- inputMasks->deliverableEvents[i] |=
- (wOtherInputMasks(tmp)->deliverableEvents[i]
- & ~inputMasks->
- dontPropagateMask[i] & PropagateMask[i]);
- }
- if (pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- break;
- pChild = pChild->nextSib;
- }
-}
-
-#ifdef _MSC_VER
-#pragma warning(disable:4715) /* Not all control paths return a value */
-#endif
-
-int
-InputClientGone(WindowPtr pWin, XID id)
-{
- InputClientsPtr other, prev;
-
- if (!wOtherInputMasks(pWin))
- return Success;
- prev = 0;
- for (other = wOtherInputMasks(pWin)->inputClients; other;
- other = other->next) {
- if (other->resource == id) {
- if (prev) {
- prev->next = other->next;
- free(other);
- } else if (!(other->next)) {
- if (ShouldFreeInputMasks(pWin, TRUE)) {
- wOtherInputMasks(pWin)->inputClients = other->next;
- free(wOtherInputMasks(pWin));
- pWin->optional->inputMasks = (OtherInputMasks *) NULL;
- CheckWindowOptionalNeed(pWin);
- free(other);
- } else {
- other->resource = FakeClientID(0);
- if (!AddResource(other->resource, RT_INPUTCLIENT,
- (pointer) pWin))
- return BadAlloc;
- }
- } else {
- wOtherInputMasks(pWin)->inputClients = other->next;
- free(other);
- }
- RecalculateDeviceDeliverableEvents(pWin);
- return Success;
- }
- prev = other;
- }
- FatalError("client not on device event list");
-}
-
-int
-SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate,
- xEvent * ev, Mask mask, int count)
-{
- WindowPtr pWin;
- WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
- WindowPtr spriteWin = GetSpriteWindow(d);
-
- if (dest == PointerWindow)
- pWin = spriteWin;
- else if (dest == InputFocus) {
- WindowPtr inputFocus;
-
- if (!d->focus)
- inputFocus = spriteWin;
- else
- inputFocus = d->focus->win;
-
- if (inputFocus == FollowKeyboardWin)
- inputFocus = inputInfo.keyboard->focus->win;
-
- if (inputFocus == NoneWin)
- return Success;
-
- /* If the input focus is PointerRootWin, send the event to where
- * the pointer is if possible, then perhaps propogate up to root. */
- if (inputFocus == PointerRootWin)
- inputFocus = GetCurrentRootWindow(d);
-
- if (IsParent(inputFocus, spriteWin)) {
- effectiveFocus = inputFocus;
- pWin = spriteWin;
- } else
- effectiveFocus = pWin = inputFocus;
- } else
- dixLookupWindow(&pWin, dest, client, DixSendAccess);
- if (!pWin)
- return BadWindow;
- if ((propagate != xFalse) && (propagate != xTrue)) {
- client->errorValue = propagate;
- return BadValue;
- }
- ev->u.u.type |= 0x80;
- if (propagate) {
- for (; pWin; pWin = pWin->parent) {
- if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab))
- return Success;
- if (pWin == effectiveFocus)
- return Success;
- if (wOtherInputMasks(pWin))
- mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id];
- if (!mask)
- break;
- }
- } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count))
- DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab);
- return Success;
-}
-
-int
-SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map)
-{
- int i;
- ButtonClassPtr b = dev->button;
-
- if (b == NULL)
- return BadMatch;
-
- if (nElts != b->numButtons) {
- client->errorValue = nElts;
- return BadValue;
- }
- if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue))
- return BadValue;
- for (i = 0; i < nElts; i++)
- if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1))
- return MappingBusy;
- for (i = 0; i < nElts; i++)
- b->map[i + 1] = map[i];
- return Success;
-}
-
-int
-ChangeKeyMapping(ClientPtr client,
- DeviceIntPtr dev,
- unsigned len,
- int type,
- KeyCode firstKeyCode,
- CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map)
-{
- KeySymsRec keysyms;
- KeyClassPtr k = dev->key;
-
- if (k == NULL)
- return BadMatch;
-
- if (len != (keyCodes * keySymsPerKeyCode))
- return BadLength;
-
- if ((firstKeyCode < k->xkbInfo->desc->min_key_code) ||
- (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) {
- client->errorValue = firstKeyCode;
- return BadValue;
- }
- if (keySymsPerKeyCode == 0) {
- client->errorValue = 0;
- return BadValue;
- }
- keysyms.minKeyCode = firstKeyCode;
- keysyms.maxKeyCode = firstKeyCode + keyCodes - 1;
- keysyms.mapWidth = keySymsPerKeyCode;
- keysyms.map = map;
-
- XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL,
- serverClient);
-
- return Success;
-}
-
-static void
-DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
-{
- WindowPtr parent;
-
- /* Deactivate any grabs performed on this window, before making
- * any input focus changes.
- * Deactivating a device grab should cause focus events. */
-
- if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin))
- (*dev->deviceGrab.DeactivateGrab) (dev);
-
- /* If the focus window is a root window (ie. has no parent)
- * then don't delete the focus from it. */
-
- if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) {
- int focusEventMode = NotifyNormal;
-
- /* If a grab is in progress, then alter the mode of focus events. */
-
- if (dev->deviceGrab.grab)
- focusEventMode = NotifyWhileGrabbed;
-
- switch (dev->focus->revert) {
- case RevertToNone:
- if (!ActivateFocusInGrab(dev, pWin, NoneWin))
- DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
- dev->focus->win = NoneWin;
- dev->focus->traceGood = 0;
- break;
- case RevertToParent:
- parent = pWin;
- do {
- parent = parent->parent;
- dev->focus->traceGood--;
- }
- while (!parent->realized);
- if (!ActivateFocusInGrab(dev, pWin, parent))
- DoFocusEvents(dev, pWin, parent, focusEventMode);
- dev->focus->win = parent;
- dev->focus->revert = RevertToNone;
- break;
- case RevertToPointerRoot:
- if (!ActivateFocusInGrab(dev, pWin, PointerRootWin))
- DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
- dev->focus->win = PointerRootWin;
- dev->focus->traceGood = 0;
- break;
- case RevertToFollowKeyboard:
- {
- DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD);
- if (!kbd || (kbd == dev && kbd != inputInfo.keyboard))
- kbd = inputInfo.keyboard;
- if (kbd->focus->win) {
- if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win))
- DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
- dev->focus->win = FollowKeyboardWin;
- dev->focus->traceGood = 0;
- } else {
- if (!ActivateFocusInGrab(dev, pWin, NoneWin))
- DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
- dev->focus->win = NoneWin;
- dev->focus->traceGood = 0;
- }
- }
- break;
- }
- }
-
- if (dev->valuator)
- if (dev->valuator->motionHintWindow == pWin)
- dev->valuator->motionHintWindow = NullWindow;
-}
-
-void
-DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources)
-{
- int i;
- DeviceIntPtr dev;
- InputClientsPtr ic;
- struct _OtherInputMasks *inputMasks;
-
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- DeleteDeviceFromAnyExtEvents(pWin, dev);
- }
-
- for (dev = inputInfo.off_devices; dev; dev = dev->next)
- DeleteDeviceFromAnyExtEvents(pWin, dev);
-
- if (freeResources)
- while ((inputMasks = wOtherInputMasks(pWin)) != 0) {
- ic = inputMasks->inputClients;
- for (i = 0; i < EMASKSIZE; i++)
- inputMasks->dontPropagateMask[i] = 0;
- FreeResource(ic->resource, RT_NONE);
- }
-}
-
-int
-MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask)
-{
- DeviceIntPtr dev;
-
- dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient,
- DixReadAccess);
- if (!dev)
- return 0;
-
- if (pEvents->type == DeviceMotionNotify) {
- if (mask & DevicePointerMotionHintMask) {
- if (WID(dev->valuator->motionHintWindow) == pEvents->event) {
- return 1; /* don't send, but pretend we did */
- }
- pEvents->detail = NotifyHint;
- } else {
- pEvents->detail = NotifyNormal;
- }
- }
- return 0;
-}
-
-void
-CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
- deviceKeyButtonPointer * xE, GrabPtr grab,
- ClientPtr client, Mask deliveryMask)
-{
- DeviceIntPtr dev;
-
- dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient,
- DixGrabAccess);
- if (!dev)
- return;
-
- if (type == DeviceMotionNotify)
- dev->valuator->motionHintWindow = pWin;
- else if ((type == DeviceButtonPress) && (!grab) &&
- (deliveryMask & DeviceButtonGrabMask)) {
- GrabRec tempGrab;
-
- tempGrab.device = dev;
- tempGrab.resource = client->clientAsMask;
- tempGrab.window = pWin;
- tempGrab.ownerEvents =
- (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
- tempGrab.eventMask = deliveryMask;
- tempGrab.keyboardMode = GrabModeAsync;
- tempGrab.pointerMode = GrabModeAsync;
- tempGrab.confineTo = NullWindow;
- tempGrab.cursor = NullCursor;
- tempGrab.next = NULL;
- (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE);
- }
-}
-
-static Mask
-DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client)
-{
- InputClientsPtr other;
-
- if (!wOtherInputMasks(pWin))
- return 0;
- for (other = wOtherInputMasks(pWin)->inputClients; other;
- other = other->next) {
- if (SameClient(other, client))
- return other->mask[dev->id];
- }
- return 0;
-}
-
-void
-MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client)
-{
- WindowPtr pWin;
- GrabPtr grab = dev->deviceGrab.grab;
-
- pWin = dev->valuator->motionHintWindow;
-
- if ((grab && SameClient(grab, client) &&
- ((grab->eventMask & DevicePointerMotionHintMask) ||
- (grab->ownerEvents &&
- (DeviceEventMaskForClient(dev, pWin, client) &
- DevicePointerMotionHintMask)))) ||
- (!grab &&
- (DeviceEventMaskForClient(dev, pWin, client) &
- DevicePointerMotionHintMask)))
- dev->valuator->motionHintWindow = NullWindow;
-}
-
-int
-DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask,
- int maskndx)
-{
- struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
-
- if (mask & ~PropagateMask[maskndx]) {
- client->errorValue = mask;
- return BadValue;
- }
-
- if (mask == 0) {
- if (inputMasks)
- inputMasks->dontPropagateMask[maskndx] = mask;
- } else {
- if (!inputMasks)
- AddExtensionClient(pWin, client, 0, 0);
- inputMasks = wOtherInputMasks(pWin);
- inputMasks->dontPropagateMask[maskndx] = mask;
- }
- RecalculateDeviceDeliverableEvents(pWin);
- if (ShouldFreeInputMasks(pWin, FALSE))
- FreeResource(inputMasks->inputClients->resource, RT_NONE);
- return Success;
-}
-
-Bool
-ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents)
-{
- int i;
- Mask allInputEventMasks = 0;
- struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
-
- for (i = 0; i < EMASKSIZE; i++)
- allInputEventMasks |= inputMasks->dontPropagateMask[i];
- if (!ignoreSelectedEvents)
- for (i = 0; i < EMASKSIZE; i++)
- allInputEventMasks |= inputMasks->inputEvents[i];
- if (allInputEventMasks == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-/***********************************************************************
- *
- * Walk through the window tree, finding all clients that want to know
- * about the Event.
- *
- */
-
-static void
-FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask,
- xEvent * ev, int count)
-{
- WindowPtr p2;
-
- while (p1) {
- p2 = p1->firstChild;
- DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab);
- FindInterestedChildren(dev, p2, mask, ev, count);
- p1 = p1->nextSib;
- }
-}
-
-/***********************************************************************
- *
- * Send an event to interested clients in all windows on all screens.
- *
- */
-
-void
-SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count)
-{
- int i;
- WindowPtr pWin, p1;
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- pWin = screenInfo.screens[i]->root;
- if (!pWin)
- continue;
- DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab);
- p1 = pWin->firstChild;
- FindInterestedChildren(dev, p1, mask, ev, 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)
- */
-int
-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;
- }
- }
- }
-
- len = min(len, sizeof(others->xi2mask[dev->id]));
-
- if (len && !others)
- {
- if (AddExtensionClient(win, client, 0, 0) != Success)
- return BadAlloc;
- others= wOtherInputMasks(win)->inputClients;
- }
-
- if (others)
- memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id]));
-
- if (len)
- memcpy(others->xi2mask[dev->id], mask, len);
-
- RecalculateDeviceDeliverableEvents(win);
-
- return Success;
-}
+/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + All Rights Reserved + +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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/******************************************************************** + * + * Routines to register and initialize extension input devices. + * This also contains ProcessOtherEvent, the routine called from DDX + * to route extension events. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#else +#define XINPUT +#endif + +#include "inputstr.h" +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include <X11/extensions/XI2proto.h> +#include <X11/extensions/geproto.h> +#include "windowstr.h" +#include "miscstruct.h" +#include "region.h" +#include "exevents.h" +#include "extnsionst.h" +#include "exglobals.h" +#include "dixevents.h" /* DeliverFocusedEvent */ +#include "dixgrabs.h" /* CreateGrab() */ +#include "scrnintstr.h" +#include "listdev.h" /* for CopySwapXXXClass */ +#include "xace.h" +#include "xiquerydevice.h" /* For List*Info */ +#include "eventconvert.h" +#include "eventstr.h" +#include "inpututils.h" + +#include <X11/extensions/XKBproto.h> +#include "xkbsrv.h" + +#define WID(w) ((w) ? ((w)->drawable.id) : 0) +#define AllModifiersMask ( \ + ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ + Mod3Mask | Mod4Mask | Mod5Mask ) +#define AllButtonsMask ( \ + Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) + +Bool ShouldFreeInputMasks(WindowPtr /* pWin */ , + Bool /* ignoreSelectedEvents */ + ); +static Bool MakeInputMasks(WindowPtr /* pWin */ + ); + +/* + * Only let the given client know of core events which will affect its + * interpretation of input events, if the client's ClientPointer (or the + * paired keyboard) is the current device. + */ +int +XIShouldNotify(ClientPtr client, DeviceIntPtr dev) +{ + DeviceIntPtr current_ptr = PickPointer(client); + DeviceIntPtr current_kbd = GetPairedDevice(current_ptr); + + if (dev == current_kbd || dev == current_ptr) + return 1; + + return 0; +} + +Bool +IsPointerEvent(InternalEvent* event) +{ + switch(event->any.type) + { + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_Motion: + /* XXX: enter/leave ?? */ + return TRUE; + default: + break; + } + return FALSE; +} + +/** + * @return the device matching the deviceid of the device set in the event, or + * NULL if the event is not an XInput event. + */ +DeviceIntPtr +XIGetDevice(xEvent* xE) +{ + DeviceIntPtr pDev = NULL; + + if (xE->u.u.type == DeviceButtonPress || + xE->u.u.type == DeviceButtonRelease || + xE->u.u.type == DeviceMotionNotify || + xE->u.u.type == ProximityIn || + xE->u.u.type == ProximityOut || + xE->u.u.type == DevicePropertyNotify) + { + int rc; + int id; + + id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS; + + rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess); + if (rc != Success) + ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc); + } + return pDev; +} + + +/** + * Copy the device->key into master->key and send a mapping notify to the + * clients if appropriate. + * master->key needs to be allocated by the caller. + * + * Device is the slave device. If it is attached to a master device, we may + * need to send a mapping notify to the client because it causes the MD + * to change state. + * + * Mapping notify needs to be sent in the following cases: + * - different slave device on same master + * - different master + * + * XXX: They way how the code is we also send a map notify if the slave device + * stays the same, but the master changes. This isn't really necessary though. + * + * XXX: this gives you funny behaviour with the ClientPointer. When a + * MappingNotify is sent to the client, the client usually responds with a + * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard + * mapping, regardless of which keyboard sent the last mapping notify request. + * So depending on the CP setting, your keyboard may change layout in each + * app... + * + * This code is basically the old SwitchCoreKeyboard. + */ + +void +CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) +{ + KeyClassPtr mk = master->key; + + if (device == master) + return; + + mk->sourceid = device->id; + + + if (!XkbCopyDeviceKeymap(master, device)) + FatalError("Couldn't pivot keymap from device to core!\n"); +} + +/** + * Copies the feedback classes from device "from" into device "to". Classes + * are duplicated (not just flipping the pointers). All feedback classes are + * linked lists, the full list is duplicated. + */ +static void +DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) +{ + ClassesPtr classes; + + + if (from->intfeed) + { + IntegerFeedbackPtr *i, it; + + if (!to->intfeed) + { + classes = to->unused_classes; + to->intfeed = classes->intfeed; + classes->intfeed = NULL; + } + + i = &to->intfeed; + for (it = from->intfeed; it; it = it->next) + { + if (!(*i)) + { + *i = calloc(1, sizeof(IntegerFeedbackClassRec)); + if (!(*i)) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*i)->CtrlProc = it->CtrlProc; + (*i)->ctrl = it->ctrl; + + i = &(*i)->next; + } + } else if (to->intfeed && !from->intfeed) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->intfeed = to->intfeed; + to->intfeed = NULL; + } + + if (from->stringfeed) + { + StringFeedbackPtr *s, it; + + if (!to->stringfeed) + { + classes = to->unused_classes; + to->stringfeed = classes->stringfeed; + classes->stringfeed = NULL; + } + + s = &to->stringfeed; + for (it = from->stringfeed; it; it = it->next) + { + if (!(*s)) + { + *s = calloc(1, sizeof(StringFeedbackClassRec)); + if (!(*s)) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*s)->CtrlProc = it->CtrlProc; + (*s)->ctrl = it->ctrl; + + s = &(*s)->next; + } + } else if (to->stringfeed && !from->stringfeed) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->stringfeed = to->stringfeed; + to->stringfeed = NULL; + } + + if (from->bell) + { + BellFeedbackPtr *b, it; + + if (!to->bell) + { + classes = to->unused_classes; + to->bell = classes->bell; + classes->bell = NULL; + } + + b = &to->bell; + for (it = from->bell; it; it = it->next) + { + if (!(*b)) + { + *b = calloc(1, sizeof(BellFeedbackClassRec)); + if (!(*b)) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*b)->BellProc = it->BellProc; + (*b)->CtrlProc = it->CtrlProc; + (*b)->ctrl = it->ctrl; + + b = &(*b)->next; + } + } else if (to->bell && !from->bell) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->bell = to->bell; + to->bell = NULL; + } + + if (from->leds) + { + LedFeedbackPtr *l, it; + + if (!to->leds) + { + classes = to->unused_classes; + to->leds = classes->leds; + classes->leds = NULL; + } + + l = &to->leds; + for (it = from->leds; it; it = it->next) + { + if (!(*l)) + { + *l = calloc(1, sizeof(LedFeedbackClassRec)); + if (!(*l)) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*l)->CtrlProc = it->CtrlProc; + (*l)->ctrl = it->ctrl; + if ((*l)->xkb_sli) + XkbFreeSrvLedInfo((*l)->xkb_sli); + (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); + + l = &(*l)->next; + } + } else if (to->leds && !from->leds) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->leds = to->leds; + to->leds = NULL; + } +} + +static void +DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) +{ + ClassesPtr classes; + + /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the + * kbdfeed to be set up properly, so let's do the feedback classes first. + */ + if (from->kbdfeed) + { + KbdFeedbackPtr *k, it; + + if (!to->kbdfeed) + { + classes = to->unused_classes; + + to->kbdfeed = classes->kbdfeed; + if (!to->kbdfeed) + InitKeyboardDeviceStruct(to, NULL, NULL, NULL); + classes->kbdfeed = NULL; + } + + k = &to->kbdfeed; + for(it = from->kbdfeed; it; it = it->next) + { + if (!(*k)) + { + *k = calloc(1, sizeof(KbdFeedbackClassRec)); + if (!*k) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*k)->BellProc = it->BellProc; + (*k)->CtrlProc = it->CtrlProc; + (*k)->ctrl = it->ctrl; + if ((*k)->xkb_sli) + XkbFreeSrvLedInfo((*k)->xkb_sli); + (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); + + k = &(*k)->next; + } + } else if (to->kbdfeed && !from->kbdfeed) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->kbdfeed = to->kbdfeed; + to->kbdfeed = NULL; + } + + if (from->key) + { + if (!to->key) + { + classes = to->unused_classes; + to->key = classes->key; + if (!to->key) + InitKeyboardDeviceStruct(to, NULL, NULL, NULL); + else + classes->key = NULL; + } + + CopyKeyClass(from, to); + } else if (to->key && !from->key) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->key = to->key; + to->key = NULL; + } + + /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps + * pointer point into the xkbInfo->desc struct. XkbCopySrvLedInfo + * didn't update the pointers so we need to do it manually here. + */ + if (to->kbdfeed) + { + KbdFeedbackPtr k; + + for (k = to->kbdfeed; k; k = k->next) + { + if (!k->xkb_sli) + continue; + if (k->xkb_sli->flags & XkbSLI_IsDefault) + { + k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators; + k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps; + } + } + } + + /* We can't just copy over the focus class. When an app sets the focus, + * it'll do so on the master device. Copying the SDs focus means losing + * the focus. + * So we only copy the focus class if the device didn't have one, + * otherwise we leave it as it is. + */ + if (from->focus) + { + if (!to->focus) + { + WindowPtr *oldTrace; + + classes = to->unused_classes; + to->focus = classes->focus; + if (!to->focus) + { + to->focus = calloc(1, sizeof(FocusClassRec)); + if (!to->focus) + FatalError("[Xi] no memory for class shift.\n"); + } else + classes->focus = NULL; + + oldTrace = to->focus->trace; + memcpy(to->focus, from->focus, sizeof(FocusClassRec)); + to->focus->trace = realloc(oldTrace, + to->focus->traceSize * sizeof(WindowPtr)); + if (!to->focus->trace && to->focus->traceSize) + FatalError("[Xi] no memory for trace.\n"); + memcpy(to->focus->trace, from->focus->trace, + from->focus->traceSize * sizeof(WindowPtr)); + to->focus->sourceid = from->id; + } + } else if (to->focus) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->focus = to->focus; + to->focus = NULL; + } + +} + +static void +DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) +{ + ClassesPtr classes; + + /* Feedback classes must be copied first */ + if (from->ptrfeed) + { + PtrFeedbackPtr *p, it; + if (!to->ptrfeed) + { + classes = to->unused_classes; + to->ptrfeed = classes->ptrfeed; + classes->ptrfeed = NULL; + } + + p = &to->ptrfeed; + for (it = from->ptrfeed; it; it = it->next) + { + if (!(*p)) + { + *p = calloc(1, sizeof(PtrFeedbackClassRec)); + if (!*p) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*p)->CtrlProc = it->CtrlProc; + (*p)->ctrl = it->ctrl; + + p = &(*p)->next; + } + } else if (to->ptrfeed && !from->ptrfeed) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->ptrfeed = to->ptrfeed; + to->ptrfeed = NULL; + } + + if (from->valuator) + { + ValuatorClassPtr v; + + if (!to->valuator) + { + classes = to->unused_classes; + to->valuator = classes->valuator; + if (to->valuator) + classes->valuator = NULL; + } + + v = AllocValuatorClass(to->valuator, from->valuator->numAxes); + + if (!v) + FatalError("[Xi] no memory for class shift.\n"); + + to->valuator = v; + memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); + + v->sourceid = from->id; + } else if (to->valuator && !from->valuator) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->valuator = to->valuator; + to->valuator = NULL; + } + + if (from->button) + { + if (!to->button) + { + classes = to->unused_classes; + to->button = classes->button; + if (!to->button) + { + to->button = calloc(1, sizeof(ButtonClassRec)); + if (!to->button) + FatalError("[Xi] no memory for class shift.\n"); + } else + classes->button = NULL; + } + + if (from->button->xkb_acts) + { + if (!to->button->xkb_acts) + { + to->button->xkb_acts = calloc(1, sizeof(XkbAction)); + if (!to->button->xkb_acts) + FatalError("[Xi] not enough memory for xkb_acts.\n"); + } + memcpy(to->button->xkb_acts, from->button->xkb_acts, + sizeof(XkbAction)); + } else + free(to->button->xkb_acts); + + memcpy(to->button->labels, from->button->labels, + from->button->numButtons * sizeof(Atom)); + to->button->sourceid = from->id; + } else if (to->button && !from->button) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->button = to->button; + to->button = NULL; + } + + if (from->proximity) + { + if (!to->proximity) + { + classes = to->unused_classes; + to->proximity = classes->proximity; + if (!to->proximity) + { + to->proximity = calloc(1, sizeof(ProximityClassRec)); + if (!to->proximity) + FatalError("[Xi] no memory for class shift.\n"); + } else + classes->proximity = NULL; + } + memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); + to->proximity->sourceid = from->id; + } else if (to->proximity) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->proximity = to->proximity; + to->proximity = NULL; + } +} + +/** + * Copies the CONTENT of the classes of device from into the classes in device + * to. From and to are identical after finishing. + * + * If to does not have classes from currenly has, the classes are stored in + * to's devPrivates system. Later, we recover it again from there if needed. + * Saves a few memory allocations. + */ +void +DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce) +{ + /* generic feedback classes, not tied to pointer and/or keyboard */ + DeepCopyFeedbackClasses(from, to); + + if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT)) + DeepCopyKeyboardClasses(from, to); + if ((dce->flags & DEVCHANGE_POINTER_EVENT)) + DeepCopyPointerClasses(from, to); +} + + +/** + * Send an XI2 DeviceChangedEvent to all interested clients. + */ +void +XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce) +{ + xXIDeviceChangedEvent *dcce; + int rc; + + rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce); + if (rc != Success) + { + ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc); + return; + } + + /* we don't actually swap if there's a NullClient, swapping is done + * later when event is delivered. */ + SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1); + free(dcce); +} + +static void +ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) +{ + DeviceIntPtr slave; + int rc; + + /* For now, we don't have devices that change physically. */ + if (!IsMaster(device)) + return; + + rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess); + + if (rc != Success) + return; /* Device has disappeared */ + + if (IsMaster(slave)) + return; + + if (IsFloating(slave)) + return; /* set floating since the event */ + + if (GetMaster(slave, MASTER_ATTACHED)->id != dce->masterid) + return; /* not our slave anymore, don't care */ + + /* FIXME: we probably need to send a DCE for the new slave now */ + + device->public.devicePrivate = slave->public.devicePrivate; + + /* FIXME: the classes may have changed since we generated the event. */ + DeepCopyDeviceClasses(slave, device, dce); + XISendDeviceChangedEvent(slave, device, dce); +} + +/** + * Update the device state according to the data in the event. + * + * return values are + * DEFAULT ... process as normal + * DONT_PROCESS ... return immediately from caller + */ +#define DEFAULT 0 +#define DONT_PROCESS 1 +int +UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) +{ + int i; + int key = 0, + bit = 0, + last_valuator; + + KeyClassPtr k = NULL; + ButtonClassPtr b = NULL; + ValuatorClassPtr v = NULL; + + /* This event is always the first we get, before the actual events with + * the data. However, the way how the DDX is set up, "device" will + * actually be the slave device that caused the event. + */ + switch(event->type) + { + case ET_DeviceChanged: + ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event); + return DONT_PROCESS; /* event has been sent already */ + case ET_Motion: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_KeyPress: + case ET_KeyRelease: + case ET_ProximityIn: + case ET_ProximityOut: + break; + default: + /* other events don't update the device */ + return DEFAULT; + } + + k = device->key; + v = device->valuator; + b = device->button; + + key = event->detail.key; + bit = 1 << (key & 7); + + /* Update device axis */ + /* Check valuators first */ + last_valuator = -1; + for (i = 0; i < MAX_VALUATORS; i++) + { + if (BitIsOn(&event->valuators.mask, i)) + { + if (!v) + { + ErrorF("[Xi] Valuators reported for non-valuator device '%s'. " + "Ignoring event.\n", device->name); + return DONT_PROCESS; + } else if (v->numAxes < i) + { + ErrorF("[Xi] Too many valuators reported for device '%s'. " + "Ignoring event.\n", device->name); + return DONT_PROCESS; + } + last_valuator = i; + } + } + + for (i = 0; i <= last_valuator && i < v->numAxes; i++) + { + if (BitIsOn(&event->valuators.mask, i)) + { + /* XXX: Relative/Absolute mode */ + v->axisVal[i] = event->valuators.data[i]; + v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16)); + } + } + + if (event->type == ET_KeyPress) { + if (!k) + return DONT_PROCESS; + + /* don't allow ddx to generate multiple downs, but repeats are okay */ + if (key_is_down(device, key, KEY_PROCESSED) && !event->key_repeat) + return DONT_PROCESS; + + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; + set_key_down(device, key, KEY_PROCESSED); + } else if (event->type == ET_KeyRelease) { + if (!k) + return DONT_PROCESS; + + if (!key_is_down(device, key, KEY_PROCESSED)) /* guard against duplicates */ + return DONT_PROCESS; + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; + set_key_up(device, key, KEY_PROCESSED); + } else if (event->type == ET_ButtonPress) { + Mask mask; + if (!b) + return DONT_PROCESS; + + if (button_is_down(device, key, BUTTON_PROCESSED)) + return DONT_PROCESS; + + set_button_down(device, key, BUTTON_PROCESSED); + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; + if (!b->map[key]) + return DONT_PROCESS; + b->buttonsDown++; + b->motionMask = DeviceButtonMotionMask; + if (b->map[key] <= 5) + b->state |= (Button1Mask >> 1) << b->map[key]; + + /* Add state and motionMask to the filter for this event */ + mask = DevicePointerMotionMask | b->state | b->motionMask; + SetMaskForEvent(device->id, mask, DeviceMotionNotify); + mask = PointerMotionMask | b->state | b->motionMask; + SetMaskForEvent(device->id, mask, MotionNotify); + } else if (event->type == ET_ButtonRelease) { + Mask mask; + if (!b) + return DONT_PROCESS; + + if (!button_is_down(device, key, BUTTON_PROCESSED)) + return DONT_PROCESS; + if (IsMaster(device)) { + DeviceIntPtr sd; + + /* + * Leave the button down if any slave has the + * button still down. Note that this depends on the + * event being delivered through the slave first + */ + for (sd = inputInfo.devices; sd; sd = sd->next) { + if (IsMaster(sd) || GetMaster(sd, MASTER_POINTER) != device) + continue; + if (!sd->button) + continue; + for (i = 1; i <= sd->button->numButtons; i++) + if (sd->button->map[i] == key && + button_is_down(sd, i, BUTTON_PROCESSED)) + return DONT_PROCESS; + } + } + set_button_up(device, key, BUTTON_PROCESSED); + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; + if (!b->map[key]) + return DONT_PROCESS; + if (b->buttonsDown >= 1 && !--b->buttonsDown) + b->motionMask = 0; + if (b->map[key] <= 5) + b->state &= ~((Button1Mask >> 1) << b->map[key]); + + /* Add state and motionMask to the filter for this event */ + mask = DevicePointerMotionMask | b->state | b->motionMask; + SetMaskForEvent(device->id, mask, DeviceMotionNotify); + mask = PointerMotionMask | b->state | b->motionMask; + SetMaskForEvent(device->id, mask, MotionNotify); + } else if (event->type == ET_ProximityIn) + device->proximity->in_proximity = TRUE; + else if (event->type == ET_ProximityOut) + device->proximity->in_proximity = FALSE; + + return DEFAULT; +} + +/** + * Main device event processing function. + * Called from when processing the events from the event queue. + * + */ +void +ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) +{ + GrabPtr grab; + Bool deactivateDeviceGrab = FALSE; + int key = 0, rootX, rootY; + ButtonClassPtr b; + KeyClassPtr k; + ValuatorClassPtr v; + int ret = 0; + int state, i; + DeviceIntPtr mouse = NULL, kbd = NULL; + DeviceEvent *event = &ev->device_event; + + verify_internal_event(ev); + + if (ev->any.type == ET_RawKeyPress || + ev->any.type == ET_RawKeyRelease || + ev->any.type == ET_RawButtonPress || + ev->any.type == ET_RawButtonRelease || + ev->any.type == ET_RawMotion) + { + DeliverRawEvent(&ev->raw_event, device); + return; + } + + if (IsPointerDevice(device)) + { + kbd = GetPairedDevice(device); + mouse = device; + if (kbd && !kbd->key) /* can happen with floating SDs */ + kbd = NULL; + } else + { + mouse = GetPairedDevice(device); + kbd = device; + if (!mouse->valuator || !mouse->button) /* may be float. SDs */ + mouse = NULL; + } + + /* State needs to be assembled BEFORE the device is updated. */ + state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0; + state |= (mouse && mouse->button) ? (mouse->button->state) : 0; + + for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) + if (BitIsOn(mouse->button->down, i)) + SetBit(event->buttons, i); + + if (kbd && kbd->key) + { + XkbStatePtr state; + /* we need the state before the event happens */ + if (event->type == ET_KeyPress || event->type == ET_KeyRelease) + state = &kbd->key->xkbInfo->prev_state; + else + state = &kbd->key->xkbInfo->state; + + event->mods.base = state->base_mods; + event->mods.latched = state->latched_mods; + event->mods.locked = state->locked_mods; + event->mods.effective = state->mods; + + event->group.base = state->base_group; + event->group.latched = state->latched_group; + event->group.locked = state->locked_group; + event->group.effective = state->group; + } + + ret = UpdateDeviceState(device, event); + if (ret == DONT_PROCESS) + return; + + v = device->valuator; + b = device->button; + k = device->key; + + if (IsMaster(device) || IsFloating(device)) + CheckMotion(event, device); + + switch (event->type) + { + case ET_Motion: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_KeyPress: + case ET_KeyRelease: + case ET_ProximityIn: + case ET_ProximityOut: + if (!device->spriteInfo->sprite) + return; + GetSpritePosition(device, &rootX, &rootY); + event->root_x = rootX; + event->root_y = rootY; + NoticeEventTime((InternalEvent*)event); + event->corestate = state; + key = event->detail.key; + break; + default: + break; + } + + if (DeviceEventCallback && !syncEvents.playingEvents) { + DeviceEventInfoRec eventinfo; + SpritePtr pSprite = device->spriteInfo->sprite; + + /* see comment in EnqueueEvents regarding the next three lines */ + if (ev->any.type == ET_Motion) + ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id; + + eventinfo.device = device; + eventinfo.event = ev; + CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); + } + + grab = device->deviceGrab.grab; + + switch(event->type) + { + case ET_KeyPress: + if (!grab && CheckDeviceGrabs(device, event, 0)) + return; + break; + case ET_KeyRelease: + if (grab && device->deviceGrab.fromPassiveGrab && + (key == device->deviceGrab.activatingKey) && + (device->deviceGrab.grab->type == KeyPress || + device->deviceGrab.grab->type == DeviceKeyPress || + device->deviceGrab.grab->type == XI_KeyPress)) + deactivateDeviceGrab = TRUE; + break; + case ET_ButtonPress: + event->detail.button = b->map[key]; + if (!event->detail.button) { /* there's no button 0 */ + event->detail.button = key; + return; + } + if (!grab && CheckDeviceGrabs(device, event, 0)) + { + /* if a passive grab was activated, the event has been sent + * already */ + return; + } + break; + case ET_ButtonRelease: + event->detail.button = b->map[key]; + if (!event->detail.button) { /* there's no button 0 */ + event->detail.button = key; + return; + } + if (grab && !b->buttonsDown && + device->deviceGrab.fromPassiveGrab && + (device->deviceGrab.grab->type == ButtonPress || + device->deviceGrab.grab->type == DeviceButtonPress || + device->deviceGrab.grab->type == XI_ButtonPress)) + deactivateDeviceGrab = TRUE; + default: + break; + } + + + if (grab) + DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab); + else if (device->focus && !IsPointerEvent((InternalEvent*)ev)) + DeliverFocusedEvent(device, (InternalEvent*)event, + GetSpriteWindow(device)); + else + DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event, + NullGrab, NullWindow, device); + + if (deactivateDeviceGrab == TRUE) + (*device->deviceGrab.DeactivateGrab) (device); + event->detail.key = key; +} + +int +InitProximityClassDeviceStruct(DeviceIntPtr dev) +{ + ProximityClassPtr proxc; + + proxc = (ProximityClassPtr) malloc(sizeof(ProximityClassRec)); + if (!proxc) + return FALSE; + proxc->sourceid = dev->id; + proxc->in_proximity = TRUE; + dev->proximity = proxc; + return TRUE; +} + +/** + * Initialise the device's valuators. The memory must already be allocated, + * this function merely inits the matching axis (specified through axnum) to + * sane values. + * + * It is a condition that (minval < maxval). + * + * @see InitValuatorClassDeviceStruct + */ +void +InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, + int resolution, int min_res, int max_res, int mode) +{ + AxisInfoPtr ax; + + if (!dev || !dev->valuator || minval > maxval) + return; + if (axnum >= dev->valuator->numAxes) + return; + + ax = dev->valuator->axes + axnum; + + ax->min_value = minval; + ax->max_value = maxval; + ax->resolution = resolution; + ax->min_resolution = min_res; + ax->max_resolution = max_res; + ax->label = label; + ax->mode = mode; + + if (mode & OutOfProximity) + dev->proximity->in_proximity = FALSE; +} + +static void +FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, + ButtonClassPtr b, ValuatorClassPtr v, int first) +{ + ev->type = DeviceStateNotify; + ev->deviceid = dev->id; + ev->time = currentTime.milliseconds; + ev->classes_reported = 0; + ev->num_keys = 0; + ev->num_buttons = 0; + ev->num_valuators = 0; + + if (b) { + ev->classes_reported |= (1 << ButtonClass); + ev->num_buttons = b->numButtons; + memcpy((char*)ev->buttons, (char*)b->down, 4); + } else if (k) { + ev->classes_reported |= (1 << KeyClass); + ev->num_keys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code; + memmove((char *)&ev->keys[0], (char *)k->down, 4); + } + if (v) { + int nval = v->numAxes - first; + + ev->classes_reported |= (1 << ValuatorClass); + ev->classes_reported |= valuator_get_mode(dev, 0) << ModeBitsShift; + ev->num_valuators = nval < 3 ? nval : 3; + switch (ev->num_valuators) { + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: + ev->valuator1 = v->axisVal[first + 1]; + case 1: + ev->valuator0 = v->axisVal[first]; + break; + } + } +} + +static void +FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, + int first) +{ + int nval = v->numAxes - first; + + ev->type = DeviceValuator; + ev->deviceid = dev->id; + ev->num_valuators = nval < 3 ? nval : 3; + ev->first_valuator = first; + switch (ev->num_valuators) { + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: + ev->valuator1 = v->axisVal[first + 1]; + case 1: + ev->valuator0 = v->axisVal[first]; + break; + } + first += ev->num_valuators; +} + +static void +DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) +{ + int evcount = 1; + deviceStateNotify *ev, *sev; + deviceKeyStateNotify *kev; + deviceButtonStateNotify *bev; + + KeyClassPtr k; + ButtonClassPtr b; + ValuatorClassPtr v; + int nval = 0, nkeys = 0, nbuttons = 0, first = 0; + + if (!(wOtherInputMasks(win)) || + !(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask)) + return; + + if ((b = dev->button) != NULL) { + nbuttons = b->numButtons; + if (nbuttons > 32) + evcount++; + } + if ((k = dev->key) != NULL) { + nkeys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code; + if (nkeys > 32) + evcount++; + if (nbuttons > 0) { + evcount++; + } + } + if ((v = dev->valuator) != NULL) { + nval = v->numAxes; + + if (nval > 3) + evcount++; + if (nval > 6) { + if (!(k && b)) + evcount++; + if (nval > 9) + evcount += ((nval - 7) / 3); + } + } + + sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); + FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); + + if (b != NULL) { + FixDeviceStateNotify(dev, ev++, NULL, b, v, first); + first += 3; + nval -= 3; + if (nbuttons > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + bev = (deviceButtonStateNotify *) ev++; + bev->type = DeviceButtonStateNotify; + bev->deviceid = dev->id; + memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + if (k != NULL) { + FixDeviceStateNotify(dev, ev++, k, NULL, v, first); + first += 3; + nval -= 3; + if (nkeys > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + kev = (deviceKeyStateNotify *) ev++; + kev->type = DeviceKeyStateNotify; + kev->deviceid = dev->id; + memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + while (nval > 0) { + FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); + first += 3; + nval -= 3; + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, + DeviceStateNotifyMask, NullGrab); + free(sev); +} + +void +DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, + WindowPtr pWin) +{ + deviceFocus event; + xXIFocusInEvent *xi2event; + DeviceIntPtr mouse; + int btlen, len, i; + + mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER); + + /* XI 2 event */ + btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; + btlen = bytes_to_int32(btlen); + len = sizeof(xXIFocusInEvent) + btlen * 4; + + xi2event = calloc(1, len); + xi2event->type = GenericEvent; + xi2event->extension = IReqCode; + xi2event->evtype = type; + xi2event->length = bytes_to_int32(len - sizeof(xEvent)); + xi2event->buttons_len = btlen; + xi2event->detail = detail; + xi2event->time = currentTime.milliseconds; + xi2event->deviceid = dev->id; + xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ + xi2event->mode = mode; + xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); + xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); + + for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) + if (BitIsOn(mouse->button->down, i)) + SetBit(&xi2event[1], i); + + if (dev->key) + { + xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; + xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; + xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; + xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; + + xi2event->group.base_group = dev->key->xkbInfo->state.base_group; + xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; + xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; + xi2event->group.effective_group = dev->key->xkbInfo->state.group; + } + + FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent*)xi2event, pWin, + None, FALSE); + + DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, + GetEventFilter(dev, (xEvent*)xi2event), NullGrab); + + free(xi2event); + + /* XI 1.x event */ + event.deviceid = dev->id; + event.mode = mode; + event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; + event.detail = detail; + event.window = pWin->drawable.id; + event.time = currentTime.milliseconds; + + DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, + DeviceFocusChangeMask, NullGrab); + + if (event.type == DeviceFocusIn) + DeliverStateNotifyEvent(dev, pWin); +} + +int +CheckGrabValues(ClientPtr client, GrabParameters* param) +{ + if (param->grabtype != GRABTYPE_CORE && + param->grabtype != GRABTYPE_XI && + param->grabtype != GRABTYPE_XI2) + { + ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); + return BadImplementation; + } + + if ((param->this_device_mode != GrabModeSync) && + (param->this_device_mode != GrabModeAsync)) { + client->errorValue = param->this_device_mode; + return BadValue; + } + if ((param->other_devices_mode != GrabModeSync) && + (param->other_devices_mode != GrabModeAsync)) { + client->errorValue = param->other_devices_mode; + return BadValue; + } + + if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && + (param->modifiers & ~AllModifiersMask)) { + client->errorValue = param->modifiers; + return BadValue; + } + + if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { + client->errorValue = param->ownerEvents; + return BadValue; + } + return Success; +} + +int +GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, + int button, GrabParameters *param, GrabType grabtype, + GrabMask *mask) +{ + WindowPtr pWin, confineTo; + CursorPtr cursor; + GrabPtr grab; + int rc, type = -1; + Mask access_mode = DixGrabAccess; + + rc = CheckGrabValues(client, param); + if (rc != Success) + return rc; + if (param->confineTo == None) + confineTo = NullWindow; + else { + rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); + if (rc != Success) + return rc; + } + if (param->cursor == None) + cursor = NullCursor; + else { + rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, + RT_CURSOR, client, DixUseAccess); + if (rc != Success) + { + client->errorValue = param->cursor; + return rc; + } + access_mode |= DixForceAccess; + } + if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) + access_mode |= DixFreezeAccess; + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); + if (rc != Success) + return rc; + rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); + if (rc != Success) + return rc; + + if (grabtype == GRABTYPE_XI) + type = DeviceButtonPress; + else if (grabtype == GRABTYPE_XI2) + type = XI_ButtonPress; + + grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, + mask, param, type, button, confineTo, cursor); + if (!grab) + return BadAlloc; + return AddPassiveGrabToList(client, grab); +} + +/** + * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If + * grabtype is GRABTYPE_XI2, the key is a keysym. + */ +int +GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, + int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) +{ + WindowPtr pWin; + GrabPtr grab; + KeyClassPtr k = dev->key; + Mask access_mode = DixGrabAccess; + int rc, type = -1; + + rc = CheckGrabValues(client, param); + if (rc != Success) + return rc; + if (k == NULL) + return BadMatch; + if (grabtype == GRABTYPE_XI) + { + if ((key > k->xkbInfo->desc->max_key_code || + key < k->xkbInfo->desc->min_key_code) + && (key != AnyKey)) { + client->errorValue = key; + return BadValue; + } + type = DeviceKeyPress; + } else if (grabtype == GRABTYPE_XI2) + type = XI_KeyPress; + + rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); + if (rc != Success) + return rc; + if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) + access_mode |= DixFreezeAccess; + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); + if (rc != Success) + return rc; + + grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, + mask, param, type, key, NULL, NULL); + if (!grab) + return BadAlloc; + return AddPassiveGrabToList(client, grab); +} + +/* Enter/FocusIn grab */ +int +GrabWindow(ClientPtr client, DeviceIntPtr dev, int type, + GrabParameters *param, GrabMask *mask) +{ + WindowPtr pWin; + CursorPtr cursor; + GrabPtr grab; + Mask access_mode = DixGrabAccess; + int rc; + + rc = CheckGrabValues(client, param); + if (rc != Success) + return rc; + + rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); + if (rc != Success) + return rc; + if (param->cursor == None) + cursor = NullCursor; + else { + rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, + RT_CURSOR, client, DixUseAccess); + if (rc != Success) + { + client->errorValue = param->cursor; + return rc; + } + access_mode |= DixForceAccess; + } + if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) + access_mode |= DixFreezeAccess; + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); + if (rc != Success) + return rc; + + grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, + mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, + 0, NULL, cursor); + + if (!grab) + return BadAlloc; + + return AddPassiveGrabToList(client, grab); +} + +int +SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, + Mask mask, Mask exclusivemasks) +{ + int mskidx = dev->id; + int i, ret; + Mask check; + InputClientsPtr others; + + check = (mask & exclusivemasks); + if (wOtherInputMasks(pWin)) { + if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different + * clients to select on any of the + * events for maskcheck. However, + * it is OK, for some client to + * continue selecting on one of those + * events. */ + for (others = wOtherInputMasks(pWin)->inputClients; others; + others = others->next) { + if (!SameClient(others, client) && (check & + others->mask[mskidx])) + return BadAccess; + } + } + for (others = wOtherInputMasks(pWin)->inputClients; others; + others = others->next) { + if (SameClient(others, client)) { + check = others->mask[mskidx]; + others->mask[mskidx] = mask; + if (mask == 0) { + for (i = 0; i < EMASKSIZE; i++) + if (i != mskidx && others->mask[i] != 0) + break; + if (i == EMASKSIZE) { + RecalculateDeviceDeliverableEvents(pWin); + if (ShouldFreeInputMasks(pWin, FALSE)) + FreeResource(others->resource, RT_NONE); + return Success; + } + } + goto maskSet; + } + } + } + check = 0; + if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) + return ret; + maskSet: + if (dev->valuator) + if ((dev->valuator->motionHintWindow == pWin) && + (mask & DevicePointerMotionHintMask) && + !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) + dev->valuator->motionHintWindow = NullWindow; + RecalculateDeviceDeliverableEvents(pWin); + return Success; +} + +int +AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) +{ + InputClientsPtr others; + + if (!pWin->optional && !MakeWindowOptional(pWin)) + return BadAlloc; + others = calloc(1, sizeof(InputClients)); + if (!others) + return BadAlloc; + if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) + goto bail; + others->mask[mskidx] = mask; + others->resource = FakeClientID(client->index); + others->next = pWin->optional->inputMasks->inputClients; + pWin->optional->inputMasks->inputClients = others; + if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) + goto bail; + return Success; + +bail: + free(others); + return BadAlloc; +} + +static Bool +MakeInputMasks(WindowPtr pWin) +{ + struct _OtherInputMasks *imasks; + + imasks = calloc(1, sizeof(struct _OtherInputMasks)); + if (!imasks) + return FALSE; + pWin->optional->inputMasks = imasks; + return TRUE; +} + +void +RecalculateDeviceDeliverableEvents(WindowPtr pWin) +{ + InputClientsPtr others; + struct _OtherInputMasks *inputMasks; /* default: NULL */ + WindowPtr pChild, tmp; + 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]; + for (tmp = pChild->parent; tmp; tmp = tmp->parent) + if (wOtherInputMasks(tmp)) + for (i = 0; i < EMASKSIZE; i++) + inputMasks->deliverableEvents[i] |= + (wOtherInputMasks(tmp)->deliverableEvents[i] + & ~inputMasks-> + dontPropagateMask[i] & PropagateMask[i]); + } + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + while (!pChild->nextSib && (pChild != pWin)) + pChild = pChild->parent; + if (pChild == pWin) + break; + pChild = pChild->nextSib; + } +} + +#ifdef _MSC_VER +#pragma warning(disable:4715) /* Not all control paths return a value */ +#endif + +int +InputClientGone(WindowPtr pWin, XID id) +{ + InputClientsPtr other, prev; + + if (!wOtherInputMasks(pWin)) + return Success; + prev = 0; + for (other = wOtherInputMasks(pWin)->inputClients; other; + other = other->next) { + if (other->resource == id) { + if (prev) { + prev->next = other->next; + free(other); + } else if (!(other->next)) { + if (ShouldFreeInputMasks(pWin, TRUE)) { + wOtherInputMasks(pWin)->inputClients = other->next; + free(wOtherInputMasks(pWin)); + pWin->optional->inputMasks = (OtherInputMasks *) NULL; + CheckWindowOptionalNeed(pWin); + free(other); + } else { + other->resource = FakeClientID(0); + if (!AddResource(other->resource, RT_INPUTCLIENT, + (pointer) pWin)) + return BadAlloc; + } + } else { + wOtherInputMasks(pWin)->inputClients = other->next; + free(other); + } + RecalculateDeviceDeliverableEvents(pWin); + return Success; + } + prev = other; + } + FatalError("client not on device event list"); +} + +int +SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, + xEvent * ev, Mask mask, int count) +{ + WindowPtr pWin; + WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ + WindowPtr spriteWin = GetSpriteWindow(d); + + if (dest == PointerWindow) + pWin = spriteWin; + else if (dest == InputFocus) { + WindowPtr inputFocus; + + if (!d->focus) + inputFocus = spriteWin; + else + inputFocus = d->focus->win; + + if (inputFocus == FollowKeyboardWin) + inputFocus = inputInfo.keyboard->focus->win; + + if (inputFocus == NoneWin) + return Success; + + /* If the input focus is PointerRootWin, send the event to where + * the pointer is if possible, then perhaps propogate up to root. */ + if (inputFocus == PointerRootWin) + inputFocus = GetCurrentRootWindow(d); + + if (IsParent(inputFocus, spriteWin)) { + effectiveFocus = inputFocus; + pWin = spriteWin; + } else + effectiveFocus = pWin = inputFocus; + } else + dixLookupWindow(&pWin, dest, client, DixSendAccess); + if (!pWin) + return BadWindow; + if ((propagate != xFalse) && (propagate != xTrue)) { + client->errorValue = propagate; + return BadValue; + } + ev->u.u.type |= 0x80; + if (propagate) { + for (; pWin; pWin = pWin->parent) { + if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) + return Success; + if (pWin == effectiveFocus) + return Success; + if (wOtherInputMasks(pWin)) + mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; + if (!mask) + break; + } + } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) + DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); + return Success; +} + +int +SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) +{ + int i; + ButtonClassPtr b = dev->button; + + if (b == NULL) + return BadMatch; + + if (nElts != b->numButtons) { + client->errorValue = nElts; + return BadValue; + } + if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) + return BadValue; + for (i = 0; i < nElts; i++) + if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) + return MappingBusy; + for (i = 0; i < nElts; i++) + b->map[i + 1] = map[i]; + return Success; +} + +int +ChangeKeyMapping(ClientPtr client, + DeviceIntPtr dev, + unsigned len, + int type, + KeyCode firstKeyCode, + CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) +{ + KeySymsRec keysyms; + KeyClassPtr k = dev->key; + + if (k == NULL) + return BadMatch; + + if (len != (keyCodes * keySymsPerKeyCode)) + return BadLength; + + if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || + (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { + client->errorValue = firstKeyCode; + return BadValue; + } + if (keySymsPerKeyCode == 0) { + client->errorValue = 0; + return BadValue; + } + keysyms.minKeyCode = firstKeyCode; + keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; + keysyms.mapWidth = keySymsPerKeyCode; + keysyms.map = map; + + XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, + serverClient); + + return Success; +} + +static void +DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) +{ + WindowPtr parent; + + /* Deactivate any grabs performed on this window, before making + * any input focus changes. + * Deactivating a device grab should cause focus events. */ + + if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) + (*dev->deviceGrab.DeactivateGrab) (dev); + + /* If the focus window is a root window (ie. has no parent) + * then don't delete the focus from it. */ + + if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { + int focusEventMode = NotifyNormal; + + /* If a grab is in progress, then alter the mode of focus events. */ + + if (dev->deviceGrab.grab) + focusEventMode = NotifyWhileGrabbed; + + switch (dev->focus->revert) { + case RevertToNone: + if (!ActivateFocusInGrab(dev, pWin, NoneWin)) + DoFocusEvents(dev, pWin, NoneWin, focusEventMode); + dev->focus->win = NoneWin; + dev->focus->traceGood = 0; + break; + case RevertToParent: + parent = pWin; + do { + parent = parent->parent; + dev->focus->traceGood--; + } + while (!parent->realized); + if (!ActivateFocusInGrab(dev, pWin, parent)) + DoFocusEvents(dev, pWin, parent, focusEventMode); + dev->focus->win = parent; + dev->focus->revert = RevertToNone; + break; + case RevertToPointerRoot: + if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) + DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); + dev->focus->win = PointerRootWin; + dev->focus->traceGood = 0; + break; + case RevertToFollowKeyboard: + { + DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); + if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) + kbd = inputInfo.keyboard; + if (kbd->focus->win) { + if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) + DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); + dev->focus->win = FollowKeyboardWin; + dev->focus->traceGood = 0; + } else { + if (!ActivateFocusInGrab(dev, pWin, NoneWin)) + DoFocusEvents(dev, pWin, NoneWin, focusEventMode); + dev->focus->win = NoneWin; + dev->focus->traceGood = 0; + } + } + break; + } + } + + if (dev->valuator) + if (dev->valuator->motionHintWindow == pWin) + dev->valuator->motionHintWindow = NullWindow; +} + +void +DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) +{ + int i; + DeviceIntPtr dev; + InputClientsPtr ic; + struct _OtherInputMasks *inputMasks; + + for (dev = inputInfo.devices; dev; dev = dev->next) { + DeleteDeviceFromAnyExtEvents(pWin, dev); + } + + for (dev = inputInfo.off_devices; dev; dev = dev->next) + DeleteDeviceFromAnyExtEvents(pWin, dev); + + if (freeResources) + while ((inputMasks = wOtherInputMasks(pWin)) != 0) { + ic = inputMasks->inputClients; + for (i = 0; i < EMASKSIZE; i++) + inputMasks->dontPropagateMask[i] = 0; + FreeResource(ic->resource, RT_NONE); + } +} + +int +MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) +{ + DeviceIntPtr dev; + + dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, + DixReadAccess); + if (!dev) + return 0; + + if (pEvents->type == DeviceMotionNotify) { + if (mask & DevicePointerMotionHintMask) { + if (WID(dev->valuator->motionHintWindow) == pEvents->event) { + return 1; /* don't send, but pretend we did */ + } + pEvents->detail = NotifyHint; + } else { + pEvents->detail = NotifyNormal; + } + } + return 0; +} + +void +CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, + deviceKeyButtonPointer * xE, GrabPtr grab, + ClientPtr client, Mask deliveryMask) +{ + DeviceIntPtr dev; + + dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, + DixGrabAccess); + if (!dev) + return; + + if (type == DeviceMotionNotify) + dev->valuator->motionHintWindow = pWin; + else if ((type == DeviceButtonPress) && (!grab) && + (deliveryMask & DeviceButtonGrabMask)) { + GrabRec tempGrab; + + tempGrab.device = dev; + tempGrab.resource = client->clientAsMask; + tempGrab.window = pWin; + tempGrab.ownerEvents = + (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; + tempGrab.eventMask = deliveryMask; + tempGrab.keyboardMode = GrabModeAsync; + tempGrab.pointerMode = GrabModeAsync; + tempGrab.confineTo = NullWindow; + tempGrab.cursor = NullCursor; + tempGrab.next = NULL; + (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); + } +} + +static Mask +DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) +{ + InputClientsPtr other; + + if (!wOtherInputMasks(pWin)) + return 0; + for (other = wOtherInputMasks(pWin)->inputClients; other; + other = other->next) { + if (SameClient(other, client)) + return other->mask[dev->id]; + } + return 0; +} + +void +MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) +{ + WindowPtr pWin; + GrabPtr grab = dev->deviceGrab.grab; + + pWin = dev->valuator->motionHintWindow; + + if ((grab && SameClient(grab, client) && + ((grab->eventMask & DevicePointerMotionHintMask) || + (grab->ownerEvents && + (DeviceEventMaskForClient(dev, pWin, client) & + DevicePointerMotionHintMask)))) || + (!grab && + (DeviceEventMaskForClient(dev, pWin, client) & + DevicePointerMotionHintMask))) + dev->valuator->motionHintWindow = NullWindow; +} + +int +DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, + int maskndx) +{ + struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); + + if (mask & ~PropagateMask[maskndx]) { + client->errorValue = mask; + return BadValue; + } + + if (mask == 0) { + if (inputMasks) + inputMasks->dontPropagateMask[maskndx] = mask; + } else { + if (!inputMasks) + AddExtensionClient(pWin, client, 0, 0); + inputMasks = wOtherInputMasks(pWin); + inputMasks->dontPropagateMask[maskndx] = mask; + } + RecalculateDeviceDeliverableEvents(pWin); + if (ShouldFreeInputMasks(pWin, FALSE)) + FreeResource(inputMasks->inputClients->resource, RT_NONE); + return Success; +} + +Bool +ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) +{ + int i; + Mask allInputEventMasks = 0; + struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); + + for (i = 0; i < EMASKSIZE; i++) + allInputEventMasks |= inputMasks->dontPropagateMask[i]; + if (!ignoreSelectedEvents) + for (i = 0; i < EMASKSIZE; i++) + allInputEventMasks |= inputMasks->inputEvents[i]; + if (allInputEventMasks == 0) + return TRUE; + else + return FALSE; +} + +/*********************************************************************** + * + * Walk through the window tree, finding all clients that want to know + * about the Event. + * + */ + +static void +FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, + xEvent * ev, int count) +{ + WindowPtr p2; + + while (p1) { + p2 = p1->firstChild; + DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); + FindInterestedChildren(dev, p2, mask, ev, count); + p1 = p1->nextSib; + } +} + +/*********************************************************************** + * + * Send an event to interested clients in all windows on all screens. + * + */ + +void +SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) +{ + int i; + WindowPtr pWin, p1; + + for (i = 0; i < screenInfo.numScreens; i++) { + pWin = screenInfo.screens[i]->root; + if (!pWin) + continue; + DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); + p1 = pWin->firstChild; + FindInterestedChildren(dev, p1, mask, ev, 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) + */ +int +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; + } + } + } + + len = min(len, sizeof(others->xi2mask[dev->id])); + + if (len && !others) + { + if (AddExtensionClient(win, client, 0, 0) != Success) + return BadAlloc; + others= wOtherInputMasks(win)->inputClients; + } + + if (others) + memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); + + if (len) + memcpy(others->xi2mask[dev->id], mask, len); + + RecalculateDeviceDeliverableEvents(win); + + return Success; +} diff --git a/xorg-server/Xi/exglobals.h b/xorg-server/Xi/exglobals.h index cba7efed7..8c5a42e6e 100644 --- a/xorg-server/Xi/exglobals.h +++ b/xorg-server/Xi/exglobals.h @@ -1,84 +1,84 @@ -/************************************************************
-
-Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
-
- All Rights Reserved
-
-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 the above listed
-copyright holder(s) not be used in advertising or publicity pertaining
-to distribution of the software without specific, written prior
-permission.
-
-THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
-TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
-
-********************************************************/
-
-/*****************************************************************
- *
- * Globals referenced elsewhere in the server.
- *
- */
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-#include "privates.h"
-
-#ifndef EXGLOBALS_H
-#define EXGLOBALS_H 1
-
-extern int IReqCode;
-extern int IEventBase;
-extern int BadDevice;
-extern int BadMode;
-extern int DeviceBusy;
-extern int BadClass;
-
-/* Note: only the ones needed in files other than extinit.c are declared */
-extern const Mask DevicePointerMotionMask;
-extern const Mask DevicePointerMotionHintMask;
-extern const Mask DeviceFocusChangeMask;
-extern const Mask DeviceStateNotifyMask;
-extern const Mask DeviceMappingNotifyMask;
-extern const Mask DeviceOwnerGrabButtonMask;
-extern const Mask DeviceButtonGrabMask;
-extern const Mask DeviceButtonMotionMask;
-extern const Mask DevicePresenceNotifyMask;
-extern const Mask DevicePropertyNotifyMask;
-extern const Mask XIAllMasks;
-
-extern Mask PropagateMask[];
-
-extern int DeviceValuator;
-extern int DeviceKeyPress;
-extern int DeviceKeyRelease;
-extern int DeviceButtonPress;
-extern int DeviceButtonRelease;
-extern int DeviceMotionNotify;
-extern int DeviceFocusIn;
-extern int DeviceFocusOut;
-extern int ProximityIn;
-extern int ProximityOut;
-extern int DeviceStateNotify;
-extern int DeviceKeyStateNotify;
-extern int DeviceButtonStateNotify;
-extern int DeviceMappingNotify;
-extern int ChangeDeviceNotify;
-extern int DevicePresenceNotify;
-extern int DevicePropertyNotify;
-
-extern RESTYPE RT_INPUTCLIENT;
-
-extern DevPrivateKeyRec XIClientPrivateKeyRec;
-#define XIClientPrivateKey (&XIClientPrivateKeyRec)
-
-#endif /* EXGLOBALS_H */
+/************************************************************ + +Copyright 1996 by Thomas E. Dickey <dickey@clark.net> + + All Rights Reserved + +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 the above listed +copyright holder(s) not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. + +THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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. + +********************************************************/ + +/***************************************************************** + * + * Globals referenced elsewhere in the server. + * + */ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif +#include "privates.h" + +#ifndef EXGLOBALS_H +#define EXGLOBALS_H 1 + +extern int IReqCode; +extern int IEventBase; +extern int BadDevice; +extern int BadMode; +extern int DeviceBusy; +extern int BadClass; + +/* Note: only the ones needed in files other than extinit.c are declared */ +extern const Mask DevicePointerMotionMask; +extern const Mask DevicePointerMotionHintMask; +extern const Mask DeviceFocusChangeMask; +extern const Mask DeviceStateNotifyMask; +extern const Mask DeviceMappingNotifyMask; +extern const Mask DeviceOwnerGrabButtonMask; +extern const Mask DeviceButtonGrabMask; +extern const Mask DeviceButtonMotionMask; +extern const Mask DevicePresenceNotifyMask; +extern const Mask DevicePropertyNotifyMask; +extern const Mask XIAllMasks; + +extern Mask PropagateMask[]; + +extern int DeviceValuator; +extern int DeviceKeyPress; +extern int DeviceKeyRelease; +extern int DeviceButtonPress; +extern int DeviceButtonRelease; +extern int DeviceMotionNotify; +extern int DeviceFocusIn; +extern int DeviceFocusOut; +extern int ProximityIn; +extern int ProximityOut; +extern int DeviceStateNotify; +extern int DeviceKeyStateNotify; +extern int DeviceButtonStateNotify; +extern int DeviceMappingNotify; +extern int ChangeDeviceNotify; +extern int DevicePresenceNotify; +extern int DevicePropertyNotify; + +extern RESTYPE RT_INPUTCLIENT; + +extern DevPrivateKeyRec XIClientPrivateKeyRec; +#define XIClientPrivateKey (&XIClientPrivateKeyRec) + +#endif /* EXGLOBALS_H */ diff --git a/xorg-server/Xi/extinit.c b/xorg-server/Xi/extinit.c index 300278f7d..0905e1877 100644 --- a/xorg-server/Xi/extinit.c +++ b/xorg-server/Xi/extinit.c @@ -1,1310 +1,1310 @@ -/************************************************************
-
-Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California.
-
- All Rights Reserved
-
-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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-HEWLETT-PACKARD 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.
-
-********************************************************/
-
-/********************************************************************
- *
- * Dispatch routines and initialization routines for the X input extension.
- *
- */
-#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0]))
-
-#define NUMTYPES 15
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "inputstr.h"
-#include "gcstruct.h" /* pointer for extnsionst.h */
-#include "extnsionst.h" /* extension entry */
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include <X11/extensions/XI2proto.h>
-#include <X11/extensions/geproto.h>
-#include "geext.h" /* extension interfaces for ge */
-
-#include "dixevents.h"
-#include "exevents.h"
-#include "extinit.h"
-#include "exglobals.h"
-#include "swaprep.h"
-#include "privates.h"
-#include "protocol-versions.h"
-
-/* modules local to Xi */
-#include "allowev.h"
-#include "chgdctl.h"
-#include "chgfctl.h"
-#include "chgkbd.h"
-#include "chgprop.h"
-#include "chgptr.h"
-#include "closedev.h"
-#include "devbell.h"
-#include "getbmap.h"
-#include "getdctl.h"
-#include "getfctl.h"
-#include "getfocus.h"
-#include "getkmap.h"
-#include "getmmap.h"
-#include "getprop.h"
-#include "getselev.h"
-#include "getvers.h"
-#include "grabdev.h"
-#include "grabdevb.h"
-#include "grabdevk.h"
-#include "gtmotion.h"
-#include "listdev.h"
-#include "opendev.h"
-#include "queryst.h"
-#include "selectev.h"
-#include "sendexev.h"
-#include "chgkmap.h"
-#include "setbmap.h"
-#include "setdval.h"
-#include "setfocus.h"
-#include "setmmap.h"
-#include "setmode.h"
-#include "ungrdev.h"
-#include "ungrdevb.h"
-#include "ungrdevk.h"
-#include "xiallowev.h"
-#include "xiselectev.h"
-#include "xigrabdev.h"
-#include "xipassivegrab.h"
-#include "xisetdevfocus.h"
-#include "xiproperty.h"
-#include "xichangecursor.h"
-#include "xichangehierarchy.h"
-#include "xigetclientpointer.h"
-#include "xiquerydevice.h"
-#include "xiquerypointer.h"
-#include "xiqueryversion.h"
-#include "xisetclientpointer.h"
-#include "xiwarppointer.h"
-
-
-/* Masks for XI events have to be aligned with core event (partially anyway).
- * If DeviceButtonMotionMask is != ButtonMotionMask, event delivery
- * breaks down. The device needs the dev->button->motionMask. If DBMM is
- * the same as BMM, we can ensure that both core and device events can be
- * delivered, without the need for extra structures in the DeviceIntRec. */
-const Mask DeviceKeyPressMask = KeyPressMask;
-const Mask DeviceKeyReleaseMask = KeyReleaseMask;
-const Mask DeviceButtonPressMask = ButtonPressMask;
-const Mask DeviceButtonReleaseMask = ButtonReleaseMask;
-const Mask DeviceProximityMask = (1L << 4);
-const Mask DeviceStateNotifyMask = (1L << 5);
-const Mask DevicePointerMotionMask = PointerMotionMask;
-const Mask DevicePointerMotionHintMask = PointerMotionHintMask;
-const Mask DeviceButton1MotionMask = Button1MotionMask;
-const Mask DeviceButton2MotionMask = Button2MotionMask;
-const Mask DeviceButton3MotionMask = Button3MotionMask;
-const Mask DeviceButton4MotionMask = Button4MotionMask;
-const Mask DeviceButton5MotionMask = Button5MotionMask;
-const Mask DeviceButtonMotionMask = ButtonMotionMask;
-const Mask DeviceFocusChangeMask = (1L << 14);
-const Mask DeviceMappingNotifyMask = (1L << 15);
-const Mask ChangeDeviceNotifyMask = (1L << 16);
-const Mask DeviceButtonGrabMask = (1L << 17);
-const Mask DeviceOwnerGrabButtonMask = (1L << 17);
-const Mask DevicePresenceNotifyMask = (1L << 18);
-const Mask DeviceEnterWindowMask = (1L << 18);
-const Mask DeviceLeaveWindowMask = (1L << 19);
-const Mask DevicePropertyNotifyMask = (1L << 20);
-const Mask XIAllMasks = (1L << 21) - 1;
-
-int ExtEventIndex;
-Mask ExtExclusiveMasks[EMASKSIZE];
-
-static struct dev_type
-{
- Atom type;
- char *name;
-} dev_type[] = {
- {
- 0, XI_KEYBOARD}, {
- 0, XI_MOUSE}, {
- 0, XI_TABLET}, {
- 0, XI_TOUCHSCREEN}, {
- 0, XI_TOUCHPAD}, {
- 0, XI_BARCODE}, {
- 0, XI_BUTTONBOX}, {
- 0, XI_KNOB_BOX}, {
- 0, XI_ONE_KNOB}, {
- 0, XI_NINE_KNOB}, {
- 0, XI_TRACKBALL}, {
- 0, XI_QUADRATURE}, {
- 0, XI_ID_MODULE}, {
- 0, XI_SPACEBALL}, {
- 0, XI_DATAGLOVE}, {
- 0, XI_EYETRACKER}, {
- 0, XI_CURSORKEYS}, {
-0, XI_FOOTMOUSE}};
-
-CARD8 event_base[numInputClasses];
-XExtEventInfo EventInfo[32];
-
-static DeviceIntRec xi_all_devices;
-static DeviceIntRec xi_all_master_devices;
-
-/**
- * Dispatch vector. Functions defined in here will be called when the matching
- * request arrives.
- */
-static int (*ProcIVector[])(ClientPtr) = {
- NULL, /* 0 */
- ProcXGetExtensionVersion, /* 1 */
- ProcXListInputDevices, /* 2 */
- ProcXOpenDevice, /* 3 */
- ProcXCloseDevice, /* 4 */
- ProcXSetDeviceMode, /* 5 */
- ProcXSelectExtensionEvent, /* 6 */
- ProcXGetSelectedExtensionEvents, /* 7 */
- ProcXChangeDeviceDontPropagateList, /* 8 */
- ProcXGetDeviceDontPropagateList, /* 9 */
- ProcXGetDeviceMotionEvents, /* 10 */
- ProcXChangeKeyboardDevice, /* 11 */
- ProcXChangePointerDevice, /* 12 */
- ProcXGrabDevice, /* 13 */
- ProcXUngrabDevice, /* 14 */
- ProcXGrabDeviceKey, /* 15 */
- ProcXUngrabDeviceKey, /* 16 */
- ProcXGrabDeviceButton, /* 17 */
- ProcXUngrabDeviceButton, /* 18 */
- ProcXAllowDeviceEvents, /* 19 */
- ProcXGetDeviceFocus, /* 20 */
- ProcXSetDeviceFocus, /* 21 */
- ProcXGetFeedbackControl, /* 22 */
- ProcXChangeFeedbackControl, /* 23 */
- ProcXGetDeviceKeyMapping, /* 24 */
- ProcXChangeDeviceKeyMapping, /* 25 */
- ProcXGetDeviceModifierMapping, /* 26 */
- ProcXSetDeviceModifierMapping, /* 27 */
- ProcXGetDeviceButtonMapping, /* 28 */
- ProcXSetDeviceButtonMapping, /* 29 */
- ProcXQueryDeviceState, /* 30 */
- ProcXSendExtensionEvent, /* 31 */
- ProcXDeviceBell, /* 32 */
- ProcXSetDeviceValuators, /* 33 */
- ProcXGetDeviceControl, /* 34 */
- ProcXChangeDeviceControl, /* 35 */
- /* XI 1.5 */
- ProcXListDeviceProperties, /* 36 */
- ProcXChangeDeviceProperty, /* 37 */
- ProcXDeleteDeviceProperty, /* 38 */
- ProcXGetDeviceProperty, /* 39 */
- /* XI 2 */
- ProcXIQueryPointer, /* 40 */
- ProcXIWarpPointer, /* 41 */
- ProcXIChangeCursor, /* 42 */
- ProcXIChangeHierarchy, /* 43 */
- ProcXISetClientPointer, /* 44 */
- ProcXIGetClientPointer, /* 45 */
- ProcXISelectEvents, /* 46 */
- ProcXIQueryVersion, /* 47 */
- ProcXIQueryDevice, /* 48 */
- ProcXISetFocus, /* 49 */
- ProcXIGetFocus, /* 50 */
- ProcXIGrabDevice, /* 51 */
- ProcXIUngrabDevice, /* 52 */
- ProcXIAllowEvents, /* 53 */
- ProcXIPassiveGrabDevice, /* 54 */
- ProcXIPassiveUngrabDevice, /* 55 */
- ProcXIListProperties, /* 56 */
- ProcXIChangeProperty, /* 57 */
- ProcXIDeleteProperty, /* 58 */
- ProcXIGetProperty, /* 59 */
- ProcXIGetSelectedEvents /* 60 */
-};
-
-/* For swapped clients */
-static int (*SProcIVector[])(ClientPtr) = {
- NULL, /* 0 */
- SProcXGetExtensionVersion, /* 1 */
- SProcXListInputDevices, /* 2 */
- SProcXOpenDevice, /* 3 */
- SProcXCloseDevice, /* 4 */
- SProcXSetDeviceMode, /* 5 */
- SProcXSelectExtensionEvent, /* 6 */
- SProcXGetSelectedExtensionEvents, /* 7 */
- SProcXChangeDeviceDontPropagateList, /* 8 */
- SProcXGetDeviceDontPropagateList, /* 9 */
- SProcXGetDeviceMotionEvents, /* 10 */
- SProcXChangeKeyboardDevice, /* 11 */
- SProcXChangePointerDevice, /* 12 */
- SProcXGrabDevice, /* 13 */
- SProcXUngrabDevice, /* 14 */
- SProcXGrabDeviceKey, /* 15 */
- SProcXUngrabDeviceKey, /* 16 */
- SProcXGrabDeviceButton, /* 17 */
- SProcXUngrabDeviceButton, /* 18 */
- SProcXAllowDeviceEvents, /* 19 */
- SProcXGetDeviceFocus, /* 20 */
- SProcXSetDeviceFocus, /* 21 */
- SProcXGetFeedbackControl, /* 22 */
- SProcXChangeFeedbackControl, /* 23 */
- SProcXGetDeviceKeyMapping, /* 24 */
- SProcXChangeDeviceKeyMapping, /* 25 */
- SProcXGetDeviceModifierMapping, /* 26 */
- SProcXSetDeviceModifierMapping, /* 27 */
- SProcXGetDeviceButtonMapping, /* 28 */
- SProcXSetDeviceButtonMapping, /* 29 */
- SProcXQueryDeviceState, /* 30 */
- SProcXSendExtensionEvent, /* 31 */
- SProcXDeviceBell, /* 32 */
- SProcXSetDeviceValuators, /* 33 */
- SProcXGetDeviceControl, /* 34 */
- SProcXChangeDeviceControl, /* 35 */
- SProcXListDeviceProperties, /* 36 */
- SProcXChangeDeviceProperty, /* 37 */
- SProcXDeleteDeviceProperty, /* 38 */
- SProcXGetDeviceProperty, /* 39 */
- SProcXIQueryPointer, /* 40 */
- SProcXIWarpPointer, /* 41 */
- SProcXIChangeCursor, /* 42 */
- SProcXIChangeHierarchy, /* 43 */
- SProcXISetClientPointer, /* 44 */
- SProcXIGetClientPointer, /* 45 */
- SProcXISelectEvents, /* 46 */
- SProcXIQueryVersion, /* 47 */
- SProcXIQueryDevice, /* 48 */
- SProcXISetFocus, /* 49 */
- SProcXIGetFocus, /* 50 */
- SProcXIGrabDevice, /* 51 */
- SProcXIUngrabDevice, /* 52 */
- SProcXIAllowEvents, /* 53 */
- SProcXIPassiveGrabDevice, /* 54 */
- SProcXIPassiveUngrabDevice, /* 55 */
- SProcXIListProperties, /* 56 */
- SProcXIChangeProperty, /* 57 */
- SProcXIDeleteProperty, /* 58 */
- SProcXIGetProperty, /* 59 */
- SProcXIGetSelectedEvents /* 60 */
-};
-
-/*****************************************************************
- *
- * Globals referenced elsewhere in the server.
- *
- */
-
-int IReqCode = 0;
-int IEventBase = 0;
-int BadDevice = 0;
-static int BadEvent = 1;
-int BadMode = 2;
-int DeviceBusy = 3;
-int BadClass = 4;
-
-int DeviceValuator;
-int DeviceKeyPress;
-int DeviceKeyRelease;
-int DeviceButtonPress;
-int DeviceButtonRelease;
-int DeviceMotionNotify;
-int DeviceFocusIn;
-int DeviceFocusOut;
-int ProximityIn;
-int ProximityOut;
-int DeviceStateNotify;
-int DeviceKeyStateNotify;
-int DeviceButtonStateNotify;
-int DeviceMappingNotify;
-int ChangeDeviceNotify;
-int DevicePresenceNotify;
-int DevicePropertyNotify;
-
-RESTYPE RT_INPUTCLIENT;
-
-/*****************************************************************
- *
- * Externs defined elsewhere in the X server.
- *
- */
-
-extern XExtensionVersion XIVersion;
-
-
-Mask PropagateMask[MAXDEVICES];
-
-/*****************************************************************
- *
- * Versioning support
- *
- */
-
-DevPrivateKeyRec XIClientPrivateKeyRec;
-
-/*****************************************************************
- *
- * Declarations of local routines.
- *
- */
-
-static void
-XIClientCallback(CallbackListPtr *list,
- pointer closure,
- pointer data)
-{
- NewClientInfoRec *clientinfo = (NewClientInfoRec*)data;
- ClientPtr pClient = clientinfo->client;
- XIClientPtr pXIClient;
-
- pXIClient = dixLookupPrivate(&pClient->devPrivates, XIClientPrivateKey);
- pXIClient->major_version = 0;
- pXIClient->minor_version = 0;
-}
-
-/*************************************************************************
- *
- * ProcIDispatch - main dispatch routine for requests to this extension.
- * This routine is used if server and client have the same byte ordering.
- *
- */
-
-static int
-ProcIDispatch(ClientPtr client)
-{
- REQUEST(xReq);
- if (stuff->data > ARRAY_SIZE(ProcIVector) || !ProcIVector[stuff->data])
- return BadRequest;
-
- return (*ProcIVector[stuff->data])(client);
-}
-
-/*******************************************************************************
- *
- * SProcXDispatch
- *
- * Main swapped dispatch routine for requests to this extension.
- * This routine is used if server and client do not have the same byte ordering.
- *
- */
-
-static int
-SProcIDispatch(ClientPtr client)
-{
- REQUEST(xReq);
- if (stuff->data > ARRAY_SIZE(SProcIVector) || !SProcIVector[stuff->data])
- return BadRequest;
-
- return (*SProcIVector[stuff->data])(client);
-}
-
-/**********************************************************************
- *
- * SReplyIDispatch
- * Swap any replies defined in this extension.
- *
- */
-
-static void
-SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
- /* All we look at is the type field */
-{ /* This is common to all replies */
- if (rep->RepType == X_GetExtensionVersion)
- SRepXGetExtensionVersion(client, len,
- (xGetExtensionVersionReply *) rep);
- else if (rep->RepType == X_ListInputDevices)
- SRepXListInputDevices(client, len, (xListInputDevicesReply *) rep);
- else if (rep->RepType == X_OpenDevice)
- SRepXOpenDevice(client, len, (xOpenDeviceReply *) rep);
- else if (rep->RepType == X_SetDeviceMode)
- SRepXSetDeviceMode(client, len, (xSetDeviceModeReply *) rep);
- else if (rep->RepType == X_GetSelectedExtensionEvents)
- SRepXGetSelectedExtensionEvents(client, len,
- (xGetSelectedExtensionEventsReply *)
- rep);
- else if (rep->RepType == X_GetDeviceDontPropagateList)
- SRepXGetDeviceDontPropagateList(client, len,
- (xGetDeviceDontPropagateListReply *)
- rep);
- else if (rep->RepType == X_GetDeviceMotionEvents)
- SRepXGetDeviceMotionEvents(client, len,
- (xGetDeviceMotionEventsReply *) rep);
- else if (rep->RepType == X_GrabDevice)
- SRepXGrabDevice(client, len, (xGrabDeviceReply *) rep);
- else if (rep->RepType == X_GetDeviceFocus)
- SRepXGetDeviceFocus(client, len, (xGetDeviceFocusReply *) rep);
- else if (rep->RepType == X_GetFeedbackControl)
- SRepXGetFeedbackControl(client, len, (xGetFeedbackControlReply *) rep);
- else if (rep->RepType == X_GetDeviceKeyMapping)
- SRepXGetDeviceKeyMapping(client, len,
- (xGetDeviceKeyMappingReply *) rep);
- else if (rep->RepType == X_GetDeviceModifierMapping)
- SRepXGetDeviceModifierMapping(client, len,
- (xGetDeviceModifierMappingReply *) rep);
- else if (rep->RepType == X_SetDeviceModifierMapping)
- SRepXSetDeviceModifierMapping(client, len,
- (xSetDeviceModifierMappingReply *) rep);
- else if (rep->RepType == X_GetDeviceButtonMapping)
- SRepXGetDeviceButtonMapping(client, len,
- (xGetDeviceButtonMappingReply *) rep);
- else if (rep->RepType == X_SetDeviceButtonMapping)
- SRepXSetDeviceButtonMapping(client, len,
- (xSetDeviceButtonMappingReply *) rep);
- else if (rep->RepType == X_QueryDeviceState)
- SRepXQueryDeviceState(client, len, (xQueryDeviceStateReply *) rep);
- else if (rep->RepType == X_SetDeviceValuators)
- SRepXSetDeviceValuators(client, len, (xSetDeviceValuatorsReply *) rep);
- else if (rep->RepType == X_GetDeviceControl)
- SRepXGetDeviceControl(client, len, (xGetDeviceControlReply *) rep);
- else if (rep->RepType == X_ChangeDeviceControl)
- SRepXChangeDeviceControl(client, len,
- (xChangeDeviceControlReply *) rep);
- else if (rep->RepType == X_ListDeviceProperties)
- SRepXListDeviceProperties(client, len, (xListDevicePropertiesReply*)rep);
- else if (rep->RepType == X_GetDeviceProperty)
- SRepXGetDeviceProperty(client, len, (xGetDevicePropertyReply *) rep);
- else if (rep->RepType == X_XIQueryPointer)
- SRepXIQueryPointer(client, len, (xXIQueryPointerReply *) rep);
- else if (rep->RepType == X_XIGetClientPointer)
- SRepXIGetClientPointer(client, len, (xXIGetClientPointerReply*) rep);
- else if (rep->RepType == X_XIQueryVersion)
- SRepXIQueryVersion(client, len, (xXIQueryVersionReply*)rep);
- else if (rep->RepType == X_XIQueryDevice)
- SRepXIQueryDevice(client, len, (xXIQueryDeviceReply*)rep);
- else if (rep->RepType == X_XIGrabDevice)
- SRepXIGrabDevice(client, len, (xXIGrabDeviceReply *) rep);
- else if (rep->RepType == X_XIPassiveGrabDevice)
- SRepXIPassiveGrabDevice(client, len, (xXIPassiveGrabDeviceReply *) rep);
- else if (rep->RepType == X_XIListProperties)
- SRepXIListProperties(client, len, (xXIListPropertiesReply *) rep);
- else if (rep->RepType == X_XIGetProperty)
- SRepXIGetProperty(client, len, (xXIGetPropertyReply *) rep);
- else if (rep->RepType == X_XIGetSelectedEvents)
- SRepXIGetSelectedEvents(client, len, (xXIGetSelectedEventsReply *) rep);
- else if (rep->RepType == X_XIGetFocus)
- SRepXIGetFocus(client, len, (xXIGetFocusReply *) rep);
- else {
- FatalError("XINPUT confused sending swapped reply");
- }
-}
-
-/************************************************************************
- *
- * This function swaps the DeviceValuator event.
- *
- */
-
-static void
-SEventDeviceValuator(deviceValuator * from, deviceValuator * to)
-{
- char n;
- int i;
- INT32 *ip B32;
-
- *to = *from;
- swaps(&to->sequenceNumber, n);
- swaps(&to->device_state, n);
- ip = &to->valuator0;
- for (i = 0; i < 6; i++) {
- swapl((ip + i), n); /* macro - braces are required */
- }
-}
-
-static void
-SEventFocus(deviceFocus * from, deviceFocus * to)
-{
- char n;
-
- *to = *from;
- swaps(&to->sequenceNumber, n);
- swapl(&to->time, n);
- swapl(&to->window, n);
-}
-
-static void
-SDeviceStateNotifyEvent(deviceStateNotify * from, deviceStateNotify * to)
-{
- int i;
- char n;
- INT32 *ip B32;
-
- *to = *from;
- swaps(&to->sequenceNumber, n);
- swapl(&to->time, n);
- ip = &to->valuator0;
- for (i = 0; i < 3; i++) {
- swapl((ip + i), n); /* macro - braces are required */
- }
-}
-
-static void
-SDeviceKeyStateNotifyEvent(deviceKeyStateNotify * from,
- deviceKeyStateNotify * to)
-{
- char n;
-
- *to = *from;
- swaps(&to->sequenceNumber, n);
-}
-
-static void
-SDeviceButtonStateNotifyEvent(deviceButtonStateNotify * from,
- deviceButtonStateNotify * to)
-{
- char n;
-
- *to = *from;
- swaps(&to->sequenceNumber, n);
-}
-
-static void
-SChangeDeviceNotifyEvent(changeDeviceNotify * from, changeDeviceNotify * to)
-{
- char n;
-
- *to = *from;
- swaps(&to->sequenceNumber, n);
- swapl(&to->time, n);
-}
-
-static void
-SDeviceMappingNotifyEvent(deviceMappingNotify * from, deviceMappingNotify * to)
-{
- char n;
-
- *to = *from;
- swaps(&to->sequenceNumber, n);
- swapl(&to->time, n);
-}
-
-static void
-SDevicePresenceNotifyEvent (devicePresenceNotify *from, devicePresenceNotify *to)
-{
- char n;
-
- *to = *from;
- swaps(&to->sequenceNumber,n);
- swapl(&to->time, n);
- swaps(&to->control, n);
-}
-
-static void
-SDevicePropertyNotifyEvent (devicePropertyNotify *from, devicePropertyNotify *to)
-{
- char n;
-
- *to = *from;
- swaps(&to->sequenceNumber,n);
- swapl(&to->time, n);
- swapl(&to->atom, n);
-}
-
-static void
-SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to)
-{
- char n;
-
- *to = *from;
- swaps(&to->sequenceNumber,n);
- swapl(&to->length, n);
- swaps(&to->evtype, n);
- swaps(&to->deviceid, n);
- swapl(&to->time, n);
- swapl(&to->root, n);
- swapl(&to->event, n);
- swapl(&to->child, n);
- swapl(&to->root_x, n);
- swapl(&to->root_y, n);
- swapl(&to->event_x, n);
- swapl(&to->event_y, n);
- swaps(&to->sourceid, n);
- swaps(&to->buttons_len, n);
- swapl(&to->mods.base_mods, n);
- swapl(&to->mods.latched_mods, n);
- swapl(&to->mods.locked_mods, n);
-}
-
-static void
-SDeviceChangedEvent(xXIDeviceChangedEvent* from, xXIDeviceChangedEvent* to)
-{
- char n;
- int i, j;
- xXIAnyInfo *any;
-
- *to = *from;
- memcpy(&to[1], &from[1], from->length * 4);
-
- any = (xXIAnyInfo*)&to[1];
- for (i = 0; i < to->num_classes; i++)
- {
- int length = any->length;
-
- switch(any->type)
- {
- case KeyClass:
- {
- xXIKeyInfo *ki = (xXIKeyInfo*)any;
- uint32_t *key = (uint32_t*)&ki[1];
- for (j = 0; j < ki->num_keycodes; j++, key++)
- swapl(key, n);
- swaps(&ki->num_keycodes, n);
- }
- break;
- case ButtonClass:
- {
- xXIButtonInfo *bi = (xXIButtonInfo*)any;
- Atom *labels = (Atom*)((char*)bi + sizeof(xXIButtonInfo) +
- pad_to_int32(bits_to_bytes(bi->num_buttons)));
- for (j = 0; j < bi->num_buttons; j++)
- swapl(&labels[j], n);
- swaps(&bi->num_buttons, n);
- }
- break;
- case ValuatorClass:
- {
- xXIValuatorInfo* ai = (xXIValuatorInfo*)any;
- swapl(&ai->label, n);
- swapl(&ai->min.integral, n);
- swapl(&ai->min.frac, n);
- swapl(&ai->max.integral, n);
- swapl(&ai->max.frac, n);
- swapl(&ai->resolution, n);
- swaps(&ai->number, n);
- }
- break;
- }
-
- swaps(&any->type, n);
- swaps(&any->length, n);
- swaps(&any->sourceid, n);
-
- any = (xXIAnyInfo*)((char*)any + length * 4);
- }
-
- swaps(&to->sequenceNumber, n);
- swapl(&to->length, n);
- swaps(&to->evtype, n);
- swaps(&to->deviceid, n);
- swapl(&to->time, n);
- swaps(&to->num_classes, n);
- swaps(&to->sourceid, n);
-
-}
-
-static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to)
-{
- int i;
- char n;
- char *ptr;
- char *vmask;
-
- memcpy(to, from, sizeof(xEvent) + from->length * 4);
-
- swaps(&to->sequenceNumber, n);
- swapl(&to->length, n);
- swaps(&to->evtype, n);
- swaps(&to->deviceid, n);
- swapl(&to->time, n);
- swapl(&to->detail, n);
- swapl(&to->root, n);
- swapl(&to->event, n);
- swapl(&to->child, n);
- swapl(&to->root_x, n);
- swapl(&to->root_y, n);
- swapl(&to->event_x, n);
- swapl(&to->event_y, n);
- swaps(&to->buttons_len, n);
- swaps(&to->valuators_len, n);
- swaps(&to->sourceid, n);
- swapl(&to->mods.base_mods, n);
- swapl(&to->mods.latched_mods, n);
- swapl(&to->mods.locked_mods, n);
- swapl(&to->mods.effective_mods, n);
- swapl(&to->flags, n);
-
- ptr = (char*)(&to[1]);
- ptr += from->buttons_len * 4;
- vmask = ptr; /* valuator mask */
- ptr += from->valuators_len * 4;
- for (i = 0; i < from->valuators_len * 32; i++)
- {
- if (BitIsOn(vmask, i))
- {
- swapl(((uint32_t*)ptr), n);
- ptr += 4;
- swapl(((uint32_t*)ptr), n);
- ptr += 4;
- }
- }
-}
-
-static void SDeviceHierarchyEvent(xXIHierarchyEvent *from,
- xXIHierarchyEvent *to)
-{
- int i;
- char n;
- xXIHierarchyInfo *info;
-
- *to = *from;
- memcpy(&to[1], &from[1], from->length * 4);
- swaps(&to->sequenceNumber, n);
- swapl(&to->length, n);
- swaps(&to->evtype, n);
- swaps(&to->deviceid, n);
- swapl(&to->time, n);
- swapl(&to->flags, n);
- swaps(&to->num_info, n);
-
- info = (xXIHierarchyInfo*)&to[1];
- for (i = 0; i< from->num_info; i++)
- {
- swaps(&info->deviceid, n);
- swaps(&info->attachment, n);
- info++;
- }
-}
-
-static void SXIPropertyEvent(xXIPropertyEvent *from, xXIPropertyEvent *to)
-{
- char n;
-
- *to = *from;
- swaps(&to->sequenceNumber, n);
- swapl(&to->length, n);
- swaps(&to->evtype, n);
- swaps(&to->deviceid, n);
- swapl(&to->property, n);
-}
-
-static void SRawEvent(xXIRawEvent *from, xXIRawEvent *to)
-{
- char n;
- int i;
- FP3232 *values;
- unsigned char *mask;
-
- memcpy(to, from, sizeof(xEvent) + from->length * 4);
-
- swaps(&to->sequenceNumber, n);
- swapl(&to->length, n);
- swaps(&to->evtype, n);
- swaps(&to->deviceid, n);
- swapl(&to->time, n);
- swapl(&to->detail, n);
-
-
- mask = (unsigned char*)&to[1];
- values = (FP3232*)(mask + from->valuators_len * 4);
-
- for (i = 0; i < from->valuators_len * 4 * 8; i++)
- {
- if (BitIsOn(mask, i))
- {
- /* for each bit set there are two FP3232 values on the wire, in
- * the order abcABC for data and data_raw. Here we swap as if
- * they were in aAbBcC order because it's easier and really
- * doesn't matter.
- */
- swapl(&values->integral, n);
- swapl(&values->frac, n);
- values++;
- swapl(&values->integral, n);
- swapl(&values->frac, n);
- values++;
- }
- }
-
- swaps(&to->valuators_len, n);
-}
-
-
-/** Event swapping function for XI2 events. */
-void
-XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
-{
- switch(from->evtype)
- {
- case XI_Enter:
- case XI_Leave:
- case XI_FocusIn:
- case XI_FocusOut:
- SDeviceLeaveNotifyEvent((xXILeaveEvent*)from, (xXILeaveEvent*)to);
- break;
- case XI_DeviceChanged:
- SDeviceChangedEvent((xXIDeviceChangedEvent*)from,
- (xXIDeviceChangedEvent*)to);
- break;
- case XI_HierarchyChanged:
- SDeviceHierarchyEvent((xXIHierarchyEvent*)from, (xXIHierarchyEvent*)to);
- break;
- case XI_PropertyEvent:
- SXIPropertyEvent((xXIPropertyEvent*)from,
- (xXIPropertyEvent*)to);
- break;
- case XI_Motion:
- case XI_KeyPress:
- case XI_KeyRelease:
- case XI_ButtonPress:
- case XI_ButtonRelease:
- SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to);
- break;
- case XI_RawMotion:
- case XI_RawKeyPress:
- case XI_RawKeyRelease:
- case XI_RawButtonPress:
- case XI_RawButtonRelease:
- SRawEvent((xXIRawEvent*)from, (xXIRawEvent*)to);
- break;
- default:
- ErrorF("[Xi] Unknown event type to swap. This is a bug.\n");
- break;
- }
-}
-
-/**************************************************************************
- *
- * Allow the specified event to have its propagation suppressed.
- * The default is to not allow suppression of propagation.
- *
- */
-
-static void
-AllowPropagateSuppress(Mask mask)
-{
- int i;
-
- for (i = 0; i < MAXDEVICES; i++)
- PropagateMask[i] |= mask;
-}
-
-/**************************************************************************
- *
- * Record an event mask where there is no unique corresponding event type.
- * We can't call SetMaskForEvent, since that would clobber the existing
- * mask for that event. MotionHint and ButtonMotion are examples.
- *
- * Since extension event types will never be less than 64, we can use
- * 0-63 in the EventInfo array as the "type" to be used to look up this
- * mask. This means that the corresponding macros such as
- * DevicePointerMotionHint must have access to the same constants.
- *
- */
-
-static void
-SetEventInfo(Mask mask, int constant)
-{
- EventInfo[ExtEventIndex].mask = mask;
- EventInfo[ExtEventIndex++].type = constant;
-}
-
-/**************************************************************************
- *
- * Allow the specified event to be restricted to being selected by one
- * client at a time.
- * The default is to allow more than one client to select the event.
- *
- */
-
-static void
-SetExclusiveAccess(Mask mask)
-{
- int i;
-
- for (i = 0; i < MAXDEVICES; i++)
- ExtExclusiveMasks[i] |= mask;
-}
-
-/**************************************************************************
- *
- * Assign the specified mask to the specified event.
- *
- */
-
-static void
-SetMaskForExtEvent(Mask mask, int event)
-{
- int i;
-
- EventInfo[ExtEventIndex].mask = mask;
- EventInfo[ExtEventIndex++].type = event;
-
- if ((event < LASTEvent) || (event >= 128))
- FatalError("MaskForExtensionEvent: bogus event number");
-
- for (i = 0; i < MAXDEVICES; i++)
- SetMaskForEvent(i, mask, event);
-}
-
-/************************************************************************
- *
- * This function sets up extension event types and masks.
- *
- */
-
-static void
-FixExtensionEvents(ExtensionEntry * extEntry)
-{
- DeviceValuator = extEntry->eventBase;
- DeviceKeyPress = DeviceValuator + 1;
- DeviceKeyRelease = DeviceKeyPress + 1;
- DeviceButtonPress = DeviceKeyRelease + 1;
- DeviceButtonRelease = DeviceButtonPress + 1;
- DeviceMotionNotify = DeviceButtonRelease + 1;
- DeviceFocusIn = DeviceMotionNotify + 1;
- DeviceFocusOut = DeviceFocusIn + 1;
- ProximityIn = DeviceFocusOut + 1;
- ProximityOut = ProximityIn + 1;
- DeviceStateNotify = ProximityOut + 1;
- DeviceMappingNotify = DeviceStateNotify + 1;
- ChangeDeviceNotify = DeviceMappingNotify + 1;
- DeviceKeyStateNotify = ChangeDeviceNotify + 1;
- DeviceButtonStateNotify = DeviceKeyStateNotify + 1;
- DevicePresenceNotify = DeviceButtonStateNotify + 1;
- DevicePropertyNotify = DevicePresenceNotify + 1;
-
- event_base[KeyClass] = DeviceKeyPress;
- event_base[ButtonClass] = DeviceButtonPress;
- event_base[ValuatorClass] = DeviceMotionNotify;
- event_base[ProximityClass] = ProximityIn;
- event_base[FocusClass] = DeviceFocusIn;
- event_base[OtherClass] = DeviceStateNotify;
-
- BadDevice += extEntry->errorBase;
- BadEvent += extEntry->errorBase;
- BadMode += extEntry->errorBase;
- DeviceBusy += extEntry->errorBase;
- BadClass += extEntry->errorBase;
-
- SetMaskForExtEvent(DeviceKeyPressMask, DeviceKeyPress);
- AllowPropagateSuppress(DeviceKeyPressMask);
- SetCriticalEvent(DeviceKeyPress);
-
- SetMaskForExtEvent(DeviceKeyReleaseMask, DeviceKeyRelease);
- AllowPropagateSuppress(DeviceKeyReleaseMask);
- SetCriticalEvent(DeviceKeyRelease);
-
- SetMaskForExtEvent(DeviceButtonPressMask, DeviceButtonPress);
- AllowPropagateSuppress(DeviceButtonPressMask);
- SetCriticalEvent(DeviceButtonPress);
-
- SetMaskForExtEvent(DeviceButtonReleaseMask, DeviceButtonRelease);
- AllowPropagateSuppress(DeviceButtonReleaseMask);
- SetCriticalEvent(DeviceButtonRelease);
-
- SetMaskForExtEvent(DeviceProximityMask, ProximityIn);
- SetMaskForExtEvent(DeviceProximityMask, ProximityOut);
-
- SetMaskForExtEvent(DeviceStateNotifyMask, DeviceStateNotify);
-
- SetMaskForExtEvent(DevicePointerMotionMask, DeviceMotionNotify);
- AllowPropagateSuppress(DevicePointerMotionMask);
- SetCriticalEvent(DeviceMotionNotify);
-
- SetEventInfo(DevicePointerMotionHintMask, _devicePointerMotionHint);
- SetEventInfo(DeviceButton1MotionMask, _deviceButton1Motion);
- SetEventInfo(DeviceButton2MotionMask, _deviceButton2Motion);
- SetEventInfo(DeviceButton3MotionMask, _deviceButton3Motion);
- SetEventInfo(DeviceButton4MotionMask, _deviceButton4Motion);
- SetEventInfo(DeviceButton5MotionMask, _deviceButton5Motion);
- SetEventInfo(DeviceButtonMotionMask, _deviceButtonMotion);
-
- SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusIn);
- SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusOut);
-
- SetMaskForExtEvent(DeviceMappingNotifyMask, DeviceMappingNotify);
- SetMaskForExtEvent(ChangeDeviceNotifyMask, ChangeDeviceNotify);
-
- SetEventInfo(DeviceButtonGrabMask, _deviceButtonGrab);
- SetExclusiveAccess(DeviceButtonGrabMask);
-
- SetEventInfo(DeviceOwnerGrabButtonMask, _deviceOwnerGrabButton);
- SetEventInfo(DevicePresenceNotifyMask, _devicePresence);
- SetMaskForExtEvent(DevicePropertyNotifyMask, DevicePropertyNotify);
-
- SetEventInfo(0, _noExtensionEvent);
-}
-
-/************************************************************************
- *
- * This function restores extension event types and masks to their
- * initial state.
- *
- */
-
-static void
-RestoreExtensionEvents(void)
-{
- int i, j;
-
- IReqCode = 0;
- IEventBase = 0;
-
- for (i = 0; i < ExtEventIndex - 1; i++) {
- if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128))
- {
- for (j = 0; j < MAXDEVICES; j++)
- SetMaskForEvent(j, 0, EventInfo[i].type);
- }
- EventInfo[i].mask = 0;
- EventInfo[i].type = 0;
- }
- ExtEventIndex = 0;
- DeviceValuator = 0;
- DeviceKeyPress = 1;
- DeviceKeyRelease = 2;
- DeviceButtonPress = 3;
- DeviceButtonRelease = 4;
- DeviceMotionNotify = 5;
- DeviceFocusIn = 6;
- DeviceFocusOut = 7;
- ProximityIn = 8;
- ProximityOut = 9;
- DeviceStateNotify = 10;
- DeviceMappingNotify = 11;
- ChangeDeviceNotify = 12;
- DeviceKeyStateNotify = 13;
- DeviceButtonStateNotify = 13;
- DevicePresenceNotify = 14;
- DevicePropertyNotify = 15;
-
- BadDevice = 0;
- BadEvent = 1;
- BadMode = 2;
- DeviceBusy = 3;
- BadClass = 4;
-
-}
-
-/***********************************************************************
- *
- * IResetProc.
- * Remove reply-swapping routine.
- * Remove event-swapping routine.
- *
- */
-
-static void
-IResetProc(ExtensionEntry * unused)
-{
- ReplySwapVector[IReqCode] = ReplyNotSwappd;
- EventSwapVector[DeviceValuator] = NotImplemented;
- EventSwapVector[DeviceKeyPress] = NotImplemented;
- EventSwapVector[DeviceKeyRelease] = NotImplemented;
- EventSwapVector[DeviceButtonPress] = NotImplemented;
- EventSwapVector[DeviceButtonRelease] = NotImplemented;
- EventSwapVector[DeviceMotionNotify] = NotImplemented;
- EventSwapVector[DeviceFocusIn] = NotImplemented;
- EventSwapVector[DeviceFocusOut] = NotImplemented;
- EventSwapVector[ProximityIn] = NotImplemented;
- EventSwapVector[ProximityOut] = NotImplemented;
- EventSwapVector[DeviceStateNotify] = NotImplemented;
- EventSwapVector[DeviceKeyStateNotify] = NotImplemented;
- EventSwapVector[DeviceButtonStateNotify] = NotImplemented;
- EventSwapVector[DeviceMappingNotify] = NotImplemented;
- EventSwapVector[ChangeDeviceNotify] = NotImplemented;
- EventSwapVector[DevicePresenceNotify] = NotImplemented;
- EventSwapVector[DevicePropertyNotify] = NotImplemented;
- RestoreExtensionEvents();
-}
-
-
-/***********************************************************************
- *
- * Assign an id and type to an input device.
- *
- */
-
-void
-AssignTypeAndName(DeviceIntPtr dev, Atom type, char *name)
-{
- dev->xinput_type = type;
- dev->name = strdup(name);
-}
-
-/***********************************************************************
- *
- * Make device type atoms.
- *
- */
-
-static void
-MakeDeviceTypeAtoms(void)
-{
- int i;
-
- for (i = 0; i < NUMTYPES; i++)
- dev_type[i].type =
- MakeAtom(dev_type[i].name, strlen(dev_type[i].name), 1);
-}
-
-/*****************************************************************************
- *
- * SEventIDispatch
- *
- * Swap any events defined in this extension.
- */
-#define DO_SWAP(func,type) func ((type *)from, (type *)to)
-
-static void
-SEventIDispatch(xEvent * from, xEvent * to)
-{
- int type = from->u.u.type & 0177;
-
- if (type == DeviceValuator)
- DO_SWAP(SEventDeviceValuator, deviceValuator);
- else if (type == DeviceKeyPress) {
- SKeyButtonPtrEvent(from, to);
- to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
- } else if (type == DeviceKeyRelease) {
- SKeyButtonPtrEvent(from, to);
- to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
- } else if (type == DeviceButtonPress) {
- SKeyButtonPtrEvent(from, to);
- to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
- } else if (type == DeviceButtonRelease) {
- SKeyButtonPtrEvent(from, to);
- to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
- } else if (type == DeviceMotionNotify) {
- SKeyButtonPtrEvent(from, to);
- to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
- } else if (type == DeviceFocusIn)
- DO_SWAP(SEventFocus, deviceFocus);
- else if (type == DeviceFocusOut)
- DO_SWAP(SEventFocus, deviceFocus);
- else if (type == ProximityIn) {
- SKeyButtonPtrEvent(from, to);
- to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
- } else if (type == ProximityOut) {
- SKeyButtonPtrEvent(from, to);
- to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
- } else if (type == DeviceStateNotify)
- DO_SWAP(SDeviceStateNotifyEvent, deviceStateNotify);
- else if (type == DeviceKeyStateNotify)
- DO_SWAP(SDeviceKeyStateNotifyEvent, deviceKeyStateNotify);
- else if (type == DeviceButtonStateNotify)
- DO_SWAP(SDeviceButtonStateNotifyEvent, deviceButtonStateNotify);
- else if (type == DeviceMappingNotify)
- DO_SWAP(SDeviceMappingNotifyEvent, deviceMappingNotify);
- else if (type == ChangeDeviceNotify)
- DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify);
- else if (type == DevicePresenceNotify)
- DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify);
- else if (type == DevicePropertyNotify)
- DO_SWAP(SDevicePropertyNotifyEvent, devicePropertyNotify);
- else {
- FatalError("XInputExtension: Impossible event!\n");
- }
-}
-
-/**********************************************************************
- *
- * IExtensionInit - 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.
- *
- * XI is mandatory nowadays, so if we fail to init XI, we die.
- */
-
-void
-XInputExtensionInit(void)
-{
- ExtensionEntry *extEntry;
- XExtensionVersion thisversion = { XI_Present,
- SERVER_XI_MAJOR_VERSION,
- SERVER_XI_MINOR_VERSION,
- };
-
- if (!dixRegisterPrivateKey(&XIClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XIClientRec)))
- FatalError("Cannot request private for XI.\n");
-
- if (!AddCallback(&ClientStateCallback, XIClientCallback, 0))
- FatalError("Failed to add callback to XI.\n");
-
- extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch,
- SProcIDispatch, IResetProc, StandardMinorOpcode);
- if (extEntry) {
- IReqCode = extEntry->base;
- IEventBase = extEntry->eventBase;
- XIVersion = thisversion;
- MakeDeviceTypeAtoms();
- RT_INPUTCLIENT = CreateNewResourceType((DeleteType) InputClientGone,
- "INPUTCLIENT");
- if (!RT_INPUTCLIENT)
- FatalError("Failed to add resource type for XI.\n");
- FixExtensionEvents(extEntry);
- ReplySwapVector[IReqCode] = (ReplySwapPtr) SReplyIDispatch;
- EventSwapVector[DeviceValuator] = SEventIDispatch;
- EventSwapVector[DeviceKeyPress] = SEventIDispatch;
- EventSwapVector[DeviceKeyRelease] = SEventIDispatch;
- EventSwapVector[DeviceButtonPress] = SEventIDispatch;
- EventSwapVector[DeviceButtonRelease] = SEventIDispatch;
- EventSwapVector[DeviceMotionNotify] = SEventIDispatch;
- EventSwapVector[DeviceFocusIn] = SEventIDispatch;
- EventSwapVector[DeviceFocusOut] = SEventIDispatch;
- EventSwapVector[ProximityIn] = SEventIDispatch;
- EventSwapVector[ProximityOut] = SEventIDispatch;
- EventSwapVector[DeviceStateNotify] = SEventIDispatch;
- EventSwapVector[DeviceKeyStateNotify] = SEventIDispatch;
- EventSwapVector[DeviceButtonStateNotify] = SEventIDispatch;
- EventSwapVector[DeviceMappingNotify] = SEventIDispatch;
- EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
- EventSwapVector[DevicePresenceNotify] = SEventIDispatch;
-
- GERegisterExtension(IReqCode, XI2EventSwap);
-
-
- memset(&xi_all_devices, 0, sizeof(xi_all_devices));
- memset(&xi_all_master_devices, 0, sizeof(xi_all_master_devices));
- xi_all_devices.id = XIAllDevices;
- xi_all_devices.name = "XIAllDevices";
- xi_all_master_devices.id = XIAllMasterDevices;
- xi_all_master_devices.name = "XIAllMasterDevices";
-
- inputInfo.all_devices = &xi_all_devices;
- inputInfo.all_master_devices = &xi_all_master_devices;
-
- XIResetProperties();
- } else {
- FatalError("IExtensionInit: AddExtensions failed\n");
- }
-}
-
+/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + All Rights Reserved + +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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/******************************************************************** + * + * Dispatch routines and initialization routines for the X input extension. + * + */ +#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0])) + +#define NUMTYPES 15 + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "inputstr.h" +#include "gcstruct.h" /* pointer for extnsionst.h */ +#include "extnsionst.h" /* extension entry */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include <X11/extensions/XI2proto.h> +#include <X11/extensions/geproto.h> +#include "geext.h" /* extension interfaces for ge */ + +#include "dixevents.h" +#include "exevents.h" +#include "extinit.h" +#include "exglobals.h" +#include "swaprep.h" +#include "privates.h" +#include "protocol-versions.h" + +/* modules local to Xi */ +#include "allowev.h" +#include "chgdctl.h" +#include "chgfctl.h" +#include "chgkbd.h" +#include "chgprop.h" +#include "chgptr.h" +#include "closedev.h" +#include "devbell.h" +#include "getbmap.h" +#include "getdctl.h" +#include "getfctl.h" +#include "getfocus.h" +#include "getkmap.h" +#include "getmmap.h" +#include "getprop.h" +#include "getselev.h" +#include "getvers.h" +#include "grabdev.h" +#include "grabdevb.h" +#include "grabdevk.h" +#include "gtmotion.h" +#include "listdev.h" +#include "opendev.h" +#include "queryst.h" +#include "selectev.h" +#include "sendexev.h" +#include "chgkmap.h" +#include "setbmap.h" +#include "setdval.h" +#include "setfocus.h" +#include "setmmap.h" +#include "setmode.h" +#include "ungrdev.h" +#include "ungrdevb.h" +#include "ungrdevk.h" +#include "xiallowev.h" +#include "xiselectev.h" +#include "xigrabdev.h" +#include "xipassivegrab.h" +#include "xisetdevfocus.h" +#include "xiproperty.h" +#include "xichangecursor.h" +#include "xichangehierarchy.h" +#include "xigetclientpointer.h" +#include "xiquerydevice.h" +#include "xiquerypointer.h" +#include "xiqueryversion.h" +#include "xisetclientpointer.h" +#include "xiwarppointer.h" + + +/* Masks for XI events have to be aligned with core event (partially anyway). + * If DeviceButtonMotionMask is != ButtonMotionMask, event delivery + * breaks down. The device needs the dev->button->motionMask. If DBMM is + * the same as BMM, we can ensure that both core and device events can be + * delivered, without the need for extra structures in the DeviceIntRec. */ +const Mask DeviceKeyPressMask = KeyPressMask; +const Mask DeviceKeyReleaseMask = KeyReleaseMask; +const Mask DeviceButtonPressMask = ButtonPressMask; +const Mask DeviceButtonReleaseMask = ButtonReleaseMask; +const Mask DeviceProximityMask = (1L << 4); +const Mask DeviceStateNotifyMask = (1L << 5); +const Mask DevicePointerMotionMask = PointerMotionMask; +const Mask DevicePointerMotionHintMask = PointerMotionHintMask; +const Mask DeviceButton1MotionMask = Button1MotionMask; +const Mask DeviceButton2MotionMask = Button2MotionMask; +const Mask DeviceButton3MotionMask = Button3MotionMask; +const Mask DeviceButton4MotionMask = Button4MotionMask; +const Mask DeviceButton5MotionMask = Button5MotionMask; +const Mask DeviceButtonMotionMask = ButtonMotionMask; +const Mask DeviceFocusChangeMask = (1L << 14); +const Mask DeviceMappingNotifyMask = (1L << 15); +const Mask ChangeDeviceNotifyMask = (1L << 16); +const Mask DeviceButtonGrabMask = (1L << 17); +const Mask DeviceOwnerGrabButtonMask = (1L << 17); +const Mask DevicePresenceNotifyMask = (1L << 18); +const Mask DeviceEnterWindowMask = (1L << 18); +const Mask DeviceLeaveWindowMask = (1L << 19); +const Mask DevicePropertyNotifyMask = (1L << 20); +const Mask XIAllMasks = (1L << 21) - 1; + +int ExtEventIndex; +Mask ExtExclusiveMasks[EMASKSIZE]; + +static struct dev_type +{ + Atom type; + char *name; +} dev_type[] = { + { + 0, XI_KEYBOARD}, { + 0, XI_MOUSE}, { + 0, XI_TABLET}, { + 0, XI_TOUCHSCREEN}, { + 0, XI_TOUCHPAD}, { + 0, XI_BARCODE}, { + 0, XI_BUTTONBOX}, { + 0, XI_KNOB_BOX}, { + 0, XI_ONE_KNOB}, { + 0, XI_NINE_KNOB}, { + 0, XI_TRACKBALL}, { + 0, XI_QUADRATURE}, { + 0, XI_ID_MODULE}, { + 0, XI_SPACEBALL}, { + 0, XI_DATAGLOVE}, { + 0, XI_EYETRACKER}, { + 0, XI_CURSORKEYS}, { +0, XI_FOOTMOUSE}}; + +CARD8 event_base[numInputClasses]; +XExtEventInfo EventInfo[32]; + +static DeviceIntRec xi_all_devices; +static DeviceIntRec xi_all_master_devices; + +/** + * Dispatch vector. Functions defined in here will be called when the matching + * request arrives. + */ +static int (*ProcIVector[])(ClientPtr) = { + NULL, /* 0 */ + ProcXGetExtensionVersion, /* 1 */ + ProcXListInputDevices, /* 2 */ + ProcXOpenDevice, /* 3 */ + ProcXCloseDevice, /* 4 */ + ProcXSetDeviceMode, /* 5 */ + ProcXSelectExtensionEvent, /* 6 */ + ProcXGetSelectedExtensionEvents, /* 7 */ + ProcXChangeDeviceDontPropagateList, /* 8 */ + ProcXGetDeviceDontPropagateList, /* 9 */ + ProcXGetDeviceMotionEvents, /* 10 */ + ProcXChangeKeyboardDevice, /* 11 */ + ProcXChangePointerDevice, /* 12 */ + ProcXGrabDevice, /* 13 */ + ProcXUngrabDevice, /* 14 */ + ProcXGrabDeviceKey, /* 15 */ + ProcXUngrabDeviceKey, /* 16 */ + ProcXGrabDeviceButton, /* 17 */ + ProcXUngrabDeviceButton, /* 18 */ + ProcXAllowDeviceEvents, /* 19 */ + ProcXGetDeviceFocus, /* 20 */ + ProcXSetDeviceFocus, /* 21 */ + ProcXGetFeedbackControl, /* 22 */ + ProcXChangeFeedbackControl, /* 23 */ + ProcXGetDeviceKeyMapping, /* 24 */ + ProcXChangeDeviceKeyMapping, /* 25 */ + ProcXGetDeviceModifierMapping, /* 26 */ + ProcXSetDeviceModifierMapping, /* 27 */ + ProcXGetDeviceButtonMapping, /* 28 */ + ProcXSetDeviceButtonMapping, /* 29 */ + ProcXQueryDeviceState, /* 30 */ + ProcXSendExtensionEvent, /* 31 */ + ProcXDeviceBell, /* 32 */ + ProcXSetDeviceValuators, /* 33 */ + ProcXGetDeviceControl, /* 34 */ + ProcXChangeDeviceControl, /* 35 */ + /* XI 1.5 */ + ProcXListDeviceProperties, /* 36 */ + ProcXChangeDeviceProperty, /* 37 */ + ProcXDeleteDeviceProperty, /* 38 */ + ProcXGetDeviceProperty, /* 39 */ + /* XI 2 */ + ProcXIQueryPointer, /* 40 */ + ProcXIWarpPointer, /* 41 */ + ProcXIChangeCursor, /* 42 */ + ProcXIChangeHierarchy, /* 43 */ + ProcXISetClientPointer, /* 44 */ + ProcXIGetClientPointer, /* 45 */ + ProcXISelectEvents, /* 46 */ + ProcXIQueryVersion, /* 47 */ + ProcXIQueryDevice, /* 48 */ + ProcXISetFocus, /* 49 */ + ProcXIGetFocus, /* 50 */ + ProcXIGrabDevice, /* 51 */ + ProcXIUngrabDevice, /* 52 */ + ProcXIAllowEvents, /* 53 */ + ProcXIPassiveGrabDevice, /* 54 */ + ProcXIPassiveUngrabDevice, /* 55 */ + ProcXIListProperties, /* 56 */ + ProcXIChangeProperty, /* 57 */ + ProcXIDeleteProperty, /* 58 */ + ProcXIGetProperty, /* 59 */ + ProcXIGetSelectedEvents /* 60 */ +}; + +/* For swapped clients */ +static int (*SProcIVector[])(ClientPtr) = { + NULL, /* 0 */ + SProcXGetExtensionVersion, /* 1 */ + SProcXListInputDevices, /* 2 */ + SProcXOpenDevice, /* 3 */ + SProcXCloseDevice, /* 4 */ + SProcXSetDeviceMode, /* 5 */ + SProcXSelectExtensionEvent, /* 6 */ + SProcXGetSelectedExtensionEvents, /* 7 */ + SProcXChangeDeviceDontPropagateList, /* 8 */ + SProcXGetDeviceDontPropagateList, /* 9 */ + SProcXGetDeviceMotionEvents, /* 10 */ + SProcXChangeKeyboardDevice, /* 11 */ + SProcXChangePointerDevice, /* 12 */ + SProcXGrabDevice, /* 13 */ + SProcXUngrabDevice, /* 14 */ + SProcXGrabDeviceKey, /* 15 */ + SProcXUngrabDeviceKey, /* 16 */ + SProcXGrabDeviceButton, /* 17 */ + SProcXUngrabDeviceButton, /* 18 */ + SProcXAllowDeviceEvents, /* 19 */ + SProcXGetDeviceFocus, /* 20 */ + SProcXSetDeviceFocus, /* 21 */ + SProcXGetFeedbackControl, /* 22 */ + SProcXChangeFeedbackControl, /* 23 */ + SProcXGetDeviceKeyMapping, /* 24 */ + SProcXChangeDeviceKeyMapping, /* 25 */ + SProcXGetDeviceModifierMapping, /* 26 */ + SProcXSetDeviceModifierMapping, /* 27 */ + SProcXGetDeviceButtonMapping, /* 28 */ + SProcXSetDeviceButtonMapping, /* 29 */ + SProcXQueryDeviceState, /* 30 */ + SProcXSendExtensionEvent, /* 31 */ + SProcXDeviceBell, /* 32 */ + SProcXSetDeviceValuators, /* 33 */ + SProcXGetDeviceControl, /* 34 */ + SProcXChangeDeviceControl, /* 35 */ + SProcXListDeviceProperties, /* 36 */ + SProcXChangeDeviceProperty, /* 37 */ + SProcXDeleteDeviceProperty, /* 38 */ + SProcXGetDeviceProperty, /* 39 */ + SProcXIQueryPointer, /* 40 */ + SProcXIWarpPointer, /* 41 */ + SProcXIChangeCursor, /* 42 */ + SProcXIChangeHierarchy, /* 43 */ + SProcXISetClientPointer, /* 44 */ + SProcXIGetClientPointer, /* 45 */ + SProcXISelectEvents, /* 46 */ + SProcXIQueryVersion, /* 47 */ + SProcXIQueryDevice, /* 48 */ + SProcXISetFocus, /* 49 */ + SProcXIGetFocus, /* 50 */ + SProcXIGrabDevice, /* 51 */ + SProcXIUngrabDevice, /* 52 */ + SProcXIAllowEvents, /* 53 */ + SProcXIPassiveGrabDevice, /* 54 */ + SProcXIPassiveUngrabDevice, /* 55 */ + SProcXIListProperties, /* 56 */ + SProcXIChangeProperty, /* 57 */ + SProcXIDeleteProperty, /* 58 */ + SProcXIGetProperty, /* 59 */ + SProcXIGetSelectedEvents /* 60 */ +}; + +/***************************************************************** + * + * Globals referenced elsewhere in the server. + * + */ + +int IReqCode = 0; +int IEventBase = 0; +int BadDevice = 0; +static int BadEvent = 1; +int BadMode = 2; +int DeviceBusy = 3; +int BadClass = 4; + +int DeviceValuator; +int DeviceKeyPress; +int DeviceKeyRelease; +int DeviceButtonPress; +int DeviceButtonRelease; +int DeviceMotionNotify; +int DeviceFocusIn; +int DeviceFocusOut; +int ProximityIn; +int ProximityOut; +int DeviceStateNotify; +int DeviceKeyStateNotify; +int DeviceButtonStateNotify; +int DeviceMappingNotify; +int ChangeDeviceNotify; +int DevicePresenceNotify; +int DevicePropertyNotify; + +RESTYPE RT_INPUTCLIENT; + +/***************************************************************** + * + * Externs defined elsewhere in the X server. + * + */ + +extern XExtensionVersion XIVersion; + + +Mask PropagateMask[MAXDEVICES]; + +/***************************************************************** + * + * Versioning support + * + */ + +DevPrivateKeyRec XIClientPrivateKeyRec; + +/***************************************************************** + * + * Declarations of local routines. + * + */ + +static void +XIClientCallback(CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec*)data; + ClientPtr pClient = clientinfo->client; + XIClientPtr pXIClient; + + pXIClient = dixLookupPrivate(&pClient->devPrivates, XIClientPrivateKey); + pXIClient->major_version = 0; + pXIClient->minor_version = 0; +} + +/************************************************************************* + * + * ProcIDispatch - main dispatch routine for requests to this extension. + * This routine is used if server and client have the same byte ordering. + * + */ + +static int +ProcIDispatch(ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data > ARRAY_SIZE(ProcIVector) || !ProcIVector[stuff->data]) + return BadRequest; + + return (*ProcIVector[stuff->data])(client); +} + +/******************************************************************************* + * + * SProcXDispatch + * + * Main swapped dispatch routine for requests to this extension. + * This routine is used if server and client do not have the same byte ordering. + * + */ + +static int +SProcIDispatch(ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data > ARRAY_SIZE(SProcIVector) || !SProcIVector[stuff->data]) + return BadRequest; + + return (*SProcIVector[stuff->data])(client); +} + +/********************************************************************** + * + * SReplyIDispatch + * Swap any replies defined in this extension. + * + */ + +static void +SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep) + /* All we look at is the type field */ +{ /* This is common to all replies */ + if (rep->RepType == X_GetExtensionVersion) + SRepXGetExtensionVersion(client, len, + (xGetExtensionVersionReply *) rep); + else if (rep->RepType == X_ListInputDevices) + SRepXListInputDevices(client, len, (xListInputDevicesReply *) rep); + else if (rep->RepType == X_OpenDevice) + SRepXOpenDevice(client, len, (xOpenDeviceReply *) rep); + else if (rep->RepType == X_SetDeviceMode) + SRepXSetDeviceMode(client, len, (xSetDeviceModeReply *) rep); + else if (rep->RepType == X_GetSelectedExtensionEvents) + SRepXGetSelectedExtensionEvents(client, len, + (xGetSelectedExtensionEventsReply *) + rep); + else if (rep->RepType == X_GetDeviceDontPropagateList) + SRepXGetDeviceDontPropagateList(client, len, + (xGetDeviceDontPropagateListReply *) + rep); + else if (rep->RepType == X_GetDeviceMotionEvents) + SRepXGetDeviceMotionEvents(client, len, + (xGetDeviceMotionEventsReply *) rep); + else if (rep->RepType == X_GrabDevice) + SRepXGrabDevice(client, len, (xGrabDeviceReply *) rep); + else if (rep->RepType == X_GetDeviceFocus) + SRepXGetDeviceFocus(client, len, (xGetDeviceFocusReply *) rep); + else if (rep->RepType == X_GetFeedbackControl) + SRepXGetFeedbackControl(client, len, (xGetFeedbackControlReply *) rep); + else if (rep->RepType == X_GetDeviceKeyMapping) + SRepXGetDeviceKeyMapping(client, len, + (xGetDeviceKeyMappingReply *) rep); + else if (rep->RepType == X_GetDeviceModifierMapping) + SRepXGetDeviceModifierMapping(client, len, + (xGetDeviceModifierMappingReply *) rep); + else if (rep->RepType == X_SetDeviceModifierMapping) + SRepXSetDeviceModifierMapping(client, len, + (xSetDeviceModifierMappingReply *) rep); + else if (rep->RepType == X_GetDeviceButtonMapping) + SRepXGetDeviceButtonMapping(client, len, + (xGetDeviceButtonMappingReply *) rep); + else if (rep->RepType == X_SetDeviceButtonMapping) + SRepXSetDeviceButtonMapping(client, len, + (xSetDeviceButtonMappingReply *) rep); + else if (rep->RepType == X_QueryDeviceState) + SRepXQueryDeviceState(client, len, (xQueryDeviceStateReply *) rep); + else if (rep->RepType == X_SetDeviceValuators) + SRepXSetDeviceValuators(client, len, (xSetDeviceValuatorsReply *) rep); + else if (rep->RepType == X_GetDeviceControl) + SRepXGetDeviceControl(client, len, (xGetDeviceControlReply *) rep); + else if (rep->RepType == X_ChangeDeviceControl) + SRepXChangeDeviceControl(client, len, + (xChangeDeviceControlReply *) rep); + else if (rep->RepType == X_ListDeviceProperties) + SRepXListDeviceProperties(client, len, (xListDevicePropertiesReply*)rep); + else if (rep->RepType == X_GetDeviceProperty) + SRepXGetDeviceProperty(client, len, (xGetDevicePropertyReply *) rep); + else if (rep->RepType == X_XIQueryPointer) + SRepXIQueryPointer(client, len, (xXIQueryPointerReply *) rep); + else if (rep->RepType == X_XIGetClientPointer) + SRepXIGetClientPointer(client, len, (xXIGetClientPointerReply*) rep); + else if (rep->RepType == X_XIQueryVersion) + SRepXIQueryVersion(client, len, (xXIQueryVersionReply*)rep); + else if (rep->RepType == X_XIQueryDevice) + SRepXIQueryDevice(client, len, (xXIQueryDeviceReply*)rep); + else if (rep->RepType == X_XIGrabDevice) + SRepXIGrabDevice(client, len, (xXIGrabDeviceReply *) rep); + else if (rep->RepType == X_XIPassiveGrabDevice) + SRepXIPassiveGrabDevice(client, len, (xXIPassiveGrabDeviceReply *) rep); + else if (rep->RepType == X_XIListProperties) + SRepXIListProperties(client, len, (xXIListPropertiesReply *) rep); + else if (rep->RepType == X_XIGetProperty) + SRepXIGetProperty(client, len, (xXIGetPropertyReply *) rep); + else if (rep->RepType == X_XIGetSelectedEvents) + SRepXIGetSelectedEvents(client, len, (xXIGetSelectedEventsReply *) rep); + else if (rep->RepType == X_XIGetFocus) + SRepXIGetFocus(client, len, (xXIGetFocusReply *) rep); + else { + FatalError("XINPUT confused sending swapped reply"); + } +} + +/************************************************************************ + * + * This function swaps the DeviceValuator event. + * + */ + +static void +SEventDeviceValuator(deviceValuator * from, deviceValuator * to) +{ + char n; + int i; + INT32 *ip B32; + + *to = *from; + swaps(&to->sequenceNumber, n); + swaps(&to->device_state, n); + ip = &to->valuator0; + for (i = 0; i < 6; i++) { + swapl((ip + i), n); /* macro - braces are required */ + } +} + +static void +SEventFocus(deviceFocus * from, deviceFocus * to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber, n); + swapl(&to->time, n); + swapl(&to->window, n); +} + +static void +SDeviceStateNotifyEvent(deviceStateNotify * from, deviceStateNotify * to) +{ + int i; + char n; + INT32 *ip B32; + + *to = *from; + swaps(&to->sequenceNumber, n); + swapl(&to->time, n); + ip = &to->valuator0; + for (i = 0; i < 3; i++) { + swapl((ip + i), n); /* macro - braces are required */ + } +} + +static void +SDeviceKeyStateNotifyEvent(deviceKeyStateNotify * from, + deviceKeyStateNotify * to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber, n); +} + +static void +SDeviceButtonStateNotifyEvent(deviceButtonStateNotify * from, + deviceButtonStateNotify * to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber, n); +} + +static void +SChangeDeviceNotifyEvent(changeDeviceNotify * from, changeDeviceNotify * to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber, n); + swapl(&to->time, n); +} + +static void +SDeviceMappingNotifyEvent(deviceMappingNotify * from, deviceMappingNotify * to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber, n); + swapl(&to->time, n); +} + +static void +SDevicePresenceNotifyEvent (devicePresenceNotify *from, devicePresenceNotify *to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber,n); + swapl(&to->time, n); + swaps(&to->control, n); +} + +static void +SDevicePropertyNotifyEvent (devicePropertyNotify *from, devicePropertyNotify *to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber,n); + swapl(&to->time, n); + swapl(&to->atom, n); +} + +static void +SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber,n); + swapl(&to->length, n); + swaps(&to->evtype, n); + swaps(&to->deviceid, n); + swapl(&to->time, n); + swapl(&to->root, n); + swapl(&to->event, n); + swapl(&to->child, n); + swapl(&to->root_x, n); + swapl(&to->root_y, n); + swapl(&to->event_x, n); + swapl(&to->event_y, n); + swaps(&to->sourceid, n); + swaps(&to->buttons_len, n); + swapl(&to->mods.base_mods, n); + swapl(&to->mods.latched_mods, n); + swapl(&to->mods.locked_mods, n); +} + +static void +SDeviceChangedEvent(xXIDeviceChangedEvent* from, xXIDeviceChangedEvent* to) +{ + char n; + int i, j; + xXIAnyInfo *any; + + *to = *from; + memcpy(&to[1], &from[1], from->length * 4); + + any = (xXIAnyInfo*)&to[1]; + for (i = 0; i < to->num_classes; i++) + { + int length = any->length; + + switch(any->type) + { + case KeyClass: + { + xXIKeyInfo *ki = (xXIKeyInfo*)any; + uint32_t *key = (uint32_t*)&ki[1]; + for (j = 0; j < ki->num_keycodes; j++, key++) + swapl(key, n); + swaps(&ki->num_keycodes, n); + } + break; + case ButtonClass: + { + xXIButtonInfo *bi = (xXIButtonInfo*)any; + Atom *labels = (Atom*)((char*)bi + sizeof(xXIButtonInfo) + + pad_to_int32(bits_to_bytes(bi->num_buttons))); + for (j = 0; j < bi->num_buttons; j++) + swapl(&labels[j], n); + swaps(&bi->num_buttons, n); + } + break; + case ValuatorClass: + { + xXIValuatorInfo* ai = (xXIValuatorInfo*)any; + swapl(&ai->label, n); + swapl(&ai->min.integral, n); + swapl(&ai->min.frac, n); + swapl(&ai->max.integral, n); + swapl(&ai->max.frac, n); + swapl(&ai->resolution, n); + swaps(&ai->number, n); + } + break; + } + + swaps(&any->type, n); + swaps(&any->length, n); + swaps(&any->sourceid, n); + + any = (xXIAnyInfo*)((char*)any + length * 4); + } + + swaps(&to->sequenceNumber, n); + swapl(&to->length, n); + swaps(&to->evtype, n); + swaps(&to->deviceid, n); + swapl(&to->time, n); + swaps(&to->num_classes, n); + swaps(&to->sourceid, n); + +} + +static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to) +{ + int i; + char n; + char *ptr; + char *vmask; + + memcpy(to, from, sizeof(xEvent) + from->length * 4); + + swaps(&to->sequenceNumber, n); + swapl(&to->length, n); + swaps(&to->evtype, n); + swaps(&to->deviceid, n); + swapl(&to->time, n); + swapl(&to->detail, n); + swapl(&to->root, n); + swapl(&to->event, n); + swapl(&to->child, n); + swapl(&to->root_x, n); + swapl(&to->root_y, n); + swapl(&to->event_x, n); + swapl(&to->event_y, n); + swaps(&to->buttons_len, n); + swaps(&to->valuators_len, n); + swaps(&to->sourceid, n); + swapl(&to->mods.base_mods, n); + swapl(&to->mods.latched_mods, n); + swapl(&to->mods.locked_mods, n); + swapl(&to->mods.effective_mods, n); + swapl(&to->flags, n); + + ptr = (char*)(&to[1]); + ptr += from->buttons_len * 4; + vmask = ptr; /* valuator mask */ + ptr += from->valuators_len * 4; + for (i = 0; i < from->valuators_len * 32; i++) + { + if (BitIsOn(vmask, i)) + { + swapl(((uint32_t*)ptr), n); + ptr += 4; + swapl(((uint32_t*)ptr), n); + ptr += 4; + } + } +} + +static void SDeviceHierarchyEvent(xXIHierarchyEvent *from, + xXIHierarchyEvent *to) +{ + int i; + char n; + xXIHierarchyInfo *info; + + *to = *from; + memcpy(&to[1], &from[1], from->length * 4); + swaps(&to->sequenceNumber, n); + swapl(&to->length, n); + swaps(&to->evtype, n); + swaps(&to->deviceid, n); + swapl(&to->time, n); + swapl(&to->flags, n); + swaps(&to->num_info, n); + + info = (xXIHierarchyInfo*)&to[1]; + for (i = 0; i< from->num_info; i++) + { + swaps(&info->deviceid, n); + swaps(&info->attachment, n); + info++; + } +} + +static void SXIPropertyEvent(xXIPropertyEvent *from, xXIPropertyEvent *to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber, n); + swapl(&to->length, n); + swaps(&to->evtype, n); + swaps(&to->deviceid, n); + swapl(&to->property, n); +} + +static void SRawEvent(xXIRawEvent *from, xXIRawEvent *to) +{ + char n; + int i; + FP3232 *values; + unsigned char *mask; + + memcpy(to, from, sizeof(xEvent) + from->length * 4); + + swaps(&to->sequenceNumber, n); + swapl(&to->length, n); + swaps(&to->evtype, n); + swaps(&to->deviceid, n); + swapl(&to->time, n); + swapl(&to->detail, n); + + + mask = (unsigned char*)&to[1]; + values = (FP3232*)(mask + from->valuators_len * 4); + + for (i = 0; i < from->valuators_len * 4 * 8; i++) + { + if (BitIsOn(mask, i)) + { + /* for each bit set there are two FP3232 values on the wire, in + * the order abcABC for data and data_raw. Here we swap as if + * they were in aAbBcC order because it's easier and really + * doesn't matter. + */ + swapl(&values->integral, n); + swapl(&values->frac, n); + values++; + swapl(&values->integral, n); + swapl(&values->frac, n); + values++; + } + } + + swaps(&to->valuators_len, n); +} + + +/** Event swapping function for XI2 events. */ +void +XI2EventSwap(xGenericEvent *from, xGenericEvent *to) +{ + switch(from->evtype) + { + case XI_Enter: + case XI_Leave: + case XI_FocusIn: + case XI_FocusOut: + SDeviceLeaveNotifyEvent((xXILeaveEvent*)from, (xXILeaveEvent*)to); + break; + case XI_DeviceChanged: + SDeviceChangedEvent((xXIDeviceChangedEvent*)from, + (xXIDeviceChangedEvent*)to); + break; + case XI_HierarchyChanged: + SDeviceHierarchyEvent((xXIHierarchyEvent*)from, (xXIHierarchyEvent*)to); + break; + case XI_PropertyEvent: + SXIPropertyEvent((xXIPropertyEvent*)from, + (xXIPropertyEvent*)to); + break; + case XI_Motion: + case XI_KeyPress: + case XI_KeyRelease: + case XI_ButtonPress: + case XI_ButtonRelease: + SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to); + break; + case XI_RawMotion: + case XI_RawKeyPress: + case XI_RawKeyRelease: + case XI_RawButtonPress: + case XI_RawButtonRelease: + SRawEvent((xXIRawEvent*)from, (xXIRawEvent*)to); + break; + default: + ErrorF("[Xi] Unknown event type to swap. This is a bug.\n"); + break; + } +} + +/************************************************************************** + * + * Allow the specified event to have its propagation suppressed. + * The default is to not allow suppression of propagation. + * + */ + +static void +AllowPropagateSuppress(Mask mask) +{ + int i; + + for (i = 0; i < MAXDEVICES; i++) + PropagateMask[i] |= mask; +} + +/************************************************************************** + * + * Record an event mask where there is no unique corresponding event type. + * We can't call SetMaskForEvent, since that would clobber the existing + * mask for that event. MotionHint and ButtonMotion are examples. + * + * Since extension event types will never be less than 64, we can use + * 0-63 in the EventInfo array as the "type" to be used to look up this + * mask. This means that the corresponding macros such as + * DevicePointerMotionHint must have access to the same constants. + * + */ + +static void +SetEventInfo(Mask mask, int constant) +{ + EventInfo[ExtEventIndex].mask = mask; + EventInfo[ExtEventIndex++].type = constant; +} + +/************************************************************************** + * + * Allow the specified event to be restricted to being selected by one + * client at a time. + * The default is to allow more than one client to select the event. + * + */ + +static void +SetExclusiveAccess(Mask mask) +{ + int i; + + for (i = 0; i < MAXDEVICES; i++) + ExtExclusiveMasks[i] |= mask; +} + +/************************************************************************** + * + * Assign the specified mask to the specified event. + * + */ + +static void +SetMaskForExtEvent(Mask mask, int event) +{ + int i; + + EventInfo[ExtEventIndex].mask = mask; + EventInfo[ExtEventIndex++].type = event; + + if ((event < LASTEvent) || (event >= 128)) + FatalError("MaskForExtensionEvent: bogus event number"); + + for (i = 0; i < MAXDEVICES; i++) + SetMaskForEvent(i, mask, event); +} + +/************************************************************************ + * + * This function sets up extension event types and masks. + * + */ + +static void +FixExtensionEvents(ExtensionEntry * extEntry) +{ + DeviceValuator = extEntry->eventBase; + DeviceKeyPress = DeviceValuator + 1; + DeviceKeyRelease = DeviceKeyPress + 1; + DeviceButtonPress = DeviceKeyRelease + 1; + DeviceButtonRelease = DeviceButtonPress + 1; + DeviceMotionNotify = DeviceButtonRelease + 1; + DeviceFocusIn = DeviceMotionNotify + 1; + DeviceFocusOut = DeviceFocusIn + 1; + ProximityIn = DeviceFocusOut + 1; + ProximityOut = ProximityIn + 1; + DeviceStateNotify = ProximityOut + 1; + DeviceMappingNotify = DeviceStateNotify + 1; + ChangeDeviceNotify = DeviceMappingNotify + 1; + DeviceKeyStateNotify = ChangeDeviceNotify + 1; + DeviceButtonStateNotify = DeviceKeyStateNotify + 1; + DevicePresenceNotify = DeviceButtonStateNotify + 1; + DevicePropertyNotify = DevicePresenceNotify + 1; + + event_base[KeyClass] = DeviceKeyPress; + event_base[ButtonClass] = DeviceButtonPress; + event_base[ValuatorClass] = DeviceMotionNotify; + event_base[ProximityClass] = ProximityIn; + event_base[FocusClass] = DeviceFocusIn; + event_base[OtherClass] = DeviceStateNotify; + + BadDevice += extEntry->errorBase; + BadEvent += extEntry->errorBase; + BadMode += extEntry->errorBase; + DeviceBusy += extEntry->errorBase; + BadClass += extEntry->errorBase; + + SetMaskForExtEvent(DeviceKeyPressMask, DeviceKeyPress); + AllowPropagateSuppress(DeviceKeyPressMask); + SetCriticalEvent(DeviceKeyPress); + + SetMaskForExtEvent(DeviceKeyReleaseMask, DeviceKeyRelease); + AllowPropagateSuppress(DeviceKeyReleaseMask); + SetCriticalEvent(DeviceKeyRelease); + + SetMaskForExtEvent(DeviceButtonPressMask, DeviceButtonPress); + AllowPropagateSuppress(DeviceButtonPressMask); + SetCriticalEvent(DeviceButtonPress); + + SetMaskForExtEvent(DeviceButtonReleaseMask, DeviceButtonRelease); + AllowPropagateSuppress(DeviceButtonReleaseMask); + SetCriticalEvent(DeviceButtonRelease); + + SetMaskForExtEvent(DeviceProximityMask, ProximityIn); + SetMaskForExtEvent(DeviceProximityMask, ProximityOut); + + SetMaskForExtEvent(DeviceStateNotifyMask, DeviceStateNotify); + + SetMaskForExtEvent(DevicePointerMotionMask, DeviceMotionNotify); + AllowPropagateSuppress(DevicePointerMotionMask); + SetCriticalEvent(DeviceMotionNotify); + + SetEventInfo(DevicePointerMotionHintMask, _devicePointerMotionHint); + SetEventInfo(DeviceButton1MotionMask, _deviceButton1Motion); + SetEventInfo(DeviceButton2MotionMask, _deviceButton2Motion); + SetEventInfo(DeviceButton3MotionMask, _deviceButton3Motion); + SetEventInfo(DeviceButton4MotionMask, _deviceButton4Motion); + SetEventInfo(DeviceButton5MotionMask, _deviceButton5Motion); + SetEventInfo(DeviceButtonMotionMask, _deviceButtonMotion); + + SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusIn); + SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusOut); + + SetMaskForExtEvent(DeviceMappingNotifyMask, DeviceMappingNotify); + SetMaskForExtEvent(ChangeDeviceNotifyMask, ChangeDeviceNotify); + + SetEventInfo(DeviceButtonGrabMask, _deviceButtonGrab); + SetExclusiveAccess(DeviceButtonGrabMask); + + SetEventInfo(DeviceOwnerGrabButtonMask, _deviceOwnerGrabButton); + SetEventInfo(DevicePresenceNotifyMask, _devicePresence); + SetMaskForExtEvent(DevicePropertyNotifyMask, DevicePropertyNotify); + + SetEventInfo(0, _noExtensionEvent); +} + +/************************************************************************ + * + * This function restores extension event types and masks to their + * initial state. + * + */ + +static void +RestoreExtensionEvents(void) +{ + int i, j; + + IReqCode = 0; + IEventBase = 0; + + for (i = 0; i < ExtEventIndex - 1; i++) { + if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128)) + { + for (j = 0; j < MAXDEVICES; j++) + SetMaskForEvent(j, 0, EventInfo[i].type); + } + EventInfo[i].mask = 0; + EventInfo[i].type = 0; + } + ExtEventIndex = 0; + DeviceValuator = 0; + DeviceKeyPress = 1; + DeviceKeyRelease = 2; + DeviceButtonPress = 3; + DeviceButtonRelease = 4; + DeviceMotionNotify = 5; + DeviceFocusIn = 6; + DeviceFocusOut = 7; + ProximityIn = 8; + ProximityOut = 9; + DeviceStateNotify = 10; + DeviceMappingNotify = 11; + ChangeDeviceNotify = 12; + DeviceKeyStateNotify = 13; + DeviceButtonStateNotify = 13; + DevicePresenceNotify = 14; + DevicePropertyNotify = 15; + + BadDevice = 0; + BadEvent = 1; + BadMode = 2; + DeviceBusy = 3; + BadClass = 4; + +} + +/*********************************************************************** + * + * IResetProc. + * Remove reply-swapping routine. + * Remove event-swapping routine. + * + */ + +static void +IResetProc(ExtensionEntry * unused) +{ + ReplySwapVector[IReqCode] = ReplyNotSwappd; + EventSwapVector[DeviceValuator] = NotImplemented; + EventSwapVector[DeviceKeyPress] = NotImplemented; + EventSwapVector[DeviceKeyRelease] = NotImplemented; + EventSwapVector[DeviceButtonPress] = NotImplemented; + EventSwapVector[DeviceButtonRelease] = NotImplemented; + EventSwapVector[DeviceMotionNotify] = NotImplemented; + EventSwapVector[DeviceFocusIn] = NotImplemented; + EventSwapVector[DeviceFocusOut] = NotImplemented; + EventSwapVector[ProximityIn] = NotImplemented; + EventSwapVector[ProximityOut] = NotImplemented; + EventSwapVector[DeviceStateNotify] = NotImplemented; + EventSwapVector[DeviceKeyStateNotify] = NotImplemented; + EventSwapVector[DeviceButtonStateNotify] = NotImplemented; + EventSwapVector[DeviceMappingNotify] = NotImplemented; + EventSwapVector[ChangeDeviceNotify] = NotImplemented; + EventSwapVector[DevicePresenceNotify] = NotImplemented; + EventSwapVector[DevicePropertyNotify] = NotImplemented; + RestoreExtensionEvents(); +} + + +/*********************************************************************** + * + * Assign an id and type to an input device. + * + */ + +void +AssignTypeAndName(DeviceIntPtr dev, Atom type, char *name) +{ + dev->xinput_type = type; + dev->name = strdup(name); +} + +/*********************************************************************** + * + * Make device type atoms. + * + */ + +static void +MakeDeviceTypeAtoms(void) +{ + int i; + + for (i = 0; i < NUMTYPES; i++) + dev_type[i].type = + MakeAtom(dev_type[i].name, strlen(dev_type[i].name), 1); +} + +/***************************************************************************** + * + * SEventIDispatch + * + * Swap any events defined in this extension. + */ +#define DO_SWAP(func,type) func ((type *)from, (type *)to) + +static void +SEventIDispatch(xEvent * from, xEvent * to) +{ + int type = from->u.u.type & 0177; + + if (type == DeviceValuator) + DO_SWAP(SEventDeviceValuator, deviceValuator); + else if (type == DeviceKeyPress) { + SKeyButtonPtrEvent(from, to); + to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1; + } else if (type == DeviceKeyRelease) { + SKeyButtonPtrEvent(from, to); + to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1; + } else if (type == DeviceButtonPress) { + SKeyButtonPtrEvent(from, to); + to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1; + } else if (type == DeviceButtonRelease) { + SKeyButtonPtrEvent(from, to); + to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1; + } else if (type == DeviceMotionNotify) { + SKeyButtonPtrEvent(from, to); + to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1; + } else if (type == DeviceFocusIn) + DO_SWAP(SEventFocus, deviceFocus); + else if (type == DeviceFocusOut) + DO_SWAP(SEventFocus, deviceFocus); + else if (type == ProximityIn) { + SKeyButtonPtrEvent(from, to); + to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1; + } else if (type == ProximityOut) { + SKeyButtonPtrEvent(from, to); + to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1; + } else if (type == DeviceStateNotify) + DO_SWAP(SDeviceStateNotifyEvent, deviceStateNotify); + else if (type == DeviceKeyStateNotify) + DO_SWAP(SDeviceKeyStateNotifyEvent, deviceKeyStateNotify); + else if (type == DeviceButtonStateNotify) + DO_SWAP(SDeviceButtonStateNotifyEvent, deviceButtonStateNotify); + else if (type == DeviceMappingNotify) + DO_SWAP(SDeviceMappingNotifyEvent, deviceMappingNotify); + else if (type == ChangeDeviceNotify) + DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify); + else if (type == DevicePresenceNotify) + DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify); + else if (type == DevicePropertyNotify) + DO_SWAP(SDevicePropertyNotifyEvent, devicePropertyNotify); + else { + FatalError("XInputExtension: Impossible event!\n"); + } +} + +/********************************************************************** + * + * IExtensionInit - 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. + * + * XI is mandatory nowadays, so if we fail to init XI, we die. + */ + +void +XInputExtensionInit(void) +{ + ExtensionEntry *extEntry; + XExtensionVersion thisversion = { XI_Present, + SERVER_XI_MAJOR_VERSION, + SERVER_XI_MINOR_VERSION, + }; + + if (!dixRegisterPrivateKey(&XIClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XIClientRec))) + FatalError("Cannot request private for XI.\n"); + + if (!AddCallback(&ClientStateCallback, XIClientCallback, 0)) + FatalError("Failed to add callback to XI.\n"); + + extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch, + SProcIDispatch, IResetProc, StandardMinorOpcode); + if (extEntry) { + IReqCode = extEntry->base; + IEventBase = extEntry->eventBase; + XIVersion = thisversion; + MakeDeviceTypeAtoms(); + RT_INPUTCLIENT = CreateNewResourceType((DeleteType) InputClientGone, + "INPUTCLIENT"); + if (!RT_INPUTCLIENT) + FatalError("Failed to add resource type for XI.\n"); + FixExtensionEvents(extEntry); + ReplySwapVector[IReqCode] = (ReplySwapPtr) SReplyIDispatch; + EventSwapVector[DeviceValuator] = SEventIDispatch; + EventSwapVector[DeviceKeyPress] = SEventIDispatch; + EventSwapVector[DeviceKeyRelease] = SEventIDispatch; + EventSwapVector[DeviceButtonPress] = SEventIDispatch; + EventSwapVector[DeviceButtonRelease] = SEventIDispatch; + EventSwapVector[DeviceMotionNotify] = SEventIDispatch; + EventSwapVector[DeviceFocusIn] = SEventIDispatch; + EventSwapVector[DeviceFocusOut] = SEventIDispatch; + EventSwapVector[ProximityIn] = SEventIDispatch; + EventSwapVector[ProximityOut] = SEventIDispatch; + EventSwapVector[DeviceStateNotify] = SEventIDispatch; + EventSwapVector[DeviceKeyStateNotify] = SEventIDispatch; + EventSwapVector[DeviceButtonStateNotify] = SEventIDispatch; + EventSwapVector[DeviceMappingNotify] = SEventIDispatch; + EventSwapVector[ChangeDeviceNotify] = SEventIDispatch; + EventSwapVector[DevicePresenceNotify] = SEventIDispatch; + + GERegisterExtension(IReqCode, XI2EventSwap); + + + memset(&xi_all_devices, 0, sizeof(xi_all_devices)); + memset(&xi_all_master_devices, 0, sizeof(xi_all_master_devices)); + xi_all_devices.id = XIAllDevices; + xi_all_devices.name = "XIAllDevices"; + xi_all_master_devices.id = XIAllMasterDevices; + xi_all_master_devices.name = "XIAllMasterDevices"; + + inputInfo.all_devices = &xi_all_devices; + inputInfo.all_master_devices = &xi_all_master_devices; + + XIResetProperties(); + } else { + FatalError("IExtensionInit: AddExtensions failed\n"); + } +} + diff --git a/xorg-server/Xi/getdctl.c b/xorg-server/Xi/getdctl.c index c334c77aa..4e04b8b06 100644 --- a/xorg-server/Xi/getdctl.c +++ b/xorg-server/Xi/getdctl.c @@ -1,241 +1,241 @@ -/************************************************************
-
-Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California.
-
- All Rights Reserved
-
-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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-HEWLETT-PACKARD 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.
-
-********************************************************/
-
-/********************************************************************
- *
- * Get Device control attributes for an extension device.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "inputstr.h" /* DeviceIntPtr */
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "exglobals.h"
-
-#include "getdctl.h"
-
-/***********************************************************************
- *
- * This procedure gets the control attributes for an extension device,
- * for clients on machines with a different byte ordering than the server.
- *
- */
-
-int
-SProcXGetDeviceControl(ClientPtr client)
-{
- char n;
-
- REQUEST(xGetDeviceControlReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xGetDeviceControlReq);
- swaps(&stuff->control, n);
- return (ProcXGetDeviceControl(client));
-}
-
-/***********************************************************************
- *
- * This procedure copies DeviceResolution data, swapping if necessary.
- *
- */
-
-static void
-CopySwapDeviceResolution(ClientPtr client, ValuatorClassPtr v, char *buf,
- int length)
-{
- char n;
- AxisInfoPtr a;
- xDeviceResolutionState *r;
- int i, *iptr;
-
- r = (xDeviceResolutionState *) buf;
- r->control = DEVICE_RESOLUTION;
- r->length = length;
- r->num_valuators = v->numAxes;
- buf += sizeof(xDeviceResolutionState);
- iptr = (int *)buf;
- for (i = 0, a = v->axes; i < v->numAxes; i++, a++)
- *iptr++ = a->resolution;
- for (i = 0, a = v->axes; i < v->numAxes; i++, a++)
- *iptr++ = a->min_resolution;
- for (i = 0, a = v->axes; i < v->numAxes; i++, a++)
- *iptr++ = a->max_resolution;
- if (client->swapped) {
- swaps(&r->control, n);
- swaps(&r->length, n);
- swapl(&r->num_valuators, n);
- iptr = (int *)buf;
- for (i = 0; i < (3 * v->numAxes); i++, iptr++) {
- swapl(iptr, n);
- }
- }
-}
-
-static void CopySwapDeviceCore (ClientPtr client, DeviceIntPtr dev, char *buf)
-{
- char n;
- xDeviceCoreState *c = (xDeviceCoreState *) buf;
-
- c->control = DEVICE_CORE;
- c->length = sizeof(xDeviceCoreState);
- c->status = dev->coreEvents;
- c->iscore = (dev == inputInfo.keyboard || dev == inputInfo.pointer);
-
- if (client->swapped) {
- swaps(&c->control, n);
- swaps(&c->length, n);
- swaps(&c->status, n);
- }
-}
-
-static void CopySwapDeviceEnable (ClientPtr client, DeviceIntPtr dev, char *buf)
-{
- char n;
- xDeviceEnableState *e = (xDeviceEnableState *) buf;
-
- e->control = DEVICE_ENABLE;
- e->length = sizeof(xDeviceEnableState);
- e->enable = dev->enabled;
-
- if (client->swapped) {
- swaps(&e->control, n);
- swaps(&e->length, n);
- swaps(&e->enable, n);
- }
-}
-
-/***********************************************************************
- *
- * This procedure writes the reply for the xGetDeviceControl function,
- * if the client and server have a different byte ordering.
- *
- */
-
-void
-SRepXGetDeviceControl(ClientPtr client, int size, xGetDeviceControlReply * rep)
-{
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- WriteToClient(client, size, (char *)rep);
-}
-
-/***********************************************************************
- *
- * Get the state of the specified device control.
- *
- */
-
-int
-ProcXGetDeviceControl(ClientPtr client)
-{
- int rc, total_length = 0;
- char *buf, *savbuf;
- DeviceIntPtr dev;
- xGetDeviceControlReply rep;
-
- REQUEST(xGetDeviceControlReq);
- REQUEST_SIZE_MATCH(xGetDeviceControlReq);
-
- rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.repType = X_Reply;
- rep.RepType = X_GetDeviceControl;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- switch (stuff->control) {
- case DEVICE_RESOLUTION:
- if (!dev->valuator)
- return BadMatch;
- total_length = sizeof(xDeviceResolutionState) +
- (3 * sizeof(int) * dev->valuator->numAxes);
- break;
- case DEVICE_ABS_CALIB:
- case DEVICE_ABS_AREA:
- return BadMatch;
- case DEVICE_CORE:
- total_length = sizeof(xDeviceCoreState);
- break;
- case DEVICE_ENABLE:
- total_length = sizeof(xDeviceEnableState);
- break;
- default:
- return BadValue;
- }
-
- buf = (char *)malloc(total_length);
- if (!buf)
- return BadAlloc;
- savbuf = buf;
-
- switch (stuff->control) {
- case DEVICE_RESOLUTION:
- CopySwapDeviceResolution(client, dev->valuator, buf, total_length);
- break;
- case DEVICE_CORE:
- CopySwapDeviceCore(client, dev, buf);
- break;
- case DEVICE_ENABLE:
- CopySwapDeviceEnable(client, dev, buf);
- break;
- default:
- break;
- }
-
- rep.length = bytes_to_int32(total_length);
- WriteReplyToClient(client, sizeof(xGetDeviceControlReply), &rep);
- WriteToClient(client, total_length, savbuf);
- free(savbuf);
- return Success;
-}
+/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + All Rights Reserved + +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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/******************************************************************** + * + * Get Device control attributes for an extension device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "exglobals.h" + +#include "getdctl.h" + +/*********************************************************************** + * + * This procedure gets the control attributes for an extension device, + * for clients on machines with a different byte ordering than the server. + * + */ + +int +SProcXGetDeviceControl(ClientPtr client) +{ + char n; + + REQUEST(xGetDeviceControlReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xGetDeviceControlReq); + swaps(&stuff->control, n); + return (ProcXGetDeviceControl(client)); +} + +/*********************************************************************** + * + * This procedure copies DeviceResolution data, swapping if necessary. + * + */ + +static void +CopySwapDeviceResolution(ClientPtr client, ValuatorClassPtr v, char *buf, + int length) +{ + char n; + AxisInfoPtr a; + xDeviceResolutionState *r; + int i, *iptr; + + r = (xDeviceResolutionState *) buf; + r->control = DEVICE_RESOLUTION; + r->length = length; + r->num_valuators = v->numAxes; + buf += sizeof(xDeviceResolutionState); + iptr = (int *)buf; + for (i = 0, a = v->axes; i < v->numAxes; i++, a++) + *iptr++ = a->resolution; + for (i = 0, a = v->axes; i < v->numAxes; i++, a++) + *iptr++ = a->min_resolution; + for (i = 0, a = v->axes; i < v->numAxes; i++, a++) + *iptr++ = a->max_resolution; + if (client->swapped) { + swaps(&r->control, n); + swaps(&r->length, n); + swapl(&r->num_valuators, n); + iptr = (int *)buf; + for (i = 0; i < (3 * v->numAxes); i++, iptr++) { + swapl(iptr, n); + } + } +} + +static void CopySwapDeviceCore (ClientPtr client, DeviceIntPtr dev, char *buf) +{ + char n; + xDeviceCoreState *c = (xDeviceCoreState *) buf; + + c->control = DEVICE_CORE; + c->length = sizeof(xDeviceCoreState); + c->status = dev->coreEvents; + c->iscore = (dev == inputInfo.keyboard || dev == inputInfo.pointer); + + if (client->swapped) { + swaps(&c->control, n); + swaps(&c->length, n); + swaps(&c->status, n); + } +} + +static void CopySwapDeviceEnable (ClientPtr client, DeviceIntPtr dev, char *buf) +{ + char n; + xDeviceEnableState *e = (xDeviceEnableState *) buf; + + e->control = DEVICE_ENABLE; + e->length = sizeof(xDeviceEnableState); + e->enable = dev->enabled; + + if (client->swapped) { + swaps(&e->control, n); + swaps(&e->length, n); + swaps(&e->enable, n); + } +} + +/*********************************************************************** + * + * This procedure writes the reply for the xGetDeviceControl function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetDeviceControl(ClientPtr client, int size, xGetDeviceControlReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} + +/*********************************************************************** + * + * Get the state of the specified device control. + * + */ + +int +ProcXGetDeviceControl(ClientPtr client) +{ + int rc, total_length = 0; + char *buf, *savbuf; + DeviceIntPtr dev; + xGetDeviceControlReply rep; + + REQUEST(xGetDeviceControlReq); + REQUEST_SIZE_MATCH(xGetDeviceControlReq); + + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.repType = X_Reply; + rep.RepType = X_GetDeviceControl; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + switch (stuff->control) { + case DEVICE_RESOLUTION: + if (!dev->valuator) + return BadMatch; + total_length = sizeof(xDeviceResolutionState) + + (3 * sizeof(int) * dev->valuator->numAxes); + break; + case DEVICE_ABS_CALIB: + case DEVICE_ABS_AREA: + return BadMatch; + case DEVICE_CORE: + total_length = sizeof(xDeviceCoreState); + break; + case DEVICE_ENABLE: + total_length = sizeof(xDeviceEnableState); + break; + default: + return BadValue; + } + + buf = (char *)malloc(total_length); + if (!buf) + return BadAlloc; + savbuf = buf; + + switch (stuff->control) { + case DEVICE_RESOLUTION: + CopySwapDeviceResolution(client, dev->valuator, buf, total_length); + break; + case DEVICE_CORE: + CopySwapDeviceCore(client, dev, buf); + break; + case DEVICE_ENABLE: + CopySwapDeviceEnable(client, dev, buf); + break; + default: + break; + } + + rep.length = bytes_to_int32(total_length); + WriteReplyToClient(client, sizeof(xGetDeviceControlReply), &rep); + WriteToClient(client, total_length, savbuf); + free(savbuf); + return Success; +} diff --git a/xorg-server/Xi/getprop.c b/xorg-server/Xi/getprop.c index fbf43f3fd..5e102627d 100644 --- a/xorg-server/Xi/getprop.c +++ b/xorg-server/Xi/getprop.c @@ -1,187 +1,187 @@ -/************************************************************
-
-Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California.
-
- All Rights Reserved
-
-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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-HEWLETT-PACKARD 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.
-
-********************************************************/
-
-/***********************************************************************
- *
- * Function to return the dont-propagate-list for an extension device.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "inputstr.h" /* DeviceIntPtr */
-#include "windowstr.h" /* window structs */
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "exglobals.h"
-#include "swaprep.h"
-
-#include "getprop.h"
-
-extern XExtEventInfo EventInfo[];
-extern int ExtEventIndex;
-
-/***********************************************************************
- *
- * Handle a request from a client with a different byte order.
- *
- */
-
-int
-SProcXGetDeviceDontPropagateList(ClientPtr client)
-{
- char n;
-
- REQUEST(xGetDeviceDontPropagateListReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq);
- swapl(&stuff->window, n);
- return (ProcXGetDeviceDontPropagateList(client));
-}
-
-/***********************************************************************
- *
- * This procedure lists the input devices available to the server.
- *
- */
-
-int
-ProcXGetDeviceDontPropagateList(ClientPtr client)
-{
- CARD16 count = 0;
- int i, rc;
- XEventClass *buf = NULL, *tbuf;
- WindowPtr pWin;
- xGetDeviceDontPropagateListReply rep;
- OtherInputMasks *others;
-
- REQUEST(xGetDeviceDontPropagateListReq);
- REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq);
-
- rep.repType = X_Reply;
- rep.RepType = X_GetDeviceDontPropagateList;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.count = 0;
-
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- if ((others = wOtherInputMasks(pWin)) != 0) {
- for (i = 0; i < EMASKSIZE; i++)
- ClassFromMask(NULL, others->dontPropagateMask[i], i,
- &count, COUNT);
- if (count) {
- rep.count = count;
- buf = (XEventClass *) malloc(rep.count * sizeof(XEventClass));
- rep.length = bytes_to_int32(rep.count * sizeof(XEventClass));
-
- tbuf = buf;
- for (i = 0; i < EMASKSIZE; i++)
- tbuf = ClassFromMask(tbuf, others->dontPropagateMask[i], i,
- NULL, CREATE);
- }
- }
-
- WriteReplyToClient(client, sizeof(xGetDeviceDontPropagateListReply), &rep);
-
- if (count) {
- client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
- WriteSwappedDataToClient(client, count * sizeof(XEventClass), buf);
- free(buf);
- }
- return Success;
-}
-
-/***********************************************************************
- *
- * This procedure gets a list of event classes from a mask word.
- * A single mask may translate to more than one event class.
- *
- */
-
-XEventClass
- * ClassFromMask(XEventClass * buf, Mask mask, int maskndx, CARD16 * count,
- int mode)
-{
- int i, j;
- int id = maskndx;
- Mask tmask = 0x80000000;
-
- for (i = 0; i < 32; i++, tmask >>= 1)
- if (tmask & mask) {
- for (j = 0; j < ExtEventIndex; j++)
- if (EventInfo[j].mask == tmask) {
- if (mode == COUNT)
- (*count)++;
- else
- *buf++ = (id << 8) | EventInfo[j].type;
- }
- }
- return buf;
-}
-
-/***********************************************************************
- *
- * This procedure writes the reply for the XGetDeviceDontPropagateList function,
- * if the client and server have a different byte ordering.
- *
- */
-
-void
-SRepXGetDeviceDontPropagateList(ClientPtr client, int size,
- xGetDeviceDontPropagateListReply * rep)
-{
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->count, n);
- WriteToClient(client, size, (char *)rep);
-}
+/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + All Rights Reserved + +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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/*********************************************************************** + * + * Function to return the dont-propagate-list for an extension device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structs */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "exglobals.h" +#include "swaprep.h" + +#include "getprop.h" + +extern XExtEventInfo EventInfo[]; +extern int ExtEventIndex; + +/*********************************************************************** + * + * Handle a request from a client with a different byte order. + * + */ + +int +SProcXGetDeviceDontPropagateList(ClientPtr client) +{ + char n; + + REQUEST(xGetDeviceDontPropagateListReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq); + swapl(&stuff->window, n); + return (ProcXGetDeviceDontPropagateList(client)); +} + +/*********************************************************************** + * + * This procedure lists the input devices available to the server. + * + */ + +int +ProcXGetDeviceDontPropagateList(ClientPtr client) +{ + CARD16 count = 0; + int i, rc; + XEventClass *buf = NULL, *tbuf; + WindowPtr pWin; + xGetDeviceDontPropagateListReply rep; + OtherInputMasks *others; + + REQUEST(xGetDeviceDontPropagateListReq); + REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq); + + rep.repType = X_Reply; + rep.RepType = X_GetDeviceDontPropagateList; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.count = 0; + + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + if ((others = wOtherInputMasks(pWin)) != 0) { + for (i = 0; i < EMASKSIZE; i++) + ClassFromMask(NULL, others->dontPropagateMask[i], i, + &count, COUNT); + if (count) { + rep.count = count; + buf = (XEventClass *) malloc(rep.count * sizeof(XEventClass)); + rep.length = bytes_to_int32(rep.count * sizeof(XEventClass)); + + tbuf = buf; + for (i = 0; i < EMASKSIZE; i++) + tbuf = ClassFromMask(tbuf, others->dontPropagateMask[i], i, + NULL, CREATE); + } + } + + WriteReplyToClient(client, sizeof(xGetDeviceDontPropagateListReply), &rep); + + if (count) { + client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; + WriteSwappedDataToClient(client, count * sizeof(XEventClass), buf); + free(buf); + } + return Success; +} + +/*********************************************************************** + * + * This procedure gets a list of event classes from a mask word. + * A single mask may translate to more than one event class. + * + */ + +XEventClass + * ClassFromMask(XEventClass * buf, Mask mask, int maskndx, CARD16 * count, + int mode) +{ + int i, j; + int id = maskndx; + Mask tmask = 0x80000000; + + for (i = 0; i < 32; i++, tmask >>= 1) + if (tmask & mask) { + for (j = 0; j < ExtEventIndex; j++) + if (EventInfo[j].mask == tmask) { + if (mode == COUNT) + (*count)++; + else + *buf++ = (id << 8) | EventInfo[j].type; + } + } + return buf; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XGetDeviceDontPropagateList function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetDeviceDontPropagateList(ClientPtr client, int size, + xGetDeviceDontPropagateListReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->count, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/getselev.c b/xorg-server/Xi/getselev.c index fb45a0627..7304738b3 100644 --- a/xorg-server/Xi/getselev.c +++ b/xorg-server/Xi/getselev.c @@ -1,178 +1,178 @@ -/************************************************************
-
-Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California.
-
- All Rights Reserved
-
-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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-HEWLETT-PACKARD 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.
-
-********************************************************/
-
-/***********************************************************************
- *
- * Extension function to get the current selected events for a given window.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "inputstr.h" /* DeviceIntPtr */
-#include "windowstr.h" /* window struct */
-#include "exglobals.h"
-#include "swaprep.h"
-
-#include "getprop.h"
-#include "getselev.h"
-
-/***********************************************************************
- *
- * This procedure gets the current selected extension events.
- *
- */
-
-int
-SProcXGetSelectedExtensionEvents(ClientPtr client)
-{
- char n;
-
- REQUEST(xGetSelectedExtensionEventsReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq);
- swapl(&stuff->window, n);
- return (ProcXGetSelectedExtensionEvents(client));
-}
-
-/***********************************************************************
- *
- * This procedure gets the current device select mask,
- * if the client and server have a different byte ordering.
- *
- */
-
-int
-ProcXGetSelectedExtensionEvents(ClientPtr client)
-{
- int i, rc, total_length = 0;
- xGetSelectedExtensionEventsReply rep;
- WindowPtr pWin;
- XEventClass *buf = NULL;
- XEventClass *tclient;
- XEventClass *aclient;
- OtherInputMasks *pOthers;
- InputClientsPtr others;
-
- REQUEST(xGetSelectedExtensionEventsReq);
- REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq);
-
- rep.repType = X_Reply;
- rep.RepType = X_GetSelectedExtensionEvents;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.this_client_count = 0;
- rep.all_clients_count = 0;
-
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- if ((pOthers = wOtherInputMasks(pWin)) != 0) {
- for (others = pOthers->inputClients; others; others = others->next)
- for (i = 0; i < EMASKSIZE; i++)
- ClassFromMask(NULL, others->mask[i], i,
- &rep.all_clients_count, COUNT);
-
- for (others = pOthers->inputClients; others; others = others->next)
- if (SameClient(others, client)) {
- for (i = 0; i < EMASKSIZE; i++)
- ClassFromMask(NULL, others->mask[i], i,
- &rep.this_client_count, COUNT);
- break;
- }
-
- total_length = (rep.all_clients_count + rep.this_client_count) *
- sizeof(XEventClass);
- rep.length = bytes_to_int32(total_length);
- buf = (XEventClass *) malloc(total_length);
-
- tclient = buf;
- aclient = buf + rep.this_client_count;
- if (others)
- for (i = 0; i < EMASKSIZE; i++)
- tclient =
- ClassFromMask(tclient, others->mask[i], i, NULL, CREATE);
-
- for (others = pOthers->inputClients; others; others = others->next)
- for (i = 0; i < EMASKSIZE; i++)
- aclient =
- ClassFromMask(aclient, others->mask[i], i, NULL, CREATE);
- }
-
- WriteReplyToClient(client, sizeof(xGetSelectedExtensionEventsReply), &rep);
-
- if (total_length) {
- client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
- WriteSwappedDataToClient(client, total_length, buf);
- }
- free(buf);
- return Success;
-}
-
-/***********************************************************************
- *
- * This procedure writes the reply for the XGetSelectedExtensionEvents function,
- * if the client and server have a different byte ordering.
- *
- */
-
-void
-SRepXGetSelectedExtensionEvents(ClientPtr client, int size,
- xGetSelectedExtensionEventsReply * rep)
-{
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->this_client_count, n);
- swaps(&rep->all_clients_count, n);
- WriteToClient(client, size, (char *)rep);
-}
+/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + All Rights Reserved + +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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/*********************************************************************** + * + * Extension function to get the current selected events for a given window. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window struct */ +#include "exglobals.h" +#include "swaprep.h" + +#include "getprop.h" +#include "getselev.h" + +/*********************************************************************** + * + * This procedure gets the current selected extension events. + * + */ + +int +SProcXGetSelectedExtensionEvents(ClientPtr client) +{ + char n; + + REQUEST(xGetSelectedExtensionEventsReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq); + swapl(&stuff->window, n); + return (ProcXGetSelectedExtensionEvents(client)); +} + +/*********************************************************************** + * + * This procedure gets the current device select mask, + * if the client and server have a different byte ordering. + * + */ + +int +ProcXGetSelectedExtensionEvents(ClientPtr client) +{ + int i, rc, total_length = 0; + xGetSelectedExtensionEventsReply rep; + WindowPtr pWin; + XEventClass *buf = NULL; + XEventClass *tclient; + XEventClass *aclient; + OtherInputMasks *pOthers; + InputClientsPtr others; + + REQUEST(xGetSelectedExtensionEventsReq); + REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq); + + rep.repType = X_Reply; + rep.RepType = X_GetSelectedExtensionEvents; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.this_client_count = 0; + rep.all_clients_count = 0; + + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + if ((pOthers = wOtherInputMasks(pWin)) != 0) { + for (others = pOthers->inputClients; others; others = others->next) + for (i = 0; i < EMASKSIZE; i++) + ClassFromMask(NULL, others->mask[i], i, + &rep.all_clients_count, COUNT); + + for (others = pOthers->inputClients; others; others = others->next) + if (SameClient(others, client)) { + for (i = 0; i < EMASKSIZE; i++) + ClassFromMask(NULL, others->mask[i], i, + &rep.this_client_count, COUNT); + break; + } + + total_length = (rep.all_clients_count + rep.this_client_count) * + sizeof(XEventClass); + rep.length = bytes_to_int32(total_length); + buf = (XEventClass *) malloc(total_length); + + tclient = buf; + aclient = buf + rep.this_client_count; + if (others) + for (i = 0; i < EMASKSIZE; i++) + tclient = + ClassFromMask(tclient, others->mask[i], i, NULL, CREATE); + + for (others = pOthers->inputClients; others; others = others->next) + for (i = 0; i < EMASKSIZE; i++) + aclient = + ClassFromMask(aclient, others->mask[i], i, NULL, CREATE); + } + + WriteReplyToClient(client, sizeof(xGetSelectedExtensionEventsReply), &rep); + + if (total_length) { + client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; + WriteSwappedDataToClient(client, total_length, buf); + } + free(buf); + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XGetSelectedExtensionEvents function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetSelectedExtensionEvents(ClientPtr client, int size, + xGetSelectedExtensionEventsReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->this_client_count, n); + swaps(&rep->all_clients_count, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/stubs.c b/xorg-server/Xi/stubs.c index ec6be9361..6a4c18158 100644 --- a/xorg-server/Xi/stubs.c +++ b/xorg-server/Xi/stubs.c @@ -1,146 +1,146 @@ -/************************************************************
-
-Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California.
-
- All Rights Reserved
-
-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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-HEWLETT-PACKARD 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.
-
-********************************************************/
-
-/*
- * stubs.c -- stub routines for the X server side of the XINPUT
- * extension. This file is mainly to be used only as documentation.
- * There is not much code here, and you can't get a working XINPUT
- * server just using this.
- * The Xvfb server uses this file so it will compile with the same
- * object files as the real X server for a platform that has XINPUT.
- * Xnest could do the same thing.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "inputstr.h"
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "XIstubs.h"
-#include "xace.h"
-
-/****************************************************************************
- *
- * Caller: ProcXSetDeviceMode
- *
- * Change the mode of an extension device.
- * This function is used to change the mode of a device from reporting
- * relative motion to reporting absolute positional information, and
- * vice versa.
- * The default implementation below is that no such devices are supported.
- *
- */
-
-int
-SetDeviceMode(ClientPtr client, DeviceIntPtr dev, int mode)
-{
- return BadMatch;
-}
-
-/****************************************************************************
- *
- * Caller: ProcXSetDeviceValuators
- *
- * Set the value of valuators on an extension input device.
- * This function is used to set the initial value of valuators on
- * those input devices that are capable of reporting either relative
- * motion or an absolute position, and allow an initial position to be set.
- * The default implementation below is that no such devices are supported.
- *
- */
-
-int
-SetDeviceValuators(ClientPtr client, DeviceIntPtr dev,
- int *valuators, int first_valuator, int num_valuators)
-{
- return BadMatch;
-}
-
-/****************************************************************************
- *
- * Caller: ProcXChangeDeviceControl
- *
- * Change the specified device controls on an extension input device.
- *
- */
-
-int
-ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev,
- xDeviceCtl * control)
-{
- return BadMatch;
-}
-
-
-/****************************************************************************
- *
- * Caller: configAddDevice (and others)
- *
- * Add a new device with the specified options.
- *
- */
-int
-NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
- DeviceIntPtr *pdev)
-{
- return BadValue;
-}
-
-/****************************************************************************
- *
- * Caller: configRemoveDevice (and others)
- *
- * Remove the specified device previously added.
- *
- */
-void
-DeleteInputDeviceRequest(DeviceIntPtr dev)
-{
-}
+/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + All Rights Reserved + +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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/* + * stubs.c -- stub routines for the X server side of the XINPUT + * extension. This file is mainly to be used only as documentation. + * There is not much code here, and you can't get a working XINPUT + * server just using this. + * The Xvfb server uses this file so it will compile with the same + * object files as the real X server for a platform that has XINPUT. + * Xnest could do the same thing. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "inputstr.h" +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "XIstubs.h" +#include "xace.h" + +/**************************************************************************** + * + * Caller: ProcXSetDeviceMode + * + * Change the mode of an extension device. + * This function is used to change the mode of a device from reporting + * relative motion to reporting absolute positional information, and + * vice versa. + * The default implementation below is that no such devices are supported. + * + */ + +int +SetDeviceMode(ClientPtr client, DeviceIntPtr dev, int mode) +{ + return BadMatch; +} + +/**************************************************************************** + * + * Caller: ProcXSetDeviceValuators + * + * Set the value of valuators on an extension input device. + * This function is used to set the initial value of valuators on + * those input devices that are capable of reporting either relative + * motion or an absolute position, and allow an initial position to be set. + * The default implementation below is that no such devices are supported. + * + */ + +int +SetDeviceValuators(ClientPtr client, DeviceIntPtr dev, + int *valuators, int first_valuator, int num_valuators) +{ + return BadMatch; +} + +/**************************************************************************** + * + * Caller: ProcXChangeDeviceControl + * + * Change the specified device controls on an extension input device. + * + */ + +int +ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev, + xDeviceCtl * control) +{ + return BadMatch; +} + + +/**************************************************************************** + * + * Caller: configAddDevice (and others) + * + * Add a new device with the specified options. + * + */ +int +NewInputDeviceRequest(InputOption *options, InputAttributes *attrs, + DeviceIntPtr *pdev) +{ + return BadValue; +} + +/**************************************************************************** + * + * Caller: configRemoveDevice (and others) + * + * Remove the specified device previously added. + * + */ +void +DeleteInputDeviceRequest(DeviceIntPtr dev) +{ +} diff --git a/xorg-server/Xi/xichangehierarchy.c b/xorg-server/Xi/xichangehierarchy.c index f83af77c3..96ead6fcd 100644 --- a/xorg-server/Xi/xichangehierarchy.c +++ b/xorg-server/Xi/xichangehierarchy.c @@ -1,496 +1,496 @@ -/*
- * Copyright 2007-2008 Peter Hutterer
- * Copyright 2009 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, University of South Australia, NICTA
- */
-
-/***********************************************************************
- *
- * Request change in the device hierarchy.
- *
- */
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h> /* for inputstr.h */
-#include <X11/Xproto.h> /* Request macro */
-#include "inputstr.h" /* DeviceIntPtr */
-#include "windowstr.h" /* window structure */
-#include "scrnintstr.h" /* screen structure */
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XI2proto.h>
-#include <X11/extensions/geproto.h>
-#include "extnsionst.h"
-#include "exevents.h"
-#include "exglobals.h"
-#include "geext.h"
-#include "xace.h"
-#include "xiquerydevice.h" /* for GetDeviceUse */
-
-#include "xkbsrv.h"
-
-#include "xichangehierarchy.h"
-
-/**
- * Send the current state of the device hierarchy to all clients.
- */
-void XISendDeviceHierarchyEvent(int flags[MAXDEVICES])
-{
- xXIHierarchyEvent *ev;
- xXIHierarchyInfo *info;
- DeviceIntRec dummyDev;
- DeviceIntPtr dev;
- int i;
-
- if (!flags)
- return;
-
- ev = calloc(1, sizeof(xXIHierarchyEvent) +
- MAXDEVICES * sizeof(xXIHierarchyInfo));
- if (!ev)
- return;
- ev->type = GenericEvent;
- ev->extension = IReqCode;
- ev->evtype = XI_HierarchyChanged;
- ev->time = GetTimeInMillis();
- ev->flags = 0;
- ev->num_info = inputInfo.numDevices;
-
- info = (xXIHierarchyInfo*)&ev[1];
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- info->deviceid = dev->id;
- info->enabled = dev->enabled;
- info->use = GetDeviceUse(dev, &info->attachment);
- info->flags = flags[dev->id];
- ev->flags |= info->flags;
- info++;
- }
- for (dev = inputInfo.off_devices; dev; dev = dev->next)
- {
- info->deviceid = dev->id;
- info->enabled = dev->enabled;
- info->use = GetDeviceUse(dev, &info->attachment);
- info->flags = flags[dev->id];
- ev->flags |= info->flags;
- info++;
- }
-
-
- for (i = 0; i < MAXDEVICES; i++)
- {
- if (flags[i] & (XIMasterRemoved | XISlaveRemoved))
- {
- info->deviceid = i;
- info->enabled = FALSE;
- info->flags = flags[i];
- info->use = 0;
- ev->flags |= info->flags;
- ev->num_info++;
- info++;
- }
- }
-
- ev->length = bytes_to_int32(ev->num_info * sizeof(xXIHierarchyInfo));
-
- memset(&dummyDev, 0, sizeof(dummyDev));
- dummyDev.id = XIAllDevices;
- dummyDev.type = SLAVE;
- SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1);
- free(ev);
-}
-
-
-/***********************************************************************
- *
- * This procedure allows a client to change the device hierarchy through
- * adding new master devices, removing them, etc.
- *
- */
-
-int SProcXIChangeHierarchy(ClientPtr client)
-{
- char n;
-
- REQUEST(xXIChangeHierarchyReq);
- swaps(&stuff->length, n);
- return (ProcXIChangeHierarchy(client));
-}
-
-static int
-add_master(ClientPtr client, xXIAddMasterInfo *c, int flags[MAXDEVICES])
-{
- DeviceIntPtr ptr, keybd, XTestptr, XTestkeybd;
- char* name;
- int rc;
-
- name = calloc(c->name_len + 1, sizeof(char));
- strncpy(name, (char*)&c[1], c->name_len);
-
- rc = AllocDevicePair(client, name, &ptr, &keybd,
- CorePointerProc, CoreKeyboardProc, TRUE);
- if (rc != Success)
- goto unwind;
-
- if (!c->send_core)
- ptr->coreEvents = keybd->coreEvents = FALSE;
-
- /* Allocate virtual slave devices for xtest events */
- rc = AllocXTestDevice(client, name, &XTestptr, &XTestkeybd, ptr, keybd);
- if (rc != Success)
- {
- DeleteInputDeviceRequest(ptr);
- DeleteInputDeviceRequest(keybd);
- goto unwind;
- }
-
- ActivateDevice(ptr, FALSE);
- ActivateDevice(keybd, FALSE);
- flags[ptr->id] |= XIMasterAdded;
- flags[keybd->id] |= XIMasterAdded;
-
- ActivateDevice(XTestptr, FALSE);
- ActivateDevice(XTestkeybd, FALSE);
- flags[XTestptr->id] |= XISlaveAdded;
- flags[XTestkeybd->id] |= XISlaveAdded;
-
- if (c->enable)
- {
- EnableDevice(ptr, FALSE);
- EnableDevice(keybd, FALSE);
- flags[ptr->id] |= XIDeviceEnabled;
- flags[keybd->id] |= XIDeviceEnabled;
-
- EnableDevice(XTestptr, FALSE);
- EnableDevice(XTestkeybd, FALSE);
- flags[XTestptr->id] |= XIDeviceEnabled;
- flags[XTestkeybd->id] |= XIDeviceEnabled;
- }
-
- /* Attach the XTest virtual devices to the newly
- created master device */
- AttachDevice(NULL, XTestptr, ptr);
- AttachDevice(NULL, XTestkeybd, keybd);
- flags[XTestptr->id] |= XISlaveAttached;
- flags[XTestkeybd->id] |= XISlaveAttached;
-
-unwind:
- free(name);
- return rc;
-}
-
-static int
-remove_master(ClientPtr client, xXIRemoveMasterInfo *r,
- int flags[MAXDEVICES])
-{
- DeviceIntPtr ptr, keybd, XTestptr, XTestkeybd;
- int rc = Success;
-
- if (r->return_mode != XIAttachToMaster &&
- r->return_mode != XIFloating)
- return BadValue;
-
- rc = dixLookupDevice(&ptr, r->deviceid, client, DixDestroyAccess);
- if (rc != Success)
- goto unwind;
-
- if (!IsMaster(ptr))
- {
- client->errorValue = r->deviceid;
- rc = BadDevice;
- goto unwind;
- }
-
- /* XXX: For now, don't allow removal of VCP, VCK */
- if (ptr == inputInfo.pointer || ptr == inputInfo.keyboard)
- {
- rc = BadDevice;
- goto unwind;
- }
-
-
- ptr = GetMaster(ptr, MASTER_POINTER);
- rc = dixLookupDevice(&ptr, ptr->id, client, DixDestroyAccess);
- if (rc != Success)
- goto unwind;
- keybd = GetMaster(ptr, MASTER_KEYBOARD);
- rc = dixLookupDevice(&keybd, keybd->id, client, DixDestroyAccess);
- if (rc != Success)
- goto unwind;
-
- XTestptr = GetXTestDevice(ptr);
- rc = dixLookupDevice(&XTestptr, XTestptr->id, client, DixDestroyAccess);
- if (rc != Success)
- goto unwind;
-
- XTestkeybd = GetXTestDevice(keybd);
- rc = dixLookupDevice(&XTestkeybd, XTestkeybd->id, client,
- DixDestroyAccess);
- if (rc != Success)
- goto unwind;
-
- /* Disabling sends the devices floating, reattach them if
- * desired. */
- if (r->return_mode == XIAttachToMaster)
- {
- DeviceIntPtr attached,
- newptr,
- newkeybd;
-
- rc = dixLookupDevice(&newptr, r->return_pointer, client, DixAddAccess);
- if (rc != Success)
- goto unwind;
-
- if (!IsMaster(newptr))
- {
- client->errorValue = r->return_pointer;
- rc = BadDevice;
- goto unwind;
- }
-
- rc = dixLookupDevice(&newkeybd, r->return_keyboard,
- client, DixAddAccess);
- if (rc != Success)
- goto unwind;
-
- if (!IsMaster(newkeybd))
- {
- client->errorValue = r->return_keyboard;
- rc = BadDevice;
- goto unwind;
- }
-
- for (attached = inputInfo.devices; attached; attached = attached->next)
- {
- if (!IsMaster(attached)) {
- if (GetMaster(attached, MASTER_ATTACHED) == ptr)
- {
- AttachDevice(client, attached, newptr);
- flags[attached->id] |= XISlaveAttached;
- }
- if (GetMaster(attached, MASTER_ATTACHED) == keybd)
- {
- AttachDevice(client, attached, newkeybd);
- flags[attached->id] |= XISlaveAttached;
- }
- }
- }
- }
-
- /* can't disable until we removed pairing */
- keybd->spriteInfo->paired = NULL;
- ptr->spriteInfo->paired = NULL;
- XTestptr->spriteInfo->paired = NULL;
- XTestkeybd->spriteInfo->paired = NULL;
-
- /* disable the remove the devices, XTest devices must be done first
- else the sprites they rely on will be destroyed */
- DisableDevice(XTestptr, FALSE);
- DisableDevice(XTestkeybd, FALSE);
- DisableDevice(keybd, FALSE);
- DisableDevice(ptr, FALSE);
- flags[XTestptr->id] |= XIDeviceDisabled | XISlaveDetached;
- flags[XTestkeybd->id] |= XIDeviceDisabled | XISlaveDetached;
- flags[keybd->id] |= XIDeviceDisabled;
- flags[ptr->id] |= XIDeviceDisabled;
-
- RemoveDevice(XTestptr, FALSE);
- RemoveDevice(XTestkeybd, FALSE);
- RemoveDevice(keybd, FALSE);
- RemoveDevice(ptr, FALSE);
- flags[XTestptr->id] |= XISlaveRemoved;
- flags[XTestkeybd->id] |= XISlaveRemoved;
- flags[keybd->id] |= XIMasterRemoved;
- flags[ptr->id] |= XIMasterRemoved;
-
-unwind:
- return rc;
-}
-
-static int
-detach_slave(ClientPtr client, xXIDetachSlaveInfo *c, int flags[MAXDEVICES])
-{
- DeviceIntPtr dev;
- int rc;
-
- rc = dixLookupDevice(&dev, c->deviceid, client, DixManageAccess);
- if (rc != Success)
- goto unwind;
-
- if (IsMaster(dev))
- {
- client->errorValue = c->deviceid;
- rc = BadDevice;
- goto unwind;
- }
-
- /* Don't allow changes to XTest Devices, these are fixed */
- if (IsXTestDevice(dev, NULL))
- {
- client->errorValue = c->deviceid;
- rc = BadDevice;
- goto unwind;
- }
-
- ReleaseButtonsAndKeys(dev);
- AttachDevice(client, dev, NULL);
- flags[dev->id] |= XISlaveDetached;
-
-unwind:
- return rc;
-}
-
-static int
-attach_slave(ClientPtr client, xXIAttachSlaveInfo *c,
- int flags[MAXDEVICES])
-{
- DeviceIntPtr dev;
- DeviceIntPtr newmaster;
- int rc;
-
- rc = dixLookupDevice(&dev, c->deviceid, client, DixManageAccess);
- if (rc != Success)
- goto unwind;
-
- if (IsMaster(dev))
- {
- client->errorValue = c->deviceid;
- rc = BadDevice;
- goto unwind;
- }
-
- /* Don't allow changes to XTest Devices, these are fixed */
- if (IsXTestDevice(dev, NULL))
- {
- client->errorValue = c->deviceid;
- rc = BadDevice;
- goto unwind;
- }
-
- rc = dixLookupDevice(&newmaster, c->new_master, client, DixAddAccess);
- if (rc != Success)
- goto unwind;
- if (!IsMaster(newmaster))
- {
- client->errorValue = c->new_master;
- rc = BadDevice;
- goto unwind;
- }
-
- if (!((IsPointerDevice(newmaster) && IsPointerDevice(dev)) ||
- (IsKeyboardDevice(newmaster) && IsKeyboardDevice(dev))))
- {
- rc = BadDevice;
- goto unwind;
- }
-
- ReleaseButtonsAndKeys(dev);
- AttachDevice(client, dev, newmaster);
- flags[dev->id] |= XISlaveAttached;
-
-unwind:
- return rc;
-}
-
-
-
-#define SWAPIF(cmd) if (client->swapped) { cmd; }
-
-int
-ProcXIChangeHierarchy(ClientPtr client)
-{
- xXIAnyHierarchyChangeInfo *any;
- int required_len = sizeof(xXIChangeHierarchyReq);
- char n;
- int rc = Success;
- int flags[MAXDEVICES] = {0};
-
- REQUEST(xXIChangeHierarchyReq);
- REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq);
-
- if (!stuff->num_changes)
- return rc;
-
- any = (xXIAnyHierarchyChangeInfo*)&stuff[1];
- while(stuff->num_changes--)
- {
- SWAPIF(swapl(&any->type, n));
- SWAPIF(swaps(&any->length, n));
-
- required_len += any->length;
- if ((stuff->length * 4) < required_len)
- return BadLength;
-
- switch(any->type)
- {
- case XIAddMaster:
- {
- xXIAddMasterInfo* c = (xXIAddMasterInfo*)any;
- SWAPIF(swaps(&c->name_len, n));
-
- rc = add_master(client, c, flags);
- if (rc != Success)
- goto unwind;
- }
- break;
- case XIRemoveMaster:
- {
- xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)any;
-
- rc = remove_master(client, r, flags);
- if (rc != Success)
- goto unwind;
- }
- break;
- case XIDetachSlave:
- {
- xXIDetachSlaveInfo* c = (xXIDetachSlaveInfo*)any;
-
- rc = detach_slave(client, c, flags);
- if (rc != Success)
- goto unwind;
- }
- break;
- case XIAttachSlave:
- {
- xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)any;
-
- rc = attach_slave(client, c, flags);
- if (rc != Success)
- goto unwind;
- }
- break;
- }
-
- any = (xXIAnyHierarchyChangeInfo*)((char*)any + any->length * 4);
- }
-
-unwind:
-
- XISendDeviceHierarchyEvent(flags);
- return rc;
-}
-
+/* + * Copyright 2007-2008 Peter Hutterer + * Copyright 2009 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, University of South Australia, NICTA + */ + +/*********************************************************************** + * + * Request change in the device hierarchy. + * + */ + + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XI2proto.h> +#include <X11/extensions/geproto.h> +#include "extnsionst.h" +#include "exevents.h" +#include "exglobals.h" +#include "geext.h" +#include "xace.h" +#include "xiquerydevice.h" /* for GetDeviceUse */ + +#include "xkbsrv.h" + +#include "xichangehierarchy.h" + +/** + * Send the current state of the device hierarchy to all clients. + */ +void XISendDeviceHierarchyEvent(int flags[MAXDEVICES]) +{ + xXIHierarchyEvent *ev; + xXIHierarchyInfo *info; + DeviceIntRec dummyDev; + DeviceIntPtr dev; + int i; + + if (!flags) + return; + + ev = calloc(1, sizeof(xXIHierarchyEvent) + + MAXDEVICES * sizeof(xXIHierarchyInfo)); + if (!ev) + return; + ev->type = GenericEvent; + ev->extension = IReqCode; + ev->evtype = XI_HierarchyChanged; + ev->time = GetTimeInMillis(); + ev->flags = 0; + ev->num_info = inputInfo.numDevices; + + info = (xXIHierarchyInfo*)&ev[1]; + for (dev = inputInfo.devices; dev; dev = dev->next) + { + info->deviceid = dev->id; + info->enabled = dev->enabled; + info->use = GetDeviceUse(dev, &info->attachment); + info->flags = flags[dev->id]; + ev->flags |= info->flags; + info++; + } + for (dev = inputInfo.off_devices; dev; dev = dev->next) + { + info->deviceid = dev->id; + info->enabled = dev->enabled; + info->use = GetDeviceUse(dev, &info->attachment); + info->flags = flags[dev->id]; + ev->flags |= info->flags; + info++; + } + + + for (i = 0; i < MAXDEVICES; i++) + { + if (flags[i] & (XIMasterRemoved | XISlaveRemoved)) + { + info->deviceid = i; + info->enabled = FALSE; + info->flags = flags[i]; + info->use = 0; + ev->flags |= info->flags; + ev->num_info++; + info++; + } + } + + ev->length = bytes_to_int32(ev->num_info * sizeof(xXIHierarchyInfo)); + + memset(&dummyDev, 0, sizeof(dummyDev)); + dummyDev.id = XIAllDevices; + dummyDev.type = SLAVE; + SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1); + free(ev); +} + + +/*********************************************************************** + * + * This procedure allows a client to change the device hierarchy through + * adding new master devices, removing them, etc. + * + */ + +int SProcXIChangeHierarchy(ClientPtr client) +{ + char n; + + REQUEST(xXIChangeHierarchyReq); + swaps(&stuff->length, n); + return (ProcXIChangeHierarchy(client)); +} + +static int +add_master(ClientPtr client, xXIAddMasterInfo *c, int flags[MAXDEVICES]) +{ + DeviceIntPtr ptr, keybd, XTestptr, XTestkeybd; + char* name; + int rc; + + name = calloc(c->name_len + 1, sizeof(char)); + strncpy(name, (char*)&c[1], c->name_len); + + rc = AllocDevicePair(client, name, &ptr, &keybd, + CorePointerProc, CoreKeyboardProc, TRUE); + if (rc != Success) + goto unwind; + + if (!c->send_core) + ptr->coreEvents = keybd->coreEvents = FALSE; + + /* Allocate virtual slave devices for xtest events */ + rc = AllocXTestDevice(client, name, &XTestptr, &XTestkeybd, ptr, keybd); + if (rc != Success) + { + DeleteInputDeviceRequest(ptr); + DeleteInputDeviceRequest(keybd); + goto unwind; + } + + ActivateDevice(ptr, FALSE); + ActivateDevice(keybd, FALSE); + flags[ptr->id] |= XIMasterAdded; + flags[keybd->id] |= XIMasterAdded; + + ActivateDevice(XTestptr, FALSE); + ActivateDevice(XTestkeybd, FALSE); + flags[XTestptr->id] |= XISlaveAdded; + flags[XTestkeybd->id] |= XISlaveAdded; + + if (c->enable) + { + EnableDevice(ptr, FALSE); + EnableDevice(keybd, FALSE); + flags[ptr->id] |= XIDeviceEnabled; + flags[keybd->id] |= XIDeviceEnabled; + + EnableDevice(XTestptr, FALSE); + EnableDevice(XTestkeybd, FALSE); + flags[XTestptr->id] |= XIDeviceEnabled; + flags[XTestkeybd->id] |= XIDeviceEnabled; + } + + /* Attach the XTest virtual devices to the newly + created master device */ + AttachDevice(NULL, XTestptr, ptr); + AttachDevice(NULL, XTestkeybd, keybd); + flags[XTestptr->id] |= XISlaveAttached; + flags[XTestkeybd->id] |= XISlaveAttached; + +unwind: + free(name); + return rc; +} + +static int +remove_master(ClientPtr client, xXIRemoveMasterInfo *r, + int flags[MAXDEVICES]) +{ + DeviceIntPtr ptr, keybd, XTestptr, XTestkeybd; + int rc = Success; + + if (r->return_mode != XIAttachToMaster && + r->return_mode != XIFloating) + return BadValue; + + rc = dixLookupDevice(&ptr, r->deviceid, client, DixDestroyAccess); + if (rc != Success) + goto unwind; + + if (!IsMaster(ptr)) + { + client->errorValue = r->deviceid; + rc = BadDevice; + goto unwind; + } + + /* XXX: For now, don't allow removal of VCP, VCK */ + if (ptr == inputInfo.pointer || ptr == inputInfo.keyboard) + { + rc = BadDevice; + goto unwind; + } + + + ptr = GetMaster(ptr, MASTER_POINTER); + rc = dixLookupDevice(&ptr, ptr->id, client, DixDestroyAccess); + if (rc != Success) + goto unwind; + keybd = GetMaster(ptr, MASTER_KEYBOARD); + rc = dixLookupDevice(&keybd, keybd->id, client, DixDestroyAccess); + if (rc != Success) + goto unwind; + + XTestptr = GetXTestDevice(ptr); + rc = dixLookupDevice(&XTestptr, XTestptr->id, client, DixDestroyAccess); + if (rc != Success) + goto unwind; + + XTestkeybd = GetXTestDevice(keybd); + rc = dixLookupDevice(&XTestkeybd, XTestkeybd->id, client, + DixDestroyAccess); + if (rc != Success) + goto unwind; + + /* Disabling sends the devices floating, reattach them if + * desired. */ + if (r->return_mode == XIAttachToMaster) + { + DeviceIntPtr attached, + newptr, + newkeybd; + + rc = dixLookupDevice(&newptr, r->return_pointer, client, DixAddAccess); + if (rc != Success) + goto unwind; + + if (!IsMaster(newptr)) + { + client->errorValue = r->return_pointer; + rc = BadDevice; + goto unwind; + } + + rc = dixLookupDevice(&newkeybd, r->return_keyboard, + client, DixAddAccess); + if (rc != Success) + goto unwind; + + if (!IsMaster(newkeybd)) + { + client->errorValue = r->return_keyboard; + rc = BadDevice; + goto unwind; + } + + for (attached = inputInfo.devices; attached; attached = attached->next) + { + if (!IsMaster(attached)) { + if (GetMaster(attached, MASTER_ATTACHED) == ptr) + { + AttachDevice(client, attached, newptr); + flags[attached->id] |= XISlaveAttached; + } + if (GetMaster(attached, MASTER_ATTACHED) == keybd) + { + AttachDevice(client, attached, newkeybd); + flags[attached->id] |= XISlaveAttached; + } + } + } + } + + /* can't disable until we removed pairing */ + keybd->spriteInfo->paired = NULL; + ptr->spriteInfo->paired = NULL; + XTestptr->spriteInfo->paired = NULL; + XTestkeybd->spriteInfo->paired = NULL; + + /* disable the remove the devices, XTest devices must be done first + else the sprites they rely on will be destroyed */ + DisableDevice(XTestptr, FALSE); + DisableDevice(XTestkeybd, FALSE); + DisableDevice(keybd, FALSE); + DisableDevice(ptr, FALSE); + flags[XTestptr->id] |= XIDeviceDisabled | XISlaveDetached; + flags[XTestkeybd->id] |= XIDeviceDisabled | XISlaveDetached; + flags[keybd->id] |= XIDeviceDisabled; + flags[ptr->id] |= XIDeviceDisabled; + + RemoveDevice(XTestptr, FALSE); + RemoveDevice(XTestkeybd, FALSE); + RemoveDevice(keybd, FALSE); + RemoveDevice(ptr, FALSE); + flags[XTestptr->id] |= XISlaveRemoved; + flags[XTestkeybd->id] |= XISlaveRemoved; + flags[keybd->id] |= XIMasterRemoved; + flags[ptr->id] |= XIMasterRemoved; + +unwind: + return rc; +} + +static int +detach_slave(ClientPtr client, xXIDetachSlaveInfo *c, int flags[MAXDEVICES]) +{ + DeviceIntPtr dev; + int rc; + + rc = dixLookupDevice(&dev, c->deviceid, client, DixManageAccess); + if (rc != Success) + goto unwind; + + if (IsMaster(dev)) + { + client->errorValue = c->deviceid; + rc = BadDevice; + goto unwind; + } + + /* Don't allow changes to XTest Devices, these are fixed */ + if (IsXTestDevice(dev, NULL)) + { + client->errorValue = c->deviceid; + rc = BadDevice; + goto unwind; + } + + ReleaseButtonsAndKeys(dev); + AttachDevice(client, dev, NULL); + flags[dev->id] |= XISlaveDetached; + +unwind: + return rc; +} + +static int +attach_slave(ClientPtr client, xXIAttachSlaveInfo *c, + int flags[MAXDEVICES]) +{ + DeviceIntPtr dev; + DeviceIntPtr newmaster; + int rc; + + rc = dixLookupDevice(&dev, c->deviceid, client, DixManageAccess); + if (rc != Success) + goto unwind; + + if (IsMaster(dev)) + { + client->errorValue = c->deviceid; + rc = BadDevice; + goto unwind; + } + + /* Don't allow changes to XTest Devices, these are fixed */ + if (IsXTestDevice(dev, NULL)) + { + client->errorValue = c->deviceid; + rc = BadDevice; + goto unwind; + } + + rc = dixLookupDevice(&newmaster, c->new_master, client, DixAddAccess); + if (rc != Success) + goto unwind; + if (!IsMaster(newmaster)) + { + client->errorValue = c->new_master; + rc = BadDevice; + goto unwind; + } + + if (!((IsPointerDevice(newmaster) && IsPointerDevice(dev)) || + (IsKeyboardDevice(newmaster) && IsKeyboardDevice(dev)))) + { + rc = BadDevice; + goto unwind; + } + + ReleaseButtonsAndKeys(dev); + AttachDevice(client, dev, newmaster); + flags[dev->id] |= XISlaveAttached; + +unwind: + return rc; +} + + + +#define SWAPIF(cmd) if (client->swapped) { cmd; } + +int +ProcXIChangeHierarchy(ClientPtr client) +{ + xXIAnyHierarchyChangeInfo *any; + int required_len = sizeof(xXIChangeHierarchyReq); + char n; + int rc = Success; + int flags[MAXDEVICES] = {0}; + + REQUEST(xXIChangeHierarchyReq); + REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq); + + if (!stuff->num_changes) + return rc; + + any = (xXIAnyHierarchyChangeInfo*)&stuff[1]; + while(stuff->num_changes--) + { + SWAPIF(swapl(&any->type, n)); + SWAPIF(swaps(&any->length, n)); + + required_len += any->length; + if ((stuff->length * 4) < required_len) + return BadLength; + + switch(any->type) + { + case XIAddMaster: + { + xXIAddMasterInfo* c = (xXIAddMasterInfo*)any; + SWAPIF(swaps(&c->name_len, n)); + + rc = add_master(client, c, flags); + if (rc != Success) + goto unwind; + } + break; + case XIRemoveMaster: + { + xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)any; + + rc = remove_master(client, r, flags); + if (rc != Success) + goto unwind; + } + break; + case XIDetachSlave: + { + xXIDetachSlaveInfo* c = (xXIDetachSlaveInfo*)any; + + rc = detach_slave(client, c, flags); + if (rc != Success) + goto unwind; + } + break; + case XIAttachSlave: + { + xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)any; + + rc = attach_slave(client, c, flags); + if (rc != Success) + goto unwind; + } + break; + } + + any = (xXIAnyHierarchyChangeInfo*)((char*)any + any->length * 4); + } + +unwind: + + XISendDeviceHierarchyEvent(flags); + return rc; +} + diff --git a/xorg-server/Xi/xipassivegrab.c b/xorg-server/Xi/xipassivegrab.c index fe8c3944a..ae4343344 100644 --- a/xorg-server/Xi/xipassivegrab.c +++ b/xorg-server/Xi/xipassivegrab.c @@ -1,315 +1,315 @@ -/*
- * Copyright © 2009 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
- */
-
-/***********************************************************************
- *
- * Request to grab or ungrab input device.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "inputstr.h" /* DeviceIntPtr */
-#include "windowstr.h" /* window structure */
-#include <X11/extensions/XI2.h>
-#include <X11/extensions/XI2proto.h>
-#include "swaprep.h"
-
-#include "exglobals.h" /* BadDevice */
-#include "exevents.h"
-#include "xipassivegrab.h"
-#include "dixgrabs.h"
-#include "misc.h"
-
-int
-SProcXIPassiveGrabDevice(ClientPtr client)
-{
- int i;
- char n;
- xXIModifierInfo *mods;
-
- REQUEST(xXIPassiveGrabDeviceReq);
-
- swaps(&stuff->length, n);
- swaps(&stuff->deviceid, n);
- swapl(&stuff->grab_window, n);
- swapl(&stuff->cursor, n);
- swapl(&stuff->time, n);
- swapl(&stuff->detail, n);
- swaps(&stuff->mask_len, n);
- swaps(&stuff->num_modifiers, n);
-
- mods = (xXIModifierInfo*)&stuff[1];
-
- for (i = 0; i < stuff->num_modifiers; i++, mods++)
- {
- swapl(&mods->base_mods, n);
- swapl(&mods->latched_mods, n);
- swapl(&mods->locked_mods, n);
- }
-
- return ProcXIPassiveGrabDevice(client);
-}
-
-int
-ProcXIPassiveGrabDevice(ClientPtr client)
-{
- DeviceIntPtr dev, mod_dev;
- xXIPassiveGrabDeviceReply rep;
- int i, ret = Success;
- uint8_t status;
- uint32_t *modifiers;
- xXIGrabModifierInfo *modifiers_failed;
- GrabMask mask;
- GrabParameters param;
- void *tmp;
- int mask_len;
- int n;
-
- REQUEST(xXIPassiveGrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
-
- if (stuff->deviceid == XIAllDevices)
- dev = inputInfo.all_devices;
- else if (stuff->deviceid == XIAllMasterDevices)
- dev = inputInfo.all_master_devices;
- else
- {
- ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
- if (ret != Success)
- {
- client->errorValue = stuff->deviceid;
- return ret;
- }
- }
-
- if (stuff->grab_type != XIGrabtypeButton &&
- stuff->grab_type != XIGrabtypeKeycode &&
- stuff->grab_type != XIGrabtypeEnter &&
- stuff->grab_type != XIGrabtypeFocusIn)
- {
- client->errorValue = stuff->grab_type;
- return BadValue;
- }
-
- if ((stuff->grab_type == XIGrabtypeEnter ||
- stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
- {
- client->errorValue = stuff->detail;
- return BadValue;
- }
-
- if (XICheckInvalidMaskBits(client, (unsigned char*)&stuff[1],
- stuff->mask_len * 4) != Success)
- return BadValue;
-
- mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
- memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
- memcpy(mask.xi2mask[stuff->deviceid], &stuff[1], mask_len * 4);
-
- rep.repType = X_Reply;
- rep.RepType = X_XIPassiveGrabDevice;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.num_modifiers = 0;
-
- memset(¶m, 0, sizeof(param));
- param.grabtype = GRABTYPE_XI2;
- param.ownerEvents = stuff->owner_events;
- param.this_device_mode = stuff->grab_mode;
- param.other_devices_mode = stuff->paired_device_mode;
- param.grabWindow = stuff->grab_window;
- param.cursor = stuff->cursor;
-
- if (stuff->cursor != None)
- {
- status = dixLookupResourceByType(&tmp, stuff->cursor,
- RT_CURSOR, client, DixUseAccess);
- if (status != Success)
- {
- client->errorValue = stuff->cursor;
- return status;
- }
- }
-
- status = dixLookupWindow((WindowPtr*)&tmp, stuff->grab_window, client, DixSetAttrAccess);
- if (status != Success)
- return status;
-
- status = CheckGrabValues(client, ¶m);
- if (status != Success)
- return status;
-
- modifiers = (uint32_t*)&stuff[1] + stuff->mask_len;
- modifiers_failed = calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
- if (!modifiers_failed)
- return BadAlloc;
-
- mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
-
- for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
- {
- param.modifiers = *modifiers;
- switch(stuff->grab_type)
- {
- case XIGrabtypeButton:
- status = GrabButton(client, dev, mod_dev, stuff->detail,
- ¶m, GRABTYPE_XI2, &mask);
- break;
- case XIGrabtypeKeycode:
- status = GrabKey(client, dev, mod_dev, stuff->detail,
- ¶m, GRABTYPE_XI2, &mask);
- break;
- case XIGrabtypeEnter:
- case XIGrabtypeFocusIn:
- status = GrabWindow(client, dev, stuff->grab_type,
- ¶m, &mask);
- break;
- }
-
- if (status != GrabSuccess)
- {
- xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
-
- info->status = status;
- info->modifiers = *modifiers;
- if (client->swapped)
- swapl(&info->modifiers, n);
-
- rep.num_modifiers++;
- rep.length += bytes_to_int32(sizeof(xXIGrabModifierInfo));
- }
- }
-
- WriteReplyToClient(client, sizeof(rep), &rep);
- if (rep.num_modifiers)
- WriteToClient(client, rep.length * 4, (char*)modifiers_failed);
-
- free(modifiers_failed);
- return ret;
-}
-
-void
-SRepXIPassiveGrabDevice(ClientPtr client, int size,
- xXIPassiveGrabDeviceReply * rep)
-{
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->num_modifiers, n);
-
- WriteToClient(client, size, (char *)rep);
-}
-
-int
-SProcXIPassiveUngrabDevice(ClientPtr client)
-{
- char n;
- int i;
- uint32_t *modifiers;
-
- REQUEST(xXIPassiveUngrabDeviceReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->grab_window, n);
- swaps(&stuff->deviceid, n);
- swapl(&stuff->detail, n);
- swaps(&stuff->num_modifiers, n);
-
- modifiers = (uint32_t*)&stuff[1];
-
- for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
- swapl(modifiers, n);
-
- return ProcXIPassiveUngrabDevice(client);
-}
-
-int
-ProcXIPassiveUngrabDevice(ClientPtr client)
-{
- DeviceIntPtr dev, mod_dev;
- WindowPtr win;
- GrabRec tempGrab;
- uint32_t* modifiers;
- int i, rc;
-
- REQUEST(xXIPassiveUngrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
-
- rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
- if (rc != Success)
- return rc;
-
- if (stuff->grab_type != XIGrabtypeButton &&
- stuff->grab_type != XIGrabtypeKeycode &&
- stuff->grab_type != XIGrabtypeEnter &&
- stuff->grab_type != XIGrabtypeFocusIn)
- {
- client->errorValue = stuff->grab_type;
- return BadValue;
- }
-
- if ((stuff->grab_type == XIGrabtypeEnter ||
- stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
- {
- client->errorValue = stuff->detail;
- return BadValue;
- }
-
- rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
- if (rc != Success)
- return rc;
-
- mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
-
- tempGrab.resource = client->clientAsMask;
- tempGrab.device = dev;
- tempGrab.window = win;
- switch(stuff->grab_type)
- {
- case XIGrabtypeButton: tempGrab.type = XI_ButtonPress; break;
- case XIGrabtypeKeycode: tempGrab.type = XI_KeyPress; break;
- case XIGrabtypeEnter: tempGrab.type = XI_Enter; break;
- case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn; break;
- }
- tempGrab.grabtype = GRABTYPE_XI2;
- tempGrab.modifierDevice = mod_dev;
- tempGrab.modifiersDetail.pMask = NULL;
- tempGrab.detail.exact = stuff->detail;
- tempGrab.detail.pMask = NULL;
-
- modifiers = (uint32_t*)&stuff[1];
-
- for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
- {
- tempGrab.modifiersDetail.exact = *modifiers;
- DeletePassiveGrabFromList(&tempGrab);
- }
-
- return Success;
-}
+/* + * Copyright © 2009 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 + */ + +/*********************************************************************** + * + * Request to grab or ungrab input device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include <X11/extensions/XI2.h> +#include <X11/extensions/XI2proto.h> +#include "swaprep.h" + +#include "exglobals.h" /* BadDevice */ +#include "exevents.h" +#include "xipassivegrab.h" +#include "dixgrabs.h" +#include "misc.h" + +int +SProcXIPassiveGrabDevice(ClientPtr client) +{ + int i; + char n; + xXIModifierInfo *mods; + + REQUEST(xXIPassiveGrabDeviceReq); + + swaps(&stuff->length, n); + swaps(&stuff->deviceid, n); + swapl(&stuff->grab_window, n); + swapl(&stuff->cursor, n); + swapl(&stuff->time, n); + swapl(&stuff->detail, n); + swaps(&stuff->mask_len, n); + swaps(&stuff->num_modifiers, n); + + mods = (xXIModifierInfo*)&stuff[1]; + + for (i = 0; i < stuff->num_modifiers; i++, mods++) + { + swapl(&mods->base_mods, n); + swapl(&mods->latched_mods, n); + swapl(&mods->locked_mods, n); + } + + return ProcXIPassiveGrabDevice(client); +} + +int +ProcXIPassiveGrabDevice(ClientPtr client) +{ + DeviceIntPtr dev, mod_dev; + xXIPassiveGrabDeviceReply rep; + int i, ret = Success; + uint8_t status; + uint32_t *modifiers; + xXIGrabModifierInfo *modifiers_failed; + GrabMask mask; + GrabParameters param; + void *tmp; + int mask_len; + int n; + + REQUEST(xXIPassiveGrabDeviceReq); + REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq); + + if (stuff->deviceid == XIAllDevices) + dev = inputInfo.all_devices; + else if (stuff->deviceid == XIAllMasterDevices) + dev = inputInfo.all_master_devices; + else + { + ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); + if (ret != Success) + { + client->errorValue = stuff->deviceid; + return ret; + } + } + + if (stuff->grab_type != XIGrabtypeButton && + stuff->grab_type != XIGrabtypeKeycode && + stuff->grab_type != XIGrabtypeEnter && + stuff->grab_type != XIGrabtypeFocusIn) + { + client->errorValue = stuff->grab_type; + return BadValue; + } + + if ((stuff->grab_type == XIGrabtypeEnter || + stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0) + { + client->errorValue = stuff->detail; + return BadValue; + } + + if (XICheckInvalidMaskBits(client, (unsigned char*)&stuff[1], + stuff->mask_len * 4) != Success) + return BadValue; + + mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4); + memset(mask.xi2mask, 0, sizeof(mask.xi2mask)); + memcpy(mask.xi2mask[stuff->deviceid], &stuff[1], mask_len * 4); + + rep.repType = X_Reply; + rep.RepType = X_XIPassiveGrabDevice; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.num_modifiers = 0; + + memset(¶m, 0, sizeof(param)); + param.grabtype = GRABTYPE_XI2; + param.ownerEvents = stuff->owner_events; + param.this_device_mode = stuff->grab_mode; + param.other_devices_mode = stuff->paired_device_mode; + param.grabWindow = stuff->grab_window; + param.cursor = stuff->cursor; + + if (stuff->cursor != None) + { + status = dixLookupResourceByType(&tmp, stuff->cursor, + RT_CURSOR, client, DixUseAccess); + if (status != Success) + { + client->errorValue = stuff->cursor; + return status; + } + } + + status = dixLookupWindow((WindowPtr*)&tmp, stuff->grab_window, client, DixSetAttrAccess); + if (status != Success) + return status; + + status = CheckGrabValues(client, ¶m); + if (status != Success) + return status; + + modifiers = (uint32_t*)&stuff[1] + stuff->mask_len; + modifiers_failed = calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo)); + if (!modifiers_failed) + return BadAlloc; + + mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD); + + for (i = 0; i < stuff->num_modifiers; i++, modifiers++) + { + param.modifiers = *modifiers; + switch(stuff->grab_type) + { + case XIGrabtypeButton: + status = GrabButton(client, dev, mod_dev, stuff->detail, + ¶m, GRABTYPE_XI2, &mask); + break; + case XIGrabtypeKeycode: + status = GrabKey(client, dev, mod_dev, stuff->detail, + ¶m, GRABTYPE_XI2, &mask); + break; + case XIGrabtypeEnter: + case XIGrabtypeFocusIn: + status = GrabWindow(client, dev, stuff->grab_type, + ¶m, &mask); + break; + } + + if (status != GrabSuccess) + { + xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers; + + info->status = status; + info->modifiers = *modifiers; + if (client->swapped) + swapl(&info->modifiers, n); + + rep.num_modifiers++; + rep.length += bytes_to_int32(sizeof(xXIGrabModifierInfo)); + } + } + + WriteReplyToClient(client, sizeof(rep), &rep); + if (rep.num_modifiers) + WriteToClient(client, rep.length * 4, (char*)modifiers_failed); + + free(modifiers_failed); + return ret; +} + +void +SRepXIPassiveGrabDevice(ClientPtr client, int size, + xXIPassiveGrabDeviceReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_modifiers, n); + + WriteToClient(client, size, (char *)rep); +} + +int +SProcXIPassiveUngrabDevice(ClientPtr client) +{ + char n; + int i; + uint32_t *modifiers; + + REQUEST(xXIPassiveUngrabDeviceReq); + + swaps(&stuff->length, n); + swapl(&stuff->grab_window, n); + swaps(&stuff->deviceid, n); + swapl(&stuff->detail, n); + swaps(&stuff->num_modifiers, n); + + modifiers = (uint32_t*)&stuff[1]; + + for (i = 0; i < stuff->num_modifiers; i++, modifiers++) + swapl(modifiers, n); + + return ProcXIPassiveUngrabDevice(client); +} + +int +ProcXIPassiveUngrabDevice(ClientPtr client) +{ + DeviceIntPtr dev, mod_dev; + WindowPtr win; + GrabRec tempGrab; + uint32_t* modifiers; + int i, rc; + + REQUEST(xXIPassiveUngrabDeviceReq); + REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq); + + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); + if (rc != Success) + return rc; + + if (stuff->grab_type != XIGrabtypeButton && + stuff->grab_type != XIGrabtypeKeycode && + stuff->grab_type != XIGrabtypeEnter && + stuff->grab_type != XIGrabtypeFocusIn) + { + client->errorValue = stuff->grab_type; + return BadValue; + } + + if ((stuff->grab_type == XIGrabtypeEnter || + stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0) + { + client->errorValue = stuff->detail; + return BadValue; + } + + rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess); + if (rc != Success) + return rc; + + mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD); + + tempGrab.resource = client->clientAsMask; + tempGrab.device = dev; + tempGrab.window = win; + switch(stuff->grab_type) + { + case XIGrabtypeButton: tempGrab.type = XI_ButtonPress; break; + case XIGrabtypeKeycode: tempGrab.type = XI_KeyPress; break; + case XIGrabtypeEnter: tempGrab.type = XI_Enter; break; + case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn; break; + } + tempGrab.grabtype = GRABTYPE_XI2; + tempGrab.modifierDevice = mod_dev; + tempGrab.modifiersDetail.pMask = NULL; + tempGrab.detail.exact = stuff->detail; + tempGrab.detail.pMask = NULL; + + modifiers = (uint32_t*)&stuff[1]; + + for (i = 0; i < stuff->num_modifiers; i++, modifiers++) + { + tempGrab.modifiersDetail.exact = *modifiers; + DeletePassiveGrabFromList(&tempGrab); + } + + return Success; +} diff --git a/xorg-server/Xi/xiquerydevice.c b/xorg-server/Xi/xiquerydevice.c index 7066a1ab9..a768d499c 100644 --- a/xorg-server/Xi/xiquerydevice.c +++ b/xorg-server/Xi/xiquerydevice.c @@ -1,506 +1,506 @@ -/*
- * Copyright © 2009 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.
- *
- * Authors: Peter Hutterer
- *
- */
-
-/**
- * @file Protocol handling for the XIQueryDevice request/reply.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "inputstr.h"
-#include <X11/X.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/XI2proto.h>
-#include "xkbstr.h"
-#include "xkbsrv.h"
-#include "xserver-properties.h"
-#include "exevents.h"
-#include "xace.h"
-
-#include "xiquerydevice.h"
-
-static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d);
-static int
-ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info);
-static int SizeDeviceInfo(DeviceIntPtr dev);
-static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info);
-int
-SProcXIQueryDevice(ClientPtr client)
-{
- char n;
-
- REQUEST(xXIQueryDeviceReq);
-
- swaps(&stuff->length, n);
- swaps(&stuff->deviceid, n);
-
- return ProcXIQueryDevice(client);
-}
-
-int
-ProcXIQueryDevice(ClientPtr client)
-{
- xXIQueryDeviceReply rep;
- DeviceIntPtr dev = NULL;
- int rc = Success;
- int i = 0, len = 0;
- char *info, *ptr;
- Bool *skip = NULL;
-
- REQUEST(xXIQueryDeviceReq);
- REQUEST_SIZE_MATCH(xXIQueryDeviceReq);
-
- if (stuff->deviceid != XIAllDevices && stuff->deviceid != XIAllMasterDevices)
- {
- rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->deviceid;
- return rc;
- }
- len += SizeDeviceInfo(dev);
- }
- else
- {
- skip = calloc(sizeof(Bool), inputInfo.numDevices);
- if (!skip)
- return BadAlloc;
-
- for (dev = inputInfo.devices; dev; dev = dev->next, i++)
- {
- skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev);
- if (!skip[i])
- len += SizeDeviceInfo(dev);
- }
-
- for (dev = inputInfo.off_devices; dev; dev = dev->next, i++)
- {
- skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev);
- if (!skip[i])
- len += SizeDeviceInfo(dev);
- }
- }
-
- info = calloc(1, len);
- if (!info) {
- free(skip);
- return BadAlloc;
- }
-
- memset(&rep, 0, sizeof(xXIQueryDeviceReply));
- rep.repType = X_Reply;
- rep.RepType = X_XIQueryDevice;
- rep.sequenceNumber = client->sequence;
- rep.length = len/4;
- rep.num_devices = 0;
-
- ptr = info;
- if (dev)
- {
- len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
- if (client->swapped)
- SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
- info += len;
- rep.num_devices = 1;
- } else
- {
- i = 0;
- for (dev = inputInfo.devices; dev; dev = dev->next, i++)
- {
- if (!skip[i])
- {
- len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
- if (client->swapped)
- SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
- info += len;
- rep.num_devices++;
- }
- }
-
- for (dev = inputInfo.off_devices; dev; dev = dev->next, i++)
- {
- if (!skip[i])
- {
- len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
- if (client->swapped)
- SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
- info += len;
- rep.num_devices++;
- }
- }
- }
-
- len = rep.length * 4;
- WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep);
- WriteToClient(client, len, ptr);
- free(ptr);
- free(skip);
- return rc;
-}
-
-void
-SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep)
-{
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->num_devices, n);
-
- /* Device info is already swapped, see ProcXIQueryDevice */
-
- WriteToClient(client, size, (char *)rep);
-}
-
-
-/**
- * @return Whether the device should be included in the returned list.
- */
-static Bool
-ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr dev)
-{
- /* if all devices are not being queried, only master devices are */
- if (deviceid == XIAllDevices || IsMaster(dev))
- {
- int rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess);
- if (rc == Success)
- return FALSE;
- }
- return TRUE;
-}
-
-/**
- * @return The number of bytes needed to store this device's xXIDeviceInfo
- * (and its classes).
- */
-static int
-SizeDeviceInfo(DeviceIntPtr dev)
-{
- int len = sizeof(xXIDeviceInfo);
-
- /* 4-padded name */
- len += pad_to_int32(strlen(dev->name));
-
- return len + SizeDeviceClasses(dev);
-
-}
-
-/*
- * @return The number of bytes needed to store this device's classes.
- */
-int
-SizeDeviceClasses(DeviceIntPtr dev)
-{
- int len = 0;
-
- if (dev->button)
- {
- len += sizeof(xXIButtonInfo);
- len += dev->button->numButtons * sizeof(Atom);
- len += pad_to_int32(bits_to_bytes(dev->button->numButtons));
- }
-
- if (dev->key)
- {
- XkbDescPtr xkb = dev->key->xkbInfo->desc;
- len += sizeof(xXIKeyInfo);
- len += (xkb->max_key_code - xkb->min_key_code + 1) * sizeof(uint32_t);
- }
-
- if (dev->valuator)
- len += sizeof(xXIValuatorInfo) * dev->valuator->numAxes;
-
- return len;
-}
-
-
-/**
- * Write button information into info.
- * @return Number of bytes written into info.
- */
-int
-ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info, Bool reportState)
-{
- unsigned char *bits;
- int mask_len;
- int i;
-
- if (!dev || !dev->button)
- return 0;
-
- mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons));
-
- info->type = ButtonClass;
- info->num_buttons = dev->button->numButtons;
- info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
- info->num_buttons + mask_len;
- info->sourceid = dev->button->sourceid;
-
- bits = (unsigned char*)&info[1];
- memset(bits, 0, mask_len * 4);
-
- if (reportState)
- for (i = 0; i < dev->button->numButtons; i++)
- if (BitIsOn(dev->button->down, i))
- SetBit(bits, i);
-
- bits += mask_len * 4;
- memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom));
-
- return info->length * 4;
-}
-
-static void
-SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
-{
- char n;
- Atom *btn;
- int i;
- swaps(&info->type, n);
- swaps(&info->length, n);
- swaps(&info->sourceid, n);
-
- for (i = 0, btn = (Atom*)&info[1]; i < info->num_buttons; i++, btn++)
- swaps(btn, n);
-
- swaps(&info->num_buttons, n);
-}
-
-/**
- * Write key information into info.
- * @return Number of bytes written into info.
- */
-int
-ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
-{
- int i;
- XkbDescPtr xkb = dev->key->xkbInfo->desc;
- uint32_t *kc;
-
- info->type = KeyClass;
- info->num_keycodes = xkb->max_key_code - xkb->min_key_code + 1;
- info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
- info->sourceid = dev->key->sourceid;
-
- kc = (uint32_t*)&info[1];
- for (i = xkb->min_key_code; i <= xkb->max_key_code; i++, kc++)
- *kc = i;
-
- return info->length * 4;
-}
-
-static void
-SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
-{
- char n;
- uint32_t *key;
- int i;
- swaps(&info->type, n);
- swaps(&info->length, n);
- swaps(&info->sourceid, n);
-
- for (i = 0, key = (uint32_t*)&info[1]; i < info->num_keycodes; i++, key++)
- swapl(key, n);
-
- swaps(&info->num_keycodes, n);
-}
-
-/**
- * List axis information for the given axis.
- *
- * @return The number of bytes written into info.
- */
-int
-ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber,
- Bool reportState)
-{
- ValuatorClassPtr v = dev->valuator;
-
- info->type = ValuatorClass;
- info->length = sizeof(xXIValuatorInfo)/4;
- info->label = v->axes[axisnumber].label;
- info->min.integral = v->axes[axisnumber].min_value;
- info->min.frac = 0;
- info->max.integral = v->axes[axisnumber].max_value;
- info->max.frac = 0;
- info->value.integral = (int)v->axisVal[axisnumber];
- info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16));
- info->resolution = v->axes[axisnumber].resolution;
- info->number = axisnumber;
- info->mode = valuator_get_mode(dev, axisnumber);
- info->sourceid = v->sourceid;
-
- if (!reportState)
- info->value = info->min;
-
- return info->length * 4;
-}
-
-static void
-SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info)
-{
- char n;
- swaps(&info->type, n);
- swaps(&info->length, n);
- swapl(&info->label, n);
- swapl(&info->min.integral, n);
- swapl(&info->min.frac, n);
- swapl(&info->max.integral, n);
- swapl(&info->max.frac, n);
- swaps(&info->number, n);
- swaps(&info->sourceid, n);
-}
-
-int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment)
-{
- DeviceIntPtr master = GetMaster(dev, MASTER_ATTACHED);
- int use;
-
- if (IsMaster(dev))
- {
- DeviceIntPtr paired = GetPairedDevice(dev);
- use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard;
- *attachment = (paired ? paired->id : 0);
- } else if (!IsFloating(dev))
- {
- use = IsPointerDevice(master) ? XISlavePointer : XISlaveKeyboard;
- *attachment = master->id;
- } else
- use = XIFloatingSlave;
-
- return use;
-}
-
-/**
- * Write the info for device dev into the buffer pointed to by info.
- *
- * @return The number of bytes used.
- */
-static int
-ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info)
-{
- char *any = (char*)&info[1];
- int len = 0, total_len = 0;
-
- info->deviceid = dev->id;
- info->use = GetDeviceUse(dev, &info->attachment);
- info->num_classes = 0;
- info->name_len = strlen(dev->name);
- info->enabled = dev->enabled;
- total_len = sizeof(xXIDeviceInfo);
-
- len = pad_to_int32(info->name_len);
- memset(any, 0, len);
- strncpy(any, dev->name, info->name_len);
- any += len;
- total_len += len;
-
- total_len += ListDeviceClasses(client, dev, any, &info->num_classes);
- return total_len;
-}
-
-/**
- * Write the class info of the device into the memory pointed to by any, set
- * nclasses to the number of classes in total and return the number of bytes
- * written.
- */
-int
-ListDeviceClasses(ClientPtr client, DeviceIntPtr dev,
- char *any, uint16_t *nclasses)
-{
- int total_len = 0;
- int len;
- int i;
- int rc;
-
- /* Check if the current device state should be suppressed */
- rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess);
-
- if (dev->button)
- {
- (*nclasses)++;
- len = ListButtonInfo(dev, (xXIButtonInfo*)any, rc == Success);
- any += len;
- total_len += len;
- }
-
- if (dev->key)
- {
- (*nclasses)++;
- len = ListKeyInfo(dev, (xXIKeyInfo*)any);
- any += len;
- total_len += len;
- }
-
- for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++)
- {
- (*nclasses)++;
- len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i, rc == Success);
- any += len;
- total_len += len;
- }
-
- return total_len;
-}
-
-static void
-SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
-{
- char n;
- char *any = (char*)&info[1];
- int i;
-
- /* Skip over name */
- any += pad_to_int32(info->name_len);
-
- for (i = 0; i < info->num_classes; i++)
- {
- int len = ((xXIAnyInfo*)any)->length;
- switch(((xXIAnyInfo*)any)->type)
- {
- case XIButtonClass:
- SwapButtonInfo(dev, (xXIButtonInfo*)any);
- break;
- case XIKeyClass:
- SwapKeyInfo(dev, (xXIKeyInfo*)any);
- break;
- case XIValuatorClass:
- SwapValuatorInfo(dev, (xXIValuatorInfo*)any);
- break;
- }
-
- any += len * 4;
- }
-
- swaps(&info->deviceid, n);
- swaps(&info->use, n);
- swaps(&info->attachment, n);
- swaps(&info->num_classes, n);
- swaps(&info->name_len, n);
-
-}
+/* + * Copyright © 2009 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. + * + * Authors: Peter Hutterer + * + */ + +/** + * @file Protocol handling for the XIQueryDevice request/reply. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "inputstr.h" +#include <X11/X.h> +#include <X11/Xatom.h> +#include <X11/extensions/XI2proto.h> +#include "xkbstr.h" +#include "xkbsrv.h" +#include "xserver-properties.h" +#include "exevents.h" +#include "xace.h" + +#include "xiquerydevice.h" + +static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d); +static int +ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info); +static int SizeDeviceInfo(DeviceIntPtr dev); +static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info); +int +SProcXIQueryDevice(ClientPtr client) +{ + char n; + + REQUEST(xXIQueryDeviceReq); + + swaps(&stuff->length, n); + swaps(&stuff->deviceid, n); + + return ProcXIQueryDevice(client); +} + +int +ProcXIQueryDevice(ClientPtr client) +{ + xXIQueryDeviceReply rep; + DeviceIntPtr dev = NULL; + int rc = Success; + int i = 0, len = 0; + char *info, *ptr; + Bool *skip = NULL; + + REQUEST(xXIQueryDeviceReq); + REQUEST_SIZE_MATCH(xXIQueryDeviceReq); + + if (stuff->deviceid != XIAllDevices && stuff->deviceid != XIAllMasterDevices) + { + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->deviceid; + return rc; + } + len += SizeDeviceInfo(dev); + } + else + { + skip = calloc(sizeof(Bool), inputInfo.numDevices); + if (!skip) + return BadAlloc; + + for (dev = inputInfo.devices; dev; dev = dev->next, i++) + { + skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); + if (!skip[i]) + len += SizeDeviceInfo(dev); + } + + for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) + { + skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); + if (!skip[i]) + len += SizeDeviceInfo(dev); + } + } + + info = calloc(1, len); + if (!info) { + free(skip); + return BadAlloc; + } + + memset(&rep, 0, sizeof(xXIQueryDeviceReply)); + rep.repType = X_Reply; + rep.RepType = X_XIQueryDevice; + rep.sequenceNumber = client->sequence; + rep.length = len/4; + rep.num_devices = 0; + + ptr = info; + if (dev) + { + len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info); + if (client->swapped) + SwapDeviceInfo(dev, (xXIDeviceInfo*)info); + info += len; + rep.num_devices = 1; + } else + { + i = 0; + for (dev = inputInfo.devices; dev; dev = dev->next, i++) + { + if (!skip[i]) + { + len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info); + if (client->swapped) + SwapDeviceInfo(dev, (xXIDeviceInfo*)info); + info += len; + rep.num_devices++; + } + } + + for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) + { + if (!skip[i]) + { + len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info); + if (client->swapped) + SwapDeviceInfo(dev, (xXIDeviceInfo*)info); + info += len; + rep.num_devices++; + } + } + } + + len = rep.length * 4; + WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep); + WriteToClient(client, len, ptr); + free(ptr); + free(skip); + return rc; +} + +void +SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_devices, n); + + /* Device info is already swapped, see ProcXIQueryDevice */ + + WriteToClient(client, size, (char *)rep); +} + + +/** + * @return Whether the device should be included in the returned list. + */ +static Bool +ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr dev) +{ + /* if all devices are not being queried, only master devices are */ + if (deviceid == XIAllDevices || IsMaster(dev)) + { + int rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); + if (rc == Success) + return FALSE; + } + return TRUE; +} + +/** + * @return The number of bytes needed to store this device's xXIDeviceInfo + * (and its classes). + */ +static int +SizeDeviceInfo(DeviceIntPtr dev) +{ + int len = sizeof(xXIDeviceInfo); + + /* 4-padded name */ + len += pad_to_int32(strlen(dev->name)); + + return len + SizeDeviceClasses(dev); + +} + +/* + * @return The number of bytes needed to store this device's classes. + */ +int +SizeDeviceClasses(DeviceIntPtr dev) +{ + int len = 0; + + if (dev->button) + { + len += sizeof(xXIButtonInfo); + len += dev->button->numButtons * sizeof(Atom); + len += pad_to_int32(bits_to_bytes(dev->button->numButtons)); + } + + if (dev->key) + { + XkbDescPtr xkb = dev->key->xkbInfo->desc; + len += sizeof(xXIKeyInfo); + len += (xkb->max_key_code - xkb->min_key_code + 1) * sizeof(uint32_t); + } + + if (dev->valuator) + len += sizeof(xXIValuatorInfo) * dev->valuator->numAxes; + + return len; +} + + +/** + * Write button information into info. + * @return Number of bytes written into info. + */ +int +ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info, Bool reportState) +{ + unsigned char *bits; + int mask_len; + int i; + + if (!dev || !dev->button) + return 0; + + mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons)); + + info->type = ButtonClass; + info->num_buttons = dev->button->numButtons; + info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + + info->num_buttons + mask_len; + info->sourceid = dev->button->sourceid; + + bits = (unsigned char*)&info[1]; + memset(bits, 0, mask_len * 4); + + if (reportState) + for (i = 0; i < dev->button->numButtons; i++) + if (BitIsOn(dev->button->down, i)) + SetBit(bits, i); + + bits += mask_len * 4; + memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom)); + + return info->length * 4; +} + +static void +SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info) +{ + char n; + Atom *btn; + int i; + swaps(&info->type, n); + swaps(&info->length, n); + swaps(&info->sourceid, n); + + for (i = 0, btn = (Atom*)&info[1]; i < info->num_buttons; i++, btn++) + swaps(btn, n); + + swaps(&info->num_buttons, n); +} + +/** + * Write key information into info. + * @return Number of bytes written into info. + */ +int +ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info) +{ + int i; + XkbDescPtr xkb = dev->key->xkbInfo->desc; + uint32_t *kc; + + info->type = KeyClass; + info->num_keycodes = xkb->max_key_code - xkb->min_key_code + 1; + info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes; + info->sourceid = dev->key->sourceid; + + kc = (uint32_t*)&info[1]; + for (i = xkb->min_key_code; i <= xkb->max_key_code; i++, kc++) + *kc = i; + + return info->length * 4; +} + +static void +SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info) +{ + char n; + uint32_t *key; + int i; + swaps(&info->type, n); + swaps(&info->length, n); + swaps(&info->sourceid, n); + + for (i = 0, key = (uint32_t*)&info[1]; i < info->num_keycodes; i++, key++) + swapl(key, n); + + swaps(&info->num_keycodes, n); +} + +/** + * List axis information for the given axis. + * + * @return The number of bytes written into info. + */ +int +ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber, + Bool reportState) +{ + ValuatorClassPtr v = dev->valuator; + + info->type = ValuatorClass; + info->length = sizeof(xXIValuatorInfo)/4; + info->label = v->axes[axisnumber].label; + info->min.integral = v->axes[axisnumber].min_value; + info->min.frac = 0; + info->max.integral = v->axes[axisnumber].max_value; + info->max.frac = 0; + info->value.integral = (int)v->axisVal[axisnumber]; + info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16)); + info->resolution = v->axes[axisnumber].resolution; + info->number = axisnumber; + info->mode = valuator_get_mode(dev, axisnumber); + info->sourceid = v->sourceid; + + if (!reportState) + info->value = info->min; + + return info->length * 4; +} + +static void +SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info) +{ + char n; + swaps(&info->type, n); + swaps(&info->length, n); + swapl(&info->label, n); + swapl(&info->min.integral, n); + swapl(&info->min.frac, n); + swapl(&info->max.integral, n); + swapl(&info->max.frac, n); + swaps(&info->number, n); + swaps(&info->sourceid, n); +} + +int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment) +{ + DeviceIntPtr master = GetMaster(dev, MASTER_ATTACHED); + int use; + + if (IsMaster(dev)) + { + DeviceIntPtr paired = GetPairedDevice(dev); + use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard; + *attachment = (paired ? paired->id : 0); + } else if (!IsFloating(dev)) + { + use = IsPointerDevice(master) ? XISlavePointer : XISlaveKeyboard; + *attachment = master->id; + } else + use = XIFloatingSlave; + + return use; +} + +/** + * Write the info for device dev into the buffer pointed to by info. + * + * @return The number of bytes used. + */ +static int +ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info) +{ + char *any = (char*)&info[1]; + int len = 0, total_len = 0; + + info->deviceid = dev->id; + info->use = GetDeviceUse(dev, &info->attachment); + info->num_classes = 0; + info->name_len = strlen(dev->name); + info->enabled = dev->enabled; + total_len = sizeof(xXIDeviceInfo); + + len = pad_to_int32(info->name_len); + memset(any, 0, len); + strncpy(any, dev->name, info->name_len); + any += len; + total_len += len; + + total_len += ListDeviceClasses(client, dev, any, &info->num_classes); + return total_len; +} + +/** + * Write the class info of the device into the memory pointed to by any, set + * nclasses to the number of classes in total and return the number of bytes + * written. + */ +int +ListDeviceClasses(ClientPtr client, DeviceIntPtr dev, + char *any, uint16_t *nclasses) +{ + int total_len = 0; + int len; + int i; + int rc; + + /* Check if the current device state should be suppressed */ + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess); + + if (dev->button) + { + (*nclasses)++; + len = ListButtonInfo(dev, (xXIButtonInfo*)any, rc == Success); + any += len; + total_len += len; + } + + if (dev->key) + { + (*nclasses)++; + len = ListKeyInfo(dev, (xXIKeyInfo*)any); + any += len; + total_len += len; + } + + for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++) + { + (*nclasses)++; + len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i, rc == Success); + any += len; + total_len += len; + } + + return total_len; +} + +static void +SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info) +{ + char n; + char *any = (char*)&info[1]; + int i; + + /* Skip over name */ + any += pad_to_int32(info->name_len); + + for (i = 0; i < info->num_classes; i++) + { + int len = ((xXIAnyInfo*)any)->length; + switch(((xXIAnyInfo*)any)->type) + { + case XIButtonClass: + SwapButtonInfo(dev, (xXIButtonInfo*)any); + break; + case XIKeyClass: + SwapKeyInfo(dev, (xXIKeyInfo*)any); + break; + case XIValuatorClass: + SwapValuatorInfo(dev, (xXIValuatorInfo*)any); + break; + } + + any += len * 4; + } + + swaps(&info->deviceid, n); + swaps(&info->use, n); + swaps(&info->attachment, n); + swaps(&info->num_classes, n); + swaps(&info->name_len, n); + +} diff --git a/xorg-server/Xi/xiquerypointer.c b/xorg-server/Xi/xiquerypointer.c index ce025432e..51317994b 100644 --- a/xorg-server/Xi/xiquerypointer.c +++ b/xorg-server/Xi/xiquerypointer.c @@ -1,229 +1,229 @@ -/*
- * 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
- */
-
-/***********************************************************************
- *
- * Request to query the pointer location of an extension input device.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h> /* for inputstr.h */
-#include <X11/Xproto.h> /* Request macro */
-#include "inputstr.h" /* DeviceIntPtr */
-#include "windowstr.h" /* window structure */
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XI2proto.h>
-#include "extnsionst.h"
-#include "exevents.h"
-#include "exglobals.h"
-#include "eventconvert.h"
-#include "scrnintstr.h"
-#include "xkbsrv.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-#include "xiquerypointer.h"
-
-/***********************************************************************
- *
- * This procedure allows a client to query the pointer of a device.
- *
- */
-
-int
-SProcXIQueryPointer(ClientPtr client)
-{
- char n;
-
- REQUEST(xXIQueryPointerReq);
- swaps(&stuff->length, n);
- swaps(&stuff->deviceid, n);
- swapl(&stuff->win, n);
- return (ProcXIQueryPointer(client));
-}
-
-int
-ProcXIQueryPointer(ClientPtr client)
-{
- int rc;
- xXIQueryPointerReply rep;
- DeviceIntPtr pDev, kbd;
- WindowPtr pWin, t;
- SpritePtr pSprite;
- XkbStatePtr state;
- char *buttons = NULL;
- int buttons_size = 0; /* size of buttons array */
-
- REQUEST(xXIQueryPointerReq);
- REQUEST_SIZE_MATCH(xXIQueryPointerReq);
-
- rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->deviceid;
- return rc;
- }
-
- if (pDev->valuator == NULL || IsKeyboardDevice(pDev) ||
- (!IsMaster(pDev) && !IsFloating(pDev))) /* no attached devices */
- {
- client->errorValue = stuff->deviceid;
- return BadDevice;
- }
-
- rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess);
- if (rc != Success)
- {
- SendErrorToClient(client, IReqCode, X_XIQueryPointer,
- stuff->win, rc);
- return Success;
- }
-
- if (pDev->valuator->motionHintWindow)
- MaybeStopHint(pDev, client);
-
- if (IsMaster(pDev))
- kbd = GetPairedDevice(pDev);
- else
- kbd = (pDev->key) ? pDev : NULL;
-
- pSprite = pDev->spriteInfo->sprite;
-
- memset(&rep, 0, sizeof(rep));
- rep.repType = X_Reply;
- rep.RepType = X_XIQueryPointer;
- rep.length = 6;
- rep.sequenceNumber = client->sequence;
- rep.root = (GetCurrentRootWindow(pDev))->drawable.id;
- rep.root_x = FP1616(pSprite->hot.x, 0);
- rep.root_y = FP1616(pSprite->hot.y, 0);
- rep.child = None;
-
- if (kbd)
- {
- state = &kbd->key->xkbInfo->state;
- rep.mods.base_mods = state->base_mods;
- rep.mods.latched_mods = state->latched_mods;
- rep.mods.locked_mods = state->locked_mods;
-
- rep.group.base_group = state->base_group;
- rep.group.latched_group = state->latched_group;
- rep.group.locked_group = state->locked_group;
- }
-
- if (pDev->button)
- {
- int i, down;
- rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
- rep.length += rep.buttons_len;
- buttons_size = rep.buttons_len * 4;
- buttons = calloc(1, buttons_size);
- if (!buttons)
- return BadAlloc;
-
- down = pDev->button->buttonsDown;
-
- for (i = 0; i < pDev->button->numButtons && down; i++)
- {
- if (BitIsOn(pDev->button->down, i))
- {
- SetBit(buttons, i);
- down--;
- }
- }
- } else
- rep.buttons_len = 0;
-
- if (pSprite->hot.pScreen == pWin->drawable.pScreen)
- {
- rep.same_screen = xTrue;
- rep.win_x = FP1616(pSprite->hot.x - pWin->drawable.x, 0);
- rep.win_y = FP1616(pSprite->hot.y - pWin->drawable.y, 0);
- for (t = pSprite->win; t; t = t->parent)
- if (t->parent == pWin)
- {
- rep.child = t->drawable.id;
- break;
- }
- } else
- {
- rep.same_screen = xFalse;
- rep.win_x = 0;
- rep.win_y = 0;
- }
-
-#ifdef PANORAMIX
- if(!noPanoramiXExtension) {
- rep.root_x += FP1616(screenInfo.screens[0]->x, 0);
- rep.root_y += FP1616(screenInfo.screens[0]->y, 0);
- if (stuff->win == rep.root)
- {
- rep.win_x += FP1616(screenInfo.screens[0]->x, 0);
- rep.win_y += FP1616(screenInfo.screens[0]->y, 0);
- }
- }
-#endif
-
- WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep);
- if (buttons)
- WriteToClient(client, buttons_size, buttons);
-
- free(buttons);
-
- return Success;
-}
-
-/***********************************************************************
- *
- * This procedure writes the reply for the XIQueryPointer function,
- * if the client and server have a different byte ordering.
- *
- */
-
-void
-SRepXIQueryPointer(ClientPtr client, int size,
- xXIQueryPointerReply * rep)
-{
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swapl(&rep->root, n);
- swapl(&rep->child, n);
- swapl(&rep->root_x, n);
- swapl(&rep->root_y, n);
- swapl(&rep->win_x, n);
- swapl(&rep->win_y, n);
- swaps(&rep->buttons_len, n);
-
- WriteToClient(client, size, (char *)rep);
-}
-
+/* + * 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 + */ + +/*********************************************************************** + * + * Request to query the pointer location of an extension input device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XI2proto.h> +#include "extnsionst.h" +#include "exevents.h" +#include "exglobals.h" +#include "eventconvert.h" +#include "scrnintstr.h" +#include "xkbsrv.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +#include "xiquerypointer.h" + +/*********************************************************************** + * + * This procedure allows a client to query the pointer of a device. + * + */ + +int +SProcXIQueryPointer(ClientPtr client) +{ + char n; + + REQUEST(xXIQueryPointerReq); + swaps(&stuff->length, n); + swaps(&stuff->deviceid, n); + swapl(&stuff->win, n); + return (ProcXIQueryPointer(client)); +} + +int +ProcXIQueryPointer(ClientPtr client) +{ + int rc; + xXIQueryPointerReply rep; + DeviceIntPtr pDev, kbd; + WindowPtr pWin, t; + SpritePtr pSprite; + XkbStatePtr state; + char *buttons = NULL; + int buttons_size = 0; /* size of buttons array */ + + REQUEST(xXIQueryPointerReq); + REQUEST_SIZE_MATCH(xXIQueryPointerReq); + + rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess); + if (rc != Success) + { + client->errorValue = stuff->deviceid; + return rc; + } + + if (pDev->valuator == NULL || IsKeyboardDevice(pDev) || + (!IsMaster(pDev) && !IsFloating(pDev))) /* no attached devices */ + { + client->errorValue = stuff->deviceid; + return BadDevice; + } + + rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess); + if (rc != Success) + { + SendErrorToClient(client, IReqCode, X_XIQueryPointer, + stuff->win, rc); + return Success; + } + + if (pDev->valuator->motionHintWindow) + MaybeStopHint(pDev, client); + + if (IsMaster(pDev)) + kbd = GetPairedDevice(pDev); + else + kbd = (pDev->key) ? pDev : NULL; + + pSprite = pDev->spriteInfo->sprite; + + memset(&rep, 0, sizeof(rep)); + rep.repType = X_Reply; + rep.RepType = X_XIQueryPointer; + rep.length = 6; + rep.sequenceNumber = client->sequence; + rep.root = (GetCurrentRootWindow(pDev))->drawable.id; + rep.root_x = FP1616(pSprite->hot.x, 0); + rep.root_y = FP1616(pSprite->hot.y, 0); + rep.child = None; + + if (kbd) + { + state = &kbd->key->xkbInfo->state; + rep.mods.base_mods = state->base_mods; + rep.mods.latched_mods = state->latched_mods; + rep.mods.locked_mods = state->locked_mods; + + rep.group.base_group = state->base_group; + rep.group.latched_group = state->latched_group; + rep.group.locked_group = state->locked_group; + } + + if (pDev->button) + { + int i, down; + rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); + rep.length += rep.buttons_len; + buttons_size = rep.buttons_len * 4; + buttons = calloc(1, buttons_size); + if (!buttons) + return BadAlloc; + + down = pDev->button->buttonsDown; + + for (i = 0; i < pDev->button->numButtons && down; i++) + { + if (BitIsOn(pDev->button->down, i)) + { + SetBit(buttons, i); + down--; + } + } + } else + rep.buttons_len = 0; + + if (pSprite->hot.pScreen == pWin->drawable.pScreen) + { + rep.same_screen = xTrue; + rep.win_x = FP1616(pSprite->hot.x - pWin->drawable.x, 0); + rep.win_y = FP1616(pSprite->hot.y - pWin->drawable.y, 0); + for (t = pSprite->win; t; t = t->parent) + if (t->parent == pWin) + { + rep.child = t->drawable.id; + break; + } + } else + { + rep.same_screen = xFalse; + rep.win_x = 0; + rep.win_y = 0; + } + +#ifdef PANORAMIX + if(!noPanoramiXExtension) { + rep.root_x += FP1616(screenInfo.screens[0]->x, 0); + rep.root_y += FP1616(screenInfo.screens[0]->y, 0); + if (stuff->win == rep.root) + { + rep.win_x += FP1616(screenInfo.screens[0]->x, 0); + rep.win_y += FP1616(screenInfo.screens[0]->y, 0); + } + } +#endif + + WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep); + if (buttons) + WriteToClient(client, buttons_size, buttons); + + free(buttons); + + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XIQueryPointer function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXIQueryPointer(ClientPtr client, int size, + xXIQueryPointerReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->root, n); + swapl(&rep->child, n); + swapl(&rep->root_x, n); + swapl(&rep->root_y, n); + swapl(&rep->win_x, n); + swapl(&rep->win_y, n); + swaps(&rep->buttons_len, n); + + WriteToClient(client, size, (char *)rep); +} + diff --git a/xorg-server/Xi/xiqueryversion.c b/xorg-server/Xi/xiqueryversion.c index a84c07279..f647f9872 100644 --- a/xorg-server/Xi/xiqueryversion.c +++ b/xorg-server/Xi/xiqueryversion.c @@ -1,125 +1,125 @@ -/*
- * Copyright © 2009 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.
- *
- * Authors: Peter Hutterer
- *
- */
-
-/**
- * @file xiqueryversion.c
- * Protocol handling for the XIQueryVersion request/reply.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-
-#include "inputstr.h"
-
-#include <X11/Xmd.h>
-#include <X11/X.h>
-#include <X11/extensions/XI2proto.h>
-
-#include "exglobals.h"
-#include "exevents.h"
-#include "xiqueryversion.h"
-#include "misc.h"
-
-extern XExtensionVersion XIVersion; /* defined in getvers.c */
-/**
- * Return the supported XI version.
- *
- * Saves the version the client claims to support as well, for future
- * reference.
- */
-int
-ProcXIQueryVersion(ClientPtr client)
-{
- xXIQueryVersionReply rep;
- XIClientPtr pXIClient;
- int major, minor;
-
- REQUEST(xXIQueryVersionReq);
- REQUEST_SIZE_MATCH(xXIQueryVersionReq);
-
- /* This request only exists after XI2 */
- if (stuff->major_version < 2)
- {
- client->errorValue = stuff->major_version;
- return BadValue;
- }
-
- pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
-
- if (version_compare(XIVersion.major_version, XIVersion.minor_version,
- stuff->major_version, stuff->minor_version) > 0)
- {
- major = stuff->major_version;
- minor = stuff->minor_version;
- } else
- {
- major = XIVersion.major_version;
- minor = XIVersion.minor_version;
- }
-
- pXIClient->major_version = major;
- pXIClient->minor_version = minor;
-
- memset(&rep, 0, sizeof(xXIQueryVersionReply));
- rep.repType = X_Reply;
- rep.RepType = X_XIQueryVersion;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.major_version = major;
- rep.minor_version = minor;
-
- WriteReplyToClient(client, sizeof(xXIQueryVersionReply), &rep);
-
- return Success;
-}
-
-/* Swapping routines */
-
-int
-SProcXIQueryVersion(ClientPtr client)
-{
- char n;
-
- REQUEST(xXIQueryVersionReq);
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXIQueryVersionReq);
- swaps(&stuff->major_version, n);
- swaps(&stuff->minor_version, n);
- return (ProcXIQueryVersion(client));
-}
-
-void
-SRepXIQueryVersion(ClientPtr client, int size, xXIQueryVersionReply *rep)
-{
- char n;
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->major_version, n);
- swaps(&rep->minor_version, n);
- WriteToClient(client, size, (char *)rep);
-}
+/* + * Copyright © 2009 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. + * + * Authors: Peter Hutterer + * + */ + +/** + * @file xiqueryversion.c + * Protocol handling for the XIQueryVersion request/reply. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + + +#include "inputstr.h" + +#include <X11/Xmd.h> +#include <X11/X.h> +#include <X11/extensions/XI2proto.h> + +#include "exglobals.h" +#include "exevents.h" +#include "xiqueryversion.h" +#include "misc.h" + +extern XExtensionVersion XIVersion; /* defined in getvers.c */ +/** + * Return the supported XI version. + * + * Saves the version the client claims to support as well, for future + * reference. + */ +int +ProcXIQueryVersion(ClientPtr client) +{ + xXIQueryVersionReply rep; + XIClientPtr pXIClient; + int major, minor; + + REQUEST(xXIQueryVersionReq); + REQUEST_SIZE_MATCH(xXIQueryVersionReq); + + /* This request only exists after XI2 */ + if (stuff->major_version < 2) + { + client->errorValue = stuff->major_version; + return BadValue; + } + + pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); + + if (version_compare(XIVersion.major_version, XIVersion.minor_version, + stuff->major_version, stuff->minor_version) > 0) + { + major = stuff->major_version; + minor = stuff->minor_version; + } else + { + major = XIVersion.major_version; + minor = XIVersion.minor_version; + } + + pXIClient->major_version = major; + pXIClient->minor_version = minor; + + memset(&rep, 0, sizeof(xXIQueryVersionReply)); + rep.repType = X_Reply; + rep.RepType = X_XIQueryVersion; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.major_version = major; + rep.minor_version = minor; + + WriteReplyToClient(client, sizeof(xXIQueryVersionReply), &rep); + + return Success; +} + +/* Swapping routines */ + +int +SProcXIQueryVersion(ClientPtr client) +{ + char n; + + REQUEST(xXIQueryVersionReq); + swaps(&stuff->length, n); + REQUEST_AT_LEAST_SIZE(xXIQueryVersionReq); + swaps(&stuff->major_version, n); + swaps(&stuff->minor_version, n); + return (ProcXIQueryVersion(client)); +} + +void +SRepXIQueryVersion(ClientPtr client, int size, xXIQueryVersionReply *rep) +{ + char n; + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->major_version, n); + swaps(&rep->minor_version, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/xiwarppointer.c b/xorg-server/Xi/xiwarppointer.c index 66888008f..a463ab94d 100644 --- a/xorg-server/Xi/xiwarppointer.c +++ b/xorg-server/Xi/xiwarppointer.c @@ -1,203 +1,203 @@ -/*
- * 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
- */
-
-/***********************************************************************
- *
- * Request to Warp the pointer location of an extension input device.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h> /* for inputstr.h */
-#include <X11/Xproto.h> /* Request macro */
-#include "inputstr.h" /* DeviceIntPtr */
-#include "windowstr.h" /* window structure */
-#include "scrnintstr.h" /* screen structure */
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XI2proto.h>
-#include "extnsionst.h"
-#include "exevents.h"
-#include "exglobals.h"
-#include "mipointer.h" /* for miPointerUpdateSprite */
-
-
-#include "xiwarppointer.h"
-/***********************************************************************
- *
- * This procedure allows a client to warp the pointer of a device.
- *
- */
-
-int
-SProcXIWarpPointer(ClientPtr client)
-{
- char n;
-
- REQUEST(xXIWarpPointerReq);
- swaps(&stuff->length, n);
- swapl(&stuff->src_win, n);
- swapl(&stuff->dst_win, n);
- swapl(&stuff->src_x, n);
- swapl(&stuff->src_y, n);
- swaps(&stuff->src_width, n);
- swaps(&stuff->src_height, n);
- swapl(&stuff->dst_x, n);
- swapl(&stuff->dst_y, n);
- swaps(&stuff->deviceid, n);
- return (ProcXIWarpPointer(client));
-}
-
-int
-ProcXIWarpPointer(ClientPtr client)
-{
- int rc;
- int x, y;
- WindowPtr dest = NULL;
- DeviceIntPtr pDev;
- SpritePtr pSprite;
- ScreenPtr newScreen;
- int src_x, src_y;
- int dst_x, dst_y;
-
- REQUEST(xXIWarpPointerReq);
- REQUEST_SIZE_MATCH(xXIWarpPointerReq);
-
- /* FIXME: panoramix stuff is missing, look at ProcWarpPointer */
-
- rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixWriteAccess);
-
- if (rc != Success)
- {
- client->errorValue = stuff->deviceid;
- return rc;
- }
-
- if ((!IsMaster(pDev) && !IsFloating(pDev)) ||
- (IsMaster(pDev) && !IsPointerDevice(pDev)))
- {
- client->errorValue = stuff->deviceid;
- return BadDevice;
- }
-
- if (stuff->dst_win != None)
- {
- rc = dixLookupWindow(&dest, stuff->dst_win, client, DixGetAttrAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->dst_win;
- return rc;
- }
- }
-
- pSprite = pDev->spriteInfo->sprite;
- x = pSprite->hotPhys.x;
- y = pSprite->hotPhys.y;
-
- src_x = stuff->src_x / (double)(1 << 16);
- src_y = stuff->src_y / (double)(1 << 16);
- dst_x = stuff->dst_x / (double)(1 << 16);
- dst_y = stuff->dst_y / (double)(1 << 16);
-
- if (stuff->src_win != None)
- {
- int winX, winY;
- WindowPtr src;
-
- rc = dixLookupWindow(&src, stuff->src_win, client, DixGetAttrAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->src_win;
- return rc;
- }
-
- winX = src->drawable.x;
- winY = src->drawable.y;
- if (src->drawable.pScreen != pSprite->hotPhys.pScreen ||
- x < winX + src_x ||
- y < winY + src_y ||
- (stuff->src_width != 0 &&
- winX + src_x + (int)stuff->src_width < 0) ||
- (stuff->src_height != 0 &&
- winY + src_y + (int)stuff->src_height < y) ||
- !PointInWindowIsVisible(src, x, y))
- return Success;
- }
-
- if (dest)
- {
- x = dest->drawable.x;
- y = dest->drawable.y;
- newScreen = dest->drawable.pScreen;
- } else
- newScreen = pSprite->hotPhys.pScreen;
-
- x += dst_x;
- y += dst_y;
-
- if (x < 0)
- x = 0;
- else if (x > newScreen->width)
- x = newScreen->width - 1;
-
- if (y < 0)
- y = 0;
- else if (y > newScreen->height)
- y = newScreen->height - 1;
-
- if (newScreen == pSprite->hotPhys.pScreen)
- {
- if (x < pSprite->physLimits.x1)
- x = pSprite->physLimits.x1;
- else if (x >= pSprite->physLimits.x2)
- x = pSprite->physLimits.x2 - 1;
-
- if (y < pSprite->physLimits.y1)
- y = pSprite->physLimits.y1;
- else if (y >= pSprite->physLimits.y2)
- y = pSprite->physLimits.y2 - 1;
-
- if (pSprite->hotShape)
- ConfineToShape(pDev, pSprite->hotShape, &x, &y);
- (*newScreen->SetCursorPosition)(pDev, newScreen, x, y, TRUE);
- } else if (!PointerConfinedToScreen(pDev))
- {
- NewCurrentScreen(pDev, newScreen, x, y);
- }
-
- /* if we don't update the device, we get a jump next time it moves */
- pDev->last.valuators[0] = x;
- pDev->last.valuators[1] = y;
- pDev->last.remainder[0] = 0;
- pDev->last.remainder[1] = 0;
- miPointerUpdateSprite(pDev);
-
- /* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it
- here though. */
- return Success;
-}
-
+/* + * 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 + */ + +/*********************************************************************** + * + * Request to Warp the pointer location of an extension input device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XI2proto.h> +#include "extnsionst.h" +#include "exevents.h" +#include "exglobals.h" +#include "mipointer.h" /* for miPointerUpdateSprite */ + + +#include "xiwarppointer.h" +/*********************************************************************** + * + * This procedure allows a client to warp the pointer of a device. + * + */ + +int +SProcXIWarpPointer(ClientPtr client) +{ + char n; + + REQUEST(xXIWarpPointerReq); + swaps(&stuff->length, n); + swapl(&stuff->src_win, n); + swapl(&stuff->dst_win, n); + swapl(&stuff->src_x, n); + swapl(&stuff->src_y, n); + swaps(&stuff->src_width, n); + swaps(&stuff->src_height, n); + swapl(&stuff->dst_x, n); + swapl(&stuff->dst_y, n); + swaps(&stuff->deviceid, n); + return (ProcXIWarpPointer(client)); +} + +int +ProcXIWarpPointer(ClientPtr client) +{ + int rc; + int x, y; + WindowPtr dest = NULL; + DeviceIntPtr pDev; + SpritePtr pSprite; + ScreenPtr newScreen; + int src_x, src_y; + int dst_x, dst_y; + + REQUEST(xXIWarpPointerReq); + REQUEST_SIZE_MATCH(xXIWarpPointerReq); + + /* FIXME: panoramix stuff is missing, look at ProcWarpPointer */ + + rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixWriteAccess); + + if (rc != Success) + { + client->errorValue = stuff->deviceid; + return rc; + } + + if ((!IsMaster(pDev) && !IsFloating(pDev)) || + (IsMaster(pDev) && !IsPointerDevice(pDev))) + { + client->errorValue = stuff->deviceid; + return BadDevice; + } + + if (stuff->dst_win != None) + { + rc = dixLookupWindow(&dest, stuff->dst_win, client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->dst_win; + return rc; + } + } + + pSprite = pDev->spriteInfo->sprite; + x = pSprite->hotPhys.x; + y = pSprite->hotPhys.y; + + src_x = stuff->src_x / (double)(1 << 16); + src_y = stuff->src_y / (double)(1 << 16); + dst_x = stuff->dst_x / (double)(1 << 16); + dst_y = stuff->dst_y / (double)(1 << 16); + + if (stuff->src_win != None) + { + int winX, winY; + WindowPtr src; + + rc = dixLookupWindow(&src, stuff->src_win, client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->src_win; + return rc; + } + + winX = src->drawable.x; + winY = src->drawable.y; + if (src->drawable.pScreen != pSprite->hotPhys.pScreen || + x < winX + src_x || + y < winY + src_y || + (stuff->src_width != 0 && + winX + src_x + (int)stuff->src_width < 0) || + (stuff->src_height != 0 && + winY + src_y + (int)stuff->src_height < y) || + !PointInWindowIsVisible(src, x, y)) + return Success; + } + + if (dest) + { + x = dest->drawable.x; + y = dest->drawable.y; + newScreen = dest->drawable.pScreen; + } else + newScreen = pSprite->hotPhys.pScreen; + + x += dst_x; + y += dst_y; + + if (x < 0) + x = 0; + else if (x > newScreen->width) + x = newScreen->width - 1; + + if (y < 0) + y = 0; + else if (y > newScreen->height) + y = newScreen->height - 1; + + if (newScreen == pSprite->hotPhys.pScreen) + { + if (x < pSprite->physLimits.x1) + x = pSprite->physLimits.x1; + else if (x >= pSprite->physLimits.x2) + x = pSprite->physLimits.x2 - 1; + + if (y < pSprite->physLimits.y1) + y = pSprite->physLimits.y1; + else if (y >= pSprite->physLimits.y2) + y = pSprite->physLimits.y2 - 1; + + if (pSprite->hotShape) + ConfineToShape(pDev, pSprite->hotShape, &x, &y); + (*newScreen->SetCursorPosition)(pDev, newScreen, x, y, TRUE); + } else if (!PointerConfinedToScreen(pDev)) + { + NewCurrentScreen(pDev, newScreen, x, y); + } + + /* if we don't update the device, we get a jump next time it moves */ + pDev->last.valuators[0] = x; + pDev->last.valuators[1] = y; + pDev->last.remainder[0] = 0; + pDev->last.remainder[1] = 0; + miPointerUpdateSprite(pDev); + + /* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it + here though. */ + return Success; +} + |