/* Filename: xwindow.c */
/* Author: Andy Lowry */
/* SCCS Info: @(#)xwindow.c	1.1 6/18/90 */

#define _BSD
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include "TtyText.h"
#include <stdio.h>
#include <fcntl.h>

static XrmOptionDescRec table[] = {
    {"-Wh", "ht", XrmoptionSepArg, "10"},
    {"-Ww", "wd", XrmoptionSepArg, "40"},
    {"-inverse", "inverse", XrmoptionNoArg, "on"},
    {"-debug" , "debug", XrmoptionNoArg, "on"},
};

typedef struct {
    int height, width;
    Boolean inverse;
    Boolean debug;
} app_resourceRec, *app_res;

app_resourceRec app_resources;

static char default_value[] =
	"This is a\ntest.  If this\nhad been an actual\nemergency...";

#define offset(x) XtOffset(app_res, x)
static XtResource resources[] = {
    {"ht", "Height", XtRInt, sizeof(int),
       offset(height), XtRImmediate, (caddr_t) 10 },
    {"wd", "Width", XtRInt, sizeof(int),
       offset(width), XtRImmediate, (caddr_t) 40 },
    {"inverse", "Inverse",  XtRBoolean, sizeof(Boolean),
       offset(inverse), XtRImmediate, (caddr_t) False},
    {"debug", "Debug", XtRBoolean, sizeof(Boolean),
       offset(debug), XtRImmediate, (caddr_t) False},
};
#undef offset


void getTypein(w, client_data, call_data)
     Widget w;
     caddr_t client_data;
     caddr_t call_data;
{
    XtTextBlock *text;

    text = (XtTextBlock *)call_data;
    fwrite(&text->ptr[text->firstPos], sizeof(char),
	   text->length-text->firstPos, stdout);
    fflush(stdout);
}

XtInputCallbackProc stdinAvail(client_data, source, id)
     caddr_t client_data;
     int *source;
     XtInputId id;
{
    char buf[1000];
    Widget tty;
    XtTextBlock text;

    tty = (Widget) client_data;    
    text.ptr = buf;
    text.firstPos = 0;
    text.format = FMT8BIT;
    while ((text.length = fread(buf, sizeof(char), 1000, stdin)) > 0)
	TtyTextAddText(tty, &text);
    if (feof(stdin))
      exit(0);
}



main(argc, argv)
unsigned int argc;
char **argv;
{
    char **newargv, *arg;
    int newargc, newmax, arglen, i;

    Widget toplevel, tty;
    static XtCallbackRec callbacks[] = {
	{ getTypein, NULL },
	{ NULL, NULL },
    };
    static Arg args[20];
    int n;
    static Arg fixArgs[] = {
	{XtNforeground, (XtArgVal) NULL},
	{XtNbackground, (XtArgVal) NULL},
	{XtNfont, (XtArgVal) NULL},
	{XtNheight, (XtArgVal) NULL},
	{XtNwidth, (XtArgVal) NULL},
    };
    char *index();


    if (argc < 2)
      usage(argv[0]);
        
    newmax = 10;
    newargv = (char **) XtMalloc(10*sizeof(char *));
    newargc = 0;

    newargv[newargc++] = argv[0];
    newargv[newargc++] = "-title";
    newargv[newargc++] = argv[1];
    newargv[newargc++] = "-name";
    newargv[newargc++] = argv[1];
    
    for (i = 2; i < argc; i++) {
	arg = argv[i];
	while (*arg != '\0') {
	    while (*arg == ' ')
	      arg++;
	    arglen = 0;
	    while (arg[arglen] != ' ' & arg[arglen] != '\0')
	      arglen++;
	    if (arglen != 0) {
		if (newargc == newmax) {
		    newmax += 10;
		    newargv = (char **) XtRealloc((char *) newargv,
						  newmax*sizeof(char *));
		}
		newargv[newargc] = (char *) XtMalloc(1+arglen);
		strncpy(newargv[newargc], arg, arglen);
		newargv[newargc++][arglen] = '\0';
		arg += arglen;
	    }
	}
    }
    toplevel = XtInitialize("xwindow", "HermesDemo", table, XtNumber(table),
			    &newargc, newargv);

    XtGetApplicationResources(toplevel, &app_resources, resources,
			      XtNumber(resources), NULL, 0);


#define setarg(name,arg) XtSetArg(args[n],name,(XtArgVal)arg); n++
    setarg(XtNcallback, callbacks);
    setarg(XtNtextOptions, wordBreak | scrollOnOverflow);

    tty = XtCreateManagedWidget( argv[0], ttyTextWidgetClass,
				toplevel, args, n );
    XtRealizeWidget(toplevel);
    
    XtGetValues(tty, fixArgs, XtNumber(fixArgs));
    if (app_resources.inverse) {
	XtArgVal tmp;
	tmp = fixArgs[0].value;
	fixArgs[0].value = fixArgs[1].value;
	fixArgs[1].value = tmp;
    }
    {
	XFontStruct *font;
	int lineheight, maxwidth, height, width;
	
	font = (XFontStruct *) fixArgs[2].value;
	lineheight = font->ascent + font->descent;
	maxwidth = font->max_bounds.width;
	height = app_resources.height * lineheight + font->descent;
	width = app_resources.width * maxwidth + maxwidth/2;
	fixArgs[3].value = (XtArgVal) height;
	fixArgs[4].value = (XtArgVal) width;
    }
    XtSetValues(tty, fixArgs, XtNumber(fixArgs));
    XtSetValues(toplevel, fixArgs, XtNumber(fixArgs));

    if (! app_resources.debug) {
	int flags;
	fcntl(fileno(stdin), F_GETFL, &flags);
	fcntl(fileno(stdin), F_SETFL, flags | FNDELAY);
    }
    XtAppAddInput(XtWidgetToApplicationContext(toplevel),
		  fileno(stdin), XtInputReadMask, stdinAvail, 
		  (caddr_t) tty);
    XtMainLoop();
}

usage(progname)
     char *progname;
{
    fprintf(stderr, "Usage: %s label options...\n", progname);
    exit(1);
}
