summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Jon McCann <mccann@jhu.edu>2007-10-02 14:19:05 +0000
committerWilliam Jon McCann <mccann@src.gnome.org>2007-10-02 14:19:05 +0000
commit1d6d2e1b5d502ae980313300fac2c00573cd25ad (patch)
treebba3d855c5de81acef967d88bded5aa94eece5dc
parentc67fd11bb6c10d9eee11e58a20dcb59ae2cca6ae (diff)
downloadgdm-1d6d2e1b5d502ae980313300fac2c00573cd25ad.tar.gz
Add skeleton for user switcher widget.
2007-10-02 William Jon McCann <mccann@jhu.edu> * gui/simple-greeter/Makefile.am: * gui/simple-greeter/gdm-language-chooser-widget.c: * gui/simple-greeter/gdm-session-chooser-dialog.c: (gdm_session_chooser_dialog_init): * gui/simple-greeter/gdm-session-chooser-widget.c: * gui/simple-greeter/gdm-simple-greeter.c: (create_greeter): * gui/simple-greeter/gdm-user-chooser-dialog.c: (gdm_user_chooser_dialog_get_current_user_name), (gdm_user_chooser_dialog_set_property), (gdm_user_chooser_dialog_get_property), (gdm_user_chooser_dialog_constructor), (gdm_user_chooser_dialog_dispose), (gdm_user_chooser_dialog_class_init), (on_response), (gdm_user_chooser_dialog_init), (gdm_user_chooser_dialog_finalize), (gdm_user_chooser_dialog_new): * gui/simple-greeter/gdm-user-chooser-dialog.h: * gui/simple-greeter/gdm-user-chooser-widget.c: (chooser_user_free), (gdm_user_chooser_widget_get_current_user_name), (select_name), (gdm_user_chooser_widget_set_current_user_name), (gdm_user_chooser_widget_set_property), (gdm_user_chooser_widget_get_property), (gdm_user_chooser_widget_constructor), (gdm_user_chooser_widget_dispose), (gdm_user_chooser_widget_class_init), (on_selection_changed), (collect_users), (on_item_activated), (add_user_to_model), (get_pixbuf_for_user), (populate_model), (separator_func), (compare_user_names), (compare_user), (gdm_user_chooser_widget_init), (gdm_user_chooser_widget_finalize), (gdm_user_chooser_widget_new): * gui/simple-greeter/gdm-user-chooser-widget.h: * gui/simple-greeter/greeter-main.c: (activate_power_manager): * gui/simple-greeter/test-user-chooser.c: (main): Add skeleton for user switcher widget. svn path=/branches/mccann-gobject/; revision=5326
-rw-r--r--ChangeLog37
-rw-r--r--gui/simple-greeter/Makefile.am13
-rw-r--r--gui/simple-greeter/gdm-language-chooser-widget.c1
-rw-r--r--gui/simple-greeter/gdm-session-chooser-dialog.c1
-rw-r--r--gui/simple-greeter/gdm-session-chooser-widget.c1
-rw-r--r--gui/simple-greeter/gdm-simple-greeter.c6
-rw-r--r--gui/simple-greeter/gdm-user-chooser-dialog.c196
-rw-r--r--gui/simple-greeter/gdm-user-chooser-dialog.h57
-rw-r--r--gui/simple-greeter/gdm-user-chooser-widget.c570
-rw-r--r--gui/simple-greeter/gdm-user-chooser-widget.h61
-rw-r--r--gui/simple-greeter/greeter-main.c2
-rw-r--r--gui/simple-greeter/test-user-chooser.c61
12 files changed, 999 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index a9f2fc55..3be94160 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2007-10-02 William Jon McCann <mccann@jhu.edu>
+
+ * gui/simple-greeter/Makefile.am:
+ * gui/simple-greeter/gdm-language-chooser-widget.c:
+ * gui/simple-greeter/gdm-session-chooser-dialog.c:
+ (gdm_session_chooser_dialog_init):
+ * gui/simple-greeter/gdm-session-chooser-widget.c:
+ * gui/simple-greeter/gdm-simple-greeter.c: (create_greeter):
+ * gui/simple-greeter/gdm-user-chooser-dialog.c:
+ (gdm_user_chooser_dialog_get_current_user_name),
+ (gdm_user_chooser_dialog_set_property),
+ (gdm_user_chooser_dialog_get_property),
+ (gdm_user_chooser_dialog_constructor),
+ (gdm_user_chooser_dialog_dispose),
+ (gdm_user_chooser_dialog_class_init), (on_response),
+ (gdm_user_chooser_dialog_init), (gdm_user_chooser_dialog_finalize),
+ (gdm_user_chooser_dialog_new):
+ * gui/simple-greeter/gdm-user-chooser-dialog.h:
+ * gui/simple-greeter/gdm-user-chooser-widget.c:
+ (chooser_user_free),
+ (gdm_user_chooser_widget_get_current_user_name), (select_name),
+ (gdm_user_chooser_widget_set_current_user_name),
+ (gdm_user_chooser_widget_set_property),
+ (gdm_user_chooser_widget_get_property),
+ (gdm_user_chooser_widget_constructor),
+ (gdm_user_chooser_widget_dispose),
+ (gdm_user_chooser_widget_class_init), (on_selection_changed),
+ (collect_users), (on_item_activated), (add_user_to_model),
+ (get_pixbuf_for_user), (populate_model), (separator_func),
+ (compare_user_names), (compare_user),
+ (gdm_user_chooser_widget_init), (gdm_user_chooser_widget_finalize),
+ (gdm_user_chooser_widget_new):
+ * gui/simple-greeter/gdm-user-chooser-widget.h:
+ * gui/simple-greeter/greeter-main.c: (activate_power_manager):
+ * gui/simple-greeter/test-user-chooser.c: (main):
+ Add skeleton for user switcher widget.
+
2007-10-01 William Jon McCann <mccann@jhu.edu>
* gui/simple-greeter/gdm-session-chooser-widget.c:
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
index 7c7c4f74..1058525f 100644
--- a/gui/simple-greeter/Makefile.am
+++ b/gui/simple-greeter/Makefile.am
@@ -27,6 +27,7 @@ noinst_PROGRAMS = \
test-greeter-panel \
test-language-chooser \
test-session-chooser \
+ test-user-chooser \
$(NULL)
test_greeter_background_SOURCES = \
@@ -76,6 +77,18 @@ test_session_chooser_LDADD = \
$(GUI_LIBS) \
$(NULL)
+test_user_chooser_SOURCES = \
+ test-user-chooser.c \
+ gdm-user-chooser-widget.h \
+ gdm-user-chooser-widget.c \
+ gdm-user-chooser-dialog.h \
+ gdm-user-chooser-dialog.c \
+ $(NULL)
+
+test_user_chooser_LDADD = \
+ $(GUI_LIBS) \
+ $(NULL)
+
libexec_PROGRAMS = \
gdm-simple-greeter
diff --git a/gui/simple-greeter/gdm-language-chooser-widget.c b/gui/simple-greeter/gdm-language-chooser-widget.c
index 45492847..5921ec0d 100644
--- a/gui/simple-greeter/gdm-language-chooser-widget.c
+++ b/gui/simple-greeter/gdm-language-chooser-widget.c
@@ -1,6 +1,5 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
- * Copyright (C) 1998, 1999, 2000 Martin K, Petersen <mkp@mkp.net>
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/gui/simple-greeter/gdm-session-chooser-dialog.c b/gui/simple-greeter/gdm-session-chooser-dialog.c
index 02b124c5..1435e9fb 100644
--- a/gui/simple-greeter/gdm-session-chooser-dialog.c
+++ b/gui/simple-greeter/gdm-session-chooser-dialog.c
@@ -154,7 +154,6 @@ gdm_session_chooser_dialog_init (GdmSessionChooserDialog *dialog)
dialog->priv = GDM_SESSION_CHOOSER_DIALOG_GET_PRIVATE (dialog);
dialog->priv->chooser_widget = gdm_session_chooser_widget_new ();
- gdm_session_chooser_widget_set_current_session_name (GDM_SESSION_CHOOSER_WIDGET (dialog->priv->chooser_widget), g_getenv ("LANG"));
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), dialog->priv->chooser_widget);
diff --git a/gui/simple-greeter/gdm-session-chooser-widget.c b/gui/simple-greeter/gdm-session-chooser-widget.c
index 0be29dd4..7763da79 100644
--- a/gui/simple-greeter/gdm-session-chooser-widget.c
+++ b/gui/simple-greeter/gdm-session-chooser-widget.c
@@ -1,6 +1,5 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
- * Copyright (C) 1998, 1999, 2000 Martin K, Petersen <mkp@mkp.net>
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/gui/simple-greeter/gdm-simple-greeter.c b/gui/simple-greeter/gdm-simple-greeter.c
index 850100cc..760d7bbe 100644
--- a/gui/simple-greeter/gdm-simple-greeter.c
+++ b/gui/simple-greeter/gdm-simple-greeter.c
@@ -416,21 +416,21 @@ create_greeter (GdmSimpleGreeter *greeter)
#if 0
error = NULL;
- g_spawn_command_line_async ("gtk-window-decorator", &error);
+ g_spawn_command_line_async ("gtk-window-decorator --replace", &error);
if (error != NULL) {
g_warning ("Error starting WM: %s", error->message);
g_error_free (error);
}
error = NULL;
- g_spawn_command_line_async ("compiz", &error);
+ g_spawn_command_line_async ("compiz --replace", &error);
if (error != NULL) {
g_warning ("Error starting WM: %s", error->message);
g_error_free (error);
}
#else
error = NULL;
- g_spawn_command_line_async ("metacity", &error);
+ g_spawn_command_line_async ("metacity --replace", &error);
if (error != NULL) {
g_warning ("Error starting WM: %s", error->message);
g_error_free (error);
diff --git a/gui/simple-greeter/gdm-user-chooser-dialog.c b/gui/simple-greeter/gdm-user-chooser-dialog.c
new file mode 100644
index 00000000..89552a0e
--- /dev/null
+++ b/gui/simple-greeter/gdm-user-chooser-dialog.c
@@ -0,0 +1,196 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gdm-user-chooser-widget.h"
+#include "gdm-user-chooser-dialog.h"
+
+#define GDM_USER_CHOOSER_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_USER_CHOOSER_DIALOG, GdmUserChooserDialogPrivate))
+
+struct GdmUserChooserDialogPrivate
+{
+ GtkWidget *chooser_widget;
+};
+
+enum {
+ PROP_0,
+};
+
+static void gdm_user_chooser_dialog_class_init (GdmUserChooserDialogClass *klass);
+static void gdm_user_chooser_dialog_init (GdmUserChooserDialog *user_chooser_dialog);
+static void gdm_user_chooser_dialog_finalize (GObject *object);
+
+G_DEFINE_TYPE (GdmUserChooserDialog, gdm_user_chooser_dialog, GTK_TYPE_DIALOG)
+
+char *
+gdm_user_chooser_dialog_get_current_user_name (GdmUserChooserDialog *dialog)
+{
+ char *user_name;
+
+ g_return_val_if_fail (GDM_IS_USER_CHOOSER_DIALOG (dialog), NULL);
+
+ user_name = gdm_user_chooser_widget_get_current_user_name (GDM_USER_CHOOSER_WIDGET (dialog->priv->chooser_widget));
+
+ return user_name;
+}
+
+static void
+gdm_user_chooser_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GdmUserChooserDialog *self;
+
+ self = GDM_USER_CHOOSER_DIALOG (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gdm_user_chooser_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdmUserChooserDialog *self;
+
+ self = GDM_USER_CHOOSER_DIALOG (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GObject *
+gdm_user_chooser_dialog_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GdmUserChooserDialog *user_chooser_dialog;
+ GdmUserChooserDialogClass *klass;
+
+ klass = GDM_USER_CHOOSER_DIALOG_CLASS (g_type_class_peek (GDM_TYPE_USER_CHOOSER_DIALOG));
+
+ user_chooser_dialog = GDM_USER_CHOOSER_DIALOG (G_OBJECT_CLASS (gdm_user_chooser_dialog_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+
+ return G_OBJECT (user_chooser_dialog);
+}
+
+static void
+gdm_user_chooser_dialog_dispose (GObject *object)
+{
+ GdmUserChooserDialog *user_chooser_dialog;
+
+ user_chooser_dialog = GDM_USER_CHOOSER_DIALOG (object);
+
+ G_OBJECT_CLASS (gdm_user_chooser_dialog_parent_class)->dispose (object);
+}
+
+static void
+gdm_user_chooser_dialog_class_init (GdmUserChooserDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = gdm_user_chooser_dialog_get_property;
+ object_class->set_property = gdm_user_chooser_dialog_set_property;
+ object_class->constructor = gdm_user_chooser_dialog_constructor;
+ object_class->dispose = gdm_user_chooser_dialog_dispose;
+ object_class->finalize = gdm_user_chooser_dialog_finalize;
+
+ g_type_class_add_private (klass, sizeof (GdmUserChooserDialogPrivate));
+}
+
+static void
+on_response (GdmUserChooserDialog *dialog,
+ gint response_id)
+{
+ switch (response_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gdm_user_chooser_dialog_init (GdmUserChooserDialog *dialog)
+{
+
+ dialog->priv = GDM_USER_CHOOSER_DIALOG_GET_PRIVATE (dialog);
+
+ dialog->priv->chooser_widget = gdm_user_chooser_widget_new ();
+
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), dialog->priv->chooser_widget);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ g_signal_connect (dialog,
+ "response",
+ G_CALLBACK (on_response),
+ dialog);
+
+ gtk_widget_show_all (GTK_WIDGET (dialog));
+}
+
+static void
+gdm_user_chooser_dialog_finalize (GObject *object)
+{
+ GdmUserChooserDialog *user_chooser_dialog;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GDM_IS_USER_CHOOSER_DIALOG (object));
+
+ user_chooser_dialog = GDM_USER_CHOOSER_DIALOG (object);
+
+ g_return_if_fail (user_chooser_dialog->priv != NULL);
+
+ G_OBJECT_CLASS (gdm_user_chooser_dialog_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gdm_user_chooser_dialog_new (void)
+{
+ GObject *object;
+
+ object = g_object_new (GDM_TYPE_USER_CHOOSER_DIALOG,
+ NULL);
+
+ return GTK_WIDGET (object);
+}
diff --git a/gui/simple-greeter/gdm-user-chooser-dialog.h b/gui/simple-greeter/gdm-user-chooser-dialog.h
new file mode 100644
index 00000000..30fdcf49
--- /dev/null
+++ b/gui/simple-greeter/gdm-user-chooser-dialog.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __GDM_USER_CHOOSER_DIALOG_H
+#define __GDM_USER_CHOOSER_DIALOG_H
+
+#include <glib-object.h>
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_USER_CHOOSER_DIALOG (gdm_user_chooser_dialog_get_type ())
+#define GDM_USER_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_USER_CHOOSER_DIALOG, GdmUserChooserDialog))
+#define GDM_USER_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_USER_CHOOSER_DIALOG, GdmUserChooserDialogClass))
+#define GDM_IS_USER_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_USER_CHOOSER_DIALOG))
+#define GDM_IS_USER_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_USER_CHOOSER_DIALOG))
+#define GDM_USER_CHOOSER_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_USER_CHOOSER_DIALOG, GdmUserChooserDialogClass))
+
+typedef struct GdmUserChooserDialogPrivate GdmUserChooserDialogPrivate;
+
+typedef struct
+{
+ GtkDialog parent;
+ GdmUserChooserDialogPrivate *priv;
+} GdmUserChooserDialog;
+
+typedef struct
+{
+ GtkDialogClass parent_class;
+} GdmUserChooserDialogClass;
+
+GType gdm_user_chooser_dialog_get_type (void);
+
+GtkWidget * gdm_user_chooser_dialog_new (void);
+
+char * gdm_user_chooser_dialog_get_current_user_name (GdmUserChooserDialog *dialog);
+
+G_END_DECLS
+
+#endif /* __GDM_USER_CHOOSER_DIALOG_H */
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
new file mode 100644
index 00000000..69919861
--- /dev/null
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
@@ -0,0 +1,570 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+
+#include "gdm-user-chooser-widget.h"
+
+enum {
+ USER_NO_DISPLAY = 1 << 0,
+ USER_ACCOUNT_DISABLED = 1 << 1,
+};
+
+#define GDM_USER_CHOOSER_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_USER_CHOOSER_WIDGET, GdmUserChooserWidgetPrivate))
+
+typedef struct _GdmChooserUser {
+ char *name;
+ char *realname;
+ GdkPixbuf *pixbuf;
+ guint flags;
+} GdmChooserUser;
+
+struct GdmUserChooserWidgetPrivate
+{
+ GtkWidget *iconview;
+
+ GHashTable *available_users;
+ char *current_user;
+};
+
+enum {
+ PROP_0,
+};
+
+enum {
+ USER_ACTIVATED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
+static void gdm_user_chooser_widget_class_init (GdmUserChooserWidgetClass *klass);
+static void gdm_user_chooser_widget_init (GdmUserChooserWidget *user_chooser_widget);
+static void gdm_user_chooser_widget_finalize (GObject *object);
+
+G_DEFINE_TYPE (GdmUserChooserWidget, gdm_user_chooser_widget, GTK_TYPE_VBOX)
+
+enum {
+ CHOOSER_LIST_PIXBUF_COLUMN = 0,
+ CHOOSER_LIST_CAPTION_COLUMN,
+ CHOOSER_LIST_ID_COLUMN
+};
+
+static void
+chooser_user_free (GdmChooserUser *user)
+{
+ if (user == NULL) {
+ return;
+ }
+
+ if (user->pixbuf != NULL) {
+ g_object_unref (user->pixbuf);
+ }
+
+ g_free (user->name);
+ g_free (user->realname);
+
+ g_free (user);
+}
+
+char *
+gdm_user_chooser_widget_get_current_user_name (GdmUserChooserWidget *widget)
+{
+ char *user_name;
+
+ g_return_val_if_fail (GDM_IS_USER_CHOOSER_WIDGET (widget), NULL);
+
+ user_name = NULL;
+ if (widget->priv->current_user != NULL) {
+ user_name = g_strdup (widget->priv->current_user);
+ }
+
+ return user_name;
+}
+
+static void
+select_name (GdmUserChooserWidget *widget,
+ const char *name)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ path = NULL;
+
+ model = gtk_icon_view_get_model (GTK_ICON_VIEW (widget->priv->iconview));
+
+ if (name != NULL && gtk_tree_model_get_iter_first (model, &iter)) {
+
+ do {
+ GdmChooserUser *user;
+ char *id;
+ gboolean found;
+
+ user = NULL;
+ id = NULL;
+ gtk_tree_model_get (model,
+ &iter,
+ CHOOSER_LIST_ID_COLUMN, &id,
+ -1);
+ if (id != NULL) {
+ user = g_hash_table_lookup (widget->priv->available_users, id);
+ g_free (id);
+ }
+
+ found = (user != NULL
+ && user->name != NULL
+ && strcmp (user->name, name) == 0);
+
+ if (found) {
+ path = gtk_tree_model_get_path (model, &iter);
+ break;
+ }
+
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+
+ if (path != NULL) {
+ gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (widget->priv->iconview),
+ path,
+ TRUE,
+ 0.5,
+ 0.0);
+ gtk_icon_view_set_cursor (GTK_ICON_VIEW (widget->priv->iconview),
+ path,
+ NULL,
+ FALSE);
+
+ gtk_tree_path_free (path);
+ }
+}
+
+void
+gdm_user_chooser_widget_set_current_user_name (GdmUserChooserWidget *widget,
+ const char *name)
+{
+ g_return_if_fail (GDM_IS_USER_CHOOSER_WIDGET (widget));
+
+ if (name == NULL) {
+ gtk_icon_view_unselect_all (GTK_ICON_VIEW (widget->priv->iconview));
+ } else {
+ select_name (widget, name);
+ }
+}
+
+static void
+gdm_user_chooser_widget_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GdmUserChooserWidget *self;
+
+ self = GDM_USER_CHOOSER_WIDGET (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gdm_user_chooser_widget_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdmUserChooserWidget *self;
+
+ self = GDM_USER_CHOOSER_WIDGET (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GObject *
+gdm_user_chooser_widget_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GdmUserChooserWidget *user_chooser_widget;
+ GdmUserChooserWidgetClass *klass;
+
+ klass = GDM_USER_CHOOSER_WIDGET_CLASS (g_type_class_peek (GDM_TYPE_USER_CHOOSER_WIDGET));
+
+ user_chooser_widget = GDM_USER_CHOOSER_WIDGET (G_OBJECT_CLASS (gdm_user_chooser_widget_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+
+ return G_OBJECT (user_chooser_widget);
+}
+
+static void
+gdm_user_chooser_widget_dispose (GObject *object)
+{
+ GdmUserChooserWidget *widget;
+
+ widget = GDM_USER_CHOOSER_WIDGET (object);
+
+ if (widget->priv->available_users != NULL) {
+ g_hash_table_destroy (widget->priv->available_users);
+ widget->priv->available_users = NULL;
+ }
+
+ g_free (widget->priv->current_user);
+ widget->priv->current_user = NULL;
+
+ G_OBJECT_CLASS (gdm_user_chooser_widget_parent_class)->dispose (object);
+}
+
+static void
+gdm_user_chooser_widget_class_init (GdmUserChooserWidgetClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = gdm_user_chooser_widget_get_property;
+ object_class->set_property = gdm_user_chooser_widget_set_property;
+ object_class->constructor = gdm_user_chooser_widget_constructor;
+ object_class->dispose = gdm_user_chooser_widget_dispose;
+ object_class->finalize = gdm_user_chooser_widget_finalize;
+
+ signals [USER_ACTIVATED] = g_signal_new ("user-activated",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdmUserChooserWidgetClass, user_activated),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private (klass, sizeof (GdmUserChooserWidgetPrivate));
+}
+
+static void
+on_selection_changed (GtkIconView *icon_view,
+ GdmUserChooserWidget *widget)
+{
+ GList *items;
+ char *id;
+
+ id = NULL;
+
+ items = gtk_icon_view_get_selected_items (icon_view);
+ if (items != NULL) {
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ path = items->data;
+ model = gtk_icon_view_get_model (icon_view);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, CHOOSER_LIST_ID_COLUMN, &id, -1);
+ }
+
+ g_free (widget->priv->current_user);
+ widget->priv->current_user = g_strdup (id);
+
+ g_list_foreach (items, (GFunc)gtk_tree_path_free, NULL);
+ g_list_free (items);
+}
+
+static void
+collect_users (GdmUserChooserWidget *widget)
+{
+
+}
+
+static void
+on_item_activated (GtkIconView *icon_view,
+ GtkTreePath *tree_path,
+ GdmUserChooserWidget *widget)
+{
+ g_signal_emit (widget, signals[USER_ACTIVATED], 0);
+}
+
+static void
+add_user_to_model (const char *name,
+ GdmChooserUser *user,
+ GdmUserChooserWidget *widget)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ char *caption;
+
+ if (user->flags & USER_NO_DISPLAY
+ || user->flags & USER_ACCOUNT_DISABLED) {
+ /* skip */
+ g_debug ("Not adding user to list: %s", user->name);
+ }
+
+ caption = g_strdup_printf ("<span size=\"x-large\">%s</span>\n(%s)",
+ user->realname,
+ user->name);
+
+ model = gtk_icon_view_get_model (GTK_ICON_VIEW (widget->priv->iconview));
+
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model),
+ &iter,
+ CHOOSER_LIST_PIXBUF_COLUMN, user->pixbuf,
+ CHOOSER_LIST_CAPTION_COLUMN, caption,
+ CHOOSER_LIST_ID_COLUMN, name,
+ -1);
+ g_free (caption);
+}
+
+static GdkPixbuf *
+get_pixbuf_for_user (GdmUserChooserWidget *widget,
+ const char *username)
+{
+ GtkIconTheme *theme;
+ GdkPixbuf *pixbuf;
+ int size;
+
+ theme = gtk_icon_theme_get_default ();
+ gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &size, NULL);
+ pixbuf = gtk_icon_theme_load_icon (theme, "stock_person", size, 0, NULL);
+
+ return pixbuf;
+}
+
+static void
+populate_model (GdmUserChooserWidget *widget,
+ GtkTreeModel *model)
+{
+ GtkTreeIter iter;
+ GdkPixbuf *pixbuf;
+ char *caption;
+
+ /* Add some fake entries */
+
+ caption = g_strdup_printf ("<span size=\"x-large\">%s</span>\n<span size=\"small\">(%s)</span>\n<i>%s</i>",
+ _("Guest User"),
+ "guest",
+ _("Already logged in"));
+ pixbuf = get_pixbuf_for_user (widget, "guest");
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ CHOOSER_LIST_PIXBUF_COLUMN, pixbuf,
+ CHOOSER_LIST_CAPTION_COLUMN, caption,
+ CHOOSER_LIST_ID_COLUMN, "guest",
+ -1);
+ g_free (caption);
+
+ caption = g_strdup_printf ("<span size=\"x-large\">%s</span>\n<span size=\"small\">(%s)</span>",
+ _("Administrator"),
+ "administrator");
+
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ CHOOSER_LIST_PIXBUF_COLUMN, pixbuf,
+ CHOOSER_LIST_CAPTION_COLUMN, caption,
+ CHOOSER_LIST_ID_COLUMN, "administrator",
+ -1);
+ g_free (caption);
+
+ if (pixbuf != NULL) {
+ g_object_unref (pixbuf);
+ }
+
+ g_hash_table_foreach (widget->priv->available_users,
+ (GHFunc)add_user_to_model,
+ widget);
+}
+
+static gboolean
+separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int column = GPOINTER_TO_INT (data);
+ char *text;
+
+ gtk_tree_model_get (model, iter, column, &text, -1);
+
+ if (text != NULL && strcmp (text, "__separator") == 0) {
+ return TRUE;
+ }
+
+ g_free (text);
+
+ return FALSE;
+}
+
+static int
+compare_user_names (char *name_a,
+ char *name_b,
+ char *id_a,
+ char *id_b)
+{
+
+ if (id_a == NULL) {
+ return 1;
+ } else if (id_b == NULL) {
+ return -1;
+ }
+
+ if (strcmp (id_a, "__previous-user") == 0) {
+ return -1;
+ } else if (strcmp (id_b, "__previous-user") == 0) {
+ return 1;
+ } else if (strcmp (id_a, "__default-user") == 0) {
+ return -1;
+ } else if (strcmp (id_b, "__default-user") == 0) {
+ return 1;
+ } else if (strcmp (id_a, "__separator") == 0) {
+ return -1;
+ } else if (strcmp (id_b, "__separator") == 0) {
+ return 1;
+ }
+
+ if (name_a == NULL) {
+ return 1;
+ } else if (name_b == NULL) {
+ return -1;
+ }
+
+ return g_utf8_collate (name_a, name_b);
+}
+
+static int
+compare_user (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
+{
+ char *name_a;
+ char *name_b;
+ char *id_a;
+ char *id_b;
+ int result;
+
+ gtk_tree_model_get (model, a, CHOOSER_LIST_CAPTION_COLUMN, &name_a, -1);
+ gtk_tree_model_get (model, b, CHOOSER_LIST_CAPTION_COLUMN, &name_b, -1);
+ gtk_tree_model_get (model, a, CHOOSER_LIST_ID_COLUMN, &id_a, -1);
+ gtk_tree_model_get (model, b, CHOOSER_LIST_ID_COLUMN, &id_b, -1);
+
+ result = compare_user_names (name_a, name_b, id_a, id_b);
+
+ g_free (name_a);
+ g_free (name_b);
+ g_free (id_a);
+ g_free (id_b);
+
+ return result;
+}
+
+static void
+gdm_user_chooser_widget_init (GdmUserChooserWidget *widget)
+{
+ GtkWidget *scrolled;
+ GtkTreeModel *model;
+
+ widget->priv = GDM_USER_CHOOSER_WIDGET_GET_PRIVATE (widget);
+
+ widget->priv->available_users = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)chooser_user_free);
+
+ scrolled = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
+ GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start (GTK_BOX (widget), scrolled, TRUE, TRUE, 0);
+
+ widget->priv->iconview = gtk_icon_view_new ();
+ gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (widget->priv->iconview), GTK_SELECTION_SINGLE);
+ gtk_icon_view_set_orientation (GTK_ICON_VIEW (widget->priv->iconview), GTK_ORIENTATION_VERTICAL);
+ g_signal_connect (widget->priv->iconview,
+ "item-activated",
+ G_CALLBACK (on_item_activated),
+ widget);
+ g_signal_connect (widget->priv->iconview,
+ "selection-changed",
+ G_CALLBACK (on_selection_changed),
+ widget);
+ gtk_container_add (GTK_CONTAINER (scrolled), widget->priv->iconview);
+
+
+ model = (GtkTreeModel *)gtk_list_store_new (3,
+ GDK_TYPE_PIXBUF,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+ gtk_icon_view_set_model (GTK_ICON_VIEW (widget->priv->iconview), model);
+
+ gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (widget->priv->iconview), CHOOSER_LIST_PIXBUF_COLUMN);
+ gtk_icon_view_set_markup_column (GTK_ICON_VIEW (widget->priv->iconview), CHOOSER_LIST_CAPTION_COLUMN);
+
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model),
+ CHOOSER_LIST_CAPTION_COLUMN,
+ compare_user,
+ NULL, NULL);
+
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
+ CHOOSER_LIST_CAPTION_COLUMN,
+ GTK_SORT_ASCENDING);
+
+ collect_users (widget);
+
+ populate_model (widget, model);
+}
+
+static void
+gdm_user_chooser_widget_finalize (GObject *object)
+{
+ GdmUserChooserWidget *user_chooser_widget;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GDM_IS_USER_CHOOSER_WIDGET (object));
+
+ user_chooser_widget = GDM_USER_CHOOSER_WIDGET (object);
+
+ g_return_if_fail (user_chooser_widget->priv != NULL);
+
+ G_OBJECT_CLASS (gdm_user_chooser_widget_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gdm_user_chooser_widget_new (void)
+{
+ GObject *object;
+
+ object = g_object_new (GDM_TYPE_USER_CHOOSER_WIDGET,
+ NULL);
+
+ return GTK_WIDGET (object);
+}
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.h b/gui/simple-greeter/gdm-user-chooser-widget.h
new file mode 100644
index 00000000..5c17b9f4
--- /dev/null
+++ b/gui/simple-greeter/gdm-user-chooser-widget.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __GDM_USER_CHOOSER_WIDGET_H
+#define __GDM_USER_CHOOSER_WIDGET_H
+
+#include <glib-object.h>
+#include <gtk/gtkvbox.h>
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_USER_CHOOSER_WIDGET (gdm_user_chooser_widget_get_type ())
+#define GDM_USER_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_USER_CHOOSER_WIDGET, GdmUserChooserWidget))
+#define GDM_USER_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_USER_CHOOSER_WIDGET, GdmUserChooserWidgetClass))
+#define GDM_IS_USER_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_USER_CHOOSER_WIDGET))
+#define GDM_IS_USER_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_USER_CHOOSER_WIDGET))
+#define GDM_USER_CHOOSER_WIDGET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_USER_CHOOSER_WIDGET, GdmUserChooserWidgetClass))
+
+typedef struct GdmUserChooserWidgetPrivate GdmUserChooserWidgetPrivate;
+
+typedef struct
+{
+ GtkVBox parent;
+ GdmUserChooserWidgetPrivate *priv;
+} GdmUserChooserWidget;
+
+typedef struct
+{
+ GtkVBoxClass parent_class;
+
+ /* signals */
+ void (* user_activated) (GdmUserChooserWidget *widget);
+} GdmUserChooserWidgetClass;
+
+GType gdm_user_chooser_widget_get_type (void);
+GtkWidget * gdm_user_chooser_widget_new (void);
+
+char * gdm_user_chooser_widget_get_current_user_name (GdmUserChooserWidget *widget);
+void gdm_user_chooser_widget_set_current_user_name (GdmUserChooserWidget *widget,
+ const char *user_name);
+
+G_END_DECLS
+
+#endif /* __GDM_USER_CHOOSER_WIDGET_H */
diff --git a/gui/simple-greeter/greeter-main.c b/gui/simple-greeter/greeter-main.c
index 8ed414ce..3bebf434 100644
--- a/gui/simple-greeter/greeter-main.c
+++ b/gui/simple-greeter/greeter-main.c
@@ -337,7 +337,7 @@ activate_power_manager (void)
g_debug ("Activating power management");
error = NULL;
- res = g_spawn_command_line_async ("gnome-power-manager --no-daemon --verbose", &error);
+ res = g_spawn_command_line_async ("gnome-power-manager --no-daemon", &error);
if (! res) {
g_warning ("Unable to activate power management: %s", error->message);
g_error_free (error);
diff --git a/gui/simple-greeter/test-user-chooser.c b/gui/simple-greeter/test-user-chooser.c
new file mode 100644
index 00000000..d3c9fec2
--- /dev/null
+++ b/gui/simple-greeter/test-user-chooser.c
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <libintl.h>
+#include <locale.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "gdm-user-chooser-dialog.h"
+
+int
+main (int argc, char *argv[])
+{
+ GtkWidget *dialog;
+
+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ setlocale (LC_ALL, "");
+
+ gtk_init (&argc, &argv);
+
+ dialog = gdm_user_chooser_dialog_new ();
+ /*gtk_widget_set_size_request (dialog, 480, 128);*/
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+ char *name;
+
+ name = gdm_user_chooser_dialog_get_current_user_name (GDM_USER_CHOOSER_DIALOG (dialog));
+ g_message ("User: %s", name ? name : "(null)");
+ g_free (name);
+ }
+ gtk_widget_destroy (dialog);
+
+ return 0;
+}