aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xi
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/Xi')
-rw-r--r--xorg-server/Xi/exevents.c19
-rw-r--r--xorg-server/Xi/xichangehierarchy.c982
-rw-r--r--xorg-server/Xi/xipassivegrab.c620
-rw-r--r--xorg-server/Xi/xiquerydevice.c1006
-rw-r--r--xorg-server/Xi/xiquerypointer.c458
-rw-r--r--xorg-server/Xi/xiwarppointer.c2
6 files changed, 1542 insertions, 1545 deletions
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c
index 327873e29..c7089bb69 100644
--- a/xorg-server/Xi/exevents.c
+++ b/xorg-server/Xi/exevents.c
@@ -710,10 +710,13 @@ ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
if (rc != Success)
return; /* Device has disappeared */
- if (!slave->u.master)
+ if (IsMaster(slave))
+ return;
+
+ if (IsFloating(slave))
return; /* set floating since the event */
- if (slave->u.master->id != dce->masterid)
+ 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 */
@@ -866,7 +869,7 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
* event being delivered through the slave first
*/
for (sd = inputInfo.devices; sd; sd = sd->next) {
- if (IsMaster(sd) || sd->u.master != device)
+ if (IsMaster(sd) || GetMaster(sd, MASTER_POINTER) != device)
continue;
if (!sd->button)
continue;
@@ -1006,7 +1009,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
b = device->button;
k = device->key;
- if (IsMaster(device) || !device->u.master)
+ if (IsMaster(device) || IsFloating(device))
CheckMotion(event, device);
switch (event->type)
@@ -1047,10 +1050,8 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
switch(event->type)
{
case ET_KeyPress:
- if (!grab && CheckDeviceGrabs(device, event, 0)) {
- device->deviceGrab.activatingKey = key;
+ if (!grab && CheckDeviceGrabs(device, event, 0))
return;
- }
break;
case ET_KeyRelease:
if (grab && device->deviceGrab.fromPassiveGrab &&
@@ -1223,7 +1224,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
DeviceIntPtr mouse;
int btlen, len, i;
- mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev;
+ mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER);
/* XI 2 event */
btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
@@ -1280,7 +1281,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
DeviceFocusChangeMask, NullGrab);
- if ((type == DeviceFocusIn) &&
+ if ((event.type == DeviceFocusIn) &&
(wOtherInputMasks(pWin)) &&
(wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask))
{
diff --git a/xorg-server/Xi/xichangehierarchy.c b/xorg-server/Xi/xichangehierarchy.c
index 6b0288c88..a3dcab57e 100644
--- a/xorg-server/Xi/xichangehierarchy.c
+++ b/xorg-server/Xi/xichangehierarchy.c
@@ -1,490 +1,492 @@
-/*
- * 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));
- 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));
-
- dummyDev.id = XIAllDevices;
- 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 (attached->u.master == ptr)
- {
- AttachDevice(client, attached, newptr);
- flags[attached->id] |= XISlaveAttached;
- }
- if (attached->u.master == 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;
- }
-
- 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;
- }
-
- 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));
+
+ dummyDev.id = XIAllDevices;
+ 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;
+ }
+
+ 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;
+ }
+
+ 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 6b689f45e..8663d12a1 100644
--- a/xorg-server/Xi/xipassivegrab.c
+++ b/xorg-server/Xi/xipassivegrab.c
@@ -1,313 +1,307 @@
-/*
- * 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"
-
-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;
-
- 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)
- 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(&param, 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, &param);
-
- modifiers = (uint32_t*)&stuff[1] + stuff->mask_len;
- modifiers_failed = calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
- if (!modifiers_failed)
- return BadAlloc;
-
- if (!IsMaster(dev) && dev->u.master)
- mod_dev = GetMaster(dev, MASTER_KEYBOARD);
- else
- mod_dev = dev;
-
- 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,
- &param, GRABTYPE_XI2, &mask);
- break;
- case XIGrabtypeKeycode:
- status = GrabKey(client, dev, mod_dev, stuff->detail,
- &param, GRABTYPE_XI2, &mask);
- break;
- case XIGrabtypeEnter:
- case XIGrabtypeFocusIn:
- status = GrabWindow(client, dev, stuff->grab_type,
- &param, &mask);
- break;
- }
-
- if (status != GrabSuccess)
- {
- xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
-
- info->status = status;
- info->modifiers = *modifiers;
- rep.num_modifiers++;
- rep.length++;
- }
- }
-
- WriteReplyToClient(client, sizeof(rep), &rep);
- if (rep.num_modifiers)
- {
- client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
- WriteSwappedDataToClient(client, rep.num_modifiers * 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;
-
- if (!IsMaster(dev) && dev->u.master)
- mod_dev = GetMaster(dev, MASTER_KEYBOARD);
- else
- mod_dev = dev;
-
- 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"
+
+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;
+
+ 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)
+ 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(&param, 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, &param);
+
+ 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,
+ &param, GRABTYPE_XI2, &mask);
+ break;
+ case XIGrabtypeKeycode:
+ status = GrabKey(client, dev, mod_dev, stuff->detail,
+ &param, GRABTYPE_XI2, &mask);
+ break;
+ case XIGrabtypeEnter:
+ case XIGrabtypeFocusIn:
+ status = GrabWindow(client, dev, stuff->grab_type,
+ &param, &mask);
+ break;
+ }
+
+ if (status != GrabSuccess)
+ {
+ xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
+
+ info->status = status;
+ info->modifiers = *modifiers;
+ rep.num_modifiers++;
+ rep.length++;
+ }
+ }
+
+ WriteReplyToClient(client, sizeof(rep), &rep);
+ if (rep.num_modifiers)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, rep.num_modifiers * 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 4e1cae406..8b5421130 100644
--- a/xorg-server/Xi/xiquerydevice.c
+++ b/xorg-server/Xi/xiquerydevice.c
@@ -1,503 +1,503 @@
-/*
- * 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)
- 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++;
- }
- }
- }
-
- WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep);
- WriteToClient(client, rep.length * 4, 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 = dev->u.master;
- int use;
-
- if (IsMaster(dev))
- {
- DeviceIntPtr paired = GetPairedDevice(dev);
- use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard;
- *attachment = (paired ? paired->id : 0);
- } else if (master)
- {
- 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)
+ 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++;
+ }
+ }
+ }
+
+ WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep);
+ WriteToClient(client, rep.length * 4, 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 2dc057d67..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) && pDev->u.master)) /* 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/xiwarppointer.c b/xorg-server/Xi/xiwarppointer.c
index c01b115f3..a463ab94d 100644
--- a/xorg-server/Xi/xiwarppointer.c
+++ b/xorg-server/Xi/xiwarppointer.c
@@ -97,7 +97,7 @@ ProcXIWarpPointer(ClientPtr client)
return rc;
}
- if ((!IsMaster(pDev) && pDev->u.master) ||
+ if ((!IsMaster(pDev) && !IsFloating(pDev)) ||
(IsMaster(pDev) && !IsPointerDevice(pDev)))
{
client->errorValue = stuff->deviceid;