]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - src/login1.c
Load all users only when really needed
[sojka/lightdm.git] / src / login1.c
index 58186a02cb777f1d8ff859283e3b08c8c2c550ba..dc60a492a02a09557ba842d0809a71210103e330 100644 (file)
@@ -43,6 +43,7 @@ struct Login1ServicePrivate
 
 enum {
     CAN_GRAPHICAL_CHANGED,
+    ACTIVE_SESSION_CHANGED,
     LAST_SEAT_SIGNAL
 };
 static guint seat_signals[LAST_SEAT_SIGNAL] = { 0 };
@@ -73,135 +74,28 @@ G_DEFINE_TYPE (Login1Seat, login1_seat, G_TYPE_OBJECT);
 
 static Login1Service *singleton = NULL;
 
-void
-login1_lock_session (const gchar *session_id)
+Login1Service *
+login1_service_get_instance (void)
 {
-    GDBusConnection *bus;
-    GError *error = NULL;
-
-    g_return_if_fail (session_id != NULL);
-
-    g_debug ("Locking login1 session %s", session_id);
-
-    bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
-    if (error)
-        g_warning ("Failed to get system bus: %s", error->message);
-    g_clear_error (&error);
-    if (!bus)
-        return;
-
-    if (session_id)
-    {
-        GVariant *result;
-
-        result = g_dbus_connection_call_sync (bus,
-                                              LOGIN1_SERVICE_NAME,
-                                              LOGIN1_OBJECT_NAME,
-                                              LOGIN1_MANAGER_INTERFACE_NAME,
-                                              "LockSession",
-                                              g_variant_new ("(s)", session_id),
-                                              G_VARIANT_TYPE ("()"),
-                                              G_DBUS_CALL_FLAGS_NONE,
-                                              -1,
-                                              NULL,
-                                              &error);
-        if (error)
-            g_warning ("Error locking login1 session: %s", error->message);
-        g_clear_error (&error);
-        if (result)
-            g_variant_unref (result);
-    }
-    g_object_unref (bus);
+    if (!singleton)
+        singleton = g_object_new (LOGIN1_SERVICE_TYPE, NULL);
+    return singleton;
 }
 
-void
-login1_unlock_session (const gchar *session_id)
+static void
+update_property (Login1Seat *seat, const gchar *name, GVariant *value)
 {
-    GDBusConnection *bus;
-    GError *error = NULL;
-
-    g_return_if_fail (session_id != NULL);
-
-    g_debug ("Unlocking login1 session %s", session_id);
-
-    bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
-    if (error)
-        g_warning ("Failed to get system bus: %s", error->message);
-    g_clear_error (&error);
-    if (!bus)
-        return;
-
-    if (session_id)
+    if (strcmp (name, "CanGraphical") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN))
     {
-        GVariant *result;
-
-        result = g_dbus_connection_call_sync (bus,
-                                              LOGIN1_SERVICE_NAME,
-                                              LOGIN1_OBJECT_NAME,
-                                              LOGIN1_MANAGER_INTERFACE_NAME,
-                                              "UnlockSession",
-                                              g_variant_new ("(s)", session_id),
-                                              G_VARIANT_TYPE ("()"),
-                                              G_DBUS_CALL_FLAGS_NONE,
-                                              -1,
-                                              NULL,
-                                              &error);
-        if (error)
-            g_warning ("Error unlocking login1 session: %s", error->message);
-        g_clear_error (&error);
-        if (result)
-            g_variant_unref (result);
+        seat->priv->can_graphical = g_variant_get_boolean (value);
+        g_signal_emit (seat, seat_signals[CAN_GRAPHICAL_CHANGED], 0);
     }
-    g_object_unref (bus);
-}
-
-void
-login1_activate_session (const gchar *session_id)
-{
-    GDBusConnection *bus;
-    GError *error = NULL;
-
-    g_return_if_fail (session_id != NULL);
-
-    g_debug ("Activating login1 session %s", session_id);
-
-    bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
-    if (error)
-        g_warning ("Failed to get system bus: %s", error->message);
-    g_clear_error (&error);
-    if (!bus)
-        return;
-
-    if (session_id)
+    else if (strcmp (name, "ActiveSession") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE ("(so)")))
     {
-        GVariant *result;
-
-        result = g_dbus_connection_call_sync (bus,
-                                              LOGIN1_SERVICE_NAME,
-                                              LOGIN1_OBJECT_NAME,
-                                              LOGIN1_MANAGER_INTERFACE_NAME,
-                                              "ActivateSession",
-                                              g_variant_new ("(s)", session_id),
-                                              G_VARIANT_TYPE ("()"),
-                                              G_DBUS_CALL_FLAGS_NONE,
-                                              -1,
-                                              NULL,
-                                              &error);
-        if (error)
-            g_warning ("Error activating login1 session: %s", error->message);
-        g_clear_error (&error);
-        if (result)
-            g_variant_unref (result);
+        const gchar *login1_session_id;
+        g_variant_get (value, "(&so)", &login1_session_id, NULL);
+        g_signal_emit (seat, seat_signals[ACTIVE_SESSION_CHANGED], 0, login1_session_id);
     }
-    g_object_unref (bus);
-}
-
-Login1Service *
-login1_service_get_instance (void)
-{
-    if (!singleton)
-        singleton = g_object_new (LOGIN1_SERVICE_TYPE, NULL);
-    return singleton;
 }
 
 static void
@@ -214,43 +108,40 @@ seat_properties_changed_cb (GDBusConnection *connection,
                             gpointer user_data)
 {
     Login1Seat *seat = user_data;
+    GVariantIter *iter;
     GVariantIter *invalidated_properties;
-    const gchar *property_name;
-
-    g_variant_get (parameters, "(sa{sv}as)", NULL, NULL, &invalidated_properties);
-    while (g_variant_iter_loop (invalidated_properties, "&s", &property_name))
+    const gchar *name;
+    GVariant *value;
+
+    g_variant_get (parameters, "(sa{sv}as)", NULL, &iter, &invalidated_properties);
+    while (g_variant_iter_loop (iter, "{&sv}", &name, &value))
+        update_property (seat, name, value);
+    g_variant_iter_free (iter);
+    while (g_variant_iter_loop (invalidated_properties, "&s", &name))
     {
-        if (strcmp (property_name, "CanGraphical") == 0)
-        {
-            GVariant *result;
-            GError *error = NULL;
-
-            result = g_dbus_connection_call_sync (connection,
-                                                  LOGIN1_SERVICE_NAME,
-                                                  seat->priv->path,
-                                                  "org.freedesktop.DBus.Properties",
-                                                  "Get",
-                                                  g_variant_new ("(ss)", "org.freedesktop.login1.Seat", property_name),
-                                                  G_VARIANT_TYPE ("(v)"),
-                                                  G_DBUS_CALL_FLAGS_NONE,
-                                                  -1,
-                                                  NULL,
-                                                  &error);
-            if (error)
-                g_warning ("Error updating CanGraphical: %s", error->message);
-            g_clear_error (&error);
-            if (result)
-            {
-                GVariant *value;
-
-                g_variant_get (result, "(v)", &value);
-                seat->priv->can_graphical = g_variant_get_boolean (value);
-                g_variant_unref (value);
-
-                g_signal_emit (seat, seat_signals[CAN_GRAPHICAL_CHANGED], 0);
+        GVariant *result;
+        GError *error = NULL;
 
-                g_variant_unref (result);
-            }
+        result = g_dbus_connection_call_sync (connection,
+                                              LOGIN1_SERVICE_NAME,
+                                              seat->priv->path,
+                                              "org.freedesktop.DBus.Properties",
+                                              "Get",
+                                              g_variant_new ("(ss)", "org.freedesktop.login1.Seat", name),
+                                              G_VARIANT_TYPE ("(v)"),
+                                              G_DBUS_CALL_FLAGS_NONE,
+                                              -1,
+                                              NULL,
+                                              &error);
+        if (error)
+            g_warning ("Error updating seat property %s: %s", name, error->message);
+        g_clear_error (&error);
+        if (result)
+        {
+            g_variant_get (result, "(v)", &value);
+            update_property (seat, name, value);
+            g_variant_unref (value);
+            g_variant_unref (result);
         }
     }
     g_variant_iter_free (invalidated_properties);
@@ -350,11 +241,11 @@ signal_cb (GDBusConnection *connection,
         seat = login1_service_get_seat (service, id);
         if (seat)
         {
-            service->priv->seats = g_list_remove (service->priv->seats, seat);            
+            service->priv->seats = g_list_remove (service->priv->seats, seat);
             g_signal_emit (service, service_signals[SEAT_REMOVED], 0, seat);
             g_object_unref (seat);
-        }                        
-    } 
+        }
+    }
 }
 
 gboolean
@@ -447,6 +338,105 @@ login1_service_get_seat (Login1Service *service, const gchar *id)
     return NULL;
 }
 
+void
+login1_service_lock_session (Login1Service *service, const gchar *session_id)
+{
+    GError *error = NULL;
+
+    g_return_if_fail (service != NULL);
+    g_return_if_fail (session_id != NULL);
+
+    g_debug ("Locking login1 session %s", session_id);
+
+    if (session_id)
+    {
+        GVariant *result;
+
+        result = g_dbus_connection_call_sync (service->priv->connection,
+                                              LOGIN1_SERVICE_NAME,
+                                              LOGIN1_OBJECT_NAME,
+                                              LOGIN1_MANAGER_INTERFACE_NAME,
+                                              "LockSession",
+                                              g_variant_new ("(s)", session_id),
+                                              G_VARIANT_TYPE ("()"),
+                                              G_DBUS_CALL_FLAGS_NONE,
+                                              -1,
+                                              NULL,
+                                              &error);
+        if (error)
+            g_warning ("Error locking login1 session: %s", error->message);
+        g_clear_error (&error);
+        if (result)
+            g_variant_unref (result);
+    }
+}
+
+void
+login1_service_unlock_session (Login1Service *service, const gchar *session_id)
+{
+    GError *error = NULL;
+
+    g_return_if_fail (service != NULL);
+    g_return_if_fail (session_id != NULL);
+
+    g_debug ("Unlocking login1 session %s", session_id);
+
+    if (session_id)
+    {
+        GVariant *result;
+
+        result = g_dbus_connection_call_sync (service->priv->connection,
+                                              LOGIN1_SERVICE_NAME,
+                                              LOGIN1_OBJECT_NAME,
+                                              LOGIN1_MANAGER_INTERFACE_NAME,
+                                              "UnlockSession",
+                                              g_variant_new ("(s)", session_id),
+                                              G_VARIANT_TYPE ("()"),
+                                              G_DBUS_CALL_FLAGS_NONE,
+                                              -1,
+                                              NULL,
+                                              &error);
+        if (error)
+            g_warning ("Error unlocking login1 session: %s", error->message);
+        g_clear_error (&error);
+        if (result)
+            g_variant_unref (result);
+    }
+}
+
+void
+login1_service_activate_session (Login1Service *service, const gchar *session_id)
+{
+    GError *error = NULL;
+
+    g_return_if_fail (service != NULL);
+    g_return_if_fail (session_id != NULL);
+
+    g_debug ("Activating login1 session %s", session_id);
+
+    if (session_id)
+    {
+        GVariant *result;
+
+        result = g_dbus_connection_call_sync (service->priv->connection,
+                                              LOGIN1_SERVICE_NAME,
+                                              LOGIN1_OBJECT_NAME,
+                                              LOGIN1_MANAGER_INTERFACE_NAME,
+                                              "ActivateSession",
+                                              g_variant_new ("(s)", session_id),
+                                              G_VARIANT_TYPE ("()"),
+                                              G_DBUS_CALL_FLAGS_NONE,
+                                              -1,
+                                              NULL,
+                                              &error);
+        if (error)
+            g_warning ("Error activating login1 session: %s", error->message);
+        g_clear_error (&error);
+        if (result)
+            g_variant_unref (result);
+    }
+}
+
 static void
 login1_service_init (Login1Service *service)
 {
@@ -460,7 +450,7 @@ login1_service_finalize (GObject *object)
 
     g_list_free_full (self->priv->seats, g_object_unref);
     g_dbus_connection_signal_unsubscribe (self->priv->connection, self->priv->signal_id);
-    g_object_unref (self->priv->connection);
+    g_clear_object (&self->priv->connection);
 
     G_OBJECT_CLASS (login1_service_parent_class)->finalize (object);
 }
@@ -475,7 +465,7 @@ login1_service_class_init (Login1ServiceClass *klass)
     g_type_class_add_private (klass, sizeof (Login1ServicePrivate));
 
     service_signals[SEAT_ADDED] =
-        g_signal_new ("seat-added",
+        g_signal_new (LOGIN1_SERVICE_SIGNAL_SEAT_ADDED,
                       G_TYPE_FROM_CLASS (klass),
                       G_SIGNAL_RUN_LAST,
                       G_STRUCT_OFFSET (Login1ServiceClass, seat_added),
@@ -483,7 +473,7 @@ login1_service_class_init (Login1ServiceClass *klass)
                       NULL,
                       G_TYPE_NONE, 1, LOGIN1_SEAT_TYPE);
     service_signals[SEAT_REMOVED] =
-        g_signal_new ("seat-removed",
+        g_signal_new (LOGIN1_SERVICE_SIGNAL_SEAT_REMOVED,
                       G_TYPE_FROM_CLASS (klass),
                       G_SIGNAL_RUN_LAST,
                       G_STRUCT_OFFSET (Login1ServiceClass, seat_removed),
@@ -542,11 +532,20 @@ login1_seat_class_init (Login1SeatClass *klass)
     g_type_class_add_private (klass, sizeof (Login1SeatPrivate));
 
     seat_signals[CAN_GRAPHICAL_CHANGED] =
-        g_signal_new ("can-graphical-changed",
+        g_signal_new (LOGIN1_SEAT_SIGNAL_CAN_GRAPHICAL_CHANGED,
                       G_TYPE_FROM_CLASS (klass),
                       G_SIGNAL_RUN_LAST,
                       G_STRUCT_OFFSET (Login1SeatClass, can_graphical_changed),
                       NULL, NULL,
                       NULL,
                       G_TYPE_NONE, 0);
+
+    seat_signals[ACTIVE_SESSION_CHANGED] =
+        g_signal_new (LOGIN1_SIGNAL_ACTIVE_SESION_CHANGED,
+                      G_TYPE_FROM_CLASS (klass),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (Login1SeatClass, active_session_changed),
+                      NULL, NULL,
+                      NULL,
+                      G_TYPE_NONE, 1, G_TYPE_STRING);
 }