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