aboutsummaryrefslogtreecommitdiff
path: root/input
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2010-09-02 17:09:37 +0100
committerJohan Hedberg <johan.hedberg@nokia.com>2010-09-02 23:11:55 +0300
commit6f605b84359b159bb961a6a93cfdbb3a628c267e (patch)
tree0ac65211aaa19855fadbcd94d3845cc5033eb62e /input
parent5774e8c8834fcfb2995203b137fb3b886a3f2c82 (diff)
downloadbluez-6f605b84359b159bb961a6a93cfdbb3a628c267e.tar.gz
Remember fake devices for the daemon's lifetime
This would allow faster reconnection of already known devices, so that no keypresses would be lost when reconnecting. We only setup uinput the first time around, which will avoid problems with devices not disappearing when disconnected. Based on patch by Ruslan N. Marchenko <rufferson@gmail.com>
Diffstat (limited to 'input')
-rw-r--r--input/device.c8
-rw-r--r--input/device.h1
-rw-r--r--input/fakehid.c32
-rw-r--r--input/fakehid.h3
4 files changed, 36 insertions, 8 deletions
diff --git a/input/device.c b/input/device.c
index 0bcbbdb7..b2885c49 100644
--- a/input/device.c
+++ b/input/device.c
@@ -635,12 +635,16 @@ static int hidp_add_connection(const struct input_device *idev,
fake_hid = get_fake_hid(req->vendor, req->product);
if (fake_hid) {
+ err = 0;
fake = g_new0(struct fake_input, 1);
fake->connect = fake_hid_connect;
fake->disconnect = fake_hid_disconnect;
fake->priv = fake_hid;
- err = fake_hid_connadd(fake, iconn->intr_io, fake_hid);
- if (err == 0)
+ fake->idev = idev;
+ fake = fake_hid_connadd(fake, iconn->intr_io, fake_hid);
+ if (fake == NULL)
+ err = -ENOMEM;
+ else
fake->flags |= FI_FLAG_CONNECTED;
goto cleanup;
}
diff --git a/input/device.h b/input/device.h
index 3390a0b6..14c0f97c 100644
--- a/input/device.h
+++ b/input/device.h
@@ -39,6 +39,7 @@ struct fake_input {
gboolean (*connect) (struct input_conn *iconn, GError **err);
int (*disconnect) (struct input_conn *iconn);
void *priv;
+ const struct input_device *idev;
};
int fake_input_register(DBusConnection *conn, struct btd_device *device,
diff --git a/input/fakehid.c b/input/fakehid.c
index ee1f77a0..6346a3ef 100644
--- a/input/fakehid.c
+++ b/input/fakehid.c
@@ -348,6 +348,7 @@ static struct fake_hid fake_hid_table[] = {
.disconnect = fake_hid_common_disconnect,
.event = ps3remote_event,
.setup_uinput = ps3remote_setup_uinput,
+ .devices = NULL,
},
{ },
@@ -370,12 +371,33 @@ struct fake_hid *get_fake_hid(uint16_t vendor, uint16_t product)
return NULL;
}
-int fake_hid_connadd(struct fake_input *fake, GIOChannel *intr_io,
+struct fake_input *fake_hid_connadd(struct fake_input *fake, GIOChannel *intr_io,
struct fake_hid *fake_hid)
{
- if (fake_hid->setup_uinput(fake, fake_hid)) {
- error("Error setting up uinput");
- return ENOMEM;
+ GList *l;
+ struct fake_input *old = NULL;
+
+ /* Look for an already setup device */
+ for (l = fake_hid->devices; l != NULL; l = l->next) {
+ old = l->data;
+ if (old->idev == fake->idev) {
+ g_free (fake);
+ fake = old;
+ fake_hid->connect(fake, NULL);
+ break;
+ }
+ old = NULL;
+ }
+
+ /* New device? Add it to the list of known devices,
+ * and create the uinput necessary */
+ if (old == NULL) {
+ if (fake_hid->setup_uinput(fake, fake_hid)) {
+ error("Error setting up uinput");
+ g_free(fake);
+ return NULL;
+ }
+ fake_hid->devices = g_list_append(fake_hid->devices, fake);
}
fake->io = g_io_channel_ref(intr_io);
@@ -383,5 +405,5 @@ int fake_hid_connadd(struct fake_input *fake, GIOChannel *intr_io,
g_io_add_watch(fake->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
(GIOFunc) fake_hid->event, fake);
- return 0;
+ return fake;
}
diff --git a/input/fakehid.h b/input/fakehid.h
index 33b1e70f..3a5d7c42 100644
--- a/input/fakehid.h
+++ b/input/fakehid.h
@@ -31,9 +31,10 @@ struct fake_hid {
int (*disconnect) (struct fake_input *fake_input);
gboolean (*event) (GIOChannel *chan, GIOCondition cond, gpointer data);
int (*setup_uinput) (struct fake_input *fake, struct fake_hid *fake_hid);
+ GList *devices;
};
struct fake_hid *get_fake_hid(uint16_t vendor, uint16_t product);
-int fake_hid_connadd(struct fake_input *fake, GIOChannel *intr_io,
+struct fake_input *fake_hid_connadd(struct fake_input *fake, GIOChannel *intr_io,
struct fake_hid *fake_hid);