Home | History | Annotate | Line # | Download | only in dist
      1 /* $Xorg: choose.c,v 1.4 2001/02/09 02:05:59 xorgcvs Exp $ */
      2 /******************************************************************************
      3 
      4 Copyright 1993, 1998  The Open Group
      5 
      6 Permission to use, copy, modify, distribute, and sell this software and its
      7 documentation for any purpose is hereby granted without fee, provided that
      8 the above copyright notice appear in all copies and that both that
      9 copyright notice and this permission notice appear in supporting
     10 documentation.
     11 
     12 The above copyright notice and this permission notice shall be included in
     13 all copies or substantial portions of the Software.
     14 
     15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 Except as contained in this notice, the name of The Open Group shall not be
     23 used in advertising or otherwise to promote the sale, use or other dealings
     24 in this Software without prior written authorization from The Open Group.
     25 ******************************************************************************/
     26 /* $XFree86: xc/programs/xsm/choose.c,v 1.6tsi Exp $ */
     27 
     28 #include "xsm.h"
     29 #include "saveutil.h"
     30 #include "lock.h"
     31 #include "choose.h"
     32 #include <sys/types.h>
     33 
     34 #include <X11/Shell.h>
     35 #include <X11/Xaw/Form.h>
     36 #include <X11/Xaw/List.h>
     37 #include <X11/Xaw/Command.h>
     38 
     39 #ifndef X_NOT_POSIX
     40 #include <dirent.h>
     41 #else
     42 #include <sys/dir.h>
     43 #ifndef dirent
     44 #define dirent direct
     45 #endif
     46 #endif
     47 
     48 static Pixel save_message_foreground;
     49 static Pixel save_message_background;
     50 
     51 static int delete_session_phase = 0;
     52 static int break_lock_phase = 0;
     53 
     54 static Widget chooseSessionPopup;
     55 static Widget chooseSessionForm;
     56 static Widget chooseSessionLabel;
     57 static Widget chooseSessionListWidget;
     58 static Widget chooseSessionMessageLabel;
     59 static Widget chooseSessionLoadButton;
     60 static Widget chooseSessionDeleteButton;
     61 static Widget chooseSessionBreakLockButton;
     62 static Widget chooseSessionFailSafeButton;
     63 static Widget chooseSessionCancelButton;
     64 
     65 
     66 
     67 int
     69 GetSessionNames(int *count_ret, String **short_names_ret,
     70 		String **long_names_ret, Bool **locked_ret)
     71 {
     72     DIR *dir;
     73     struct dirent *entry;
     74     const char *path;
     75     int count;
     76 
     77     path = getenv ("SM_SAVE_DIR");
     78     if (!path)
     79     {
     80 	path = getenv ("HOME");
     81 	if (!path)
     82 	    path = ".";
     83     }
     84 
     85     *count_ret = 0;
     86     *short_names_ret = NULL;
     87     *locked_ret = NULL;
     88     if (long_names_ret)
     89 	*long_names_ret = NULL;
     90 
     91     if ((dir = opendir (path)) == NULL)
     92 	return 0;
     93 
     94     fcntl(dirfd(dir), F_SETFD, FD_CLOEXEC);
     95 
     96     count = 0;
     97 
     98     while ((entry = readdir (dir)) != NULL)
     99     {
    100 	if (strncmp (entry->d_name, ".XSM-", 5) == 0)
    101 	    count++;
    102     }
    103 
    104     if (count == 0 ||
    105        ((*short_names_ret = (String *) XtMalloc (
    106            count * sizeof (String))) == NULL) ||
    107        (long_names_ret && (*long_names_ret =
    108            (String *) XtMalloc (count * sizeof (String))) == NULL) ||
    109        ((*locked_ret = (Bool *) XtMalloc (count * sizeof (Bool))) == NULL))
    110     {
    111 	closedir (dir);
    112 	if (*short_names_ret)
    113 	    XtFree ((char *) *short_names_ret);
    114 	if (long_names_ret && *long_names_ret)
    115 	    XtFree ((char *) *long_names_ret);
    116 	return 0;
    117     }
    118 
    119     rewinddir (dir);
    120 
    121     while ((entry = readdir (dir)) != NULL && *count_ret < count)
    122     {
    123 	if (strncmp (entry->d_name, ".XSM-", 5) == 0)
    124 	{
    125 	    char *name = (char *) entry->d_name + 5;
    126 	    char *id = NULL;
    127 	    Bool locked = CheckSessionLocked (name, long_names_ret!=NULL, &id);
    128 
    129 	    (*short_names_ret)[*count_ret] = XtNewString (name);
    130 	    (*locked_ret)[*count_ret] = locked;
    131 
    132 	    if (long_names_ret)
    133 	    {
    134 		if (!locked)
    135 		{
    136 		    (*long_names_ret)[*count_ret] =
    137 			(*short_names_ret)[*count_ret];
    138 		}
    139 		else
    140 		{
    141 		    char *host = ((char *) strchr (id, '/')) + 1;
    142 		    char *colon = (char *) strrchr (host, ':');
    143 		    char *lockmsg;
    144 
    145 		    /* backtrack over previous colon if there are 2 (DECnet),
    146 		       but not three (IPv6) */
    147 		    if ((*(colon - 1) == ':') && (*(colon - 2) != ':'))
    148 			colon--;
    149 
    150 		    *colon = '\0';
    151 
    152 		    XtAsprintf (&lockmsg, "%s (locked at %s)", name, host);
    153 		    (*long_names_ret)[*count_ret] = lockmsg;
    154 		    *colon = ':';
    155 
    156 		    XtFree (id);
    157 		}
    158 	    }
    159 
    160 	    (*count_ret)++;
    161 	}
    162     }
    163 
    164     closedir (dir);
    165 
    166     return 1;
    167 }
    168 
    169 
    170 
    171 void
    173 FreeSessionNames(int count, String *namesShort, String *namesLong,
    174 		 Bool *lockFlags)
    175 {
    176     int i;
    177 
    178     for (i = 0; i < count; i++)
    179 	XtFree ((char *) namesShort[i]);
    180     XtFree ((char *) namesShort);
    181 
    182     if (namesLong)
    183     {
    184 	for (i = 0; i < count; i++)
    185 	    if (lockFlags[i])
    186 		XtFree ((char *) namesLong[i]);
    187 	XtFree ((char *) namesLong);
    188     }
    189 
    190     XtFree ((char *) lockFlags);
    191 }
    192 
    193 
    194 
    195 static void
    197 SessionSelected(int number, Bool highlight)
    198 {
    199     if (number >= 0)
    200     {
    201 	Bool locked = sessionsLocked[number];
    202 
    203 	if (highlight)
    204 	    XawListHighlight (chooseSessionListWidget, number);
    205 
    206 	XtSetSensitive (chooseSessionLoadButton, !locked);
    207 	XtSetSensitive (chooseSessionDeleteButton, !locked);
    208 	XtSetSensitive (chooseSessionBreakLockButton, locked);
    209     }
    210     else
    211     {
    212 	XtSetSensitive (chooseSessionLoadButton, False);
    213 	XtSetSensitive (chooseSessionDeleteButton, False);
    214 	XtSetSensitive (chooseSessionBreakLockButton, False);
    215     }
    216 }
    217 
    218 
    219 
    220 static void
    222 AddSessionNames(int count, String *names)
    223 {
    224     int i;
    225 
    226     XawListChange (chooseSessionListWidget, names, count, 0, True);
    227 
    228     /*
    229      * Highlight the first unlocked session, if any.
    230      */
    231 
    232     for (i = 0; i < sessionNameCount; i++)
    233 	if (!sessionsLocked[i])
    234 	    break;
    235 
    236     SessionSelected (i < sessionNameCount ? i : -1, True);
    237 }
    238 
    239 
    240 
    241 void
    243 ChooseWindowStructureNotifyXtHandler(Widget w, XtPointer closure,
    244 				     XEvent *event,
    245 				     Boolean *continue_to_dispatch)
    246 {
    247     if (event->type == MapNotify)
    248     {
    249 	/*
    250 	 * Set the input focus to the choose window and direct all keyboard
    251 	 * events to the list widget.  This way, the user can make selections
    252 	 * using the keyboard.
    253 	 */
    254 
    255 	XtSetKeyboardFocus (chooseSessionPopup, chooseSessionListWidget);
    256 
    257 	XSetInputFocus (XtDisplay (topLevel), XtWindow (chooseSessionPopup),
    258 	    RevertToPointerRoot, CurrentTime);
    259 
    260 	XSync (XtDisplay (topLevel), 0);
    261 
    262 	XtRemoveEventHandler (chooseSessionPopup, StructureNotifyMask, False,
    263 	    ChooseWindowStructureNotifyXtHandler, NULL);
    264     }
    265 }
    266 
    267 
    268 void
    269 ChooseSession(void)
    270 {
    271     Dimension   width, height;
    272     Position	x, y;
    273 
    274 
    275     /*
    276      * Add the session names to the list
    277      */
    278 
    279     AddSessionNames (sessionNameCount, sessionNamesLong);
    280 
    281 
    282     /*
    283      * Center popup containing choice of sessions
    284      */
    285 
    286     XtRealizeWidget (chooseSessionPopup);
    287 
    288     XtVaGetValues (chooseSessionPopup,
    289 	XtNwidth, &width,
    290 	XtNheight, &height,
    291 	NULL);
    292 
    293     x = (Position)(WidthOfScreen (XtScreen (topLevel)) - width) / 2;
    294     y = (Position)(HeightOfScreen (XtScreen (topLevel)) - height) / 3;
    295 
    296     XtVaSetValues (chooseSessionPopup,
    297 	XtNx, x,
    298 	XtNy, y,
    299 	NULL);
    300 
    301     XtVaSetValues (chooseSessionListWidget,
    302 	XtNlongest, width,
    303 	NULL);
    304 
    305     XtVaSetValues (chooseSessionLabel,
    306 	XtNwidth, width,
    307 	NULL);
    308 
    309     XtVaGetValues (chooseSessionMessageLabel,
    310 	XtNforeground, &save_message_foreground,
    311 	XtNbackground, &save_message_background,
    312 	NULL);
    313 
    314     XtVaSetValues (chooseSessionMessageLabel,
    315 	XtNwidth, width,
    316 	XtNforeground, save_message_background,
    317 	NULL);
    318 
    319     /*
    320      * Wait for a map notify on the popup, then set input focus.
    321      */
    322 
    323     XtAddEventHandler (chooseSessionPopup, StructureNotifyMask, False,
    324 	ChooseWindowStructureNotifyXtHandler, NULL);
    325 
    326     XtPopup (chooseSessionPopup, XtGrabNone);
    327 }
    328 
    329 
    330 
    331 static void
    333 CheckDeleteCancel (void)
    334 {
    335     if (delete_session_phase > 0)
    336     {
    337 	XtVaSetValues (chooseSessionMessageLabel,
    338 	    XtNforeground, save_message_background,
    339             NULL);
    340 
    341 	delete_session_phase = 0;
    342     }
    343 }
    344 
    345 
    346 static void
    347 CheckBreakLockCancel(void)
    348 {
    349     if (break_lock_phase > 0)
    350     {
    351 	XtVaSetValues (chooseSessionMessageLabel,
    352 	    XtNforeground, save_message_background,
    353             NULL);
    354 
    355 	break_lock_phase = 0;
    356     }
    357 }
    358 
    359 
    360 
    361 static void
    363 ChooseSessionUp(Widget w, XEvent *event, String *params, Cardinal *numParams)
    364 {
    365     XawListReturnStruct *current;
    366 
    367     CheckDeleteCancel ();
    368     CheckBreakLockCancel ();
    369 
    370     current = XawListShowCurrent (chooseSessionListWidget);
    371     if (current->list_index > 0)
    372 	SessionSelected (current->list_index - 1, True);
    373     XtFree ((char *) current);
    374 }
    375 
    376 
    377 static void
    378 ChooseSessionDown(Widget w, XEvent *event, String *params, Cardinal *numParams)
    379 {
    380     XawListReturnStruct *current;
    381 
    382     CheckDeleteCancel ();
    383     CheckBreakLockCancel ();
    384 
    385     current = XawListShowCurrent (chooseSessionListWidget);
    386     if (current->list_index < sessionNameCount - 1)
    387 	SessionSelected (current->list_index + 1, True);
    388     XtFree ((char *) current);
    389 }
    390 
    391 
    392 
    393 static void
    395 ChooseSessionBtn1Down(Widget w, XEvent *event, String *params,
    396 		      Cardinal *numParams)
    397 {
    398     XawListReturnStruct *current;
    399 
    400     CheckDeleteCancel ();
    401     CheckBreakLockCancel ();
    402 
    403     current = XawListShowCurrent (chooseSessionListWidget);
    404     SessionSelected (current->list_index, False /* already highlighted */);
    405     XtFree ((char *) current);
    406 }
    407 
    408 
    409 
    410 static void
    412 ChooseSessionLoadXtProc(Widget w, XtPointer client_data, XtPointer callData)
    413 {
    414     XawListReturnStruct *current;
    415 
    416     CheckDeleteCancel ();
    417     CheckBreakLockCancel ();
    418 
    419     current = XawListShowCurrent (chooseSessionListWidget);
    420 
    421     if (!current || !current->string || *(current->string) == '\0')
    422     {
    423 	if (current)
    424 	    XtFree ((char *) current);
    425 #ifdef XKB
    426 	XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
    427 #else
    428 	XBell (XtDisplay (topLevel), 0);
    429 #endif
    430 	return;
    431     }
    432 
    433     /*
    434      * Pop down choice of sessions and start the specified session.
    435      */
    436 
    437     XtPopdown (chooseSessionPopup);
    438 
    439     if (session_name)
    440 	XtFree (session_name);
    441 
    442     session_name = XtNewString (current->string);
    443 
    444     XtFree ((char *) current);
    445 
    446     FreeSessionNames (sessionNameCount,
    447 	sessionNamesShort, sessionNamesLong, sessionsLocked);
    448 
    449 
    450     /*
    451      * Start the session, looking for .XSM-<session name> startup file.
    452      */
    453 
    454     if (!StartSession (session_name, False))
    455 	UnableToLockSession (session_name);
    456 }
    457 
    458 
    459 
    460 static void
    462 ChooseSessionDeleteXtProc(Widget w, XtPointer client_data, XtPointer callData)
    463 {
    464     XawListReturnStruct *current;
    465     int longest;
    466     String name;
    467 
    468     CheckBreakLockCancel ();
    469 
    470     current = XawListShowCurrent (chooseSessionListWidget);
    471 
    472     if (!current || !(name = current->string) || *name == '\0')
    473     {
    474 	if (current)
    475 	    XtFree ((char *) current);
    476 #ifdef XKB
    477 	XkbStdBell(XtDisplay(w),XtWindow(w),0,XkbBI_BadValue);
    478 #else
    479 	XBell (XtDisplay (topLevel), 0);
    480 #endif
    481 	return;
    482     }
    483 
    484     delete_session_phase++;
    485 
    486     if (delete_session_phase == 1)
    487     {
    488 	XtVaSetValues (chooseSessionMessageLabel,
    489 	    XtNforeground, save_message_foreground,
    490             NULL);
    491 
    492 #ifdef XKB
    493 	XkbStdBell(XtDisplay(w),XtWindow(w),0,XkbBI_BadValue);
    494 #else
    495 	XBell (XtDisplay (topLevel), 0);
    496 #endif
    497     }
    498     else
    499     {
    500 	XtVaSetValues (chooseSessionMessageLabel,
    501 	    XtNforeground, save_message_background,
    502             NULL);
    503 
    504 	if (DeleteSession (name))
    505 	{
    506 	    int i, j;
    507 
    508 	    for (i = 0; i < sessionNameCount; i++)
    509 	    {
    510 		if (strcmp (sessionNamesLong[i], name) == 0)
    511 		{
    512 		    XtFree ((char *) sessionNamesShort[i]);
    513 
    514 		    if (sessionsLocked[i])
    515 			XtFree ((char *) sessionNamesLong[i]);
    516 
    517 		    for (j = i; j < sessionNameCount - 1; j++)
    518 		    {
    519 			sessionNamesLong[j] = sessionNamesLong[j + 1];
    520 			sessionNamesShort[j] = sessionNamesShort[j + 1];
    521 			sessionsLocked[j] = sessionsLocked[j + 1];
    522 		    }
    523 		    sessionNameCount--;
    524 		    break;
    525 		}
    526 	    }
    527 
    528 	    if (sessionNameCount == 0)
    529 	    {
    530 		XtSetSensitive (chooseSessionLoadButton, 0);
    531 		XtSetSensitive (chooseSessionDeleteButton, 0);
    532 		XtUnmanageChild (chooseSessionListWidget);
    533 	    }
    534 	    else
    535 	    {
    536 		XtVaGetValues (chooseSessionListWidget,
    537 		    XtNlongest, &longest,
    538 		    NULL);
    539 
    540 		XawListChange (chooseSessionListWidget,
    541 		    sessionNamesLong, sessionNameCount, longest, True);
    542 
    543 		SessionSelected (-1, False);
    544 	    }
    545 	}
    546 
    547 	delete_session_phase = 0;
    548     }
    549 
    550     XtFree ((char *) current);
    551 }
    552 
    553 
    554 
    555 static void
    557 ChooseSessionBreakLockXtProc(Widget w, XtPointer client_data,
    558 			     XtPointer callData)
    559 {
    560     XawListReturnStruct *current;
    561     String name;
    562 
    563     CheckDeleteCancel ();
    564 
    565     current = XawListShowCurrent (chooseSessionListWidget);
    566 
    567     if (!current || !(name = current->string) || *name == '\0')
    568     {
    569 	if (current)
    570 	    XtFree ((char *) current);
    571 #ifdef XKB
    572 	XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
    573 #else
    574 	XBell (XtDisplay (topLevel), 0);
    575 #endif
    576 	return;
    577     }
    578 
    579     break_lock_phase++;
    580 
    581     if (break_lock_phase == 1)
    582     {
    583 	XtVaSetValues (chooseSessionMessageLabel,
    584 	    XtNforeground, save_message_foreground,
    585             NULL);
    586 
    587 #ifdef XKB
    588 	XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
    589 #else
    590 	XBell (XtDisplay (topLevel), 0);
    591 #endif
    592     }
    593     else
    594     {
    595 	int longest;
    596 
    597 	XtVaSetValues (chooseSessionMessageLabel,
    598 	    XtNforeground, save_message_background,
    599             NULL);
    600 
    601 	name = sessionNamesShort[current->list_index];
    602 
    603 	(void) GetLockId (name);
    604 
    605 	UnlockSession (name);
    606 
    607 	sessionsLocked[current->list_index] = False;
    608 	XtFree ((char *) sessionNamesLong[current->list_index]);
    609 	sessionNamesLong[current->list_index] =
    610 	    sessionNamesShort[current->list_index];
    611 
    612 	XtVaGetValues (chooseSessionListWidget,
    613 	    XtNlongest, &longest,
    614 	    NULL);
    615 
    616 	XawListChange (chooseSessionListWidget,
    617 	    sessionNamesLong, sessionNameCount, longest, True);
    618 
    619 	SessionSelected (current->list_index, True);
    620 
    621 	break_lock_phase = 0;
    622     }
    623 
    624     XtFree ((char *) current);
    625 }
    626 
    627 
    628 
    629 static void
    631 ChooseSessionFailSafeXtProc(Widget w, XtPointer client_data,
    632 			    XtPointer callData)
    633 {
    634     /*
    635      * Pop down choice of sessions, and start the fail safe session.
    636      */
    637 
    638     CheckDeleteCancel ();
    639     CheckBreakLockCancel ();
    640 
    641     XtPopdown (chooseSessionPopup);
    642 
    643     if (session_name)
    644 	XtFree (session_name);
    645 
    646     session_name = XtNewString (FAILSAFE_SESSION_NAME);
    647 
    648     FreeSessionNames (sessionNameCount,
    649 	sessionNamesShort, sessionNamesLong, sessionsLocked);
    650 
    651 
    652     /*
    653      * We don't need to check return value of StartSession in this case,
    654      * because we are using the default session, and StartSession will
    655      * not try to lock the session at this time.  It will try to lock
    656      * it as soon as the user gives the session a name.
    657      */
    658 
    659     StartSession (session_name,
    660 	True /* Use ~/.xsmstartup if found, else system.xsm */);
    661 }
    662 
    663 
    664 
    665 static void
    667 ChooseSessionCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
    668 {
    669     if (delete_session_phase > 0 || break_lock_phase > 0)
    670     {
    671 	XtVaSetValues (chooseSessionMessageLabel,
    672 	    XtNforeground, save_message_background,
    673             NULL);
    674 
    675 	delete_session_phase = 0;
    676 	break_lock_phase = 0;
    677     }
    678     else
    679 	EndSession (2);
    680 }
    681 
    682 
    683 
    684 void
    686 create_choose_session_popup(void)
    687 
    688 {
    689     static XtActionsRec choose_actions[] = {
    690         {"ChooseSessionUp", ChooseSessionUp},
    691         {"ChooseSessionDown", ChooseSessionDown},
    692         {"ChooseSessionBtn1Down", ChooseSessionBtn1Down}
    693     };
    694 
    695     /*
    696      * Pop up for choosing session at startup
    697      */
    698 
    699     chooseSessionPopup = XtVaCreatePopupShell (
    700 	"chooseSessionPopup", transientShellWidgetClass, topLevel,
    701 	XtNallowShellResize, True,
    702 	NULL);
    703 
    704 
    705     chooseSessionForm = XtVaCreateManagedWidget (
    706 	"chooseSessionForm", formWidgetClass, chooseSessionPopup,
    707 	NULL);
    708 
    709 
    710     chooseSessionLabel = XtVaCreateManagedWidget (
    711 	"chooseSessionLabel", labelWidgetClass, chooseSessionForm,
    712         XtNfromHoriz, NULL,
    713         XtNfromVert, NULL,
    714         XtNborderWidth, 0,
    715 	XtNresizable, True,
    716 	XtNjustify, XtJustifyCenter,
    717 	NULL);
    718 
    719     chooseSessionListWidget = XtVaCreateManagedWidget (
    720 	"chooseSessionListWidget", listWidgetClass, chooseSessionForm,
    721 	XtNresizable, True,
    722         XtNdefaultColumns, 1,
    723 	XtNforceColumns, True,
    724         XtNfromHoriz, NULL,
    725         XtNfromVert, chooseSessionLabel,
    726 	XtNvertDistance, 25,
    727 	NULL);
    728 
    729     chooseSessionMessageLabel = XtVaCreateManagedWidget (
    730 	"chooseSessionMessageLabel", labelWidgetClass, chooseSessionForm,
    731         XtNfromHoriz, NULL,
    732         XtNfromVert, chooseSessionListWidget,
    733         XtNborderWidth, 0,
    734 	XtNresizable, True,
    735 	XtNjustify, XtJustifyCenter,
    736 	NULL);
    737 
    738     chooseSessionLoadButton = XtVaCreateManagedWidget (
    739 	"chooseSessionLoadButton", commandWidgetClass, chooseSessionForm,
    740         XtNfromHoriz, NULL,
    741         XtNfromVert, chooseSessionMessageLabel,
    742         NULL);
    743 
    744     XtAddCallback (chooseSessionLoadButton, XtNcallback,
    745 	ChooseSessionLoadXtProc, NULL);
    746 
    747     chooseSessionDeleteButton = XtVaCreateManagedWidget (
    748 	"chooseSessionDeleteButton", commandWidgetClass, chooseSessionForm,
    749         XtNfromHoriz, chooseSessionLoadButton,
    750         XtNfromVert, chooseSessionMessageLabel,
    751         NULL);
    752 
    753     XtAddCallback (chooseSessionDeleteButton, XtNcallback,
    754 	ChooseSessionDeleteXtProc, NULL);
    755 
    756     chooseSessionBreakLockButton = XtVaCreateManagedWidget (
    757 	"chooseSessionBreakLockButton",
    758 	commandWidgetClass, chooseSessionForm,
    759         XtNfromHoriz, chooseSessionDeleteButton,
    760         XtNfromVert, chooseSessionMessageLabel,
    761         NULL);
    762 
    763     XtAddCallback (chooseSessionBreakLockButton, XtNcallback,
    764 	ChooseSessionBreakLockXtProc, NULL);
    765 
    766     chooseSessionFailSafeButton = XtVaCreateManagedWidget (
    767 	"chooseSessionFailSafeButton", commandWidgetClass, chooseSessionForm,
    768         XtNfromHoriz, chooseSessionBreakLockButton,
    769         XtNfromVert, chooseSessionMessageLabel,
    770         NULL);
    771 
    772     XtAddCallback (chooseSessionFailSafeButton, XtNcallback,
    773 	ChooseSessionFailSafeXtProc, NULL);
    774 
    775 
    776     chooseSessionCancelButton = XtVaCreateManagedWidget (
    777 	"chooseSessionCancelButton", commandWidgetClass, chooseSessionForm,
    778         XtNfromHoriz, chooseSessionFailSafeButton,
    779         XtNfromVert, chooseSessionMessageLabel,
    780         NULL);
    781 
    782     XtAddCallback (chooseSessionCancelButton, XtNcallback,
    783 	ChooseSessionCancelXtProc, NULL);
    784 
    785     XtAppAddActions (appContext, choose_actions, XtNumber (choose_actions));
    786 
    787     XtInstallAllAccelerators (chooseSessionListWidget, chooseSessionPopup);
    788 }
    789