Diff between 6df15b54156e9492aaab7a130fe44eb1ae2af973 and 1750153b67b852d6feef82bdd97d59468627bf47

Changed Files

File Additions Deletions Status
profiles/input/hog.c +36 -19 modified

Full Patch

diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index df2b30b..30f9ed1 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -306,12 +306,16 @@ static void external_report_reference_cb(guint8 status, const guint8 *pdu,
 					external_service_char_cb, hogdev);
 }
 
-static int report_type_cmp(gconstpointer a, gconstpointer b)
+static int report_cmp(gconstpointer a, gconstpointer b)
 {
-	const struct report *report = a;
-	uint8_t type = GPOINTER_TO_UINT(b);
+	const struct report *ra = a, *rb = b;
 
-	return report->type - type;
+	/* sort by type first.. */
+	if (ra->type != rb->type)
+		return ra->type - rb->type;
+
+	/* ..then by id */
+	return ra->id - rb->id;
 }
 
 static void output_written_cb(guint8 status, const guint8 *pdu,
@@ -326,31 +330,44 @@ static void output_written_cb(guint8 status, const guint8 *pdu,
 static void forward_report(struct uhid_event *ev, void *user_data)
 {
 	struct hog_device *hogdev = user_data;
-	struct report *report;
+	struct report *report, cmp;
 	GSList *l;
-	void *data;
-	int size;
-	guint type;
+	uint8_t *data;
+	int size, type, id;
+
+	switch (ev->u.output.rtype) {
+	case UHID_FEATURE_REPORT:
+		type = HOG_REPORT_TYPE_FEATURE;
+		break;
+	case UHID_OUTPUT_REPORT:
+		type = HOG_REPORT_TYPE_OUTPUT;
+		break;
+	case UHID_INPUT_REPORT:
+		type = HOG_REPORT_TYPE_INPUT;
+		break;
+	default:
+		return;
+	}
 
-	if (hogdev->has_report_id) {
-		data = ev->u.output.data + 1;
-		size = ev->u.output.size - 1;
-	} else {
-		data = ev->u.output.data;
-		size = ev->u.output.size;
+	id = 0;
+	data = ev->u.output.data;
+	size = ev->u.output.size;
+	if (hogdev->has_report_id && size > 0) {
+		id = *data++;
+		--size;
 	}
 
-	type = HOG_REPORT_TYPE_OUTPUT;
+	cmp.type = type;
+	cmp.id = id;
 
-	l = g_slist_find_custom(hogdev->reports, GUINT_TO_POINTER(type),
-							report_type_cmp);
+	l = g_slist_find_custom(hogdev->reports, &cmp, report_cmp);
 	if (!l)
 		return;
 
 	report = l->data;
 
-	DBG("Sending report type %d to device 0x%04X handle 0x%X", type,
-				hogdev->id, report->decl->value_handle);
+	DBG("Sending report type %d ID %d to device 0x%04X handle 0x%X",
+			type, id, hogdev->id, report->decl->value_handle);
 
 	if (hogdev->attrib == NULL)
 		return;