--- a/patches/SUNWtgnome-xagent-01-trusted-extensions.diff Mon Jul 21 15:59:36 2008 +0000
+++ b/patches/SUNWtgnome-xagent-01-trusted-extensions.diff Mon Jul 21 16:06:58 2008 +0000
@@ -1,285 +1,226 @@
-diff -urN -x '*.orig' gnome-session-2.22.2/gnome-session/Makefile.am ../SUNWtgnome-xagent-2.21.4.hacked/gnome-session-2.22.2/gnome-session/Makefile.am
---- gnome-session-2.22.2/gnome-session/Makefile.am 2008-01-11 17:50:08.036684000 +0000
-+++ ../SUNWtgnome-xagent-2.22.2.hacked/gnome-session-2.20.3/gnome-session/Makefile.am 2008-01-11 17:49:03.375239000 +0000
-@@ -4,6 +4,7 @@
+diff -urN xagent.orig/gnome-session/Makefile.am xagent.new/gnome-session/Makefile.am
+--- xagent.orig/gnome-session/Makefile.am 2008-07-14 17:46:08.660910000 +0100
++++ xagent.new/gnome-session/Makefile.am 2008-07-14 19:35:52.590734000 +0100
+@@ -1,4 +1,4 @@
+-bin_PROGRAMS = gnome-session
++bin_PROGRAMS = tsoljds-xagent
+
+ noinst_LTLIBRARIES = libgsmutil.la
+
+@@ -16,7 +16,7 @@
+ -DGCONF_SANITY_CHECK=\""$(GCONF_SANITY_CHECK)"\" \
+ -DGCONFTOOL_CMD=\"$(GCONFTOOL)\"
+
+-gnome_session_LDADD = \
++tsoljds_xagent_LDADD = \
+ -lSM -lICE -lsecdb \
+ libgsmutil.la \
+ $(top_builddir)/egg/libeggdesktopfile.la \
+@@ -25,7 +25,7 @@
+ $(GCONF_LIBS) \
+ $(POLKIT_GNOME_LIBS)
- INCLUDES = \
- $(GNOME_SESSION_CFLAGS) \
-+ $(LIBWNCK_CFLAGS) \
- $(STANDARD_PROPERTIES_CFLAGS) \
- $(WARN_CFLAGS) \
- $(DISABLE_DEPRECATED_CFLAGS) \
-@@ -35,6 +36,14 @@
- gnome_session_properties_LDADD = $(GNOME_SESSION_LIBS)
- splash_test_LDADD = $(X_LIBS) $(GNOME_SESSION_LIBS)
- logout_test_LDADD = $(X_LIBS) $(GNOME_SESSION_LIBS)
-+if XTSOL_DEFINED
-+tsoljds_xagent_LDADD = $(XTSOL_LIBS) $(GNOME_SESSION_LIBS)
-+endif
-+
-+if XTSOL_DEFINED
-+TSOLJDS_bin = \
-+ tsoljds-xagent
-+endif
-
- if SESSION
- noinst_PROGRAMS = \
-@@ -45,7 +54,8 @@
- gnome-session \
- gnome-session-save \
- gnome-session-remove \
-- gnome-session-properties
-+ gnome-session-properties\
-+ $(TSOLJDS_bin)
- endif
-
- splash_test_SOURCES = \
-@@ -125,6 +135,47 @@
- migrate-trash.c \
- migrate-trash.h
+-gnome_session_SOURCES = \
++tsoljds_xagent_SOURCES = \
+ app-autostart.c \
+ app-autostart.h \
+ app-resumed.c \
+@@ -47,11 +47,9 @@
+ gsm.h \
+ logout-dialog.h \
+ logout-dialog.c \
+- main.c \
++ xagent.c \
+ power-manager.h \
+ power-manager.c \
+- trusted.h \
+- trusted.c \
+ session.c \
+ session.h \
+ xsmp.c \
+diff -urN xagent.orig/gnome-session/session.c xagent.new/gnome-session/session.c
+--- xagent.orig/gnome-session/session.c 2008-07-14 17:46:08.661992000 +0100
++++ xagent.new/gnome-session/session.c 2008-07-21 16:22:09.831012000 +0100
+@@ -171,6 +171,20 @@
+ session->name = g_strdup (name);
+ }
-+if XTSOL_DEFINED
-+tsoljds_xagent_SOURCES = \
-+ tsoljds-xagent.c \
-+ save.c \
-+ save.h \
-+ manager.c \
-+ manager.h \
-+ remote.c \
-+ remote.h \
-+ ice.c \
-+ ice.h \
-+ gsm-dbus.c \
-+ gsm-dbus.h \
-+ gsm-keyring.c \
-+ gsm-keyring.h \
-+ splash-widget.c \
-+ splash-widget.h \
-+ logout.c \
-+ logout.h \
-+ prop.c \
-+ command.c \
-+ command.h \
-+ gsm-protocol.c \
-+ gsm-protocol.h \
-+ gsm-typebuiltins.c \
-+ gsm-typebuiltins.h \
-+ headers.h \
-+ util.c \
-+ util.h \
-+ gsm-multiscreen.c \
-+ gsm-multiscreen.h \
-+ gdm-logout-action.c \
-+ gdm-logout-action.h \
-+ gsm-autostart.c \
-+ gsm-autostart.h \
-+ gsm-keyfile.c \
-+ gsm-keyfile.h \
-+ tsoljds-misc.c \
-+ tsoljds-misc.h
-+endif
++static gboolean
++app_is_in_xagent_blacklist (char *name)
++{
++ char **app;
++ char *xagent_blacklist[] = {"metacity", "gnome-panel", "tsoljdsselmgr",
++ "tsoljds-tstripe", "gnome-session-splash", NULL};
++
++ for (app = xagent_blacklist; *app != NULL; app++) {
++ if (strncmp (name, *app, strlen (*app)) == 0) return TRUE;
++ }
++
++ return FALSE;
++}
+
- gnome_session_save_SOURCES = \
- gnome-session-save.c \
- gsm-typebuiltins.c \
-diff -urN -x '*.orig' gnome-session-2.20.3/gnome-session/tsoljds-xagent.c ../SUNWtgnome-xagent-2.21.4.hacked/gnome-session-2.20.3/gnome-session/tsoljds-xagent.c
---- gnome-session-2.20.3/gnome-session/tsoljds-xagent.c 1970-01-01 00:00:00.000000000 +0000
-+++ ../SUNWtgnome-xagent-2.21.4.hacked/gnome-session-2.20.3/gnome-session/tsoljds-xagent.c 2008-01-11 17:56:14.079640000 +0000
-@@ -0,0 +1,522 @@
+ static void
+ append_app (GsmSession *session, GsmApp *app)
+ {
+@@ -178,7 +192,7 @@
+ GsmApp *dup;
+
+ basename = gsm_app_get_basename (app);
+- if (basename == NULL)
++ if (basename == NULL || app_is_in_xagent_blacklist (basename))
+ {
+ g_object_unref (app);
+ return;
+diff -urN xagent.orig/gnome-session/xagent.c xagent.new/gnome-session/xagent.c
+--- xagent.orig/gnome-session/xagent.c 1970-01-01 01:00:00.000000000 +0100
++++ xagent.new/gnome-session/xagent.c 2008-07-21 16:54:05.363806000 +0100
+@@ -0,0 +1,288 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/*
++ * xagent.c: gnome-session startup
++ *
++ * Copyright (C) 2006 Novel, Inc.
++ * Copyright (C) 2008 SUN Microsystems, Inc.
++ */
++
++#ifdef HAVE_CONFIG_H
+#include <config.h>
-+#ifdef HAVE_XTSOL
++#endif
+
-+#include <glib.h>
-+#include <gtk/gtk.h>
-+#include <gdk/gdkx.h>
-+
++#include <libintl.h>
++#include <signal.h>
++#include <stdlib.h>
++#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <pwd.h>
-+
-+#include <X11/Xlib.h>
-+#include <X11/Xutil.h>
-+#include <X11/Xos.h>
-+#include <X11/Xatom.h>
++#include <fcntl.h>
+
-+#include <stdio.h>
-+#include <fcntl.h>
-+#include <signal.h>
-+#include <zone.h>
-+
-+#include <priv.h>
-+#include <sys/tsol/priv.h>
-+#include <tsol/label.h>
-+#include <sys/tsol/label.h>
-+#include <sys/tsol/label_macro.h>
-+#include <X11/extensions/Xtsol.h>
-+#include <prof_attr.h>
-+#include <secdb.h>
-+#include <libgnome/gnome-config.h>
-+#include <libgnome/gnome-program.h>
-+#include <libgnomeui/gnome-ui-init.h>
-+#include <libgnomeui/gnome-client.h>
++#include <glib/gi18n.h>
++#include <glib/goption.h>
++#include <gdk/gdkx.h>
++#include <gtk/gtklabel.h>
++#include <gtk/gtkvbox.h>
++#include <gtk/gtkprogressbar.h>
++#include <gtk/gtkmain.h>
++#include <gtk/gtkmessagedialog.h>
+
-+#include "ice.h"
-+#include "headers.h"
-+#include "save.h"
-+#include "gsm-dbus.h"
-+#include "gsm-keyring.h"
++#include "dbus.h"
++#include "gconf.h"
++#include "gsm.h"
++#include "session.h"
++#include "util.h"
++#include "xsmp.h"
++
++#define TSOLJDS_MIGRATION_SCRIPT "/usr/dt/config/tsoljds-migration"
++GsmSession *global_session;
+
-+gint purge_delay = 30000;
-+gint warn_delay = 30000;
-+gint suicide_delay = 10000;
-+gboolean failsafe = FALSE;
-+gboolean autosave = FALSE;
-+gboolean save_selected = FALSE;
-+gboolean logout_prompt = TRUE;
-+gboolean session_save = FALSE;
-+gchar *session_name = NULL;
-+gboolean managesession = TRUE;
-+gboolean trusted_session = FALSE;
-+gboolean default_session = FALSE;
++gboolean defaultsession;
++gboolean nosession;
+
-+typedef struct tcb_component {
-+ char *name;
-+} tcb_component;
-+
-+const tcb_component tcb[] = {
-+ {"metacity" },
-+ {"gnome-volcheck" }, /* This is not a tcb component, but it is not zone aware so remove */
-+ {"gnome-panel"},
-+ {"gnome-smproxy"},
-+ {"gnome-wm"},
-+ {"tsoljdsselmgr"},
-+ {"tsoljds-tstripe"}
++static GOptionEntry entries[] = {
++ { "defaultsession", '\0', 0, G_OPTION_ARG_NONE, &defaultsession,
++ N_("Do not load user-specified applications"),
++ NULL },
++ { "nosession", '\0', 0, G_OPTION_ARG_NONE, &nosession,
++ N_("Do not startup any applications"),
++ NULL },
++ { NULL, 0, 0, 0, NULL, NULL, NULL }
+};
+
-+
-+#define _XA_MOTIF_WINDOW "_MOTIF_DRAG_WINDOW"
-+#define _XA_MOTIF_PROXY_WINDOW "_MOTIF_DRAG_PROXY_WINDOW"
-+#define TSOLJDS_MIGRATION_SCRIPT "/usr/dt/config/tsoljds-migration"
-+
-+static void trim_tcb (Session* session);
-+static Window GetPropertyWindow(Display *dpy, Window in_win, Atom atom);
-+static Window CreateMotifDragWindow(Display *dpy);
-+static void WriteMotifDragWindow(Display *dpy, Window *motifWindow);
-+static void SetUpPolyprop (Display *x_dpy);
-+static gboolean setPrivForTsol (void);
-+int TsolErrorHandler(Display *dpy, XErrorEvent *error);
++/**
++ * gsm_initialization_error:
++ * @fatal: whether or not the error is fatal to the login session
++ * @format: printf-style error message format
++ * @...: error message args
++ *
++ * Displays the error message to the user. If @fatal is %TRUE, gsm
++ * will exit after displaying the message.
++ *
++ * This should be called for major errors that occur before the
++ * session is up and running. (Notably, it positions the dialog box
++ * itself, since no window manager will be running yet.)
++ **/
++void
++gsm_initialization_error (gboolean fatal, const char *format, ...)
++{
++ GtkWidget *dialog;
++ char *msg;
++ va_list args;
+
-+struct passwd *pwent = NULL; /* Password entry for this user */
-+int pipe_fd; /* Pipe read from dtwm */
-+
-+void trim_tcb (Session* session)
-+{
-+ GSList* list;
-+ int i;
-+ gboolean found = FALSE;
-+ list = session->client_list;
-+
-+ for (; list; list = list->next)
-+ {
-+ Client* client = (Client*)list->data;
-+ GSList* prop_list = client->properties;
-+
-+ found = FALSE;
++ va_start (args, format);
++ msg = g_strdup_vprintf (format, args);
++ va_end (args);
+
-+ for (; prop_list; prop_list = prop_list->next) {
-+ SmProp* prop = (SmProp*)prop_list->data;
++ /* If option parsing failed, Gtk won't have been initialized... */
++ if (!gdk_display_get_default ())
++ {
++ if (!gtk_init_check (NULL, NULL))
++ {
++ /* Oh well, no X for you! */
++ g_printerr (_("Unable to start login session (and unable connect to the X server)"));
++ g_printerr (msg);
++ exit (1);
++ }
++ }
+
-+ /* Go through the TCB list, if it is found, remove it */
-+ for (i = 0; i < G_N_ELEMENTS(tcb); i++) {
-+ if (strcmp (prop->vals->value, tcb[i].name)==0) {
-+ REMOVE ( client->properties, prop);
-+ found = TRUE;
-+ break;
-+ }
-+ }
-+ /* Since the prop for the client has been removed, go on to next */
-+ if (found) break;
-+ }
-+ }
-+}
++ dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
++ GTK_BUTTONS_CLOSE, "%s", msg);
+
-+char *get_desktop_window_atom_name (void)
-+{
-+ static char *atom_name = NULL;
-+ uid_t uid;
-+ zoneid_t zid;
++ g_free (msg);
++
++ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
++ gtk_dialog_run (GTK_DIALOG (dialog));
+
-+ if (!atom_name) {
-+ uid = geteuid ();
-+ zid = getzoneid ();
-+ atom_name = g_strdup_printf ("NAUTILUS_DESKTOP_WINDOW_%d_%d",
-+ uid, zid);
-+ }
-+ return atom_name;
++ gtk_widget_destroy (dialog);
++
++ gtk_main_quit ();
+}
+
+int
-+get_screen_number (char *exec_cmd)
++XAgentXErrorHandler (Display *dpy, XErrorEvent *error)
+{
-+ gchar **token;
-+ int scrnum;
-+
-+ token = g_strsplit (exec_cmd, ":", 2);
-+ if (token[0]) {
-+ scrnum = atoi (token[0]);
-+ return scrnum;
-+ }
-+ else return 0;
-+}
-+
-+gchar *
-+get_real_command (char *exec_cmd)
-+{
-+ gchar **token;
-+
-+ token = g_strsplit (exec_cmd, ":", 2);
-+ if (token[1])
-+ return (token[1]);
-+ else return exec_cmd;
-+}
++ char err_msg[132];
++
++ XGetErrorText (dpy, error->error_code, err_msg, sizeof (err_msg));
+
-+static char * cond( GIOCondition condition)
-+{
-+ char value[50];
-+
-+ switch (condition)
-+ {
-+ case 1: strcpy (value, "GLIB_SYSDEF_POLLIN");
-+ break;
-+ case 2: strcpy (value, "GLIB_SYSDEF_POLLPRI");
-+ break;
-+ case 4: strcpy (value, "GLIB_SYSDEF_POLLOUT");
-+ break;
-+ case 8: strcpy (value, "GLIB_SYSDEF_POLLERR");
-+ break;
-+ case 16: strcpy (value, "GLIB_SYSDEF_POLLHUP");
-+ break;
-+ case 32: strcpy (value, "GLIB_SYSDEF_POLLNVAL");
-+ break;
-+ default: strcpy (value, "Unknown condition");
-+ break;
-+ }
-+
-+ return(value);
++ return 0;
+}
+
+static void
+so_long_pipe (gpointer data)
+{
-+ /*
-+ * The pipe is bust which probably means the stripe
-+ * has died. So there's nothing to do but die.
-+ */
-+ exit (2);
++ /*
++ * The pipe is bust which probably means the stripe
++ * has died. So there's nothing to do but die.
++ */
++ exit (2);
+}
+
-+static gboolean handle_pipe_input (GIOChannel *source,
-+ GIOCondition condition,
-+ gpointer data)
++static void
++parse_exec_string (char *exec, int *screen, char **command)
++{
++ gchar **tokens = g_strsplit (exec, ":", 2);
++
++ if (tokens[0]) {
++ *screen = atoi (tokens[0]);
++ } else {
++ *screen = 0;
++ }
++
++ if (tokens[1]) {
++ *command = g_strdup (tokens[1]);
++ } else {
++ *command = g_strdup (exec);
++ }
++
++ g_strfreev (tokens);
++
++}
++
++static gboolean
++handle_pipe_input (GIOChannel *source,
++ GIOCondition condition,
++ gpointer data)
+{
+#define BUFSIZE 1024
+ gsize byteread, pos;
@@ -288,323 +229,137 @@
+ GIOStatus status=0;
+ int screen_num;
+ gchar *real_cmd;
++ GdkDisplay *gdk_dpy;
+
-+ if (condition & G_IO_ERR)
-+ return FALSE;
++ if (condition & G_IO_ERR) return FALSE;
+
-+ if (condition & G_IO_HUP)
-+ /* Seems like another good cue to get out of here */
-+ return FALSE;
++ if (condition & G_IO_HUP) return FALSE;
+
-+ if (condition & G_IO_IN) {
-+ status = g_io_channel_read_line (source, &str, &byteread, &pos, &error);
++ if (condition & G_IO_IN) {
++ status = g_io_channel_read_line (source, &str, &byteread, &pos, &error);
+
+ switch (status)
-+ {
-+ case G_IO_STATUS_NORMAL: str[pos] = '\0';
-+ screen_num = get_screen_number (str);
-+ real_cmd = get_real_command (str);
-+ if ((strncmp (real_cmd, "save_yourself", 13) == 0) && (managesession == TRUE))
-+ {
-+ write_session ();
-+ }
-+ else {
-+ GdkDisplay *gdk_dpy;
-+ gdk_dpy = gdk_display_get_default ();
-+ gdk_spawn_command_line_on_screen (gdk_display_get_screen (gdk_dpy, screen_num), real_cmd, &error);
-+ }
-+ return TRUE;
++ {
++ case G_IO_STATUS_NORMAL:
++ str[pos] = '\0';
++ parse_exec_string (str, &screen_num, &real_cmd);
++ gdk_dpy = gdk_display_get_default ();
++ gdk_spawn_command_line_on_screen (gdk_display_get_screen (gdk_dpy,
++ screen_num), real_cmd, &error);
++ g_free (real_cmd);
++ return TRUE;
+
-+ case G_IO_STATUS_AGAIN: fprintf (stderr, "G_IO_STATUS_AGAIN\n");
-+ return FALSE;
++ case G_IO_STATUS_AGAIN:
++ return FALSE;
++
++ case G_IO_STATUS_EOF:
++ sleep(1);
++ return FALSE;
+
-+ case G_IO_STATUS_EOF:
-+ fprintf (stderr, "G_IO_STATUS_EOF\n");
-+ sleep(1);
-+ return FALSE;
++ case G_IO_STATUS_ERROR:
++ return FALSE;
+
-+ case G_IO_STATUS_ERROR:
-+ fprintf (stderr, "G_IO_STATUS_ERROR: %s\n", error->message);
-+ return FALSE;
-+
-+ default: g_assert_not_reached ();
-+ return FALSE;
++ default:
++ g_assert_not_reached ();
++ return FALSE;
+ }
+ }
+}
+
-+static void
-+AtExit (void)
-+{
-+ gsm_keyring_daemon_stop ();
-+}
-+
-+int main (int argc, char *argv[])
++int
++main (int argc, char **argv)
+{
-+ GtkWidget *window, **windows;
-+
-+ GdkDisplay *gdk_dpy;
-+ Display *x_dpy;
-+ Window win;
-+ gchar *displayname = NULL;
-+ gint screen_count;
-+ GdkScreen **screen_list;
-+ gint i;
-+ long myid;
++ struct sigaction sa;
++ GError *err = NULL;
++ char *display_str;
++ Display *xdisp;
++ GdkDisplay *gdisp;
++ int dummy_fd, pipe_fd;
+ GIOChannel *channel;
+ guint result;
-+ Session *session;
-+ gboolean dbus_daemon_owner;
-+ static gboolean first_startup= TRUE;
+
-+ /* redirect stdout and stderr to /dev/null */
-+ int fd = open ("/dev/null", O_RDWR);
-+ dup2 (fd, 1);
-+ dup2 (fd, 2);
++ bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
++ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
++ textdomain (GETTEXT_PACKAGE);
+
-+ /* See if session management is needed */
-+ if ((argc > 1) && !(strcmp (argv[1], "--nosession"))) {
-+ managesession = FALSE;
-+ } else {
-+ gsm_keyring_daemon_start ();
-+ atexit (AtExit);
-+ }
++ int fd = open ("/dev/null", O_RDWR);
++ dup2 (fd, 1);
++ dup2 (fd, 2);
+
-+ dbus_daemon_owner = gsm_dbus_daemon_start ();
-+
-+ if ((argc > 1) && !(strcmp (argv[1], "--defaultsession")))
-+ default_session = TRUE;
++ sa.sa_handler = SIG_IGN;
++ sa.sa_flags = 0;
++ sigemptyset (&sa.sa_mask);
++ sigaction (SIGPIPE, &sa, 0);
+
-+ /* This is required such that the ~/.gnome2 are setup */
-+ if (managesession) {
-+ /* unset the environment variable that was defined in gnome-session */
-+ g_unsetenv ("SESSION_MANAGER");
-+ gnome_program_init ("tsoljds-xagent", "0.1", LIBGNOMEUI_MODULE,
-+ argc, argv,
-+ NULL);
-+ initialize_ice ();
-+ }
-+
-+ /* Ignore all child deaths */
-+ signal(SIGCHLD, SIG_IGN);
++ if ((pipe_fd = dup (fileno(stdin))) != -1) {
++ close (fileno(stdin));
++ dummy_fd = open ("/dev/null", O_RDONLY);
++ fcntl (pipe_fd, F_SETFD, 1);
++ } else {
++ pipe_fd = fileno (stdin);
++ }
+
-+ /* Get password entry to use the pw_shell entry later */
-+ pwent = getpwuid(getuid());
-+
-+ if ((pipe_fd = dup(fileno(stdin))) != -1) {
-+ int dummy_fd;
-+
-+ close(fileno(stdin));
-+ /* Open /dev/null as stdin */
-+ dummy_fd = open("/dev/null", O_RDONLY);
-+ /* Set close_on_exec */
-+ fcntl(pipe_fd, F_SETFD, 1);
-+ } else
-+ pipe_fd = fileno(stdin);
-+
-+ gtk_init (&argc, &argv);
++ gtk_init_with_args (&argc, &argv,
++ (char *) _(" - the GNOME session manager"),
++ entries, GETTEXT_PACKAGE,
++ &err);
++ if (err)
++ gsm_initialization_error (TRUE, "%s", err->message);
+
-+ /* Get GdkDisplay and number of screens */
-+ gdk_dpy = gdk_display_get_default ();
-+ x_dpy = GDK_DISPLAY_XDISPLAY (gdk_dpy);
-+ screen_count = gdk_display_get_n_screens (gdk_dpy);
-+
-+ displayname = g_strdup (gdk_display_get_name (gdk_dpy));
++ /* Set DISPLAY explicitly for all our children, in case --display
++ * was specified on the command line.
++ */
++ display_str = gdk_get_display ();
++ g_setenv ("DISPLAY", display_str, TRUE);
++ g_free (display_str);
+
-+ if (screen_count <= 0) {
-+ screen_count = 1; /* at least one screen */
-+ }
++ gdisp = gdk_display_get_default ();
++ xdisp = gdk_x11_display_get_xdisplay (gdisp);
++ XInternAtom (xdisp, "GNOME_SM_DESKTOP", FALSE);
+
-+ /* allocation memory for the number of screens */
-+ screen_list = g_new (GdkScreen *, screen_count);
-+ windows = g_new (GtkWidget *, screen_count);
-+
-+ for (i = 0; i < screen_count; i++) {
-+ windows[i] = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-+ gtk_widget_realize (windows[i]);
-+ }
++ XSetErrorHandler (XAgentXErrorHandler);
+
-+ /* Trap the Xserver error as this is an essential hack to make the program
-+ * to start up in the local zone.
-+ */
-+ XSetErrorHandler(TsolErrorHandler);
-+
-+ /* Set to Polyinstantiated properties for selection manager */
-+ SetUpPolyprop (x_dpy);
-+
-+ if (managesession == TRUE) {
-+ /*
-+ * This script is needed to enable input method per zones and roles.
-+ * start_session () is shared between gnome-session and tsoljds-xagent
-+ * so putting this out of start_session () here.
-+ */
-+ if (g_file_test (TSOLJDS_MIGRATION_SCRIPT, G_FILE_TEST_IS_EXECUTABLE)) {
-+ system (TSOLJDS_MIGRATION_SCRIPT);
-+ }
++ /* Start up gconfd and dbus-daemon (in parallel) if they're not
++ * already running. This requires us to initialize XSMP too, because
++ * we want $SESSION_MANAGER to be set before launching dbus-daemon.
++ */
++ gsm_gconf_init ();
++ gsm_xsmp_init ();
++ gsm_dbus_init ();
+
-+ if (session_name == NULL &&
-+ g_getenv ("GDM_GNOME_SESSION") != NULL) {
-+ session_name = g_strdup (g_getenv ("GDM_GNOME_SESSION"));
-+ }
++ /* Now make sure they succeeded. (They'll call
++ * gsm_initialization_error() if they failed.)
++ */
++ gsm_gconf_check ();
++ gsm_dbus_check ();
+
-+ /* If the session name hasn't been specified from the command line */
-+ if(session_name == NULL) {
-+ /* If there is no key specified, fall back to the default session */
-+ session_name = gnome_config_get_string (CURRENT_SESSION_KEY "=" DEFAULT_SESSION);
-+ /* if key was specified but is blank, just use the default */
-+ if (!*session_name) {
-+ g_free (session_name);
-+ session_name = g_strdup (DEFAULT_SESSION);
-+ }
-+ }
++ global_session = gsm_session_new (defaultsession);
+
-+ session = read_session (session_name);
-+ trim_tcb (session);
-+ start_session (session);
++ gsm_xsmp_run ();
++ gsm_dbus_run ();
++
++ if (!nosession) {
++ if (g_file_test (TSOLJDS_MIGRATION_SCRIPT, G_FILE_TEST_IS_EXECUTABLE)) {
++ system (TSOLJDS_MIGRATION_SCRIPT);
+ }
+
-+ if (first_startup) {
-+ GError *err=NULL;
-+ /* FIXME: need to get the screen info some how, but default to 0 for now */
-+ gdk_spawn_command_line_on_screen (gdk_display_get_screen (gdk_dpy, 0), g_getenv("LABEL_EXEC_COMMAND"), &err);
-+
-+ if (err)
-+ g_print ("error is %s\n", err->message);
-+
-+ first_startup = FALSE;
-+ }
-+
-+ channel = g_io_channel_unix_new (pipe_fd);
-+ result = g_io_add_watch_full (channel, G_PRIORITY_HIGH,
-+ G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
-+ (GIOFunc)handle_pipe_input, NULL, so_long_pipe);
-+ gtk_main ();
-+
-+ if (dbus_daemon_owner) {
-+ gsm_dbus_daemon_stop ();
-+ }
-+
-+ return 0;
-+}
-+
-+static void SetUpPolyprop (Display *x_dpy)
-+{
-+ /* copy motif_proxy_win from user's clearance to current label */
-+#define ROOT_UID 0
-+ XTsolResAttributes resattr;
-+ Atom ATOM_MOTIF_DRAG_WIN;
-+ Atom ATOM_MOTIF_PROXY_WIN;
-+ m_label_t *slabel;
-+ Window motif_drag_win = None;
-+ Window proxy_win = None;
-+ XWindowAttributes wattr;
-+
-+ /* Set up to look up the polyprop used by the sel_mgr */
-+ slabel = blabel_alloc();
-+ bsllow(slabel);
-+ resattr.sl = slabel;
-+ resattr.uid = ROOT_UID;
-+ XTSOLsetPolyInstInfo(x_dpy, resattr.sl, (uid_t *)(&resattr.uid), True);
-+ ATOM_MOTIF_DRAG_WIN = XInternAtom(x_dpy, _XA_MOTIF_WINDOW, False);
-+ ATOM_MOTIF_PROXY_WIN = XInternAtom(x_dpy, _XA_MOTIF_PROXY_WINDOW, False);
-+ motif_drag_win = GetPropertyWindow(x_dpy, DefaultRootWindow(x_dpy),
-+ ATOM_MOTIF_DRAG_WIN);
-+ if (motif_drag_win != None) {
-+ proxy_win = GetPropertyWindow(x_dpy, motif_drag_win,
-+ ATOM_MOTIF_PROXY_WIN);
-+ }
-+
-+ /* put back our original polyprop settings */
-+ getplabel(slabel);
-+ resattr.uid = getuid();
-+ XTSOLsetPolyInstInfo(x_dpy, resattr.sl, (uid_t *)(&resattr.uid), False);
-+ blabel_free(slabel);
-+
-+ motif_drag_win = GetPropertyWindow(x_dpy, DefaultRootWindow(x_dpy),
-+ ATOM_MOTIF_DRAG_WIN);
-+
-+ /* Validate motif_drag_win */
-+ if (XGetWindowAttributes(x_dpy, motif_drag_win, &wattr) == 0) {
-+ /* if window is invalid, create a new one */
-+ motif_drag_win = CreateMotifDragWindow(x_dpy);
-+ }
++ gsm_session_start (global_session);
++ }
+
-+ if (motif_drag_win != None) {
-+ XChangeProperty(x_dpy, motif_drag_win, ATOM_MOTIF_PROXY_WIN,
-+ XA_WINDOW, 32, PropModeReplace,
-+ (unsigned char *) &proxy_win, 1);
-+ }
-+}
-+
-+Window
-+GetPropertyWindow(Display *dpy, Window in_win, Atom atom)
-+{
-+ Atom type;
-+ int format;
-+ unsigned long lengthRtn;
-+ unsigned long bytesafter;
-+ Window *property = NULL;
-+ Window win = None;
-+
-+ if ((XGetWindowProperty (dpy, in_win, atom, 0L, 1, False, AnyPropertyType,
-+ &type, &format, &lengthRtn, &bytesafter,
-+ (unsigned char **) &property) == Success) &&
-+ (type == XA_WINDOW) && (format == 32) && (lengthRtn == 1)) {
-+ win = *property;
-+ }
-+
-+ if (property) {
-+ XFree ((char *)property);
-+ }
-+
-+ return (win);
-+}
-+
-+
-+static Window
-+CreateMotifDragWindow(Display *dpy)
-+{
-+ XSetWindowAttributes sAttributes;
-+ Window motifWindow;
++ /* we may have to spawn an exec immediately */
++ gdk_spawn_command_line_on_screen (gdk_display_get_screen (gdisp, 0),
++ g_getenv ("LABEL_EXEC_COMMAND"), &err);
++
++ channel = g_io_channel_unix_new (pipe_fd);
++ result = g_io_add_watch_full (channel, G_PRIORITY_HIGH,
++ G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
++ (GIOFunc)handle_pipe_input, NULL, so_long_pipe);
+
-+ XSetCloseDownMode (dpy, RetainPermanent);
-+
-+ sAttributes.override_redirect = True;
-+ sAttributes.event_mask = PropertyChangeMask;
-+ motifWindow = XCreateWindow (dpy, DefaultRootWindow (dpy), -100, -100,
-+ 10, 10, 0, 0, InputOnly, CopyFromParent,
-+ (CWOverrideRedirect |CWEventMask),
-+ &sAttributes);
-+ XMapWindow (dpy, motifWindow);
-+ WriteMotifDragWindow (dpy, &motifWindow);
-+
-+ return (motifWindow);
-+}
-+
-+static void
-+WriteMotifDragWindow(Display *dpy, Window *motifWindow)
-+{
-+ Atom motifWindowAtom;
++ gtk_main ();
+
-+ motifWindowAtom = XInternAtom (dpy, _XA_MOTIF_WINDOW, False);
-+
-+ XChangeProperty (dpy, RootWindow (dpy, 0), motifWindowAtom,
-+ XA_WINDOW, 32, PropModeReplace,
-+ (unsigned char *) motifWindow, 1);
-+}
-+
-+/*
-+ * Ignore X protocol errors
-+ */
-+int
-+TsolErrorHandler(Display *dpy, XErrorEvent *error)
-+{
-+ char err_msg[132];
-+
-+ /* ignore all errors */
-+
-+ XGetErrorText(dpy, error->error_code, err_msg, sizeof(err_msg));
++ gsm_xsmp_shutdown ();
++ gsm_gconf_shutdown ();
++ gsm_dbus_shutdown ();
+
+ return 0;
+}
-+#endif