mirror of
https://github.com/libratbag/libratbag.git
synced 2026-11-07 23:23:52 +01:00
ratbagd: export the Model property for the device
When the SVGs need to be maintained elsewhere, we need something reliable to match devices with SVGs. The easiest is to provide a unique model string, usually composed from the usb/bluetooth information. A string format was chosen to make it more flexible for the glorious future where we have something other than usb or bluetooth devices. Meanwhile, the format is the well-known "usb:1234:56ef:0" string (bus, vid, pid, version). The version in this string is a future-proof safeguard for libratbag. It will be used where libratbag supports two devices with the same VID/PID and where this is not otherwise differentiable. We don't have any such devices yet, so libratbag just returns a hardcoded 0. The format is currently defined for usb and bluetooth, in the future we may have other strings. The base guarantee is that this is a reliable identifier for the model that will never change for that model. IOW this is what piper can use to map devices to their SVGs. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
committed by
Benjamin Tissoires
parent
367aa29dfe
commit
10a1cc9bbc
42
doc/dbus.rst
42
doc/dbus.rst
@@ -120,6 +120,48 @@ known to ratbagd.
|
||||
content of the ID is undefined, the client should treat it as an
|
||||
opaque string.
|
||||
|
||||
.. attribute:: Model
|
||||
|
||||
:type: s
|
||||
:flags: read-only, constant
|
||||
|
||||
An ID identifying the physical device model. This string is
|
||||
guaranteed to be unique for a specific model and always identical
|
||||
for devices of that model.
|
||||
|
||||
This is a string of one of the following formats:
|
||||
|
||||
- ``usb:1234:abcd:0``
|
||||
- ``bluetooth:5678:ef01:0``
|
||||
- ``unknown``
|
||||
|
||||
In the future, other formats may get added. Clients must ignore
|
||||
unknown string formats.
|
||||
|
||||
For a string starting with `usb:`, the format is the bus type (USB)
|
||||
followed by a 4-digit lowercase hex USB vendor ID, followed by a
|
||||
4-digit lowercase hex USB product ID, followed by an decimal version
|
||||
number of unspecified length. These four elements are separated by a
|
||||
colon (``:``).
|
||||
|
||||
For a string starting with `bluetooth:`, the format is the bus type
|
||||
(Bluetooth) followed by a 4-digit lowercase hex Bluetooth vendor ID,
|
||||
followed by a 4-digit lowercase hex Bluetooth product ID, followed
|
||||
by an decimal version number of unspecified length. These four
|
||||
elements are separated by a colon (``:``).
|
||||
|
||||
For the string ``unknown``, the model of the device cannot be
|
||||
determined. This is usually a bug in libratbag.
|
||||
|
||||
For ``DeviceId``s of type ``usb`` and ``bluetooth``, the version
|
||||
number is reserved for use by libratbag. Device with identical
|
||||
vendor and product IDs but different versions must be considered
|
||||
different devices. For example, the version may increase when a
|
||||
manufacturer re-uses USB Ids.
|
||||
|
||||
Vendor or product IDs of 0 are valid IDs (e.g. used used by test
|
||||
devices).
|
||||
|
||||
.. attribute:: Name
|
||||
|
||||
:type: s
|
||||
|
||||
@@ -232,9 +232,36 @@ static int ratbagd_device_commit(sd_bus_message *m,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ratbag_device_get_model(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_device *device = userdata;
|
||||
struct ratbag_device *lib_device = device->lib_device;
|
||||
const char *bustype = ratbag_device_get_bustype(lib_device);
|
||||
uint32_t vid = ratbag_device_get_vendor_id(lib_device),
|
||||
pid = ratbag_device_get_product_id(lib_device),
|
||||
version = ratbag_device_get_product_version(lib_device);
|
||||
char model[64];
|
||||
|
||||
if (!bustype)
|
||||
return sd_bus_message_append(reply, "s", "unknown");
|
||||
|
||||
snprintf(model, sizeof(model), "%s:%04x:%04x:%d",
|
||||
bustype, vid, pid, version);
|
||||
|
||||
return sd_bus_message_append(reply, "s", model);
|
||||
}
|
||||
|
||||
const sd_bus_vtable ratbagd_device_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(struct ratbagd_device, id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Model", "s", ratbag_device_get_model, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Name", "s", ratbagd_device_get_device_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Profiles", "ao", ratbagd_device_get_profiles, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_METHOD("GetSvgFd", "s", "h", ratbagd_device_get_theme_svg_fd, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
@@ -517,6 +517,39 @@ ratbag_device_get_svg_name(const struct ratbag_device* device)
|
||||
return name;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT const char *
|
||||
ratbag_device_get_bustype(const struct ratbag_device *device)
|
||||
{
|
||||
switch (device->ids.bustype) {
|
||||
case BUS_USB:
|
||||
return "usb";
|
||||
case BUS_BLUETOOTH:
|
||||
return "bluetooth";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT uint32_t
|
||||
ratbag_device_get_vendor_id(const struct ratbag_device *device)
|
||||
{
|
||||
return device->ids.vendor;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT uint32_t
|
||||
ratbag_device_get_product_id(const struct ratbag_device *device)
|
||||
{
|
||||
return device->ids.product;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT uint32_t
|
||||
ratbag_device_get_product_version(const struct ratbag_device *device)
|
||||
{
|
||||
/* change this when we have a need for it, i.e. when we start supporting devices
|
||||
* where the USB ID gets reused */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ratbag_register_driver(struct ratbag *ratbag, struct ratbag_driver *driver)
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <libudev.h>
|
||||
@@ -439,6 +440,47 @@ ratbag_device_get_name(const struct ratbag_device* device);
|
||||
const char *
|
||||
ratbag_device_get_svg_name(const struct ratbag_device* device);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
* Returns the bustype of the device, "usb", "bluetooth" or NULL for
|
||||
* unknown.
|
||||
*/
|
||||
const char *
|
||||
ratbag_device_get_bustype(const struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
* Returns the vendor ID of the device.
|
||||
*/
|
||||
uint32_t
|
||||
ratbag_device_get_vendor_id(const struct ratbag_device *device);
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
* Returns the product ID of the device.
|
||||
*/
|
||||
uint32_t
|
||||
ratbag_device_get_product_id(const struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
* Returns the product version of the device. This is a made-up number,
|
||||
* internal to libratbag. It's purpose is to provide an extra bit of
|
||||
* differentiation where devices use the same VID/PID for different models.
|
||||
*
|
||||
* Devices with identical VID/PID but different versions must be considered
|
||||
* different devices.
|
||||
*
|
||||
* Usually the version will be 0.
|
||||
*/
|
||||
uint32_t
|
||||
ratbag_device_get_product_version(const struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
|
||||
@@ -249,6 +249,17 @@ class RatbagdDevice(metaclass=MetaRatbag):
|
||||
"""The unique identifier of this device."""
|
||||
return self._path
|
||||
|
||||
@property
|
||||
def model(self):
|
||||
"""The unique identifier for this device model."""
|
||||
bus = libratbag.ratbag_device_get_bus(self._device)
|
||||
if not bus:
|
||||
return "unknown"
|
||||
vid = libratbag.ratbag_device_get_vendor_id(self._device)
|
||||
pid = libratbag.ratbag_device_get_product_id(self._device)
|
||||
version = libratbag.ratbag_device_get_product_version(self._device)
|
||||
return "{}:{04x}:{04x}:{d}".format(bus, vid, pid, version)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""The device name, usually provided by the kernel."""
|
||||
|
||||
@@ -347,6 +347,11 @@ class RatbagdDevice(_RatbagdDBus):
|
||||
"""The unique identifier of this device."""
|
||||
return self._get_dbus_property("Id")
|
||||
|
||||
@GObject.Property
|
||||
def model(self):
|
||||
"""The unique identifier for this device model."""
|
||||
return self._get_dbus_property("Model")
|
||||
|
||||
@GObject.Property
|
||||
def name(self):
|
||||
"""The device name, usually provided by the kernel."""
|
||||
|
||||
Reference in New Issue
Block a user