[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xorg-server: Changes to 'ubuntu'



 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 <tjaalton@cc.hut.fi>
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 <tepsipakki@ubuntu.com>  Wed, 13 Aug 2008 10:45:48 +0300
+ -- Timo Aaltonen <tepsipakki@ubuntu.com>  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 <tjaalton@cc.hut.fi>
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 <tepsipakki@ubuntu.com>  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 <peter.hutterer@redhat.com>
+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,


Reply to: