dtsession: Coverity (memory corruption)
[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, slen;
174     Widget      loginLabel, instructLabel, tmpLock, indFrame;
175     Widget      passwdLabel, passwdForm, picFrame, loginPic, loginFrame;
176     Dimension   width;          /* width, height of login label    */
177     XmString    lockString, passwordString;
178     char        *lockMessage;
179     char        *envLog;
180     Pixel       fg, bg, focus_color;  /* foreground, background colors */
181     
182     i = 0;
183     XtSetArg(uiArgs[i], XmNallowShellResize, True); i++;
184     XtSetArg(uiArgs[i], XmNmarginWidth, 0); i++;
185     XtSetArg(uiArgs[i], XmNmarginHeight, 0); i++;
186     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
187     XtSetArg(uiArgs[i], XmNshadowThickness,5); i++;
188     XtSetArg(uiArgs[i], XmNunitType, XmPIXELS); i++;
189     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
190     XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
191     XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
192     XtSetArg(uiArgs[i], XmNmappedWhenManaged, True); i++;
193     tmpLock = XmCreateFormDialog(smGD.topLevelWid, "lockDialog", uiArgs, i);
194     XtAddCallback (XtParent(tmpLock), XmNpopupCallback,
195                    LockDialogUp, NULL);
196     smDD.matte[0] = tmpLock;
197
198     i = 0;
199     XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
200     XtSetArg(uiArgs[i], XmNmwmDecorations, 0);i++;
201     XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
202     XtSetValues(XtParent(tmpLock), uiArgs, i);
203                 
204     i = 0;
205     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
206     XtSetArg(uiArgs[i], XmNshadowThickness, 2); i++; 
207     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_FORM); i++;
208     XtSetArg(uiArgs[i], XmNtopOffset, 15); i++;
209     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_FORM); i++;
210     XtSetArg(uiArgs[i], XmNbottomOffset, 15); i++;
211     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
212     XtSetArg(uiArgs[i], XmNrightOffset, 15); i++;
213     picFrame = XmCreateFrame(tmpLock, "picFrame", uiArgs, i);
214
215         i = 0;
216         XtSetArg(uiArgs[i], XmNforeground, &fg); i++;
217         XtSetArg(uiArgs[i], XmNbackground, &bg); i++;
218         XtGetValues(tmpLock, uiArgs, i);
219
220     i = 0;
221         XtSetArg(uiArgs[i], XmNfillMode, XmFILL_SELF); i++;
222         XtSetArg(uiArgs[i], XmNbehavior, XmICON_LABEL); i++;
223         XtSetArg(uiArgs[i], XmNpixmapForeground, fg); i++;
224         XtSetArg(uiArgs[i], XmNpixmapBackground, bg); i++;
225         XtSetArg(uiArgs[i], XmNstring, NULL); i++;
226         XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++;
227         XtSetArg(uiArgs[i], XmNtraversalOn, False); i++;
228         loginPic = _DtCreateIcon(picFrame, "lockLabelPixmap", uiArgs, i);
229
230     i = 0;
231     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
232     XtSetArg(uiArgs[i], XmNshadowThickness, 2); i++; 
233     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_FORM); i++;
234     XtSetArg(uiArgs[i], XmNtopOffset, 15); i++;
235     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_FORM); i++;
236     XtSetArg(uiArgs[i], XmNbottomOffset, 15); i++;
237     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
238     XtSetArg(uiArgs[i], XmNleftOffset, 15); i++;
239     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_WIDGET); i++;
240     XtSetArg(uiArgs[i], XmNrightOffset, 0); i++;
241     XtSetArg(uiArgs[i], XmNrightWidget, loginPic); i++;
242     loginFrame = XmCreateFrame(tmpLock, "loginFrame", uiArgs, i);
243
244
245     /* 
246      * create the login matte...
247      */
248     i = 0;
249     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
250     smDD.loginMatte[0] = XmCreateForm(loginFrame, "loginMatte", uiArgs, i);
251
252     /*
253      *  create the login/password forms
254      */
255     i = 0;
256     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++; 
257     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
258     XtSetArg(uiArgs[i], XmNrightOffset, 15); i++;
259     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
260     XtSetArg(uiArgs[i], XmNbottomPosition, 50); i++;
261     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
262     XtSetArg(uiArgs[i], XmNleftOffset, 15); i++;
263     smDD.loginForm[0] = XmCreateForm(smDD.loginMatte[0], "loginForm", uiArgs, i);
264
265     i = 0;
266     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
267     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++; 
268     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
269     XtSetArg(uiArgs[i], XmNtopPosition, 50); i++;
270         XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
271         XtSetArg(uiArgs[i], XmNleftWidget, smDD.loginForm[0]); i++;
272         XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
273         XtSetArg(uiArgs[i], XmNrightWidget, smDD.loginForm[0]); i++;
274     passwdForm = XmCreateForm(smDD.loginMatte[0], "passwdForm", uiArgs, i);
275
276
277     /*
278      *  create the login/password labels...
279      */
280     i = 0;
281     envLog = getenv("LOGNAME");
282     slen = 100 + strlen(envLog) + 1;
283     lockMessage = XtCalloc(1, slen);
284     snprintf(lockMessage, slen - 1,
285              (char*) GETMESSAGE(18, 1, "Display locked by user %s."), envLog);
286     lockString = XmStringCreateLocalized(lockMessage);
287     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
288     XtSetArg(uiArgs[i], XmNtopPosition, 20); i++;
289     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_CENTER); i++;
290     XtSetArg(uiArgs[i], XmNlabelString, lockString); i++;
291     loginLabel = XmCreateLabelGadget(smDD.loginForm[0],
292                                      "loginLabel", uiArgs, i);
293     XtManageChild(loginLabel);
294     XmStringFree(lockString);
295     XtFree(lockMessage);
296
297     i = 0;
298     lockString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 2, "Enter password to unlock.")));
299     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
300     XtSetArg(uiArgs[i], XmNtopWidget, loginLabel); i++;
301     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_CENTER); i++;
302     XtSetArg(uiArgs[i], XmNlabelString, lockString); i++;
303     instructLabel = XmCreateLabelGadget(smDD.loginForm[0], "instructLabel",
304                                         uiArgs, i);
305     XtManageChild(instructLabel);
306     XmStringFree(lockString);
307
308     i = 0;
309     passwordString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 3, "Password: ")));
310     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
311     XtSetArg(uiArgs[i], XmNtopPosition, 20); i++;
312     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
313     XtSetArg(uiArgs[i], XmNbottomPosition, 80); i++;
314     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
315     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_END); i++;
316     XtSetArg(uiArgs[i], XmNlabelString, passwordString); i++;
317     passwdLabel = XmCreateLabelGadget(passwdForm,
318                                       "passwdLabel", uiArgs, i);
319     XtManageChild(passwdLabel);
320     XmStringFree(passwordString);
321
322     /*
323      * Give the password label an offset
324      */
325     i = 0;
326     XtSetArg(uiArgs[i], XmNwidth, &width);i++;
327     XtGetValues(passwdLabel, uiArgs, i);
328
329     i = 0;
330     width += (width/6);
331     XtSetArg(uiArgs[i], XmNwidth, width);i++;
332     XtSetArg(uiArgs[i], XmNrecomputeSize, False);i++;
333     XtSetValues(passwdLabel, uiArgs, i);
334
335
336     i = 0;
337     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_IN); i++;
338     XtSetArg(uiArgs[i], XmNshadowThickness, 1); i++;
339     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
340     XtSetArg(uiArgs[i], XmNtopPosition, 20); i++;
341     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
342     XtSetArg(uiArgs[i], XmNbottomPosition, 80); i++;
343     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_WIDGET); i++;
344     XtSetArg(uiArgs[i], XmNleftWidget, passwdLabel); i++;
345     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
346     XtSetArg(uiArgs[i], XmNrightOffset, 10); i++;
347     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_END); i++;
348     indFrame = XmCreateFrame(passwdForm,  "indFrame", uiArgs, i);
349
350     i = 0;
351     passwordString = XmStringCreateLocalized("|");
352     XtSetArg(uiArgs[i], XmNlabelString, passwordString); i++;
353     XtSetArg(uiArgs[i], XmNalignment, XmALIGNMENT_BEGINNING); i++;
354     smDD.indLabel[0] = XmCreateLabel(indFrame, "indLabel",
355                                         uiArgs, i);
356     XtManageChild(smDD.indLabel[0]);
357     XmStringFree(passwordString);
358
359     i = 0;
360     XtSetArg(uiArgs[i], XmNhighlightColor,  &focus_color); i++;
361     XtGetValues(indFrame, uiArgs, i);
362     XtVaSetValues ( smDD.indLabel[0],
363                     XmNborderWidth, 2,
364                     XmNborderColor,  focus_color, 
365                     NULL );
366     
367     /*
368      * Manage forms AFTER all children have been managed
369      */
370     XtManageChild(indFrame);
371     XtManageChild(passwdForm);
372     XtManageChild(smDD.loginForm[0]);
373     XtManageChild(smDD.loginMatte[0]);
374     XtManageChild(loginPic);
375     XtManageChild(picFrame);
376     XtManageChild(loginFrame);
377
378     return(tmpLock);
379 }
380
381
382 \f
383 /*************************************<->*************************************
384  *
385  *  ExitSession ()
386  *
387  *
388  *  Description:
389  *  -----------
390  *  Determines which exit routines get called when an exit request is made
391  *  of the session manager.  
392  *  If smGD.bmsDead == false, we just exit.
393  *  If ASK_STATE is turned on, the query dialog is
394  *  put up, if VERBOSE is on, confirm exit in current mode (restart or reset)
395  *  if confirmation is turned off - exit immediately.
396  *
397  *
398  *  Inputs:
399  *  ------
400  *  msg -- if non-zero, Session_Exit request to reply/fail && destroy
401  *
402  * 
403  *  Outputs:
404  *  -------
405  *  None.
406  *
407  *
408  *  Comments:
409  *  --------
410  * 
411  *************************************<->***********************************/
412 void
413 ExitSession(
414         Tt_message msg)
415 {
416     if (smGD.bmsDead == True)
417     {
418         ImmediateExit(-1, msg, True);
419     }
420     if(smGD.compatMode == True)
421     {
422         if (msg != 0) {
423             tt_message_reply( msg );
424             tt_message_destroy( msg );
425         }
426         CompatModeExit();
427     }
428     else
429     {
430         if(smSettings.confirmMode == DtSM_VERBOSE_MODE || 
431            smSettings.startState == DtSM_ASK_STATE)
432         {
433             ConfirmExit( msg, True );
434         }
435         else
436         {
437             ImmediateExit(smSettings.startState, msg, True);
438         }
439     }
440 }
441
442
443 \f
444 /*************************************<->*************************************
445  *
446  *  ConfirmExit ()
447  *
448  *
449  *  Description:
450  *  -----------
451  *  Create the exit confirmation dialog box (if it hasn't been) and confirm
452  *  that the user wants to exit the session.  This routine only gets called
453  *  when the user hasn't turned of exit confirmation and is not in ASK mode
454  *
455  *
456  *  Inputs:
457  *  ------
458  *  msg -- if non-zero, Session_Exit request to reply/fail && destroy
459  *
460  * 
461  *  Outputs:
462  *  -------
463  *  None.
464  *
465  *
466  *  Comments:
467  *  --------
468  * 
469  *************************************<->***********************************/
470 int 
471 ConfirmExit( 
472     Tt_message msg,
473     Boolean doSave)
474 {
475     int         i;
476     String      tmpString;
477     ExitRecord  *exitRec;
478     Tt_message  *pmsg;
479     static      XmString homeToHome;    /* started Home, restore to Home */
480     static      XmString returnToCurrent; /* started Home or Current but
481                                             retrun to Current */
482     static      XmString currentToHome; /* started Current, return to Home */
483
484     if(smDD.confExit == NULL)
485     {
486         /*
487          * Create all compound strings for confirmation dialogs
488          */
489         returnToCurrent = XmStringCreateLocalized(((char *)GETMESSAGE(18, 4, 
490                 "Exiting the desktop session...\n\n\
491 Your Current session will be restored upon login.\n\n\
492 Application updates you have not saved will be lost.\n\n\
493 Continue Logout?")));
494
495         homeToHome = XmStringCreateLocalized(((char *)GETMESSAGE(18, 5, 
496                 "Exiting the desktop session...\n\n\
497 Your Home session will be restored upon login.\n\
498 Your Current session will not be saved.\n\n\
499 Application updates you have not saved will be lost.\n\n\
500 Continue Logout?")));
501
502         currentToHome = XmStringCreateLocalized(((char *)GETMESSAGE(18, 75,
503                 "Exiting the desktop session...\n\n\
504 Your Current session will be saved but your Home\n\
505 session will be restored upon login.\n\n\
506 Application updates you have not saved will be lost.\n\n\
507 Continue Logout?")));
508
509         /*
510          * Build up the correct string for this dialog
511          */
512         i = 0;
513         if (smGD.sessionType == HOME_SESSION && 
514             smSettings.startState == DtSM_HOME_STATE) 
515         {
516             XtSetArg(uiArgs[i], XmNmessageString, homeToHome); i++;
517         }
518         else if (smGD.sessionType == CURRENT_SESSION &&
519                  smSettings.startState == DtSM_HOME_STATE) 
520         {
521             XtSetArg(uiArgs[i], XmNmessageString, currentToHome); i++;
522         }
523         else
524         {
525             XtSetArg(uiArgs[i], XmNmessageString, returnToCurrent); i++;
526         }
527
528         /*
529          * Now create the dialog box
530          */
531         tmpString = GETMESSAGE(18, 6, "Logout Confirmation");
532         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
533         XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
534         XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_CENTER); i++;
535         XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
536         XtSetArg(uiArgs[i], XmNokLabelString, smDD.okLogoutString); i++;
537         XtSetArg(uiArgs[i], XmNcancelLabelString, smDD.cancelLogoutString); i++;
538         XtSetArg(uiArgs[i], XmNhelpLabelString, smDD.helpString); i++;
539         XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
540
541         pmsg = (Tt_message *)XtMalloc(sizeof(Tt_message));
542         XtSetArg(uiArgs[i], XmNuserData, pmsg); i++;
543
544         smDD.confExit = XmCreateWarningDialog(smGD.topLevelWid, "exitDialog",
545                                               uiArgs, i);
546         
547         i = 0;
548         XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
549         XtSetArg(uiArgs[i], XmNmwmFunctions, 0);i++;
550         XtSetArg(uiArgs[i], XmNmwmDecorations,
551                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER));i++;
552         XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
553         XtSetValues(XtParent(smDD.confExit), uiArgs, i);
554
555         exitRec = (ExitRecord *)XtMalloc( sizeof(ExitRecord) );
556         exitRec->pmsg = pmsg;
557         exitRec->doSave = doSave;
558         XtAddCallback (smDD.confExit, XmNokCallback, ExitConfirmed, exitRec);
559 #ifndef NO_XVH
560         XtAddCallback (smDD.confExit, XmNhelpCallback,
561                        TopicHelpRequested, HELP_LOGOUT_STR);
562 #endif
563         exitRec = (ExitRecord *)XtMalloc( sizeof(ExitRecord) );
564         exitRec->pmsg = pmsg;
565         exitRec->doSave = doSave;
566         exitRec->u.exitCancelledDialog = smDD.confExit;
567         XtAddCallback (smDD.confExit, XmNcancelCallback,
568                        ExitCancelled, exitRec);
569     }
570     else
571     {
572         /*
573          * The user may have changed the type of session to be
574          * restored so must update the dialog's message.
575          */
576         i = 0;
577         if (smGD.sessionType == HOME_SESSION && 
578             smSettings.startState == DtSM_HOME_STATE) 
579         {
580             XtSetArg(uiArgs[i], XmNmessageString, homeToHome); i++;
581         }
582         else if (smGD.sessionType == CURRENT_SESSION &&
583                  smSettings.startState == DtSM_HOME_STATE) 
584         {
585             XtSetArg(uiArgs[i], XmNmessageString, currentToHome); i++;
586         }
587         else
588         {
589             XtSetArg(uiArgs[i], XmNmessageString, returnToCurrent); i++;
590         }
591
592         XtSetValues(smDD.confExit, uiArgs, i);
593     }
594
595    /*
596     * Refresh buffer containing pointer to Tt_message.
597     */
598     i=0;
599     XtSetArg(uiArgs[i], XmNuserData, &pmsg); i++;
600     XtGetValues(smDD.confExit, uiArgs, i);
601     *pmsg = msg;
602
603
604     XtAddCallback (XtParent(smDD.confExit), XmNpopupCallback, DialogUp, NULL);
605         
606     XtManageChild(smDD.confExit);
607     return(0);
608 }
609
610 \f
611 /*************************************<->*************************************
612  *
613  *  WarnMsgFailue ()
614  *
615  *
616  *  Description:
617  *  -----------
618  *  Let the user know that the bms has died and that the current session
619  *  will not be saved.
620  *
621  *
622  *  Inputs:
623  *  ------
624  *
625  * 
626  *  Outputs:
627  *  -------
628  *  None.
629  *
630  *
631  *  Comments:
632  *  --------
633  * 
634  *************************************<->***********************************/
635 int 
636 WarnMsgFailure( void )
637 {
638     int         i;
639     XmString    bmsDeadString;
640     String      tmpString;
641
642     if(smDD.deadWid == NULL)
643     {
644         bmsDeadString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 38, 
645                 "Messaging System Inoperative\n\n\
646 To restart:\n\n1) Save all open data files.\n\
647 2) Logout.\n\
648 3) Log in again.\n\nNote: The current session will not be saved.\n\n\
649 When you are ready to begin the restart process, click [OK] and\n\
650 proceed to save your files.")));
651
652         /*
653          * Now create the dialog box
654          */
655         i = 0;
656         tmpString = GETMESSAGE(18, 12, "Message Failure");
657         XtSetArg(uiArgs[i], XmNmessageString, bmsDeadString);i++;
658         XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
659         XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
660         XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
661         XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
662         XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
663         XtSetArg(uiArgs[i], XmNhelpLabelString, smDD.helpString); i++;
664         XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
665         smDD.deadWid = XmCreateWarningDialog(smGD.topLevelWid, "deadDialog",
666                                              uiArgs, i);
667
668         i = 0;
669         XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
670         XtSetArg(uiArgs[i], XmNmwmFunctions, 0);i++;
671         XtSetArg(uiArgs[i], XmNmwmDecorations,
672                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER));i++;
673         XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
674         XtSetValues(XtParent(smDD.deadWid), uiArgs, i);
675         
676         XtAddCallback (XtParent(smDD.deadWid),
677                        XmNpopupCallback, DialogUp, NULL);
678         XtUnmanageChild(XmMessageBoxGetChild(smDD.deadWid,
679                                              XmDIALOG_CANCEL_BUTTON));
680
681         /*
682          * Now add in the callback and get out of here
683          */
684         XtAddCallback (smDD.deadWid, XmNokCallback,
685                        SimpleOK, (XtPointer) smDD.deadWid);
686 #ifndef NO_XVH
687         XtAddCallback (smDD.deadWid, XmNhelpCallback,
688                        TopicHelpRequested, HELP_BMS_DEAD_STR);
689 #endif
690         XtAddCallback (smDD.deadWid, XmNcancelCallback,
691                         NULL, NULL);
692         XmStringFree(bmsDeadString);
693     }
694
695     XtManageChild(smDD.deadWid);
696     return(0);
697 }
698
699 \f
700 /*************************************<->*************************************
701  *
702  *  CompatModeExit ()
703  *
704  *
705  *  Description:
706  *  -----------
707  *  Let the user know that the logout button can not be used to exit in
708  *  compatibility mode.
709  *
710  *
711  *  Inputs:
712  *  ------
713  *
714  * 
715  *  Outputs:
716  *  -------
717  *  None.
718  *
719  *
720  *  Comments:
721  *  --------
722  * 
723  *************************************<->***********************************/
724 static int 
725 CompatModeExit( void )
726 {
727     int         i;
728     XmString    compatModeString;
729     String      tmpString;
730
731     if(smDD.compatExit == NULL)
732     {
733         compatModeString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 34, 
734                 "This session was started from an X Window System startup script.\n\n\
735 No session information will be saved.\n\nUse the reset key sequence to log out.")));
736
737         /*
738          * Now create the dialog box
739          */
740         i = 0;
741         tmpString = GETMESSAGE(18, 35, "Logout Message");
742         XtSetArg(uiArgs[i], XmNmessageString, compatModeString);i++;
743         XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
744         XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
745         XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_CENTER); i++;
746         XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
747         XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
748         XtSetArg(uiArgs[i], XmNhelpLabelString, smDD.helpString); i++;
749         XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
750         smDD.compatExit = XmCreateInformationDialog(smGD.topLevelWid,
751                                                     "compatDialog",
752                                                     uiArgs, i);
753
754         i = 0;
755         XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
756         XtSetArg(uiArgs[i], XmNmwmFunctions, 0);i++;
757         XtSetArg(uiArgs[i], XmNmwmDecorations,
758                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER));i++;
759     XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
760         XtSetValues(XtParent(smDD.compatExit), uiArgs, i);
761         
762         XtAddCallback (XtParent(smDD.compatExit),
763                        XmNpopupCallback, DialogUp, NULL);
764         XtUnmanageChild(XmMessageBoxGetChild(smDD.compatExit,
765                                              XmDIALOG_CANCEL_BUTTON));
766
767         /*
768          * Now add in the callback and get out of here
769          */
770         XtAddCallback (smDD.compatExit, XmNokCallback,
771                        SimpleOK, smDD.compatExit);
772 #ifndef NO_XVH
773         XtAddCallback (smDD.compatExit, XmNhelpCallback,
774                        TopicHelpRequested, HELP_LOGOUT_COMPAT_MODE_STR);
775 #endif
776         XmStringFree(compatModeString);
777     }
778
779     XtManageChild(smDD.compatExit);
780     return(0);
781 }
782
783
784 \f
785 /*************************************<->*************************************
786  *
787  *  CreateLockDialogWithCover()
788  *
789  *
790  *  Description:
791  *  -----------
792  *  Create the lock dialog when it exists as a part of a cover
793  *
794  *
795  *  Inputs:
796  *  ------
797  *
798  * 
799  *  Outputs:
800  *  -------
801  *  None.
802  *
803  *
804  *  Comments:
805  *  --------
806  * 
807  *************************************<->***********************************/
808 Widget 
809 CreateLockDialogWithCover(
810         Widget parent )
811 {
812     int         i;
813     Widget      loginLabel, instructLabel, tmpLock;
814     Widget      indFrame, loginPic, picFrame, loginFrame;
815     Widget      passwdLabel, passwdForm;
816     Dimension   width;          /* width, height of drop shadow    */
817     XmString    lockString, passwordString;
818     char        *lockMessage;
819     char        *envLog;
820     Pixel   fg, bg, focus_color;         /* foreground, background colors   */
821
822     i = 0;
823     XtSetArg(uiArgs[i], XmNmarginWidth, 0); i++;
824     XtSetArg(uiArgs[i], XmNmarginHeight, 0); i++;
825     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
826     XtSetArg(uiArgs[i], XmNshadowThickness,5); i++;
827     XtSetArg(uiArgs[i], XmNunitType, XmPIXELS); i++;
828     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
829     XtSetArg(uiArgs[i], XmNmappedWhenManaged, False); i++;
830     tmpLock = XmCreateForm(parent, "lockDialog", uiArgs, i);
831     smDD.matte[1] = tmpLock;
832
833     i = 0;
834     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
835     XtSetArg(uiArgs[i], XmNshadowThickness, 2); i++;
836     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_FORM); i++;
837     XtSetArg(uiArgs[i], XmNtopOffset, 15); i++;
838     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_FORM); i++;
839     XtSetArg(uiArgs[i], XmNbottomOffset, 15); i++;
840     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
841     XtSetArg(uiArgs[i], XmNrightOffset, 15); i++;
842     picFrame = XmCreateFrame(tmpLock, "picFrame", uiArgs, i);
843
844     i = 0;
845     XtSetArg(uiArgs[i], XmNforeground, &fg); i++;
846     XtSetArg(uiArgs[i], XmNbackground, &bg); i++;
847     XtGetValues(tmpLock, uiArgs, i);
848      
849     i = 0;
850     XtSetArg(uiArgs[i], XmNfillMode, XmFILL_SELF); i++;
851     XtSetArg(uiArgs[i], XmNbehavior, XmICON_LABEL); i++;
852     XtSetArg(uiArgs[i], XmNpixmapForeground, fg); i++;
853     XtSetArg(uiArgs[i], XmNpixmapBackground, bg); i++;
854     XtSetArg(uiArgs[i], XmNstring, NULL); i++;
855     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++;
856     XtSetArg(uiArgs[i], XmNtraversalOn, False); i++;
857     loginPic = _DtCreateIcon(picFrame, "lockLabelPixmap", uiArgs, i);
858      
859     i = 0;
860     XtSetArg(uiArgs[i], XmNshadowType, XmSHADOW_OUT); i++;
861     XtSetArg(uiArgs[i], XmNshadowThickness, 2); i++; 
862     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_FORM); i++;
863     XtSetArg(uiArgs[i], XmNtopOffset, 15); i++;
864     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_FORM); i++;
865     XtSetArg(uiArgs[i], XmNbottomOffset, 15); i++;
866     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
867     XtSetArg(uiArgs[i], XmNleftOffset, 15); i++;
868     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_WIDGET); i++;
869     XtSetArg(uiArgs[i], XmNrightWidget, picFrame); i++;
870     XtSetArg(uiArgs[i], XmNrightOffset, 0); i++;
871     loginFrame = XmCreateFrame(tmpLock, "loginFrame", uiArgs, i);
872
873     /* 
874      * create the login matte...
875      */
876     i = 0;
877     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
878     smDD.loginMatte[1] = XmCreateForm(loginFrame, "loginMatte", uiArgs, i);
879
880     /*
881      *  create the login/password forms
882      */
883     i = 0;
884     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++; 
885     XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_FORM); i++;
886     XtSetArg(uiArgs[i], XmNrightOffset, 15); i++;
887     XtSetArg(uiArgs[i], XmNbottomAttachment, XmATTACH_POSITION); i++;
888     XtSetArg(uiArgs[i], XmNbottomPosition, 50); i++;
889     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
890     XtSetArg(uiArgs[i], XmNleftOffset, 15); i++;
891     smDD.loginForm[1] = XmCreateForm(smDD.loginMatte[1], "loginForm", uiArgs, i);
892
893     i = 0;
894     XtSetArg(uiArgs[i], XmNresizePolicy, XmRESIZE_NONE);i++;
895     XtSetArg(uiArgs[i], XmNshadowThickness, 0); i++; 
896     XtSetArg(uiArgs[i], XmNtopAttachment, XmATTACH_POSITION); i++;
897     XtSetArg(uiArgs[i], XmNtopPosition, 50); i++;
898         XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
899         XtSetArg(uiArgs[i], XmNleftWidget, smDD.loginForm[1]); i++;
900         XtSetArg(uiArgs[i], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); i++;
901         XtSetArg(uiArgs[i], XmNrightWidget, smDD.loginForm[1]); i++;
902     passwdForm = XmCreateForm(smDD.loginMatte[1], "passwdForm", uiArgs, i);
903
904
905     /*
906      *  create the login/password labels...
907      */
908     i = 0;
909     envLog = getenv("LOGNAME");
910     lockMessage = 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 = XtMalloc(numChars + 1);
1690     XmString tmpString;
1691
1692     if (!passwdMessage) {
1693       PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1694       return;
1695     }
1696
1697     if(numChars > 0)
1698     {
1699         strcpy(passwdMessage, "|");
1700         for(i = 1;i < numChars;i++)
1701         {
1702             if(i==1)
1703                 strcpy(passwdMessage, "|");
1704             else
1705                 strcat(passwdMessage, " ");
1706         }
1707         strcat(passwdMessage, PASSWORD_INDICATOR);
1708     }
1709     else
1710     {
1711         strcpy(passwdMessage, "|");
1712     }
1713
1714     tmpString = XmStringCreateLocalized (passwdMessage);
1715     XtFree(passwdMessage);
1716     /*
1717      * Set the index for the indLabel widget
1718      */
1719     if(smGD.coverScreen == True)
1720     {
1721         index = 1;
1722     }
1723     else
1724     {
1725         index = 0;
1726     }
1727     
1728     i = 0;
1729     XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1730     XtSetValues(smDD.indLabel[index], uiArgs, i);
1731
1732     XmStringFree(tmpString);
1733 }
1734
1735
1736 \f
1737 /*************************************<->*************************************
1738  *
1739  *  WarnNoStartup ()
1740  *
1741  *
1742  *  Description:
1743  *  -----------
1744  *  When the BMS refuses to be started, warn the user about why dt is
1745  *  crashing and then exit.
1746  *
1747  *
1748  *  Inputs:
1749  *  ------
1750  *
1751  * 
1752  *  Outputs:
1753  *  -------
1754  *  None.
1755  *
1756  *
1757  *  Comments:
1758  *  --------
1759  * 
1760  *************************************<->***********************************/
1761 int 
1762 WarnNoStartup( void )
1763 {
1764     int         i;
1765     XmString    bmsNoStartString;
1766     String      tmpString;
1767
1768 #ifdef __osf__
1769
1770     bmsNoStartString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 76,
1771         "The DT messaging system could not be started.\n\n\
1772 To correct the problem:\n\n\
1773 1.  Choose [OK] to return to the login screen.\n\n\
1774 2.  Select Failsafe Session from the login screen's option\n\
1775          menu and log in.\n\n\
1776 3.  Check to see that your hostname exists correctly in /etc/hosts if your\n\
1777      network has already been configured.\n\
1778 4.  If your network has not yet been configured, make sure that /etc/hosts\n\
1779      has the following entry in it:\n\
1780      127.0.0.1 localhost \n\n\
1781 For additional information, see the CDE User's Guide.")));
1782 #else
1783
1784     bmsNoStartString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 36,
1785         "The desktop messaging system could not be started.\n\n\
1786 To correct the problem:\n\n\
1787 1.  Choose [OK] to return to the login screen.\n\n\
1788 2.  Select Failsafe Session from the login screen's option\n\
1789          menu and log in.\n\n\
1790 3.  Check to see that the desktop is properly installed,\n\
1791          the hostname is correct (/etc/hosts) and that the\n\
1792          network is properly configured.\n\n\
1793 For additional information, see the CDE User's Guide.")));
1794 #endif
1795
1796     /*
1797      * Now create the dialog box
1798      */
1799     i = 0;
1800     tmpString = GETMESSAGE(18, 37, "Action Required");
1801     XtSetArg(uiArgs[i], XmNmessageString, bmsNoStartString);i++;
1802     XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
1803     XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
1804     XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
1805     XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
1806     XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
1807     XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
1808     smDD.noStart = XmCreateWarningDialog(smGD.topLevelWid, "noStartDialog",
1809                                              uiArgs, i);
1810
1811     XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
1812     XtSetValues(XtParent(smDD.noStart), uiArgs, i);
1813
1814     XtAddCallback (XtParent(smDD.noStart),
1815                    XmNpopupCallback, DialogUp, NULL);
1816     XtUnmanageChild(XmMessageBoxGetChild(smDD.noStart,
1817                                          XmDIALOG_HELP_BUTTON));
1818     XtUnmanageChild(XmMessageBoxGetChild(smDD.noStart,
1819                                          XmDIALOG_CANCEL_BUTTON));
1820
1821     /*
1822      * Now add in the callback and get out of here
1823      */
1824     XtAddCallback (smDD.noStart, XmNokCallback,
1825                    SimpleOK, smDD.noStart);
1826     XmStringFree(bmsNoStartString);
1827
1828     XtManageChild(smDD.noStart);
1829
1830     return(0);
1831 } /* END OF FUNCTION WarnNoStartup */
1832
1833
1834 #ifdef __osf__
1835
1836 /*************************************<->*************************************
1837  *
1838  *  WarnNewProfile()
1839  *
1840  *
1841  *  Description:
1842  *  -----------
1843  *  Warn the user that a new .dtprofile has just been added to their $HOME
1844  *  directory, indicating a need to edit it and their .login/.profile files.
1845  *
1846  *
1847  *  Inputs:
1848  *  ------
1849  *
1850  * 
1851  *  Outputs:
1852  *  -------
1853  *  None.
1854  *
1855  *
1856  *  Comments:
1857  *  --------
1858  * 
1859  *************************************<->***********************************/
1860 int 
1861 WarnNewProfile( void )
1862 {
1863     int       i;
1864     XmString  newProfileString;
1865     String    tmpString;
1866
1867     newProfileString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 99,
1868    "The new file '.dtprofile' has been added to your home directory.\n\
1869 \n\
1870    Follow the instructions in this file to ensure that when you log in\n\
1871    again your '.login' or '.profile' file will be activated and \n\
1872    that it will interact correctly with CDE. \n\
1873 \n\
1874    For additional information, see the CDE Advanced User's and System\n\
1875    Administrator's Guide.")));
1876
1877
1878     /*
1879      * Now create the dialog box
1880      */
1881     i = 0;
1882     tmpString = GETMESSAGE(18, 37, "Action Required");
1883     XtSetArg(uiArgs[i], XmNmessageString, newProfileString);i++;
1884     XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
1885     XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
1886     XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
1887     XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
1888     XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
1889     XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
1890     smDD.newProfile = XmCreateWarningDialog(smGD.topLevelWid, 
1891                                             "newProfileDialog",
1892                                             uiArgs, i);
1893
1894     XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
1895     XtSetValues(XtParent(smDD.newProfile), uiArgs, i);
1896
1897     XtAddCallback (XtParent(smDD.newProfile),
1898                    XmNpopupCallback, DialogUp, NULL);
1899     XtUnmanageChild(XmMessageBoxGetChild(smDD.newProfile,
1900                                          XmDIALOG_HELP_BUTTON));
1901     XtUnmanageChild(XmMessageBoxGetChild(smDD.newProfile,
1902                                          XmDIALOG_CANCEL_BUTTON));
1903
1904     /*
1905      * Now add in the callback and get out of here
1906      */
1907     XtAddCallback (smDD.newProfile, XmNokCallback,
1908                    SimpleOK, smDD.newProfile);
1909     XmStringFree(newProfileString);
1910
1911     XtManageChild(smDD.newProfile);
1912
1913     return(0);
1914 } /* END OF FUNCTION WarnNewProfile */
1915
1916
1917 #endif
1918
1919
1920 /*************************************<->*************************************
1921  *
1922  *  ConfirmSessionCreation () -
1923  *
1924  *  Description:
1925  *  -----------
1926  *
1927  *  Inputs:
1928  *  ------
1929  * 
1930  *  Outputs:
1931  *  -------
1932  *
1933  *  Returns True if the user says to continue the session; False otherwise
1934  *     or if malloc fails;
1935  *
1936  *  Comments:
1937  *  --------
1938  * 
1939  *************************************<->***********************************/
1940 Boolean
1941 ConfirmSessionCreation (
1942         short           session_type,
1943         unsigned int    _argc,
1944         char            **_argv)
1945 {
1946         int             i, j;
1947         XmString        title_string;
1948         XmString        ok_string;
1949         XmString        cancel_string;
1950         XmString        help_string;
1951         XmString        msg_string;
1952         Widget          tmp_widget;
1953         Arg             args[20];
1954         char            *pch1;
1955         char            *pch2;
1956         char            *pch3;
1957         Dimension       width, height;
1958         Position        x, y;
1959         XEvent          next;
1960         int             argc = _argc;
1961         char            **argv = NULL;
1962
1963         /*
1964          * Create temporary argv because the X toolkit may remove
1965          * pieces of the command line options.
1966          */
1967         if (_argc > 0) {
1968                 argv = (char **) XtMalloc (_argc * sizeof (char *));
1969                 for (i = 0; i < _argc; i++)
1970                         argv[i] = _argv[i];
1971         }
1972
1973         if (session_type == HOME_SESSION)
1974                 pch1 = strdup ((char *) GETMESSAGE(18, 50, "Home"));
1975         else
1976                 pch1 = strdup ((char *) GETMESSAGE(18, 51, "Current"));
1977         if (!pch1) {
1978                 PrintError(DtError, smNLS.cantMallocErrorString);
1979                 SM_EXIT(1);
1980         }
1981
1982         pch2 = strdup ((char *) GETMESSAGE(18, 52, 
1983                 "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."));
1984         if (!pch2) {
1985                 PrintError(DtError, smNLS.cantMallocErrorString);
1986                 SM_EXIT(1);
1987         }
1988
1989         pch3 = XtMalloc (strlen (pch1) +
1990                              strlen (XDisplayName (getenv("DISPLAY"))) +
1991                              strlen (pch2) +
1992                              4);
1993         if (!pch3) {
1994                 PrintError(DtError, smNLS.cantMallocErrorString);
1995                 SM_EXIT(1);
1996         }
1997         (void) sprintf (pch3, pch2, pch1, XDisplayName (getenv("DISPLAY")));
1998
1999         /*
2000          * The X toolkit has not yet been initialized, so do it now.
2001          */
2002         j = 0;
2003         XtToolkitInitialize ();
2004         smGD.appCon = XtCreateApplicationContext();
2005         smGD.display = XtOpenDisplay(smGD.appCon, NULL, argv[0], 
2006                         SM_RESOURCE_CLASS, NULL, 0, &argc, argv);
2007
2008         XtSetArg(args[j], XmNbackground,
2009                 XBlackPixel(smGD.display, XDefaultScreen(smGD.display))); j++;
2010         XtSetArg(args[j], XmNmappedWhenManaged, False); j++;
2011         XtSetArg (args[j], XmNwidth, 1); j++;
2012         XtSetArg (args[j], XmNheight, 1); j++;
2013         tmp_widget = XtAppCreateShell (
2014                         "foo", "foo",
2015                         applicationShellWidgetClass,
2016                         smGD.display, args, j);
2017         XtRealizeWidget(tmp_widget);
2018
2019         /*
2020          * Create the compound strings for the confirmation dialog
2021          */
2022         msg_string = XmStringCreateLocalized (pch3);
2023         title_string = XmStringCreateLocalized(pch3);
2024
2025         ok_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 39, "OK")));
2026         cancel_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 40, "Cancel")));
2027         help_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 41, "Help")));
2028
2029         free (pch1); free (pch2); XtFree (pch3);
2030
2031         /*
2032          * Create the dialog box
2033          */
2034         i = 0;
2035         XtSetArg (uiArgs[i], XmNmessageString, msg_string); i++;
2036         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
2037         XtSetArg (uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
2038         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2039         XtSetArg (uiArgs[i], XmNmappedWhenManaged, True); i++;
2040         XtSetArg (uiArgs[i], XmNtitle, title_string); i++;
2041         XtSetArg (uiArgs[i], XmNokLabelString, ok_string); i++;
2042         XtSetArg (uiArgs[i], XmNcancelLabelString, cancel_string); i++;
2043         XtSetArg (uiArgs[i], XmNhelpLabelString,  help_string); i++;
2044         XtSetArg (uiArgs[i], XmNautoUnmanage, False); i++;
2045
2046         smDD.confirmSession = XmCreateWarningDialog(
2047                         tmp_widget, "confirmDialog", uiArgs, i);
2048
2049         XtAddCallback (smDD.confirmSession, XmNokCallback, 
2050                         ConfirmOKCB, NULL);
2051
2052         /*
2053          * Some help state is not yet initialized and the help
2054          * callback assumes it is so some initializations must
2055          * be done now.
2056          */
2057         smDD.smHelpDialog = NULL;
2058         smDD.okString = ok_string;
2059         smGD.topLevelWid = tmp_widget;
2060
2061         XtAddCallback (smDD.confirmSession, XmNhelpCallback,
2062                        TopicHelpRequested, HELP_CONFIRMATION_SESSION_STR);
2063
2064         XtAddCallback (smDD.confirmSession, XmNcancelCallback,
2065                         ConfirmCancelCB, NULL);
2066         
2067         XtManageChild(smDD.confirmSession);
2068
2069         /*
2070          * Center the dialog on the display
2071          */
2072         i = 0;
2073         XtSetArg(uiArgs[i], XmNwidth, &width); i++;
2074         XtSetArg(uiArgs[i], XmNheight, &height); i++;
2075         XtGetValues(smDD.confirmSession, uiArgs, i);
2076
2077         x = (DisplayWidth(smGD.display,  XDefaultScreen(smGD.display)) / 2) 
2078                         - (width / 2);
2079         y = (DisplayHeight(smGD.display, XDefaultScreen(smGD.display)) / 2) 
2080                         - (height / 2);
2081
2082         i = 0;
2083         XtSetArg(uiArgs[i], XmNx, x); i++;
2084         XtSetArg(uiArgs[i], XmNy, y); i++;
2085         XtSetValues(smDD.confirmSession, uiArgs, i);
2086
2087         XmStringFree (msg_string);
2088         XmStringFree (title_string);
2089         XmStringFree (cancel_string);
2090         XmStringFree (help_string);
2091
2092         /*
2093          * Spin until the OK or Cancel CB is invoked
2094          */
2095         confirmState = ConfirmationNone;
2096         while(1) {
2097                 XtAppNextEvent(smGD.appCon, &next);
2098                 if (next.type != 0)
2099                         XtDispatchEvent(&next);
2100                 if (confirmState == ConfirmationOK) {
2101                         XtDestroyWidget (tmp_widget);
2102                         XmStringFree (ok_string);
2103                         return (True);
2104                 }
2105                 else if (confirmState == ConfirmationCancel) {
2106                         XtDestroyWidget (tmp_widget);
2107                         XmStringFree (ok_string);
2108                         return (False);
2109                 }
2110         }
2111 }
2112
2113
2114 /*************************************<->*************************************
2115  *
2116  *  ConfirmOKCB ()
2117  *
2118  *************************************<->***********************************/
2119 static void 
2120 ConfirmOKCB(
2121         Widget                  w,
2122         XtPointer               client_data,
2123         XtPointer               call_data )
2124 {
2125         XtUnmanageChild(smDD.confirmSession);
2126         confirmState = ConfirmationOK;
2127 }
2128
2129
2130 /*************************************<->*************************************
2131  *
2132  *  ConfirmCancelCB ()
2133  * 
2134  *************************************<->***********************************/
2135 static void 
2136 ConfirmCancelCB(
2137         Widget                  w,
2138         XtPointer               client_data,
2139         XtPointer               call_data )
2140 {
2141         XtUnmanageChild(smDD.confirmSession);
2142         confirmState = ConfirmationCancel;
2143 }
2144
2145
2146 /*************************************<->*************************************
2147  *
2148  *  PostXSMPFailureDialog () -
2149  *
2150  *  Description:
2151  *  -----------
2152  *
2153  *  Inputs:
2154  *  ------
2155  * 
2156  *  Outputs:
2157  *  -------
2158  *
2159  *  Returns True if the user says to continue the session; False otherwise
2160  *     or if malloc fails;
2161  *
2162  *  Comments:
2163  *  --------
2164  * 
2165  *************************************<->***********************************/
2166 void
2167 PostXSMPFailureDialog (
2168         XSMPFailure             failure_code,
2169         Boolean                 check_errorlog)
2170 {
2171         int             i, j;
2172         XmString        ok_string;
2173         XmString        help_string;
2174         XmString        msg_string;
2175         Arg             args[20];
2176         char            *pch1;
2177         char            *pch2 = "";
2178         char            *pch3;
2179         char            *pch4;
2180         char            *pch5;
2181         char            *error_file;
2182         Dimension       width, height;
2183         Position        x, y;
2184         XEvent          next;
2185         int             len;
2186
2187         pch1 = strdup ((char *) GETMESSAGE(40, 1, 
2188                 "A session cannot be started because of the\nfollowing error:"));
2189         if (!pch1) {
2190                 PrintError(DtError, smNLS.cantMallocErrorString);
2191                 SM_EXIT(1);
2192         }
2193
2194         switch (failure_code) {
2195                 case XSMP_FAILURE_SMS_INITIALIZE:
2196                         pch2 = strdup ((char *) GETMESSAGE (40, 2,
2197                                 "SmsInitialize failed."));
2198                         break;
2199                 case XSMP_FAILURE_ICE_LISTEN:
2200                         pch2 = strdup ((char *) GETMESSAGE (40, 3,
2201                                 "IceListenForConnections failed."));
2202                         break;
2203                 case XSMP_FAILURE_AUTHENTICATION:
2204                         pch2 = strdup ((char *) GETMESSAGE (40, 4,
2205                                 "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."));
2206                         break;
2207                 case XSMP_FAILURE_ICE_ADD_WATCH:
2208                         pch2 = strdup ((char *) GETMESSAGE (40, 5,
2209                                 "IceAddConnectionWatch failed."));
2210                         break;
2211                 case XSMP_FAILURE_ICE_COMPOSE_IDS:
2212                         pch2 = strdup ((char *) GETMESSAGE (40, 6,
2213                                 "IceComposeNetworkIds failed."));
2214                         break;
2215                 case XSMP_FAILURE_MALLOC:
2216                         pch2 = strdup ((char *) GETMESSAGE (40, 7,
2217                                 "Could not create the SESSION_MANAGER environment variable."));
2218                         break;
2219         }
2220         if (!pch2) {
2221                 PrintError(DtError, smNLS.cantMallocErrorString);
2222                 SM_EXIT(1);
2223         }
2224
2225         pch3 = strdup ((char *) GETMESSAGE(18, 70, 
2226                 "See the following for more information:"));
2227         if (!pch3) {
2228                 PrintError(DtError, smNLS.cantMallocErrorString);
2229                 SM_EXIT(1);
2230         }
2231
2232         pch4 = strdup ((char *) GETMESSAGE(18, 71, 
2233                 "CDE Advanced Users and System's Administration Guide"));
2234         if (!pch4) {
2235                 PrintError(DtError, smNLS.cantMallocErrorString);
2236                 SM_EXIT(1);
2237         }
2238
2239         error_file = XtMalloc(MAXPATHLEN+1);
2240         strcpy (error_file, "");
2241
2242         /* JET - VU#497553 */
2243         if (check_errorlog) 
2244           {
2245             char                *home;
2246
2247             if (home = getenv ("HOME"))
2248               {
2249                 len = strlen(home) +
2250                   strlen(DtPERSONAL_CONFIG_DIRECTORY) +
2251                   strlen(DtERRORLOG_FILE);
2252
2253                 if (len > MAXPATHLEN)
2254                   error_file = XtRealloc(error_file, len + 1);
2255
2256                 sprintf (error_file, "%s/%s/%s", home, 
2257                          DtPERSONAL_CONFIG_DIRECTORY,
2258                          DtERRORLOG_FILE);
2259               }
2260           }
2261
2262         pch5 = XtMalloc (strlen (pch1) + strlen (pch2) + strlen (pch3) + strlen (pch4) + 
2263                                 strlen (error_file) + 15);
2264         if (!pch5) {
2265                 PrintError(DtError, smNLS.cantMallocErrorString);
2266                 SM_EXIT(1);
2267         }
2268         (void) sprintf (pch5, "%s\n\n   %s\n\n%s\n\n   %s\n   %s\n",
2269                         pch1, pch2, pch3, pch4, error_file);
2270
2271         XtFree(error_file);
2272
2273         /*
2274          * No top level widget has been created so must create one now.
2275          */
2276         j = 0;
2277         XtSetArg (args[j], XmNbackground, XBlackPixel(smGD.display, 
2278                         XDefaultScreen(smGD.display))); j++;
2279         XtSetArg (args[j], XmNmappedWhenManaged, False); j++;
2280         XtSetArg (args[j], XmNwidth, 1); j++;
2281         XtSetArg (args[j], XmNheight, 1); j++;
2282
2283         smGD.topLevelWid = XtAppCreateShell (SM_RESOURCE_NAME, 
2284                         SM_RESOURCE_CLASS, applicationShellWidgetClass,
2285                         smGD.display, args, j);
2286
2287         XtRealizeWidget(smGD.topLevelWid);
2288
2289         /*
2290          * Create the compound strings for the confirmation dialog
2291          */
2292         msg_string = XmStringCreateLocalized (pch5);
2293
2294         ok_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 39, "OK")));
2295         help_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 41, "Help")));
2296
2297         free (pch1); free (pch2); free (pch3); free (pch4); XtFree (pch5);
2298
2299         /*
2300          * Create the dialog box
2301          */
2302         i = 0;
2303         XtSetArg (uiArgs[i], XmNmessageString, msg_string); i++;
2304         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
2305         XtSetArg (uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
2306         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2307         XtSetArg (uiArgs[i], XmNmappedWhenManaged, True); i++;
2308         XtSetArg (uiArgs[i], XmNokLabelString, ok_string); i++;
2309         XtSetArg (uiArgs[i], XmNhelpLabelString,  help_string); i++;
2310         XtSetArg (uiArgs[i], XmNautoUnmanage, False); i++;
2311
2312         smDD.confirmSession = XmCreateWarningDialog(
2313                         smGD.topLevelWid, "confirmDialog", uiArgs, i);
2314
2315         XtAddCallback (smDD.confirmSession, XmNokCallback, 
2316                         XSMPFailureOKCB, NULL);
2317
2318         /*
2319          * Some help state is not yet initialized and the help
2320          * callback assumes it is so some initializations must
2321          * be done now.
2322          */
2323         smDD.smHelpDialog = NULL;
2324         smDD.okString = ok_string;
2325
2326         XtAddCallback (smDD.confirmSession, XmNhelpCallback,
2327                        TopicHelpRequested, HELP_XSMP_INIT_FAILURE_STR);
2328
2329         XtUnmanageChild(XmMessageBoxGetChild(smDD.confirmSession,
2330                                              XmDIALOG_CANCEL_BUTTON));
2331
2332         XtManageChild(smDD.confirmSession);
2333
2334         /*
2335          * Center the dialog on the display
2336          */
2337         i = 0;
2338         XtSetArg(uiArgs[i], XmNwidth, &width); i++;
2339         XtSetArg(uiArgs[i], XmNheight, &height); i++;
2340         XtGetValues(smDD.confirmSession, uiArgs, i);
2341
2342         x = (DisplayWidth(smGD.display,  XDefaultScreen(smGD.display)) / 2) 
2343                         - (width / 2);
2344         y = (DisplayHeight(smGD.display, XDefaultScreen(smGD.display)) / 2) 
2345                         - (height / 2);
2346
2347         i = 0;
2348         XtSetArg(uiArgs[i], XmNx, x); i++;
2349         XtSetArg(uiArgs[i], XmNy, y); i++;
2350         XtSetValues(smDD.confirmSession, uiArgs, i);
2351
2352         XmStringFree (msg_string);
2353         XmStringFree (help_string);
2354
2355         /*
2356          * Spin until the OK CB is invoked
2357          */
2358         while(1) {
2359                 XtAppNextEvent(smGD.appCon, &next);
2360                 if (next.type != 0)
2361                         XtDispatchEvent(&next);
2362         }
2363 }
2364
2365
2366 /*************************************<->*************************************
2367  *
2368  *  XSMPFailureOKCB ()
2369  *
2370  *************************************<->***********************************/
2371 static void 
2372 XSMPFailureOKCB(
2373         Widget                  w,
2374         XtPointer               client_data,
2375         XtPointer               call_data )
2376 {
2377         XtUnmanageChild(smDD.confirmSession);
2378         SM_EXIT(1);
2379 }
2380
2381
2382
2383
2384 /*************************************<->*************************************
2385  *
2386  *  PostSaveSessionErrorDialog
2387  *
2388  *  Description:
2389  *  -----------
2390  *  Let the user know that the Save_Session message does not have the
2391  *  required data and the session will not be saved.
2392  *
2393  *  Inputs:
2394  *  ------
2395  * 
2396  *  Outputs:
2397  *  -------
2398  *
2399  *************************************<->***********************************/
2400 void 
2401 PostSaveSessionErrorDialog ( void )
2402 {
2403     int         i;
2404     XmString    messageString;
2405     String      titleString;
2406
2407     if(smDD.saveSession == NULL)
2408     {
2409         messageString = XmStringCreateLocalized (((char *) GETMESSAGE(18, 56, 
2410                 "The session cannot be saved because the required\n\
2411 'save_type' parameter was not in the message.\n\n\
2412 The session will not be saved.")));
2413
2414         titleString = GETMESSAGE(18, 55, "Save Session Failure");
2415
2416         i = 0;
2417         XtSetArg (uiArgs[i], XmNmessageString,    messageString); i++;
2418         XtSetArg (uiArgs[i], XmNallowShellResize, True); i++;
2419         XtSetArg (uiArgs[i], XmNdialogStyle,      XmDIALOG_SYSTEM_MODAL); i++;
2420         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2421         XtSetArg (uiArgs[i], XmNtitle,            titleString); i++;
2422         XtSetArg (uiArgs[i], XmNokLabelString,    smDD.okString); i++;
2423         XtSetArg (uiArgs[i], XmNhelpLabelString,  smDD.helpString); i++;
2424         XtSetArg (uiArgs[i], XmNautoUnmanage,     False); i++;
2425
2426         smDD.saveSession = XmCreateErrorDialog(smGD.topLevelWid, 
2427                         "sessionSaveDialog", uiArgs, i);
2428
2429         i = 0;
2430         XtSetArg (uiArgs[i], XmNuseAsyncGeometry, True);i++;
2431         XtSetArg (uiArgs[i], XmNmwmFunctions,     0);i++;
2432         XtSetArg (uiArgs[i], XmNmwmDecorations,
2433                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER)); i++;
2434         XtSetArg (uiArgs[i], XmNmwmInputMode,     MWM_INPUT_SYSTEM_MODAL);i++;
2435
2436         XtSetValues(XtParent(smDD.saveSession), uiArgs, i);
2437         
2438         XtAddCallback (XtParent(smDD.saveSession),
2439                        XmNpopupCallback, DialogUp, NULL);
2440
2441         XtUnmanageChild (XmMessageBoxGetChild(smDD.saveSession,
2442                                              XmDIALOG_CANCEL_BUTTON));
2443
2444         XtAddCallback (smDD.saveSession, XmNokCallback,
2445                        SimpleOK, (XtPointer) smDD.saveSession);
2446 #ifndef NO_XVH
2447         XtAddCallback (smDD.saveSession, XmNhelpCallback,
2448                        TopicHelpRequested, HELP_SESSION_SAVE_ERROR_STR);
2449 #endif
2450         XmStringFree(messageString);
2451     }
2452
2453     XtManageChild(smDD.saveSession);
2454
2455     return;
2456 }
2457
2458
2459
2460 /*************************************<->*************************************
2461  *
2462  *  PostReasonsDialog - posts a Warning dialog on behalf of a client
2463  *      that supplied a "reason" when it closed its connection
2464  *
2465  *  Inputs:
2466  *  ------
2467  * 
2468  *  Outputs:    void
2469  *  -------
2470  *
2471  *************************************<->***********************************/
2472 void
2473 PostReasonsDialog (
2474         char                    * progName,
2475         int                     numMsgs,
2476         char                    ** message,
2477         Boolean                 waitForResponse)
2478 {
2479         XmString                msgString;
2480         XmString                okString;
2481         XmString                helpString;
2482         Arg                     args[20];
2483         char                    * titleString;
2484         char                    * str1;
2485         char                    * str2;
2486         char                    * str3;
2487         int                     i;
2488         int                     len;
2489         XEvent                  next;
2490
2491         str1 = strdup ((char *) GETMESSAGE(40, 28, 
2492                 "Application '%s'\nexited for the following reason:\n\n%s"));
2493         if (!str1) {
2494                 PrintError(DtError, smNLS.cantMallocErrorString);
2495                 SM_EXIT(1);
2496         }
2497
2498         for (i = 0, len = 0; i < numMsgs; i++) 
2499                 len += strlen (message[i]);
2500
2501         str2 = XtMalloc (len + (numMsgs * 3) + 1);
2502         if (!str2) {
2503                 PrintError(DtError, smNLS.cantMallocErrorString);
2504                 SM_EXIT(1);
2505         }
2506         str2[0] = '\000';
2507         for (i = 0; i < numMsgs; i++) {
2508                 strcat (str2, message[i]);
2509                 strcat (str2, "\n");
2510         }
2511
2512         str3 = XtMalloc (strlen (str1) + strlen (str2) + strlen (progName) + 4);
2513         if (!str3) {
2514                 PrintError(DtError, smNLS.cantMallocErrorString);
2515                 SM_EXIT(1);
2516         }
2517         (void) sprintf (str3, str1, progName, str2);
2518
2519         DtMsgLogMessage (smGD.programName, DtMsgLogWarning, str3);
2520
2521         free (str1);
2522         str1 = strdup ((char *) GETMESSAGE(40, 29, 
2523                 "Application Close Reasons"));
2524         if (!str1) {
2525                 PrintError(DtError, smNLS.cantMallocErrorString);
2526                 SM_EXIT(1);
2527         }
2528
2529         msgString = XmStringCreateLocalized (str3);
2530
2531         okString = XmStringCreateLocalized(((char *) GETMESSAGE(18, 39, "OK")));
2532
2533         helpString = XmStringCreateLocalized(((char *) GETMESSAGE(18, 41, "Help")));
2534
2535         /*
2536          * Create the dialog box
2537          */
2538         i = 0;
2539         XtSetArg (uiArgs[i], XmNmessageString, msgString); i++;
2540         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
2541         XtSetArg (uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
2542         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2543         XtSetArg (uiArgs[i], XmNmappedWhenManaged, True); i++;
2544         XtSetArg (uiArgs[i], XmNtitle, str1); i++;
2545         XtSetArg (uiArgs[i], XmNokLabelString, okString); i++;
2546         XtSetArg (uiArgs[i], XmNhelpLabelString, helpString); i++;
2547         XtSetArg (uiArgs[i], XmNautoUnmanage, False); i++;
2548
2549         smDD.clientReasons = XmCreateWarningDialog(smGD.topLevelWid, 
2550                 "clientReasons", uiArgs, i);
2551
2552         i = 0;
2553         XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
2554         XtSetArg(uiArgs[i], XmNmwmFunctions, 0);i++;
2555         XtSetArg(uiArgs[i], XmNmwmDecorations,
2556                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER));i++;
2557         XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
2558         XtSetValues(XtParent(smDD.clientReasons), uiArgs, i);
2559         
2560         XtAddCallback (XtParent(smDD.clientReasons),
2561                        XmNpopupCallback, DialogUp, NULL);
2562
2563         XtUnmanageChild (XmMessageBoxGetChild (smDD.clientReasons,
2564                                              XmDIALOG_CANCEL_BUTTON));
2565
2566         /*
2567          * Now add in the callback and get out of here
2568          */
2569         XtAddCallback (smDD.clientReasons, XmNokCallback,
2570                        SimpleOK, (XtPointer) smDD.clientReasons);
2571 #ifndef NO_XVH
2572         XtAddCallback (smDD.clientReasons, XmNhelpCallback,
2573                        TopicHelpRequested, HELP_APP_CLOSE_REASONS_STR);
2574 #endif
2575         free (str1); 
2576         XtFree (str2); 
2577         XtFree (str3);
2578         XmStringFree (msgString);
2579         XmStringFree (okString);
2580         XmStringFree (helpString);
2581
2582         XtManageChild (smDD.clientReasons);
2583
2584         /*
2585          * Spin until the OK callback is invoked.  If a shutdown
2586          * is in progress, we don't want to return until the
2587          * user has acknowledged this message.
2588          */
2589         reasonsDialogOK = False;
2590         if (waitForResponse) {
2591                 while (1) {
2592                         XtAppNextEvent (smGD.appCon, &next);
2593                         if (next.type != 0)
2594                                 XtDispatchEvent(&next);
2595                         if (reasonsDialogOK == True)
2596                                 break;
2597                 }
2598         }
2599 }
2600
2601
2602 /*************************************<->*************************************
2603  *
2604  *  SaveTimeout
2605  *
2606  *  Description:
2607  *  -----------
2608  *  Timeout procedure that is invoked when a save timer expires.
2609  *
2610  *  Inputs:
2611  *  ------
2612  *
2613  *  Outputs: None
2614  *  -------
2615  *
2616  *************************************<->***********************************/
2617 static void
2618 SaveTimeout (
2619         XtPointer               client_data,
2620         XtIntervalId            *id)
2621 {
2622         saveTimeout = True;
2623
2624         if (smXSMP.saveState.shutdownCanceled == False) {
2625                 /* 
2626                  * Run the user's exit script if there is one
2627                  */
2628                 if (smGD.compatMode == False)
2629                         StartEtc(True);    /* run sessionexit */
2630
2631                 _DtReleaseLock(smGD.display, SM_RUNNING_LOCK);
2632                 SM_EXIT(0);
2633         }
2634 }