remove msm from here, now in its own module

This commit is contained in:
Havoc Pennington 2001-09-16 20:43:45 +00:00
parent 52dc32031d
commit b09a781a80
16 changed files with 0 additions and 3942 deletions

View File

@ -1,23 +0,0 @@
INCLUDES=@MSM_CFLAGS@ -DMSM_PKGDATADIR=\"$(datadir)/msm\"
msm_SOURCES= \
client.c \
client.h \
gui.c \
gui.h \
main.c \
main.h \
props.c \
props.h \
server.c \
server.h \
session.c \
session.h \
util.c \
util.h
noinst_PROGRAMS=msm
msm_LDADD= @MSM_LIBS@

View File

@ -1,343 +0,0 @@
/* msm client object */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "client.h"
#include "props.h"
#include "util.h"
#include <stdlib.h>
#include <string.h>
struct _MsmClient
{
MsmServer *server;
SmsConn cnxn;
MsmClientState state;
char *id;
char *hostname;
char *desc;
int restart_style;
GList *properties;
};
#define DEFAULT_RESTART_STYLE SmRestartIfRunning
MsmClient*
msm_client_new (MsmServer *server,
SmsConn cnxn)
{
MsmClient *client;
client = g_new (MsmClient, 1);
client->server = server;
client->cnxn = cnxn;
client->state = MSM_CLIENT_STATE_NEW;
client->id = NULL;
client->hostname = NULL;
client->desc = g_strdup ("unknown");
client->restart_style = DEFAULT_RESTART_STYLE;
client->properties = NULL;
return client;
}
void
msm_client_free (MsmClient *client)
{
IceConn ice_cnxn;
GList *tmp;
ice_cnxn = SmsGetIceConnection (client->cnxn);
SmsCleanUp (client->cnxn);
IceSetShutdownNegotiation (ice_cnxn, False);
IceCloseConnection (ice_cnxn);
tmp = client->properties;
while (tmp != NULL)
{
SmProp *prop = tmp->data;
SmFreeProperty (prop);
tmp = tmp->next;
}
g_list_free (client->properties);
g_free (client->id);
g_free (client->hostname);
g_free (client->desc);
g_free (client);
}
SmsConn
msm_client_get_connection (MsmClient *client)
{
return client->cnxn;
}
const char*
msm_client_get_description (MsmClient *client)
{
return client->desc;
}
MsmClientState
msm_client_get_state (MsmClient *client)
{
return client->state;
}
MsmServer*
msm_client_get_server (MsmClient *client)
{
return client->server;
}
const char*
msm_client_get_id (MsmClient *client)
{
return client->id;
}
int
msm_client_get_restart_style (MsmClient *client)
{
return client->restart_style;
}
void
msm_client_register (MsmClient *client,
const char *id)
{
char *p;
if (client->state != MSM_CLIENT_STATE_NEW)
{
msm_warning (_("Client '%s' attempted to register when it was already registered\n"), client->desc);
return;
}
client->state = MSM_CLIENT_STATE_IDLE;
client->id = g_strdup (id);
SmsRegisterClientReply (client->cnxn, client->id);
p = SmsClientHostName (client->cnxn);
client->hostname = g_strdup (p);
free (p);
}
void
msm_client_interact_request (MsmClient *client)
{
if (client->state != MSM_CLIENT_STATE_SAVING &&
client->state != MSM_CLIENT_STATE_SAVING_PHASE2)
{
msm_warning (_("Client '%s' requested interaction when it was not being saved\n"),
client->desc);
return;
}
msm_server_queue_interaction (client->server, client);
}
void
msm_client_begin_interact (MsmClient *client)
{
SmsInteract (client->cnxn);
}
static void
internal_save (MsmClient *client,
int save_style,
gboolean allow_interaction,
gboolean shut_down)
{
if (client->state != MSM_CLIENT_STATE_IDLE)
{
msm_warning (_("Tried to save client '%s' but it was not in the idle state\n"),
client->desc);
return;
}
client->state = MSM_CLIENT_STATE_SAVING;
SmsSaveYourself (client->cnxn,
save_style,
shut_down,
allow_interaction ? SmInteractStyleAny : SmInteractStyleNone,
FALSE /* not "fast" */);
}
void
msm_client_save (MsmClient *client,
gboolean allow_interaction,
gboolean shut_down)
{
internal_save (client, SmSaveBoth, /* ? don't know what to do here */
allow_interaction, shut_down);
}
void
msm_client_initial_save (MsmClient *client)
{
/* This is the save on client registration in the spec under
* RegisterClientReply
*/
internal_save (client, SmSaveLocal, FALSE, FALSE);
}
void
msm_client_shutdown_cancelled (MsmClient *client)
{
if (client->state != MSM_CLIENT_STATE_SAVING &&
client->state != MSM_CLIENT_STATE_SAVING_PHASE2)
{
msm_warning (_("Tried to send cancel shutdown to client '%s' which was not saving\n"),
client->desc);
return;
}
client->state = MSM_CLIENT_STATE_IDLE;
SmsShutdownCancelled (client->cnxn);
}
void
msm_client_phase2_request (MsmClient *client)
{
if (client->state != MSM_CLIENT_STATE_SAVING)
{
msm_warning (_("Client '%s' requested phase 2 save but was not in a phase 1 save\n"),
client->desc);
return;
}
client->state = MSM_CLIENT_STATE_PHASE2_REQUESTED;
}
void
msm_client_save_phase2 (MsmClient *client)
{
if (client->state != MSM_CLIENT_STATE_PHASE2_REQUESTED)
{
msm_warning (_("We tried to save client '%s' in phase 2, but it hadn't requested it.\n"), client->desc);
return;
}
SmsSaveYourselfPhase2 (client->cnxn);
}
void
msm_client_die (MsmClient *client)
{
client->state = MSM_CLIENT_STATE_DEAD;
SmsDie (client->cnxn);
}
void
msm_client_save_complete (MsmClient *client)
{
client->state = MSM_CLIENT_STATE_IDLE;
SmsSaveComplete (client->cnxn);
}
void
msm_client_save_confirmed (MsmClient *client,
gboolean successful)
{
if (client->state != MSM_CLIENT_STATE_SAVING &&
client->state != MSM_CLIENT_STATE_SAVING_PHASE2)
{
msm_warning (_("Client '%s' said it was done saving, but it hadn't been told to save\n"),
client->desc);
return;
}
if (successful)
client->state = MSM_CLIENT_STATE_SAVE_DONE;
else
client->state = MSM_CLIENT_STATE_SAVE_FAILED;
}
void
msm_client_set_property_taking_ownership (MsmClient *client,
SmProp *prop)
{
/* we own prop which should be freed with SmFreeProperty() */
/* pass our ownership into the proplist */
client->properties = proplist_replace (client->properties, prop);
/* update pieces of the client struct */
if (strcmp (prop->name, "SmRestartStyleHint") == 0)
{
int hint;
if (smprop_get_card8 (prop, &hint))
client->restart_style = hint;
else
client->restart_style = DEFAULT_RESTART_STYLE;
}
}
void
msm_client_unset_property (MsmClient *client,
const char *name)
{
client->properties = proplist_delete (client->properties, name);
/* Return to default values */
if (strcmp (name, "SmRestartStyleHint") == 0)
{
client->restart_style = DEFAULT_RESTART_STYLE;
}
}
void
msm_client_send_properties (MsmClient *client)
{
int n_props;
SmProp **props;
GList *tmp;
int i;
n_props = g_list_length (client->properties);
props = g_new (SmProp*, n_props);
i = 0;
tmp = client->properties;
while (tmp != NULL)
{
props[i] = tmp->data;
tmp = tmp->next;
++i;
}
SmsReturnProperties (client->cnxn, n_props, props);
g_free (props);
}

View File

@ -1,97 +0,0 @@
/* msm client object */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef MSM_CLIENT_H
#define MSM_CLIENT_H
#include <glib.h>
#include "server.h"
/* See xsmp docs for a state description. This enum doesn't
* correspond exactly, but close enough.
*/
typedef enum
{
/* Client has just newly connected, not yet registered */
MSM_CLIENT_STATE_NEW,
/* Client has registered with us successfully, isn't doing
* anything special
*/
MSM_CLIENT_STATE_IDLE,
/* Client is saving self in phase 1 */
MSM_CLIENT_STATE_SAVING,
/* Client has requested phase 2 save, but we aren't in phase 2 yet */
MSM_CLIENT_STATE_PHASE2_REQUESTED,
/* Client is in phase 2 save; all the same things are
* allowed as with STATE_SAVING, except you can't request
* a phase 2 save
*/
MSM_CLIENT_STATE_SAVING_PHASE2,
/* Client sent SaveYourselfDone with success = TRUE */
MSM_CLIENT_STATE_SAVE_DONE,
/* Client sent SaveYourselfDone with success = FALSE */
MSM_CLIENT_STATE_SAVE_FAILED,
/* Client was asked to die */
MSM_CLIENT_STATE_DEAD
} MsmClientState;
MsmClient* msm_client_new (MsmServer *server,
SmsConn cnxn);
void msm_client_free (MsmClient *client);
SmsConn msm_client_get_connection (MsmClient *client);
const char* msm_client_get_description (MsmClient *client);
MsmClientState msm_client_get_state (MsmClient *client);
MsmServer* msm_client_get_server (MsmClient *client);
/* can return NULL */
const char* msm_client_get_id (MsmClient *client);
int msm_client_get_restart_style (MsmClient *client);
void msm_client_set_property_taking_ownership (MsmClient *client,
SmProp *prop);
void msm_client_unset_property (MsmClient *client,
const char *name);
void msm_client_send_properties (MsmClient *client);
void msm_client_register (MsmClient *client,
const char *id);
void msm_client_interact_request (MsmClient *client);
void msm_client_begin_interact (MsmClient *client);
void msm_client_save (MsmClient *client,
gboolean allow_interaction,
gboolean shut_down);
void msm_client_initial_save (MsmClient *client);
void msm_client_shutdown_cancelled (MsmClient *client);
void msm_client_phase2_request (MsmClient *client);
void msm_client_save_phase2 (MsmClient *client);
void msm_client_save_confirmed (MsmClient *client,
gboolean successful);
void msm_client_die (MsmClient *client);
void msm_client_save_complete (MsmClient *client);
#endif

View File

@ -1,359 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* this file Copyright (C) 2001 Havoc Pennington
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
/* FIXME implementation contains a bunch of cut-and-paste from GtkFrame
* that would be easy to avoid by adding an "int space_before_label_widget"
* in GtkFrame that was overridden by subclasses.
*/
/* FIXME the whole GtkFrame derivation idea is fucked since we can't get
* the click event on the arrow.
*/
#define ARROW_SIZE 12
#define ARROW_PAD 2
enum {
PROP_0,
PROP_DISCLOSED,
PROP_LAST
};
static void gtk_disclosure_box_class_init (GtkDisclosureBoxClass *klass);
static void gtk_disclosure_box_init (GtkDisclosureBox *box);
static void gtk_disclosure_box_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_disclosure_box_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gtk_disclosure_box_paint (GtkWidget *widget,
GdkRectangle *area);
static gint gtk_disclosure_box_expose (GtkWidget *widget,
GdkEventExpose *event);
static void gtk_disclosure_box_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_disclosure_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_frame_compute_child_allocation (GtkFrame *frame,
GtkAllocation *child_allocation);
GType
gtk_disclosure_box_get_type (void)
{
static GType disclosure_box_type = 0;
if (!disclosure_box_type)
{
static const GtkTypeInfo disclosure_box_info =
{
"GtkDisclosureBox",
sizeof (GtkDisclosureBox),
sizeof (GtkDisclosureBoxClass),
(GtkClassInitFunc) gtk_disclosure_box_class_init,
(GtkObjectInitFunc) gtk_disclosure_box_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
disclosure_box_type = gtk_type_unique (gtk_box_get_type (), &disclosure_box_info);
}
return disclosure_box_type;
}
static void
gtk_disclosure_box_class_init (GtkDisclosureBoxClass *class)
{
GtkWidgetClass *widget_class;
GObjectClass *gobject_class;
GtkContainerClass *container_class;
GtkFrameClass *frame_class;
gobject_class = G_OBJECT_CLASS (class);
widget_class = GTK_WIDGET_CLASS (class);
container_class = GTK_CONTAINER_CLASS (class);
frame_class = GTK_FRAME_CLASS (class);
gobject_class->set_property = gtk_disclosure_box_set_property;
gobject_class->get_property = gtk_disclosure_box_get_property;
widget_class->size_request = gtk_disclosure_box_size_request;
widget_class->size_allocate = gtk_disclosure_box_size_allocate;
widget_class->expose_event = gtk_disclosure_box_expose;
}
static void
gtk_disclosure_box_init (GtkDisclosureBox *disclosure_box)
{
}
GtkWidget*
gtk_disclosure_box_new (const char *label)
{
return g_object_new (GTK_TYPE_DISCLOSURE_BOX, "label", label, NULL);
}
static void
gtk_disclosure_box_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkDisclosureBox *box;
box = GTK_DISCLOSURE_BOX (object);
switch (prop_id)
{
case PROP_DISCLOSED:
gtk_disclosure_box_set_disclosed (box,
g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_disclosure_box_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkDisclosureBox *box;
box = GTK_DISCLOSURE_BOX (object);
switch (prop_id)
{
case PROP_DISCLOSED:
g_value_set_boolean (value, box->disclosed);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
void
gtk_disclosure_box_set_disclosed (GtkDisclosureBox *box,
gboolean disclosed)
{
g_return_if_fail (GTK_IS_DISCLOSURE_BOX (box));
disclosed = disclosed != FALSE;
if (disclosed != box->disclosed)
{
box->disclosed = disclosed;
gtk_widget_queue_resize (GTK_WIDGET (box));
}
}
gboolean
gtk_disclosure_box_get_disclosed (GtkDisclosureBox *box)
{
g_return_val_if_fail (GTK_IS_DISCLOSURE_BOX (box), FALSE);
return box->disclosed;
}
static void
gtk_disclosure_box_paint (GtkWidget *widget,
GdkRectangle *area)
{
GtkFrame *frame;
gint x, y, width, height;
if (GTK_WIDGET_DRAWABLE (widget))
{
frame = GTK_FRAME (widget);
x = frame->child_allocation.x - widget->style->xthickness;
y = frame->child_allocation.y - widget->style->ythickness;
width = frame->child_allocation.width + 2 * widget->style->xthickness;
height = frame->child_allocation.height + 2 * widget->style->ythickness;
if (frame->label_widget)
{
GtkRequisition child_requisition;
gfloat xalign;
gint height_extra;
gint x2;
gtk_widget_get_child_requisition (frame->label_widget, &child_requisition);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
xalign = frame->label_xalign;
else
xalign = 1 - frame->label_xalign;
height_extra = MAX (0, child_requisition.height - widget->style->xthickness);
y -= height_extra * (1 - frame->label_yalign);
height += height_extra * (1 - frame->label_yalign);
x2 = widget->style->xthickness + (frame->child_allocation.width - child_requisition.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_SIDE_PAD;
gtk_paint_shadow_gap (widget->style, widget->window,
GTK_STATE_NORMAL, frame->shadow_type,
area, widget, "frame",
x, y, width, height,
GTK_POS_TOP,
x2 + ARROW_SIZE + ARROW_PAD * 2, child_requisition.width + 2 * LABEL_PAD);
gtk_paint_arrow (widget->style, widget->window,
widget->state, GTK_SHADOW_OUT,
area, widget, "arrow",
GTK_DISCLOSURE_BOX (widget)->disclosed ?
GTK_ARROW_RIGHT : GTK_ARROW_DOWN,
TRUE,
x2 + ARROW_PAD, y, ARROW_SIZE, ARROW_SIZE);
}
else
gtk_paint_shadow (widget->style, widget->window,
GTK_STATE_NORMAL, frame->shadow_type,
area, widget, "frame",
x, y, width, height);
}
}
static gboolean
gtk_disclosure_box_expose (GtkWidget *widget,
GdkEventExpose *event)
{
if (GTK_WIDGET_DRAWABLE (widget))
{
gtk_disclosure_box_paint (widget, &event->area);
(* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
}
return FALSE;
}
static void
gtk_disclosure_box_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
GtkFrame *frame = GTK_FRAME (widget);
GtkBin *bin = GTK_BIN (widget);
GtkRequisition child_requisition;
if (frame->label_widget && GTK_WIDGET_VISIBLE (frame->label_widget))
{
gtk_widget_size_request (frame->label_widget, &child_requisition);
requisition->width = child_requisition.width + 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD + ARROW_SIZE + ARROW_PAD * 2;
requisition->height =
MAX (0, child_requisition.height - GTK_WIDGET (widget)->style->xthickness);
}
else
{
requisition->width = 0;
requisition->height = 0;
}
if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
{
gtk_widget_size_request (bin->child, &child_requisition);
requisition->width = MAX (requisition->width, child_requisition.width);
requisition->height += child_requisition.height;
}
requisition->width += (GTK_CONTAINER (widget)->border_width +
GTK_WIDGET (widget)->style->xthickness) * 2;
requisition->height += (GTK_CONTAINER (widget)->border_width +
GTK_WIDGET (widget)->style->ythickness) * 2;
}
static void
gtk_disclosure_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkFrame *frame = GTK_FRAME (widget);
GtkBin *bin = GTK_BIN (widget);
GtkAllocation new_allocation;
widget->allocation = *allocation;
gtk_frame_compute_child_allocation (frame, &new_allocation);
/* If the child allocation changed, that means that the frame is drawn
* in a new place, so we must redraw the entire widget.
*/
if (GTK_WIDGET_MAPPED (widget) &&
(new_allocation.x != frame->child_allocation.x ||
new_allocation.y != frame->child_allocation.y ||
new_allocation.width != frame->child_allocation.width ||
new_allocation.height != frame->child_allocation.height))
gtk_widget_queue_clear (widget);
if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
gtk_widget_size_allocate (bin->child, &new_allocation);
frame->child_allocation = new_allocation;
if (frame->label_widget && GTK_WIDGET_VISIBLE (frame->label_widget))
{
GtkRequisition child_requisition;
GtkAllocation child_allocation;
gfloat xalign;
gtk_widget_get_child_requisition (frame->label_widget, &child_requisition);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
xalign = frame->label_xalign;
else
xalign = 1 - frame->label_xalign;
child_allocation.x = frame->child_allocation.x + LABEL_SIDE_PAD +
(frame->child_allocation.width - child_requisition.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_PAD + ARROW_SIZE + ARROW_PAD * 2;
child_allocation.width = child_requisition.width;
child_allocation.y = frame->child_allocation.y - child_requisition.height;
child_allocation.height = child_requisition.height;
gtk_widget_size_allocate (frame->label_widget, &child_allocation);
}
}

View File

@ -1,76 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* this file Copyright (C) 2001 Havoc Pennington
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_DISCLOSURE_BOX_H__
#define __GTK_DISCLOSURE_BOX_H__
#include <gdk/gdk.h>
#include <gtk/gtkframe.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GTK_TYPE_DISCLOSURE_BOX (gtk_disclosure_box_get_type ())
#define GTK_DISCLOSURE_BOX(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_DISCLOSURE_BOX, GtkDisclosureBox))
#define GTK_DISCLOSURE_BOX_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_DISCLOSURE_BOX, GtkDisclosureBoxClass))
#define GTK_IS_DISCLOSURE_BOX(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_DISCLOSURE_BOX))
#define GTK_IS_DISCLOSURE_BOX_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_DISCLOSURE_BOX))
#define GTK_DISCLOSURE_BOX_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_DISCLOSURE_BOX, GtkDisclosureBoxClass))
typedef struct _GtkDisclosureBox GtkDisclosureBox;
typedef struct _GtkDisclosureBoxClass GtkDisclosureBoxClass;
struct _GtkDisclosureBox
{
GtkFrame parent_instance;
guint disclosed : 1;
};
struct _GtkDisclosureBoxClass
{
GtkFrameClass parent_class;
};
GType gtk_disclosure_box_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_disclosure_box_new (const char *label);
void gtk_disclosure_box_set_disclosed (GtkDisclosureBox *box,
gboolean disclosed);
gboolean gtk_disclosure_box_get_disclosed (GtkDisclosureBox *box);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GTK_FRAME_H__ */

View File

@ -1,22 +0,0 @@
/* msm GUI stuff */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "gui.h"

View File

@ -1,27 +0,0 @@
/* msm GUI stuff */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef MSM_GUI_H
#define MSM_GUI_H
#endif

View File

@ -1,136 +0,0 @@
/* msm main() */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <gtk/gtk.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include "server.h"
#include "util.h"
static GMainLoop *main_loop = NULL;
static void
usage (void)
{
g_print ("msm [--choose-session=NAME] [--failsafe]\n");
exit (1);
}
static void
shutdown_cleanly_on_signal (int signo)
{
if (main_loop && g_main_is_running (main_loop))
g_main_quit (main_loop);
}
void
msm_quit (void)
{
if (main_loop && g_main_is_running (main_loop))
g_main_quit (main_loop);
}
int
main (int argc, char **argv)
{
int i;
const char *prev_arg;
char *session_name;
gboolean failsafe;
struct sigaction act;
sigset_t empty_mask;
MsmServer *server;
sigemptyset (&empty_mask);
act.sa_handler = SIG_IGN;
act.sa_mask = empty_mask;
act.sa_flags = 0;
sigaction (SIGPIPE, &act, 0);
act.sa_handler = shutdown_cleanly_on_signal;
sigaction (SIGHUP, &act, 0);
sigaction (SIGINT, &act, 0);
/* connect to display */
gtk_init (&argc, &argv);
/* Parse options lamely */
session_name = NULL;
failsafe = FALSE;
prev_arg = NULL;
i = 1;
while (i < argc)
{
const char *arg = argv[i];
if (strcmp (arg, "--help") == 0 ||
strcmp (arg, "-h") == 0 ||
strcmp (arg, "-?") == 0)
usage ();
else if (strcmp (arg, "--failsafe") == 0)
failsafe = TRUE;
else if (strstr (arg, "--choose-session=") == arg)
{
const char *name;
if (session_name != NULL)
msm_fatal ("Can't specify session name twice\n");
name = strchr (arg, '=');
++name;
session_name = g_strdup (name);
}
else if (prev_arg &&
strcmp (prev_arg, "--choose-session") == 0)
{
if (session_name != NULL)
msm_fatal ("Can't specify session name twice\n");
session_name = g_strdup (arg);
}
else if (strcmp (arg, "--choose-session") == 0)
; /* wait for next arg */
else
usage ();
prev_arg = arg;
++i;
}
if (failsafe)
server = msm_server_new_failsafe ();
else
server = msm_server_new (session_name);
msm_server_launch_session (server);
main_loop = g_main_loop_new (NULL, FALSE);
g_main_run (main_loop);
return 0;
}

View File

@ -1,351 +0,0 @@
/* msm SmProp utils */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "props.h"
#include "util.h"
#include <stdlib.h>
#include <string.h>
/* Property functions stolen from gnome-session */
GList*
proplist_find_link_by_name (GList *list,
const char *name)
{
for (; list; list = list->next)
{
SmProp *prop = (SmProp *) list->data;
if (strcmp (prop->name, name) == 0)
return list;
}
return NULL;
}
SmProp*
proplist_find_by_name (GList *list, const char *name)
{
GList *ret;
ret = proplist_find_link_by_name (list, name);
return ret ? ret->data : NULL;
}
gboolean
proplist_find_card8 (GList *list, const char *name,
int *result)
{
SmProp *prop;
g_return_val_if_fail (result != NULL, FALSE);
prop = proplist_find_by_name (list, name);
if (prop == NULL)
return FALSE;
else
return smprop_get_card8 (prop, result);
}
gboolean
proplist_find_string (GList *list, const char *name,
char **result)
{
SmProp *prop;
g_return_val_if_fail (result != NULL, FALSE);
prop = proplist_find_by_name (list, name);
if (prop == NULL)
return FALSE;
else
return smprop_get_string (prop, result);
}
GList*
proplist_replace (GList *list,
SmProp *new_prop)
{
GList *link;
link = proplist_find_link_by_name (list, new_prop->name);
if (link)
{
SmFreeProperty (link->data);
link->data = new_prop;
}
else
{
list = g_list_prepend (list, new_prop);
}
return list;
}
GList*
proplist_delete (GList *list,
const char *name)
{
GList *link;
link = proplist_find_link_by_name (list, name);
if (link)
{
SmFreeProperty (link->data);
list = g_list_delete_link (list, link);
}
return list;
}
GList*
proplist_replace_card8 (GList *list,
const char *name,
int value)
{
SmProp *prop;
prop = smprop_new_card8 (name, value);
return proplist_replace (list, prop);
}
GList*
proplist_replace_string (GList *list,
const char *name,
const char *str,
int len)
{
SmProp *prop;
prop = smprop_new_string (name, str, len);
return proplist_replace (list, prop);
}
GList*
proplist_replace_vector (GList *list,
const char *name,
int argc,
char **argv)
{
SmProp *prop;
prop = smprop_new_vector (name, argc, argv);
return proplist_replace (list, prop);
}
gboolean
proplist_find_vector (GList *list, const char *name,
int *argcp, char ***argvp)
{
SmProp *prop;
g_return_val_if_fail (argcp != NULL, FALSE);
g_return_val_if_fail (argvp != NULL, FALSE);
prop = proplist_find_by_name (list, name);
if (prop == NULL)
return FALSE;
else
return smprop_get_vector (prop, argcp, argvp);
}
gboolean
smprop_get_card8 (SmProp *prop,
int *result)
{
g_return_val_if_fail (result != NULL, FALSE);
if (strcmp (prop->type, SmCARD8) == 0)
{
char *p;
p = prop->vals[0].value;
*result = *p;
return TRUE;
}
else
return FALSE;
}
gboolean
smprop_get_string (SmProp *prop,
char **result)
{
g_return_val_if_fail (result != NULL, FALSE);
if (strcmp (prop->type, SmARRAY8) == 0)
{
*result = g_malloc (prop->vals[0].length + 1);
memcpy (*result, prop->vals[0].value, prop->vals[0].length);
(*result)[prop->vals[0].length] = '\0';
return TRUE;
}
else
return FALSE;
}
gboolean
smprop_get_vector (SmProp *prop,
int *argcp,
char ***argvp)
{
g_return_val_if_fail (argcp != NULL, FALSE);
g_return_val_if_fail (argvp != NULL, FALSE);
if (strcmp (prop->type, SmLISTofARRAY8) == 0)
{
int i;
*argcp = prop->num_vals;
*argvp = g_new0 (char *, *argcp + 1);
for (i = 0; i < *argcp; ++i)
{
(*argvp)[i] = g_malloc (prop->vals[i].length + 1);
memcpy ((*argvp)[i], prop->vals[i].value, prop->vals[i].length);
(*argvp)[i][prop->vals[i].length] = '\0';
}
return TRUE;
}
else
return FALSE;
}
SmProp*
smprop_copy (SmProp *prop)
{
int i;
SmProp *copy;
/* This all uses malloc so we can use SmFreeProperty() */
copy = msm_non_glib_malloc (sizeof (SmProp));
if (prop->name)
copy->name = msm_non_glib_strdup (prop->name);
else
copy->name = NULL;
if (prop->type)
copy->type = msm_non_glib_strdup (prop->type);
else
copy->type = NULL;
copy->num_vals = prop->num_vals;
copy->vals = NULL;
if (copy->num_vals > 0 && prop->vals)
{
copy->vals = msm_non_glib_malloc (sizeof (SmPropValue) * copy->num_vals);
for (i = 0; i < copy->num_vals; i++)
{
if (prop->vals[i].value)
{
copy->vals[i].length = prop->vals[i].length;
copy->vals[i].value = msm_non_glib_malloc (copy->vals[i].length);
memcpy (copy->vals[i].value, prop->vals[i].value,
copy->vals[i].length);
}
else
{
copy->vals[i].length = 0;
copy->vals[i].value = NULL;
}
}
}
return copy;
}
SmProp*
smprop_new_vector (const char *name,
int argc,
char **argv)
{
SmProp *prop;
int i;
prop = msm_non_glib_malloc (sizeof (SmProp));
prop->name = msm_non_glib_strdup (name);
prop->type = msm_non_glib_strdup (SmLISTofARRAY8);
prop->num_vals = argc;
prop->vals = msm_non_glib_malloc (sizeof (SmPropValue) * prop->num_vals);
i = 0;
while (i < argc)
{
prop->vals[i].length = strlen (argv[i]);
prop->vals[i].value = msm_non_glib_strdup (argv[i]);
++i;
}
return prop;
}
SmProp*
smprop_new_string (const char *name,
const char *str,
int len)
{
SmProp *prop;
if (len < 0)
len = strlen (str);
prop = msm_non_glib_malloc (sizeof (SmProp));
prop->name = msm_non_glib_strdup (name);
prop->type = msm_non_glib_strdup (SmARRAY8);
prop->num_vals = 1;
prop->vals = msm_non_glib_malloc (sizeof (SmPropValue) * prop->num_vals);
prop->vals[0].length = len;
prop->vals[0].value = msm_non_glib_malloc (len);
memcpy (prop->vals[0].value, str, len);
return prop;
}
SmProp*
smprop_new_card8 (const char *name,
int value)
{
SmProp *prop;
prop = msm_non_glib_malloc (sizeof (SmProp));
prop->name = msm_non_glib_strdup (name);
prop->type = msm_non_glib_strdup (SmARRAY8);
prop->num_vals = 1;
prop->vals = msm_non_glib_malloc (sizeof (SmPropValue) * prop->num_vals);
prop->vals[0].length = 1;
prop->vals[0].value = msm_non_glib_malloc (1);
(* (char*) prop->vals[0].value) = (char) value;
return prop;
}

View File

@ -1,83 +0,0 @@
/* msm SmProp utils */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef MSM_PROPS_H
#define MSM_PROPS_H
#include <glib.h>
#include <X11/ICE/ICElib.h>
#include <X11/SM/SMlib.h>
GList* proplist_find_link_by_name (GList *list,
const char *name);
SmProp* proplist_find_by_name (GList *list,
const char *name);
gboolean proplist_find_card8 (GList *list,
const char *name,
int *result);
gboolean proplist_find_string (GList *list,
const char *name,
char **result);
gboolean proplist_find_vector (GList *list,
const char *name,
int *argcp,
char ***argvp);
GList* proplist_replace (GList *list,
SmProp *new_prop);
GList* proplist_delete (GList *list,
const char *name);
GList* proplist_replace_card8 (GList *list,
const char *name,
int value);
GList* proplist_replace_string (GList *list,
const char *name,
const char *str,
int len);
GList* proplist_replace_vector (GList *list,
const char *name,
int argc,
char **argv);
gboolean smprop_get_card8 (SmProp *prop,
int *result);
gboolean smprop_get_string (SmProp *prop,
char **result);
gboolean smprop_get_vector (SmProp *prop,
int *argcp,
char ***argvp);
SmProp* smprop_new_card8 (const char *name,
int value);
SmProp* smprop_new_string (const char *name,
const char *str,
int len);
SmProp* smprop_new_vector (const char *name,
int argc,
char **argv);
SmProp* smprop_copy (SmProp *prop);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,63 +0,0 @@
/* msm server object */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef MSM_SERVER_H
#define MSM_SERVER_H
#include <glib.h>
#include <X11/ICE/ICElib.h>
#include <X11/SM/SMlib.h>
typedef struct _MsmClient MsmClient;
typedef struct _MsmServer MsmServer;
typedef void (* MsmClientFunc) (MsmClient* client);
MsmServer* msm_server_new (const char *session_name);
MsmServer* msm_server_new_failsafe (void);
void msm_server_free (MsmServer *server);
void msm_server_queue_interaction (MsmServer *server,
MsmClient *client);
void msm_server_save_all (MsmServer *server,
gboolean allow_interaction,
gboolean shut_down);
void msm_server_cancel_shutdown (MsmServer *server);
void msm_server_consider_phase_change (MsmServer *server);
void msm_server_foreach_client (MsmServer *server,
MsmClientFunc func);
void msm_server_drop_client (MsmServer *server,
MsmClient *client);
void msm_server_next_pending_interaction (MsmServer *server);
gboolean msm_server_client_id_in_use (MsmServer *server,
const char *id);
void msm_server_launch_session (MsmServer *server);
gboolean msm_server_in_shutdown (MsmServer *server);
#endif

View File

@ -1,759 +0,0 @@
/* msm session */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "session.h"
#include "util.h"
#include "props.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <gtk/gtk.h>
typedef struct _MsmSavedClient MsmSavedClient;
struct _MsmSavedClient
{
char *id;
GList *properties;
};
struct _MsmSession
{
char *name;
GList *clients;
char *filename;
char *full_filename;
int lock_fd;
};
typedef enum
{
MSM_SESSION_FAILURE_OPENING_FILE,
MSM_SESSION_FAILURE_LOCKING,
MSM_SESSION_FAILURE_BAD_FILE,
MSM_SESSION_FAILURE_EMPTY
} MsmSessionFailureReason;
static GHashTable *sessions = NULL;
MsmSavedClient *saved_new (void);
void saved_free (MsmSavedClient *saved);
static MsmSession* recover_failed_session (MsmSession *session,
MsmSessionFailureReason reason,
const char *details);
static gboolean parse_session_file (MsmSession *session,
GError **error);
static char* decode_text_from_utf8 (const char *text);
static char* encode_text_as_utf8 (const char *text);
void
msm_session_clear (MsmSession *session)
{
}
void
msm_session_update_client (MsmSession *session,
MsmClient *client)
{
}
void
msm_session_remove_client (MsmSession *session,
MsmClient *client)
{
}
gboolean
msm_session_client_id_known (MsmSession *session,
const char *previous_id)
{
return FALSE;
}
void
msm_session_launch (MsmSession *session)
{
system ("xclock &");
}
MsmSavedClient*
saved_new (void)
{
MsmSavedClient *saved;
saved = g_new (MsmSavedClient, 1);
saved->id = NULL;
saved->properties = NULL;
return saved;
}
void
saved_free (MsmSavedClient *saved)
{
g_free (saved->id);
g_free (saved);
}
static const char*
session_dir (void)
{
static char *dir;
if (dir == NULL)
{
dir = g_strconcat (msm_get_work_directory (),
"/sessions",
NULL);
}
return dir;
}
static void
set_close_on_exec (int fd)
{
int val;
val = fcntl (fd, F_GETFD, 0);
if (val < 0)
{
msm_warning ("couldn't F_GETFD: %s\n", g_strerror (errno));
return;
}
val |= FD_CLOEXEC;
if (fcntl (fd, F_SETFD, val) < 0)
msm_warning ("couldn't F_SETFD: %s\n", g_strerror (errno));
}
/* Your basic Stevens cut-and-paste */
static int
lock_reg (int fd, int cmd, int type, off_t offset, int whence, off_t len)
{
struct flock lock;
lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */
lock.l_start = offset; /* byte offset relative to whence */
lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
lock.l_len = len; /* #bytes, 0 for eof */
return fcntl (fd, cmd, &lock);
}
#define lock_entire_file(fd) \
lock_reg ((fd), F_SETLK, F_WRLCK, 0, SEEK_SET, 0)
#define unlock_entire_file(fd) \
lock_reg ((fd), F_SETLK, F_UNLCK, 0, SEEK_SET, 0)
static MsmSession*
msm_session_get_for_filename (const char *name,
const char *filename)
{
MsmSession *session;
int fd = -1;
GError *dir_error = NULL;
GError *err;
if (sessions)
{
session = g_hash_table_lookup (sessions, filename);
if (session)
return session;
}
session = g_new0 (MsmSession, 1);
session->name = g_strdup (name);
session->clients = NULL;
session->filename = g_strdup (filename);
session->full_filename = g_strconcat (session_dir (), "/", filename, NULL);
session->lock_fd = -1;
dir_error = NULL;
msm_create_dir_and_parents (session_dir (), 0700, &dir_error);
/* We save dir_error for later; if creating the file fails,
* we give dir_error in the reason.
*/
/* To use a session, we need to lock the file in the user's
* save dir (by default in .msm/sessions/).
*
* If the file didn't previously exist, then we
* init the session from the global session of the same name,
* if any.
*
* This locking stuff has several races in it, and probably doesn't
* work over NFS, and all that jazz, but avoiding the races
* introduces stale lock issues, which are in practice more serious
* for users than the usual issues one worries about when locking.
*/
fd = open (session->full_filename, O_RDWR | O_CREAT, 0700);
if (fd < 0)
{
char *message;
message = g_strdup_printf (_("Failed to open the session file '%s': %s (%s)"),
session->full_filename,
g_strerror (errno),
dir_error ?
dir_error->message :
_("file's parent directory created successfully"));
if (dir_error)
g_error_free (dir_error);
session = recover_failed_session (session,
MSM_SESSION_FAILURE_OPENING_FILE,
message);
g_free (message);
return session;
}
if (dir_error)
{
g_error_free (dir_error);
dir_error = NULL;
}
if (lock_entire_file (fd) < 0)
{
char *message;
close (fd);
message = g_strdup_printf (_("Failed to lock the session file '%s': %s"),
session->full_filename,
g_strerror (errno));
session = recover_failed_session (session,
MSM_SESSION_FAILURE_LOCKING,
message);
g_free (message);
return session;
}
session->lock_fd = fd;
set_close_on_exec (fd);
err = NULL;
if (!parse_session_file (session, &err))
{
char *message;
message = g_strdup_printf (_("Failed to parse the session file '%s': %s\n"),
session->full_filename,
err->message);
g_error_free (err);
session = recover_failed_session (session,
MSM_SESSION_FAILURE_BAD_FILE,
message);
g_free (message);
return session;
}
/* FIXME FALSE */
if (FALSE && session->clients == NULL)
{
session = recover_failed_session (session,
MSM_SESSION_FAILURE_EMPTY,
NULL);
return session;
}
return session;
}
MsmSession*
msm_session_get (const char *name)
{
if (name == NULL)
{
return msm_session_get_for_filename (_("Default"), "Default.session");
}
else
{
char *filename;
char *p;
MsmSession *session;
filename = g_strconcat (name, ".session", NULL);
/* Remove path separators from the filename */
p = filename;
while (*p)
{
if (*p == '/')
*p = '_';
++p;
}
session = msm_session_get_for_filename (name, filename);
g_free (filename);
return session;
}
}
MsmSession*
msm_session_get_failsafe (void)
{
return msm_session_get_for_filename (_("Failsafe"), "Failsafe.session");
}
static void
write_proplist (FILE *fp,
GList *properties)
{
GList *tmp;
tmp = properties;
while (tmp != NULL)
{
SmProp *prop = tmp->data;
char *name_encoded;
char *type_encoded;
name_encoded = encode_text_as_utf8 (prop->name);
type_encoded = encode_text_as_utf8 (prop->type);
fprintf (fp, " <prop name=\"%s\" type=\"%s\">\n",
name_encoded, type_encoded);
g_free (name_encoded);
g_free (type_encoded);
if (strcmp (prop->type, SmCARD8) == 0)
{
int val = 0;
smprop_get_card8 (prop, &val);
fprintf (fp, " <value>%d</value>\n", val);
}
else if (strcmp (prop->type, SmARRAY8) == 0)
{
char *str = NULL;
char *encoded = NULL;
smprop_get_string (prop, &str);
if (str)
encoded = encode_text_as_utf8 (str);
if (encoded)
fprintf (fp, " <value>%s</value>\n", encoded);
g_free (encoded);
g_free (str);
}
else if (strcmp (prop->type, SmLISTofARRAY8) == 0)
{
char **vec;
int vec_len;
int i;
vec = NULL;
vec_len = 0;
smprop_get_vector (prop, &vec_len, &vec);
i = 0;
while (i < vec_len)
{
char *encoded;
encoded = encode_text_as_utf8 (vec[i]);
fprintf (fp, " <value>%s</value>\n", encoded);
g_free (encoded);
++i;
}
g_strfreev (vec);
}
else
{
msm_warning (_("Not saving unknown property type '%s'\n"),
prop->type);
}
fputs (" </prop>\n", fp);
tmp = tmp->next;
}
}
void
msm_session_save (MsmSession *session,
MsmServer *server)
{
/* We save to a secondary file then copy over, to handle
* out-of-disk-space robustly
*/
int new_fd;
char *new_filename;
char *error;
FILE *fp;
error = NULL;
new_fd = -1;
new_filename = g_strconcat (session->full_filename, ".new", NULL);
new_fd = open (session->full_filename, O_RDWR | O_CREAT | O_EXCL, 0700);
if (new_fd < 0)
{
error = g_strdup_printf (_("Failed to open '%s': %s\n"),
new_filename, g_strerror (errno));
goto out;
}
if (lock_entire_file (new_fd) < 0)
{
error = g_strdup_printf (_("Failed to lock file '%s': %s"),
new_filename,
g_strerror (errno));
goto out;
}
fp = fdopen (new_fd, "w");
if (fp == NULL)
{
error = g_strdup_printf (_("Failed to write to new session file '%s': %s"),
new_filename, g_strerror (errno));
goto out;
}
fputs ("<msm_session>\n", fp);
{
GList *tmp;
tmp = session->clients;
while (tmp != NULL)
{
MsmSavedClient *saved = tmp->data;
char *encoded;
encoded = encode_text_as_utf8 (saved->id);
fprintf (fp, " <client id=\"%s\">\n",
encoded);
g_free (encoded);
write_proplist (fp, saved->properties);
fputs (" </client>\n", fp);
tmp = tmp->next;
}
}
fputs ("</msm_session>\n", fp);
if (ferror (fp))
{
error = g_strdup_printf (_("Error writing new session file '%s': %s"),
new_filename, g_strerror (errno));
fclose (fp);
goto out;
}
if (fclose (fp) < 0)
{
error = g_strdup_printf (_("Failed to close to new session file '%s': %s"),
new_filename, g_strerror (errno));
goto out;
}
if (rename (new_filename, session->full_filename) < 0)
{
error = g_strdup_printf (_("Failed to replace the old session file '%s' with the new session contents in the temporary file '%s': %s"),
session->full_filename,
new_filename, g_strerror (errno));
goto out;
}
out:
g_free (new_filename);
if (error)
{
if (new_fd >= 0)
close (new_fd);
}
else
{
if (session->lock_fd >= 0)
close (session->lock_fd);
session->lock_fd = new_fd;
set_close_on_exec (new_fd);
}
}
static void
add_details_to_dialog (GtkDialog *dialog,
const char *details)
{
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *label;
GtkRequisition req;
hbox = gtk_hbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
gtk_box_pack_start (GTK_BOX (dialog->vbox),
hbox,
FALSE, FALSE, 0);
button = gtk_button_new_with_mnemonic (_("_Details"));
gtk_box_pack_end (GTK_BOX (hbox), button,
FALSE, FALSE, 0);
label = gtk_label_new (details);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_box_pack_start (GTK_BOX (hbox), label,
TRUE, TRUE, 0);
/* show the label on click */
g_signal_connect_swapped (G_OBJECT (button),
"clicked",
G_CALLBACK (gtk_widget_show),
label);
/* second callback destroys the button (note disconnects first callback) */
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (gtk_widget_destroy),
NULL);
/* Set default dialog size to size with the label,
* and without the button, but then rehide the label
*/
gtk_widget_show_all (hbox);
gtk_widget_size_request (GTK_WIDGET (dialog), &req);
#if 0
/* Omitted for now because it triggers a GTK 1.3.7 bug */
gtk_window_set_default_size (GTK_WINDOW (dialog), req.width, req.height);
#endif
gtk_widget_hide (label);
}
static MsmSession*
recover_failed_session (MsmSession *session,
MsmSessionFailureReason reason,
const char *details)
{
/* FIXME, actually give option to recover, don't just complain */
GtkWidget *dialog;
char *message;
message = NULL;
switch (reason)
{
case MSM_SESSION_FAILURE_OPENING_FILE:
message = g_strdup_printf (_("Could not open the session \"%s.\""),
session->name);
/* FIXME recovery options:
* - give up and exit; something pathological is going on
* - choose another session?
* - use default session in read-only mode?
* - open xterm to repair the problem, then try again (experts only)
*/
break;
case MSM_SESSION_FAILURE_LOCKING:
message = g_strdup_printf (_("You are already logged in elsewhere, using the session \"%s.\" You can only use a session from one location at a time."),
session->name);
/* FIXME recovery options:
* - log in anyhow, with possible weirdness
* - try again (after logging out the other session)
* - choose another session
* - open xterm to repair the problem, then try again (experts only)
*/
break;
case MSM_SESSION_FAILURE_BAD_FILE:
message = g_strdup_printf (_("The session file for session \"%s\" appears to be invalid or corrupted."),
session->name);
/* FIXME recovery options:
* - revert session to defaults
* - choose another session
* - open xterm to repair the problem, then try again (experts only)
*/
break;
case MSM_SESSION_FAILURE_EMPTY:
message = g_strdup_printf (_("The session \"%s\" contains no applications."),
session->name);
/* FIXME recovery options:
* - put default applications in the session
* - choose another session
* - open xterm to repair the problem, then try again (experts only)
*/
break;
}
dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
message);
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
if (details)
add_details_to_dialog (GTK_DIALOG (dialog), details);
g_free (message);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
exit (1);
/* FIXME instead of exiting, always recover by coming up with some sort
* of session. Also, offer nice recovery options specific to each of the above
* failure modes.
*/
return NULL;
}
static gboolean
parse_session_file (MsmSession *session,
GError **error)
{
char *parse_file;
struct stat sb;
gboolean file_empty;
parse_file = NULL;
file_empty = FALSE;
/* If the file is empty, probably because we just created it or have
* never saved our session, then parse the global session file
* instead of the user session file for our initial state.
*/
if (fstat (session->lock_fd, &sb) < 0)
{
/* Can't imagine this actually happening */
msm_warning (_("Failed to stat new session file descriptor (%s)\n"),
g_strerror (errno));
}
else
{
if (sb.st_size == 0)
file_empty = TRUE;
}
if (file_empty)
parse_file = g_strconcat (MSM_PKGDATADIR, "/", session->filename, NULL);
else
parse_file = g_strdup (session->full_filename);
/* FIXME do the parsing */
g_free (parse_file);
return TRUE;
}
static char*
encode_text_as_utf8 (const char *text)
{
/* text can be any encoding, and is nul-terminated.
* we pretend it's Latin-1 and encode as UTF-8
*/
GString *str;
const char *p;
str = g_string_new ("");
p = text;
while (*p)
{
g_string_append_unichar (str, *p);
++p;
}
return g_string_free (str, FALSE);
}
static char*
decode_text_from_utf8 (const char *text)
{
/* Convert back from the encoded UTF-8 */
GString *str;
const char *p;
str = g_string_new ("");
p = text;
while (*p)
{
/* obviously this barfs if the UTF-8 contains chars > 255 */
g_string_append_c (str, g_utf8_get_char (p));
p = g_utf8_next_char (p);
}
return g_string_free (str, FALSE);
}

View File

@ -1,44 +0,0 @@
/* msm session */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef MSM_SESSION_H
#define MSM_SESSION_H
#include "client.h"
typedef struct _MsmSession MsmSession;
MsmSession* msm_session_get (const char *name);
MsmSession* msm_session_get_failsafe (void);
void msm_session_save (MsmSession *session,
MsmServer *server);
void msm_session_clear (MsmSession *session);
void msm_session_update_client (MsmSession *session,
MsmClient *client);
void msm_session_remove_client (MsmSession *session,
MsmClient *client);
void msm_session_launch (MsmSession *session);
gboolean msm_session_client_id_known (MsmSession *session,
const char *previous_id);
#endif

View File

@ -1,181 +0,0 @@
/* msm utils */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "util.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
void
msm_fatal (const char *format, ...)
{
va_list args;
gchar *str;
g_return_if_fail (format != NULL);
va_start (args, format);
str = g_strdup_vprintf (format, args);
va_end (args);
fputs ("Session manager: ", stderr);
fputs (str, stderr);
fflush (stderr);
g_free (str);
exit (1);
}
void
msm_warning (const char *format, ...)
{
va_list args;
gchar *str;
g_return_if_fail (format != NULL);
va_start (args, format);
str = g_strdup_vprintf (format, args);
va_end (args);
fputs ("Session manager: ", stderr);
fputs (str, stderr);
fflush (stderr);
g_free (str);
}
gboolean
msm_create_dir_and_parents (const char *dir,
int mode,
GError **error)
{
char *parent;
GSList *parents;
GSList *tmp;
/* This function is crap; GNU fileutils has some really
* robust code that does this.
*/
parents = NULL;
parent = g_path_get_dirname (dir);
while (parent && parent[0] &&
strcmp (parent, ".") != 0 &&
strcmp (parent, "..") != 0 &&
strcmp (parent, "/") != 0 &&
/* an optimization since we will normally be using a homedir */
strcmp (parent, g_get_home_dir ()) != 0)
{
parents = g_slist_prepend (parents, parent);
parent = g_path_get_dirname (parent);
}
/* Errors are a bit tricky; if we can't create /foo because
* we lack write perms, and can't create /foo/bar because it exists,
* but can create /foo/bar/baz, then it's not really an error.
*
* We more or less punt, and just display an error for the last mkdir.
*/
tmp = parents;
while (tmp != NULL)
{
mkdir (tmp->data, mode);
g_free (tmp->data);
tmp = tmp->next;
}
g_slist_free (parents);
if (mkdir (dir, mode) < 0)
{
if (errno != EEXIST)
{
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
_("Failed to create directory '%s': %s\n"),
dir, g_strerror (errno));
return FALSE;
}
}
return TRUE;
}
const char*
msm_get_work_directory (void)
{
static const char *dir = NULL;
if (dir == NULL)
{
dir = g_getenv ("SM_SAVE_DIR");
if (dir == NULL)
dir = g_strconcat (g_get_home_dir (), "/.msm", NULL);
}
/* ignore errors here, we'll catch them later when we
* try to use the dir
*/
msm_create_dir_and_parents (dir, 0700, NULL);
return dir;
}
char*
msm_non_glib_strdup (const char *str)
{
char *new_str;
if (str)
{
new_str = msm_non_glib_malloc (strlen (str) + 1);
strcpy (new_str, str);
}
else
new_str = NULL;
return new_str;
}
void*
msm_non_glib_malloc (int bytes)
{
void *ptr;
ptr = malloc (bytes);
if (ptr == NULL)
g_error ("Failed to allocate %d bytes\n", bytes);
return ptr;
}

View File

@ -1,48 +0,0 @@
/* msm utils */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef MSM_UTIL_H
#define MSM_UTIL_H
#include <glib.h>
/* FIXME */
#include <config.h>
#define _(x) x
#define N_(x) x
void msm_warning (const char *format,
...) G_GNUC_PRINTF (1, 2);
void msm_fatal (const char *format,
...) G_GNUC_PRINTF (1, 2);
void msm_quit (void);
const char* msm_get_work_directory (void);
char* msm_non_glib_strdup (const char *src);
void* msm_non_glib_malloc (int bytes);
gboolean msm_create_dir_and_parents (const char *dir,
int mode,
GError **error);
#endif