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