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