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