diff --git a/src/linux/up-backend.c b/src/linux/up-backend.c index 2c46ab0..04e6f2f 100644 --- a/src/linux/up-backend.c +++ b/src/linux/up-backend.c @@ -86,6 +86,14 @@ G_DEFINE_TYPE_WITH_PRIVATE (UpBackend, up_backend, G_TYPE_OBJECT) static gboolean up_backend_device_add (UpBackend *backend, GUdevDevice *native); static void up_backend_device_remove (UpBackend *backend, GUdevDevice *native); +static void +input_switch_changed_cb (UpInput *input, + gboolean switch_value, + UpBackend *backend) +{ + up_daemon_set_lid_is_closed (backend->priv->daemon, switch_value); +} + static UpDevice * up_backend_device_new (UpBackend *backend, GUdevDevice *native) { @@ -159,10 +167,14 @@ up_backend_device_new (UpBackend *backend, GUdevDevice *native) /* check input device */ input = up_input_new (); - ret = up_input_coldplug (input, backend->priv->daemon, native); + ret = up_input_coldplug (input, native); if (ret) { /* we now have a lid */ up_daemon_set_lid_is_present (backend->priv->daemon, TRUE); + g_signal_connect (G_OBJECT (input), "switch-changed", + G_CALLBACK (input_switch_changed_cb), backend); + up_daemon_set_lid_is_closed (backend->priv->daemon, + up_input_get_switch_value (input)); /* not a power device, add it to the managed devices * and don't return a power device */ diff --git a/src/linux/up-input.c b/src/linux/up-input.c index 155377b..35e537d 100644 --- a/src/linux/up-input.c +++ b/src/linux/up-input.c @@ -41,7 +41,6 @@ #include "sysfs-utils.h" #include "up-types.h" -#include "up-daemon.h" #include "up-input.h" struct _UpInput @@ -49,11 +48,11 @@ struct _UpInput GObject parent_instance; guint watched_switch; + int last_switch_state; int eventfp; struct input_event event; gsize offset; GIOChannel *channel; - UpDaemon *daemon; }; G_DEFINE_TYPE (UpInput, up_input, G_TYPE_OBJECT) @@ -63,6 +62,13 @@ enum { PROP_WATCHED_SWITCH }; +enum { + SWITCH_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + /* we must use this kernel-compatible implementation */ #define BITS_PER_LONG (sizeof(long) * 8) #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) @@ -109,7 +115,6 @@ up_input_event_io (GIOChannel *channel, GIOCondition condition, gpointer data) GError *error = NULL; gsize read_bytes; glong bitmask[NBITS(SW_MAX)]; - gboolean ret; /* uninteresting */ if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) @@ -155,8 +160,10 @@ up_input_event_io (GIOChannel *channel, GIOCondition condition, gpointer data) } /* are we set */ - ret = test_bit (input->event.code, bitmask); - up_daemon_set_lid_is_closed (input->daemon, ret); + input->last_switch_state = test_bit (input->event.code, bitmask); + g_signal_emit_by_name (G_OBJECT (input), + "switch-changed", + input->last_switch_state); } out: return TRUE; @@ -166,7 +173,7 @@ out: * up_input_coldplug: **/ gboolean -up_input_coldplug (UpInput *input, UpDaemon *daemon, GUdevDevice *d) +up_input_coldplug (UpInput *input, GUdevDevice *d) { gboolean ret = FALSE; gchar *path; @@ -252,15 +259,13 @@ up_input_coldplug (UpInput *input, UpDaemon *daemon, GUdevDevice *d) goto out; } - /* save daemon */ - input->daemon = g_object_ref (daemon); - /* watch this */ g_io_add_watch (input->channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, up_input_event_io, input); /* set if we are closed */ g_debug ("using %s for watched switch event", native_path); - up_daemon_set_lid_is_closed (input->daemon, test_bit (input->watched_switch, bitmask)); + input->last_switch_state = test_bit (input->watched_switch, bitmask); + out: g_free (path); g_free (contents); @@ -274,6 +279,7 @@ static void up_input_init (UpInput *input) { input->eventfp = -1; + input->last_switch_state = -1; } /** @@ -289,7 +295,6 @@ up_input_finalize (GObject *object) input = UP_INPUT (object); - g_clear_object (&input->daemon); if (input->channel) { g_io_channel_shutdown (input->channel, FALSE, NULL); input->eventfp = -1; @@ -351,6 +356,17 @@ up_input_class_init (UpInputClass *klass) "The input switch to watch", SW_LID, SW_MAX, SW_LID, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + signals[SWITCH_CHANGED] = g_signal_new ("switch-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, + 1, + G_TYPE_BOOLEAN); } /** @@ -377,3 +393,20 @@ up_input_new_for_switch (guint watched_switch) "watched-switch", watched_switch, NULL); } + +/** + * up_input_get_switch_value: + * @input: a #UpInput + * + * Returns the last state of the switch. It is an error + * to call this without having successfully run + * up_input_coldplug(). + **/ +gboolean +up_input_get_switch_value (UpInput *input) +{ + g_return_val_if_fail (UP_IS_INPUT(input), FALSE); + g_return_val_if_fail (input->last_switch_state != -1, FALSE); + + return input->last_switch_state; +} diff --git a/src/linux/up-input.h b/src/linux/up-input.h index b512fa0..6c257e8 100644 --- a/src/linux/up-input.h +++ b/src/linux/up-input.h @@ -34,8 +34,8 @@ GType up_input_get_type (void); UpInput *up_input_new (void); UpInput *up_input_new_for_switch (guint watched_switch); gboolean up_input_coldplug (UpInput *input, - UpDaemon *daemon, GUdevDevice *d); +gboolean up_input_get_switch_value (UpInput *input); G_END_DECLS