|
From: Peter H. <pet...@wh...> - 2010-05-24 02:50:47
|
Note that the patch below won't apply just yet, you'll need some changes to
the X server, marginal ones though. Also, hence the FIXME's the ABI number
needs to be bumped.
The problem we face at the moment is that the driver can hotplug dependent
devices but the configuration options from the xorg.conf.d snippets only
apply to the first device (usually the stylus). It's not possible to use
xorg.conf.d snippets to configure the eraser, for example.
With a proposed change to the X server to copy the input attributes into the
device file, we can counteract this by passing these attributes to the next
device. The attributes are essentially what we get from the config backend
(hal or udev) and contain some of the information exported by the kernel.
That's easy enough and the code is quite straightforward as you can see
below.
Now, what we need to decide on though is which path to chose for the extra
information (this patch implements both).
Approach 1 is to append the type to the product name - as we do with the
device name. So if the device has a product name of "Wacom Intuos", the
eraser will have a product name of "Wacom Intuos eraser".
This would lead to the following configuration:
Section "InputClass"
Identifier "Wacom eraser class"
MatchProduct "Wacom"
MatchProduct "eraser"
Option "Foo" "bar"
EndSection
MatchProduct doesn't do regex, so a match of "Wacom*eraser" won't work, it
has to be two different lines.
The MatchProduct "Wacom" is just there so other devices that may have
"eraser" in their name won't get matched.
Approach 2 is to append the type to the tags (tags are arbitrary names
assigned to devices by the config backend that can be mached against).
This would lead to the following configuration:
Section "InputClass"
Identifier "Wacom eraser class"
MatchProduct "Wacom"
MatchTag "eraser"
Option "Foo" "bar"
EndSection
The MatchProduct "Wacom" is just there so other devices that may have the
same tag don't get matched.
I personally prefer the first approach since the name is quite exposed
already anyway and it IMO makes for more obvious matching. But I'd like to
hear some comments on which one is preferable.
Cheers,
Peter
---
src/wcmValidateDevice.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 83 insertions(+), 1 deletions(-)
diff --git a/src/wcmValidateDevice.c b/src/wcmValidateDevice.c
index 438cf38..3f668b4 100644
--- a/src/wcmValidateDevice.c
+++ b/src/wcmValidateDevice.c
@@ -295,6 +295,76 @@ static void wcmFreeInputOpts(InputOption* opts)
}
}
+/* FIXME: should be different number */
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 9
+/**
+ * Duplicate the attributes of the given device. "product" gets the type
+ * appended, so a device of product "Wacom" will then have a product "Wacom
+ * eraser", "Wacom cursor", etc.
+ * And the type is added to the tags as well.
+ */
+static InputAttributes* wcmDuplicateAttributes(LocalDevicePtr local,
+ const char *type)
+{
+ InputAttributes *new_attr = NULL;
+
+ InputAttributes *attr = local->attrs;
+ char **tag, **new_tag;
+ int ntags = 0;
+
+ new_attr = calloc(1, sizeof(InputAttributes));
+ new_attr->flags = attr->flags;
+ if (attr->vendor)
+ new_attr->vendor = strdup(attr->vendor);
+ if (attr->device)
+ new_attr->device = strdup(attr->device);
+
+ if (attr->product)
+ {
+ /* one space, one \0 */
+ new_attr->product = calloc(strlen(attr->product) + strlen(type) + 2, 1);
+ strcpy(new_attr->product, attr->product);
+ }
+ if (type) {
+ strcat(new_attr->product, " ");
+ strcat(new_attr->product, type);
+ }
+
+ tag = attr->tags;
+ while(*tag++)
+ ntags++;
+
+ new_attr->tags = calloc(ntags + 2, sizeof(char*));
+
+ tag = attr->tags;
+ new_tag = new_attr->tags;
+ while(*tag)
+ {
+ *new_tag = strdup(*tag);
+ tag++;
+ new_tag++;
+ }
+ *new_tag = strdup(type);
+ return new_attr;
+}
+
+static void wcmFreeAttributes(InputAttributes *attr)
+{
+ char **tag = attr->tags;
+ while(*tag)
+ {
+ free(*tag);
+ tag++;
+ }
+
+ free(attr->tags);
+ free(attr->product);
+ free(attr->vendor);
+ free(attr->device);
+ free(attr);
+}
+#endif
+
/**
* Hotplug one device of the given type.
* Device has the same options as the "parent" device, type is one of
@@ -305,15 +375,27 @@ static void wcmHotplug(LocalDevicePtr local, const char *type)
{
DeviceIntPtr dev; /* dummy */
InputOption *input_options;
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 9
+ InputAttributes *attrs = NULL;
+#endif
input_options = wcmOptionDupConvert(local, type);
+/* FIXME: should be different number */
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 9
+ attrs = wcmDuplicateAttributes(local, type);
+#endif
+
NewInputDeviceRequest(input_options,
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 9
- NULL,
+ attrs,
#endif
&dev);
wcmFreeInputOpts(input_options);
+
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 9
+ wcmFreeAttributes(attrs);
+#endif
}
void wcmHotplugOthers(LocalDevicePtr local)
--
1.7.0.1
|