From 0a5888393c68f6f7db86206d1f277232db18240b Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 4 Mar 2011 13:54:03 +0000 Subject: xserver xkeyboard-config mesa git update 4 Marc 2011 --- xorg-server/Xi/exevents.c | 19 +- xorg-server/Xi/xichangehierarchy.c | 982 +++++++++++++++++------------------ xorg-server/Xi/xipassivegrab.c | 620 +++++++++++----------- xorg-server/Xi/xiquerydevice.c | 1006 ++++++++++++++++++------------------ xorg-server/Xi/xiquerypointer.c | 458 ++++++++-------- xorg-server/Xi/xiwarppointer.c | 2 +- 6 files changed, 1542 insertions(+), 1545 deletions(-) (limited to 'xorg-server/Xi') 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 -#endif - -#include /* for inputstr.h */ -#include /* Request macro */ -#include "inputstr.h" /* DeviceIntPtr */ -#include "windowstr.h" /* window structure */ -#include "scrnintstr.h" /* screen structure */ -#include -#include -#include -#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 +#endif + +#include /* for inputstr.h */ +#include /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include +#include +#include +#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 -#endif - -#include "inputstr.h" /* DeviceIntPtr */ -#include "windowstr.h" /* window structure */ -#include -#include -#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(¶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); - - 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, - ¶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; - 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 +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include +#include +#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(¶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); + + 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; + 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 -#endif - -#include "inputstr.h" -#include -#include -#include -#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 +#endif + +#include "inputstr.h" +#include +#include +#include +#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 -#endif - -#include /* for inputstr.h */ -#include /* Request macro */ -#include "inputstr.h" /* DeviceIntPtr */ -#include "windowstr.h" /* window structure */ -#include -#include -#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 +#endif + +#include /* for inputstr.h */ +#include /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include +#include +#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; -- cgit v1.2.3