Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtsession / SmUI.c
1 /* $TOG: SmUI.c /main/32 1998/07/23 18:08:17 mgreess $ */
2 /*                                                                      *
3  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
4  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
5  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
6  * (c) Copyright 1993, 1994 Novell, Inc.                                *
7  */
8
9 /*************************************<+>*************************************
10  *****************************************************************************
11  **
12  **  File:        SmUI.c
13  **
14  **  Project:     DT Session Manager (dtsession)
15  **
16  **  Description:
17  **  -----------
18  **  This file handles all UI components of the session manager.  This
19  **  includes all dialog boxes.   The session manager does not handle its
20  **  representations in the front panel and customizer.  That is handled
21  **  by those tools.
22  **
23  **
24  **
25  *******************************************************************
26  **  (c) Copyright Hewlett-Packard Company, 1990.  All rights are  
27  **  reserved.  Copying or other reproduction of this program      
28  **  except for archival purposes is prohibited without prior      
29  **  written consent of Hewlett-Packard Company.                     
30  ********************************************************************
31  **
32  **
33  **
34  *****************************************************************************
35  *************************************<+>*************************************/
36
37 #include <signal.h>
38 #include <stdio.h>
39 #include <sys/param.h>
40 #include <X11/Intrinsic.h>
41 #include <Xm/MwmUtil.h>
42 #include <Xm/Xm.h>
43 #include <Xm/PushB.h>
44 #include <Xm/Form.h>
45 #include <Xm/Label.h>
46 #include <Xm/LabelG.h>
47 #include <Xm/DrawingA.h>
48 #include <Xm/Frame.h>
49 #include <Xm/Separator.h>
50 #include <Xm/MessageB.h>
51 #include <Xm/DialogS.h>
52 #include <Xm/Text.h>
53 #include <Dt/DtP.h>
54 #include <Dt/SessionM.h>
55 #include <Dt/Icon.h>
56 #include <Dt/MsgLog.h>
57
58 #include "Sm.h"
59 #include "SmUI.h"
60 #include "SmSave.h"
61 #include "SmHelp.h"
62 #include "SmGlobals.h"
63
64 typedef enum {
65         ConfirmationNone,
66         ConfirmationOK,
67         ConfirmationCancel,
68         ConfirmationHelp
69 } ConfirmState;
70
71 ConfirmState    confirmState;
72
73 /*
74  * #define statements
75  */
76 #define PASSWORD_INDICATOR " "
77
78 typedef struct _ExitRecord {
79   Tt_message     *pmsg;
80   union {
81     Widget exitCancelledDialog;
82     int queryExitConfirmedMode;
83   } u;
84   Boolean       doSave;
85 } ExitRecord;
86
87 /*
88  * Global variables
89  */
90 DialogData      smDD;
91 Arg                     uiArgs[20];
92
93 /*
94  * Local Function Declarations
95  */
96
97 static int CompatModeExit( void ) ;
98 static void ExitConfirmed( Widget, XtPointer, XtPointer ) ;
99 static void ExitCancelled( Widget, XtPointer, XtPointer ) ;
100 static void LockDialogUp( Widget, XtPointer, XtPointer ) ;
101 static void SimpleOK( Widget, XtPointer, XtPointer ) ;
102 static void ConfirmOKCB ( Widget, XtPointer, XtPointer ) ;
103 static void ConfirmCancelCB ( Widget, XtPointer, XtPointer ) ;
104 static void ConfirmHelpCB ( Widget, XtPointer, XtPointer ) ;
105 static void XSMPFailureOKCB( Widget w, XtPointer client_data, XtPointer call_data );
106 static void SaveTimeout( XtPointer , XtIntervalId *) ;
107
108
109 /*
110  * Local vars
111  */
112 static Boolean session_confirmed = False;
113 static Boolean reasonsDialogOK;
114 static Boolean saveTimeout;
115
116
117 \f
118 /*************************************<->*************************************
119  *
120  *  CreateLockDialog ()
121  *
122  *
123  *  Description:
124  *  -----------
125  *  Create the lock dialog when it exists NOT as a part of a cover
126  *
127  *
128  *  Inputs:
129  *  ------
130  *
131  * 
132  *  Outputs:
133  *  -------
134  *  None.
135  *
136  *
137  *  Comments:
138  *  --------
139  * 
140  *************************************<->***********************************/
141 Widget 
142 CreateLockDialog( void )
143 {
144     int         i;
145     Widget      loginLabel, instructLabel, tmpLock, indFrame;
146     Widget      passwdLabel, passwdForm, picFrame, loginPic, loginFrame;
147     Dimension   width;          /* width, height of login label    */
148     XmString    lockString, passwordString;
149     char        *lockMessage;
150     char        *envLog;
151     Pixel       fg, bg, focus_color;  /* foreground, background colors */
152     
153     i = 0;
154     XtSetArg(uiArgs[i], XmNallowShellResize, True); i++;
155     XtSetArg(uiArgs[i], XmNmarginWidth, 0); i++;
156     XtSetArg(uiArgs[i], XmNmarginHeight, 0); i++;
157     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
158     XtSetArg(uiArgs[i], XmNshadowThickness,5); i++;
159     XtSetArg(uiArgs[i], XmNunitType, XmPIXELS); i++;
160     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
161     XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
162     XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
163     XtSetArg(uiArgs[i], XmNmappedWhenManaged, True); i++;
164     tmpLock = XmCreateFormDialog(smGD.topLevelWid, "lockDialog", uiArgs, i);
165     XtAddCallback (XtParent(tmpLock), XmNpopupCallback,
166                    LockDialogUp, NULL);
167     smDD.matte[0] = tmpLock;
168
169     i = 0;
170     XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
171     XtSetArg(uiArgs[i], XmNmwmDecorations, 0);i++;
172     XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
173     XtSetValues(XtParent(tmpLock), uiArgs, i);
174                 
175     i = 0;
176     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
177     XtSetArg(uiArgs[i], XmNshadowThickness, 2); i++; 
178     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_FORM); i++;
179     XtSetArg(uiArgs[i], XmNtopOffset, 15); i++;
180     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_FORM); i++;
181     XtSetArg(uiArgs[i], XmNbottomOffset, 15); i++;
182     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
183     XtSetArg(uiArgs[i], XmNrightOffset, 15); i++;
184     picFrame = XmCreateFrame(tmpLock, "picFrame", uiArgs, i);
185
186         i = 0;
187         XtSetArg(uiArgs[i], XmNforeground, &fg); i++;
188         XtSetArg(uiArgs[i], XmNbackground, &bg); i++;
189         XtGetValues(tmpLock, uiArgs, i);
190
191     i = 0;
192         XtSetArg(uiArgs[i], XmNfillMode, XmFILL_SELF); i++;
193         XtSetArg(uiArgs[i], XmNbehavior, XmICON_LABEL); i++;
194         XtSetArg(uiArgs[i], XmNpixmapForeground, fg); i++;
195         XtSetArg(uiArgs[i], XmNpixmapBackground, bg); i++;
196         XtSetArg(uiArgs[i], XmNstring, NULL); i++;
197         XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++;
198         XtSetArg(uiArgs[i], XmNtraversalOn, False); i++;
199         loginPic = _DtCreateIcon(picFrame, "lockLabelPixmap", uiArgs, i);
200
201     i = 0;
202     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
203     XtSetArg(uiArgs[i], XmNshadowThickness, 2); i++; 
204     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_FORM); i++;
205     XtSetArg(uiArgs[i], XmNtopOffset, 15); i++;
206     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_FORM); i++;
207     XtSetArg(uiArgs[i], XmNbottomOffset, 15); i++;
208     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
209     XtSetArg(uiArgs[i], XmNleftOffset, 15); i++;
210     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_WIDGET); i++;
211     XtSetArg(uiArgs[i], XmNrightOffset, 0); i++;
212     XtSetArg(uiArgs[i], XmNrightWidget, loginPic); i++;
213     loginFrame = XmCreateFrame(tmpLock, "loginFrame", uiArgs, i);
214
215
216     /* 
217      * create the login matte...
218      */
219     i = 0;
220     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
221     smDD.loginMatte[0] = XmCreateForm(loginFrame, "loginMatte", uiArgs, i);
222
223     /*
224      *  create the login/password forms
225      */
226     i = 0;
227     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++; 
228     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
229     XtSetArg(uiArgs[i], XmNrightOffset, 15); i++;
230     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
231     XtSetArg(uiArgs[i], XmNbottomPosition, 50); i++;
232     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
233     XtSetArg(uiArgs[i], XmNleftOffset, 15); i++;
234     smDD.loginForm[0] = XmCreateForm(smDD.loginMatte[0], "loginForm", uiArgs, i);
235
236     i = 0;
237     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
238     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++; 
239     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
240     XtSetArg(uiArgs[i], XmNtopPosition, 50); i++;
241         XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
242         XtSetArg(uiArgs[i], XmNleftWidget, smDD.loginForm[0]); i++;
243         XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
244         XtSetArg(uiArgs[i], XmNrightWidget, smDD.loginForm[0]); i++;
245     passwdForm = XmCreateForm(smDD.loginMatte[0], "passwdForm", uiArgs, i);
246
247
248     /*
249      *  create the login/password labels...
250      */
251     i = 0;
252     envLog = getenv("LOGNAME");
253     lockMessage = XtMalloc(100 + strlen(envLog));
254     sprintf(
255         lockMessage,
256         (char*) GETMESSAGE(18, 1, "Display locked by user %s."), envLog);
257     lockString = XmStringCreateLocalized(lockMessage);
258     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
259     XtSetArg(uiArgs[i], XmNtopPosition, 20); i++;
260     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_CENTER); i++;
261     XtSetArg(uiArgs[i], XmNlabelString, lockString); i++;
262     loginLabel = XmCreateLabelGadget(smDD.loginForm[0],
263                                      "loginLabel", uiArgs, i);
264     XtManageChild(loginLabel);
265     XmStringFree(lockString);
266     XtFree(lockMessage);
267
268     i = 0;
269     lockString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 2, "Enter password to unlock.")));
270     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
271     XtSetArg(uiArgs[i], XmNtopWidget, loginLabel); i++;
272     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_CENTER); i++;
273     XtSetArg(uiArgs[i], XmNlabelString, lockString); i++;
274     instructLabel = XmCreateLabelGadget(smDD.loginForm[0], "instructLabel",
275                                         uiArgs, i);
276     XtManageChild(instructLabel);
277     XmStringFree(lockString);
278
279     i = 0;
280     passwordString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 3, "Password: ")));
281     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
282     XtSetArg(uiArgs[i], XmNtopPosition, 20); i++;
283     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
284     XtSetArg(uiArgs[i], XmNbottomPosition, 80); i++;
285     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
286     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_END); i++;
287     XtSetArg(uiArgs[i], XmNlabelString, passwordString); i++;
288     passwdLabel = XmCreateLabelGadget(passwdForm,
289                                       "passwdLabel", uiArgs, i);
290     XtManageChild(passwdLabel);
291     XmStringFree(passwordString);
292
293     /*
294      * Give the password label an offset
295      */
296     i = 0;
297     XtSetArg(uiArgs[i], XmNwidth, &width);i++;
298     XtGetValues(passwdLabel, uiArgs, i);
299
300     i = 0;
301     width += (width/6);
302     XtSetArg(uiArgs[i], XmNwidth, width);i++;
303     XtSetArg(uiArgs[i], XmNrecomputeSize, False);i++;
304     XtSetValues(passwdLabel, uiArgs, i);
305
306
307     i = 0;
308     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_IN); i++;
309     XtSetArg(uiArgs[i], XmNshadowThickness, 1); i++;
310     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
311     XtSetArg(uiArgs[i], XmNtopPosition, 20); i++;
312     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
313     XtSetArg(uiArgs[i], XmNbottomPosition, 80); i++;
314     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
315     XtSetArg(uiArgs[i], XmNleftWidget, passwdLabel); i++;
316     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
317     XtSetArg(uiArgs[i], XmNrightOffset, 10); i++;
318     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_END); i++;
319     indFrame = XmCreateFrame(passwdForm,  "indFrame", uiArgs, i);
320
321     i = 0;
322     passwordString = XmStringCreateLocalized("|");
323     XtSetArg(uiArgs[i], XmNlabelString, passwordString); i++;
324     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_BEGINNING); i++;
325     smDD.indLabel[0] = XmCreateLabel(indFrame, "indLabel",
326                                         uiArgs, i);
327     XtManageChild(smDD.indLabel[0]);
328     XmStringFree(passwordString);
329
330     i = 0;
331     XtSetArg(uiArgs[i], XmNhighlightColor,  &focus_color); i++;
332     XtGetValues(indFrame, uiArgs, i);
333     XtVaSetValues ( smDD.indLabel[0],
334                     XmNborderWidth, 2,
335                     XmNborderColor,  focus_color, 
336                     NULL );
337     
338     /*
339      * Manage forms AFTER all children have been managed
340      */
341     XtManageChild(indFrame);
342     XtManageChild(passwdForm);
343     XtManageChild(smDD.loginForm[0]);
344     XtManageChild(smDD.loginMatte[0]);
345     XtManageChild(loginPic);
346     XtManageChild(picFrame);
347     XtManageChild(loginFrame);
348
349     return(tmpLock);
350 }
351
352
353 \f
354 /*************************************<->*************************************
355  *
356  *  ExitSession ()
357  *
358  *
359  *  Description:
360  *  -----------
361  *  Determines which exit routines get called when an exit request is made
362  *  of the session manager.  
363  *  If smGD.bmsDead == false, we just exit.
364  *  If ASK_STATE is turned on, the query dialog is
365  *  put up, if VERBOSE is on, confirm exit in current mode (restart or reset)
366  *  if confirmation is turned off - exit immediately.
367  *
368  *
369  *  Inputs:
370  *  ------
371  *  msg -- if non-zero, Session_Exit request to reply/fail && destroy
372  *
373  * 
374  *  Outputs:
375  *  -------
376  *  None.
377  *
378  *
379  *  Comments:
380  *  --------
381  * 
382  *************************************<->***********************************/
383 void
384 ExitSession(
385         Tt_message msg)
386 {
387     if (smGD.bmsDead == True)
388     {
389         ImmediateExit(-1, msg, True);
390     }
391     if(smGD.compatMode == True)
392     {
393         if (msg != 0) {
394             tt_message_reply( msg );
395             tt_message_destroy( msg );
396         }
397         CompatModeExit();
398     }
399     else
400     {
401         if(smSettings.confirmMode == DtSM_VERBOSE_MODE || 
402            smSettings.startState == DtSM_ASK_STATE)
403         {
404             ConfirmExit( msg, True );
405         }
406         else
407         {
408             ImmediateExit(smSettings.startState, msg, True);
409         }
410     }
411 }
412
413
414 \f
415 /*************************************<->*************************************
416  *
417  *  ConfirmExit ()
418  *
419  *
420  *  Description:
421  *  -----------
422  *  Create the exit confirmation dialog box (if it hasn't been) and confirm
423  *  that the user wants to exit the session.  This routine only gets called
424  *  when the user hasn't turned of exit confirmation and is not in ASK mode
425  *
426  *
427  *  Inputs:
428  *  ------
429  *  msg -- if non-zero, Session_Exit request to reply/fail && destroy
430  *
431  * 
432  *  Outputs:
433  *  -------
434  *  None.
435  *
436  *
437  *  Comments:
438  *  --------
439  * 
440  *************************************<->***********************************/
441 int 
442 ConfirmExit( 
443     Tt_message msg,
444     Boolean doSave)
445 {
446     int         i;
447     String      tmpString;
448     ExitRecord  *exitRec;
449     Tt_message  *pmsg;
450     static      XmString homeToHome;    /* started Home, restore to Home */
451     static      XmString returnToCurrent; /* started Home or Current but
452                                             retrun to Current */
453     static      XmString currentToHome; /* started Current, return to Home */
454
455     if(smDD.confExit == NULL)
456     {
457         /*
458          * Create all compound strings for confirmation dialogs
459          */
460         returnToCurrent = XmStringCreateLocalized(((char *)GETMESSAGE(18, 4, 
461                 "Exiting the desktop session...\n\n\
462 Your Current session will be restored upon login.\n\n\
463 Application updates you have not saved will be lost.\n\n\
464 Continue Logout?")));
465
466         homeToHome = XmStringCreateLocalized(((char *)GETMESSAGE(18, 5, 
467                 "Exiting the desktop session...\n\n\
468 Your Home session will be restored upon login.\n\
469 Your Current session will not be saved.\n\n\
470 Application updates you have not saved will be lost.\n\n\
471 Continue Logout?")));
472
473         currentToHome = XmStringCreateLocalized(((char *)GETMESSAGE(18, 75,
474                 "Exiting the desktop session...\n\n\
475 Your Current session will be saved but your Home\n\
476 session will be restored upon login.\n\n\
477 Application updates you have not saved will be lost.\n\n\
478 Continue Logout?")));
479
480         /*
481          * Build up the correct string for this dialog
482          */
483         i = 0;
484         if (smGD.sessionType == HOME_SESSION && 
485             smSettings.startState == DtSM_HOME_STATE) 
486         {
487             XtSetArg(uiArgs[i], XmNmessageString, homeToHome); i++;
488         }
489         else if (smGD.sessionType == CURRENT_SESSION &&
490                  smSettings.startState == DtSM_HOME_STATE) 
491         {
492             XtSetArg(uiArgs[i], XmNmessageString, currentToHome); i++;
493         }
494         else
495         {
496             XtSetArg(uiArgs[i], XmNmessageString, returnToCurrent); i++;
497         }
498
499         /*
500          * Now create the dialog box
501          */
502         tmpString = GETMESSAGE(18, 6, "Logout Confirmation");
503         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
504         XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
505         XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_CENTER); i++;
506         XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
507         XtSetArg(uiArgs[i], XmNokLabelString, smDD.okLogoutString); i++;
508         XtSetArg(uiArgs[i], XmNcancelLabelString, smDD.cancelLogoutString); i++;
509         XtSetArg(uiArgs[i], XmNhelpLabelString, smDD.helpString); i++;
510         XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
511
512         pmsg = (Tt_message *)XtMalloc(sizeof(Tt_message));
513         XtSetArg(uiArgs[i], XmNuserData, pmsg); i++;
514
515         smDD.confExit = XmCreateWarningDialog(smGD.topLevelWid, "exitDialog",
516                                               uiArgs, i);
517         
518         i = 0;
519         XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
520         XtSetArg(uiArgs[i], XmNmwmFunctions, 0);i++;
521         XtSetArg(uiArgs[i], XmNmwmDecorations,
522                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER));i++;
523         XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
524         XtSetValues(XtParent(smDD.confExit), uiArgs, i);
525
526         exitRec = (ExitRecord *)XtMalloc( sizeof(ExitRecord) );
527         exitRec->pmsg = pmsg;
528         exitRec->doSave = doSave;
529         XtAddCallback (smDD.confExit, XmNokCallback, ExitConfirmed, exitRec);
530 #ifndef NO_XVH
531         XtAddCallback (smDD.confExit, XmNhelpCallback,
532                        TopicHelpRequested, HELP_LOGOUT_STR);
533 #endif
534         exitRec = (ExitRecord *)XtMalloc( sizeof(ExitRecord) );
535         exitRec->pmsg = pmsg;
536         exitRec->doSave = doSave;
537         exitRec->u.exitCancelledDialog = smDD.confExit;
538         XtAddCallback (smDD.confExit, XmNcancelCallback,
539                        ExitCancelled, exitRec);
540     }
541     else
542     {
543         /*
544          * The user may have changed the type of session to be
545          * restored so must update the dialog's message.
546          */
547         i = 0;
548         if (smGD.sessionType == HOME_SESSION && 
549             smSettings.startState == DtSM_HOME_STATE) 
550         {
551             XtSetArg(uiArgs[i], XmNmessageString, homeToHome); i++;
552         }
553         else if (smGD.sessionType == CURRENT_SESSION &&
554                  smSettings.startState == DtSM_HOME_STATE) 
555         {
556             XtSetArg(uiArgs[i], XmNmessageString, currentToHome); i++;
557         }
558         else
559         {
560             XtSetArg(uiArgs[i], XmNmessageString, returnToCurrent); i++;
561         }
562
563         XtSetValues(smDD.confExit, uiArgs, i);
564     }
565
566    /*
567     * Refresh buffer containing pointer to Tt_message.
568     */
569     i=0;
570     XtSetArg(uiArgs[i], XmNuserData, &pmsg); i++;
571     XtGetValues(smDD.confExit, uiArgs, i);
572     *pmsg = msg;
573
574
575     XtAddCallback (XtParent(smDD.confExit), XmNpopupCallback, DialogUp, NULL);
576         
577     XtManageChild(smDD.confExit);
578     return(0);
579 }
580
581 \f
582 /*************************************<->*************************************
583  *
584  *  WarnMsgFailue ()
585  *
586  *
587  *  Description:
588  *  -----------
589  *  Let the user know that the bms has died and that the current session
590  *  will not be saved.
591  *
592  *
593  *  Inputs:
594  *  ------
595  *
596  * 
597  *  Outputs:
598  *  -------
599  *  None.
600  *
601  *
602  *  Comments:
603  *  --------
604  * 
605  *************************************<->***********************************/
606 int 
607 WarnMsgFailure( void )
608 {
609     int         i;
610     XmString    bmsDeadString;
611     String      tmpString;
612
613     if(smDD.deadWid == NULL)
614     {
615         bmsDeadString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 38, 
616                 "Messaging System Inoperative\n\n\
617 To restart:\n\n1) Save all open data files.\n\
618 2) Logout.\n\
619 3) Log in again.\n\nNote: The current session will not be saved.\n\n\
620 When you are ready to begin the restart process, click [OK] and\n\
621 proceed to save your files.")));
622
623         /*
624          * Now create the dialog box
625          */
626         i = 0;
627         tmpString = GETMESSAGE(18, 12, "Message Failure");
628         XtSetArg(uiArgs[i], XmNmessageString, bmsDeadString);i++;
629         XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
630         XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
631         XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
632         XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
633         XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
634         XtSetArg(uiArgs[i], XmNhelpLabelString, smDD.helpString); i++;
635         XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
636         smDD.deadWid = XmCreateWarningDialog(smGD.topLevelWid, "deadDialog",
637                                              uiArgs, i);
638
639         i = 0;
640         XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
641         XtSetArg(uiArgs[i], XmNmwmFunctions, 0);i++;
642         XtSetArg(uiArgs[i], XmNmwmDecorations,
643                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER));i++;
644         XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
645         XtSetValues(XtParent(smDD.deadWid), uiArgs, i);
646         
647         XtAddCallback (XtParent(smDD.deadWid),
648                        XmNpopupCallback, DialogUp, NULL);
649         XtUnmanageChild(XmMessageBoxGetChild(smDD.deadWid,
650                                              XmDIALOG_CANCEL_BUTTON));
651
652         /*
653          * Now add in the callback and get out of here
654          */
655         XtAddCallback (smDD.deadWid, XmNokCallback,
656                        SimpleOK, (XtPointer) smDD.deadWid);
657 #ifndef NO_XVH
658         XtAddCallback (smDD.deadWid, XmNhelpCallback,
659                        TopicHelpRequested, HELP_BMS_DEAD_STR);
660 #endif
661         XtAddCallback (smDD.deadWid, XmNcancelCallback,
662                         NULL, NULL);
663         XmStringFree(bmsDeadString);
664     }
665
666     XtManageChild(smDD.deadWid);
667     return(0);
668 }
669
670 \f
671 /*************************************<->*************************************
672  *
673  *  CompatModeExit ()
674  *
675  *
676  *  Description:
677  *  -----------
678  *  Let the user know that the logout button can not be used to exit in
679  *  compatibility mode.
680  *
681  *
682  *  Inputs:
683  *  ------
684  *
685  * 
686  *  Outputs:
687  *  -------
688  *  None.
689  *
690  *
691  *  Comments:
692  *  --------
693  * 
694  *************************************<->***********************************/
695 static int 
696 CompatModeExit( void )
697 {
698     int         i;
699     XmString    compatModeString;
700     String      tmpString;
701
702     if(smDD.compatExit == NULL)
703     {
704         compatModeString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 34, 
705                 "This session was started from an X Window System startup script.\n\n\
706 No session information will be saved.\n\nUse the reset key sequence to log out.")));
707
708         /*
709          * Now create the dialog box
710          */
711         i = 0;
712         tmpString = GETMESSAGE(18, 35, "Logout Message");
713         XtSetArg(uiArgs[i], XmNmessageString, compatModeString);i++;
714         XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
715         XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
716         XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_CENTER); i++;
717         XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
718         XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
719         XtSetArg(uiArgs[i], XmNhelpLabelString, smDD.helpString); i++;
720         XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
721         smDD.compatExit = XmCreateInformationDialog(smGD.topLevelWid,
722                                                     "compatDialog",
723                                                     uiArgs, i);
724
725         i = 0;
726         XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
727         XtSetArg(uiArgs[i], XmNmwmFunctions, 0);i++;
728         XtSetArg(uiArgs[i], XmNmwmDecorations,
729                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER));i++;
730     XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
731         XtSetValues(XtParent(smDD.compatExit), uiArgs, i);
732         
733         XtAddCallback (XtParent(smDD.compatExit),
734                        XmNpopupCallback, DialogUp, NULL);
735         XtUnmanageChild(XmMessageBoxGetChild(smDD.compatExit,
736                                              XmDIALOG_CANCEL_BUTTON));
737
738         /*
739          * Now add in the callback and get out of here
740          */
741         XtAddCallback (smDD.compatExit, XmNokCallback,
742                        SimpleOK, smDD.compatExit);
743 #ifndef NO_XVH
744         XtAddCallback (smDD.compatExit, XmNhelpCallback,
745                        TopicHelpRequested, HELP_LOGOUT_COMPAT_MODE_STR);
746 #endif
747         XmStringFree(compatModeString);
748     }
749
750     XtManageChild(smDD.compatExit);
751     return(0);
752 }
753
754
755 \f
756 /*************************************<->*************************************
757  *
758  *  CreateLockDialogWithCover()
759  *
760  *
761  *  Description:
762  *  -----------
763  *  Create the lock dialog when it exists as a part of a cover
764  *
765  *
766  *  Inputs:
767  *  ------
768  *
769  * 
770  *  Outputs:
771  *  -------
772  *  None.
773  *
774  *
775  *  Comments:
776  *  --------
777  * 
778  *************************************<->***********************************/
779 Widget 
780 CreateLockDialogWithCover(
781         Widget parent )
782 {
783     int         i;
784     Widget      loginLabel, instructLabel, tmpLock;
785     Widget      indFrame, loginPic, picFrame, loginFrame;
786     Widget      passwdLabel, passwdForm;
787     Dimension   width;          /* width, height of drop shadow    */
788     XmString    lockString, passwordString;
789     char        *lockMessage;
790     char        *envLog;
791     Pixel   fg, bg, focus_color;         /* foreground, background colors   */
792
793     i = 0;
794     XtSetArg(uiArgs[i], XmNmarginWidth, 0); i++;
795     XtSetArg(uiArgs[i], XmNmarginHeight, 0); i++;
796     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
797     XtSetArg(uiArgs[i], XmNshadowThickness,5); i++;
798     XtSetArg(uiArgs[i], XmNunitType, XmPIXELS); i++;
799     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
800     XtSetArg(uiArgs[i], XmNmappedWhenManaged, False); i++;
801     tmpLock = XmCreateForm(parent, "lockDialog", uiArgs, i);
802     smDD.matte[1] = tmpLock;
803
804     i = 0;
805     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
806     XtSetArg(uiArgs[i], XmNshadowThickness, 2); i++;
807     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_FORM); i++;
808     XtSetArg(uiArgs[i], XmNtopOffset, 15); i++;
809     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_FORM); i++;
810     XtSetArg(uiArgs[i], XmNbottomOffset, 15); i++;
811     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
812     XtSetArg(uiArgs[i], XmNrightOffset, 15); i++;
813     picFrame = XmCreateFrame(tmpLock, "picFrame", uiArgs, i);
814
815     i = 0;
816     XtSetArg(uiArgs[i], XmNforeground, &fg); i++;
817     XtSetArg(uiArgs[i], XmNbackground, &bg); i++;
818     XtGetValues(tmpLock, uiArgs, i);
819      
820     i = 0;
821     XtSetArg(uiArgs[i], XmNfillMode, XmFILL_SELF); i++;
822     XtSetArg(uiArgs[i], XmNbehavior, XmICON_LABEL); i++;
823     XtSetArg(uiArgs[i], XmNpixmapForeground, fg); i++;
824     XtSetArg(uiArgs[i], XmNpixmapBackground, bg); i++;
825     XtSetArg(uiArgs[i], XmNstring, NULL); i++;
826     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++;
827     XtSetArg(uiArgs[i], XmNtraversalOn, False); i++;
828     loginPic = _DtCreateIcon(picFrame, "lockLabelPixmap", uiArgs, i);
829      
830     i = 0;
831     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
832     XtSetArg(uiArgs[i], XmNshadowThickness, 2); i++; 
833     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_FORM); i++;
834     XtSetArg(uiArgs[i], XmNtopOffset, 15); i++;
835     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_FORM); i++;
836     XtSetArg(uiArgs[i], XmNbottomOffset, 15); i++;
837     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
838     XtSetArg(uiArgs[i], XmNleftOffset, 15); i++;
839     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_WIDGET); i++;
840     XtSetArg(uiArgs[i], XmNrightWidget, picFrame); i++;
841     XtSetArg(uiArgs[i], XmNrightOffset, 0); i++;
842     loginFrame = XmCreateFrame(tmpLock, "loginFrame", uiArgs, i);
843
844     /* 
845      * create the login matte...
846      */
847     i = 0;
848     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
849     smDD.loginMatte[1] = XmCreateForm(loginFrame, "loginMatte", uiArgs, i);
850
851     /*
852      *  create the login/password forms
853      */
854     i = 0;
855     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++; 
856     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
857     XtSetArg(uiArgs[i], XmNrightOffset, 15); i++;
858     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
859     XtSetArg(uiArgs[i], XmNbottomPosition, 50); i++;
860     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
861     XtSetArg(uiArgs[i], XmNleftOffset, 15); i++;
862     smDD.loginForm[1] = XmCreateForm(smDD.loginMatte[1], "loginForm", uiArgs, i);
863
864     i = 0;
865     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
866     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++; 
867     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
868     XtSetArg(uiArgs[i], XmNtopPosition, 50); i++;
869         XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
870         XtSetArg(uiArgs[i], XmNleftWidget, smDD.loginForm[1]); i++;
871         XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
872         XtSetArg(uiArgs[i], XmNrightWidget, smDD.loginForm[1]); i++;
873     passwdForm = XmCreateForm(smDD.loginMatte[1], "passwdForm", uiArgs, i);
874
875
876     /*
877      *  create the login/password labels...
878      */
879     i = 0;
880     envLog = getenv("LOGNAME");
881     lockMessage = XtMalloc(100 + strlen(envLog));
882     sprintf(
883         lockMessage,
884         ((char *)GETMESSAGE(18, 1, "Display locked by user %s.")), envLog);
885     lockString = XmStringCreateLocalized(lockMessage);
886     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
887     XtSetArg(uiArgs[i], XmNtopPosition, 20); i++;
888     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_CENTER); i++;
889     XtSetArg(uiArgs[i], XmNlabelString, lockString); i++;
890     loginLabel = XmCreateLabelGadget(smDD.loginForm[1],
891                                      "loginLabel", uiArgs, i);
892     XtManageChild(loginLabel);
893     XmStringFree(lockString);
894     XtFree(lockMessage);
895
896     i = 0;
897     lockString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 2, "Enter password to unlock.")));
898     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
899     XtSetArg(uiArgs[i], XmNtopWidget, loginLabel); i++;
900     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_CENTER); i++;
901     XtSetArg(uiArgs[i], XmNlabelString, lockString); i++;
902     instructLabel = XmCreateLabelGadget(smDD.loginForm[1], "instructLabel",
903                                         uiArgs, i);
904     XtManageChild(instructLabel);
905     XmStringFree(lockString);
906
907     i = 0;
908     passwordString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 3, "Password: ")));
909     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
910     XtSetArg(uiArgs[i], XmNtopPosition, 20); i++;
911     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
912     XtSetArg(uiArgs[i], XmNbottomPosition, 80); i++;
913     XtSetArg(uiArgs[i], XmNleftOffset, 0); i++;
914     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_END); i++;
915     XtSetArg(uiArgs[i], XmNlabelString, passwordString); i++;
916     passwdLabel = XmCreateLabelGadget(passwdForm,
917                                       "passwdLabel", uiArgs, i);
918     XtManageChild(passwdLabel);
919     XmStringFree(passwordString);
920
921     /*
922      * Give the password label an offset
923      */
924     i = 0;
925     XtSetArg(uiArgs[i], XmNwidth, &width);i++;
926     XtGetValues(passwdLabel, uiArgs, i);
927
928     i = 0;
929     width += (width/6);
930     XtSetArg(uiArgs[i], XmNwidth, width);i++;
931     XtSetArg(uiArgs[i], XmNrecomputeSize, False);i++;
932     XtSetValues(passwdLabel, uiArgs, i);
933
934
935     i = 0;
936     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_IN); i++;
937     XtSetArg(uiArgs[i], XmNshadowThickness, 1); i++;
938     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
939     XtSetArg(uiArgs[i], XmNtopPosition, 20); i++;
940     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
941     XtSetArg(uiArgs[i], XmNbottomPosition, 80); i++;
942     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
943     XtSetArg(uiArgs[i], XmNleftWidget, passwdLabel); i++;
944     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
945     XtSetArg(uiArgs[i], XmNrightOffset, 10); i++;
946     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_END); i++;
947     indFrame = XmCreateFrame(passwdForm,  "indFrame", uiArgs, i);
948
949     i = 0;
950     passwordString = XmStringCreateLocalized("|");
951     XtSetArg(uiArgs[i], XmNlabelString, passwordString); i++;
952     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_BEGINNING); i++;
953     smDD.indLabel[1] = XmCreateLabel(indFrame, "indLabel",
954                                         uiArgs, i);
955     XtManageChild(smDD.indLabel[1]);
956     XmStringFree(passwordString);
957     
958     i = 0;
959     XtSetArg(uiArgs[i], XmNhighlightColor,  &focus_color); i++;
960     XtGetValues(indFrame, uiArgs, i);
961     XtVaSetValues ( smDD.indLabel[1],
962                     XmNborderWidth, 2,
963                     XmNborderColor,  focus_color,
964                     NULL );
965     /*
966      * Manage forms AFTER all children have been managed
967      */
968     XtManageChild(indFrame);
969     XtManageChild(passwdForm);
970     XtManageChild(smDD.loginForm[1]);
971     XtManageChild(smDD.loginMatte[1]);
972     XtManageChild(loginPic);
973     XtManageChild(picFrame);
974     XtManageChild(loginFrame);
975         
976     return(tmpLock);
977 }
978
979
980 \f
981 /*************************************<->*************************************
982  *
983  *  CreateCoverDialog ()
984  *
985  *
986  *  Description:
987  *  -----------
988  *  Create the cover dialogs for all the screens
989  *
990  *
991  *  Inputs:
992  *  ------
993  *
994  * 
995  *  Outputs:
996  *  -------
997  *  None.
998  *
999  *
1000  *  Comments:
1001  *  --------
1002  * 
1003  *************************************<->***********************************/
1004 Widget 
1005 CreateCoverDialog(
1006         int screenNum,
1007         Boolean withLock )
1008 {
1009     int i;
1010     Widget      tmpCover, table;
1011     char        geomString[50];
1012
1013     sprintf(geomString, "%dx%d+0+0",
1014             DisplayWidth(smGD.display, screenNum),
1015             DisplayHeight(smGD.display, screenNum));
1016
1017     i = 0;
1018     XtSetArg(uiArgs[i], XmNmwmDecorations, 0);i++;
1019     XtSetArg(uiArgs[i], XmNgeometry, (String) geomString);i++;
1020     XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
1021     XtSetArg(uiArgs[i], XmNallowShellResize, True); i++;
1022     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
1023     XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
1024     XtSetArg(uiArgs[i], XmNdepth, DefaultDepth(smGD.display, screenNum));i++;
1025     XtSetArg(uiArgs[i], XmNscreen,
1026              ScreenOfDisplay(smGD.display, screenNum));i++;
1027     XtSetArg(uiArgs[i], XmNcolormap,
1028              DefaultColormap(smGD.display, screenNum));i++;
1029     tmpCover = XtCreatePopupShell("coverDialog", topLevelShellWidgetClass,
1030                                   smGD.topLevelWid,  uiArgs, i);
1031
1032     i = 0;
1033     XtSetArg(uiArgs[i], XmNmarginWidth, 0); i++;
1034     XtSetArg(uiArgs[i], XmNmarginHeight, 0); i++;
1035     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++;
1036     XtSetArg(uiArgs[i], XmNheight,
1037              (Dimension) DisplayHeight(smGD.display, smGD.screen)); i++;
1038     XtSetArg(uiArgs[i], XmNwidth,
1039              (Dimension) DisplayWidth(smGD.display, smGD.screen)); i++;
1040     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
1041     table = XmCreateDrawingArea(tmpCover, "drawArea", uiArgs, i);
1042     XtManageChild(table);
1043     smDD.coverDrawing[screenNum] = table;
1044
1045     if(withLock == True)
1046     {
1047         XtAddCallback (tmpCover, XmNpopupCallback,
1048                        LockDialogUp, NULL);
1049     }
1050
1051     XtRealizeWidget(tmpCover);
1052     
1053     return(tmpCover);
1054 }
1055
1056 \f
1057 /*************************************<->*************************************
1058  *
1059  *  ExitConfirmed ()
1060  *
1061  *
1062  *  Description:
1063  *  -----------
1064  *  Callback that is called when user confirms the exit of a session by
1065  *  pressing the OK button on the confirmation dialog.  This routine just
1066  *  facilitates the exit process.
1067  *
1068  *
1069  *  Inputs:
1070  *  ------
1071  *
1072  * 
1073  *  Outputs:
1074  *  -------
1075  *  None.
1076  *
1077  *
1078  *  Comments:
1079  *  --------
1080  * 
1081  *************************************<->***********************************/
1082 static void 
1083 ExitConfirmed(
1084         Widget w,
1085         XtPointer client_data,
1086         XtPointer call_data )
1087 {
1088     ExitRecord *exitRec = (ExitRecord *)client_data;
1089
1090     XtUnmanageChild(smDD.confExit);
1091
1092     ImmediateExit(smSettings.startState, *exitRec->pmsg, exitRec->doSave);
1093 }
1094
1095
1096 \f
1097 /*************************************<->*************************************
1098  *
1099  *  ImmediateExit -
1100  *
1101  *
1102  *  Description:
1103  *  -----------
1104  *  This process puts in motion the exit procedure, and then exits.
1105  *
1106  *
1107  *  Inputs:
1108  *  ------
1109  *  mode = Whether this session should be reset or restarted
1110  *  msg -- if non-zero, Session_Exit request to reply/fail && destroy
1111  *  doSave - if True, the session will be saved.
1112  *
1113  * 
1114  *  Outputs:
1115  *  -------
1116  *  None.
1117  *
1118  *
1119  *  Comments:
1120  *  --------
1121  * 
1122  *************************************<->***********************************/
1123 void 
1124 ImmediateExit(
1125         int mode,
1126         Tt_message msg,
1127         Boolean doSave)
1128 {
1129     long old;
1130     Tt_message notice;
1131
1132     /*
1133      * Turn off SIGTERM so we don't catch one in the middle of shutting
1134      * down
1135      */
1136 #if !defined(SVR4) && !defined(sco)
1137     old = sigblock(sigmask(SIGTERM));
1138 #else
1139     old = sighold(SIGTERM);
1140 #endif
1141     /*
1142      *
1143      */
1144     if(smGD.bmsDead == False)
1145     {
1146         notice = (Tt_message) tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
1147                                                   "XSession_Ending", 0);
1148         tt_message_send( notice );
1149         tt_message_destroy( notice );
1150     }
1151     if (msg != 0) {
1152         tt_message_reply( msg );
1153         tt_message_destroy( msg );
1154     }
1155
1156     if (doSave)
1157     {
1158         XEvent          next;
1159         Tt_message      msg;
1160         int             sessionType = smGD.sessionType;
1161         XtIntervalId    timerId;
1162
1163         msg = (Tt_message) tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
1164                                                "DtActivity_Beginning", 0 );
1165         tt_message_send( msg );
1166         tt_message_destroy( msg );
1167
1168         if (smGD.sessionType == CURRENT_SESSION ||
1169             smGD.sessionType == DEFAULT_SESSION)
1170             SaveState (False, DtSM_CURRENT_STATE, SmSaveLocal, True, 
1171                  DEFAULT_INTERACT_STYLE, DEFAULT_FAST, DEFAULT_GLOBAL);
1172         else if (smGD.sessionType == HOME_SESSION && 
1173                  smSettings.startState == DtSM_CURRENT_STATE)
1174             SaveState (False, DtSM_HOME_STATE, SmSaveLocal, True, 
1175                  DEFAULT_INTERACT_STYLE, DEFAULT_FAST, DEFAULT_GLOBAL);
1176         else
1177             SaveState (False, DtSM_HOME_STATE, SmSaveGlobal, True, 
1178                  DEFAULT_INTERACT_STYLE, DEFAULT_FAST, DEFAULT_GLOBAL);
1179
1180         /*
1181          * Restore sessionType - it may have been changed in SaveState
1182          */
1183         smGD.sessionType = sessionType;
1184
1185         XSync(smGD.display, 0);
1186
1187         smGD.loggingOut = True;
1188
1189         saveTimeout = False;
1190         timerId = XtAppAddTimeOut (smGD.appCon, smRes.saveYourselfTimeout, 
1191                                    SaveTimeout, NULL);
1192
1193         while (smXSMP.saveState.saveComplete == False && 
1194                smXSMP.saveState.shutdownCanceled == False) {
1195             if (saveTimeout)
1196                 break;
1197             XtAppNextEvent(smGD.appCon, &next);
1198             if (next.type != 0)
1199                 XtDispatchEvent(&next);
1200         }
1201     }
1202
1203     if (smXSMP.saveState.shutdownCanceled == False) {
1204         /* 
1205          * Run the user's exit script if there is one
1206          */
1207         if (smGD.compatMode == False) 
1208         {
1209             StartEtc(True);    /* run sessionexit */
1210         }
1211
1212         _DtReleaseLock(smGD.display, SM_RUNNING_LOCK);
1213         SM_EXIT(0);
1214     }
1215 }
1216
1217
1218 \f
1219 /*************************************<->*************************************
1220  *
1221  *  ExitCancelled ()
1222  *
1223  *
1224  *  Description:
1225  *  -----------
1226  *  Called when the user bails out from a logout at the confirmation dialog
1227  *
1228  *
1229  *  Inputs:
1230  *  ------
1231  *  client_data - tells which dialog to unmange (the query or confirm exit)
1232  *  msg -- if non-zero, Session_Exit request to reply/fail && destroy
1233  *
1234  * 
1235  *  Outputs:
1236  *  -------
1237  *  None.
1238  *
1239  *
1240  *  Comments:
1241  *  --------
1242  * 
1243  *************************************<->***********************************/
1244 static void 
1245 ExitCancelled(
1246         Widget w,
1247         XtPointer client_data,
1248         XtPointer call_data )
1249 {
1250     ExitRecord *exitRec = (ExitRecord *)client_data;
1251
1252     if(XtIsManaged(exitRec->u.exitCancelledDialog))
1253     {
1254         XtUnmanageChild(exitRec->u.exitCancelledDialog);
1255     }
1256
1257     if(smDD.smHelpDialog && XtIsManaged(smDD.smHelpDialog))
1258     {
1259         XtUnmanageChild(smDD.smHelpDialog);
1260     }
1261
1262     if (*exitRec->pmsg != 0) {
1263             tttk_message_fail(*exitRec->pmsg, TT_DESKTOP_ECANCELED, 0, 1 );
1264     }
1265     SetSystemReady();
1266 }
1267
1268
1269 \f
1270 /*************************************<->*************************************
1271  *
1272  *  DialogUp ()
1273  *
1274  *
1275  *  Description:
1276  *  -----------
1277  *  Once the dialog is managed, but not popped up - reposition it so that
1278  *  it appears in the middle of the screen then remove the popup callback
1279  *
1280  *
1281  *  Inputs:
1282  *  ------
1283  *
1284  * 
1285  *  Outputs:
1286  *  -------
1287  *  None
1288  *
1289  *
1290  *  Comments:
1291  *  --------
1292  *  This routine can be used for any generic SYSTEM_MODAL dialog
1293  * 
1294  *************************************<->***********************************/
1295 void 
1296 DialogUp(
1297         Widget w,
1298         XtPointer client_data,
1299         XtPointer call_data )
1300 {
1301     int         i;
1302     Dimension   width, height;
1303     Position    x, y;
1304
1305     /*
1306      * Get the size of the dialog box - then compute its position
1307      */
1308     i = 0;
1309     XtSetArg(uiArgs[i], XmNwidth, &width);i++;
1310     XtSetArg(uiArgs[i], XmNheight, &height);i++;
1311     XtGetValues(w, uiArgs, i);
1312     
1313     x = (DisplayWidth(smGD.display, smGD.screen) / 2) - (width / 2);
1314     y = (DisplayHeight(smGD.display, smGD.screen) / 2) - (height / 2);
1315     
1316     i = 0;
1317     XtSetArg(uiArgs[i], XmNx, x);i++;
1318     XtSetArg(uiArgs[i], XmNy, y);i++;
1319     XtSetValues(w, uiArgs, i);
1320
1321     XtRemoveCallback(w, XmNpopupCallback, DialogUp, NULL);
1322 }
1323
1324
1325
1326 \f
1327 /*************************************<->*************************************
1328  *
1329  *  ShowWaitState (flag)
1330  *
1331  *
1332  *  Description:
1333  *  -----------
1334  *  Enter/Leave the wait state.
1335  *
1336  *
1337  *  Inputs:
1338  *  ------
1339  *  flag = TRUE for Enter, FALSE for Leave.
1340  *
1341  * 
1342  *  Outputs:
1343  *  -------
1344  *  None.
1345  *
1346  *
1347  *  Comments:
1348  *  --------
1349  *  Stolen from the window manager code.
1350  * 
1351  *************************************<->***********************************/
1352
1353 void 
1354 ShowWaitState(
1355         Boolean flag )
1356 {
1357     if (flag)
1358     {
1359         XGrabPointer (smGD.display, DefaultRootWindow(smGD.display), FALSE, 
1360                       0, GrabModeAsync, GrabModeAsync, None, 
1361                       smGD.waitCursor, CurrentTime);
1362         XGrabKeyboard (smGD.display, DefaultRootWindow(smGD.display), FALSE, 
1363                        GrabModeAsync, GrabModeAsync, CurrentTime);
1364     }
1365     else
1366     {
1367         XUngrabPointer (smGD.display, CurrentTime);
1368         XUngrabKeyboard (smGD.display, CurrentTime);
1369     }
1370     XSync(smGD.display, 0);
1371 }
1372
1373 \f
1374 /*************************************<->*************************************
1375  *
1376  *  InitCursorInfo ()
1377  *
1378  *
1379  *  Description:
1380  *  -----------
1381  *  This function determines whether a server supports large cursors.  It it
1382  *  does large feedback cursors are used in some cases (wait state and
1383  *  system modal state); otherwise smaller (16x16) standard cursors are used.
1384  *
1385  *  Outputs:
1386  *  -------
1387  *  Returns true if large cursors are supported, false otherwise
1388  *
1389  *  Comments:
1390  *  ---------
1391  *  This code was stolen from the window manager
1392  * 
1393  *************************************<->***********************************/
1394 Boolean 
1395 InitCursorInfo( void )
1396 {
1397     unsigned int cWidth;
1398     unsigned int cHeight;
1399
1400     if (XQueryBestCursor (smGD.display, DefaultRootWindow(smGD.display),
1401                           32, 32, &cWidth, &cHeight))
1402     {
1403         if ((cWidth >= 32) && (cHeight >= 32))
1404         {
1405            return(True);
1406         }
1407     }
1408
1409     return(False);
1410 }
1411
1412
1413 \f
1414 /*************************************<->*************************************
1415  *
1416  *  LockDialogUp ()
1417  *
1418  *
1419  *  Description:
1420  *  -----------
1421  *  Once the lock dialog is managed, but not popped up - reposition it so that
1422  *  it appears in the middle of the screen then remove the popup callback
1423  *
1424  *
1425  *  Inputs:
1426  *  ------
1427  *
1428  * 
1429  *  Outputs:
1430  *  -------
1431  *  None.
1432  *
1433  *
1434  *  Comments:
1435  *  --------
1436  * 
1437  *************************************<->***********************************/
1438 static void 
1439 LockDialogUp(
1440         Widget w,
1441         XtPointer client_data,
1442         XtPointer call_data )
1443 {
1444     
1445     register int        i;
1446     Dimension   width, height;  /* size values returned by XtGetValues     */
1447     Dimension   shadowThickness;/* size values returned by XtGetValues     */
1448     
1449     struct
1450     {                   /* position, size of widgets (pixels)      */
1451         int x, y;
1452         int     width;
1453         int height;
1454         int shadow;
1455     } mw;       /* matte, logo, drop shadow & login matte  */
1456
1457     int         width1, width2; /* general width variable                  */
1458     int         x1, y1;         /* general position variables              */
1459     int         index;
1460     
1461     /*
1462      * The partial cover has widgets of index 0 - the cover has
1463      * index 1
1464      */
1465     if(smGD.coverScreen == True)
1466     {
1467         index = 1;
1468     }
1469     else
1470     {
1471         index = 0;
1472     }
1473     
1474     /*
1475      *  - center the main matte horizontally and vertically...
1476      */
1477     i = 0;
1478     XtSetArg(uiArgs[i], XmNwidth, &width); i++;
1479     XtSetArg(uiArgs[i], XmNheight, &height); i++;
1480     XtSetArg(uiArgs[i], XmNshadowThickness, &shadowThickness); i++;
1481     XtGetValues(smDD.matte[index], uiArgs, i);
1482
1483     mw.shadow = shadowThickness;
1484     mw.width  = width;
1485     mw.height = height;
1486     mw.x      = (DisplayWidth(smGD.display, smGD.screen)  - mw.width)/2;
1487     mw.y      = (DisplayHeight(smGD.display, smGD.screen) - mw.height)/2;
1488
1489     if ( mw.x < 0 ) mw.x = 0;
1490     if ( mw.y < 0 ) mw.y = 0;
1491     
1492     x1 = mw.x;
1493     y1 = mw.y;
1494
1495     i = 0;
1496
1497     XtSetArg(uiArgs[i], XmNx, x1); i++;
1498     XtSetArg(uiArgs[i], XmNy, y1); i++;
1499
1500     XtSetValues(smDD.matte[index], uiArgs, i);
1501
1502     /*
1503      *  - center the login/password frames horizontally in the login_matte...
1504      */
1505     XtSetArg(uiArgs[0], XmNwidth,  &width);
1506     XtGetValues(smDD.loginMatte[index], uiArgs, 1);
1507     width1 = (int)width;    
1508
1509     XtSetArg(uiArgs[0], XmNwidth,  &width);
1510     XtGetValues(smDD.loginForm[index], uiArgs, 1);
1511     width2 = (int)width;
1512     
1513     i = 0;
1514     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
1515     XtSetArg(uiArgs[i], XmNleftOffset, (width1 - width2) / 2); i++;
1516     XtSetValues(smDD.loginForm[index],  uiArgs, i);
1517 }
1518
1519
1520 \f
1521 /*************************************<->*************************************
1522  *
1523  *  SimpleOK()
1524  *
1525  *
1526  *  Description:
1527  *  -----------
1528  *  Simply dismiss a dialog.  Does special process for a compatibility mode
1529  *  logout dialog and when the bms won't start.
1530  *
1531  *
1532  *  Inputs:
1533  *  ------
1534  *  client_data - sends in the dialog to be dismissed.
1535  *
1536  * 
1537  *  Outputs:
1538  *  -------
1539  *  None.
1540  *
1541  *
1542  *  Comments:
1543  *  --------
1544  * 
1545  *************************************<->***********************************/
1546 static void 
1547 SimpleOK(
1548         Widget w,
1549         XtPointer client_data,
1550         XtPointer call_data )
1551 {
1552     Widget      dismissDialog = (Widget) client_data;
1553
1554     if(XtIsManaged(dismissDialog))
1555     {
1556         XtUnmanageChild(dismissDialog);
1557     }
1558
1559     if(dismissDialog == smDD.compatExit)
1560     {
1561         SetSystemReady();
1562     }
1563
1564     if(dismissDialog == smDD.noStart)
1565     {
1566         SM_EXIT(-1);
1567     }
1568     if(dismissDialog == smDD.clientReasons)
1569     {
1570         reasonsDialogOK == True;
1571     }
1572 }
1573
1574
1575 \f
1576 /*************************************<->*************************************
1577  *
1578  *  UpdatePasswdField ()
1579  *
1580  *
1581  *  Description:
1582  *  -----------
1583  *  Give the visual feedback neccessary when the user is entering a password
1584  *
1585  *
1586  *  Inputs:
1587  *  ------
1588  *  numChars = number of characters entered into the field
1589  *
1590  * 
1591  *  Outputs:
1592  *  -------
1593  *  None.
1594  *
1595  *
1596  *  Comments:
1597  *  --------
1598  * 
1599  *************************************<->***********************************/
1600 void 
1601 UpdatePasswdField(
1602         int numChars )
1603 {
1604     int i, index;
1605     char passwdMessage[25];
1606     XmString tmpString;
1607
1608
1609     if(numChars > 0)
1610     {
1611         strcpy(passwdMessage, "|");
1612         for(i = 1;i < numChars;i++)
1613         {
1614             if(i==1)
1615                 strcpy(passwdMessage, "|");
1616             else
1617                 strcat(passwdMessage, " ");
1618         }
1619         strcat(passwdMessage, PASSWORD_INDICATOR);
1620     }
1621     else
1622     {
1623         strcpy(passwdMessage, "|");
1624     }
1625
1626     tmpString = XmStringCreateLocalized (passwdMessage);
1627
1628     /*
1629      * Set the index for the indLabel widget
1630      */
1631     if(smGD.coverScreen == True)
1632     {
1633         index = 1;
1634     }
1635     else
1636     {
1637         index = 0;
1638     }
1639     
1640     i = 0;
1641     XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1642     XtSetValues(smDD.indLabel[index], uiArgs, i);
1643
1644     XmStringFree(tmpString);
1645 }
1646
1647
1648 \f
1649 /*************************************<->*************************************
1650  *
1651  *  WarnNoStartup ()
1652  *
1653  *
1654  *  Description:
1655  *  -----------
1656  *  When the BMS refuses to be started, warn the user about why dt is
1657  *  crashing and then exit.
1658  *
1659  *
1660  *  Inputs:
1661  *  ------
1662  *
1663  * 
1664  *  Outputs:
1665  *  -------
1666  *  None.
1667  *
1668  *
1669  *  Comments:
1670  *  --------
1671  * 
1672  *************************************<->***********************************/
1673 int 
1674 WarnNoStartup( void )
1675 {
1676     int         i;
1677     XmString    bmsNoStartString;
1678     String      tmpString;
1679
1680 #ifdef __osf__
1681
1682     bmsNoStartString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 76,
1683         "The DT messaging system could not be started.\n\n\
1684 To correct the problem:\n\n\
1685 1.  Choose [OK] to return to the login screen.\n\n\
1686 2.  Select Failsafe Session from the login screen's option\n\
1687          menu and log in.\n\n\
1688 3.  Check to see that your hostname exists correctly in /etc/hosts if your\n\
1689      network has already been configured.\n\
1690 4.  If your network has not yet been configured, make sure that /etc/hosts\n\
1691      has the following entry in it:\n\
1692      127.0.0.1 localhost \n\n\
1693 For additional information, see the CDE User's Guide.")));
1694 #else
1695
1696     bmsNoStartString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 36,
1697         "The desktop messaging system could not be started.\n\n\
1698 To correct the problem:\n\n\
1699 1.  Choose [OK] to return to the login screen.\n\n\
1700 2.  Select Failsafe Session from the login screen's option\n\
1701          menu and log in.\n\n\
1702 3.  Check to see that the desktop is properly installed,\n\
1703          the hostname is correct (/etc/hosts) and that the\n\
1704          network is properly configured.\n\n\
1705 For additional information, see the CDE User's Guide.")));
1706 #endif
1707
1708     /*
1709      * Now create the dialog box
1710      */
1711     i = 0;
1712     tmpString = GETMESSAGE(18, 37, "Action Required");
1713     XtSetArg(uiArgs[i], XmNmessageString, bmsNoStartString);i++;
1714     XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
1715     XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
1716     XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
1717     XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
1718     XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
1719     XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
1720     smDD.noStart = XmCreateWarningDialog(smGD.topLevelWid, "noStartDialog",
1721                                              uiArgs, i);
1722
1723     XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
1724     XtSetValues(XtParent(smDD.noStart), uiArgs, i);
1725
1726     XtAddCallback (XtParent(smDD.noStart),
1727                    XmNpopupCallback, DialogUp, NULL);
1728     XtUnmanageChild(XmMessageBoxGetChild(smDD.noStart,
1729                                          XmDIALOG_HELP_BUTTON));
1730     XtUnmanageChild(XmMessageBoxGetChild(smDD.noStart,
1731                                          XmDIALOG_CANCEL_BUTTON));
1732
1733     /*
1734      * Now add in the callback and get out of here
1735      */
1736     XtAddCallback (smDD.noStart, XmNokCallback,
1737                    SimpleOK, smDD.noStart);
1738     XmStringFree(bmsNoStartString);
1739
1740     XtManageChild(smDD.noStart);
1741
1742     return(0);
1743 } /* END OF FUNCTION WarnNoStartup */
1744
1745
1746 #ifdef __osf__
1747
1748 /*************************************<->*************************************
1749  *
1750  *  WarnNewProfile()
1751  *
1752  *
1753  *  Description:
1754  *  -----------
1755  *  Warn the user that a new .dtprofile has just been added to their $HOME
1756  *  directory, indicating a need to edit it and their .login/.profile files.
1757  *
1758  *
1759  *  Inputs:
1760  *  ------
1761  *
1762  * 
1763  *  Outputs:
1764  *  -------
1765  *  None.
1766  *
1767  *
1768  *  Comments:
1769  *  --------
1770  * 
1771  *************************************<->***********************************/
1772 int 
1773 WarnNewProfile( void )
1774 {
1775     int       i;
1776     XmString  newProfileString;
1777     String    tmpString;
1778
1779     newProfileString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 99,
1780    "The new file '.dtprofile' has been added to your home directory.\n\
1781 \n\
1782    Follow the instructions in this file to ensure that when you log in\n\
1783    again your '.login' or '.profile' file will be activated and \n\
1784    that it will interact correctly with CDE. \n\
1785 \n\
1786    For additional information, see the CDE Advanced User's and System\n\
1787    Administrator's Guide.")));
1788
1789
1790     /*
1791      * Now create the dialog box
1792      */
1793     i = 0;
1794     tmpString = GETMESSAGE(18, 37, "Action Required");
1795     XtSetArg(uiArgs[i], XmNmessageString, newProfileString);i++;
1796     XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
1797     XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
1798     XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
1799     XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
1800     XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
1801     XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
1802     smDD.newProfile = XmCreateWarningDialog(smGD.topLevelWid, 
1803                                             "newProfileDialog",
1804                                             uiArgs, i);
1805
1806     XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
1807     XtSetValues(XtParent(smDD.newProfile), uiArgs, i);
1808
1809     XtAddCallback (XtParent(smDD.newProfile),
1810                    XmNpopupCallback, DialogUp, NULL);
1811     XtUnmanageChild(XmMessageBoxGetChild(smDD.newProfile,
1812                                          XmDIALOG_HELP_BUTTON));
1813     XtUnmanageChild(XmMessageBoxGetChild(smDD.newProfile,
1814                                          XmDIALOG_CANCEL_BUTTON));
1815
1816     /*
1817      * Now add in the callback and get out of here
1818      */
1819     XtAddCallback (smDD.newProfile, XmNokCallback,
1820                    SimpleOK, smDD.newProfile);
1821     XmStringFree(newProfileString);
1822
1823     XtManageChild(smDD.newProfile);
1824
1825     return(0);
1826 } /* END OF FUNCTION WarnNewProfile */
1827
1828
1829 #endif
1830
1831
1832 /*************************************<->*************************************
1833  *
1834  *  ConfirmSessionCreation () -
1835  *
1836  *  Description:
1837  *  -----------
1838  *
1839  *  Inputs:
1840  *  ------
1841  * 
1842  *  Outputs:
1843  *  -------
1844  *
1845  *  Returns True if the user says to continue the session; False otherwise
1846  *     or if malloc fails;
1847  *
1848  *  Comments:
1849  *  --------
1850  * 
1851  *************************************<->***********************************/
1852 Boolean
1853 ConfirmSessionCreation (
1854         short           session_type,
1855         unsigned int    _argc,
1856         char            **_argv)
1857 {
1858         int             i, j;
1859         XmString        title_string;
1860         XmString        ok_string;
1861         XmString        cancel_string;
1862         XmString        help_string;
1863         XmString        msg_string;
1864         Widget          tmp_widget;
1865         Arg             args[20];
1866         char            *pch1;
1867         char            *pch2;
1868         char            *pch3;
1869         Dimension       width, height;
1870         Position        x, y;
1871         XEvent          next;
1872         int             argc = _argc;
1873         char            **argv = NULL;
1874
1875         /*
1876          * Create temporary argv because the X toolkit may remove
1877          * pieces of the command line options.
1878          */
1879         if (_argc > 0) {
1880                 argv = (char **) XtMalloc (_argc * sizeof (char *));
1881                 for (i = 0; i < _argc; i++)
1882                         argv[i] = _argv[i];
1883         }
1884
1885         if (session_type == HOME_SESSION)
1886                 pch1 = strdup ((char *) GETMESSAGE(18, 50, "Home"));
1887         else
1888                 pch1 = strdup ((char *) GETMESSAGE(18, 51, "Current"));
1889         if (!pch1) {
1890                 PrintError(DtError, smNLS.cantMallocErrorString);
1891                 SM_EXIT(1);
1892         }
1893
1894         pch2 = strdup ((char *) GETMESSAGE(18, 52, 
1895                 "A display-specific '%s' session was selected\nfor display '%s' but one does not exist.\n\nIf you continue, a new display-specific session will\nbe created."));
1896         if (!pch2) {
1897                 PrintError(DtError, smNLS.cantMallocErrorString);
1898                 SM_EXIT(1);
1899         }
1900
1901         pch3 = XtMalloc (strlen (pch1) +
1902                              strlen (XDisplayName (getenv("DISPLAY"))) +
1903                              strlen (pch2) +
1904                              4);
1905         if (!pch3) {
1906                 PrintError(DtError, smNLS.cantMallocErrorString);
1907                 SM_EXIT(1);
1908         }
1909         (void) sprintf (pch3, pch2, pch1, XDisplayName (getenv("DISPLAY")));
1910
1911         /*
1912          * The X toolkit has not yet been initialized, so do it now.
1913          */
1914         j = 0;
1915         XtToolkitInitialize ();
1916         smGD.appCon = XtCreateApplicationContext();
1917         smGD.display = XtOpenDisplay(smGD.appCon, NULL, argv[0], 
1918                         SM_RESOURCE_CLASS, NULL, 0, &argc, argv);
1919
1920         XtSetArg(args[j], XmNbackground,
1921                 XBlackPixel(smGD.display, XDefaultScreen(smGD.display))); j++;
1922         XtSetArg(args[j], XmNmappedWhenManaged, False); j++;
1923         XtSetArg (args[j], XmNwidth, 1); j++;
1924         XtSetArg (args[j], XmNheight, 1); j++;
1925         tmp_widget = XtAppCreateShell (
1926                         "foo", "foo",
1927                         applicationShellWidgetClass,
1928                         smGD.display, args, j);
1929         XtRealizeWidget(tmp_widget);
1930
1931         /*
1932          * Create the compound strings for the confirmation dialog
1933          */
1934         msg_string = XmStringCreateLocalized (pch3);
1935         title_string = XmStringCreateLocalized(pch3);
1936
1937         ok_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 39, "OK")));
1938         cancel_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 40, "Cancel")));
1939         help_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 41, "Help")));
1940
1941         free (pch1); free (pch2); XtFree (pch3);
1942
1943         /*
1944          * Create the dialog box
1945          */
1946         i = 0;
1947         XtSetArg (uiArgs[i], XmNmessageString, msg_string); i++;
1948         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
1949         XtSetArg (uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
1950         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
1951         XtSetArg (uiArgs[i], XmNmappedWhenManaged, True); i++;
1952         XtSetArg (uiArgs[i], XmNtitle, title_string); i++;
1953         XtSetArg (uiArgs[i], XmNokLabelString, ok_string); i++;
1954         XtSetArg (uiArgs[i], XmNcancelLabelString, cancel_string); i++;
1955         XtSetArg (uiArgs[i], XmNhelpLabelString,  help_string); i++;
1956         XtSetArg (uiArgs[i], XmNautoUnmanage, False); i++;
1957
1958         smDD.confirmSession = XmCreateWarningDialog(
1959                         tmp_widget, "confirmDialog", uiArgs, i);
1960
1961         XtAddCallback (smDD.confirmSession, XmNokCallback, 
1962                         ConfirmOKCB, NULL);
1963
1964         /*
1965          * Some help state is not yet initialized and the help
1966          * callback assumes it is so some initializations must
1967          * be done now.
1968          */
1969         smDD.smHelpDialog = NULL;
1970         smDD.okString = ok_string;
1971         smGD.topLevelWid = tmp_widget;
1972
1973         XtAddCallback (smDD.confirmSession, XmNhelpCallback,
1974                        TopicHelpRequested, HELP_CONFIRMATION_SESSION_STR);
1975
1976         XtAddCallback (smDD.confirmSession, XmNcancelCallback,
1977                         ConfirmCancelCB, NULL);
1978         
1979         XtManageChild(smDD.confirmSession);
1980
1981         /*
1982          * Center the dialog on the display
1983          */
1984         i = 0;
1985         XtSetArg(uiArgs[i], XmNwidth, &width); i++;
1986         XtSetArg(uiArgs[i], XmNheight, &height); i++;
1987         XtGetValues(smDD.confirmSession, uiArgs, i);
1988
1989         x = (DisplayWidth(smGD.display,  XDefaultScreen(smGD.display)) / 2) 
1990                         - (width / 2);
1991         y = (DisplayHeight(smGD.display, XDefaultScreen(smGD.display)) / 2) 
1992                         - (height / 2);
1993
1994         i = 0;
1995         XtSetArg(uiArgs[i], XmNx, x); i++;
1996         XtSetArg(uiArgs[i], XmNy, y); i++;
1997         XtSetValues(smDD.confirmSession, uiArgs, i);
1998
1999         XmStringFree (msg_string);
2000         XmStringFree (title_string);
2001         XmStringFree (cancel_string);
2002         XmStringFree (help_string);
2003
2004         /*
2005          * Spin until the OK or Cancel CB is invoked
2006          */
2007         confirmState = ConfirmationNone;
2008         while(1) {
2009                 XtAppNextEvent(smGD.appCon, &next);
2010                 if (next.type != 0)
2011                         XtDispatchEvent(&next);
2012                 if (confirmState == ConfirmationOK) {
2013                         XtDestroyWidget (tmp_widget);
2014                         XmStringFree (ok_string);
2015                         return (True);
2016                 }
2017                 else if (confirmState == ConfirmationCancel) {
2018                         XtDestroyWidget (tmp_widget);
2019                         XmStringFree (ok_string);
2020                         return (False);
2021                 }
2022         }
2023 }
2024
2025
2026 /*************************************<->*************************************
2027  *
2028  *  ConfirmOKCB ()
2029  *
2030  *************************************<->***********************************/
2031 static void 
2032 ConfirmOKCB(
2033         Widget                  w,
2034         XtPointer               client_data,
2035         XtPointer               call_data )
2036 {
2037         XtUnmanageChild(smDD.confirmSession);
2038         confirmState = ConfirmationOK;
2039 }
2040
2041
2042 /*************************************<->*************************************
2043  *
2044  *  ConfirmCancelCB ()
2045  * 
2046  *************************************<->***********************************/
2047 static void 
2048 ConfirmCancelCB(
2049         Widget                  w,
2050         XtPointer               client_data,
2051         XtPointer               call_data )
2052 {
2053         XtUnmanageChild(smDD.confirmSession);
2054         confirmState = ConfirmationCancel;
2055 }
2056
2057
2058 /*************************************<->*************************************
2059  *
2060  *  PostXSMPFailureDialog () -
2061  *
2062  *  Description:
2063  *  -----------
2064  *
2065  *  Inputs:
2066  *  ------
2067  * 
2068  *  Outputs:
2069  *  -------
2070  *
2071  *  Returns True if the user says to continue the session; False otherwise
2072  *     or if malloc fails;
2073  *
2074  *  Comments:
2075  *  --------
2076  * 
2077  *************************************<->***********************************/
2078 void
2079 PostXSMPFailureDialog (
2080         XSMPFailure             failure_code,
2081         Boolean                 check_errorlog)
2082 {
2083         int             i, j;
2084         XmString        ok_string;
2085         XmString        help_string;
2086         XmString        msg_string;
2087         Arg             args[20];
2088         char            *pch1;
2089         char            *pch2 = "";
2090         char            *pch3;
2091         char            *pch4;
2092         char            *pch5;
2093         char            *error_file;
2094         Dimension       width, height;
2095         Position        x, y;
2096         XEvent          next;
2097
2098         pch1 = strdup ((char *) GETMESSAGE(40, 1, 
2099                 "A session cannot be started because of the\nfollowing error:"));
2100         if (!pch1) {
2101                 PrintError(DtError, smNLS.cantMallocErrorString);
2102                 SM_EXIT(1);
2103         }
2104
2105         switch (failure_code) {
2106                 case XSMP_FAILURE_SMS_INITIALIZE:
2107                         pch2 = strdup ((char *) GETMESSAGE (40, 2,
2108                                 "SmsInitialize failed."));
2109                         break;
2110                 case XSMP_FAILURE_ICE_LISTEN:
2111                         pch2 = strdup ((char *) GETMESSAGE (40, 3,
2112                                 "IceListenForConnections failed."));
2113                         break;
2114                 case XSMP_FAILURE_AUTHENTICATION:
2115                         pch2 = strdup ((char *) GETMESSAGE (40, 4,
2116                                 "The authentication file ~/.ICEauthority could not be created.\n   If the files ~/.ICEauthority-c and ~/.ICEauthority-l exist,\n   they must be removed before your session can be started."));
2117                         break;
2118                 case XSMP_FAILURE_ICE_ADD_WATCH:
2119                         pch2 = strdup ((char *) GETMESSAGE (40, 5,
2120                                 "IceAddConnectionWatch failed."));
2121                         break;
2122                 case XSMP_FAILURE_ICE_COMPOSE_IDS:
2123                         pch2 = strdup ((char *) GETMESSAGE (40, 6,
2124                                 "IceComposeNetworkIds failed."));
2125                         break;
2126                 case XSMP_FAILURE_MALLOC:
2127                         pch2 = strdup ((char *) GETMESSAGE (40, 7,
2128                                 "Could not create the SESSION_MANAGER environment variable."));
2129                         break;
2130         }
2131         if (!pch2) {
2132                 PrintError(DtError, smNLS.cantMallocErrorString);
2133                 SM_EXIT(1);
2134         }
2135
2136         pch3 = strdup ((char *) GETMESSAGE(18, 70, 
2137                 "See the following for more information:"));
2138         if (!pch3) {
2139                 PrintError(DtError, smNLS.cantMallocErrorString);
2140                 SM_EXIT(1);
2141         }
2142
2143         pch4 = strdup ((char *) GETMESSAGE(18, 71, 
2144                 "CDE Advanced Users and System's Administration Guide"));
2145         if (!pch4) {
2146                 PrintError(DtError, smNLS.cantMallocErrorString);
2147                 SM_EXIT(1);
2148         }
2149
2150         error_file = XtMalloc(MAXPATHLEN+1);
2151         strcpy (error_file, "");
2152         if (check_errorlog) {
2153                 char            *home;
2154
2155                 if (home = getenv ("HOME"))
2156                         sprintf (error_file, "%s/%s/%s", home, DtPERSONAL_CONFIG_DIRECTORY,
2157                                          DtERRORLOG_FILE);
2158         }
2159
2160         pch5 = XtMalloc (strlen (pch1) + strlen (pch2) + strlen (pch3) + strlen (pch4) + 
2161                                 strlen (error_file) + 15);
2162         if (!pch5) {
2163                 PrintError(DtError, smNLS.cantMallocErrorString);
2164                 SM_EXIT(1);
2165         }
2166         (void) sprintf (pch5, "%s\n\n   %s\n\n%s\n\n   %s\n   %s\n",
2167                         pch1, pch2, pch3, pch4, error_file);
2168
2169         XtFree(error_file);
2170
2171         /*
2172          * No top level widget has been created so must create one now.
2173          */
2174         j = 0;
2175         XtSetArg (args[j], XmNbackground, XBlackPixel(smGD.display, 
2176                         XDefaultScreen(smGD.display))); j++;
2177         XtSetArg (args[j], XmNmappedWhenManaged, False); j++;
2178         XtSetArg (args[j], XmNwidth, 1); j++;
2179         XtSetArg (args[j], XmNheight, 1); j++;
2180
2181         smGD.topLevelWid = XtAppCreateShell (SM_RESOURCE_NAME, 
2182                         SM_RESOURCE_CLASS, applicationShellWidgetClass,
2183                         smGD.display, args, j);
2184
2185         XtRealizeWidget(smGD.topLevelWid);
2186
2187         /*
2188          * Create the compound strings for the confirmation dialog
2189          */
2190         msg_string = XmStringCreateLocalized (pch5);
2191
2192         ok_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 39, "OK")));
2193         help_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 41, "Help")));
2194
2195         free (pch1); free (pch2); free (pch3); free (pch4); XtFree (pch5);
2196
2197         /*
2198          * Create the dialog box
2199          */
2200         i = 0;
2201         XtSetArg (uiArgs[i], XmNmessageString, msg_string); i++;
2202         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
2203         XtSetArg (uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
2204         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2205         XtSetArg (uiArgs[i], XmNmappedWhenManaged, True); i++;
2206         XtSetArg (uiArgs[i], XmNokLabelString, ok_string); i++;
2207         XtSetArg (uiArgs[i], XmNhelpLabelString,  help_string); i++;
2208         XtSetArg (uiArgs[i], XmNautoUnmanage, False); i++;
2209
2210         smDD.confirmSession = XmCreateWarningDialog(
2211                         smGD.topLevelWid, "confirmDialog", uiArgs, i);
2212
2213         XtAddCallback (smDD.confirmSession, XmNokCallback, 
2214                         XSMPFailureOKCB, NULL);
2215
2216         /*
2217          * Some help state is not yet initialized and the help
2218          * callback assumes it is so some initializations must
2219          * be done now.
2220          */
2221         smDD.smHelpDialog = NULL;
2222         smDD.okString = ok_string;
2223
2224         XtAddCallback (smDD.confirmSession, XmNhelpCallback,
2225                        TopicHelpRequested, HELP_XSMP_INIT_FAILURE_STR);
2226
2227         XtUnmanageChild(XmMessageBoxGetChild(smDD.confirmSession,
2228                                              XmDIALOG_CANCEL_BUTTON));
2229
2230         XtManageChild(smDD.confirmSession);
2231
2232         /*
2233          * Center the dialog on the display
2234          */
2235         i = 0;
2236         XtSetArg(uiArgs[i], XmNwidth, &width); i++;
2237         XtSetArg(uiArgs[i], XmNheight, &height); i++;
2238         XtGetValues(smDD.confirmSession, uiArgs, i);
2239
2240         x = (DisplayWidth(smGD.display,  XDefaultScreen(smGD.display)) / 2) 
2241                         - (width / 2);
2242         y = (DisplayHeight(smGD.display, XDefaultScreen(smGD.display)) / 2) 
2243                         - (height / 2);
2244
2245         i = 0;
2246         XtSetArg(uiArgs[i], XmNx, x); i++;
2247         XtSetArg(uiArgs[i], XmNy, y); i++;
2248         XtSetValues(smDD.confirmSession, uiArgs, i);
2249
2250         XmStringFree (msg_string);
2251         XmStringFree (help_string);
2252
2253         /*
2254          * Spin until the OK CB is invoked
2255          */
2256         while(1) {
2257                 XtAppNextEvent(smGD.appCon, &next);
2258                 if (next.type != 0)
2259                         XtDispatchEvent(&next);
2260         }
2261 }
2262
2263
2264 /*************************************<->*************************************
2265  *
2266  *  XSMPFailureOKCB ()
2267  *
2268  *************************************<->***********************************/
2269 static void 
2270 XSMPFailureOKCB(
2271         Widget                  w,
2272         XtPointer               client_data,
2273         XtPointer               call_data )
2274 {
2275         XtUnmanageChild(smDD.confirmSession);
2276         SM_EXIT(1);
2277 }
2278
2279
2280
2281
2282 /*************************************<->*************************************
2283  *
2284  *  PostSaveSessionErrorDialog
2285  *
2286  *  Description:
2287  *  -----------
2288  *  Let the user know that the Save_Session message does not have the
2289  *  required data and the session will not be saved.
2290  *
2291  *  Inputs:
2292  *  ------
2293  * 
2294  *  Outputs:
2295  *  -------
2296  *
2297  *************************************<->***********************************/
2298 void 
2299 PostSaveSessionErrorDialog ( void )
2300 {
2301     int         i;
2302     XmString    messageString;
2303     String      titleString;
2304
2305     if(smDD.saveSession == NULL)
2306     {
2307         messageString = XmStringCreateLocalized (((char *) GETMESSAGE(18, 56, 
2308                 "The session cannot be saved because the required\n\
2309 'save_type' parameter was not in the message.\n\n\
2310 The session will not be saved.")));
2311
2312         titleString = GETMESSAGE(18, 55, "Save Session Failure");
2313
2314         i = 0;
2315         XtSetArg (uiArgs[i], XmNmessageString,    messageString); i++;
2316         XtSetArg (uiArgs[i], XmNallowShellResize, True); i++;
2317         XtSetArg (uiArgs[i], XmNdialogStyle,      XmDIALOG_SYSTEM_MODAL); i++;
2318         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2319         XtSetArg (uiArgs[i], XmNtitle,            titleString); i++;
2320         XtSetArg (uiArgs[i], XmNokLabelString,    smDD.okString); i++;
2321         XtSetArg (uiArgs[i], XmNhelpLabelString,  smDD.helpString); i++;
2322         XtSetArg (uiArgs[i], XmNautoUnmanage,     False); i++;
2323
2324         smDD.saveSession = XmCreateErrorDialog(smGD.topLevelWid, 
2325                         "sessionSaveDialog", uiArgs, i);
2326
2327         i = 0;
2328         XtSetArg (uiArgs[i], XmNuseAsyncGeometry, True);i++;
2329         XtSetArg (uiArgs[i], XmNmwmFunctions,     0);i++;
2330         XtSetArg (uiArgs[i], XmNmwmDecorations,
2331                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER)); i++;
2332         XtSetArg (uiArgs[i], XmNmwmInputMode,     MWM_INPUT_SYSTEM_MODAL);i++;
2333
2334         XtSetValues(XtParent(smDD.saveSession), uiArgs, i);
2335         
2336         XtAddCallback (XtParent(smDD.saveSession),
2337                        XmNpopupCallback, DialogUp, NULL);
2338
2339         XtUnmanageChild (XmMessageBoxGetChild(smDD.saveSession,
2340                                              XmDIALOG_CANCEL_BUTTON));
2341
2342         XtAddCallback (smDD.saveSession, XmNokCallback,
2343                        SimpleOK, (XtPointer) smDD.saveSession);
2344 #ifndef NO_XVH
2345         XtAddCallback (smDD.saveSession, XmNhelpCallback,
2346                        TopicHelpRequested, HELP_SESSION_SAVE_ERROR_STR);
2347 #endif
2348         XmStringFree(messageString);
2349     }
2350
2351     XtManageChild(smDD.saveSession);
2352
2353     return;
2354 }
2355
2356
2357
2358 /*************************************<->*************************************
2359  *
2360  *  PostReasonsDialog - posts a Warning dialog on behalf of a client
2361  *      that supplied a "reason" when it closed its connection
2362  *
2363  *  Inputs:
2364  *  ------
2365  * 
2366  *  Outputs:    void
2367  *  -------
2368  *
2369  *************************************<->***********************************/
2370 void
2371 PostReasonsDialog (
2372         char                    * progName,
2373         int                     numMsgs,
2374         char                    ** message,
2375         Boolean                 waitForResponse)
2376 {
2377         XmString                msgString;
2378         XmString                okString;
2379         XmString                helpString;
2380         Arg                     args[20];
2381         char                    * titleString;
2382         char                    * str1;
2383         char                    * str2;
2384         char                    * str3;
2385         int                     i;
2386         int                     len;
2387         XEvent                  next;
2388
2389         str1 = strdup ((char *) GETMESSAGE(40, 28, 
2390                 "Application '%s'\nexited for the following reason:\n\n%s"));
2391         if (!str1) {
2392                 PrintError(DtError, smNLS.cantMallocErrorString);
2393                 SM_EXIT(1);
2394         }
2395
2396         for (i = 0, len = 0; i < numMsgs; i++) 
2397                 len += strlen (message[i]);
2398
2399         str2 = XtMalloc (len + (numMsgs * 3) + 1);
2400         if (!str2) {
2401                 PrintError(DtError, smNLS.cantMallocErrorString);
2402                 SM_EXIT(1);
2403         }
2404         str2[0] = '\000';
2405         for (i = 0; i < numMsgs; i++) {
2406                 strcat (str2, message[i]);
2407                 strcat (str2, "\n");
2408         }
2409
2410         str3 = XtMalloc (strlen (str1) + strlen (str2) + strlen (progName) + 4);
2411         if (!str3) {
2412                 PrintError(DtError, smNLS.cantMallocErrorString);
2413                 SM_EXIT(1);
2414         }
2415         (void) sprintf (str3, str1, progName, str2);
2416
2417         DtMsgLogMessage (smGD.programName, DtMsgLogWarning, str3);
2418
2419         free (str1);
2420         str1 = strdup ((char *) GETMESSAGE(40, 29, 
2421                 "Application Close Reasons"));
2422         if (!str1) {
2423                 PrintError(DtError, smNLS.cantMallocErrorString);
2424                 SM_EXIT(1);
2425         }
2426
2427         msgString = XmStringCreateLocalized (str3);
2428
2429         okString = XmStringCreateLocalized(((char *) GETMESSAGE(18, 39, "OK")));
2430
2431         helpString = XmStringCreateLocalized(((char *) GETMESSAGE(18, 41, "Help")));
2432
2433         /*
2434          * Create the dialog box
2435          */
2436         i = 0;
2437         XtSetArg (uiArgs[i], XmNmessageString, msgString); i++;
2438         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
2439         XtSetArg (uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
2440         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2441         XtSetArg (uiArgs[i], XmNmappedWhenManaged, True); i++;
2442         XtSetArg (uiArgs[i], XmNtitle, str1); i++;
2443         XtSetArg (uiArgs[i], XmNokLabelString, okString); i++;
2444         XtSetArg (uiArgs[i], XmNhelpLabelString, helpString); i++;
2445         XtSetArg (uiArgs[i], XmNautoUnmanage, False); i++;
2446
2447         smDD.clientReasons = XmCreateWarningDialog(smGD.topLevelWid, 
2448                 "clientReasons", uiArgs, i);
2449
2450         i = 0;
2451         XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
2452         XtSetArg(uiArgs[i], XmNmwmFunctions, 0);i++;
2453         XtSetArg(uiArgs[i], XmNmwmDecorations,
2454                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER));i++;
2455         XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
2456         XtSetValues(XtParent(smDD.clientReasons), uiArgs, i);
2457         
2458         XtAddCallback (XtParent(smDD.clientReasons),
2459                        XmNpopupCallback, DialogUp, NULL);
2460
2461         XtUnmanageChild (XmMessageBoxGetChild (smDD.clientReasons,
2462                                              XmDIALOG_CANCEL_BUTTON));
2463
2464         /*
2465          * Now add in the callback and get out of here
2466          */
2467         XtAddCallback (smDD.clientReasons, XmNokCallback,
2468                        SimpleOK, (XtPointer) smDD.clientReasons);
2469 #ifndef NO_XVH
2470         XtAddCallback (smDD.clientReasons, XmNhelpCallback,
2471                        TopicHelpRequested, HELP_APP_CLOSE_REASONS_STR);
2472 #endif
2473         free (str1); 
2474         XtFree (str2); 
2475         XtFree (str3);
2476         XmStringFree (msgString);
2477         XmStringFree (okString);
2478         XmStringFree (helpString);
2479
2480         XtManageChild (smDD.clientReasons);
2481
2482         /*
2483          * Spin until the OK callback is invoked.  If a shutdown
2484          * is in progress, we don't want to return until the
2485          * user has acknowledged this message.
2486          */
2487         reasonsDialogOK = False;
2488         if (waitForResponse) {
2489                 while (1) {
2490                         XtAppNextEvent (smGD.appCon, &next);
2491                         if (next.type != 0)
2492                                 XtDispatchEvent(&next);
2493                         if (reasonsDialogOK == True)
2494                                 break;
2495                 }
2496         }
2497 }
2498
2499
2500 /*************************************<->*************************************
2501  *
2502  *  SaveTimeout
2503  *
2504  *  Description:
2505  *  -----------
2506  *  Timeout procedure that is invoked when a save timer expires.
2507  *
2508  *  Inputs:
2509  *  ------
2510  *
2511  *  Outputs: None
2512  *  -------
2513  *
2514  *************************************<->***********************************/
2515 static void
2516 SaveTimeout (
2517         XtPointer               client_data,
2518         XtIntervalId            *id)
2519 {
2520         saveTimeout = True;
2521
2522         if (smXSMP.saveState.shutdownCanceled == False) {
2523                 /* 
2524                  * Run the user's exit script if there is one
2525                  */
2526                 if (smGD.compatMode == False)
2527                         StartEtc(True);    /* run sessionexit */
2528
2529                 _DtReleaseLock(smGD.display, SM_RUNNING_LOCK);
2530                 SM_EXIT(0);
2531         }
2532 }