main.c revision 6d36ef34
1/*
2
3Copyright (c) 1987, 1988  X Consortium
4
5Permission is hereby granted, free of charge, to any person obtaining
6a copy of this software and associated documentation files (the
7"Software"), to deal in the Software without restriction, including
8without limitation the rights to use, copy, modify, merge, publish,
9distribute, sublicense, and/or sell copies of the Software, and to
10permit persons to whom the Software is furnished to do so, subject to
11the following conditions:
12
13The above copyright notice and this permission notice shall be included
14in all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
20OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of the X Consortium shall
25not be used in advertising or otherwise to promote the sale, use or
26other dealings in this Software without prior written authorization
27from the X Consortium.
28
29*/
30
31/*
32 * xman - X window system manual page display program.
33 * Author:    Chris D. Peterson, MIT Project Athena
34 * Created:   October 22, 1987
35 */
36
37#include "globals.h"
38#ifndef ZERO
39#include <X11/Xaw/Cardinals.h>
40#endif /* ZERO */
41
42static void ArgError(int argc, char **argv);
43static void AdjustDefResources(void);
44
45#define Offset(field) (XtOffsetOf(Xman_Resources , field))
46
47static XtResource my_resources[] = {
48    {"directoryFontNormal", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
49     Offset(fonts.directory), XtRString, DIRECTORY_NORMAL},
50    {"bothShown", XtCBoolean, XtRBoolean, sizeof(Boolean),
51     Offset(both_shown_initial), XtRString, "False"},
52    {"directoryHeight", "DirectoryHeight", XtRInt, sizeof(int),
53     Offset(directory_height), XtRString, "150"},
54    {"topCursor", XtCCursor, XtRCursor, sizeof(Cursor),
55     Offset(cursors.top), XtRString, XMAN_CURSOR},
56    {"helpCursor", XtCCursor, XtRCursor, sizeof(Cursor),
57     Offset(cursors.help), XtRString, HELP_CURSOR},
58    {"manpageCursor", XtCCursor, XtRCursor, sizeof(Cursor),
59     Offset(cursors.manpage), XtRString, MANPAGE_CURSOR},
60    {"searchEntryCursor", XtCCursor, XtRCursor, sizeof(Cursor),
61     Offset(cursors.search_entry), XtRString, SEARCH_ENTRY_CURSOR},
62    {"pointerColor", XtCForeground, XtRPixel, sizeof(Pixel),
63     Offset(cursors.fg_color), XtRString, "XtDefaultForeground"},
64    {"pointerColorBackground", XtCBackground, XtRPixel, sizeof(Pixel),
65     Offset(cursors.bg_color), XtRString, "XtDefaultBackground"},
66    {"help", XtCBoolean, XtRBoolean, sizeof(Boolean),
67     Offset(show_help_syntax), XtRImmediate, NULL},
68    {"helpFile", XtCFile, XtRString, sizeof(char *),
69     Offset(help_file), XtRString, HELPFILE},
70    {"topBox", XtCBoolean, XtRBoolean, sizeof(Boolean),
71     Offset(top_box_active), XtRString, "True"},
72    {"clearSearchString", "ClearSearchString", XtRBoolean, sizeof(Boolean),
73     Offset(clear_search_string), XtRImmediate, (caddr_t) TRUE},
74    {"title", XtCString, XtRString, sizeof(char *),
75     Offset(title), XtRString, "xman"},
76    {"iconic", XtCBoolean, XtRBoolean, sizeof(Boolean),
77     Offset(iconic), XtRString, "False"},
78};
79
80#undef Offset
81
82/*
83 * The resource that we absolutely need.
84 */
85
86static char *fallback_resources[] = {
87    "Xman*quitButton.translations:	#override \\n   <Btn1Up>: Quit() reset()",
88    "Xman*helpButton.sensitive:                    FALSE",
89    "Xman*manpageButton.sensitive:                 FALSE",
90    "Xman*helpButton.Label:			Help",
91    "Xman*quitButton.Label:			Quit",
92    "Xman*manpageButton.Label:		        Manual Page",
93    "Xman*topLabel.label:         		        No App-Defaults File",
94    NULL,
95};
96
97/*
98 * This is necessary to keep all TopLevel shells from becoming
99 * the size that is specified on the command line.
100 */
101
102static XrmOptionDescRec xman_options[] = {
103    {"-geometry", "*topBox.geometry", XrmoptionSepArg, (caddr_t) NULL},
104    {"-help", "help", XrmoptionNoArg, (caddr_t) "True"},
105    {"=", "*topBox.geometry", XrmoptionIsArg, (caddr_t) NULL},
106    {"-pagesize", "*manualBrowser.geometry", XrmoptionSepArg, (caddr_t) NULL},
107    {"-notopbox", "topBox", XrmoptionNoArg, (caddr_t) "False"},
108    {"-helpfile", "helpFile", XrmoptionSepArg, (caddr_t) NULL},
109    {"-bothshown", "bothShown", XrmoptionNoArg, (caddr_t) "True"},
110    {"-title", "title", XrmoptionSepArg, (caddr_t) "xman"},
111    {"-iconic", "iconic", XrmoptionNoArg, (caddr_t) "True"},
112};
113
114static XtActionsRec xman_actions[] = {
115    {"GotoPage", GotoPage},
116    {"Quit", Quit},
117    {"Search", Search},
118    {"PopupHelp", PopupHelp},
119    {"PopupSearch", PopupSearch},
120    {"CreateNewManpage", CreateNewManpage},
121    {"RemoveThisManpage", RemoveThisManpage},
122    {"SaveFormattedPage", SaveFormattedPage},
123#ifdef INCLUDE_XPRINT_SUPPORT
124    {"PrintThisManpage", PrintThisManpage},
125#endif                          /* INCLUDE_XPRINT_SUPPORT */
126    {"ShowVersion", ShowVersion},
127};
128
129char **saved_argv;
130int saved_argc;
131
132/*
133 * This atom is used to make the application ICCCM compliant.
134 */
135Atom wm_delete_window;
136
137/*	Function Name: main
138 *	Description: This is the main driver for Xman.
139 *	Arguments: argc, argv - the command line arguments.
140 *	Returns: return, what return.
141 */
142
143int
144main(int argc, char **argv)
145{
146    XtAppContext app_con;
147
148    saved_argc = argc;
149    saved_argv = (char **) XtMalloc(argc * sizeof(char *));
150    bcopy(argv, saved_argv, argc * sizeof(char *));
151
152    XtSetLanguageProc(NULL, (XtLanguageProc) NULL, NULL);
153
154    initial_widget = XtAppInitialize(&app_con, "Xman", xman_options,
155                                     XtNumber(xman_options), &argc, argv,
156                                     fallback_resources, NULL, ZERO);
157    wm_delete_window =
158        XInternAtom(XtDisplay(initial_widget), "WM_DELETE_WINDOW", False);
159
160    manglobals_context = XStringToContext(MANNAME);
161
162    AdjustDefResources();
163
164    XtGetApplicationResources(initial_widget, (caddr_t) & resources,
165                              my_resources, XtNumber(my_resources),
166                              NULL, (Cardinal) 0);
167
168    if ((argc != 1) || (resources.show_help_syntax)) {
169        ArgError(argc, argv);
170        return EXIT_FAILURE;
171    }
172
173    XtAppAddActions(app_con, xman_actions, XtNumber(xman_actions));
174
175    if (!resources.fonts.directory)
176        PrintError("Failed to get the directory font.");
177
178#ifdef DEBUG
179    printf("debugging mode\n");
180#endif
181
182/*
183 * Set the default width and height.
184 * I am not real happy with this method, but it will usually do something
185 * reasonable, if not the "right" thing.  It is not a real big issue since
186 * it is easy to change the values with resources or command line options.
187 * NOTE: if you are in a 100 dpi display you will lose.
188 */
189
190    default_width = DEFAULT_WIDTH;
191    default_height = DisplayHeight(XtDisplay(initial_widget),
192                                   DefaultScreen(XtDisplay(initial_widget)));
193    default_height *= 3;
194    default_height /= 4;
195
196    if ((sections = Man()) == 0)
197        PrintError
198            ("There are no manual sections to display, check your MANPATH.");
199
200    if (resources.top_box_active)
201        MakeTopBox();
202    else
203        (void) CreateManpage(NULL);
204
205/*
206 * We need to keep track of the number of manual pages that are shown on
207 * the screen so that if this user does not have a top box then when he
208 * removes all his manual pages we can kill off the xman process.
209 * To make things easier we will consider the top box a shown manual page
210 * here, but since you cannot remove it, man_page_shown only goes to zero when
211 * no top box is present.
212 */
213
214    man_pages_shown = 1;
215
216    XtAppMainLoop(app_con);
217
218    return EXIT_SUCCESS;
219}
220
221/*	Function Name: ArgError
222 *	Description:  Prints error message about unknown arguments.
223 *	Arguments: argc, argv - args not understood.
224 *	Returns: none.
225 */
226
227static void
228ArgError(int argc, char **argv)
229{
230    int i;
231
232    static const char **syntax, *syntax_def[] = {
233        "-help", "Print this message",
234        "-helpfile <filename>", "Specifies the helpfile to use.",
235        "-bothshown", "Show both the directory and manpage at once.",
236        "-notopbox", "Starts with manpage rather than topbox.",
237        "-geometry <geom>", "Specifies the geometry of the top box.",
238        "=<geom>", "Specifies the geometry of the top box.",
239        "-pagesize <geom>", "Specifies the geometry of the manual page.",
240        "-bw <pixels>", "Width of all window borders.",
241        "-borderwidth <pixels>", "Width of all window borders.",
242        "-bd <color>", "Color of all window borders.",
243        "-bordercolor <color>", "Color of all window borders.",
244        "-fg <color>", "Foreground color for the application.",
245        "-foreground <color>", "Foreground color for the application.",
246        "-bg <color>", "Background color for the application.",
247        "-background <color>", "Background color for the application.",
248        "-display <display name>", "Specify a display that is not the default",
249        "-fn <font>", "Font to be used for button and label text.",
250        "-font <font>", "Font to be used for button and label text.",
251        "-name <name>", "Change the name used for retrieving resources.",
252        "-title <name>", "Change the name without affecting resources.",
253        "-xrm <resource>", "Specifies a resource on the command line.",
254        NULL, NULL,
255    };
256
257    syntax = syntax_def;
258
259    for (i = 1; i < argc; i++)
260        (void) printf("This argument is unknown to Xman: %s\n", argv[i]);
261
262    (void) printf("\nKnown arguments are:\n");
263
264    while (*syntax != NULL) {
265        printf("%-30s - %s\n", syntax[0], syntax[1]);
266        syntax += 2;
267    }
268}
269
270/*    Function Name: AdjustDefResources
271 *    Description: Changes default resources which contain paths when
272 *            XWINHOME is set
273 *    Arguments: none
274 *    Returns: nothing
275 */
276
277static void
278AdjustDefResources(void)
279{
280    char *xwinhome = NULL;
281    int i;
282
283    if (!(xwinhome = getenv("XWINHOME")))
284        return;
285
286    for (i = 0; i < sizeof(my_resources) / sizeof(XtResource); i++) {
287        if (!strcmp(my_resources[i].resource_name, "helpFile")) {
288            char filename[PATH_MAX];
289
290            snprintf(filename, sizeof(filename), "%s/lib/X11/xman.help",
291                     xwinhome);
292            if (!(my_resources[i].default_addr = strdup(filename))) {
293                fprintf(stderr, "malloc failure\n");
294                exit(EXIT_FAILURE);
295            }
296        }
297    }
298}
299