We register to read the Lock, Unlock and IdleHintChanged signals from ConsoleKit.Session. The Lock/Unlock signals should be the right signals for the job but not all Desktop Managers implement its locking in a way that trigger those signals. That's why we double-check with IdleHintChanged signal that it might be triggered by other services like screen savers. --- src/console-kit.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/src/console-kit.c b/src/console-kit.c index 9662d3d..748a6bc 100644 --- a/src/console-kit.c +++ b/src/console-kit.c @@ -35,6 +35,9 @@ struct session_info { char *active_session; int verbose; gchar *match_seat_signals; + gchar *match_session_signals; + gboolean session_is_locked; + gboolean session_idle_hint; }; #define INTERFACE_CONSOLE_KIT "org.freedesktop.ConsoleKit" @@ -45,8 +48,15 @@ struct session_info { #define INTERFACE_CK_SEAT INTERFACE_CONSOLE_KIT ".Seat" +#define INTERFACE_CK_SESSION INTERFACE_CONSOLE_KIT ".Session" +#define OBJ_PATH_CK_SESSION OBJ_PATH_CONSOLE_KIT "/Session" + #define CK_SEAT_SIGNAL_ACTIVE_SESSION_CHANGED "ActiveSessionChanged" +#define CK_SESSION_SIGNAL_LOCK "Lock" +#define CK_SESSION_SIGNAL_UNLOCK "Unlock" +#define CK_SESSION_SIGNAL_IDLE_HINT_CHANGED "IdleHintChanged" + static char *console_kit_get_first_seat(struct session_info *si); static char *console_kit_check_active_session_change(struct session_info *si); @@ -63,6 +73,18 @@ static void si_dbus_match_remove(struct session_info *si) si->match_seat_signals); g_free(si->match_seat_signals); } + + if (si->match_session_signals != NULL) { + dbus_error_init(&error); + dbus_bus_remove_match(si->connection, + si->match_session_signals, + &error); + + if (si->verbose) + syslog(LOG_DEBUG, "(console-kit) session match removed: %s", + si->match_session_signals); + g_free(si->match_session_signals); + } } static void si_dbus_match_rule_update(struct session_info *si) @@ -96,6 +118,28 @@ static void si_dbus_match_rule_update(struct session_info *si) g_free(si->match_seat_signals); } } + + /* Session signals */ + if (si->active_session != NULL) { + si->match_session_signals = + g_strdup_printf ("type='signal',interface='%s',path='%s'", + INTERFACE_CK_SESSION, + si->active_session); + if (si->verbose) + syslog(LOG_DEBUG, "(console-kit) session match: %s", + si->match_session_signals); + + dbus_error_init(&error); + dbus_bus_add_match(si->connection, + si->match_session_signals, + &error); + if (dbus_error_is_set(&error)) { + syslog(LOG_WARNING, "Unable to add dbus rule match: %s", + error.message); + dbus_error_free(&error); + g_free(si->match_session_signals); + } + } } static void @@ -129,6 +173,7 @@ si_dbus_read_signals(struct session_info *si) dbus_message_iter_get_basic(&iter, &session); if (session != NULL && session[0] != '\0') { si->active_session = g_strdup(session); + si_dbus_match_rule_update(si); } else if (si->verbose) { syslog(LOG_WARNING, "(console-kit) received invalid session. " "No active-session at the moment"); @@ -141,6 +186,25 @@ si_dbus_read_signals(struct session_info *si) "ActiveSessionChanged message has unexpected type: '%c'", type); } + } else if (g_strcmp0(member, CK_SESSION_SIGNAL_LOCK) == 0) { + si->session_is_locked = TRUE; + } else if (g_strcmp0(member, CK_SESSION_SIGNAL_UNLOCK) == 0) { + si->session_is_locked = FALSE; + } else if (g_strcmp0(member, CK_SESSION_SIGNAL_IDLE_HINT_CHANGED) == 0) { + DBusMessageIter iter; + gint type; + dbus_bool_t idle_hint; + + dbus_message_iter_init(message, &iter); + type = dbus_message_iter_get_arg_type(&iter); + if (type == DBUS_TYPE_BOOLEAN) { + dbus_message_iter_get_basic(&iter, &idle_hint); + si->session_idle_hint = (idle_hint); + } else { + syslog(LOG_ERR, + "(console-kit) IdleHintChanged has unexpected type: '%c'", + type); + } } else if (si->verbose) { syslog(LOG_DEBUG, "(console-kit) Signal not handled: %s", member); } @@ -161,6 +225,8 @@ struct session_info *session_info_create(int verbose) return NULL; si->verbose = verbose; + si->session_is_locked = FALSE; + si->session_idle_hint = FALSE; dbus_error_init(&error); si->connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); @@ -324,6 +390,7 @@ const char *session_info_get_active_session(struct session_info *si) } si->active_session = strdup(session); + si_dbus_match_rule_update(si); exit: if (reply != NULL) { @@ -413,13 +480,23 @@ static char *console_kit_check_active_session_change(struct session_info *si) if (si->verbose) syslog(LOG_DEBUG, "(console-kit) active-session: '%s'", (si->active_session ? si->active_session : "None")); - return si->active_session; } gboolean session_info_session_is_locked(struct session_info *si) { - /* TODO: It could be implemented based on Lock/Unlock signals from Session - * interface. */ - return FALSE; + if (si == NULL) + return FALSE; + + /* Not every system does emit Lock and Unlock signals (for instance, such + * is the case for RHEL6) but most of the systems seems to emit the + * IdleHintChanged. So, we give priority to the Lock signal, if it is Locked + * we return that the session is locked, otherwise we double check with the + * IdleHint value */ + si_dbus_read_signals(si); + if (si->verbose) { + syslog(LOG_DEBUG, "(console-kit) session is locked: %s", + (si->session_is_locked || si->session_idle_hint) ? "yes" : "no"); + } + return (si->session_is_locked || si->session_idle_hint); } -- 2.5.5 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel