Back to index

lightdm  1.3.2
session.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2010 Robert Ancell.
00003  * Author: Robert Ancell <robert.ancell@canonical.com>
00004  * 
00005  * This library is free software; you can redistribute it and/or modify it under
00006  * the terms of the GNU Lesser General Public License as published by the Free
00007  * Software Foundation; either version 3 of the License, or (at your option) any
00008  * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
00009  * license.
00010  */
00011 
00012 #include <string.h>
00013 #include <gio/gdesktopappinfo.h>
00014 
00015 #include "lightdm/session.h"
00016 
00017 enum {
00018     PROP_0,
00019     PROP_KEY,
00020     PROP_NAME,
00021     PROP_COMMENT
00022 };
00023 
00024 typedef struct
00025 {
00026     gchar *key;
00027     gchar *name;
00028     gchar *comment;
00029 } LightDMSessionPrivate;
00030 
00031 G_DEFINE_TYPE (LightDMSession, lightdm_session, G_TYPE_OBJECT);
00032 
00033 #define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_SESSION, LightDMSessionPrivate)
00034 
00035 static gboolean have_sessions = FALSE;
00036 static GList *sessions = NULL;
00037 
00038 static gint 
00039 compare_session (gconstpointer a, gconstpointer b)
00040 {
00041     LightDMSessionPrivate *priv_a = GET_PRIVATE (a);
00042     LightDMSessionPrivate *priv_b = GET_PRIVATE (b);
00043     return strcmp (priv_a->name, priv_b->name);
00044 }
00045 
00046 static LightDMSession *
00047 load_session (GKeyFile *key_file, const gchar *key)
00048 {
00049     gchar *domain, *name;
00050     LightDMSession *session;
00051     LightDMSessionPrivate *priv;
00052     gchar *try_exec;
00053   
00054     if (g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL) ||
00055         g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL))
00056         return NULL;
00057 
00058 #ifdef G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN
00059     domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, NULL);
00060 #else
00061     domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL);
00062 #endif
00063     name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, domain, NULL);
00064     if (!name)
00065     {
00066         g_warning ("Ignoring session without name");
00067         g_free (domain);
00068         return NULL;
00069     }
00070 
00071     try_exec = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, domain, NULL);
00072     if (try_exec)
00073     {
00074         gchar *full_path;
00075 
00076         full_path = g_find_program_in_path (try_exec);
00077         g_free (try_exec);
00078 
00079         if (!full_path)
00080         {
00081             g_free (name);
00082             g_free (domain);
00083             return NULL;
00084         }
00085         g_free (full_path);
00086     }
00087 
00088     session = g_object_new (LIGHTDM_TYPE_SESSION, NULL);
00089     priv = GET_PRIVATE (session);
00090 
00091     g_free (priv->key);
00092     priv->key = g_strdup (key);
00093 
00094     g_free (priv->name);
00095     priv->name = name;
00096 
00097     g_free (priv->comment);
00098     priv->comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, domain, NULL);
00099     if (!priv->comment)
00100         priv->comment = g_strdup ("");
00101 
00102     sessions = g_list_insert_sorted (sessions, session, compare_session);
00103 
00104     g_free (domain);
00105 
00106     return session;
00107 }
00108 
00109 static void
00110 update_sessions (void)
00111 {
00112     GDir *directory;
00113     gboolean result;
00114     GError *error = NULL;
00115 
00116     GKeyFile *config_key_file = NULL;
00117     gchar *config_path = NULL;
00118     gchar *xsessions_dir = g_strdup (XSESSIONS_DIR);
00119 
00120     if (have_sessions)
00121         return;
00122 
00123     config_path = g_build_filename (CONFIG_DIR, "lightdm.conf", NULL);
00124     config_key_file = g_key_file_new ();
00125     result = g_key_file_load_from_file (config_key_file, config_path, G_KEY_FILE_NONE, &error);
00126     if (error)
00127         g_warning ("Failed to open configuration file: %s", error->message);
00128     g_clear_error (&error);
00129     if (result)
00130     {
00131         gchar *xd_value = g_key_file_get_string (config_key_file, "LightDM", "xsessions-directory", NULL);
00132         if (xd_value)
00133         {
00134             g_free (xsessions_dir);
00135             xsessions_dir = xd_value;
00136         }
00137     }
00138     g_key_file_free (config_key_file);
00139     g_free (config_path);
00140     
00141     directory = g_dir_open (xsessions_dir, 0, &error);
00142     if (error)
00143         g_warning ("Failed to open sessions directory: %s", error->message);
00144     g_clear_error (&error);
00145     if (!directory)
00146     {
00147         g_free (xsessions_dir);
00148         return;
00149     }
00150 
00151     while (TRUE)
00152     {
00153         const gchar *filename;
00154         gchar *path;
00155         GKeyFile *key_file;
00156         gboolean result;
00157 
00158         filename = g_dir_read_name (directory);
00159         if (filename == NULL)
00160             break;
00161 
00162         if (!g_str_has_suffix (filename, ".desktop"))
00163             continue;
00164 
00165         path = g_build_filename (xsessions_dir, filename, NULL);
00166 
00167         key_file = g_key_file_new ();
00168         result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
00169         if (error)
00170             g_warning ("Failed to load session file %s: %s:", path, error->message);
00171         g_clear_error (&error);
00172 
00173         if (result)
00174         {
00175             gchar *key;
00176             LightDMSession *session;
00177 
00178             key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
00179             session = load_session (key_file, key);
00180             if (session)
00181                 g_debug ("Loaded session %s (%s, %s)", path, GET_PRIVATE (session)->name, GET_PRIVATE (session)->comment);
00182             else
00183                 g_debug ("Ignoring session %s", path);
00184             g_free (key);
00185         }
00186 
00187         g_free (path);
00188         g_key_file_free (key_file);
00189     }
00190 
00191     g_dir_close (directory);
00192     g_free (xsessions_dir);
00193 
00194     have_sessions = TRUE;
00195 }
00196 
00204 GList *
00205 lightdm_get_sessions (void)
00206 {
00207     update_sessions ();
00208     return sessions;
00209 }
00210 
00219 const gchar *
00220 lightdm_session_get_key (LightDMSession *session)
00221 {
00222     g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
00223     return GET_PRIVATE (session)->key;
00224 }
00225 
00234 const gchar *
00235 lightdm_session_get_name (LightDMSession *session)
00236 {
00237     g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
00238     return GET_PRIVATE (session)->name;
00239 }
00240 
00249 const gchar *
00250 lightdm_session_get_comment (LightDMSession *session)
00251 {
00252     g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
00253     return GET_PRIVATE (session)->comment;
00254 }
00255 
00256 static void
00257 lightdm_session_init (LightDMSession *session)
00258 {
00259 }
00260 
00261 static void
00262 lightdm_session_set_property (GObject      *object,
00263                           guint         prop_id,
00264                           const GValue *value,
00265                           GParamSpec   *pspec)
00266 {
00267     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00268 }
00269 
00270 static void
00271 lightdm_session_get_property (GObject    *object,
00272                           guint       prop_id,
00273                           GValue     *value,
00274                           GParamSpec *pspec)
00275 {
00276     LightDMSession *self;
00277 
00278     self = LIGHTDM_SESSION (object);
00279 
00280     switch (prop_id) {
00281     case PROP_KEY:
00282         g_value_set_string (value, lightdm_session_get_key (self));
00283         break;
00284     case PROP_NAME:
00285         g_value_set_string (value, lightdm_session_get_name (self));
00286         break;
00287     case PROP_COMMENT:
00288         g_value_set_string (value, lightdm_session_get_comment (self));
00289         break;
00290     default:
00291         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00292         break;
00293     }
00294 }
00295 
00296 static void
00297 lightdm_session_finalize (GObject *object)
00298 {
00299     LightDMSession *self = LIGHTDM_SESSION (object);
00300     LightDMSessionPrivate *priv = GET_PRIVATE (self);
00301 
00302     g_free (priv->key);
00303     g_free (priv->name);
00304     g_free (priv->comment);
00305 }
00306 
00307 static void
00308 lightdm_session_class_init (LightDMSessionClass *klass)
00309 {
00310     GObjectClass *object_class = G_OBJECT_CLASS (klass);
00311   
00312     g_type_class_add_private (klass, sizeof (LightDMSessionPrivate));
00313 
00314     object_class->set_property = lightdm_session_set_property;
00315     object_class->get_property = lightdm_session_get_property;
00316     object_class->finalize = lightdm_session_finalize;
00317 
00318     g_object_class_install_property (object_class,
00319                                      PROP_KEY,
00320                                      g_param_spec_string ("key",
00321                                                           "key",
00322                                                           "Session key",
00323                                                           NULL,
00324                                                           G_PARAM_READABLE));
00325     g_object_class_install_property (object_class,
00326                                      PROP_NAME,
00327                                      g_param_spec_string ("name",
00328                                                           "name",
00329                                                           "Session name",
00330                                                           NULL,
00331                                                           G_PARAM_READABLE));
00332     g_object_class_install_property (object_class,
00333                                      PROP_COMMENT,
00334                                      g_param_spec_string ("comment",
00335                                                           "comment",
00336                                                           "Session comment",
00337                                                           NULL,
00338                                                           G_PARAM_READABLE));
00339 }