aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Paulo Rechi Vita <jprvita@openbossa.org>2012-03-28 18:58:27 -0300
committerJoão Paulo Rechi Vita <jprvita@openbossa.org>2012-06-21 17:09:37 -0300
commit55f84a0a52f1fc6a6c9980bbf5939c2deb6d7663 (patch)
treec5dec7183e2a344ebdd7d1dfb98daa78a893259e
parent305e6657cca59e08a55b050fda2bef4868bd00ad (diff)
downloadbluez-55f84a0a52f1fc6a6c9980bbf5939c2deb6d7663.tar.gz
bluez-55f84a0a52f1fc6a6c9980bbf5939c2deb6d7663.tar.xz
bluez-55f84a0a52f1fc6a6c9980bbf5939c2deb6d7663.zip
hog: Add support for uHID events
This patch adds the GLib GIOChannel watcher to monitor uhid events.
-rw-r--r--input/hog_device.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/input/hog_device.c b/input/hog_device.c
index f58b16fd..cd5d1bfb 100644
--- a/input/hog_device.c
+++ b/input/hog_device.c
@@ -53,6 +53,7 @@
#define HOG_REPORT_MAP_UUID 0x2A4B
#define HOG_REPORT_UUID 0x2A4D
+
#define UHID_DEVICE_FILE "/dev/uhid"
#define HOG_REPORT_MAP_MAX_SIZE 512
@@ -71,6 +72,7 @@ struct hog_device {
GSList *reports;
int uhid_fd;
gboolean prepend_id;
+ guint uhid_watch_id;
};
struct report {
@@ -335,6 +337,36 @@ static void char_discovered_cb(GSList *chars, guint8 status, gpointer user_data)
}
}
+static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ struct hog_device *hogdev = user_data;
+ struct uhid_event ev;
+ ssize_t bread;
+ int fd;
+
+ if (cond & (G_IO_ERR | G_IO_NVAL))
+ goto failed;
+
+ fd = g_io_channel_unix_get_fd(io);
+ memset(&ev, 0, sizeof(ev));
+
+ bread = read(fd, &ev, sizeof(ev));
+ if (bread < 0) {
+ int err = errno;
+ DBG("uhid-dev read: %s(%d)", strerror(err), err);
+ goto failed;
+ }
+
+ DBG("uHID event type %d received", ev.type);
+
+ return TRUE;
+
+failed:
+ hogdev->uhid_watch_id = 0;
+ return FALSE;
+}
+
static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
struct hog_device *hogdev = user_data;
@@ -433,6 +465,8 @@ int hog_device_register(struct btd_device *device, const char *path)
{
struct hog_device *hogdev;
struct gatt_primary *prim;
+ GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
+ GIOChannel *io;
hogdev = find_device_by_path(devices, path);
if (hogdev)
@@ -453,12 +487,19 @@ int hog_device_register(struct btd_device *device, const char *path)
return -errno;
}
+ io = g_io_channel_unix_new(hogdev->uhid_fd);
+ g_io_channel_set_encoding(io, NULL, NULL);
+ hogdev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb,
+ hogdev);
+ g_io_channel_unref(io);
+
hogdev->hog_primary = g_memdup(prim, sizeof(*prim));
hogdev->attioid = btd_device_add_attio_callback(device,
attio_connected_cb,
attio_disconnected_cb,
hogdev);
+
device_set_auto_connect(device, TRUE);
devices = g_slist_append(devices, hogdev);
@@ -476,6 +517,9 @@ int hog_device_unregister(const char *path)
btd_device_remove_attio_callback(hogdev->device, hogdev->attioid);
+ g_source_remove(hogdev->uhid_watch_id);
+ hogdev->uhid_watch_id = 0;
+
close(hogdev->uhid_fd);
hogdev->uhid_fd = -1;