dtwm: basic multihead(xinerama only) support
[oweals/cde.git] / cde / programs / dtpad / printJob.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: printJob.c /main/29 1997/08/01 14:32:04 samborn $ */
24 /**********************************<+>*************************************
25 ***************************************************************************
26 **
27 **  File:        printJob.c
28 **
29 **  Project:     HP DT dtpad, a memo maker type editor based on the
30 **               Dt Editor widget.
31 **
32 **  Description:  Routines which manipulate the print setup dialog
33 **
34 **************************************************************************
35 **********************************<+>*************************************/
36 /*
37  *                   Common Desktop Environment
38  *
39  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
40  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
41  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
42  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
43  *   (c) Copyright 1995 Digital Equipment Corp.
44  *   (c) Copyright 1995 Fujitsu Limited
45  *   (c) Copyright 1995 Hitachi, Ltd.
46  *
47  *
48  *                     RESTRICTED RIGHTS LEGEND
49  *
50  *Use, duplication, or disclosure by the U.S. Government is subject to
51  *restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
52  *Technical Data and Computer Software clause in DFARS 252.227-7013.  Rights
53  *for non-DOD U.S. Government Departments and Agencies are as set forth in
54  *FAR 52.227-19(c)(1,2).
55
56  *Hewlett-Packard Company, 3000 Hanover Street, Palo Alto, CA 94304 U.S.A.
57  *International Business Machines Corp., Route 100, Somers, NY 10589 U.S.A.
58  *Sun Microsystems, Inc., 2550 Garcia Avenue, Mountain View, CA 94043 U.S.A.
59  *Novell, Inc., 190 River Road, Summit, NJ 07901 U.S.A.
60  *Digital Equipment Corp., 111 Powdermill Road, Maynard, MA 01754, U.S.A.
61  *Fujitsu Limited, 1015, Kamikodanaka Nakahara-Ku, Kawasaki 211, Japan
62  *Hitachi, Ltd., 6, Kanda Surugadai 4-Chome, Chiyoda-ku, Tokyo 101, Japan
63  */
64
65
66 #include <errno.h>
67 #include <pwd.h>
68 #include <stdio.h>
69 #include <string.h>
70 #include <sys/types.h>
71 #include <time.h>
72
73 #include <X11/Intrinsic.h>
74 #include <X11/Shell.h>
75 #include <Xm/Xm.h>
76 #include <Xm/DialogS.h>
77 #include <Xm/Form.h>
78 #include <Xm/Label.h>
79 #if 0 && defined(PRINTING_SUPPORTED)
80 #include <Xm/Print.h>
81 #endif /* PRINTING_SUPPORTED */
82 #include <Dt/Editor.h>
83 #include <Dt/Print.h>
84
85 #include "dtpad.h"
86
87 static void     _pjCreatePrintShell(PrintJob *pJob);
88 static void     _pjCreateOutputWidgets(PrintJob *pJob);
89 static void     _pjDoPrint(PrintJob*);
90 static void     _pjUpdatePageHeaders(
91                                 PrintJob*,
92                                 PrintStringTypeEnum,
93                                 PrintStringTypeEnum,
94                                 PrintStringTypeEnum,
95                                 PrintStringTypeEnum);
96 #if 0 && defined(PRINTING_SUPPORTED)
97 static void     _pjFinishedPrintToFile(
98                                 Display*,
99                                 XPContext,
100                                 XPGetDocStatus,
101                                 XPointer);
102 #endif /* PRINTING_SUPPORTED */
103 static char *   _pjGetPageHeaderString(PrintJob*, PrintStringTypeEnum);
104
105 static void     _pjCancelCB (Widget, XtPointer client_data, XtPointer);
106 static void     _pjCloseDisplayCB (Widget, XtPointer client_data, XtPointer);
107 static void     _pjPdmSetupCB (Widget, XtPointer client_data, XtPointer);
108 static void     _pjPdmNotificationCB (Widget, XtPointer client_data, XtPointer);
109 static void     _pjPrintCB (Widget, XtPointer client_data, XtPointer);
110 static void     _pjPrintOnePageCB(Widget, XtPointer, XtPointer);
111
112 static void     _pjRegisterActivePrintDisplay(Display*);
113 static void     _pjUnregisterActivePrintDisplay(Display*);
114
115 static Display  *_pjErrorPrintDisplay = NULL;
116 static Display  **_pjActivePrintDisplay = NULL;
117 static int      _pjMaxActivePrintDisplay = 0;
118
119 /************************************************************************
120  * PrintJobCreate
121  *      Creates a new print job for the specified document file.
122  ************************************************************************/
123 PrintJob *
124 PrintJobCreate(
125         char *documentName,
126         char *tempFileName,
127         Boolean silent,
128         Editor *pPad
129         )
130 {
131     PrintJob *pJob;
132
133     pJob = (PrintJob *) XtMalloc( sizeof(PrintJob) );
134     memset(pJob, 0, sizeof(PrintJob));
135
136     pJob->pPad = pPad;
137     pJob->parentShell = pPad->app_shell;
138     pJob->documentName = strdup(documentName);
139     pJob->tempFileName = strdup(tempFileName);
140     pJob->silent = silent;
141
142     pJob->pOutput = NULL;
143     pJob->pSetup = NULL;
144     pJob->pShell = NULL;
145     pJob->printData = (DtPrintSetupData*) XtMalloc(sizeof(DtPrintSetupData));
146     memset(pJob->printData, 0, sizeof(DtPrintSetupData));
147
148     pJob->npagesDone = 0;
149     pJob->npagesTotal = 0;
150
151     pJob->nextpageShell = NULL;
152     pJob->nextpageButton = NULL;
153
154     return pJob;
155 }
156
157 /************************************************************************
158  * PrintJobDestroy
159  *      Destroys the specified PrintJob.
160  ************************************************************************/
161 void
162 PrintJobDestroy(PrintJob *pJob)
163 {
164     if (pJob == NULL)
165       return;
166
167     if (pJob->pPad)
168     {
169         pJob->pPad->numPendingTasks--;
170         ClearStatusMessage(pJob->pPad);
171         XtSetSensitive(pJob->pPad->fileStuff.fileWidgets.printBtn, True);
172         /*
173         XtSetSensitive(pJob->pPad->fileStuff.fileWidgets.silentPrintBtn, True);
174         */
175     }
176     if (pJob->documentName != NULL)
177     {
178         free((char*) pJob->documentName);
179         pJob->documentName = NULL;
180     }
181     if (pJob->tempFileName != NULL)
182     {
183         free((char*) pJob->tempFileName);
184         pJob->tempFileName = NULL;
185     }
186     if (pJob->pOutput != NULL)
187     {
188         PrintOutputDestroy(pJob->pOutput);
189         pJob->pOutput = NULL;
190     }
191     if (pJob->pShell != NULL)
192     {
193         _pjRegisterActivePrintDisplay(XtDisplay(pJob->pShell));
194         if (XtDisplay(pJob->pShell) == PrintJobGetErrorPrintDisplay())
195         {
196             char *errMsg;
197
198             /*
199              * Need to display an error dialog;
200              */
201             errMsg =
202               GETMESSAGE(
203                 14, 24,
204                 "The X Print Server is temporarily out of resources.");
205
206             Warning(pJob->pPad, (char *) errMsg, XmDIALOG_ERROR);
207             PrintJobSetErrorPrintDisplay(NULL);
208         }
209
210         XtDestroyWidget(pJob->pShell);
211         pJob->pShell = NULL;
212     }
213     if (pJob->pSetup != NULL)
214     {
215         PrintSetupDestroy(pJob->pSetup);
216         pJob->pSetup = NULL;
217     }
218     if (pJob->printData)
219     {
220         DtPrintFreeSetupData(pJob->printData);
221         XtFree((XtPointer) pJob->printData);
222         pJob->printData = NULL;
223     }
224     if (pJob->nextpageShell)
225     {
226         XtDestroyWidget(pJob->nextpageShell);
227         pJob->nextpageShell = NULL;
228     }
229
230     XtFree((char *) pJob);
231 }
232
233 /************************************************************************
234  * PrintJobExecute
235  *      Executes the specified PrintJob
236  ************************************************************************/
237 void
238 PrintJobExecute(PrintJob *pJob)
239 {
240     if (pJob == NULL) return;
241
242     pJob->pSetup = PrintSetupCreate(
243                                 pJob->parentShell,
244                                 pJob->documentName,
245                                 pJob->pPad->xrdb.wordWrap,
246                                 pJob->pPad,
247                                 (XtCallbackProc) _pjCancelCB, pJob,
248                                 (XtCallbackProc) _pjCloseDisplayCB, pJob,
249                                 (XtCallbackProc) _pjPrintCB, pJob,
250                                 (XtCallbackProc) _pjPdmSetupCB, pJob);
251     if (pJob->silent)
252     {
253         /*
254          * The DtPrintSetupDialog will display itself automatically
255          * along with an error message in the event of an error.
256          */
257         if (FALSE == PrintSetupGetDefaultPrintData(
258                                                 pJob->pSetup,
259                                                 pJob->printData))
260           return;
261
262         _pjCreatePrintShell(pJob);
263         _pjDoPrint(pJob);
264     }
265     else
266       PrintSetupDisplay(pJob->pSetup);
267 }
268
269 /************************************************************************
270  * PrintJobCancel
271  *      Cancels and deletes the specified print job.
272  ************************************************************************/
273 void
274 PrintJobCancel(PrintJob *pJob)
275 {
276     PrintJobDestroy(pJob);
277 }
278
279
280 /************************************************************************
281  * PrintJobGetErrorPrintDisplay
282  *      Returns the last print display on which an error occured.
283  ************************************************************************/
284 Display *
285 PrintJobGetErrorPrintDisplay()
286 {
287     return _pjErrorPrintDisplay;
288 }
289
290 /************************************************************************
291  * PrintJobSetErrorPrintDisplay
292  *      Save a pointer to the print display on which an error occured.
293  ************************************************************************/
294 void
295 PrintJobSetErrorPrintDisplay(Display *display)
296 {
297     _pjErrorPrintDisplay = display;
298 }
299
300 /************************************************************************
301  * PrintJobIsActivePrintDisplay
302  *      Save a pointer to the print display on which an error occured.
303  ************************************************************************/
304 Boolean
305 PrintJobIsActivePrintDisplay(Display *display)
306 {
307     int i;
308
309     for (i = 0; i < _pjMaxActivePrintDisplay; i++)
310       if (display == _pjActivePrintDisplay[i])
311         return True;
312
313     return False;
314 }
315
316 /************************************************************************
317  * _pjRegisterActivePrintDisplay
318  *      Save the Display pointer for an active print display connection
319  ************************************************************************/
320 static void
321 _pjRegisterActivePrintDisplay(Display *display)
322 {
323     size_t size;
324     int i;
325
326     if (0 == _pjMaxActivePrintDisplay)
327     {
328         _pjMaxActivePrintDisplay = 10;
329         size = _pjMaxActivePrintDisplay * sizeof(Display*);
330         _pjActivePrintDisplay = (Display**) malloc(size);
331         memset((char*) _pjActivePrintDisplay, 0, size);
332     }
333
334     for (i = 0; i < _pjMaxActivePrintDisplay; i++)
335     {
336         if (NULL == _pjActivePrintDisplay[i])
337         {
338             _pjActivePrintDisplay[i] = display;
339             return;
340         }
341     }
342
343     size = _pjMaxActivePrintDisplay * sizeof(Display*);
344     _pjActivePrintDisplay =
345         (Display**) realloc((void*) _pjActivePrintDisplay, 2*size);
346     memset((char*) (_pjActivePrintDisplay + size), 0, size);
347     _pjActivePrintDisplay[_pjMaxActivePrintDisplay] = display;
348     _pjMaxActivePrintDisplay *= 2;
349 }
350
351 /************************************************************************
352  * _pjUnregisterActivePrintDisplay
353  *      Delete the Display pointer for an active print display connection
354  ************************************************************************/
355 static void
356 _pjUnregisterActivePrintDisplay(Display *display)
357 {
358     int i;
359
360     for (i = 0; i < _pjMaxActivePrintDisplay; i++)
361       if (display == _pjActivePrintDisplay[i])
362         _pjActivePrintDisplay[i] = NULL;
363 }
364
365
366 /************************************************************************
367  * _pjCreatePrintShell
368  *      Creates the print shell (XmPrintShell or XmDialogShell) to control
369  *      printing.
370  ************************************************************************/
371 static void
372 _pjCreatePrintShell(PrintJob *pJob)
373 {
374     DtPrintSetupData    *psd = NULL;
375
376     if (pJob == NULL ||
377         pJob->pShell != NULL ||
378         pJob->parentShell == NULL ||
379         pJob->pSetup == NULL) return;
380
381 #if 0 && defined(PRINTING_SUPPORTED)
382     
383     /*
384      * Create the print shell and
385      * the print output widgets
386      */
387 #ifdef PRINT_TO_VIDEO
388     /*
389      * Create a dialog shell widget on the video display.
390      */
391     pJob->pShell = XmCreateDialogShell(
392                                 pJob->parentShell,
393                                 "PrintVideo",
394                                 NULL, 0);
395     {
396         XmString    xms;
397
398         pJob->nextpageShell = XmCreateDialogShell(
399                                         pJob->parentShell,
400                                         "PrintNextPage",
401                                         NULL, 0);
402
403         xms = XmStringCreateLocalized("Push for Next Page");
404         pJob->nextpageButton = XtVaCreateManagedWidget(
405                                         "NextPageButton",
406                                         xmPushButtonWidgetClass,
407                                         pJob->nextpageShell,
408                                         XmNlabelString, xms,
409                                         XmNwidth, 200,
410                                         XmNheight, 200,
411                                         NULL);
412         XmStringFree(xms);
413
414         XtAddCallback(
415                 pJob->nextpageButton,
416                 XmNactivateCallback,
417                 _pjPrintOnePageCB,
418                 (XtPointer) pJob);
419
420         XtManageChild(pJob->nextpageShell);
421         XtRealizeWidget(pJob->nextpageShell);
422     }
423 #else
424
425     /*
426      * Create an XmPrintShell widget on the print display.  
427      */ 
428     psd = pJob->printData;
429     if (psd != NULL)
430       pJob->pShell = XmPrintSetup(
431                 pJob->parentShell,
432                 XpGetScreenOfContext(psd->print_display, psd->print_context),
433                 "Print",
434                 NULL, 0);
435
436     XtAddCallback(
437                 pJob->pShell,
438                 XmNpageSetupCallback,
439                 _pjPrintOnePageCB,
440                 (XtPointer) pJob);
441     XtAddCallback(
442                 pJob->pShell,
443                 XmNpdmNotificationCallback,
444                 _pjPdmNotificationCB,
445                 (XtPointer) pJob);
446 #endif
447
448     if (pJob->pShell == NULL) return;
449 #endif  /* PRINTING_SUPPORTED */
450
451 }
452
453
454
455 /************************************************************************
456  * _pjCreateOutputWidgets
457  *      Actually run the specified PrintJob.
458  *      Creates the PrintOutput object to be used for printing.
459  *      Initializes the mailbox to iterate through the messages.
460  *      Calls spoolOne to send a print job to the Xp server.
461  ************************************************************************/
462 static void
463 _pjCreateOutputWidgets(PrintJob *pJob)
464 {
465     DtEditorErrorCode   errorCode;
466     Boolean             parseError;
467     DtPrintSetupData    *psd = NULL;
468     int                 save_data;
469
470     /*
471      * Notify the user that we're printing
472      */
473     /* TBD:  Is there a status bar on pPad? */
474
475     if (pJob->pShell == NULL)
476     {
477         {/* TBD error dialog */}
478         PrintJobDestroy(pJob);
479         return;
480     }
481
482     pJob->pOutput = PrintOutputCreate(pJob->pShell);
483     PrintOutputSetWordWrap(pJob->pOutput, PrintSetupUseWordWrap(pJob->pSetup));
484     PrintOutputSetPageMargins(
485         pJob->pOutput,
486         PrintSetupGetMarginSpec(pJob->pSetup, DTPRINT_OPTION_MARGIN_TOP),
487         PrintSetupGetMarginSpec(pJob->pSetup, DTPRINT_OPTION_MARGIN_RIGHT),
488         PrintSetupGetMarginSpec(pJob->pSetup, DTPRINT_OPTION_MARGIN_BOTTOM),
489         PrintSetupGetMarginSpec(pJob->pSetup, DTPRINT_OPTION_MARGIN_LEFT),
490         &parseError
491         );
492     if (parseError)
493     {
494         /*
495          * Display an error dialog.
496         DtMailGenDialog *genDialog = new DtMailGenDialog(
497                                                         "Dialog",
498                                                         _parent->baseWidget());
499          */
500         char    *i18nMsg;
501         char    *errMsg;
502
503         i18nMsg = GETMESSAGE(
504                         14, 1,
505                         "One of the following margin specifiers \n has incorrect syntax: \n %s \n %s \n %s \n %s \nContinue using default margins?"
506                         );
507
508         errMsg = (char *) XtMalloc(1024);
509         sprintf(
510             errMsg,
511             i18nMsg,
512             PrintSetupGetMarginSpec(pJob->pSetup, DTPRINT_OPTION_MARGIN_TOP),
513             PrintSetupGetMarginSpec(pJob->pSetup, DTPRINT_OPTION_MARGIN_RIGHT),
514             PrintSetupGetMarginSpec(pJob->pSetup, DTPRINT_OPTION_MARGIN_BOTTOM),
515             PrintSetupGetMarginSpec(pJob->pSetup, DTPRINT_OPTION_MARGIN_LEFT)
516             );
517
518         Warning(pJob->pPad, (char *) errMsg, XmDIALOG_WARNING);
519         XtFree(errMsg);
520     }
521
522     /*
523      * Load the file
524      */
525     errorCode = PrintOutputLoadFile(pJob->pOutput, pJob->tempFileName);
526     switch (errorCode)
527     {
528         case DtEDITOR_NO_ERRORS:
529         case DtEDITOR_READ_ONLY_FILE:
530             break;
531         case DtEDITOR_NONEXISTENT_FILE:
532             Warning(
533                 pJob->pPad,
534                 (char *) GETMESSAGE(14, 2, "File does not exist."),
535                 XmDIALOG_WARNING);
536             break;
537         case DtEDITOR_DIRECTORY:
538             Warning(
539                 pJob->pPad,
540                 (char *) GETMESSAGE(14, 3, "Specified file is a directory."),
541                 XmDIALOG_WARNING);
542             break;
543         case DtEDITOR_CHAR_SPECIAL_FILE:
544         case DtEDITOR_BLOCK_MODE_FILE:
545             Warning(
546                 pJob->pPad,
547                 (char *) GETMESSAGE(14, 4, "File type error."),
548                 XmDIALOG_WARNING);
549             break;
550         case DtEDITOR_NULLS_REMOVED:
551             Warning(
552                 pJob->pPad,
553                 (char *) GETMESSAGE(14, 5, "File contains NULL characters."),
554                 XmDIALOG_WARNING);
555             break;
556         case DtEDITOR_INSUFFICIENT_MEMORY:
557             Warning(
558                 pJob->pPad,
559                 (char*)
560                 GETMESSAGE(14, 6, "Unable to load file (insufficient memory)."),
561                 XmDIALOG_ERROR);
562                 break;
563         case DtEDITOR_NO_FILE_ACCESS:
564         case DtEDITOR_UNREADABLE_FILE:
565         default:
566             Warning(
567                 pJob->pPad,
568                 (char *)
569                 GETMESSAGE(14, 7, "File does not have read permissions"),
570                 XmDIALOG_WARNING);
571             break;
572     }
573
574     XtRealizeWidget( pJob->pShell );
575
576     PrintOutputFirstPage(pJob->pOutput);
577     pJob->npagesTotal = PrintOutputGetNumLines(pJob->pOutput) +
578                         PrintOutputGetLinesPerPage(pJob->pOutput) - 1;
579     pJob->npagesTotal /= PrintOutputGetLinesPerPage(pJob->pOutput);
580     pJob->npagesDone = 0;
581 }
582
583
584
585
586 /************************************************************************
587  * _pjDoPrint
588  *      Actually run the specified PrintJob.
589  *      Creates the PrintOutput object to be used for printing.
590  *      Initializes the mailbox to iterate through the messages.
591  *      Calls spoolOne to send a print job to the Xp server.
592  ************************************************************************/
593 static void
594 _pjDoPrint(PrintJob *pJob)
595 {
596 #if 0 && defined(PRINTING_SUPPORTED)
597
598     static char         buf[1024];
599     static char         *format;
600     DtPrintSetupData    *psd = NULL;
601     int                 dest = XPSpool;
602
603     /*
604      * Notify the user that we're printing
605      */
606     if (pJob->pPad != NULL) {
607         pJob->pPad->numPendingTasks++;
608         format = GETMESSAGE(14, 21, "Printing %s ...");
609         sprintf(buf, format, pJob->documentName);
610         SetStatusMessage(pJob->pPad, buf);
611         XtSetSensitive(pJob->pPad->fileStuff.fileWidgets.printBtn, False);
612     }
613
614 #ifndef PRINT_TO_VIDEO
615     psd = pJob->printData;
616
617     if (psd->destination == DtPRINT_TO_FILE)
618       dest = XPGetData;
619
620     _pjRegisterActivePrintDisplay(XtDisplay(pJob->pShell));
621     XpStartJob(XtDisplay(pJob->pShell), dest);
622     XFlush(XtDisplay(pJob->pShell));
623
624     if (psd->destination == DtPRINT_TO_FILE)
625     {
626         if (FALSE == XmPrintToFile(
627                                 XtDisplay(pJob->pShell),
628                                 psd->dest_info,
629                                 _pjFinishedPrintToFile,
630                                 (XPointer) pJob))
631         {
632             char        *fmt = "%s\n%s:  %s";
633             char        *message;
634             char        *appmessage = NULL;
635             char        *sysmessage = strerror(errno);
636
637             appmessage = (char *) GETMESSAGE(
638                             14, 14,
639                             "'Print to File' was unsuccessful.");
640             
641             if (NULL == sysmessage)
642             {
643                 message = XtMalloc(strlen(appmessage) + 1);
644                 sprintf(message, "%s", appmessage);
645             }
646             else
647             {
648                 message = XtMalloc(
649                                 strlen(appmessage) +
650                                 strlen(sysmessage) +
651                                 strlen(psd->dest_info) +
652                                 strlen(fmt) + 1);
653                 sprintf(message, fmt, appmessage, psd->dest_info, sysmessage);
654             }
655             
656             Warning(pJob->pPad, message, XmDIALOG_WARNING);
657             XtFree(message);
658             
659             XpCancelJob(XtDisplay(pJob->pShell), False);
660             PrintJobDestroy(pJob);
661         }
662     }
663 #endif
664 #endif  /* PRINTING_SUPPORTED */
665
666
667 }
668
669 /************************************************************************
670  * _pjUpdatePageHeaders
671  *      Configures the header and footer string in the PrintOutput. 
672  ************************************************************************/
673 static void
674 _pjUpdatePageHeaders(
675                 PrintJob                *pJob,
676                 PrintStringTypeEnum     hl_type,
677                 PrintStringTypeEnum     hr_type,
678                 PrintStringTypeEnum     fl_type,
679                 PrintStringTypeEnum     fr_type
680                 )
681 {
682     char *hl_string,
683          *hr_string,
684          *fl_string,
685          *fr_string;
686
687     if (pJob == (PrintJob *) NULL) return;
688
689     hl_string = _pjGetPageHeaderString(pJob, hl_type);
690     hr_string = _pjGetPageHeaderString(pJob, hr_type);
691     fl_string = _pjGetPageHeaderString(pJob, fl_type);
692     fr_string = _pjGetPageHeaderString(pJob, fr_type);
693
694     if (PRINT_NONE_STRING_TYPE_ENUM == hl_type &&
695         PRINT_NONE_STRING_TYPE_ENUM == hr_type)
696       PrintOutputHideHeaders(pJob->pOutput);
697     else
698       PrintOutputShowHeaders(pJob->pOutput);
699
700     if (PRINT_NONE_STRING_TYPE_ENUM == fl_type &&
701         PRINT_NONE_STRING_TYPE_ENUM == fr_type)
702       PrintOutputHideFooters(pJob->pOutput);
703     else
704       PrintOutputShowFooters(pJob->pOutput);
705
706
707     PrintOutputSetHdrFtrStrings(
708                                 pJob->pOutput,
709                                 hl_string,
710                                 hr_string,
711                                 fl_string,
712                                 fr_string
713                                 );
714     free(hl_string);
715     free(hr_string);
716     free(fl_string);
717     free(fr_string);
718 }
719
720 /************************************************************************
721  * _pjGetPageHeaderString
722  *      Returns a header and footer string of the specified type.
723  ************************************************************************/
724 static char *
725 _pjGetPageHeaderString(PrintJob *pJob, PrintStringTypeEnum type)
726 {
727     char *format,
728          *buf = (char *) NULL;
729
730     switch (type)
731     {
732         case PRINT_NONE_STRING_TYPE_ENUM:
733             buf = strdup(" ");
734             break;
735         case PRINT_DATE_STRING_TYPE_ENUM:
736             {
737                 time_t  clock;
738                 char    *date;
739
740                 clock = time((time_t*) NULL);
741                 date = ctime(&clock);
742                 /* Strip off the trailing newline. */
743                 date[strlen(date)-1] = '\0';
744                 format = GETMESSAGE(14, 8, "Date:  %s");
745                 buf = (char *) malloc(strlen(format) + strlen(date) + 1);
746                 if (buf != (char *) NULL)
747                   sprintf(buf, format, date);
748             }
749             break;
750         case PRINT_DOCNAME_STRING_TYPE_ENUM:
751             {
752                 unsigned        buflen;
753
754                 format = GETMESSAGE(14, 9, "Document:  %s");
755                 buflen = strlen(format) + strlen(pJob->documentName) + 1;
756                 buf = (char *) malloc(buflen);
757                 if (buf != (char *) NULL)
758                   sprintf(buf, format, pJob->documentName);
759             }
760             break;
761         case PRINT_PAGE_NUMBER_STRING_TYPE_ENUM:
762             /*
763              * Allocate space for the format and the translated page number.
764              */
765             {
766                 format = GETMESSAGE(14, 10, "Page %d of %d");
767                 buf = (char *) malloc(strlen(format) + 16);
768                 if (buf != (char *) NULL)
769                   sprintf(buf, format, pJob->npagesDone, pJob->npagesTotal);
770             }
771             break;
772         case PRINT_USER_NAME_STRING_TYPE_ENUM:
773             /*
774              * Allocate space for the format and the username.
775              */
776             {
777                 struct passwd   *pw;
778
779                 format = GETMESSAGE(14, 11, "Document For:  %s");
780                 pw = getpwuid(getuid());
781                 buf = (char *) malloc(strlen(format) + strlen(pw->pw_name) + 1);
782                 if (buf != (char *) NULL)
783                   sprintf(buf, format, pw->pw_name);
784             }
785             break;
786         default:
787             buf = strdup("DEFAULT not impld");
788             break;
789     }
790     return buf;
791 }
792
793
794 /*
795  *
796  * Name: _pjFinishedPrintToFile
797  *
798  * Description:
799  *
800  *     App-specific print data holder allocate function.
801  *
802  */
803 #if 0 && defined(PRINTING_SUPPORTED)
804 static void _pjFinishedPrintToFile(
805                         Display         *display,
806                         XPContext       context,
807                         XPGetDocStatus  status,
808                         XPointer        client_data)
809 {
810     char        *message = NULL;
811     PrintJob    *pJob = (PrintJob *) client_data;
812     Editor      *pPad = pJob->pPad;
813
814     if (status != XPGetDocFinished)
815     {
816
817         message = (char *) GETMESSAGE(
818                                 14, 14,
819                                 "'Print to File' was unsuccessful.");
820         Warning(pPad, message, XmDIALOG_WARNING);
821     }
822     else if (display != PrintJobGetErrorPrintDisplay())
823     {
824
825         message = (char *) GETMESSAGE(
826                                 14, 15,
827                                 "'Print to File' completed successfully.");
828         Warning(pPad, message, XmDIALOG_INFORMATION);
829     }
830     PrintJobDestroy(pJob);
831 }
832 #endif /* PRINTING_SUPPORTED */
833
834
835 /*
836  * Name: _pjCancelCB
837  * Description:
838  *      An XtCallbackProc which can be added to the callback list of
839  *      a widget to cancel the print job passed back as client_data.
840  */
841 static void
842 _pjCancelCB (Widget widget, XtPointer client_data, XtPointer call_data)
843 {
844     PrintJob *pJob = (PrintJob *) client_data;
845
846     PrintJobDestroy(pJob);
847 }
848
849 /*
850  * Name: _pjCloseDisplayCB
851  * Description:
852  *      An XtCallbackProc which can be added to the callback list of
853  *      a widget to cancel the print job passed back as client_data.
854  */
855 static void
856 _pjCloseDisplayCB (Widget widget, XtPointer client_data, XtPointer call_data)
857 {
858     PrintJob *pJob = (PrintJob *) client_data;
859     DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct *) call_data;
860
861     if (pJob->pShell != NULL)
862     {
863         XtDestroyWidget(pJob->pShell);
864         pJob->pShell = NULL;
865     }
866     DtPrintFreeSetupData(pJob->printData);
867 }
868
869 /*
870  * Name: _pjPrintCB
871  * Description:
872  *      An XtCallbackProc which can be added to the callback list of
873  *      a widget to execute the print job passed back as client_data.
874  */
875 static void
876 _pjPrintCB (Widget widget, XtPointer client_data, XtPointer call_data)
877 {
878     PrintJob *pJob = (PrintJob *) client_data;
879     DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct *) call_data;
880
881     DtPrintCopySetupData(pJob->printData, pbs->print_data);
882     _pjCreatePrintShell(pJob);
883     _pjDoPrint(pJob);
884 }
885
886
887 /*
888  * Name: _pjPdmSetupCB
889  * Description:
890  *      An XtCallbackProc which can be added to the callback list of
891  *      a widget to popup the PDM for the print job.
892  */
893 static void
894 _pjPdmSetupCB(Widget print_setup, XtPointer client_data, XtPointer call_data)
895 {
896 #if 0 && defined(PRINTING_SUPPORTED)
897     char        *pname = "_pjPdmSetupCB";
898     PrintJob    *pJob = (PrintJob *) client_data;
899     DtPrintSetupCallbackStruct
900                 *pbs = (DtPrintSetupCallbackStruct *) call_data;
901
902     DtPrintCopySetupData(pJob->printData, pbs->print_data);
903     _pjCreatePrintShell(pJob);
904
905     /* Pop up the PDM */
906     if (pJob->pShell)
907     {
908         Widget  shell = print_setup;
909
910         while (! (shell == NULL || XtIsShell(shell)) )
911           shell = XtParent(shell);
912
913         if (shell)
914           XmPrintPopupPDM(pJob->pShell, shell);
915         else
916           fprintf(stderr, "Internal Error %s:  Missing XmPrintShell.", pname);
917     }
918 #endif  /* PRINTING_SUPPORTED */
919 }
920
921
922 /************************************************************************
923  * _pjPdmNotificationCB
924  *      XmNpdmNotificationCallback for the XmPrintShell
925  ************************************************************************/
926 static void
927 _pjPdmNotificationCB (Widget widget, XtPointer client_data, XtPointer call_data)
928 {
929 #if 0 && defined(PRINTING_SUPPORTED)
930     PrintJob                    *pJob = (PrintJob*) client_data;
931     XmPrintShellCallbackStruct  *pscbs = (XmPrintShellCallbackStruct*)call_data;
932     char                        *message = NULL;
933
934     switch (pscbs->reason)
935     {
936     
937         case XmCR_PDM_NONE:
938         case XmCR_PDM_START_ERROR:
939         case XmCR_PDM_START_VXAUTH:
940         case XmCR_PDM_START_PXAUTH:
941             message = (char *) GETMESSAGE(
942                         14, 25,
943                         "Print Dialog Manager error - setup failed.");
944             break;
945         default:
946             message = NULL;
947             break;
948     }
949
950     if (message != NULL)
951       Warning( pJob->pPad, message, XmDIALOG_WARNING);
952 #endif  /* PRINTING_SUPPORTED */
953 }
954
955
956
957 /************************************************************************
958  * _pjPrintOnePageCB
959  *      XmNpageSetupCallback for the XmPrintShell
960  ************************************************************************/
961 static void
962 _pjPrintOnePageCB(
963                 Widget widget,
964                 XtPointer client_data,
965                 XtPointer call_data
966                 )
967 {
968 #if 0 && defined(PRINTING_SUPPORTED)
969     PrintJob    *pJob = (PrintJob *) client_data;
970
971     XmPrintShellCallbackStruct  *pscbs = (XmPrintShellCallbackStruct*)call_data;
972     int                         top = 0;
973
974     if (pJob->pOutput == NULL)
975     {
976         XtArgVal        width0, height0;
977         Dimension       width, height;
978
979         width = 0; height=0;
980         XtVaGetValues(
981                 pJob->pShell,
982                 XmNwidth, &width0,
983                 XmNheight, &height0,
984                 NULL);
985         width = (Dimension)width0;
986         height = (Dimension)height0;
987
988 #if defined(PRINT_TO_VIDEO)
989         printf("PrintShell in _pjPrintOnePageCB: <W %d - H %d>\n",width,height);
990 #endif
991
992         if (width < 100 || height < 100)
993         {
994             width = 2550; height=3250;
995             XtVaSetValues(
996                 pJob->pShell,
997                 XmNwidth, width,
998                 XmNheight, height,
999                 NULL);
1000             width = 0; height=0;
1001             XtVaGetValues(
1002                 pJob->pShell,
1003                 XmNwidth, &width,
1004                 XmNheight, &height,
1005                 NULL);
1006 #if defined(PRINT_TO_VIDEO)
1007             printf(
1008               "PrintShell in _pjPrintOnePageCB: <W %d - H %d>\n",width,height);
1009 #endif
1010         }
1011         _pjCreateOutputWidgets(pJob);
1012     }
1013
1014 #ifdef PRINT_TO_VIDEO
1015     if (pJob->npagesDone > 0 && pJob->npagesDone == pJob->npagesTotal)
1016 #else
1017     if (pscbs->last_page)
1018 #endif
1019     {
1020         DtPrintSetupData    *psd = pJob->printData;
1021
1022         /*
1023          * This spool job is done.  Clean up.
1024          * If this is a print to file job,
1025          * clean up in the job finished callback.
1026          */
1027         if (psd->destination != DtPRINT_TO_FILE)
1028           PrintJobDestroy(pJob);
1029         return;
1030     }
1031
1032     if (pJob->npagesDone > 0 && PrintOutputPageDown(pJob->pOutput) == FALSE)
1033     {
1034 #ifndef PRINT_TO_VIDEO
1035         pscbs->last_page = TRUE;
1036 #endif
1037         return;
1038     }
1039
1040     /*
1041      * Update header and footer strings.
1042      */
1043     pJob->npagesDone++;
1044     _pjUpdatePageHeaders(
1045         pJob,
1046         PrintSetupGetHdrFtrSpec(pJob->pSetup, DTPRINT_OPTION_HEADER_LEFT),
1047         PrintSetupGetHdrFtrSpec(pJob->pSetup, DTPRINT_OPTION_HEADER_RIGHT),
1048         PrintSetupGetHdrFtrSpec(pJob->pSetup, DTPRINT_OPTION_FOOTER_LEFT),
1049         PrintSetupGetHdrFtrSpec(pJob->pSetup, DTPRINT_OPTION_FOOTER_RIGHT)
1050         );
1051
1052     /*
1053      * Notify the user that we're printing
1054      */
1055     if (pJob->pPad != NULL)
1056     {
1057         static char     buf[1024];
1058         char            *format;
1059
1060         format = GETMESSAGE(14, 22, "Printing %s: page %d of %d ...");
1061         sprintf(buf, format,
1062                 pJob->documentName,
1063                 pJob->npagesDone,
1064                 pJob->npagesTotal);
1065         SetStatusMessage(pJob->pPad, buf);
1066     }
1067
1068 #ifndef PRINT_TO_VIDEO
1069     if (pJob->npagesDone >= pJob->npagesTotal)
1070       pscbs->last_page = TRUE;
1071 #endif
1072
1073 #endif /* PRINTING_SUPPORTED */
1074 }