diff options
Diffstat (limited to 'xorg-server/Xi/xiquerydevice.c')
-rw-r--r-- | xorg-server/Xi/xiquerydevice.c | 1006 |
1 files changed, 503 insertions, 503 deletions
diff --git a/xorg-server/Xi/xiquerydevice.c b/xorg-server/Xi/xiquerydevice.c index 8b5421130..f8a4eb8a5 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 = GetMaster(dev, MASTER_ATTACHED); - int use; - - if (IsMaster(dev)) - { - DeviceIntPtr paired = GetPairedDevice(dev); - use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard; - *attachment = (paired ? paired->id : 0); - } else if (!IsFloating(dev)) - { - use = IsPointerDevice(master) ? XISlavePointer : XISlaveKeyboard; - *attachment = master->id; - } else - use = XIFloatingSlave; - - return use; -} - -/** - * Write the info for device dev into the buffer pointed to by info. - * - * @return The number of bytes used. - */ -static int -ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info) -{ - char *any = (char*)&info[1]; - int len = 0, total_len = 0; - - info->deviceid = dev->id; - info->use = GetDeviceUse(dev, &info->attachment); - info->num_classes = 0; - info->name_len = strlen(dev->name); - info->enabled = dev->enabled; - total_len = sizeof(xXIDeviceInfo); - - len = pad_to_int32(info->name_len); - memset(any, 0, len); - strncpy(any, dev->name, info->name_len); - any += len; - total_len += len; - - total_len += ListDeviceClasses(client, dev, any, &info->num_classes); - return total_len; -} - -/** - * Write the class info of the device into the memory pointed to by any, set - * nclasses to the number of classes in total and return the number of bytes - * written. - */ -int -ListDeviceClasses(ClientPtr client, DeviceIntPtr dev, - char *any, uint16_t *nclasses) -{ - int total_len = 0; - int len; - int i; - int rc; - - /* Check if the current device state should be suppressed */ - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess); - - if (dev->button) - { - (*nclasses)++; - len = ListButtonInfo(dev, (xXIButtonInfo*)any, rc == Success); - any += len; - total_len += len; - } - - if (dev->key) - { - (*nclasses)++; - len = ListKeyInfo(dev, (xXIKeyInfo*)any); - any += len; - total_len += len; - } - - for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++) - { - (*nclasses)++; - len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i, rc == Success); - any += len; - total_len += len; - } - - return total_len; -} - -static void -SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info) -{ - char n; - char *any = (char*)&info[1]; - int i; - - /* Skip over name */ - any += pad_to_int32(info->name_len); - - for (i = 0; i < info->num_classes; i++) - { - int len = ((xXIAnyInfo*)any)->length; - switch(((xXIAnyInfo*)any)->type) - { - case XIButtonClass: - SwapButtonInfo(dev, (xXIButtonInfo*)any); - break; - case XIKeyClass: - SwapKeyInfo(dev, (xXIKeyInfo*)any); - break; - case XIValuatorClass: - SwapValuatorInfo(dev, (xXIValuatorInfo*)any); - break; - } - - any += len * 4; - } - - swaps(&info->deviceid, n); - swaps(&info->use, n); - swaps(&info->attachment, n); - swaps(&info->num_classes, n); - swaps(&info->name_len, n); - -} +/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Peter Hutterer
+ *
+ */
+
+/**
+ * @file Protocol handling for the XIQueryDevice request/reply.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h"
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/XI2proto.h>
+#include "xkbstr.h"
+#include "xkbsrv.h"
+#include "xserver-properties.h"
+#include "exevents.h"
+#include "xace.h"
+
+#include "xiquerydevice.h"
+
+static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d);
+static int
+ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info);
+static int SizeDeviceInfo(DeviceIntPtr dev);
+static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info);
+int
+SProcXIQueryDevice(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xXIQueryDeviceReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+
+ return ProcXIQueryDevice(client);
+}
+
+int
+ProcXIQueryDevice(ClientPtr client)
+{
+ xXIQueryDeviceReply rep;
+ DeviceIntPtr dev = NULL;
+ int rc = Success;
+ int i = 0, len = 0;
+ char *info, *ptr;
+ Bool *skip = NULL;
+
+ REQUEST(xXIQueryDeviceReq);
+ REQUEST_SIZE_MATCH(xXIQueryDeviceReq);
+
+ if (stuff->deviceid != XIAllDevices && stuff->deviceid != XIAllMasterDevices)
+ {
+ rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->deviceid;
+ return rc;
+ }
+ len += SizeDeviceInfo(dev);
+ }
+ else
+ {
+ skip = calloc(sizeof(Bool), inputInfo.numDevices);
+ if (!skip)
+ return BadAlloc;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next, i++)
+ {
+ skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev);
+ if (!skip[i])
+ len += SizeDeviceInfo(dev);
+ }
+
+ for (dev = inputInfo.off_devices; dev; dev = dev->next, i++)
+ {
+ skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev);
+ if (!skip[i])
+ len += SizeDeviceInfo(dev);
+ }
+ }
+
+ info = calloc(1, len);
+ if (!info)
+ 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);
+
+}
|