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