[monkey-bubble: 4/753] Wrote functions to handle client side of session management. Modified desktop property programs to s
- From: Sven Herzberg <herzi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [monkey-bubble: 4/753] Wrote functions to handle client side of session management. Modified desktop property programs to s
- Date: Wed, 14 Jul 2010 21:56:01 +0000 (UTC)
commit e5debcee028eb6cd8fed6616cba6758a096856e8
Author: Tom Tromey <tromey src gnome org>
Date: Sun Dec 7 06:57:01 1997 +0000
Wrote functions to handle client side of session management.
Modified desktop property programs to save state in a hacky way
as a test.
libgnomeui/Makefile.am | 6 +-
libgnomeui/gnome-session.c | 379 ++++++++++++++++++++++++++++++++++++++++++++
libgnomeui/gnome-session.h | 115 +++++++++++++
3 files changed, 498 insertions(+), 2 deletions(-)
---
diff --git a/libgnomeui/Makefile.am b/libgnomeui/Makefile.am
index 7f8f60c..46c619c 100644
--- a/libgnomeui/Makefile.am
+++ b/libgnomeui/Makefile.am
@@ -14,7 +14,8 @@ libgnomeui_la_SOURCES = \
gnome-messagebox.c \
gnome-pixmap.c \
gnome-toolbar.c \
- gnome-colors.c
+ gnome-colors.c \
+ gnome-session.c
libgnomeuiinclude_HEADERS = \
gnome-actionarea.h \
@@ -24,7 +25,8 @@ libgnomeuiinclude_HEADERS = \
gnome-properties.h \
gnome-pixmap.h \
gnome-toolbar.h \
- libgnomeui.h
+ libgnomeui.h \
+ gnome-session.h
libgnomeui_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
diff --git a/libgnomeui/gnome-session.c b/libgnomeui/gnome-session.c
new file mode 100644
index 0000000..316f62f
--- /dev/null
+++ b/libgnomeui/gnome-session.c
@@ -0,0 +1,379 @@
+/* gnome-session.c - Gnome session client library. */
+
+#include <config.h>
+
+#include <assert.h>
+#include <X11/ICE/ICElib.h>
+
+#include "gnome.h"
+#include "gnome-session.h"
+
+#define PAD(n,P) ((((n) % (P)) == 0) ? (n) : ((n) + (P) - ((n) % (P))))
+
+#ifdef HAVE_LIBSM
+
+typedef enum
+{
+ c_idle,
+ c_save_yourself,
+ c_shutdown_cancelled,
+ c_interact_request,
+ c_interact,
+ c_die,
+} client_state;
+
+/* A struct of this type holds information about the client. */
+struct client_info
+{
+ client_state state;
+ gpointer client_data;
+ GnomeSaveFunction *saver;
+ GnomeDeathFunction *death;
+ SmcConn connection;
+};
+
+/* The state for this client. */
+static struct client_info *info;
+
+/* True if we've started listening to ICE. */
+static int ice_init = 0;
+
+/* ICE connection tag as known by GDK event loop. */
+static guint ice_tag;
+
+
+/* This is called when data is available on an ICE connection. */
+static void
+process_ice_messages (gpointer client_data, gint source,
+ GdkInputCondition condition)
+{
+ IceProcessMessagesStatus status;
+ IceConn connection = (IceConn) client_data;
+
+ status = IceProcessMessages (connection, NULL, NULL);
+ /* FIXME: handle case when status==closed. */
+}
+
+/* This is called when a new ICE connection is made. It arranges for
+ the ICE connection to be handled via the event loop. */
+static void
+new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
+ IcePointer *watch_data)
+{
+ if (opening)
+ ice_tag = gdk_input_add (IceConnectionNumber (connection),
+ GDK_INPUT_READ, process_ice_messages,
+ (gpointer) connection);
+ else
+ gdk_input_remove (ice_tag);
+}
+
+static void
+save_yourself (SmcConn connection, SmPointer client_data, int save_type,
+ Bool shutdown, int interact_style, Bool fast)
+{
+ int status;
+
+ info->state = c_save_yourself;
+ if (info->saver)
+ status = info->saver (info->client_data, save_type, shutdown,
+ interact_style, fast);
+ else
+ status = True;
+ SmcSaveYourselfDone (connection, status);
+
+ /* State might have changed while calling SAVER. Assume that if it
+ has changed, then we are ok. */
+ /* FIXME: Make it impossible for the user to interact. */
+ while (info->state == c_save_yourself
+ && ! gtk_main_iteration ())
+ ;
+
+ info->state = c_idle;
+}
+
+static void
+die (SmcConn connection, SmPointer client_data)
+{
+ info->state = c_die;
+ SmcCloseConnection (connection, 0, NULL);
+ if (info->death)
+ info->death (info->client_data);
+ /* FIXME. */
+ exit (0);
+}
+
+static void
+save_complete (SmcConn connection, SmPointer client_data)
+{
+ assert (info->state == c_save_yourself);
+ info->state = c_idle;
+}
+
+static void
+shutdown_cancelled (SmcConn connection, SmPointer client_data)
+{
+ assert (info->state == c_save_yourself || info->state == c_interact_request);
+ info->state = c_shutdown_cancelled;
+}
+
+#endif /* HAVE_LIBSM */
+
+char *
+gnome_init_session (GnomeSaveFunction saver,
+ GnomeDeathFunction death,
+ gpointer client_data,
+ char *previous)
+{
+#ifdef HAVE_LIBSM
+ SmcConn connection;
+ unsigned long mask;
+ SmcCallbacks callbacks;
+ char *client_id;
+ char buf[256];
+
+ assert (! info);
+
+ if (! ice_init)
+ {
+ IceAddConnectionWatch (new_ice_connection, NULL);
+ ice_init = 1;
+ }
+
+ info = g_new (struct client_info, 1);
+ info->state = c_idle;
+ info->client_data = client_data;
+ info->saver = saver;
+ info->death = death;
+
+ callbacks.save_yourself.callback = save_yourself;
+ callbacks.save_yourself.client_data = NULL;
+ callbacks.die.callback = die;
+ callbacks.die.client_data = NULL;
+ callbacks.save_complete.callback = save_complete;
+ callbacks.save_complete.client_data = NULL;
+ callbacks.shutdown_cancelled.callback = shutdown_cancelled;
+ callbacks.shutdown_cancelled.client_data = NULL;
+
+ mask = (SmcSaveYourselfProcMask | SmcDieProcMask
+ | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask);
+
+ info->connection = SmcOpenConnection (NULL, NULL, SmProtoMajor, SmProtoMinor,
+ mask, &callbacks, previous, &client_id,
+ sizeof buf, buf);
+ if (! info->connection)
+ {
+ free (info);
+ info = NULL;
+ return NULL;
+ }
+
+ return client_id;
+#else
+ return NULL;
+#endif /* HAVE_LIBSM */
+}
+
+void
+gnome_set_restart_style (GnomeRestartStyle style)
+{
+#ifdef HAVE_LIBSM
+ SmProp prop, *proplist[1];
+ SmPropValue val;
+ char c = (char) style;
+
+ if (! info)
+ return;
+
+ prop.name = SmRestartStyleHint;
+ prop.type = SmCARD8;
+ prop.num_vals = 1;
+ prop.vals = &val;
+ val.length = 1;
+ val.value = &style;
+ proplist[0] = ∝
+ SmcSetProperties (info->connection, 1, proplist);
+#endif /* HAVE_LIBSM */
+}
+
+void
+gnome_set_current_directory (char *dir)
+{
+#ifdef HAVE_LIBSM
+ SmProp prop, *proplist[1];
+ SmPropValue val;
+ int len;
+
+ if (! info)
+ return;
+
+ prop.name = SmCurrentDirectory;
+ prop.type = SmARRAY8;
+ prop.num_vals = 1;
+ prop.vals = &val;
+ val.length = strlen (dir) + 1;
+ val.value = dir;
+ proplist[0] = ∝
+ SmcSetProperties (info->connection, 1, proplist);
+#endif /* HAVE_LIBSM */
+}
+
+void
+gnome_set_program (char *name)
+{
+#ifdef HAVE_LIBSM
+ SmProp prop, *proplist[1];
+ SmPropValue val;
+ int len;
+
+ if (! info)
+ return;
+
+ prop.name = SmProgram;
+ prop.type = SmARRAY8;
+ prop.num_vals = 1;
+ prop.vals = &val;
+ val.length = strlen (name) + 1;
+ val.value = name;
+ proplist[0] = ∝
+ SmcSetProperties (info->connection, 1, proplist);
+#endif /* HAVE_LIBSM */
+}
+
+void
+gnome_set_discard_command (int argc, char *argv[])
+{
+#ifdef HAVE_LIBSM
+ SmProp prop, *proplist[1];
+ SmPropValue *vals;
+ int i;
+
+ if (! info)
+ return;
+
+ prop.name = SmDiscardCommand;
+ prop.type = SmLISTofARRAY8;
+
+ vals = (SmPropValue *) malloc (argc * sizeof (SmPropValue));
+ for (i = 0; i < argc; ++i)
+ {
+ vals[i].length = strlen (argv[i]) + 1;
+ vals[i].value = argv[i];
+ }
+
+ prop.num_vals = argc;
+ prop.vals = vals;
+ proplist[0] = ∝
+
+ SmcSetProperties (info->connection, 1, proplist);
+
+ free (vals);
+#endif /* HAVE_LIBSM */
+}
+
+void
+gnome_set_restart_command (int argc, char *argv[])
+{
+#ifdef HAVE_LIBSM
+ SmProp prop, *proplist[1];
+ SmPropValue *vals;
+ int i;
+
+ if (! info)
+ return;
+
+ prop.name = SmRestartCommand;
+ prop.type = SmLISTofARRAY8;
+
+ vals = (SmPropValue *) malloc (argc * sizeof (SmPropValue));
+ for (i = 0; i < argc; ++i)
+ {
+ vals[i].length = strlen (argv[i]) + 1;
+ vals[i].value = argv[i];
+ }
+
+ prop.num_vals = argc;
+ prop.vals = vals;
+ proplist[0] = ∝
+
+ SmcSetProperties (info->connection, 1, proplist);
+
+ free (vals);
+#endif /* HAVE_LIBSM */
+}
+
+void
+gnome_set_clone_command (int argc, char *argv[])
+{
+#ifdef HAVE_LIBSM
+ SmProp prop, *proplist[1];
+ SmPropValue *vals;
+ int i;
+
+ if (! info)
+ return;
+
+ prop.name = SmCloneCommand;
+ prop.type = SmLISTofARRAY8;
+
+ vals = (SmPropValue *) malloc (argc * sizeof (SmPropValue));
+ for (i = 0; i < argc; ++i)
+ {
+ vals[i].length = strlen (argv[i]) + 1;
+ vals[i].value = argv[i];
+ }
+
+ prop.num_vals = argc;
+ prop.vals = vals;
+ proplist[0] = ∝
+
+ SmcSetProperties (info->connection, 1, proplist);
+
+ free (vals);
+#endif /* HAVE_LIBSM */
+}
+
+#ifdef HAVE_LIBSM
+
+static void
+interact (SmcConn connection, SmPointer client_data)
+{
+ assert (info->state == c_interact_request);
+ info->state = c_interact;
+}
+
+#endif /* HAVE_LIBSM */
+
+int
+gnome_request_interaction (GnomeDialogType type)
+{
+#ifdef HAVE_LIBSM
+ int status;
+
+ assert (info->state == c_save_yourself);
+ info->state = c_interact_request;
+ status = SmcInteractRequest (info->connection, type,
+ interact, NULL);
+ if (! status)
+ return 0;
+
+ /* FIXME: Make it impossible for the user to interact. */
+ while (info->state == c_interact_request
+ && ! gtk_main_iteration ())
+ ;
+
+ return (info->state == c_interact);
+#else
+ return 1;
+#endif /* HAVE_LIBSM */
+}
+
+void
+gnome_interaction_done (int shutdown)
+{
+#ifdef HAVE_LIBSM
+ assert (info->state == c_interact);
+ info->state = c_save_yourself;
+ SmcInteractDone (info->connection, shutdown);
+#endif /* HAVE_LIBSM */
+}
diff --git a/libgnomeui/gnome-session.h b/libgnomeui/gnome-session.h
new file mode 100644
index 0000000..771387e
--- /dev/null
+++ b/libgnomeui/gnome-session.h
@@ -0,0 +1,115 @@
+/* gnome-session.h - Session management support for Gnome apps. */
+
+#ifndef GNOME_SESSION_H
+#define GNOME_SESSION_H
+
+BEGIN_GNOME_DECLS
+
+/* If we don't have libSM, then we just define bogus values for the
+ things we need from SMlib.h. The values don't matter because this
+ whole library is just stubbed out in this case. */
+#ifdef HAVE_LIBSM
+#include <X11/SM/SMlib.h>
+#else /* HAVE_LIBSM */
+#define SmInteractStyleNone 0
+#define SmInteractStyleErrors 1
+#define SmInteractStyleAny 2
+#define SmDialogError 0
+#define SmDialogNormal 1
+#define SmSaveGlobal 0
+#define SmSaveLocal 1
+#define SmSaveBoth 2
+#define SmRestartIfRunning 0
+#define SmRestartAnyway 1
+#define SmRestartImmediately 2
+#define SmRestartNever 3
+#endif /* HAVE_LIBSM */
+
+/* Some redefinitions so we can use familiar names. */
+typedef enum
+{
+ GNOME_INTERACT_NONE = SmInteractStyleNone,
+ GNOME_INTERACT_ERRORS = SmInteractStyleErrors,
+ GNOME_INTERACT_ANY = SmInteractStyleAny
+} GnomeInteractStyle;
+
+typedef enum
+{
+ GNOME_DIALOG_ERROR = SmDialogError,
+ GNOME_DIALOG_NORMAL = SmDialogNormal
+} GnomeDialogType;
+
+typedef enum
+{
+ GNOME_SAVE_GLOBAL = SmSaveGlobal,
+ GNOME_SAVE_LOCAL = SmSaveLocal,
+ GNOME_SAVE_BOTH = SmSaveBoth
+} GnomeSaveStyle;
+
+typedef enum
+{
+ GNOME_RESTART_IF_RUNNING = SmRestartIfRunning,
+ GNOME_RESTART_ANYWAY = SmRestartAnyway,
+ GNOME_RESTART_IMMEDIATELY = SmRestartImmediately,
+ GNOME_RESTART_NEVER = SmRestartNever
+} GnomeRestartStyle;
+
+
+/* A function of this type is called when the state should be saved.
+ The function should return 1 if the save was successful, 0
+ otherwise. */
+typedef int GnomeSaveFunction (gpointer client_data,
+ GnomeSaveStyle save_style,
+ int /*bool*/ is_shutdown,
+ GnomeInteractStyle interact_style,
+ int /*bool*/ is_fast);
+
+/* A function of this type is called when the session manager requests
+ us to exit. State will have already been saved. If this function
+ returns, the handler will exit with status 0. */
+typedef void GnomeDeathFunction (gpointer client_data);
+
+
+
+/* Initialize. This returns the current client id (which should be
+ saved for restarting), or NULL on error. If this client has been
+ restarted from a saved session, the old client id should be passed
+ as PREVIOUS_ID. Otherwise NULL should be used. */
+char *gnome_init_session (GnomeSaveFunction saver,
+ GnomeDeathFunction death,
+ gpointer client_data,
+ char *previous_id);
+
+/* Set the restart style. Default is GNOME_RESTART_IF_RUNNING. */
+void gnome_set_restart_style (GnomeRestartStyle style);
+
+/* Set the current directory property. */
+void gnome_set_current_directory (char *dir);
+
+/* Set the discard command. This is a command that can clean up
+ after a local save. */
+void gnome_set_discard_command (int argc, char *argv[]);
+
+/* Set the restart command. */
+void gnome_set_restart_command (int argc, char *argv[]);
+
+/* Set the clone command. This is like the restart command but
+ doesn't preserve session id info. */
+void gnome_set_clone_command (int argc, char *argv[]);
+
+/* Set the program name. The argument should just be ARGV[0]. */
+void gnome_set_program (char *name);
+
+/* Request the interaction token. This will return 1 when this client
+ has the interaction token. If it returns 0, then the shutdown has
+ been cancelled, and so the interaction should not take place. */
+int gnome_request_interaction (GnomeDialogType dialog_type);
+
+/* Release the interaction token. If SHUTDOWN is true, then the
+ shutdown will be cancelled. */
+void gnome_interaction_done (int shutdown);
+
+
+END_GNOME_DECLS
+
+#endif /* GNOME_SESSION_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]