SHA256
1
0
forked from pool/gdm
gdm/gdm-domain-logon.patch

2274 lines
83 KiB
Diff
Raw Normal View History

Index: gdm-2.29.5/gui/simple-greeter/Makefile.am
===================================================================
--- gdm-2.29.5.orig/gui/simple-greeter/Makefile.am
+++ gdm-2.29.5/gui/simple-greeter/Makefile.am
@@ -134,6 +134,14 @@ test_greeter_panel_SOURCES = \
gdm-sessions.c \
gdm-session-option-widget.h \
gdm-session-option-widget.c \
+ gdm-domain-chooser-dialog.h \
+ gdm-domain-chooser-dialog.c \
+ gdm-domain-chooser-widget.h \
+ gdm-domain-chooser-widget.c \
+ gdm-domain-option-widget.h \
+ gdm-domain-option-widget.c \
+ gdm-domain-provider.h \
+ gdm-domain-provider.c \
$(NULL)
test_greeter_panel_LDADD = \
@@ -312,12 +320,20 @@ gdm_simple_greeter_SOURCES = \
gdm-language-chooser-dialog.c \
gdm-language-option-widget.h \
gdm-language-option-widget.c \
+ gdm-domain-chooser-dialog.h \
+ gdm-domain-chooser-dialog.c \
+ gdm-domain-chooser-widget.h \
+ gdm-domain-chooser-widget.c \
+ gdm-domain-option-widget.h \
+ gdm-domain-option-widget.c \
gdm-sessions.h \
gdm-sessions.c \
gdm-session-option-widget.h \
gdm-session-option-widget.c \
gdm-user-chooser-widget.h \
gdm-user-chooser-widget.c \
+ gdm-domain-provider.h \
+ gdm-domain-provider.c \
$(NULL)
gdm_simple_greeter_LDADD = \
Index: gdm-2.29.5/gui/simple-greeter/gdm-chooser-widget.c
===================================================================
--- gdm-2.29.5.orig/gui/simple-greeter/gdm-chooser-widget.c
+++ gdm-2.29.5/gui/simple-greeter/gdm-chooser-widget.c
@@ -2121,6 +2121,21 @@ gdm_chooser_widget_remove_item (GdmChoos
update_chooser_visibility (widget);
}
+void
+gdm_chooser_widget_remove_all_items (GdmChooserWidget *widget)
+{
+ widget->priv->number_of_rows_with_images = 0;
+ widget->priv->number_of_rows_with_status = 0;
+ widget->priv->number_of_separated_rows = 0;
+ widget->priv->number_of_normal_rows = 0;
+
+ gtk_list_store_clear (widget->priv->list_store);
+
+ update_separator_visibility (widget);
+ move_cursor_to_top (widget);
+ update_chooser_visibility (widget);
+}
+
gboolean
gdm_chooser_widget_lookup_item (GdmChooserWidget *widget,
const char *id,
Index: gdm-2.29.5/gui/simple-greeter/gdm-chooser-widget.h
===================================================================
--- gdm-2.29.5.orig/gui/simple-greeter/gdm-chooser-widget.h
+++ gdm-2.29.5/gui/simple-greeter/gdm-chooser-widget.h
@@ -96,6 +96,8 @@ void gdm_chooser_widget_update_i
void gdm_chooser_widget_remove_item (GdmChooserWidget *widget,
const char *id);
+void gdm_chooser_widget_remove_all_items (GdmChooserWidget *widget);
+
gboolean gdm_chooser_widget_lookup_item (GdmChooserWidget *widget,
const char *id,
GdkPixbuf **image,
Index: gdm-2.29.5/gui/simple-greeter/gdm-domain-chooser-dialog.c
===================================================================
--- /dev/null
+++ gdm-2.29.5/gui/simple-greeter/gdm-domain-chooser-dialog.c
@@ -0,0 +1,207 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Hans Petter Jansson
+ *
+ * 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: Hans Petter Jansson <hpj@novell.com>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gdm-domain-chooser-widget.h"
+#include "gdm-domain-chooser-dialog.h"
+
+#define GDM_DOMAIN_CHOOSER_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DOMAIN_CHOOSER_DIALOG, GdmDomainChooserDialogPrivate))
+
+struct GdmDomainChooserDialogPrivate
+{
+ GtkWidget *chooser_widget;
+};
+
+
+static void gdm_domain_chooser_dialog_class_init (GdmDomainChooserDialogClass *klass);
+static void gdm_domain_chooser_dialog_init (GdmDomainChooserDialog *domain_chooser_dialog);
+static void gdm_domain_chooser_dialog_finalize (GObject *object);
+
+G_DEFINE_TYPE (GdmDomainChooserDialog, gdm_domain_chooser_dialog, GTK_TYPE_DIALOG)
+
+char *
+gdm_domain_chooser_dialog_get_current_domain_name (GdmDomainChooserDialog *dialog)
+{
+ char *domain_name;
+
+ g_return_val_if_fail (GDM_IS_DOMAIN_CHOOSER_DIALOG (dialog), NULL);
+
+ domain_name = gdm_domain_chooser_widget_get_current_domain_name (GDM_DOMAIN_CHOOSER_WIDGET (dialog->priv->chooser_widget));
+
+ return domain_name;
+}
+
+void
+gdm_domain_chooser_dialog_set_current_domain_name (GdmDomainChooserDialog *dialog,
+ const char *domain_name)
+{
+ g_return_if_fail (GDM_IS_DOMAIN_CHOOSER_DIALOG (dialog));
+
+ gdm_domain_chooser_widget_set_current_domain_name (GDM_DOMAIN_CHOOSER_WIDGET (dialog->priv->chooser_widget), domain_name);
+}
+
+static void
+gdm_domain_chooser_dialog_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ int screen_w;
+ int screen_h;
+ GtkRequisition child_requisition;
+
+ if (GTK_WIDGET_CLASS (gdm_domain_chooser_dialog_parent_class)->size_request) {
+ GTK_WIDGET_CLASS (gdm_domain_chooser_dialog_parent_class)->size_request (widget, requisition);
+ }
+
+ screen_w = gdk_screen_get_width (gtk_widget_get_screen (widget));
+ screen_h = gdk_screen_get_height (gtk_widget_get_screen (widget));
+
+ gtk_widget_get_child_requisition (GTK_BIN (widget)->child, &child_requisition);
+ *requisition = child_requisition;
+
+ requisition->width += 2 * GTK_CONTAINER (widget)->border_width;
+ requisition->height += 2 * GTK_CONTAINER (widget)->border_width;
+
+ requisition->width = MIN (requisition->width, .50 * screen_w);
+ requisition->height = MIN (requisition->height, .80 * screen_h);
+}
+
+static void
+gdm_domain_chooser_dialog_realize (GtkWidget *widget)
+{
+ GdmDomainChooserDialog *chooser_dialog;
+ GdkWindow *root_window;
+ GdkCursor *cursor;
+
+ root_window = gdk_screen_get_root_window (gdk_screen_get_default ());
+ cursor = gdk_cursor_new (GDK_WATCH);
+ gdk_window_set_cursor (root_window, cursor);
+ gdk_cursor_unref (cursor);
+
+ chooser_dialog = GDM_DOMAIN_CHOOSER_DIALOG (widget);
+
+ gtk_widget_show (chooser_dialog->priv->chooser_widget);
+
+ GTK_WIDGET_CLASS (gdm_domain_chooser_dialog_parent_class)->realize (widget);
+
+ cursor = gdk_cursor_new (GDK_LEFT_PTR);
+ gdk_window_set_cursor (root_window, cursor);
+ gdk_cursor_unref (cursor);
+}
+
+static void
+gdm_domain_chooser_dialog_class_init (GdmDomainChooserDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = gdm_domain_chooser_dialog_finalize;
+ widget_class->size_request = gdm_domain_chooser_dialog_size_request;
+ widget_class->realize = gdm_domain_chooser_dialog_realize;
+
+ g_type_class_add_private (klass, sizeof (GdmDomainChooserDialogPrivate));
+}
+
+static gboolean
+respond (GdmDomainChooserDialog *dialog)
+{
+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ return FALSE;
+}
+
+static void
+queue_response (GdmDomainChooserDialog *dialog)
+{
+ g_idle_add ((GSourceFunc) respond, dialog);
+}
+
+static void
+gdm_domain_chooser_dialog_init (GdmDomainChooserDialog *dialog)
+{
+
+ dialog->priv = GDM_DOMAIN_CHOOSER_DIALOG_GET_PRIVATE (dialog);
+
+ dialog->priv->chooser_widget = gdm_domain_chooser_widget_new ();
+ gdm_chooser_widget_set_hide_inactive_items (GDM_CHOOSER_WIDGET (dialog->priv->chooser_widget),
+ FALSE);
+
+ gdm_domain_chooser_widget_set_current_domain_name (GDM_DOMAIN_CHOOSER_WIDGET (dialog->priv->chooser_widget),
+ "__local");
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), dialog->priv->chooser_widget);
+
+ g_signal_connect_swapped (G_OBJECT (dialog->priv->chooser_widget),
+ "activated", G_CALLBACK (queue_response),
+ dialog);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog->priv->chooser_widget), 5);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 512, 440);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+}
+
+static void
+gdm_domain_chooser_dialog_finalize (GObject *object)
+{
+ GdmDomainChooserDialog *domain_chooser_dialog;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GDM_IS_DOMAIN_CHOOSER_DIALOG (object));
+
+ domain_chooser_dialog = GDM_DOMAIN_CHOOSER_DIALOG (object);
+
+ g_return_if_fail (domain_chooser_dialog->priv != NULL);
+
+ G_OBJECT_CLASS (gdm_domain_chooser_dialog_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gdm_domain_chooser_dialog_new (void)
+{
+ GObject *object;
+
+ object = g_object_new (GDM_TYPE_DOMAIN_CHOOSER_DIALOG,
+ "icon-name", "preferences-system-network",
+ "title", _("Domains"),
+ "border-width", 8,
+ "modal", TRUE,
+ NULL);
+
+ return GTK_WIDGET (object);
+}
Index: gdm-2.29.5/gui/simple-greeter/gdm-domain-chooser-dialog.h
===================================================================
--- /dev/null
+++ gdm-2.29.5/gui/simple-greeter/gdm-domain-chooser-dialog.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Hans Petter Jansson
+ *
+ * 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: Hans Petter Jansson <hpj@novell.com>
+ */
+
+#ifndef __GDM_DOMAIN_CHOOSER_DIALOG_H
+#define __GDM_DOMAIN_CHOOSER_DIALOG_H
+
+#include <glib-object.h>
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_DOMAIN_CHOOSER_DIALOG (gdm_domain_chooser_dialog_get_type ())
+#define GDM_DOMAIN_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_DOMAIN_CHOOSER_DIALOG, GdmDomainChooserDialog))
+#define GDM_DOMAIN_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_DOMAIN_CHOOSER_DIALOG, GdmDomainChooserDialogClass))
+#define GDM_IS_DOMAIN_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_DOMAIN_CHOOSER_DIALOG))
+#define GDM_IS_DOMAIN_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_DOMAIN_CHOOSER_DIALOG))
+#define GDM_DOMAIN_CHOOSER_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_DOMAIN_CHOOSER_DIALOG, GdmDomainChooserDialogClass))
+
+typedef struct GdmDomainChooserDialogPrivate GdmDomainChooserDialogPrivate;
+
+typedef struct
+{
+ GtkDialog parent;
+ GdmDomainChooserDialogPrivate *priv;
+} GdmDomainChooserDialog;
+
+typedef struct
+{
+ GtkDialogClass parent_class;
+} GdmDomainChooserDialogClass;
+
+GType gdm_domain_chooser_dialog_get_type (void);
+
+GtkWidget * gdm_domain_chooser_dialog_new (void);
+
+char * gdm_domain_chooser_dialog_get_current_domain_name (GdmDomainChooserDialog *dialog);
+void gdm_domain_chooser_dialog_set_current_domain_name (GdmDomainChooserDialog *dialog,
+ const char *domain_name);
+
+G_END_DECLS
+
+#endif /* __GDM_DOMAIN_CHOOSER_DIALOG_H */
Index: gdm-2.29.5/gui/simple-greeter/gdm-domain-chooser-widget.c
===================================================================
--- /dev/null
+++ gdm-2.29.5/gui/simple-greeter/gdm-domain-chooser-widget.c
@@ -0,0 +1,237 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Hans Petter Jansson
+ *
+ * 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: Hans Petter Jansson <hpj@novell.com>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <locale.h>
+#include <sys/stat.h>
+
+#include <fontconfig/fontconfig.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+
+#include "gdm-domain-chooser-widget.h"
+#include "gdm-chooser-widget.h"
+#include "gdm-domain-provider.h"
+
+#define GDM_DOMAIN_CHOOSER_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DOMAIN_CHOOSER_WIDGET, GdmDomainChooserWidgetPrivate))
+
+struct GdmDomainChooserWidgetPrivate
+{
+ GdmDomainProvider *domain_provider;
+};
+
+static void gdm_domain_chooser_widget_class_init (GdmDomainChooserWidgetClass *klass);
+static void gdm_domain_chooser_widget_init (GdmDomainChooserWidget *domain_chooser_widget);
+static void gdm_domain_chooser_widget_finalize (GObject *object);
+
+G_DEFINE_TYPE (GdmDomainChooserWidget, gdm_domain_chooser_widget, GDM_TYPE_CHOOSER_WIDGET)
+
+#if 0
+
+enum {
+ CHOOSER_LIST_TITLE_COLUMN = 0,
+ CHOOSER_LIST_TRANSLATED_COLUMN,
+ CHOOSER_LIST_DOMAIN_COLUMN
+};
+
+#endif
+
+static gchar *
+convert_domain_name_to_display (const gchar *domain_name)
+{
+ gchar *utf8_name;
+ gchar *normalized_name;
+
+ utf8_name = g_locale_to_utf8 (domain_name, -1, NULL, NULL, NULL);
+ if (!utf8_name)
+ return NULL;
+
+ normalized_name = g_utf8_strdown (utf8_name, -1);
+ g_free (utf8_name);
+
+ return normalized_name;
+}
+
+char *
+gdm_domain_chooser_widget_get_current_domain_name (GdmDomainChooserWidget *widget)
+{
+ char *domain_name;
+
+ g_return_val_if_fail (GDM_IS_DOMAIN_CHOOSER_WIDGET (widget), NULL);
+
+ domain_name = gdm_chooser_widget_get_selected_item (GDM_CHOOSER_WIDGET (widget));
+
+ if (domain_name == NULL) {
+ domain_name = g_strdup ("__local");
+ }
+
+ return domain_name;
+}
+
+void
+gdm_domain_chooser_widget_set_current_domain_name (GdmDomainChooserWidget *widget,
+ const char *domain_name)
+{
+ g_return_if_fail (GDM_IS_DOMAIN_CHOOSER_WIDGET (widget));
+
+ if (domain_name == NULL) {
+ gdm_chooser_widget_set_selected_item (GDM_CHOOSER_WIDGET (widget),
+ NULL);
+ return;
+ }
+
+ gdm_chooser_widget_set_selected_item (GDM_CHOOSER_WIDGET (widget),
+ domain_name);
+}
+
+static void
+populate_widget (GdmDomainChooserWidget *domain_chooser_widget)
+{
+ GdmDomainChooserWidgetPrivate *priv = domain_chooser_widget->priv;
+ GdmChooserWidget *chooser_widget = GDM_CHOOSER_WIDGET (domain_chooser_widget);
+ GList *domain_list;
+ GList *l;
+ gchar *current_domain_name;
+
+ domain_list = gdm_domain_provider_peek_domains (priv->domain_provider);
+
+ current_domain_name = gdm_domain_chooser_widget_get_current_domain_name (domain_chooser_widget);
+ gdm_chooser_widget_remove_all_items (chooser_widget);
+
+ for (l = domain_list; l; l = g_list_next (l)) {
+ const gchar *domain_name = l->data;
+ gchar *display_name;
+
+ display_name = convert_domain_name_to_display (domain_name);
+ if (!display_name)
+ continue;
+
+ gdm_chooser_widget_add_item (chooser_widget,
+ domain_name,
+ NULL,
+ display_name,
+ display_name,
+ 0,
+ FALSE,
+ FALSE);
+
+ g_free (display_name);
+ }
+
+ gdm_chooser_widget_add_item (chooser_widget,
+ "__local",
+ NULL,
+ _("Local login"),
+ _("Log in to the local computer."),
+ 0,
+ FALSE,
+ TRUE);
+
+ gdm_domain_chooser_widget_set_current_domain_name (domain_chooser_widget, current_domain_name);
+}
+
+static void
+gdm_domain_chooser_widget_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (gdm_domain_chooser_widget_parent_class)->dispose (object);
+}
+
+static void
+gdm_domain_chooser_widget_realize (GtkWidget *widget)
+{
+ GdmDomainChooserWidget *chooser;
+
+ chooser = GDM_DOMAIN_CHOOSER_WIDGET (widget);
+
+ GTK_WIDGET_CLASS (gdm_domain_chooser_widget_parent_class)->realize (widget);
+}
+
+static void
+gdm_domain_chooser_widget_class_init (GdmDomainChooserWidgetClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->dispose = gdm_domain_chooser_widget_dispose;
+ object_class->finalize = gdm_domain_chooser_widget_finalize;
+ widget_class->realize = gdm_domain_chooser_widget_realize;
+
+ g_type_class_add_private (klass, sizeof (GdmDomainChooserWidgetPrivate));
+}
+
+static void
+gdm_domain_chooser_widget_init (GdmDomainChooserWidget *domain_chooser_widget)
+{
+ GdmDomainChooserWidgetPrivate *priv;
+
+ priv = domain_chooser_widget->priv = GDM_DOMAIN_CHOOSER_WIDGET_GET_PRIVATE (domain_chooser_widget);
+
+ priv->domain_provider = gdm_get_domain_provider ();
+ g_signal_connect_swapped (priv->domain_provider, "changed",
+ (GCallback) populate_widget, domain_chooser_widget);
+
+ populate_widget (domain_chooser_widget);
+
+ gdm_chooser_widget_set_separator_position (GDM_CHOOSER_WIDGET (domain_chooser_widget),
+ GDM_CHOOSER_WIDGET_POSITION_TOP);
+}
+
+static void
+gdm_domain_chooser_widget_finalize (GObject *object)
+{
+ GdmDomainChooserWidgetPrivate *priv;
+ GdmDomainChooserWidget *domain_chooser_widget;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GDM_IS_DOMAIN_CHOOSER_WIDGET (object));
+
+ domain_chooser_widget = GDM_DOMAIN_CHOOSER_WIDGET (object);
+ priv = domain_chooser_widget->priv;
+
+ g_return_if_fail (priv != NULL);
+
+ g_signal_handlers_disconnect_by_func (priv->domain_provider, populate_widget, domain_chooser_widget);
+
+ G_OBJECT_CLASS (gdm_domain_chooser_widget_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gdm_domain_chooser_widget_new (void)
+{
+ GObject *object;
+
+ object = g_object_new (GDM_TYPE_DOMAIN_CHOOSER_WIDGET,
+ "inactive-text", _("_Domains:"),
+ "active-text", _("_Domain:"),
+ NULL);
+
+ return GTK_WIDGET (object);
+}
Index: gdm-2.29.5/gui/simple-greeter/gdm-domain-chooser-widget.h
===================================================================
--- /dev/null
+++ gdm-2.29.5/gui/simple-greeter/gdm-domain-chooser-widget.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Hans Petter Jansson
+ *
+ * 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: Hans Petter Jansson
+ */
+
+#ifndef __GDM_DOMAIN_CHOOSER_WIDGET_H
+#define __GDM_DOMAIN_CHOOSER_WIDGET_H
+
+#include <glib-object.h>
+#include "gdm-chooser-widget.h"
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_DOMAIN_CHOOSER_WIDGET (gdm_domain_chooser_widget_get_type ())
+#define GDM_DOMAIN_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_DOMAIN_CHOOSER_WIDGET, GdmDomainChooserWidget))
+#define GDM_DOMAIN_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_DOMAIN_CHOOSER_WIDGET, GdmDomainChooserWidgetClass))
+#define GDM_IS_DOMAIN_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_DOMAIN_CHOOSER_WIDGET))
+#define GDM_IS_DOMAIN_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_DOMAIN_CHOOSER_WIDGET))
+#define GDM_DOMAIN_CHOOSER_WIDGET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_DOMAIN_CHOOSER_WIDGET, GdmDomainChooserWidgetClass))
+
+typedef struct GdmDomainChooserWidgetPrivate GdmDomainChooserWidgetPrivate;
+
+typedef struct
+{
+ GdmChooserWidget parent;
+ GdmDomainChooserWidgetPrivate *priv;
+} GdmDomainChooserWidget;
+
+typedef struct
+{
+ GdmChooserWidgetClass parent_class;
+} GdmDomainChooserWidgetClass;
+
+GType gdm_domain_chooser_widget_get_type (void);
+GtkWidget * gdm_domain_chooser_widget_new (void);
+
+char * gdm_domain_chooser_widget_get_current_domain_name (GdmDomainChooserWidget *widget);
+void gdm_domain_chooser_widget_set_current_domain_name (GdmDomainChooserWidget *widget,
+ const char *lang_name);
+
+G_END_DECLS
+
+#endif /* __GDM_DOMAIN_CHOOSER_WIDGET_H */
Index: gdm-2.29.5/gui/simple-greeter/gdm-domain-option-widget.c
===================================================================
--- /dev/null
+++ gdm-2.29.5/gui/simple-greeter/gdm-domain-option-widget.c
@@ -0,0 +1,379 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Hans Petter Jansson
+ *
+ * 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: Hans Petter Jansson <hpj@novell.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-profile.h"
+#include "gdm-domain-option-widget.h"
+#include "gdm-recent-option-widget.h"
+#include "gdm-domain-chooser-dialog.h"
+#include "gdm-domain-provider.h"
+
+#define GDM_DOMAIN_OPTION_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DOMAIN_OPTION_WIDGET, GdmDomainOptionWidgetPrivate))
+
+struct GdmDomainOptionWidgetPrivate
+{
+ GtkWidget *dialog;
+ GdmDomainProvider *domain_provider;
+};
+
+enum {
+ DOMAIN_ACTIVATED,
+ NUMBER_OF_SIGNALS
+};
+
+static guint signals [NUMBER_OF_SIGNALS] = { 0, };
+
+static void gdm_domain_option_widget_class_init (GdmDomainOptionWidgetClass *klass);
+static void gdm_domain_option_widget_init (GdmDomainOptionWidget *domain_option_widget);
+static void gdm_domain_option_widget_finalize (GObject *object);
+static void gdm_domain_option_widget_hide_dialog (GdmDomainOptionWidget *widget);
+
+G_DEFINE_TYPE (GdmDomainOptionWidget, gdm_domain_option_widget, GDM_TYPE_RECENT_OPTION_WIDGET)
+
+static gchar *
+convert_domain_name_to_display (const gchar *domain_name)
+{
+ gchar *utf8_name;
+ gchar *normalized_name;
+
+ utf8_name = g_locale_to_utf8 (domain_name, -1, NULL, NULL, NULL);
+ if (!utf8_name)
+ return NULL;
+
+ normalized_name = g_utf8_strdown (utf8_name, -1);
+ g_free (utf8_name);
+
+ return normalized_name;
+}
+
+static void
+gdm_domain_option_widget_set_domain_from_dialog (GdmDomainOptionWidget *widget)
+{
+ char *domain_name;
+
+ domain_name = gdm_domain_chooser_dialog_get_current_domain_name (GDM_DOMAIN_CHOOSER_DIALOG (widget->priv->dialog));
+ gdm_domain_option_widget_set_current_domain_name (widget, domain_name);
+ g_free (domain_name);
+}
+
+static void
+on_dialog_response (GtkDialog *dialog,
+ int response_id,
+ GdmDomainOptionWidget *widget)
+{
+ switch (response_id) {
+ case GTK_RESPONSE_OK:
+ gdm_domain_option_widget_set_domain_from_dialog (widget);
+ break;
+
+ default:
+ break;
+ }
+
+ gdm_domain_option_widget_hide_dialog (widget);
+}
+
+static void
+gdm_domain_option_widget_hide_dialog (GdmDomainOptionWidget *widget)
+{
+ gtk_widget_destroy (widget->priv->dialog);
+ widget->priv->dialog = NULL;
+}
+
+static void
+create_dialog (GdmDomainOptionWidget *widget)
+{
+ gdm_profile_start (NULL);
+
+ g_assert (widget->priv->dialog == NULL);
+
+ widget->priv->dialog = gdm_domain_chooser_dialog_new ();
+
+ gdm_profile_end (NULL);
+}
+
+static void
+gdm_domain_option_widget_show_dialog (GdmDomainOptionWidget *widget,
+ const char *active_item_id)
+{
+ if (widget->priv->dialog == NULL) {
+ create_dialog (widget);
+ }
+
+ g_signal_connect (GTK_DIALOG (widget->priv->dialog),
+ "response",
+ G_CALLBACK (on_dialog_response),
+ widget);
+
+ gtk_widget_show_all (GTK_WIDGET (widget->priv->dialog));
+
+ gdm_domain_chooser_dialog_set_current_domain_name (GDM_DOMAIN_CHOOSER_DIALOG (GDM_DOMAIN_OPTION_WIDGET (widget)->priv->dialog),
+ active_item_id);
+}
+
+static gint
+find_domain_name_in_list (GdmDomainOptionWidget *domain_option_widget, const gchar *domain_name)
+{
+ GdmDomainOptionWidgetPrivate *priv = domain_option_widget->priv;
+ GList *domain_list;
+ GList *domain_list_item;
+ gint result = -1;
+
+ domain_list = gdm_domain_provider_peek_domains (priv->domain_provider);
+ domain_list_item = g_list_find_custom (domain_list, domain_name, (GCompareFunc) g_strcasecmp);
+
+ if (domain_list_item)
+ result = g_list_position (domain_list, domain_list_item);
+
+ return result;
+}
+
+static gboolean
+gdm_domain_option_widget_lookup_item (GdmRecentOptionWidget *domain_option_widget,
+ const char *id,
+ char **name,
+ char **comment)
+{
+ gchar *display_name;
+
+ if (!find_domain_name_in_list (GDM_DOMAIN_OPTION_WIDGET (domain_option_widget), id))
+ return FALSE;
+
+ display_name = convert_domain_name_to_display (id);
+ if (!display_name)
+ return FALSE;
+
+ if (name)
+ *name = g_strdup (display_name);
+ if (comment)
+ *comment = g_strdup (display_name);
+
+ g_free (display_name);
+ return TRUE;
+}
+
+static void
+gdm_domain_option_widget_activated (GdmOptionWidget *widget)
+{
+ char *active_item_id;
+
+ active_item_id = gdm_option_widget_get_active_item (GDM_OPTION_WIDGET (widget));
+ if (active_item_id == NULL) {
+ return;
+ }
+
+ if (strcmp (active_item_id, "__other") == 0) {
+ active_item_id = gdm_option_widget_get_default_item (widget);
+ gdm_domain_option_widget_set_current_domain_name (GDM_DOMAIN_OPTION_WIDGET (widget), active_item_id);
+ gdm_domain_option_widget_show_dialog (GDM_DOMAIN_OPTION_WIDGET (widget), active_item_id);
+ }
+
+ g_signal_emit (G_OBJECT (widget), signals [DOMAIN_ACTIVATED], 0);
+
+ g_free (active_item_id);
+}
+
+static void
+gdm_domain_option_widget_class_init (GdmDomainOptionWidgetClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GdmOptionWidgetClass *option_widget_class = GDM_OPTION_WIDGET_CLASS (klass);
+
+ object_class->finalize = gdm_domain_option_widget_finalize;
+
+ option_widget_class->activated = gdm_domain_option_widget_activated;
+
+ signals [DOMAIN_ACTIVATED] = g_signal_new ("domain-activated",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GdmDomainOptionWidgetClass, domain_activated),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private (klass, sizeof (GdmDomainOptionWidgetPrivate));
+}
+
+static void
+populate_widget (GdmDomainOptionWidget *domain_option_widget)
+{
+ GdmDomainOptionWidgetPrivate *priv = domain_option_widget->priv;
+ GdmOptionWidget *option_widget = GDM_OPTION_WIDGET (domain_option_widget);
+ GList *domain_list;
+ GList *l;
+ gchar *current_domain_name;
+
+ domain_list = gdm_domain_provider_peek_domains (priv->domain_provider);
+
+ current_domain_name = gdm_domain_option_widget_get_current_domain_name (domain_option_widget);
+ gdm_option_widget_remove_all_items (option_widget);
+
+ for (l = domain_list; l; l = g_list_next (l)) {
+ const gchar *domain_name = l->data;
+ gchar *display_name;
+
+ display_name = convert_domain_name_to_display (domain_name);
+ if (!display_name)
+ continue;
+
+ gdm_option_widget_add_item (option_widget,
+ domain_name,
+ display_name,
+ display_name,
+ GDM_OPTION_WIDGET_POSITION_MIDDLE);
+ g_free (display_name);
+ }
+
+ if (current_domain_name) {
+ gdm_domain_option_widget_set_current_domain_name (domain_option_widget, current_domain_name);
+ g_free (current_domain_name);
+ }
+}
+
+static void
+gdm_domain_option_widget_init (GdmDomainOptionWidget *domain_option_widget)
+{
+ GdmDomainOptionWidgetPrivate *priv;
+ GdmOptionWidget *option_widget = GDM_OPTION_WIDGET (domain_option_widget);
+ GError *error = NULL;
+
+ priv = domain_option_widget->priv = GDM_DOMAIN_OPTION_WIDGET_GET_PRIVATE (domain_option_widget);
+
+ priv->domain_provider = gdm_get_domain_provider ();
+ g_signal_connect_swapped (priv->domain_provider, "changed",
+ (GCallback) populate_widget, domain_option_widget);
+
+ gdm_option_widget_add_item (option_widget,
+ "__local",
+ _("Local login"),
+ _("Log in to the local computer."),
+ GDM_OPTION_WIDGET_POSITION_TOP);
+
+ gdm_option_widget_add_item (option_widget,
+ "__other",
+ _("Other..."),
+ _("Choose a domain from the "
+ "full list of available domains."),
+ GDM_OPTION_WIDGET_POSITION_BOTTOM);
+
+ gdm_option_widget_set_default_item (option_widget, "__local");
+
+ populate_widget (domain_option_widget);
+
+ gdm_recent_option_widget_set_gconf_key (GDM_RECENT_OPTION_WIDGET (domain_option_widget),
+ "/apps/gdm/simple-greeter/recent-domains",
+ (GdmRecentOptionLookupItemFunc) gdm_domain_option_widget_lookup_item,
+ &error);
+
+ if (error != NULL) {
+ g_warning ("Could not read recent domains from gconf: %s",
+ error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+gdm_domain_option_widget_finalize (GObject *object)
+{
+ GdmDomainOptionWidgetPrivate *priv;
+ GdmDomainOptionWidget *domain_option_widget;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GDM_IS_DOMAIN_OPTION_WIDGET (object));
+
+ domain_option_widget = GDM_DOMAIN_OPTION_WIDGET (object);
+ priv = domain_option_widget->priv;
+
+ g_return_if_fail (priv != NULL);
+
+ if (priv->dialog != NULL) {
+ gtk_widget_destroy (priv->dialog);
+ }
+
+ g_signal_handlers_disconnect_by_func (priv->domain_provider, populate_widget, domain_option_widget);
+
+ G_OBJECT_CLASS (gdm_domain_option_widget_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gdm_domain_option_widget_new (void)
+{
+ GObject *object;
+
+ object = g_object_new (GDM_TYPE_DOMAIN_OPTION_WIDGET,
+ "label-text", _("_Domain:"),
+ "icon-name", "preferences-system-network",
+ "max-item-count", 16,
+ NULL);
+
+ return GTK_WIDGET (object);
+}
+
+char *
+gdm_domain_option_widget_get_current_domain_name (GdmDomainOptionWidget *widget)
+{
+ char *active_item_id;
+
+ active_item_id = gdm_option_widget_get_active_item (GDM_OPTION_WIDGET (widget));
+ if (active_item_id == NULL) {
+ return NULL;
+ }
+
+ if (strcmp (active_item_id, "__other") == 0) {
+ g_free (active_item_id);
+ return NULL;
+ }
+
+ return active_item_id;
+}
+
+void
+gdm_domain_option_widget_set_current_domain_name (GdmDomainOptionWidget *widget,
+ const char *domain_name)
+{
+ g_return_if_fail (GDM_IS_DOMAIN_OPTION_WIDGET (widget));
+
+ if (domain_name != NULL &&
+ !gdm_option_widget_lookup_item (GDM_OPTION_WIDGET (widget),
+ domain_name, NULL, NULL, NULL)) {
+ gdm_recent_option_widget_add_item (GDM_RECENT_OPTION_WIDGET (widget),
+ domain_name);
+ }
+
+ gdm_option_widget_set_active_item (GDM_OPTION_WIDGET (widget), domain_name);
+}
Index: gdm-2.29.5/gui/simple-greeter/gdm-domain-option-widget.h
===================================================================
--- /dev/null
+++ gdm-2.29.5/gui/simple-greeter/gdm-domain-option-widget.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Hans Petter Jansson
+ *
+ * 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: Hans Petter Jansson <hpj@novell.com>
+ */
+
+#ifndef __GDM_DOMAIN_OPTION_WIDGET_H
+#define __GDM_DOMAIN_OPTION_WIDGET_H
+
+#include <glib-object.h>
+#include "gdm-recent-option-widget.h"
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_DOMAIN_OPTION_WIDGET (gdm_domain_option_widget_get_type ())
+#define GDM_DOMAIN_OPTION_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_DOMAIN_OPTION_WIDGET, GdmDomainOptionWidget))
+#define GDM_DOMAIN_OPTION_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_DOMAIN_OPTION_WIDGET, GdmDomainOptionWidgetClass))
+#define GDM_IS_DOMAIN_OPTION_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_DOMAIN_OPTION_WIDGET))
+#define GDM_IS_DOMAIN_OPTION_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_DOMAIN_OPTION_WIDGET))
+#define GDM_DOMAIN_OPTION_WIDGET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_DOMAIN_OPTION_WIDGET, GdmDomainOptionWidgetClass))
+
+typedef struct GdmDomainOptionWidgetPrivate GdmDomainOptionWidgetPrivate;
+
+typedef struct
+{
+ GdmRecentOptionWidget parent;
+ GdmDomainOptionWidgetPrivate *priv;
+} GdmDomainOptionWidget;
+
+typedef struct
+{
+ GdmRecentOptionWidgetClass parent_class;
+
+ void (* domain_activated) (GdmDomainOptionWidget *widget);
+} GdmDomainOptionWidgetClass;
+
+GType gdm_domain_option_widget_get_type (void);
+GtkWidget * gdm_domain_option_widget_new (void);
+
+char * gdm_domain_option_widget_get_current_domain_name (GdmDomainOptionWidget *widget);
+void gdm_domain_option_widget_set_current_domain_name (GdmDomainOptionWidget *widget,
+ const char *domain_name);
+
+#endif /* __GDM_DOMAIN_OPTION_WIDGET_H */
Index: gdm-2.29.5/gui/simple-greeter/gdm-domain-provider.c
===================================================================
--- /dev/null
+++ gdm-2.29.5/gui/simple-greeter/gdm-domain-provider.c
@@ -0,0 +1,536 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Hans Petter Jansson <hpj@novell.com>
+ *
+ * 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: Hans Petter Jansson <hpj@novell.com>
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+
+#include "gdm-domain-provider.h"
+
+#define QUERY_TIMEOUT_S 30
+#define N_DOMAINS_MAX 128
+#define BUFFER_READ_MAX 256
+
+#define GDM_DOMAIN_PROVIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DOMAIN_PROVIDER, GdmDomainProviderPrivate))
+
+typedef enum
+{
+ STATE_IDLE, /* Next state: STATE_QUERY_SEPARATOR */
+ STATE_QUERY_SEPARATOR, /* Next state: STATE_QUERY_OWN_DOMAIN or STATE_IDLE */
+ STATE_QUERY_OWN_DOMAIN, /* Next state: STATE_QUERY_TRUSTED_DOMAINS or STATE_IDLE */
+ STATE_QUERY_TRUSTED_DOMAINS, /* Next state: STATE_IDLE */
+}
+State;
+
+enum
+{
+ CHANGED,
+ NUMBER_OF_SIGNALS
+};
+
+typedef void (*CmdEndFunc) (GdmDomainProvider *domain_provider, gchar *output, gint status);
+
+struct GdmDomainProviderPrivate
+{
+ gchar *separator;
+ GList *domains;
+
+ State state;
+ guint something_changed : 1;
+
+ GIOChannel *cmd_channel;
+ GString *cmd_output_string;
+ GPid cmd_pid;
+ CmdEndFunc cmd_end_func;
+
+ gchar *domains_output;
+
+ guint callback_id;
+};
+
+static void gdm_domain_provider_class_init (GdmDomainProviderClass *klass);
+static void gdm_domain_provider_init (GdmDomainProvider *domain_provider);
+static void gdm_domain_provider_finalize (GObject *object);
+
+static void get_separator_begin (GdmDomainProvider *domain_provider);
+
+static GdmDomainProvider *global_domain_provider = NULL;
+static guint signals [NUMBER_OF_SIGNALS] = { 0, };
+
+G_DEFINE_TYPE (GdmDomainProvider, gdm_domain_provider, G_TYPE_OBJECT)
+
+static gint
+compare_strings (const gchar *string_a, const gchar *string_b)
+{
+ gint result = 0;
+
+ if (string_a) {
+ if (string_b) {
+ result = g_ascii_strcasecmp (string_a, string_b);
+ } else {
+ result = -1;
+ }
+ } else if (string_b) {
+ result = 1;
+ }
+
+ return result;
+}
+
+static gint
+compare_string_lists (GList *list_a, GList *list_b)
+{
+ gint result = 0;
+
+ for (;;) {
+ if (list_a == NULL) {
+ if (list_b != NULL)
+ result = 1;
+ break;
+ } else if (list_b == NULL) {
+ result = -1;
+ break;
+ }
+
+ result = g_ascii_strcasecmp (list_a->data, list_b->data);
+ if (result != 0)
+ break;
+
+ list_a = g_list_next (list_a);
+ list_b = g_list_next (list_b);
+ }
+
+ return result;
+}
+
+static gint
+cmd_cleanup (GdmDomainProvider *domain_provider, gchar **output)
+{
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+ gint cmd_status = 0;
+ gchar *cmd_output;
+
+ /* When idle, callback_id represents the timeout until we run the next
+ * series of queries. Otherwise, it represents the GIOChannel watch. */
+
+ if (priv->callback_id)
+ g_source_remove (priv->callback_id);
+ priv->callback_id = 0;
+ priv->cmd_channel = NULL;
+
+ if (priv->state == STATE_IDLE)
+ return 0;
+
+ priv->state = STATE_IDLE;
+
+ waitpid (priv->cmd_pid, &cmd_status, 0);
+ g_spawn_close_pid (priv->cmd_pid);
+
+ cmd_output = g_string_free (priv->cmd_output_string, FALSE);
+ priv->cmd_output_string = NULL;
+
+ if (output)
+ *output = cmd_output;
+ else
+ g_free (cmd_output);
+
+ return WEXITSTATUS (cmd_status);
+}
+
+static gboolean
+cmd_handle_output (GIOChannel *channel, GIOCondition condition, gpointer data)
+{
+ GdmDomainProvider *domain_provider = data;
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+ gchar buf [BUFFER_READ_MAX];
+ gsize bytes_read;
+ GIOStatus status;
+
+ g_assert (priv->cmd_output_string != NULL);
+ g_assert (priv->state != STATE_IDLE);
+
+ status = g_io_channel_read_chars (channel, buf, BUFFER_READ_MAX, &bytes_read, NULL);
+
+ if (bytes_read < 1) {
+ gchar *cmd_output;
+ gint cmd_status;
+
+ cmd_status = cmd_cleanup (domain_provider, &cmd_output);
+
+ if (priv->cmd_end_func) {
+ CmdEndFunc cmd_end_func = priv->cmd_end_func;
+ priv->cmd_end_func = NULL;
+
+ cmd_end_func (domain_provider, cmd_output, cmd_status);
+ }
+
+ /* cmd_cleanup () removes the watch for us */
+ return TRUE;
+ }
+
+ g_string_append_len (priv->cmd_output_string, buf, bytes_read);
+ return TRUE;
+}
+
+static gboolean
+async_spawn_and_read (GdmDomainProvider *domain_provider,
+ const gchar * const *spawn_args,
+ CmdEndFunc end_func)
+{
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+ gint cmd_stdout_fd;
+
+ g_assert (priv->state == STATE_IDLE);
+
+ /* NOTE: The GLib docs don't say if g_spawn_async_with_pipes () can actually cause
+ * spawn_args to be written to. We assume that won't happen. */
+
+ if (!g_spawn_async_with_pipes ("/",
+ (gchar **) spawn_args,
+ NULL,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL |
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL /* child setup function */,
+ NULL /* child setup user_data */,
+ &priv->cmd_pid,
+ NULL /* &cmd_stdin_fd */,
+ &cmd_stdout_fd,
+ NULL /* &cmd_stderr_fd */,
+ NULL))
+ return FALSE;
+
+ priv->cmd_end_func = end_func;
+ priv->cmd_output_string = g_string_new ("");
+
+ fcntl (cmd_stdout_fd, F_SETFL, O_NONBLOCK);
+
+ priv->cmd_channel = g_io_channel_unix_new (cmd_stdout_fd);
+ g_io_channel_set_encoding (priv->cmd_channel, NULL, NULL);
+ g_io_channel_set_close_on_unref (priv->cmd_channel, TRUE);
+ priv->callback_id = g_io_add_watch (priv->cmd_channel,
+ G_IO_IN | G_IO_HUP,
+ cmd_handle_output,
+ domain_provider);
+ g_io_channel_unref (priv->cmd_channel); /* Watch holds remaining ref */
+
+ return TRUE;
+}
+
+static gboolean
+idle_end (GdmDomainProvider *domain_provider)
+{
+ cmd_cleanup (domain_provider, NULL);
+
+ /* Next state */
+
+ get_separator_begin (domain_provider);
+
+ /* cmd_cleanup () removes the callback for us */
+ return TRUE;
+}
+
+static void
+idle_begin (GdmDomainProvider *domain_provider)
+{
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+
+ g_free (priv->domains_output);
+ priv->domains_output = NULL;
+
+ if (priv->something_changed) {
+ /* Emit changed signal */
+
+ g_signal_emit (G_OBJECT (domain_provider), signals [CHANGED], 0);
+ priv->something_changed = FALSE;
+ }
+
+ priv->callback_id = g_timeout_add_seconds (QUERY_TIMEOUT_S, (GSourceFunc) idle_end, domain_provider);
+ priv->state = STATE_IDLE;
+}
+
+static void
+get_trusted_domains_end (GdmDomainProvider *domain_provider, gchar *output, gint status)
+{
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+ GList *domains = NULL;
+ GList *old_domains;
+
+ if (status == 0 && output != NULL && *output) {
+ gchar **tokens;
+ gint i;
+
+ if (priv->domains_output) {
+ output = g_realloc (output, strlen (output) + strlen (priv->domains_output) + 1);
+ strcat (output, priv->domains_output);
+ }
+
+ tokens = g_strsplit_set (output, "\n\r", N_DOMAINS_MAX);
+
+ g_qsort_with_data (tokens,
+ g_strv_length (tokens),
+ sizeof (gchar *),
+ (GCompareDataFunc) g_ascii_strcasecmp,
+ NULL);
+
+ for (i = 0; tokens [i]; i++) {
+ /* Ensure no blank entries */
+ if (!strlen (tokens [i]))
+ continue;
+
+ /* Ensure no duplicates */
+ if (i > 0 && !g_ascii_strcasecmp (tokens [i], tokens [i - 1]))
+ continue;
+
+ /* Ensure no builtin */
+ if (!g_ascii_strcasecmp (tokens [i], "BUILTIN"))
+ continue;
+
+ /* Ensure no local host name */
+ if (!g_ascii_strcasecmp (tokens [i], g_get_host_name ()))
+ continue;
+
+ domains = g_list_prepend (domains, tokens [i]);
+ }
+
+ g_free (tokens);
+
+ domains = g_list_reverse (domains);
+ }
+
+ g_free (output);
+
+ old_domains = priv->domains;
+ priv->domains = domains;
+
+ if (compare_string_lists (domains, old_domains) != 0)
+ priv->something_changed = TRUE;
+
+ g_list_foreach (old_domains, (GFunc) g_free, NULL);
+ g_list_free (old_domains);
+
+ /* Next state */
+
+ idle_begin (domain_provider);
+}
+
+static void
+get_trusted_domains_begin (GdmDomainProvider *domain_provider)
+{
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+ const gchar * const cmd_args [] = { "wbinfo", "--trusted-domains", NULL };
+
+ if (async_spawn_and_read (domain_provider, cmd_args, get_trusted_domains_end))
+ priv->state = STATE_QUERY_TRUSTED_DOMAINS;
+ else
+ idle_begin (domain_provider);
+}
+
+static void
+get_own_domain_end (GdmDomainProvider *domain_provider, gchar *output, gint status)
+{
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+
+ if (status == 0 && output != NULL && *output)
+ priv->domains_output = output;
+
+ /* Next state */
+
+ get_trusted_domains_begin (domain_provider);
+}
+
+static void
+get_own_domain_begin (GdmDomainProvider *domain_provider)
+{
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+ const gchar * const cmd_args [] = { "wbinfo", "--own-domain", NULL };
+
+ if (async_spawn_and_read (domain_provider, cmd_args, get_own_domain_end))
+ priv->state = STATE_QUERY_OWN_DOMAIN;
+ else
+ idle_begin (domain_provider);
+}
+
+static void
+get_separator_end (GdmDomainProvider *domain_provider, gchar *output, gint status)
+{
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+ gchar *separator = NULL;
+ gchar *old_separator;
+
+ if (status == 0 && output != NULL) {
+ gchar *p0, *p1;
+
+ p0 = strchr (output, '\n');
+ p1 = strchr (output, '\r');
+ if (!p0 || (p1 && p1 < p0))
+ p0 = p1;
+
+ if (p0 && p0 != output) {
+ *p0 = 0;
+ separator = output;
+ } else {
+ g_free (output);
+ }
+ }
+
+ old_separator = priv->separator;
+ priv->separator = separator;
+
+ if (compare_strings (separator, old_separator))
+ priv->something_changed = TRUE;
+
+ g_free (old_separator);
+
+ /* Next state */
+
+ if (priv->separator)
+ get_own_domain_begin (domain_provider);
+ else
+ idle_begin (domain_provider);
+}
+
+static void
+get_separator_begin (GdmDomainProvider *domain_provider)
+{
+ GdmDomainProviderPrivate *priv = domain_provider->priv;
+ const gchar * const cmd_args [] = { "wbinfo", "--separator", NULL };
+
+ if (async_spawn_and_read (domain_provider, cmd_args, get_separator_end))
+ priv->state = STATE_QUERY_SEPARATOR;
+ else
+ idle_begin (domain_provider);
+}
+
+static void
+gdm_domain_provider_class_init (GdmDomainProviderClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gdm_domain_provider_finalize;
+
+ signals [CHANGED] = g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GdmDomainProviderClass, changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private (klass, sizeof (GdmDomainProviderPrivate));
+}
+
+static void
+gdm_domain_provider_init (GdmDomainProvider *domain_provider)
+{
+ GdmDomainProviderPrivate *priv;
+
+ priv = domain_provider->priv = GDM_DOMAIN_PROVIDER_GET_PRIVATE (domain_provider);
+
+ priv->state = STATE_IDLE;
+
+ /* Start the state machine */
+ get_separator_begin (domain_provider);
+}
+
+static void
+gdm_domain_provider_finalize (GObject *object)
+{
+ GdmDomainProvider *domain_provider;
+ GdmDomainProviderPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GDM_IS_DOMAIN_PROVIDER (object));
+
+ domain_provider = GDM_DOMAIN_PROVIDER (object);
+ priv = domain_provider->priv;
+
+ /* Stop the state machine */
+ cmd_cleanup (domain_provider, NULL);
+
+ g_free (priv->domains_output);
+ priv->domains_output = NULL;
+
+ G_OBJECT_CLASS (gdm_domain_provider_parent_class)->finalize (object);
+}
+
+/* --- *
+ * API *
+ * --- */
+
+GdmDomainProvider *
+gdm_get_domain_provider (void)
+{
+ if (!global_domain_provider)
+ global_domain_provider = g_object_new (GDM_TYPE_DOMAIN_PROVIDER, NULL);
+
+ return global_domain_provider;
+}
+
+gboolean
+gdm_domain_provider_is_domain_logon_enabled (GdmDomainProvider *domain_provider)
+{
+ GdmDomainProviderPrivate *priv;
+
+ g_return_val_if_fail (GDM_IS_DOMAIN_PROVIDER (domain_provider), FALSE);
+
+ priv = domain_provider->priv;
+
+ return priv->separator ? TRUE : FALSE;
+}
+
+const gchar *
+gdm_domain_provider_peek_separator (GdmDomainProvider *domain_provider)
+{
+ GdmDomainProviderPrivate *priv;
+
+ g_return_val_if_fail (GDM_IS_DOMAIN_PROVIDER (domain_provider), NULL);
+
+ priv = domain_provider->priv;
+
+ return priv->separator;
+}
+
+GList *
+gdm_domain_provider_peek_domains (GdmDomainProvider *domain_provider)
+{
+ GdmDomainProviderPrivate *priv;
+
+ g_return_val_if_fail (GDM_IS_DOMAIN_PROVIDER (domain_provider), NULL);
+
+ priv = domain_provider->priv;
+
+ return priv->domains;
+}
Index: gdm-2.29.5/gui/simple-greeter/gdm-domain-provider.h
===================================================================
--- /dev/null
+++ gdm-2.29.5/gui/simple-greeter/gdm-domain-provider.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Hans Petter Jansson <hpj@novell.com>
+ *
+ * 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: Hans Petter Jansson <hpj@novell.com>
+ */
+
+#ifndef __GDM_DOMAIN_PROVIDER_H
+#define __GDM_DOMAIN_PROVIDER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_DOMAIN_PROVIDER (gdm_domain_provider_get_type ())
+#define GDM_DOMAIN_PROVIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_DOMAIN_PROVIDER, GdmDomainProvider))
+#define GDM_DOMAIN_PROVIDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_DOMAIN_PROVIDER, GdmDomainProviderClass))
+#define GDM_IS_DOMAIN_PROVIDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_DOMAIN_PROVIDER))
+#define GDM_IS_DOMAIN_PROVIDER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_DOMAIN_PROVIDER))
+#define GDM_DOMAIN_PROVIDER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_DOMAIN_PROVIDER, GdmDomainProviderClass))
+
+typedef struct GdmDomainProviderPrivate GdmDomainProviderPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GdmDomainProviderPrivate *priv;
+} GdmDomainProvider;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+ void (* changed) (GdmDomainProvider *domain_provider);
+} GdmDomainProviderClass;
+
+GType gdm_domain_provider_get_type (void);
+
+GdmDomainProvider * gdm_get_domain_provider (void);
+
+gboolean gdm_domain_provider_is_domain_logon_enabled (GdmDomainProvider *domain_provider);
+const gchar * gdm_domain_provider_peek_separator (GdmDomainProvider *domain_provider);
+GList * gdm_domain_provider_peek_domains (GdmDomainProvider *domain_provider);
+
+G_END_DECLS
+
+#endif /* __GDM_DOMAIN_PROVIDER_H */
Index: gdm-2.29.5/gui/simple-greeter/gdm-greeter-panel.c
===================================================================
--- gdm-2.29.5.orig/gui/simple-greeter/gdm-greeter-panel.c
+++ gdm-2.29.5/gui/simple-greeter/gdm-greeter-panel.c
@@ -52,7 +52,10 @@
#include "gdm-layout-option-widget.h"
#include "gdm-session-option-widget.h"
#include "gdm-timer.h"
+#include "gdm-domain-option-widget.h"
#include "gdm-profile.h"
+#include "gdm-settings-client.h"
+#include "gdm-settings-keys.h"
#include "na-tray.h"
@@ -83,6 +86,9 @@ struct GdmGreeterPanelPrivate
GtkWidget *language_option_widget;
GtkWidget *layout_option_widget;
GtkWidget *session_option_widget;
+ GtkWidget *domain_option_widget;
+
+ gboolean show_domain;
GdmTimer *animation_timer;
double progress;
@@ -104,6 +110,7 @@ enum {
LANGUAGE_SELECTED,
LAYOUT_SELECTED,
SESSION_SELECTED,
+ DOMAIN_SELECTED,
DIALOG_HIDDEN,
NUMBER_OF_SIGNALS
};
@@ -497,6 +504,17 @@ gdm_greeter_panel_class_init (GdmGreeter
G_TYPE_NONE,
1, G_TYPE_STRING);
+ signals[DOMAIN_SELECTED] =
+ g_signal_new ("domain-selected",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdmGreeterPanelClass, domain_selected),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+
signals[DIALOG_HIDDEN] =
g_signal_new ("dialog-hidden",
G_TYPE_FROM_CLASS (object_class),
@@ -832,6 +850,32 @@ on_shutdown_menu_deactivate (GdmGreeterP
}
static void
+on_domain_activated (GdmDomainOptionWidget *widget,
+ GdmGreeterPanel *panel)
+{
+
+ char *domain;
+
+ domain = gdm_domain_option_widget_get_current_domain_name (GDM_DOMAIN_OPTION_WIDGET (panel->priv->domain_option_widget));
+
+ if (domain == NULL) {
+ return;
+ }
+
+ g_signal_emit (panel, signals[DOMAIN_SELECTED], 0, domain);
+
+ g_free (domain);
+}
+
+static void
+on_domain_dialog_hidden (GdmLanguageOptionWidget *widget,
+ GdmGreeterPanel *panel)
+{
+
+ g_signal_emit (panel, signals[DIALOG_HIDDEN], 0);
+}
+
+static void
gdm_greeter_panel_init (GdmGreeterPanel *panel)
{
NaTray *tray;
@@ -849,6 +893,11 @@ gdm_greeter_panel_init (GdmGreeterPanel
panel->priv->geometry.width = -1;
panel->priv->geometry.height = -1;
+ if (!gdm_settings_client_get_boolean (GDM_KEY_SUSE_SHOW_DOMAIN,
+ &panel->priv->show_domain)) {
+ panel->priv->show_domain = FALSE;
+ }
+
gtk_window_set_title (GTK_WINDOW (panel), _("Panel"));
gtk_window_set_decorated (GTK_WINDOW (panel), FALSE);
@@ -901,6 +950,15 @@ gdm_greeter_panel_init (GdmGreeterPanel
G_CALLBACK (on_session_activated), panel);
gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), panel->priv->session_option_widget, FALSE, FALSE, 6);
+ panel->priv->domain_option_widget = gdm_domain_option_widget_new ();
+ g_signal_connect (G_OBJECT (panel->priv->domain_option_widget),
+ "domain-activated",
+ G_CALLBACK (on_domain_activated), panel);
+ g_signal_connect (G_OBJECT (panel->priv->domain_option_widget),
+ "dialog-hidden",
+ G_CALLBACK (on_domain_dialog_hidden), panel);
+ gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), panel->priv->domain_option_widget, FALSE, FALSE, 6);
+
spacer = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), spacer, TRUE, TRUE, 6);
gtk_widget_show (spacer);
@@ -1025,6 +1083,11 @@ gdm_greeter_panel_show_user_options (Gdm
gtk_widget_show (panel->priv->session_option_widget);
gtk_widget_show (panel->priv->language_option_widget);
gtk_widget_show (panel->priv->layout_option_widget);
+ if (panel->priv->show_domain) {
+ gtk_widget_show (panel->priv->domain_option_widget);
+ } else {
+ gtk_widget_hide (panel->priv->domain_option_widget);
+ }
}
void
@@ -1033,18 +1096,30 @@ gdm_greeter_panel_hide_user_options (Gdm
gtk_widget_hide (panel->priv->session_option_widget);
gtk_widget_hide (panel->priv->language_option_widget);
gtk_widget_hide (panel->priv->layout_option_widget);
+ if (panel->priv->show_domain) {
+ gtk_widget_show (panel->priv->domain_option_widget);
+ } else {
+ gtk_widget_hide (panel->priv->domain_option_widget);
+ }
g_debug ("GdmGreeterPanel: activating default layout");
gdm_layout_activate (NULL);
}
void
+gdm_greeter_panel_set_domain_enabled (GdmGreeterPanel *panel, gboolean enabled)
+{
+ gtk_widget_set_sensitive (panel->priv->domain_option_widget, enabled);
+}
+
+void
gdm_greeter_panel_reset (GdmGreeterPanel *panel)
{
gdm_greeter_panel_set_default_language_name (panel, NULL);
gdm_greeter_panel_set_default_layout_name (panel, NULL);
gdm_greeter_panel_set_default_session_name (panel, NULL);
gdm_greeter_panel_hide_user_options (panel);
+ gdm_greeter_panel_set_domain_enabled (panel, TRUE);
}
void
@@ -1126,3 +1201,20 @@ gdm_greeter_panel_set_default_session_na
gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (panel->priv->session_option_widget),
session_name);
}
+
+void
+gdm_greeter_panel_set_default_domain_name (GdmGreeterPanel *panel,
+ const char *domain_name)
+{
+ g_return_if_fail (GDM_IS_GREETER_PANEL (panel));
+
+ if (domain_name != NULL &&
+ !gdm_option_widget_lookup_item (GDM_OPTION_WIDGET (panel->priv->domain_option_widget),
+ domain_name, NULL, NULL, NULL)) {
+ g_warning ("Default domain is not available");
+ return;
+ }
+
+ gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (panel->priv->domain_option_widget),
+ domain_name);
+}
Index: gdm-2.29.5/gui/simple-greeter/gdm-greeter-panel.h
===================================================================
--- gdm-2.29.5.orig/gui/simple-greeter/gdm-greeter-panel.h
+++ gdm-2.29.5/gui/simple-greeter/gdm-greeter-panel.h
@@ -54,6 +54,9 @@ typedef struct
void (* session_selected) (GdmGreeterPanel *panel,
const char *text);
+ void (* domain_selected) (GdmGreeterPanel *panel,
+ const char *text);
+
void (* dialog_hidden) (GdmGreeterPanel *panel);
} GdmGreeterPanelClass;
@@ -67,12 +70,16 @@ void gdm_greeter_panel
void gdm_greeter_panel_hide_user_options (GdmGreeterPanel *panel);
void gdm_greeter_panel_reset (GdmGreeterPanel *panel);
+void gdm_greeter_panel_set_domain_enabled (GdmGreeterPanel *panel, gboolean enabled);
+
void gdm_greeter_panel_set_default_language_name (GdmGreeterPanel *panel,
const char *language_name);
void gdm_greeter_panel_set_default_layout_name (GdmGreeterPanel *panel,
const char *layout_name);
void gdm_greeter_panel_set_default_session_name (GdmGreeterPanel *panel,
const char *session_name);
+void gdm_greeter_panel_set_default_domain_name (GdmGreeterPanel *panel,
+ const char *domain_name);
G_END_DECLS
#endif /* __GDM_GREETER_PANEL_H */
Index: gdm-2.29.5/gui/simple-greeter/gdm-greeter-session.c
===================================================================
--- gdm-2.29.5.orig/gui/simple-greeter/gdm-greeter-session.c
+++ gdm-2.29.5/gui/simple-greeter/gdm-greeter-session.c
@@ -39,6 +39,8 @@
#include "gdm-greeter-login-window.h"
#include "gdm-user-chooser-widget.h"
+#include "gdm-domain-provider.h"
+
#include "gdm-profile.h"
#define GDM_GREETER_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_SESSION, GdmGreeterSessionPrivate))
@@ -49,6 +51,11 @@ struct GdmGreeterSessionPrivate
GtkWidget *login_window;
GtkWidget *panel;
+
+ char *user;
+ char *domain;
+
+ gint n_info_queries;
};
enum {
@@ -63,6 +70,33 @@ G_DEFINE_TYPE (GdmGreeterSession, gdm_gr
static gpointer session_object = NULL;
+static char *
+maybe_prepend_domain_to_user (GdmGreeterSession *session, const char *user)
+{
+ char *domain_and_user = NULL;
+ const char *separator;
+
+ separator = gdm_domain_provider_peek_separator (gdm_get_domain_provider ());
+
+ if (user) {
+ if (separator) {
+ /* The user string may already contain a domain, so we look for the
+ * separator and prepend ours only if it's not already there. */
+
+ if (session->priv->domain && !strstr (user, separator))
+ domain_and_user = g_strconcat (session->priv->domain,
+ separator,
+ user,
+ NULL);
+ }
+
+ if (!domain_and_user)
+ domain_and_user = g_strdup (user);
+ }
+
+ return domain_and_user;
+}
+
static void
on_info (GdmGreeterClient *client,
const char *text,
@@ -100,6 +134,10 @@ on_reset (GdmGreeterClient *client,
gdm_greeter_panel_reset (GDM_GREETER_PANEL (session->priv->panel));
gdm_greeter_login_window_reset (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window));
+
+ session->priv->n_info_queries = 0;
+ if (session->priv->panel)
+ gdm_greeter_panel_set_domain_enabled (GDM_GREETER_PANEL (session->priv->panel), TRUE);
}
static void
@@ -187,6 +225,9 @@ on_secret_info_query (GdmGreeterClient
{
g_debug ("GdmGreeterSession: Secret info query: %s", text);
+ if (session->priv->panel)
+ gdm_greeter_panel_set_domain_enabled (GDM_GREETER_PANEL (session->priv->panel), FALSE);
+
gdm_greeter_login_window_secret_info_query (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), text);
}
@@ -211,8 +252,14 @@ on_begin_verification_for_user (GdmGreet
const char *username,
GdmGreeterSession *session)
{
+ char *domain_and_user;
+
+ domain_and_user = maybe_prepend_domain_to_user (session, username);
+
gdm_greeter_client_call_begin_verification_for_user (session->priv->client,
- username);
+ domain_and_user);
+
+ g_free (domain_and_user);
}
static void
@@ -220,8 +267,21 @@ on_query_answer (GdmGreeterLoginWindow *
const char *text,
GdmGreeterSession *session)
{
+ gchar *temp;
+
+ if (session->priv->n_info_queries == 0)
+ temp = maybe_prepend_domain_to_user (session, text);
+ else
+ temp = g_strdup (text);
+
+ if (session->priv->panel)
+ gdm_greeter_panel_set_domain_enabled (GDM_GREETER_PANEL (session->priv->panel), FALSE);
+
gdm_greeter_client_call_answer_query (session->priv->client,
- text);
+ temp);
+
+ g_free (temp);
+ session->priv->n_info_queries++;
}
static void
@@ -249,6 +309,17 @@ on_select_layout (GdmGreeterSession
}
static void
+on_select_domain (GdmGreeterSession *session,
+ const char *text)
+{
+ g_free (session->priv->domain);
+ session->priv->domain = NULL;
+
+ if (text && strcmp (text, "__local") && strcmp (text, "__other"))
+ session->priv->domain = g_strdup (text);
+}
+
+static void
on_dialog_hidden (GdmGreeterSession *session)
{
gtk_window_present (GTK_WINDOW (session->priv->login_window));
@@ -259,9 +330,21 @@ on_select_user (GdmGreeterLoginWindow *l
const char *text,
GdmGreeterSession *session)
{
- show_or_hide_user_options (session, text);
+ char *domain_and_user;
+
+ g_free (session->priv->user);
+ session->priv->user = NULL;
+
+ if (text)
+ session->priv->user = g_strdup (text);
+
+ domain_and_user = maybe_prepend_domain_to_user (session, text);
+
+ show_or_hide_user_options (session, domain_and_user);
gdm_greeter_client_call_select_user (session->priv->client,
- text);
+ domain_and_user);
+
+ g_free (domain_and_user);
}
static void
@@ -270,6 +353,10 @@ on_cancelled (GdmGreeterLoginWindow *log
{
gdm_greeter_panel_hide_user_options (GDM_GREETER_PANEL (session->priv->panel));
gdm_greeter_client_call_cancel (session->priv->client);
+
+ session->priv->n_info_queries = 0;
+ if (session->priv->panel)
+ gdm_greeter_panel_set_domain_enabled (GDM_GREETER_PANEL (session->priv->panel), TRUE);
}
static void
@@ -358,6 +445,11 @@ toggle_panel (GdmGreeterSession *session
session);
g_signal_connect_swapped (session->priv->panel,
+ "domain-selected",
+ G_CALLBACK (on_select_domain),
+ session);
+
+ g_signal_connect_swapped (session->priv->panel,
"dialog-hidden",
G_CALLBACK (on_dialog_hidden),
session);
@@ -604,6 +696,8 @@ gdm_greeter_session_init (GdmGreeterSess
G_CALLBACK (on_user_authorized),
session);
+ session->priv->n_info_queries = 0;
+
/* We want to listen for panel mnemonics even if the
* login window is focused, so we intercept them here.
*/
@@ -625,6 +719,9 @@ gdm_greeter_session_finalize (GObject *o
g_return_if_fail (greeter_session->priv != NULL);
+ g_free (greeter_session->priv->user);
+ g_free (greeter_session->priv->domain);
+
G_OBJECT_CLASS (gdm_greeter_session_parent_class)->finalize (object);
}
Index: gdm-2.29.5/gui/simple-greeter/gdm-simple-greeter.schemas.in
===================================================================
--- gdm-2.29.5.orig/gui/simple-greeter/gdm-simple-greeter.schemas.in
+++ gdm-2.29.5/gui/simple-greeter/gdm-simple-greeter.schemas.in
@@ -91,6 +91,18 @@
</locale>
</schema>
<schema>
+ <key>/schemas/apps/gdm/simple-greeter/recent-domains</key>
+ <applyto>/apps/gdm/simple-greeter/recent-domains</applyto>
+ <owner>gdm-simple-greeter</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default>[]</default>
+ <locale name="C">
+ <short>Recently selected domains</short>
+ <long>Set to a list of login domains to be shown by default at the login window.</long>
+ </locale>
+ </schema>
+ <schema>
<key>/schemas/apps/gdm/simple-greeter/wm_use_compiz</key>
<applyto>/apps/gdm/simple-greeter/wm_use_compiz</applyto>
<owner>gdm-simple-greeter</owner>
Index: gdm-2.29.5/po/POTFILES.in
===================================================================
--- gdm-2.29.5.orig/po/POTFILES.in
+++ gdm-2.29.5/po/POTFILES.in
@@ -64,6 +64,9 @@ gui/simple-chooser/gdm-host-chooser-widg
gui/simple-greeter/gdm-cell-renderer-timer.c
gui/simple-greeter/gdm-chooser-widget.c
gui/simple-greeter/gdm-clock-widget.c
+gui/simple-greeter/gdm-domain-chooser-dialog.c
+gui/simple-greeter/gdm-domain-chooser-widget.c
+gui/simple-greeter/gdm-domain-option-widget.c
gui/simple-greeter/gdm-greeter-login-window.c
gui/simple-greeter/gdm-greeter-login-window.c
[type: gettext/glade]gui/simple-greeter/gdm-greeter-login-window.ui
Index: gdm-2.29.5/common/gdm-settings-keys.h
===================================================================
--- gdm-2.29.5.orig/common/gdm-settings-keys.h
+++ gdm-2.29.5/common/gdm-settings-keys.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
#define GDM_KEY_DEBUG "debug/Enable"
+#define GDM_KEY_SUSE_SHOW_DOMAIN "greeter/SUSEShowDomain"
#define GDM_KEY_INCLUDE "greeter/Include"
#define GDM_KEY_EXCLUDE "greeter/Exclude"
#define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll"
Index: gdm-2.29.5/common/gdm-settings-system-backend.c
===================================================================
--- gdm-2.29.5.orig/common/gdm-settings-system-backend.c
+++ gdm-2.29.5/common/gdm-settings-system-backend.c
@@ -44,11 +44,11 @@
#define SYSCONFIG_AUTOLOGIN_KEY "DISPLAYMANAGER_AUTOLOGIN"
#define SYSCONFIG_TCP_OPEN_KEY "DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN"
#define SYSCONFIG_XDMCP_KEY "DISPLAYMANAGER_REMOTE_ACCESS"
+#define SYSCONFIG_AD_KEY "DISPLAYMANAGER_AD_INTEGRATION"
/* Keys from sysconfig that have no equivalent in GDM:
* - DISPLAYMANAGER_ROOT_LOGIN_REMOTE
* - DISPLAYMANAGER_STARTS_XSERVER (we always have a local display manager,
* see gdm_manager_constructor())
- * - DISPLAYMANAGER_AD_INTEGRATION
* - DISPLAYMANAGER_SHUTDOWN (handled by ConsoleKit)
*/
@@ -65,12 +65,14 @@ struct GdmSettingsSystemBackendPrivate
gboolean dirty_autologin_user;
gboolean dirty_tcp_open;
gboolean dirty_xdmcp;
+ gboolean dirty_show_domain;
gchar *set_autologin_user;
gboolean set_autologin_enabled;
gboolean set_tcp_open;
gboolean set_xdmcp;
+ gboolean set_show_domain;
};
static void gdm_settings_system_backend_class_init (GdmSettingsSystemBackendClass *klass);
@@ -140,6 +142,16 @@ gdm_settings_system_backend_get_value (G
val = g_strdup (xdmcp ? "true" : "false");
}
}
+ } else if (!strcasecmp (key, GDM_KEY_SUSE_SHOW_DOMAIN)) {
+ if (priv->dirty_show_domain) {
+ val = g_strdup (priv->set_show_domain ? "true" : "false");
+ } else {
+ gboolean show_domain;
+
+ if (gdm_sysconfig_get_value_boolean ((const gchar **) priv->lines, SYSCONFIG_AD_KEY, &show_domain)) {
+ val = g_strdup (show_domain ? "true" : "false");
+ }
+ }
} else {
g_set_error (error, GDM_SETTINGS_BACKEND_ERROR, GDM_SETTINGS_BACKEND_ERROR_KEY_NOT_FOUND, "Key not found");
goto out;
@@ -200,6 +212,12 @@ save_settings (GdmSettingsSystemBackend
backend->priv->set_xdmcp ? "yes" : "no");
}
+ if (backend->priv->dirty_show_domain) {
+ if (!gdm_sysconfig_set_value_boolean (backend->priv->lines, SYSCONFIG_AD_KEY, backend->priv->set_show_domain))
+ g_warning ("Unable to set key %s to '%s'.", SYSCONFIG_AD_KEY,
+ backend->priv->set_show_domain ? "yes" : "no");
+ }
+
if (!gdm_sysconfig_save_file (backend->priv->filename, backend->priv->lines))
g_warning ("Unable to save settings to %s.", backend->priv->filename);
@@ -208,6 +226,7 @@ save_settings (GdmSettingsSystemBackend
backend->priv->dirty_autologin_user = FALSE;
backend->priv->dirty_tcp_open = FALSE;
backend->priv->dirty_xdmcp = FALSE;
+ backend->priv->dirty_show_domain = FALSE;
}
static gboolean
@@ -275,6 +294,9 @@ gdm_settings_system_backend_set_value (G
} else if (!strcasecmp (key, GDM_KEY_XDMCP_ENABLE)) {
priv->set_xdmcp = value_to_boolean (value);
GDM_SETTINGS_SYSTEM_BACKEND (backend)->priv->dirty_xdmcp = TRUE;
+ } else if (!strcasecmp (key, GDM_KEY_SUSE_SHOW_DOMAIN)) {
+ priv->set_show_domain = value_to_boolean (value);
+ GDM_SETTINGS_SYSTEM_BACKEND (backend)->priv->dirty_show_domain = TRUE;
} else {
g_set_error (error, GDM_SETTINGS_BACKEND_ERROR, GDM_SETTINGS_BACKEND_ERROR_KEY_NOT_FOUND, "Key not found");
return FALSE;
Index: gdm-2.29.5/data/gdm.schemas.in.in
===================================================================
--- gdm-2.29.5.orig/data/gdm.schemas.in.in
+++ gdm-2.29.5/data/gdm.schemas.in.in
@@ -61,6 +61,12 @@
</schema>
<schema>
+ <!-- SUSE-specific -->
+ <key>greeter/SUSEShowDomain</key>
+ <signature>b</signature>
+ <default>false</default>
+ </schema>
+ <schema>
<key>greeter/Include</key>
<signature>s</signature>
<default></default>