From a244bd9196484e824cdd93a9733df46607924d53 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 15 Aug 2016 12:53:31 -0400 Subject: build-goo: get rid of gui directory It only has the chooser in it, so just move the chooser to the toplevel. --- Makefile.am | 2 +- chooser/Makefile.am | 71 +++ chooser/chooser-main.c | 250 ++++++++ chooser/gdm-chooser-host.c | 258 ++++++++ chooser/gdm-chooser-host.h | 63 ++ chooser/gdm-chooser-session.c | 342 +++++++++++ chooser/gdm-chooser-session.h | 58 ++ chooser/gdm-host-chooser-dialog.c | 223 +++++++ chooser/gdm-host-chooser-dialog.h | 60 ++ chooser/gdm-host-chooser-widget.c | 860 +++++++++++++++++++++++++++ chooser/gdm-host-chooser-widget.h | 65 ++ chooser/gdm-host-chooser.c | 252 ++++++++ configure.ac | 3 +- gui/Makefile.am | 12 - gui/simple-chooser/Makefile.am | 71 --- gui/simple-chooser/chooser-main.c | 250 -------- gui/simple-chooser/gdm-chooser-host.c | 258 -------- gui/simple-chooser/gdm-chooser-host.h | 63 -- gui/simple-chooser/gdm-chooser-session.c | 342 ----------- gui/simple-chooser/gdm-chooser-session.h | 58 -- gui/simple-chooser/gdm-host-chooser-dialog.c | 223 ------- gui/simple-chooser/gdm-host-chooser-dialog.h | 60 -- gui/simple-chooser/gdm-host-chooser-widget.c | 860 --------------------------- gui/simple-chooser/gdm-host-chooser-widget.h | 65 -- gui/simple-chooser/gdm-host-chooser.c | 252 -------- 25 files changed, 2504 insertions(+), 2517 deletions(-) create mode 100644 chooser/Makefile.am create mode 100644 chooser/chooser-main.c create mode 100644 chooser/gdm-chooser-host.c create mode 100644 chooser/gdm-chooser-host.h create mode 100644 chooser/gdm-chooser-session.c create mode 100644 chooser/gdm-chooser-session.h create mode 100644 chooser/gdm-host-chooser-dialog.c create mode 100644 chooser/gdm-host-chooser-dialog.h create mode 100644 chooser/gdm-host-chooser-widget.c create mode 100644 chooser/gdm-host-chooser-widget.h create mode 100644 chooser/gdm-host-chooser.c delete mode 100644 gui/Makefile.am delete mode 100644 gui/simple-chooser/Makefile.am delete mode 100644 gui/simple-chooser/chooser-main.c delete mode 100644 gui/simple-chooser/gdm-chooser-host.c delete mode 100644 gui/simple-chooser/gdm-chooser-host.h delete mode 100644 gui/simple-chooser/gdm-chooser-session.c delete mode 100644 gui/simple-chooser/gdm-chooser-session.h delete mode 100644 gui/simple-chooser/gdm-host-chooser-dialog.c delete mode 100644 gui/simple-chooser/gdm-host-chooser-dialog.h delete mode 100644 gui/simple-chooser/gdm-host-chooser-widget.c delete mode 100644 gui/simple-chooser/gdm-host-chooser-widget.h delete mode 100644 gui/simple-chooser/gdm-host-chooser.c diff --git a/Makefile.am b/Makefile.am index 561d695f..7fcfd2b2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ SUBDIRS = \ common \ daemon \ libgdm \ - gui \ + chooser \ utils \ po \ tests \ diff --git a/chooser/Makefile.am b/chooser/Makefile.am new file mode 100644 index 00000000..b649d38b --- /dev/null +++ b/chooser/Makefile.am @@ -0,0 +1,71 @@ +NULL = + +AM_CPPFLAGS = \ + -I$(top_srcdir)/common \ + -I$(top_srcdir)/libgdm \ + -I$(top_builddir)/libgdm \ + -DDATADIR=\""$(datadir)"\" \ + -DGDMCONFDIR=\"$(gdmconfdir)\" \ + -DDMCONFDIR=\""$(dmconfdir)"\" \ + -DGDMLOCALEDIR=\""$(gdmlocaledir)"\" \ + -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ + -DLIBEXECDIR=\""$(libexecdir)"\" \ + -DSBINDIR=\""$(sbindir)"\" \ + -DPIXMAPDIR=\""$(pixmapdir)"\" \ + -DAT_SPI_REGISTRYD_DIR="\"$(AT_SPI_REGISTRYD_DIR)\"" \ + -DGNOME_SETTINGS_DAEMON_DIR="\"$(GNOME_SETTINGS_DAEMON_DIR)\"" \ + $(GTK_CFLAGS) \ + $(XLIB_CFLAGS) \ + $(XDMCP_CFLAGS) \ + $(EXTRA_CHOOSER_CFLAGS) \ + $(SIMPLE_CHOOSER_CFLAGS) \ + $(NULL) + +libexec_PROGRAMS = \ + gdm-simple-chooser \ + gdm-host-chooser \ + $(NULL) + +gdm_simple_chooser_SOURCES = \ + chooser-main.c \ + gdm-chooser-host.c \ + gdm-chooser-host.h \ + gdm-host-chooser-widget.c \ + gdm-host-chooser-widget.h \ + gdm-host-chooser-dialog.c \ + gdm-host-chooser-dialog.h \ + gdm-chooser-session.c \ + gdm-chooser-session.h \ + $(NULL) + +gdm_simple_chooser_LDADD = \ + $(top_builddir)/common/libgdmcommon.la \ + $(top_builddir)/libgdm/libgdm.la \ + $(GTK_LIBS) \ + $(EXTRA_CHOOSER_LIBS) \ + $(SIMPLE_CHOOSER_LIBS) \ + $(XLIB_LIBS) \ + $(XDMCP_LIBS) \ + $(NULL) + +gdm_host_chooser_SOURCES = \ + gdm-host-chooser.c \ + gdm-chooser-host.c \ + gdm-chooser-host.h \ + gdm-host-chooser-widget.c \ + gdm-host-chooser-widget.h \ + gdm-host-chooser-dialog.c \ + gdm-host-chooser-dialog.h \ + $(NULL) + +gdm_host_chooser_LDADD = \ + $(top_builddir)/common/libgdmcommon.la \ + $(GTK_LIBS) \ + $(EXTRA_CHOOSER_LIBS) \ + $(SIMPLE_CHOOSER_LIBS) \ + $(XLIB_LIBS) \ + $(XDMCP_LIBS) \ + $(NULL) + +EXTRA_DIST = \ + $(NULL) diff --git a/chooser/chooser-main.c b/chooser/chooser-main.c new file mode 100644 index 00000000..54aebf17 --- /dev/null +++ b/chooser/chooser-main.c @@ -0,0 +1,250 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "gdm-common.h" +#include "gdm-log.h" + +#include "gdm-chooser-session.h" + +#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility" + +static Atom AT_SPI_IOR; + + +static gboolean +assistive_registry_launch (void) +{ + GPid pid; + GError *error; + const char *command; + char **argv; + gboolean res; + + command = AT_SPI_REGISTRYD_DIR "/at-spi-registryd"; + + argv = NULL; + error = NULL; + res = g_shell_parse_argv (command, NULL, &argv, &error); + if (! res) { + g_warning ("Unable to parse command: %s", error->message); + return FALSE; + } + + error = NULL; + res = g_spawn_async (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH + | G_SPAWN_STDOUT_TO_DEV_NULL + | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, + NULL, + &pid, + &error); + g_strfreev (argv); + + if (! res) { + g_warning ("Unable to run command %s: %s", command, error->message); + return FALSE; + } + + if (kill (pid, 0) < 0) { + g_warning ("at-spi-registryd not running"); + return FALSE; + } + + return TRUE; +} + +static GdkFilterReturn +filter_watch (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + XEvent *xev = (XEvent *)xevent; + + if (xev->xany.type == PropertyNotify + && xev->xproperty.atom == AT_SPI_IOR) { + gtk_main_quit (); + + return GDK_FILTER_REMOVE; + } + + return GDK_FILTER_CONTINUE; +} + +static gboolean +filter_timeout (gpointer data) +{ + g_warning ("The accessibility registry was not found."); + + gtk_main_quit (); + + return FALSE; +} + +static void +assistive_registry_start (void) +{ + GdkWindow *root; + guint tid; + + root = gdk_get_default_root_window (); + + if ( ! AT_SPI_IOR) { + AT_SPI_IOR = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "AT_SPI_IOR", False); + } + + gdk_window_set_events (root, GDK_PROPERTY_CHANGE_MASK); + + if ( ! assistive_registry_launch ()) { + g_warning ("The accessibility registry could not be started."); + return; + } + + gdk_window_add_filter (root, filter_watch, NULL); + tid = g_timeout_add_seconds (5, filter_timeout, NULL); + + gtk_main (); + + gdk_window_remove_filter (root, filter_watch, NULL); + g_source_remove (tid); +} + +static void +at_set_gtk_modules (void) +{ + GSList *modules_list; + GSList *l; + const char *old; + char **modules; + gboolean found_gail; + gboolean found_atk_bridge; + int n; + + n = 0; + modules_list = NULL; + found_gail = FALSE; + found_atk_bridge = FALSE; + + if ((old = g_getenv ("GTK_MODULES")) != NULL) { + modules = g_strsplit (old, ":", -1); + for (n = 0; modules[n]; n++) { + if (!strcmp (modules[n], "gail")) { + found_gail = TRUE; + } else if (!strcmp (modules[n], "atk-bridge")) { + found_atk_bridge = TRUE; + } + + modules_list = g_slist_prepend (modules_list, modules[n]); + modules[n] = NULL; + } + g_free (modules); + } + + if (!found_gail) { + modules_list = g_slist_prepend (modules_list, "gail"); + ++n; + } + + if (!found_atk_bridge) { + modules_list = g_slist_prepend (modules_list, "atk-bridge"); + ++n; + } + + modules = g_new (char *, n + 1); + modules[n--] = NULL; + for (l = modules_list; l; l = l->next) { + modules[n--] = g_strdup (l->data); + } + + g_setenv ("GTK_MODULES", g_strjoinv (":", modules), TRUE); + g_strfreev (modules); + g_slist_free (modules_list); +} + +static void +load_a11y (void) +{ + assistive_registry_start (); + at_set_gtk_modules (); +} + +int +main (int argc, char *argv[]) +{ + GdmChooserSession *session; + gboolean res; + GError *error; + + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + setlocale (LC_ALL, ""); + + gdm_log_init (); + gdm_log_set_debug (TRUE); + + g_debug ("Chooser for display %s xauthority:%s", + g_getenv ("DISPLAY"), + g_getenv ("XAUTHORITY")); + + gdk_init (&argc, &argv); + + load_a11y (); + + gtk_init (&argc, &argv); + + session = gdm_chooser_session_new (); + if (session == NULL) { + g_critical ("Unable to create chooser session"); + exit (1); + } + + error = NULL; + res = gdm_chooser_session_start (session, &error); + if (! res) { + g_warning ("Unable to start chooser session: %s", error->message); + g_error_free (error); + exit (1); + } + + gtk_main (); + + if (session != NULL) { + g_object_unref (session); + } + + return 0; +} diff --git a/chooser/gdm-chooser-host.c b/chooser/gdm-chooser-host.c new file mode 100644 index 00000000..5b76f652 --- /dev/null +++ b/chooser/gdm-chooser-host.c @@ -0,0 +1,258 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "gdm-address.h" +#include "gdm-chooser-host.h" + +#define GDM_CHOOSER_HOST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_CHOOSER_HOST, GdmChooserHostPrivate)) + +struct GdmChooserHostPrivate +{ + GdmAddress *address; + char *description; + GdmChooserHostKind kind; + gboolean willing; +}; + +enum { + PROP_0, + PROP_ADDRESS, + PROP_DESCRIPTION, + PROP_KIND, + PROP_WILLING, +}; + +static void gdm_chooser_host_class_init (GdmChooserHostClass *klass); +static void gdm_chooser_host_init (GdmChooserHost *chooser_host); +static void gdm_chooser_host_finalize (GObject *object); + +G_DEFINE_TYPE (GdmChooserHost, gdm_chooser_host, G_TYPE_OBJECT) + +GdmAddress * +gdm_chooser_host_get_address (GdmChooserHost *host) +{ + g_return_val_if_fail (GDM_IS_CHOOSER_HOST (host), NULL); + + return host->priv->address; +} + +G_CONST_RETURN char * +gdm_chooser_host_get_description (GdmChooserHost *host) +{ + g_return_val_if_fail (GDM_IS_CHOOSER_HOST (host), NULL); + + return host->priv->description; +} + +GdmChooserHostKind +gdm_chooser_host_get_kind (GdmChooserHost *host) +{ + g_return_val_if_fail (GDM_IS_CHOOSER_HOST (host), 0); + + return host->priv->kind; +} + +gboolean +gdm_chooser_host_get_willing (GdmChooserHost *host) +{ + g_return_val_if_fail (GDM_IS_CHOOSER_HOST (host), FALSE); + + return host->priv->willing; +} + +static void +_gdm_chooser_host_set_address (GdmChooserHost *host, + GdmAddress *address) +{ + if (host->priv->address != NULL) { + gdm_address_free (host->priv->address); + } + + g_assert (address != NULL); + + gdm_address_debug (address); + host->priv->address = gdm_address_copy (address); +} + +static void +_gdm_chooser_host_set_description (GdmChooserHost *host, + const char *description) +{ + g_free (host->priv->description); + host->priv->description = g_strdup (description); +} + +static void +_gdm_chooser_host_set_kind (GdmChooserHost *host, + int kind) +{ + if (host->priv->kind != kind) { + host->priv->kind = kind; + } +} + +static void +_gdm_chooser_host_set_willing (GdmChooserHost *host, + gboolean willing) +{ + if (host->priv->willing != willing) { + host->priv->willing = willing; + } +} + +static void +gdm_chooser_host_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + GdmChooserHost *host; + + host = GDM_CHOOSER_HOST (object); + + switch (param_id) { + case PROP_ADDRESS: + _gdm_chooser_host_set_address (host, g_value_get_boxed (value)); + break; + case PROP_DESCRIPTION: + _gdm_chooser_host_set_description (host, g_value_get_string (value)); + break; + case PROP_KIND: + _gdm_chooser_host_set_kind (host, g_value_get_int (value)); + break; + case PROP_WILLING: + _gdm_chooser_host_set_willing (host, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +gdm_chooser_host_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + GdmChooserHost *host; + + host = GDM_CHOOSER_HOST (object); + + switch (param_id) { + case PROP_ADDRESS: + g_value_set_boxed (value, host->priv->address); + break; + case PROP_DESCRIPTION: + g_value_set_string (value, host->priv->description); + break; + case PROP_KIND: + g_value_set_int (value, host->priv->kind); + break; + case PROP_WILLING: + g_value_set_boolean (value, host->priv->willing); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +gdm_chooser_host_class_init (GdmChooserHostClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gdm_chooser_host_set_property; + object_class->get_property = gdm_chooser_host_get_property; + object_class->finalize = gdm_chooser_host_finalize; + + + g_object_class_install_property (object_class, + PROP_ADDRESS, + g_param_spec_boxed ("address", + "address", + "address", + GDM_TYPE_ADDRESS, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_DESCRIPTION, + g_param_spec_string ("description", + "description", + "description", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, + PROP_KIND, + g_param_spec_int ("kind", + "kind", + "kind", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_WILLING, + g_param_spec_boolean ("willing", + "willing", + "willing", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + + g_type_class_add_private (klass, sizeof (GdmChooserHostPrivate)); +} + +static void +gdm_chooser_host_init (GdmChooserHost *widget) +{ + widget->priv = GDM_CHOOSER_HOST_GET_PRIVATE (widget); +} + +static void +gdm_chooser_host_finalize (GObject *object) +{ + GdmChooserHost *host; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_CHOOSER_HOST (object)); + + host = GDM_CHOOSER_HOST (object); + + g_return_if_fail (host->priv != NULL); + + g_free (host->priv->description); + gdm_address_free (host->priv->address); + + G_OBJECT_CLASS (gdm_chooser_host_parent_class)->finalize (object); +} diff --git a/chooser/gdm-chooser-host.h b/chooser/gdm-chooser-host.h new file mode 100644 index 00000000..fda6e9f9 --- /dev/null +++ b/chooser/gdm-chooser-host.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __GDM_CHOOSER_HOST__ +#define __GDM_CHOOSER_HOST__ + +#include +#include "gdm-address.h" + +G_BEGIN_DECLS + +#define GDM_TYPE_CHOOSER_HOST (gdm_chooser_host_get_type ()) +#define GDM_CHOOSER_HOST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_CHOOSER_HOST, GdmChooserHost)) +#define GDM_CHOOSER_HOST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_CHOOSER_HOST, GdmChooserHostClass)) +#define GDM_IS_CHOOSER_HOST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_CHOOSER_HOST)) +#define GDM_IS_CHOOSER_HOST_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_CHOOSER_HOST)) +#define GDM_CHOOSER_HOST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_CHOOSER_HOST, GdmChooserHostClass)) + +typedef enum { + GDM_CHOOSER_HOST_KIND_XDMCP = 1 << 0, +} GdmChooserHostKind; + +#define GDM_CHOOSER_HOST_KIND_MASK_ALL (GDM_CHOOSER_HOST_KIND_XDMCP) + +typedef struct GdmChooserHostPrivate GdmChooserHostPrivate; + +typedef struct +{ + GObject parent; + GdmChooserHostPrivate *priv; +} GdmChooserHost; + +typedef struct +{ + GObjectClass parent_class; +} GdmChooserHostClass; + +GType gdm_chooser_host_get_type (void) G_GNUC_CONST; + +G_CONST_RETURN char *gdm_chooser_host_get_description (GdmChooserHost *chooser_host); +GdmAddress * gdm_chooser_host_get_address (GdmChooserHost *chooser_host); +gboolean gdm_chooser_host_get_willing (GdmChooserHost *chooser_host); +GdmChooserHostKind gdm_chooser_host_get_kind (GdmChooserHost *chooser_host); + +G_END_DECLS + +#endif diff --git a/chooser/gdm-chooser-session.c b/chooser/gdm-chooser-session.c new file mode 100644 index 00000000..dd618b8a --- /dev/null +++ b/chooser/gdm-chooser-session.c @@ -0,0 +1,342 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "gdm-chooser-session.h" +#include "gdm-client.h" + +#include "gdm-host-chooser-dialog.h" + +#define GDM_CHOOSER_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_CHOOSER_SESSION, GdmChooserSessionPrivate)) + +struct GdmChooserSessionPrivate +{ + GdmClient *client; + GdmRemoteGreeter *remote_greeter; + GdmChooser *chooser; + GtkWidget *chooser_dialog; +}; + +enum { + PROP_0, +}; + +static void gdm_chooser_session_class_init (GdmChooserSessionClass *klass); +static void gdm_chooser_session_init (GdmChooserSession *chooser_session); +static void gdm_chooser_session_finalize (GObject *object); + +G_DEFINE_TYPE (GdmChooserSession, gdm_chooser_session, G_TYPE_OBJECT) + +static gpointer session_object = NULL; + +static gboolean +launch_compiz (GdmChooserSession *session) +{ + GError *error; + gboolean ret; + + g_debug ("GdmChooserSession: Launching compiz"); + + ret = FALSE; + + error = NULL; + g_spawn_command_line_async ("gtk-window-decorator --replace", &error); + if (error != NULL) { + g_warning ("Error starting WM: %s", error->message); + g_error_free (error); + goto out; + } + + error = NULL; + g_spawn_command_line_async ("compiz --replace", &error); + if (error != NULL) { + g_warning ("Error starting WM: %s", error->message); + g_error_free (error); + goto out; + } + + ret = TRUE; + + /* FIXME: should try to detect if it actually works */ + + out: + return ret; +} + +static gboolean +launch_metacity (GdmChooserSession *session) +{ + GError *error; + gboolean ret; + + g_debug ("GdmChooserSession: Launching metacity"); + + ret = FALSE; + + error = NULL; + g_spawn_command_line_async ("metacity --replace", &error); + if (error != NULL) { + g_warning ("Error starting WM: %s", error->message); + g_error_free (error); + goto out; + } + + ret = TRUE; + + out: + return ret; +} + +static void +start_window_manager (GdmChooserSession *session) +{ + if (! launch_metacity (session)) { + launch_compiz (session); + } +} + +static gboolean +start_settings_daemon (GdmChooserSession *session) +{ + GError *error; + gboolean ret; + + g_debug ("GdmChooserSession: Launching settings daemon"); + + ret = FALSE; + + error = NULL; + g_spawn_command_line_async (GNOME_SETTINGS_DAEMON_DIR "/gnome-settings-daemon", &error); + if (error != NULL) { + g_warning ("Error starting settings daemon: %s", error->message); + g_error_free (error); + goto out; + } + + ret = TRUE; + + out: + return ret; +} + +static void +on_dialog_response (GtkDialog *dialog, + int response_id, + GdmChooserSession *session) +{ + GdmChooserHost *host; + GError *error = NULL; + + host = NULL; + switch (response_id) { + case GTK_RESPONSE_OK: + host = gdm_host_chooser_dialog_get_host (GDM_HOST_CHOOSER_DIALOG (dialog)); + case GTK_RESPONSE_NONE: + /* delete event */ + default: + break; + } + + if (host != NULL) { + char *hostname; + + /* only support XDMCP hosts in remote chooser */ + g_assert (gdm_chooser_host_get_kind (host) == GDM_CHOOSER_HOST_KIND_XDMCP); + + hostname = NULL; + gdm_address_get_hostname (gdm_chooser_host_get_address (host), &hostname); + /* FIXME: fall back to numerical address? */ + if (hostname != NULL) { + g_debug ("GdmChooserSession: Selected hostname '%s'", hostname); + gdm_chooser_call_select_hostname_sync (session->priv->chooser, + hostname, + NULL, + &error); + + if (error != NULL) { + g_debug ("GdmChooserSession: %s", error->message); + g_clear_error (&error); + } + g_free (hostname); + } + } + + gdm_remote_greeter_call_disconnect_sync (session->priv->remote_greeter, + NULL, + &error); + if (error != NULL) { + g_debug ("GdmChooserSession: disconnect failed: %s", error->message); + } +} + +gboolean +gdm_chooser_session_start (GdmChooserSession *session, + GError **error) +{ + g_return_val_if_fail (GDM_IS_CHOOSER_SESSION (session), FALSE); + + session->priv->remote_greeter = gdm_client_get_remote_greeter_sync (session->priv->client, + NULL, + error); + if (session->priv->remote_greeter == NULL) { + return FALSE; + } + + session->priv->chooser = gdm_client_get_chooser_sync (session->priv->client, + NULL, + error); + if (session->priv->chooser == NULL) { + return FALSE; + } + + start_settings_daemon (session); + start_window_manager (session); + + /* Only support XDMCP on remote choosers */ + session->priv->chooser_dialog = gdm_host_chooser_dialog_new (GDM_CHOOSER_HOST_KIND_XDMCP); + g_signal_connect (session->priv->chooser_dialog, + "response", + G_CALLBACK (on_dialog_response), + session); + gtk_widget_show (session->priv->chooser_dialog); + + return TRUE; +} + +void +gdm_chooser_session_stop (GdmChooserSession *session) +{ + g_return_if_fail (GDM_IS_CHOOSER_SESSION (session)); + +} + +static void +gdm_chooser_session_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_chooser_session_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gdm_chooser_session_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GdmChooserSession *chooser_session; + + chooser_session = GDM_CHOOSER_SESSION (G_OBJECT_CLASS (gdm_chooser_session_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (chooser_session); +} + +static void +gdm_chooser_session_dispose (GObject *object) +{ + g_debug ("GdmChooserSession: Disposing chooser_session"); + + G_OBJECT_CLASS (gdm_chooser_session_parent_class)->dispose (object); +} + +static void +gdm_chooser_session_class_init (GdmChooserSessionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gdm_chooser_session_get_property; + object_class->set_property = gdm_chooser_session_set_property; + object_class->constructor = gdm_chooser_session_constructor; + object_class->dispose = gdm_chooser_session_dispose; + object_class->finalize = gdm_chooser_session_finalize; + + g_type_class_add_private (klass, sizeof (GdmChooserSessionPrivate)); +} + +static void +gdm_chooser_session_init (GdmChooserSession *session) +{ + + session->priv = GDM_CHOOSER_SESSION_GET_PRIVATE (session); + + session->priv->client = gdm_client_new (); +} + +static void +gdm_chooser_session_finalize (GObject *object) +{ + GdmChooserSession *chooser_session; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_CHOOSER_SESSION (object)); + + chooser_session = GDM_CHOOSER_SESSION (object); + + g_return_if_fail (chooser_session->priv != NULL); + + g_clear_object (&chooser_session->priv->chooser); + g_clear_object (&chooser_session->priv->remote_greeter); + g_clear_object (&chooser_session->priv->client); + + G_OBJECT_CLASS (gdm_chooser_session_parent_class)->finalize (object); +} + +GdmChooserSession * +gdm_chooser_session_new (void) +{ + if (session_object != NULL) { + g_object_ref (session_object); + } else { + session_object = g_object_new (GDM_TYPE_CHOOSER_SESSION, NULL); + g_object_add_weak_pointer (session_object, + (gpointer *) &session_object); + } + + return GDM_CHOOSER_SESSION (session_object); +} diff --git a/chooser/gdm-chooser-session.h b/chooser/gdm-chooser-session.h new file mode 100644 index 00000000..b6d8ccdf --- /dev/null +++ b/chooser/gdm-chooser-session.h @@ -0,0 +1,58 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __GDM_CHOOSER_SESSION_H +#define __GDM_CHOOSER_SESSION_H + +#include + +G_BEGIN_DECLS + +#define GDM_TYPE_CHOOSER_SESSION (gdm_chooser_session_get_type ()) +#define GDM_CHOOSER_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_CHOOSER_SESSION, GdmChooserSession)) +#define GDM_CHOOSER_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_CHOOSER_SESSION, GdmChooserSessionClass)) +#define GDM_IS_CHOOSER_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_CHOOSER_SESSION)) +#define GDM_IS_CHOOSER_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_CHOOSER_SESSION)) +#define GDM_CHOOSER_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_CHOOSER_SESSION, GdmChooserSessionClass)) + +typedef struct GdmChooserSessionPrivate GdmChooserSessionPrivate; + +typedef struct +{ + GObject parent; + GdmChooserSessionPrivate *priv; +} GdmChooserSession; + +typedef struct +{ + GObjectClass parent_class; +} GdmChooserSessionClass; + +GType gdm_chooser_session_get_type (void); + +GdmChooserSession * gdm_chooser_session_new (void); + +gboolean gdm_chooser_session_start (GdmChooserSession *session, + GError **error); +void gdm_chooser_session_stop (GdmChooserSession *session); + +G_END_DECLS + +#endif /* __GDM_CHOOSER_SESSION_H */ diff --git a/chooser/gdm-host-chooser-dialog.c b/chooser/gdm-host-chooser-dialog.c new file mode 100644 index 00000000..02169502 --- /dev/null +++ b/chooser/gdm-host-chooser-dialog.c @@ -0,0 +1,223 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "gdm-host-chooser-dialog.h" +#include "gdm-host-chooser-widget.h" + +#define GDM_HOST_CHOOSER_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_HOST_CHOOSER_DIALOG, GdmHostChooserDialogPrivate)) + +struct GdmHostChooserDialogPrivate +{ + GtkWidget *chooser_widget; + int kind_mask; +}; + +enum { + PROP_0, + PROP_KIND_MASK, +}; + +static void gdm_host_chooser_dialog_class_init (GdmHostChooserDialogClass *klass); +static void gdm_host_chooser_dialog_init (GdmHostChooserDialog *host_chooser_dialog); +static void gdm_host_chooser_dialog_finalize (GObject *object); + +G_DEFINE_TYPE (GdmHostChooserDialog, gdm_host_chooser_dialog, GTK_TYPE_DIALOG) + +GdmChooserHost * +gdm_host_chooser_dialog_get_host (GdmHostChooserDialog *dialog) +{ + GdmChooserHost *host; + + g_return_val_if_fail (GDM_IS_HOST_CHOOSER_DIALOG (dialog), NULL); + + host = gdm_host_chooser_widget_get_host (GDM_HOST_CHOOSER_WIDGET (dialog->priv->chooser_widget)); + + return host; +} + +static void +_gdm_host_chooser_dialog_set_kind_mask (GdmHostChooserDialog *dialog, + int kind_mask) +{ + if (dialog->priv->kind_mask != kind_mask) { + dialog->priv->kind_mask = kind_mask; + } +} + +static void +gdm_host_chooser_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdmHostChooserDialog *self; + + self = GDM_HOST_CHOOSER_DIALOG (object); + + switch (prop_id) { + case PROP_KIND_MASK: + _gdm_host_chooser_dialog_set_kind_mask (self, g_value_get_int (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_host_chooser_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +on_response (GdmHostChooserDialog *dialog, + gint response_id) +{ + switch (response_id) { + case GTK_RESPONSE_APPLY: + gdm_host_chooser_widget_refresh (GDM_HOST_CHOOSER_WIDGET (dialog->priv->chooser_widget)); + g_signal_stop_emission_by_name (dialog, "response"); + break; + default: + break; + } +} + +static GObject * +gdm_host_chooser_dialog_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GdmHostChooserDialog *dialog; + + dialog = GDM_HOST_CHOOSER_DIALOG (G_OBJECT_CLASS (gdm_host_chooser_dialog_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + + dialog->priv->chooser_widget = gdm_host_chooser_widget_new (dialog->priv->kind_mask); + gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), dialog->priv->chooser_widget); + gtk_container_set_border_width (GTK_CONTAINER (dialog->priv->chooser_widget), 5); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_REFRESH, GTK_RESPONSE_APPLY, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_CONNECT, GTK_RESPONSE_OK, + NULL); + + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); + gtk_window_set_title (GTK_WINDOW (dialog), _("Select System")); + gtk_window_set_icon_name (GTK_WINDOW (dialog), "computer"); + + g_signal_connect (dialog, + "response", + G_CALLBACK (on_response), + dialog); + + gtk_widget_show_all (GTK_WIDGET (dialog)); + + return G_OBJECT (dialog); +} + +static void +gdm_host_chooser_dialog_dispose (GObject *object) +{ + g_debug ("Disposing host_chooser_dialog"); + + G_OBJECT_CLASS (gdm_host_chooser_dialog_parent_class)->dispose (object); +} + +static void +gdm_host_chooser_dialog_class_init (GdmHostChooserDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gdm_host_chooser_dialog_get_property; + object_class->set_property = gdm_host_chooser_dialog_set_property; + object_class->constructor = gdm_host_chooser_dialog_constructor; + object_class->dispose = gdm_host_chooser_dialog_dispose; + object_class->finalize = gdm_host_chooser_dialog_finalize; + + g_object_class_install_property (object_class, + PROP_KIND_MASK, + g_param_spec_int ("kind-mask", + "kind mask", + "kind mask", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_type_class_add_private (klass, sizeof (GdmHostChooserDialogPrivate)); +} + +static void +gdm_host_chooser_dialog_init (GdmHostChooserDialog *dialog) +{ + dialog->priv = GDM_HOST_CHOOSER_DIALOG_GET_PRIVATE (dialog); +} + +static void +gdm_host_chooser_dialog_finalize (GObject *object) +{ + GdmHostChooserDialog *host_chooser_dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_HOST_CHOOSER_DIALOG (object)); + + host_chooser_dialog = GDM_HOST_CHOOSER_DIALOG (object); + + g_return_if_fail (host_chooser_dialog->priv != NULL); + + G_OBJECT_CLASS (gdm_host_chooser_dialog_parent_class)->finalize (object); +} + +GtkWidget * +gdm_host_chooser_dialog_new (int kind_mask) +{ + GObject *object; + + object = g_object_new (GDM_TYPE_HOST_CHOOSER_DIALOG, + "kind-mask", kind_mask, + NULL); + + return GTK_WIDGET (object); +} diff --git a/chooser/gdm-host-chooser-dialog.h b/chooser/gdm-host-chooser-dialog.h new file mode 100644 index 00000000..f413091b --- /dev/null +++ b/chooser/gdm-host-chooser-dialog.h @@ -0,0 +1,60 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __GDM_HOST_CHOOSER_DIALOG_H +#define __GDM_HOST_CHOOSER_DIALOG_H + +#include +#include +#include "gdm-chooser-host.h" + +G_BEGIN_DECLS + +#define GDM_TYPE_HOST_CHOOSER_DIALOG (gdm_host_chooser_dialog_get_type ()) +#define GDM_HOST_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_HOST_CHOOSER_DIALOG, GdmHostChooserDialog)) +#define GDM_HOST_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_HOST_CHOOSER_DIALOG, GdmHostChooserDialogClass)) +#define GDM_IS_HOST_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_HOST_CHOOSER_DIALOG)) +#define GDM_IS_HOST_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_HOST_CHOOSER_DIALOG)) +#define GDM_HOST_CHOOSER_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_HOST_CHOOSER_DIALOG, GdmHostChooserDialogClass)) + +typedef struct GdmHostChooserDialogPrivate GdmHostChooserDialogPrivate; + +typedef struct +{ + GtkDialog parent; + GdmHostChooserDialogPrivate *priv; +} GdmHostChooserDialog; + +typedef struct +{ + GtkDialogClass parent_class; +} GdmHostChooserDialogClass; + +GType gdm_host_chooser_dialog_get_type (void); + +GtkWidget * gdm_host_chooser_dialog_new (int kind_mask); +void gdm_host_chooser_dialog_set_kind_mask (GdmHostChooserDialog *dialog, + int kind_mask); + +GdmChooserHost * gdm_host_chooser_dialog_get_host (GdmHostChooserDialog *dialog); + +G_END_DECLS + +#endif /* __GDM_HOST_CHOOSER_DIALOG_H */ diff --git a/chooser/gdm-host-chooser-widget.c b/chooser/gdm-host-chooser-widget.c new file mode 100644 index 00000000..f9200aa0 --- /dev/null +++ b/chooser/gdm-host-chooser-widget.c @@ -0,0 +1,860 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 1998, 1999, 2000 Martin K, Petersen + * Copyright (C) 2007 William Jon McCann + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif + +#include +#include + +#include +#include +#include +#include + +#include "gdm-address.h" +#include "gdm-chooser-host.h" +#include "gdm-host-chooser-widget.h" + +#define GDM_HOST_CHOOSER_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_HOST_CHOOSER_WIDGET, GdmHostChooserWidgetPrivate)) + +struct GdmHostChooserWidgetPrivate +{ + GtkWidget *treeview; + + int kind_mask; + + char **hosts; + + XdmcpBuffer broadcast_buf; + XdmcpBuffer query_buf; + gboolean have_ipv6; + int socket_fd; + guint io_watch_id; + guint scan_time_id; + guint ping_try_id; + + int ping_tries; + + GSList *broadcast_addresses; + GSList *query_addresses; + GSList *chooser_hosts; + + GdmChooserHost *current_host; +}; + +enum { + PROP_0, + PROP_KIND_MASK, +}; + +enum { + HOST_ACTIVATED, + LAST_SIGNAL +}; + +static guint signals [LAST_SIGNAL] = { 0, }; + +static void gdm_host_chooser_widget_class_init (GdmHostChooserWidgetClass *klass); +static void gdm_host_chooser_widget_init (GdmHostChooserWidget *host_chooser_widget); +static void gdm_host_chooser_widget_finalize (GObject *object); + +G_DEFINE_TYPE (GdmHostChooserWidget, gdm_host_chooser_widget, GTK_TYPE_VBOX) + +#define GDM_XDMCP_PROTOCOL_VERSION 1001 +#define SCAN_TIMEOUT 30 +#define PING_TIMEOUT 2 +#define PING_TRIES 3 + +enum { + CHOOSER_LIST_ICON_COLUMN = 0, + CHOOSER_LIST_LABEL_COLUMN, + CHOOSER_LIST_HOST_COLUMN +}; + +static void +chooser_host_add (GdmHostChooserWidget *widget, + GdmChooserHost *host) +{ + widget->priv->chooser_hosts = g_slist_prepend (widget->priv->chooser_hosts, host); +} + +#if 0 +static void +chooser_host_remove (GdmHostChooserWidget *widget, + GdmChooserHost *host) +{ + widget->priv->chooser_hosts = g_slist_remove (widget->priv->chooser_hosts, host); +} +#endif + +static GdmChooserHost * +find_known_host (GdmHostChooserWidget *widget, + GdmAddress *address) +{ + GSList *li; + GdmChooserHost *host; + + for (li = widget->priv->chooser_hosts; li != NULL; li = li->next) { + host = li->data; + if (gdm_address_equal (gdm_chooser_host_get_address (host), address)) { + goto out; + } + } + + host = NULL; + out: + + return host; +} + +static void +browser_add_host (GdmHostChooserWidget *widget, + GdmChooserHost *host) +{ + char *hostname; + char *name; + char *desc; + char *label; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean res; + + g_assert (host != NULL); + + if (! gdm_chooser_host_get_willing (host)) { + gtk_widget_set_sensitive (GTK_WIDGET (widget), TRUE); + return; + } + + res = gdm_address_get_hostname (gdm_chooser_host_get_address (host), &hostname); + if (! res) { + gdm_address_get_numeric_info (gdm_chooser_host_get_address (host), &hostname, NULL); + } + + name = g_markup_escape_text (hostname, -1); + desc = g_markup_escape_text (gdm_chooser_host_get_description (host), -1); + label = g_strdup_printf ("%s\n%s", name, desc); + g_free (name); + g_free (desc); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget->priv->treeview)); + + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + gtk_list_store_set (GTK_LIST_STORE (model), + &iter, + CHOOSER_LIST_ICON_COLUMN, NULL, + CHOOSER_LIST_LABEL_COLUMN, label, + CHOOSER_LIST_HOST_COLUMN, host, + -1); + g_free (label); + +} + +static gboolean +decode_packet (GIOChannel *source, + GIOCondition condition, + GdmHostChooserWidget *widget) +{ + struct sockaddr_storage clnt_ss; + GdmAddress *address; + int ss_len; + XdmcpHeader header; + int res; + static XdmcpBuffer buf; + ARRAY8 auth = {0}; + ARRAY8 host = {0}; + ARRAY8 stat = {0}; + char *status; + GdmChooserHost *chooser_host; + + status = NULL; + address = NULL; + + g_debug ("decode_packet: GIOCondition %d", (int)condition); + + if ( ! (condition & G_IO_IN)) { + return TRUE; + } + + ss_len = (int) sizeof (clnt_ss); + + res = XdmcpFill (widget->priv->socket_fd, &buf, (XdmcpNetaddr)&clnt_ss, &ss_len); + if G_UNLIKELY (! res) { + g_debug (_("XDMCP: Could not create XDMCP buffer!")); + return TRUE; + } + + res = XdmcpReadHeader (&buf, &header); + if G_UNLIKELY (! res) { + g_warning (_("XDMCP: Could not read XDMCP header!")); + return TRUE; + } + + if G_UNLIKELY (header.version != XDM_PROTOCOL_VERSION && + header.version != GDM_XDMCP_PROTOCOL_VERSION) { + g_warning (_("XDMCP: Incorrect XDMCP version!")); + return TRUE; + } + + address = gdm_address_new_from_sockaddr ((struct sockaddr *) &clnt_ss, ss_len); + if (address == NULL) { + g_warning (_("XDMCP: Unable to parse address")); + return TRUE; + } + + gdm_address_debug (address); + + if (header.opcode == WILLING) { + if (! XdmcpReadARRAY8 (&buf, &auth)) { + goto done; + } + + if (! XdmcpReadARRAY8 (&buf, &host)) { + goto done; + } + + if (! XdmcpReadARRAY8 (&buf, &stat)) { + goto done; + } + + status = g_strndup ((char *) stat.data, MIN (stat.length, 256)); + } else if (header.opcode == UNWILLING) { + /* immaterial, will not be shown */ + status = NULL; + } else { + goto done; + } + + g_debug ("STATUS: %s", status); + + chooser_host = find_known_host (widget, address); + if (chooser_host == NULL) { + chooser_host = g_object_new (GDM_TYPE_CHOOSER_HOST, + "address", address, + "description", status, + "willing", (header.opcode == WILLING), + "kind", GDM_CHOOSER_HOST_KIND_XDMCP, + NULL); + chooser_host_add (widget, chooser_host); + browser_add_host (widget, chooser_host); + } else { + /* server changed it's mind */ + if (header.opcode == WILLING + && ! gdm_chooser_host_get_willing (chooser_host)) { + g_object_set (chooser_host, "willing", TRUE, NULL); + browser_add_host (widget, chooser_host); + } + /* FIXME: handle unwilling? */ + } + + done: + if (header.opcode == WILLING) { + XdmcpDisposeARRAY8 (&auth); + XdmcpDisposeARRAY8 (&host); + XdmcpDisposeARRAY8 (&stat); + } + + g_free (status); + gdm_address_free (address); + + return TRUE; +} + +static void +do_ping (GdmHostChooserWidget *widget, + gboolean full) +{ + GSList *l; + + g_debug ("do ping full:%d", full); + + for (l = widget->priv->broadcast_addresses; l != NULL; l = l->next) { + GdmAddress *address; + int res; + + address = l->data; + + gdm_address_debug (address); + errno = 0; + g_debug ("fd:%d", widget->priv->socket_fd); + res = XdmcpFlush (widget->priv->socket_fd, + &widget->priv->broadcast_buf, + (XdmcpNetaddr)gdm_address_peek_sockaddr_storage (address), + (int)gdm_sockaddr_len (gdm_address_peek_sockaddr_storage (address))); + + if (! res) { + g_warning ("Unable to flush the XDMCP broadcast packet: %s", g_strerror (errno)); + } + } + + if (full) { + for (l = widget->priv->query_addresses; l != NULL; l = l->next) { + GdmAddress *address; + int res; + + address = l->data; + + gdm_address_debug (address); + res = XdmcpFlush (widget->priv->socket_fd, + &widget->priv->query_buf, + (XdmcpNetaddr)gdm_address_peek_sockaddr_storage (address), + (int)gdm_sockaddr_len (gdm_address_peek_sockaddr_storage (address))); + if (! res) { + g_warning ("Unable to flush the XDMCP query packet"); + } + } + } +} + +static gboolean +ping_try (GdmHostChooserWidget *widget) +{ + do_ping (widget, FALSE); + + widget->priv->ping_tries --; + + if (widget->priv->ping_tries <= 0) { + widget->priv->ping_try_id = 0; + return FALSE; + } else { + return TRUE; + } +} + +static void +xdmcp_discover (GdmHostChooserWidget *widget) +{ +#if 0 + gtk_widget_set_sensitive (GTK_WIDGET (manage), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (rescan), FALSE); + gtk_list_store_clear (GTK_LIST_STORE (browser_model)); + gtk_widget_set_sensitive (GTK_WIDGET (browser), FALSE); + gtk_label_set_label (GTK_LABEL (status_label), + _(scanning_message)); + + while (hl) { + gdm_chooser_host_dispose ((GdmChooserHost *) hl->data); + hl = hl->next; + } + + g_list_free (chooser_hosts); + chooser_hosts = NULL; +#endif + + do_ping (widget, TRUE); + +#if 0 + if (widget->priv->scan_time_id > 0) { + g_source_remove (widget->priv->scan_time_id); + } + + widget->priv->scan_time_id = g_timeout_add_seconds (SCAN_TIMEOUT, + chooser_scan_time_update, + widget); +#endif + /* Note we already used up one try */ + widget->priv->ping_tries = PING_TRIES - 1; + if (widget->priv->ping_try_id > 0) { + g_source_remove (widget->priv->ping_try_id); + } + + widget->priv->ping_try_id = g_timeout_add_seconds (PING_TIMEOUT, + (GSourceFunc)ping_try, + widget); +} + +/* Find broadcast address for all active, non pointopoint interfaces */ +static void +find_broadcast_addresses (GdmHostChooserWidget *widget) +{ + int i; + int num; + int sock; + struct ifconf ifc; + char *buf; + struct ifreq *ifr; + + g_debug ("Finding broadcast addresses"); + + sock = socket (AF_INET, SOCK_DGRAM, 0); +#ifdef SIOCGIFNUM + if (ioctl (sock, SIOCGIFNUM, &num) < 0) { + num = 64; + } +#else + num = 64; +#endif + + ifc.ifc_len = sizeof (struct ifreq) * num; + ifc.ifc_buf = buf = g_malloc0 (ifc.ifc_len); + if (ioctl (sock, SIOCGIFCONF, &ifc) < 0) { + g_warning ("Could not get local addresses!"); + goto out; + } + + ifr = ifc.ifc_req; + num = ifc.ifc_len / sizeof (struct ifreq); + for (i = 0 ; i < num ; i++) { + const char *name; + + name = ifr[i].ifr_name; + g_debug ("Checking if %s", name); + if (name != NULL && name[0] != '\0') { + struct ifreq ifreq; + GdmAddress *address; + struct sockaddr_in sin; + + memset (&ifreq, 0, sizeof (ifreq)); + + strncpy (ifreq.ifr_name, + ifr[i].ifr_name, + sizeof (ifreq.ifr_name)); + /* paranoia */ + ifreq.ifr_name[sizeof (ifreq.ifr_name) - 1] = '\0'; + + if ((ioctl (sock, SIOCGIFFLAGS, &ifreq) < 0) && (errno != ENXIO)) { + g_warning ("Could not get SIOCGIFFLAGS for %s", ifr[i].ifr_name); + } + + if ((ifreq.ifr_flags & IFF_UP) == 0 || + (ifreq.ifr_flags & IFF_BROADCAST) == 0 || + ioctl (sock, SIOCGIFBRDADDR, &ifreq) < 0) { + g_debug ("Skipping if %s", name); + continue; + } + + g_memmove (&sin, &ifreq.ifr_broadaddr, sizeof (struct sockaddr_in)); + sin.sin_port = htons (XDM_UDP_PORT); + address = gdm_address_new_from_sockaddr ((struct sockaddr *) &sin, sizeof (sin)); + if (address != NULL) { + g_debug ("Adding if %s", name); + gdm_address_debug (address); + + widget->priv->broadcast_addresses = g_slist_append (widget->priv->broadcast_addresses, address); + } + } + } + out: + g_free (buf); + close (sock); +} + +static void +add_hosts (GdmHostChooserWidget *widget) +{ + int i; + + for (i = 0; widget->priv->hosts != NULL && widget->priv->hosts[i] != NULL; i++) { + struct addrinfo hints; + struct addrinfo *result; + struct addrinfo *ai; + int gaierr; + const char *name; + char serv_buf [NI_MAXSERV]; + const char *serv; + + name = widget->priv->hosts[i]; + + if (strcmp (name, "BROADCAST") == 0) { + find_broadcast_addresses (widget); + continue; + } + + if (strcmp (name, "MULTICAST") == 0) { + /*gdm_chooser_find_mcaddr ();*/ + continue; + } + + result = NULL; + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + + snprintf (serv_buf, sizeof (serv_buf), "%u", XDM_UDP_PORT); + serv = serv_buf; + + gaierr = getaddrinfo (name, serv, &hints, &result); + if (gaierr != 0) { + g_warning ("Unable to get address info for name %s: %s", name, gai_strerror (gaierr)); + continue; + } + + for (ai = result; ai != NULL; ai = ai->ai_next) { + GdmAddress *address; + + address = gdm_address_new_from_sockaddr (ai->ai_addr, ai->ai_addrlen); + if (address != NULL) { + widget->priv->query_addresses = g_slist_append (widget->priv->query_addresses, address); + } + } + + freeaddrinfo (result); + } + + if (widget->priv->broadcast_addresses == NULL && widget->priv->query_addresses == NULL) { + find_broadcast_addresses (widget); + } +} + +static void +xdmcp_init (GdmHostChooserWidget *widget) +{ + XdmcpHeader header; + int sockopts; + int res; + GIOChannel *ioc; + ARRAYofARRAY8 aanames; + + sockopts = 1; + + widget->priv->socket_fd = -1; + + /* Open socket for communication */ +#ifdef ENABLE_IPV6 + widget->priv->socket_fd = socket (AF_INET6, SOCK_DGRAM, 0); + if (widget->priv->socket_fd != -1) { + widget->priv->have_ipv6 = TRUE; +#ifdef IPV6_V6ONLY + { + int zero = 0; + if (setsockopt(widget->priv->socket_fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)) < 0) + g_warning("setsockopt(IPV6_V6ONLY): %s", g_strerror(errno)); + } +#endif + } +#endif + if (! widget->priv->have_ipv6) { + widget->priv->socket_fd = socket (AF_INET, SOCK_DGRAM, 0); + if (widget->priv->socket_fd == -1) { + g_critical ("Could not create socket!"); + } + } + + res = setsockopt (widget->priv->socket_fd, + SOL_SOCKET, + SO_BROADCAST, + (char *) &sockopts, + sizeof (sockopts)); + if (res < 0) { + g_critical ("Could not set socket options!"); + } + + /* Assemble XDMCP BROADCAST_QUERY packet in static buffer */ + memset (&header, 0, sizeof (XdmcpHeader)); + header.opcode = (CARD16) BROADCAST_QUERY; + header.length = 1; + header.version = XDM_PROTOCOL_VERSION; + aanames.length = 0; + XdmcpWriteHeader (&widget->priv->broadcast_buf, &header); + XdmcpWriteARRAYofARRAY8 (&widget->priv->broadcast_buf, &aanames); + + /* Assemble XDMCP QUERY packet in static buffer */ + memset (&header, 0, sizeof (XdmcpHeader)); + header.opcode = (CARD16) QUERY; + header.length = 1; + header.version = XDM_PROTOCOL_VERSION; + memset (&widget->priv->query_buf, 0, sizeof (XdmcpBuffer)); + XdmcpWriteHeader (&widget->priv->query_buf, &header); + XdmcpWriteARRAYofARRAY8 (&widget->priv->query_buf, &aanames); + + add_hosts (widget); + + ioc = g_io_channel_unix_new (widget->priv->socket_fd); + g_io_channel_set_encoding (ioc, NULL, NULL); + g_io_channel_set_buffered (ioc, FALSE); + widget->priv->io_watch_id = g_io_add_watch (ioc, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + (GIOFunc)decode_packet, + widget); + g_io_channel_unref (ioc); +} + +void +gdm_host_chooser_widget_refresh (GdmHostChooserWidget *widget) +{ + g_return_if_fail (GDM_IS_HOST_CHOOSER_WIDGET (widget)); + + xdmcp_discover (widget); +} + +GdmChooserHost * +gdm_host_chooser_widget_get_host (GdmHostChooserWidget *widget) +{ + GdmChooserHost *host; + + g_return_val_if_fail (GDM_IS_HOST_CHOOSER_WIDGET (widget), NULL); + + host = NULL; + if (widget->priv->current_host != NULL) { + host = g_object_ref (widget->priv->current_host); + } + + return host; +} + +static void +_gdm_host_chooser_widget_set_kind_mask (GdmHostChooserWidget *widget, + int kind_mask) +{ + if (widget->priv->kind_mask != kind_mask) { + widget->priv->kind_mask = kind_mask; + } +} + +static void +gdm_host_chooser_widget_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdmHostChooserWidget *self; + + self = GDM_HOST_CHOOSER_WIDGET (object); + + switch (prop_id) { + case PROP_KIND_MASK: + _gdm_host_chooser_widget_set_kind_mask (self, g_value_get_int (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_host_chooser_widget_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gdm_host_chooser_widget_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GdmHostChooserWidget *widget; + + widget = GDM_HOST_CHOOSER_WIDGET (G_OBJECT_CLASS (gdm_host_chooser_widget_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + xdmcp_init (widget); + xdmcp_discover (widget); + + return G_OBJECT (widget); +} + +static void +gdm_host_chooser_widget_dispose (GObject *object) +{ + GdmHostChooserWidget *widget; + + widget = GDM_HOST_CHOOSER_WIDGET (object); + + g_debug ("Disposing host_chooser_widget"); + + if (widget->priv->broadcast_addresses != NULL) { + g_slist_foreach (widget->priv->broadcast_addresses, + (GFunc)gdm_address_free, + NULL); + g_slist_free (widget->priv->broadcast_addresses); + widget->priv->broadcast_addresses = NULL; + } + if (widget->priv->query_addresses != NULL) { + g_slist_foreach (widget->priv->query_addresses, + (GFunc)gdm_address_free, + NULL); + g_slist_free (widget->priv->query_addresses); + widget->priv->query_addresses = NULL; + } + if (widget->priv->chooser_hosts != NULL) { + g_slist_foreach (widget->priv->chooser_hosts, + (GFunc)g_object_unref, + NULL); + g_slist_free (widget->priv->chooser_hosts); + widget->priv->chooser_hosts = NULL; + } + + widget->priv->current_host = NULL; + + G_OBJECT_CLASS (gdm_host_chooser_widget_parent_class)->dispose (object); +} + +static void +gdm_host_chooser_widget_class_init (GdmHostChooserWidgetClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gdm_host_chooser_widget_get_property; + object_class->set_property = gdm_host_chooser_widget_set_property; + object_class->constructor = gdm_host_chooser_widget_constructor; + object_class->dispose = gdm_host_chooser_widget_dispose; + object_class->finalize = gdm_host_chooser_widget_finalize; + + g_object_class_install_property (object_class, + PROP_KIND_MASK, + g_param_spec_int ("kind-mask", + "kind mask", + "kind mask", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + signals [HOST_ACTIVATED] = g_signal_new ("host-activated", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdmHostChooserWidgetClass, host_activated), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + g_type_class_add_private (klass, sizeof (GdmHostChooserWidgetPrivate)); +} + +static void +on_host_selected (GtkTreeSelection *selection, + GdmHostChooserWidget *widget) +{ + GtkTreeModel *model = NULL; + GtkTreeIter iter = {0}; + GdmChooserHost *curhost; + + curhost = NULL; + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) { + gtk_tree_model_get (model, &iter, CHOOSER_LIST_HOST_COLUMN, &curhost, -1); + } + + widget->priv->current_host = curhost; +} + +static void +on_row_activated (GtkTreeView *tree_view, + GtkTreePath *tree_path, + GtkTreeViewColumn *tree_column, + GdmHostChooserWidget *widget) +{ + g_signal_emit (widget, signals[HOST_ACTIVATED], 0); +} + +static void +gdm_host_chooser_widget_init (GdmHostChooserWidget *widget) +{ + GtkWidget *scrolled; + GtkTreeSelection *selection; + GtkTreeViewColumn *column; + GtkTreeModel *model; + + widget->priv = GDM_HOST_CHOOSER_WIDGET_GET_PRIVATE (widget); + + scrolled = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (widget), scrolled, TRUE, TRUE, 0); + + widget->priv->treeview = gtk_tree_view_new (); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget->priv->treeview), FALSE); + g_signal_connect (widget->priv->treeview, + "row-activated", + G_CALLBACK (on_row_activated), + widget); + gtk_container_add (GTK_CONTAINER (scrolled), widget->priv->treeview); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget->priv->treeview)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); + g_signal_connect (selection, "changed", + G_CALLBACK (on_host_selected), + widget); + + model = (GtkTreeModel *)gtk_list_store_new (3, + GDK_TYPE_PIXBUF, + G_TYPE_STRING, + G_TYPE_POINTER); + gtk_tree_view_set_model (GTK_TREE_VIEW (widget->priv->treeview), model); + + column = gtk_tree_view_column_new_with_attributes ("Icon", + gtk_cell_renderer_pixbuf_new (), + "pixbuf", CHOOSER_LIST_ICON_COLUMN, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (widget->priv->treeview), column); + + column = gtk_tree_view_column_new_with_attributes ("Hostname", + gtk_cell_renderer_text_new (), + "markup", CHOOSER_LIST_LABEL_COLUMN, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (widget->priv->treeview), column); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), + CHOOSER_LIST_LABEL_COLUMN, + GTK_SORT_ASCENDING); +} + +static void +gdm_host_chooser_widget_finalize (GObject *object) +{ + GdmHostChooserWidget *host_chooser_widget; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_HOST_CHOOSER_WIDGET (object)); + + host_chooser_widget = GDM_HOST_CHOOSER_WIDGET (object); + + g_return_if_fail (host_chooser_widget->priv != NULL); + + G_OBJECT_CLASS (gdm_host_chooser_widget_parent_class)->finalize (object); +} + +GtkWidget * +gdm_host_chooser_widget_new (int kind_mask) +{ + GObject *object; + + object = g_object_new (GDM_TYPE_HOST_CHOOSER_WIDGET, + "kind-mask", kind_mask, + NULL); + + return GTK_WIDGET (object); +} diff --git a/chooser/gdm-host-chooser-widget.h b/chooser/gdm-host-chooser-widget.h new file mode 100644 index 00000000..739eac01 --- /dev/null +++ b/chooser/gdm-host-chooser-widget.h @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __GDM_HOST_CHOOSER_WIDGET_H +#define __GDM_HOST_CHOOSER_WIDGET_H + +#include +#include +#include "gdm-chooser-host.h" + +G_BEGIN_DECLS + +#define GDM_TYPE_HOST_CHOOSER_WIDGET (gdm_host_chooser_widget_get_type ()) +#define GDM_HOST_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_HOST_CHOOSER_WIDGET, GdmHostChooserWidget)) +#define GDM_HOST_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_HOST_CHOOSER_WIDGET, GdmHostChooserWidgetClass)) +#define GDM_IS_HOST_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_HOST_CHOOSER_WIDGET)) +#define GDM_IS_HOST_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_HOST_CHOOSER_WIDGET)) +#define GDM_HOST_CHOOSER_WIDGET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_HOST_CHOOSER_WIDGET, GdmHostChooserWidgetClass)) + +typedef struct GdmHostChooserWidgetPrivate GdmHostChooserWidgetPrivate; + +typedef struct +{ + GtkVBox parent; + GdmHostChooserWidgetPrivate *priv; +} GdmHostChooserWidget; + +typedef struct +{ + GtkVBoxClass parent_class; + + /* signals */ + void (* host_activated) (GdmHostChooserWidget *widget); +} GdmHostChooserWidgetClass; + +GType gdm_host_chooser_widget_get_type (void); +GtkWidget * gdm_host_chooser_widget_new (int kind_mask); + +void gdm_host_chooser_widget_set_kind_mask (GdmHostChooserWidget *widget, + int kind_mask); + +void gdm_host_chooser_widget_refresh (GdmHostChooserWidget *widget); + +GdmChooserHost * gdm_host_chooser_widget_get_host (GdmHostChooserWidget *widget); + +G_END_DECLS + +#endif /* __GDM_HOST_CHOOSER_WIDGET_H */ diff --git a/chooser/gdm-host-chooser.c b/chooser/gdm-host-chooser.c new file mode 100644 index 00000000..47f37d47 --- /dev/null +++ b/chooser/gdm-host-chooser.c @@ -0,0 +1,252 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "gdm-common.h" +#include "gdm-log.h" + +#include "gdm-chooser-host.h" +#include "gdm-host-chooser-dialog.h" + +#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility" + +static Atom AT_SPI_IOR; + + +static gboolean +assistive_registry_launch (void) +{ + GPid pid; + GError *error; + const char *command; + char **argv; + gboolean res; + + command = AT_SPI_REGISTRYD_DIR "/at-spi-registryd"; + + argv = NULL; + error = NULL; + res = g_shell_parse_argv (command, NULL, &argv, &error); + if (! res) { + g_warning ("Unable to parse command: %s", error->message); + return FALSE; + } + + error = NULL; + res = g_spawn_async (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH + | G_SPAWN_STDOUT_TO_DEV_NULL + | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, + NULL, + &pid, + &error); + g_strfreev (argv); + + if (! res) { + g_warning ("Unable to run command %s: %s", command, error->message); + return FALSE; + } + + if (kill (pid, 0) < 0) { + g_warning ("at-spi-registryd not running"); + return FALSE; + } + + return TRUE; +} + +static GdkFilterReturn +filter_watch (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + XEvent *xev = (XEvent *)xevent; + + if (xev->xany.type == PropertyNotify + && xev->xproperty.atom == AT_SPI_IOR) { + gtk_main_quit (); + + return GDK_FILTER_REMOVE; + } + + return GDK_FILTER_CONTINUE; +} + +static gboolean +filter_timeout (gpointer data) +{ + g_warning ("The accessibility registry was not found."); + + gtk_main_quit (); + + return FALSE; +} + +static void +assistive_registry_start (void) +{ + GdkWindow *root; + guint tid; + + root = gdk_get_default_root_window (); + + if ( ! AT_SPI_IOR) { + AT_SPI_IOR = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "AT_SPI_IOR", False); + } + + gdk_window_set_events (root, GDK_PROPERTY_CHANGE_MASK); + + if ( ! assistive_registry_launch ()) { + g_warning ("The accessibility registry could not be started."); + return; + } + + gdk_window_add_filter (root, filter_watch, NULL); + tid = g_timeout_add_seconds (5, filter_timeout, NULL); + + gtk_main (); + + gdk_window_remove_filter (root, filter_watch, NULL); + g_source_remove (tid); +} + +static void +at_set_gtk_modules (void) +{ + GSList *modules_list; + GSList *l; + const char *old; + char **modules; + gboolean found_gail; + gboolean found_atk_bridge; + int n; + + n = 0; + modules_list = NULL; + found_gail = FALSE; + found_atk_bridge = FALSE; + + if ((old = g_getenv ("GTK_MODULES")) != NULL) { + modules = g_strsplit (old, ":", -1); + for (n = 0; modules[n]; n++) { + if (!strcmp (modules[n], "gail")) { + found_gail = TRUE; + } else if (!strcmp (modules[n], "atk-bridge")) { + found_atk_bridge = TRUE; + } + + modules_list = g_slist_prepend (modules_list, modules[n]); + modules[n] = NULL; + } + g_free (modules); + } + + if (!found_gail) { + modules_list = g_slist_prepend (modules_list, "gail"); + ++n; + } + + if (!found_atk_bridge) { + modules_list = g_slist_prepend (modules_list, "atk-bridge"); + ++n; + } + + modules = g_new (char *, n + 1); + modules[n--] = NULL; + for (l = modules_list; l; l = l->next) { + modules[n--] = g_strdup (l->data); + } + + g_setenv ("GTK_MODULES", g_strjoinv (":", modules), TRUE); + g_strfreev (modules); + g_slist_free (modules_list); +} + +static void +load_a11y (void) +{ + assistive_registry_start (); + at_set_gtk_modules (); +} + +int +main (int argc, char *argv[]) +{ + GtkWidget *chooser; + + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + setlocale (LC_ALL, ""); + + gdm_log_init (); + gdm_log_set_debug (TRUE); + + g_debug ("Chooser for display %s xauthority:%s", + g_getenv ("DISPLAY"), + g_getenv ("XAUTHORITY")); + + gdk_init (&argc, &argv); + + load_a11y (); + + gtk_init (&argc, &argv); + + chooser = gdm_host_chooser_dialog_new (GDM_CHOOSER_HOST_KIND_MASK_ALL); + gtk_widget_set_size_request (chooser, 480, 600); + + if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_OK) { + GdmChooserHost *host; + + host = gdm_host_chooser_dialog_get_host (GDM_HOST_CHOOSER_DIALOG (chooser)); + if (host != NULL) { + char *hostname; + /* FIXME: handle different host types here? */ + + hostname = NULL; + gdm_address_get_hostname (gdm_chooser_host_get_address (host), &hostname); + /* FIXME: fall back to numerical address? */ + if (hostname != NULL) { + g_print ("hostname: %s\n", hostname); + g_free (hostname); + } + } + } + + gtk_widget_destroy (chooser); + + return 0; +} diff --git a/configure.ac b/configure.ac index 8f3a8702..3307d806 100644 --- a/configure.ac +++ b/configure.ac @@ -1515,8 +1515,7 @@ AC_CONFIG_FILES([ Makefile daemon/Makefile docs/Makefile -gui/Makefile -gui/simple-chooser/Makefile +chooser/Makefile libgdm/Makefile libgdm/gdm.pc utils/Makefile diff --git a/gui/Makefile.am b/gui/Makefile.am deleted file mode 100644 index 604422c4..00000000 --- a/gui/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -NULL = - -SUBDIRS = \ - $(NULL) - -if XDMCP_SUPPORT -SUBDIRS += simple-chooser -endif - -DIST_SUBDIRS = \ - simple-chooser \ - $(NULL) diff --git a/gui/simple-chooser/Makefile.am b/gui/simple-chooser/Makefile.am deleted file mode 100644 index b649d38b..00000000 --- a/gui/simple-chooser/Makefile.am +++ /dev/null @@ -1,71 +0,0 @@ -NULL = - -AM_CPPFLAGS = \ - -I$(top_srcdir)/common \ - -I$(top_srcdir)/libgdm \ - -I$(top_builddir)/libgdm \ - -DDATADIR=\""$(datadir)"\" \ - -DGDMCONFDIR=\"$(gdmconfdir)\" \ - -DDMCONFDIR=\""$(dmconfdir)"\" \ - -DGDMLOCALEDIR=\""$(gdmlocaledir)"\" \ - -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ - -DLIBEXECDIR=\""$(libexecdir)"\" \ - -DSBINDIR=\""$(sbindir)"\" \ - -DPIXMAPDIR=\""$(pixmapdir)"\" \ - -DAT_SPI_REGISTRYD_DIR="\"$(AT_SPI_REGISTRYD_DIR)\"" \ - -DGNOME_SETTINGS_DAEMON_DIR="\"$(GNOME_SETTINGS_DAEMON_DIR)\"" \ - $(GTK_CFLAGS) \ - $(XLIB_CFLAGS) \ - $(XDMCP_CFLAGS) \ - $(EXTRA_CHOOSER_CFLAGS) \ - $(SIMPLE_CHOOSER_CFLAGS) \ - $(NULL) - -libexec_PROGRAMS = \ - gdm-simple-chooser \ - gdm-host-chooser \ - $(NULL) - -gdm_simple_chooser_SOURCES = \ - chooser-main.c \ - gdm-chooser-host.c \ - gdm-chooser-host.h \ - gdm-host-chooser-widget.c \ - gdm-host-chooser-widget.h \ - gdm-host-chooser-dialog.c \ - gdm-host-chooser-dialog.h \ - gdm-chooser-session.c \ - gdm-chooser-session.h \ - $(NULL) - -gdm_simple_chooser_LDADD = \ - $(top_builddir)/common/libgdmcommon.la \ - $(top_builddir)/libgdm/libgdm.la \ - $(GTK_LIBS) \ - $(EXTRA_CHOOSER_LIBS) \ - $(SIMPLE_CHOOSER_LIBS) \ - $(XLIB_LIBS) \ - $(XDMCP_LIBS) \ - $(NULL) - -gdm_host_chooser_SOURCES = \ - gdm-host-chooser.c \ - gdm-chooser-host.c \ - gdm-chooser-host.h \ - gdm-host-chooser-widget.c \ - gdm-host-chooser-widget.h \ - gdm-host-chooser-dialog.c \ - gdm-host-chooser-dialog.h \ - $(NULL) - -gdm_host_chooser_LDADD = \ - $(top_builddir)/common/libgdmcommon.la \ - $(GTK_LIBS) \ - $(EXTRA_CHOOSER_LIBS) \ - $(SIMPLE_CHOOSER_LIBS) \ - $(XLIB_LIBS) \ - $(XDMCP_LIBS) \ - $(NULL) - -EXTRA_DIST = \ - $(NULL) diff --git a/gui/simple-chooser/chooser-main.c b/gui/simple-chooser/chooser-main.c deleted file mode 100644 index 54aebf17..00000000 --- a/gui/simple-chooser/chooser-main.c +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "gdm-common.h" -#include "gdm-log.h" - -#include "gdm-chooser-session.h" - -#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility" - -static Atom AT_SPI_IOR; - - -static gboolean -assistive_registry_launch (void) -{ - GPid pid; - GError *error; - const char *command; - char **argv; - gboolean res; - - command = AT_SPI_REGISTRYD_DIR "/at-spi-registryd"; - - argv = NULL; - error = NULL; - res = g_shell_parse_argv (command, NULL, &argv, &error); - if (! res) { - g_warning ("Unable to parse command: %s", error->message); - return FALSE; - } - - error = NULL; - res = g_spawn_async (NULL, - argv, - NULL, - G_SPAWN_SEARCH_PATH - | G_SPAWN_STDOUT_TO_DEV_NULL - | G_SPAWN_STDERR_TO_DEV_NULL, - NULL, - NULL, - &pid, - &error); - g_strfreev (argv); - - if (! res) { - g_warning ("Unable to run command %s: %s", command, error->message); - return FALSE; - } - - if (kill (pid, 0) < 0) { - g_warning ("at-spi-registryd not running"); - return FALSE; - } - - return TRUE; -} - -static GdkFilterReturn -filter_watch (GdkXEvent *xevent, - GdkEvent *event, - gpointer data) -{ - XEvent *xev = (XEvent *)xevent; - - if (xev->xany.type == PropertyNotify - && xev->xproperty.atom == AT_SPI_IOR) { - gtk_main_quit (); - - return GDK_FILTER_REMOVE; - } - - return GDK_FILTER_CONTINUE; -} - -static gboolean -filter_timeout (gpointer data) -{ - g_warning ("The accessibility registry was not found."); - - gtk_main_quit (); - - return FALSE; -} - -static void -assistive_registry_start (void) -{ - GdkWindow *root; - guint tid; - - root = gdk_get_default_root_window (); - - if ( ! AT_SPI_IOR) { - AT_SPI_IOR = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "AT_SPI_IOR", False); - } - - gdk_window_set_events (root, GDK_PROPERTY_CHANGE_MASK); - - if ( ! assistive_registry_launch ()) { - g_warning ("The accessibility registry could not be started."); - return; - } - - gdk_window_add_filter (root, filter_watch, NULL); - tid = g_timeout_add_seconds (5, filter_timeout, NULL); - - gtk_main (); - - gdk_window_remove_filter (root, filter_watch, NULL); - g_source_remove (tid); -} - -static void -at_set_gtk_modules (void) -{ - GSList *modules_list; - GSList *l; - const char *old; - char **modules; - gboolean found_gail; - gboolean found_atk_bridge; - int n; - - n = 0; - modules_list = NULL; - found_gail = FALSE; - found_atk_bridge = FALSE; - - if ((old = g_getenv ("GTK_MODULES")) != NULL) { - modules = g_strsplit (old, ":", -1); - for (n = 0; modules[n]; n++) { - if (!strcmp (modules[n], "gail")) { - found_gail = TRUE; - } else if (!strcmp (modules[n], "atk-bridge")) { - found_atk_bridge = TRUE; - } - - modules_list = g_slist_prepend (modules_list, modules[n]); - modules[n] = NULL; - } - g_free (modules); - } - - if (!found_gail) { - modules_list = g_slist_prepend (modules_list, "gail"); - ++n; - } - - if (!found_atk_bridge) { - modules_list = g_slist_prepend (modules_list, "atk-bridge"); - ++n; - } - - modules = g_new (char *, n + 1); - modules[n--] = NULL; - for (l = modules_list; l; l = l->next) { - modules[n--] = g_strdup (l->data); - } - - g_setenv ("GTK_MODULES", g_strjoinv (":", modules), TRUE); - g_strfreev (modules); - g_slist_free (modules_list); -} - -static void -load_a11y (void) -{ - assistive_registry_start (); - at_set_gtk_modules (); -} - -int -main (int argc, char *argv[]) -{ - GdmChooserSession *session; - gboolean res; - GError *error; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - setlocale (LC_ALL, ""); - - gdm_log_init (); - gdm_log_set_debug (TRUE); - - g_debug ("Chooser for display %s xauthority:%s", - g_getenv ("DISPLAY"), - g_getenv ("XAUTHORITY")); - - gdk_init (&argc, &argv); - - load_a11y (); - - gtk_init (&argc, &argv); - - session = gdm_chooser_session_new (); - if (session == NULL) { - g_critical ("Unable to create chooser session"); - exit (1); - } - - error = NULL; - res = gdm_chooser_session_start (session, &error); - if (! res) { - g_warning ("Unable to start chooser session: %s", error->message); - g_error_free (error); - exit (1); - } - - gtk_main (); - - if (session != NULL) { - g_object_unref (session); - } - - return 0; -} diff --git a/gui/simple-chooser/gdm-chooser-host.c b/gui/simple-chooser/gdm-chooser-host.c deleted file mode 100644 index 5b76f652..00000000 --- a/gui/simple-chooser/gdm-chooser-host.c +++ /dev/null @@ -1,258 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "gdm-address.h" -#include "gdm-chooser-host.h" - -#define GDM_CHOOSER_HOST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_CHOOSER_HOST, GdmChooserHostPrivate)) - -struct GdmChooserHostPrivate -{ - GdmAddress *address; - char *description; - GdmChooserHostKind kind; - gboolean willing; -}; - -enum { - PROP_0, - PROP_ADDRESS, - PROP_DESCRIPTION, - PROP_KIND, - PROP_WILLING, -}; - -static void gdm_chooser_host_class_init (GdmChooserHostClass *klass); -static void gdm_chooser_host_init (GdmChooserHost *chooser_host); -static void gdm_chooser_host_finalize (GObject *object); - -G_DEFINE_TYPE (GdmChooserHost, gdm_chooser_host, G_TYPE_OBJECT) - -GdmAddress * -gdm_chooser_host_get_address (GdmChooserHost *host) -{ - g_return_val_if_fail (GDM_IS_CHOOSER_HOST (host), NULL); - - return host->priv->address; -} - -G_CONST_RETURN char * -gdm_chooser_host_get_description (GdmChooserHost *host) -{ - g_return_val_if_fail (GDM_IS_CHOOSER_HOST (host), NULL); - - return host->priv->description; -} - -GdmChooserHostKind -gdm_chooser_host_get_kind (GdmChooserHost *host) -{ - g_return_val_if_fail (GDM_IS_CHOOSER_HOST (host), 0); - - return host->priv->kind; -} - -gboolean -gdm_chooser_host_get_willing (GdmChooserHost *host) -{ - g_return_val_if_fail (GDM_IS_CHOOSER_HOST (host), FALSE); - - return host->priv->willing; -} - -static void -_gdm_chooser_host_set_address (GdmChooserHost *host, - GdmAddress *address) -{ - if (host->priv->address != NULL) { - gdm_address_free (host->priv->address); - } - - g_assert (address != NULL); - - gdm_address_debug (address); - host->priv->address = gdm_address_copy (address); -} - -static void -_gdm_chooser_host_set_description (GdmChooserHost *host, - const char *description) -{ - g_free (host->priv->description); - host->priv->description = g_strdup (description); -} - -static void -_gdm_chooser_host_set_kind (GdmChooserHost *host, - int kind) -{ - if (host->priv->kind != kind) { - host->priv->kind = kind; - } -} - -static void -_gdm_chooser_host_set_willing (GdmChooserHost *host, - gboolean willing) -{ - if (host->priv->willing != willing) { - host->priv->willing = willing; - } -} - -static void -gdm_chooser_host_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - GdmChooserHost *host; - - host = GDM_CHOOSER_HOST (object); - - switch (param_id) { - case PROP_ADDRESS: - _gdm_chooser_host_set_address (host, g_value_get_boxed (value)); - break; - case PROP_DESCRIPTION: - _gdm_chooser_host_set_description (host, g_value_get_string (value)); - break; - case PROP_KIND: - _gdm_chooser_host_set_kind (host, g_value_get_int (value)); - break; - case PROP_WILLING: - _gdm_chooser_host_set_willing (host, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -gdm_chooser_host_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - GdmChooserHost *host; - - host = GDM_CHOOSER_HOST (object); - - switch (param_id) { - case PROP_ADDRESS: - g_value_set_boxed (value, host->priv->address); - break; - case PROP_DESCRIPTION: - g_value_set_string (value, host->priv->description); - break; - case PROP_KIND: - g_value_set_int (value, host->priv->kind); - break; - case PROP_WILLING: - g_value_set_boolean (value, host->priv->willing); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -gdm_chooser_host_class_init (GdmChooserHostClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = gdm_chooser_host_set_property; - object_class->get_property = gdm_chooser_host_get_property; - object_class->finalize = gdm_chooser_host_finalize; - - - g_object_class_install_property (object_class, - PROP_ADDRESS, - g_param_spec_boxed ("address", - "address", - "address", - GDM_TYPE_ADDRESS, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_DESCRIPTION, - g_param_spec_string ("description", - "description", - "description", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_object_class_install_property (object_class, - PROP_KIND, - g_param_spec_int ("kind", - "kind", - "kind", - 0, - G_MAXINT, - 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_WILLING, - g_param_spec_boolean ("willing", - "willing", - "willing", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - - g_type_class_add_private (klass, sizeof (GdmChooserHostPrivate)); -} - -static void -gdm_chooser_host_init (GdmChooserHost *widget) -{ - widget->priv = GDM_CHOOSER_HOST_GET_PRIVATE (widget); -} - -static void -gdm_chooser_host_finalize (GObject *object) -{ - GdmChooserHost *host; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_CHOOSER_HOST (object)); - - host = GDM_CHOOSER_HOST (object); - - g_return_if_fail (host->priv != NULL); - - g_free (host->priv->description); - gdm_address_free (host->priv->address); - - G_OBJECT_CLASS (gdm_chooser_host_parent_class)->finalize (object); -} diff --git a/gui/simple-chooser/gdm-chooser-host.h b/gui/simple-chooser/gdm-chooser-host.h deleted file mode 100644 index fda6e9f9..00000000 --- a/gui/simple-chooser/gdm-chooser-host.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __GDM_CHOOSER_HOST__ -#define __GDM_CHOOSER_HOST__ - -#include -#include "gdm-address.h" - -G_BEGIN_DECLS - -#define GDM_TYPE_CHOOSER_HOST (gdm_chooser_host_get_type ()) -#define GDM_CHOOSER_HOST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_CHOOSER_HOST, GdmChooserHost)) -#define GDM_CHOOSER_HOST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_CHOOSER_HOST, GdmChooserHostClass)) -#define GDM_IS_CHOOSER_HOST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_CHOOSER_HOST)) -#define GDM_IS_CHOOSER_HOST_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_CHOOSER_HOST)) -#define GDM_CHOOSER_HOST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_CHOOSER_HOST, GdmChooserHostClass)) - -typedef enum { - GDM_CHOOSER_HOST_KIND_XDMCP = 1 << 0, -} GdmChooserHostKind; - -#define GDM_CHOOSER_HOST_KIND_MASK_ALL (GDM_CHOOSER_HOST_KIND_XDMCP) - -typedef struct GdmChooserHostPrivate GdmChooserHostPrivate; - -typedef struct -{ - GObject parent; - GdmChooserHostPrivate *priv; -} GdmChooserHost; - -typedef struct -{ - GObjectClass parent_class; -} GdmChooserHostClass; - -GType gdm_chooser_host_get_type (void) G_GNUC_CONST; - -G_CONST_RETURN char *gdm_chooser_host_get_description (GdmChooserHost *chooser_host); -GdmAddress * gdm_chooser_host_get_address (GdmChooserHost *chooser_host); -gboolean gdm_chooser_host_get_willing (GdmChooserHost *chooser_host); -GdmChooserHostKind gdm_chooser_host_get_kind (GdmChooserHost *chooser_host); - -G_END_DECLS - -#endif diff --git a/gui/simple-chooser/gdm-chooser-session.c b/gui/simple-chooser/gdm-chooser-session.c deleted file mode 100644 index dd618b8a..00000000 --- a/gui/simple-chooser/gdm-chooser-session.c +++ /dev/null @@ -1,342 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include "gdm-chooser-session.h" -#include "gdm-client.h" - -#include "gdm-host-chooser-dialog.h" - -#define GDM_CHOOSER_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_CHOOSER_SESSION, GdmChooserSessionPrivate)) - -struct GdmChooserSessionPrivate -{ - GdmClient *client; - GdmRemoteGreeter *remote_greeter; - GdmChooser *chooser; - GtkWidget *chooser_dialog; -}; - -enum { - PROP_0, -}; - -static void gdm_chooser_session_class_init (GdmChooserSessionClass *klass); -static void gdm_chooser_session_init (GdmChooserSession *chooser_session); -static void gdm_chooser_session_finalize (GObject *object); - -G_DEFINE_TYPE (GdmChooserSession, gdm_chooser_session, G_TYPE_OBJECT) - -static gpointer session_object = NULL; - -static gboolean -launch_compiz (GdmChooserSession *session) -{ - GError *error; - gboolean ret; - - g_debug ("GdmChooserSession: Launching compiz"); - - ret = FALSE; - - error = NULL; - g_spawn_command_line_async ("gtk-window-decorator --replace", &error); - if (error != NULL) { - g_warning ("Error starting WM: %s", error->message); - g_error_free (error); - goto out; - } - - error = NULL; - g_spawn_command_line_async ("compiz --replace", &error); - if (error != NULL) { - g_warning ("Error starting WM: %s", error->message); - g_error_free (error); - goto out; - } - - ret = TRUE; - - /* FIXME: should try to detect if it actually works */ - - out: - return ret; -} - -static gboolean -launch_metacity (GdmChooserSession *session) -{ - GError *error; - gboolean ret; - - g_debug ("GdmChooserSession: Launching metacity"); - - ret = FALSE; - - error = NULL; - g_spawn_command_line_async ("metacity --replace", &error); - if (error != NULL) { - g_warning ("Error starting WM: %s", error->message); - g_error_free (error); - goto out; - } - - ret = TRUE; - - out: - return ret; -} - -static void -start_window_manager (GdmChooserSession *session) -{ - if (! launch_metacity (session)) { - launch_compiz (session); - } -} - -static gboolean -start_settings_daemon (GdmChooserSession *session) -{ - GError *error; - gboolean ret; - - g_debug ("GdmChooserSession: Launching settings daemon"); - - ret = FALSE; - - error = NULL; - g_spawn_command_line_async (GNOME_SETTINGS_DAEMON_DIR "/gnome-settings-daemon", &error); - if (error != NULL) { - g_warning ("Error starting settings daemon: %s", error->message); - g_error_free (error); - goto out; - } - - ret = TRUE; - - out: - return ret; -} - -static void -on_dialog_response (GtkDialog *dialog, - int response_id, - GdmChooserSession *session) -{ - GdmChooserHost *host; - GError *error = NULL; - - host = NULL; - switch (response_id) { - case GTK_RESPONSE_OK: - host = gdm_host_chooser_dialog_get_host (GDM_HOST_CHOOSER_DIALOG (dialog)); - case GTK_RESPONSE_NONE: - /* delete event */ - default: - break; - } - - if (host != NULL) { - char *hostname; - - /* only support XDMCP hosts in remote chooser */ - g_assert (gdm_chooser_host_get_kind (host) == GDM_CHOOSER_HOST_KIND_XDMCP); - - hostname = NULL; - gdm_address_get_hostname (gdm_chooser_host_get_address (host), &hostname); - /* FIXME: fall back to numerical address? */ - if (hostname != NULL) { - g_debug ("GdmChooserSession: Selected hostname '%s'", hostname); - gdm_chooser_call_select_hostname_sync (session->priv->chooser, - hostname, - NULL, - &error); - - if (error != NULL) { - g_debug ("GdmChooserSession: %s", error->message); - g_clear_error (&error); - } - g_free (hostname); - } - } - - gdm_remote_greeter_call_disconnect_sync (session->priv->remote_greeter, - NULL, - &error); - if (error != NULL) { - g_debug ("GdmChooserSession: disconnect failed: %s", error->message); - } -} - -gboolean -gdm_chooser_session_start (GdmChooserSession *session, - GError **error) -{ - g_return_val_if_fail (GDM_IS_CHOOSER_SESSION (session), FALSE); - - session->priv->remote_greeter = gdm_client_get_remote_greeter_sync (session->priv->client, - NULL, - error); - if (session->priv->remote_greeter == NULL) { - return FALSE; - } - - session->priv->chooser = gdm_client_get_chooser_sync (session->priv->client, - NULL, - error); - if (session->priv->chooser == NULL) { - return FALSE; - } - - start_settings_daemon (session); - start_window_manager (session); - - /* Only support XDMCP on remote choosers */ - session->priv->chooser_dialog = gdm_host_chooser_dialog_new (GDM_CHOOSER_HOST_KIND_XDMCP); - g_signal_connect (session->priv->chooser_dialog, - "response", - G_CALLBACK (on_dialog_response), - session); - gtk_widget_show (session->priv->chooser_dialog); - - return TRUE; -} - -void -gdm_chooser_session_stop (GdmChooserSession *session) -{ - g_return_if_fail (GDM_IS_CHOOSER_SESSION (session)); - -} - -static void -gdm_chooser_session_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_chooser_session_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GObject * -gdm_chooser_session_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - GdmChooserSession *chooser_session; - - chooser_session = GDM_CHOOSER_SESSION (G_OBJECT_CLASS (gdm_chooser_session_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - return G_OBJECT (chooser_session); -} - -static void -gdm_chooser_session_dispose (GObject *object) -{ - g_debug ("GdmChooserSession: Disposing chooser_session"); - - G_OBJECT_CLASS (gdm_chooser_session_parent_class)->dispose (object); -} - -static void -gdm_chooser_session_class_init (GdmChooserSessionClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gdm_chooser_session_get_property; - object_class->set_property = gdm_chooser_session_set_property; - object_class->constructor = gdm_chooser_session_constructor; - object_class->dispose = gdm_chooser_session_dispose; - object_class->finalize = gdm_chooser_session_finalize; - - g_type_class_add_private (klass, sizeof (GdmChooserSessionPrivate)); -} - -static void -gdm_chooser_session_init (GdmChooserSession *session) -{ - - session->priv = GDM_CHOOSER_SESSION_GET_PRIVATE (session); - - session->priv->client = gdm_client_new (); -} - -static void -gdm_chooser_session_finalize (GObject *object) -{ - GdmChooserSession *chooser_session; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_CHOOSER_SESSION (object)); - - chooser_session = GDM_CHOOSER_SESSION (object); - - g_return_if_fail (chooser_session->priv != NULL); - - g_clear_object (&chooser_session->priv->chooser); - g_clear_object (&chooser_session->priv->remote_greeter); - g_clear_object (&chooser_session->priv->client); - - G_OBJECT_CLASS (gdm_chooser_session_parent_class)->finalize (object); -} - -GdmChooserSession * -gdm_chooser_session_new (void) -{ - if (session_object != NULL) { - g_object_ref (session_object); - } else { - session_object = g_object_new (GDM_TYPE_CHOOSER_SESSION, NULL); - g_object_add_weak_pointer (session_object, - (gpointer *) &session_object); - } - - return GDM_CHOOSER_SESSION (session_object); -} diff --git a/gui/simple-chooser/gdm-chooser-session.h b/gui/simple-chooser/gdm-chooser-session.h deleted file mode 100644 index b6d8ccdf..00000000 --- a/gui/simple-chooser/gdm-chooser-session.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GDM_CHOOSER_SESSION_H -#define __GDM_CHOOSER_SESSION_H - -#include - -G_BEGIN_DECLS - -#define GDM_TYPE_CHOOSER_SESSION (gdm_chooser_session_get_type ()) -#define GDM_CHOOSER_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_CHOOSER_SESSION, GdmChooserSession)) -#define GDM_CHOOSER_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_CHOOSER_SESSION, GdmChooserSessionClass)) -#define GDM_IS_CHOOSER_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_CHOOSER_SESSION)) -#define GDM_IS_CHOOSER_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_CHOOSER_SESSION)) -#define GDM_CHOOSER_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_CHOOSER_SESSION, GdmChooserSessionClass)) - -typedef struct GdmChooserSessionPrivate GdmChooserSessionPrivate; - -typedef struct -{ - GObject parent; - GdmChooserSessionPrivate *priv; -} GdmChooserSession; - -typedef struct -{ - GObjectClass parent_class; -} GdmChooserSessionClass; - -GType gdm_chooser_session_get_type (void); - -GdmChooserSession * gdm_chooser_session_new (void); - -gboolean gdm_chooser_session_start (GdmChooserSession *session, - GError **error); -void gdm_chooser_session_stop (GdmChooserSession *session); - -G_END_DECLS - -#endif /* __GDM_CHOOSER_SESSION_H */ diff --git a/gui/simple-chooser/gdm-host-chooser-dialog.c b/gui/simple-chooser/gdm-host-chooser-dialog.c deleted file mode 100644 index 02169502..00000000 --- a/gui/simple-chooser/gdm-host-chooser-dialog.c +++ /dev/null @@ -1,223 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "gdm-host-chooser-dialog.h" -#include "gdm-host-chooser-widget.h" - -#define GDM_HOST_CHOOSER_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_HOST_CHOOSER_DIALOG, GdmHostChooserDialogPrivate)) - -struct GdmHostChooserDialogPrivate -{ - GtkWidget *chooser_widget; - int kind_mask; -}; - -enum { - PROP_0, - PROP_KIND_MASK, -}; - -static void gdm_host_chooser_dialog_class_init (GdmHostChooserDialogClass *klass); -static void gdm_host_chooser_dialog_init (GdmHostChooserDialog *host_chooser_dialog); -static void gdm_host_chooser_dialog_finalize (GObject *object); - -G_DEFINE_TYPE (GdmHostChooserDialog, gdm_host_chooser_dialog, GTK_TYPE_DIALOG) - -GdmChooserHost * -gdm_host_chooser_dialog_get_host (GdmHostChooserDialog *dialog) -{ - GdmChooserHost *host; - - g_return_val_if_fail (GDM_IS_HOST_CHOOSER_DIALOG (dialog), NULL); - - host = gdm_host_chooser_widget_get_host (GDM_HOST_CHOOSER_WIDGET (dialog->priv->chooser_widget)); - - return host; -} - -static void -_gdm_host_chooser_dialog_set_kind_mask (GdmHostChooserDialog *dialog, - int kind_mask) -{ - if (dialog->priv->kind_mask != kind_mask) { - dialog->priv->kind_mask = kind_mask; - } -} - -static void -gdm_host_chooser_dialog_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdmHostChooserDialog *self; - - self = GDM_HOST_CHOOSER_DIALOG (object); - - switch (prop_id) { - case PROP_KIND_MASK: - _gdm_host_chooser_dialog_set_kind_mask (self, g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_host_chooser_dialog_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -on_response (GdmHostChooserDialog *dialog, - gint response_id) -{ - switch (response_id) { - case GTK_RESPONSE_APPLY: - gdm_host_chooser_widget_refresh (GDM_HOST_CHOOSER_WIDGET (dialog->priv->chooser_widget)); - g_signal_stop_emission_by_name (dialog, "response"); - break; - default: - break; - } -} - -static GObject * -gdm_host_chooser_dialog_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - GdmHostChooserDialog *dialog; - - dialog = GDM_HOST_CHOOSER_DIALOG (G_OBJECT_CLASS (gdm_host_chooser_dialog_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - - dialog->priv->chooser_widget = gdm_host_chooser_widget_new (dialog->priv->kind_mask); - gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), dialog->priv->chooser_widget); - gtk_container_set_border_width (GTK_CONTAINER (dialog->priv->chooser_widget), 5); - - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - GTK_STOCK_REFRESH, GTK_RESPONSE_APPLY, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_CONNECT, GTK_RESPONSE_OK, - NULL); - - gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS); - gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); - gtk_window_set_title (GTK_WINDOW (dialog), _("Select System")); - gtk_window_set_icon_name (GTK_WINDOW (dialog), "computer"); - - g_signal_connect (dialog, - "response", - G_CALLBACK (on_response), - dialog); - - gtk_widget_show_all (GTK_WIDGET (dialog)); - - return G_OBJECT (dialog); -} - -static void -gdm_host_chooser_dialog_dispose (GObject *object) -{ - g_debug ("Disposing host_chooser_dialog"); - - G_OBJECT_CLASS (gdm_host_chooser_dialog_parent_class)->dispose (object); -} - -static void -gdm_host_chooser_dialog_class_init (GdmHostChooserDialogClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gdm_host_chooser_dialog_get_property; - object_class->set_property = gdm_host_chooser_dialog_set_property; - object_class->constructor = gdm_host_chooser_dialog_constructor; - object_class->dispose = gdm_host_chooser_dialog_dispose; - object_class->finalize = gdm_host_chooser_dialog_finalize; - - g_object_class_install_property (object_class, - PROP_KIND_MASK, - g_param_spec_int ("kind-mask", - "kind mask", - "kind mask", - 0, - G_MAXINT, - 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_type_class_add_private (klass, sizeof (GdmHostChooserDialogPrivate)); -} - -static void -gdm_host_chooser_dialog_init (GdmHostChooserDialog *dialog) -{ - dialog->priv = GDM_HOST_CHOOSER_DIALOG_GET_PRIVATE (dialog); -} - -static void -gdm_host_chooser_dialog_finalize (GObject *object) -{ - GdmHostChooserDialog *host_chooser_dialog; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_HOST_CHOOSER_DIALOG (object)); - - host_chooser_dialog = GDM_HOST_CHOOSER_DIALOG (object); - - g_return_if_fail (host_chooser_dialog->priv != NULL); - - G_OBJECT_CLASS (gdm_host_chooser_dialog_parent_class)->finalize (object); -} - -GtkWidget * -gdm_host_chooser_dialog_new (int kind_mask) -{ - GObject *object; - - object = g_object_new (GDM_TYPE_HOST_CHOOSER_DIALOG, - "kind-mask", kind_mask, - NULL); - - return GTK_WIDGET (object); -} diff --git a/gui/simple-chooser/gdm-host-chooser-dialog.h b/gui/simple-chooser/gdm-host-chooser-dialog.h deleted file mode 100644 index f413091b..00000000 --- a/gui/simple-chooser/gdm-host-chooser-dialog.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GDM_HOST_CHOOSER_DIALOG_H -#define __GDM_HOST_CHOOSER_DIALOG_H - -#include -#include -#include "gdm-chooser-host.h" - -G_BEGIN_DECLS - -#define GDM_TYPE_HOST_CHOOSER_DIALOG (gdm_host_chooser_dialog_get_type ()) -#define GDM_HOST_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_HOST_CHOOSER_DIALOG, GdmHostChooserDialog)) -#define GDM_HOST_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_HOST_CHOOSER_DIALOG, GdmHostChooserDialogClass)) -#define GDM_IS_HOST_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_HOST_CHOOSER_DIALOG)) -#define GDM_IS_HOST_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_HOST_CHOOSER_DIALOG)) -#define GDM_HOST_CHOOSER_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_HOST_CHOOSER_DIALOG, GdmHostChooserDialogClass)) - -typedef struct GdmHostChooserDialogPrivate GdmHostChooserDialogPrivate; - -typedef struct -{ - GtkDialog parent; - GdmHostChooserDialogPrivate *priv; -} GdmHostChooserDialog; - -typedef struct -{ - GtkDialogClass parent_class; -} GdmHostChooserDialogClass; - -GType gdm_host_chooser_dialog_get_type (void); - -GtkWidget * gdm_host_chooser_dialog_new (int kind_mask); -void gdm_host_chooser_dialog_set_kind_mask (GdmHostChooserDialog *dialog, - int kind_mask); - -GdmChooserHost * gdm_host_chooser_dialog_get_host (GdmHostChooserDialog *dialog); - -G_END_DECLS - -#endif /* __GDM_HOST_CHOOSER_DIALOG_H */ diff --git a/gui/simple-chooser/gdm-host-chooser-widget.c b/gui/simple-chooser/gdm-host-chooser-widget.c deleted file mode 100644 index f9200aa0..00000000 --- a/gui/simple-chooser/gdm-host-chooser-widget.c +++ /dev/null @@ -1,860 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 1998, 1999, 2000 Martin K, Petersen - * Copyright (C) 2007 William Jon McCann - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif - -#include -#include - -#include -#include -#include -#include - -#include "gdm-address.h" -#include "gdm-chooser-host.h" -#include "gdm-host-chooser-widget.h" - -#define GDM_HOST_CHOOSER_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_HOST_CHOOSER_WIDGET, GdmHostChooserWidgetPrivate)) - -struct GdmHostChooserWidgetPrivate -{ - GtkWidget *treeview; - - int kind_mask; - - char **hosts; - - XdmcpBuffer broadcast_buf; - XdmcpBuffer query_buf; - gboolean have_ipv6; - int socket_fd; - guint io_watch_id; - guint scan_time_id; - guint ping_try_id; - - int ping_tries; - - GSList *broadcast_addresses; - GSList *query_addresses; - GSList *chooser_hosts; - - GdmChooserHost *current_host; -}; - -enum { - PROP_0, - PROP_KIND_MASK, -}; - -enum { - HOST_ACTIVATED, - LAST_SIGNAL -}; - -static guint signals [LAST_SIGNAL] = { 0, }; - -static void gdm_host_chooser_widget_class_init (GdmHostChooserWidgetClass *klass); -static void gdm_host_chooser_widget_init (GdmHostChooserWidget *host_chooser_widget); -static void gdm_host_chooser_widget_finalize (GObject *object); - -G_DEFINE_TYPE (GdmHostChooserWidget, gdm_host_chooser_widget, GTK_TYPE_VBOX) - -#define GDM_XDMCP_PROTOCOL_VERSION 1001 -#define SCAN_TIMEOUT 30 -#define PING_TIMEOUT 2 -#define PING_TRIES 3 - -enum { - CHOOSER_LIST_ICON_COLUMN = 0, - CHOOSER_LIST_LABEL_COLUMN, - CHOOSER_LIST_HOST_COLUMN -}; - -static void -chooser_host_add (GdmHostChooserWidget *widget, - GdmChooserHost *host) -{ - widget->priv->chooser_hosts = g_slist_prepend (widget->priv->chooser_hosts, host); -} - -#if 0 -static void -chooser_host_remove (GdmHostChooserWidget *widget, - GdmChooserHost *host) -{ - widget->priv->chooser_hosts = g_slist_remove (widget->priv->chooser_hosts, host); -} -#endif - -static GdmChooserHost * -find_known_host (GdmHostChooserWidget *widget, - GdmAddress *address) -{ - GSList *li; - GdmChooserHost *host; - - for (li = widget->priv->chooser_hosts; li != NULL; li = li->next) { - host = li->data; - if (gdm_address_equal (gdm_chooser_host_get_address (host), address)) { - goto out; - } - } - - host = NULL; - out: - - return host; -} - -static void -browser_add_host (GdmHostChooserWidget *widget, - GdmChooserHost *host) -{ - char *hostname; - char *name; - char *desc; - char *label; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean res; - - g_assert (host != NULL); - - if (! gdm_chooser_host_get_willing (host)) { - gtk_widget_set_sensitive (GTK_WIDGET (widget), TRUE); - return; - } - - res = gdm_address_get_hostname (gdm_chooser_host_get_address (host), &hostname); - if (! res) { - gdm_address_get_numeric_info (gdm_chooser_host_get_address (host), &hostname, NULL); - } - - name = g_markup_escape_text (hostname, -1); - desc = g_markup_escape_text (gdm_chooser_host_get_description (host), -1); - label = g_strdup_printf ("%s\n%s", name, desc); - g_free (name); - g_free (desc); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget->priv->treeview)); - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - CHOOSER_LIST_ICON_COLUMN, NULL, - CHOOSER_LIST_LABEL_COLUMN, label, - CHOOSER_LIST_HOST_COLUMN, host, - -1); - g_free (label); - -} - -static gboolean -decode_packet (GIOChannel *source, - GIOCondition condition, - GdmHostChooserWidget *widget) -{ - struct sockaddr_storage clnt_ss; - GdmAddress *address; - int ss_len; - XdmcpHeader header; - int res; - static XdmcpBuffer buf; - ARRAY8 auth = {0}; - ARRAY8 host = {0}; - ARRAY8 stat = {0}; - char *status; - GdmChooserHost *chooser_host; - - status = NULL; - address = NULL; - - g_debug ("decode_packet: GIOCondition %d", (int)condition); - - if ( ! (condition & G_IO_IN)) { - return TRUE; - } - - ss_len = (int) sizeof (clnt_ss); - - res = XdmcpFill (widget->priv->socket_fd, &buf, (XdmcpNetaddr)&clnt_ss, &ss_len); - if G_UNLIKELY (! res) { - g_debug (_("XDMCP: Could not create XDMCP buffer!")); - return TRUE; - } - - res = XdmcpReadHeader (&buf, &header); - if G_UNLIKELY (! res) { - g_warning (_("XDMCP: Could not read XDMCP header!")); - return TRUE; - } - - if G_UNLIKELY (header.version != XDM_PROTOCOL_VERSION && - header.version != GDM_XDMCP_PROTOCOL_VERSION) { - g_warning (_("XDMCP: Incorrect XDMCP version!")); - return TRUE; - } - - address = gdm_address_new_from_sockaddr ((struct sockaddr *) &clnt_ss, ss_len); - if (address == NULL) { - g_warning (_("XDMCP: Unable to parse address")); - return TRUE; - } - - gdm_address_debug (address); - - if (header.opcode == WILLING) { - if (! XdmcpReadARRAY8 (&buf, &auth)) { - goto done; - } - - if (! XdmcpReadARRAY8 (&buf, &host)) { - goto done; - } - - if (! XdmcpReadARRAY8 (&buf, &stat)) { - goto done; - } - - status = g_strndup ((char *) stat.data, MIN (stat.length, 256)); - } else if (header.opcode == UNWILLING) { - /* immaterial, will not be shown */ - status = NULL; - } else { - goto done; - } - - g_debug ("STATUS: %s", status); - - chooser_host = find_known_host (widget, address); - if (chooser_host == NULL) { - chooser_host = g_object_new (GDM_TYPE_CHOOSER_HOST, - "address", address, - "description", status, - "willing", (header.opcode == WILLING), - "kind", GDM_CHOOSER_HOST_KIND_XDMCP, - NULL); - chooser_host_add (widget, chooser_host); - browser_add_host (widget, chooser_host); - } else { - /* server changed it's mind */ - if (header.opcode == WILLING - && ! gdm_chooser_host_get_willing (chooser_host)) { - g_object_set (chooser_host, "willing", TRUE, NULL); - browser_add_host (widget, chooser_host); - } - /* FIXME: handle unwilling? */ - } - - done: - if (header.opcode == WILLING) { - XdmcpDisposeARRAY8 (&auth); - XdmcpDisposeARRAY8 (&host); - XdmcpDisposeARRAY8 (&stat); - } - - g_free (status); - gdm_address_free (address); - - return TRUE; -} - -static void -do_ping (GdmHostChooserWidget *widget, - gboolean full) -{ - GSList *l; - - g_debug ("do ping full:%d", full); - - for (l = widget->priv->broadcast_addresses; l != NULL; l = l->next) { - GdmAddress *address; - int res; - - address = l->data; - - gdm_address_debug (address); - errno = 0; - g_debug ("fd:%d", widget->priv->socket_fd); - res = XdmcpFlush (widget->priv->socket_fd, - &widget->priv->broadcast_buf, - (XdmcpNetaddr)gdm_address_peek_sockaddr_storage (address), - (int)gdm_sockaddr_len (gdm_address_peek_sockaddr_storage (address))); - - if (! res) { - g_warning ("Unable to flush the XDMCP broadcast packet: %s", g_strerror (errno)); - } - } - - if (full) { - for (l = widget->priv->query_addresses; l != NULL; l = l->next) { - GdmAddress *address; - int res; - - address = l->data; - - gdm_address_debug (address); - res = XdmcpFlush (widget->priv->socket_fd, - &widget->priv->query_buf, - (XdmcpNetaddr)gdm_address_peek_sockaddr_storage (address), - (int)gdm_sockaddr_len (gdm_address_peek_sockaddr_storage (address))); - if (! res) { - g_warning ("Unable to flush the XDMCP query packet"); - } - } - } -} - -static gboolean -ping_try (GdmHostChooserWidget *widget) -{ - do_ping (widget, FALSE); - - widget->priv->ping_tries --; - - if (widget->priv->ping_tries <= 0) { - widget->priv->ping_try_id = 0; - return FALSE; - } else { - return TRUE; - } -} - -static void -xdmcp_discover (GdmHostChooserWidget *widget) -{ -#if 0 - gtk_widget_set_sensitive (GTK_WIDGET (manage), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (rescan), FALSE); - gtk_list_store_clear (GTK_LIST_STORE (browser_model)); - gtk_widget_set_sensitive (GTK_WIDGET (browser), FALSE); - gtk_label_set_label (GTK_LABEL (status_label), - _(scanning_message)); - - while (hl) { - gdm_chooser_host_dispose ((GdmChooserHost *) hl->data); - hl = hl->next; - } - - g_list_free (chooser_hosts); - chooser_hosts = NULL; -#endif - - do_ping (widget, TRUE); - -#if 0 - if (widget->priv->scan_time_id > 0) { - g_source_remove (widget->priv->scan_time_id); - } - - widget->priv->scan_time_id = g_timeout_add_seconds (SCAN_TIMEOUT, - chooser_scan_time_update, - widget); -#endif - /* Note we already used up one try */ - widget->priv->ping_tries = PING_TRIES - 1; - if (widget->priv->ping_try_id > 0) { - g_source_remove (widget->priv->ping_try_id); - } - - widget->priv->ping_try_id = g_timeout_add_seconds (PING_TIMEOUT, - (GSourceFunc)ping_try, - widget); -} - -/* Find broadcast address for all active, non pointopoint interfaces */ -static void -find_broadcast_addresses (GdmHostChooserWidget *widget) -{ - int i; - int num; - int sock; - struct ifconf ifc; - char *buf; - struct ifreq *ifr; - - g_debug ("Finding broadcast addresses"); - - sock = socket (AF_INET, SOCK_DGRAM, 0); -#ifdef SIOCGIFNUM - if (ioctl (sock, SIOCGIFNUM, &num) < 0) { - num = 64; - } -#else - num = 64; -#endif - - ifc.ifc_len = sizeof (struct ifreq) * num; - ifc.ifc_buf = buf = g_malloc0 (ifc.ifc_len); - if (ioctl (sock, SIOCGIFCONF, &ifc) < 0) { - g_warning ("Could not get local addresses!"); - goto out; - } - - ifr = ifc.ifc_req; - num = ifc.ifc_len / sizeof (struct ifreq); - for (i = 0 ; i < num ; i++) { - const char *name; - - name = ifr[i].ifr_name; - g_debug ("Checking if %s", name); - if (name != NULL && name[0] != '\0') { - struct ifreq ifreq; - GdmAddress *address; - struct sockaddr_in sin; - - memset (&ifreq, 0, sizeof (ifreq)); - - strncpy (ifreq.ifr_name, - ifr[i].ifr_name, - sizeof (ifreq.ifr_name)); - /* paranoia */ - ifreq.ifr_name[sizeof (ifreq.ifr_name) - 1] = '\0'; - - if ((ioctl (sock, SIOCGIFFLAGS, &ifreq) < 0) && (errno != ENXIO)) { - g_warning ("Could not get SIOCGIFFLAGS for %s", ifr[i].ifr_name); - } - - if ((ifreq.ifr_flags & IFF_UP) == 0 || - (ifreq.ifr_flags & IFF_BROADCAST) == 0 || - ioctl (sock, SIOCGIFBRDADDR, &ifreq) < 0) { - g_debug ("Skipping if %s", name); - continue; - } - - g_memmove (&sin, &ifreq.ifr_broadaddr, sizeof (struct sockaddr_in)); - sin.sin_port = htons (XDM_UDP_PORT); - address = gdm_address_new_from_sockaddr ((struct sockaddr *) &sin, sizeof (sin)); - if (address != NULL) { - g_debug ("Adding if %s", name); - gdm_address_debug (address); - - widget->priv->broadcast_addresses = g_slist_append (widget->priv->broadcast_addresses, address); - } - } - } - out: - g_free (buf); - close (sock); -} - -static void -add_hosts (GdmHostChooserWidget *widget) -{ - int i; - - for (i = 0; widget->priv->hosts != NULL && widget->priv->hosts[i] != NULL; i++) { - struct addrinfo hints; - struct addrinfo *result; - struct addrinfo *ai; - int gaierr; - const char *name; - char serv_buf [NI_MAXSERV]; - const char *serv; - - name = widget->priv->hosts[i]; - - if (strcmp (name, "BROADCAST") == 0) { - find_broadcast_addresses (widget); - continue; - } - - if (strcmp (name, "MULTICAST") == 0) { - /*gdm_chooser_find_mcaddr ();*/ - continue; - } - - result = NULL; - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = SOCK_STREAM; - - snprintf (serv_buf, sizeof (serv_buf), "%u", XDM_UDP_PORT); - serv = serv_buf; - - gaierr = getaddrinfo (name, serv, &hints, &result); - if (gaierr != 0) { - g_warning ("Unable to get address info for name %s: %s", name, gai_strerror (gaierr)); - continue; - } - - for (ai = result; ai != NULL; ai = ai->ai_next) { - GdmAddress *address; - - address = gdm_address_new_from_sockaddr (ai->ai_addr, ai->ai_addrlen); - if (address != NULL) { - widget->priv->query_addresses = g_slist_append (widget->priv->query_addresses, address); - } - } - - freeaddrinfo (result); - } - - if (widget->priv->broadcast_addresses == NULL && widget->priv->query_addresses == NULL) { - find_broadcast_addresses (widget); - } -} - -static void -xdmcp_init (GdmHostChooserWidget *widget) -{ - XdmcpHeader header; - int sockopts; - int res; - GIOChannel *ioc; - ARRAYofARRAY8 aanames; - - sockopts = 1; - - widget->priv->socket_fd = -1; - - /* Open socket for communication */ -#ifdef ENABLE_IPV6 - widget->priv->socket_fd = socket (AF_INET6, SOCK_DGRAM, 0); - if (widget->priv->socket_fd != -1) { - widget->priv->have_ipv6 = TRUE; -#ifdef IPV6_V6ONLY - { - int zero = 0; - if (setsockopt(widget->priv->socket_fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)) < 0) - g_warning("setsockopt(IPV6_V6ONLY): %s", g_strerror(errno)); - } -#endif - } -#endif - if (! widget->priv->have_ipv6) { - widget->priv->socket_fd = socket (AF_INET, SOCK_DGRAM, 0); - if (widget->priv->socket_fd == -1) { - g_critical ("Could not create socket!"); - } - } - - res = setsockopt (widget->priv->socket_fd, - SOL_SOCKET, - SO_BROADCAST, - (char *) &sockopts, - sizeof (sockopts)); - if (res < 0) { - g_critical ("Could not set socket options!"); - } - - /* Assemble XDMCP BROADCAST_QUERY packet in static buffer */ - memset (&header, 0, sizeof (XdmcpHeader)); - header.opcode = (CARD16) BROADCAST_QUERY; - header.length = 1; - header.version = XDM_PROTOCOL_VERSION; - aanames.length = 0; - XdmcpWriteHeader (&widget->priv->broadcast_buf, &header); - XdmcpWriteARRAYofARRAY8 (&widget->priv->broadcast_buf, &aanames); - - /* Assemble XDMCP QUERY packet in static buffer */ - memset (&header, 0, sizeof (XdmcpHeader)); - header.opcode = (CARD16) QUERY; - header.length = 1; - header.version = XDM_PROTOCOL_VERSION; - memset (&widget->priv->query_buf, 0, sizeof (XdmcpBuffer)); - XdmcpWriteHeader (&widget->priv->query_buf, &header); - XdmcpWriteARRAYofARRAY8 (&widget->priv->query_buf, &aanames); - - add_hosts (widget); - - ioc = g_io_channel_unix_new (widget->priv->socket_fd); - g_io_channel_set_encoding (ioc, NULL, NULL); - g_io_channel_set_buffered (ioc, FALSE); - widget->priv->io_watch_id = g_io_add_watch (ioc, - G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL, - (GIOFunc)decode_packet, - widget); - g_io_channel_unref (ioc); -} - -void -gdm_host_chooser_widget_refresh (GdmHostChooserWidget *widget) -{ - g_return_if_fail (GDM_IS_HOST_CHOOSER_WIDGET (widget)); - - xdmcp_discover (widget); -} - -GdmChooserHost * -gdm_host_chooser_widget_get_host (GdmHostChooserWidget *widget) -{ - GdmChooserHost *host; - - g_return_val_if_fail (GDM_IS_HOST_CHOOSER_WIDGET (widget), NULL); - - host = NULL; - if (widget->priv->current_host != NULL) { - host = g_object_ref (widget->priv->current_host); - } - - return host; -} - -static void -_gdm_host_chooser_widget_set_kind_mask (GdmHostChooserWidget *widget, - int kind_mask) -{ - if (widget->priv->kind_mask != kind_mask) { - widget->priv->kind_mask = kind_mask; - } -} - -static void -gdm_host_chooser_widget_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdmHostChooserWidget *self; - - self = GDM_HOST_CHOOSER_WIDGET (object); - - switch (prop_id) { - case PROP_KIND_MASK: - _gdm_host_chooser_widget_set_kind_mask (self, g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_host_chooser_widget_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GObject * -gdm_host_chooser_widget_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - GdmHostChooserWidget *widget; - - widget = GDM_HOST_CHOOSER_WIDGET (G_OBJECT_CLASS (gdm_host_chooser_widget_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - xdmcp_init (widget); - xdmcp_discover (widget); - - return G_OBJECT (widget); -} - -static void -gdm_host_chooser_widget_dispose (GObject *object) -{ - GdmHostChooserWidget *widget; - - widget = GDM_HOST_CHOOSER_WIDGET (object); - - g_debug ("Disposing host_chooser_widget"); - - if (widget->priv->broadcast_addresses != NULL) { - g_slist_foreach (widget->priv->broadcast_addresses, - (GFunc)gdm_address_free, - NULL); - g_slist_free (widget->priv->broadcast_addresses); - widget->priv->broadcast_addresses = NULL; - } - if (widget->priv->query_addresses != NULL) { - g_slist_foreach (widget->priv->query_addresses, - (GFunc)gdm_address_free, - NULL); - g_slist_free (widget->priv->query_addresses); - widget->priv->query_addresses = NULL; - } - if (widget->priv->chooser_hosts != NULL) { - g_slist_foreach (widget->priv->chooser_hosts, - (GFunc)g_object_unref, - NULL); - g_slist_free (widget->priv->chooser_hosts); - widget->priv->chooser_hosts = NULL; - } - - widget->priv->current_host = NULL; - - G_OBJECT_CLASS (gdm_host_chooser_widget_parent_class)->dispose (object); -} - -static void -gdm_host_chooser_widget_class_init (GdmHostChooserWidgetClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gdm_host_chooser_widget_get_property; - object_class->set_property = gdm_host_chooser_widget_set_property; - object_class->constructor = gdm_host_chooser_widget_constructor; - object_class->dispose = gdm_host_chooser_widget_dispose; - object_class->finalize = gdm_host_chooser_widget_finalize; - - g_object_class_install_property (object_class, - PROP_KIND_MASK, - g_param_spec_int ("kind-mask", - "kind mask", - "kind mask", - 0, - G_MAXINT, - 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - signals [HOST_ACTIVATED] = g_signal_new ("host-activated", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdmHostChooserWidgetClass, host_activated), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - g_type_class_add_private (klass, sizeof (GdmHostChooserWidgetPrivate)); -} - -static void -on_host_selected (GtkTreeSelection *selection, - GdmHostChooserWidget *widget) -{ - GtkTreeModel *model = NULL; - GtkTreeIter iter = {0}; - GdmChooserHost *curhost; - - curhost = NULL; - - if (gtk_tree_selection_get_selected (selection, &model, &iter)) { - gtk_tree_model_get (model, &iter, CHOOSER_LIST_HOST_COLUMN, &curhost, -1); - } - - widget->priv->current_host = curhost; -} - -static void -on_row_activated (GtkTreeView *tree_view, - GtkTreePath *tree_path, - GtkTreeViewColumn *tree_column, - GdmHostChooserWidget *widget) -{ - g_signal_emit (widget, signals[HOST_ACTIVATED], 0); -} - -static void -gdm_host_chooser_widget_init (GdmHostChooserWidget *widget) -{ - GtkWidget *scrolled; - GtkTreeSelection *selection; - GtkTreeViewColumn *column; - GtkTreeModel *model; - - widget->priv = GDM_HOST_CHOOSER_WIDGET_GET_PRIVATE (widget); - - scrolled = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_box_pack_start (GTK_BOX (widget), scrolled, TRUE, TRUE, 0); - - widget->priv->treeview = gtk_tree_view_new (); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget->priv->treeview), FALSE); - g_signal_connect (widget->priv->treeview, - "row-activated", - G_CALLBACK (on_row_activated), - widget); - gtk_container_add (GTK_CONTAINER (scrolled), widget->priv->treeview); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget->priv->treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - g_signal_connect (selection, "changed", - G_CALLBACK (on_host_selected), - widget); - - model = (GtkTreeModel *)gtk_list_store_new (3, - GDK_TYPE_PIXBUF, - G_TYPE_STRING, - G_TYPE_POINTER); - gtk_tree_view_set_model (GTK_TREE_VIEW (widget->priv->treeview), model); - - column = gtk_tree_view_column_new_with_attributes ("Icon", - gtk_cell_renderer_pixbuf_new (), - "pixbuf", CHOOSER_LIST_ICON_COLUMN, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (widget->priv->treeview), column); - - column = gtk_tree_view_column_new_with_attributes ("Hostname", - gtk_cell_renderer_text_new (), - "markup", CHOOSER_LIST_LABEL_COLUMN, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (widget->priv->treeview), column); - - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), - CHOOSER_LIST_LABEL_COLUMN, - GTK_SORT_ASCENDING); -} - -static void -gdm_host_chooser_widget_finalize (GObject *object) -{ - GdmHostChooserWidget *host_chooser_widget; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_HOST_CHOOSER_WIDGET (object)); - - host_chooser_widget = GDM_HOST_CHOOSER_WIDGET (object); - - g_return_if_fail (host_chooser_widget->priv != NULL); - - G_OBJECT_CLASS (gdm_host_chooser_widget_parent_class)->finalize (object); -} - -GtkWidget * -gdm_host_chooser_widget_new (int kind_mask) -{ - GObject *object; - - object = g_object_new (GDM_TYPE_HOST_CHOOSER_WIDGET, - "kind-mask", kind_mask, - NULL); - - return GTK_WIDGET (object); -} diff --git a/gui/simple-chooser/gdm-host-chooser-widget.h b/gui/simple-chooser/gdm-host-chooser-widget.h deleted file mode 100644 index 739eac01..00000000 --- a/gui/simple-chooser/gdm-host-chooser-widget.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GDM_HOST_CHOOSER_WIDGET_H -#define __GDM_HOST_CHOOSER_WIDGET_H - -#include -#include -#include "gdm-chooser-host.h" - -G_BEGIN_DECLS - -#define GDM_TYPE_HOST_CHOOSER_WIDGET (gdm_host_chooser_widget_get_type ()) -#define GDM_HOST_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_HOST_CHOOSER_WIDGET, GdmHostChooserWidget)) -#define GDM_HOST_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_HOST_CHOOSER_WIDGET, GdmHostChooserWidgetClass)) -#define GDM_IS_HOST_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_HOST_CHOOSER_WIDGET)) -#define GDM_IS_HOST_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_HOST_CHOOSER_WIDGET)) -#define GDM_HOST_CHOOSER_WIDGET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_HOST_CHOOSER_WIDGET, GdmHostChooserWidgetClass)) - -typedef struct GdmHostChooserWidgetPrivate GdmHostChooserWidgetPrivate; - -typedef struct -{ - GtkVBox parent; - GdmHostChooserWidgetPrivate *priv; -} GdmHostChooserWidget; - -typedef struct -{ - GtkVBoxClass parent_class; - - /* signals */ - void (* host_activated) (GdmHostChooserWidget *widget); -} GdmHostChooserWidgetClass; - -GType gdm_host_chooser_widget_get_type (void); -GtkWidget * gdm_host_chooser_widget_new (int kind_mask); - -void gdm_host_chooser_widget_set_kind_mask (GdmHostChooserWidget *widget, - int kind_mask); - -void gdm_host_chooser_widget_refresh (GdmHostChooserWidget *widget); - -GdmChooserHost * gdm_host_chooser_widget_get_host (GdmHostChooserWidget *widget); - -G_END_DECLS - -#endif /* __GDM_HOST_CHOOSER_WIDGET_H */ diff --git a/gui/simple-chooser/gdm-host-chooser.c b/gui/simple-chooser/gdm-host-chooser.c deleted file mode 100644 index 47f37d47..00000000 --- a/gui/simple-chooser/gdm-host-chooser.c +++ /dev/null @@ -1,252 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "gdm-common.h" -#include "gdm-log.h" - -#include "gdm-chooser-host.h" -#include "gdm-host-chooser-dialog.h" - -#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility" - -static Atom AT_SPI_IOR; - - -static gboolean -assistive_registry_launch (void) -{ - GPid pid; - GError *error; - const char *command; - char **argv; - gboolean res; - - command = AT_SPI_REGISTRYD_DIR "/at-spi-registryd"; - - argv = NULL; - error = NULL; - res = g_shell_parse_argv (command, NULL, &argv, &error); - if (! res) { - g_warning ("Unable to parse command: %s", error->message); - return FALSE; - } - - error = NULL; - res = g_spawn_async (NULL, - argv, - NULL, - G_SPAWN_SEARCH_PATH - | G_SPAWN_STDOUT_TO_DEV_NULL - | G_SPAWN_STDERR_TO_DEV_NULL, - NULL, - NULL, - &pid, - &error); - g_strfreev (argv); - - if (! res) { - g_warning ("Unable to run command %s: %s", command, error->message); - return FALSE; - } - - if (kill (pid, 0) < 0) { - g_warning ("at-spi-registryd not running"); - return FALSE; - } - - return TRUE; -} - -static GdkFilterReturn -filter_watch (GdkXEvent *xevent, - GdkEvent *event, - gpointer data) -{ - XEvent *xev = (XEvent *)xevent; - - if (xev->xany.type == PropertyNotify - && xev->xproperty.atom == AT_SPI_IOR) { - gtk_main_quit (); - - return GDK_FILTER_REMOVE; - } - - return GDK_FILTER_CONTINUE; -} - -static gboolean -filter_timeout (gpointer data) -{ - g_warning ("The accessibility registry was not found."); - - gtk_main_quit (); - - return FALSE; -} - -static void -assistive_registry_start (void) -{ - GdkWindow *root; - guint tid; - - root = gdk_get_default_root_window (); - - if ( ! AT_SPI_IOR) { - AT_SPI_IOR = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "AT_SPI_IOR", False); - } - - gdk_window_set_events (root, GDK_PROPERTY_CHANGE_MASK); - - if ( ! assistive_registry_launch ()) { - g_warning ("The accessibility registry could not be started."); - return; - } - - gdk_window_add_filter (root, filter_watch, NULL); - tid = g_timeout_add_seconds (5, filter_timeout, NULL); - - gtk_main (); - - gdk_window_remove_filter (root, filter_watch, NULL); - g_source_remove (tid); -} - -static void -at_set_gtk_modules (void) -{ - GSList *modules_list; - GSList *l; - const char *old; - char **modules; - gboolean found_gail; - gboolean found_atk_bridge; - int n; - - n = 0; - modules_list = NULL; - found_gail = FALSE; - found_atk_bridge = FALSE; - - if ((old = g_getenv ("GTK_MODULES")) != NULL) { - modules = g_strsplit (old, ":", -1); - for (n = 0; modules[n]; n++) { - if (!strcmp (modules[n], "gail")) { - found_gail = TRUE; - } else if (!strcmp (modules[n], "atk-bridge")) { - found_atk_bridge = TRUE; - } - - modules_list = g_slist_prepend (modules_list, modules[n]); - modules[n] = NULL; - } - g_free (modules); - } - - if (!found_gail) { - modules_list = g_slist_prepend (modules_list, "gail"); - ++n; - } - - if (!found_atk_bridge) { - modules_list = g_slist_prepend (modules_list, "atk-bridge"); - ++n; - } - - modules = g_new (char *, n + 1); - modules[n--] = NULL; - for (l = modules_list; l; l = l->next) { - modules[n--] = g_strdup (l->data); - } - - g_setenv ("GTK_MODULES", g_strjoinv (":", modules), TRUE); - g_strfreev (modules); - g_slist_free (modules_list); -} - -static void -load_a11y (void) -{ - assistive_registry_start (); - at_set_gtk_modules (); -} - -int -main (int argc, char *argv[]) -{ - GtkWidget *chooser; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - setlocale (LC_ALL, ""); - - gdm_log_init (); - gdm_log_set_debug (TRUE); - - g_debug ("Chooser for display %s xauthority:%s", - g_getenv ("DISPLAY"), - g_getenv ("XAUTHORITY")); - - gdk_init (&argc, &argv); - - load_a11y (); - - gtk_init (&argc, &argv); - - chooser = gdm_host_chooser_dialog_new (GDM_CHOOSER_HOST_KIND_MASK_ALL); - gtk_widget_set_size_request (chooser, 480, 600); - - if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_OK) { - GdmChooserHost *host; - - host = gdm_host_chooser_dialog_get_host (GDM_HOST_CHOOSER_DIALOG (chooser)); - if (host != NULL) { - char *hostname; - /* FIXME: handle different host types here? */ - - hostname = NULL; - gdm_address_get_hostname (gdm_chooser_host_get_address (host), &hostname); - /* FIXME: fall back to numerical address? */ - if (hostname != NULL) { - g_print ("hostname: %s\n", hostname); - g_free (hostname); - } - } - } - - gtk_widget_destroy (chooser); - - return 0; -} -- cgit v1.2.1