diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c index bd130d1f9..72efb67b1 100644 --- a/Xi/xiproperty.c +++ b/Xi/xiproperty.c @@ -98,7 +98,9 @@ XIRegisterPropertyHandler(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop), int (*GetProperty) (DeviceIntPtr dev, - Atom property)) + Atom property), + int (*DeleteProperty) (DeviceIntPtr dev, + Atom property)) { XIPropertyHandlerPtr new_handler; @@ -109,6 +111,7 @@ XIRegisterPropertyHandler(DeviceIntPtr dev, new_handler->id = XIPropHandlerID++; new_handler->SetProperty = SetProperty; new_handler->GetProperty = GetProperty; + new_handler->DeleteProperty = DeleteProperty; new_handler->next = dev->properties.handlers; dev->properties.handlers = new_handler; @@ -153,6 +156,7 @@ XICreateDeviceProperty (Atom property) prop->value.format = 0; prop->value.size = 0; prop->value.data = NULL; + prop->deletable = TRUE; return prop; } @@ -218,11 +222,29 @@ XIDeleteDeviceProperty (DeviceIntPtr device, Atom property, Bool fromClient) { XIPropertyPtr prop, *prev; devicePropertyNotify event; + int rc = Success; for (prev = &device->properties.properties; (prop = *prev); prev = &(prop->next)) if (prop->propertyName == property) break; + if (fromClient && !prop->deletable) + return BadAccess; + + /* Ask handlers if we may delete the property */ + if (device->properties.handlers) + { + XIPropertyHandlerPtr handler = device->properties.handlers; + while(handler) + { + if (handler->DeleteProperty) + rc = handler->DeleteProperty(device, prop->propertyName); + if (rc != Success) + return (rc); + handler = handler->next; + } + } + if (prop) { *prev = prop->next; @@ -402,6 +424,18 @@ XIGetDeviceProperty (DeviceIntPtr dev, Atom property, XIPropertyValuePtr *value) return Success; } +int +XISetDevicePropertyDeletable(DeviceIntPtr dev, Atom property, Bool deletable) +{ + XIPropertyPtr prop = XIFetchDeviceProperty(dev, property); + + if (!prop) + return BadAtom; + + prop->deletable = deletable; + return Success; +} + int ProcXListDeviceProperties (ClientPtr client) { diff --git a/dix/devices.c b/dix/devices.c index fb634730f..e6f21c924 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -223,7 +223,8 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), XA_INTEGER, 8, PropModeReplace, 1, &dev->enabled, FALSE); - XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL); + XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE); + XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL); return dev; } diff --git a/include/exevents.h b/include/exevents.h index c3a2ad610..4df0aee48 100644 --- a/include/exevents.h +++ b/include/exevents.h @@ -222,13 +222,21 @@ extern int XIGetDeviceProperty( XIPropertyValuePtr* /* value */ ); +extern int XISetDevicePropertyDeletable( + DeviceIntPtr /* dev */, + Atom /* property */, + Bool /* deletable */ +); + extern long XIRegisterPropertyHandler( DeviceIntPtr dev, int (*SetProperty) (DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop), int (*GetProperty) (DeviceIntPtr dev, - Atom property) + Atom property), + int (*DeleteProperty) (DeviceIntPtr dev, + Atom property) ); extern void XIUnRegisterPropertyHandler( diff --git a/include/inputstr.h b/include/inputstr.h index 93b32934d..65cb1b97f 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -353,6 +353,7 @@ typedef struct _XIProperty { struct _XIProperty *next; Atom propertyName; + BOOL deletable; /* clients can delete this prop? */ XIPropertyValueRec value; } XIPropertyRec; @@ -369,6 +370,8 @@ typedef struct _XIPropertyHandler XIPropertyValuePtr prop); int (*GetProperty) (DeviceIntPtr dev, Atom property); + int (*DeleteProperty) (DeviceIntPtr dev, + Atom property); } XIPropertyHandler, *XIPropertyHandlerPtr; /* states for devices */