debian/changelog | 11 debian/control | 4 debian/patches/137_add_device_property_support.patch | 1215 ++++++++++++++ debian/patches/138_xi_expose_enable_disabledevice.patch | 201 ++ debian/patches/139_xi_protect_against_null_handlers.patch | 37 debian/patches/series | 3 6 files changed, 1469 insertions(+), 2 deletions(-)
New commits: commit d57441bb5b57923021ac175148474507f2ad872a Author: Timo Aaltonen <[EMAIL PROTECTED]> Date: Thu Aug 21 16:56:19 2008 +0300 Bump the build-depends on x11proto-input-dev and libxi-dev. diff --git a/debian/changelog b/debian/changelog index fd213ea..3be6e0a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,8 +4,10 @@ xorg-server (2:1.4.99.906-1ubuntu4) UNRELEASED; urgency=low 138_xi_expose_enable_disabledevice.patch, 139_xi_protect_against_null_handlers.patch: - Add support for input-device properties. + * debian/control: Bump the build-depends on x11proto-input-dev + and libxi-dev. - -- Timo Aaltonen <[EMAIL PROTECTED]> Wed, 13 Aug 2008 10:45:48 +0300 + -- Timo Aaltonen <[EMAIL PROTECTED]> Thu, 21 Aug 2008 16:35:24 +0300 xorg-server (2:1.4.99.906-1ubuntu3) intrepid; urgency=low diff --git a/debian/control b/debian/control index 752bf8c..15c6335 100644 --- a/debian/control +++ b/debian/control @@ -19,7 +19,7 @@ Build-Depends: debhelper (>= 4.0.0), lsb-release, pkg-config, bison, flex, x11proto-xcmisc-dev, x11proto-xext-dev (>= 6.9.99.0), x11proto-xf86bigfont-dev, x11proto-xf86dga-dev, x11proto-xf86misc-dev, x11proto-xf86vidmode-dev, xtrans-dev, libxau-dev (>= 1:0.99.1), - x11proto-input-dev (>= 1.4.2), + x11proto-input-dev (>= 1.4.3-2ubuntu1), libxdmcp-dev (>= 1:0.99.1), libxfont-dev, libfontenc-dev, libxkbfile-dev (>= 1:0.99.1), libpixman-1-dev (>= 0.9.5), libpciaccess-dev, libssl-dev, @@ -28,7 +28,7 @@ Build-Depends: debhelper (>= 4.0.0), lsb-release, pkg-config, bison, flex, x11proto-gl-dev (>= 1.4.9), libgl1-mesa-dev (>= 7.1~rc1), libxmuu-dev (>= 1:0.99.1), libxext-dev (>= 1:0.99.1), libx11-dev (>= 1:0.99.2), libxrender-dev (>= 1:0.9.0), - libxi-dev (>= 1:0.99.1), x11proto-dmx-dev, quilt, libdmx-dev (>= 1:1.0.1), + libxi-dev (>= 2:1.1.3-1ubuntu2), x11proto-dmx-dev, quilt, libdmx-dev (>= 1:1.0.1), libxpm-dev (>= 1:3.5.3), libxaw7-dev (>= 1:0.99.1), libxt-dev (>= 1:0.99.1), libxmu-dev (>= 1:0.99.1), libxtst-dev (>= 1:0.99.1), libxres-dev (>= 1:0.99.1), commit 8c0f581e11a11c862f26a7107d7e9e5e56e677f1 Author: Timo Aaltonen <[EMAIL PROTECTED]> Date: Thu Aug 14 10:20:30 2008 +0300 Add support for input-device properties. diff --git a/debian/changelog b/debian/changelog index 21011b4..fd213ea 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +xorg-server (2:1.4.99.906-1ubuntu4) UNRELEASED; urgency=low + + * 137_add_device_property_support.patch, + 138_xi_expose_enable_disabledevice.patch, + 139_xi_protect_against_null_handlers.patch: + - Add support for input-device properties. + + -- Timo Aaltonen <[EMAIL PROTECTED]> Wed, 13 Aug 2008 10:45:48 +0300 + xorg-server (2:1.4.99.906-1ubuntu3) intrepid; urgency=low * 130_fedora_fix_procxkbsetxyz_to_work_on_all.patch diff --git a/debian/patches/137_add_device_property_support.patch b/debian/patches/137_add_device_property_support.patch new file mode 100644 index 0000000..4ad706a --- /dev/null +++ b/debian/patches/137_add_device_property_support.patch @@ -0,0 +1,1215 @@ +From 80f706255859726a584a4190ddecb6273d1c9f08 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer <[EMAIL PROTECTED]> +Date: Wed, 13 Aug 2008 15:48:11 +0930 +Subject: [PATCH] Add device property support. + +Cherry-picked from master, with the commits fixed and squashed. +--- + Xi/Makefile.am | 2 + + Xi/exglobals.h | 2 + + Xi/extinit.c | 36 +++ + Xi/xiproperty.c | 822 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + Xi/xiproperty.h | 43 +++ + dix/devices.c | 8 + + include/exevents.h | 61 ++++- + include/inputstr.h | 48 +++ + 8 files changed, 1021 insertions(+), 1 deletions(-) + create mode 100644 Xi/xiproperty.c + create mode 100644 Xi/xiproperty.h + +diff --git a/Xi/Makefile.am b/Xi/Makefile.am +index fbe4385..b08bbf0 100644 +--- a/Xi/Makefile.am ++++ b/Xi/Makefile.am +@@ -76,5 +76,7 @@ libXi_la_SOURCES = \ + ungrdevb.h \ + ungrdevk.c \ + ungrdevk.h ++ xiproperty.c \ ++ xiproperty.h + + EXTRA_DIST = stubs.c +diff --git a/Xi/exglobals.h b/Xi/exglobals.h +index 50bb33f..1740c29 100644 +--- a/Xi/exglobals.h ++++ b/Xi/exglobals.h +@@ -50,6 +50,7 @@ extern Mask DeviceOwnerGrabButtonMask; + extern Mask DeviceButtonGrabMask; + extern Mask DeviceButtonMotionMask; + extern Mask DevicePresenceNotifyMask; ++extern Mask DevicePropertyNotifyMask; + extern Mask PropagateMask[]; + + extern int DeviceValuator; +@@ -68,6 +69,7 @@ extern int DeviceButtonStateNotify; + extern int DeviceMappingNotify; + extern int ChangeDeviceNotify; + extern int DevicePresenceNotify; ++extern int DevicePropertyNotify; + + extern int RT_INPUTCLIENT; + +diff --git a/Xi/extinit.c b/Xi/extinit.c +index 2ffdafb..86160c4 100644 +--- a/Xi/extinit.c ++++ b/Xi/extinit.c +@@ -109,6 +109,8 @@ SOFTWARE. + #include "ungrdev.h" + #include "ungrdevb.h" + #include "ungrdevk.h" ++#include "xiproperty.c" ++ + + static Mask lastExtEventMask = 1; + int ExtEventIndex; +@@ -166,6 +168,7 @@ Mask DeviceOwnerGrabButtonMask; + Mask DeviceButtonGrabMask; + Mask DeviceButtonMotionMask; + Mask DevicePresenceNotifyMask; ++Mask DevicePropertyNotifyMask; + + int DeviceValuator; + int DeviceKeyPress; +@@ -183,6 +186,7 @@ int DeviceButtonStateNotify; + int DeviceMappingNotify; + int ChangeDeviceNotify; + int DevicePresenceNotify; ++int DevicePropertyNotify; + + int RT_INPUTCLIENT; + +@@ -288,6 +292,18 @@ ProcIDispatch(ClientPtr client) + return (ProcXGetDeviceControl(client)); + else if (stuff->data == X_ChangeDeviceControl) + return (ProcXChangeDeviceControl(client)); ++ else if (stuff->data == X_ListDeviceProperties) ++ return (ProcXListDeviceProperties(client)); ++ else if (stuff->data == X_QueryDeviceProperty) ++ return (ProcXQueryDeviceProperty(client)); ++ else if (stuff->data == X_ConfigureDeviceProperty) ++ return ProcXConfigureDeviceProperty(client); ++ else if (stuff->data == X_ChangeDeviceProperty) ++ return ProcXChangeDeviceProperty(client); ++ else if (stuff->data == X_DeleteDeviceProperty) ++ return ProcXDeleteDeviceProperty(client); ++ else if (stuff->data == X_GetDeviceProperty) ++ return ProcXGetDeviceProperty(client); + + return (BadRequest); + } +@@ -550,6 +566,17 @@ SDevicePresenceNotifyEvent (devicePresenceNotify *from, devicePresenceNotify *to + swaps(&to->control, n); + } + ++static void ++SDevicePropertyNotifyEvent (devicePropertyNotify *from, devicePropertyNotify *to) ++{ ++ char n; ++ ++ *to = *from; ++ swaps(&to->sequenceNumber,n); ++ swapl(&to->time, n); ++ swapl(&to->atom, n); ++} ++ + /************************************************************************** + * + * Allow the specified event to have its propagation suppressed. +@@ -670,6 +697,7 @@ FixExtensionEvents(ExtensionEntry * extEntry) + DeviceKeyStateNotify = ChangeDeviceNotify + 1; + DeviceButtonStateNotify = DeviceKeyStateNotify + 1; + DevicePresenceNotify = DeviceButtonStateNotify + 1; ++ DevicePropertyNotify = DevicePresenceNotify + 1; + + event_base[KeyClass] = DeviceKeyPress; + event_base[ButtonClass] = DeviceButtonPress; +@@ -745,6 +773,10 @@ FixExtensionEvents(ExtensionEntry * extEntry) + + DevicePresenceNotifyMask = GetNextExtEventMask(); + SetEventInfo(DevicePresenceNotifyMask, _devicePresence); ++ ++ DevicePropertyNotifyMask = GetNextExtEventMask(); ++ SetMaskForExtEvent(DevicePropertyNotifyMask, DevicePropertyNotify); ++ + SetEventInfo(0, _noExtensionEvent); + } + +@@ -786,6 +818,7 @@ RestoreExtensionEvents(void) + DeviceKeyStateNotify = 13; + DeviceButtonStateNotify = 13; + DevicePresenceNotify = 14; ++ DevicePropertyNotify = 15; + + BadDevice = 0; + BadEvent = 1; +@@ -824,6 +857,7 @@ IResetProc(ExtensionEntry * unused) + EventSwapVector[DeviceMappingNotify] = NotImplemented; + EventSwapVector[ChangeDeviceNotify] = NotImplemented; + EventSwapVector[DevicePresenceNotify] = NotImplemented; ++ EventSwapVector[DevicePropertyNotify] = NotImplemented; + RestoreExtensionEvents(); + } + +@@ -909,6 +943,8 @@ SEventIDispatch(xEvent * from, xEvent * to) + DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify); + else if (type == DevicePresenceNotify) + DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify); ++ else if (type == DevicePropertyNotify) ++ DO_SWAP(SDevicePropertyNotifyEvent, devicePropertyNotify); + else { + FatalError("XInputExtension: Impossible event!\n"); + } +diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c +new file mode 100644 +index 0000000..85a3caa +--- /dev/null ++++ b/Xi/xiproperty.c +@@ -0,0 +1,822 @@ ++/* ++ * Copyright © 2006 Keith Packard ++ * Copyright © 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 WAXIANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WAXIANTIES 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. ++ * ++ */ ++ ++/* This code is a modified version of randr/rrproperty.c */ ++ ++#ifdef HAVE_DIX_CONFIG_H ++#include <dix-config.h> ++#endif ++ ++#include "dix.h" ++#include "inputstr.h" ++#include <X11/extensions/XI.h> ++#include <X11/extensions/XIproto.h> ++#include "exglobals.h" ++#include "exevents.h" ++#include "swaprep.h" ++ ++#include "xiproperty.h" ++ ++static long XIPropHandlerID = 1; ++ ++/* Registers a new property handler on the given device and returns a unique ++ * identifier for this handler. This identifier is required to unregister the ++ * property handler again. ++ * @return The handler's identifier or 0 if an error occured. ++ */ ++long ++XIRegisterPropertyHandler(DeviceIntPtr dev, ++ Bool (*SetProperty) (DeviceIntPtr dev, ++ Atom property, ++ XIPropertyValuePtr prop), ++ Bool (*GetProperty) (DeviceIntPtr dev, ++ Atom property)) ++{ ++ XIPropertyHandlerPtr new_handler; ++ ++ new_handler = xcalloc(1, sizeof(XIPropertyHandler)); ++ if (!new_handler) ++ return 0; ++ ++ new_handler->id = XIPropHandlerID++; ++ new_handler->SetProperty = SetProperty; ++ new_handler->GetProperty = GetProperty; ++ new_handler->next = dev->properties.handlers; ++ dev->properties.handlers = new_handler; ++ ++ return new_handler->id; ++} ++ ++void ++XIUnRegisterPropertyHandler(DeviceIntPtr dev, long id) ++{ ++ XIPropertyHandlerPtr curr, prev = NULL; ++ ++ curr = dev->properties.handlers; ++ while(curr && curr->id != id) ++ { ++ prev = curr; ++ curr = curr->next; ++ } ++ ++ if (!curr) ++ return; ++ ++ if (!prev) /* first one */ ++ dev->properties.handlers = curr->next; ++ else ++ prev->next = curr->next; ++ ++ xfree(curr); ++} ++ ++static void ++XIInitDevicePropertyValue (XIPropertyValuePtr property_value) ++{ ++ property_value->type = None; ++ property_value->format = 0; ++ property_value->size = 0; ++ property_value->data = NULL; ++} ++ ++static XIPropertyPtr ++XICreateDeviceProperty (Atom property) ++{ ++ XIPropertyPtr prop; ++ ++ prop = (XIPropertyPtr)xalloc(sizeof(XIPropertyRec)); ++ if (!prop) ++ return NULL; ++ ++ prop->next = NULL; ++ prop->propertyName = property; ++ prop->is_pending = FALSE; ++ prop->range = FALSE; ++ prop->fromClient = FALSE; ++ prop->immutable = FALSE; ++ prop->num_valid = 0; ++ prop->valid_values = NULL; ++ ++ XIInitDevicePropertyValue (&prop->current); ++ XIInitDevicePropertyValue (&prop->pending); ++ return prop; ++} ++ ++static void ++XIDestroyDeviceProperty (XIPropertyPtr prop) ++{ ++ if (prop->valid_values) ++ xfree (prop->valid_values); ++ if (prop->current.data) ++ xfree(prop->current.data); ++ if (prop->pending.data) ++ xfree(prop->pending.data); ++ xfree(prop); ++} ++ ++/* This function destroys all of the device's property-related stuff, ++ * including removing all device handlers. ++ * DO NOT CALL FROM THE DRIVER. ++ */ ++void ++XIDeleteAllDeviceProperties (DeviceIntPtr device) ++{ ++ XIPropertyPtr prop, next; ++ XIPropertyHandlerPtr curr_handler, next_handler; ++ devicePropertyNotify event; ++ ++ for (prop = device->properties.properties; prop; prop = next) ++ { ++ next = prop->next; ++ ++ event.type = DevicePropertyNotify; ++ event.deviceid = device->id; ++ event.state = PropertyDelete; ++ event.atom = prop->propertyName; ++ event.time = currentTime.milliseconds; ++ SendEventToAllWindows(device, DevicePropertyNotifyMask, ++ (xEvent*)&event, 1); ++ ++ XIDestroyDeviceProperty(prop); ++ } ++ ++ /* Now free all handlers */ ++ curr_handler = device->properties.handlers; ++ while(curr_handler) ++ { ++ next_handler = curr_handler->next; ++ xfree(curr_handler); ++ curr_handler = next_handler; ++ } ++} ++ ++ ++int ++XIDeleteDeviceProperty (DeviceIntPtr device, Atom property, Bool fromClient) ++{ ++ XIPropertyPtr prop, *prev; ++ devicePropertyNotify event; ++ ++ for (prev = &device->properties.properties; (prop = *prev); prev = &(prop->next)) ++ if (prop->propertyName == property) ++ break; ++ ++ if (!prop->fromClient && fromClient) ++ return BadAtom; ++ ++ if (prop) ++ { ++ *prev = prop->next; ++ event.type = DevicePropertyNotify; ++ event.deviceid = device->id; ++ event.state = PropertyDelete; ++ event.atom = prop->propertyName; ++ event.time = currentTime.milliseconds; ++ SendEventToAllWindows(device, DevicePropertyNotifyMask, ++ (xEvent*)&event, 1); ++ XIDestroyDeviceProperty (prop); ++ } ++ ++ return Success; ++} ++ ++int ++XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type, ++ int format, int mode, unsigned long len, ++ pointer value, Bool sendevent, Bool pending, ++ Bool fromClient) ++{ ++ XIPropertyPtr prop; ++ devicePropertyNotify event; ++ int size_in_bytes; ++ int total_size; ++ unsigned long total_len; ++ XIPropertyValuePtr prop_value; ++ XIPropertyValueRec new_value; ++ Bool add = FALSE; ++ ++ size_in_bytes = format >> 3; ++ ++ /* first see if property already exists */ ++ prop = XIQueryDeviceProperty (dev, property); ++ if (!prop) /* just add to list */ ++ { ++ prop = XICreateDeviceProperty (property); ++ if (!prop) ++ return(BadAlloc); ++ prop->fromClient = fromClient; ++ add = TRUE; ++ mode = PropModeReplace; ++ } ++ if (pending && prop->is_pending) ++ prop_value = &prop->pending; ++ else ++ prop_value = &prop->current; ++ ++ /* To append or prepend to a property the request format and type ++ must match those of the already defined property. The ++ existing format and type are irrelevant when using the mode ++ "PropModeReplace" since they will be written over. */ ++ ++ if ((format != prop_value->format) && (mode != PropModeReplace)) ++ return(BadMatch); ++ if ((prop_value->type != type) && (mode != PropModeReplace)) ++ return(BadMatch); ++ new_value = *prop_value; ++ if (mode == PropModeReplace) ++ total_len = len; ++ else ++ total_len = prop_value->size + len; ++ ++ if (mode == PropModeReplace || len > 0) ++ { ++ pointer new_data = NULL, old_data = NULL; ++ ++ total_size = total_len * size_in_bytes; ++ new_value.data = (pointer)xalloc (total_size); ++ if (!new_value.data && total_size) ++ { ++ if (add) ++ XIDestroyDeviceProperty (prop); ++ return BadAlloc; ++ } ++ new_value.size = len; ++ new_value.type = type; ++ new_value.format = format; ++ ++ switch (mode) { ++ case PropModeReplace: ++ new_data = new_value.data; ++ old_data = NULL; ++ break; ++ case PropModeAppend: ++ new_data = (pointer) (((char *) new_value.data) + ++ (prop_value->size * size_in_bytes)); ++ old_data = new_value.data; ++ break; ++ case PropModePrepend: ++ new_data = new_value.data; ++ old_data = (pointer) (((char *) new_value.data) + ++ (prop_value->size * size_in_bytes)); ++ break; ++ } ++ if (new_data) ++ memcpy ((char *) new_data, (char *) value, len * size_in_bytes); ++ if (old_data) ++ memcpy ((char *) old_data, (char *) prop_value->data, ++ prop_value->size * size_in_bytes); ++ ++ /* We must set pendingProperties TRUE before we commit to the driver, ++ we're in a single thread after all ++ */ ++ if (pending && prop->is_pending) ++ dev->properties.pendingProperties = TRUE; ++ if (pending && dev->properties.handlers) ++ { ++ XIPropertyHandlerPtr handler = dev->properties.handlers; ++ while(handler) ++ { ++ if (!handler->SetProperty(dev, prop->propertyName, &new_value)) ++ { ++ if (new_value.data) ++ xfree (new_value.data); ++ return (BadValue); ++ } ++ handler = handler->next; ++ } ++ } ++ if (prop_value->data) ++ xfree (prop_value->data); ++ *prop_value = new_value; ++ } ++ ++ else if (len == 0) ++ { ++ /* do nothing */ ++ } ++ ++ if (add) ++ { ++ prop->next = dev->properties.properties; ++ dev->properties.properties = prop; ++ } ++ ++ ++ if (sendevent) ++ { ++ event.type = DevicePropertyNotify; ++ event.deviceid = dev->id; ++ event.state = PropertyNewValue; ++ event.atom = prop->propertyName; ++ event.time = currentTime.milliseconds; ++ SendEventToAllWindows(dev, DevicePropertyNotifyMask, ++ (xEvent*)&event, 1); ++ } ++ return(Success); ++} ++ ++XIPropertyPtr ++XIQueryDeviceProperty (DeviceIntPtr dev, Atom property) ++{ ++ XIPropertyPtr prop; ++ ++ for (prop = dev->properties.properties; prop; prop = prop->next) ++ if (prop->propertyName == property) ++ return prop; ++ return NULL; ++} ++ ++XIPropertyValuePtr ++XIGetDeviceProperty (DeviceIntPtr dev, Atom property, Bool pending) ++{ ++ XIPropertyPtr prop = XIQueryDeviceProperty (dev, property); ++ ++ if (!prop) ++ return NULL; ++ if (pending && prop->is_pending) ++ return &prop->pending; ++ else { ++ /* If we can, try to update the property value first */ ++ if (dev->properties.handlers) ++ { ++ XIPropertyHandlerPtr handler = dev->properties.handlers; ++ while(handler) ++ { ++ handler->GetProperty(dev, prop->propertyName); ++ handler = handler->next; ++ } ++ } ++ return &prop->current; ++ } ++} ++ ++int ++XIConfigureDeviceProperty (DeviceIntPtr dev, Atom property, ++ Bool pending, Bool range, Bool immutable, ++ int num_values, INT32 *values) ++{ ++ XIPropertyPtr prop = XIQueryDeviceProperty (dev, property); ++ Bool add = FALSE; ++ INT32 *new_values; ++ ++ if (!prop) ++ { ++ prop = XICreateDeviceProperty (property); ++ if (!prop) ++ return(BadAlloc); ++ add = TRUE; ++ } else if (prop->immutable && !immutable) ++ return(BadAccess); ++ ++ /* ++ * ranges must have even number of values ++ */ ++ if (range && (num_values & 1)) ++ return BadMatch; ++ ++ new_values = xalloc (num_values * sizeof (INT32)); ++ if (!new_values && num_values) ++ return BadAlloc; ++ if (num_values) ++ memcpy (new_values, values, num_values * sizeof (INT32)); ++ ++ /* ++ * Property moving from pending to non-pending ++ * loses any pending values ++ */ ++ if (prop->is_pending && !pending) ++ { ++ if (prop->pending.data) ++ xfree (prop->pending.data); ++ XIInitDevicePropertyValue (&prop->pending); ++ } ++ ++ prop->is_pending = pending; ++ prop->range = range; ++ prop->immutable = immutable; ++ prop->num_valid = num_values; ++ if (prop->valid_values) ++ xfree (prop->valid_values); ++ prop->valid_values = new_values; ++ ++ if (add) { ++ prop->next = dev->properties.properties; ++ dev->properties.properties = prop; ++ } ++ ++ return Success; ++} ++ ++int ++ProcXListDeviceProperties (ClientPtr client) ++{ ++ Atom *pAtoms = NULL, *temppAtoms; ++ xListDevicePropertiesReply rep; ++ int numProps = 0; ++ DeviceIntPtr dev; ++ XIPropertyPtr prop; ++ int rc = Success; ++ ++ REQUEST(xListDevicePropertiesReq); ++ REQUEST_SIZE_MATCH(xListDevicePropertiesReq); ++ ++ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixReadAccess); ++ if (rc != Success) ++ return rc; ++ ++ for (prop = dev->properties.properties; prop; prop = prop->next) ++ numProps++; ++ if (numProps) ++ if(!(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom)))) ++ return(BadAlloc); ++ ++ rep.repType = X_Reply; ++ rep.RepType = X_ListDeviceProperties; ++ rep.length = (numProps * sizeof(Atom)) >> 2; ++ rep.sequenceNumber = client->sequence; ++ rep.nAtoms = numProps; ++ if (client->swapped) ++ { ++ int n; ++ swaps (&rep.sequenceNumber, n); ++ swapl (&rep.length, n); ++ } ++ temppAtoms = pAtoms; ++ for (prop = dev->properties.properties; prop; prop = prop->next) ++ *temppAtoms++ = prop->propertyName; ++ ++ WriteReplyToClient(client, sizeof(xListDevicePropertiesReply), &rep); ++ if (numProps) ++ { ++ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; ++ WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); ++ xfree(pAtoms); ++ } ++ return rc; ++} ++ ++int ++ProcXQueryDeviceProperty (ClientPtr client) ++{ ++ REQUEST(xQueryDevicePropertyReq); ++ xQueryDevicePropertyReply rep; ++ DeviceIntPtr dev; ++ XIPropertyPtr prop; ++ int rc; ++ ++ REQUEST_SIZE_MATCH(xQueryDevicePropertyReq); ++ ++ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixReadAccess); ++ ++ if (rc != Success) ++ return rc; ++ ++ prop = XIQueryDeviceProperty (dev, stuff->property); ++ if (!prop) ++ return BadName; ++ ++ rep.repType = X_Reply; ++ rep.length = prop->num_valid; ++ rep.sequenceNumber = client->sequence; ++ rep.pending = prop->is_pending; ++ rep.range = prop->range; ++ rep.immutable = prop->immutable; ++ rep.fromClient = prop->fromClient; ++ if (client->swapped) ++ { ++ int n; ++ swaps (&rep.sequenceNumber, n); ++ swapl (&rep.length, n); ++ } ++ WriteReplyToClient (client, sizeof (xQueryDevicePropertyReply), &rep); ++ if (prop->num_valid) ++ { ++ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; ++ WriteSwappedDataToClient(client, prop->num_valid * sizeof(INT32), ++ prop->valid_values); ++ } ++ return(client->noClientException); ++} ++ ++int ++ProcXConfigureDeviceProperty (ClientPtr client) ++{ ++ REQUEST(xConfigureDevicePropertyReq); ++ DeviceIntPtr dev; ++ int num_valid; ++ int rc; ++ ++ REQUEST_AT_LEAST_SIZE(xConfigureDevicePropertyReq); ++ ++ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixReadAccess); ++ ++ if (rc != Success) ++ return rc; ++ ++ num_valid = stuff->length - (sizeof (xConfigureDevicePropertyReq) >> 2); ++ return XIConfigureDeviceProperty (dev, stuff->property, ++ stuff->pending, stuff->range, ++ FALSE, num_valid, ++ (INT32 *) (stuff + 1)); ++} ++ ++int ++ProcXChangeDeviceProperty (ClientPtr client) ++{ ++ REQUEST(xChangeDevicePropertyReq); ++ DeviceIntPtr dev; ++ char format, mode; ++ unsigned long len; ++ int sizeInBytes; ++ int totalSize; ++ int rc; ++ ++ REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq); ++ UpdateCurrentTime(); ++ format = stuff->format; ++ mode = stuff->mode; ++ if ((mode != PropModeReplace) && (mode != PropModeAppend) && ++ (mode != PropModePrepend)) ++ { ++ client->errorValue = mode; ++ return BadValue; ++ } ++ if ((format != 8) && (format != 16) && (format != 32)) ++ { ++ client->errorValue = format; ++ return BadValue; ++ } ++ len = stuff->nUnits; ++ if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2)) ++ return BadLength; ++ sizeInBytes = format>>3; ++ totalSize = len * sizeInBytes; ++ REQUEST_FIXED_SIZE(xChangeDevicePropertyReq, totalSize); ++ ++ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixWriteAccess); ++ if (rc != Success) ++ return rc; ++ ++ if (!ValidAtom(stuff->property)) ++ { ++ client->errorValue = stuff->property; ++ return(BadAtom); ++ } ++ if (!ValidAtom(stuff->type)) ++ { ++ client->errorValue = stuff->type; ++ return(BadAtom); ++ } ++ ++ rc = XIChangeDeviceProperty(dev, stuff->property, ++ stuff->type, (int)format, ++ (int)mode, len, (pointer)&stuff[1], TRUE, ++ TRUE, TRUE); ++ ++ return rc; ++} ++ ++int ++ProcXDeleteDeviceProperty (ClientPtr client) ++{ ++ REQUEST(xDeleteDevicePropertyReq); ++ DeviceIntPtr dev; ++ int rc; ++ ++ REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq); ++ UpdateCurrentTime(); ++ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixWriteAccess); ++ if (rc != Success) ++ return rc; ++ ++ if (!ValidAtom(stuff->property)) ++ { ++ client->errorValue = stuff->property; ++ return (BadAtom); ++ } ++ ++ ++ rc = XIDeleteDeviceProperty(dev, stuff->property, TRUE); ++ return rc; ++} ++ ++int ++ProcXGetDeviceProperty (ClientPtr client) ++{ ++ REQUEST(xGetDevicePropertyReq); ++ XIPropertyPtr prop, *prev; ++ XIPropertyValuePtr prop_value; ++ unsigned long n, len, ind; ++ DeviceIntPtr dev; ++ xGetDevicePropertyReply reply; ++ int rc; ++ ++ REQUEST_SIZE_MATCH(xGetDevicePropertyReq); ++ if (stuff->delete) ++ UpdateCurrentTime(); ++ rc = dixLookupDevice (&dev, stuff->deviceid, client, ++ stuff->delete ? DixWriteAccess : ++ DixReadAccess); ++ if (rc != Success) ++ return rc; ++ ++ if (!ValidAtom(stuff->property)) ++ { ++ client->errorValue = stuff->property; ++ return(BadAtom); ++ } ++ if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) ++ { ++ client->errorValue = stuff->delete; ++ return(BadValue); ++ } ++ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) ++ { ++ client->errorValue = stuff->type; ++ return(BadAtom); ++ } ++ ++ for (prev = &dev->properties.properties; (prop = *prev); prev = &prop->next) ++ if (prop->propertyName == stuff->property) ++ break; ++ ++ reply.repType = X_Reply; ++ reply.RepType = X_GetDeviceProperty; ++ reply.sequenceNumber = client->sequence; ++ reply.deviceid = dev->id; ++ if (!prop) ++ { ++ reply.nItems = 0; ++ reply.length = 0; ++ reply.bytesAfter = 0; ++ reply.propertyType = None; ++ reply.format = 0; ++ WriteReplyToClient(client, sizeof(xGetDevicePropertyReply), &reply); ++ return(client->noClientException); ++ } ++ ++ if (prop->immutable && stuff->delete) ++ return BadAccess; ++ ++ prop_value = XIGetDeviceProperty(dev, stuff->property, stuff->pending); ++ if (!prop_value) ++ return BadAtom; ++ ++ /* If the request type and actual type don't match. Return the ++ property information, but not the data. */ ++ ++ if (((stuff->type != prop_value->type) && ++ (stuff->type != AnyPropertyType)) ++ ) ++ { ++ reply.bytesAfter = prop_value->size; ++ reply.format = prop_value->format; ++ reply.length = 0; ++ reply.nItems = 0; ++ reply.propertyType = prop_value->type; ++ WriteReplyToClient(client, sizeof(xGetDevicePropertyReply), &reply); ++ return(client->noClientException); ++ } ++ ++/* ++ * Return type, format, value to client ++ */ ++ n = (prop_value->format/8) * prop_value->size; /* size (bytes) of prop */ ++ ind = stuff->longOffset << 2; ++ ++ /* If longOffset is invalid such that it causes "len" to ++ be negative, it's a value error. */ ++ ++ if (n < ind) ++ { ++ client->errorValue = stuff->longOffset; ++ return BadValue; ++ } ++ ++ len = min(n - ind, 4 * stuff->longLength); ++ ++ reply.bytesAfter = n - (ind + len); ++ reply.format = prop_value->format; ++ reply.length = (len + 3) >> 2; ++ if (prop_value->format) ++ reply.nItems = len / (prop_value->format / 8); ++ else ++ reply.nItems = 0; ++ reply.propertyType = prop_value->type; ++ ++ if (stuff->delete && (reply.bytesAfter == 0)) ++ { ++ devicePropertyNotify event; ++ ++ event.type = DevicePropertyNotify; ++ event.deviceid = dev->id; ++ event.state = PropertyDelete; ++ event.atom = prop->propertyName; ++ event.time = currentTime.milliseconds; ++ SendEventToAllWindows(dev, DevicePropertyNotifyMask, ++ (xEvent*)&event, 1); ++ } ++ ++ WriteReplyToClient(client, sizeof(xGenericReply), &reply); ++ if (len) ++ { ++ switch (reply.format) { ++ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break; ++ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break; ++ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break; ++ } ++ WriteSwappedDataToClient(client, len, -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]