xenocara/app/xsm/save.c
2010-10-31 20:17:58 +00:00

1402 lines
31 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* $Xorg: save.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */
/******************************************************************************
Copyright 1993, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
******************************************************************************/
/* $XFree86: xc/programs/xsm/save.c,v 3.3 2001/01/17 23:46:30 dawes Exp $ */
#include "xsm.h"
#include "save.h"
#include "saveutil.h"
#include "popup.h"
#include "info.h"
#include "lock.h"
#include "choose.h"
#include <X11/Shell.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/List.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/AsciiText.h>
static Widget savePopup;
static Widget saveForm;
static Widget saveMessageLabel;
static Widget saveName;
static Widget saveTypeLabel;
static Widget saveTypeGlobal;
static Widget saveTypeLocal;
static Widget saveTypeBoth;
static Widget interactStyleLabel;
static Widget interactStyleNone;
static Widget interactStyleErrors;
static Widget interactStyleAny;
static Widget saveOkButton;
static Widget helpSaveButton;
static Widget saveCancelButton;
static Widget helpPopup;
static Widget helpForm;
static Widget helpSaveText;
static Widget helpSaveOkButton;
static Widget nameInUsePopup;
static Widget nameInUseForm;
static Widget nameInUseLabel;
static Widget nameInUseOverwriteButton;
static Widget nameInUseCancelButton;
static Widget badSavePopup;
static Widget badSaveForm;
static Widget badSaveLabel;
static Widget badSaveOkButton;
static Widget badSaveCancelButton;
static Widget badSaveListWidget;
static int saveTypeData[] = {
SmSaveLocal,
SmSaveGlobal,
SmSaveBoth
};
static int interactStyleData[] = {
SmInteractStyleNone,
SmInteractStyleErrors,
SmInteractStyleAny
};
static String *failedNames = NULL;
static int numFailedNames = 0;
static Bool help_visible = False;
static String name_in_use = NULL;
static Bool name_locked = False;
static void
MakeCurrentSession(String new_name, Bool name_changed)
{
char title[256];
List *cl;
if (session_name)
{
/*
* In the old session, for any client that was not restarted by the
* session manager (previous ID was NULL), if we did not issue a
* checkpoint to this client after the initial startup, remove the
* client's checkpoint file using the discard command.
*/
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
if (!client->restarted &&
!client->userIssuedCheckpoint &&
client->discardCommand)
{
execute_system_command (client->discardCommand);
XtFree (client->discardCommand);
client->discardCommand = NULL;
}
}
/*
* Unlock the old session.
*/
if (!need_to_name_session)
UnlockSession (session_name);
}
if (name_changed)
{
if (session_name)
XtFree (session_name);
session_name = XtNewString (new_name);
}
LockSession (session_name, True);
snprintf (title, sizeof(title), "xsm: %s", session_name);
XtVaSetValues (topLevel,
XtNtitle, title,
NULL);
set_session_save_file_name (session_name);
/*
* For each client, set the DiscardCommand ptr to NULL.
* This is so when we do a checkpoint with the new session
* name, we don't wipe out the checkpoint files needed by
* the previous session. We also set the userIssuedCheckpoint
* flag to false for each client in the new session.
*/
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
client->userIssuedCheckpoint = False;
if (client->discardCommand)
{
XtFree (client->discardCommand);
client->discardCommand = NULL;
}
}
need_to_name_session = False;
}
#define NAME_OK 0
#define NAME_EMPTY 1
#define NAME_EXISTS 2
#define NAME_LOCKED 3
static int
GetSaveName(String *nameRet)
{
String new_name = NULL;
Bool name_changed;
/*
* Get the name of the session for the save
*/
XtVaGetValues (saveName,
XtNstring, &new_name,
NULL);
*nameRet = new_name;
if (!new_name || *new_name == '\0')
return (NAME_EMPTY);
/*
* See if this is a new session. If not return.
*/
name_changed = !session_name ||
(session_name && strcmp (session_name, new_name) != 0);
if (!need_to_name_session && !name_changed)
return (NAME_OK);
/*
* Make sure the session name is unique.
*/
if (GetSessionNames (&sessionNameCount,
&sessionNamesShort, NULL, &sessionsLocked))
{
int i, no_good = 0, locked = 0;
for (i = 0; i < sessionNameCount; i++)
if (strcmp (new_name, sessionNamesShort[i]) == 0)
{
no_good = 1;
locked = sessionsLocked[i];
break;
}
FreeSessionNames (sessionNameCount,
sessionNamesShort, NULL, sessionsLocked);
if (no_good)
return (locked ? NAME_LOCKED : NAME_EXISTS);
}
MakeCurrentSession (new_name, name_changed);
return (NAME_OK);
}
static void
GetSaveOptions(int *saveType, int *interactStyle, Bool *fast)
{
XtPointer ptr;
if (help_visible)
{
XtPopdown (helpPopup);
help_visible = 0;
}
ptr = XawToggleGetCurrent (saveTypeLocal /* just 1 of the group */);
*saveType = *((int *) ptr);
ptr = XawToggleGetCurrent (interactStyleNone /* just 1 of the group */);
*interactStyle = *((int *) ptr);
*fast = False;
}
void
DoSave(int saveType, int interactStyle, Bool fast)
{
ClientRec *client;
List *cl;
char *_saveType;
char *_shutdown;
char *_interactStyle;
if (saveType == SmSaveLocal)
_saveType = "Local";
else if (saveType == SmSaveGlobal)
_saveType = "Global";
else
_saveType = "Both";
if (wantShutdown)
_shutdown = "True";
else
_shutdown = "False";
if (interactStyle == SmInteractStyleNone)
_interactStyle = "None";
else if (interactStyle == SmInteractStyleErrors)
_interactStyle = "Errors";
else
_interactStyle = "Any";
SetSaveSensitivity (False);
saveInProgress = True;
shutdownCancelled = False;
phase2InProgress = False;
if (ListCount (RunningList) == 0)
FinishUpSave ();
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
SmsSaveYourself (client->smsConn,
saveType, wantShutdown, interactStyle, fast);
ListAddLast (WaitForSaveDoneList, (char *) client);
client->userIssuedCheckpoint = True;
client->receivedDiscardCommand = False;
if (verbose)
{
printf ("Client Id = %s, sent SAVE YOURSELF [", client->clientId);
printf ("Save Type = %s, Shutdown = %s, ", _saveType, _shutdown);
printf ("Interact Style = %s, Fast = False]\n", _interactStyle);
}
}
if (verbose)
{
printf ("\n");
printf ("Sent SAVE YOURSELF to all clients. Waiting for\n");
printf ("SAVE YOURSELF DONE, INTERACT REQUEST, or\n");
printf ("SAVE YOURSELF PHASE 2 REQUEST from each client.\n");
printf ("\n");
}
}
static void
SaveOkAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
XtCallCallbacks (saveOkButton, XtNcallback, NULL);
}
static void
DelSaveWinAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
XtCallCallbacks (saveCancelButton, XtNcallback, NULL);
}
static void
DelNameInUseWinAction(Widget w, XEvent *event, String *params,
Cardinal *num_params)
{
XtCallCallbacks (nameInUseCancelButton, XtNcallback, NULL);
}
static void
DelBadSaveWinAction(Widget w, XEvent *event, String *params,
Cardinal *num_params)
{
if (XtIsManaged (badSaveCancelButton))
XtCallCallbacks (badSaveCancelButton, XtNcallback, NULL);
else
XtCallCallbacks (badSaveOkButton, XtNcallback, NULL);
}
static void
DelSaveHelpWinAction(Widget w, XEvent *event, String *params,
Cardinal *num_params)
{
XtCallCallbacks (helpSaveOkButton, XtNcallback, NULL);
}
static void
SaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
String name = NULL;
char label[256];
int status;
static int first_time = 1;
int saveType;
int interactStyle;
Bool fast;
if ((status = GetSaveName (&name)) != NAME_OK)
{
#ifdef XKB
XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
#else
XBell (XtDisplay (topLevel), 0);
#endif
if (status == NAME_EXISTS || status == NAME_LOCKED)
{
name_in_use = name;
if (status == NAME_LOCKED)
{
name_locked = True;
snprintf (label, sizeof(label), "Another session by the name '%s' is active.\nChoose another name for the session.", name);
XtUnmanageChild (nameInUseOverwriteButton);
XtVaSetValues (nameInUseCancelButton,
XtNlabel, "OK",
XtNfromHoriz, NULL,
NULL);
}
else
{
name_locked = False;
sprintf (label, "Another session by the name '%s' already exists.\nWould you like to overwrite it?", name);
XtManageChild (nameInUseOverwriteButton);
XtVaSetValues (nameInUseCancelButton,
XtNlabel, "Cancel",
XtNfromHoriz, nameInUseOverwriteButton,
NULL);
}
XtVaSetValues (nameInUseLabel,
XtNlabel, label,
NULL);
XtPopdown (savePopup);
PopupPopup (mainWindow, nameInUsePopup,
True, first_time, 25, 100, "DelNameInUseWinAction()");
if (first_time)
first_time = 0;
}
return;
}
GetSaveOptions (&saveType, &interactStyle, &fast);
DoSave (saveType, interactStyle, fast);
}
void
LetClientInteract(List *cl)
{
ClientRec *client = (ClientRec *) cl->thing;
SmsInteract (client->smsConn);
ListSearchAndFreeOne (WaitForInteractList, (char *) client);
if (verbose)
{
printf ("Client Id = %s, sent INTERACT\n", client->clientId);
}
}
void
StartPhase2(void)
{
List *cl;
if (verbose)
{
printf ("\n");
printf ("Starting PHASE 2 of SAVE YOURSELF\n");
printf ("\n");
}
for (cl = ListFirst (WaitForPhase2List); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
SmsSaveYourselfPhase2 (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent SAVE YOURSELF PHASE 2",
client->clientId);
}
}
ListFreeAllButHead (WaitForPhase2List);
phase2InProgress = True;
}
void
FinishUpSave(void)
{
ClientRec *client;
List *cl;
if (verbose)
{
printf ("\n");
printf ("All clients issued SAVE YOURSELF DONE\n");
printf ("\n");
}
saveInProgress = False;
phase2InProgress = False;
/*
* Now execute discard commands
*/
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
if (!client->receivedDiscardCommand)
continue;
if (client->discardCommand)
{
execute_system_command (client->discardCommand);
XtFree (client->discardCommand);
client->discardCommand = NULL;
}
if (client->saveDiscardCommand)
{
client->discardCommand = client->saveDiscardCommand;
client->saveDiscardCommand = NULL;
}
}
/*
* Write the save file
*/
WriteSave (sm_id);
if (wantShutdown && shutdownCancelled)
{
shutdownCancelled = False;
}
else if (wantShutdown)
{
if (ListCount (RunningList) == 0)
EndSession (0);
shutdownInProgress = True;
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
SmsDie (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent DIE\n", client->clientId);
}
}
}
else
{
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
SmsSaveComplete (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent SAVE COMPLETE\n",
client->clientId);
}
}
}
if (!shutdownInProgress)
{
XtPopdown (savePopup);
SetAllSensitive (1);
if (checkpoint_from_signal)
checkpoint_from_signal = False;
}
}
static void
SaveCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
XtPopdown (savePopup);
if (help_visible)
{
XtPopdown (helpPopup);
help_visible = 0;
}
SetAllSensitive (1);
}
/*
* Add toggle button
*/
static Widget
AddToggle(char *widgetName, Widget parent, int state, Widget radioGroup,
XtPointer radioData, Widget fromHoriz, Widget fromVert)
{
Widget toggle;
toggle = XtVaCreateManagedWidget (
widgetName, toggleWidgetClass, parent,
XtNstate, state,
XtNradioGroup, radioGroup,
XtNradioData, radioData,
XtNfromHoriz, fromHoriz,
XtNfromVert, fromVert,
NULL);
return (toggle);
}
void
SetSaveSensitivity(Bool on)
{
XtSetSensitive (savePopup, on);
#if 0
/*
* When we turn of sensitivity in the save dialog, we want to keep
* the cancel button sensitive (so the user can cancel in case of
* a problem). Unfortunately, we can not turn off the sensitivity on
* the save popup, and then just turn on sensitivity for the cancel
* button. We must do each widget individually.
*/
XtSetSensitive (saveTypeLabel, on);
XtSetSensitive (saveTypeGlobal, on);
XtSetSensitive (saveTypeLocal, on);
XtSetSensitive (saveTypeBoth, on);
XtSetSensitive (interactStyleLabel, on);
XtSetSensitive (interactStyleNone, on);
XtSetSensitive (interactStyleErrors, on);
XtSetSensitive (interactStyleAny, on);
XtSetSensitive (saveOkButton, on);
#endif
}
void
SavePopupStructureNotifyXtHandler(Widget w, XtPointer closure, XEvent *event,
Boolean *continue_to_dispatch)
{
if (event->type == MapNotify)
{
/*
* Now that the Save Dialog is back up, we can do the save.
*/
int saveType;
int interactStyle;
Bool fast;
if (name_locked)
{
/* Force shutdown */
}
DeleteSession (name_in_use);
MakeCurrentSession (name_in_use, True);
name_in_use = NULL;
GetSaveOptions (&saveType, &interactStyle, &fast);
DoSave (saveType, interactStyle, fast);
XtRemoveEventHandler (savePopup, StructureNotifyMask, False,
SavePopupStructureNotifyXtHandler, NULL);
}
}
static void
NameInUseOverwriteXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
if (name_locked)
{
/* force shutdown not implemented yet */
return;
}
XtPopdown (nameInUsePopup);
/*
* We want to popup the Save dialog again. In order to avoid a race
* condition with the BadSave handler trying to pop down the Save Dialog,
* we wait for the MapNotify on the Save dialog, and then do the save.
*/
XtAddEventHandler (savePopup, StructureNotifyMask, False,
SavePopupStructureNotifyXtHandler, NULL);
XtPopup (savePopup, XtGrabNone);
}
static void
NameInUseCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
XtPopdown (nameInUsePopup);
XtPopup (savePopup, XtGrabNone);
name_in_use = NULL;
}
static void
BadSaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
ListFreeAllButHead (FailedSaveList);
XtPopdown (badSavePopup);
FinishUpSave ();
}
static void
BadSaveCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
ListFreeAllButHead (FailedSaveList);
XtPopdown (badSavePopup);
if (wantShutdown)
{
List *cl;
shutdownCancelled = True;
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
SmsShutdownCancelled (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent SHUTDOWN CANCELLED\n",
client->clientId);
}
}
}
FinishUpSave ();
}
static void
BadSaveListXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
}
static void
HelpSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
static int first_time = 1;
if (help_visible)
{
/* Make sure it is visible */
XMapRaised (XtDisplay (topLevel), XtWindow (helpPopup));
}
else
{
PopupPopup (savePopup, helpPopup,
True, first_time, 50, 50, "DelSaveHelpWinAction()");
help_visible = 1;
if (first_time)
first_time = 0;
}
}
static void
HelpSaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
XtPopdown (helpPopup);
help_visible = 0;
}
void
create_save_popup(void)
{
XtTranslations translations;
static XtActionsRec actions[] = {
{"SaveOkAction", SaveOkAction},
{"DelSaveWinAction", DelSaveWinAction},
{"DelNameInUseWinAction", DelNameInUseWinAction},
{"DelBadSaveWinAction", DelBadSaveWinAction},
{"DelSaveHelpWinAction", DelSaveHelpWinAction}
};
/*
* Pop up for Save Yourself button.
*/
savePopup = XtVaCreatePopupShell (
"savePopup", transientShellWidgetClass, topLevel,
XtNallowShellResize, True,
NULL);
saveForm = XtCreateManagedWidget (
"saveForm", formWidgetClass, savePopup, NULL, 0);
saveMessageLabel = XtVaCreateManagedWidget (
"saveMessageLabel", labelWidgetClass, saveForm,
XtNfromHoriz, NULL,
XtNfromVert, NULL,
XtNborderWidth, 0,
NULL);
saveName = XtVaCreateManagedWidget (
"saveName", asciiTextWidgetClass, saveForm,
XtNfromVert, NULL,
XtNeditType, XawtextEdit,
XtNresizable, True,
XtNresize, XawtextResizeWidth,
NULL);
saveTypeLabel = XtVaCreateManagedWidget (
"saveTypeLabel", labelWidgetClass, saveForm,
XtNfromHoriz, NULL,
XtNfromVert, saveMessageLabel,
XtNborderWidth, 0,
XtNvertDistance, 20,
NULL);
saveTypeLocal = AddToggle (
"saveTypeLocal", /* widgetName */
saveForm, /* parent */
0, /* state */
NULL, /* radioGroup */
(XtPointer) &saveTypeData[0], /* radioData */
saveTypeLabel, /* fromHoriz */
saveMessageLabel /* fromVert */
);
saveTypeGlobal = AddToggle (
"saveTypeGlobal", /* widgetName */
saveForm, /* parent */
0, /* state */
saveTypeLocal, /* radioGroup */
(XtPointer) &saveTypeData[1], /* radioData */
saveTypeLocal, /* fromHoriz */
saveMessageLabel /* fromVert */
);
saveTypeBoth = AddToggle (
"saveTypeBoth", /* widgetName */
saveForm, /* parent */
1, /* state */
saveTypeLocal, /* radioGroup */
(XtPointer) &saveTypeData[2], /* radioData */
saveTypeGlobal, /* fromHoriz */
saveMessageLabel /* fromVert */
);
XtVaSetValues (saveName, XtNfromHoriz, saveTypeLabel, NULL);
XtVaSetValues (saveTypeLocal, XtNvertDistance, 20, NULL);
XtVaSetValues (saveTypeGlobal, XtNvertDistance, 20, NULL);
XtVaSetValues (saveTypeBoth, XtNvertDistance, 20, NULL);
interactStyleLabel = XtVaCreateManagedWidget (
"interactStyleLabel", labelWidgetClass, saveForm,
XtNfromHoriz, NULL,
XtNfromVert, saveTypeLabel,
XtNborderWidth, 0,
NULL);
interactStyleNone = AddToggle (
"interactStyleNone", /* widgetName */
saveForm, /* parent */
0, /* state */
NULL, /* radioGroup */
(XtPointer) &interactStyleData[0], /* radioData */
saveTypeLabel, /* fromHoriz */
saveTypeLabel /* fromVert */
);
interactStyleErrors = AddToggle (
"interactStyleErrors", /* widgetName */
saveForm, /* parent */
0, /* state */
interactStyleNone, /* radioGroup */
(XtPointer) &interactStyleData[1], /* radioData */
interactStyleNone, /* fromHoriz */
saveTypeLabel /* fromVert */
);
interactStyleAny = AddToggle (
"interactStyleAny", /* widgetName */
saveForm, /* parent */
1, /* state */
interactStyleNone, /* radioGroup */
(XtPointer) &interactStyleData[2], /* radioData */
interactStyleErrors, /* fromHoriz */
saveTypeLabel /* fromVert */
);
saveOkButton = XtVaCreateManagedWidget (
"saveOkButton", commandWidgetClass, saveForm,
XtNfromHoriz, NULL,
XtNfromVert, interactStyleLabel,
XtNvertDistance, 20,
XtNresizable, True,
NULL);
XtAddCallback (saveOkButton, XtNcallback, SaveOkXtProc, NULL);
helpSaveButton = XtVaCreateManagedWidget (
"helpSaveButton", commandWidgetClass, saveForm,
XtNfromHoriz, saveOkButton,
XtNfromVert, interactStyleLabel,
XtNvertDistance, 20,
NULL);
XtAddCallback (helpSaveButton, XtNcallback, HelpSaveXtProc, NULL);
saveCancelButton = XtVaCreateManagedWidget (
"saveCancelButton", commandWidgetClass, saveForm,
XtNfromHoriz, helpSaveButton,
XtNfromVert, interactStyleLabel,
XtNvertDistance, 20,
NULL);
XtAddCallback (saveCancelButton, XtNcallback, SaveCancelXtProc, NULL);
XtSetKeyboardFocus (saveForm, saveName);
XtAppAddActions (appContext, actions, XtNumber (actions));
translations = XtParseTranslationTable
("<Key>Return: SaveOkAction()\n");
XtOverrideTranslations(saveName, translations);
XtInstallAllAccelerators (saveForm, saveForm);
/*
* Pop up when user tries to save the session under an
* already used name.
*/
nameInUsePopup = XtVaCreatePopupShell (
"nameInUsePopup", transientShellWidgetClass, topLevel,
XtNallowShellResize, True,
NULL);
nameInUseForm = XtVaCreateManagedWidget (
"nameInUseForm", formWidgetClass, nameInUsePopup,
NULL);
nameInUseLabel = XtVaCreateManagedWidget (
"nameInUseLabel", labelWidgetClass, nameInUseForm,
XtNresizable, True,
XtNfromHoriz, NULL,
XtNfromVert, NULL,
XtNborderWidth, 0,
XtNtop, XawChainTop,
XtNbottom, XawChainTop,
NULL);
nameInUseOverwriteButton = XtVaCreateManagedWidget (
"nameInUseOverwriteButton", commandWidgetClass, nameInUseForm,
XtNfromHoriz, NULL,
XtNfromVert, nameInUseLabel,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (nameInUseOverwriteButton, XtNcallback,
NameInUseOverwriteXtProc, NULL);
nameInUseCancelButton = XtVaCreateManagedWidget (
"nameInUseCancelButton", commandWidgetClass, nameInUseForm,
XtNresizable, True,
XtNfromHoriz, nameInUseOverwriteButton,
XtNfromVert, nameInUseLabel,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (nameInUseCancelButton, XtNcallback,
NameInUseCancelXtProc, NULL);
/*
* Pop up for help.
*/
helpPopup = XtVaCreatePopupShell (
"helpPopup", transientShellWidgetClass, topLevel,
NULL);
helpForm = XtVaCreateManagedWidget (
"helpForm", formWidgetClass, helpPopup,
NULL);
helpSaveText = XtVaCreateManagedWidget (
"helpSaveText", labelWidgetClass, helpForm,
XtNfromHoriz, NULL,
XtNfromVert, NULL,
XtNtop, XawChainTop,
XtNbottom, XawChainTop,
NULL);
helpSaveOkButton = XtVaCreateManagedWidget (
"helpSaveOkButton", commandWidgetClass, helpForm,
XtNfromHoriz, NULL,
XtNfromVert, helpSaveText,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
XtNvertDistance, 20,
NULL);
XtAddCallback (helpSaveOkButton, XtNcallback,
HelpSaveOkXtProc, NULL);
/*
* Pop up when not all clients returned SaveSuccess
*/
badSavePopup = XtVaCreatePopupShell (
"badSavePopup", transientShellWidgetClass, topLevel,
XtNallowShellResize, True,
NULL);
badSaveForm = XtVaCreateManagedWidget (
"badSaveForm", formWidgetClass, badSavePopup,
NULL);
badSaveLabel = XtVaCreateManagedWidget (
"badSaveLabel", labelWidgetClass, badSaveForm,
XtNfromHoriz, NULL,
XtNfromVert, NULL,
XtNborderWidth, 0,
XtNtop, XawChainTop,
XtNbottom, XawChainTop,
NULL);
badSaveListWidget = XtVaCreateManagedWidget (
"badSaveListWidget", listWidgetClass, badSaveForm,
XtNresizable, True,
XtNdefaultColumns, 1,
XtNforceColumns, True,
XtNfromHoriz, NULL,
XtNfromVert, badSaveLabel,
XtNtop, XawChainTop,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (badSaveListWidget, XtNcallback, BadSaveListXtProc, NULL);
badSaveOkButton = XtVaCreateManagedWidget (
"badSaveOkButton", commandWidgetClass, badSaveForm,
XtNfromHoriz, NULL,
XtNfromVert, badSaveListWidget,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (badSaveOkButton, XtNcallback, BadSaveOkXtProc, NULL);
badSaveCancelButton = XtVaCreateManagedWidget (
"badSaveCancelButton", commandWidgetClass, badSaveForm,
XtNfromHoriz, badSaveOkButton,
XtNfromVert, badSaveListWidget,
XtNtop, XawChainBottom,
XtNbottom, XawChainBottom,
NULL);
XtAddCallback (badSaveCancelButton, XtNcallback, BadSaveCancelXtProc, NULL);
XtInstallAllAccelerators (badSaveForm, badSaveForm);
}
void
PopupSaveDialog(void)
{
static int first_time = 1;
XtSetSensitive (mainWindow, 0);
XtSetSensitive (clientInfoPopup, 0);
XtSetSensitive (clientPropPopup, 0);
XawToggleSetCurrent (saveTypeBoth,
(XtPointer) &saveTypeData[2]);
XawToggleSetCurrent (interactStyleAny,
(XtPointer) &interactStyleData[2]);
XtVaSetValues (savePopup,
XtNtitle, wantShutdown ? "Shutdown" : "Checkpoint",
NULL);
XtVaSetValues (saveName,
XtNstring, need_to_name_session ? "" : session_name,
NULL);
XtVaSetValues (saveOkButton,
XtNlabel, wantShutdown ? "Shutdown" : "Checkpoint",
NULL);
PopupPopup (mainWindow, savePopup,
True, first_time, 25, 100, "DelSaveWinAction()");
if (first_time)
first_time = 0;
}
void
CheckPointXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
wantShutdown = False;
PopupSaveDialog ();
}
void
ShutdownSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
wantShutdown = True;
PopupSaveDialog ();
}
void
PopupBadSave(void)
{
ClientRec *client;
char *progName, *hostname, *tmp1, *tmp2;
String clientInfo;
int maxlen1, maxlen2;
char extraBuf1[80], extraBuf2[80];
char *restart_service_prop;
List *cl, *pl;
int i, k;
static int first_time = 1;
if (failedNames)
{
/*
* Free the previous list of names. Xaw doesn't make a copy of
* our list, so we need to keep it around.
*/
for (i = 0; i < numFailedNames; i++)
XtFree (failedNames[i]);
XtFree ((char *) failedNames);
failedNames = NULL;
}
maxlen1 = maxlen2 = 0;
numFailedNames = 0;
for (cl = ListFirst (FailedSaveList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
progName = NULL;
restart_service_prop = NULL;
for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
{
Prop *pprop = (Prop *) pl->thing;
List *vl = ListFirst (pprop->values);
PropValue *pval = (PropValue *) vl->thing;
if (strcmp (pprop->name, SmProgram) == 0)
{
progName = GetProgramName ((char *) pval->value);
if ((int) strlen (progName) > maxlen1)
maxlen1 = strlen (progName);
}
else if (strcmp (pprop->name, "_XC_RestartService") == 0)
{
restart_service_prop = (char *) pval->value;
}
}
if (!progName)
continue;
if (restart_service_prop)
tmp1 = restart_service_prop;
else if (client->clientHostname)
tmp1 = client->clientHostname;
else
continue;
if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
hostname = tmp1;
else
hostname = tmp2 + 1;
if ((int) strlen (hostname) > maxlen2)
maxlen2 = strlen (hostname);
numFailedNames++;
}
failedNames = (String *) XtMalloc (
numFailedNames * sizeof (String));
i = 0;
for (cl = ListFirst (FailedSaveList); cl; cl = ListNext (cl))
{
ClientRec *client = (ClientRec *) cl->thing;
int extra1, extra2;
progName = NULL;
restart_service_prop = NULL;
for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
{
Prop *pprop = (Prop *) pl->thing;
List *vl = ListFirst (pprop->values);
PropValue *pval = (PropValue *) vl->thing;
if (strcmp (pprop->name, SmProgram) == 0)
{
progName = GetProgramName ((char *) pval->value);
}
else if (strcmp (pprop->name, "_XC_RestartService") == 0)
{
restart_service_prop = (char *) pval->value;
}
}
if (!progName)
continue;
if (restart_service_prop)
tmp1 = restart_service_prop;
else if (client->clientHostname)
tmp1 = client->clientHostname;
else
continue;
if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
hostname = tmp1;
else
hostname = tmp2 + 1;
extra1 = maxlen1 - strlen (progName) + 5;
extra2 = maxlen2 - strlen (hostname);
clientInfo = (String) XtMalloc (strlen (progName) +
extra1 + extra2 + 3 + strlen (hostname) + 1);
for (k = 0; k < extra1; k++)
extraBuf1[k] = ' ';
extraBuf1[extra1] = '\0';
for (k = 0; k < extra2; k++)
extraBuf2[k] = ' ';
extraBuf2[extra2] = '\0';
sprintf (clientInfo, "%s%s (%s%s)", progName, extraBuf1,
hostname, extraBuf2);
failedNames[i++] = clientInfo;
if (client->freeAfterBadSavePopup)
{
FreeClient (client, True /* free props */);
}
}
XawListChange (badSaveListWidget,
failedNames, numFailedNames, 0, True);
XtPopdown (savePopup);
if (wantShutdown && !shutdownCancelled)
XtManageChild (badSaveCancelButton);
else
XtUnmanageChild (badSaveCancelButton);
PopupPopup (mainWindow, badSavePopup,
True, first_time, 25, 100, "DelBadSaveWinAction()");
if (first_time)
first_time = 0;
}
void
ShutdownDontSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
{
List *cl;
ClientRec *client;
if (ListCount (RunningList) == 0)
EndSession (0);
/*
* For any client that was not restarted by the session
* manager (previous ID was NULL), if we did not issue a
* checkpoint to this client, remove the client's checkpoint
* file using the discard command.
*/
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
if (!client->restarted &&
!client->userIssuedCheckpoint &&
client->discardCommand)
{
execute_system_command (client->discardCommand);
XtFree (client->discardCommand);
client->discardCommand = NULL;
}
}
shutdownInProgress = True;
for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
{
client = (ClientRec *) cl->thing;
SmsDie (client->smsConn);
if (verbose)
{
printf ("Client Id = %s, sent DIE\n", client->clientId);
}
}
}