summaryrefslogtreecommitdiff
path: root/xfce4-session
diff options
context:
space:
mode:
authorBrian Tarricone <brian@tarricone.org>2008-10-03 22:51:22 +0000
committerBrian Tarricone <brian@tarricone.org>2008-10-03 22:51:22 +0000
commitc4f978186f4c3972c313907648fc5b5b6ec56a4e (patch)
tree0a67dbfb820de35c978214a5b483ad5430c57058 /xfce4-session
parent543f507292680e39d6db40afe56c9821f197cb1c (diff)
downloadxfce4-session-c4f978186f4c3972c313907648fc5b5b6ec56a4e.tar.gz
* xfce4-session/*.[ch]: Turn XfsmManager into a GObject, and
remove most of the app-global variables. This is a first step toward fixing bug 798, as well as making xfce4-session ready for a D-Bus interface. (Old svn revision: 28025)
Diffstat (limited to 'xfce4-session')
-rw-r--r--xfce4-session/ice-layer.c37
-rw-r--r--xfce4-session/ice-layer.h5
-rw-r--r--xfce4-session/main.c35
-rw-r--r--xfce4-session/shutdown.c16
-rw-r--r--xfce4-session/shutdown.h2
-rw-r--r--xfce4-session/sm-layer.c30
-rw-r--r--xfce4-session/sm-layer.h6
-rw-r--r--xfce4-session/xfsm-client.h1
-rw-r--r--xfce4-session/xfsm-compat-gnome.c11
-rw-r--r--xfce4-session/xfsm-compat-kde.c13
-rw-r--r--xfce4-session/xfsm-global.c20
-rw-r--r--xfce4-session/xfsm-global.h13
-rw-r--r--xfce4-session/xfsm-manager.c662
-rw-r--r--xfce4-session/xfsm-manager.h131
-rw-r--r--xfce4-session/xfsm-properties.c2
-rw-r--r--xfce4-session/xfsm-startup.c199
-rw-r--r--xfce4-session/xfsm-startup.h7
17 files changed, 785 insertions, 405 deletions
diff --git a/xfce4-session/ice-layer.c b/xfce4-session/ice-layer.c
index 4eb88c06..ecbafb9b 100644
--- a/xfce4-session/ice-layer.c
+++ b/xfce4-session/ice-layer.c
@@ -1,6 +1,7 @@
/* $Id$ */
/*-
* Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -51,6 +52,13 @@
#include <xfce4-session/xfsm-global.h>
#include <xfce4-session/xfsm-manager.h>
+typedef struct
+{
+ XfsmManager *manager;
+ IceConn ice_conn;
+} XfsmIceConnData;
+
+
/* prototypes */
static void ice_error_handler (IceConn);
static gboolean ice_process_messages (GIOChannel *channel,
@@ -98,13 +106,14 @@ ice_process_messages (GIOChannel *channel,
gpointer user_data)
{
IceProcessMessagesStatus status;
- IceConn ice_conn = (IceConn) user_data;
+ XfsmIceConnData *icdata = user_data;
- status = IceProcessMessages (ice_conn, NULL, NULL);
+ status = IceProcessMessages (icdata->ice_conn, NULL, NULL);
if (status == IceProcessMessagesIOError)
{
- xfsm_manager_close_connection_by_ice_conn (ice_conn);
+ xfsm_manager_close_connection_by_ice_conn (icdata->manager,
+ icdata->ice_conn);
/* remove the I/O watch */
return FALSE;
@@ -121,12 +130,17 @@ ice_connection_watch (IceConn ice_conn,
Bool opening,
IcePointer *watch_data)
{
- GIOChannel *channel;
- guint watchid;
- gint fd;
+ XfsmManager *manager = XFSM_MANAGER (client_data);
+ GIOChannel *channel;
+ guint watchid;
+ gint fd;
if (opening)
{
+ XfsmIceConnData *icdata = g_new(XfsmIceConnData, 1);
+ icdata->manager = manager;
+ icdata->ice_conn = ice_conn;
+
fd = IceConnectionNumber (ice_conn);
/* Make sure we don't pass on these file descriptors to an
@@ -135,8 +149,10 @@ ice_connection_watch (IceConn ice_conn,
fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
channel = g_io_channel_unix_new (fd);
- watchid = g_io_add_watch (channel, G_IO_ERR | G_IO_HUP | G_IO_IN,
- ice_process_messages, ice_conn);
+ watchid = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT,
+ G_IO_ERR | G_IO_HUP | G_IO_IN,
+ ice_process_messages,
+ icdata, (GDestroyNotify) g_free);
g_io_channel_unref (channel);
*watch_data = (IcePointer) GUINT_TO_POINTER (watchid);
@@ -271,7 +287,8 @@ ice_auth_add (FILE *setup_fp,
gboolean
ice_setup_listeners (int num_listeners,
- IceListenObj *listen_objs)
+ IceListenObj *listen_objs,
+ XfsmManager *manager)
{
GIOChannel *channel;
char *auth_setup_file;
@@ -282,7 +299,7 @@ ice_setup_listeners (int num_listeners,
int n;
IceSetIOErrorHandler (ice_error_handler);
- IceAddConnectionWatch (ice_connection_watch, NULL);
+ IceAddConnectionWatch (ice_connection_watch, manager);
cleanup_fp = ice_tmpfile(&auth_cleanup_file);
if (cleanup_fp == NULL)
diff --git a/xfce4-session/ice-layer.h b/xfce4-session/ice-layer.h
index 82edce5c..8425b3bb 100644
--- a/xfce4-session/ice-layer.h
+++ b/xfce4-session/ice-layer.h
@@ -26,9 +26,12 @@
#include <glib.h>
+#include "xfsm-manager.h"
+
Bool ice_auth_proc (char *hostname);
gboolean ice_setup_listeners (int num_listeners,
- IceListenObj *listen_objs);
+ IceListenObj *listen_objs,
+ XfsmManager *manager);
void ice_cleanup (void);
#endif /* !__XFSM_ICE_LAYER_H__ */
diff --git a/xfce4-session/main.c b/xfce4-session/main.c
index acf793b4..e7c43198 100644
--- a/xfce4-session/main.c
+++ b/xfce4-session/main.c
@@ -1,6 +1,7 @@
/* $Id$ */
/*-
* Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -125,9 +126,10 @@ usage (int exit_code)
static void
-init_display (GdkDisplay *dpy,
- XfceRc *rc,
- gboolean disable_tcp)
+init_display (XfsmManager *manager,
+ GdkDisplay *dpy,
+ XfceRc *rc,
+ gboolean disable_tcp)
{
const gchar *engine;
@@ -140,7 +142,7 @@ init_display (GdkDisplay *dpy,
gdk_flush ();
xfce_rc_set_group (rc, "General");
- sm_init (rc, disable_tcp);
+ sm_init (rc, disable_tcp, manager);
/* start xfsettingsd */
if ( !g_spawn_command_line_async ("xfsettingsd", NULL))
@@ -155,7 +157,9 @@ init_display (GdkDisplay *dpy,
static void
-initialize (int argc, char **argv)
+initialize (XfsmManager *manager,
+ int argc,
+ char **argv)
{
gboolean disable_tcp = FALSE;
GdkDisplay *dpy;
@@ -192,7 +196,7 @@ initialize (int argc, char **argv)
rc = xfsm_open_config (TRUE);
dpy = gdk_display_get_default ();
- init_display (dpy, rc, disable_tcp);
+ init_display (manager, dpy, rc, disable_tcp);
/* verify that the DNS settings are ok */
xfsm_splash_screen_next (splash_screen, _("Verifying DNS settings"));
@@ -200,13 +204,9 @@ initialize (int argc, char **argv)
xfsm_splash_screen_next (splash_screen, _("Loading session data"));
- xfce_rc_set_group (rc, "Compatibility");
- compat_gnome = xfce_rc_read_bool_entry (rc, "LaunchGnome", FALSE);
- compat_kde = xfce_rc_read_bool_entry (rc, "LaunchKDE", FALSE);
-
xfce_rc_set_group (rc, "General");
xfsm_startup_init (rc);
- xfsm_manager_init (rc);
+ xfsm_manager_load (manager, rc);
/* cleanup obsolete entries */
xfce_rc_set_group (rc, "General");
@@ -223,8 +223,8 @@ initialize (int argc, char **argv)
int
main (int argc, char **argv)
{
- /* imported from xfsm-manager.c */
- extern gint shutdown_type;
+ XfsmManager *manager;
+ gint shutdown_type;
xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
@@ -238,11 +238,14 @@ main (int argc, char **argv)
*/
gdk_set_sm_client_id (xfsm_manager_generate_client_id (NULL));
- initialize (argc, argv);
-
- xfsm_manager_restart ();
+ manager = xfsm_manager_new ();
+ initialize (manager, argc, argv);
+ xfsm_manager_restart (manager);
gtk_main ();
+
+ shutdown_type = xfsm_manager_get_shutdown_type (manager);
+ g_object_unref (manager);
ice_cleanup ();
diff --git a/xfce4-session/shutdown.c b/xfce4-session/shutdown.c
index 171d5843..a9a2e7b1 100644
--- a/xfce4-session/shutdown.c
+++ b/xfce4-session/shutdown.c
@@ -63,7 +63,7 @@ static GtkWidget *shutdown_dialog = NULL;
#ifdef SESSION_SCREENSHOTS
static void
-screenshot_save (GdkPixmap *pm, GdkRectangle *area)
+screenshot_save (const gchar *session_name, GdkPixmap *pm, GdkRectangle *area)
{
gchar *display_name;
gchar *resource;
@@ -137,7 +137,7 @@ halt_button_clicked (GtkWidget *b, gint *shutdownType)
/*
*/
gboolean
-shutdownDialog(gint *shutdownType, gboolean *saveSession)
+shutdownDialog(const gchar *sessionName, gint *shutdownType, gboolean *saveSession)
{
gboolean accessibility;
XfsmFadeout *fadeout = NULL;
@@ -549,7 +549,7 @@ shutdownDialog(gint *shutdownType, gboolean *saveSession)
if (result == GTK_RESPONSE_OK)
{
xfce_rc_set_group (rc, "General");
- xfce_rc_write_entry (rc, "SessionName", session_name);
+ xfce_rc_write_entry (rc, "SessionName", sessionName);
xfce_rc_write_bool_entry (rc, "SaveOnExit", *saveSession);
}
else
@@ -562,7 +562,7 @@ shutdownDialog(gint *shutdownType, gboolean *saveSession)
if (screenshot_pm != NULL)
{
if (result == GTK_RESPONSE_OK)
- screenshot_save (screenshot_pm, &screenshot_area);
+ screenshot_save (sessionName, screenshot_pm, &screenshot_area);
g_object_unref (G_OBJECT (screenshot_pm));
}
@@ -581,11 +581,9 @@ xfsm_shutdown(gint type)
{
gboolean result;
- if (compat_gnome)
- xfsm_compat_gnome_shutdown ();
-
- if (compat_kde)
- xfsm_compat_kde_shutdown ();
+ /* these two remember if they were started or not */
+ xfsm_compat_gnome_shutdown ();
+ xfsm_compat_kde_shutdown ();
/* kill legacy clients */
xfsm_legacy_shutdown ();
diff --git a/xfce4-session/shutdown.h b/xfce4-session/shutdown.h
index 6fc4b2bd..ec2d1fcb 100644
--- a/xfce4-session/shutdown.h
+++ b/xfce4-session/shutdown.h
@@ -30,7 +30,7 @@
#define SHUTDOWN_HALT 2
/* prototypes */
-extern gboolean shutdownDialog(gint *, gboolean *);
+extern gboolean shutdownDialog(const gchar *, gint *, gboolean *);
extern gint xfsm_shutdown(gint);
#endif /* !__XFSM_SHUTDOWN_H__ */
diff --git a/xfce4-session/sm-layer.c b/xfce4-session/sm-layer.c
index 620d4a98..18f2efc8 100644
--- a/xfce4-session/sm-layer.c
+++ b/xfce4-session/sm-layer.c
@@ -97,8 +97,9 @@ static IceListenObj *listen_objs;
void
-sm_init (XfceRc *rc,
- gboolean disable_tcp)
+sm_init (XfceRc *rc,
+ gboolean disable_tcp,
+ XfsmManager *manager)
{
char *network_idlist;
char error[2048];
@@ -119,7 +120,7 @@ sm_init (XfceRc *rc,
#endif
}
- if (!SmsInitialize (PACKAGE, VERSION, sm_new_client, NULL, ice_auth_proc,
+ if (!SmsInitialize (PACKAGE, VERSION, sm_new_client, manager, ice_auth_proc,
2048, error))
{
fprintf (stderr, "xfce4-session: Unable to register XSM protocol: %s\n", error);
@@ -132,7 +133,7 @@ sm_init (XfceRc *rc,
exit (EXIT_FAILURE);
}
- ice_setup_listeners (num_listeners, listen_objs);
+ ice_setup_listeners (num_listeners, listen_objs, manager);
network_idlist = IceComposeNetworkIdList (num_listeners, listen_objs);
xfce_setenv ("SESSION_MANAGER", network_idlist, TRUE);
@@ -147,13 +148,14 @@ sm_new_client (SmsConn sms_conn,
SmsCallbacks *callbacks,
char **failure_reason)
{
- XfsmClient *client;
- gchar *error = NULL;
+ XfsmManager *manager = XFSM_MANAGER (manager_data);
+ XfsmClient *client;
+ gchar *error = NULL;
xfsm_verbose ("ICE connection fd = %d, received NEW CLIENT\n\n",
IceConnectionNumber (SmsGetIceConnection (sms_conn)));
- client = xfsm_manager_new_client (sms_conn, &error);
+ client = xfsm_manager_new_client (manager, sms_conn, &error);
if (client == NULL)
{
xfsm_verbose ("NEW CLIENT failed: %s\n", error);
@@ -202,7 +204,7 @@ sm_register_client (SmsConn sms_conn,
IceConnectionNumber (SmsGetIceConnection (sms_conn)),
previous_id != NULL ? previous_id : "None");
- result = xfsm_manager_register_client (client, previous_id);
+ result = xfsm_manager_register_client (client->manager, client, previous_id);
if (previous_id != NULL)
free (previous_id);
@@ -221,7 +223,7 @@ sm_interact_request (SmsConn sms_conn,
xfsm_verbose ("Client Id = %s, received INTERACT REQUEST [Dialog type = %s]\n\n",
client->id, dialog_type == SmDialogError ? "Error" : "Normal");
- xfsm_manager_interact (client, dialog_type);
+ xfsm_manager_interact (client->manager, client, dialog_type);
}
@@ -235,7 +237,7 @@ sm_interact_done (SmsConn sms_conn,
xfsm_verbose ("Client Id = %s, received INTERACT DONE [Cancel shutdown = %s]\n\n",
client->id, cancel_shutdown ? "True" : "False");
- xfsm_manager_interact_done (client, cancel_shutdown);
+ xfsm_manager_interact_done (client->manager, client, cancel_shutdown);
}
@@ -266,7 +268,7 @@ sm_save_yourself_request (SmsConn sms_conn,
xfsm_verbose ("\n");
}
- xfsm_manager_save_yourself (client, save_type, shutdown, interact_style, fast, global);
+ xfsm_manager_save_yourself (client->manager, client, save_type, shutdown, interact_style, fast, global);
}
@@ -278,7 +280,7 @@ sm_save_yourself_phase2_request (SmsConn sms_conn,
xfsm_verbose ("Client Id = %s, received SAVE YOURSELF PHASE2 REQUEST\n\n", client->id);
- xfsm_manager_save_yourself_phase2 (client);
+ xfsm_manager_save_yourself_phase2 (client->manager, client);
}
@@ -292,7 +294,7 @@ sm_save_yourself_done (SmsConn sms_conn,
xfsm_verbose ("Client Id = %s, received SAVE YOURSELF DONE [Success = %s]\n\n",
client->id, success ? "True" : "False");
- xfsm_manager_save_yourself_done (client, success);
+ xfsm_manager_save_yourself_done (client->manager, client, success);
}
@@ -314,7 +316,7 @@ sm_close_connection (SmsConn sms_conn,
xfsm_verbose ("\n");
}
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (client->manager, client, TRUE);
if (num_reasons > 0)
SmFreeReasons (num_reasons, reasons);
diff --git a/xfce4-session/sm-layer.h b/xfce4-session/sm-layer.h
index d67d2e71..acfa8e8b 100644
--- a/xfce4-session/sm-layer.h
+++ b/xfce4-session/sm-layer.h
@@ -24,6 +24,10 @@
#include <libxfce4util/libxfce4util.h>
-void sm_init (XfceRc *rc, gboolean disable_tcp);
+#include "xfsm-manager.h"
+
+void sm_init (XfceRc *rc,
+ gboolean disable_tcp,
+ XfsmManager *manager);
#endif /* !__SM_LAYER_H__ */
diff --git a/xfce4-session/xfsm-client.h b/xfce4-session/xfsm-client.h
index dc71a79d..a06387d9 100644
--- a/xfce4-session/xfsm-client.h
+++ b/xfce4-session/xfsm-client.h
@@ -46,6 +46,7 @@ struct _XfsmClient
XfsmProperties *properties;
SmsConn sms_conn;
guint save_timeout_id;
+ gpointer manager; /* (XfsmManager *) */
};
diff --git a/xfce4-session/xfsm-compat-gnome.c b/xfce4-session/xfsm-compat-gnome.c
index aa8c34d7..a8f0c435 100644
--- a/xfce4-session/xfsm-compat-gnome.c
+++ b/xfce4-session/xfsm-compat-gnome.c
@@ -67,6 +67,7 @@ static GConfClient *gnome_conf_client = NULL;
#endif
+static gboolean gnome_compat_started = FALSE;
static pid_t gnome_keyring_daemon_pid = 0;
static Window gnome_smproxy_window = None;
@@ -237,6 +238,9 @@ xfsm_compat_gnome_smproxy_shutdown (void)
void
xfsm_compat_gnome_startup (XfsmSplashScreen *splash)
{
+ if (G_UNLIKELY (gnome_compat_started))
+ return;
+
xfsm_compat_gnome_smproxy_startup ();
/* fire up the keyring daemon */
@@ -260,6 +264,8 @@ xfsm_compat_gnome_startup (XfsmSplashScreen *splash)
}
}
#endif
+
+ gnome_compat_started = TRUE;
}
@@ -269,6 +275,9 @@ xfsm_compat_gnome_shutdown (void)
GError *error = NULL;
gint status;
+ if (G_UNLIKELY (!gnome_compat_started))
+ return;
+
/* shutdown the keyring daemon */
gnome_keyring_daemon_shutdown ();
@@ -295,5 +304,7 @@ xfsm_compat_gnome_shutdown (void)
}
xfsm_compat_gnome_smproxy_shutdown ();
+
+ gnome_compat_started = FALSE;
}
diff --git a/xfce4-session/xfsm-compat-kde.c b/xfce4-session/xfsm-compat-kde.c
index 438a5689..f7dab1de 100644
--- a/xfce4-session/xfsm-compat-kde.c
+++ b/xfce4-session/xfsm-compat-kde.c
@@ -48,6 +48,9 @@
#include <xfce4-session/xfsm-compat-kde.h>
+static gboolean kde_compat_started = FALSE;
+
+
static gboolean
run_timeout (gpointer user_data)
{
@@ -114,6 +117,9 @@ xfsm_compat_kde_startup (XfsmSplashScreen *splash)
{
gchar command[256];
+ if (G_UNLIKELY (kde_compat_started))
+ return;
+
if (G_LIKELY (splash != NULL))
xfsm_splash_screen_next (splash, _("Starting KDE services"));
@@ -132,15 +138,22 @@ xfsm_compat_kde_startup (XfsmSplashScreen *splash)
"KDE_MULTIHEAD \"true\"");
run (command);
}
+
+ kde_compat_started = TRUE;
}
void
xfsm_compat_kde_shutdown (void)
{
+ if (G_UNLIKELY (!kde_compat_started))
+ return;
+
/* shutdown KDE services */
run ("kdeinit_shutdown");
run ("dcopserver_shutdown");
run ("artsshell -q terminate");
+
+ kde_compat_started = FALSE;
}
diff --git a/xfce4-session/xfsm-global.c b/xfce4-session/xfsm-global.c
index 5d3b0286..8951bbb2 100644
--- a/xfce4-session/xfsm-global.c
+++ b/xfce4-session/xfsm-global.c
@@ -36,20 +36,18 @@
/* global variables */
gboolean verbose = FALSE;
-gboolean compat_kde = FALSE;
-gboolean compat_gnome = FALSE;
-GList *starting_properties = NULL;
-GList *pending_properties = NULL;
-GList *restart_properties = NULL;
-GList *running_clients = NULL;
-gchar *session_name = NULL;
-gchar *session_file = NULL;
-GList *failsafe_clients = NULL;
-gboolean failsafe_mode = TRUE;
-gint shutdown_type = SHUTDOWN_LOGOUT;
XfsmSplashScreen *splash_screen = NULL;
void
+xfsm_failsafe_client_free (FailsafeClient *fclient)
+{
+ if (fclient->command)
+ g_strfreev (fclient->command);
+ g_free (fclient);
+}
+
+
+void
xfsm_enable_verbose (void)
{
if (!verbose)
diff --git a/xfce4-session/xfsm-global.h b/xfce4-session/xfsm-global.h
index 25b523ad..f6102963 100644
--- a/xfce4-session/xfsm-global.h
+++ b/xfce4-session/xfsm-global.h
@@ -31,23 +31,14 @@ struct _FailsafeClient
gchar **command;
GdkScreen *screen;
};
+
+void xfsm_failsafe_client_free (FailsafeClient *fclient);
#define DEFAULT_SESSION_NAME "Default"
extern gboolean verbose;
-extern gboolean compat_kde;
-extern gboolean compat_gnome;
-extern GList *starting_properties;
-extern GList *pending_properties;
-extern GList *restart_properties;
-extern GList *running_clients;
-extern gchar *session_name;
-extern gchar *session_file;
-extern GList *failsafe_clients;
-extern gboolean failsafe_mode;
-extern gint shutdown_type;
extern XfsmSplashScreen *splash_screen;
diff --git a/xfce4-session/xfsm-manager.c b/xfce4-session/xfsm-manager.c
index eeadaaa1..b271d8fc 100644
--- a/xfce4-session/xfsm-manager.c
+++ b/xfce4-session/xfsm-manager.c
@@ -1,6 +1,7 @@
/* $Id$ */
/*-
* Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -67,36 +68,130 @@
#define DEFAULT_SESSION_NAME "Default"
+struct _XfsmManager
+{
+ GObject parent;
+
+ XfsmManagerState state;
+ gint shutdown_type;
+
+ gboolean session_chooser;
+ gchar *session_name;
+ gchar *session_file;
+
+ gboolean compat_gnome;
+ gboolean compat_kde;
+
+ GQueue *starting_properties;
+ GQueue *pending_properties;
+ GQueue *restart_properties;
+ GQueue *running_clients;
+
+ gboolean failsafe_mode;
+ GQueue *failsafe_clients;
+
+ guint die_timeout_id;
+};
+
+typedef struct _XfsmManagerClass
+{
+ GObjectClass parent;
+} XfsmManagerClass;
+
+
/*
Prototypes
*/
-static gboolean xfsm_manager_startup (void);
-static void xfsm_manager_load_settings (XfceRc *rc);
-static gboolean xfsm_manager_load_session (void);
+static void xfsm_manager_class_init (XfsmManagerClass *klass);
+static void xfsm_manager_init (XfsmManager *manager);
+static void xfsm_manager_finalize (GObject *obj);
+
+static gboolean xfsm_manager_startup (XfsmManager *manager);
+static gboolean xfsm_manager_save_timeout (gpointer client_data);
+static void xfsm_manager_load_settings (XfsmManager *manager,
+ XfceRc *rc);
+static gboolean xfsm_manager_load_session (XfsmManager *manager);
static GdkPixbuf *xfsm_manager_load_session_preview (const gchar *name);
-/*
- Static data
- */
-static XfsmManagerState state = XFSM_MANAGER_STARTUP;
-static gboolean session_chooser = FALSE;
-static guint die_timeout_id = 0;
+G_DEFINE_TYPE(XfsmManager, xfsm_manager, G_TYPE_OBJECT)
+
+
+static void
+xfsm_manager_class_init (XfsmManagerClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *)klass;
+
+ gobject_class->finalize = xfsm_manager_finalize;
+}
+
+
+static void
+xfsm_manager_init (XfsmManager *manager)
+{
+ manager->state = XFSM_MANAGER_STARTUP;
+ manager->session_chooser = FALSE;
+ manager->failsafe_mode = TRUE;
+ manager->shutdown_type = SHUTDOWN_LOGOUT;
+
+ manager->pending_properties = g_queue_new ();
+ manager->starting_properties = g_queue_new ();
+ manager->restart_properties = g_queue_new ();
+ manager->running_clients = g_queue_new ();
+ manager->failsafe_clients = g_queue_new ();
+}
+
+
+static void
+xfsm_manager_finalize (GObject *obj)
+{
+ XfsmManager *manager = XFSM_MANAGER(obj);
+
+ if (manager->die_timeout_id != 0)
+ g_source_remove (manager->die_timeout_id);
+
+ g_queue_foreach (manager->pending_properties, (GFunc) xfsm_properties_free, NULL);
+ g_queue_free (manager->pending_properties);
+
+ g_queue_foreach (manager->starting_properties, (GFunc) xfsm_properties_free, NULL);
+ g_queue_free (manager->starting_properties);
+
+ g_queue_foreach (manager->restart_properties, (GFunc) xfsm_properties_free, NULL);
+ g_queue_free (manager->restart_properties);
+
+ g_queue_foreach (manager->running_clients, (GFunc) xfsm_client_free, NULL);
+ g_queue_free (manager->running_clients);
+
+ g_queue_foreach (manager->failsafe_clients, (GFunc) xfsm_failsafe_client_free, NULL);
+ g_queue_free (manager->failsafe_clients);
+
+ g_free (manager->session_name);
+ g_free (manager->session_file);
+
+ G_OBJECT_CLASS (xfsm_manager_parent_class)->finalize (obj);
+}
+
+
+XfsmManager *
+xfsm_manager_new (void)
+{
+ return g_object_new (XFSM_TYPE_MANAGER, NULL);
+}
static gboolean
-xfsm_manager_startup (void)
+xfsm_manager_startup (XfsmManager *manager)
{
- xfsm_startup_foreign ();
- pending_properties = g_list_sort (pending_properties,
- (GCompareFunc) xfsm_properties_compare);
- xfsm_startup_begin ();
+ xfsm_startup_foreign (manager);
+ g_queue_sort (manager->pending_properties, (GCompareDataFunc) xfsm_properties_compare, NULL);
+ xfsm_startup_begin (manager);
return FALSE;
}
static void
-xfsm_manager_restore_active_workspace (XfceRc *rc)
+xfsm_manager_restore_active_workspace (XfsmManager *manager,
+ XfceRc *rc)
{
WnckWorkspace *workspace;
GdkDisplay *display;
@@ -125,7 +220,8 @@ xfsm_manager_restore_active_workspace (XfceRc *rc)
void
-xfsm_manager_handle_failed_client (XfsmProperties *properties)
+xfsm_manager_handle_failed_client (XfsmManager *manager,
+ XfsmProperties *properties)
{
/* Handle apps that failed to start here */
@@ -143,13 +239,14 @@ xfsm_manager_handle_failed_client (XfsmProperties *properties)
NULL, NULL);
}
- if (starting_properties == NULL)
- xfsm_startup_session_continue ();
+ if (g_queue_peek_head (manager->starting_properties) == NULL)
+ xfsm_startup_session_continue (manager);
}
static gboolean
-xfsm_manager_choose_session (XfceRc *rc)
+xfsm_manager_choose_session (XfsmManager *manager,
+ XfceRc *rc)
{
XfsmSessionInfo *session;
GdkPixbuf *preview_default = NULL;
@@ -193,7 +290,7 @@ xfsm_manager_choose_session (XfceRc *rc)
if (sessions != NULL)
{
result = xfsm_splash_screen_choose (splash_screen, sessions,
- session_name, &name);
+ manager->session_name, &name);
if (result == XFSM_CHOOSE_LOGOUT)
{
@@ -205,9 +302,9 @@ xfsm_manager_choose_session (XfceRc *rc)
load = TRUE;
}
- if (session_name != NULL)
- g_free (session_name);
- session_name = name;
+ if (manager->session_name != NULL)
+ g_free (manager->session_name);
+ manager->session_name = name;
for (lp = sessions; lp != NULL; lp = lp->next)
{
@@ -226,27 +323,27 @@ xfsm_manager_choose_session (XfceRc *rc)
static gboolean
-xfsm_manager_load_session (void)
+xfsm_manager_load_session (XfsmManager *manager)
{
XfsmProperties *properties;
gchar buffer[1024];
XfceRc *rc;
gint count;
- if (!g_file_test (session_file, G_FILE_TEST_IS_REGULAR))
+ if (!g_file_test (manager->session_file, G_FILE_TEST_IS_REGULAR))
return FALSE;
- rc = xfce_rc_simple_open (session_file, FALSE);
+ rc = xfce_rc_simple_open (manager->session_file, FALSE);
if (G_UNLIKELY (rc == NULL))
return FALSE;
- if (session_chooser && !xfsm_manager_choose_session (rc))
+ if (manager->session_chooser && !xfsm_manager_choose_session (manager, rc))
{
xfce_rc_close (rc);
return FALSE;
}
- g_snprintf (buffer, 1024, "Session: %s", session_name);
+ g_snprintf (buffer, 1024, "Session: %s", manager->session_name);
xfce_rc_set_group (rc, buffer);
count = xfce_rc_read_int_entry (rc, "Count", 0);
@@ -263,7 +360,7 @@ xfsm_manager_load_session (void)
if (G_UNLIKELY (properties == NULL))
continue;
if (xfsm_properties_check (properties))
- pending_properties = g_list_append (pending_properties, properties);
+ g_queue_push_tail (manager->pending_properties, properties);
else
xfsm_properties_free (properties);
}
@@ -273,12 +370,13 @@ xfsm_manager_load_session (void)
xfce_rc_close (rc);
- return pending_properties != NULL;
+ return g_queue_peek_head (manager->pending_properties) != NULL;
}
static gboolean
-xfsm_manager_load_failsafe (XfceRc *rc)
+xfsm_manager_load_failsafe (XfsmManager *manager,
+ XfceRc *rc)
{
FailsafeClient *fclient;
const gchar *old_group;
@@ -314,7 +412,7 @@ xfsm_manager_load_failsafe (XfceRc *rc)
fclient = g_new0 (FailsafeClient, 1);
fclient->command = xfce_rc_read_list_entry (rc, command_entry, NULL);
fclient->screen = gdk_display_get_screen (display, n_screen);
- failsafe_clients = g_list_append (failsafe_clients, fclient);
+ g_queue_push_tail (manager->failsafe_clients, fclient);
}
}
else
@@ -322,41 +420,42 @@ xfsm_manager_load_failsafe (XfceRc *rc)
fclient = g_new0 (FailsafeClient, 1);
fclient->command = command;
fclient->screen = gdk_screen_get_default ();
- failsafe_clients = g_list_append (failsafe_clients, fclient);
+ g_queue_push_tail (manager->failsafe_clients, fclient);
}
}
xfce_rc_set_group (rc, old_group);
- return failsafe_clients != NULL;
+ return g_queue_peek_head (manager->failsafe_clients) != NULL;
}
static void
-xfsm_manager_load_settings (XfceRc *rc)
+xfsm_manager_load_settings (XfsmManager *manager,
+ XfceRc *rc)
{
gboolean session_loaded = FALSE;
const gchar *name;
name = xfce_rc_read_entry (rc, "SessionName", NULL);
if (name != NULL && *name != '\0')
- session_name = g_strdup (name);
+ manager->session_name = g_strdup (name);
else
- session_name = g_strdup (DEFAULT_SESSION_NAME);
+ manager->session_name = g_strdup (DEFAULT_SESSION_NAME);
xfce_rc_set_group (rc, "Chooser");
- session_chooser = xfce_rc_read_bool_entry (rc, "AlwaysDisplay", FALSE);
+ manager->session_chooser = xfce_rc_read_bool_entry (rc, "AlwaysDisplay", FALSE);
- session_loaded = xfsm_manager_load_session ();
+ session_loaded = xfsm_manager_load_session (manager);
if (session_loaded)
{
- xfsm_verbose ("Session \"%s\" loaded successfully.\n\n", session_name);
- failsafe_mode = FALSE;
+ xfsm_verbose ("Session \"%s\" loaded successfully.\n\n", manager->session_name);
+ manager->failsafe_mode = FALSE;
}
else
{
- if (!xfsm_manager_load_failsafe (rc))
+ if (!xfsm_manager_load_failsafe (manager, rc))
{
fprintf (stderr, "xfce4-session: Unable to load failsafe session, exiting. Please check\n"
" the value of the environment variable XDG_CONFIG_DIRS\n"
@@ -365,13 +464,14 @@ xfsm_manager_load_settings (XfceRc *rc)
xfce_rc_close (rc);
exit (EXIT_FAILURE);
}
- failsafe_mode = TRUE;
+ manager->failsafe_mode = TRUE;
}
}
void
-xfsm_manager_init (XfceRc *rc)
+xfsm_manager_load (XfsmManager *manager,
+ XfceRc *rc)
{
gchar *display_name;
gchar *resource_name;
@@ -379,6 +479,10 @@ xfsm_manager_init (XfceRc *rc)
gchar *s;
#endif
+ xfce_rc_set_group (rc, "Compatibility");
+ manager->compat_gnome = xfce_rc_read_bool_entry (rc, "LaunchGnome", FALSE);
+ manager->compat_kde = xfce_rc_read_bool_entry (rc, "LaunchKDE", FALSE);
+
xfce_rc_set_group (rc, "General");
display_name = xfce_gdk_display_get_fullname (gdk_display_get_default ());
@@ -391,57 +495,57 @@ xfsm_manager_init (XfceRc *rc)
#endif
resource_name = g_strconcat ("sessions/xfce4-session-", display_name, NULL);
- session_file = xfce_resource_save_location (XFCE_RESOURCE_CACHE, resource_name, TRUE);
+ manager->session_file = xfce_resource_save_location (XFCE_RESOURCE_CACHE, resource_name, TRUE);
g_free (resource_name);
g_free (display_name);
- xfsm_manager_load_settings (rc);
+ xfsm_manager_load_settings (manager, rc);
}
gboolean
-xfsm_manager_restart (void)
+xfsm_manager_restart (XfsmManager *manager)
{
GdkPixbuf *preview;
unsigned steps;
- g_assert (session_name != NULL);
+ g_assert (manager->session_name != NULL);
/* setup legacy application handling */
xfsm_legacy_init ();
/* tell splash screen that the session is starting now */
- preview = xfsm_manager_load_session_preview (session_name);
+ preview = xfsm_manager_load_session_preview (manager->session_name);
if (preview == NULL)
preview = gdk_pixbuf_from_pixdata (&chooser_icon_data, FALSE, NULL);
- steps = g_list_length (failsafe_mode ? failsafe_clients : pending_properties);
- xfsm_splash_screen_start (splash_screen, session_name, preview, steps);
+ steps = g_queue_get_length (manager->failsafe_mode ? manager->failsafe_clients : manager->pending_properties);
+ xfsm_splash_screen_start (splash_screen, manager->session_name, preview, steps);
g_object_unref (preview);
- g_idle_add ((GSourceFunc) xfsm_manager_startup, NULL);
+ g_idle_add ((GSourceFunc) xfsm_manager_startup, manager);
return TRUE;
}
void
-xfsm_manager_signal_startup_done (void)
+xfsm_manager_signal_startup_done (XfsmManager *manager)
{
gchar buffer[1024];
XfceRc *rc;
xfsm_verbose ("Manager finished startup, entering IDLE mode now\n\n");
- state = XFSM_MANAGER_IDLE;
+ manager->state = XFSM_MANAGER_IDLE;
- if (!failsafe_mode)
+ if (!manager->failsafe_mode)
{
/* restore active workspace, this has to be done after the
* window manager is up, so we do it last.
*/
- g_snprintf (buffer, 1024, "Session: %s", session_name);
- rc = xfce_rc_simple_open (session_file, TRUE);
+ g_snprintf (buffer, 1024, "Session: %s", manager->session_name);
+ rc = xfce_rc_simple_open (manager->session_file, TRUE);
xfce_rc_set_group (rc, buffer);
- xfsm_manager_restore_active_workspace (rc);
+ xfsm_manager_restore_active_workspace (manager, rc);
xfce_rc_close (rc);
/* start legacy applications now */
@@ -491,53 +595,67 @@ xfsm_manager_generate_client_id (SmsConn sms_conn)
XfsmClient*
-xfsm_manager_new_client (SmsConn sms_conn,
- gchar **error)
+xfsm_manager_new_client (XfsmManager *manager,
+ SmsConn sms_conn,
+ gchar **error)
{
- if (G_UNLIKELY (state != XFSM_MANAGER_IDLE)
- && G_UNLIKELY (state != XFSM_MANAGER_STARTUP))
+ XfsmClient *client = NULL;
+
+ if (G_UNLIKELY (manager->state != XFSM_MANAGER_IDLE)
+ && G_UNLIKELY (manager->state != XFSM_MANAGER_STARTUP))
{
if (error != NULL)
*error = "We don't accept clients while in CheckPoint/Shutdown state!";
return NULL;
}
- return xfsm_client_new (sms_conn);
+ client = xfsm_client_new (sms_conn);
+ client->manager = manager; /* dirty hack until client is a GObject */
+ return client;
+}
+
+
+static gint
+xfsm_properties_queue_find (gconstpointer a,
+ gconstpointer b)
+{
+ XfsmProperties *properties = XFSM_PROPERTIES (a);
+ const gchar *previous_id = (const gchar *) b;
+
+ if (strcmp (properties->client_id, previous_id) == 0)
+ return 0;
+ return 1;
}
gboolean
-xfsm_manager_register_client (XfsmClient *client,
+xfsm_manager_register_client (XfsmManager *manager,
+ XfsmClient *client,
const gchar *previous_id)
{
XfsmProperties *properties = NULL;
gchar *client_id;
GList *lp;
-
+
if (previous_id != NULL)
{
- for (lp = starting_properties; lp != NULL; lp = lp->next)
+ lp = g_queue_find_custom (manager->starting_properties,
+ previous_id,
+ xfsm_properties_queue_find);
+ if (lp != NULL)
{
- if (strcmp (XFSM_PROPERTIES (lp->data)->client_id, previous_id) == 0)
- {
- properties = XFSM_PROPERTIES (lp->data);
- starting_properties = g_list_remove (starting_properties,
- properties);
- break;
- }
+ properties = XFSM_PROPERTIES (lp->data);
+ g_queue_delete_link (manager->starting_properties, lp);
}
-
- if (properties == NULL)
+ else
{
- for (lp = pending_properties; lp != NULL; lp = lp->next)
+ lp = g_queue_find_custom (manager->pending_properties,
+ previous_id,
+ xfsm_properties_queue_find);
+ if (lp != NULL)
{
- if (!strcmp (XFSM_PROPERTIES (lp->data)->client_id, previous_id))
- {
- properties = XFSM_PROPERTIES (lp->data);
- pending_properties = g_list_remove (pending_properties,
- properties);
- break;
- }
+ properties = XFSM_PROPERTIES (lp->data);
+ g_queue_delete_link (manager->pending_properties, lp);
}
}
@@ -565,7 +683,7 @@ xfsm_manager_register_client (XfsmClient *client,
g_free (client_id);
}
- running_clients = g_list_append (running_clients, client);
+ g_queue_push_tail (manager->running_clients, client);
SmsRegisterClientReply (client->sms_conn, (char *) client->id);
@@ -578,7 +696,8 @@ xfsm_manager_register_client (XfsmClient *client,
client);
}
- if ((failsafe_mode || previous_id != NULL) && state == XFSM_MANAGER_STARTUP)
+ if ((manager->failsafe_mode || previous_id != NULL)
+ && manager->state == XFSM_MANAGER_STARTUP)
{
/* Only continue the startup if we are either in Failsafe mode (which
* means that we don't have any previous_id at all) or the previous_id
@@ -586,8 +705,8 @@ xfsm_manager_register_client (XfsmClient *client,
* above, previous_id will be NULL here.
* See http://bugs.xfce.org/view_bug_page.php?f_id=212 for details.
*/
- if (starting_properties == NULL)
- xfsm_startup_session_continue ();
+ if (g_queue_peek_head (manager->starting_properties) == NULL)
+ xfsm_startup_session_continue (manager);
}
return TRUE;
@@ -595,7 +714,8 @@ xfsm_manager_register_client (XfsmClient *client,
void
-xfsm_manager_start_interact (XfsmClient *client)
+xfsm_manager_start_interact (XfsmManager *manager,
+ XfsmClient *client)
{
/* notify client of interact */
SmsInteract (client->sms_conn);
@@ -608,61 +728,68 @@ xfsm_manager_start_interact (XfsmClient *client)
void
-xfsm_manager_interact (XfsmClient *client,
- int dialog_type)
+xfsm_manager_interact (XfsmManager *manager,
+ XfsmClient *client,
+ int dialog_type)
{
GList *lp;
-
+
if (G_UNLIKELY (client->state != XFSM_CLIENT_SAVING))
{
xfsm_verbose ("Client Id = %s, requested INTERACT, but client is not in SAVING mode\n"
" Client will be disconnected now.\n\n",
client->id);
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (manager, client, TRUE);
}
- else if (G_UNLIKELY (state != XFSM_MANAGER_CHECKPOINT)
- && G_UNLIKELY (state != XFSM_MANAGER_SHUTDOWN))
+ else if (G_UNLIKELY (manager->state != XFSM_MANAGER_CHECKPOINT)
+ && G_UNLIKELY (manager->state != XFSM_MANAGER_SHUTDOWN))
{
xfsm_verbose ("Client Id = %s, requested INTERACT, but manager is not in CheckPoint/Shutdown mode\n"
- " Clinet will be disconnected now.\n\n",
+ " Client will be disconnected now.\n\n",
client->id);
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (manager, client, TRUE);
}
else
{
- for (lp = running_clients; lp != NULL; lp = lp->next)
- if (XFSM_CLIENT (lp->data)->state == XFSM_CLIENT_INTERACTING)
- {
- client->state = XFSM_CLIENT_WAITFORINTERACT;
- return;
- }
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ if (client->state == XFSM_CLIENT_INTERACTING)
+ {
+ client->state = XFSM_CLIENT_WAITFORINTERACT;
+ return;
+ }
+ }
- xfsm_manager_start_interact (client);
+ xfsm_manager_start_interact (manager, client);
}
}
void
-xfsm_manager_interact_done (XfsmClient *client,
- gboolean cancel_shutdown)
+xfsm_manager_interact_done (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean cancel_shutdown)
{
GList *lp;
-
+
if (G_UNLIKELY (client->state != XFSM_CLIENT_INTERACTING))
{
xfsm_verbose ("Client Id = %s, send INTERACT DONE, but client is not in INTERACTING state\n"
" Client will be disconnected now.\n\n",
client->id);
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (manager, client, TRUE);
return;
}
- else if (G_UNLIKELY (state != XFSM_MANAGER_CHECKPOINT)
- && G_UNLIKELY (state != XFSM_MANAGER_SHUTDOWN))
+ else if (G_UNLIKELY (manager->state != XFSM_MANAGER_CHECKPOINT)
+ && G_UNLIKELY (manager->state != XFSM_MANAGER_SHUTDOWN))
{
xfsm_verbose ("Client Id = %s, send INTERACT DONE, but manager is not in CheckPoint/Shutdown state\n"
" Client will be disconnected now.\n\n",
client->id);
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (manager, client, TRUE);
return;
}
@@ -675,10 +802,10 @@ xfsm_manager_interact_done (XfsmClient *client,
* for the interact-style field. Otherwise, cancel-shutdown must be
* False.
*/
- if (cancel_shutdown && state == XFSM_MANAGER_SHUTDOWN)
+ if (cancel_shutdown && manager->state == XFSM_MANAGER_SHUTDOWN)
{
/* we go into checkpoint state from here... */
- state = XFSM_MANAGER_CHECKPOINT;
+ manager->state = XFSM_MANAGER_CHECKPOINT;
/* If a shutdown is in progress, the user may have the option
* of cancelling the shutdown. If the shutdown is cancelled
@@ -686,25 +813,33 @@ xfsm_manager_interact_done (XfsmClient *client,
* manager should send a "Shutdown Cancelled" message to each
* client that requested to interact.
*/
- for (lp = running_clients; lp != NULL; lp = lp->next)
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
{
- if (XFSM_CLIENT (lp->data)->state != XFSM_CLIENT_WAITFORINTERACT)
+ XfsmClient *client = lp->data;
+ if (client->state != XFSM_CLIENT_WAITFORINTERACT)
continue;
/* reset all clients that are waiting for interact */
client->state = XFSM_CLIENT_SAVING;
- SmsShutdownCancelled (XFSM_CLIENT (lp->data)->sms_conn);
+ SmsShutdownCancelled (client->sms_conn);
}
}
else
{
/* let next client interact */
- for (lp = running_clients; lp != NULL; lp = lp->next)
- if (XFSM_CLIENT (lp->data)->state == XFSM_CLIENT_WAITFORINTERACT)
- {
- xfsm_manager_start_interact (XFSM_CLIENT (lp->data));
- break;
- }
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ if (client->state == XFSM_CLIENT_WAITFORINTERACT)
+ {
+ xfsm_manager_start_interact (manager, client);
+ break;
+ }
+ }
}
/* restart save yourself timeout for client */
@@ -715,30 +850,31 @@ xfsm_manager_interact_done (XfsmClient *client,
void
-xfsm_manager_save_yourself (XfsmClient *client,
- gint save_type,
- gboolean shutdown,
- gint interact_style,
- gboolean fast,
- gboolean global)
+xfsm_manager_save_yourself (XfsmManager *manager,
+ XfsmClient *client,
+ gint save_type,
+ gboolean shutdown,
+ gint interact_style,
+ gboolean fast,
+ gboolean global)
{
gboolean shutdown_save = TRUE;
- GList *lp;
+ GList *lp;
if (G_UNLIKELY (client->state != XFSM_CLIENT_IDLE))
{
xfsm_verbose ("Client Id = %s, requested SAVE YOURSELF, but client is not in IDLE mode.\n"
" Client will be nuked now.\n\n",
client->id);
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (manager, client, TRUE);
return;
}
- else if (G_UNLIKELY (state != XFSM_MANAGER_IDLE))
+ else if (G_UNLIKELY (manager->state != XFSM_MANAGER_IDLE))
{
xfsm_verbose ("Client Id = %s, requested SAVE YOURSELF, but manager is not in IDLE mode.\n"
" Client will be nuked now.\n\n",
client->id);
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (manager, client, TRUE);
return;
}
@@ -756,19 +892,26 @@ xfsm_manager_save_yourself (XfsmClient *client,
}
else
{
- if (!fast && shutdown && !shutdownDialog (&shutdown_type, &shutdown_save))
+ if (!fast && shutdown && !shutdownDialog (manager->session_name, &manager->shutdown_type, &shutdown_save))
return;
if (!shutdown || shutdown_save)
{
- state = shutdown ? XFSM_MANAGER_SHUTDOWN : XFSM_MANAGER_CHECKPOINT;
+ manager->state = shutdown ? XFSM_MANAGER_SHUTDOWN : XFSM_MANAGER_CHECKPOINT;
/* handle legacy applications first! */
xfsm_legacy_perform_session_save ();
- for (lp = running_clients; lp != NULL; lp = lp->next)
+ if (client->state == XFSM_CLIENT_INTERACTING)
+ {
+ client->state = XFSM_CLIENT_WAITFORINTERACT;
+ return;
+ }
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
{
- XfsmClient *client = XFSM_CLIENT (lp->data);
+ XfsmClient *client = lp->data;
/* xterm's session management is broken, so we won't
* send a SAVE YOURSELF to xterms */
@@ -793,16 +936,17 @@ xfsm_manager_save_yourself (XfsmClient *client,
else
{
/* shutdown session without saving */
- xfsm_manager_perform_shutdown ();
+ xfsm_manager_perform_shutdown (manager);
}
}
}
void
-xfsm_manager_save_yourself_phase2 (XfsmClient *client)
+xfsm_manager_save_yourself_phase2 (XfsmManager *manager,
+ XfsmClient *client)
{
- if (state != XFSM_MANAGER_CHECKPOINT && state != XFSM_MANAGER_SHUTDOWN)
+ if (manager->state != XFSM_MANAGER_CHECKPOINT && manager->state != XFSM_MANAGER_SHUTDOWN)
{
SmsSaveYourselfPhase2 (client->sms_conn);
client->state = XFSM_CLIENT_SAVINGLOCAL;
@@ -817,15 +961,16 @@ xfsm_manager_save_yourself_phase2 (XfsmClient *client)
g_source_remove (client->save_timeout_id);
client->save_timeout_id = 0;
- if (!xfsm_manager_check_clients_saving ())
- xfsm_manager_maybe_enter_phase2 ();
+ if (!xfsm_manager_check_clients_saving (manager))
+ xfsm_manager_maybe_enter_phase2 (manager);
}
}
void
-xfsm_manager_save_yourself_done (XfsmClient *client,
- gboolean success)
+xfsm_manager_save_yourself_done (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean success)
{
if (client->state != XFSM_CLIENT_SAVING && client->state != XFSM_CLIENT_SAVINGLOCAL)
{
@@ -833,7 +978,7 @@ xfsm_manager_save_yourself_done (XfsmClient *client,
"in save mode. Prepare to be nuked!\n",
client->id);
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (manager, client, TRUE);
}
/* remove client save timeout, as client responded in time */
@@ -846,27 +991,28 @@ xfsm_manager_save_yourself_done (XfsmClient *client,
client->state = XFSM_CLIENT_IDLE;
SmsSaveComplete (client->sms_conn);
}
- else if (state != XFSM_MANAGER_CHECKPOINT && state != XFSM_MANAGER_SHUTDOWN)
+ else if (manager->state != XFSM_MANAGER_CHECKPOINT && manager->state != XFSM_MANAGER_SHUTDOWN)
{
xfsm_verbose ("Client Id = %s, send SAVE YOURSELF DONE, but manager is not in CheckPoint/Shutdown mode.\n"
" Client will be nuked now.\n\n",
client->id);
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (manager, client, TRUE);
}
else
{
client->state = XFSM_CLIENT_SAVEDONE;
- xfsm_manager_complete_saveyourself ();
+ xfsm_manager_complete_saveyourself (manager);
}
}
void
-xfsm_manager_close_connection (XfsmClient *client,
- gboolean cleanup)
+xfsm_manager_close_connection (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean cleanup)
{
IceConn ice_conn;
- GList *lp;
+ GList *lp;
client->state = XFSM_CLIENT_DISCONNECTED;
if (client->save_timeout_id > 0)
@@ -883,26 +1029,35 @@ xfsm_manager_close_connection (XfsmClient *client,
IceCloseConnection (ice_conn);
}
- if (state == XFSM_MANAGER_SHUTDOWNPHASE2)
+ if (manager->state == XFSM_MANAGER_SHUTDOWNPHASE2)
{
- for (lp = running_clients; lp != NULL; lp = lp->next)
- if (XFSM_CLIENT (lp->data)->state != XFSM_CLIENT_DISCONNECTED)
- return;
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ if (client->state != XFSM_CLIENT_DISCONNECTED)
+ return;
+ }
/* all clients finished the DIE phase in time */
- g_source_remove (die_timeout_id);
+ if (manager->die_timeout_id)
+ {
+ g_source_remove (manager->die_timeout_id);
+ manager->die_timeout_id = 0;
+ }
gtk_main_quit ();
}
- else if (state == XFSM_MANAGER_SHUTDOWN || state == XFSM_MANAGER_CHECKPOINT)
+ else if (manager->state == XFSM_MANAGER_SHUTDOWN || manager->state == XFSM_MANAGER_CHECKPOINT)
{
xfsm_verbose ("Client Id = %s, closed connection in checkpoint state\n"
" Session manager will show NO MERCY\n\n",
client->id);
/* stupid client disconnected in CheckPoint state, prepare to be nuked! */
- running_clients = g_list_remove (running_clients, client);
+ g_queue_remove (manager->running_clients, client);
xfsm_client_free (client);
- xfsm_manager_complete_saveyourself ();
+ xfsm_manager_complete_saveyourself (manager);
}
else
{
@@ -912,7 +1067,7 @@ xfsm_manager_close_connection (XfsmClient *client,
{
if (properties->restart_style_hint == SmRestartAnyway)
{
- restart_properties = g_list_append (restart_properties, properties);
+ g_queue_push_tail (manager->restart_properties, properties);
client->properties = NULL;
}
else if (properties->restart_style_hint == SmRestartImmediately)
@@ -923,14 +1078,14 @@ xfsm_manager_close_connection (XfsmClient *client,
" Will be re-scheduled for run on next startup\n",
properties->client_id, properties->restart_attempts);
- restart_properties = g_list_append (restart_properties, properties);
+ g_queue_push_tail (manager->restart_properties, properties);
client->properties = NULL;
}
#if 0
else if (xfsm_manager_run_prop_command (properties, SmRestartCommand))
{
/* XXX - add a timeout here, in case the application does not come up */
- pending_properties = g_list_append (pending_properties, properties);
+ g_queue_push_tail (manager->pending_properties, properties);
client->properties = NULL;
}
#endif
@@ -945,7 +1100,7 @@ xfsm_manager_close_connection (XfsmClient *client,
* But for now, this work-around fixes the problem of the evergrowing
* number of xfwm4 session files when restarting xfwm4 within a session.
*/
- if (state == XFSM_MANAGER_IDLE && properties->discard_command != NULL)
+ if (manager->state == XFSM_MANAGER_IDLE && properties->discard_command != NULL)
{
xfsm_verbose ("Client Id = %s exited while in IDLE state, running "
"discard command now.\n\n", properties->client_id);
@@ -960,23 +1115,29 @@ xfsm_manager_close_connection (XfsmClient *client,
}
}
- running_clients = g_list_remove (running_clients, client);
+ g_queue_remove (manager->running_clients, client);
xfsm_client_free (client);
}
}
void
-xfsm_manager_close_connection_by_ice_conn (IceConn ice_conn)
+xfsm_manager_close_connection_by_ice_conn (XfsmManager *manager,
+ IceConn ice_conn)
{
GList *lp;
-
- for (lp = running_clients; lp != NULL; lp = lp->next)
- if (SmsGetIceConnection (XFSM_CLIENT (lp->data)->sms_conn) == ice_conn)
- {
- xfsm_manager_close_connection (XFSM_CLIENT (lp->data), FALSE);
- break;
- }
+
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ if (SmsGetIceConnection (client->sms_conn) == ice_conn)
+ {
+ xfsm_manager_close_connection (manager, client, FALSE);
+ break;
+ }
+ }
/* be sure to close the Ice connection in any case */
IceSetShutdownNegotiation (ice_conn, False);
@@ -985,44 +1146,56 @@ xfsm_manager_close_connection_by_ice_conn (IceConn ice_conn)
void
-xfsm_manager_perform_shutdown (void)
-{
+xfsm_manager_perform_shutdown (XfsmManager *manager)
+{
GList *lp;
-
+
/* send SmDie message to all clients */
- state = XFSM_MANAGER_SHUTDOWNPHASE2;
- for (lp = running_clients; lp != NULL; lp = lp->next)
- SmsDie (XFSM_CLIENT (lp->data)->sms_conn);
+ manager->state = XFSM_MANAGER_SHUTDOWNPHASE2;
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ SmsDie (client->sms_conn);
+ }
/* give all clients the chance to close the connection */
- die_timeout_id = g_timeout_add (DIE_TIMEOUT,
- (GSourceFunc) gtk_main_quit,
- NULL);
+ manager->die_timeout_id = g_timeout_add (DIE_TIMEOUT,
+ (GSourceFunc) gtk_main_quit,
+ NULL);
}
gboolean
-xfsm_manager_check_clients_saving (void)
+xfsm_manager_check_clients_saving (XfsmManager *manager)
{
GList *lp;
-
- for (lp = running_clients; lp != NULL; lp = lp->next)
- if (XFSM_CLIENT (lp->data)->state == XFSM_CLIENT_SAVING)
- return TRUE;
+
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ if (client->state == XFSM_CLIENT_SAVING)
+ return TRUE;
+ }
return FALSE;
}
gboolean
-xfsm_manager_maybe_enter_phase2 (void)
+xfsm_manager_maybe_enter_phase2 (XfsmManager *manager)
{
gboolean entered_phase2 = FALSE;
- GList *lp;
+ GList *lp;
- for (lp = running_clients; lp != NULL; lp = lp->next)
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
{
- XfsmClient *client = XFSM_CLIENT (lp->data);
+ XfsmClient *client = lp->data;
if (client->state == XFSM_CLIENT_WAITFORPHASE2)
{
@@ -1043,40 +1216,43 @@ xfsm_manager_maybe_enter_phase2 (void)
void
-xfsm_manager_complete_saveyourself (void)
+xfsm_manager_complete_saveyourself (XfsmManager *manager)
{
GList *lp;
-
+
/* Check if still clients in SAVING state or if we have to enter PHASE2
* now. In either case, SaveYourself cannot be completed in this run.
*/
- if (xfsm_manager_check_clients_saving () || xfsm_manager_maybe_enter_phase2 ())
+ if (xfsm_manager_check_clients_saving (manager) || xfsm_manager_maybe_enter_phase2 (manager))
return;
xfsm_verbose ("Manager finished SAVE YOURSELF, session data will be stored now.\n\n");
/* all clients done, store session data */
- xfsm_manager_store_session ();
+ xfsm_manager_store_session (manager);
- if (state == XFSM_MANAGER_CHECKPOINT)
+ if (manager->state == XFSM_MANAGER_CHECKPOINT)
{
/* reset all clients to idle state */
- state = XFSM_MANAGER_IDLE;
- for (lp = running_clients; lp != NULL; lp = lp->next)
+ manager->state = XFSM_MANAGER_IDLE;
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
{
- XFSM_CLIENT (lp->data)->state = XFSM_CLIENT_IDLE;
- SmsSaveComplete (XFSM_CLIENT (lp->data)->sms_conn);
+ XfsmClient *client = lp->data;
+ client->state = XFSM_CLIENT_IDLE;
+ SmsSaveComplete (client->sms_conn);
}
}
else
{
/* shutdown the session */
- xfsm_manager_perform_shutdown ();
+ xfsm_manager_perform_shutdown (manager);
}
}
-gboolean
+static gboolean
xfsm_manager_save_timeout (gpointer client_data)
{
XfsmClient *client = XFSM_CLIENT (client_data);
@@ -1085,14 +1261,14 @@ xfsm_manager_save_timeout (gpointer client_data)
" Client will be disconnected now.\n\n",
client->id);
- xfsm_manager_close_connection (client, TRUE);
+ xfsm_manager_close_connection (client->manager, client, TRUE);
return FALSE;
}
void
-xfsm_manager_store_session (void)
+xfsm_manager_store_session (XfsmManager *manager)
{
WnckWorkspace *workspace;
GdkDisplay *display;
@@ -1105,46 +1281,52 @@ xfsm_manager_store_session (void)
gint count = 0;
gint n, m;
- rc = xfce_rc_simple_open (session_file, FALSE);
+ rc = xfce_rc_simple_open (manager->session_file, FALSE);
if (G_UNLIKELY (rc == NULL))
{
fprintf (stderr,
"xfce4-session: Unable to open session file %s for "
"writing. Session data will not be stored. Please check "
"your installation.\n",
- session_file);
+ manager->session_file);
return;
}
/* backup the old session file first */
- if (g_file_test (session_file, G_FILE_TEST_IS_REGULAR))
+ if (g_file_test (manager->session_file, G_FILE_TEST_IS_REGULAR))
{
- backup = g_strconcat (session_file, ".bak", NULL);
+ backup = g_strconcat (manager->session_file, ".bak", NULL);
unlink (backup);
- link (session_file, backup);
+ link (manager->session_file, backup);
g_free (backup);
}
- group = g_strconcat ("Session: ", session_name, NULL);
+ group = g_strconcat ("Session: ", manager->session_name, NULL);
xfce_rc_delete_group (rc, group, TRUE);
xfce_rc_set_group (rc, group);
g_free (group);
- for (lp = restart_properties; lp != NULL; lp = lp->next)
+ for (lp = g_queue_peek_nth_link (manager->restart_properties, 0);
+ lp;
+ lp = lp->next)
{
+ XfsmProperties *properties = lp->data;
g_snprintf (prefix, 64, "Client%d_", count);
- xfsm_properties_store (XFSM_PROPERTIES (lp->data), rc, prefix);
+ xfsm_properties_store (properties, rc, prefix);
++count;
}
- for (lp = running_clients; lp != NULL; lp = lp->next)
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
{
- if (XFSM_CLIENT (lp->data)->properties == NULL
- || !xfsm_properties_check (XFSM_CLIENT (lp->data)->properties))
+ XfsmClient *client = lp->data;
+ if (client->properties == NULL
+ || !xfsm_properties_check (client->properties))
continue;
g_snprintf (prefix, 64, "Client%d_", count);
- xfsm_properties_store (XFSM_CLIENT (lp->data)->properties, rc, prefix);
+ xfsm_properties_store (client->properties, rc, prefix);
++count;
}
@@ -1174,6 +1356,60 @@ xfsm_manager_store_session (void)
}
+gint
+xfsm_manager_get_shutdown_type (XfsmManager *manager)
+{
+ return manager->shutdown_type;
+}
+
+
+GQueue *
+xfsm_manager_get_queue (XfsmManager *manager,
+ XfsmManagerQueueType q_type)
+{
+ switch(q_type)
+ {
+ case XFSM_MANAGER_QUEUE_PENDING_PROPS:
+ return manager->pending_properties;
+ case XFSM_MANAGER_QUEUE_STARTING_PROPS:
+ return manager->starting_properties;
+ case XFSM_MANAGER_QUEUE_RESTART_PROPS:
+ return manager->restart_properties;
+ case XFSM_MANAGER_QUEUE_RUNNING_CLIENTS:
+ return manager->running_clients;
+ case XFSM_MANAGER_QUEUE_FAILSAFE_CLIENTS:
+ return manager->failsafe_clients;
+ default:
+ g_warning ("Requested invalid queue type %d", (gint)q_type);
+ return NULL;
+ }
+}
+
+
+gboolean
+xfsm_manager_get_use_failsafe_mode (XfsmManager *manager)
+{
+ return manager->failsafe_mode;
+}
+
+
+gboolean
+xfsm_manager_get_compat_startup (XfsmManager *manager,
+ XfsmManagerCompatType type)
+{
+ switch (type)
+ {
+ case XFSM_MANAGER_COMPAT_GNOME:
+ return manager->compat_gnome;
+ case XFSM_MANAGER_COMPAT_KDE:
+ return manager->compat_kde;
+ default:
+ g_warning ("Invalid compat startup type %d", type);
+ return FALSE;
+ }
+}
+
+
static GdkPixbuf*
xfsm_manager_load_session_preview (const gchar *name)
{
diff --git a/xfce4-session/xfsm-manager.h b/xfce4-session/xfsm-manager.h
index fa6d0d93..d86210a8 100644
--- a/xfce4-session/xfsm-manager.h
+++ b/xfce4-session/xfsm-manager.h
@@ -1,6 +1,7 @@
/* $Id$ */
/*-
* Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -22,10 +23,17 @@
#ifndef __XFSM_MANAGER_H__
#define __XFSM_MANAGER_H__
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
#include <libxfce4util/libxfce4util.h>
#include <xfce4-session/xfsm-client.h>
+#define XFSM_TYPE_MANAGER (xfsm_manager_get_type())
+#define XFSM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XFSM_TYPE_MANAGER, XfsmManager))
+#define XFSM_IS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XFSM_TYPE_MANAGER))
#define DIE_TIMEOUT ( 7 * 1000)
#define SAVE_TIMEOUT (60 * 1000)
@@ -40,49 +48,104 @@ typedef enum
XFSM_MANAGER_SHUTDOWNPHASE2,
} XfsmManagerState;
+typedef enum
+{
+ XFSM_MANAGER_QUEUE_PENDING_PROPS = 0,
+ XFSM_MANAGER_QUEUE_STARTING_PROPS,
+ XFSM_MANAGER_QUEUE_RESTART_PROPS,
+ XFSM_MANAGER_QUEUE_RUNNING_CLIENTS,
+ XFSM_MANAGER_QUEUE_FAILSAFE_CLIENTS,
+} XfsmManagerQueueType;
+
+typedef enum
+{
+ XFSM_MANAGER_COMPAT_GNOME = 0,
+ XFSM_MANAGER_COMPAT_KDE,
+} XfsmManagerCompatType;
+
+typedef struct _XfsmManager XfsmManager;
-void xfsm_manager_init (XfceRc *rc);
+GType xfsm_manager_get_type (void) G_GNUC_CONST;
-gboolean xfsm_manager_restart (void);
+XfsmManager *xfsm_manager_new (void);
+
+void xfsm_manager_load (XfsmManager *manager,
+ XfceRc *rc);
+
+gboolean xfsm_manager_restart (XfsmManager *manager);
/* call when startup is finished */
-void xfsm_manager_signal_startup_done (void);
+void xfsm_manager_signal_startup_done (XfsmManager *manager);
/* call for each client that fails */
-void xfsm_manager_handle_failed_client (XfsmProperties *properties);
+void xfsm_manager_handle_failed_client (XfsmManager *manager,
+ XfsmProperties *properties);
gchar* xfsm_manager_generate_client_id (SmsConn sms_conn) G_GNUC_PURE;
-XfsmClient* xfsm_manager_new_client (SmsConn sms_conn,
- gchar **error);
-gboolean xfsm_manager_register_client (XfsmClient *client,
- const gchar *previous_id);
-void xfsm_manager_start_interact (XfsmClient *client);
-void xfsm_manager_interact (XfsmClient *client,
- gint dialog_type);
-void xfsm_manager_interact_done (XfsmClient *client,
- gboolean cancel_shutdown);
-void xfsm_manager_save_yourself (XfsmClient *client,
- gint save_type,
- gboolean shutdown,
- gint interact_style,
- gboolean fast,
- gboolean global);
-void xfsm_manager_save_yourself_phase2 (XfsmClient *client);
-void xfsm_manager_save_yourself_done (XfsmClient *client,
- gboolean success);
-void xfsm_manager_close_connection (XfsmClient *client,
- gboolean cleanup);
-void xfsm_manager_close_connection_by_ice_conn (IceConn ice_conn);
-
-gboolean xfsm_manager_check_clients_saving (void);
-gboolean xfsm_manager_maybe_enter_phase2 (void);
-gboolean xfsm_manager_save_timeout (gpointer client_data);
-void xfsm_manager_perform_shutdown (void);
-gboolean xfsm_manager_run_command (const XfsmProperties *properties,
+XfsmClient* xfsm_manager_new_client (XfsmManager *manager,
+ SmsConn sms_conn,
+ gchar **error);
+
+gboolean xfsm_manager_register_client (XfsmManager *manager,
+ XfsmClient *client,
+ const gchar *previous_id);
+
+void xfsm_manager_start_interact (XfsmManager *manager,
+ XfsmClient *client);
+
+void xfsm_manager_interact (XfsmManager *manager,
+ XfsmClient *client,
+ gint dialog_type);
+
+void xfsm_manager_interact_done (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean cancel_shutdown);
+
+void xfsm_manager_save_yourself (XfsmManager *manager,
+ XfsmClient *client,
+ gint save_type,
+ gboolean shutdown,
+ gint interact_style,
+ gboolean fast,
+ gboolean global);
+
+void xfsm_manager_save_yourself_phase2 (XfsmManager *manager,
+ XfsmClient *client);
+
+void xfsm_manager_save_yourself_done (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean success);
+
+void xfsm_manager_close_connection (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean cleanup);
+
+void xfsm_manager_close_connection_by_ice_conn (XfsmManager *manager,
+ IceConn ice_conn);
+
+gboolean xfsm_manager_check_clients_saving (XfsmManager *manager);
+
+gboolean xfsm_manager_maybe_enter_phase2 (XfsmManager *manager);
+
+void xfsm_manager_perform_shutdown (XfsmManager *manager);
+
+gboolean xfsm_manager_run_command (XfsmManager *manager,
+ const XfsmProperties *properties,
const gchar *command);
-void xfsm_manager_store_session (void);
-void xfsm_manager_complete_saveyourself (void);
-#endif /* !__XFSM_MANAGER_H__ */
+void xfsm_manager_store_session (XfsmManager *manager);
+
+void xfsm_manager_complete_saveyourself (XfsmManager *manager);
+
+gint xfsm_manager_get_shutdown_type (XfsmManager *manager);
+
+GQueue *xfsm_manager_get_queue (XfsmManager *manager,
+ XfsmManagerQueueType q_type);
+gboolean xfsm_manager_get_use_failsafe_mode (XfsmManager *manager);
+
+gboolean xfsm_manager_get_compat_startup (XfsmManager *manager,
+ XfsmManagerCompatType type);
+
+#endif /* !__XFSM_MANAGER_H__ */
diff --git a/xfce4-session/xfsm-properties.c b/xfce4-session/xfsm-properties.c
index a9bf92aa..a888e73e 100644
--- a/xfce4-session/xfsm-properties.c
+++ b/xfce4-session/xfsm-properties.c
@@ -658,6 +658,8 @@ xfsm_properties_free (XfsmProperties *properties)
{
g_return_if_fail (properties != NULL);
+ if (properties->startup_timeout_id != 0)
+ g_source_remove (properties->startup_timeout_id);
if (properties->client_id != NULL)
g_free (properties->client_id);
if (properties->hostname != NULL)
diff --git a/xfce4-session/xfsm-startup.c b/xfce4-session/xfsm-startup.c
index 4033cc70..a449fe2d 100644
--- a/xfce4-session/xfsm-startup.c
+++ b/xfce4-session/xfsm-startup.c
@@ -1,6 +1,7 @@
/* $Id$ */
/*-
* Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -58,17 +59,36 @@
#include "xfsm-startup.h"
+typedef struct
+{
+ XfsmManager *manager;
+ XfsmProperties *properties;
+} XfsmStartupTimeoutData;
+
+typedef struct
+{
+ XfsmManager *manager;
+ gchar *client_id;
+} XfsmStartupChildWatchData;
+
/*
Prototypes
*/
-static void xfsm_startup_failsafe (void);
-static gboolean xfsm_startup_session_next_prio_group (void);
+static void xfsm_startup_failsafe (XfsmManager *manager);
+
+static gboolean xfsm_startup_session_next_prio_group (XfsmManager *manager);
+
static void xfsm_startup_child_watch (GPid pid,
gint status,
gpointer user_data);
static void xfsm_startup_child_watch_destroy (gpointer user_data);
-static gboolean xfsm_startup_handle_failed_client (gpointer data);
+
+static gboolean xfsm_startup_timeout (gpointer data);
+static void xfsm_startup_timeout_destroy (gpointer data);
+
+static void xfsm_startup_handle_failed_client (XfsmProperties *properties,
+ XfsmManager *manager);
void
xfsm_startup_init (XfceRc *rc)
@@ -421,40 +441,39 @@ xfsm_startup_autostart (void)
void
-xfsm_startup_foreign (void)
+xfsm_startup_foreign (XfsmManager *manager)
{
- if (compat_kde)
+ if (xfsm_manager_get_compat_startup(manager, XFSM_MANAGER_COMPAT_KDE))
xfsm_compat_kde_startup (splash_screen);
- if (compat_gnome)
+ if (xfsm_manager_get_compat_startup(manager, XFSM_MANAGER_COMPAT_GNOME))
xfsm_compat_gnome_startup (splash_screen);
}
void
-xfsm_startup_begin (void)
+xfsm_startup_begin (XfsmManager *manager)
{
- if (failsafe_mode)
+ if (xfsm_manager_get_use_failsafe_mode (manager))
{
- xfsm_startup_failsafe ();
+ xfsm_startup_failsafe (manager);
xfsm_startup_autostart ();
}
else
{
- xfsm_startup_session_continue ();
+ xfsm_startup_session_continue (manager);
}
}
static void
-xfsm_startup_failsafe (void)
+xfsm_startup_failsafe (XfsmManager *manager)
{
- GList *lp;
+ GQueue *failsafe_clients = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_FAILSAFE_CLIENTS);
+ FailsafeClient *fclient;
- for (lp = failsafe_clients; lp; lp = lp->next)
+ while ((fclient = g_queue_pop_head (failsafe_clients)))
{
- FailsafeClient *fclient = (FailsafeClient *) lp->data;
-
/* FIXME: splash */
/* let the user know whats going on */
if (G_LIKELY (splash_screen != NULL))
@@ -466,16 +485,12 @@ xfsm_startup_failsafe (void)
/* start the application */
xfsm_start_application (fclient->command, NULL, fclient->screen,
NULL, NULL, NULL);
- g_strfreev (fclient->command);
- g_free (fclient);
+ xfsm_failsafe_client_free (fclient);
}
-
- g_list_free (failsafe_clients);
- failsafe_clients = NULL;
}
-static gboolean
+static GPid
xfsm_startup_session_client (XfsmProperties *properties)
{
gchar **argv;
@@ -513,75 +528,64 @@ xfsm_startup_session_client (XfsmProperties *properties)
{
/* tell the user that we failed to fork */
perror ("Failed to fork new process");
- return FALSE;
+ return -1;
}
- /* watch the child process */
- g_child_watch_add_full (G_PRIORITY_LOW, pid, xfsm_startup_child_watch, g_strdup (properties->client_id), xfsm_startup_child_watch_destroy);
- properties->startup_timeout_id = g_timeout_add (STARTUP_TIMEOUT,
- xfsm_startup_handle_failed_client,
- properties);
- return TRUE;
+ return pid;
}
void
-xfsm_startup_session_continue ()
+xfsm_startup_session_continue (XfsmManager *manager)
{
+ GQueue *pending_properties = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_PENDING_PROPS);
gboolean client_started = FALSE;
/* try to start some clients. if we fail to start anything in the current
* priority group, move right to the next one. if we *did* start something,
* the failed/registered handlers will take care of moving us on to the
* next priority group */
- while (client_started == FALSE && pending_properties != NULL)
- client_started = xfsm_startup_session_next_prio_group ();
+ while (client_started == FALSE && g_queue_peek_head (pending_properties) != NULL)
+ client_started = xfsm_startup_session_next_prio_group (manager);
- if (G_UNLIKELY (client_started == FALSE && pending_properties == NULL))
+ if (G_UNLIKELY (client_started == FALSE && g_queue_peek_head (pending_properties) == NULL))
{
/* we failed to start anything, and we don't have anything else,
* to start, so just move on to the autostart items and signal
* the manager that we're finished */
xfsm_startup_autostart ();
- xfsm_manager_signal_startup_done ();
+ xfsm_manager_signal_startup_done (manager);
}
}
/* returns TRUE if we started anything, FALSE if we didn't */
static gboolean
-xfsm_startup_session_next_prio_group (void)
+xfsm_startup_session_next_prio_group (XfsmManager *manager)
{
+ GQueue *pending_properties = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_PENDING_PROPS);
+ GQueue *starting_properties = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_STARTING_PROPS);
XfsmProperties *properties;
gint cur_prio_group;
gboolean client_started = FALSE;
+ GPid pid;
- /* can this ever happen? */
- while (G_UNLIKELY (pending_properties && pending_properties->data == NULL))
- pending_properties = g_list_delete_link (pending_properties, pending_properties);
-
- if (pending_properties == NULL)
+ properties = (XfsmProperties *) g_queue_peek_head (pending_properties);
+ if (properties == NULL)
return FALSE;
- /* determine prio group for this run */
- properties = (XfsmProperties *) pending_properties->data;
cur_prio_group = properties->priority;
xfsm_verbose ("Starting apps in prio group %d\n", cur_prio_group);
- while (pending_properties)
+ while ((properties = g_queue_pop_head (pending_properties)))
{
- XfsmProperties *properties = (XfsmProperties *) pending_properties->data;
-
- if (G_UNLIKELY (properties == NULL))
- {
- pending_properties = g_list_delete_link (pending_properties, pending_properties);
- continue;
- }
-
/* quit if we've hit all the clients in the current prio group */
if (properties->priority != cur_prio_group)
- break;
+ {
+ g_queue_push_head (pending_properties, properties);
+ break;
+ }
/* FIXME: splash */
if (G_LIKELY (splash_screen != NULL))
@@ -590,18 +594,34 @@ xfsm_startup_session_next_prio_group (void)
figure_app_name (properties->program));
}
- /* it's not pending anymore... */
- pending_properties = g_list_remove (pending_properties, properties);
-
- if (G_LIKELY (xfsm_startup_session_client (properties)))
+ if (G_LIKELY ((pid = xfsm_startup_session_client (properties)) != -1))
{
- starting_properties = g_list_append (starting_properties, properties);
+ XfsmStartupChildWatchData *cwdata;
+ XfsmStartupTimeoutData *stdata;
+
+ cwdata = g_new(XfsmStartupChildWatchData, 1);
+ cwdata->manager = g_object_ref (manager);
+ cwdata->client_id = g_strdup (properties->client_id);
+ g_child_watch_add_full (G_PRIORITY_LOW, pid,
+ xfsm_startup_child_watch, cwdata,
+ xfsm_startup_child_watch_destroy);
+
+ stdata = g_new(XfsmStartupTimeoutData, 1);
+ stdata->manager = manager;
+ stdata->properties = properties;
+ properties->startup_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
+ STARTUP_TIMEOUT,
+ xfsm_startup_timeout,
+ stdata,
+ xfsm_startup_timeout_destroy);
+
+ g_queue_push_tail (starting_properties, properties);
client_started = TRUE;
}
else
{
/* if starting the app failed, just ditch it */
- xfsm_manager_handle_failed_client (properties);
+ xfsm_manager_handle_failed_client (manager, properties);
xfsm_properties_free (properties);
}
}
@@ -615,25 +635,23 @@ xfsm_startup_child_watch (GPid pid,
gint status,
gpointer user_data)
{
- XfsmProperties *properties;
- const gchar *client_id = user_data;
- GList *lp;
+ XfsmProperties *properties;
+ XfsmStartupChildWatchData *cwdata = user_data;
+ GQueue *starting_properties;
+ gint i, n_items;
+
+ starting_properties = xfsm_manager_get_queue (cwdata->manager, XFSM_MANAGER_QUEUE_STARTING_PROPS);
+ n_items = g_queue_get_length (starting_properties);
/* check if we have a starting process with the given client_id */
- for (lp = starting_properties; lp != NULL; lp = lp->next)
+ for (i = 0; i < n_items; ++i)
{
/* check if this properties matches */
- properties = (XfsmProperties *) lp->data;
- if (strcmp (properties->client_id, client_id) == 0)
+ properties = (XfsmProperties *) g_queue_peek_nth (starting_properties, i);
+ if (strcmp (properties->client_id, cwdata->client_id) == 0)
{
- if (properties->startup_timeout_id)
- {
- g_source_remove (properties->startup_timeout_id);
- properties->startup_timeout_id = 0;
- }
-
/* continue startup, this client failed most probably */
- xfsm_startup_handle_failed_client (properties);
+ xfsm_startup_handle_failed_client (properties, cwdata->manager);
break;
}
}
@@ -643,30 +661,49 @@ xfsm_startup_child_watch (GPid pid,
static void
xfsm_startup_child_watch_destroy (gpointer user_data)
{
- /* release the client_id */
- g_free (user_data);
+ XfsmStartupChildWatchData *cwdata = user_data;
+
+ g_object_unref (cwdata->manager);
+ g_free (cwdata->client_id);
+ g_free (cwdata);
}
static gboolean
-xfsm_startup_handle_failed_client (gpointer data)
+xfsm_startup_timeout (gpointer data)
+{
+ XfsmStartupTimeoutData *stdata = data;
+
+ stdata->properties->startup_timeout_id = 0;
+ xfsm_startup_handle_failed_client(stdata->properties, stdata->manager);
+
+ return FALSE;
+}
+
+
+static void
+xfsm_startup_timeout_destroy (gpointer data)
{
- XfsmProperties *properties = (XfsmProperties *) data;
+ g_free (data);
+}
- properties->startup_timeout_id = 0;
- xfsm_manager_handle_failed_client (properties);
+static void
+xfsm_startup_handle_failed_client (XfsmProperties *properties,
+ XfsmManager *manager)
+{
+ GQueue *starting_properties = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_STARTING_PROPS);
+
+ xfsm_manager_handle_failed_client (manager, properties);
- starting_properties = g_list_remove (starting_properties, properties);
+ g_queue_remove (starting_properties, properties);
xfsm_properties_free (properties);
- if (starting_properties == NULL)
+ if (g_queue_peek_head (starting_properties) == NULL)
{
/* everything has finished starting or failed; continue startup */
- xfsm_startup_session_continue ();
+ xfsm_startup_session_continue (manager);
}
-
- return FALSE;
}
diff --git a/xfce4-session/xfsm-startup.h b/xfce4-session/xfsm-startup.h
index 5aa8f330..3593b495 100644
--- a/xfce4-session/xfsm-startup.h
+++ b/xfce4-session/xfsm-startup.h
@@ -1,6 +1,7 @@
/* $Id$ */
/*-
* Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -25,9 +26,9 @@
#include <libxfce4util/libxfce4util.h>
void xfsm_startup_init (XfceRc *rc);
-void xfsm_startup_foreign (void);
-void xfsm_startup_begin (void);
-void xfsm_startup_session_continue (void);
+void xfsm_startup_foreign (XfsmManager *manager);
+void xfsm_startup_begin (XfsmManager *manager);
+void xfsm_startup_session_continue (XfsmManager *manager);
#endif /* !__XFSM_STARTUP_H__ */