save.c revision 8108eb18
18108eb18Smrg/* $Xorg: save.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */
28108eb18Smrg/******************************************************************************
38108eb18Smrg
48108eb18SmrgCopyright 1993, 1998  The Open Group
58108eb18Smrg
68108eb18SmrgPermission to use, copy, modify, distribute, and sell this software and its
78108eb18Smrgdocumentation for any purpose is hereby granted without fee, provided that
88108eb18Smrgthe above copyright notice appear in all copies and that both that
98108eb18Smrgcopyright notice and this permission notice appear in supporting
108108eb18Smrgdocumentation.
118108eb18Smrg
128108eb18SmrgThe above copyright notice and this permission notice shall be included in
138108eb18Smrgall copies or substantial portions of the Software.
148108eb18Smrg
158108eb18SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
168108eb18SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
178108eb18SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
188108eb18SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
198108eb18SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
208108eb18SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
218108eb18Smrg
228108eb18SmrgExcept as contained in this notice, the name of The Open Group shall not be
238108eb18Smrgused in advertising or otherwise to promote the sale, use or other dealings
248108eb18Smrgin this Software without prior written authorization from The Open Group.
258108eb18Smrg******************************************************************************/
268108eb18Smrg/* $XFree86: xc/programs/xsm/save.c,v 3.3 2001/01/17 23:46:30 dawes Exp $ */
278108eb18Smrg
288108eb18Smrg#include "xsm.h"
298108eb18Smrg#include "save.h"
308108eb18Smrg#include "saveutil.h"
318108eb18Smrg#include "popup.h"
328108eb18Smrg#include "info.h"
338108eb18Smrg#include "lock.h"
348108eb18Smrg#include "choose.h"
358108eb18Smrg
368108eb18Smrg#include <X11/Shell.h>
378108eb18Smrg#include <X11/Xaw/Form.h>
388108eb18Smrg#include <X11/Xaw/List.h>
398108eb18Smrg#include <X11/Xaw/Command.h>
408108eb18Smrg#include <X11/Xaw/Toggle.h>
418108eb18Smrg#include <X11/Xaw/AsciiText.h>
428108eb18Smrg
438108eb18Smrg
448108eb18SmrgWidget savePopup;
458108eb18SmrgWidget   saveForm;
468108eb18SmrgWidget	   saveMessageLabel;
478108eb18SmrgWidget	   saveName;
488108eb18SmrgWidget	   saveTypeLabel;
498108eb18SmrgWidget	   saveTypeGlobal;
508108eb18SmrgWidget	   saveTypeLocal;
518108eb18SmrgWidget	   saveTypeBoth;
528108eb18SmrgWidget	   interactStyleLabel;
538108eb18SmrgWidget	   interactStyleNone;
548108eb18SmrgWidget	   interactStyleErrors;
558108eb18SmrgWidget	   interactStyleAny;
568108eb18SmrgWidget	   saveOkButton;
578108eb18SmrgWidget     helpSaveButton;
588108eb18SmrgWidget	   saveCancelButton;
598108eb18SmrgWidget helpPopup;
608108eb18SmrgWidget   helpForm;
618108eb18SmrgWidget     helpSaveText;
628108eb18SmrgWidget     helpSaveOkButton;
638108eb18SmrgWidget nameInUsePopup;
648108eb18SmrgWidget   nameInUseForm;
658108eb18SmrgWidget	   nameInUseLabel;
668108eb18SmrgWidget     nameInUseOverwriteButton;
678108eb18SmrgWidget	   nameInUseCancelButton;
688108eb18SmrgWidget badSavePopup;
698108eb18SmrgWidget   badSaveForm;
708108eb18SmrgWidget	   badSaveLabel;
718108eb18SmrgWidget     badSaveOkButton;
728108eb18SmrgWidget	   badSaveCancelButton;
738108eb18SmrgWidget     badSaveListWidget;
748108eb18Smrg
758108eb18Smrgextern Widget clientInfoPopup;
768108eb18Smrgextern Widget clientPropPopup;
778108eb18Smrgextern Widget nameSessionPopup;
788108eb18Smrg
798108eb18Smrgextern int checkpoint_from_signal;
808108eb18Smrg
818108eb18Smrgstatic int saveTypeData[] = {
828108eb18Smrg	SmSaveLocal,
838108eb18Smrg	SmSaveGlobal,
848108eb18Smrg	SmSaveBoth
858108eb18Smrg};
868108eb18Smrg
878108eb18Smrgstatic int interactStyleData[] = {
888108eb18Smrg	SmInteractStyleNone,
898108eb18Smrg	SmInteractStyleErrors,
908108eb18Smrg	SmInteractStyleAny
918108eb18Smrg};
928108eb18Smrg
938108eb18Smrgstatic String *failedNames = NULL;
948108eb18Smrgstatic int numFailedNames = 0;
958108eb18Smrg
968108eb18Smrgstatic Bool help_visible = False;
978108eb18Smrg
988108eb18Smrgstatic String name_in_use = NULL;
998108eb18Smrgstatic Bool name_locked = False;
1008108eb18Smrg
1018108eb18Smrg
1028108eb18Smrg
1038108eb18Smrgstatic void
1048108eb18SmrgMakeCurrentSession(String new_name, Bool name_changed)
1058108eb18Smrg{
1068108eb18Smrg    char title[256];
1078108eb18Smrg    List *cl;
1088108eb18Smrg
1098108eb18Smrg    if (session_name)
1108108eb18Smrg    {
1118108eb18Smrg	/*
1128108eb18Smrg	 * In the old session, for any client that was not restarted by the
1138108eb18Smrg	 * session manager (previous ID was NULL), if we did not issue a
1148108eb18Smrg	 * checkpoint to this client after the initial startup, remove the
1158108eb18Smrg	 * client's checkpoint file using the discard command.
1168108eb18Smrg	 */
1178108eb18Smrg
1188108eb18Smrg	for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
1198108eb18Smrg	{
1208108eb18Smrg	    ClientRec *client = (ClientRec *) cl->thing;
1218108eb18Smrg
1228108eb18Smrg	    if (!client->restarted &&
1238108eb18Smrg		!client->userIssuedCheckpoint &&
1248108eb18Smrg		client->discardCommand)
1258108eb18Smrg	    {
1268108eb18Smrg		execute_system_command (client->discardCommand);
1278108eb18Smrg		XtFree (client->discardCommand);
1288108eb18Smrg		client->discardCommand = NULL;
1298108eb18Smrg	    }
1308108eb18Smrg	}
1318108eb18Smrg
1328108eb18Smrg	/*
1338108eb18Smrg	 * Unlock the old session.
1348108eb18Smrg	 */
1358108eb18Smrg
1368108eb18Smrg	if (!need_to_name_session)
1378108eb18Smrg	    UnlockSession (session_name);
1388108eb18Smrg    }
1398108eb18Smrg
1408108eb18Smrg    if (name_changed)
1418108eb18Smrg    {
1428108eb18Smrg	if (session_name)
1438108eb18Smrg	    XtFree (session_name);
1448108eb18Smrg
1458108eb18Smrg	session_name = XtNewString (new_name);
1468108eb18Smrg    }
1478108eb18Smrg
1488108eb18Smrg    LockSession (session_name, True);
1498108eb18Smrg
1508108eb18Smrg    sprintf (title, "xsm: %s", session_name);
1518108eb18Smrg
1528108eb18Smrg    XtVaSetValues (topLevel,
1538108eb18Smrg	XtNtitle, title,
1548108eb18Smrg	NULL);
1558108eb18Smrg
1568108eb18Smrg    set_session_save_file_name (session_name);
1578108eb18Smrg
1588108eb18Smrg
1598108eb18Smrg    /*
1608108eb18Smrg     * For each client, set the DiscardCommand ptr to NULL.
1618108eb18Smrg     * This is so when we do a checkpoint with the new session
1628108eb18Smrg     * name, we don't wipe out the checkpoint files needed by
1638108eb18Smrg     * the previous session.  We also set the userIssuedCheckpoint
1648108eb18Smrg     * flag to false for each client in the new session.
1658108eb18Smrg     */
1668108eb18Smrg
1678108eb18Smrg    for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
1688108eb18Smrg    {
1698108eb18Smrg	ClientRec *client = (ClientRec *) cl->thing;
1708108eb18Smrg
1718108eb18Smrg	client->userIssuedCheckpoint = False;
1728108eb18Smrg
1738108eb18Smrg	if (client->discardCommand)
1748108eb18Smrg	{
1758108eb18Smrg	    XtFree (client->discardCommand);
1768108eb18Smrg	    client->discardCommand = NULL;
1778108eb18Smrg	}
1788108eb18Smrg    }
1798108eb18Smrg
1808108eb18Smrg    need_to_name_session = False;
1818108eb18Smrg}
1828108eb18Smrg
1838108eb18Smrg
1848108eb18Smrg
1858108eb18Smrg
1868108eb18Smrg#define NAME_OK     0
1878108eb18Smrg#define NAME_EMPTY  1
1888108eb18Smrg#define NAME_EXISTS 2
1898108eb18Smrg#define NAME_LOCKED 3
1908108eb18Smrg
1918108eb18Smrgstatic int
1928108eb18SmrgGetSaveName(String *nameRet)
1938108eb18Smrg{
1948108eb18Smrg    String new_name = NULL;
1958108eb18Smrg    Bool name_changed;
1968108eb18Smrg
1978108eb18Smrg    /*
1988108eb18Smrg     * Get the name of the session for the save
1998108eb18Smrg     */
2008108eb18Smrg
2018108eb18Smrg    XtVaGetValues (saveName,
2028108eb18Smrg	XtNstring, &new_name,
2038108eb18Smrg	NULL);
2048108eb18Smrg
2058108eb18Smrg    *nameRet = new_name;
2068108eb18Smrg
2078108eb18Smrg    if (!new_name || *new_name == '\0')
2088108eb18Smrg	return (NAME_EMPTY);
2098108eb18Smrg
2108108eb18Smrg    /*
2118108eb18Smrg     * See if this is a new session.  If not return.
2128108eb18Smrg     */
2138108eb18Smrg
2148108eb18Smrg    name_changed = !session_name ||
2158108eb18Smrg	(session_name && strcmp (session_name, new_name) != 0);
2168108eb18Smrg
2178108eb18Smrg    if (!need_to_name_session && !name_changed)
2188108eb18Smrg	return (NAME_OK);
2198108eb18Smrg
2208108eb18Smrg
2218108eb18Smrg    /*
2228108eb18Smrg     * Make sure the session name is unique.
2238108eb18Smrg     */
2248108eb18Smrg
2258108eb18Smrg    if (GetSessionNames (&sessionNameCount,
2268108eb18Smrg	&sessionNamesShort, NULL, &sessionsLocked))
2278108eb18Smrg    {
2288108eb18Smrg	int i, no_good = 0, locked = 0;
2298108eb18Smrg
2308108eb18Smrg	for (i = 0; i < sessionNameCount; i++)
2318108eb18Smrg	    if (strcmp (new_name, sessionNamesShort[i]) == 0)
2328108eb18Smrg	    {
2338108eb18Smrg		no_good = 1;
2348108eb18Smrg		locked = sessionsLocked[i];
2358108eb18Smrg		break;
2368108eb18Smrg	    }
2378108eb18Smrg
2388108eb18Smrg	FreeSessionNames (sessionNameCount,
2398108eb18Smrg	    sessionNamesShort, NULL, sessionsLocked);
2408108eb18Smrg
2418108eb18Smrg	if (no_good)
2428108eb18Smrg	    return (locked ? NAME_LOCKED : NAME_EXISTS);
2438108eb18Smrg    }
2448108eb18Smrg
2458108eb18Smrg    MakeCurrentSession (new_name, name_changed);
2468108eb18Smrg
2478108eb18Smrg    return (NAME_OK);
2488108eb18Smrg}
2498108eb18Smrg
2508108eb18Smrg
2518108eb18Smrgstatic void
2528108eb18SmrgGetSaveOptions(int *saveType, int *interactStyle, Bool *fast)
2538108eb18Smrg{
2548108eb18Smrg    XtPointer	ptr;
2558108eb18Smrg
2568108eb18Smrg    if (help_visible)
2578108eb18Smrg    {
2588108eb18Smrg	XtPopdown (helpPopup);
2598108eb18Smrg	help_visible = 0;
2608108eb18Smrg    }
2618108eb18Smrg
2628108eb18Smrg    ptr = XawToggleGetCurrent (saveTypeLocal /* just 1 of the group */);
2638108eb18Smrg    *saveType = *((int *) ptr);
2648108eb18Smrg
2658108eb18Smrg    ptr = XawToggleGetCurrent (interactStyleNone /* just 1 of the group */);
2668108eb18Smrg    *interactStyle = *((int *) ptr);
2678108eb18Smrg
2688108eb18Smrg    *fast = False;
2698108eb18Smrg}
2708108eb18Smrg
2718108eb18Smrg
2728108eb18Smrg
2738108eb18Smrgvoid
2748108eb18SmrgDoSave(int saveType, int interactStyle, Bool fast)
2758108eb18Smrg{
2768108eb18Smrg    ClientRec	*client;
2778108eb18Smrg    List	*cl;
2788108eb18Smrg    char	*_saveType;
2798108eb18Smrg    char	*_shutdown;
2808108eb18Smrg    char	*_interactStyle;
2818108eb18Smrg
2828108eb18Smrg    if (saveType == SmSaveLocal)
2838108eb18Smrg	_saveType = "Local";
2848108eb18Smrg    else if (saveType == SmSaveGlobal)
2858108eb18Smrg	_saveType = "Global";
2868108eb18Smrg    else
2878108eb18Smrg	_saveType = "Both";
2888108eb18Smrg
2898108eb18Smrg    if (wantShutdown)
2908108eb18Smrg	_shutdown = "True";
2918108eb18Smrg    else
2928108eb18Smrg	_shutdown = "False";
2938108eb18Smrg
2948108eb18Smrg    if (interactStyle == SmInteractStyleNone)
2958108eb18Smrg	_interactStyle = "None";
2968108eb18Smrg    else if (interactStyle == SmInteractStyleErrors)
2978108eb18Smrg	_interactStyle = "Errors";
2988108eb18Smrg    else
2998108eb18Smrg	_interactStyle = "Any";
3008108eb18Smrg
3018108eb18Smrg    SetSaveSensitivity (False);
3028108eb18Smrg
3038108eb18Smrg    saveInProgress = True;
3048108eb18Smrg
3058108eb18Smrg    shutdownCancelled = False;
3068108eb18Smrg    phase2InProgress = False;
3078108eb18Smrg
3088108eb18Smrg    if (ListCount (RunningList) == 0)
3098108eb18Smrg	FinishUpSave ();
3108108eb18Smrg
3118108eb18Smrg    for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
3128108eb18Smrg    {
3138108eb18Smrg	client = (ClientRec *) cl->thing;
3148108eb18Smrg
3158108eb18Smrg	SmsSaveYourself (client->smsConn,
3168108eb18Smrg	    saveType, wantShutdown, interactStyle, fast);
3178108eb18Smrg
3188108eb18Smrg	ListAddLast (WaitForSaveDoneList, (char *) client);
3198108eb18Smrg
3208108eb18Smrg	client->userIssuedCheckpoint = True;
3218108eb18Smrg	client->receivedDiscardCommand = False;
3228108eb18Smrg
3238108eb18Smrg	if (verbose)
3248108eb18Smrg	{
3258108eb18Smrg	    printf ("Client Id = %s, sent SAVE YOURSELF [", client->clientId);
3268108eb18Smrg	    printf ("Save Type = %s, Shutdown = %s, ", _saveType, _shutdown);
3278108eb18Smrg	    printf ("Interact Style = %s, Fast = False]\n", _interactStyle);
3288108eb18Smrg	}
3298108eb18Smrg    }
3308108eb18Smrg
3318108eb18Smrg    if (verbose)
3328108eb18Smrg    {
3338108eb18Smrg	printf ("\n");
3348108eb18Smrg	printf ("Sent SAVE YOURSELF to all clients.  Waiting for\n");
3358108eb18Smrg	printf ("SAVE YOURSELF DONE, INTERACT REQUEST, or\n");
3368108eb18Smrg	printf ("SAVE YOURSELF PHASE 2 REQUEST from each client.\n");
3378108eb18Smrg	printf ("\n");
3388108eb18Smrg    }
3398108eb18Smrg}
3408108eb18Smrg
3418108eb18Smrg
3428108eb18Smrg
3438108eb18Smrgstatic void
3448108eb18SmrgSaveOkAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
3458108eb18Smrg{
3468108eb18Smrg    XtCallCallbacks (saveOkButton, XtNcallback, NULL);
3478108eb18Smrg}
3488108eb18Smrg
3498108eb18Smrg
3508108eb18Smrg
3518108eb18Smrgstatic void
3528108eb18SmrgDelSaveWinAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
3538108eb18Smrg{
3548108eb18Smrg    XtCallCallbacks (saveCancelButton, XtNcallback, NULL);
3558108eb18Smrg}
3568108eb18Smrg
3578108eb18Smrg
3588108eb18Smrg
3598108eb18Smrgstatic void
3608108eb18SmrgDelNameInUseWinAction(Widget w, XEvent *event, String *params,
3618108eb18Smrg		      Cardinal *num_params)
3628108eb18Smrg{
3638108eb18Smrg    XtCallCallbacks (nameInUseCancelButton, XtNcallback, NULL);
3648108eb18Smrg}
3658108eb18Smrg
3668108eb18Smrg
3678108eb18Smrg
3688108eb18Smrgstatic void
3698108eb18SmrgDelBadSaveWinAction(Widget w, XEvent *event, String *params,
3708108eb18Smrg		    Cardinal *num_params)
3718108eb18Smrg{
3728108eb18Smrg    if (XtIsManaged (badSaveCancelButton))
3738108eb18Smrg	XtCallCallbacks (badSaveCancelButton, XtNcallback, NULL);
3748108eb18Smrg    else
3758108eb18Smrg	XtCallCallbacks (badSaveOkButton, XtNcallback, NULL);
3768108eb18Smrg}
3778108eb18Smrg
3788108eb18Smrg
3798108eb18Smrg
3808108eb18Smrgstatic void
3818108eb18SmrgDelSaveHelpWinAction(Widget w, XEvent *event, String *params,
3828108eb18Smrg		     Cardinal *num_params)
3838108eb18Smrg{
3848108eb18Smrg    XtCallCallbacks (helpSaveOkButton, XtNcallback, NULL);
3858108eb18Smrg}
3868108eb18Smrg
3878108eb18Smrg
3888108eb18Smrg
3898108eb18Smrgstatic void
3908108eb18SmrgSaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
3918108eb18Smrg{
3928108eb18Smrg    String name = NULL;
3938108eb18Smrg    char label[256];
3948108eb18Smrg    int	status;
3958108eb18Smrg    static int first_time = 1;
3968108eb18Smrg    int saveType;
3978108eb18Smrg    int interactStyle;
3988108eb18Smrg    Bool fast;
3998108eb18Smrg
4008108eb18Smrg    if ((status = GetSaveName (&name)) != NAME_OK)
4018108eb18Smrg    {
4028108eb18Smrg#ifdef XKB
4038108eb18Smrg	XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
4048108eb18Smrg#else
4058108eb18Smrg	XBell (XtDisplay (topLevel), 0);
4068108eb18Smrg#endif
4078108eb18Smrg
4088108eb18Smrg	if (status == NAME_EXISTS || status == NAME_LOCKED)
4098108eb18Smrg	{
4108108eb18Smrg	    name_in_use = name;
4118108eb18Smrg
4128108eb18Smrg	    if (status == NAME_LOCKED)
4138108eb18Smrg	    {
4148108eb18Smrg		name_locked = True;
4158108eb18Smrg
4168108eb18Smrg		sprintf (label, "Another session by the name '%s' is active.\nChoose another name for the session.", name);
4178108eb18Smrg
4188108eb18Smrg		XtUnmanageChild (nameInUseOverwriteButton);
4198108eb18Smrg
4208108eb18Smrg		XtVaSetValues (nameInUseCancelButton,
4218108eb18Smrg		    XtNlabel, "OK",
4228108eb18Smrg		    XtNfromHoriz, NULL,
4238108eb18Smrg		    NULL);
4248108eb18Smrg	    }
4258108eb18Smrg	    else
4268108eb18Smrg	    {
4278108eb18Smrg		name_locked = False;
4288108eb18Smrg
4298108eb18Smrg		sprintf (label, "Another session by the name '%s' already exists.\nWould you like to overwrite it?", name);
4308108eb18Smrg
4318108eb18Smrg		XtManageChild (nameInUseOverwriteButton);
4328108eb18Smrg
4338108eb18Smrg		XtVaSetValues (nameInUseCancelButton,
4348108eb18Smrg		    XtNlabel, "Cancel",
4358108eb18Smrg		    XtNfromHoriz, nameInUseOverwriteButton,
4368108eb18Smrg		    NULL);
4378108eb18Smrg	    }
4388108eb18Smrg
4398108eb18Smrg	    XtVaSetValues (nameInUseLabel,
4408108eb18Smrg		XtNlabel, label,
4418108eb18Smrg		NULL);
4428108eb18Smrg
4438108eb18Smrg	    XtPopdown (savePopup);
4448108eb18Smrg
4458108eb18Smrg	    PopupPopup (mainWindow, nameInUsePopup,
4468108eb18Smrg		True, first_time, 25, 100, "DelNameInUseWinAction()");
4478108eb18Smrg
4488108eb18Smrg	    if (first_time)
4498108eb18Smrg		first_time = 0;
4508108eb18Smrg	}
4518108eb18Smrg
4528108eb18Smrg	return;
4538108eb18Smrg    }
4548108eb18Smrg
4558108eb18Smrg    GetSaveOptions (&saveType, &interactStyle, &fast);
4568108eb18Smrg    DoSave (saveType, interactStyle, fast);
4578108eb18Smrg}
4588108eb18Smrg
4598108eb18Smrg
4608108eb18Smrg
4618108eb18Smrgvoid
4628108eb18SmrgLetClientInteract(List *cl)
4638108eb18Smrg{
4648108eb18Smrg    ClientRec *client = (ClientRec *) cl->thing;
4658108eb18Smrg
4668108eb18Smrg    SmsInteract (client->smsConn);
4678108eb18Smrg
4688108eb18Smrg    ListSearchAndFreeOne (WaitForInteractList, (char *) client);
4698108eb18Smrg
4708108eb18Smrg    if (verbose)
4718108eb18Smrg    {
4728108eb18Smrg	printf ("Client Id = %s, sent INTERACT\n", client->clientId);
4738108eb18Smrg    }
4748108eb18Smrg}
4758108eb18Smrg
4768108eb18Smrg
4778108eb18Smrg
4788108eb18Smrgvoid
4798108eb18SmrgStartPhase2(void)
4808108eb18Smrg{
4818108eb18Smrg    List *cl;
4828108eb18Smrg
4838108eb18Smrg    if (verbose)
4848108eb18Smrg    {
4858108eb18Smrg	printf ("\n");
4868108eb18Smrg	printf ("Starting PHASE 2 of SAVE YOURSELF\n");
4878108eb18Smrg	printf ("\n");
4888108eb18Smrg    }
4898108eb18Smrg
4908108eb18Smrg    for (cl = ListFirst (WaitForPhase2List); cl; cl = ListNext (cl))
4918108eb18Smrg    {
4928108eb18Smrg	ClientRec *client = (ClientRec *) cl->thing;
4938108eb18Smrg
4948108eb18Smrg	SmsSaveYourselfPhase2 (client->smsConn);
4958108eb18Smrg
4968108eb18Smrg	if (verbose)
4978108eb18Smrg	{
4988108eb18Smrg	    printf ("Client Id = %s, sent SAVE YOURSELF PHASE 2",
4998108eb18Smrg		client->clientId);
5008108eb18Smrg	}
5018108eb18Smrg    }
5028108eb18Smrg
5038108eb18Smrg    ListFreeAllButHead (WaitForPhase2List);
5048108eb18Smrg
5058108eb18Smrg    phase2InProgress = True;
5068108eb18Smrg}
5078108eb18Smrg
5088108eb18Smrg
5098108eb18Smrgvoid
5108108eb18SmrgFinishUpSave(void)
5118108eb18Smrg{
5128108eb18Smrg    ClientRec	*client;
5138108eb18Smrg    List	*cl;
5148108eb18Smrg
5158108eb18Smrg    if (verbose)
5168108eb18Smrg    {
5178108eb18Smrg	printf ("\n");
5188108eb18Smrg	printf ("All clients issued SAVE YOURSELF DONE\n");
5198108eb18Smrg	printf ("\n");
5208108eb18Smrg    }
5218108eb18Smrg
5228108eb18Smrg    saveInProgress = False;
5238108eb18Smrg    phase2InProgress = False;
5248108eb18Smrg
5258108eb18Smrg    /*
5268108eb18Smrg     * Now execute discard commands
5278108eb18Smrg     */
5288108eb18Smrg
5298108eb18Smrg    for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
5308108eb18Smrg    {
5318108eb18Smrg	client = (ClientRec *) cl->thing;
5328108eb18Smrg
5338108eb18Smrg	if (!client->receivedDiscardCommand)
5348108eb18Smrg	    continue;
5358108eb18Smrg
5368108eb18Smrg	if (client->discardCommand)
5378108eb18Smrg	{
5388108eb18Smrg	    execute_system_command (client->discardCommand);
5398108eb18Smrg	    XtFree (client->discardCommand);
5408108eb18Smrg	    client->discardCommand = NULL;
5418108eb18Smrg	}
5428108eb18Smrg
5438108eb18Smrg	if (client->saveDiscardCommand)
5448108eb18Smrg	{
5458108eb18Smrg	    client->discardCommand = client->saveDiscardCommand;
5468108eb18Smrg	    client->saveDiscardCommand = NULL;
5478108eb18Smrg	}
5488108eb18Smrg    }
5498108eb18Smrg
5508108eb18Smrg
5518108eb18Smrg    /*
5528108eb18Smrg     * Write the save file
5538108eb18Smrg     */
5548108eb18Smrg
5558108eb18Smrg    WriteSave (sm_id);
5568108eb18Smrg
5578108eb18Smrg
5588108eb18Smrg    if (wantShutdown && shutdownCancelled)
5598108eb18Smrg    {
5608108eb18Smrg	shutdownCancelled = False;
5618108eb18Smrg    }
5628108eb18Smrg    else if (wantShutdown)
5638108eb18Smrg    {
5648108eb18Smrg	if (ListCount (RunningList) == 0)
5658108eb18Smrg	    EndSession (0);
5668108eb18Smrg
5678108eb18Smrg	shutdownInProgress = True;
5688108eb18Smrg
5698108eb18Smrg	for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
5708108eb18Smrg	{
5718108eb18Smrg	    client = (ClientRec *) cl->thing;
5728108eb18Smrg
5738108eb18Smrg	    SmsDie (client->smsConn);
5748108eb18Smrg
5758108eb18Smrg	    if (verbose)
5768108eb18Smrg	    {
5778108eb18Smrg		printf ("Client Id = %s, sent DIE\n", client->clientId);
5788108eb18Smrg	    }
5798108eb18Smrg	}
5808108eb18Smrg    }
5818108eb18Smrg    else
5828108eb18Smrg    {
5838108eb18Smrg	for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
5848108eb18Smrg	{
5858108eb18Smrg	    client = (ClientRec *) cl->thing;
5868108eb18Smrg
5878108eb18Smrg	    SmsSaveComplete (client->smsConn);
5888108eb18Smrg
5898108eb18Smrg	    if (verbose)
5908108eb18Smrg	    {
5918108eb18Smrg		printf ("Client Id = %s, sent SAVE COMPLETE\n",
5928108eb18Smrg		    client->clientId);
5938108eb18Smrg	    }
5948108eb18Smrg	}
5958108eb18Smrg    }
5968108eb18Smrg
5978108eb18Smrg    if (!shutdownInProgress)
5988108eb18Smrg    {
5998108eb18Smrg	XtPopdown (savePopup);
6008108eb18Smrg	SetAllSensitive (1);
6018108eb18Smrg	if (checkpoint_from_signal)
6028108eb18Smrg	    checkpoint_from_signal = False;
6038108eb18Smrg    }
6048108eb18Smrg}
6058108eb18Smrg
6068108eb18Smrg
6078108eb18Smrg
6088108eb18Smrgstatic void
6098108eb18SmrgSaveCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
6108108eb18Smrg{
6118108eb18Smrg    XtPopdown (savePopup);
6128108eb18Smrg
6138108eb18Smrg    if (help_visible)
6148108eb18Smrg    {
6158108eb18Smrg	XtPopdown (helpPopup);
6168108eb18Smrg	help_visible = 0;
6178108eb18Smrg    }
6188108eb18Smrg
6198108eb18Smrg    SetAllSensitive (1);
6208108eb18Smrg}
6218108eb18Smrg
6228108eb18Smrg
6238108eb18Smrg
6248108eb18Smrg/*
6258108eb18Smrg * Add toggle button
6268108eb18Smrg */
6278108eb18Smrg
6288108eb18Smrgstatic Widget
6298108eb18SmrgAddToggle(char *widgetName, Widget parent, int state, Widget radioGroup,
6308108eb18Smrg	  XtPointer radioData,  Widget fromHoriz, Widget fromVert)
6318108eb18Smrg{
6328108eb18Smrg    Widget toggle;
6338108eb18Smrg
6348108eb18Smrg    toggle = XtVaCreateManagedWidget (
6358108eb18Smrg	widgetName, toggleWidgetClass, parent,
6368108eb18Smrg        XtNstate, state,
6378108eb18Smrg        XtNradioGroup, radioGroup,
6388108eb18Smrg        XtNradioData, radioData,
6398108eb18Smrg        XtNfromHoriz, fromHoriz,
6408108eb18Smrg        XtNfromVert, fromVert,
6418108eb18Smrg        NULL);
6428108eb18Smrg
6438108eb18Smrg    return (toggle);
6448108eb18Smrg}
6458108eb18Smrg
6468108eb18Smrg
6478108eb18Smrg
6488108eb18Smrgvoid
6498108eb18SmrgSetSaveSensitivity(Bool on)
6508108eb18Smrg{
6518108eb18Smrg    XtSetSensitive (savePopup, on);
6528108eb18Smrg
6538108eb18Smrg#if 0
6548108eb18Smrg    /*
6558108eb18Smrg     * When we turn of sensitivity in the save dialog, we want to keep
6568108eb18Smrg     * the cancel button sensitive (so the user can cancel in case of
6578108eb18Smrg     * a problem).  Unfortunately, we can not turn off the sensitivity on
6588108eb18Smrg     * the save popup, and then just turn on sensitivity for the cancel
6598108eb18Smrg     * button.  We must do each widget individually.
6608108eb18Smrg     */
6618108eb18Smrg
6628108eb18Smrg    XtSetSensitive (saveTypeLabel, on);
6638108eb18Smrg    XtSetSensitive (saveTypeGlobal, on);
6648108eb18Smrg    XtSetSensitive (saveTypeLocal, on);
6658108eb18Smrg    XtSetSensitive (saveTypeBoth, on);
6668108eb18Smrg    XtSetSensitive (interactStyleLabel, on);
6678108eb18Smrg    XtSetSensitive (interactStyleNone, on);
6688108eb18Smrg    XtSetSensitive (interactStyleErrors, on);
6698108eb18Smrg    XtSetSensitive (interactStyleAny, on);
6708108eb18Smrg    XtSetSensitive (saveOkButton, on);
6718108eb18Smrg#endif
6728108eb18Smrg}
6738108eb18Smrg
6748108eb18Smrg
6758108eb18Smrg
6768108eb18Smrgvoid
6778108eb18SmrgSavePopupStructureNotifyXtHandler(Widget w, XtPointer closure, XEvent *event,
6788108eb18Smrg				  Boolean *continue_to_dispatch)
6798108eb18Smrg{
6808108eb18Smrg    if (event->type == MapNotify)
6818108eb18Smrg    {
6828108eb18Smrg	/*
6838108eb18Smrg	 * Now that the Save Dialog is back up, we can do the save.
6848108eb18Smrg	 */
6858108eb18Smrg
6868108eb18Smrg	int saveType;
6878108eb18Smrg	int interactStyle;
6888108eb18Smrg	Bool fast;
6898108eb18Smrg
6908108eb18Smrg	if (name_locked)
6918108eb18Smrg	{
6928108eb18Smrg	    /* Force shutdown */
6938108eb18Smrg	}
6948108eb18Smrg
6958108eb18Smrg	DeleteSession (name_in_use);
6968108eb18Smrg
6978108eb18Smrg	MakeCurrentSession (name_in_use, True);
6988108eb18Smrg
6998108eb18Smrg	name_in_use = NULL;
7008108eb18Smrg
7018108eb18Smrg	GetSaveOptions (&saveType, &interactStyle, &fast);
7028108eb18Smrg	DoSave (saveType, interactStyle, fast);
7038108eb18Smrg
7048108eb18Smrg	XtRemoveEventHandler (savePopup, StructureNotifyMask, False,
7058108eb18Smrg	    SavePopupStructureNotifyXtHandler, NULL);
7068108eb18Smrg    }
7078108eb18Smrg}
7088108eb18Smrg
7098108eb18Smrg
7108108eb18Smrg
7118108eb18Smrgstatic void
7128108eb18SmrgNameInUseOverwriteXtProc(Widget w, XtPointer client_data, XtPointer callData)
7138108eb18Smrg{
7148108eb18Smrg    if (name_locked)
7158108eb18Smrg    {
7168108eb18Smrg	/* force shutdown not implemented yet */
7178108eb18Smrg
7188108eb18Smrg	return;
7198108eb18Smrg    }
7208108eb18Smrg
7218108eb18Smrg    XtPopdown (nameInUsePopup);
7228108eb18Smrg
7238108eb18Smrg    /*
7248108eb18Smrg     * We want to popup the Save dialog again.  In order to avoid a race
7258108eb18Smrg     * condition with the BadSave handler trying to pop down the Save Dialog,
7268108eb18Smrg     * we wait for the MapNotify on the Save dialog, and then do the save.
7278108eb18Smrg     */
7288108eb18Smrg
7298108eb18Smrg    XtAddEventHandler (savePopup, StructureNotifyMask, False,
7308108eb18Smrg	SavePopupStructureNotifyXtHandler, NULL);
7318108eb18Smrg
7328108eb18Smrg    XtPopup (savePopup, XtGrabNone);
7338108eb18Smrg}
7348108eb18Smrg
7358108eb18Smrg
7368108eb18Smrg
7378108eb18Smrgstatic void
7388108eb18SmrgNameInUseCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
7398108eb18Smrg{
7408108eb18Smrg    XtPopdown (nameInUsePopup);
7418108eb18Smrg    XtPopup (savePopup, XtGrabNone);
7428108eb18Smrg
7438108eb18Smrg    name_in_use = NULL;
7448108eb18Smrg}
7458108eb18Smrg
7468108eb18Smrg
7478108eb18Smrg
7488108eb18Smrgstatic void
7498108eb18SmrgBadSaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
7508108eb18Smrg{
7518108eb18Smrg    ListFreeAllButHead (FailedSaveList);
7528108eb18Smrg    XtPopdown (badSavePopup);
7538108eb18Smrg    FinishUpSave ();
7548108eb18Smrg}
7558108eb18Smrg
7568108eb18Smrg
7578108eb18Smrg
7588108eb18Smrgstatic void
7598108eb18SmrgBadSaveCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
7608108eb18Smrg{
7618108eb18Smrg    ListFreeAllButHead (FailedSaveList);
7628108eb18Smrg    XtPopdown (badSavePopup);
7638108eb18Smrg
7648108eb18Smrg    if (wantShutdown)
7658108eb18Smrg    {
7668108eb18Smrg	List *cl;
7678108eb18Smrg
7688108eb18Smrg	shutdownCancelled = True;
7698108eb18Smrg
7708108eb18Smrg	for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
7718108eb18Smrg	{
7728108eb18Smrg	    ClientRec *client = (ClientRec *) cl->thing;
7738108eb18Smrg
7748108eb18Smrg	    SmsShutdownCancelled (client->smsConn);
7758108eb18Smrg
7768108eb18Smrg	    if (verbose)
7778108eb18Smrg	    {
7788108eb18Smrg		printf ("Client Id = %s, sent SHUTDOWN CANCELLED\n",
7798108eb18Smrg			client->clientId);
7808108eb18Smrg	    }
7818108eb18Smrg	}
7828108eb18Smrg    }
7838108eb18Smrg
7848108eb18Smrg    FinishUpSave ();
7858108eb18Smrg}
7868108eb18Smrg
7878108eb18Smrg
7888108eb18Smrg
7898108eb18Smrgstatic void
7908108eb18SmrgBadSaveListXtProc(Widget w, XtPointer client_data, XtPointer callData)
7918108eb18Smrg{
7928108eb18Smrg
7938108eb18Smrg}
7948108eb18Smrg
7958108eb18Smrg
7968108eb18Smrg
7978108eb18Smrgstatic void
7988108eb18SmrgHelpSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
7998108eb18Smrg{
8008108eb18Smrg    static int first_time = 1;
8018108eb18Smrg
8028108eb18Smrg    if (help_visible)
8038108eb18Smrg    {
8048108eb18Smrg	/* Make sure it is visible */
8058108eb18Smrg
8068108eb18Smrg	XMapRaised (XtDisplay (topLevel), XtWindow (helpPopup));
8078108eb18Smrg    }
8088108eb18Smrg    else
8098108eb18Smrg    {
8108108eb18Smrg	PopupPopup (savePopup, helpPopup,
8118108eb18Smrg	    True, first_time, 50, 50, "DelSaveHelpWinAction()");
8128108eb18Smrg
8138108eb18Smrg	help_visible = 1;
8148108eb18Smrg
8158108eb18Smrg	if (first_time)
8168108eb18Smrg	    first_time = 0;
8178108eb18Smrg    }
8188108eb18Smrg}
8198108eb18Smrg
8208108eb18Smrg
8218108eb18Smrg
8228108eb18Smrgstatic void
8238108eb18SmrgHelpSaveOkXtProc(Widget w, XtPointer client_data, XtPointer callData)
8248108eb18Smrg{
8258108eb18Smrg    XtPopdown (helpPopup);
8268108eb18Smrg    help_visible = 0;
8278108eb18Smrg}
8288108eb18Smrg
8298108eb18Smrg
8308108eb18Smrg
8318108eb18Smrgvoid
8328108eb18Smrgcreate_save_popup(void)
8338108eb18Smrg
8348108eb18Smrg{
8358108eb18Smrg    XtTranslations translations;
8368108eb18Smrg
8378108eb18Smrg    static XtActionsRec actions[] = {
8388108eb18Smrg        {"SaveOkAction", SaveOkAction},
8398108eb18Smrg        {"DelSaveWinAction", DelSaveWinAction},
8408108eb18Smrg	{"DelNameInUseWinAction", DelNameInUseWinAction},
8418108eb18Smrg	{"DelBadSaveWinAction", DelBadSaveWinAction},
8428108eb18Smrg	{"DelSaveHelpWinAction", DelSaveHelpWinAction}
8438108eb18Smrg    };
8448108eb18Smrg
8458108eb18Smrg
8468108eb18Smrg    /*
8478108eb18Smrg     * Pop up for Save Yourself button.
8488108eb18Smrg     */
8498108eb18Smrg
8508108eb18Smrg    savePopup = XtVaCreatePopupShell (
8518108eb18Smrg	"savePopup", transientShellWidgetClass, topLevel,
8528108eb18Smrg	XtNallowShellResize, True,
8538108eb18Smrg	NULL);
8548108eb18Smrg
8558108eb18Smrg    saveForm = XtCreateManagedWidget (
8568108eb18Smrg	"saveForm", formWidgetClass, savePopup, NULL, 0);
8578108eb18Smrg
8588108eb18Smrg    saveMessageLabel = XtVaCreateManagedWidget (
8598108eb18Smrg	"saveMessageLabel", labelWidgetClass, saveForm,
8608108eb18Smrg        XtNfromHoriz, NULL,
8618108eb18Smrg        XtNfromVert, NULL,
8628108eb18Smrg        XtNborderWidth, 0,
8638108eb18Smrg	NULL);
8648108eb18Smrg
8658108eb18Smrg    saveName = XtVaCreateManagedWidget (
8668108eb18Smrg	"saveName", asciiTextWidgetClass, saveForm,
8678108eb18Smrg        XtNfromVert, NULL,
8688108eb18Smrg	XtNeditType, XawtextEdit,
8698108eb18Smrg	XtNresizable, True,
8708108eb18Smrg	XtNresize, XawtextResizeWidth,
8718108eb18Smrg	NULL);
8728108eb18Smrg
8738108eb18Smrg    saveTypeLabel = XtVaCreateManagedWidget (
8748108eb18Smrg	"saveTypeLabel", labelWidgetClass, saveForm,
8758108eb18Smrg        XtNfromHoriz, NULL,
8768108eb18Smrg        XtNfromVert, saveMessageLabel,
8778108eb18Smrg        XtNborderWidth, 0,
8788108eb18Smrg        XtNvertDistance, 20,
8798108eb18Smrg	NULL);
8808108eb18Smrg
8818108eb18Smrg    saveTypeLocal = AddToggle (
8828108eb18Smrg	"saveTypeLocal", 			/* widgetName */
8838108eb18Smrg	saveForm,				/* parent */
8848108eb18Smrg	0,					/* state */
8858108eb18Smrg        NULL,					/* radioGroup */
8868108eb18Smrg        (XtPointer) &saveTypeData[0],		/* radioData */
8878108eb18Smrg        saveTypeLabel,				/* fromHoriz */
8888108eb18Smrg        saveMessageLabel			/* fromVert */
8898108eb18Smrg    );
8908108eb18Smrg
8918108eb18Smrg    saveTypeGlobal = AddToggle (
8928108eb18Smrg	"saveTypeGlobal", 			/* widgetName */
8938108eb18Smrg	saveForm,				/* parent */
8948108eb18Smrg	0,					/* state */
8958108eb18Smrg        saveTypeLocal,				/* radioGroup */
8968108eb18Smrg        (XtPointer) &saveTypeData[1],		/* radioData */
8978108eb18Smrg        saveTypeLocal,				/* fromHoriz */
8988108eb18Smrg        saveMessageLabel			/* fromVert */
8998108eb18Smrg    );
9008108eb18Smrg
9018108eb18Smrg    saveTypeBoth = AddToggle (
9028108eb18Smrg	"saveTypeBoth", 			/* widgetName */
9038108eb18Smrg	saveForm,				/* parent */
9048108eb18Smrg	1,					/* state */
9058108eb18Smrg        saveTypeLocal,				/* radioGroup */
9068108eb18Smrg        (XtPointer) &saveTypeData[2],		/* radioData */
9078108eb18Smrg        saveTypeGlobal,				/* fromHoriz */
9088108eb18Smrg        saveMessageLabel			/* fromVert */
9098108eb18Smrg    );
9108108eb18Smrg
9118108eb18Smrg
9128108eb18Smrg    XtVaSetValues (saveName, XtNfromHoriz, saveTypeLabel, NULL);
9138108eb18Smrg    XtVaSetValues (saveTypeLocal, XtNvertDistance, 20, NULL);
9148108eb18Smrg    XtVaSetValues (saveTypeGlobal, XtNvertDistance, 20, NULL);
9158108eb18Smrg    XtVaSetValues (saveTypeBoth, XtNvertDistance, 20, NULL);
9168108eb18Smrg
9178108eb18Smrg    interactStyleLabel = XtVaCreateManagedWidget (
9188108eb18Smrg	"interactStyleLabel", labelWidgetClass, saveForm,
9198108eb18Smrg        XtNfromHoriz, NULL,
9208108eb18Smrg        XtNfromVert, saveTypeLabel,
9218108eb18Smrg        XtNborderWidth, 0,
9228108eb18Smrg	NULL);
9238108eb18Smrg
9248108eb18Smrg    interactStyleNone = AddToggle (
9258108eb18Smrg	"interactStyleNone", 			/* widgetName */
9268108eb18Smrg	saveForm,				/* parent */
9278108eb18Smrg	0,					/* state */
9288108eb18Smrg        NULL,					/* radioGroup */
9298108eb18Smrg        (XtPointer) &interactStyleData[0],	/* radioData */
9308108eb18Smrg        saveTypeLabel,				/* fromHoriz */
9318108eb18Smrg        saveTypeLabel				/* fromVert */
9328108eb18Smrg    );
9338108eb18Smrg
9348108eb18Smrg    interactStyleErrors = AddToggle (
9358108eb18Smrg	"interactStyleErrors", 			/* widgetName */
9368108eb18Smrg	saveForm,				/* parent */
9378108eb18Smrg	0,					/* state */
9388108eb18Smrg        interactStyleNone,			/* radioGroup */
9398108eb18Smrg        (XtPointer) &interactStyleData[1],	/* radioData */
9408108eb18Smrg        interactStyleNone,			/* fromHoriz */
9418108eb18Smrg        saveTypeLabel				/* fromVert */
9428108eb18Smrg    );
9438108eb18Smrg
9448108eb18Smrg    interactStyleAny = AddToggle (
9458108eb18Smrg	"interactStyleAny", 			/* widgetName */
9468108eb18Smrg	saveForm,				/* parent */
9478108eb18Smrg	1,					/* state */
9488108eb18Smrg        interactStyleNone,			/* radioGroup */
9498108eb18Smrg        (XtPointer) &interactStyleData[2],	/* radioData */
9508108eb18Smrg        interactStyleErrors,			/* fromHoriz */
9518108eb18Smrg        saveTypeLabel				/* fromVert */
9528108eb18Smrg    );
9538108eb18Smrg
9548108eb18Smrg
9558108eb18Smrg    saveOkButton = XtVaCreateManagedWidget (
9568108eb18Smrg	"saveOkButton",	commandWidgetClass, saveForm,
9578108eb18Smrg        XtNfromHoriz, NULL,
9588108eb18Smrg        XtNfromVert, interactStyleLabel,
9598108eb18Smrg        XtNvertDistance, 20,
9608108eb18Smrg	XtNresizable, True,
9618108eb18Smrg        NULL);
9628108eb18Smrg
9638108eb18Smrg    XtAddCallback (saveOkButton, XtNcallback, SaveOkXtProc, 0);
9648108eb18Smrg
9658108eb18Smrg
9668108eb18Smrg    helpSaveButton = XtVaCreateManagedWidget (
9678108eb18Smrg	"helpSaveButton", commandWidgetClass, saveForm,
9688108eb18Smrg        XtNfromHoriz, saveOkButton,
9698108eb18Smrg        XtNfromVert, interactStyleLabel,
9708108eb18Smrg        XtNvertDistance, 20,
9718108eb18Smrg	NULL);
9728108eb18Smrg
9738108eb18Smrg    XtAddCallback (helpSaveButton, XtNcallback, HelpSaveXtProc, 0);
9748108eb18Smrg
9758108eb18Smrg
9768108eb18Smrg    saveCancelButton = XtVaCreateManagedWidget (
9778108eb18Smrg	"saveCancelButton", commandWidgetClass, saveForm,
9788108eb18Smrg        XtNfromHoriz, helpSaveButton,
9798108eb18Smrg        XtNfromVert, interactStyleLabel,
9808108eb18Smrg        XtNvertDistance, 20,
9818108eb18Smrg        NULL);
9828108eb18Smrg
9838108eb18Smrg    XtAddCallback (saveCancelButton, XtNcallback, SaveCancelXtProc, 0);
9848108eb18Smrg
9858108eb18Smrg    XtSetKeyboardFocus (saveForm, saveName);
9868108eb18Smrg
9878108eb18Smrg    XtAppAddActions (appContext, actions, XtNumber (actions));
9888108eb18Smrg
9898108eb18Smrg    translations = XtParseTranslationTable
9908108eb18Smrg	("<Key>Return: SaveOkAction()\n");
9918108eb18Smrg    XtOverrideTranslations(saveName, translations);
9928108eb18Smrg
9938108eb18Smrg    XtInstallAllAccelerators (saveForm, saveForm);
9948108eb18Smrg
9958108eb18Smrg
9968108eb18Smrg    /*
9978108eb18Smrg     * Pop up when user tries to save the session under an
9988108eb18Smrg     * already used name.
9998108eb18Smrg     */
10008108eb18Smrg
10018108eb18Smrg    nameInUsePopup = XtVaCreatePopupShell (
10028108eb18Smrg	"nameInUsePopup", transientShellWidgetClass, topLevel,
10038108eb18Smrg	XtNallowShellResize, True,
10048108eb18Smrg	NULL);
10058108eb18Smrg
10068108eb18Smrg
10078108eb18Smrg    nameInUseForm = XtVaCreateManagedWidget (
10088108eb18Smrg	"nameInUseForm", formWidgetClass, nameInUsePopup,
10098108eb18Smrg	NULL);
10108108eb18Smrg
10118108eb18Smrg    nameInUseLabel = XtVaCreateManagedWidget (
10128108eb18Smrg	"nameInUseLabel", labelWidgetClass, nameInUseForm,
10138108eb18Smrg	XtNresizable, True,
10148108eb18Smrg        XtNfromHoriz, NULL,
10158108eb18Smrg        XtNfromVert, NULL,
10168108eb18Smrg        XtNborderWidth, 0,
10178108eb18Smrg	XtNtop, XawChainTop,
10188108eb18Smrg	XtNbottom, XawChainTop,
10198108eb18Smrg	NULL);
10208108eb18Smrg
10218108eb18Smrg    nameInUseOverwriteButton = XtVaCreateManagedWidget (
10228108eb18Smrg	"nameInUseOverwriteButton", commandWidgetClass, nameInUseForm,
10238108eb18Smrg        XtNfromHoriz, NULL,
10248108eb18Smrg        XtNfromVert, nameInUseLabel,
10258108eb18Smrg	XtNtop, XawChainBottom,
10268108eb18Smrg	XtNbottom, XawChainBottom,
10278108eb18Smrg        NULL);
10288108eb18Smrg
10298108eb18Smrg    XtAddCallback (nameInUseOverwriteButton, XtNcallback,
10308108eb18Smrg	NameInUseOverwriteXtProc, 0);
10318108eb18Smrg
10328108eb18Smrg
10338108eb18Smrg    nameInUseCancelButton = XtVaCreateManagedWidget (
10348108eb18Smrg	"nameInUseCancelButton", commandWidgetClass, nameInUseForm,
10358108eb18Smrg	XtNresizable, True,
10368108eb18Smrg        XtNfromHoriz, nameInUseOverwriteButton,
10378108eb18Smrg        XtNfromVert, nameInUseLabel,
10388108eb18Smrg	XtNtop, XawChainBottom,
10398108eb18Smrg	XtNbottom, XawChainBottom,
10408108eb18Smrg        NULL);
10418108eb18Smrg
10428108eb18Smrg    XtAddCallback (nameInUseCancelButton, XtNcallback,
10438108eb18Smrg	NameInUseCancelXtProc, 0);
10448108eb18Smrg
10458108eb18Smrg
10468108eb18Smrg    /*
10478108eb18Smrg     * Pop up for help.
10488108eb18Smrg     */
10498108eb18Smrg
10508108eb18Smrg    helpPopup = XtVaCreatePopupShell (
10518108eb18Smrg	"helpPopup", transientShellWidgetClass, topLevel,
10528108eb18Smrg	NULL);
10538108eb18Smrg
10548108eb18Smrg
10558108eb18Smrg    helpForm = XtVaCreateManagedWidget (
10568108eb18Smrg	"helpForm", formWidgetClass, helpPopup,
10578108eb18Smrg	NULL);
10588108eb18Smrg
10598108eb18Smrg    helpSaveText = XtVaCreateManagedWidget (
10608108eb18Smrg	"helpSaveText", labelWidgetClass, helpForm,
10618108eb18Smrg        XtNfromHoriz, NULL,
10628108eb18Smrg        XtNfromVert, NULL,
10638108eb18Smrg	XtNtop, XawChainTop,
10648108eb18Smrg	XtNbottom, XawChainTop,
10658108eb18Smrg	NULL);
10668108eb18Smrg
10678108eb18Smrg    helpSaveOkButton = XtVaCreateManagedWidget (
10688108eb18Smrg	"helpSaveOkButton", commandWidgetClass, helpForm,
10698108eb18Smrg        XtNfromHoriz, NULL,
10708108eb18Smrg        XtNfromVert, helpSaveText,
10718108eb18Smrg	XtNtop, XawChainBottom,
10728108eb18Smrg	XtNbottom, XawChainBottom,
10738108eb18Smrg        XtNvertDistance, 20,
10748108eb18Smrg        NULL);
10758108eb18Smrg
10768108eb18Smrg    XtAddCallback (helpSaveOkButton, XtNcallback,
10778108eb18Smrg	HelpSaveOkXtProc, 0);
10788108eb18Smrg
10798108eb18Smrg
10808108eb18Smrg    /*
10818108eb18Smrg     * Pop up when not all clients returned SaveSuccess
10828108eb18Smrg     */
10838108eb18Smrg
10848108eb18Smrg    badSavePopup = XtVaCreatePopupShell (
10858108eb18Smrg	"badSavePopup", transientShellWidgetClass, topLevel,
10868108eb18Smrg	XtNallowShellResize, True,
10878108eb18Smrg	NULL);
10888108eb18Smrg
10898108eb18Smrg
10908108eb18Smrg    badSaveForm = XtVaCreateManagedWidget (
10918108eb18Smrg	"badSaveForm", formWidgetClass, badSavePopup,
10928108eb18Smrg	NULL);
10938108eb18Smrg
10948108eb18Smrg    badSaveLabel = XtVaCreateManagedWidget (
10958108eb18Smrg	"badSaveLabel", labelWidgetClass, badSaveForm,
10968108eb18Smrg        XtNfromHoriz, NULL,
10978108eb18Smrg        XtNfromVert, NULL,
10988108eb18Smrg        XtNborderWidth, 0,
10998108eb18Smrg	XtNtop, XawChainTop,
11008108eb18Smrg	XtNbottom, XawChainTop,
11018108eb18Smrg	NULL);
11028108eb18Smrg
11038108eb18Smrg    badSaveListWidget = XtVaCreateManagedWidget (
11048108eb18Smrg	"badSaveListWidget", listWidgetClass, badSaveForm,
11058108eb18Smrg	XtNresizable, True,
11068108eb18Smrg        XtNdefaultColumns, 1,
11078108eb18Smrg	XtNforceColumns, True,
11088108eb18Smrg        XtNfromHoriz, NULL,
11098108eb18Smrg        XtNfromVert, badSaveLabel,
11108108eb18Smrg	XtNtop, XawChainTop,
11118108eb18Smrg	XtNbottom, XawChainBottom,
11128108eb18Smrg	NULL);
11138108eb18Smrg
11148108eb18Smrg    XtAddCallback (badSaveListWidget, XtNcallback, BadSaveListXtProc, 0);
11158108eb18Smrg
11168108eb18Smrg    badSaveOkButton = XtVaCreateManagedWidget (
11178108eb18Smrg	"badSaveOkButton", commandWidgetClass, badSaveForm,
11188108eb18Smrg        XtNfromHoriz, NULL,
11198108eb18Smrg        XtNfromVert, badSaveListWidget,
11208108eb18Smrg	XtNtop, XawChainBottom,
11218108eb18Smrg	XtNbottom, XawChainBottom,
11228108eb18Smrg        NULL);
11238108eb18Smrg
11248108eb18Smrg    XtAddCallback (badSaveOkButton, XtNcallback, BadSaveOkXtProc, 0);
11258108eb18Smrg
11268108eb18Smrg
11278108eb18Smrg    badSaveCancelButton = XtVaCreateManagedWidget (
11288108eb18Smrg	"badSaveCancelButton", commandWidgetClass, badSaveForm,
11298108eb18Smrg        XtNfromHoriz, badSaveOkButton,
11308108eb18Smrg        XtNfromVert, badSaveListWidget,
11318108eb18Smrg	XtNtop, XawChainBottom,
11328108eb18Smrg	XtNbottom, XawChainBottom,
11338108eb18Smrg        NULL);
11348108eb18Smrg
11358108eb18Smrg    XtAddCallback (badSaveCancelButton, XtNcallback, BadSaveCancelXtProc, 0);
11368108eb18Smrg
11378108eb18Smrg    XtInstallAllAccelerators (badSaveForm, badSaveForm);
11388108eb18Smrg}
11398108eb18Smrg
11408108eb18Smrg
11418108eb18Smrg
11428108eb18Smrgvoid
11438108eb18SmrgPopupSaveDialog(void)
11448108eb18Smrg
11458108eb18Smrg{
11468108eb18Smrg    static int first_time = 1;
11478108eb18Smrg
11488108eb18Smrg    XtSetSensitive (mainWindow, 0);
11498108eb18Smrg    XtSetSensitive (clientInfoPopup, 0);
11508108eb18Smrg    XtSetSensitive (clientPropPopup, 0);
11518108eb18Smrg
11528108eb18Smrg    XawToggleSetCurrent (saveTypeBoth,
11538108eb18Smrg	(XtPointer) &saveTypeData[2]);
11548108eb18Smrg    XawToggleSetCurrent (interactStyleAny,
11558108eb18Smrg	(XtPointer) &interactStyleData[2]);
11568108eb18Smrg
11578108eb18Smrg    XtVaSetValues (savePopup,
11588108eb18Smrg	XtNtitle, wantShutdown ? "Shutdown" : "Checkpoint",
11598108eb18Smrg	NULL);
11608108eb18Smrg
11618108eb18Smrg    XtVaSetValues (saveName,
11628108eb18Smrg	XtNstring, need_to_name_session ? "" : session_name,
11638108eb18Smrg	NULL);
11648108eb18Smrg
11658108eb18Smrg    XtVaSetValues (saveOkButton,
11668108eb18Smrg	XtNlabel, wantShutdown ? "Shutdown" : "Checkpoint",
11678108eb18Smrg	NULL);
11688108eb18Smrg
11698108eb18Smrg    PopupPopup (mainWindow, savePopup,
11708108eb18Smrg	True, first_time, 25, 100, "DelSaveWinAction()");
11718108eb18Smrg
11728108eb18Smrg    if (first_time)
11738108eb18Smrg	first_time = 0;
11748108eb18Smrg}
11758108eb18Smrg
11768108eb18Smrg
11778108eb18Smrg
11788108eb18Smrg
11798108eb18Smrgvoid
11808108eb18SmrgCheckPointXtProc(Widget w, XtPointer client_data, XtPointer callData)
11818108eb18Smrg{
11828108eb18Smrg    wantShutdown = False;
11838108eb18Smrg    PopupSaveDialog ();
11848108eb18Smrg}
11858108eb18Smrg
11868108eb18Smrg
11878108eb18Smrg
11888108eb18Smrg
11898108eb18Smrgvoid
11908108eb18SmrgShutdownSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
11918108eb18Smrg{
11928108eb18Smrg    wantShutdown = True;
11938108eb18Smrg    PopupSaveDialog ();
11948108eb18Smrg}
11958108eb18Smrg
11968108eb18Smrg
11978108eb18Smrg
11988108eb18Smrgvoid
11998108eb18SmrgPopupBadSave(void)
12008108eb18Smrg
12018108eb18Smrg{
12028108eb18Smrg    ClientRec *client;
12038108eb18Smrg    char *progName, *hostname, *tmp1, *tmp2;
12048108eb18Smrg    String clientInfo;
12058108eb18Smrg    int maxlen1, maxlen2;
12068108eb18Smrg    char extraBuf1[80], extraBuf2[80];
12078108eb18Smrg    char *restart_service_prop;
12088108eb18Smrg    List *cl, *pl;
12098108eb18Smrg    int i, k;
12108108eb18Smrg    static int first_time = 1;
12118108eb18Smrg
12128108eb18Smrg    if (failedNames)
12138108eb18Smrg    {
12148108eb18Smrg	/*
12158108eb18Smrg	 * Free the previous list of names.  Xaw doesn't make a copy of
12168108eb18Smrg	 * our list, so we need to keep it around.
12178108eb18Smrg	 */
12188108eb18Smrg
12198108eb18Smrg	for (i = 0; i < numFailedNames; i++)
12208108eb18Smrg	    XtFree (failedNames[i]);
12218108eb18Smrg
12228108eb18Smrg	XtFree ((char *) failedNames);
12238108eb18Smrg
12248108eb18Smrg	failedNames = NULL;
12258108eb18Smrg    }
12268108eb18Smrg
12278108eb18Smrg    maxlen1 = maxlen2 = 0;
12288108eb18Smrg    numFailedNames = 0;
12298108eb18Smrg
12308108eb18Smrg    for (cl = ListFirst (FailedSaveList); cl; cl = ListNext (cl))
12318108eb18Smrg    {
12328108eb18Smrg	client = (ClientRec *) cl->thing;
12338108eb18Smrg
12348108eb18Smrg	progName = NULL;
12358108eb18Smrg	restart_service_prop = NULL;
12368108eb18Smrg
12378108eb18Smrg	for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
12388108eb18Smrg	{
12398108eb18Smrg	    Prop *pprop = (Prop *) pl->thing;
12408108eb18Smrg	    List *vl = ListFirst (pprop->values);
12418108eb18Smrg	    PropValue *pval = (PropValue *) vl->thing;
12428108eb18Smrg
12438108eb18Smrg	    if (strcmp (pprop->name, SmProgram) == 0)
12448108eb18Smrg	    {
12458108eb18Smrg		progName = GetProgramName ((char *) pval->value);
12468108eb18Smrg
12478108eb18Smrg		if ((int) strlen (progName) > maxlen1)
12488108eb18Smrg		    maxlen1 = strlen (progName);
12498108eb18Smrg	    }
12508108eb18Smrg	    else if (strcmp (pprop->name, "_XC_RestartService") == 0)
12518108eb18Smrg	    {
12528108eb18Smrg		restart_service_prop = (char *) pval->value;
12538108eb18Smrg	    }
12548108eb18Smrg	}
12558108eb18Smrg
12568108eb18Smrg	if (!progName)
12578108eb18Smrg	    continue;
12588108eb18Smrg
12598108eb18Smrg	if (restart_service_prop)
12608108eb18Smrg	    tmp1 = restart_service_prop;
12618108eb18Smrg	else if (client->clientHostname)
12628108eb18Smrg	    tmp1 = client->clientHostname;
12638108eb18Smrg	else
12648108eb18Smrg	    continue;
12658108eb18Smrg
12668108eb18Smrg	if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
12678108eb18Smrg	    hostname = tmp1;
12688108eb18Smrg	else
12698108eb18Smrg	    hostname = tmp2 + 1;
12708108eb18Smrg
12718108eb18Smrg	if ((int) strlen (hostname) > maxlen2)
12728108eb18Smrg	    maxlen2 = strlen (hostname);
12738108eb18Smrg
12748108eb18Smrg	numFailedNames++;
12758108eb18Smrg    }
12768108eb18Smrg
12778108eb18Smrg    failedNames = (String *) XtMalloc (
12788108eb18Smrg	numFailedNames * sizeof (String));
12798108eb18Smrg
12808108eb18Smrg    i = 0;
12818108eb18Smrg    for (cl = ListFirst (FailedSaveList); cl; cl = ListNext (cl))
12828108eb18Smrg    {
12838108eb18Smrg	ClientRec *client = (ClientRec *) cl->thing;
12848108eb18Smrg	int extra1, extra2;
12858108eb18Smrg
12868108eb18Smrg	progName = NULL;
12878108eb18Smrg	restart_service_prop = NULL;
12888108eb18Smrg
12898108eb18Smrg	for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
12908108eb18Smrg	{
12918108eb18Smrg	    Prop *pprop = (Prop *) pl->thing;
12928108eb18Smrg	    List *vl = ListFirst (pprop->values);
12938108eb18Smrg	    PropValue *pval = (PropValue *) vl->thing;
12948108eb18Smrg
12958108eb18Smrg	    if (strcmp (pprop->name, SmProgram) == 0)
12968108eb18Smrg	    {
12978108eb18Smrg		progName = GetProgramName ((char *) pval->value);
12988108eb18Smrg	    }
12998108eb18Smrg	    else if (strcmp (pprop->name, "_XC_RestartService") == 0)
13008108eb18Smrg	    {
13018108eb18Smrg		restart_service_prop = (char *) pval->value;
13028108eb18Smrg	    }
13038108eb18Smrg	}
13048108eb18Smrg
13058108eb18Smrg	if (!progName)
13068108eb18Smrg	    continue;
13078108eb18Smrg
13088108eb18Smrg	if (restart_service_prop)
13098108eb18Smrg	    tmp1 = restart_service_prop;
13108108eb18Smrg	else if (client->clientHostname)
13118108eb18Smrg	    tmp1 = client->clientHostname;
13128108eb18Smrg	else
13138108eb18Smrg	    continue;
13148108eb18Smrg
13158108eb18Smrg	if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
13168108eb18Smrg	    hostname = tmp1;
13178108eb18Smrg	else
13188108eb18Smrg	    hostname = tmp2 + 1;
13198108eb18Smrg
13208108eb18Smrg	extra1 = maxlen1 - strlen (progName) + 5;
13218108eb18Smrg	extra2 = maxlen2 - strlen (hostname);
13228108eb18Smrg
13238108eb18Smrg	clientInfo = (String) XtMalloc (strlen (progName) +
13248108eb18Smrg	    extra1 + extra2 + 3 + strlen (hostname) + 1);
13258108eb18Smrg
13268108eb18Smrg	for (k = 0; k < extra1; k++)
13278108eb18Smrg	    extraBuf1[k] = ' ';
13288108eb18Smrg	extraBuf1[extra1] = '\0';
13298108eb18Smrg
13308108eb18Smrg	for (k = 0; k < extra2; k++)
13318108eb18Smrg	    extraBuf2[k] = ' ';
13328108eb18Smrg	extraBuf2[extra2] = '\0';
13338108eb18Smrg
13348108eb18Smrg	sprintf (clientInfo, "%s%s (%s%s)", progName, extraBuf1,
13358108eb18Smrg	    hostname, extraBuf2);
13368108eb18Smrg
13378108eb18Smrg	failedNames[i++] = clientInfo;
13388108eb18Smrg
13398108eb18Smrg	if (client->freeAfterBadSavePopup)
13408108eb18Smrg	{
13418108eb18Smrg	    FreeClient (client, True /* free props */);
13428108eb18Smrg	}
13438108eb18Smrg    }
13448108eb18Smrg
13458108eb18Smrg    XawListChange (badSaveListWidget,
13468108eb18Smrg	failedNames, numFailedNames, 0, True);
13478108eb18Smrg
13488108eb18Smrg    XtPopdown (savePopup);
13498108eb18Smrg
13508108eb18Smrg    if (wantShutdown && !shutdownCancelled)
13518108eb18Smrg	XtManageChild (badSaveCancelButton);
13528108eb18Smrg    else
13538108eb18Smrg	XtUnmanageChild (badSaveCancelButton);
13548108eb18Smrg
13558108eb18Smrg    PopupPopup (mainWindow, badSavePopup,
13568108eb18Smrg	True, first_time, 25, 100, "DelBadSaveWinAction()");
13578108eb18Smrg
13588108eb18Smrg    if (first_time)
13598108eb18Smrg	first_time = 0;
13608108eb18Smrg}
13618108eb18Smrg
13628108eb18Smrg
13638108eb18Smrg
13648108eb18Smrgvoid
13658108eb18SmrgShutdownDontSaveXtProc(Widget w, XtPointer client_data, XtPointer callData)
13668108eb18Smrg{
13678108eb18Smrg    List	*cl;
13688108eb18Smrg    ClientRec 	*client;
13698108eb18Smrg
13708108eb18Smrg    if (ListCount (RunningList) == 0)
13718108eb18Smrg	EndSession (0);
13728108eb18Smrg
13738108eb18Smrg    /*
13748108eb18Smrg     * For any client that was not restarted by the session
13758108eb18Smrg     * manager (previous ID was NULL), if we did not issue a
13768108eb18Smrg     * checkpoint to this client, remove the client's checkpoint
13778108eb18Smrg     * file using the discard command.
13788108eb18Smrg     */
13798108eb18Smrg
13808108eb18Smrg    for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
13818108eb18Smrg    {
13828108eb18Smrg	client = (ClientRec *) cl->thing;
13838108eb18Smrg
13848108eb18Smrg	if (!client->restarted &&
13858108eb18Smrg	    !client->userIssuedCheckpoint &&
13868108eb18Smrg	    client->discardCommand)
13878108eb18Smrg	{
13888108eb18Smrg	    execute_system_command (client->discardCommand);
13898108eb18Smrg	    XtFree (client->discardCommand);
13908108eb18Smrg	    client->discardCommand = NULL;
13918108eb18Smrg	}
13928108eb18Smrg    }
13938108eb18Smrg
13948108eb18Smrg    shutdownInProgress = True;
13958108eb18Smrg
13968108eb18Smrg    for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
13978108eb18Smrg    {
13988108eb18Smrg	client = (ClientRec *) cl->thing;
13998108eb18Smrg
14008108eb18Smrg	SmsDie (client->smsConn);
14018108eb18Smrg
14028108eb18Smrg	if (verbose)
14038108eb18Smrg	{
14048108eb18Smrg	    printf ("Client Id = %s, sent DIE\n", client->clientId);
14058108eb18Smrg	}
14068108eb18Smrg    }
14078108eb18Smrg}
1408