To support generic tablets, we need to extend the matching pattern of
libwacom. The Huion tablets reuse the same VID:PID accross all of the
products. To be able to differentiate between the models, we can somewhat
rely on the name of the product. It doesn't seem very reliable (for
instance, the H610 Pro and the W58 seems to share the same name), but it
should allow a good amount of them to be added to the DB.

The current usb:VID:PID pattern is still working, we add a new pattern
usb:VID:PID:NAME.

For devices with their name in the matching pattern, the function
libwacom_new_from_usbid() does not work. We encourage users to use
libwacom_new_from_path() instead. (g-c-c and g-s-d already use that, and
libinput just switched to it).
---

changes in v3:
- rebased on top of previous one

changes in v2:
- libwacom_new_from_path() now tries with or without name (or an extra match
  was appended to the device)
- rebased on previous patch

 libwacom/libwacom-database.c | 25 ++++++++++++++++++-------
 libwacom/libwacom.c          | 43 ++++++++++++++++++++++++++++++-------------
 libwacom/libwacom.h          |  1 +
 libwacom/libwacomint.h       |  6 +++---
 4 files changed, 52 insertions(+), 23 deletions(-)

diff --git a/libwacom/libwacom-database.c b/libwacom/libwacom-database.c
index 3b39dba..841d2b4 100644
--- a/libwacom/libwacom-database.c
+++ b/libwacom/libwacom-database.c
@@ -124,16 +124,21 @@ bus_to_str (WacomBusType bus)
 }
 
 char *
-make_match_string (WacomBusType bus, int vendor_id, int product_id)
+make_match_string (const char *name, WacomBusType bus, int vendor_id, int 
product_id)
 {
-       return g_strdup_printf("%s:%04x:%04x", bus_to_str (bus), vendor_id, 
product_id);
+       return g_strdup_printf("%s:%04x:%04x%s%s",
+                               bus_to_str (bus),
+                               vendor_id, product_id,
+                               name ? ":" : "",
+                               name ? name : "");
 }
 
 static gboolean
 libwacom_matchstr_to_match(WacomDevice *device, const char *match)
 {
        int rc = 1;
-       char busstr[64];
+       char busstr[64], namestr[64];
+       char *name;
        int vendor_id, product_id;
        WacomBusType bus;
 
@@ -141,18 +146,24 @@ libwacom_matchstr_to_match(WacomDevice *device, const 
char *match)
                return FALSE;
 
        if (g_strcmp0 (match, GENERIC_DEVICE_MATCH) == 0) {
-               libwacom_update_match(device, WBUSTYPE_UNKNOWN, 0, 0);
+               libwacom_update_match(device, NULL, WBUSTYPE_UNKNOWN, 0, 0);
                return TRUE;
        }
 
-       rc = sscanf(match, "%63[^:]:%x:%x", busstr, &vendor_id, &product_id);
-       if (rc != 3) {
+       memset(namestr, 0, sizeof(namestr));
+
+       rc = sscanf(match, "%63[^:]:%x:%x:%63c", busstr, &vendor_id, 
&product_id, namestr);
+       if (rc == 4) {
+               name = namestr;
+       } else if (rc == 3) {
+               name = NULL;
+       } else {
                DBG("failed to match '%s' for product/vendor IDs. Skipping.\n", 
match);
                return 0;
        }
        bus = bus_from_str (busstr);
 
-       libwacom_update_match(device, bus, vendor_id, product_id);
+       libwacom_update_match(device, name, bus, vendor_id, product_id);
 
        return TRUE;
 }
diff --git a/libwacom/libwacom.c b/libwacom/libwacom.c
index d100793..b389ef5 100644
--- a/libwacom/libwacom.c
+++ b/libwacom/libwacom.c
@@ -300,6 +300,7 @@ static WacomMatch *libwacom_copy_match(const WacomMatch 
*src)
 
        dst = g_new0(WacomMatch, 1);
        dst->match = g_strdup(src->match);
+       dst->name = g_strdup(src->name);
        dst->bus = src->bus;
        dst->vendor_id = src->vendor_id;
        dst->product_id = src->product_id;
@@ -448,7 +449,7 @@ libwacom_compare(const WacomDevice *a, const WacomDevice 
*b, WacomCompareFlags f
 }
 
 static const WacomDevice *
-libwacom_new (const WacomDeviceDatabase *db, int vendor_id, int product_id, 
WacomBusType bus, WacomError *error)
+libwacom_new (const WacomDeviceDatabase *db, const char *name, int vendor_id, 
int product_id, WacomBusType bus, WacomError *error)
 {
        const WacomDevice *device;
        char *match;
@@ -458,7 +459,7 @@ libwacom_new (const WacomDeviceDatabase *db, int vendor_id, 
int product_id, Waco
                return NULL;
        }
 
-       match = make_match_string(bus, vendor_id, product_id);
+       match = make_match_string(name, bus, vendor_id, product_id);
        device = libwacom_get_device(db, match);
        g_free (match);
 
@@ -473,7 +474,7 @@ libwacom_new_from_path(const WacomDeviceDatabase *db, const 
char *path, WacomFal
        const WacomDevice *device;
        WacomDevice *ret;
        WacomIntegrationFlags integration_flags;
-       char *name;
+       char *name, *match_name;
 
        if (!db) {
                libwacom_error_set(error, WERROR_INVALID_DB, "db is NULL");
@@ -488,7 +489,12 @@ libwacom_new_from_path(const WacomDeviceDatabase *db, 
const char *path, WacomFal
        if (!get_device_info (path, &vendor_id, &product_id, &name, &bus, 
&integration_flags, error))
                return NULL;
 
-       device = libwacom_new (db, vendor_id, product_id, bus, error);
+       match_name = name;
+       device = libwacom_new (db, match_name, vendor_id, product_id, bus, 
error);
+       if (device == NULL) {
+               match_name = NULL;
+               device = libwacom_new (db, match_name, vendor_id, product_id, 
bus, error);
+       }
        if (device != NULL)
                ret = libwacom_copy(device);
        else if (fallback == WFALLBACK_NONE)
@@ -503,14 +509,14 @@ libwacom_new_from_path(const WacomDeviceDatabase *db, 
const char *path, WacomFal
 
                if (name != NULL) {
                        g_free (ret->name);
-                       ret->name = name;
+                       ret->name = g_strdup(name);
                }
-       } else {
-               g_free (name);
        }
 
        /* for multiple-match devices, set to the one we requested */
-       libwacom_update_match(ret, bus, vendor_id, product_id);
+       libwacom_update_match(ret, match_name, bus, vendor_id, product_id);
+
+       g_free (name);
 
        if (device) {
                /* if unset, use the kernel flags. Could be unset as well. */
@@ -536,7 +542,7 @@ libwacom_new_from_usbid(const WacomDeviceDatabase *db, int 
vendor_id, int produc
                return NULL;
        }
 
-       device = libwacom_new(db, vendor_id, product_id, WBUSTYPE_USB, error);
+       device = libwacom_new(db, NULL, vendor_id, product_id, WBUSTYPE_USB, 
error);
 
        if (device)
                return libwacom_copy(device);
@@ -706,6 +712,7 @@ libwacom_print_device_description(int fd, const WacomDevice 
*device)
        dprintf(fd, "Name=%s\n", libwacom_get_name(device));
        dprintf(fd, "DeviceMatch=");
        for (match = libwacom_get_matches(device); *match; match++) {
+               const char  *name       = libwacom_match_get_name(*match);
                WacomBusType type       = libwacom_match_get_bustype(*match);
                int          vendor     = libwacom_match_get_vendor_id(*match);
                int          product    = libwacom_match_get_product_id(*match);
@@ -717,7 +724,10 @@ libwacom_print_device_description(int fd, const 
WacomDevice *device)
                        case WBUSTYPE_UNKNOWN:          bus_name = "unknown";   
break;
                        default:                        g_assert_not_reached(); 
break;
                }
-               dprintf(fd, "%s:%04x:%04x;", bus_name, vendor, product);
+               dprintf(fd, "%s:%04x:%04x", bus_name, vendor, product);
+               if (name)
+                       dprintf(fd, ":%s", name);
+               dprintf(fd, ";");
        }
        dprintf(fd, "\n");
 
@@ -758,6 +768,7 @@ libwacom_destroy(WacomDevice *device)
 
        for (i = 0; i < device->nmatches; i++) {
                g_free (device->matches[i]->match);
+               g_free (device->matches[i]->name);
                g_free (device->matches[i]);
        }
        g_free (device->matches);
@@ -768,18 +779,19 @@ libwacom_destroy(WacomDevice *device)
 }
 
 void
-libwacom_update_match(WacomDevice *device, WacomBusType bus, int vendor_id, 
int product_id)
+libwacom_update_match(WacomDevice *device, const char *name, WacomBusType bus, 
int vendor_id, int product_id)
 {
        char *newmatch;
        int i;
        WacomMatch match;
 
-       if (bus == WBUSTYPE_UNKNOWN && vendor_id == 0 && product_id == 0)
+       if (name == NULL && bus == WBUSTYPE_UNKNOWN && vendor_id == 0 && 
product_id == 0)
                newmatch = g_strdup("generic");
        else
-               newmatch = make_match_string(bus, vendor_id, product_id);
+               newmatch = make_match_string(name, bus, vendor_id, product_id);
 
        match.match = newmatch;
+       match.name = g_strdup(name);
        match.bus = bus;
        match.vendor_id = vendor_id;
        match.product_id = product_id;
@@ -1100,6 +1112,11 @@ void libwacom_stylus_destroy(WacomStylus *stylus)
 }
 
 
+const char *libwacom_match_get_name(const WacomMatch *match)
+{
+       return match->name;
+}
+
 WacomBusType libwacom_match_get_bustype(const WacomMatch *match)
 {
        return match->bus;
diff --git a/libwacom/libwacom.h b/libwacom/libwacom.h
index 60c873f..a0778c5 100644
--- a/libwacom/libwacom.h
+++ b/libwacom/libwacom.h
@@ -602,6 +602,7 @@ WacomStylusType libwacom_stylus_get_type (const WacomStylus 
*stylus);
  */
 void libwacom_print_stylus_description (int fd, const WacomStylus *stylus);
 
+const char *libwacom_match_get_name(const WacomMatch *match);
 WacomBusType libwacom_match_get_bustype(const WacomMatch *match);
 uint32_t libwacom_match_get_product_id(const WacomMatch *match);
 uint32_t libwacom_match_get_vendor_id(const WacomMatch *match);
diff --git a/libwacom/libwacomint.h b/libwacom/libwacomint.h
index 3ba54cc..825f9e9 100644
--- a/libwacom/libwacomint.h
+++ b/libwacom/libwacomint.h
@@ -54,6 +54,7 @@ enum WacomFeature {
  * make sure to update libwacom_copy_match() ! */
 struct _WacomMatch {
        char *match;
+       char *name;
        WacomBusType bus;
        uint32_t vendor_id;
        uint32_t product_id;
@@ -119,12 +120,11 @@ struct _WacomError {
 /* INTERNAL */
 void libwacom_error_set(WacomError *error, enum WacomErrorCode code, const 
char *msg, ...);
 void libwacom_stylus_destroy(WacomStylus *stylus);
-void libwacom_update_match(WacomDevice *device, WacomBusType bus, int 
vendor_id, int product_id);
+void libwacom_update_match(WacomDevice *device, const char *name, WacomBusType 
bus, int vendor_id, int product_id);
 
 WacomBusType  bus_from_str (const char *str);
 const char   *bus_to_str   (WacomBusType bus);
-char *make_match_string(WacomBusType bus, int vendor_id, int product_id);
-
+char *make_match_string(const char *name, WacomBusType bus, int vendor_id, int 
product_id);
 
 #endif /* _LIBWACOMINT_H_ */
 
-- 
2.3.1


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to