xserver: Branch 'master' - 2 commits

Keith Packard keithp at kemper.freedesktop.org
Tue May 25 10:10:22 PDT 2010


 dix/inpututils.c               |   79 +++++++++++++++++++++++++++++++
 hw/xfree86/common/xf86Helper.c |    2 
 hw/xfree86/common/xf86Option.c |    4 +
 hw/xfree86/common/xf86Xinput.c |    3 -
 hw/xfree86/common/xf86Xinput.h |    1 
 hw/xfree86/common/xf86str.h    |    1 
 include/input.h                |    2 
 test/input.c                   |  102 +++++++++++++++++++++++++++++++++++++++++
 8 files changed, 193 insertions(+), 1 deletion(-)

New commits:
commit c2d0b3b437b7ce6ce975f2ead4d8bb8295ef0ddc
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 25 17:15:32 2010 +1000

    xfree86: store the InputAttributes in the input device.
    
    InputAttributes largely decide which configuration values get merged from
    the xorg.conf.d snippets. While they are available in the config backend,
    they are not available for any other callers of NewInputDeviceRequest().
    
    Drivers implementing driver-side hotplugging do not have access to these
    attributes and cannot have xorg.conf.d snippets specific to dependent
    devices. For example, the following case cannot work right now:
    
    Section "InputClass"
            MatchProduct "Wacom"
            Option "PressCurve" "0 0 100 100"
            ...
    EndSection
    
    Section "InputClass"
            MatchProduct "Wacom"
            MatchProduct "eraser"
            Option "PressCurve" "10 10 50 50"
            ...
    EndSection
    
    The second section is not triggered, as the wacom driver cannot supply the
    InputAttributes to NewInputDeviceRequest().
    
    Add the attributes to the IDevRec and merge them into the InputInfoRec to
    make them accessible in the driver. This changes the ABI for input drivers.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dan Nicholson <dbn.lists at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index bde80ea..d4b9351 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -330,6 +330,8 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
     if (pInp->private)
 	free(pInp->private);
 
+    FreeInputAttributes(pInp->attrs);
+
     /* Remove the entry from the list. */
     if (pInp == xf86InputDevs)
 	xf86InputDevs = pInp->next;
diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index 8be893c..61d0dcc 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -164,6 +164,10 @@ xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
 	else
 	    pInfo->options = tmp;
     }
+
+    if (pInfo->conf_idev && pInfo->conf_idev->attrs) {
+        pInfo->attrs = pInfo->conf_idev->attrs;
+    }
 }
 
 /* Created for new XInput stuff -- essentially extensions to the parser	*/
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 2e25482..356ddab 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -622,7 +622,6 @@ MergeInputClasses(IDevPtr idev, InputAttributes *attrs)
         mergedopts = xf86ReplaceStrOption(mergedopts, "driver", idev->driver);
     }
     idev->commonOptions = xf86optionListMerge(idev->commonOptions, mergedopts);
-
     return Success;
 }
 
@@ -822,6 +821,8 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
         rval = MergeInputClasses(idev, attrs);
         if (rval != Success)
             goto unwind;
+
+        idev->attrs = DuplicateInputAttributes(attrs);
     }
 
     if (!idev->driver || !idev->identifier) {
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index aa9e9d5..20a3f1b 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -148,6 +148,7 @@ typedef struct _LocalDeviceRec {
     pointer		    module;
     pointer		    options;
     unsigned int            history_size;
+    InputAttributes         *attrs;
 } LocalDeviceRec, *LocalDevicePtr, InputInfoRec, *InputInfoPtr;
 
 typedef struct _DeviceAssocRec 
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 22f0261..c9b261d 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -406,6 +406,7 @@ typedef struct {
    char *			driver;
    pointer		 	commonOptions;
    pointer			extraOptions;
+   InputAttributes              *attrs;
 } IDevRec, *IDevPtr;
 
 typedef struct {
commit 86303a338ad563d0b986a3c052104301c310c4ac
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 25 17:12:34 2010 +1000

    dix: add helper functions to duplicate and free InputAttributes.
    
    No special memory handling is used to give drivers the maximum flexibility
    with the data. Drivers should be able to call realloc on the product string
    if needed and perform similar operations.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dan Nicholson <dbn.lists at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/inpututils.c b/dix/inpututils.c
index 8e75372..df2ace0 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -331,3 +331,82 @@ int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
 
     return Success;
 }
+
+/**
+ * Duplicate the InputAttributes in the most obvious way.
+ * No special memory handling is used to give drivers the maximum
+ * flexibility with the data. Drivers should be able to call realloc on the
+ * product string if needed and perform similar operations.
+ */
+InputAttributes*
+DuplicateInputAttributes(InputAttributes *attrs)
+{
+    InputAttributes *new_attr;
+    int ntags = 0;
+    char **tags, **new_tags;
+
+    if (!attrs)
+        return NULL;
+
+    if (!(new_attr = calloc(1, sizeof(InputAttributes))))
+        goto unwind;
+
+    if (attrs->product && !(new_attr->product = strdup(attrs->product)))
+        goto unwind;
+    if (attrs->vendor && !(new_attr->vendor = strdup(attrs->vendor)))
+        goto unwind;
+    if (attrs->device && !(new_attr->device = strdup(attrs->device)))
+        goto unwind;
+
+    new_attr->flags = attrs->flags;
+
+    if ((tags = attrs->tags))
+    {
+        while(*tags++)
+            ntags++;
+
+        new_attr->tags = calloc(ntags + 1, sizeof(char*));
+        if (!new_attr->tags)
+            goto unwind;
+
+        tags = attrs->tags;
+        new_tags = new_attr->tags;
+
+        while(*tags)
+        {
+            *new_tags = strdup(*tags);
+            if (!*new_tags)
+                goto unwind;
+
+            tags++;
+            new_tags++;
+        }
+    }
+
+    return new_attr;
+
+unwind:
+    FreeInputAttributes(new_attr);
+    return NULL;
+}
+
+void
+FreeInputAttributes(InputAttributes *attrs)
+{
+    char **tags;
+
+    if (!attrs)
+        return;
+
+    free(attrs->product);
+    free(attrs->vendor);
+    free(attrs->device);
+
+    if ((tags = attrs->tags))
+        while(*tags)
+            free(*tags++);
+
+    free(attrs->tags);
+    free(attrs);
+}
+
diff --git a/include/input.h b/include/input.h
index 63f981e..c68a284 100644
--- a/include/input.h
+++ b/include/input.h
@@ -518,6 +518,8 @@ extern int AllocXTestDevice(ClientPtr client,
 extern BOOL IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master);
 extern DeviceIntPtr GetXTestDevice(DeviceIntPtr master);
 extern void SendDevicePresenceEvent(int deviceid, int type);
+extern _X_EXPORT InputAttributes *DuplicateInputAttributes(InputAttributes *attrs);
+extern _X_EXPORT void FreeInputAttributes(InputAttributes *attrs);
 
 /* misc event helpers */
 extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
diff --git a/test/input.c b/test/input.c
index 63d1a18..8a54af9 100644
--- a/test/input.c
+++ b/test/input.c
@@ -771,11 +771,112 @@ static void xi_unregister_handlers(void)
 
 }
 
+static void cmp_attr_fields(InputAttributes *attr1,
+                            InputAttributes *attr2)
+{
+    char **tags1, **tags2;
+
+    g_assert(attr1 && attr2);
+    g_assert(attr1 != attr2);
+    g_assert(attr1->flags == attr2->flags);
+
+    if (attr1->product != NULL)
+    {
+        g_assert(attr1->product != attr2->product);
+        g_assert(strcmp(attr1->product, attr2->product) == 0);
+    } else
+        g_assert(attr2->product == NULL);
+
+    if (attr1->vendor != NULL)
+    {
+        g_assert(attr1->vendor != attr2->vendor);
+        g_assert(strcmp(attr1->vendor, attr2->vendor) == 0);
+    } else
+        g_assert(attr2->vendor == NULL);
+
+    if (attr1->device != NULL)
+    {
+        g_assert(attr1->device != attr2->device);
+        g_assert(strcmp(attr1->device, attr2->device) == 0);
+    } else
+        g_assert(attr2->device == NULL);
+
+    tags1 = attr1->tags;
+    tags2 = attr2->tags;
+    if (!tags1)
+    {
+        g_assert(!tags2);
+        return;
+    }
+
+    /* check for identical content, but duplicated */
+    while (*tags1)
+    {
+        g_assert(*tags1 != *tags2);
+        g_assert(strcmp(*tags1, *tags2) == 0);
+        tags1++;
+        tags2++;
+    }
+
+    g_assert(!*tags2);
+
+    /* check for not sharing memory */
+    tags1 = attr1->tags;
+    while (*tags1)
+    {
+        tags2 = attr2->tags;
+        while (*tags2)
+            g_assert(*tags1 != *tags2++);
+
+        tags1++;
+    }
+}
+
+static void dix_input_attributes(void)
+{
+    InputAttributes orig = {0};
+    InputAttributes *new;
+    char *tags[4] = {"tag1", "tag2", "tag2", NULL};
+
+    new = DuplicateInputAttributes(NULL);
+    g_assert(!new);
+
+    new = DuplicateInputAttributes(&orig);
+    g_assert(memcpy(&orig, new, sizeof(InputAttributes)));
+
+    orig.product = "product name";
+    new = DuplicateInputAttributes(&orig);
+    cmp_attr_fields(&orig, new);
+    FreeInputAttributes(new);
+
+    orig.vendor = "vendor name";
+    new = DuplicateInputAttributes(&orig);
+    cmp_attr_fields(&orig, new);
+    FreeInputAttributes(new);
+
+    orig.device = "device path";
+    new = DuplicateInputAttributes(&orig);
+    cmp_attr_fields(&orig, new);
+    FreeInputAttributes(new);
+
+    orig.flags = 0xF0;
+    new = DuplicateInputAttributes(&orig);
+    cmp_attr_fields(&orig, new);
+    FreeInputAttributes(new);
+
+    orig.tags = tags;
+    new = DuplicateInputAttributes(&orig);
+    cmp_attr_fields(&orig, new);
+    FreeInputAttributes(new);
+}
+
+
 int main(int argc, char** argv)
 {
     g_test_init(&argc, &argv,NULL);
     g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
 
+    g_test_add_func("/dix/input/attributes", dix_input_attributes);
     g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
     g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
     g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
@@ -784,5 +885,6 @@ int main(int argc, char** argv)
     g_test_add_func("/include/byte_padding_macros", include_byte_padding_macros);
     g_test_add_func("/Xi/xiproperty/register-unregister", xi_unregister_handlers);
 
+
     return g_test_run();
 }


More information about the xorg-commit mailing list