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