[gdm/multi-stack: 9/31] Add limited support for multiple pam stacks



commit d61af2ef736c3744dfcd3bf602b45a181717a9c9
Author: Ray Strode <rstrode redhat com>
Date:   Fri Jan 30 23:57:31 2009 -0500

    Add limited support for multiple pam stacks
    
    This hard codes 3 pam stacks and doesn't handle
    switching between them very well yet.

 gui/simple-greeter/Makefile.am                    |    4 +
 gui/simple-greeter/gdm-greeter-login-window.c     |   91 +++++++++--
 gui/simple-greeter/gdm-greeter-login-window.glade |   39 ++++-
 gui/simple-greeter/gdm-greeter-login-window.h     |   11 +-
 gui/simple-greeter/gdm-greeter-session.c          |   30 +++-
 gui/simple-greeter/gdm-task-list.c                |  198 +++++++++++++++++++++
 gui/simple-greeter/gdm-task-list.h                |   64 +++++++
 7 files changed, 409 insertions(+), 28 deletions(-)
---
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
index 519e652..fc2d4b3 100644
--- a/gui/simple-greeter/Makefile.am
+++ b/gui/simple-greeter/Makefile.am
@@ -85,6 +85,8 @@ test_greeter_login_window_SOURCES = 	\
 	gdm-user-chooser-widget.c	\
 	gdm-user-chooser-dialog.h	\
 	gdm-user-chooser-dialog.c	\
+	gdm-task-list.h			\
+	gdm-task-list.c			\
 	$(NULL)
 
 test_greeter_login_window_LDADD =	\
@@ -316,6 +318,8 @@ gdm_simple_greeter_SOURCES =  		\
 	gdm-session-option-widget.c	\
 	gdm-user-chooser-widget.h	\
 	gdm-user-chooser-widget.c	\
+	gdm-task-list.h			\
+	gdm-task-list.c			\
 	$(NULL)
 
 gdm_simple_greeter_LDADD = 		\
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
index 9a29a2e..82411d1 100644
--- a/gui/simple-greeter/gdm-greeter-login-window.c
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
@@ -51,12 +51,16 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
+#include "gdm-marshal.h"
+
 #include "gdm-settings-client.h"
 #include "gdm-settings-keys.h"
 #include "gdm-profile.h"
 
+#include "gdm-greeter-client.h"
 #include "gdm-greeter-login-window.h"
 #include "gdm-user-chooser-widget.h"
+#include "gdm-task-list.h"
 
 #ifdef HAVE_PAM
 #include <security/pam_appl.h>
@@ -99,6 +103,7 @@ struct GdmGreeterLoginWindowPrivate
 {
         GladeXML        *xml;
         GtkWidget       *user_chooser;
+        GtkWidget       *conversation_list;
         GtkWidget       *auth_banner_label;
         guint            display_is_local : 1;
         guint            is_interactive : 1;
@@ -126,6 +131,7 @@ enum {
 };
 
 enum {
+        START_CONVERSATION,
         BEGIN_AUTO_LOGIN,
         BEGIN_VERIFICATION,
         BEGIN_VERIFICATION_FOR_USER,
@@ -355,7 +361,7 @@ on_login_button_clicked_answer_query (GtkButton             *button,
         text = gtk_entry_get_text (GTK_ENTRY (entry));
 
         _gdm_greeter_login_window_set_interactive (login_window, TRUE);
-        g_signal_emit (login_window, signals[QUERY_ANSWER], 0, text);
+        g_signal_emit (login_window, signals[QUERY_ANSWER], 0, "gdm", text);
 }
 
 static void
@@ -602,26 +608,32 @@ gdm_greeter_login_window_reset (GdmGreeterLoginWindow *login_window)
 
 gboolean
 gdm_greeter_login_window_info (GdmGreeterLoginWindow *login_window,
+                               const char            *service_name,
                                const char            *text)
 {
         g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
 
         g_debug ("GdmGreeterLoginWindow: info: %s", text);
 
-        set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
+        if (strcmp (service_name, gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list))) == 0) {
+                set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
+        }
 
         return TRUE;
 }
 
 gboolean
 gdm_greeter_login_window_problem (GdmGreeterLoginWindow *login_window,
+                                  const char            *service_name,
                                   const char            *text)
 {
         g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
 
         g_debug ("GdmGreeterLoginWindow: problem: %s", text);
 
-        set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
+        if (strcmp (service_name, gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list))) == 0) {
+                set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
+        }
         gdk_window_beep (GTK_WIDGET (login_window)->window);
 
         return TRUE;
@@ -697,6 +709,7 @@ gdm_greeter_login_window_start_session_when_ready (GdmGreeterLoginWindow *login_
 
 gboolean
 gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
+                                     const char            *service_name,
                                      const char            *text)
 {
         GtkWidget  *entry;
@@ -704,6 +717,10 @@ gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
 
         g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
 
+        if (strcmp (service_name, gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list))) != 0) {
+                return TRUE;
+        }
+
         g_debug ("GdmGreeterLoginWindow: info query: %s", text);
 
         entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry");
@@ -726,6 +743,7 @@ gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
 
 gboolean
 gdm_greeter_login_window_secret_info_query (GdmGreeterLoginWindow *login_window,
+                                            const char            *service_name,
                                             const char            *text)
 {
         GtkWidget  *entry;
@@ -858,7 +876,10 @@ on_user_chosen (GdmUserChooserWidget  *user_chooser,
                        0, user_name);
 
         if (strcmp (user_name, GDM_USER_CHOOSER_USER_OTHER) == 0) {
-                g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0);
+                const char *service_name;
+
+                service_name = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
+                g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0, service_name);
         } else if (strcmp (user_name, GDM_USER_CHOOSER_USER_GUEST) == 0) {
                 /* FIXME: handle guest account stuff */
         } else if (strcmp (user_name, GDM_USER_CHOOSER_USER_AUTO) == 0) {
@@ -872,7 +893,10 @@ on_user_chosen (GdmUserChooserWidget  *user_chooser,
                 set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
                 set_message (login_window, _("Select language and click Log In"));
         } else {
-                g_signal_emit (login_window, signals[BEGIN_VERIFICATION_FOR_USER], 0, user_name);
+                const char *service_name;
+
+                service_name = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
+                g_signal_emit (login_window, signals[BEGIN_VERIFICATION_FOR_USER], 0, service_name, user_name);
         }
 
         switch_mode (login_window, MODE_AUTHENTICATION);
@@ -1016,6 +1040,21 @@ create_computer_info (GdmGreeterLoginWindow *login_window)
 #define INVISIBLE_CHAR_BULLET        0x2022
 #define INVISIBLE_CHAR_NONE          0
 
+static void
+on_task_activated (GdmGreeterLoginWindow *login_window,
+                   const char            *name)
+{
+        g_debug ("GdmGreeterLoginWindow: starting conversation with '%s'", name);
+        g_signal_emit (login_window, signals[START_CONVERSATION], 0, name);
+}
+
+static void
+on_task_deactivated (GdmGreeterLoginWindow *login_window,
+                     const char            *name)
+{
+        g_debug ("GdmGreeterLoginWindow: conversation '%s' now in background", name);
+}
+
 static GtkWidget *
 custom_widget_constructor (GladeXML              *xml,
                            char                  *func_name,
@@ -1038,6 +1077,8 @@ custom_widget_constructor (GladeXML              *xml,
 
         if (strcmp (name, "user-chooser") == 0) {
                widget = gdm_user_chooser_widget_new ();
+        } else if (strcmp (name, "conversation-list") == 0) {
+               widget = gdm_task_list_new ();
         }
 
         gdm_profile_end (NULL);
@@ -1116,6 +1157,25 @@ load_theme (GdmGreeterLoginWindow *login_window)
 
         gtk_widget_show (login_window->priv->user_chooser);
 
+        login_window->priv->conversation_list = glade_xml_get_widget (login_window->priv->xml,
+                                                                      "conversation-list");
+        g_signal_connect_swapped (GDM_TASK_LIST (login_window->priv->conversation_list),
+                                  "activated",
+                                  G_CALLBACK (on_task_activated),
+                                  login_window);
+        g_signal_connect_swapped (GDM_TASK_LIST (login_window->priv->conversation_list),
+                                  "deactivated",
+                                  G_CALLBACK (on_task_deactivated),
+                                  login_window);
+        gtk_widget_show (login_window->priv->conversation_list);
+
+        gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
+                                "password-auth", "dialog-password");
+        gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
+                                "fingerprint-auth", "stock_allow-effects");
+        gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
+                                "smartcard-auth", "badge-small");
+
         login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label");
         /*make_label_small_italic (login_window->priv->auth_banner_label);*/
 
@@ -1286,6 +1346,15 @@ gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass)
         widget_class->key_press_event = gdm_greeter_login_window_key_press_event;
         widget_class->size_request = gdm_greeter_login_window_size_request;
 
+        signals [START_CONVERSATION] =
+                g_signal_new ("start-conversation",
+                              G_TYPE_FROM_CLASS (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, start_conversation),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__STRING,
+                              G_TYPE_NONE, 1, G_TYPE_STRING);
         signals [BEGIN_AUTO_LOGIN] =
                 g_signal_new ("begin-auto-login",
                               G_TYPE_FROM_CLASS (object_class),
@@ -1302,9 +1371,9 @@ gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, begin_verification),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
+                              g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1, G_TYPE_STRING);
         signals [BEGIN_VERIFICATION_FOR_USER] =
                 g_signal_new ("begin-verification-for-user",
                               G_TYPE_FROM_CLASS (object_class),
@@ -1312,9 +1381,9 @@ gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, begin_verification_for_user),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1, G_TYPE_STRING);
+                              2, G_TYPE_STRING, G_TYPE_STRING);
         signals [QUERY_ANSWER] =
                 g_signal_new ("query-answer",
                               G_TYPE_FROM_CLASS (object_class),
@@ -1322,9 +1391,9 @@ gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, query_answer),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1, G_TYPE_STRING);
+                              2, G_TYPE_STRING, G_TYPE_STRING);
         signals [USER_SELECTED] =
                 g_signal_new ("user-selected",
                               G_TYPE_FROM_CLASS (object_class),
diff --git a/gui/simple-greeter/gdm-greeter-login-window.glade b/gui/simple-greeter/gdm-greeter-login-window.glade
index 7c6e94b..e06c091 100644
--- a/gui/simple-greeter/gdm-greeter-login-window.glade
+++ b/gui/simple-greeter/gdm-greeter-login-window.glade
@@ -460,11 +460,38 @@
 		      <property name="spacing">10</property>
 
 		      <child>
-			<widget class="Custom" id="user-chooser">
+			<widget class="GtkVBox" id="vbox6">
 			  <property name="visible">True</property>
-			  <property name="int1">0</property>
-			  <property name="int2">0</property>
-			  <property name="last_modification_time">Tue, 18 Nov 2008 21:55:38 GMT</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">0</property>
+
+			  <child>
+			    <widget class="Custom" id="user-chooser">
+			      <property name="visible">True</property>
+			      <property name="int1">0</property>
+			      <property name="int2">0</property>
+			      <property name="last_modification_time">Tue, 18 Nov 2008 21:55:38 GMT</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="Custom" id="conversation-list">
+			      <property name="visible">True</property>
+			      <property name="int1">0</property>
+			      <property name="int2">0</property>
+			      <property name="last_modification_time">Fri, 30 Jan 2009 16:03:30 GMT</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
 			</widget>
 			<packing>
 			  <property name="padding">0</property>
@@ -584,10 +611,6 @@
 	  </child>
 	</widget>
       </child>
-
-      <child>
-	<placeholder/>
-      </child>
     </widget>
   </child>
 </widget>
diff --git a/gui/simple-greeter/gdm-greeter-login-window.h b/gui/simple-greeter/gdm-greeter-login-window.h
index 817d0a2..559b26b 100644
--- a/gui/simple-greeter/gdm-greeter-login-window.h
+++ b/gui/simple-greeter/gdm-greeter-login-window.h
@@ -46,12 +46,17 @@ typedef struct
         GtkWindowClass   parent_class;
 
         /* signals */
+        void (* start_conversation)          (GdmGreeterLoginWindow *login_window,
+                                              const char            *service_name);
         void (* begin_auto_login)            (GdmGreeterLoginWindow *login_window,
                                               const char            *username);
-        void (* begin_verification)          (GdmGreeterLoginWindow *login_window);
+        void (* begin_verification)          (GdmGreeterLoginWindow *login_window,
+                                              const char            *service_name);
         void (* begin_verification_for_user) (GdmGreeterLoginWindow *login_window,
+                                              const char            *service_name,
                                               const char            *username);
         void (* query_answer)                (GdmGreeterLoginWindow *login_window,
+                                              const char            *service_name,
                                               const char            *text);
         void (* user_selected)               (GdmGreeterLoginWindow *login_window,
                                               const char            *text);
@@ -68,12 +73,16 @@ GtkWidget *         gdm_greeter_login_window_new                (gboolean displa
 gboolean            gdm_greeter_login_window_reset              (GdmGreeterLoginWindow *login_window);
 gboolean            gdm_greeter_login_window_ready              (GdmGreeterLoginWindow *login_window);
 gboolean            gdm_greeter_login_window_info_query         (GdmGreeterLoginWindow *login_window,
+                                                                 const char *service_name,
                                                                  const char *text);
 gboolean            gdm_greeter_login_window_secret_info_query  (GdmGreeterLoginWindow *login_window,
+                                                                 const char *service_name,
                                                                  const char *text);
 gboolean            gdm_greeter_login_window_info               (GdmGreeterLoginWindow *login_window,
+                                                                 const char *service_name,
                                                                  const char *text);
 gboolean            gdm_greeter_login_window_problem            (GdmGreeterLoginWindow *login_window,
+                                                                 const char *service_name,
                                                                  const char *text);
 
 void               gdm_greeter_login_window_request_timed_login (GdmGreeterLoginWindow *login_window,
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
index e856dd4..945e210 100644
--- a/gui/simple-greeter/gdm-greeter-session.c
+++ b/gui/simple-greeter/gdm-greeter-session.c
@@ -71,7 +71,7 @@ on_info (GdmGreeterClient  *client,
 {
         g_debug ("GdmGreeterSession: Info: %s", text);
 
-        gdm_greeter_login_window_info (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), text);
+        gdm_greeter_login_window_info (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), service_name, text);
 }
 
 static void
@@ -82,7 +82,7 @@ on_problem (GdmGreeterClient  *client,
 {
         g_debug ("GdmGreeterSession: Problem: %s", text);
 
-        gdm_greeter_login_window_problem (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), text);
+        gdm_greeter_login_window_problem (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), service_name, text);
 }
 
 static void
@@ -181,7 +181,7 @@ on_info_query (GdmGreeterClient  *client,
 {
         g_debug ("GdmGreeterSession: Info query: %s", text);
 
-        gdm_greeter_login_window_info_query (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), text);
+        gdm_greeter_login_window_info_query (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), service_name, text);
 }
 
 static void
@@ -192,10 +192,18 @@ on_secret_info_query (GdmGreeterClient  *client,
 {
         g_debug ("GdmGreeterSession: Secret info query: %s", text);
 
-        gdm_greeter_login_window_secret_info_query (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), text);
+        gdm_greeter_login_window_secret_info_query (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), service_name, text);
 }
 
 static void
+on_start_conversation (GdmGreeterLoginWindow *login_window,
+                       const char            *service_name,
+                       GdmGreeterSession     *session)
+{
+        gdm_greeter_client_call_start_conversation (session->priv->client,
+                                                    service_name);
+}
+static void
 on_begin_auto_login (GdmGreeterLoginWindow *login_window,
                      const char            *username,
                      GdmGreeterSession     *session)
@@ -206,29 +214,32 @@ on_begin_auto_login (GdmGreeterLoginWindow *login_window,
 
 static void
 on_begin_verification (GdmGreeterLoginWindow *login_window,
+                       const char            *service_name,
                        GdmGreeterSession     *session)
 {
         gdm_greeter_client_call_begin_verification (session->priv->client,
-                                                    "gdm");
+                                                    service_name);
 }
 
 static void
 on_begin_verification_for_user (GdmGreeterLoginWindow *login_window,
+                                const char            *service_name,
                                 const char            *username,
                                 GdmGreeterSession     *session)
 {
         gdm_greeter_client_call_begin_verification_for_user (session->priv->client,
-                                                             "gdm",
+                                                             service_name,
                                                              username);
 }
 
 static void
 on_query_answer (GdmGreeterLoginWindow *login_window,
+                 const char            *service_name,
                  const char            *text,
                  GdmGreeterSession     *session)
 {
         gdm_greeter_client_call_answer_query (session->priv->client,
-                                              "gdm",
+                                              service_name,
                                               text);
 }
 
@@ -392,7 +403,10 @@ toggle_login_window (GdmGreeterSession *session,
                 is_local = gdm_greeter_client_get_display_is_local (session->priv->client);
                 g_debug ("GdmGreeterSession: Starting a login window local:%d", is_local);
                 session->priv->login_window = gdm_greeter_login_window_new (is_local);
-
+                g_signal_connect (session->priv->login_window,
+                                  "start-conversation",
+                                  G_CALLBACK (on_start_conversation),
+                                  session);
                 g_signal_connect (session->priv->login_window,
                                   "begin-auto-login",
                                   G_CALLBACK (on_begin_auto_login),
diff --git a/gui/simple-greeter/gdm-task-list.c b/gui/simple-greeter/gdm-task-list.c
new file mode 100644
index 0000000..e0fd3d4
--- /dev/null
+++ b/gui/simple-greeter/gdm-task-list.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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.
+ *
+ *  Written by: Ray Strode <rstrode redhat com>
+ */
+
+#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-task-list.h"
+
+#define GDM_TASK_LIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_TASK_LIST, GdmTaskListPrivate))
+
+typedef struct
+{
+        GtkWidget *radio_button;
+        char      *name;
+} GdmTask;
+
+struct GdmTaskListPrivate
+{
+        GtkWidget *box;
+        GList     *tasks;
+};
+
+enum {
+        ACTIVATED = 0,
+        DEACTIVATED,
+        NUMBER_OF_SIGNALS
+};
+
+static guint    signals[NUMBER_OF_SIGNALS];
+
+static void     gdm_task_list_class_init  (GdmTaskListClass *klass);
+static void     gdm_task_list_init        (GdmTaskList      *task_list);
+static void     gdm_task_list_finalize    (GObject              *object);
+
+G_DEFINE_TYPE (GdmTaskList, gdm_task_list, GTK_TYPE_ALIGNMENT);
+
+static void
+on_task_toggled (GdmTaskList    *widget,
+                 GtkRadioButton *radio_button)
+{
+        GdmTask *task;
+
+        task = g_object_get_data (G_OBJECT (radio_button), "gdm-task");
+
+        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_button))) {
+                g_signal_emit (widget, signals[ACTIVATED], 0, task->name);
+        } else {
+                g_signal_emit (widget, signals[DEACTIVATED], 0, task->name);
+        }
+}
+
+void
+gdm_task_list_add_task (GdmTaskList *task_list,
+                        const char  *name,
+                        const char  *icon_name)
+{
+        GdmTask   *task;
+        GtkWidget *image;
+
+        task = g_new0 (GdmTask, 1);
+
+        task->name = g_strdup (name);
+        if (task_list->priv->tasks == NULL) {
+                task->radio_button = gtk_radio_button_new (NULL);
+        } else {
+                task->radio_button = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (((GdmTask *) task_list->priv->tasks->data)->radio_button));
+        }
+
+        g_object_set (task->radio_button, "draw-indicator", FALSE, NULL);
+        g_object_set_data (G_OBJECT (task->radio_button), "gdm-task", task);
+        g_signal_connect_swapped (task->radio_button,
+                                  "toggled", G_CALLBACK (on_task_toggled), task_list);
+        image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DND);
+        gtk_widget_show (image);
+        gtk_container_add (GTK_CONTAINER (task->radio_button), image);
+        gtk_widget_show (task->radio_button);
+        gtk_container_add (GTK_CONTAINER (task->radio_button), task_list->priv->box);
+
+        gtk_container_add (GTK_CONTAINER (task_list->priv->box), task->radio_button);
+        task_list->priv->tasks = g_list_append (task_list->priv->tasks, task);
+}
+
+static void
+gdm_task_list_class_init (GdmTaskListClass *klass)
+{
+        GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->finalize = gdm_task_list_finalize;
+
+        signals [ACTIVATED] = g_signal_new ("activated",
+                                            G_TYPE_FROM_CLASS (object_class),
+                                            G_SIGNAL_RUN_FIRST,
+                                            G_STRUCT_OFFSET (GdmTaskListClass, activated),
+                                            NULL,
+                                            NULL,
+                                            g_cclosure_marshal_VOID__STRING,
+                                            G_TYPE_NONE,
+                                            1, G_TYPE_STRING);
+
+        signals [DEACTIVATED] = g_signal_new ("deactivated",
+                                            G_TYPE_FROM_CLASS (object_class),
+                                            G_SIGNAL_RUN_FIRST,
+                                            G_STRUCT_OFFSET (GdmTaskListClass, deactivated),
+                                            NULL,
+                                            NULL,
+                                            g_cclosure_marshal_VOID__STRING,
+                                            G_TYPE_NONE,
+                                            1, G_TYPE_STRING);
+
+        g_type_class_add_private (klass, sizeof (GdmTaskListPrivate));
+}
+
+static void
+gdm_task_list_init (GdmTaskList *widget)
+{
+        widget->priv = GDM_TASK_LIST_GET_PRIVATE (widget);
+
+        gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 0, 0);
+        gtk_alignment_set (GTK_ALIGNMENT (widget), 0.0, 0.0, 0, 0);
+
+        widget->priv->box = gtk_hbox_new (FALSE, 2);
+        gtk_widget_show (widget->priv->box);
+        gtk_container_add (GTK_CONTAINER (widget),
+                           widget->priv->box);
+}
+
+static void
+gdm_task_list_finalize (GObject *object)
+{
+        GdmTaskList *widget;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GDM_IS_TASK_LIST (object));
+
+        widget = GDM_TASK_LIST (object);
+
+        g_list_foreach (widget->priv->tasks, (GFunc) g_free, NULL);
+        g_list_free (widget->priv->tasks);
+
+        G_OBJECT_CLASS (gdm_task_list_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gdm_task_list_new (void)
+{
+        GObject *object;
+
+        object = g_object_new (GDM_TYPE_TASK_LIST, NULL);
+
+        return GTK_WIDGET (object);
+}
+
+const char *
+gdm_task_list_get_active_task (GdmTaskList *widget)
+{
+        GList *node;
+
+        for (node = widget->priv->tasks; node != NULL; node = node->next) {
+                GdmTask *task;
+
+                task = node->data;
+
+                if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (task->radio_button)) ) {
+                        return task->name;
+                }
+        }
+
+        return NULL;
+}
diff --git a/gui/simple-greeter/gdm-task-list.h b/gui/simple-greeter/gdm-task-list.h
new file mode 100644
index 0000000..ade21b6
--- /dev/null
+++ b/gui/simple-greeter/gdm-task-list.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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.
+ *
+ *  Written by: Ray Strode <rstrode redhat com>
+ */
+
+#ifndef __GDM_TASK_LIST_H
+#define __GDM_TASK_LIST_H
+
+#include <glib-object.h>
+#include <gtk/gtkalignment.h>
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_TASK_LIST         (gdm_task_list_get_type ())
+#define GDM_TASK_LIST(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_TASK_LIST, GdmTaskList))
+#define GDM_TASK_LIST_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_TASK_LIST, GdmTaskListClass))
+#define GDM_IS_TASK_LIST(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_TASK_LIST))
+#define GDM_IS_TASK_LIST_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_TASK_LIST))
+#define GDM_TASK_LIST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_TASK_LIST, GdmTaskListClass))
+
+typedef struct GdmTaskListPrivate GdmTaskListPrivate;
+
+typedef struct
+{
+        GtkAlignment             parent;
+        GdmTaskListPrivate *priv;
+} GdmTaskList;
+
+typedef struct
+{
+        GtkAlignmentClass       parent_class;
+
+        void (* deactivated)      (GdmTaskList *widget,
+                                   const char  *name);
+        void (* activated)      (GdmTaskList *widget,
+                                 const char  *name);
+} GdmTaskListClass;
+
+
+GType                  gdm_task_list_get_type               (void);
+GtkWidget *            gdm_task_list_new                    (void);
+
+const char *           gdm_task_list_get_active_task (GdmTaskList *widget);
+void                   gdm_task_list_add_task (GdmTaskList *widget,
+                                               const char  *name,
+                                               const char  *icon_name);
+G_END_DECLS
+
+#endif /* __GDM_TASK_LIST_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]