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