mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-17 01:04:40 +08:00
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>
This commit is contained in:
parent
5774e8c883
commit
6f605b8435
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user