        Global variables

<<*>>=
#include "config.h"
#include <ulimit.h>
#include <Xm/Xm.h>
#include <Xm/RepType.h>
#include <Xm/Scale.h>
#include <X11/Xmu/Editres.h>
#include <X11/cursorfont.h>
#include <Xfwf/Converters.h>
#include <Xfwf/PcBar.h>
#include "str.h"
#include "w3a.h"
#include <w3alib.h>
#include "rcfile.e"

#ifndef CONFIGFILE 
#define CONFIGFILE ".argorc"
#endif
#ifndef HOMEPAGE
#define HOMEPAGE "http://www.let.rug.nl/"
#endif
#ifndef HELP_URL
#define HELP_URL "http://www.let.rug.nl/~bert/Argodocs/0.2/"
EXPORTDEF(HELP_URL)
#endif

#define VERSION "0.2"
EXPORTDEF(VERSION)

#if 1
#define MAX_ACTIVE 4				/* Concurrent requests */
#define MAX_RESERVE 4				/* Extra for high-priority */
#else
#define MAX_ACTIVE 1				/* Concurrent requests */
#define MAX_RESERVE 0				/* Extra for high-priority */
#endif
EXPORTDEF(MAX_ACTIVE)
EXPORTDEF(MAX_RESERVE)

#if 0
#define MAX_BARS_SHOWN MAX_ACTIVE		/* How many progress bars */
#else
#define MAX_BARS_SHOWN 1			/* How many progress bars */
#endif
EXPORTDEF(MAX_BARS_SHOWN)

#define INPUT_ERROR -1
EXPORTDEF(INPUT_ERROR)
#define INPUT_BUSY 0
EXPORTDEF(INPUT_BUSY)
#define INPUT_READY 1
EXPORTDEF(INPUT_READY)

EXPORT typedef struct {
    String homepage;
    String configfile;
    String proxy;
    String noproxy;
} AppData;

EXPORT Widget toplevel, tabs, area, status, scale, interrupt, functionsmenu;
EXPORT Widget tools, location;			/* Toolbar along left side */
EXPORT XtAppContext app_context;
EXPORT AppData appdata;
EXPORT int seqnr = 0;				/* Unique document number */
EXPORT Cursor waitcursor;			/* Watch cursor */

static XtResource resources[] = {
    {"homepage", "Homepage", XtRString, sizeof(String),
        XtOffsetOf(AppData, homepage), XtRImmediate, HOMEPAGE},
    {"configfile", "Configfile", XtRString, sizeof(String),
        XtOffsetOf(AppData, configfile), XtRImmediate, CONFIGFILE},
    {"proxy", "Proxy", XtRString, sizeof(String),
        XtOffsetOf(AppData, proxy), XtRImmediate, NULL},
    {"noproxy", "Noproxy", XtRString, sizeof(String),
        XtOffsetOf(AppData, noproxy), XtRImmediate, NULL},
};

static XrmOptionDescRec options[] = {
    {"-config", ".configfile", XrmoptionSepArg, NULL},
    {"-proxy", ".proxy", XrmoptionSepArg, NULL},
    {"-noproxy", ".noproxy", XrmoptionSepArg, NULL},
};

static String fallback[] = {
    "Argo.width: 700",
    "Argo.height: 800",
    "*tabs.height: 32",
    "*tabs.font: *-helvetica-medium-r-*-12-*-iso8859-1",
    "*tabs.foreground: #ffffffffaaaa",
    "*tabs.tabcolor: #a5a5a5a5a5a5",
    "*tabs.tabWidthPercentage: 66",
    "*XmTabs.shadowThickness: 2",
    "*tabs.background: #bdbdbdbdbdbd",
    "*tabs.textmargin: 1",
    "*tabs.cornerwith: 5",
    "*tabs.cornerheight: 15",
    "*open-form.dialogTitle: Open a URL",
    "*open-label.labelString: URL: ",
    "*open-ok.labelString: \\ OK ",
    "*open-cancel.labelString: \\ Cancel ",
    "*open-text.columns: 40",
    "*open-form.verticalSpacing: 10",
    "*open-form.horizontalSpacing: 10",
    "*tools.width: 50",
    "*area.shadowThickness: 0",
    "*area.viewer.shadowThickness: 0",
    "*area.viewer.shadowType: SHADOW_IN",
    "*form.marginHeight: 5",
    "*form.marginWidth: 2",
    "*form.background: #aaaab6b6aaaa",
    "*form.tools*background: #aaaab6b6aaaa",
    "*form.location.background: #ffffdbdbaaaa",
    "*form.locationlabel.background: #aaaab6b6aaaa",
    "*form.area.background: #aaaab6b6aaaa",
    /* "*form.area.?*background: #bdbdbdbdbdbd", */

    "*home.labelString: Home",
    "*save.labelString: Save...",
    "*open.labelString: Open...",
    "*reload.labelString: Reload",
    "*clone.labelString: Clone",
    "*interrupt.labelString: Interrupt",

    "*filebutton.labelString: File",
    "*filebutton.mnemonic: F",
    "*functionsbutton.labelString: Accessories",
    "*functionsbutton.mnemonic: A",
    "*helpbutton.labelString: Help",
    "*helpbutton.mnemonic: H",

    "*menu-open.labelString: Open...",
    "*menu-open.mnemonic: O",
    "*menu-open.accelerator: Alt<Key>O",
    "*menu-open.acceleratorText: Alt-O",

    "*menu-save.labelString: Save...",
    "*menu-save.mnemonic: S",
    "*menu-save.accelerator: Alt<Key>S",
    "*menu-save.acceleratorText: Alt-S",

    "*menu-home.labelString: Home",
    "*menu-home.mnemonic: m",
    "*menu-home.accelerator: Alt<Key>M",
    "*menu-home.acceleratorText: Alt-M",

    "*menu-reload.labelString: Reload",
    "*menu-reload.mnemonic: R",
    "*menu-reload.accelerator: Alt<Key>R",
    "*menu-reload.acceleratorText: Alt-R",

    "*menu-source.labelString: View source",
    "*menu-source.mnemonic: V",
    "*menu-source.accelerator: Alt<Key>V",
    "*menu-source.acceleratorText: Alt-V",

    "*menu-clone.labelString: Clone window",
    "*menu-clone.mnemonic: C",
    "*menu-clone.accelerator: Alt<Key>C",
    "*menu-clone.acceleratorText: Alt-C",

    "*menu-exit.labelString: Exit",
    "*menu-exit.mnemonic: x",
    "*menu-exit.accelerator: Alt<Key>X",
    "*menu-exit.acceleratorText: Alt+X",

    "*menu-help.labelString: Help on version " VERSION,
    "*menu-help.mnemonic: H",

    "*status.font: *-helvetica-medium-r-*-14-*-iso8859-1",
    "*locationlabel.labelString: URL:",
    "*locationlabel.height: 35",
    "*location.height: 35",
    "*warning.title: Warning",
    "*error.title: Error",
    "*bar.width: 35",
    "*bar.height: 5",
    "*bar.displaypc: False",
    "*bar.foreground: green",
    "*tools.entryBorder: 1",
    "*XmPanedWindow*allowResize: True",
    "Argo.Error.geometry: 300x100+200+200",
    "Argo.Warning.geometry: 300x100+200+200",

    "*warning_popup.title: Warning!",

    "*telnet.background: black",
    "*telnet.foreground: green",
    "*telnet-board.shadowThickness: 0",
    "*telnet.font: -*-courier-medium-r-normal--*-120-*-*-*-*-iso8859-1",

    "*html-form*background: #bdbdbdbdbdbd",
    "*html*fontFamily1: new century schoolbook",
    "*html*inline.width: 50",
    "*html*inline.height: 50",
    "*html-form*inline.background: #ffffb6b60000",
    "*html-form.width: 100",
    "*html-form.height: 100",
    "*html-status.width: 100",
    "*html-status.height: 20",
    "*html-status.resizable: False",
    "*html-status.foreground: #ffffffffaaaa",
    "*html-status.labelString: -",
    "*html-form*html-status.background: #aaaa6d6d5555",
    "*html-form*html-status.foreground: white",
    "*html-status.fontList: *-helvetica-medium-r-*-12-*-iso8859-1",
    "*html-form*balloon*background: #ffffffff0000",
    "*html-form*balloon*foreground: black",
    "*html-form*balloon*borderWidth: 1",
    "*html-form.marginWidth: 0",
    "*html-form.marginHeight: 0",
    "*html-form.sashHeight: 0",
    "*html-form.sashShadowThickness: 0",
    "*html-form.sashWidth: 0",
    "*html-form.separatorOn: False",
    "*html-form.spacing: 0",
    "*html-form.shadowThickness: 0",
    "*html*XmToggleButton.selectColor: red",
    "*activeCursor: hand2",

    "*XfwfSimpleSGML.style: *STYLE.stylesheet:override",
    "*sgml-form*background: #bdbdbdbdbdbd",
    "*sgml*fontFamily1: new century schoolbook",
    "*sgml*inline.width: 50",
    "*sgml*inline.height: 50",
    "*sgml-form*inline.background: #ffffb6b60000",
    "*sgml-form.width: 100",
    "*sgml-form.height: 100",
    "*sgml-status.width: 100",
    "*sgml-status.height: 20",
    "*sgml-status.resizable: False",
    "*sgml-status.foreground: #ffffffffaaaa",
    "*sgml-status.labelString: -",
    "*sgml-form*sgml-status.background: #aaaa6d6d5555",
    "*sgml-form*sgml-status.foreground: white",
    "*sgml-status.fontList: *-helvetica-medium-r-*-12-*-iso8859-1",
    "*sgml-form*balloon*background: #ffffffff0000",
    "*sgml-form*balloon*foreground: black",
    "*sgml-form*balloon*borderWidth: 1",
    "*sgml-form.marginWidth: 0",
    "*sgml-form.marginHeight: 0",
    "*sgml-form.sashHeight: 0",
    "*sgml-form.sashShadowThickness: 0",
    "*sgml-form.sashWidth: 0",
    "*sgml-form.separatorOn: False",
    "*sgml-form.spacing: 0",
    "*sgml-form.shadowThickness: 0",
    "*sgml*XmToggleButton.selectColor: red",

    "*plain.foreground: black",
    "*plain.fontFamily: -*-courier-*-*-*-*-0-0-*-*-*-*-iso8859-1",
    "*plain.lines: 35",
    "*hotlist.geometry: 500x400+350+300",
    "*history.geometry: 500x400+350+300",
    "*mail-compose.geometry: 500x400+350+300",
    "*mail-compose*dialogTitle: Mail Compose",

    "*postscript.prev.fontList: *symbol-medium-r-normal--*-140-*-*-*-*-*",
    "*postscript.prev.labelString: \254",
    "*postscript.next.fontList: *symbol-medium-r-normal--*-140-*-*-*-*-*",
    "*postscript.next.labelString: \256",
    "*postscript.to-start.fontList: *symbol-medium-r-normal--*-140-*-*-*-*-*",
    "*postscript.to-start.labelString: \275\254",
    "*postscript.to-end.fontList: *symbol-medium-r-normal--*-140-*-*-*-*-*",
    "*postscript.to-end.labelString: \256\275",
    "*postscript.zoom-in.labelString: Zoom +",
    "*postscript.zoom-out.labelString: Zoom -",
    "*postscript.separator.separatorType: XmSINGLE_LINE",
    "*postscript*canvas.background: #FBFBFF",
    "*postscript*canvas.borderWidth: 0",

    /* The following should be *html.style,
     * but for testing I removed the `html':
     * now it works for any SGML that happens
     * to have HTML-like elements. Not a good
     * idea in general, but it's just a test...
     */
    "*style:\\n\
*id: !ID\\n\
*language: !LANG\\n\
*target: !ID\\n\
HTML.leftindent: 6.0\\n\
HTML.justify: full\\n\
HTML.textcolor: black\\n\
HTML.rightindent: 2.0\\n\
HTML.leading: 1.2\\n\
*HEAD.hide: True\\n\
*TITLE.hide: False\\n\
*TITLE.title: True\\n\
*BODY.postbreak: 2.0\\n\
*FORM.postbreak: 2.0\\n\
*H1.size: +2\\n\
*H1.textcolor: #00002424aaaa\\n\
*H1.bold: True\\n\
*H1.justify: center\\n\
*H1.prebreak: 1.5\\n\
*H1.postbreak: 1.5\\n\
*H1.noindent: True\\n\
*H1.family: alt\\n\
*H2.size: +1\\n\
*H2.textcolor: #00006d6d5555\\n\
*H2.bold: True\\n\
*H2.justify: @ifmatch(!ALIGN,\"[Cc][Ee][Nn][Tt][Ee][Rr]\",center,left)\\n\
*H2.prebreak: 1.0\\n\
*H2.postbreak: 1.0\\n\
*H2.leftindent: -4.0\\n\
*H2.parindent: 0.0\\n\
*H2.noindent: True\\n\
*H2.family: alt\\n\
*H3.size: +1\\n\
*H3.textcolor: #00006d6d5555\\n\
*H3.slant: True\\n\
*H3.justify: @ifmatch(!ALIGN,\"[Cc][Ee][Nn][Tt][Ee][Rr]\",center,left)\\n\
*H3.prebreak: 1.0\\n\
*H3.postbreak: 1.0\\n\
*H3.leftindent: -4.0\\n\
*H3.parindent: 0.0\\n\
*H3.noindent: True\\n\
*H4.bold: True\\n\
*H4.justify: @ifmatch(!ALIGN,\"[Cc][Ee][Nn][Tt][Ee][Rr]\",center,left)\\n\
*H4.prebreak: 1.0\\n\
*H4.postbreak: 0.5\\n\
*H4.parindent: 0.0\\n\
*H4.noindent: True\\n\
*H5.slant: True\\n\
*H5.prebreak: 1.0\\n\
*H5.postbreak: 0.5\\n\
*H5.parindent: 0.0\\n\
*H6.underscore: True\\n\
*H6.prebreak: 1.0\\n\
*H6.postbreak: 0.5\\n\
*H6.parindent: 0.0\\n\
*P.parindent: 2.0\\n\
*P.postbreak: 0.0\\n\
*P.justify: @ifmatch(!ALIGN,\"[Cc][Ee][Nn][Tt][Ee][Rr]\",center,-)\\n\
*U.underscore: 1\\n\
*S.strikeout: True\\n\
*TT.family: tt\\n\
*B.bold: True\\n\
*I.slant: True\\n\
*BIG.size: +1\\n\
*SMALL.size: -1\\n\
*EM.emphasis: 1\\n\
*STRONG.emphasis: 2\\n\
*CODE.family: tt\\n\
*SAMP.family: tt\\n\
*KBD.family: tt\\n\
*KDB.underscore: 1\\n\
*VAR.slant: True\\n\
*CITE.slant: True\\n\
*DFN.bold: true\\n\
*Q.insertbefore: `\\n\
*Q.insertafter: '\\n\
*BR.empty: True\\n\
*BR.prebreak: 0.0\\n\
*BR.noindent: True\\n\
*BR.flush: @ifmatch(!CLEAR,\"all\",full,!CLEAR)\\n\
*WBR.empty: True\\n\
*WBR.insertbefore: &sbsp;\\n\
*A.textcolor: @ifmatch(!HREF,\".\",#aaaa00000000)\\n\
*A.anchor: !HREF\\n\
*A.target: !NAME\\n\
*A.underscore:  @ifmatch(!HREF,\".\",1)\\n\
*IMG.empty: True\\n\
*IMG.inline: !SRC\\n\
*IMG.valign: !ALIGN\\n\
*IMG.track: !ALIGN\\n\
*IMG.ismap: @ifmatch(!ISMAP,\"[Ii][Ss][Mm][Aa][Pp]\",True,false)\\n\
*IMG.width: !WIDTH\\n\
*IMG.height: !HEIGHT\\n\
*IMG.vmargin: 0.3\\n\
*IMG.hmargin: 0.4\\n\
*HR.empty: True\\n\
*HR.prebreak: 0.5\\n\
*HR.rulebefore: 0.0\\n\
*HR.postbreak: 0.5\\n\
*HR.flush: @ifmatch(!CLEAR,\"[aA][lL][lL]\",full,!CLEAR)\\n\
*PRE.prebreak: 0.5\\n\
*PRE.postbreak: 0.5\\n\
*PRE.family: tt\\n\
*PRE.justify: left\\n\
*PRE.width: !WIDTH\\n\
*PRE.obeyspaces: True\\n\
*PRE.size: -1\\n\
*DL.prebreak: 1.0\\n\
*DL.postbreak: 1.0\\n\
*DL.leftindent: 2.0\\n\
*DT.prebreak: 0.5\\n\
*DT.parindent: -2.0\\n\
*DT.bold: True\\n\
*DT.insertafter: &nbsp;&nbsp; \\n\
*DD.postbreak: 0.5\\n\
*OL.prebreak: 1.0\\n\
*OL.postbreak: 1.0\\n\
*OL.leftindent: 2.0\\n\
*UL.prebreak: 1.0\\n\
*UL.postbreak: 1.0\\n\
*UL.leftindent: 2.0\\n\
*LI.prebreak: 0.5\\n\
*LI.postbreak: 0.5\\n\
*OL.LI.label: @ifmatch(!TYPE, \".\", !TYPE, 1)\\n\
*OL*OL.LI.label: @ifmatch(!TYPE, \".\", !TYPE, A)\\n\
*OL*OL*OL.LI.label: @ifmatch(!TYPE, \".\", !TYPE, I)\\n\
*LI.label: @ifmatch(!TYPE, \".\", !TYPE, bullet)\\n\
*OL.LI.label: @ifmatch(!TYPE,\".\",!TYPE,1)\\n\
*ADDRESS.slant: true\\n\
*ADDRESS.justify: right\\n\
*ADDRESS.prebreak: 1.0\\n\
*ADDRESS.postbreak: 1.0\\n\
*FIG.inline: !SRC\\n\
*FIG.hide: True\\n\
*FIG.leftindent: @ifmatch(!ALIGN, \"[Ll][Ee][Ff][Tt]\", 0, -5)\\n\
*FIG.rightindent: @ifmatch(!ALIGN, \"[Ll][Ee][Ff][Tt]\", -1, 0)\\n\
*FIG.valign: !ALIGN\\n\
*FIG.track: !ALIGN\\n\
*FIG.vmargin: 0.3\\n\
*FIG.hmargin: 0.5\\n\
*FIG.P.parindent: 0\\n\
*NOBR.nowrap: True\\n\
*FONT.size: !SIZE\\n\
*CENTER.insertbefore: <DIV ALIGN=CENTER>\\n\
*CENTER.insertafter: </DIV>\\n\
*BLINK.textbackground: yellow\\n\
*STYLE.stylesheet: @ifmatch(!NOTATION,\"x-bb-stylesheet\",override,false)\\n\
*DIV.justify: !ALIGN\\n\
*DIV.prebreak: 1.0\\n\
*DIV.postbreak: 1.0\\n\
*ABSTRACT.leftindent: 3.0\\n\
*ABSTRACT.rightindent: 3.0\\n\
*NOTE.leftindent: 3.0\\n\
*NOTE.rightindent: 3.0\\n\
*NOTE.prebreak: 1.0\\n\
*NOTE.postbreak: 1.0\\n\
*NOTE.textbackground: #aaaaffff5555\\n\
*NOTE.leading: 1.0\\n\
*BLOCKQUOTE.leftindent: 3.0\\n\
*BLOCKQUOTE.rightindent: 3.0\\n\
*BLOCKQUOTE.prebreak: 1.0\\n\
*BLOCKQUOTE.postbreak: 1.0\\n\
*BLOCKQUOTE.leading: 1.0\\n\
*BLOCKQUOTE.textcolor: #000000005555\\n\
*INPUT.empty: true\\n\
*TH.justify: center\\n\
*TH.bold: true\\n\
*SUP.raise: 1\\n\
*SUB.raise: -1",
    NULL
};


/* show_error -- display an error message based on errno */
EXPORT void show_error(const char *where, W3ADocumentInfo doc)
{
    static Cardinal three = 3, two = 2, one = 1;
    const char *slist[3];

    switch (errno) {
    case 0:
	break;					/* No error */
    case EURL:
	slist[0] = doc.url ? doc.url : "";
	slist[1] = doc.status ? "Server responds: " : "";
	slist[2] = doc.status ? doc.status : "";
	XtAppWarningMsg(app_context, "URL", "goto_url", "Argo_error",
			"Incorrect URL \"%s\"?\n%s%s",
			(XtPointer) slist, &three);
	break;
    case ENYI:
	slist[0] = where;
	XtAppWarningMsg(app_context, "NYI", "goto_url", "Argo_error",
			"Not yet implemented\n%s", (XtPointer) slist, &one);
	break;
    case ENOMEM:
	XtAppWarningMsg(app_context, "NOMEM", "goto_url", "Argo_error",
			"Insufficient memory", NULL, 0);
	break;
    case ETYPE:
	slist[0] = doc.url;
	slist[1] = doc.mime_type ? doc.mime_type : "";
	XtAppWarningMsg(app_context, "TYPE", "goto_url", "Argo_error",
			"Unknown protocol or document type:\n%s\n%s",
			(XtPointer) slist, &two);
	break;
    case EFORMAT:
	slist[0] = doc.url;
	slist[1] = doc.mime_type ? doc.mime_type : "";
	XtAppWarningMsg(app_context, "FORMAT", "goto_url", "Argo_error",
			"Data is in wrong format:\n%s\n%s",
			(XtPointer) slist, &two);
	break;
    default:
	slist[0] = strerror(errno);
	if (! slist[0]) slist[0] = "An error occurred";
	slist[1] = where;
	XtAppWarningMsg(app_context, "unknown", "goto_url", "Argo_error",
			"%s\n%s",
			(XtPointer) slist, &two);
	break;
    }
}


EXPORT void init_toplevel(int argc, char *argv[])
{
    XtSetLanguageProc(NULL, NULL, NULL);
    toplevel = XtVaAppInitialize
	(&app_context, "Argo", options, XtNumber(options), &argc,
	argv, fallback, NULL);
#ifdef DEBUG
    (void) ulimit(UL_SETFSIZE, 4000);
#endif
    /* XfwfInstallStringToPixmapConverter(); */
    XtAddEventHandler(toplevel, 0, True, _XEditResCheckMessages, NULL);
    XtGetApplicationResources
	(toplevel, &appdata, resources, XtNumber(resources), NULL, 0);
    if (argc == 2)
        appdata.homepage = argv[1];
    else if (argc > 2)
        error("Usage: %s [options] [homepage]\n", argv[0]);
    XmRepTypeInstallTearOffModelConverter();
    waitcursor = XCreateFontCursor(XtDisplay(toplevel), XC_watch);
}
