nsgmls: resolve coverity warnings related to uninitialed members in C++ classes
[oweals/cde.git] / cde / programs / dtpad / printOutput.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: printOutput.c /main/6 1997/07/07 15:06:25 mgreess $ */
24 /**********************************<+>*************************************
25 ***************************************************************************
26 **
27 **  File:        printOption.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 <stdio.h>
67 #include <string.h>
68 #include <assert.h>
69
70 #include <X11/Intrinsic.h>
71 #include <Xm/Xm.h>
72 #include <Xm/DialogS.h>
73 #include <Xm/Form.h>
74 #include <Xm/Label.h>
75 #if 0 && defined(PRINTING_SUPPORTED)
76 #include <Xm/Print.h>
77 #endif /* PRINTING_SUPPORTED */
78 #include <Xm/Text.h>
79 #include <Dt/Editor.h>
80
81 #include "dtpad.h"
82
83 #define READ_ACCESS     1
84 #define WRITE_ACCESS    2
85
86 static void     _poSetInnerPageDimensions(
87                                 PrintOutput*,
88                                 Dimension,
89                                 Dimension,
90                                 Dimension,
91                                 Dimension
92                                 );
93 static int      _poDoGetLinesPerPage(PrintOutput*);
94 static int      _poGetTopPosition(PrintOutput *pOutput);
95 static DtEditorErrorCode
96                 _poGetFileContents(char **contents, char *file);
97 static DtEditorErrorCode 
98                 _poStripEmbeddedNulls(char *strbuf, int *len);
99 extern DtEditorErrorCode
100                 _poEditorValidateFileAccess(char *file, int accessType);
101
102 /*
103  * Used to initialize the top, right, bottom, and left margins
104  * between the outside edge of the page (_form) and the inner
105  * page that is written on.
106  */
107 const char *const _poDefaultMargin = ".5in";
108
109 /************************************************************************
110  * PrintOutputCreate
111  *      Creates and initialiazes a new PrintOutput output including the
112  *      widget hierarchy.
113  ************************************************************************/
114 PrintOutput*
115 PrintOutputCreate(Widget shell)
116 {
117     Widget              w;
118     Boolean             parseError;
119     PrintOutput         *pOutput;
120
121     pOutput = (PrintOutput *) XtMalloc(sizeof(PrintOutput));
122     pOutput->pShell = shell;
123
124     pOutput->currentLine = 0;
125     pOutput->linesPerPage = 0;
126
127     w = XtVaCreateWidget("Page",
128                           xmFormWidgetClass,
129                           pOutput->pShell,
130                           XmNresizePolicy, XmRESIZE_NONE,
131                           NULL);
132     pOutput->page = w;
133                  
134     w = XtVaCreateWidget("InnerPage",
135                           xmFormWidgetClass,
136                           pOutput->page,
137                           XmNresizePolicy, XmRESIZE_NONE,
138                           NULL);
139     pOutput->innerPage = w;
140                  
141     w = XtVaCreateManagedWidget("HeaderLeft",
142                                   xmLabelWidgetClass,
143                                   pOutput->innerPage,
144                                   XmNalignment, XmALIGNMENT_BEGINNING,
145                                   XmNleftAttachment, XmATTACH_FORM,
146                                   XmNtopAttachment, XmATTACH_FORM,
147                                   NULL);
148     pOutput->headerLeft = w;
149
150     w = XtVaCreateManagedWidget("HeaderRight",
151                                   xmLabelWidgetClass,
152                                   pOutput->innerPage,
153                                   XmNalignment, XmALIGNMENT_END,
154                                   XmNrightAttachment, XmATTACH_FORM,
155                                   XmNleftAttachment, XmATTACH_WIDGET,
156                                   XmNleftWidget, pOutput->headerLeft,
157                                   XmNtopAttachment, XmATTACH_FORM,
158                                   NULL);
159     pOutput->headerRight = w;
160                  
161     w = XtVaCreateManagedWidget("Editor",
162 #ifdef USE_DTEDITOR
163                                   dtEditorWidgetClass,
164 #else
165                                   xmTextWidgetClass,
166 #endif
167                                   pOutput->innerPage,
168                                   DtNscrollVertical, FALSE,
169                                   DtNscrollHorizontal, FALSE,
170                                   DtNshowStatusLine, FALSE,
171                                   DtNwordWrap, TRUE,
172                                   XmNeditMode, XmMULTI_LINE_EDIT,
173                                   XmNleftAttachment, XmATTACH_FORM,
174                                   XmNrightAttachment, XmATTACH_FORM,
175                                   XmNtopAttachment, XmATTACH_WIDGET,
176                                   XmNtopWidget, pOutput->headerLeft,
177                                   NULL);
178     pOutput->editor = w;
179                  
180     w = XtVaCreateManagedWidget("FooterLeft",
181                                   xmLabelWidgetClass,
182                                   pOutput->innerPage,
183                                   XmNalignment, XmALIGNMENT_BEGINNING,
184                                   XmNleftAttachment, XmATTACH_FORM,
185                                   XmNbottomAttachment, XmATTACH_FORM,
186                                   NULL);
187     pOutput->footerLeft = w;
188
189     w = XtVaCreateManagedWidget("FooterRight",
190                                   xmLabelWidgetClass,
191                                   pOutput->innerPage,
192                                   XmNalignment, XmALIGNMENT_END,
193                                   XmNleftAttachment, XmATTACH_WIDGET,
194                                   XmNleftWidget, pOutput->footerLeft,
195                                   XmNrightAttachment, XmATTACH_FORM,
196                                   XmNbottomAttachment, XmATTACH_FORM,
197                                   NULL);
198     pOutput->footerRight = w;
199
200     XtVaSetValues(
201                 pOutput->editor,
202                 XmNbottomAttachment, XmATTACH_WIDGET,
203                 XmNbottomWidget, pOutput->footerLeft,
204                 NULL);
205
206     XtManageChild(pOutput->innerPage);
207     XtManageChild(pOutput->page);
208
209     PrintOutputSetPageMargins(
210                 pOutput,
211                 _poDefaultMargin,
212                 _poDefaultMargin,
213                 _poDefaultMargin,
214                 _poDefaultMargin,
215                 &parseError );
216     assert(parseError == 0);
217
218     return pOutput;
219 }
220
221 /************************************************************************
222  * PrintOutputCreate
223  *      Class destructor.
224  ************************************************************************/
225 void
226 PrintOutputDestroy(PrintOutput *pOutput)
227 {
228     if (pOutput == NULL) return;
229     XtDestroyWidget(pOutput->page);
230     XtFree((char*) pOutput);
231 }
232
233 /************************************************************************
234  * PrintOutputHideFooter
235  * PrintOutputShowFooter
236  * PrintOutputHideHeader
237  * PrintOutputShowHeader
238  *      Unmanages/Manages the footer/header widgets
239  ************************************************************************/
240 void
241 PrintOutputHideFooters(PrintOutput *pOutput)
242 {
243     XtUnmanageChild(pOutput->footerLeft);
244     XtUnmanageChild(pOutput->footerRight);
245     XtVaSetValues(pOutput->editor, XmNbottomAttachment, XmATTACH_FORM, NULL);
246 }
247
248 void
249 PrintOutputShowFooters(PrintOutput *pOutput)
250 {
251     XtManageChild(pOutput->footerLeft);
252     XtManageChild(pOutput->footerRight);
253     XtVaSetValues(
254                 pOutput->editor,
255                 XmNbottomAttachment, XmATTACH_WIDGET,
256                 XmNbottomWidget, pOutput->footerLeft,
257                 NULL);
258 }
259
260 void
261 PrintOutputHideHeaders(PrintOutput *pOutput)
262 {
263     XtUnmanageChild(pOutput->headerLeft);
264     XtUnmanageChild(pOutput->headerRight);
265     XtVaSetValues(pOutput->editor, XmNtopAttachment, XmATTACH_FORM, NULL);
266 }
267
268 void
269 PrintOutputShowHeaders(PrintOutput *pOutput)
270 {
271     XtManageChild(pOutput->headerLeft);
272     XtManageChild(pOutput->headerRight);
273     XtVaSetValues(
274                 pOutput->editor,
275                 XmNtopAttachment, XmATTACH_WIDGET,
276                 XmNtopWidget, pOutput->headerLeft,
277                 NULL);
278 }
279
280 /************************************************************************
281  * PrintOutputSetHdrFtrString
282  *      Set the contents of the specifies header/footer
283  ************************************************************************/
284 void
285 PrintOutputSetHdrFtrString(
286                         PrintOutput *pOutput,
287                         _DtPrintHdrFtrEnum which,
288                         char *contents
289                         )
290 {
291     Widget      w;
292     XmString    xms;
293
294     if (contents == (char *) NULL)
295       return;
296
297     switch (which)
298     {
299         case DTPRINT_OPTION_HEADER_LEFT:
300           w = pOutput->headerLeft;
301           break;
302         case DTPRINT_OPTION_HEADER_RIGHT:
303           w = pOutput->headerRight;
304           break;
305         case DTPRINT_OPTION_FOOTER_LEFT:
306           w = pOutput->footerLeft;
307           break;
308         case DTPRINT_OPTION_FOOTER_RIGHT:
309           w = pOutput->footerRight;
310           break;
311         default:
312           return;
313     }
314
315     xms = XmStringCreateLocalized(contents);
316     XtVaSetValues(w, XmNlabelString, xms, NULL);
317     XmStringFree(xms);
318 }
319
320 /************************************************************************
321  * PrintOutputSetHdrFtrStrings
322  *      Set the contents of all the header/footers
323  ************************************************************************/
324 void
325 PrintOutputSetHdrFtrStrings(
326                         PrintOutput *pOutput,
327                         char *hdrLeft,
328                         char *hdrRight,
329                         char *ftrLeft,
330                         char *ftrRight
331                         )
332 {
333     XmString    xms;
334
335     if (hdrLeft)
336     {
337         xms = XmStringCreateLocalized(hdrLeft);
338         XtVaSetValues(pOutput->headerLeft, XmNlabelString, xms, NULL);
339         XmStringFree(xms);
340     }
341
342     if (hdrRight)
343     {
344         xms = XmStringCreateLocalized(hdrRight);
345         XtVaSetValues(pOutput->headerRight, XmNlabelString, xms, NULL);
346         XmStringFree(xms);
347     }
348
349     if (ftrLeft)
350     {
351         xms = XmStringCreateLocalized(ftrLeft);
352         XtVaSetValues(pOutput->footerLeft, XmNlabelString, xms, NULL);
353         XmStringFree(xms);
354     }
355
356     if (ftrRight)
357     {
358         xms = XmStringCreateLocalized(ftrRight);
359         XtVaSetValues(pOutput->footerRight, XmNlabelString, xms, NULL);
360         XmStringFree(xms);
361     }
362 }
363
364 /************************************************************************
365  * PrintOutputSetPageMargin
366  *      Set the contents of the specified page margin
367  ************************************************************************/
368 void
369 PrintOutputSetPageMargin(
370                         PrintOutput *pOutput,
371                         _DtPrintMarginEnum which,
372                         const char *margin,
373                         Boolean *parseError
374                         )
375 {
376     int         pixels = 0;
377     XtEnum      xtParseError = FALSE;
378     char        *marginString = XtNewString(margin);
379
380     if (parseError)
381       *parseError = FALSE;
382
383     switch (which)
384     {
385         case DTPRINT_OPTION_MARGIN_TOP:
386           pixels = XmConvertStringToUnits(
387                                         XtScreenOfObject(pOutput->pShell),
388                                         marginString,
389                                         XmVERTICAL,
390                                         XmPIXELS,
391                                         &xtParseError);
392           if (!xtParseError && pixels > 0)
393             pOutput->marginTop = pixels;
394           break;
395         case DTPRINT_OPTION_MARGIN_RIGHT:
396           pixels = XmConvertStringToUnits(
397                                         XtScreenOfObject(pOutput->pShell),
398                                         marginString,
399                                         XmHORIZONTAL,
400                                         XmPIXELS,
401                                         &xtParseError);
402           if (!xtParseError && pixels > 0)
403             pOutput->marginRight = pixels;
404           break;
405         case DTPRINT_OPTION_MARGIN_BOTTOM:
406           pixels = XmConvertStringToUnits(
407                                         XtScreenOfObject(pOutput->pShell),
408                                         marginString,
409                                         XmVERTICAL,
410                                         XmPIXELS,
411                                         &xtParseError);
412           if (!xtParseError && pixels > 0)
413             pOutput->marginBottom = pixels;
414           break;
415         case DTPRINT_OPTION_MARGIN_LEFT:
416           pixels = XmConvertStringToUnits(
417                                         XtScreenOfObject(pOutput->pShell),
418                                         marginString,
419                                         XmHORIZONTAL,
420                                         XmPIXELS,
421                                         &xtParseError);
422           if (!xtParseError && pixels > 0)
423             pOutput->marginLeft = pixels;
424           break;
425         default:
426           return;
427     }
428
429     if (!xtParseError)
430       _poSetInnerPageDimensions(
431                         pOutput,
432                         pOutput->marginTop,
433                         pOutput->marginRight,
434                         pOutput->marginBottom,
435                         pOutput->marginLeft);
436     else
437       *parseError = TRUE;
438
439     XtFree(marginString);
440 }
441
442 /************************************************************************
443  * PrintOutputSetPageMargins
444  *      Set the contents of all the page margins
445  ************************************************************************/
446 void
447 PrintOutputSetPageMargins(
448                         PrintOutput *pOutput,
449                         const char *top,
450                         const char *right,
451                         const char *bottom,
452                         const char *left,
453                         Boolean *parseError
454                         )
455 {
456     int         pixels = 0;
457     XtEnum      xtParseError = FALSE;
458     char        *margin;
459
460     *parseError = FALSE;
461
462     margin = XtNewString(top);
463     pixels = XmConvertStringToUnits(
464                                 XtScreenOfObject(pOutput->pShell),
465                                 margin,
466                                 XmVERTICAL,
467                                 XmPIXELS,
468                                 &xtParseError);
469     XtFree(margin);
470     if (!xtParseError && pixels > 0)
471     {
472         pOutput->marginTop = pixels;
473     }
474     else
475     {    
476         *parseError = TRUE;
477         return;
478     }
479
480     margin = XtNewString(right);
481     pixels = XmConvertStringToUnits(
482                                 XtScreenOfObject(pOutput->pShell),
483                                 margin,
484                                 XmHORIZONTAL,
485                                 XmPIXELS,
486                                 &xtParseError);
487     XtFree(margin);
488     if (!xtParseError && pixels > 0)
489     {
490         pOutput->marginRight = pixels;
491     }
492     else
493     {    
494         *parseError = TRUE;
495         return;
496     }
497
498     margin = XtNewString(bottom);
499     pixels = XmConvertStringToUnits(
500                                 XtScreenOfObject(pOutput->pShell),
501                                 margin,
502                                 XmVERTICAL,
503                                 XmPIXELS,
504                                 &xtParseError);
505     XtFree(margin);
506     if (!xtParseError && pixels > 0)
507     {
508         pOutput->marginBottom = pixels;
509     }
510     else
511     {    
512         *parseError = TRUE;
513         return;
514     }
515
516     margin = XtNewString(left);
517     pixels = XmConvertStringToUnits(
518                                 XtScreenOfObject(pOutput->pShell),
519                                 margin,
520                                 XmHORIZONTAL,
521                                 XmPIXELS,
522                                 &xtParseError);
523     XtFree(margin);
524     if (!xtParseError && pixels > 0)
525     {
526         pOutput->marginLeft = pixels;
527     }
528     else
529     {    
530         *parseError = TRUE;
531         return;
532     }
533
534     _poSetInnerPageDimensions(
535                         pOutput,
536                         pOutput->marginTop,
537                         pOutput->marginRight,
538                         pOutput->marginBottom,
539                         pOutput->marginLeft);
540 }
541
542
543 /************************************************************************
544  * PrintOutputSetWordWrap
545  *      Set the wrap to fit value in the editor
546  ************************************************************************/
547 void
548 PrintOutputSetWordWrap(PrintOutput *pOutput, Boolean onoff)
549 {
550 #ifdef USE_DTEDITOR
551     XtVaSetValues(pOutput->editor, DtNwordWrap, onoff, NULL);
552 #else
553     XtVaSetValues(pOutput->editor, XmNwordWrap, onoff, NULL);
554 #endif
555 }
556
557 /************************************************************************
558  * PrintOutputGetLinesPerPage
559  *      Returns the number of lines per page.
560  ************************************************************************/
561 int
562 PrintOutputGetLinesPerPage(PrintOutput *pOutput)
563 {
564     return ((int) pOutput->linesPerPage);
565 }
566
567 /************************************************************************
568  * PrintOutputGetNumLines
569  *      Returns the number of lines of test in the editor.
570  ************************************************************************/
571 int
572 PrintOutputGetNumLines(PrintOutput *pOutput)
573 {
574     XtArgVal p;
575     int total = 0;
576     int saveTop;
577
578 #ifdef USE_DTEDITOR
579     saveTop = pOutput->currentLine;
580     PrintOutputFirstPage(pOutput);
581     while (PrintOutputPageDown(pOutput))
582       total += pOutput->linesPerPage;
583
584     DtEditorGoToLine(pOutput->editor, saveTop);
585     pOutput->currentLine = saveTop;
586 #else
587     XtVaGetValues(pOutput->editor, XmNtotalLines, &p, NULL);
588     total = (int)p;
589 #endif
590     return(total);
591 }
592
593 /************************************************************************
594  * PrintOutputPageUp
595  ************************************************************************/
596 Boolean
597 PrintOutputPageUp(PrintOutput *pOutput)
598 {
599     XmTextPosition      top_before, top_after;
600     Boolean             retval;
601
602 #ifdef USE_DTEDITOR
603     DtEditorGoToLine(
604                 pOutput->editor,
605                 pOutput->currentLine - pOutput->linesPerPage
606                 );
607     pOutput->currentLine -= pOutput->linesPerPage;
608     if (pOutput->currentLine < 1)
609     {
610         pOutput->currentLine = 1;
611         retval = FALSE;
612     }
613 #else
614     top_before = (XmTextPosition) _poGetTopPosition(pOutput);
615     XmTextScroll(pOutput->editor, -1 * pOutput->linesPerPage);
616     top_after = (XmTextPosition) _poGetTopPosition(pOutput);
617     retval = (top_before > top_after) ? TRUE : FALSE;
618 #endif
619
620     return retval;
621 }
622
623 /************************************************************************
624  * PrintOutputPageDown
625  ************************************************************************/
626 Boolean
627 PrintOutputPageDown(PrintOutput *pOutput)
628 {
629     XmTextPosition      top_before, top_after;
630
631     top_before = (XmTextPosition) _poGetTopPosition(pOutput);
632
633 #ifdef USE_DTEDITOR
634     DtEditorGoToLine(
635                 pOutput->editor,
636                 pOutput->currentLine + pOutput->linesPerPage
637                 );
638     pOutput->currentLine += pOutput->linesPerPage;
639 #else
640     XmTextScroll(pOutput->editor, pOutput->linesPerPage);
641 #endif
642
643     top_after = (XmTextPosition) _poGetTopPosition(pOutput);
644     return (top_before < top_after) ? TRUE : FALSE;
645 }
646
647 /************************************************************************
648  * PrintOutputFirstPage
649  ************************************************************************/
650 void
651 PrintOutputFirstPage(PrintOutput *pOutput)
652 {
653 #ifdef USE_DTEDITOR
654     XtVaSetValues(pOutput->editor, DtNtopCharacter, (XmTextPosition) 0, NULL);
655     pOutput->currentLine = 1;
656 #else
657     XmTextSetTopCharacter(pOutput->editor, (XmTextPosition) 0);
658 #endif
659 }
660
661 /************************************************************************
662  * PrintOutputLoadFile
663  ************************************************************************/
664 DtEditorErrorCode
665 PrintOutputLoadFile( PrintOutput *pOutput, char *file)
666 {
667     char                *contents = NULL;
668     DtEditorErrorCode   errorCode;
669
670 #ifdef USE_DTEDITOR
671     errorCode = DtEditorSetContentsFromFile(pOutput->editor, file);
672 #else
673     errorCode = _poGetFileContents(&contents, file);
674     if (contents != NULL)
675     {
676         XmTextSetString(pOutput->editor, contents);
677         free(contents);
678     }
679 #endif
680
681     return errorCode;
682 }
683
684 /************************************************************************
685  ************************************************************************
686  *
687  * Private class methods
688  *
689  *     _poDoGetLinesPerPage     - Returns number of rows in the editor.
690  *     _poSetInnerPageDimensions- Sets the XmN x,y,width,height of InnerPage.
691  *     _poGetTopPosition        - Returns the position of the 1st visible char.
692  *     _poGetFileContents       - Returns the contents of the specified file.
693  *     _poStripEmbeddedNulls    - Removes any embedded NULLs (\0) in a
694  *                                string of length 'length'.  The removal
695  *                                occurs in place, with 'length' set to the
696  *                                new, stripped length.  The resulting string
697  *                                is terminated with a trailing NULL.  
698  * 
699  ************************************************************************
700  ************************************************************************/
701
702 static int
703 _poDoGetLinesPerPage(PrintOutput *pOutput)
704 {
705     XtArgVal   lpp;
706
707     XtVaGetValues(pOutput->editor, XmNrows, &lpp, NULL);
708     return ((int) lpp);
709 }
710
711
712 static void
713 _poSetInnerPageDimensions(
714                         PrintOutput *pOutput,
715                         Dimension top,
716                         Dimension right,
717                         Dimension bottom,
718                         Dimension left
719                         )
720 {
721     XtArgVal    outer_height0, outer_width0, footer_height0, header_height0;
722     Dimension   inner_height, inner_width, inner_x, inner_y,
723                 outer_height, outer_width,
724                 editor_height, footer_height, header_height;
725
726     XtVaGetValues(pOutput->page,
727                   XmNheight, &outer_height0,
728                   XmNwidth, &outer_width0,
729                   NULL);
730
731     XtVaGetValues(pOutput->headerLeft,
732                   XmNheight, &header_height0,
733                   NULL);
734
735     XtVaGetValues(pOutput->footerLeft,
736                   XmNheight, &footer_height0,
737                   NULL);
738
739     outer_height = (Dimension)outer_height0;
740     outer_width = (Dimension)outer_width0;
741     header_height = (Dimension)header_height0;
742     footer_height = (Dimension)footer_height0;
743
744     inner_x = left;
745     inner_y = top;
746     inner_height = (outer_height > (Dimension) (top + bottom)) ?
747                         (outer_height - (top +  bottom)) :
748                         outer_height;
749     inner_width = (outer_width > (Dimension) (left + right)) ?
750                         (outer_width - (left + right)) :
751                         outer_width;
752     editor_height =
753                 (inner_height > (Dimension) (header_height + footer_height)) ?
754                         (inner_height - (header_height + footer_height)) :
755                         inner_height;
756     
757     XtVaSetValues(pOutput->editor, XmNheight, editor_height, NULL);
758
759     XtVaSetValues(pOutput->innerPage,
760                 XmNleftAttachment, XmATTACH_NONE,
761                 XmNtopAttachment, XmATTACH_NONE,
762                 XmNx, inner_x,
763                 XmNy, inner_y,
764                 XmNheight, inner_height,
765                 XmNwidth, inner_width,
766                 NULL);
767
768     pOutput->linesPerPage = _poDoGetLinesPerPage(pOutput);
769 }
770
771 /*
772  * _poGetTopPosition
773  */
774 static int
775 _poGetTopPosition(PrintOutput *pOutput)
776 {
777     XmTextPosition top = (XmTextPosition) 0;
778
779 #ifdef USE_DTEDITOR
780     XtVaGetValues(pOutput->editor, DtNtopCharacter, &top, NULL);
781 #else
782     top = XmTextGetTopCharacter(pOutput->editor);
783 #endif
784     return (int) top;
785 }
786
787 static DtEditorErrorCode
788 _poGetFileContents(char **contents, char *file)
789 {
790     DtEditorErrorCode   error = DtEDITOR_NO_ERRORS;
791     struct stat         statbuf;
792     char                *buf;
793     int                 nbytes;
794     FILE                *fp = NULL;
795
796     if (file == NULL || *file == '\0') return
797
798     /*
799      * Open the file for reading.
800      */
801     error = _poEditorValidateFileAccess(file, READ_ACCESS);
802     if (error != DtEDITOR_NO_ERRORS) return error;
803
804     if( (fp = fopen(file, "r")) == NULL )
805       return DtEDITOR_UNREADABLE_FILE;
806
807     if(stat(file, &statbuf) == -1) {
808       fclose(fp);
809       return DtEDITOR_UNREADABLE_FILE;
810     }
811     nbytes = statbuf.st_size;
812
813     /* 
814      * Read the file contents (with room for null) & convert to a
815      * string.  We want to use a string because the 
816      * DtEditorSetContents/Append/Insert/... functions create another 
817      * copy of the data before actually putting it into the widget.
818      */
819     buf = (char *) malloc(nbytes + 1);
820     if (buf == NULL) {
821           fclose(fp);
822       return DtEDITOR_INSUFFICIENT_MEMORY;
823     }
824
825     nbytes = fread(buf, sizeof(char), nbytes, fp);
826     buf[nbytes] = '\0';
827
828     /* 
829      * Strip out any embedded NULLs because the text widget will only 
830      * accept data up to the first NULL.
831      */
832     error = _poStripEmbeddedNulls(buf, &nbytes);
833
834     /* Close the file */
835     fclose(fp);
836
837     *contents = buf;
838     return error;
839 } /* end LoadFile */
840
841 static DtEditorErrorCode 
842 _poStripEmbeddedNulls(char *strbuf, int *len)
843 {
844     DtEditorErrorCode retval = DtEDITOR_NO_ERRORS;
845
846     if (strlen(strbuf) != *len)
847     {
848        int firstNull;
849
850        retval = DtEDITOR_NULLS_REMOVED;
851
852        /*
853         * The file contains NULL characters, so we strip them out and
854         * report that we have done so.
855         */
856        while((firstNull = strlen(strbuf)) != *len)
857        {
858           int lastNull = firstNull;
859
860           while((lastNull+1) < *len && strbuf[lastNull+1] == (char)'\0')
861             lastNull++;
862
863           memcpy(&strbuf[firstNull], &strbuf[lastNull+1], *len-lastNull);
864           *len -= 1 + lastNull - firstNull;
865        }
866     }
867
868     return retval;
869 }
870
871 extern DtEditorErrorCode
872 _poEditorValidateFileAccess( char *file, int accessType )
873 {
874    struct stat statbuf;
875    unsigned short tmpMode;
876
877    if (file && *file ) return DtEDITOR_INVALID_FILENAME;
878
879    if (access(file, F_OK) != 0) return DtEDITOR_NONEXISTENT_FILE; 
880
881    if( stat(file, &statbuf) != 0 ) return DtEDITOR_NO_FILE_ACCESS;
882
883    if( (statbuf.st_mode & S_IFMT) == S_IFDIR ) return DtEDITOR_DIRECTORY;
884
885    if( (statbuf.st_mode & S_IFMT) == S_IFCHR ) return DtEDITOR_CHAR_SPECIAL_FILE;
886
887    if((statbuf.st_mode & S_IFMT) == S_IFBLK) return DtEDITOR_BLOCK_MODE_FILE;
888
889    switch( accessType )
890    {
891       case READ_ACCESS:
892         if (access(file, R_OK) != 0) return DtEDITOR_UNREADABLE_FILE;
893         break;
894       case WRITE_ACCESS:
895         if (access(file, W_OK) != 0) return DtEDITOR_UNWRITABLE_FILE;
896         break;
897       default:
898         break;
899    } /* end stat suceeded */
900
901    return DtEDITOR_NO_ERRORS;
902 }