2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 /*===================================================================
25 $FILEBEG$: Initialize.c
26 $COMPONENT$: dthelpprint
28 $SYSTEM$: HPUX 9.0; AIX 3.2; SunOS 5.3
29 $REVISION$: $XConsortium: Initialize.c /main/5 1996/10/30 11:35:21 drk $
31 (c) Copyright 1993, 1994 Hewlett-Packard Company
32 (c) Copyright 1993, 1994 International Business Machines Corp.
33 (c) Copyright 1993, 1994 Sun Microsystems, Inc.
34 (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of Novell, Inc.
35 ==$END$==============================================================*/
45 #include <sys/param.h> /* MAXPATHLEN */
46 #include <sys/stat.h> /* mkdir */
47 #include <sys/types.h>
50 #include <X11/Xlibint.h> /* _XGetHostname() */
51 #include <X11/Xos.h> /* FIX: remove? */
52 #include <X11/Intrinsic.h> /* for Xt macros */
53 /* dont use X11/StringDefs.h because it brings in the _XtStrings global */
55 #include "HelpPrintI.h"
59 /*=========== file/dir constants ===========*/
60 #define DTAPPDEFAULTS_DIR CDE_INSTALLATION_TOP "/app-defaults/C/"
61 #define XAPPDEFAULTS_DIR "/usr/lib/X11/app-defaults/"
62 #define XDEFAULTS_FILE "/.Xdefaults"
63 #define XDEFAULTS_HOST_FILE "/.Xdefaults-"
64 #define TMP_DIR_STR "/.dt/tmp"
65 #define DTHELPPRINTSH_FILE "/usr/dt/bin/dthelpprint.sh"
67 /*=========== helper constants ===========*/
71 #define EMPTY_STR s_EmptyStr
72 #define DIR_SLASH_STR s_DirSlashStr
74 #define RSRCSPECLEN 100
76 #define INSET 5 /* message catalog set */
78 /*=========== helper variables ===========*/
79 static char s_EmptyStr[1] = { EOS };
80 static char s_DirSlashStr[] = "/";
82 /*======== helper macro ==========*/
84 #define STR(s) _STR(s)
86 /*======== default values ==============*/
87 #define DFLT_DISPLAY ""
88 #define DFLT_PRINTER 0
89 #define DFLT_COPY_CNT "1"
90 #define DFLT_OUTPUT_FILE ""
91 #define DFLT_PAPER_SIZE RV_letter
92 #define DFLT_RSRCNAME "dthelpprint"
93 #define DFLT_RSRCCLASS "Dthelpprint"
94 #define DFLT_HELPTYPE STR(DtHELP_TYPE_TOPIC)
95 #define DFLT_LOCATIONID "_hometopic"
96 #define DFLT_ALLTOPICS 0
97 #define DFLT_SUBTOPICS 0
98 #define DFLT_ONETOPIC 0
101 #define DFLT_FRONTMATTER 0
102 /* The default Header / Footer values are designed for
103 English labels and a 70 column content. */
104 #define DFLT_TOC_HEADER "$LMARGIN$VOLUME\n\n"
105 #define DFLT_TOC_FOOTER "\n$LMARGIN $SECTNUM\n"
106 #define DFLT_BODY_HEADER "$LMARGIN$VOLUME$VOLUMEFILL $PAGENUMFILLPage $PAGENUM\n\n"
107 #define DFLT_BODY_FOOTER "\n$LMARGIN$TOPIC$TOPICFILL $SECTNUMFILLSection $SECTNUM\n"
108 #define DFLT_INDEX_HEADER "$LMARGIN$VOLUME$VOLUMEFILL $PAGENUMFILLPage $PAGENUM\n\n"
109 #define DFLT_INDEX_FOOTER "\n$LMARGIN $SECTNUM\n"
110 #define DFLT_TOPICTITLE "Help"
111 #define DFLT_SH_CMD DTHELPPRINTSH_FILE
112 #define DFLT_ICONV_CMD_AND_ARGS "iconv -f %s -t %s %s > %s"
113 #define DFLT_LP_CMD 0
114 #define DFLT_PR_CMD "pr"
115 /* pr arg values order: STRING job title, INT page height, STRING filename */
116 #define DFLT_PR_ARGS "-h \"%s\" -f -l%d %s"
117 /* pr offset arg value order: INT col offset */
118 #define DFLT_PR_OFFSET_ARG "-o%d"
119 #define DFLT_ECHO_CMD "echo"
120 /* echo arg values order: STRING string */
121 #define DFLT_ECHO_ARGS "\"%s\""
122 #define DFLT_FOLD_CMD "fold"
123 /* fold arg values order: INT column width, STRING filename */
124 #define DFLT_FOLD_ARGS "-w %d %s"
125 #define DFLT_MAN_CMD "man"
126 /* man arg values order: STRING man page */
127 #define DFLT_MAN_ARGS "%s"
128 /* redirect arg value order: STRING filename */
129 #define DFLT_REDIR_CMD_AND_ARGS " > %s"
130 #define DFLT_DEBUG_HELPPRINT 0
132 /*======== resource type constants ==============*/
133 /*** N.b.: These are currently not supported. ***/
134 #define XtRBool "Bool"
135 #define XtRBoolean "Boolean"
136 #define XtRDimension "Dimension"
137 #define XtRDisplay "Display"
138 #define XtRFile "File"
139 #define XtRFloat "Float"
140 #define XtRFont "Font"
141 #define XtRImmediate "Immediate"
143 #define XtROrientation "Orientation"
144 #define XtRScreen "Screen"
145 #define XtRShort "Short"
146 #define XtRString "String"
149 /*======== helper structures ==============*/
150 typedef struct _XtResource {
151 String resource_name;
152 String resource_class;
153 String resource_type;
154 Cardinal resource_size;
155 Cardinal resource_offset;
157 XtPointer default_addr;
158 } XtResource, * XtResourceList;
162 /*======== variables ==============*/
164 /* if resource_name or resource_class are NULL, use function arg values */
165 static XtResource s_OptionResources[] = {
170 XtOffset (_DtHPrOptionsPtr, display),
172 (XtPointer) DFLT_DISPLAY },
178 XtOffset (_DtHPrOptionsPtr, printer),
180 (XtPointer) DFLT_PRINTER },
186 XtOffset (_DtHPrOptionsPtr, copies),
188 (XtPointer) DFLT_COPY_CNT },
194 XtOffset (_DtHPrOptionsPtr, outputFile),
196 (XtPointer) DFLT_OUTPUT_FILE },
198 { RN_printer "." RN_paperSize, /* see CalculatePageSize() to grok this */
199 RC_printer "." RC_paperSize, /* see CalculatePageSize() to grok this */
202 XtOffset (_DtHPrOptionsPtr, paperSize),
204 (XtPointer) DFLT_PAPER_SIZE },
210 XtOffset (_DtHPrOptionsPtr, rsrcname),
212 (XtPointer) DFLT_RSRCNAME },
218 XtOffset (_DtHPrOptionsPtr, rsrcclass),
220 (XtPointer) DFLT_RSRCCLASS },
226 XtOffset (_DtHPrOptionsPtr, helpType),
228 (XtPointer) DFLT_HELPTYPE },
234 XtOffset (_DtHPrOptionsPtr, helpVolume),
242 XtOffset (_DtHPrOptionsPtr, locationId),
244 (XtPointer) DFLT_LOCATIONID },
250 XtOffset (_DtHPrOptionsPtr, allTopics),
252 (XtPointer) DFLT_ALLTOPICS },
258 XtOffset (_DtHPrOptionsPtr, subTopics),
260 (XtPointer) DFLT_SUBTOPICS },
262 /* recurse shadows subTopics for legacy reasons.
263 recurse was the VUE 3.0 helpprint option for subTopics */
268 XtOffset (_DtHPrOptionsPtr, subTopics),
270 (XtPointer) DFLT_SUBTOPICS },
276 XtOffset (_DtHPrOptionsPtr, oneTopic),
278 (XtPointer) DFLT_ONETOPIC },
284 XtOffset (_DtHPrOptionsPtr, toc),
286 (XtPointer) DFLT_TOC },
292 XtOffset (_DtHPrOptionsPtr, index),
294 (XtPointer) DFLT_INDEX },
300 XtOffset (_DtHPrOptionsPtr, frontMatter),
302 (XtPointer) DFLT_FRONTMATTER },
308 XtOffset (_DtHPrOptionsPtr, tocHF.evenFooter),
310 (XtPointer) DFLT_TOC_FOOTER },
316 XtOffset (_DtHPrOptionsPtr, tocHF.oddFooter),
318 (XtPointer) DFLT_TOC_FOOTER },
324 XtOffset (_DtHPrOptionsPtr, tocHF.evenHeader),
326 (XtPointer) DFLT_TOC_HEADER },
332 XtOffset (_DtHPrOptionsPtr, tocHF.oddHeader),
334 (XtPointer) DFLT_TOC_HEADER },
340 XtOffset (_DtHPrOptionsPtr, bodyHF.evenFooter),
342 (XtPointer) DFLT_BODY_FOOTER },
348 XtOffset (_DtHPrOptionsPtr, bodyHF.oddFooter),
350 (XtPointer) DFLT_BODY_FOOTER },
356 XtOffset (_DtHPrOptionsPtr, bodyHF.evenHeader),
358 (XtPointer) DFLT_BODY_HEADER },
364 XtOffset (_DtHPrOptionsPtr, bodyHF.oddHeader),
366 (XtPointer) DFLT_BODY_HEADER },
368 { RN_evenIndexFooter,
372 XtOffset (_DtHPrOptionsPtr, indexHF.evenFooter),
374 (XtPointer) DFLT_INDEX_FOOTER },
380 XtOffset (_DtHPrOptionsPtr, indexHF.oddFooter),
382 (XtPointer) DFLT_INDEX_FOOTER },
384 { RN_evenIndexHeader,
388 XtOffset (_DtHPrOptionsPtr, indexHF.evenHeader),
390 (XtPointer) DFLT_INDEX_HEADER },
396 XtOffset (_DtHPrOptionsPtr, indexHF.oddHeader),
398 (XtPointer) DFLT_INDEX_HEADER },
404 XtOffset (_DtHPrOptionsPtr, manPage),
412 XtOffset (_DtHPrOptionsPtr, stringData),
420 XtOffset (_DtHPrOptionsPtr, helpFile),
428 XtOffset (_DtHPrOptionsPtr, topicTitle),
430 (XtPointer) DFLT_TOPICTITLE },
436 XtOffset (_DtHPrOptionsPtr, echoCommand),
438 (XtPointer) DFLT_ECHO_CMD },
444 XtOffset (_DtHPrOptionsPtr, echoArgs),
446 (XtPointer) DFLT_ECHO_ARGS },
452 XtOffset (_DtHPrOptionsPtr, foldCommand),
454 (XtPointer) DFLT_FOLD_CMD },
460 XtOffset (_DtHPrOptionsPtr, foldArgs),
462 (XtPointer) DFLT_FOLD_ARGS },
468 XtOffset (_DtHPrOptionsPtr, prCommand),
470 (XtPointer) DFLT_PR_CMD },
476 XtOffset (_DtHPrOptionsPtr, prArgs),
478 (XtPointer) DFLT_PR_ARGS },
484 XtOffset (_DtHPrOptionsPtr, prOffsetArg),
486 (XtPointer) DFLT_PR_OFFSET_ARG },
492 XtOffset (_DtHPrOptionsPtr, manCommand),
494 (XtPointer) DFLT_MAN_CMD },
500 XtOffset (_DtHPrOptionsPtr, manArgs),
502 (XtPointer) DFLT_MAN_ARGS },
504 { RN_redirectCmdAndArgs,
505 RC_redirectCmdAndArgs,
508 XtOffset (_DtHPrOptionsPtr, redirectCmdAndArgs),
510 (XtPointer) DFLT_REDIR_CMD_AND_ARGS },
516 XtOffset (_DtHPrOptionsPtr, lpCommand),
518 (XtPointer) DFLT_LP_CMD },
524 XtOffset (_DtHPrOptionsPtr, shCommand),
526 (XtPointer) DFLT_SH_CMD },
528 { RN_iconvCmdAndArgs,
532 XtOffset (_DtHPrOptionsPtr, iconvCmdAndArgs),
534 (XtPointer) DFLT_ICONV_CMD_AND_ARGS },
540 XtOffset (_DtHPrOptionsPtr, debugHelpPrint),
542 (XtPointer) DFLT_DEBUG_HELPPRINT },
544 #if 0 /* Because we aren't using Xt and only emulating it,
545 we can't handle data type other than String. These
546 are all Integer values, so I process them by hand
547 below in CalculatePageSize(). */
552 XtOffset (_DtHPrOptionsPtr, colsWidth),
560 XtOffset (_DtHPrOptionsPtr, rowsHeight),
568 XtOffset (_DtHPrOptionsPtr, colsLeftMargin),
572 { RN_colsRightMargin,
576 XtOffset (_DtHPrOptionsPtr, colsRightMargin),
584 XtOffset (_DtHPrOptionsPtr, rowsTopMargin),
588 { RN_rowsBottomMargin,
592 XtOffset (_DtHPrOptionsPtr, rowsBottomMargin),
603 ===================================================================
604 $PFUNBEG$: GetHomeDir()
605 $1LINER$: Gets home directory of user owning current app
607 Gets the home directory by
608 1. using the HOME environment variable
609 or 2. using the USER env variable and the
610 directory in the password file for that user
611 or 3. using getuid() and the
612 directory in the password file for that user
614 The home directory is stored in the string that is passed
615 in. No overflow checking is possible, so the string should
616 be MAXPATHLEN bytes long.
618 Returns the 'dest' pointer
620 dest: pointer to string to hold home directory
621 ========================================================$SKIP$=====*/
624 static char *GetHomeDir (
631 if((ptr = getenv("HOME")) != NULL)
633 snprintf(dest, MAXPATHLEN, "%s", ptr);
637 if((ptr = getenv("USER")) != NULL)
639 char user[MAXPATHLEN];
640 snprintf(user, MAXPATHLEN, "%s", ptr);
649 snprintf(dest, MAXPATHLEN, "%s", pw->pw_dir);
661 ===================================================================
663 $1LINER$: Prints usage message and returns
665 This routine prints a generic help message
668 ========================================================$SKIP$=====*/
674 static char * usage[] =
676 "dthelpprint - Print program for Help\n\n",
677 "Usage: dthelpprint [options]\n",
678 "Options controlling how to print:\n",
679 "\t" AN_printer " printername printer to use\n",
680 "\t" AN_copies " number number of copies to print\n",
681 "\t" AN_outputFile " filename write output to this file\n",
682 "\t" AN_paperSize " size format content to this paper size\n",
683 "\t\tsize = {" RV_letter "|" RV_legal "|\n" ,
684 "\t\t " RV_executive "|" RV_a4 "|" RV_b5 "}\n",
685 "\t" AN_display " displayname display from which to get resources\n",
686 "\t" AN_rsrcname " name program name used when getting resources\n",
687 "\t" AN_rsrcclass " name class name used when getting resources\n",
688 "\t" AN_xrm " resourcestring additional resources\n",
689 "Options controlling what to print:\n",
690 "\t" AN_helpType " type type of Help data\n",
691 "\t\ttype = 0 (help volume), 1 (string), 2 (man page), 3 (help file)\n",
692 "\t" AN_helpVolume " volume full path of help volume file\n",
693 "\t" AN_locationId " location name of Help topic in the volume\n",
694 "\t" AN_allTopics " print all topics, toc, & index in the help volume\n",
695 "\t" AN_subTopics " print topic locationId and all subtopics\n",
696 "\t" AN_oneTopic " print topic locationId\n",
697 "\t" AN_toc " print help volume table of contents\n",
698 "\t" AN_index " print help volume index\n",
699 "\t" AN_frontMatter " print help volume front matter\n",
700 "\t" AN_manPage " manpagename name of man page\n",
701 "\t" AN_stringData " string Help text to print\n",
702 "\t" AN_helpFile " filename file containing Help text\n",
703 "\t" AN_topicTitle " title title string for Help text\n",
707 for (i=0; usage[i]; i++)
708 printf("%s", _DTGETMESSAGE(INSET,i,usage[i]));
713 ===================================================================
714 $PFUNBEG$: CalculatePageSize()
715 $1LINER$: calculates the page size based on resource values
717 Reads the resources from the database and calculates
718 the page dimensions and stores them in the resources structure.
721 ========================================================$SKIP$=====*/
725 void CalculatePageSize(
727 _DtHPrOptions * options,
732 struct unprintableMargins
734 int leftUnprintableMargin;
735 int rightUnprintableMargin;
736 int topUnprintableMargin;
737 int bottomUnprintableMargin;
740 static struct unprintableMargins blankMargins = { 6, 2, 2, 1 };
747 #define MAXVALIDSIZE 4
760 static struct page pagesize[] =
761 { /* sizes are in characters of standard HPLJIII courier */
762 /* Note that the text margin counts do *NOT* take into account the
763 printless margins, which are the margins on which the printer
764 is unable to print. */
765 /* WI: paper size width; HI: paper size height;
766 LM: desired text left margin; RM: desired text right margin
767 TM: desired text top margin; BM: desired text bottom margin
769 /*WI, HI, LM, RM, TM, BM */
770 { 91, 69, 10, 10, 6, 6 }, /* letter */
771 { 91, 88, 10, 10, 6, 6 }, /* legal */
772 { 77, 66, 10, 10, 6, 6 }, /* executive */
773 { 88, 73, 10, 10, 6, 6 }, /* A4 */
774 { 76, 63, 10, 10, 6, 6 } /* B5 */
777 #if 0 /* save these dimensions here */
778 /* Known Dimensions for standard HPLJIII courier:
779 char size: 2.37 mm width x 4.04 mm height
780 US-letter: 8.5x11 in : 91 col x 69 rows
781 US-legal: 8.5x14 in : 91 col x 88 rows
782 executive: 7.25x10.5 in : 77 col x 66 rows
783 A4: 210x297 mm : 88 col x 73 rows
784 B5: 182x257 mm : 76 col x 63 rows
787 /* Known Dimensions in 100ths of a mm */
788 { 21590, 27940, 2540, 2540, 2540, 2540 }, /* letter */
789 { 21590, 35560, 2540, 2540, 2540, 2540 }, /* legal */
790 { 18415, 26670, 2540, 2540, 2540, 2540 }, /* exec */
791 { 21000, 29700, 2540, 2540, 2540, 2540 }, /* a4 */
792 { 18200, 25700, 2540, 2540, 2540, 2540 } /* b5 */
793 static float dphm = 300.*2540.;
796 int (*stricmp)(const char *,const char *);
798 char name_prefix[RSRCSPECLEN];
799 char name_prefix_temp[sizeof(name_prefix)];
800 char class_prefix[RSRCSPECLEN];
801 char class_prefix_temp[sizeof(class_prefix)];
802 char resource_name[RSRCSPECLEN];
803 char resource_class[RSRCSPECLEN];
809 int lmargin,rmargin,tmargin,bmargin;
810 int adjLmargin,adjRmargin,adjTmargin,adjBmargin;
811 int textWidth, textHeight;
814 /* build printer resource name and class */
815 snprintf(name_prefix, sizeof(name_prefix), "%s%s", appname, RN_printer); /* e.g. dthelpprint.printer */
816 snprintf(class_prefix, sizeof(class_prefix), "%s%s", appclass, RC_printer); /* e.g. Dthelpprint.Printer */
818 /********************/
819 /* Get printer name */
820 /********************/
822 snprintf(resource_name, sizeof(resource_name), "%s%s", name_prefix, RN_rsrcname); /* e.g. dthelpprint.printer.name */
823 snprintf(resource_class, sizeof(resource_class), "%s%s", class_prefix, RC_rsrcname); /* e.g. Dthelpprint.Printer.Name */
824 if (XrmGetResource(appDB, resource_name, resource_class,
825 str_type, &value) == True)
827 else name = EMPTY_STR;
830 snprintf(name_prefix_temp, sizeof(name_prefix_temp), "%s%s%s", name_prefix, DOT_STR, name); /* e.g. dthelpprint.printer.<name> */
831 strcpy(name_prefix, name_prefix_temp);
832 snprintf(class_prefix_temp, sizeof(class_prefix_temp), "%s%s%s", class_prefix, DOT_STR, name); /* e.g. Dthelpprint.Printer.<name> */
833 strcpy(class_prefix, class_prefix_temp);
836 /**************************/
837 /* Get explicit width */
838 /**************************/
839 strcpy(resource_name, name_prefix);
840 strcat(resource_name, RN_colsWidth);
841 /* e.g. dthelpprint.printer{.<name>}.colsWidth */
842 strcpy(resource_class, class_prefix);
843 strcat(resource_class, RC_colsWidth);
844 /* e.g. Dthelpprint.Printer{.<name>}.ColsWidth */
846 if (XrmGetResource(appDB, resource_name, resource_class,
847 str_type, &value) == True)
849 width = atoi (value.addr);
850 if (width < 0) width = 0;
854 /**************************/
855 /* Get explicit height */
856 /**************************/
857 strcpy(resource_name, name_prefix);
858 strcat(resource_name, RN_rowsHeight);
859 /* e.g. dthelpprint.printer{.<name>}.rowsHeight */
860 strcpy(resource_class, class_prefix);
861 strcat(resource_class, RC_rowsHeight);
862 /* e.g. Dthelpprint.Printer{.<name>}.RowsHeight */
864 if (XrmGetResource(appDB, resource_name, resource_class,
865 str_type, &value) == True)
867 height = atoi (value.addr);
868 if (height < 0) height = 0;
872 /**********************************************************/
873 /* get the paper size (will provide default height/width) */
874 /**********************************************************/
875 strcpy(resource_name, name_prefix);
876 strcat(resource_name, RN_paperSize);
877 /* e.g. dthelpprint.printer{.<name>}.paperSize */
878 strcpy(resource_class, class_prefix);
879 strcat(resource_class, RC_paperSize);
880 /* e.g. Dthelpprint.Printer{.<name>}.PaperSize */
882 #if defined(_AIX) || defined (USL)
883 stricmp = strcmp; /* AIX and USL dont have strcasecmp */
885 stricmp = strcasecmp;
887 if (XrmGetResource(appDB, resource_name, resource_class,
888 str_type, &value) == True)
890 if ((*stricmp)(value.addr, RV_letter) == 0) papersize = LETTER;
891 else if ((*stricmp)(value.addr, RV_b5) == 0) papersize = B5;
892 else if ((*stricmp)(value.addr, RV_a4) == 0) papersize = A4;
893 else if ((*stricmp)(value.addr, RV_legal) == 0) papersize = LEGAL;
894 else if ((*stricmp)(value.addr, RV_executive) == 0) papersize = EXECUTIVE;
897 fprintf(stderr, _DTGETMESSAGE(INSET,40,
898 "%s Warning: Illegal paper size '%s'. "
899 RV_letter " used.\n"),
900 options->programName, value.addr);
903 } /* if the paper size resource is defined */
905 /* if specified only a width or height, but not both */
906 if ( papersize < 0 && (width == 0 || height == 0) )
908 fprintf(stderr, _DTGETMESSAGE(INSET,41,
909 "%s Warning: Missing paper size, height, or width value. "
910 RV_letter " used.\n"),
911 options->programName);
915 /* if an invaild papersize, dflt to letter */
916 if ( papersize < 0 || papersize > MAXVALIDSIZE ) papersize = LETTER;
918 /* use page size width and height if not specified */
919 if (width == 0) width = pagesize[papersize].width;
920 if (height == 0) height = pagesize[papersize].height;
927 strcpy(resource_name, name_prefix);
928 strcat(resource_name, RN_colsLeftMargin);
929 /* e.g. dthelpprint.printer{.<name>}.colsLeftMargin */
930 strcpy(resource_class, class_prefix);
931 strcat(resource_class, RC_colsLeftMargin);
932 /* e.g. Dthelpprint.Printer{.<name>}.ColsLeftMargin */
935 if (XrmGetResource(appDB, resource_name, resource_class,
936 str_type, &value) == True)
937 i = atoi (value.addr); /* custom margin */
939 i = pagesize[papersize].leftMargin; /* papersize margin */
941 if (i < width) lmargin = i;
943 /* available text width, part 1 */
944 textWidth = width - lmargin;
946 /* all printed text subject to this offset */
947 adjLmargin = lmargin - blankMargins.leftUnprintableMargin;
948 if (adjLmargin < 0) adjLmargin = 0;
953 strcpy(resource_name, name_prefix);
954 strcat(resource_name, RN_colsRightMargin);
955 /* e.g. dthelpprint.printer{.<name>}.colsRightMargin */
956 strcpy(resource_class, class_prefix);
957 strcat(resource_class, RC_colsRightMargin);
958 /* e.g. Dthelpprint.Printer{.<name>}.ColsRightMargin */
961 if (XrmGetResource(appDB, resource_name, resource_class,
962 str_type, &value) == True)
963 i = atoi (value.addr); /* custom margin */
965 i = pagesize[papersize].rightMargin; /* size margin */
967 if (i < textWidth) rmargin = i;
969 /* available text width, part 2 */
970 textWidth -= rmargin;
972 /* all printed text subject to this offset */
973 adjRmargin = rmargin - blankMargins.rightUnprintableMargin;
974 if (adjRmargin < 0) adjRmargin = 0;
979 strcpy(resource_name, name_prefix);
980 strcat(resource_name, RN_rowsTopMargin);
981 /* e.g. dthelpprint.printer{.<name>}.rowsTopMargin */
982 strcpy(resource_class, class_prefix);
983 strcat(resource_class, RC_rowsTopMargin);
984 /* e.g. Dthelpprint.Printer{.<name>}.RowsTopMargin */
987 if (XrmGetResource(appDB, resource_name, resource_class,
988 str_type, &value) == True)
989 i = atoi (value.addr); /* custom margin */
991 i = pagesize[papersize].topMargin; /* papersize margin */
993 if (i < height) tmargin = i;
995 /* available text height, part 1 */
996 textHeight = height - tmargin;
998 /* all printed text subject to this offset */
999 adjTmargin = tmargin - blankMargins.topUnprintableMargin;
1000 if (adjTmargin < 0) adjTmargin = 0;
1005 strcpy(resource_name, name_prefix);
1006 strcat(resource_name, RN_rowsBottomMargin);
1007 /* e.g. dthelpprint.printer{.<name>}.rowsBottommargin */
1008 strcpy(resource_class, class_prefix);
1009 strcat(resource_class, RC_rowsBottomMargin);
1010 /* e.g. Dthelpprint.Printer{.<name>}.RowsBottommargin */
1013 if (XrmGetResource(appDB, resource_name, resource_class,
1014 str_type, &value) == True)
1015 i = atoi (value.addr); /* custom margin */
1017 i = pagesize[papersize].bottomMargin; /* size margin */
1019 if ( i < textHeight ) bmargin = i;
1021 /* available text height, part 2 */
1022 textHeight -= bmargin;
1024 /* all printed text subject to this offset */
1025 adjBmargin = tmargin - blankMargins.bottomUnprintableMargin;
1026 if (adjBmargin < 0) adjBmargin = 0;
1028 /*** set the values ***/
1029 options->rowsHeight = height;
1030 options->colsWidth = width;
1031 options->colsLeftMargin = lmargin;
1032 options->colsRightMargin = rmargin;
1033 options->rowsTopMargin = tmargin;
1034 options->rowsBottomMargin = bmargin;
1035 options->rowsTextHeight = textHeight;
1036 options->colsTextWidth = textWidth;
1037 options->colsAdjLeftMargin = adjLmargin;
1038 options->colsAdjRightMargin = adjRmargin;
1039 options->rowsAdjTopMargin = adjTmargin;
1040 options->rowsAdjBottomMargin = adjBmargin;
1042 if (options->debugHelpPrint)
1044 printf("options.%s: %d\n","rowsHeight",options->rowsHeight);
1045 printf("options.%s: %d\n","colsWidth",options->colsWidth);
1046 printf("options.%s: %d\n","colsLeftMargin",options->colsLeftMargin);
1047 printf("options.%s: %d\n","colsRightMargin",options->colsRightMargin);
1048 printf("options.%s: %d\n","rowsTopMargin",options->rowsTopMargin);
1049 printf("options.%s: %d\n","rowsBottomMargin",options->rowsBottomMargin);
1050 printf("options.%s: %d\n","rowsTextHeight",options->rowsTextHeight);
1051 printf("options.%s: %d\n","colsTextWidth",options->colsTextWidth);
1052 printf("options.%s: %d\n","colsAdjLeftMargin",options->colsAdjLeftMargin);
1053 printf("options.%s: %d\n","colsAdjRightMargin",options->colsAdjRightMargin);
1054 printf("options.%s: %d\n","rowsAdjTopMargin",options->rowsAdjTopMargin);
1055 printf("options.%s: %d\n","rowsAdjBottomMargin",options->rowsAdjBottomMargin);
1061 ===================================================================
1062 $FUNBEG$: _DtHPrBuildResourceDb()
1063 $1LINER$: Parses command line and constructs a single db of resources
1065 This routine parses the command line and reads various data bases
1066 to create a single data base that copntains all resources associated
1067 with this application.
1069 It generates the resulting resource database by merging the
1070 following databases:
1071 help-print specific cmdline & environment var->resources database
1072 $PRINTER -> RN_printer, RC_printer
1073 $DISPLAY -> RN_display, RC_display
1074 AN_rsrcname -> RN_appname
1075 AC_rsrcname -> RC_appname
1076 AN_rsrcclass -> RN_appclass
1077 AC_rsrcclass -> RC_appclass
1078 app-specific class resource file on local host
1079 /usr/lib/X11/app-defaults/<appclass>
1080 app-specific user resource file on local host
1082 display server resources or user preferences file on local host
1083 XResourceManagerString() or $HOME/.Xdefaults
1084 screen resources from display server
1085 XScreenResourcesString()
1086 user environment resource file on local host
1087 $XENVIRONMENT or $HOME/.Xdefaults-<host>
1088 application command line
1090 This function is a replacement for XtAppInitialize/XtInitialize()
1091 and XtDisplayInitialize() to remove dependency on Xt.
1093 argc is modified to be the number of remaining args
1094 argv is modified to point to the remaining args
1095 appDB is filled with the option settings used by the rest of the program
1097 ========================================================$SKIP$=====*/
1100 void _DtHPrBuildResourceDb(
1103 XrmDatabase * appDB,
1106 static XrmOptionDescRec optionsTable[] = {
1108 {AN_display, RN_display, XrmoptionSepArg, (caddr_t) NULL},
1109 {AN_printer, RN_printer, XrmoptionSepArg, (caddr_t) NULL},
1110 {AN_copies, RN_copies, XrmoptionSepArg, (caddr_t) NULL},
1111 {AN_outputFile, RN_outputFile, XrmoptionSepArg, (caddr_t) NULL},
1112 {AN_paperSize, RN_printer "." RN_paperSize,
1113 XrmoptionSepArg, (caddr_t) NULL},
1114 {AN_xrm, NULL, XrmoptionResArg, (caddr_t) NULL},
1115 {AN_rsrcname, RN_rsrcname, XrmoptionSepArg, (caddr_t) NULL},
1116 {AN_rsrcclass, RN_rsrcclass, XrmoptionSepArg, (caddr_t) NULL},
1117 {AN_evenTocFooter, RN_evenTocFooter, XrmoptionSepArg, (caddr_t) NULL},
1118 {AN_oddTocFooter, RN_oddTocFooter, XrmoptionSepArg, (caddr_t) NULL},
1119 {AN_evenTocHeader, RN_evenTocHeader, XrmoptionSepArg, (caddr_t) NULL},
1120 {AN_oddTocHeader, RN_oddTocHeader, XrmoptionSepArg, (caddr_t) NULL},
1121 {AN_evenBodyFooter, RN_evenBodyFooter, XrmoptionSepArg, (caddr_t) NULL},
1122 {AN_oddBodyFooter, RN_oddBodyFooter, XrmoptionSepArg, (caddr_t) NULL},
1123 {AN_evenBodyHeader, RN_evenBodyHeader, XrmoptionSepArg, (caddr_t) NULL},
1124 {AN_oddBodyHeader, RN_oddBodyHeader, XrmoptionSepArg, (caddr_t) NULL},
1125 {AN_evenIndexFooter,RN_evenIndexFooter, XrmoptionSepArg, (caddr_t) NULL},
1126 {AN_oddIndexFooter, RN_oddIndexFooter, XrmoptionSepArg, (caddr_t) NULL},
1127 {AN_evenIndexHeader,RN_evenIndexHeader, XrmoptionSepArg, (caddr_t) NULL},
1128 {AN_oddIndexHeader, RN_oddIndexHeader, XrmoptionSepArg, (caddr_t) NULL},
1130 {AN_helpType, RN_helpType, XrmoptionSepArg, (caddr_t) NULL},
1131 {AN_helpVolume, RN_helpVolume, XrmoptionSepArg, (caddr_t) NULL},
1132 {AN_locationId, RN_locationId, XrmoptionSepArg, (caddr_t) NULL},
1133 {AN_allTopics, RN_allTopics, XrmoptionNoArg, (caddr_t) "True"},
1134 {AN_subTopics, RN_subTopics, XrmoptionNoArg, (caddr_t) "True"},
1135 {AN_recurse, RN_recurse, XrmoptionNoArg, (caddr_t) "True"},
1136 {AN_oneTopic, RN_oneTopic, XrmoptionNoArg, (caddr_t) "True"},
1137 {AN_toc, RN_toc, XrmoptionNoArg, (caddr_t) "True"},
1138 {AN_index, RN_index, XrmoptionNoArg, (caddr_t) "True"},
1139 {AN_frontMatter, RN_frontMatter, XrmoptionNoArg, (caddr_t) "True"},
1140 {AN_manPage, RN_manPage, XrmoptionSepArg, (caddr_t) NULL},
1141 {AN_stringData, RN_stringData, XrmoptionSepArg, (caddr_t) NULL},
1142 {AN_helpFile, RN_helpFile, XrmoptionSepArg, (caddr_t) NULL},
1143 {AN_topicTitle, RN_topicTitle, XrmoptionSepArg, (caddr_t) NULL},
1145 static int numOptions = XtNumber(optionsTable); /*number entries in table*/
1147 XrmDatabase appClassDB = NULL;
1148 XrmDatabase appUserDB = NULL;
1149 XrmDatabase dispDB = NULL;
1150 XrmDatabase homeDB = NULL;
1151 XrmDatabase scrnDB = NULL;
1152 XrmDatabase envDB = NULL;
1153 XrmDatabase commandLineDB = NULL;
1154 char filename[MAXPATHLEN+1];
1156 char * str_type[20];
1157 char * invocationName=NULL;
1158 char name_prefix[RSRCSPECLEN];
1159 char class_prefix[RSRCSPECLEN];
1160 char resource_name[RSRCSPECLEN];
1161 char resource_class[RSRCSPECLEN];
1162 char * commandLineName = NULL;
1163 char * environment = NULL;
1164 char * display = NULL;
1165 char * dispDBStr = NULL;
1166 char * scrnDBStr = NULL;
1170 /** n.b.: If *appDB == NULL, the first XrmPutResource() call
1171 creates a database and stored its ref in appDB. We dont
1172 need to explicitly create the db. **/
1178 Usage(); /* print message if no arguments */
1182 /** Parse the commandline and put options into a db **/
1183 /* Do this now so that we can recover options from
1184 the db for immediate use. */
1186 /* search arguments for AN_rsrcname option */
1187 for (i=1; i<(*argc-1); i++)
1189 if ( strcmp(argv[i], AN_rsrcname)==0 )
1191 invocationName=argv[i+1];
1195 if (invocationName == NULL)
1197 /* search for last '/' of string */
1198 if ( _DtHelpCeStrrchr(argv[0],DIR_SLASH_STR,MB_CUR_MAX,&commandLineName) == 0 )
1199 invocationName = commandLineName+1;
1200 else /* Starts at character after the last slash */
1201 invocationName = argv[0];
1204 XrmParseCommand(&commandLineDB, optionsTable, numOptions, invocationName,
1209 Usage(); /* print message if any arguments left */
1213 /** now create a baseline appDB with a few minimal resources in it **/
1215 /* Set name and class initial values */
1216 strcpy(name_prefix, invocationName); /* e.g. dthelpprint */
1217 strcpy(class_prefix, HELPPRINT_APPLICATION_CLASS); /* e.g. Dthelpprint */
1220 strcpy(resource_name, name_prefix);
1221 strcat(resource_name, RN_rsrcclass); /* e.g. dthelpprint.class */
1222 strcpy(resource_class, class_prefix);
1223 strcat(resource_class, RC_rsrcclass); /* e.g. Dthelpprint.Class */
1224 if (XrmGetResource(commandLineDB, resource_name, resource_class,
1225 str_type, &value) == True)
1227 strcpy(class_prefix, value.addr);
1231 value.size = strlen(HELPPRINT_APPLICATION_CLASS)+1;
1232 value.addr = HELPPRINT_APPLICATION_CLASS;
1234 /* CHK: Note that *str_type may be NULL here. Is this ok? */
1235 XrmPutResource(appDB, RN_appclass, NULL, &value);
1236 XrmPutResource(appDB, RC_appclass, NULL, &value);
1238 strcpy(resource_name, name_prefix);
1239 strcat(resource_name, RN_rsrcname); /* e.g. dthelpprint.name */
1240 strcpy(resource_class, class_prefix);
1241 strcat(resource_class, RC_rsrcname); /* e.g. Dthelpprint.Name */
1242 if (invocationName != NULL) /* always true */
1244 value.size = strlen(invocationName)+1;
1245 value.addr = invocationName; /* e.g. dthelpprint */
1246 /* CHK: state of *str_type unknown here. Is this ok? */
1247 XrmPutResource(appDB, RN_appname, NULL, &value);
1248 XrmPutResource(appDB, RC_appname, NULL, &value);
1250 /* CHK: currently, this and the next 'elses' are never executed */
1251 else if( XrmGetResource((XrmDatabase)commandLineDB, resource_name,
1252 resource_class, str_type, &value) == True)
1254 strcpy(name_prefix, value.addr);
1258 value.size = strlen(HELPPRINT_APPLICATION_NAME)+1;
1259 value.addr = HELPPRINT_APPLICATION_NAME; /* i.e. dthelpprint */
1260 XrmPutResource(appDB, RN_appname, NULL, &value);
1261 XrmPutResource(appDB, RC_appname, NULL, &value);
1262 strcpy(name_prefix, value.addr);
1266 /** Get environment variables and put values in appDB as resource **/
1268 if ((tmp_string = getenv("DISPLAY")) != NULL)
1270 i = strlen(tmp_string);
1271 value.addr=malloc(i+1); /* FIX: use tmp_string here directly? */
1273 strcpy(value.addr, tmp_string);
1274 strcpy(resource_name, name_prefix);
1275 strcat(resource_name, RN_display); /* e.g. dthelpprint.display */
1276 strcpy(resource_class, class_prefix);
1277 strcat(resource_class, RC_display); /* e.g. Dthelpprint.Display */
1278 XrmPutResource(appDB, resource_name, NULL, &value);
1279 XrmPutResource(appDB, resource_class, NULL, &value);
1282 if ((tmp_string = getenv("PRINTER")) != NULL)
1284 i = strlen(tmp_string);
1285 value.addr=malloc(i+1); /* FIX: use tmp_string here directly? */
1287 strcpy(value.addr, tmp_string);
1288 strcpy(resource_name, name_prefix);
1289 strcat(resource_name, RN_printer); /* e.g. dthelpprint.printer */
1290 strcpy(resource_class, class_prefix);
1291 strcat(resource_class, RC_printer); /* e.g. Dthelpprint.Printer */
1292 XrmPutResource(appDB, resource_name, NULL, &value);
1293 XrmPutResource(appDB, resource_class, NULL, &value);
1296 /*** Build the display resource db ***/
1298 /* Sequence and logic of db overlays taken from the X11R5 description
1299 of XtDisplayInitialize() (p. 172, Xt Ref Man) and enhanced to use
1300 appDB baseline values. Note that it is my opinion that the
1301 description in the manual DOES NOT match the implementation
1302 of XtScreenDatabase(), which is the actual routine used
1303 by XtDisplayInitialize(). The following is the order
1305 help-print specific environment var->resources database
1306 DT app-specific class resource file on local host
1307 X app-specific class resource file on local host
1308 app-specific user resource file on local host
1309 display server resources or user
1310 preferences file on local host
1311 screen resources from display server
1312 user environment resource file on local host
1313 application command line
1315 N.B. This code does not pay attention to XFILESEARCHPATH and
1316 does not consider languages other than C in /usr/dt/app-defaults/%L.
1319 /* Overlay the central Dt app-defaults */
1320 (void) strcpy(filename, DTAPPDEFAULTS_DIR);
1321 strcat(filename, class_prefix);/*eg. /usr/dt/app-defaults/C/Dthelpprint*/
1322 appClassDB = XrmGetFileDatabase(filename);
1323 if (appClassDB != NULL)
1324 (void) XrmMergeDatabases(appClassDB, appDB);
1326 /* Overlay the central X app-defaults (if exists) */
1327 (void) strcpy(filename, XAPPDEFAULTS_DIR);
1328 strcat(filename, class_prefix);/*eg. /usr/lib/X11/app-defaults/Dthelpprint*/
1329 appClassDB = XrmGetFileDatabase(filename);
1330 if (appClassDB != NULL)
1331 (void) XrmMergeDatabases(appClassDB, appDB);
1333 /* Overlay the user class resources */
1334 GetHomeDir(filename);
1335 strcat(filename, DIR_SLASH_STR);
1336 strcat(filename, class_prefix); /* e.g. $HOME/Dthelpprint */
1337 appUserDB = XrmGetFileDatabase(filename);
1338 if (appUserDB != NULL)
1339 (void) XrmMergeDatabases(appUserDB, appDB);
1341 /** to get the display's resources, we need to open the display first **/
1342 /* to get the display name, we first look in the commandLineDB,
1343 and if not found there, in the appDB loaded thus far. */
1344 strcpy(resource_name, name_prefix);
1345 strcat(resource_name, RN_display); /* e.g. dthelpprint.display */
1346 strcpy(resource_class, class_prefix);
1347 strcat(resource_class, RC_display); /* e.g. Dthelpprint.Display */
1348 if ( XrmGetResource((XrmDatabase)commandLineDB, resource_name,
1349 resource_class, str_type, &value) == True
1350 || XrmGetResource((XrmDatabase)*appDB, resource_name,
1351 resource_class, str_type, &value) == True)
1352 display = value.addr;
1355 /* if display == NULL, uses DISPLAY env var */
1356 *pDpy = XOpenDisplay(display); /* FIX: should this be .printer ?? */
1359 /* FIX: chg msg to match above semantics */
1360 fprintf(stderr, _DTGETMESSAGE(INSET,42,
1361 "%s Warning: Unable to open display %s\n"),
1362 argv[0], (NULL == display ? "" : display) );
1363 } /* if bad display */
1365 { /* Good display */
1366 /* try to overlay the display's resources (i.e. the xrdb-managed ones) */
1367 dispDBStr = XResourceManagerString(*pDpy);
1368 if (dispDBStr) dispDB = XrmGetStringDatabase(dispDBStr);
1369 else /* if no display resources, overlay $HOME/.Xdefaults file */
1372 (void) GetHomeDir (filename);
1373 (void) strcat (filename, XDEFAULTS_FILE); /* e.g. $HOME/.Xdefaults */
1374 dispDB = XrmGetFileDatabase (filename);
1377 (void) XrmMergeDatabases(dispDB, appDB);
1379 scrnDBStr = XScreenResourceString(DefaultScreenOfDisplay(*pDpy));
1380 if (scrnDBStr) scrnDB = XrmGetStringDatabase(scrnDBStr);
1382 (void) XrmMergeDatabases(scrnDB, appDB);
1383 } /* else good display */
1385 /* Overlay either file from XENVIRONMENT or $HOME/.Xdefaults-<host> */
1386 if ((environment = getenv ("XENVIRONMENT")) == NULL)
1387 { /* no XENVIRONMENT variable */
1390 (void) GetHomeDir (filename);
1391 (void) strcat (filename, XDEFAULTS_HOST_FILE);
1392 len = strlen (filename);
1393 (void) _XGetHostname (filename+len, 1024-len);
1394 environment = filename; /* e.g. $HOME/.Xdefaults-<host> */
1396 envDB = XrmGetFileDatabase (environment);
1398 (void) XrmMergeDatabases(envDB, appDB);
1400 /* Overlay command line */
1401 if (*appDB == NULL) *appDB = commandLineDB;
1402 else XrmMergeDatabases (commandLineDB, appDB);
1410 ===================================================================
1411 $FUNBEG$: _DtHPrGetResources()
1412 $1LINER$: Retrieves options from a Xrm db and assigns value to a struct
1414 Retrieves options from a Xrm db and assigns value to a struct
1416 This is a poor-man emulation to the mechanism Xt provides for
1417 setting values of widgets.
1421 ========================================================$SKIP$=====*/
1424 void _DtHPrGetResources(
1426 _DtHPrOptions * options)
1430 char * str_type[20];
1431 char resource_name[256];
1432 char resource_class[256];
1434 char * class_prefix;
1438 /* Get name and class */
1439 if (XrmGetResource(db, RN_appname, RC_appname,
1440 str_type, &value) == True)
1441 name_prefix = value.addr;
1442 else name_prefix = HELPPRINT_APPLICATION_NAME; /*e.g. dthelpprint*/
1444 if (XrmGetResource(db, RN_appclass, RC_appclass,
1445 str_type, &value) == True)
1446 class_prefix = value.addr;
1447 else class_prefix = HELPPRINT_APPLICATION_CLASS; /*e.g. Dthelpprint*/
1449 if (XrmGetResource(db, STAR_RN_debugHelpPrint, STAR_RC_debugHelpPrint,
1450 str_type, &value) == True)
1452 else debugHelpPrint = 0;
1454 /* walk thru all resources and get their values */
1455 for ( rsrc = s_OptionResources, cnt = XtNumber(s_OptionResources);
1459 snprintf(resource_name, sizeof(resource_name), "%s%s", name_prefix, rsrc->resource_name);
1460 snprintf(resource_class, sizeof(resource_class), "%s%s", class_prefix, rsrc->resource_class);
1461 if (XrmGetResource(db, resource_name,
1462 resource_class, str_type, &value) == True)
1463 *XtRefOffset(options,rsrc->resource_offset) = value.addr;
1465 *XtRefOffset(options,rsrc->resource_offset) = rsrc->default_addr;
1469 if (*XtRefOffset(options,rsrc->resource_offset))
1470 printf("options%s: %s\n", (char *) rsrc->resource_name,
1471 (char *) *XtRefOffset(options,rsrc->resource_offset));
1473 printf("options%s: <NULL>\n", (char *) rsrc->resource_name);
1476 /* and calculate the page sizes */
1477 CalculatePageSize(db, options, name_prefix, class_prefix);
1484 ===================================================================
1485 $FUNBEG$: _DtHPrCreateTmpFile()
1486 $1LINER$: Creates a tmp file in $HOME/.dt/tmp
1488 The file is put in $HOME/.dt/tmp so that the
1489 file can be referenced from other systems. This
1490 assumes that the user home directory is mounted
1494 ========================================================$SKIP$=====*/
1497 char * _DtHPrCreateTmpFile(
1501 static int filecnt = 0;
1502 char dirname[MAXPATHLEN+1];
1508 if (NULL == prefix) prefix = EMPTY_STR;
1509 if (NULL == suffix) suffix = EMPTY_STR;
1511 GetHomeDir(dirname);
1512 tmppath = dirname + strlen(dirname) + 1;
1513 strcat(dirname, TMP_DIR_STR);
1515 /* create the directory */
1516 for ( tmppath = strchr(tmppath,DIR_SLASH);
1518 tmppath = strchr(++tmppath,DIR_SLASH) )
1521 mkdir(dirname,0777);
1522 *tmppath = DIR_SLASH;
1524 mkdir(dirname,0777);
1526 #define FILENAMELEN 25
1527 /* generate the new tmp file */
1528 newtmpfile=malloc((strlen(dirname) + FILENAMELEN + 2) * sizeof(char));
1529 if (NULL == newtmpfile)
1531 fprintf(stderr, "%s", _DTGETMESSAGE(INSET,45,
1532 "Error: Unable to allocate memory for temporary file\n"));
1536 sprintf(newtmpfile, _DTGETMESSAGE(INSET,50,"%1$s/%2$s%3$d_%4$d%5$s"),
1537 dirname, prefix, getpid(), filecnt++, suffix );