summaryrefslogtreecommitdiff
path: root/hw/usb/hid-logitech-hidpp20.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-03-24 12:35:26 +0100
committerPeter Wu <peter@lekensteyn.nl>2014-03-24 12:35:26 +0100
commit4215730f0ac21c625effe50ba14fbf050dc991a8 (patch)
treec0c44b81ce2acdd4f7197243293febf3cfdb6acf /hw/usb/hid-logitech-hidpp20.c
parent7249fb7b3ac3e05b604228314a48ad5703506c1d (diff)
downloadqemu-4215730f0ac21c625effe50ba14fbf050dc991a8.tar.gz
unifying: impl HID++ 2.0 DeviceName, adjust device info
Set K800 to use HID++ 1.0; add a device_name field to store long device names for HID++ 2.0 devices. The device types constants are slightly different between HID++ 1.0 and HID++ 2.0, two constants are not implemented (and those will probably never be implemented). Signed-off-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'hw/usb/hid-logitech-hidpp20.c')
-rw-r--r--hw/usb/hid-logitech-hidpp20.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/hw/usb/hid-logitech-hidpp20.c b/hw/usb/hid-logitech-hidpp20.c
index eb15ab1c96..3c664cc089 100644
--- a/hw/usb/hid-logitech-hidpp20.c
+++ b/hw/usb/hid-logitech-hidpp20.c
@@ -146,10 +146,51 @@ static HIDPP20_FEATURE(feat_devicefwversion)
}
}
+/* returns the HID++ 2.0 Device Type constant for a device */
+static uint8_t hidpp20_get_device_type(LHidDevice *hd)
+{
+ static const uint8_t device_types_map[0x10] = {
+ [DEVTYPE_KEYBOARD] = 0,
+ [DEVTYPE_MOUSE] = 3,
+ [DEVTYPE_NUMPAD] = 2,
+ [DEVTYPE_PRESENTER] = 6,
+ [DEVTYPE_TRACKBALL] = 5,
+ [DEVTYPE_TOUCHPAD] = 4,
+ // Not handled: RemoteControl (1) Receiver (7)
+ };
+
+ assert(hd->info.device_type < ARRAY_SIZE(device_types_map));
+ return device_types_map[hd->info.device_type];
+}
+
+static HIDPP20_FEATURE(feat_devicename)
+{
+ switch (fn) {
+ case 0: /* nameLength = GetCount() */
+ params[0] = strlen(hd->info.device_name);
+ return 1;
+ case 1: /* DeviceName = GetDeviceName(CharIndex) */
+ if (params[0] > strlen(hd->info.device_name)) {
+ return -HIDPP20_ERR_CODE_OUTOFRANGE;
+ }
+ const char *name = hd->info.device_name + params[0];
+ /* always include trailing 0 such that the param len > 0 (non-void) */
+ unsigned len = MIN(sizeof(msg->params), strlen(name) + 1);
+ memcpy(params, name, len);
+ return len;
+ case 2: /* DeviceType, deviceInterface(s) = GetDeviceType() */
+ params[0] = hidpp20_get_device_type(hd);
+ return 1;
+ default:
+ return -HIDPP20_ERR_CODE_INVALID_FUNCTION_ID;
+ }
+}
+
/* root feature not included! */
static const HidppFeature features_m525[] = {
{ 0x0001, 0, feat_featureset },
{ 0x0003, 0, feat_devicefwversion },
+ { 0x0005, 0, feat_devicename },
};
void hidpp20_init_features(LHidDevice *hd) {