Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtmail / dtmail / DmxPrintOutput.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: DmxPrintOutput.C /main/6 1997/07/07 13:57:21 mgreess $ */
24
25 /*
26  *+SNOTICE
27  *
28  *      $:$
29  *
30  *      RESTRICTED CONFIDENTIAL INFORMATION:
31  *      
32  *      The information in this document is subject to special
33  *      restrictions in a confidential disclosure agreement between
34  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
35  *      document outside HP, IBM, Sun, USL, SCO, or Univel without
36  *      Sun's specific written approval.  This document and all copies
37  *      and derivative works thereof must be returned or destroyed at
38  *      Sun's request.
39  *
40  *      Copyright 1994 Sun Microsystems, Inc.  All rights reserved.
41  *
42  *+ENOTICE
43  */
44 /*
45  *                   Common Desktop Environment
46  *
47  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
48  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
49  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
50  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
51  *   (c) Copyright 1995 Digital Equipment Corp.
52  *   (c) Copyright 1995 Fujitsu Limited
53  *   (c) Copyright 1995 Hitachi, Ltd.
54  *                                                                   
55  *
56  *                     RESTRICTED RIGHTS LEGEND                              
57  *
58  *Use, duplication, or disclosure by the U.S. Government is subject to
59  *restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
60  *Technical Data and Computer Software clause in DFARS 252.227-7013.  Rights
61  *for non-DOD U.S. Government Departments and Agencies are as set forth in
62  *FAR 52.227-19(c)(1,2).
63
64  *Hewlett-Packard Company, 3000 Hanover Street, Palo Alto, CA 94304 U.S.A.
65  *International Business Machines Corp., Route 100, Somers, NY 10589 U.S.A. 
66  *Sun Microsystems, Inc., 2550 Garcia Avenue, Mountain View, CA 94043 U.S.A.
67  *Novell, Inc., 190 River Road, Summit, NJ 07901 U.S.A.
68  *Digital Equipment Corp., 111 Powdermill Road, Maynard, MA 01754, U.S.A.
69  *Fujitsu Limited, 1015, Kamikodanaka Nakahara-Ku, Kawasaki 211, Japan
70  *Hitachi, Ltd., 6, Kanda Surugadai 4-Chome, Chiyoda-ku, Tokyo 101, Japan
71  */
72
73
74 #include <stdio.h>
75 #include <X11/Intrinsic.h>
76 #include <Xm/Xm.h>
77 #include <Xm/DialogS.h>
78 #include <Xm/Form.h>
79 #include <Xm/Label.h>
80 #include <Xm/Print.h>
81 #include <Xm/Text.h>
82 #include <Dt/Editor.h>
83
84 #include "Dmx.h"
85 #include "DmxPrintOutput.h"
86 #include "RoamMenuWindow.h"
87
88 //
89 // Used to initialize the top, right, bottom, and left margins
90 // between the outside edge of the page (_form) and the inner
91 // page that is written on.
92 //
93 const char *const DmxPrintOutput::_default_margin = ".5in";
94
95 DmxPrintOutput::DmxPrintOutput (
96                                 Widget pshell
97                                 ) : UIComponent( "PrintOutput" )
98 {
99     Widget              w;
100     DtMailBoolean       parse_error;
101
102     _w = NULL;
103     _pshell = pshell;
104
105     w = XtVaCreateWidget("Page",
106                         xmFormWidgetClass,
107                         _pshell,
108                         XmNresizePolicy, XmRESIZE_NONE,
109                         NULL);
110     _form = w;
111     _w = _form;
112                  
113     w = XtVaCreateWidget("InnerPage",
114                         xmFormWidgetClass,
115                         _form,
116                         XmNresizePolicy, XmRESIZE_NONE,
117                         NULL);
118     _inner_form = w;
119                  
120     w = XtVaCreateManagedWidget("HeaderLeft",
121                                   xmLabelWidgetClass,
122                                   _inner_form,
123                                   XmNalignment, XmALIGNMENT_BEGINNING,
124                                   XmNleftAttachment, XmATTACH_FORM,
125                                   XmNtopAttachment, XmATTACH_FORM,
126                                   NULL);
127     _header_left = w;
128
129     w = XtVaCreateManagedWidget("HeaderRight",
130                                   xmLabelWidgetClass,
131                                   _inner_form,
132                                   XmNalignment, XmALIGNMENT_END,
133                                   XmNrightAttachment, XmATTACH_FORM,
134                                   XmNleftAttachment, XmATTACH_WIDGET,
135                                   XmNleftWidget, _header_left,
136                                   XmNtopAttachment, XmATTACH_FORM,
137                                   NULL);
138     _header_right = w;
139                  
140     w = XtVaCreateManagedWidget("Editor",
141 #ifdef USE_DTEDITOR
142                                   dtEditorWidgetClass,
143 #else
144                                   xmTextWidgetClass,
145 #endif
146                                   _inner_form,
147                                   DtNscrollVertical, FALSE,
148                                   DtNscrollHorizontal, FALSE,
149                                   DtNshowStatusLine, FALSE,
150                                   DtNwordWrap, TRUE,
151                                   XmNeditMode, XmMULTI_LINE_EDIT,
152                                   XmNleftAttachment, XmATTACH_FORM,
153                                   XmNrightAttachment, XmATTACH_FORM,
154                                   XmNtopAttachment, XmATTACH_WIDGET,
155                                   XmNtopWidget, _header_left,
156                                   NULL);
157     _editor = w;
158                  
159     w = XtVaCreateManagedWidget("FooterLeft",
160                                   xmLabelWidgetClass,
161                                   _inner_form,
162                                   XmNalignment, XmALIGNMENT_BEGINNING,
163                                   XmNleftAttachment, XmATTACH_FORM,
164                                   XmNbottomAttachment, XmATTACH_FORM,
165                                   NULL);
166     _footer_left = w;
167
168     w = XtVaCreateManagedWidget("FooterRight",
169                                   xmLabelWidgetClass,
170                                   _inner_form,
171                                   XmNalignment, XmALIGNMENT_END,
172                                   XmNleftAttachment, XmATTACH_WIDGET,
173                                   XmNleftWidget, _footer_left,
174                                   XmNrightAttachment, XmATTACH_FORM,
175                                   XmNbottomAttachment, XmATTACH_FORM,
176                                   NULL);
177     _footer_right = w;
178
179     XtVaSetValues(
180                 _editor,
181                 XmNbottomAttachment, XmATTACH_WIDGET,
182                 XmNbottomWidget, _footer_left,
183                 NULL);
184
185     installDestroyHandler();
186     XtManageChild(_inner_form);
187     XtManageChild(_form);
188
189     setPageMargins(
190                 _default_margin,
191                 _default_margin,
192                 _default_margin,
193                 _default_margin,
194                 &parse_error );
195     assert(!parse_error);
196 }
197
198 DmxPrintOutput::~DmxPrintOutput (void)
199 {
200     //
201     //  Don't destroy anything here.
202     //  The BasicComponent class takes care of destroying
203     //  the _form widget.
204     //
205 }
206
207 void DmxPrintOutput::hideFooters (void)
208 {
209     XtUnmanageChild(_footer_left);
210     XtUnmanageChild(_footer_right);
211     XtVaSetValues(_editor, XmNbottomAttachment, XmATTACH_FORM, NULL);
212 }
213
214 void DmxPrintOutput::showFooters (void)
215 {
216     XtManageChild(_footer_left);
217     XtManageChild(_footer_right);
218     XtVaSetValues(
219                 _editor,
220                 XmNbottomAttachment, XmATTACH_WIDGET,
221                 XmNbottomWidget, _footer_left,
222                 NULL);
223 }
224
225 void DmxPrintOutput::hideHeaders (void)
226 {
227     XtUnmanageChild(_header_left);
228     XtUnmanageChild(_header_right);
229     XtVaSetValues(_editor, XmNtopAttachment, XmATTACH_FORM, NULL);
230 }
231
232 void DmxPrintOutput::showHeaders (void)
233 {
234     XtManageChild(_header_left);
235     XtManageChild(_header_right);
236     XtVaSetValues(
237                 _editor,
238                 XmNtopAttachment, XmATTACH_WIDGET,
239                 XmNtopWidget, _header_left,
240                 NULL);
241 }
242
243
244 void
245 DmxPrintOutput::setHdrFtrString (_DtPrintHdrFtrEnum which, char *label)
246 {
247     Widget      w;
248     XmString    xms;
249
250     if (label == (char *) NULL)
251       return;
252
253     switch (which)
254     {
255         case DTPRINT_OPTION_HEADER_LEFT:
256           w = _header_left;
257           break;
258         case DTPRINT_OPTION_HEADER_RIGHT:
259           w = _header_right;
260           break;
261         case DTPRINT_OPTION_FOOTER_LEFT:
262           w = _footer_left;
263           break;
264         case DTPRINT_OPTION_FOOTER_RIGHT:
265           w = _footer_right;
266           break;
267         default:
268           // TBD:  Need to log an error.
269           return;
270     }
271
272     xms = XmStringCreateLocalized(label);
273     XtVaSetValues(w, XmNlabelString, xms, NULL);
274     XmStringFree(xms);
275 }
276
277 void
278 DmxPrintOutput::setHdrFtrStrings (
279                                 char *hdr_left,
280                                 char *hdr_right,
281                                 char *ftr_left,
282                                 char *ftr_right
283                                    )
284 {
285     XmString    xms;
286
287     if (hdr_left)
288     {
289         xms = XmStringCreateLocalized(hdr_left);
290         XtVaSetValues(_header_left, XmNlabelString, xms, NULL);
291         XmStringFree(xms);
292     }
293
294     if (hdr_right)
295     {
296         xms = XmStringCreateLocalized(hdr_right);
297         XtVaSetValues(_header_right, XmNlabelString, xms, NULL);
298         XmStringFree(xms);
299     }
300
301     if (ftr_left)
302     {
303         xms = XmStringCreateLocalized(ftr_left);
304         XtVaSetValues(_footer_left, XmNlabelString, xms, NULL);
305         XmStringFree(xms);
306     }
307
308     if (ftr_right)
309     {
310         xms = XmStringCreateLocalized(ftr_right);
311         XtVaSetValues(_footer_right, XmNlabelString, xms, NULL);
312         XmStringFree(xms);
313     }
314 }
315
316 void
317 DmxPrintOutput::setPageMargin (
318                                 _DtPrintMarginEnum which,
319                                 const char *margin,
320                                 DtMailBoolean *parse_error
321                                 )
322 {
323     int         pixels = 0;
324     XtEnum      xt_parse_error = FALSE;
325     char        *marginstring = strdup(margin);
326
327     if (parse_error)
328       *parse_error = DTM_FALSE;
329
330     switch (which)
331     {
332         case DTPRINT_OPTION_MARGIN_TOP:
333           pixels = XmConvertStringToUnits(
334                                         XtScreenOfObject(_pshell),
335                                         marginstring,
336                                         XmVERTICAL,
337                                         XmPIXELS,
338                                         &xt_parse_error);
339           if (!xt_parse_error && pixels > 0)
340             _margin_top = pixels;
341           break;
342         case DTPRINT_OPTION_MARGIN_RIGHT:
343           pixels = XmConvertStringToUnits(
344                                         XtScreenOfObject(_pshell),
345                                         marginstring,
346                                         XmHORIZONTAL,
347                                         XmPIXELS,
348                                         &xt_parse_error);
349           if (!xt_parse_error && pixels > 0)
350             _margin_right = pixels;
351           break;
352         case DTPRINT_OPTION_MARGIN_BOTTOM:
353           _margin_bottom = pixels;
354           pixels = XmConvertStringToUnits(
355                                         XtScreenOfObject(_pshell),
356                                         marginstring,
357                                         XmVERTICAL,
358                                         XmPIXELS,
359                                         &xt_parse_error);
360           if (!xt_parse_error && pixels > 0)
361             _margin_bottom = pixels;
362           break;
363         case DTPRINT_OPTION_MARGIN_LEFT:
364           pixels = XmConvertStringToUnits(
365                                         XtScreenOfObject(_pshell),
366                                         marginstring,
367                                         XmHORIZONTAL,
368                                         XmPIXELS,
369                                         &xt_parse_error);
370           if (!xt_parse_error && pixels > 0)
371             _margin_left = pixels;
372           break;
373         default:
374           // TBD:  Need to log an error.
375           return;
376     }
377
378     if (!xt_parse_error)
379       setInnerPageDimensions(
380                         _margin_top,
381                         _margin_right,
382                         _margin_bottom,
383                         _margin_left);
384     else
385       *parse_error = DTM_TRUE;
386
387     free(marginstring);
388 }
389
390 void
391 DmxPrintOutput::setPageMargin (_DtPrintMarginEnum which, int margin)
392 {
393     Dimension   pixels = (Dimension) margin;
394
395     switch (which)
396     {
397         case DTPRINT_OPTION_MARGIN_TOP:
398           _margin_top = pixels;
399           break;
400         case DTPRINT_OPTION_MARGIN_RIGHT:
401           _margin_right = pixels;
402           break;
403         case DTPRINT_OPTION_MARGIN_BOTTOM:
404           _margin_bottom = pixels;
405           break;
406         case DTPRINT_OPTION_MARGIN_LEFT:
407           _margin_left = pixels;
408           break;
409         default:
410           // TBD:  Need to log an error.
411           return;
412     }
413
414     setInnerPageDimensions(
415                         _margin_top,
416                         _margin_right,
417                         _margin_bottom,
418                         _margin_left);
419 }
420
421 void
422 DmxPrintOutput::setPageMargins (
423                                 const char *top,
424                                 const char *right,
425                                 const char *bottom,
426                                 const char *left,
427                                 DtMailBoolean *parse_error
428                                  )
429 {
430     int         pixels = 0;
431     XtEnum      xt_parse_error = FALSE;
432     char        *margin;
433
434     *parse_error = DTM_FALSE;
435
436     margin = strdup(top);
437     pixels = XmConvertStringToUnits(
438                                 XtScreenOfObject(_pshell),
439                                 margin,
440                                 XmVERTICAL,
441                                 XmPIXELS,
442                                 &xt_parse_error);
443     free(margin);
444     if (!xt_parse_error && pixels > 0)
445     {
446         _margin_top = pixels;
447     }
448     else
449     {    
450         *parse_error = DTM_TRUE;
451         return;
452     }
453
454     margin = strdup(right);
455     pixels = XmConvertStringToUnits(
456                                 XtScreenOfObject(_pshell),
457                                 margin,
458                                 XmHORIZONTAL,
459                                 XmPIXELS,
460                                 &xt_parse_error);
461     free(margin);
462     if (!xt_parse_error && pixels > 0)
463     {
464         _margin_right = pixels;
465     }
466     else
467     {    
468         *parse_error = DTM_TRUE;
469         return;
470     }
471
472     margin = strdup(bottom);
473     pixels = XmConvertStringToUnits(
474                                 XtScreenOfObject(_pshell),
475                                 margin,
476                                 XmVERTICAL,
477                                 XmPIXELS,
478                                 &xt_parse_error);
479     free(margin);
480     if (!xt_parse_error && pixels > 0)
481     {
482         _margin_bottom = pixels;
483     }
484     else
485     {    
486         *parse_error = DTM_TRUE;
487         return;
488     }
489
490     margin = strdup(left);
491     pixels = XmConvertStringToUnits(
492                                 XtScreenOfObject(_pshell),
493                                 margin,
494                                 XmHORIZONTAL,
495                                 XmPIXELS,
496                                 &xt_parse_error);
497     free(margin);
498     if (!xt_parse_error && pixels > 0)
499     {
500         _margin_left = pixels;
501     }
502     else
503     {    
504         *parse_error = DTM_TRUE;
505         return;
506     }
507
508     setInnerPageDimensions(
509                         _margin_top,
510                         _margin_right,
511                         _margin_bottom,
512                         _margin_left);
513 }
514
515 void
516 DmxPrintOutput::setPageMargins (
517                                 int top,
518                                 int right,
519                                 int bottom,
520                                 int left
521                                  )
522 {
523     _margin_top = (top > 0) ? (Dimension) top : _margin_top;
524     _margin_right = (right > 0) ? (Dimension) right : _margin_right;
525     _margin_bottom = (bottom > 0) ? (Dimension) bottom : _margin_bottom;
526     _margin_left = (left > 0) ? (Dimension) left : _margin_left;
527
528     setInnerPageDimensions(
529                         _margin_top,
530                         _margin_right,
531                         _margin_bottom,
532                         _margin_left);
533 }
534
535 void
536 DmxPrintOutput::setWrapToFit (DtMailBoolean onoff)
537 {
538 #ifdef USE_DTEDITOR
539     XtVaSetValues(_editor, DtNwordWrap, onoff, NULL);
540 #else
541     XtVaSetValues(_editor, XmNwordWrap, onoff, NULL);
542 #endif
543 }
544
545
546
547 int DmxPrintOutput::getCharactersPerLine ()
548 {
549     short       columns = 0;
550
551 #ifdef USE_DTEDITOR
552     XtVaGetValues(_editor, DtNcolumns, &columns, NULL);
553 #else
554     XtVaGetValues(_editor, XmNcolumns, &columns, NULL);
555 #endif
556     return((int) columns);
557 }
558
559
560
561 int DmxPrintOutput::getNumLines ()
562 {
563     int total = 0;
564
565 #ifdef USE_DTEDITOR
566 #else
567     XtVaGetValues(_editor, XmNtotalLines, &total, NULL);
568     //
569     // Correct for off by one error.
570     //
571     total -= 1;
572 #endif
573     return(total);
574 }
575
576
577 int DmxPrintOutput::getLastPosition ()
578 {
579     XmTextPosition last;
580
581 #ifdef USE_DTEDITOR
582     last = DtEditorGetLastPosition(_editor);
583 #else
584     last = XmTextGetLastPosition(_editor);
585 #endif
586     return((int) last);
587 }
588
589 int DmxPrintOutput::getTopPosition ()
590 {
591     XmTextPosition top;
592
593 #ifdef USE_DTEDITOR
594     XtVaGetValues(_editor, DtNtopCharacter, &top, NULL);
595 #else
596     top = XmTextGetTopCharacter(_editor);
597 #endif
598     return((int) top);
599 }
600
601 DtMailBoolean DmxPrintOutput::pageUp ()
602 {
603     XmTextPosition top_before, top_after;
604
605 #ifdef USE_DTEDITOR
606     return DTM_FALSE;
607 #else
608     top_before = XmTextGetTopCharacter(_editor);
609     XmTextScroll(_editor, -1 * _lines_per_page);
610     top_after = XmTextGetTopCharacter(_editor);
611
612     return (top_before > top_after) ? DTM_TRUE : DTM_FALSE;
613 #endif
614 }
615
616 DtMailBoolean DmxPrintOutput::pageDown ()
617 {
618     XmTextPosition top_before, top_after;
619
620 #ifdef USE_DTEDITOR
621     return DTM_FALSE;
622 #else
623     top_before = XmTextGetTopCharacter(_editor);
624     XmTextScroll(_editor, _lines_per_page);
625     top_after = XmTextGetTopCharacter(_editor);
626
627     return (top_before < top_after) ? DTM_TRUE : DTM_FALSE;
628 #endif
629 }
630
631 void DmxPrintOutput::setTopPosition ( int pos )
632 {
633     XmTextPosition top = (XmTextPosition) pos;
634
635 #ifdef USE_DTEDITOR
636     XtVaSetValues(_editor, DtNtopCharacter, top, NULL);
637 #else
638     XmTextSetTopCharacter(_editor, top);
639 #endif
640 }
641
642 void DmxPrintOutput::appendContents (void* stream, char *contents)
643 {
644     DmxPrintOutput      *thisOutput = (DmxPrintOutput *) stream;
645
646 #ifdef USE_DTEDITOR
647     DtEditorContentRec  rec;
648
649     rec.type = DtEDITOR_TEXT;
650     rec.value.string = contents;
651     DtEditorInsert(thisOutput->_editor, &rec);
652 #else
653     XmTextPosition pos;
654
655     pos = XmTextGetLastPosition(thisOutput->_editor);
656     XmTextInsert(thisOutput->_editor, pos, contents);
657 #endif
658 }
659
660 void DmxPrintOutput::appendNewLine ()
661 {
662 #ifdef PRINT_TO_VIDEO 
663     char        *contents = "=========== NewLine ==========\n";
664 #else
665     char        *contents = "\n";
666 #endif
667     appendContents((XtPointer) this, contents);
668 }
669
670 void DmxPrintOutput::appendPageBreak ()
671 {
672     char *      buf;
673     char        *contents = "\n";
674     int         nlines, missing;
675
676     nlines = getNumLines();
677     missing = ((nlines % _lines_per_page) > 0) ?
678                 (_lines_per_page - (nlines % _lines_per_page)) :
679                 0;
680
681     if (! missing)
682       return;
683     
684 #ifdef PRINT_TO_VIDEO 
685     for (int i=0; i<missing; i++)
686     {
687         char    buffer[128];
688
689         sprintf(buffer, "Page Break Line:  %d\n", i);
690         appendContents((XtPointer) this, buffer);
691     }
692     fprintf(
693         stdout,
694         "Total Lines:  %d;  Lines Per Page:  %d;  Missing Lines:  %d\n",
695         nlines,
696         _lines_per_page,
697         missing);
698 #else
699     buf = (char *) malloc((missing * 2) + 1);
700     for (int i=0; i<missing; i++)
701       strcat(buf, contents);
702
703     appendContents(this, contents);
704
705     free(buf);
706 #endif
707 }
708
709 void DmxPrintOutput::clearContents (void)
710 {
711 #ifdef USE_DTEDITOR
712     DtEditorContentRec  content;
713
714     content.type = DtEDITOR_TEXT;
715     rec.value.string = NULL;
716     status = DtEditorSetContents(my_text, &content);
717 #else
718     XmTextSetString(_editor, "");
719 #endif
720 }
721
722
723 /*
724  * Private class methods
725  */
726 int
727 DmxPrintOutput::doGetLinesPerPage ()
728 {
729     Dimension   lpp;
730
731     XtVaGetValues(_editor, XmNrows, &lpp, NULL);
732     return ((int) lpp);
733 }
734
735
736 void
737 DmxPrintOutput::setInnerPageDimensions (
738                                         Dimension top,
739                                         Dimension right,
740                                         Dimension bottom,
741                                         Dimension left
742                                            )
743 {
744     Dimension   inner_height, inner_width, inner_x, inner_y,
745                 outer_height, outer_width,
746                 editor_height, footer_height, header_height;
747
748     XtVaGetValues(_form,
749                   XmNheight, &outer_height,
750                   XmNwidth, &outer_width,
751                   NULL);
752
753     XtVaGetValues(_header_left,
754                   XmNheight, &header_height,
755                   NULL);
756
757     XtVaGetValues(_footer_left,
758                   XmNheight, &footer_height,
759                   NULL);
760
761     inner_x = left;
762     inner_y = top;
763     inner_height = ((int) outer_height > (top + bottom)) ?
764                         (outer_height - (top +  bottom)) :
765                         outer_height;
766     inner_width = ((int) outer_width > (left + right)) ?
767                         (outer_width - (left + right)) :
768                         outer_width;
769     editor_height = ((int) inner_height > (header_height + footer_height)) ?
770                         (inner_height - (header_height + footer_height)) :
771                         inner_height;
772     
773     XtVaSetValues(_editor, XmNheight, editor_height, NULL);
774
775     XtVaSetValues(_inner_form,
776                 XmNleftAttachment, XmATTACH_NONE,
777                 XmNtopAttachment, XmATTACH_NONE,
778                 XmNx, inner_x,
779                 XmNy, inner_y,
780                 XmNheight, inner_height,
781                 XmNwidth, inner_width,
782                 NULL);
783
784     _lines_per_page = doGetLinesPerPage();
785 }