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