123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781 |
- /* $Xorg: choose.c,v 1.4 2001/02/09 02:05:59 xorgcvs Exp $ */
- /******************************************************************************
- Copyright 1993, 1998 The Open Group
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of The Open Group shall not be
- used in advertising or otherwise to promote the sale, use or other dealings
- in this Software without prior written authorization from The Open Group.
- ******************************************************************************/
- /* $XFree86: xc/programs/xsm/choose.c,v 1.6tsi Exp $ */
- #include "xsm.h"
- #include "saveutil.h"
- #include "lock.h"
- #include "choose.h"
- #include <sys/types.h>
- #include <X11/Shell.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/List.h>
- #include <X11/Xaw/Command.h>
- #ifndef X_NOT_POSIX
- #include <dirent.h>
- #else
- #ifdef SYSV
- #include <dirent.h>
- #else
- #ifdef USG
- #include <dirent.h>
- #else
- #include <sys/dir.h>
- #ifndef dirent
- #define dirent direct
- #endif
- #endif
- #endif
- #endif
- static Pixel save_message_foreground;
- static Pixel save_message_background;
- static int delete_session_phase = 0;
- static int break_lock_phase = 0;
- static Widget chooseSessionPopup;
- static Widget chooseSessionForm;
- static Widget chooseSessionLabel;
- static Widget chooseSessionListWidget;
- static Widget chooseSessionMessageLabel;
- static Widget chooseSessionLoadButton;
- static Widget chooseSessionDeleteButton;
- static Widget chooseSessionBreakLockButton;
- static Widget chooseSessionFailSafeButton;
- static Widget chooseSessionCancelButton;
- int
- GetSessionNames(int *count_ret, String **short_names_ret,
- String **long_names_ret, Bool **locked_ret)
- {
- DIR *dir;
- struct dirent *entry;
- const char *path;
- int count;
- path = getenv ("SM_SAVE_DIR");
- if (!path)
- {
- path = getenv ("HOME");
- if (!path)
- path = ".";
- }
-
- *count_ret = 0;
- *short_names_ret = NULL;
- *locked_ret = NULL;
- if (long_names_ret)
- *long_names_ret = NULL;
- if ((dir = opendir (path)) == NULL)
- return 0;
- count = 0;
- while ((entry = readdir (dir)) != NULL)
- {
- if (strncmp (entry->d_name, ".XSM-", 5) == 0)
- count++;
- }
- if (count == 0 ||
- ((*short_names_ret = (String *) XtMalloc (
- count * sizeof (String))) == NULL) ||
- (long_names_ret && (*long_names_ret =
- (String *) XtMalloc (count * sizeof (String))) == NULL) ||
- ((*locked_ret = (Bool *) XtMalloc (count * sizeof (Bool))) == NULL))
- {
- closedir (dir);
- if (*short_names_ret)
- XtFree ((char *) *short_names_ret);
- if (long_names_ret && *long_names_ret)
- XtFree ((char *) *long_names_ret);
- return 0;
- }
- rewinddir (dir);
- while ((entry = readdir (dir)) != NULL && *count_ret < count)
- {
- if (strncmp (entry->d_name, ".XSM-", 5) == 0)
- {
- char *name = (char *) entry->d_name + 5;
- char *id = NULL;
- Bool locked = CheckSessionLocked (name, long_names_ret!=NULL, &id);
- (*short_names_ret)[*count_ret] = XtNewString (name);
- (*locked_ret)[*count_ret] = locked;
- if (long_names_ret)
- {
- if (!locked)
- {
- (*long_names_ret)[*count_ret] =
- (*short_names_ret)[*count_ret];
- }
- else
- {
- char *host = ((char *) strchr (id, '/')) + 1;
- char *colon = (char *) strrchr (host, ':');
- char *lockmsg;
- /* backtrack over previous colon if there are 2 (DECnet),
- but not three (IPv6) */
- if ((*(colon - 1) == ':') && (*(colon - 2) != ':'))
- colon--;
- *colon = '\0';
- XtAsprintf (&lockmsg, "%s (locked at %s)", name, host);
- (*long_names_ret)[*count_ret] = lockmsg;
- *colon = ':';
- XtFree (id);
- }
- }
- (*count_ret)++;
- }
- }
- closedir (dir);
- return 1;
- }
- void
- FreeSessionNames(int count, String *namesShort, String *namesLong,
- Bool *lockFlags)
- {
- int i;
- for (i = 0; i < count; i++)
- XtFree ((char *) namesShort[i]);
- XtFree ((char *) namesShort);
- if (namesLong)
- {
- for (i = 0; i < count; i++)
- if (lockFlags[i])
- XtFree ((char *) namesLong[i]);
- XtFree ((char *) namesLong);
- }
- XtFree ((char *) lockFlags);
- }
- static void
- SessionSelected(int number, Bool highlight)
- {
- if (number >= 0)
- {
- Bool locked = sessionsLocked[number];
- if (highlight)
- XawListHighlight (chooseSessionListWidget, number);
- XtSetSensitive (chooseSessionLoadButton, !locked);
- XtSetSensitive (chooseSessionDeleteButton, !locked);
- XtSetSensitive (chooseSessionBreakLockButton, locked);
- }
- else
- {
- XtSetSensitive (chooseSessionLoadButton, False);
- XtSetSensitive (chooseSessionDeleteButton, False);
- XtSetSensitive (chooseSessionBreakLockButton, False);
- }
- }
- static void
- AddSessionNames(int count, String *names)
- {
- int i;
- XawListChange (chooseSessionListWidget, names, count, 0, True);
- /*
- * Highlight the first unlocked session, if any.
- */
- for (i = 0; i < sessionNameCount; i++)
- if (!sessionsLocked[i])
- break;
- SessionSelected (i < sessionNameCount ? i : -1, True);
- }
- void
- ChooseWindowStructureNotifyXtHandler(Widget w, XtPointer closure,
- XEvent *event,
- Boolean *continue_to_dispatch)
- {
- if (event->type == MapNotify)
- {
- /*
- * Set the input focus to the choose window and direct all keyboard
- * events to the list widget. This way, the user can make selections
- * using the keyboard.
- */
- XtSetKeyboardFocus (chooseSessionPopup, chooseSessionListWidget);
- XSetInputFocus (XtDisplay (topLevel), XtWindow (chooseSessionPopup),
- RevertToPointerRoot, CurrentTime);
- XSync (XtDisplay (topLevel), 0);
- XtRemoveEventHandler (chooseSessionPopup, StructureNotifyMask, False,
- ChooseWindowStructureNotifyXtHandler, NULL);
- }
- }
- void
- ChooseSession(void)
- {
- Dimension width, height;
- Position x, y;
- /*
- * Add the session names to the list
- */
- AddSessionNames (sessionNameCount, sessionNamesLong);
- /*
- * Center popup containing choice of sessions
- */
-
- XtRealizeWidget (chooseSessionPopup);
- XtVaGetValues (chooseSessionPopup,
- XtNwidth, &width,
- XtNheight, &height,
- NULL);
- x = (Position)(WidthOfScreen (XtScreen (topLevel)) - width) / 2;
- y = (Position)(HeightOfScreen (XtScreen (topLevel)) - height) / 3;
- XtVaSetValues (chooseSessionPopup,
- XtNx, x,
- XtNy, y,
- NULL);
- XtVaSetValues (chooseSessionListWidget,
- XtNlongest, width,
- NULL);
- XtVaSetValues (chooseSessionLabel,
- XtNwidth, width,
- NULL);
- XtVaGetValues (chooseSessionMessageLabel,
- XtNforeground, &save_message_foreground,
- XtNbackground, &save_message_background,
- NULL);
- XtVaSetValues (chooseSessionMessageLabel,
- XtNwidth, width,
- XtNforeground, save_message_background,
- NULL);
- /*
- * Wait for a map notify on the popup, then set input focus.
- */
- XtAddEventHandler (chooseSessionPopup, StructureNotifyMask, False,
- ChooseWindowStructureNotifyXtHandler, NULL);
- XtPopup (chooseSessionPopup, XtGrabNone);
- }
- static void
- CheckDeleteCancel (void)
- {
- if (delete_session_phase > 0)
- {
- XtVaSetValues (chooseSessionMessageLabel,
- XtNforeground, save_message_background,
- NULL);
- delete_session_phase = 0;
- }
- }
- static void
- CheckBreakLockCancel(void)
- {
- if (break_lock_phase > 0)
- {
- XtVaSetValues (chooseSessionMessageLabel,
- XtNforeground, save_message_background,
- NULL);
- break_lock_phase = 0;
- }
- }
- static void
- ChooseSessionUp(Widget w, XEvent *event, String *params, Cardinal *numParams)
- {
- XawListReturnStruct *current;
-
- CheckDeleteCancel ();
- CheckBreakLockCancel ();
- current = XawListShowCurrent (chooseSessionListWidget);
- if (current->list_index > 0)
- SessionSelected (current->list_index - 1, True);
- XtFree ((char *) current);
- }
- static void
- ChooseSessionDown(Widget w, XEvent *event, String *params, Cardinal *numParams)
- {
- XawListReturnStruct *current;
-
- CheckDeleteCancel ();
- CheckBreakLockCancel ();
- current = XawListShowCurrent (chooseSessionListWidget);
- if (current->list_index < sessionNameCount - 1)
- SessionSelected (current->list_index + 1, True);
- XtFree ((char *) current);
- }
- static void
- ChooseSessionBtn1Down(Widget w, XEvent *event, String *params,
- Cardinal *numParams)
- {
- XawListReturnStruct *current;
- CheckDeleteCancel ();
- CheckBreakLockCancel ();
- current = XawListShowCurrent (chooseSessionListWidget);
- SessionSelected (current->list_index, False /* already highlighted */);
- XtFree ((char *) current);
- }
- static void
- ChooseSessionLoadXtProc(Widget w, XtPointer client_data, XtPointer callData)
- {
- XawListReturnStruct *current;
- CheckDeleteCancel ();
- CheckBreakLockCancel ();
- current = XawListShowCurrent (chooseSessionListWidget);
- if (!current || !current->string || *(current->string) == '\0')
- {
- if (current)
- XtFree ((char *) current);
- #ifdef XKB
- XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
- #else
- XBell (XtDisplay (topLevel), 0);
- #endif
- return;
- }
- /*
- * Pop down choice of sessions and start the specified session.
- */
- XtPopdown (chooseSessionPopup);
- if (session_name)
- XtFree (session_name);
- session_name = XtNewString (current->string);
- XtFree ((char *) current);
- FreeSessionNames (sessionNameCount,
- sessionNamesShort, sessionNamesLong, sessionsLocked);
- /*
- * Start the session, looking for .XSM-<session name> startup file.
- */
- if (!StartSession (session_name, False))
- UnableToLockSession (session_name);
- }
- static void
- ChooseSessionDeleteXtProc(Widget w, XtPointer client_data, XtPointer callData)
- {
- XawListReturnStruct *current;
- int longest;
- char *name;
- CheckBreakLockCancel ();
- current = XawListShowCurrent (chooseSessionListWidget);
- if (!current || !(name = current->string) || *name == '\0')
- {
- if (current)
- XtFree ((char *) current);
- #ifdef XKB
- XkbStdBell(XtDisplay(w),XtWindow(w),0,XkbBI_BadValue);
- #else
- XBell (XtDisplay (topLevel), 0);
- #endif
- return;
- }
- delete_session_phase++;
- if (delete_session_phase == 1)
- {
- XtVaSetValues (chooseSessionMessageLabel,
- XtNforeground, save_message_foreground,
- NULL);
- #ifdef XKB
- XkbStdBell(XtDisplay(w),XtWindow(w),0,XkbBI_BadValue);
- #else
- XBell (XtDisplay (topLevel), 0);
- #endif
- }
- else
- {
- XtVaSetValues (chooseSessionMessageLabel,
- XtNforeground, save_message_background,
- NULL);
- if (DeleteSession (name))
- {
- int i, j;
- for (i = 0; i < sessionNameCount; i++)
- {
- if (strcmp (sessionNamesLong[i], name) == 0)
- {
- XtFree ((char *) sessionNamesShort[i]);
- if (sessionsLocked[i])
- XtFree ((char *) sessionNamesLong[i]);
- for (j = i; j < sessionNameCount - 1; j++)
- {
- sessionNamesLong[j] = sessionNamesLong[j + 1];
- sessionNamesShort[j] = sessionNamesShort[j + 1];
- sessionsLocked[j] = sessionsLocked[j + 1];
- }
- sessionNameCount--;
- break;
- }
- }
- if (sessionNameCount == 0)
- {
- XtSetSensitive (chooseSessionLoadButton, 0);
- XtSetSensitive (chooseSessionDeleteButton, 0);
- XtUnmanageChild (chooseSessionListWidget);
- }
- else
- {
- XtVaGetValues (chooseSessionListWidget,
- XtNlongest, &longest,
- NULL);
- XawListChange (chooseSessionListWidget,
- sessionNamesLong, sessionNameCount, longest, True);
- SessionSelected (-1, False);
- }
- }
- delete_session_phase = 0;
- }
- XtFree ((char *) current);
- }
- static void
- ChooseSessionBreakLockXtProc(Widget w, XtPointer client_data,
- XtPointer callData)
- {
- XawListReturnStruct *current;
- char *name;
- CheckDeleteCancel ();
- current = XawListShowCurrent (chooseSessionListWidget);
- if (!current || !(name = current->string) || *name == '\0')
- {
- if (current)
- XtFree ((char *) current);
- #ifdef XKB
- XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
- #else
- XBell (XtDisplay (topLevel), 0);
- #endif
- return;
- }
- break_lock_phase++;
- if (break_lock_phase == 1)
- {
- XtVaSetValues (chooseSessionMessageLabel,
- XtNforeground, save_message_foreground,
- NULL);
- #ifdef XKB
- XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_BadValue);
- #else
- XBell (XtDisplay (topLevel), 0);
- #endif
- }
- else
- {
- int longest;
- XtVaSetValues (chooseSessionMessageLabel,
- XtNforeground, save_message_background,
- NULL);
- name = sessionNamesShort[current->list_index];
- (void) GetLockId (name);
- UnlockSession (name);
- sessionsLocked[current->list_index] = False;
- XtFree ((char *) sessionNamesLong[current->list_index]);
- sessionNamesLong[current->list_index] =
- sessionNamesShort[current->list_index];
- XtVaGetValues (chooseSessionListWidget,
- XtNlongest, &longest,
- NULL);
- XawListChange (chooseSessionListWidget,
- sessionNamesLong, sessionNameCount, longest, True);
- SessionSelected (current->list_index, True);
- break_lock_phase = 0;
- }
- XtFree ((char *) current);
- }
- static void
- ChooseSessionFailSafeXtProc(Widget w, XtPointer client_data,
- XtPointer callData)
- {
- /*
- * Pop down choice of sessions, and start the fail safe session.
- */
- CheckDeleteCancel ();
- CheckBreakLockCancel ();
- XtPopdown (chooseSessionPopup);
- if (session_name)
- XtFree (session_name);
- session_name = XtNewString (FAILSAFE_SESSION_NAME);
- FreeSessionNames (sessionNameCount,
- sessionNamesShort, sessionNamesLong, sessionsLocked);
- /*
- * We don't need to check return value of StartSession in this case,
- * because we are using the default session, and StartSession will
- * not try to lock the session at this time. It will try to lock
- * it as soon as the user gives the session a name.
- */
- StartSession (session_name,
- True /* Use ~/.xsmstartup if found, else system.xsm */);
- }
- static void
- ChooseSessionCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
- {
- if (delete_session_phase > 0 || break_lock_phase > 0)
- {
- XtVaSetValues (chooseSessionMessageLabel,
- XtNforeground, save_message_background,
- NULL);
- delete_session_phase = 0;
- break_lock_phase = 0;
- }
- else
- EndSession (2);
- }
- void
- create_choose_session_popup(void)
- {
- static XtActionsRec choose_actions[] = {
- {"ChooseSessionUp", ChooseSessionUp},
- {"ChooseSessionDown", ChooseSessionDown},
- {"ChooseSessionBtn1Down", ChooseSessionBtn1Down}
- };
- /*
- * Pop up for choosing session at startup
- */
- chooseSessionPopup = XtVaCreatePopupShell (
- "chooseSessionPopup", transientShellWidgetClass, topLevel,
- XtNallowShellResize, True,
- NULL);
-
- chooseSessionForm = XtVaCreateManagedWidget (
- "chooseSessionForm", formWidgetClass, chooseSessionPopup,
- NULL);
- chooseSessionLabel = XtVaCreateManagedWidget (
- "chooseSessionLabel", labelWidgetClass, chooseSessionForm,
- XtNfromHoriz, NULL,
- XtNfromVert, NULL,
- XtNborderWidth, 0,
- XtNresizable, True,
- XtNjustify, XtJustifyCenter,
- NULL);
- chooseSessionListWidget = XtVaCreateManagedWidget (
- "chooseSessionListWidget", listWidgetClass, chooseSessionForm,
- XtNresizable, True,
- XtNdefaultColumns, 1,
- XtNforceColumns, True,
- XtNfromHoriz, NULL,
- XtNfromVert, chooseSessionLabel,
- XtNvertDistance, 25,
- NULL);
- chooseSessionMessageLabel = XtVaCreateManagedWidget (
- "chooseSessionMessageLabel", labelWidgetClass, chooseSessionForm,
- XtNfromHoriz, NULL,
- XtNfromVert, chooseSessionListWidget,
- XtNborderWidth, 0,
- XtNresizable, True,
- XtNjustify, XtJustifyCenter,
- NULL);
- chooseSessionLoadButton = XtVaCreateManagedWidget (
- "chooseSessionLoadButton", commandWidgetClass, chooseSessionForm,
- XtNfromHoriz, NULL,
- XtNfromVert, chooseSessionMessageLabel,
- NULL);
- XtAddCallback (chooseSessionLoadButton, XtNcallback,
- ChooseSessionLoadXtProc, NULL);
- chooseSessionDeleteButton = XtVaCreateManagedWidget (
- "chooseSessionDeleteButton", commandWidgetClass, chooseSessionForm,
- XtNfromHoriz, chooseSessionLoadButton,
- XtNfromVert, chooseSessionMessageLabel,
- NULL);
- XtAddCallback (chooseSessionDeleteButton, XtNcallback,
- ChooseSessionDeleteXtProc, NULL);
- chooseSessionBreakLockButton = XtVaCreateManagedWidget (
- "chooseSessionBreakLockButton",
- commandWidgetClass, chooseSessionForm,
- XtNfromHoriz, chooseSessionDeleteButton,
- XtNfromVert, chooseSessionMessageLabel,
- NULL);
- XtAddCallback (chooseSessionBreakLockButton, XtNcallback,
- ChooseSessionBreakLockXtProc, NULL);
- chooseSessionFailSafeButton = XtVaCreateManagedWidget (
- "chooseSessionFailSafeButton", commandWidgetClass, chooseSessionForm,
- XtNfromHoriz, chooseSessionBreakLockButton,
- XtNfromVert, chooseSessionMessageLabel,
- NULL);
- XtAddCallback (chooseSessionFailSafeButton, XtNcallback,
- ChooseSessionFailSafeXtProc, NULL);
- chooseSessionCancelButton = XtVaCreateManagedWidget (
- "chooseSessionCancelButton", commandWidgetClass, chooseSessionForm,
- XtNfromHoriz, chooseSessionFailSafeButton,
- XtNfromVert, chooseSessionMessageLabel,
- NULL);
- XtAddCallback (chooseSessionCancelButton, XtNcallback,
- ChooseSessionCancelXtProc, NULL);
- XtAppAddActions (appContext, choose_actions, XtNumber (choose_actions));
- XtInstallAllAccelerators (chooseSessionListWidget, chooseSessionPopup);
- }
|