gdm r5689 - in trunk: . gui/simple-greeter
- From: mccann svn gnome org
- To: svn-commits-list gnome org
- Subject: gdm r5689 - in trunk: . gui/simple-greeter
- Date: Mon, 4 Feb 2008 15:23:20 +0000 (GMT)
Author: mccann
Date: Mon Feb 4 15:23:19 2008
New Revision: 5689
URL: http://svn.gnome.org/viewvc/gdm?rev=5689&view=rev
Log:
2008-02-04 William Jon McCann <jmccann redhat com>
* gui/simple-greeter/gdm-chooser-widget.c: (foreach_item),
(compare_item), (gdm_chooser_widget_init),
(gdm_chooser_widget_update_item), (gdm_chooser_widget_add_item),
(gdm_chooser_widget_lookup_item),
(gdm_chooser_widget_set_item_priority):
* gui/simple-greeter/gdm-chooser-widget.h:
* gui/simple-greeter/gdm-language-chooser-widget.c:
(gdm_language_chooser_widget_add_language):
* gui/simple-greeter/gdm-session-chooser-widget.c: (add_session),
(add_available_sessions):
* gui/simple-greeter/gdm-user-chooser-widget.c:
(add_special_users), (on_user_added),
(on_user_login_frequency_changed), (gdm_user_chooser_widget_init):
* gui/simple-greeter/gdm-user-manager.c: (parse_value_as_ulong),
(parse_ck_history_line), (process_ck_history_line),
(ck_history_watch), (reload_users), (reload_users_timeout),
(queue_reload_users), (gdm_user_manager_class_init),
(gdm_user_manager_init), (gdm_user_manager_finalize):
* gui/simple-greeter/gdm-user-manager.h:
* gui/simple-greeter/gdm-user.c: (_gdm_user_set_login_frequency),
(gdm_user_set_property), (gdm_user_get_property),
(gdm_user_class_init), (gdm_user_init),
(gdm_user_get_login_frequency):
* gui/simple-greeter/gdm-user.h:
Only show users that have frequently logged in.
Modified:
trunk/ChangeLog
trunk/gui/simple-greeter/gdm-chooser-widget.c
trunk/gui/simple-greeter/gdm-chooser-widget.h
trunk/gui/simple-greeter/gdm-language-chooser-widget.c
trunk/gui/simple-greeter/gdm-session-chooser-widget.c
trunk/gui/simple-greeter/gdm-user-chooser-widget.c
trunk/gui/simple-greeter/gdm-user-manager.c
trunk/gui/simple-greeter/gdm-user-manager.h
trunk/gui/simple-greeter/gdm-user.c
trunk/gui/simple-greeter/gdm-user.h
Modified: trunk/gui/simple-greeter/gdm-chooser-widget.c
==============================================================================
--- trunk/gui/simple-greeter/gdm-chooser-widget.c (original)
+++ trunk/gui/simple-greeter/gdm-chooser-widget.c Mon Feb 4 15:23:19 2008
@@ -114,6 +114,7 @@
CHOOSER_IMAGE_COLUMN = 0,
CHOOSER_NAME_COLUMN,
CHOOSER_COMMENT_COLUMN,
+ CHOOSER_PRIORITY_COLUMN,
CHOOSER_ITEM_IS_IN_USE_COLUMN,
CHOOSER_ITEM_IS_SEPARATED_COLUMN,
CHOOSER_ITEM_IS_VISIBLE_COLUMN,
@@ -176,6 +177,7 @@
gboolean is_separate;
gboolean res;
char *id;
+ gulong priority;
gtk_tree_model_get (model,
iter,
@@ -183,6 +185,7 @@
CHOOSER_IMAGE_COLUMN, &image,
CHOOSER_NAME_COLUMN, &name,
CHOOSER_COMMENT_COLUMN, &comment,
+ CHOOSER_PRIORITY_COLUMN, &priority,
CHOOSER_ITEM_IS_IN_USE_COLUMN, &in_use,
CHOOSER_ITEM_IS_SEPARATED_COLUMN, &is_separate,
-1);
@@ -191,6 +194,7 @@
&image,
&name,
&comment,
+ &priority,
&in_use,
&is_separate,
data->user_data);
@@ -201,6 +205,7 @@
CHOOSER_IMAGE_COLUMN, image,
CHOOSER_NAME_COLUMN, name,
CHOOSER_COMMENT_COLUMN, comment,
+ CHOOSER_PRIORITY_COLUMN, priority,
CHOOSER_ITEM_IS_IN_USE_COLUMN, in_use,
CHOOSER_ITEM_IS_SEPARATED_COLUMN, is_separate,
-1);
@@ -1226,11 +1231,14 @@
GdmChooserWidget *widget;
char *name_a;
char *name_b;
+ gulong prio_a;
+ gulong prio_b;
gboolean is_separate_a;
gboolean is_separate_b;
int result;
int direction;
GtkTreeIter *separator_iter;
+ char *id;
g_assert (GDM_IS_CHOOSER_WIDGET (data));
@@ -1260,17 +1268,18 @@
if (separator_iter != a) {
gtk_tree_model_get (model, a,
CHOOSER_NAME_COLUMN, &name_a,
+ CHOOSER_PRIORITY_COLUMN, &prio_a,
CHOOSER_ITEM_IS_SEPARATED_COLUMN, &is_separate_a,
-1);
}
- char *id;
name_b = NULL;
is_separate_b = FALSE;
if (separator_iter != b) {
gtk_tree_model_get (model, b,
CHOOSER_NAME_COLUMN, &name_b,
CHOOSER_ID_COLUMN, &id,
+ CHOOSER_PRIORITY_COLUMN, &prio_b,
CHOOSER_ITEM_IS_SEPARATED_COLUMN, &is_separate_b,
-1);
}
@@ -1288,7 +1297,13 @@
result = is_separate_b? -1 : 1;
result *= direction;
} else if (is_separate_b == is_separate_a) {
- result = g_utf8_collate (name_a, name_b);
+ if (prio_a == prio_b) {
+ result = g_utf8_collate (name_a, name_b);
+ } else if (prio_a > prio_b) {
+ result = -1;
+ } else {
+ result = 1;
+ }
} else {
result = is_separate_a - is_separate_b;
result *= direction;
@@ -1545,11 +1560,12 @@
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget->priv->items_view));
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
- g_assert (NUMBER_OF_CHOOSER_COLUMNS == 7);
+ g_assert (NUMBER_OF_CHOOSER_COLUMNS == 8);
widget->priv->list_store = gtk_list_store_new (NUMBER_OF_CHOOSER_COLUMNS,
GDK_TYPE_PIXBUF,
G_TYPE_STRING,
G_TYPE_STRING,
+ G_TYPE_ULONG,
G_TYPE_BOOLEAN,
G_TYPE_BOOLEAN,
G_TYPE_BOOLEAN,
@@ -1667,6 +1683,7 @@
GdkPixbuf *new_image,
const char *new_name,
const char *new_comment,
+ gulong new_priority,
gboolean new_in_use,
gboolean new_is_separate)
{
@@ -1728,6 +1745,7 @@
CHOOSER_IMAGE_COLUMN, new_image,
CHOOSER_NAME_COLUMN, new_name,
CHOOSER_COMMENT_COLUMN, new_comment,
+ CHOOSER_PRIORITY_COLUMN, new_priority,
CHOOSER_ITEM_IS_IN_USE_COLUMN, new_in_use,
CHOOSER_ITEM_IS_SEPARATED_COLUMN, new_is_separate,
-1);
@@ -1739,6 +1757,7 @@
GdkPixbuf *image,
const char *name,
const char *comment,
+ gulong priority,
gboolean in_use,
gboolean keep_separate)
{
@@ -1769,6 +1788,7 @@
CHOOSER_IMAGE_COLUMN, image,
CHOOSER_NAME_COLUMN, name,
CHOOSER_COMMENT_COLUMN, comment,
+ CHOOSER_PRIORITY_COLUMN, priority,
CHOOSER_ITEM_IS_IN_USE_COLUMN, in_use,
CHOOSER_ITEM_IS_SEPARATED_COLUMN, keep_separate,
CHOOSER_ITEM_IS_VISIBLE_COLUMN, is_visible,
@@ -1831,6 +1851,7 @@
GdkPixbuf **image,
char **name,
char **comment,
+ gulong *priority,
gboolean *is_in_use,
gboolean *is_separate)
{
@@ -1854,6 +1875,7 @@
gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
CHOOSER_IMAGE_COLUMN, image,
CHOOSER_NAME_COLUMN, name,
+ CHOOSER_PRIORITY_COLUMN, priority,
CHOOSER_ITEM_IS_IN_USE_COLUMN, is_in_use,
CHOOSER_ITEM_IS_SEPARATED_COLUMN, is_separate,
-1);
@@ -1897,6 +1919,34 @@
}
void
+gdm_chooser_widget_set_item_priority (GdmChooserWidget *widget,
+ const char *id,
+ gulong priority)
+{
+ GtkTreeIter iter;
+ gulong was_priority;
+
+ g_return_if_fail (GDM_IS_CHOOSER_WIDGET (widget));
+
+ if (!find_item (widget, id, &iter)) {
+ return;
+ }
+
+ gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
+ CHOOSER_PRIORITY_COLUMN, &was_priority,
+ -1);
+
+ if (was_priority != priority) {
+
+ gtk_list_store_set (widget->priv->list_store,
+ &iter,
+ CHOOSER_PRIORITY_COLUMN, priority,
+ -1);
+ gtk_tree_model_filter_refilter (widget->priv->model_filter);
+ }
+}
+
+void
gdm_chooser_widget_set_in_use_message (GdmChooserWidget *widget,
const char *message)
{
Modified: trunk/gui/simple-greeter/gdm-chooser-widget.h
==============================================================================
--- trunk/gui/simple-greeter/gdm-chooser-widget.h (original)
+++ trunk/gui/simple-greeter/gdm-chooser-widget.h Mon Feb 4 15:23:19 2008
@@ -64,6 +64,7 @@
GdkPixbuf **image,
char **name,
char **comment,
+ gulong *priority,
gboolean *is_in_use,
gboolean *is_separate,
gpointer data);
@@ -77,6 +78,7 @@
GdkPixbuf *image,
const char *name,
const char *comment,
+ gulong priority,
gboolean is_in_use,
gboolean keep_separate);
@@ -89,6 +91,7 @@
GdkPixbuf *new_image,
const char *new_name,
const char *new_comment,
+ gulong priority,
gboolean new_in_use,
gboolean new_is_separate);
@@ -100,6 +103,7 @@
GdkPixbuf **image,
char **name,
char **comment,
+ gulong *priority,
gboolean *is_in_use,
gboolean *is_separate);
@@ -110,6 +114,9 @@
void gdm_chooser_widget_set_item_in_use (GdmChooserWidget *widget,
const char *id,
gboolean is_in_use);
+void gdm_chooser_widget_set_item_priority (GdmChooserWidget *widget,
+ const char *id,
+ gulong priority);
void gdm_chooser_widget_set_in_use_message (GdmChooserWidget *widget,
const char *message);
Modified: trunk/gui/simple-greeter/gdm-language-chooser-widget.c
==============================================================================
--- trunk/gui/simple-greeter/gdm-language-chooser-widget.c (original)
+++ trunk/gui/simple-greeter/gdm-language-chooser-widget.c Mon Feb 4 15:23:19 2008
@@ -127,7 +127,11 @@
if (language != NULL) {
gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget),
normalized_name,
- NULL, language, "", FALSE,
+ NULL,
+ language,
+ "",
+ 0,
+ FALSE,
FALSE);
g_free (language);
}
Modified: trunk/gui/simple-greeter/gdm-session-chooser-widget.c
==============================================================================
--- trunk/gui/simple-greeter/gdm-session-chooser-widget.c (original)
+++ trunk/gui/simple-greeter/gdm-session-chooser-widget.c Mon Feb 4 15:23:19 2008
@@ -349,9 +349,14 @@
g_debug ("Not adding session to list: %s", session->filename);
}
- gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget), name,
- NULL, session->translated_name,
- session->translated_comment, FALSE, FALSE);
+ gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget),
+ name,
+ NULL,
+ session->translated_name,
+ session->translated_comment,
+ 0,
+ FALSE,
+ FALSE);
}
static void
@@ -359,15 +364,21 @@
{
gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget),
GDM_SESSION_CHOOSER_SESSION_PREVIOUS,
- NULL, _("Default"),
+ NULL,
+ _("Default"),
_("Login with the same session as "
"last time."),
- FALSE, TRUE);
+ 0,
+ FALSE,
+ TRUE);
gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget),
GDM_SESSION_CHOOSER_SESSION_DEFAULT,
- NULL, _("Legacy"),
+ NULL,
+ _("Legacy"),
_("Login based on preset legacy configuration"),
- FALSE, TRUE);
+ 0,
+ FALSE,
+ TRUE);
g_hash_table_foreach (widget->priv->available_sessions,
(GHFunc) add_session,
Modified: trunk/gui/simple-greeter/gdm-user-chooser-widget.c
==============================================================================
--- trunk/gui/simple-greeter/gdm-user-chooser-widget.c (original)
+++ trunk/gui/simple-greeter/gdm-user-chooser-widget.c Mon Feb 4 15:23:19 2008
@@ -312,14 +312,18 @@
GDM_USER_CHOOSER_USER_OTHER,
widget->priv->stock_person_pixbuf,
_("Other..."),
- _("Choose a different account"), FALSE,
+ _("Choose a different account"),
+ 0,
+ FALSE,
TRUE);
gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget),
GDM_USER_CHOOSER_USER_GUEST,
widget->priv->stock_person_pixbuf,
_("Guest"),
- _("Login as a temporary guest"), FALSE,
+ _("Login as a temporary guest"),
+ 0,
+ FALSE,
TRUE);
return FALSE;
@@ -354,6 +358,7 @@
pixbuf,
gdm_user_get_real_name (user),
tooltip,
+ gdm_user_get_login_frequency (user),
is_logged_in,
FALSE);
g_free (tooltip);
@@ -397,6 +402,24 @@
}
static void
+on_user_login_frequency_changed (GdmUserManager *manager,
+ GdmUser *user,
+ GdmUserChooserWidget *widget)
+{
+ const char *user_name;
+ gulong freq;
+
+ g_debug ("GdmUserChooserWidget: User login frequency changed: %s", gdm_user_get_user_name (user));
+
+ user_name = gdm_user_get_user_name (user);
+ freq = gdm_user_get_login_frequency (user);
+
+ gdm_chooser_widget_set_item_priority (GDM_CHOOSER_WIDGET (widget),
+ user_name,
+ freq);
+}
+
+static void
gdm_user_chooser_widget_init (GdmUserChooserWidget *widget)
{
widget->priv = GDM_USER_CHOOSER_WIDGET_GET_PRIVATE (widget);
@@ -419,6 +442,10 @@
"user-is-logged-in-changed",
G_CALLBACK (on_user_is_logged_in_changed),
widget);
+ g_signal_connect (widget->priv->manager,
+ "user-login-frequency-changed",
+ G_CALLBACK (on_user_login_frequency_changed),
+ widget);
setup_icons (widget);
add_special_users (widget);
Modified: trunk/gui/simple-greeter/gdm-user-manager.c
==============================================================================
--- trunk/gui/simple-greeter/gdm-user-manager.c (original)
+++ trunk/gui/simple-greeter/gdm-user-manager.c Mon Feb 4 15:23:19 2008
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
- * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ * Copyright (C) 2007-2008 William Jon McCann <mccann jhu edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,13 +34,11 @@
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <glib-object.h>
-#define DBUS_API_SUBJECT_TO_CHANGE
+
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
-#include <libgnomevfs/gnome-vfs.h>
-
#include "gdm-user-manager.h"
#include "gdm-user-private.h"
@@ -60,15 +58,10 @@
#define DEFAULT_MAX_ICON_SIZE 128
#define DEFAULT_USER_MAX_FILE 65536
-#ifdef __sun
-#define DEFAULT_MINIMAL_UID 100
-#else
-#define DEFAULT_MINIMAL_UID 500
-#endif
-
#define DEFAULT_GLOBAL_FACE_DIR DATADIR "/faces"
#define DEFAULT_USER_ICON "stock_person"
#define DEFAULT_EXCLUDE { "bin", \
+ "root", \
"daemon", \
"adm", \
"lp", \
@@ -92,16 +85,13 @@
{
GHashTable *users;
GHashTable *sessions;
- GHashTable *shells;
GHashTable *exclusions;
- GnomeVFSMonitorHandle *passwd_monitor;
- GnomeVFSMonitorHandle *shells_monitor;
DBusGConnection *connection;
DBusGProxy *seat_proxy;
char *seat_id;
guint reload_id;
- uid_t minimal_uid;
+ guint ck_history_id;
guint8 users_dirty : 1;
};
@@ -110,6 +100,7 @@
USER_ADDED,
USER_REMOVED,
USER_IS_LOGGED_IN_CHANGED,
+ USER_LOGIN_FREQUENCY_CHANGED,
LAST_SIGNAL
};
@@ -664,143 +655,236 @@
return g_slist_sort (retval, (GCompareFunc) gdm_user_collate);
}
-static void
-reload_passwd (GdmUserManager *manager)
+static gboolean
+parse_value_as_ulong (const char *value,
+ gulong *ulongval)
{
- struct passwd *pwent;
- GSList *old_users;
- GSList *new_users;
- GSList *list;
-
- old_users = NULL;
- new_users = NULL;
-
- g_hash_table_foreach (manager->priv->users, listify_hash_values_hfunc, &old_users);
- g_slist_foreach (old_users, (GFunc) g_object_ref, NULL);
-
- /* Make sure we keep users who are logged in no matter what. */
- for (list = old_users; list; list = list->next) {
- if (gdm_user_get_num_sessions (list->data) > 0) {
- g_object_freeze_notify (G_OBJECT (list->data));
- new_users = g_slist_prepend (new_users, g_object_ref (list->data));
- }
+ char *end_of_valid_long;
+ glong long_value;
+ gulong ulong_value;
+
+ errno = 0;
+ long_value = strtol (value, &end_of_valid_long, 10);
+
+ if (*value == '\0' || *end_of_valid_long != '\0') {
+ return FALSE;
}
- setpwent ();
+ ulong_value = long_value;
+ if (ulong_value != long_value || errno == ERANGE) {
+ return FALSE;
+ }
- for (pwent = getpwent (); pwent; pwent = getpwent ()) {
- GdmUser *user;
+ *ulongval = ulong_value;
- user = NULL;
+ return TRUE;
+}
- /* Skip users below MinimalUID... */
- if (pwent->pw_uid < manager->priv->minimal_uid) {
- continue;
- }
+static gboolean
+parse_ck_history_line (const char *line,
+ char **user_namep,
+ gulong *frequencyp)
+{
+ GRegex *re;
+ GMatchInfo *match_info;
+ gboolean res;
+ gboolean ret;
+ GError *error;
- /* ...And users w/ invalid shells... */
- if (!pwent->pw_shell ||
- !g_hash_table_lookup (manager->priv->shells, pwent->pw_shell)) {
- continue;
- }
+ ret = FALSE;
+ re = NULL;
+ match_info = NULL;
- /* ...And explicitly excluded users */
- if (g_hash_table_lookup (manager->priv->exclusions, pwent->pw_name)) {
- continue;
- }
+ error = NULL;
+ re = g_regex_new ("(?P<username>[0-9a-zA-Z]+)[ ]+(?P<frequency>[0-9]+)", 0, 0, &error);
+ if (re == NULL) {
+ g_critical (error->message);
+ goto out;
+ }
- user = g_hash_table_lookup (manager->priv->users, pwent->pw_name);
+ g_regex_match (re, line, 0, &match_info);
- /* Update users already in the *new* list */
- if (g_slist_find (new_users, user)) {
- _gdm_user_update (user, pwent);
- continue;
- }
+ res = g_match_info_matches (match_info);
+ if (! res) {
+ g_warning ("Unable to parse history: %s", line);
+ goto out;
+ }
+
+ if (user_namep != NULL) {
+ *user_namep = g_match_info_fetch_named (match_info, "username");
+ }
- if (user == NULL) {
- user = create_user (manager);
- } else {
- g_object_ref (user);
+ if (frequencyp != NULL) {
+ char *freq;
+ freq = g_match_info_fetch_named (match_info, "frequency");
+ res = parse_value_as_ulong (freq, frequencyp);
+ g_free (freq);
+ if (! res) {
+ goto out;
}
+ }
- /* Freeze & update users not already in the new list */
- g_object_freeze_notify (G_OBJECT (user));
- _gdm_user_update (user, pwent);
+ ret = TRUE;
- new_users = g_slist_prepend (new_users, user);
+ out:
+ if (match_info != NULL) {
+ g_match_info_free (match_info);
+ }
+ if (re != NULL) {
+ g_regex_unref (re);
}
+ return ret;
+}
- endpwent ();
+static void
+process_ck_history_line (GdmUserManager *manager,
+ const char *line)
+{
+ gboolean res;
+ char *username;
+ gulong frequency;
+ GdmUser *user;
- /* Go through and handle added users */
- for (list = new_users; list; list = list->next) {
- if (! g_slist_find (old_users, list->data)) {
- add_user (manager, list->data);
- }
+ frequency = 0;
+ username = NULL;
+ res = parse_ck_history_line (line, &username, &frequency);
+ if (! res) {
+ return;
}
- /* Go through and handle removed users */
- for (list = old_users; list; list = list->next) {
- if (! g_slist_find (new_users, list->data)) {
- g_signal_emit (manager, signals[USER_REMOVED], 0, list->data);
- g_hash_table_remove (manager->priv->users,
- gdm_user_get_user_name (list->data));
+ if (g_hash_table_lookup (manager->priv->exclusions, username)) {
+ g_debug ("GdmUserManager: excluding user '%s'", username);
+ g_free (username);
+ return;
+ }
+
+ user = gdm_user_manager_get_user (manager, username);
+ g_object_set (user, "login-frequency", frequency, NULL);
+ g_signal_emit (manager, signals [USER_LOGIN_FREQUENCY_CHANGED], 0, user);
+}
+
+static gboolean
+ck_history_watch (GIOChannel *source,
+ GIOCondition condition,
+ GdmUserManager *manager)
+{
+ GIOStatus status;
+ gboolean done = FALSE;
+
+ g_return_val_if_fail (manager != NULL, FALSE);
+
+ if (condition & G_IO_IN) {
+ char *str;
+ GError *error;
+
+ error = NULL;
+ status = g_io_channel_read_line (source, &str, NULL, NULL, &error);
+ if (error != NULL) {
+ g_warning ("GdmUserManager: unable to read line: %s", error->message);
+ g_error_free (error);
+ }
+
+ if (status == G_IO_STATUS_NORMAL) {
+ g_debug ("GdmUserManager: history output: %s", str);
+ process_ck_history_line (manager, str);
+ } else if (status == G_IO_STATUS_EOF) {
+ done = TRUE;
}
+
+ g_free (str);
+ } else if (condition & G_IO_HUP) {
+ done = TRUE;
}
- /* Cleanup */
- g_slist_foreach (new_users, (GFunc) g_object_thaw_notify, NULL);
- g_slist_foreach (new_users, (GFunc) g_object_unref, NULL);
- g_slist_free (new_users);
+ if (done) {
+ manager->priv->ck_history_id = 0;
+ return FALSE;
+ }
- g_slist_foreach (old_users, (GFunc) g_object_unref, NULL);
- g_slist_free (old_users);
+ return TRUE;
}
static void
-reload_shells (GdmUserManager *manager)
+reload_users (GdmUserManager *manager)
{
- char *shell;
+ char *command;
+ const char *seat_id;
+ GError *error;
+ gboolean res;
+ char **argv;
+ int standard_out;
+ GIOChannel *channel;
- setusershell ();
+ seat_id = NULL;
+ if (manager->priv->seat_id != NULL
+ && g_str_has_prefix (manager->priv->seat_id, "/org/freedesktop/ConsoleKit/")) {
- g_hash_table_remove_all (manager->priv->shells);
- for (shell = getusershell (); shell; shell = getusershell ()) {
- g_hash_table_insert (manager->priv->shells,
- g_strdup (shell),
- GUINT_TO_POINTER (TRUE));
+ seat_id = manager->priv->seat_id + strlen ("/org/freedesktop/ConsoleKit/");
+ }
+
+ if (seat_id == NULL) {
+ g_warning ("Unable to find users: no seat-id found");
}
- endusershell ();
+ command = g_strdup_printf ("ck-history --frequent --seat='%s' --session-type=''",
+ seat_id);
+ g_debug ("GdmUserManager: running '%s'", command);
+ error = NULL;
+ if (! g_shell_parse_argv (command, NULL, &argv, &error)) {
+ g_warning ("Could not parse command: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ error = NULL;
+ res = g_spawn_async_with_pipes (NULL,
+ argv,
+ NULL,
+ G_SPAWN_SEARCH_PATH,
+ NULL,
+ NULL,
+ NULL, /* pid */
+ NULL,
+ &standard_out,
+ NULL,
+ &error);
+ if (! res) {
+ g_warning ("Unable to run ck-history: %s", error->message);
+ g_error_free (error);
+ }
+ g_strfreev (argv);
+
+ channel = g_io_channel_unix_new (standard_out);
+ g_io_channel_set_close_on_unref (channel, TRUE);
+ g_io_channel_set_flags (channel,
+ g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK,
+ NULL);
+ manager->priv->ck_history_id = g_io_add_watch (channel,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ (GIOFunc)ck_history_watch,
+ manager);
+ g_io_channel_unref (channel);
+
+ out:
+ g_free (command);
}
-static void
-shells_monitor_cb (GnomeVFSMonitorHandle *handle,
- const gchar *text_uri,
- const gchar *info_uri,
- GnomeVFSMonitorEventType event_type,
- GdmUserManager *manager)
+static gboolean
+reload_users_timeout (GdmUserManager *manager)
{
- if (event_type != GNOME_VFS_MONITOR_EVENT_CHANGED &&
- event_type != GNOME_VFS_MONITOR_EVENT_CREATED)
- return;
-
- reload_shells (manager);
- reload_passwd (manager);
+ reload_users (manager);
+ manager->priv->reload_id = 0;
+ return FALSE;
}
static void
-passwd_monitor_cb (GnomeVFSMonitorHandle *handle,
- const gchar *text_uri,
- const gchar *info_uri,
- GnomeVFSMonitorEventType event_type,
- GdmUserManager *manager)
+queue_reload_users (GdmUserManager *manager)
{
- if (event_type != GNOME_VFS_MONITOR_EVENT_CHANGED &&
- event_type != GNOME_VFS_MONITOR_EVENT_CREATED)
+ if (manager->priv->reload_id > 0) {
return;
+ }
- reload_passwd (manager);
+ manager->priv->reload_id = g_idle_add ((GSourceFunc)reload_users_timeout, manager);
}
static void
@@ -834,45 +918,26 @@
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, GDM_TYPE_USER);
+ signals [USER_LOGIN_FREQUENCY_CHANGED] =
+ g_signal_new ("user-login-frequency-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdmUserManagerClass, user_login_frequency_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, GDM_TYPE_USER);
g_type_class_add_private (klass, sizeof (GdmUserManagerPrivate));
}
-static gboolean
-reload_passwd_timeout (GdmUserManager *manager)
-{
- reload_passwd (manager);
- manager->priv->reload_id = 0;
- return FALSE;
-}
-
-static void
-queue_reload_passwd (GdmUserManager *manager)
-{
- if (manager->priv->reload_id > 0) {
- return;
- }
-
- manager->priv->reload_id = g_idle_add ((GSourceFunc)reload_passwd_timeout, manager);
-}
-
static void
gdm_user_manager_init (GdmUserManager *manager)
{
- GError *error;
- char *uri;
- GnomeVFSResult result;
int i;
const char *exclude_default[] = DEFAULT_EXCLUDE;
- if (! gnome_vfs_initialized ()) {
- gnome_vfs_init ();
- }
-
manager->priv = GDM_USER_MANAGER_GET_PRIVATE (manager);
- manager->priv->minimal_uid = DEFAULT_MINIMAL_UID;
-
/* sessions */
manager->priv->sessions = g_hash_table_new_full (g_str_hash,
g_str_equal,
@@ -890,58 +955,14 @@
GUINT_TO_POINTER (TRUE));
}
- /* /etc/shells */
- manager->priv->shells = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- NULL);
- reload_shells (manager);
- error = NULL;
- uri = g_filename_to_uri ("/etc/shells", NULL, &error);
- if (uri == NULL) {
- g_warning ("Could not create URI for shells file `/etc/shells': %s",
- error->message);
- g_error_free (error);
- } else {
- result = gnome_vfs_monitor_add (&(manager->priv->shells_monitor),
- uri,
- GNOME_VFS_MONITOR_FILE,
- (GnomeVFSMonitorCallback)shells_monitor_cb,
- manager);
- g_free (uri);
-
- if (result != GNOME_VFS_OK)
- g_warning ("Could not install monitor for shells file `/etc/shells': %s",
- gnome_vfs_result_to_string (result));
- }
-
- /* /etc/passwd */
manager->priv->users = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) g_object_run_dispose);
- error = NULL;
- uri = g_filename_to_uri ("/etc/passwd", NULL, &error);
- if (uri == NULL) {
- g_warning ("Could not create URI for password file `/etc/passwd': %s",
- error->message);
- g_error_free (error);
- } else {
- result = gnome_vfs_monitor_add (&(manager->priv->passwd_monitor),
- uri,
- GNOME_VFS_MONITOR_FILE,
- (GnomeVFSMonitorCallback)passwd_monitor_cb,
- manager);
- g_free (uri);
-
- if (result != GNOME_VFS_OK)
- g_warning ("Could not install monitor for password file `/etc/passwd: %s",
- gnome_vfs_result_to_string (result));
- }
get_seat_proxy (manager);
- queue_reload_passwd (manager);
+ queue_reload_users (manager);
manager->priv->users_dirty = FALSE;
}
@@ -962,6 +983,11 @@
g_object_unref (manager->priv->seat_proxy);
}
+ if (manager->priv->ck_history_id != 0) {
+ g_source_remove (manager->priv->ck_history_id);
+ manager->priv->ck_history_id = 0;
+ }
+
if (manager->priv->reload_id > 0) {
g_source_remove (manager->priv->reload_id);
manager->priv->reload_id = 0;
@@ -969,10 +995,6 @@
g_hash_table_destroy (manager->priv->sessions);
- gnome_vfs_monitor_cancel (manager->priv->shells_monitor);
- g_hash_table_destroy (manager->priv->shells);
-
- gnome_vfs_monitor_cancel (manager->priv->passwd_monitor);
g_hash_table_destroy (manager->priv->users);
g_free (manager->priv->seat_id);
Modified: trunk/gui/simple-greeter/gdm-user-manager.h
==============================================================================
--- trunk/gui/simple-greeter/gdm-user-manager.h (original)
+++ trunk/gui/simple-greeter/gdm-user-manager.h Mon Feb 4 15:23:19 2008
@@ -52,6 +52,8 @@
GdmUser *user);
void (* user_is_logged_in_changed) (GdmUserManager *user_manager,
GdmUser *user);
+ void (* user_login_frequency_changed) (GdmUserManager *user_manager,
+ GdmUser *user);
} GdmUserManagerClass;
typedef enum
Modified: trunk/gui/simple-greeter/gdm-user.c
==============================================================================
--- trunk/gui/simple-greeter/gdm-user.c (original)
+++ trunk/gui/simple-greeter/gdm-user.c Mon Feb 4 15:23:19 2008
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2004-2005 James M. Cape <jcape ignore-your tv>.
- * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ * Copyright (C) 2007-2008 William Jon McCann <mccann jhu edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -51,6 +51,7 @@
PROP_UID,
PROP_HOME_DIR,
PROP_SHELL,
+ PROP_LOGIN_FREQUENCY,
};
enum {
@@ -70,6 +71,7 @@
char *home_dir;
char *shell;
GSList *sessions;
+ gulong login_frequency;
};
typedef struct _GdmUserClass
@@ -145,6 +147,14 @@
}
static void
+_gdm_user_set_login_frequency (GdmUser *user,
+ gulong login_frequency)
+{
+ user->login_frequency = login_frequency;
+ g_object_notify (G_OBJECT (user), "login-frequency");
+}
+
+static void
gdm_user_set_property (GObject *object,
guint param_id,
const GValue *value,
@@ -159,7 +169,9 @@
user->manager = g_value_get_object (value);
g_assert (user->manager);
break;
-
+ case PROP_LOGIN_FREQUENCY:
+ _gdm_user_set_login_frequency (user, g_value_get_ulong (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -195,6 +207,9 @@
case PROP_SHELL:
g_value_set_string (value, user->shell);
break;
+ case PROP_LOGIN_FREQUENCY:
+ g_value_set_ulong (value, user->login_frequency);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -257,6 +272,15 @@
"The shell for this user.",
NULL,
G_PARAM_READABLE));
+ g_object_class_install_property (gobject_class,
+ PROP_LOGIN_FREQUENCY,
+ g_param_spec_ulong ("login-frequency",
+ "login frequency",
+ "login frequency",
+ 0,
+ G_MAXULONG,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
signals [ICON_CHANGED] =
g_signal_new ("icon-changed",
@@ -283,6 +307,10 @@
user->user_name = NULL;
user->real_name = NULL;
user->sessions = NULL;
+
+ if (! gnome_vfs_initialized ()) {
+ gnome_vfs_init ();
+ }
}
static void
@@ -507,6 +535,14 @@
return user->shell;
}
+gulong
+gdm_user_get_login_frequency (GdmUser *user)
+{
+ g_return_val_if_fail (GDM_IS_USER (user), 0);
+
+ return user->login_frequency;
+}
+
gint
gdm_user_collate (GdmUser *user1,
GdmUser *user2)
Modified: trunk/gui/simple-greeter/gdm-user.h
==============================================================================
--- trunk/gui/simple-greeter/gdm-user.h (original)
+++ trunk/gui/simple-greeter/gdm-user.h Mon Feb 4 15:23:19 2008
@@ -1,6 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2004-2005 James M. Cape <jcape ignore-your tv>.
+ * Copyright (C) 2007-2008 William Jon McCann <mccann jhu edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,6 +45,7 @@
G_CONST_RETURN char *gdm_user_get_home_directory (GdmUser *user);
G_CONST_RETURN char *gdm_user_get_shell (GdmUser *user);
guint gdm_user_get_num_sessions (GdmUser *user);
+gulong gdm_user_get_login_frequency (GdmUser *user);
GdkPixbuf *gdm_user_render_icon (GdmUser *user,
gint icon_size);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]