dtsession: also block HUP and PIPE when preparing to shutdown
[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     sigblock(sigmask(SIGHUP));
1161     sigblock(sigmask(SIGPIPE));
1162 #else
1163     old = sighold(SIGTERM);
1164 #endif
1165     /*
1166      *
1167      */
1168     if(smGD.bmsDead == False)
1169     {
1170         notice = (Tt_message) tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
1171                                                   "XSession_Ending", 0);
1172         tt_message_send( notice );
1173         tt_message_destroy( notice );
1174     }
1175     if (msg != 0) {
1176         tt_message_reply( msg );
1177         tt_message_destroy( msg );
1178     }
1179
1180     if (doSave)
1181     {
1182         XEvent          next;
1183         Tt_message      msg;
1184         int             sessionType = smGD.sessionType;
1185         XtIntervalId    timerId;
1186
1187         msg = (Tt_message) tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
1188                                                "DtActivity_Beginning", 0 );
1189         tt_message_send( msg );
1190         tt_message_destroy( msg );
1191
1192         if (smGD.sessionType == CURRENT_SESSION ||
1193             smGD.sessionType == DEFAULT_SESSION)
1194             SaveState (False, DtSM_CURRENT_STATE, SmSaveLocal, True, 
1195                  DEFAULT_INTERACT_STYLE, DEFAULT_FAST, DEFAULT_GLOBAL);
1196         else if (smGD.sessionType == HOME_SESSION && 
1197                  smSettings.startState == DtSM_CURRENT_STATE)
1198             SaveState (False, DtSM_HOME_STATE, SmSaveLocal, True, 
1199                  DEFAULT_INTERACT_STYLE, DEFAULT_FAST, DEFAULT_GLOBAL);
1200         else
1201             SaveState (False, DtSM_HOME_STATE, SmSaveGlobal, True, 
1202                  DEFAULT_INTERACT_STYLE, DEFAULT_FAST, DEFAULT_GLOBAL);
1203
1204         /*
1205          * Restore sessionType - it may have been changed in SaveState
1206          */
1207         smGD.sessionType = sessionType;
1208
1209         XSync(smGD.display, 0);
1210
1211         smGD.loggingOut = True;
1212
1213         /* JET - set this here so we don't exit prematurely (while
1214          * handling our own SM exit callback - duh).
1215          */
1216         smGD.ExitComplete = False;
1217
1218         saveTimeout = False;
1219         timerId = XtAppAddTimeOut (smGD.appCon, smRes.saveYourselfTimeout, 
1220                                    SaveTimeout, NULL);
1221
1222         while (smXSMP.saveState.saveComplete == False && 
1223                smXSMP.saveState.shutdownCanceled == False) {
1224             if (saveTimeout)
1225                 break;
1226             XtAppNextEvent(smGD.appCon, &next);
1227             if (next.type != 0)
1228                 XtDispatchEvent(&next);
1229         }
1230     }
1231     
1232     /* JET - need this, since dtsession was exiting in the
1233      * XtAppNextEvent above (receiving it's own EXIT SM message) This
1234      * is checked in SmExit() so exit's will only occur after this
1235      * housekeeping has been completed.
1236      */
1237     smGD.ExitComplete = True; 
1238
1239     if (smXSMP.saveState.shutdownCanceled == False) {
1240         /* 
1241          * Run the user's exit script if there is one
1242          */
1243         if (smGD.compatMode == False) 
1244         {
1245             StartEtc(True);    /* run sessionexit */
1246         }
1247
1248         _DtReleaseLock(smGD.display, SM_RUNNING_LOCK);
1249         SM_EXIT(0);
1250     }
1251 }
1252
1253
1254 \f
1255 /*************************************<->*************************************
1256  *
1257  *  ExitCancelled ()
1258  *
1259  *
1260  *  Description:
1261  *  -----------
1262  *  Called when the user bails out from a logout at the confirmation dialog
1263  *
1264  *
1265  *  Inputs:
1266  *  ------
1267  *  client_data - tells which dialog to unmange (the query or confirm exit)
1268  *  msg -- if non-zero, Session_Exit request to reply/fail && destroy
1269  *
1270  * 
1271  *  Outputs:
1272  *  -------
1273  *  None.
1274  *
1275  *
1276  *  Comments:
1277  *  --------
1278  * 
1279  *************************************<->***********************************/
1280 static void 
1281 ExitCancelled(
1282         Widget w,
1283         XtPointer client_data,
1284         XtPointer call_data )
1285 {
1286     ExitRecord *exitRec = (ExitRecord *)client_data;
1287
1288     if(XtIsManaged(exitRec->u.exitCancelledDialog))
1289     {
1290         XtUnmanageChild(exitRec->u.exitCancelledDialog);
1291     }
1292
1293     if(smDD.smHelpDialog && XtIsManaged(smDD.smHelpDialog))
1294     {
1295         XtUnmanageChild(smDD.smHelpDialog);
1296     }
1297
1298     if (*exitRec->pmsg != 0) {
1299             tttk_message_fail(*exitRec->pmsg, TT_DESKTOP_ECANCELED, 0, 1 );
1300     }
1301     SetSystemReady();
1302 }
1303
1304
1305 \f
1306 /*************************************<->*************************************
1307  *
1308  *  DialogUp ()
1309  *
1310  *
1311  *  Description:
1312  *  -----------
1313  *  Once the dialog is managed, but not popped up - reposition it so that
1314  *  it appears in the middle of the screen then remove the popup callback
1315  *
1316  *
1317  *  Inputs:
1318  *  ------
1319  *
1320  * 
1321  *  Outputs:
1322  *  -------
1323  *  None
1324  *
1325  *
1326  *  Comments:
1327  *  --------
1328  *  This routine can be used for any generic SYSTEM_MODAL dialog
1329  * 
1330  *************************************<->***********************************/
1331 void 
1332 DialogUp(
1333         Widget w,
1334         XtPointer client_data,
1335         XtPointer call_data )
1336 {
1337     int         i;
1338     Dimension   width, height;
1339     Position    x, y;
1340
1341     /*
1342      * Get the size of the dialog box - then compute its position
1343      */
1344     i = 0;
1345     XtSetArg(uiArgs[i], XmNwidth, &width);i++;
1346     XtSetArg(uiArgs[i], XmNheight, &height);i++;
1347     XtGetValues(w, uiArgs, i);
1348     
1349     x = (DisplayWidth(smGD.display, smGD.screen) / 2) - (width / 2);
1350     y = (DisplayHeight(smGD.display, smGD.screen) / 2) - (height / 2);
1351     
1352     i = 0;
1353     XtSetArg(uiArgs[i], XmNx, x);i++;
1354     XtSetArg(uiArgs[i], XmNy, y);i++;
1355     XtSetValues(w, uiArgs, i);
1356
1357     XtRemoveCallback(w, XmNpopupCallback, DialogUp, NULL);
1358 }
1359
1360
1361
1362 \f
1363 /*************************************<->*************************************
1364  *
1365  *  ShowWaitState (flag)
1366  *
1367  *
1368  *  Description:
1369  *  -----------
1370  *  Enter/Leave the wait state.
1371  *
1372  *
1373  *  Inputs:
1374  *  ------
1375  *  flag = TRUE for Enter, FALSE for Leave.
1376  *
1377  * 
1378  *  Outputs:
1379  *  -------
1380  *  None.
1381  *
1382  *
1383  *  Comments:
1384  *  --------
1385  *  Stolen from the window manager code.
1386  * 
1387  *************************************<->***********************************/
1388
1389 void 
1390 ShowWaitState(
1391         Boolean flag )
1392 {
1393     if (flag)
1394     {
1395         XGrabPointer (smGD.display, DefaultRootWindow(smGD.display), FALSE, 
1396                       0, GrabModeAsync, GrabModeAsync, None, 
1397                       smGD.waitCursor, CurrentTime);
1398         XGrabKeyboard (smGD.display, DefaultRootWindow(smGD.display), FALSE, 
1399                        GrabModeAsync, GrabModeAsync, CurrentTime);
1400     }
1401     else
1402     {
1403         XUngrabPointer (smGD.display, CurrentTime);
1404         XUngrabKeyboard (smGD.display, CurrentTime);
1405     }
1406     XSync(smGD.display, 0);
1407 }
1408
1409 \f
1410 /*************************************<->*************************************
1411  *
1412  *  InitCursorInfo ()
1413  *
1414  *
1415  *  Description:
1416  *  -----------
1417  *  This function determines whether a server supports large cursors.  It it
1418  *  does large feedback cursors are used in some cases (wait state and
1419  *  system modal state); otherwise smaller (16x16) standard cursors are used.
1420  *
1421  *  Outputs:
1422  *  -------
1423  *  Returns true if large cursors are supported, false otherwise
1424  *
1425  *  Comments:
1426  *  ---------
1427  *  This code was stolen from the window manager
1428  * 
1429  *************************************<->***********************************/
1430 Boolean 
1431 InitCursorInfo( void )
1432 {
1433     unsigned int cWidth;
1434     unsigned int cHeight;
1435
1436     if (XQueryBestCursor (smGD.display, DefaultRootWindow(smGD.display),
1437                           32, 32, &cWidth, &cHeight))
1438     {
1439         if ((cWidth >= 32) && (cHeight >= 32))
1440         {
1441            return(True);
1442         }
1443     }
1444
1445     return(False);
1446 }
1447
1448
1449 \f
1450 /*************************************<->*************************************
1451  *
1452  *  LockDialogUp ()
1453  *
1454  *
1455  *  Description:
1456  *  -----------
1457  *  Once the lock dialog is managed, but not popped up - reposition it so that
1458  *  it appears in the middle of the screen then remove the popup callback
1459  *
1460  *
1461  *  Inputs:
1462  *  ------
1463  *
1464  * 
1465  *  Outputs:
1466  *  -------
1467  *  None.
1468  *
1469  *
1470  *  Comments:
1471  *  --------
1472  * 
1473  *************************************<->***********************************/
1474 static void 
1475 LockDialogUp(
1476         Widget w,
1477         XtPointer client_data,
1478         XtPointer call_data )
1479 {
1480     
1481     register int        i;
1482     Dimension   width, height;  /* size values returned by XtGetValues     */
1483     Dimension   shadowThickness;/* size values returned by XtGetValues     */
1484     
1485     struct
1486     {                   /* position, size of widgets (pixels)      */
1487         int x, y;
1488         int     width;
1489         int height;
1490         int shadow;
1491     } mw;       /* matte, logo, drop shadow & login matte  */
1492
1493     int         width1, width2; /* general width variable                  */
1494     int         x1, y1;         /* general position variables              */
1495     int         index;
1496     
1497     /*
1498      * The partial cover has widgets of index 0 - the cover has
1499      * index 1
1500      */
1501     if(smGD.coverScreen == True)
1502     {
1503         index = 1;
1504     }
1505     else
1506     {
1507         index = 0;
1508     }
1509     
1510     /*
1511      *  - center the main matte horizontally and vertically...
1512      */
1513     i = 0;
1514     XtSetArg(uiArgs[i], XmNwidth, &width); i++;
1515     XtSetArg(uiArgs[i], XmNheight, &height); i++;
1516     XtSetArg(uiArgs[i], XmNshadowThickness, &shadowThickness); i++;
1517     XtGetValues(smDD.matte[index], uiArgs, i);
1518
1519     mw.shadow = shadowThickness;
1520     mw.width  = width;
1521     mw.height = height;
1522     mw.x      = (DisplayWidth(smGD.display, smGD.screen)  - mw.width)/2;
1523     mw.y      = (DisplayHeight(smGD.display, smGD.screen) - mw.height)/2;
1524
1525     if ( mw.x < 0 ) mw.x = 0;
1526     if ( mw.y < 0 ) mw.y = 0;
1527     
1528     x1 = mw.x;
1529     y1 = mw.y;
1530
1531     i = 0;
1532
1533     XtSetArg(uiArgs[i], XmNx, x1); i++;
1534     XtSetArg(uiArgs[i], XmNy, y1); i++;
1535
1536     XtSetValues(smDD.matte[index], uiArgs, i);
1537
1538     /*
1539      *  - center the login/password frames horizontally in the login_matte...
1540      */
1541     XtSetArg(uiArgs[0], XmNwidth,  &width);
1542     XtGetValues(smDD.loginMatte[index], uiArgs, 1);
1543     width1 = (int)width;    
1544
1545     XtSetArg(uiArgs[0], XmNwidth,  &width);
1546     XtGetValues(smDD.loginForm[index], uiArgs, 1);
1547     width2 = (int)width;
1548     
1549     i = 0;
1550     XtSetArg(uiArgs[i], XmNleftAttachment, XmATTACH_FORM); i++;
1551     XtSetArg(uiArgs[i], XmNleftOffset, (width1 - width2) / 2); i++;
1552     XtSetValues(smDD.loginForm[index],  uiArgs, i);
1553 }
1554
1555
1556 \f
1557 /*************************************<->*************************************
1558  *
1559  *  SimpleOK()
1560  *
1561  *
1562  *  Description:
1563  *  -----------
1564  *  Simply dismiss a dialog.  Does special process for a compatibility mode
1565  *  logout dialog and when the bms won't start.
1566  *
1567  *
1568  *  Inputs:
1569  *  ------
1570  *  client_data - sends in the dialog to be dismissed.
1571  *
1572  * 
1573  *  Outputs:
1574  *  -------
1575  *  None.
1576  *
1577  *
1578  *  Comments:
1579  *  --------
1580  * 
1581  *************************************<->***********************************/
1582 static void 
1583 SimpleOK(
1584         Widget w,
1585         XtPointer client_data,
1586         XtPointer call_data )
1587 {
1588     Widget      dismissDialog = (Widget) client_data;
1589
1590     if(XtIsManaged(dismissDialog))
1591     {
1592         XtUnmanageChild(dismissDialog);
1593     }
1594
1595     if(dismissDialog == smDD.compatExit)
1596     {
1597         SetSystemReady();
1598     }
1599
1600     if(dismissDialog == smDD.noStart)
1601     {
1602         SM_EXIT(-1);
1603     }
1604     if(dismissDialog == smDD.clientReasons)
1605     {
1606         reasonsDialogOK == True;
1607     }
1608 }
1609
1610
1611 \f
1612 /*************************************<->*************************************
1613  *
1614  *  UpdatePasswdField ()
1615  *
1616  *
1617  *  Description:
1618  *  -----------
1619  *  Give the visual feedback neccessary when the user is entering a password
1620  *
1621  *
1622  *  Inputs:
1623  *  ------
1624  *  numChars = number of characters entered into the field
1625  *
1626  * 
1627  *  Outputs:
1628  *  -------
1629  *  None.
1630  *
1631  *
1632  *  Comments:
1633  *  --------
1634  * 
1635  *************************************<->***********************************/
1636 void 
1637 UpdatePasswdField(
1638         int numChars )
1639 {
1640     int i, index;
1641     char passwdMessage[25];
1642     XmString tmpString;
1643
1644
1645     if(numChars > 0)
1646     {
1647         strcpy(passwdMessage, "|");
1648         for(i = 1;i < numChars;i++)
1649         {
1650             if(i==1)
1651                 strcpy(passwdMessage, "|");
1652             else
1653                 strcat(passwdMessage, " ");
1654         }
1655         strcat(passwdMessage, PASSWORD_INDICATOR);
1656     }
1657     else
1658     {
1659         strcpy(passwdMessage, "|");
1660     }
1661
1662     tmpString = XmStringCreateLocalized (passwdMessage);
1663
1664     /*
1665      * Set the index for the indLabel widget
1666      */
1667     if(smGD.coverScreen == True)
1668     {
1669         index = 1;
1670     }
1671     else
1672     {
1673         index = 0;
1674     }
1675     
1676     i = 0;
1677     XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1678     XtSetValues(smDD.indLabel[index], uiArgs, i);
1679
1680     XmStringFree(tmpString);
1681 }
1682
1683
1684 \f
1685 /*************************************<->*************************************
1686  *
1687  *  WarnNoStartup ()
1688  *
1689  *
1690  *  Description:
1691  *  -----------
1692  *  When the BMS refuses to be started, warn the user about why dt is
1693  *  crashing and then exit.
1694  *
1695  *
1696  *  Inputs:
1697  *  ------
1698  *
1699  * 
1700  *  Outputs:
1701  *  -------
1702  *  None.
1703  *
1704  *
1705  *  Comments:
1706  *  --------
1707  * 
1708  *************************************<->***********************************/
1709 int 
1710 WarnNoStartup( void )
1711 {
1712     int         i;
1713     XmString    bmsNoStartString;
1714     String      tmpString;
1715
1716 #ifdef __osf__
1717
1718     bmsNoStartString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 76,
1719         "The DT 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 your hostname exists correctly in /etc/hosts if your\n\
1725      network has already been configured.\n\
1726 4.  If your network has not yet been configured, make sure that /etc/hosts\n\
1727      has the following entry in it:\n\
1728      127.0.0.1 localhost \n\n\
1729 For additional information, see the CDE User's Guide.")));
1730 #else
1731
1732     bmsNoStartString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 36,
1733         "The desktop messaging system could not be started.\n\n\
1734 To correct the problem:\n\n\
1735 1.  Choose [OK] to return to the login screen.\n\n\
1736 2.  Select Failsafe Session from the login screen's option\n\
1737          menu and log in.\n\n\
1738 3.  Check to see that the desktop is properly installed,\n\
1739          the hostname is correct (/etc/hosts) and that the\n\
1740          network is properly configured.\n\n\
1741 For additional information, see the CDE User's Guide.")));
1742 #endif
1743
1744     /*
1745      * Now create the dialog box
1746      */
1747     i = 0;
1748     tmpString = GETMESSAGE(18, 37, "Action Required");
1749     XtSetArg(uiArgs[i], XmNmessageString, bmsNoStartString);i++;
1750     XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
1751     XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
1752     XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
1753     XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
1754     XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
1755     XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
1756     smDD.noStart = XmCreateWarningDialog(smGD.topLevelWid, "noStartDialog",
1757                                              uiArgs, i);
1758
1759     XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
1760     XtSetValues(XtParent(smDD.noStart), uiArgs, i);
1761
1762     XtAddCallback (XtParent(smDD.noStart),
1763                    XmNpopupCallback, DialogUp, NULL);
1764     XtUnmanageChild(XmMessageBoxGetChild(smDD.noStart,
1765                                          XmDIALOG_HELP_BUTTON));
1766     XtUnmanageChild(XmMessageBoxGetChild(smDD.noStart,
1767                                          XmDIALOG_CANCEL_BUTTON));
1768
1769     /*
1770      * Now add in the callback and get out of here
1771      */
1772     XtAddCallback (smDD.noStart, XmNokCallback,
1773                    SimpleOK, smDD.noStart);
1774     XmStringFree(bmsNoStartString);
1775
1776     XtManageChild(smDD.noStart);
1777
1778     return(0);
1779 } /* END OF FUNCTION WarnNoStartup */
1780
1781
1782 #ifdef __osf__
1783
1784 /*************************************<->*************************************
1785  *
1786  *  WarnNewProfile()
1787  *
1788  *
1789  *  Description:
1790  *  -----------
1791  *  Warn the user that a new .dtprofile has just been added to their $HOME
1792  *  directory, indicating a need to edit it and their .login/.profile files.
1793  *
1794  *
1795  *  Inputs:
1796  *  ------
1797  *
1798  * 
1799  *  Outputs:
1800  *  -------
1801  *  None.
1802  *
1803  *
1804  *  Comments:
1805  *  --------
1806  * 
1807  *************************************<->***********************************/
1808 int 
1809 WarnNewProfile( void )
1810 {
1811     int       i;
1812     XmString  newProfileString;
1813     String    tmpString;
1814
1815     newProfileString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 99,
1816    "The new file '.dtprofile' has been added to your home directory.\n\
1817 \n\
1818    Follow the instructions in this file to ensure that when you log in\n\
1819    again your '.login' or '.profile' file will be activated and \n\
1820    that it will interact correctly with CDE. \n\
1821 \n\
1822    For additional information, see the CDE Advanced User's and System\n\
1823    Administrator's Guide.")));
1824
1825
1826     /*
1827      * Now create the dialog box
1828      */
1829     i = 0;
1830     tmpString = GETMESSAGE(18, 37, "Action Required");
1831     XtSetArg(uiArgs[i], XmNmessageString, newProfileString);i++;
1832     XtSetArg(uiArgs[i], XmNallowShellResize, True);  i++;
1833     XtSetArg(uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
1834     XtSetArg(uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
1835     XtSetArg(uiArgs[i], XmNtitle, tmpString); i++;
1836     XtSetArg(uiArgs[i], XmNokLabelString, smDD.okString); i++;
1837     XtSetArg(uiArgs[i], XmNautoUnmanage, False); i++;
1838     smDD.newProfile = XmCreateWarningDialog(smGD.topLevelWid, 
1839                                             "newProfileDialog",
1840                                             uiArgs, i);
1841
1842     XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
1843     XtSetValues(XtParent(smDD.newProfile), uiArgs, i);
1844
1845     XtAddCallback (XtParent(smDD.newProfile),
1846                    XmNpopupCallback, DialogUp, NULL);
1847     XtUnmanageChild(XmMessageBoxGetChild(smDD.newProfile,
1848                                          XmDIALOG_HELP_BUTTON));
1849     XtUnmanageChild(XmMessageBoxGetChild(smDD.newProfile,
1850                                          XmDIALOG_CANCEL_BUTTON));
1851
1852     /*
1853      * Now add in the callback and get out of here
1854      */
1855     XtAddCallback (smDD.newProfile, XmNokCallback,
1856                    SimpleOK, smDD.newProfile);
1857     XmStringFree(newProfileString);
1858
1859     XtManageChild(smDD.newProfile);
1860
1861     return(0);
1862 } /* END OF FUNCTION WarnNewProfile */
1863
1864
1865 #endif
1866
1867
1868 /*************************************<->*************************************
1869  *
1870  *  ConfirmSessionCreation () -
1871  *
1872  *  Description:
1873  *  -----------
1874  *
1875  *  Inputs:
1876  *  ------
1877  * 
1878  *  Outputs:
1879  *  -------
1880  *
1881  *  Returns True if the user says to continue the session; False otherwise
1882  *     or if malloc fails;
1883  *
1884  *  Comments:
1885  *  --------
1886  * 
1887  *************************************<->***********************************/
1888 Boolean
1889 ConfirmSessionCreation (
1890         short           session_type,
1891         unsigned int    _argc,
1892         char            **_argv)
1893 {
1894         int             i, j;
1895         XmString        title_string;
1896         XmString        ok_string;
1897         XmString        cancel_string;
1898         XmString        help_string;
1899         XmString        msg_string;
1900         Widget          tmp_widget;
1901         Arg             args[20];
1902         char            *pch1;
1903         char            *pch2;
1904         char            *pch3;
1905         Dimension       width, height;
1906         Position        x, y;
1907         XEvent          next;
1908         int             argc = _argc;
1909         char            **argv = NULL;
1910
1911         /*
1912          * Create temporary argv because the X toolkit may remove
1913          * pieces of the command line options.
1914          */
1915         if (_argc > 0) {
1916                 argv = (char **) XtMalloc (_argc * sizeof (char *));
1917                 for (i = 0; i < _argc; i++)
1918                         argv[i] = _argv[i];
1919         }
1920
1921         if (session_type == HOME_SESSION)
1922                 pch1 = strdup ((char *) GETMESSAGE(18, 50, "Home"));
1923         else
1924                 pch1 = strdup ((char *) GETMESSAGE(18, 51, "Current"));
1925         if (!pch1) {
1926                 PrintError(DtError, smNLS.cantMallocErrorString);
1927                 SM_EXIT(1);
1928         }
1929
1930         pch2 = strdup ((char *) GETMESSAGE(18, 52, 
1931                 "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."));
1932         if (!pch2) {
1933                 PrintError(DtError, smNLS.cantMallocErrorString);
1934                 SM_EXIT(1);
1935         }
1936
1937         pch3 = XtMalloc (strlen (pch1) +
1938                              strlen (XDisplayName (getenv("DISPLAY"))) +
1939                              strlen (pch2) +
1940                              4);
1941         if (!pch3) {
1942                 PrintError(DtError, smNLS.cantMallocErrorString);
1943                 SM_EXIT(1);
1944         }
1945         (void) sprintf (pch3, pch2, pch1, XDisplayName (getenv("DISPLAY")));
1946
1947         /*
1948          * The X toolkit has not yet been initialized, so do it now.
1949          */
1950         j = 0;
1951         XtToolkitInitialize ();
1952         smGD.appCon = XtCreateApplicationContext();
1953         smGD.display = XtOpenDisplay(smGD.appCon, NULL, argv[0], 
1954                         SM_RESOURCE_CLASS, NULL, 0, &argc, argv);
1955
1956         XtSetArg(args[j], XmNbackground,
1957                 XBlackPixel(smGD.display, XDefaultScreen(smGD.display))); j++;
1958         XtSetArg(args[j], XmNmappedWhenManaged, False); j++;
1959         XtSetArg (args[j], XmNwidth, 1); j++;
1960         XtSetArg (args[j], XmNheight, 1); j++;
1961         tmp_widget = XtAppCreateShell (
1962                         "foo", "foo",
1963                         applicationShellWidgetClass,
1964                         smGD.display, args, j);
1965         XtRealizeWidget(tmp_widget);
1966
1967         /*
1968          * Create the compound strings for the confirmation dialog
1969          */
1970         msg_string = XmStringCreateLocalized (pch3);
1971         title_string = XmStringCreateLocalized(pch3);
1972
1973         ok_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 39, "OK")));
1974         cancel_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 40, "Cancel")));
1975         help_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 41, "Help")));
1976
1977         free (pch1); free (pch2); XtFree (pch3);
1978
1979         /*
1980          * Create the dialog box
1981          */
1982         i = 0;
1983         XtSetArg (uiArgs[i], XmNmessageString, msg_string); i++;
1984         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
1985         XtSetArg (uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
1986         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
1987         XtSetArg (uiArgs[i], XmNmappedWhenManaged, True); i++;
1988         XtSetArg (uiArgs[i], XmNtitle, title_string); i++;
1989         XtSetArg (uiArgs[i], XmNokLabelString, ok_string); i++;
1990         XtSetArg (uiArgs[i], XmNcancelLabelString, cancel_string); i++;
1991         XtSetArg (uiArgs[i], XmNhelpLabelString,  help_string); i++;
1992         XtSetArg (uiArgs[i], XmNautoUnmanage, False); i++;
1993
1994         smDD.confirmSession = XmCreateWarningDialog(
1995                         tmp_widget, "confirmDialog", uiArgs, i);
1996
1997         XtAddCallback (smDD.confirmSession, XmNokCallback, 
1998                         ConfirmOKCB, NULL);
1999
2000         /*
2001          * Some help state is not yet initialized and the help
2002          * callback assumes it is so some initializations must
2003          * be done now.
2004          */
2005         smDD.smHelpDialog = NULL;
2006         smDD.okString = ok_string;
2007         smGD.topLevelWid = tmp_widget;
2008
2009         XtAddCallback (smDD.confirmSession, XmNhelpCallback,
2010                        TopicHelpRequested, HELP_CONFIRMATION_SESSION_STR);
2011
2012         XtAddCallback (smDD.confirmSession, XmNcancelCallback,
2013                         ConfirmCancelCB, NULL);
2014         
2015         XtManageChild(smDD.confirmSession);
2016
2017         /*
2018          * Center the dialog on the display
2019          */
2020         i = 0;
2021         XtSetArg(uiArgs[i], XmNwidth, &width); i++;
2022         XtSetArg(uiArgs[i], XmNheight, &height); i++;
2023         XtGetValues(smDD.confirmSession, uiArgs, i);
2024
2025         x = (DisplayWidth(smGD.display,  XDefaultScreen(smGD.display)) / 2) 
2026                         - (width / 2);
2027         y = (DisplayHeight(smGD.display, XDefaultScreen(smGD.display)) / 2) 
2028                         - (height / 2);
2029
2030         i = 0;
2031         XtSetArg(uiArgs[i], XmNx, x); i++;
2032         XtSetArg(uiArgs[i], XmNy, y); i++;
2033         XtSetValues(smDD.confirmSession, uiArgs, i);
2034
2035         XmStringFree (msg_string);
2036         XmStringFree (title_string);
2037         XmStringFree (cancel_string);
2038         XmStringFree (help_string);
2039
2040         /*
2041          * Spin until the OK or Cancel CB is invoked
2042          */
2043         confirmState = ConfirmationNone;
2044         while(1) {
2045                 XtAppNextEvent(smGD.appCon, &next);
2046                 if (next.type != 0)
2047                         XtDispatchEvent(&next);
2048                 if (confirmState == ConfirmationOK) {
2049                         XtDestroyWidget (tmp_widget);
2050                         XmStringFree (ok_string);
2051                         return (True);
2052                 }
2053                 else if (confirmState == ConfirmationCancel) {
2054                         XtDestroyWidget (tmp_widget);
2055                         XmStringFree (ok_string);
2056                         return (False);
2057                 }
2058         }
2059 }
2060
2061
2062 /*************************************<->*************************************
2063  *
2064  *  ConfirmOKCB ()
2065  *
2066  *************************************<->***********************************/
2067 static void 
2068 ConfirmOKCB(
2069         Widget                  w,
2070         XtPointer               client_data,
2071         XtPointer               call_data )
2072 {
2073         XtUnmanageChild(smDD.confirmSession);
2074         confirmState = ConfirmationOK;
2075 }
2076
2077
2078 /*************************************<->*************************************
2079  *
2080  *  ConfirmCancelCB ()
2081  * 
2082  *************************************<->***********************************/
2083 static void 
2084 ConfirmCancelCB(
2085         Widget                  w,
2086         XtPointer               client_data,
2087         XtPointer               call_data )
2088 {
2089         XtUnmanageChild(smDD.confirmSession);
2090         confirmState = ConfirmationCancel;
2091 }
2092
2093
2094 /*************************************<->*************************************
2095  *
2096  *  PostXSMPFailureDialog () -
2097  *
2098  *  Description:
2099  *  -----------
2100  *
2101  *  Inputs:
2102  *  ------
2103  * 
2104  *  Outputs:
2105  *  -------
2106  *
2107  *  Returns True if the user says to continue the session; False otherwise
2108  *     or if malloc fails;
2109  *
2110  *  Comments:
2111  *  --------
2112  * 
2113  *************************************<->***********************************/
2114 void
2115 PostXSMPFailureDialog (
2116         XSMPFailure             failure_code,
2117         Boolean                 check_errorlog)
2118 {
2119         int             i, j;
2120         XmString        ok_string;
2121         XmString        help_string;
2122         XmString        msg_string;
2123         Arg             args[20];
2124         char            *pch1;
2125         char            *pch2 = "";
2126         char            *pch3;
2127         char            *pch4;
2128         char            *pch5;
2129         char            *error_file;
2130         Dimension       width, height;
2131         Position        x, y;
2132         XEvent          next;
2133         int             len;
2134
2135         pch1 = strdup ((char *) GETMESSAGE(40, 1, 
2136                 "A session cannot be started because of the\nfollowing error:"));
2137         if (!pch1) {
2138                 PrintError(DtError, smNLS.cantMallocErrorString);
2139                 SM_EXIT(1);
2140         }
2141
2142         switch (failure_code) {
2143                 case XSMP_FAILURE_SMS_INITIALIZE:
2144                         pch2 = strdup ((char *) GETMESSAGE (40, 2,
2145                                 "SmsInitialize failed."));
2146                         break;
2147                 case XSMP_FAILURE_ICE_LISTEN:
2148                         pch2 = strdup ((char *) GETMESSAGE (40, 3,
2149                                 "IceListenForConnections failed."));
2150                         break;
2151                 case XSMP_FAILURE_AUTHENTICATION:
2152                         pch2 = strdup ((char *) GETMESSAGE (40, 4,
2153                                 "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."));
2154                         break;
2155                 case XSMP_FAILURE_ICE_ADD_WATCH:
2156                         pch2 = strdup ((char *) GETMESSAGE (40, 5,
2157                                 "IceAddConnectionWatch failed."));
2158                         break;
2159                 case XSMP_FAILURE_ICE_COMPOSE_IDS:
2160                         pch2 = strdup ((char *) GETMESSAGE (40, 6,
2161                                 "IceComposeNetworkIds failed."));
2162                         break;
2163                 case XSMP_FAILURE_MALLOC:
2164                         pch2 = strdup ((char *) GETMESSAGE (40, 7,
2165                                 "Could not create the SESSION_MANAGER environment variable."));
2166                         break;
2167         }
2168         if (!pch2) {
2169                 PrintError(DtError, smNLS.cantMallocErrorString);
2170                 SM_EXIT(1);
2171         }
2172
2173         pch3 = strdup ((char *) GETMESSAGE(18, 70, 
2174                 "See the following for more information:"));
2175         if (!pch3) {
2176                 PrintError(DtError, smNLS.cantMallocErrorString);
2177                 SM_EXIT(1);
2178         }
2179
2180         pch4 = strdup ((char *) GETMESSAGE(18, 71, 
2181                 "CDE Advanced Users and System's Administration Guide"));
2182         if (!pch4) {
2183                 PrintError(DtError, smNLS.cantMallocErrorString);
2184                 SM_EXIT(1);
2185         }
2186
2187         error_file = XtMalloc(MAXPATHLEN+1);
2188         strcpy (error_file, "");
2189
2190         /* JET - VU#497553 */
2191         if (check_errorlog) 
2192           {
2193             char                *home;
2194
2195             if (home = getenv ("HOME"))
2196               {
2197                 len = strlen(home) +
2198                   strlen(DtPERSONAL_CONFIG_DIRECTORY) +
2199                   strlen(DtERRORLOG_FILE);
2200
2201                 if (len > MAXPATHLEN)
2202                   error_file = XtRealloc(error_file, len + 1);
2203
2204                 sprintf (error_file, "%s/%s/%s", home, 
2205                          DtPERSONAL_CONFIG_DIRECTORY,
2206                          DtERRORLOG_FILE);
2207               }
2208           }
2209
2210         pch5 = XtMalloc (strlen (pch1) + strlen (pch2) + strlen (pch3) + strlen (pch4) + 
2211                                 strlen (error_file) + 15);
2212         if (!pch5) {
2213                 PrintError(DtError, smNLS.cantMallocErrorString);
2214                 SM_EXIT(1);
2215         }
2216         (void) sprintf (pch5, "%s\n\n   %s\n\n%s\n\n   %s\n   %s\n",
2217                         pch1, pch2, pch3, pch4, error_file);
2218
2219         XtFree(error_file);
2220
2221         /*
2222          * No top level widget has been created so must create one now.
2223          */
2224         j = 0;
2225         XtSetArg (args[j], XmNbackground, XBlackPixel(smGD.display, 
2226                         XDefaultScreen(smGD.display))); j++;
2227         XtSetArg (args[j], XmNmappedWhenManaged, False); j++;
2228         XtSetArg (args[j], XmNwidth, 1); j++;
2229         XtSetArg (args[j], XmNheight, 1); j++;
2230
2231         smGD.topLevelWid = XtAppCreateShell (SM_RESOURCE_NAME, 
2232                         SM_RESOURCE_CLASS, applicationShellWidgetClass,
2233                         smGD.display, args, j);
2234
2235         XtRealizeWidget(smGD.topLevelWid);
2236
2237         /*
2238          * Create the compound strings for the confirmation dialog
2239          */
2240         msg_string = XmStringCreateLocalized (pch5);
2241
2242         ok_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 39, "OK")));
2243         help_string = XmStringCreateLocalized(((char *) GETMESSAGE(18, 41, "Help")));
2244
2245         free (pch1); free (pch2); free (pch3); free (pch4); XtFree (pch5);
2246
2247         /*
2248          * Create the dialog box
2249          */
2250         i = 0;
2251         XtSetArg (uiArgs[i], XmNmessageString, msg_string); i++;
2252         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
2253         XtSetArg (uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
2254         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2255         XtSetArg (uiArgs[i], XmNmappedWhenManaged, True); i++;
2256         XtSetArg (uiArgs[i], XmNokLabelString, ok_string); i++;
2257         XtSetArg (uiArgs[i], XmNhelpLabelString,  help_string); i++;
2258         XtSetArg (uiArgs[i], XmNautoUnmanage, False); i++;
2259
2260         smDD.confirmSession = XmCreateWarningDialog(
2261                         smGD.topLevelWid, "confirmDialog", uiArgs, i);
2262
2263         XtAddCallback (smDD.confirmSession, XmNokCallback, 
2264                         XSMPFailureOKCB, NULL);
2265
2266         /*
2267          * Some help state is not yet initialized and the help
2268          * callback assumes it is so some initializations must
2269          * be done now.
2270          */
2271         smDD.smHelpDialog = NULL;
2272         smDD.okString = ok_string;
2273
2274         XtAddCallback (smDD.confirmSession, XmNhelpCallback,
2275                        TopicHelpRequested, HELP_XSMP_INIT_FAILURE_STR);
2276
2277         XtUnmanageChild(XmMessageBoxGetChild(smDD.confirmSession,
2278                                              XmDIALOG_CANCEL_BUTTON));
2279
2280         XtManageChild(smDD.confirmSession);
2281
2282         /*
2283          * Center the dialog on the display
2284          */
2285         i = 0;
2286         XtSetArg(uiArgs[i], XmNwidth, &width); i++;
2287         XtSetArg(uiArgs[i], XmNheight, &height); i++;
2288         XtGetValues(smDD.confirmSession, uiArgs, i);
2289
2290         x = (DisplayWidth(smGD.display,  XDefaultScreen(smGD.display)) / 2) 
2291                         - (width / 2);
2292         y = (DisplayHeight(smGD.display, XDefaultScreen(smGD.display)) / 2) 
2293                         - (height / 2);
2294
2295         i = 0;
2296         XtSetArg(uiArgs[i], XmNx, x); i++;
2297         XtSetArg(uiArgs[i], XmNy, y); i++;
2298         XtSetValues(smDD.confirmSession, uiArgs, i);
2299
2300         XmStringFree (msg_string);
2301         XmStringFree (help_string);
2302
2303         /*
2304          * Spin until the OK CB is invoked
2305          */
2306         while(1) {
2307                 XtAppNextEvent(smGD.appCon, &next);
2308                 if (next.type != 0)
2309                         XtDispatchEvent(&next);
2310         }
2311 }
2312
2313
2314 /*************************************<->*************************************
2315  *
2316  *  XSMPFailureOKCB ()
2317  *
2318  *************************************<->***********************************/
2319 static void 
2320 XSMPFailureOKCB(
2321         Widget                  w,
2322         XtPointer               client_data,
2323         XtPointer               call_data )
2324 {
2325         XtUnmanageChild(smDD.confirmSession);
2326         SM_EXIT(1);
2327 }
2328
2329
2330
2331
2332 /*************************************<->*************************************
2333  *
2334  *  PostSaveSessionErrorDialog
2335  *
2336  *  Description:
2337  *  -----------
2338  *  Let the user know that the Save_Session message does not have the
2339  *  required data and the session will not be saved.
2340  *
2341  *  Inputs:
2342  *  ------
2343  * 
2344  *  Outputs:
2345  *  -------
2346  *
2347  *************************************<->***********************************/
2348 void 
2349 PostSaveSessionErrorDialog ( void )
2350 {
2351     int         i;
2352     XmString    messageString;
2353     String      titleString;
2354
2355     if(smDD.saveSession == NULL)
2356     {
2357         messageString = XmStringCreateLocalized (((char *) GETMESSAGE(18, 56, 
2358                 "The session cannot be saved because the required\n\
2359 'save_type' parameter was not in the message.\n\n\
2360 The session will not be saved.")));
2361
2362         titleString = GETMESSAGE(18, 55, "Save Session Failure");
2363
2364         i = 0;
2365         XtSetArg (uiArgs[i], XmNmessageString,    messageString); i++;
2366         XtSetArg (uiArgs[i], XmNallowShellResize, True); i++;
2367         XtSetArg (uiArgs[i], XmNdialogStyle,      XmDIALOG_SYSTEM_MODAL); i++;
2368         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2369         XtSetArg (uiArgs[i], XmNtitle,            titleString); i++;
2370         XtSetArg (uiArgs[i], XmNokLabelString,    smDD.okString); i++;
2371         XtSetArg (uiArgs[i], XmNhelpLabelString,  smDD.helpString); i++;
2372         XtSetArg (uiArgs[i], XmNautoUnmanage,     False); i++;
2373
2374         smDD.saveSession = XmCreateErrorDialog(smGD.topLevelWid, 
2375                         "sessionSaveDialog", uiArgs, i);
2376
2377         i = 0;
2378         XtSetArg (uiArgs[i], XmNuseAsyncGeometry, True);i++;
2379         XtSetArg (uiArgs[i], XmNmwmFunctions,     0);i++;
2380         XtSetArg (uiArgs[i], XmNmwmDecorations,
2381                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER)); i++;
2382         XtSetArg (uiArgs[i], XmNmwmInputMode,     MWM_INPUT_SYSTEM_MODAL);i++;
2383
2384         XtSetValues(XtParent(smDD.saveSession), uiArgs, i);
2385         
2386         XtAddCallback (XtParent(smDD.saveSession),
2387                        XmNpopupCallback, DialogUp, NULL);
2388
2389         XtUnmanageChild (XmMessageBoxGetChild(smDD.saveSession,
2390                                              XmDIALOG_CANCEL_BUTTON));
2391
2392         XtAddCallback (smDD.saveSession, XmNokCallback,
2393                        SimpleOK, (XtPointer) smDD.saveSession);
2394 #ifndef NO_XVH
2395         XtAddCallback (smDD.saveSession, XmNhelpCallback,
2396                        TopicHelpRequested, HELP_SESSION_SAVE_ERROR_STR);
2397 #endif
2398         XmStringFree(messageString);
2399     }
2400
2401     XtManageChild(smDD.saveSession);
2402
2403     return;
2404 }
2405
2406
2407
2408 /*************************************<->*************************************
2409  *
2410  *  PostReasonsDialog - posts a Warning dialog on behalf of a client
2411  *      that supplied a "reason" when it closed its connection
2412  *
2413  *  Inputs:
2414  *  ------
2415  * 
2416  *  Outputs:    void
2417  *  -------
2418  *
2419  *************************************<->***********************************/
2420 void
2421 PostReasonsDialog (
2422         char                    * progName,
2423         int                     numMsgs,
2424         char                    ** message,
2425         Boolean                 waitForResponse)
2426 {
2427         XmString                msgString;
2428         XmString                okString;
2429         XmString                helpString;
2430         Arg                     args[20];
2431         char                    * titleString;
2432         char                    * str1;
2433         char                    * str2;
2434         char                    * str3;
2435         int                     i;
2436         int                     len;
2437         XEvent                  next;
2438
2439         str1 = strdup ((char *) GETMESSAGE(40, 28, 
2440                 "Application '%s'\nexited for the following reason:\n\n%s"));
2441         if (!str1) {
2442                 PrintError(DtError, smNLS.cantMallocErrorString);
2443                 SM_EXIT(1);
2444         }
2445
2446         for (i = 0, len = 0; i < numMsgs; i++) 
2447                 len += strlen (message[i]);
2448
2449         str2 = XtMalloc (len + (numMsgs * 3) + 1);
2450         if (!str2) {
2451                 PrintError(DtError, smNLS.cantMallocErrorString);
2452                 SM_EXIT(1);
2453         }
2454         str2[0] = '\000';
2455         for (i = 0; i < numMsgs; i++) {
2456                 strcat (str2, message[i]);
2457                 strcat (str2, "\n");
2458         }
2459
2460         str3 = XtMalloc (strlen (str1) + strlen (str2) + strlen (progName) + 4);
2461         if (!str3) {
2462                 PrintError(DtError, smNLS.cantMallocErrorString);
2463                 SM_EXIT(1);
2464         }
2465         (void) sprintf (str3, str1, progName, str2);
2466
2467         DtMsgLogMessage (smGD.programName, DtMsgLogWarning, str3);
2468
2469         free (str1);
2470         str1 = strdup ((char *) GETMESSAGE(40, 29, 
2471                 "Application Close Reasons"));
2472         if (!str1) {
2473                 PrintError(DtError, smNLS.cantMallocErrorString);
2474                 SM_EXIT(1);
2475         }
2476
2477         msgString = XmStringCreateLocalized (str3);
2478
2479         okString = XmStringCreateLocalized(((char *) GETMESSAGE(18, 39, "OK")));
2480
2481         helpString = XmStringCreateLocalized(((char *) GETMESSAGE(18, 41, "Help")));
2482
2483         /*
2484          * Create the dialog box
2485          */
2486         i = 0;
2487         XtSetArg (uiArgs[i], XmNmessageString, msgString); i++;
2488         XtSetArg (uiArgs[i], XmNallowShellResize, False);  i++;
2489         XtSetArg (uiArgs[i], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); i++;
2490         XtSetArg (uiArgs[i], XmNmessageAlignment, XmALIGNMENT_BEGINNING); i++;
2491         XtSetArg (uiArgs[i], XmNmappedWhenManaged, True); i++;
2492         XtSetArg (uiArgs[i], XmNtitle, str1); i++;
2493         XtSetArg (uiArgs[i], XmNokLabelString, okString); i++;
2494         XtSetArg (uiArgs[i], XmNhelpLabelString, helpString); i++;
2495         XtSetArg (uiArgs[i], XmNautoUnmanage, False); i++;
2496
2497         smDD.clientReasons = XmCreateWarningDialog(smGD.topLevelWid, 
2498                 "clientReasons", uiArgs, i);
2499
2500         i = 0;
2501         XtSetArg(uiArgs[i], XmNuseAsyncGeometry, True);i++;
2502         XtSetArg(uiArgs[i], XmNmwmFunctions, 0);i++;
2503         XtSetArg(uiArgs[i], XmNmwmDecorations,
2504                  (MWM_DECOR_TITLE | MWM_DECOR_BORDER));i++;
2505         XtSetArg(uiArgs[i], XmNmwmInputMode, MWM_INPUT_SYSTEM_MODAL);i++;
2506         XtSetValues(XtParent(smDD.clientReasons), uiArgs, i);
2507         
2508         XtAddCallback (XtParent(smDD.clientReasons),
2509                        XmNpopupCallback, DialogUp, NULL);
2510
2511         XtUnmanageChild (XmMessageBoxGetChild (smDD.clientReasons,
2512                                              XmDIALOG_CANCEL_BUTTON));
2513
2514         /*
2515          * Now add in the callback and get out of here
2516          */
2517         XtAddCallback (smDD.clientReasons, XmNokCallback,
2518                        SimpleOK, (XtPointer) smDD.clientReasons);
2519 #ifndef NO_XVH
2520         XtAddCallback (smDD.clientReasons, XmNhelpCallback,
2521                        TopicHelpRequested, HELP_APP_CLOSE_REASONS_STR);
2522 #endif
2523         free (str1); 
2524         XtFree (str2); 
2525         XtFree (str3);
2526         XmStringFree (msgString);
2527         XmStringFree (okString);
2528         XmStringFree (helpString);
2529
2530         XtManageChild (smDD.clientReasons);
2531
2532         /*
2533          * Spin until the OK callback is invoked.  If a shutdown
2534          * is in progress, we don't want to return until the
2535          * user has acknowledged this message.
2536          */
2537         reasonsDialogOK = False;
2538         if (waitForResponse) {
2539                 while (1) {
2540                         XtAppNextEvent (smGD.appCon, &next);
2541                         if (next.type != 0)
2542                                 XtDispatchEvent(&next);
2543                         if (reasonsDialogOK == True)
2544                                 break;
2545                 }
2546         }
2547 }
2548
2549
2550 /*************************************<->*************************************
2551  *
2552  *  SaveTimeout
2553  *
2554  *  Description:
2555  *  -----------
2556  *  Timeout procedure that is invoked when a save timer expires.
2557  *
2558  *  Inputs:
2559  *  ------
2560  *
2561  *  Outputs: None
2562  *  -------
2563  *
2564  *************************************<->***********************************/
2565 static void
2566 SaveTimeout (
2567         XtPointer               client_data,
2568         XtIntervalId            *id)
2569 {
2570         saveTimeout = True;
2571
2572         if (smXSMP.saveState.shutdownCanceled == False) {
2573                 /* 
2574                  * Run the user's exit script if there is one
2575                  */
2576                 if (smGD.compatMode == False)
2577                         StartEtc(True);    /* run sessionexit */
2578
2579                 _DtReleaseLock(smGD.display, SM_RUNNING_LOCK);
2580                 SM_EXIT(0);
2581         }
2582 }