11abf7346Smrg/*
21abf7346Smrg
31abf7346SmrgCopyright (c) 1987, 1988  X Consortium
41abf7346Smrg
51abf7346SmrgPermission is hereby granted, free of charge, to any person obtaining
61abf7346Smrga copy of this software and associated documentation files (the
71abf7346Smrg"Software"), to deal in the Software without restriction, including
81abf7346Smrgwithout limitation the rights to use, copy, modify, merge, publish,
91abf7346Smrgdistribute, sublicense, and/or sell copies of the Software, and to
101abf7346Smrgpermit persons to whom the Software is furnished to do so, subject to
111abf7346Smrgthe following conditions:
121abf7346Smrg
131abf7346SmrgThe above copyright notice and this permission notice shall be included
141abf7346Smrgin all copies or substantial portions of the Software.
151abf7346Smrg
161abf7346SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
171abf7346SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
181abf7346SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
191abf7346SmrgIN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
201abf7346SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
211abf7346SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
221abf7346SmrgOTHER DEALINGS IN THE SOFTWARE.
231abf7346Smrg
241abf7346SmrgExcept as contained in this notice, the name of the X Consortium shall
251abf7346Smrgnot be used in advertising or otherwise to promote the sale, use or
261abf7346Smrgother dealings in this Software without prior written authorization
271abf7346Smrgfrom the X Consortium.
281abf7346Smrg
291abf7346Smrg*/
301abf7346Smrg
311abf7346Smrg/*
321abf7346Smrg * xman - X window system manual page display program.
331abf7346Smrg * Author:    Chris D. Peterson, MIT Project Athena
341abf7346Smrg * Created:   October 22, 1987
351abf7346Smrg */
361abf7346Smrg
371abf7346Smrg#include "globals.h"
381abf7346Smrg#ifndef ZERO
391abf7346Smrg#include <X11/Xaw/Cardinals.h>
401abf7346Smrg#endif /* ZERO */
411abf7346Smrg
426d36ef34Smrgstatic void ArgError(int argc, char **argv);
431abf7346Smrgstatic void AdjustDefResources(void);
441abf7346Smrg
451abf7346Smrg#define Offset(field) (XtOffsetOf(Xman_Resources , field))
461abf7346Smrg
471abf7346Smrgstatic XtResource my_resources[] = {
486d36ef34Smrg    {"directoryFontNormal", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
491abf7346Smrg     Offset(fonts.directory), XtRString, DIRECTORY_NORMAL},
506d36ef34Smrg    {"bothShown", XtCBoolean, XtRBoolean, sizeof(Boolean),
511abf7346Smrg     Offset(both_shown_initial), XtRString, "False"},
526d36ef34Smrg    {"directoryHeight", "DirectoryHeight", XtRInt, sizeof(int),
536d36ef34Smrg     Offset(directory_height), XtRString, "150"},
546d36ef34Smrg    {"topCursor", XtCCursor, XtRCursor, sizeof(Cursor),
551abf7346Smrg     Offset(cursors.top), XtRString, XMAN_CURSOR},
566d36ef34Smrg    {"helpCursor", XtCCursor, XtRCursor, sizeof(Cursor),
571abf7346Smrg     Offset(cursors.help), XtRString, HELP_CURSOR},
586d36ef34Smrg    {"manpageCursor", XtCCursor, XtRCursor, sizeof(Cursor),
591abf7346Smrg     Offset(cursors.manpage), XtRString, MANPAGE_CURSOR},
606d36ef34Smrg    {"searchEntryCursor", XtCCursor, XtRCursor, sizeof(Cursor),
611abf7346Smrg     Offset(cursors.search_entry), XtRString, SEARCH_ENTRY_CURSOR},
626d36ef34Smrg    {"pointerColor", XtCForeground, XtRPixel, sizeof(Pixel),
631abf7346Smrg     Offset(cursors.fg_color), XtRString, "XtDefaultForeground"},
646d36ef34Smrg    {"pointerColorBackground", XtCBackground, XtRPixel, sizeof(Pixel),
651abf7346Smrg     Offset(cursors.bg_color), XtRString, "XtDefaultBackground"},
666d36ef34Smrg    {"help", XtCBoolean, XtRBoolean, sizeof(Boolean),
678b6d6341Smrg     Offset(show_help_syntax), XtRImmediate, NULL},
686d36ef34Smrg    {"helpFile", XtCFile, XtRString, sizeof(char *),
691abf7346Smrg     Offset(help_file), XtRString, HELPFILE},
706d36ef34Smrg    {"topBox", XtCBoolean, XtRBoolean, sizeof(Boolean),
711abf7346Smrg     Offset(top_box_active), XtRString, "True"},
726d36ef34Smrg    {"clearSearchString", "ClearSearchString", XtRBoolean, sizeof(Boolean),
731abf7346Smrg     Offset(clear_search_string), XtRImmediate, (caddr_t) TRUE},
746d36ef34Smrg    {"title", XtCString, XtRString, sizeof(char *),
751abf7346Smrg     Offset(title), XtRString, "xman"},
766d36ef34Smrg    {"iconic", XtCBoolean, XtRBoolean, sizeof(Boolean),
771abf7346Smrg     Offset(iconic), XtRString, "False"},
781abf7346Smrg};
791abf7346Smrg
801abf7346Smrg#undef Offset
811abf7346Smrg
821abf7346Smrg/*
831abf7346Smrg * The resource that we absolutely need.
841abf7346Smrg */
851abf7346Smrg
86ae5a67adSmrgstatic String fallback_resources[] = {
876d36ef34Smrg    "Xman*quitButton.translations:	#override \\n   <Btn1Up>: Quit() reset()",
886d36ef34Smrg    "Xman*helpButton.sensitive:                    FALSE",
896d36ef34Smrg    "Xman*manpageButton.sensitive:                 FALSE",
906d36ef34Smrg    "Xman*helpButton.Label:			Help",
916d36ef34Smrg    "Xman*quitButton.Label:			Quit",
926d36ef34Smrg    "Xman*manpageButton.Label:		        Manual Page",
936d36ef34Smrg    "Xman*topLabel.label:         		        No App-Defaults File",
946d36ef34Smrg    NULL,
951abf7346Smrg};
961abf7346Smrg
971abf7346Smrg/*
981abf7346Smrg * This is necessary to keep all TopLevel shells from becoming
991abf7346Smrg * the size that is specified on the command line.
1001abf7346Smrg */
1011abf7346Smrg
1021abf7346Smrgstatic XrmOptionDescRec xman_options[] = {
1036d36ef34Smrg    {"-geometry", "*topBox.geometry", XrmoptionSepArg, (caddr_t) NULL},
1046d36ef34Smrg    {"-help", "help", XrmoptionNoArg, (caddr_t) "True"},
1056d36ef34Smrg    {"=", "*topBox.geometry", XrmoptionIsArg, (caddr_t) NULL},
1066d36ef34Smrg    {"-pagesize", "*manualBrowser.geometry", XrmoptionSepArg, (caddr_t) NULL},
1076d36ef34Smrg    {"-notopbox", "topBox", XrmoptionNoArg, (caddr_t) "False"},
1086d36ef34Smrg    {"-helpfile", "helpFile", XrmoptionSepArg, (caddr_t) NULL},
1096d36ef34Smrg    {"-bothshown", "bothShown", XrmoptionNoArg, (caddr_t) "True"},
1106d36ef34Smrg    {"-title", "title", XrmoptionSepArg, (caddr_t) "xman"},
1116d36ef34Smrg    {"-iconic", "iconic", XrmoptionNoArg, (caddr_t) "True"},
1121abf7346Smrg};
1131abf7346Smrg
1148b6d6341Smrgstatic XtActionsRec xman_actions[] = {
1156d36ef34Smrg    {"GotoPage", GotoPage},
1166d36ef34Smrg    {"Quit", Quit},
1176d36ef34Smrg    {"Search", Search},
1186d36ef34Smrg    {"PopupHelp", PopupHelp},
1196d36ef34Smrg    {"PopupSearch", PopupSearch},
120a5a2a776Smrg    {"RemoveSearch", RemoveSearch},
1216d36ef34Smrg    {"CreateNewManpage", CreateNewManpage},
1226d36ef34Smrg    {"RemoveThisManpage", RemoveThisManpage},
1236d36ef34Smrg    {"SaveFormattedPage", SaveFormattedPage},
1246d36ef34Smrg    {"ShowVersion", ShowVersion},
1251abf7346Smrg};
1261abf7346Smrg
1271abf7346Smrgchar **saved_argv;
1281abf7346Smrgint saved_argc;
1291abf7346Smrg
1301abf7346Smrg/*
1311abf7346Smrg * This atom is used to make the application ICCCM compliant.
1321abf7346Smrg */
1331abf7346SmrgAtom wm_delete_window;
1341abf7346Smrg
1351abf7346Smrg/*	Function Name: main
1361abf7346Smrg *	Description: This is the main driver for Xman.
1371abf7346Smrg *	Arguments: argc, argv - the command line arguments.
1381abf7346Smrg *	Returns: return, what return.
1391abf7346Smrg */
1401abf7346Smrg
1416d36ef34Smrgint
1426d36ef34Smrgmain(int argc, char **argv)
1431abf7346Smrg{
1446d36ef34Smrg    XtAppContext app_con;
1451abf7346Smrg
1466d36ef34Smrg    saved_argc = argc;
1476d36ef34Smrg    saved_argv = (char **) XtMalloc(argc * sizeof(char *));
1486d36ef34Smrg    bcopy(argv, saved_argv, argc * sizeof(char *));
1491abf7346Smrg
1506d36ef34Smrg    XtSetLanguageProc(NULL, (XtLanguageProc) NULL, NULL);
1511abf7346Smrg
152a5a2a776Smrg    /* Handle args that don't require opening a display */
153a5a2a776Smrg    for (int i = 1; i < argc; i++) {
154a5a2a776Smrg        const char *arg = argv[i];
155a5a2a776Smrg        /* accept single or double dash for -help & -version */
156a5a2a776Smrg        if (arg[0] == '-' && arg[1] == '-') {
157a5a2a776Smrg            arg++;
158a5a2a776Smrg        }
159a5a2a776Smrg        if (strcmp(arg, "-help") == 0) {
160a5a2a776Smrg            ArgError(0, NULL);
161a5a2a776Smrg            exit(0);
162a5a2a776Smrg        }
163a5a2a776Smrg        if (strcmp(arg, "-version") == 0) {
164a5a2a776Smrg            puts(PACKAGE_STRING);
165a5a2a776Smrg            exit(0);
166a5a2a776Smrg        }
167a5a2a776Smrg    }
168a5a2a776Smrg
1696d36ef34Smrg    initial_widget = XtAppInitialize(&app_con, "Xman", xman_options,
1706d36ef34Smrg                                     XtNumber(xman_options), &argc, argv,
1716d36ef34Smrg                                     fallback_resources, NULL, ZERO);
1726d36ef34Smrg    wm_delete_window =
1736d36ef34Smrg        XInternAtom(XtDisplay(initial_widget), "WM_DELETE_WINDOW", False);
1741abf7346Smrg
1756d36ef34Smrg    manglobals_context = XStringToContext(MANNAME);
1761abf7346Smrg
1776d36ef34Smrg    AdjustDefResources();
1781abf7346Smrg
1796d36ef34Smrg    XtGetApplicationResources(initial_widget, (caddr_t) & resources,
1806d36ef34Smrg                              my_resources, XtNumber(my_resources),
1816d36ef34Smrg                              NULL, (Cardinal) 0);
1821abf7346Smrg
1836d36ef34Smrg    if ((argc != 1) || (resources.show_help_syntax)) {
1846d36ef34Smrg        ArgError(argc, argv);
1856d36ef34Smrg        return EXIT_FAILURE;
1866d36ef34Smrg    }
1871abf7346Smrg
1886d36ef34Smrg    XtAppAddActions(app_con, xman_actions, XtNumber(xman_actions));
1891abf7346Smrg
1906d36ef34Smrg    if (!resources.fonts.directory)
1916d36ef34Smrg        PrintError("Failed to get the directory font.");
1921abf7346Smrg
1931abf7346Smrg#ifdef DEBUG
1946d36ef34Smrg    printf("debugging mode\n");
1951abf7346Smrg#endif
1961abf7346Smrg
1971abf7346Smrg/*
1981abf7346Smrg * Set the default width and height.
1991abf7346Smrg * I am not real happy with this method, but it will usually do something
2001abf7346Smrg * reasonable, if not the "right" thing.  It is not a real big issue since
2011abf7346Smrg * it is easy to change the values with resources or command line options.
2021abf7346Smrg * NOTE: if you are in a 100 dpi display you will lose.
2031abf7346Smrg */
2041abf7346Smrg
2056d36ef34Smrg    default_width = DEFAULT_WIDTH;
2066d36ef34Smrg    default_height = DisplayHeight(XtDisplay(initial_widget),
2076d36ef34Smrg                                   DefaultScreen(XtDisplay(initial_widget)));
2086d36ef34Smrg    default_height *= 3;
2096d36ef34Smrg    default_height /= 4;
2101abf7346Smrg
2116d36ef34Smrg    if ((sections = Man()) == 0)
2126d36ef34Smrg        PrintError
2136d36ef34Smrg            ("There are no manual sections to display, check your MANPATH.");
2141abf7346Smrg
2156d36ef34Smrg    if (resources.top_box_active)
2166d36ef34Smrg        MakeTopBox();
2176d36ef34Smrg    else
2186d36ef34Smrg        (void) CreateManpage(NULL);
2191abf7346Smrg
2201abf7346Smrg/*
2211abf7346Smrg * We need to keep track of the number of manual pages that are shown on
222da4a0041Smrg * the screen so that if this user does not have a top box then when they
223da4a0041Smrg * remove all their manual pages we can kill off the xman process.
2241abf7346Smrg * To make things easier we will consider the top box a shown manual page
2251abf7346Smrg * here, but since you cannot remove it, man_page_shown only goes to zero when
2261abf7346Smrg * no top box is present.
2271abf7346Smrg */
2281abf7346Smrg
2296d36ef34Smrg    man_pages_shown = 1;
2301abf7346Smrg
2316d36ef34Smrg    XtAppMainLoop(app_con);
2321abf7346Smrg
2336d36ef34Smrg    return EXIT_SUCCESS;
2341abf7346Smrg}
2351abf7346Smrg
2361abf7346Smrg/*	Function Name: ArgError
2376d36ef34Smrg *	Description:  Prints error message about unknown arguments.
2381abf7346Smrg *	Arguments: argc, argv - args not understood.
2391abf7346Smrg *	Returns: none.
2401abf7346Smrg */
2411abf7346Smrg
2426d36ef34Smrgstatic void
2436d36ef34SmrgArgError(int argc, char **argv)
2441abf7346Smrg{
2456d36ef34Smrg    int i;
2466d36ef34Smrg
2476d36ef34Smrg    static const char **syntax, *syntax_def[] = {
2486d36ef34Smrg        "-help", "Print this message",
2496d36ef34Smrg        "-helpfile <filename>", "Specifies the helpfile to use.",
2506d36ef34Smrg        "-bothshown", "Show both the directory and manpage at once.",
2516d36ef34Smrg        "-notopbox", "Starts with manpage rather than topbox.",
2526d36ef34Smrg        "-geometry <geom>", "Specifies the geometry of the top box.",
2536d36ef34Smrg        "=<geom>", "Specifies the geometry of the top box.",
2546d36ef34Smrg        "-pagesize <geom>", "Specifies the geometry of the manual page.",
2556d36ef34Smrg        "-bw <pixels>", "Width of all window borders.",
2566d36ef34Smrg        "-borderwidth <pixels>", "Width of all window borders.",
2576d36ef34Smrg        "-bd <color>", "Color of all window borders.",
2586d36ef34Smrg        "-bordercolor <color>", "Color of all window borders.",
2596d36ef34Smrg        "-fg <color>", "Foreground color for the application.",
2606d36ef34Smrg        "-foreground <color>", "Foreground color for the application.",
2616d36ef34Smrg        "-bg <color>", "Background color for the application.",
2626d36ef34Smrg        "-background <color>", "Background color for the application.",
2636d36ef34Smrg        "-display <display name>", "Specify a display that is not the default",
2646d36ef34Smrg        "-fn <font>", "Font to be used for button and label text.",
2656d36ef34Smrg        "-font <font>", "Font to be used for button and label text.",
2666d36ef34Smrg        "-name <name>", "Change the name used for retrieving resources.",
2676d36ef34Smrg        "-title <name>", "Change the name without affecting resources.",
2686d36ef34Smrg        "-xrm <resource>", "Specifies a resource on the command line.",
2696d36ef34Smrg        NULL, NULL,
2706d36ef34Smrg    };
2716d36ef34Smrg
2726d36ef34Smrg    syntax = syntax_def;
2736d36ef34Smrg
2746d36ef34Smrg    for (i = 1; i < argc; i++)
2756d36ef34Smrg        (void) printf("This argument is unknown to Xman: %s\n", argv[i]);
2766d36ef34Smrg
2776d36ef34Smrg    (void) printf("\nKnown arguments are:\n");
2786d36ef34Smrg
2796d36ef34Smrg    while (*syntax != NULL) {
2806d36ef34Smrg        printf("%-30s - %s\n", syntax[0], syntax[1]);
2816d36ef34Smrg        syntax += 2;
2826d36ef34Smrg    }
2831abf7346Smrg}
2841abf7346Smrg
2851abf7346Smrg/*    Function Name: AdjustDefResources
2861abf7346Smrg *    Description: Changes default resources which contain paths when
2871abf7346Smrg *            XWINHOME is set
2881abf7346Smrg *    Arguments: none
2891abf7346Smrg *    Returns: nothing
2901abf7346Smrg */
2911abf7346Smrg
2921abf7346Smrgstatic void
2931abf7346SmrgAdjustDefResources(void)
2941abf7346Smrg{
2956d36ef34Smrg    char *xwinhome = NULL;
2966d36ef34Smrg    int i;
2976d36ef34Smrg
2986d36ef34Smrg    if (!(xwinhome = getenv("XWINHOME")))
2996d36ef34Smrg        return;
3006d36ef34Smrg
3016d36ef34Smrg    for (i = 0; i < sizeof(my_resources) / sizeof(XtResource); i++) {
3026d36ef34Smrg        if (!strcmp(my_resources[i].resource_name, "helpFile")) {
3036d36ef34Smrg            char filename[PATH_MAX];
3046d36ef34Smrg
3056d36ef34Smrg            snprintf(filename, sizeof(filename), "%s/lib/X11/xman.help",
3066d36ef34Smrg                     xwinhome);
3076d36ef34Smrg            if (!(my_resources[i].default_addr = strdup(filename))) {
3086d36ef34Smrg                fprintf(stderr, "malloc failure\n");
3096d36ef34Smrg                exit(EXIT_FAILURE);
3106d36ef34Smrg            }
3116d36ef34Smrg        }
3121abf7346Smrg    }
3131abf7346Smrg}
314