Exceptionally hacky linux fix. gnu gencat is returning != 0 even when it's
[oweals/cde.git] / cde / programs / dtpad / fileCB.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: fileCB.c /main/13 1999/11/08 08:23:14 mgreess $ */
24 /**********************************<+>*************************************
25 ***************************************************************************
26 **
27 **  File:        fileCB.c
28 **
29 **  Project:     DT dtpad, a memo maker type editor based on the Dt Editor
30 **               widget.
31 **
32 **  Description: 
33 **  -----------
34 **
35 **      This file contains the callbacks for the "File" menu items.
36 **      There's some hair here, due to the nested nature of some of
37 **      the dialogs.  The "New, "Open" and "Exit" callbacks can cause
38 **      the opening of a do-you-wish-to-save dialog, and we have to
39 **      remember how we got there.  This is done through the use
40 **      of the pendingFileFunc field of the Editor struct.
41 **
42 *******************************************************************
43 **  (c) Copyright Hewlett-Packard Company, 1991.  All rights are
44 **  reserved.  Copying or other reproduction of this program
45 **  except for archival purposes is prohibited without prior
46 **  written consent of Hewlett-Packard Company.
47 ********************************************************************
48 **
49 ********************************************************************
50 **  (c) Copyright 1993, 1994 Hewlett-Packard Company
51 **  (c) Copyright 1993, 1994 International Business Machines Corp.
52 **  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
53 **  (c) Copyright 1993, 1994 Novell, Inc.
54 ********************************************************************
55 **
56 **
57 **************************************************************************
58 **********************************<+>*************************************/
59 #include <Dt/DtpadM.h>
60 #include <Dt/Action.h>
61
62 #include "dtpad.h"
63
64 extern int numActivePads;  /* declared in main.c */
65
66
67 /************************************************************************
68  *                      Forward Declarations
69  ************************************************************************/
70 static void FileDoXpPrint(
71         Editor* pPad,
72         Boolean silent);
73 static void FileOpenOkCB(
74         Widget w,
75         caddr_t client_data,
76         caddr_t call_data );
77 static void IncludeFile(
78         Widget w,
79         caddr_t client_data,
80         caddr_t call_data );
81 static Boolean SaveUnsaved(
82         Editor* pPad,
83         void (*callingFunc)() );
84 static Boolean FileExitWP(
85         XtPointer client_data);
86
87
88 /************************************************************************
89  * FileCascadingCB -  callback assigned to "File" menu to determine
90  *      whether Save button in menu is labeled "Save" or "Save (needed)".
91  ************************************************************************/
92 /* ARGSUSED */
93 void
94 FileCascadingCB(
95         Widget w,
96         caddr_t client_data,
97         caddr_t call_data )
98 {
99     Editor *pPad = (Editor *)client_data;
100     Arg al[1];
101
102     if (DtEditorCheckForUnsavedChanges(pPad->editor)) {
103         XtSetArg(al[0], XmNlabelString, pPad->fileStuff.saveNeededBtnLabel);
104     } else {
105         XtSetArg(al[0], XmNlabelString, pPad->fileStuff.saveBtnLabel);
106     }
107     XtSetValues(pPad->fileStuff.fileWidgets.saveBtn, al, 1);
108
109 }
110
111
112 /************************************************************************
113  * FileNewCB -  callback assigned to "File" menu "New" button which
114  *      saves the current text if it hasn't been saved and then calls
115  *      LoadFile().  Since pPad->fileStuff.fileName is NULL, LoadFile
116  *      sets the contents to "" rather than loading a file.
117  ************************************************************************/
118 /* ARGSUSED */
119 void
120 FileNewCB(
121         Widget w,
122         caddr_t client_data,
123         caddr_t call_data )
124 {
125     Editor *pPad = (Editor *)client_data;
126
127     if (SaveUnsaved(pPad, FileNewCB)) {
128         return;
129     }
130
131     if (pPad->ttEditReq.contract && pPad->ttEditReq.op != TTME_INSTANTIATE) {
132         TTmediaReply(pPad);     /* reply/close ToolTalk media request */
133     }
134
135     if (pPad->fileStuff.fileName != (char *)NULL) {
136         XtFree(pPad->fileStuff.fileName);
137         pPad->fileStuff.fileName = (char *)NULL;
138     }
139     _DtTurnOnHourGlass(pPad->app_shell);
140     LoadFile(pPad, NULL);
141     ChangeMainWindowTitle(pPad);
142     _DtTurnOffHourGlass(pPad->app_shell);
143 }
144
145
146 /************************************************************************
147  * FileOpenCB - callback assigned to "File" menu "Open..." button
148  ************************************************************************/
149 /* ARGSUSED */
150 void
151 FileOpenCB(
152         Widget w,
153         caddr_t client_data,
154         caddr_t call_data )
155 {
156     Editor *pPad = (Editor *)client_data;
157     FileStuff *pStuff = &pPad->fileStuff;
158
159     if (SaveUnsaved(pPad, FileOpenCB)) {
160         return;
161     }
162
163     /* ToolTalk media requests are replied to (and closed) in FileOpenOkCB */
164     
165     /* -----> set FSB title passed GetFileName */
166     if(pStuff->openTitle == (XmString)NULL) {
167         char buf[256];
168
169         strcpy(buf, DialogTitle(pPad));
170         strcat(buf, (char *)GETMESSAGE(4, 1, "Open a File"));
171         pStuff->openTitle = XmStringCreateLocalized(buf);
172     }
173
174     /* -----> obtain the name of the file to open (via a Xm file selection box)
175      *        and load its contents (via FileOpenOkCB) to the Editor widget */
176     pStuff->pendingFileFunc = FileOpenOkCB;     /* FSB XmNokCallback */
177     pStuff->pendingFileHelpFunc = HelpOpenDialogCB;  /* FSB XmNhelpCallback */
178     GetFileName(pPad, pStuff->openTitle, OPEN);
179 }
180
181
182 /************************************************************************
183  * FileIncludeCB - callback assigned to "File" menu "Include..." button
184  ************************************************************************/
185 /* ARGSUSED */
186 void
187 FileIncludeCB(
188         Widget w,
189         caddr_t client_data,
190         caddr_t call_data )
191 {
192     Editor *pPad = (Editor *)client_data;
193     FileStuff *pStuff = &pPad->fileStuff;
194
195     if (pStuff->includeTitle == (XmString)NULL) {
196         char buf[256];
197
198         strcpy(buf, DialogTitle(pPad));
199         strcat(buf, (char *)GETMESSAGE(4, 3, "Include a File"));
200         pStuff->includeTitle = XmStringCreateLocalized(buf);
201     }
202     pPad->fileStuff.pendingFileFunc = IncludeFile;
203     pPad->fileStuff.pendingFileHelpFunc = HelpIncludeDialogCB;
204     GetFileName(pPad, pStuff->includeTitle, INCLUDE);
205 }
206
207
208 /************************************************************************
209  * FileSaveCB - callback assigned to "File" menu "Save" button and to the
210  *      AskIfSave dialog's "OK" button (which is displayed when there are
211  *      unsaved changes when switching to a new file/buffer).
212  *
213  *
214  ************************************************************************/
215 void
216 FileSaveCB(
217         Widget w,
218         caddr_t client_data,
219         caddr_t call_data )
220 {
221     Editor *pPad = (Editor *)client_data;
222     void (*pFunc)();
223     DtEditorErrorCode errorCode;
224     Boolean addNewlines = pPad->xrdb.wordWrap == True &&
225                           pPad->fileStuff.saveWithNewlines == True;
226     Tt_message m;
227
228     if (pPad->fileStuff.fileName && *pPad->fileStuff.fileName) { /* filename? */
229         /* -----> if called directly from [Save] menu and word wrap is on,
230          *         display Save dialog so that saveWithNewlines can be set */
231         if (pPad->xrdb.wordWrap &&
232           !pPad->fileStuff.pendingFileFunc && !pPad->ttSaveReq.contract) {
233             AskIfSave(pPad);  
234             pPad->fileStuff.pendingFileFunc = FileSaveCB;
235             return;
236         }
237         _DtTurnOnHourGlass(pPad->app_shell);
238         errorCode = DtEditorSaveContentsToFile(
239                         pPad->editor,
240                         pPad->fileStuff.fileName,
241                         True,                   /* overwrite existing file */
242                         addNewlines,            /* replace soft line feeds? */
243                         True);                  /* mark contents as saved */
244         _DtTurnOffHourGlass(pPad->app_shell);
245         if (errorCode != DtEDITOR_NO_ERRORS) {
246             PostSaveError(pPad, pPad->fileStuff.fileName, errorCode);
247             pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
248             TTfailPendingSave(pPad);
249             return;
250         }
251         if (pPad->ttEditReq.contract) {
252             /* ZZZ -----> Create and send Saved notice */
253             m = ttdt_file_notice(
254                         pPad->ttEditReq.contract,       /* context */
255                         TTDT_SAVED,                     /* op */
256                         TT_SESSION,                     /* Tt_scope */
257                         pPad->fileStuff.fileName,       /* msg file name */
258                         True);                          /* send & destroy */
259         }
260         if (pPad->ttSaveReq.contract) {
261             if (! pPad->ttEditReq.contract) {
262                 TTfailPendingSave(pPad);
263             } else {
264                 tt_message_reply(pPad->ttSaveReq.contract);
265                 tttk_message_destroy(pPad->ttSaveReq.contract);
266             }
267         }
268     } else {    /* no fileName associated with current text */
269         if (pPad->ttEditReq.contract) {
270             if (pPad->ttEditReq.contents) {
271                 if (TTmediaDepositContents(pPad) != 0) {
272                     if (pPad->fileStuff.pendingFileFunc == FileExitCB) {
273                         TTfailPendingQuit(pPad);
274                     }
275                     TTfailPendingSave(pPad);
276                     pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
277                     return;     /* deposit failed */
278                 }
279             } else {    /* TT request without fileName and contents */
280                 FileSaveAsCB(w, client_data, call_data);
281                 return;
282             }
283             if (pPad->ttSaveReq.contract) {
284                 tt_message_reply(pPad->ttSaveReq.contract);
285                 tttk_message_destroy(pPad->ttSaveReq.contract);
286             }
287         } else {  /* non-TT request and no file name */
288             if (pPad->ttSaveReq.contract) {
289                 TTfailPendingSave(pPad);
290             } else {
291                 FileSaveAsCB(w, client_data, call_data);
292             }
293             return;
294         }
295     }
296
297     if ((pFunc = pPad->fileStuff.pendingFileFunc) != (void (*)())NULL)  {
298         pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
299         if (pFunc != FileSaveCB) {
300             (*pFunc)(w, client_data, call_data);
301         }
302     }
303
304 }
305
306
307 /************************************************************************
308  * FileSaveAsCB - callback assigned to "File" menu "SaveAs..." button
309  ************************************************************************/
310 void
311 FileSaveAsCB(
312         Widget w,
313         caddr_t client_data,
314         caddr_t call_data )
315 {
316     Editor *pPad = (Editor *)client_data;
317     SaveAs *pSaveAs = &pPad->fileStuff.fileWidgets.saveAs;
318     Widget textField;
319
320     if (!pSaveAs->saveAs_form) {
321         CreateSaveAsDialog(pPad);
322         XtManageChild (pSaveAs->saveAs_form);
323 /*
324  * XXX - Should be dealing with the FSB instead of the text field directly.
325  *       Also, should be setting an XmString, rather than a char *
326  */
327         textField = XmFileSelectionBoxGetChild(
328                         pPad->fileStuff.fileWidgets.saveAs.saveAs_form,
329                         XmDIALOG_TEXT);
330         XmTextFieldSetString(textField, "");
331     } else {
332         XtManageChild (pSaveAs->saveAs_form);
333         textField = XmFileSelectionBoxGetChild(
334                         pPad->fileStuff.fileWidgets.saveAs.saveAs_form,
335                         XmDIALOG_TEXT);
336     }
337
338     SetSaveAsDirAndFile(pPad); /* seed the SaveAs FSB dir and file fields */
339
340     /* Force the focus to the text field */
341     XmProcessTraversal(textField, XmTRAVERSE_CURRENT);
342     XSync(pPad->display, 0);
343
344     _DtTurnOffHourGlass(pPad->app_shell);
345 }
346
347
348 extern Boolean ActionDBInitialized; /* declared in main.c */
349
350
351 /************************************************************************
352  * PrintActionCB - callback assigned to "File" menu "Print" button
353  ************************************************************************/
354 /* ARGSUSED */
355 void
356 PrintActionCB(
357         DtActionInvocationID actionID,
358         XtPointer client_data,
359         DtActionArg *actionArgp,
360         int argCount,
361         DtActionStatus actionStatus)
362 {
363     Editor *pPad = (Editor *) client_data;
364     switch ((DtActionStatus) actionStatus) {
365         case DtACTION_INVOKED:
366         case DtACTION_STATUS_UPDATE:
367             /* break; */
368         case DtACTION_DONE:
369         case DtACTION_FAILED:
370         case DtACTION_CANCELED:
371         default:
372 /*          XtSetSensitive(pPad->app_shell, True); */
373             _DtTurnOffHourGlass(pPad->app_shell);
374             break;
375     }
376 }
377
378
379 /************************************************************************
380  * FilePrintCB - callback assigned to "File" menu "Print" button
381  ************************************************************************/
382 /* ARGSUSED */
383 void
384 FilePrintCB(
385         Widget w,
386         caddr_t client_data,
387         caddr_t call_data)
388 {
389     Editor *pPad = (Editor *) client_data;
390     DtActionArg *actionArgp = (DtActionArg *) XtCalloc(2,sizeof(DtActionArg));
391     DtActionInvocationID actionID;
392     char *pr_name = (char *) NULL, *user_name;
393     DtEditorErrorCode errorCode;
394
395     Boolean addNewlines = pPad->xrdb.wordWrap == True &&
396                           pPad->fileStuff.saveWithNewlines == True;
397
398     _DtTurnOnHourGlass(pPad->app_shell);
399     /* -----> Disallow keyboard, button, motion, window enter/leave & focus
400      *        events till print (dialog) action is done
401      * XtSetSensitive(pPad->app_shell, False);
402      */
403
404     /* -----> Get a place to temporarily write the text */
405     if ((pr_name = GetTempFile()) == (char *)NULL) {
406         _DtTurnOffHourGlass(pPad->app_shell);
407         Warning(pPad, ((char *)
408                 GETMESSAGE(4, 5, "Unable to create a temporary file.")),                XmDIALOG_ERROR);
409         return;
410     }
411
412     /* -----> Write the contents to the temp file */
413     errorCode = DtEditorSaveContentsToFile(
414                         pPad->editor,
415                         pr_name,
416                         True,           /* overwrite existing file */
417                         addNewlines,    /* replace soft line feeds? */
418                         False);         /* don't mark contents as saved */
419     if (errorCode != SUCCESS) {         /* this should never occur */
420         _DtTurnOffHourGlass(pPad->app_shell);
421         PostSaveError(pPad, pr_name, errorCode);
422         return;
423     }
424
425     /* -----> Load the action database */
426     if (! ActionDBInitialized) {
427         StartDbUpdate( (XtPointer) NULL );
428         /* register interest in Action DB changes (for printing) */
429         DtDbReloadNotify( StartDbUpdate, (XtPointer) NULL );
430     }
431
432     /* -----> Determine the name the user will see in the Print dialog */
433     if (pPad->ttEditReq.contract &&
434                 (pPad->ttEditReq.docName && *pPad->ttEditReq.docName)) {
435         user_name = strdup(pPad->ttEditReq.docName);
436     } else if (pPad->fileStuff.fileName && *pPad->fileStuff.fileName) {
437         user_name = strdup(pPad->fileStuff.fileName);
438     } else {
439         user_name = strdup(UNNAMED_TITLE_P);
440     }
441
442     /* ----> Setup the action arguments - one for the filename as known by
443      *       the user (Arg_1) and one for the temporary print file (Arg_2).
444      *       PRINT_DTPAD_TEMPFILE does something like:
445      *          /usr/dt/bin/dtlp -u %(String)Arg_2% -e %(File)Arg_1%
446      *       dtlp displays a dialog to gather lp paramters and then prints
447      *       the file.  The -e says to remove the temporary file after it
448      *       it has been passed to lp. */
449     actionArgp[0].argClass = DtACTION_FILE;
450     actionArgp[0].u.file.name = pr_name;
451     actionArgp[1].argClass = DtACTION_FILE;
452     actionArgp[1].u.file.name = user_name;
453
454     /* XXX - Try this after everything's working - don't directly output to
455      *       a temp file but to a buffer and pass the buffer to the action
456      *       and let the action automatically create/remove the temp file.
457      *       This'll require a new action w/o -e.
458      * actionArgp[0].argClass = DtACTION_BUFFER;
459      * actionArgp[0].u.buffer.bp = (void *) buffer;
460      * actionArgp[0].u.buffer.size = strlen(buffer;
461      * actionArgp[0].u.buffer.type = TEXT;
462      * actionArgp[0].u.buffer.writable = False;
463      */
464
465     /* XXX - Also, may want to set XtNsensitive to False on pPad->app_shell
466      *       and turn it back on in PrintActionCB() when it receives a
467      *       DtACTION_DONE status */ 
468     /* ----> Invoke the print action */
469     actionID = DtActionInvoke(pPad->app_shell,
470                 "PRINT_DTPAD_TEMPFILE",         /* action */
471                 actionArgp, 2,                  /* action arguments & count */
472                 (char *) NULL,                  /* terminal options */
473                 (char *) NULL,                  /* execution host */
474                 (char *) NULL,                  /* context dir */
475                 False,                          /* no "use indicator" */
476                 PrintActionCB,                  /* action callback */
477                 (XtPointer) pPad);              /* callback client data */
478
479     XtFree(pr_name);
480     XtFree(user_name);
481
482    /*  _DtTurnOffHourGlass(pPad->app_shell);  this is done in PrintActionCB */
483 }
484
485
486
487
488 /************************************************************************
489  * FileDoXpPrint - procedure doing the work of the XpPrint callbacks
490  ************************************************************************/
491 /* ARGSUSED */
492 static void FileDoXpPrint(Editor *pPad, Boolean silent)
493 {
494     PrintJob *pJob;
495
496     DtActionArg *actionArgp = (DtActionArg *) XtCalloc(2,sizeof(DtActionArg));
497     DtActionInvocationID actionID;
498     DtEditorErrorCode errorCode;
499
500     char *pr_name = (char *) NULL, *user_name;
501
502     Boolean addNewlines = pPad->xrdb.wordWrap == True &&
503                           pPad->fileStuff.saveWithNewlines == True;
504
505     _DtTurnOnHourGlass(pPad->app_shell);
506     /* -----> Disallow keyboard, button, motion, window enter/leave & focus
507      *        events till print (dialog) action is done
508      * XtSetSensitive(pPad->app_shell, False);
509      */
510
511     /* -----> Get a place to temporarily write the text */
512     if ((pr_name = GetTempFile()) == (char *)NULL) {
513         _DtTurnOffHourGlass(pPad->app_shell);
514         Warning(pPad, ((char *)
515                 GETMESSAGE(4, 5, "Unable to create a temporary file.")),                XmDIALOG_ERROR);
516         return;
517     }
518
519     /* -----> Write the contents to the temp file */
520     errorCode = DtEditorSaveContentsToFile(
521                         pPad->editor,
522                         pr_name,
523                         True,           /* overwrite existing file */
524                         addNewlines,    /* replace soft line feeds? */
525                         False);         /* don't mark contents as saved */
526     if (errorCode != SUCCESS) {         /* this should never occur */
527         _DtTurnOffHourGlass(pPad->app_shell);
528         PostSaveError(pPad, pr_name, errorCode);
529         return;
530     }
531
532     /* -----> Determine the name the user will see in the Print dialog */
533     if (pPad->ttEditReq.contract &&
534                 (pPad->ttEditReq.docName && *pPad->ttEditReq.docName)) {
535         user_name = strdup(pPad->ttEditReq.docName);
536     } else if (pPad->fileStuff.fileName && *pPad->fileStuff.fileName) {
537         user_name = strdup(pPad->fileStuff.fileName);
538     } else {
539         user_name = strdup(UNNAMED_TITLE_P);
540     }
541
542     /* ----> XPPRINT:  Create and execute a print job. */
543     pJob = PrintJobCreate(user_name, pr_name, silent, pPad);
544     PrintJobExecute(pJob);
545
546     XtFree(pr_name);
547     XtFree(user_name);
548
549    _DtTurnOffHourGlass(pPad->app_shell);
550 }
551
552 /************************************************************************
553  * FileXpPrintCB - callback assigned to "File" menu "Print..." button
554  ************************************************************************/
555 /* ARGSUSED */
556 void
557 FileXpPrintCB(
558         Widget w,
559         caddr_t client_data,
560         caddr_t call_data)
561 {
562     Editor *pPad = (Editor *) client_data;
563     FileDoXpPrint(pPad, FALSE);
564 }
565
566
567 /************************************************************************
568  * FileExitCB - callback assigned to "File" menu "Close" button
569  ************************************************************************/
570 /* ARGSUSED */
571 void
572 FileExitCB(
573         Widget w,
574         caddr_t client_data,
575         caddr_t call_data)
576 {
577     Editor *pPad = (Editor *)client_data;
578
579     if (SaveUnsaved(pPad, FileExitCB)) {
580         /*
581          * If SaveUnsaved() returns True, don't close the window at this
582          * time since either:
583          *
584          * 1) a dialog has been posted which needs to be responded to
585          *    (and pendingFileFunc has been set to FileExitCB so that
586          *    this function will be resumed after the response) or
587          * 2) an error has occurred (in which case we abort the exit operation,
588          *    failing the TTDT_QUIT request if it initiated the exit).
589          */
590         if (pPad->fileStuff.pendingFileFunc != FileExitCB) { /* error occurred */
591             TTfailPendingQuit(pPad);
592         }
593         return;
594     }
595
596     if (pPad->numPendingTasks > 0)
597     {
598         char    *msg;
599
600         msg =
601         GETMESSAGE(14, 20, "Close pending:  waiting for task to terminate ...");
602         SetStatusMessage(pPad, msg);
603
604         if (pPad->fileExitWorkprocID == 0)
605           pPad->fileExitWorkprocID = XtAppAddWorkProc(
606                                         pPad->app_context,
607                                         FileExitWP, pPad);
608     }
609     else
610         FileExitWP((XtPointer) pPad);
611 }
612
613
614 /************************************************************************
615  * FileExitWP - workproc called from FileExitCB
616  ************************************************************************/
617 /* ARGSUSED */
618 static Boolean
619 FileExitWP(XtPointer client_data)
620 {
621     Editor *pPad = (Editor *)client_data;
622     Tt_status status;
623
624     if (pPad->numPendingTasks > 0)
625       return FALSE;
626
627     if (pPad->fileExitWorkprocID != 0)
628     {
629         XtRemoveWorkProc(pPad->fileExitWorkprocID);
630         pPad->fileExitWorkprocID = 0;
631     }
632
633     if (pPad->ttQuitReq.contract) {  /* reply to ToolTalk Quit request */
634         status = tt_message_reply(pPad->ttQuitReq.contract);
635         status = tttk_message_destroy(pPad->ttQuitReq.contract);
636     }
637
638     if (pPad->ttEditReq.contract) {
639         TTmediaReply(pPad);     /* reply/close ToolTalk Edit/Display request */
640     }
641
642     if (pPad->xrdb.standAlone) {
643         exit(pPad->confirmStuff.confirmationStatus);
644     }
645
646     pPad->inUse = False;
647     numActivePads--;
648     UnmanageAllDialogs(pPad);
649     XtSetMappedWhenManaged(pPad->app_shell, False);
650         XmImUnregister(pPad->editor);
651     XtPopdown(pPad->app_shell);
652     XWithdrawWindow(pPad->display, XtWindow(pPad->app_shell),
653                         XDefaultScreen(pPad->display));
654     XFlush(pPad->display);
655
656     /* -----> Send "DONE" notice if dealing with a requestor dtpad */
657 /*     if (!pPad->ttEditReq.contract && pPad->xrdb.blocking) { */
658 /*      char numBuf[10]; */
659 /*      sprintf(numBuf, "%d", pPad->confirmStuff.confirmationStatus); */
660 /*      _DtSendSuccessNotification( */
661 /*                      "*", */
662 /*                      (DtString) NULL, */
663 /*                      (DtString) DTPAD_DONE, */
664 /*                      pPad->blockChannel, numBuf, NULL); */
665 /*     } */
666
667     if (numActivePads == 0 && pPad->xrdb.exitOnLastClose) {
668         exit(pPad->confirmStuff.confirmationStatus);
669     }
670
671     /*
672      * If we're going to remain around, clean up Pad for its next use.
673      * This speeds up opening a cached Pad at the expense of cycles at
674      * close time.  Perception is reality.
675      */
676
677     /* -----> clear ToolTalk message info */
678     TTresetQuitArgs(pPad);
679     pPad->ttEditReq.contract = 0;
680     if (pPad->ttEditReq.msg_id != (char *)NULL) {
681         XtFree(pPad->ttEditReq.msg_id);
682         pPad->ttEditReq.msg_id = (char *)NULL;
683     }
684     if (pPad->ttEditReq.vtype != (char *)NULL) {
685         XtFree(pPad->ttEditReq.vtype);
686         pPad->ttEditReq.vtype = (char *)NULL;
687     }
688     if (pPad->ttEditReq.fileName != (char *)NULL) {
689         XtFree(pPad->ttEditReq.fileName);
690         pPad->ttEditReq.fileName = (char *)NULL;
691     }
692     if (pPad->ttEditReq.docName != (char *)NULL) {
693         XtFree(pPad->ttEditReq.docName);
694         pPad->ttEditReq.docName = (char *)NULL;
695     }
696     if (pPad->ttEditReq.savePattern) {
697         tt_pattern_destroy(pPad->ttEditReq.savePattern);
698         pPad->ttEditReq.savePattern = NULL;
699     }
700
701     if (pPad->dialogTitle != (char *)NULL) {
702         XtFree(pPad->dialogTitle);
703         pPad->dialogTitle = NULL;
704     }
705
706     pPad->saveRestore = False;
707
708     pPad->fileStuff.pendingFileFunc = (void (*)())NULL;
709     pPad->fileStuff.pendingFileHelpFunc = (void (*)())NULL;
710     pPad->fileStuff.fileExists = False;
711     pPad->fileStuff.saveWithNewlines = True;
712     pPad->fileStuff.readOnly = False;
713     if (pPad->fileStuff.fileName != (char *) NULL) {
714         XtFree(pPad->fileStuff.fileName);
715         pPad->fileStuff.fileName = (char *) NULL;
716     }
717     if (pPad->fileStuff.netfile != (char *) NULL) {
718         tt_free(pPad->fileStuff.netfile);
719          pPad->fileStuff.netfile = (char *) NULL;
720     }
721
722     /* -----> Clear contents, undo, find/change, format and message area */
723     DtEditorReset(pPad->editor);
724
725     /* -----> Reset resources to server's initial resource state */
726     RestoreInitialServerResources(pPad);
727
728     /* -----> Set iconic state to false */
729     pPad->iconic = False;
730
731     /* -----> Set app shell geo (pixels), resize hints, position & size hints */
732     SetWindowSize(pPad);
733
734     /* -----> Clear director "seed" in SaveAs FSB */
735     if (pPad->fileStuff.fileWidgets.saveAs.saveAs_form != (Widget)NULL) {
736         Widget textField = XmFileSelectionBoxGetChild(
737                                 pPad->fileStuff.fileWidgets.saveAs.saveAs_form,
738                                 XmDIALOG_TEXT);
739         XmTextFieldSetString(textField, "");
740     }
741
742     return TRUE;
743 }
744
745
746 /************************************************************************
747  * oldFileExitCB - callback assigned to "File" menu "Close" button
748  ************************************************************************/
749 /* ARGSUSED */
750 void
751 oldFileExitCB(
752         Widget w,
753         caddr_t client_data,
754         caddr_t call_data)
755 {
756     Editor *pPad = (Editor *)client_data;
757     Tt_status status;
758
759     if (SaveUnsaved(pPad, FileExitCB)) {
760         /*
761          * If SaveUnsaved() returns True, don't close the window at this
762          * time since either:
763          *
764          * 1) a dialog has been posted which needs to be responded to
765          *    (and pendingFileFunc has been set to FileExitCB so that
766          *    this function will be resumed after the response) or
767          * 2) an error has occurred (in which case we abort the exit operation,
768          *    failing the TTDT_QUIT request if it initiated the exit).
769          */
770         if (pPad->fileStuff.pendingFileFunc != FileExitCB) { /* error occurred */
771             TTfailPendingQuit(pPad);
772         }
773         return;
774     }
775
776     if (pPad->ttQuitReq.contract) {  /* reply to ToolTalk Quit request */
777         status = tt_message_reply(pPad->ttQuitReq.contract);
778         status = tttk_message_destroy(pPad->ttQuitReq.contract);
779     }
780
781     if (pPad->ttEditReq.contract) {
782         TTmediaReply(pPad);     /* reply/close ToolTalk Edit/Display request */
783     }
784
785     if (pPad->xrdb.standAlone) {
786         exit(pPad->confirmStuff.confirmationStatus);
787     }
788
789     pPad->inUse = False;
790     numActivePads--;
791     UnmanageAllDialogs(pPad);
792     XtSetMappedWhenManaged(pPad->app_shell, False);
793         XmImUnregister(pPad->editor);
794     XtPopdown(pPad->app_shell);
795     XWithdrawWindow(pPad->display, XtWindow(pPad->app_shell),
796                         XDefaultScreen(pPad->display));
797     XFlush(pPad->display);
798
799     /* -----> Send "DONE" notice if dealing with a requestor dtpad */
800 /*     if (!pPad->ttEditReq.contract && pPad->xrdb.blocking) { */
801 /*      char numBuf[10]; */
802 /*      sprintf(numBuf, "%d", pPad->confirmStuff.confirmationStatus); */
803 /*      _DtSendSuccessNotification( */
804 /*                      "*", */
805 /*                      (DtString) NULL, */
806 /*                      (DtString) DTPAD_DONE, */
807 /*                      pPad->blockChannel, numBuf, NULL); */
808 /*     } */
809
810     if (numActivePads == 0 && pPad->xrdb.exitOnLastClose) {
811         exit(pPad->confirmStuff.confirmationStatus);
812     }
813
814     /*
815      * If we're going to remain around, clean up Pad for its next use.
816      * This speeds up opening a cached Pad at the expense of cycles at
817      * close time.  Perception is reality.
818      */
819
820     /* -----> clear ToolTalk message info */
821     TTresetQuitArgs(pPad);
822     pPad->ttEditReq.contract = 0;
823     if (pPad->ttEditReq.msg_id != (char *)NULL) {
824         XtFree(pPad->ttEditReq.msg_id);
825         pPad->ttEditReq.msg_id = (char *)NULL;
826     }
827     if (pPad->ttEditReq.vtype != (char *)NULL) {
828         XtFree(pPad->ttEditReq.vtype);
829         pPad->ttEditReq.vtype = (char *)NULL;
830     }
831     if (pPad->ttEditReq.fileName != (char *)NULL) {
832         XtFree(pPad->ttEditReq.fileName);
833         pPad->ttEditReq.fileName = (char *)NULL;
834     }
835     if (pPad->ttEditReq.docName != (char *)NULL) {
836         XtFree(pPad->ttEditReq.docName);
837         pPad->ttEditReq.docName = (char *)NULL;
838     }
839     if (pPad->ttEditReq.savePattern) {
840         tt_pattern_destroy(pPad->ttEditReq.savePattern);
841         pPad->ttEditReq.savePattern = NULL;
842     }
843
844     if (pPad->dialogTitle != (char *)NULL) {
845         XtFree(pPad->dialogTitle);
846     }
847
848     pPad->saveRestore = False;
849
850     pPad->fileStuff.pendingFileFunc = (void (*)())NULL;
851     pPad->fileStuff.pendingFileHelpFunc = (void (*)())NULL;
852     pPad->fileStuff.fileExists = False;
853     pPad->fileStuff.saveWithNewlines = True;
854     pPad->fileStuff.readOnly = False;
855     if (pPad->fileStuff.fileName != (char *) NULL) {
856         XtFree(pPad->fileStuff.fileName);
857         pPad->fileStuff.fileName = (char *) NULL;
858     }
859     if (pPad->fileStuff.netfile != (char *) NULL) {
860         tt_free(pPad->fileStuff.netfile);
861          pPad->fileStuff.netfile = (char *) NULL;
862     }
863
864     /* -----> Clear contents, undo, find/change, format and message area */
865     DtEditorReset(pPad->editor);
866
867     /* -----> Reset resources to server's initial resource state */
868     RestoreInitialServerResources(pPad);
869
870     /* -----> Set iconic state to false */
871     pPad->iconic = False;
872
873     /* -----> Set app shell geo (pixels), resize hints, position & size hints */
874     SetWindowSize(pPad);
875
876     /* -----> Clear director "seed" in SaveAs FSB */
877     if (pPad->fileStuff.fileWidgets.saveAs.saveAs_form != (Widget)NULL) {
878         Widget textField = XmFileSelectionBoxGetChild(
879                                 pPad->fileStuff.fileWidgets.saveAs.saveAs_form,
880                                 XmDIALOG_TEXT);
881         XmTextFieldSetString(textField, "");
882     }
883 }
884
885
886 /************************************************************************
887  * NoSaveCB - callback associated with the [No] button in the "Save changes
888  *      to <file>?" PromptDialog created by CreateSaveWarning().
889  ************************************************************************/
890 void
891 NoSaveCB(
892         Widget w,
893         caddr_t client_data,
894         caddr_t call_data )
895 {
896     Editor *pPad = (Editor *)client_data;
897     void (*pFunc)();
898
899     XtUnmanageChild(pPad->fileStuff.fileWidgets.select.save_warning);
900
901
902     if ((pFunc = pPad->fileStuff.pendingFileFunc) != (void(*)()) NULL)  {
903         /* -----> don't clear the pending function if it calls SaveUnsaved() */
904         if (pPad->fileStuff.pendingFileFunc != FileNewCB &&
905           pPad->fileStuff.pendingFileFunc != FileOpenCB &&
906           pPad->fileStuff.pendingFileFunc != FileExitCB) {
907             pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
908         }
909         if (pFunc != FileSaveCB) {
910             (*pFunc)(w, client_data, call_data);
911         }
912     }
913 }
914
915
916 /************************************************************************
917  * CancelFileSelectCB - 
918  ************************************************************************/
919 /* ARGSUSED */
920 void
921 CancelFileSelectCB(
922         Widget w,
923         caddr_t client_data,
924         caddr_t call_data )
925 {
926     Editor *pPad = (Editor *)client_data;
927
928     pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
929     pPad->fileStuff.pendingFileHelpFunc = (void(*)()) NULL;
930
931     /* popdown the file selection box */
932     XtUnmanageChild (w);
933     _DtTurnOffHourGlass(w);
934     _DtTurnOffHourGlass(pPad->app_shell);
935 }
936
937
938 /************************************************************************
939  * FileOpenOkCB - saves the name of a file to be opened and its directory,
940  *      and then loads its contents into the DtEditor widget.
941  *
942  *      This callback is assigned to the "Ok" button of the File
943  *      Selection Box displayed by the callback, FileOpenCB() assigned
944  *      to the "File" menu "Open" button.
945  ************************************************************************/
946 static void
947 FileOpenOkCB(
948         Widget w,
949         caddr_t client_data,
950         caddr_t call_data )
951 {
952     Editor      *pPad = (Editor *)client_data;
953     FileStuff   *pStuff = &pPad->fileStuff;
954     XmFileSelectionBoxCallbackStruct *cb = (XmFileSelectionBoxCallbackStruct *)
955                                            call_data;
956     char *name = (char *) XtMalloc( sizeof(char) * cb->length + 1 );
957     name[0] ='\0';
958
959     _DtTurnOnHourGlass(pPad->app_shell);
960     _DtTurnOnHourGlass(w);
961
962     if (pPad->ttEditReq.contract && pPad->ttEditReq.op != TTME_INSTANTIATE) {
963         TTmediaReply(pPad);     /* reply/close ToolTalk media request */
964     }
965
966     /* -----> Get the name of the directory and file.
967      * XXX - Eventually, it makes sense to store the name/etc. as an XmString
968      * rather than convert everything to a string.  This will mean
969      * changing the pPad.fileName type.
970      * Additionally, we can get quit saving the text field ID and
971      * deal only with the FSB. */
972
973     name = (char *) _XmStringUngenerate(cb->value, NULL,
974                                         XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
975
976     if (pStuff->fileName != (char *)NULL) {
977         XtFree(pStuff->fileName);
978     }
979     pStuff->fileName = name;
980     ExtractAndStoreDir(pPad, name, OPEN); /* store pPad->fileStuff.pathDir */
981
982     LoadFile(pPad, NULL);               /* this is always successful */
983     ChangeMainWindowTitle(pPad);
984
985     CancelFileSelectCB(w, client_data, call_data);
986 }
987
988
989 /************************************************************************
990  * IncludeFile - obtains the name of a file to include (via a Xm FSB),
991  *      parses the name and then
992  *      inserts the file contents into the Dt Editor Widget (via LoadFile).
993  *
994  *      This callback is assigned to the "Ok" button of the
995  *      File Selection Box displayed by the callback,
996  *      FileIncludeCB() assigned to the "File" menu "Include" button.
997  ************************************************************************/
998 static void
999 IncludeFile(
1000         Widget w,
1001         caddr_t client_data,
1002         caddr_t call_data )
1003 {
1004     Editor      *pPad = (Editor *)client_data;
1005     XmFileSelectionBoxCallbackStruct *cb = (XmFileSelectionBoxCallbackStruct *)
1006                                            call_data;
1007     char *name = (char *) XtMalloc( sizeof(char) * cb->length + 1 );
1008     name[0] ='\0';
1009
1010     _DtTurnOnHourGlass(pPad->app_shell);
1011     _DtTurnOnHourGlass(w);
1012
1013     /*
1014      *  Get the name of the file
1015      * ******
1016      * Eventually, it makes sense to store the name/etc. as an XmString
1017      * rather than convert everything to a string.  This will mean
1018      * changing the pPad.fileName type.
1019      * Additionally, we can get quit saving the text field ID and
1020      * deal only with the FSB.
1021      */
1022
1023     name = (char *) _XmStringUngenerate(cb->value, NULL,
1024                                         XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1025
1026     ExtractAndStoreDir(pPad, name, INCLUDE); /* store pPad->fileStuff.pathDir */
1027
1028     LoadFile(pPad, name);
1029     ChangeMainWindowTitle(pPad);
1030     CancelFileSelectCB(w, client_data, call_data);
1031     if (name != (char *)NULL)
1032         XtFree(name);
1033 }
1034
1035
1036 /************************************************************************
1037  * SaveUnsaved - allows unsaved changes to be saved to the current file
1038  *      or buffer.  If the AskIfSave dialog is posted, sets the global
1039  *      pendingFileFunc to the callingFunc so that the calling function
1040  *      can be reentered to finish its processing.
1041  *
1042  *      Returns True if the calling function should not continue due to:
1043  *
1044  *      1) some error condition (e.g. the file couldn't be saved), or
1045  *      2) a dialog has been posted which needs to be responded to
1046  *         (pPad->fileStuff.pendingFileFunc will be set to the calling
1047  *         function which may again be executed via a callback set on
1048  *         the posted dialog)
1049  *
1050  ************************************************************************/
1051 static Boolean
1052 SaveUnsaved(
1053         Editor* pPad,
1054         void (*callingFunc)() )
1055 {
1056     Boolean addNewlines;
1057     Tt_message m;
1058
1059     /*
1060      * If there are unsaved changes, ask the user if they wish to
1061      * write them out.  If saveOnClose is True, then just write it.
1062      */
1063     if (DtEditorCheckForUnsavedChanges(pPad->editor)) {
1064
1065         /* -----> If handling a "silent" TTDT_QUIT request, don't AskIfSave
1066          *        and don't save any unsaved changes (TTDT_SAVE does this) */
1067         if (callingFunc == FileExitCB && 
1068           pPad->ttQuitReq.contract && pPad->ttQuitReq.silent) {
1069             if (pPad->ttQuitReq.force) {
1070                 return False;   /* close edit window */
1071             } else {
1072                 return True;    /* don't close edit window */
1073             }
1074         }
1075
1076         pPad->ttEditReq.returnBufContents = True;
1077
1078         if ((pPad->xrdb.saveOnClose) && 
1079                 (pPad->fileStuff.fileName && *pPad->fileStuff.fileName)) {
1080             DtEditorErrorCode errorCode;
1081             addNewlines = pPad->xrdb.wordWrap == True &&
1082                                   pPad->fileStuff.saveWithNewlines == True;
1083             _DtTurnOnHourGlass(pPad->app_shell);
1084             errorCode = DtEditorSaveContentsToFile(
1085                         pPad->editor,
1086                         pPad->fileStuff.fileName,
1087                         True,                   /* overwrite existing file */
1088                         addNewlines,            /* replace soft line feeds? */
1089                         True);                  /* mark contents as saved */
1090             _DtTurnOffHourGlass(pPad->app_shell);
1091             if (errorCode != SUCCESS) {
1092                 PostSaveError(pPad, pPad->fileStuff.fileName, errorCode);
1093                 if (callingFunc == FileExitCB) {
1094                     /* Set saveOnClose to False to force user to explicitly
1095                      * choose to not save changes in order to exit. */
1096                     pPad->xrdb.saveOnClose = False;
1097                 }
1098                 pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
1099                 return True;    /* don't finish calling func */
1100             } else {
1101                 if (pPad->ttEditReq.contract) {
1102                     /* ZZZ -----> Create and send Saved notice */
1103                     m = ttdt_file_notice(
1104                         pPad->ttEditReq.contract,       /* context */
1105                         TTDT_SAVED,                     /* op */
1106                         TT_SESSION,                     /* Tt_scope */
1107                         pPad->fileStuff.fileName,       /* msg file name */
1108                         True);                          /* send & destroy */
1109                 }
1110             }
1111         } else {
1112             if (callingFunc == pPad->fileStuff.pendingFileFunc) {
1113                 /* We've already did AskIfSave but the user responded
1114                  * "No" so lets not keep asking (NoSaveCB does not clear
1115                  * pPad->fileStuff.pendingFileFunc). */
1116                 pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
1117                 pPad->ttEditReq.returnBufContents = False;
1118             } else {
1119                 /* AskIfSave assigns either FileSaveAsCB or FileSaveCB to the
1120                  * the o.k. dialog button that it posts.  These callbacks
1121                  * execute pPad->fileStuff.pendingFileFunc when done. */
1122                 pPad->fileStuff.pendingFileFunc = callingFunc;
1123                 AskIfSave(pPad);
1124                 return True;    /* don't finish calling func */
1125             }
1126         }
1127     } else {    /* no unsaved contents */
1128         pPad->ttEditReq.returnBufContents = False;
1129     }
1130
1131     return False;       /* finish calling funct */
1132 }
1133
1134
1135 /************************************************************************
1136  * SaveNewLinesCB - 
1137  ************************************************************************/
1138 /* ARGSUSED */
1139 void 
1140 SaveNewLinesCB( 
1141         Widget w,
1142         XtPointer client_data,
1143         XtPointer call_data) 
1144 {
1145     Editor *pPad = (Editor *)client_data;
1146
1147     if (w == pPad->fileStuff.fileWidgets.saveAs.toggleWidgets.with_newl ||
1148         w == pPad->fileStuff.fileWidgets.select.toggleWidgets.with_newl)
1149         pPad->fileStuff.saveWithNewlines = True;
1150     else
1151         pPad->fileStuff.saveWithNewlines = False;
1152 }
1153
1154
1155 /************************************************************************
1156  * SaveAsOkCB - save the file
1157  ************************************************************************/
1158 void
1159 SaveAsOkCB(
1160         Widget w,
1161         caddr_t client_data,
1162         caddr_t call_data )
1163 {
1164     Editor *pPad = (Editor *)client_data;
1165     SaveAs *pSaveAs = &pPad->fileStuff.fileWidgets.saveAs;
1166     void (*pFunc)();
1167     Widget textField = XmFileSelectionBoxGetChild(
1168                     pPad->fileStuff.fileWidgets.saveAs.saveAs_form,
1169                     XmDIALOG_TEXT);
1170     DtEditorErrorCode errorCode;
1171     Tt_message m;
1172     Boolean addNewlines = pPad->xrdb.wordWrap == True &&
1173                           pPad->fileStuff.saveWithNewlines == True;
1174     Boolean overWrite, markSaved;
1175     XmFileSelectionBoxCallbackStruct *cb = (XmFileSelectionBoxCallbackStruct *)
1176                                            call_data;
1177     char *name = (char *) XtMalloc( sizeof(char) * cb->length + 1 );
1178     name[0] ='\0';
1179
1180     _DtTurnOnHourGlass(pPad->app_shell);
1181     _DtTurnOnHourGlass(pSaveAs->saveAs_form);
1182
1183     /* -----> Get the "save as" file name */
1184
1185     name = (char *) _XmStringUngenerate(cb->value, NULL,
1186                                         XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1187
1188     pPad->fileStuff.savingName = name;
1189     ExtractAndStoreDir(pPad, name, OPEN);  /* store pPad->fileStuff.pathDir */
1190
1191     /*
1192      * Normally, we would first try writing without overwriting the file
1193      * in which case we would get an error if the file pre-exists and we
1194      * would post a dialog asking the user if they wished to overwrite it.
1195      * However, if the name of the file to save is the same as the file
1196      * being edited, the user opened the file and knows that it exists.
1197      * In this case we would overwrite it without presenting the overwrite
1198      * option dialog.
1199      */
1200     if (strcmp(pPad->fileStuff.fileName, pPad->fileStuff.savingName) == 0) {
1201         overWrite = True;                       /* overwrite */
1202     } else {
1203         overWrite = False;                      /* don't overwrite yet */
1204     }
1205
1206     /* -----> Don't mark the current contents as saved if saved to a
1207      *        file different than the (to be) current file */
1208     if (! pPad->xrdb.nameChange &&
1209       pPad->fileStuff.fileName &&   /* allow for -noNameChange w/o a fileName */
1210       ! overWrite) {
1211         markSaved = False;
1212     } else {
1213         markSaved = True;
1214     }
1215
1216     errorCode = DtEditorSaveContentsToFile(
1217                         pPad->editor,
1218                         pPad->fileStuff.savingName,
1219                         overWrite,
1220                         addNewlines,            /* replace soft line feeds? */
1221                         markSaved);             /* mark contents as saved? */
1222     if (errorCode == DtEDITOR_WRITABLE_FILE) { /* file exists & not overwriting */
1223         PostAlreadyExistsDlg(pPad);     /* save handled in AlrdyExistsOkCB */
1224         XtUnmanageChild (pSaveAs->saveAs_form);
1225         _DtTurnOffHourGlass(pSaveAs->saveAs_form);
1226         _DtTurnOffHourGlass(pPad->app_shell);
1227         return;
1228     }
1229     if (errorCode != SUCCESS) {
1230         PostSaveError(pPad, pPad->fileStuff.savingName, errorCode);
1231         XtFree(pPad->fileStuff.savingName);
1232         pPad->fileStuff.savingName = (char *)NULL;
1233         pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
1234     } else {
1235         if (pPad->ttEditReq.contract) {
1236             /* ZZZ -----> Create and send Saved notice */
1237             m = ttdt_file_notice(
1238                         pPad->ttEditReq.contract,       /* context */
1239                         TTDT_SAVED,                     /* op */
1240                         TT_SESSION,                     /* Tt_scope */
1241                         pPad->fileStuff.savingName,     /* msg file name */
1242                         True);                          /* send & destroy */
1243             
1244         }
1245         if (pPad->xrdb.nameChange == True) {
1246             if (pPad->ttEditReq.contract && pPad->ttEditReq.op != TTME_INSTANTIATE) {
1247                 pPad->ttEditReq.returnBufContents = False;  /* drop chgs w/o notice */
1248                 TTmediaReply(pPad);     /* reply/close ToolTalk media request */
1249             }
1250             XtFree(pPad->fileStuff.fileName);
1251             pPad->fileStuff.fileName = pPad->fileStuff.savingName;
1252             ChangeMainWindowTitle(pPad);
1253         }
1254     }
1255
1256     pPad->nodo = TRUE;
1257     XtUnmanageChild (pSaveAs->saveAs_form);
1258     _DtTurnOffHourGlass(pSaveAs->saveAs_form);
1259     _DtTurnOffHourGlass(pPad->app_shell);
1260     if ((pFunc = pPad->fileStuff.pendingFileFunc) != (void (*)())NULL)  {
1261         pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
1262         (*pFunc)(w, client_data, call_data);
1263     }
1264 }
1265
1266
1267 /************************************************************************
1268  * AlrdyExistsOkCB - the ok callback for a saveAs of a file which already
1269  *      exists.  Specifically, this routine:
1270  *
1271  *      - saves the current text to the file specified by
1272  *        pPad->fileStuff.savingName
1273  *      - if appropriate, resets the name of the current file
1274  *        (pPad->fileStuff.fileName) to pPad->fileStuff.savingName and
1275  *        frees pPad->fileStuff.savingName
1276  *      - executes pPad->fileStuff.pendingFileFunc if specified
1277  
1278  ************************************************************************/
1279 void
1280 AlrdyExistsOkCB(
1281         Widget w,
1282         caddr_t client_data,
1283         caddr_t call_data )
1284 {
1285     Editor *pPad = (Editor *)client_data;
1286     void (*pFunc)();
1287     DtEditorErrorCode errorCode;
1288     Boolean addNewlines = pPad->xrdb.wordWrap == True &&
1289                           pPad->fileStuff.saveWithNewlines == True;
1290     Boolean markSaved;
1291     Tt_message m;
1292
1293     _DtTurnOnHourGlass(pPad->app_shell);
1294     _DtTurnOnHourGlass(w);
1295
1296     /* -----> Don't mark the current contents as saved if saved to a
1297      *        file different than the (to be) current file */
1298     if (! pPad->xrdb.nameChange && 
1299       pPad->fileStuff.fileName &&   /* allow for -noNameChange w/o a fileName */
1300       (strcmp(pPad->fileStuff.fileName, pPad->fileStuff.savingName) != 0)) {
1301         markSaved = False;
1302     } else {
1303         markSaved = True;
1304     }
1305
1306     errorCode = DtEditorSaveContentsToFile(
1307                         pPad->editor,
1308                         pPad->fileStuff.savingName,
1309                         True,                   /* overwrite existing file */
1310                         addNewlines,            /* replace soft line feeds? */
1311                         markSaved);             /* mark contents as saved? */
1312
1313     XtUnmanageChild (w);
1314     _DtTurnOffHourGlass(w);
1315     _DtTurnOffHourGlass(pPad->app_shell);
1316
1317     if (errorCode == SUCCESS) {
1318         if (pPad->ttEditReq.contract) {
1319             /* ZZZ -----> Create and send Saved notice */
1320             m = ttdt_file_notice(
1321                         pPad->ttEditReq.contract,       /* context */
1322                         TTDT_SAVED,                     /* op */
1323                         TT_SESSION,                     /* Tt_scope */
1324                         pPad->fileStuff.savingName,     /* msg file name */
1325                         True);                          /* send & destroy */
1326         }
1327         if (pPad->xrdb.nameChange == True) {
1328             if (pPad->ttEditReq.contract && pPad->ttEditReq.op != TTME_INSTANTIATE) {
1329                 pPad->ttEditReq.returnBufContents = False;  /* drop chgs w/o notice */
1330                 TTmediaReply(pPad);     /* reply/close ToolTalk media request */
1331             }
1332             XtFree(pPad->fileStuff.fileName);
1333             pPad->fileStuff.fileName = pPad->fileStuff.savingName;
1334             ChangeMainWindowTitle(pPad);
1335         }
1336     } else {
1337         PostSaveError(pPad, pPad->fileStuff.savingName, errorCode);
1338     }
1339     if (pPad->fileStuff.savingName != pPad->fileStuff.fileName)
1340         XtFree(pPad->fileStuff.savingName);
1341     pPad->fileStuff.savingName = (char *)NULL;
1342
1343     if ((pFunc = pPad->fileStuff.pendingFileFunc) != (void (*)())NULL)  {
1344         pPad->fileStuff.pendingFileFunc = (void(*)()) NULL;
1345         (*pFunc)(w, client_data, call_data);
1346     }
1347 }
1348
1349
1350 /************************************************************************
1351  * SaveAsCancelCB - Unmanage the SaveAs dialog
1352  ************************************************************************/
1353 /* ARGSUSED */
1354 void
1355 SaveAsCancelCB(
1356         Widget w,
1357         caddr_t client_data,
1358         caddr_t call_data )
1359 {
1360     Editor *pPad = (Editor *) client_data;
1361
1362     XtUnmanageChild ((Widget) pPad->fileStuff.fileWidgets.saveAs.saveAs_form);
1363     pPad->fileStuff.pendingFileFunc = (void (*)())NULL;
1364     pPad->fileStuff.pendingFileHelpFunc = (void (*)())NULL;
1365 }
1366
1367
1368 /************************************************************************
1369  * AlrdyExistsCancelCB - Unmanage the AlreadyExists dialog
1370  ************************************************************************/
1371 /* ARGSUSED */
1372 void
1373 AlrdyExistsCancelCB(
1374         Widget w,
1375         caddr_t client_data,
1376         caddr_t call_data )
1377 {
1378     Editor *pPad = (Editor *)client_data;
1379     XtUnmanageChild ((Widget) pPad->fileStuff.fileWidgets.saveAs.alrdy_exist);
1380     XtFree(pPad->fileStuff.savingName);
1381     pPad->fileStuff.savingName = (char *) NULL;
1382     pPad->fileStuff.pendingFileFunc = (void (*)())NULL;
1383     pPad->fileStuff.pendingFileHelpFunc = (void (*)())NULL;
1384 }
1385
1386
1387 /************************************************************************
1388  * AskIfSaveCancelCB - 
1389  ************************************************************************/
1390 /* ARGSUSED */
1391 void
1392 AskIfSaveCancelCB(
1393         Widget w,
1394         caddr_t client_data,
1395         caddr_t call_data )
1396 {
1397     Editor *pPad = (Editor *)client_data;
1398
1399     XtUnmanageChild ((Widget) pPad->fileStuff.fileWidgets.select.save_warning);
1400     if (pPad->fileStuff.pendingFileFunc == FileExitCB) {
1401         TTfailPendingQuit(pPad);
1402     }
1403     pPad->fileStuff.pendingFileFunc = (void (*)())NULL;
1404     pPad->fileStuff.pendingFileHelpFunc = (void (*)())NULL;
1405 }
1406