choose.c revision 2bc08f26
18108eb18Smrg/* $Xorg: choose.c,v 1.4 2001/02/09 02:05:59 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/choose.c,v 1.6tsi Exp $ */
278108eb18Smrg
288108eb18Smrg#include "xsm.h"
298108eb18Smrg#include "saveutil.h"
308108eb18Smrg#include "lock.h"
318108eb18Smrg#include "choose.h"
328108eb18Smrg#include <sys/types.h>
338108eb18Smrg
348108eb18Smrg#include <X11/Shell.h>
358108eb18Smrg#include <X11/Xaw/Form.h>
368108eb18Smrg#include <X11/Xaw/List.h>
378108eb18Smrg#include <X11/Xaw/Command.h>
388108eb18Smrg
398108eb18Smrg#ifndef X_NOT_POSIX
408108eb18Smrg#include <dirent.h>
418108eb18Smrg#else
428108eb18Smrg#ifdef SYSV
438108eb18Smrg#include <dirent.h>
448108eb18Smrg#else
458108eb18Smrg#ifdef USG
468108eb18Smrg#include <dirent.h>
478108eb18Smrg#else
488108eb18Smrg#include <sys/dir.h>
498108eb18Smrg#ifndef dirent
508108eb18Smrg#define dirent direct
518108eb18Smrg#endif
528108eb18Smrg#endif
538108eb18Smrg#endif
548108eb18Smrg#endif
558108eb18Smrg
568108eb18Smrgstatic Pixel save_message_foreground;
578108eb18Smrgstatic Pixel save_message_background;
588108eb18Smrg
598108eb18Smrgstatic int delete_session_phase = 0;
608108eb18Smrgstatic int break_lock_phase = 0;
618108eb18Smrg
621a650d1eSmrgstatic Widget chooseSessionPopup;
631a650d1eSmrgstatic Widget chooseSessionForm;
641a650d1eSmrgstatic Widget chooseSessionLabel;
651a650d1eSmrgstatic Widget chooseSessionListWidget;
661a650d1eSmrgstatic Widget chooseSessionMessageLabel;
671a650d1eSmrgstatic Widget chooseSessionLoadButton;
681a650d1eSmrgstatic Widget chooseSessionDeleteButton;
691a650d1eSmrgstatic Widget chooseSessionBreakLockButton;
701a650d1eSmrgstatic Widget chooseSessionFailSafeButton;
711a650d1eSmrgstatic Widget chooseSessionCancelButton;
728108eb18Smrg
738108eb18Smrg
748108eb18Smrg
758108eb18Smrgint
768108eb18SmrgGetSessionNames(int *count_ret, String **short_names_ret,
778108eb18Smrg		String **long_names_ret, Bool **locked_ret)
788108eb18Smrg{
798108eb18Smrg    DIR *dir;
808108eb18Smrg    struct dirent *entry;
815977a007Smrg    const char *path;
828108eb18Smrg    int count;
838108eb18Smrg
845977a007Smrg    path = getenv ("SM_SAVE_DIR");
858108eb18Smrg    if (!path)
868108eb18Smrg    {
875977a007Smrg	path = getenv ("HOME");
888108eb18Smrg	if (!path)
898108eb18Smrg	    path = ".";
908108eb18Smrg    }
918108eb18Smrg
928108eb18Smrg    *count_ret = 0;
938108eb18Smrg    *short_names_ret = NULL;
948108eb18Smrg    *locked_ret = NULL;
958108eb18Smrg    if (long_names_ret)
968108eb18Smrg	*long_names_ret = NULL;
978108eb18Smrg
988108eb18Smrg    if ((dir = opendir (path)) == NULL)
998108eb18Smrg	return 0;
1008108eb18Smrg
1012bc08f26Swiz    fcntl(dirfd(dir), F_SETFD, FD_CLOEXEC);
1027e748ac2Schristos
1038108eb18Smrg    count = 0;
1048108eb18Smrg
1058108eb18Smrg    while ((entry = readdir (dir)) != NULL)
1068108eb18Smrg    {
1078108eb18Smrg	if (strncmp (entry->d_name, ".XSM-", 5) == 0)
1088108eb18Smrg	    count++;
1098108eb18Smrg    }
1108108eb18Smrg
1118108eb18Smrg    if (count == 0 ||
1128108eb18Smrg       ((*short_names_ret = (String *) XtMalloc (
1138108eb18Smrg           count * sizeof (String))) == NULL) ||
1148108eb18Smrg       (long_names_ret && (*long_names_ret =
1158108eb18Smrg           (String *) XtMalloc (count * sizeof (String))) == NULL) ||
1168108eb18Smrg       ((*locked_ret = (Bool *) XtMalloc (count * sizeof (Bool))) == NULL))
1178108eb18Smrg    {
1188108eb18Smrg	closedir (dir);
1198108eb18Smrg	if (*short_names_ret)
1208108eb18Smrg	    XtFree ((char *) *short_names_ret);
1218108eb18Smrg	if (long_names_ret && *long_names_ret)
1228108eb18Smrg	    XtFree ((char *) *long_names_ret);
1238108eb18Smrg	return 0;
1248108eb18Smrg    }
1258108eb18Smrg
1268108eb18Smrg    rewinddir (dir);
1278108eb18Smrg
1288108eb18Smrg    while ((entry = readdir (dir)) != NULL && *count_ret < count)
1298108eb18Smrg    {
1308108eb18Smrg	if (strncmp (entry->d_name, ".XSM-", 5) == 0)
1318108eb18Smrg	{
1328108eb18Smrg	    char *name = (char *) entry->d_name + 5;
1338108eb18Smrg	    char *id = NULL;
1348108eb18Smrg	    Bool locked = CheckSessionLocked (name, long_names_ret!=NULL, &id);
1358108eb18Smrg
1368108eb18Smrg	    (*short_names_ret)[*count_ret] = XtNewString (name);
1378108eb18Smrg	    (*locked_ret)[*count_ret] = locked;
1388108eb18Smrg
1398108eb18Smrg	    if (long_names_ret)
1408108eb18Smrg	    {
1418108eb18Smrg		if (!locked)
1428108eb18Smrg		{
1438108eb18Smrg		    (*long_names_ret)[*count_ret] =
1448108eb18Smrg			(*short_names_ret)[*count_ret];
1458108eb18Smrg		}
1468108eb18Smrg		else
1478108eb18Smrg		{
1488108eb18Smrg		    char *host = ((char *) strchr (id, '/')) + 1;
1498108eb18Smrg		    char *colon = (char *) strrchr (host, ':');
1505977a007Smrg		    char *lockmsg;
1518108eb18Smrg
1528108eb18Smrg		    /* backtrack over previous colon if there are 2 (DECnet),
1538108eb18Smrg		       but not three (IPv6) */
1548108eb18Smrg		    if ((*(colon - 1) == ':') && (*(colon - 2) != ':'))
1558108eb18Smrg			colon--;
1568108eb18Smrg
1578108eb18Smrg		    *colon = '\0';
1588108eb18Smrg
1595977a007Smrg		    XtAsprintf (&lockmsg, "%s (locked at %s)", name, host);
1605977a007Smrg		    (*long_names_ret)[*count_ret] = lockmsg;
1618108eb18Smrg		    *colon = ':';
1628108eb18Smrg
1638108eb18Smrg		    XtFree (id);
1648108eb18Smrg		}
1658108eb18Smrg	    }
1668108eb18Smrg
1678108eb18Smrg	    (*count_ret)++;
1688108eb18Smrg	}
1698108eb18Smrg    }
1708108eb18Smrg
1718108eb18Smrg    closedir (dir);
1728108eb18Smrg
1738108eb18Smrg    return 1;
1748108eb18Smrg}
1758108eb18Smrg
1768108eb18Smrg
1778108eb18Smrg
1788108eb18Smrgvoid
1798108eb18SmrgFreeSessionNames(int count, String *namesShort, String *namesLong,
1808108eb18Smrg		 Bool *lockFlags)
1818108eb18Smrg{
1828108eb18Smrg    int i;
1838108eb18Smrg
1848108eb18Smrg    for (i = 0; i < count; i++)
1858108eb18Smrg	XtFree ((char *) namesShort[i]);
1868108eb18Smrg    XtFree ((char *) namesShort);
1878108eb18Smrg
1888108eb18Smrg    if (namesLong)
1898108eb18Smrg    {
1908108eb18Smrg	for (i = 0; i < count; i++)
1918108eb18Smrg	    if (lockFlags[i])
1928108eb18Smrg		XtFree ((char *) namesLong[i]);
1938108eb18Smrg	XtFree ((char *) namesLong);
1948108eb18Smrg    }
1958108eb18Smrg
1968108eb18Smrg    XtFree ((char *) lockFlags);
1978108eb18Smrg}
1988108eb18Smrg
1998108eb18Smrg
2008108eb18Smrg
2018108eb18Smrgstatic void
2028108eb18SmrgSessionSelected(int number, Bool highlight)
2038108eb18Smrg{
2048108eb18Smrg    if (number >= 0)
2058108eb18Smrg    {
2068108eb18Smrg	Bool locked = sessionsLocked[number];
2078108eb18Smrg
2088108eb18Smrg	if (highlight)
2098108eb18Smrg	    XawListHighlight (chooseSessionListWidget, number);
2108108eb18Smrg
2118108eb18Smrg	XtSetSensitive (chooseSessionLoadButton, !locked);
2128108eb18Smrg	XtSetSensitive (chooseSessionDeleteButton, !locked);
2138108eb18Smrg	XtSetSensitive (chooseSessionBreakLockButton, locked);
2148108eb18Smrg    }
2158108eb18Smrg    else
2168108eb18Smrg    {
2178108eb18Smrg	XtSetSensitive (chooseSessionLoadButton, False);
2188108eb18Smrg	XtSetSensitive (chooseSessionDeleteButton, False);
2198108eb18Smrg	XtSetSensitive (chooseSessionBreakLockButton, False);
2208108eb18Smrg    }
2218108eb18Smrg}
2228108eb18Smrg
2238108eb18Smrg
2248108eb18Smrg
2258108eb18Smrgstatic void
2268108eb18SmrgAddSessionNames(int count, String *names)
2278108eb18Smrg{
2288108eb18Smrg    int i;
2298108eb18Smrg
2308108eb18Smrg    XawListChange (chooseSessionListWidget, names, count, 0, True);
2318108eb18Smrg
2328108eb18Smrg    /*
2338108eb18Smrg     * Highlight the first unlocked session, if any.
2348108eb18Smrg     */
2358108eb18Smrg
2368108eb18Smrg    for (i = 0; i < sessionNameCount; i++)
2378108eb18Smrg	if (!sessionsLocked[i])
2388108eb18Smrg	    break;
2398108eb18Smrg
2408108eb18Smrg    SessionSelected (i < sessionNameCount ? i : -1, True);
2418108eb18Smrg}
2428108eb18Smrg
2438108eb18Smrg
2448108eb18Smrg
2458108eb18Smrgvoid
2468108eb18SmrgChooseWindowStructureNotifyXtHandler(Widget w, XtPointer closure,
2478108eb18Smrg				     XEvent *event,
2488108eb18Smrg				     Boolean *continue_to_dispatch)
2498108eb18Smrg{
2508108eb18Smrg    if (event->type == MapNotify)
2518108eb18Smrg    {
2528108eb18Smrg	/*
2538108eb18Smrg	 * Set the input focus to the choose window and direct all keyboard
2548108eb18Smrg	 * events to the list widget.  This way, the user can make selections
2558108eb18Smrg	 * using the keyboard.
2568108eb18Smrg	 */
2578108eb18Smrg
2588108eb18Smrg	XtSetKeyboardFocus (chooseSessionPopup, chooseSessionListWidget);
2598108eb18Smrg
2608108eb18Smrg	XSetInputFocus (XtDisplay (topLevel), XtWindow (chooseSessionPopup),
2618108eb18Smrg	    RevertToPointerRoot, CurrentTime);
2628108eb18Smrg
2638108eb18Smrg	XSync (XtDisplay (topLevel), 0);
2648108eb18Smrg
2658108eb18Smrg	XtRemoveEventHandler (chooseSessionPopup, StructureNotifyMask, False,
2668108eb18Smrg	    ChooseWindowStructureNotifyXtHandler, NULL);
2678108eb18Smrg    }
2688108eb18Smrg}
2698108eb18Smrg
2708108eb18Smrg
2718108eb18Smrgvoid
2728108eb18SmrgChooseSession(void)
2738108eb18Smrg{
2748108eb18Smrg    Dimension   width, height;
2758108eb18Smrg    Position	x, y;
2768108eb18Smrg
2778108eb18Smrg
2788108eb18Smrg    /*
2798108eb18Smrg     * Add the session names to the list
2808108eb18Smrg     */
2818108eb18Smrg
2828108eb18Smrg    AddSessionNames (sessionNameCount, sessionNamesLong);
2838108eb18Smrg
2848108eb18Smrg
2858108eb18Smrg    /*
2868108eb18Smrg     * Center popup containing choice of sessions
2878108eb18Smrg     */
2888108eb18Smrg
2898108eb18Smrg    XtRealizeWidget (chooseSessionPopup);
2908108eb18Smrg
2918108eb18Smrg    XtVaGetValues (chooseSessionPopup,
2928108eb18Smrg	XtNwidth, &width,
2938108eb18Smrg	XtNheight, &height,
2948108eb18Smrg	NULL);
2958108eb18Smrg
2968108eb18Smrg    x = (Position)(WidthOfScreen (XtScreen (topLevel)) - width) / 2;
2978108eb18Smrg    y = (Position)(HeightOfScreen (XtScreen (topLevel)) - height) / 3;
2988108eb18Smrg
2998108eb18Smrg    XtVaSetValues (chooseSessionPopup,
3008108eb18Smrg	XtNx, x,
3018108eb18Smrg	XtNy, y,
3028108eb18Smrg	NULL);
3038108eb18Smrg
3048108eb18Smrg    XtVaSetValues (chooseSessionListWidget,
3058108eb18Smrg	XtNlongest, width,
3068108eb18Smrg	NULL);
3078108eb18Smrg
3088108eb18Smrg    XtVaSetValues (chooseSessionLabel,
3098108eb18Smrg	XtNwidth, width,
3108108eb18Smrg	NULL);
3118108eb18Smrg
3128108eb18Smrg    XtVaGetValues (chooseSessionMessageLabel,
3138108eb18Smrg	XtNforeground, &save_message_foreground,
3148108eb18Smrg	XtNbackground, &save_message_background,
3158108eb18Smrg	NULL);
3168108eb18Smrg
3178108eb18Smrg    XtVaSetValues (chooseSessionMessageLabel,
3188108eb18Smrg	XtNwidth, width,
3198108eb18Smrg	XtNforeground, save_message_background,
3208108eb18Smrg	NULL);
3218108eb18Smrg
3228108eb18Smrg    /*
3238108eb18Smrg     * Wait for a map notify on the popup, then set input focus.
3248108eb18Smrg     */
3258108eb18Smrg
3268108eb18Smrg    XtAddEventHandler (chooseSessionPopup, StructureNotifyMask, False,
3278108eb18Smrg	ChooseWindowStructureNotifyXtHandler, NULL);
3288108eb18Smrg
3298108eb18Smrg    XtPopup (chooseSessionPopup, XtGrabNone);
3308108eb18Smrg}
3318108eb18Smrg
3328108eb18Smrg
3338108eb18Smrg
3348108eb18Smrgstatic void
3358108eb18SmrgCheckDeleteCancel (void)
3368108eb18Smrg{
3378108eb18Smrg    if (delete_session_phase > 0)
3388108eb18Smrg    {
3398108eb18Smrg	XtVaSetValues (chooseSessionMessageLabel,
3408108eb18Smrg	    XtNforeground, save_message_background,
3418108eb18Smrg            NULL);
3428108eb18Smrg
3438108eb18Smrg	delete_session_phase = 0;
3448108eb18Smrg    }
3458108eb18Smrg}
3468108eb18Smrg
3478108eb18Smrg
3488108eb18Smrgstatic void
3498108eb18SmrgCheckBreakLockCancel(void)
3508108eb18Smrg{
3518108eb18Smrg    if (break_lock_phase > 0)
3528108eb18Smrg    {
3538108eb18Smrg	XtVaSetValues (chooseSessionMessageLabel,
3548108eb18Smrg	    XtNforeground, save_message_background,
3558108eb18Smrg            NULL);
3568108eb18Smrg
3578108eb18Smrg	break_lock_phase = 0;
3588108eb18Smrg    }
3598108eb18Smrg}
3608108eb18Smrg
3618108eb18Smrg
3628108eb18Smrg
3638108eb18Smrgstatic void
3648108eb18SmrgChooseSessionUp(Widget w, XEvent *event, String *params, Cardinal *numParams)
3658108eb18Smrg{
3668108eb18Smrg    XawListReturnStruct *current;
3678108eb18Smrg
3688108eb18Smrg    CheckDeleteCancel ();
3698108eb18Smrg    CheckBreakLockCancel ();
3708108eb18Smrg
3718108eb18Smrg    current = XawListShowCurrent (chooseSessionListWidget);
3728108eb18Smrg    if (current->list_index > 0)
3738108eb18Smrg	SessionSelected (current->list_index - 1, True);
3748108eb18Smrg    XtFree ((char *) current);
3758108eb18Smrg}
3768108eb18Smrg
3778108eb18Smrg
3788108eb18Smrgstatic void
3798108eb18SmrgChooseSessionDown(Widget w, XEvent *event, String *params, Cardinal *numParams)
3808108eb18Smrg{
3818108eb18Smrg    XawListReturnStruct *current;
3828108eb18Smrg
3838108eb18Smrg    CheckDeleteCancel ();
3848108eb18Smrg    CheckBreakLockCancel ();
3858108eb18Smrg
3868108eb18Smrg    current = XawListShowCurrent (chooseSessionListWidget);
3878108eb18Smrg    if (current->list_index < sessionNameCount - 1)
3888108eb18Smrg	SessionSelected (current->list_index + 1, True);
3898108eb18Smrg    XtFree ((char *) current);
3908108eb18Smrg}
3918108eb18Smrg
3928108eb18Smrg
3938108eb18Smrg
3948108eb18Smrgstatic void
3958108eb18SmrgChooseSessionBtn1Down(Widget w, XEvent *event, String *params,
3968108eb18Smrg		      Cardinal *numParams)
3978108eb18Smrg{
3988108eb18Smrg    XawListReturnStruct *current;
3998108eb18Smrg
4008108eb18Smrg    CheckDeleteCancel ();
4018108eb18Smrg    CheckBreakLockCancel ();
4028108eb18Smrg
4038108eb18Smrg    current = XawListShowCurrent (chooseSessionListWidget);
4048108eb18Smrg    SessionSelected (current->list_index, False /* already highlighted */);
4058108eb18Smrg    XtFree ((char *) current);
4068108eb18Smrg}
4078108eb18Smrg
4088108eb18Smrg
4098108eb18Smrg
4108108eb18Smrgstatic void
4118108eb18SmrgChooseSessionLoadXtProc(Widget w, XtPointer client_data, XtPointer callData)
4128108eb18Smrg{
4138108eb18Smrg    XawListReturnStruct *current;
4148108eb18Smrg
4158108eb18Smrg    CheckDeleteCancel ();
4168108eb18Smrg    CheckBreakLockCancel ();
4178108eb18Smrg
4188108eb18Smrg    current = XawListShowCurrent (chooseSessionListWidget);
4198108eb18Smrg
4208108eb18Smrg    if (!current || !current->string || *(current->string) == '\0')
4218108eb18Smrg    {
4228108eb18Smrg	if (current)
4238108eb18Smrg	    XtFree ((char *) current);
4248108eb18Smrg#ifdef XKB
4258108eb18Smrg	XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
4268108eb18Smrg#else
4278108eb18Smrg	XBell (XtDisplay (topLevel), 0);
4288108eb18Smrg#endif
4298108eb18Smrg	return;
4308108eb18Smrg    }
4318108eb18Smrg
4328108eb18Smrg    /*
4338108eb18Smrg     * Pop down choice of sessions and start the specified session.
4348108eb18Smrg     */
4358108eb18Smrg
4368108eb18Smrg    XtPopdown (chooseSessionPopup);
4378108eb18Smrg
4388108eb18Smrg    if (session_name)
4398108eb18Smrg	XtFree (session_name);
4408108eb18Smrg
4418108eb18Smrg    session_name = XtNewString (current->string);
4428108eb18Smrg
4438108eb18Smrg    XtFree ((char *) current);
4448108eb18Smrg
4458108eb18Smrg    FreeSessionNames (sessionNameCount,
4468108eb18Smrg	sessionNamesShort, sessionNamesLong, sessionsLocked);
4478108eb18Smrg
4488108eb18Smrg
4498108eb18Smrg    /*
4508108eb18Smrg     * Start the session, looking for .XSM-<session name> startup file.
4518108eb18Smrg     */
4528108eb18Smrg
4538108eb18Smrg    if (!StartSession (session_name, False))
4548108eb18Smrg	UnableToLockSession (session_name);
4558108eb18Smrg}
4568108eb18Smrg
4578108eb18Smrg
4588108eb18Smrg
4598108eb18Smrgstatic void
4608108eb18SmrgChooseSessionDeleteXtProc(Widget w, XtPointer client_data, XtPointer callData)
4618108eb18Smrg{
4628108eb18Smrg    XawListReturnStruct *current;
4638108eb18Smrg    int longest;
4648108eb18Smrg    char *name;
4658108eb18Smrg
4668108eb18Smrg    CheckBreakLockCancel ();
4678108eb18Smrg
4688108eb18Smrg    current = XawListShowCurrent (chooseSessionListWidget);
4698108eb18Smrg
4708108eb18Smrg    if (!current || !(name = current->string) || *name == '\0')
4718108eb18Smrg    {
4728108eb18Smrg	if (current)
4738108eb18Smrg	    XtFree ((char *) current);
4748108eb18Smrg#ifdef XKB
4758108eb18Smrg	XkbStdBell(XtDisplay(w),XtWindow(w),0,XkbBI_BadValue);
4768108eb18Smrg#else
4778108eb18Smrg	XBell (XtDisplay (topLevel), 0);
4788108eb18Smrg#endif
4798108eb18Smrg	return;
4808108eb18Smrg    }
4818108eb18Smrg
4828108eb18Smrg    delete_session_phase++;
4838108eb18Smrg
4848108eb18Smrg    if (delete_session_phase == 1)
4858108eb18Smrg    {
4868108eb18Smrg	XtVaSetValues (chooseSessionMessageLabel,
4878108eb18Smrg	    XtNforeground, save_message_foreground,
4888108eb18Smrg            NULL);
4898108eb18Smrg
4908108eb18Smrg#ifdef XKB
4918108eb18Smrg	XkbStdBell(XtDisplay(w),XtWindow(w),0,XkbBI_BadValue);
4928108eb18Smrg#else
4938108eb18Smrg	XBell (XtDisplay (topLevel), 0);
4948108eb18Smrg#endif
4958108eb18Smrg    }
4968108eb18Smrg    else
4978108eb18Smrg    {
4988108eb18Smrg	XtVaSetValues (chooseSessionMessageLabel,
4998108eb18Smrg	    XtNforeground, save_message_background,
5008108eb18Smrg            NULL);
5018108eb18Smrg
5028108eb18Smrg	if (DeleteSession (name))
5038108eb18Smrg	{
5048108eb18Smrg	    int i, j;
5058108eb18Smrg
5068108eb18Smrg	    for (i = 0; i < sessionNameCount; i++)
5078108eb18Smrg	    {
5088108eb18Smrg		if (strcmp (sessionNamesLong[i], name) == 0)
5098108eb18Smrg		{
5108108eb18Smrg		    XtFree ((char *) sessionNamesShort[i]);
5118108eb18Smrg
5128108eb18Smrg		    if (sessionsLocked[i])
5138108eb18Smrg			XtFree ((char *) sessionNamesLong[i]);
5148108eb18Smrg
5158108eb18Smrg		    for (j = i; j < sessionNameCount - 1; j++)
5168108eb18Smrg		    {
5178108eb18Smrg			sessionNamesLong[j] = sessionNamesLong[j + 1];
5188108eb18Smrg			sessionNamesShort[j] = sessionNamesShort[j + 1];
5198108eb18Smrg			sessionsLocked[j] = sessionsLocked[j + 1];
5208108eb18Smrg		    }
5218108eb18Smrg		    sessionNameCount--;
5228108eb18Smrg		    break;
5238108eb18Smrg		}
5248108eb18Smrg	    }
5258108eb18Smrg
5268108eb18Smrg	    if (sessionNameCount == 0)
5278108eb18Smrg	    {
5288108eb18Smrg		XtSetSensitive (chooseSessionLoadButton, 0);
5298108eb18Smrg		XtSetSensitive (chooseSessionDeleteButton, 0);
5308108eb18Smrg		XtUnmanageChild (chooseSessionListWidget);
5318108eb18Smrg	    }
5328108eb18Smrg	    else
5338108eb18Smrg	    {
5348108eb18Smrg		XtVaGetValues (chooseSessionListWidget,
5358108eb18Smrg		    XtNlongest, &longest,
5368108eb18Smrg		    NULL);
5378108eb18Smrg
5388108eb18Smrg		XawListChange (chooseSessionListWidget,
5398108eb18Smrg		    sessionNamesLong, sessionNameCount, longest, True);
5408108eb18Smrg
5418108eb18Smrg		SessionSelected (-1, False);
5428108eb18Smrg	    }
5438108eb18Smrg	}
5448108eb18Smrg
5458108eb18Smrg	delete_session_phase = 0;
5468108eb18Smrg    }
5478108eb18Smrg
5488108eb18Smrg    XtFree ((char *) current);
5498108eb18Smrg}
5508108eb18Smrg
5518108eb18Smrg
5528108eb18Smrg
5538108eb18Smrgstatic void
5548108eb18SmrgChooseSessionBreakLockXtProc(Widget w, XtPointer client_data,
5558108eb18Smrg			     XtPointer callData)
5568108eb18Smrg{
5578108eb18Smrg    XawListReturnStruct *current;
5588108eb18Smrg    char *name;
5598108eb18Smrg
5608108eb18Smrg    CheckDeleteCancel ();
5618108eb18Smrg
5628108eb18Smrg    current = XawListShowCurrent (chooseSessionListWidget);
5638108eb18Smrg
5648108eb18Smrg    if (!current || !(name = current->string) || *name == '\0')
5658108eb18Smrg    {
5668108eb18Smrg	if (current)
5678108eb18Smrg	    XtFree ((char *) current);
5688108eb18Smrg#ifdef XKB
5698108eb18Smrg	XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
5708108eb18Smrg#else
5718108eb18Smrg	XBell (XtDisplay (topLevel), 0);
5728108eb18Smrg#endif
5738108eb18Smrg	return;
5748108eb18Smrg    }
5758108eb18Smrg
5768108eb18Smrg    break_lock_phase++;
5778108eb18Smrg
5788108eb18Smrg    if (break_lock_phase == 1)
5798108eb18Smrg    {
5808108eb18Smrg	XtVaSetValues (chooseSessionMessageLabel,
5818108eb18Smrg	    XtNforeground, save_message_foreground,
5828108eb18Smrg            NULL);
5838108eb18Smrg
5848108eb18Smrg#ifdef XKB
5858108eb18Smrg	XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
5868108eb18Smrg#else
5878108eb18Smrg	XBell (XtDisplay (topLevel), 0);
5888108eb18Smrg#endif
5898108eb18Smrg    }
5908108eb18Smrg    else
5918108eb18Smrg    {
5928108eb18Smrg	int longest;
5938108eb18Smrg
5948108eb18Smrg	XtVaSetValues (chooseSessionMessageLabel,
5958108eb18Smrg	    XtNforeground, save_message_background,
5968108eb18Smrg            NULL);
5978108eb18Smrg
5988108eb18Smrg	name = sessionNamesShort[current->list_index];
5998108eb18Smrg
6008108eb18Smrg	(void) GetLockId (name);
6018108eb18Smrg
6028108eb18Smrg	UnlockSession (name);
6038108eb18Smrg
6048108eb18Smrg	sessionsLocked[current->list_index] = False;
6058108eb18Smrg	XtFree ((char *) sessionNamesLong[current->list_index]);
6068108eb18Smrg	sessionNamesLong[current->list_index] =
6078108eb18Smrg	    sessionNamesShort[current->list_index];
6088108eb18Smrg
6098108eb18Smrg	XtVaGetValues (chooseSessionListWidget,
6108108eb18Smrg	    XtNlongest, &longest,
6118108eb18Smrg	    NULL);
6128108eb18Smrg
6138108eb18Smrg	XawListChange (chooseSessionListWidget,
6148108eb18Smrg	    sessionNamesLong, sessionNameCount, longest, True);
6158108eb18Smrg
6168108eb18Smrg	SessionSelected (current->list_index, True);
6178108eb18Smrg
6188108eb18Smrg	break_lock_phase = 0;
6198108eb18Smrg    }
6208108eb18Smrg
6218108eb18Smrg    XtFree ((char *) current);
6228108eb18Smrg}
6238108eb18Smrg
6248108eb18Smrg
6258108eb18Smrg
6268108eb18Smrgstatic void
6278108eb18SmrgChooseSessionFailSafeXtProc(Widget w, XtPointer client_data,
6288108eb18Smrg			    XtPointer callData)
6298108eb18Smrg{
6308108eb18Smrg    /*
6318108eb18Smrg     * Pop down choice of sessions, and start the fail safe session.
6328108eb18Smrg     */
6338108eb18Smrg
6348108eb18Smrg    CheckDeleteCancel ();
6358108eb18Smrg    CheckBreakLockCancel ();
6368108eb18Smrg
6378108eb18Smrg    XtPopdown (chooseSessionPopup);
6388108eb18Smrg
6398108eb18Smrg    if (session_name)
6408108eb18Smrg	XtFree (session_name);
6418108eb18Smrg
6428108eb18Smrg    session_name = XtNewString (FAILSAFE_SESSION_NAME);
6438108eb18Smrg
6448108eb18Smrg    FreeSessionNames (sessionNameCount,
6458108eb18Smrg	sessionNamesShort, sessionNamesLong, sessionsLocked);
6468108eb18Smrg
6478108eb18Smrg
6488108eb18Smrg    /*
6498108eb18Smrg     * We don't need to check return value of StartSession in this case,
6508108eb18Smrg     * because we are using the default session, and StartSession will
6518108eb18Smrg     * not try to lock the session at this time.  It will try to lock
6528108eb18Smrg     * it as soon as the user gives the session a name.
6538108eb18Smrg     */
6548108eb18Smrg
6558108eb18Smrg    StartSession (session_name,
6568108eb18Smrg	True /* Use ~/.xsmstartup if found, else system.xsm */);
6578108eb18Smrg}
6588108eb18Smrg
6598108eb18Smrg
6608108eb18Smrg
6618108eb18Smrgstatic void
6628108eb18SmrgChooseSessionCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
6638108eb18Smrg{
6648108eb18Smrg    if (delete_session_phase > 0 || break_lock_phase > 0)
6658108eb18Smrg    {
6668108eb18Smrg	XtVaSetValues (chooseSessionMessageLabel,
6678108eb18Smrg	    XtNforeground, save_message_background,
6688108eb18Smrg            NULL);
6698108eb18Smrg
6708108eb18Smrg	delete_session_phase = 0;
6718108eb18Smrg	break_lock_phase = 0;
6728108eb18Smrg    }
6738108eb18Smrg    else
6748108eb18Smrg	EndSession (2);
6758108eb18Smrg}
6768108eb18Smrg
6778108eb18Smrg
6788108eb18Smrg
6798108eb18Smrgvoid
6808108eb18Smrgcreate_choose_session_popup(void)
6818108eb18Smrg
6828108eb18Smrg{
6838108eb18Smrg    static XtActionsRec choose_actions[] = {
6848108eb18Smrg        {"ChooseSessionUp", ChooseSessionUp},
6858108eb18Smrg        {"ChooseSessionDown", ChooseSessionDown},
6868108eb18Smrg        {"ChooseSessionBtn1Down", ChooseSessionBtn1Down}
6878108eb18Smrg    };
6888108eb18Smrg
6898108eb18Smrg    /*
6908108eb18Smrg     * Pop up for choosing session at startup
6918108eb18Smrg     */
6928108eb18Smrg
6938108eb18Smrg    chooseSessionPopup = XtVaCreatePopupShell (
6948108eb18Smrg	"chooseSessionPopup", transientShellWidgetClass, topLevel,
6958108eb18Smrg	XtNallowShellResize, True,
6968108eb18Smrg	NULL);
6978108eb18Smrg
6988108eb18Smrg
6998108eb18Smrg    chooseSessionForm = XtVaCreateManagedWidget (
7008108eb18Smrg	"chooseSessionForm", formWidgetClass, chooseSessionPopup,
7018108eb18Smrg	NULL);
7028108eb18Smrg
7038108eb18Smrg
7048108eb18Smrg    chooseSessionLabel = XtVaCreateManagedWidget (
7058108eb18Smrg	"chooseSessionLabel", labelWidgetClass, chooseSessionForm,
7068108eb18Smrg        XtNfromHoriz, NULL,
7078108eb18Smrg        XtNfromVert, NULL,
7088108eb18Smrg        XtNborderWidth, 0,
7098108eb18Smrg	XtNresizable, True,
7108108eb18Smrg	XtNjustify, XtJustifyCenter,
7118108eb18Smrg	NULL);
7128108eb18Smrg
7138108eb18Smrg    chooseSessionListWidget = XtVaCreateManagedWidget (
7148108eb18Smrg	"chooseSessionListWidget", listWidgetClass, chooseSessionForm,
7158108eb18Smrg	XtNresizable, True,
7168108eb18Smrg        XtNdefaultColumns, 1,
7178108eb18Smrg	XtNforceColumns, True,
7188108eb18Smrg        XtNfromHoriz, NULL,
7198108eb18Smrg        XtNfromVert, chooseSessionLabel,
7208108eb18Smrg	XtNvertDistance, 25,
7218108eb18Smrg	NULL);
7228108eb18Smrg
7238108eb18Smrg    chooseSessionMessageLabel = XtVaCreateManagedWidget (
7248108eb18Smrg	"chooseSessionMessageLabel", labelWidgetClass, chooseSessionForm,
7258108eb18Smrg        XtNfromHoriz, NULL,
7268108eb18Smrg        XtNfromVert, chooseSessionListWidget,
7278108eb18Smrg        XtNborderWidth, 0,
7288108eb18Smrg	XtNresizable, True,
7298108eb18Smrg	XtNjustify, XtJustifyCenter,
7308108eb18Smrg	NULL);
7318108eb18Smrg
7328108eb18Smrg    chooseSessionLoadButton = XtVaCreateManagedWidget (
7338108eb18Smrg	"chooseSessionLoadButton", commandWidgetClass, chooseSessionForm,
7348108eb18Smrg        XtNfromHoriz, NULL,
7358108eb18Smrg        XtNfromVert, chooseSessionMessageLabel,
7368108eb18Smrg        NULL);
7378108eb18Smrg
7388108eb18Smrg    XtAddCallback (chooseSessionLoadButton, XtNcallback,
7391a650d1eSmrg	ChooseSessionLoadXtProc, NULL);
7408108eb18Smrg
7418108eb18Smrg    chooseSessionDeleteButton = XtVaCreateManagedWidget (
7428108eb18Smrg	"chooseSessionDeleteButton", commandWidgetClass, chooseSessionForm,
7438108eb18Smrg        XtNfromHoriz, chooseSessionLoadButton,
7448108eb18Smrg        XtNfromVert, chooseSessionMessageLabel,
7458108eb18Smrg        NULL);
7468108eb18Smrg
7478108eb18Smrg    XtAddCallback (chooseSessionDeleteButton, XtNcallback,
7481a650d1eSmrg	ChooseSessionDeleteXtProc, NULL);
7498108eb18Smrg
7508108eb18Smrg    chooseSessionBreakLockButton = XtVaCreateManagedWidget (
7518108eb18Smrg	"chooseSessionBreakLockButton",
7528108eb18Smrg	commandWidgetClass, chooseSessionForm,
7538108eb18Smrg        XtNfromHoriz, chooseSessionDeleteButton,
7548108eb18Smrg        XtNfromVert, chooseSessionMessageLabel,
7558108eb18Smrg        NULL);
7568108eb18Smrg
7578108eb18Smrg    XtAddCallback (chooseSessionBreakLockButton, XtNcallback,
7581a650d1eSmrg	ChooseSessionBreakLockXtProc, NULL);
7598108eb18Smrg
7608108eb18Smrg    chooseSessionFailSafeButton = XtVaCreateManagedWidget (
7618108eb18Smrg	"chooseSessionFailSafeButton", commandWidgetClass, chooseSessionForm,
7628108eb18Smrg        XtNfromHoriz, chooseSessionBreakLockButton,
7638108eb18Smrg        XtNfromVert, chooseSessionMessageLabel,
7648108eb18Smrg        NULL);
7658108eb18Smrg
7668108eb18Smrg    XtAddCallback (chooseSessionFailSafeButton, XtNcallback,
7671a650d1eSmrg	ChooseSessionFailSafeXtProc, NULL);
7688108eb18Smrg
7698108eb18Smrg
7708108eb18Smrg    chooseSessionCancelButton = XtVaCreateManagedWidget (
7718108eb18Smrg	"chooseSessionCancelButton", commandWidgetClass, chooseSessionForm,
7728108eb18Smrg        XtNfromHoriz, chooseSessionFailSafeButton,
7738108eb18Smrg        XtNfromVert, chooseSessionMessageLabel,
7748108eb18Smrg        NULL);
7758108eb18Smrg
7768108eb18Smrg    XtAddCallback (chooseSessionCancelButton, XtNcallback,
7771a650d1eSmrg	ChooseSessionCancelXtProc, NULL);
7788108eb18Smrg
7798108eb18Smrg    XtAppAddActions (appContext, choose_actions, XtNumber (choose_actions));
7808108eb18Smrg
7818108eb18Smrg    XtInstallAllAccelerators (chooseSessionListWidget, chooseSessionPopup);
7828108eb18Smrg}
783