diff options
Diffstat (limited to 'Xi/listdev.c')
-rw-r--r-- | Xi/listdev.c | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/Xi/listdev.c b/Xi/listdev.c new file mode 100644 index 000000000..ff6155f19 --- /dev/null +++ b/Xi/listdev.c @@ -0,0 +1,409 @@ +/* $Xorg: listdev.c,v 1.4 2001/02/09 02:04:34 xorgcvs Exp $ */ + +/************************************************************ + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1989 by Hewlett-Packard Company, Palo Alto, California. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +********************************************************/ + +/*********************************************************************** + * + * Extension function to list the available input devices. + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#include "X.h" /* for inputstr.h */ +#include "Xproto.h" /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "XI.h" +#include "XIproto.h" + +#define VPC 20 /* Max # valuators per chunk */ +extern InputInfo inputInfo; +extern int IReqCode; +extern int BadDevice; +extern void (*ReplySwapVector[256]) (); +DeviceIntPtr LookupDeviceIntRec(); + +void CopySwapKeyClass (); +void CopySwapButtonClass (); +int CopySwapValuatorClass (); +void SizeDeviceInfo (); +void ListDeviceInfo (); +void AddOtherInputDevices (); +void CopyDeviceName (); +void CopySwapDevice (); + +/*********************************************************************** + * + * This procedure lists the input devices available to the server. + * + */ + +int +SProcXListInputDevices(client) + register ClientPtr client; + { + register char n; + + REQUEST(xListInputDevicesReq); + swaps(&stuff->length, n); + return(ProcXListInputDevices(client)); + } + +/*********************************************************************** + * + * This procedure lists the input devices available to the server. + * + */ + +ProcXListInputDevices (client) + register ClientPtr client; + { + xListInputDevicesReply rep; + int numdevs; + int namesize = 1; /* need 1 extra byte for strcpy */ + int size = 0; + int total_length; + char *devbuf; + char *classbuf; + char *namebuf; + char *savbuf; + xDeviceInfo *dev; + DeviceIntPtr d; + + REQUEST(xListInputDevicesReq); + REQUEST_SIZE_MATCH(xListInputDevicesReq); + + rep.repType = X_Reply; + rep.RepType = X_ListInputDevices; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + AddOtherInputDevices (); + numdevs = inputInfo.numDevices; + + for (d=inputInfo.devices; d; d=d->next) + SizeDeviceInfo (d, &namesize, &size); + for (d=inputInfo.off_devices; d; d=d->next) + SizeDeviceInfo (d, &namesize, &size); + + total_length = numdevs * sizeof (xDeviceInfo) + size + namesize; + devbuf = (char *) Xalloc (total_length); + classbuf = devbuf + (numdevs * sizeof (xDeviceInfo)); + namebuf = classbuf + size; + savbuf = devbuf; + + dev = (xDeviceInfoPtr) devbuf; + for (d=inputInfo.devices; d; d=d->next,dev++) + ListDeviceInfo (client, d, dev, &devbuf, &classbuf, &namebuf); + for (d=inputInfo.off_devices; d; d=d->next,dev++) + ListDeviceInfo (client, d, dev, &devbuf, &classbuf, &namebuf); + + rep.ndevices = numdevs; + rep.length = (total_length + 3) >> 2; + WriteReplyToClient (client, sizeof (xListInputDevicesReply), &rep); + WriteToClient(client, total_length, savbuf); + Xfree (savbuf); + return Success; + } + +/*********************************************************************** + * + * This procedure calculates the size of the information to be returned + * for an input device. + * + */ + +void +SizeDeviceInfo (d, namesize, size) + DeviceIntPtr d; + int *namesize; + int *size; + { + int chunks; + + *namesize += 1; + if (d->name) + *namesize += strlen (d->name); + if (d->key != NULL) + *size += sizeof (xKeyInfo); + if (d->button != NULL) + *size += sizeof (xButtonInfo); + if (d->valuator != NULL) + { + chunks = ((int) d->valuator->numAxes + 19) / VPC; + *size += (chunks * sizeof(xValuatorInfo) + + d->valuator->numAxes * sizeof(xAxisInfo)); + } + } + +/*********************************************************************** + * + * This procedure lists information to be returned for an input device. + * + */ + +void +ListDeviceInfo (client, d, dev, devbuf, classbuf, namebuf) + ClientPtr client; + DeviceIntPtr d; + xDeviceInfoPtr dev; + char **devbuf; + char **classbuf; + char **namebuf; + { + CopyDeviceName (namebuf, d->name); + CopySwapDevice (client, d, 0, devbuf); + if (d->key != NULL) + { + CopySwapKeyClass(client, d->key, classbuf); + dev->num_classes++; + } + if (d->button != NULL) + { + CopySwapButtonClass(client, d->button, classbuf); + dev->num_classes++; + } + if (d->valuator != NULL) + { + dev->num_classes += CopySwapValuatorClass(client, d->valuator, classbuf); + } + } + +/*********************************************************************** + * + * This procedure copies data to the DeviceInfo struct, swapping if necessary. + * + * We need the extra byte in the allocated buffer, because the trailing null + * hammers one extra byte, which is overwritten by the next name except for + * the last name copied. + * + */ + +void +CopyDeviceName (namebuf, name) + char **namebuf; + char *name; + { + char *nameptr = (char *) *namebuf; + + if (name) + { + *nameptr++ = strlen (name); + strcpy (nameptr, name); + *namebuf += (strlen (name)+1); + } + else + { + *nameptr++ = 0; + *namebuf += 1; + } + } + +/*********************************************************************** + * + * This procedure copies data to the DeviceInfo struct, swapping if necessary. + * + */ + +void +CopySwapDevice (client, d, num_classes, buf) + register ClientPtr client; + DeviceIntPtr d; + int num_classes; + char **buf; + { + register char n; + xDeviceInfoPtr dev; + + dev = (xDeviceInfoPtr) *buf; + + dev->id = d->id; + dev->type = d->type; + dev->num_classes = num_classes; + if (d == inputInfo.keyboard) + dev->use = IsXKeyboard; + else if (d == inputInfo.pointer) + dev->use = IsXPointer; + else + dev->use = IsXExtensionDevice; + if (client->swapped) + { + swapl(&dev->type, n); /* macro - braces are required */ + } + *buf += sizeof (xDeviceInfo); + } + +/*********************************************************************** + * + * This procedure copies KeyClass information, swapping if necessary. + * + */ + +void +CopySwapKeyClass (client, k, buf) + register ClientPtr client; + KeyClassPtr k; + char **buf; + { + register char n; + xKeyInfoPtr k2; + + k2 = (xKeyInfoPtr) *buf; + k2->class = KeyClass; + k2->length = sizeof (xKeyInfo); + k2->min_keycode = k->curKeySyms.minKeyCode; + k2->max_keycode = k->curKeySyms.maxKeyCode; + k2->num_keys = k2->max_keycode - k2->min_keycode + 1; + if (client->swapped) + { + swaps(&k2->num_keys,n); + } + *buf += sizeof (xKeyInfo); + } + +/*********************************************************************** + * + * This procedure copies ButtonClass information, swapping if necessary. + * + */ + +void +CopySwapButtonClass (client, b, buf) + register ClientPtr client; + ButtonClassPtr b; + char **buf; + { + register char n; + xButtonInfoPtr b2; + + b2 = (xButtonInfoPtr) *buf; + b2->class = ButtonClass; + b2->length = sizeof (xButtonInfo); + b2->num_buttons = b->numButtons; + if (client->swapped) + { + swaps(&b2->num_buttons,n); /* macro - braces are required */ + } + *buf += sizeof (xButtonInfo); + } + +/*********************************************************************** + * + * This procedure copies ValuatorClass information, swapping if necessary. + * + * Devices may have up to 255 valuators. The length of a ValuatorClass is + * defined to be sizeof(ValuatorClassInfo) + num_axes * sizeof (xAxisInfo). + * The maximum length is therefore (8 + 255 * 12) = 3068. However, the + * length field is one byte. If a device has more than 20 valuators, we + * must therefore return multiple valuator classes to the client. + * + */ + +int +CopySwapValuatorClass (client, v, buf) + register ClientPtr client; + ValuatorClassPtr v; + char **buf; +{ + int i, j, axes, t_axes; + register char n; + xValuatorInfoPtr v2; + AxisInfo *a; + xAxisInfoPtr a2; + + for (i=0,axes=v->numAxes; i < ((v->numAxes+19)/VPC); i++, axes-=VPC) { + t_axes = axes < VPC ? axes : VPC; + if (t_axes < 0) + t_axes = v->numAxes % VPC; + v2 = (xValuatorInfoPtr) *buf; + v2->class = ValuatorClass; + v2->length = sizeof (xValuatorInfo) + t_axes * sizeof (xAxisInfo); + v2->num_axes = t_axes; + v2->mode = v->mode & DeviceMode; + v2->motion_buffer_size = v->numMotionEvents; + if (client->swapped) + { + swapl(&v2->motion_buffer_size,n); + } + *buf += sizeof (xValuatorInfo); + a = v->axes + (VPC * i); + a2 = (xAxisInfoPtr) *buf; + for (j=0; j<t_axes; j++) { + a2->min_value = a->min_value; + a2->max_value = a->max_value; + a2->resolution = a->resolution; + if (client->swapped) { + swapl(&a2->min_value,n); + swapl(&a2->max_value,n); + swapl(&a2->resolution,n); + } + a2++; + a++; + *buf += sizeof (xAxisInfo); + } + } + return (i); +} + +/*********************************************************************** + * + * This procedure writes the reply for the XListInputDevices function, + * if the client and server have a different byte ordering. + * + */ + +SRepXListInputDevices (client, size, rep) + ClientPtr client; + int size; + xListInputDevicesReply *rep; + { + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); + } |