diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-01-14 20:31:00 +0100 |
---|---|---|
committer | Colin Guthrie <cguthrie@mandriva.org> | 2010-02-09 22:44:00 +0000 |
commit | 544fa0b7dbc5ba5684f2a4dac7dbc7eebb74afc6 (patch) | |
tree | 3c1def8ec60d85bb74013ba7daca18d582ca254d /src/modules/udev-util.c | |
parent | 4315f277bcdb89d2e17c7bf9bd5ac0c2b9b3aa6e (diff) | |
download | pulseaudio-544fa0b7dbc5ba5684f2a4dac7dbc7eebb74afc6.tar.gz |
udev: use ID_MODEL_ENC instead of ID_MODEL if it is set
That way we should be able to make use of the nicer USB strings the USB
hw provides.
Fixes the issues pointed out in:
https://tango.0pointer.de/pipermail/pulseaudio-discuss/2010-January/006248.html
Diffstat (limited to 'src/modules/udev-util.c')
-rw-r--r-- | src/modules/udev-util.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/modules/udev-util.c b/src/modules/udev-util.c index cc824465e..eee5409a7 100644 --- a/src/modules/udev-util.c +++ b/src/modules/udev-util.c @@ -58,6 +58,112 @@ static int read_id(struct udev_device *d, const char *n) { return u; } +static int dehex(char x) { + if (x >= '0' && x <= '9') + return x - '0'; + + if (x >= 'A' && x <= 'F') + return x - 'A'; + + if (x >= 'a' && x <= 'f') + return x - 'a'; + + return -1; +} + +static void proplist_sets_unescape(pa_proplist *p, const char *prop, const char *s) { + const char *f; + char *t, *r; + int c; + + enum { + TEXT, + BACKSLASH, + EX, + FIRST + } state = TEXT; + + /* The resulting string is definitely shorter than the source string */ + r = pa_xnew(char, strlen(s)+1); + + for (f = s, t = r; *f; f++) { + + switch (state) { + + case TEXT: + if (*f == '\\') + state = BACKSLASH; + else + *(t++) = *f; + break; + + case BACKSLASH: + if (*f == 'x') + state = EX; + else { + *(t++) = '\\'; + *(t++) = *f; + state = TEXT; + } + break; + + case EX: + c = dehex(*f); + + if (c < 0) { + *(t++) = '\\'; + *(t++) = 'x'; + *(t++) = *f; + state = TEXT; + } else + state = FIRST; + + break; + + case FIRST: { + int d = dehex(*f); + + if (d < 0) { + *(t++) = '\\'; + *(t++) = 'x'; + *(t++) = *(f-1); + *(t++) = *f; + } else + *(t++) = (char) (c << 4) | d; + + state = TEXT; + break; + } + } + } + + switch (state) { + + case TEXT: + break; + + case BACKSLASH: + *(t++) = '\\'; + break; + + case EX: + *(t++) = '\\'; + *(t++) = 'x'; + break; + + case FIRST: + *(t++) = '\\'; + *(t++) = 'x'; + *(t++) = *(f-1); + break; + } + + *t = 0; + + pa_proplist_sets(p, prop, r); + pa_xfree(r); +} + int pa_udev_get_info(int card_idx, pa_proplist *p) { int r = -1; struct udev *udev; @@ -107,6 +213,8 @@ int pa_udev_get_info(int card_idx, pa_proplist *p) { if (!pa_proplist_contains(p, PA_PROP_DEVICE_VENDOR_NAME)) { if ((v = udev_device_get_property_value(card, "ID_VENDOR_FROM_DATABASE")) && *v) pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v); + else if ((v = udev_device_get_property_value(card, "ID_VENDOR_ENC")) && *v) + proplist_sets_unescape(p, PA_PROP_DEVICE_VENDOR_NAME, v); else if ((v = udev_device_get_property_value(card, "ID_VENDOR")) && *v) pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v); } @@ -118,6 +226,8 @@ int pa_udev_get_info(int card_idx, pa_proplist *p) { if (!pa_proplist_contains(p, PA_PROP_DEVICE_PRODUCT_NAME)) { if ((v = udev_device_get_property_value(card, "ID_MODEL_FROM_DATABASE")) && *v) pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v); + else if ((v = udev_device_get_property_value(card, "ID_MODEL_ENC")) && *v) + proplist_sets_unescape(p, PA_PROP_DEVICE_PRODUCT_NAME, v); else if ((v = udev_device_get_property_value(card, "ID_MODEL")) && *v) pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v); } |