/* Written by Dan Heller and Paula Ferguson.  
 * Copyright 1994, O'Reilly & Associates, Inc.
 * Permission to use, copy, and modify this program without
 * restriction is hereby granted, as long as this copyright
 * notice appears in each copy of the program source code.
 * This program is freely distributable without licensing fees and
 * is provided without guarantee or warrantee expressed or implied.
 * This program is -not- in the public domain.
 */

/* error_test.c -- test the error handlers and wprint() routine
 */
#include <Xm/Text.h>
#include <Xm/MainW.h>
#include <Xm/PushBG.h>
#include <Xm/RowColumn.h>
#include 
/*#include   */
#include  

void wprint();
Widget text_output;

static int 
x_error(dpy, err_event)
Display      *dpy;
XErrorEvent  *err_event;
{
    char                buf[256];

    XGetErrorText (dpy, err_event->error_code, buf, (sizeof buf));

    wprint("X Error: <%s>\n", buf);
    return 0;
}

static void
xt_error(message)
char *message;
{
    wprint ("Xt Error: %s\n", message);
}

static void
make_error(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
    int which = (int) client_data;

    switch (which) {
	case 0 : 
	    XLookupColor (XtDisplay (text_output), NULL, "", NULL, NULL);
	    break;
	case 2 : 
	    XtError ("This is an XtError call!"); 
	    break;
	case 3 : 
	    XtWarning ("This is an XtWarning call."); 
	    break;
    }
}

main(argc, argv)
int argc;
char *argv[];
{
    XtAppContext app;
    Widget       toplevel, main_window, rowcol, pb;
    Arg          args[10];
    int          n;

    XtSetLanguageProc (NULL, NULL, NULL);

    toplevel = XtVaAppInitialize (&app, "Demos",
	NULL, 0, &argc, argv, NULL, NULL);

    main_window = XtVaCreateWidget ("main_window", 
	xmMainWindowWidgetClass, toplevel, NULL);

    rowcol = XtVaCreateWidget ("rowcol", 
	xmRowColumnWidgetClass, main_window, NULL);

    pb = XtVaCreateManagedWidget ("XLib Error",
        xmPushButtonGadgetClass, rowcol,
        NULL);
    XtAddCallback (pb, XmNactivateCallback, make_error, 0);

    pb = XtVaCreateManagedWidget ("Xt Error",
        xmPushButtonGadgetClass, rowcol,
        NULL);
    XtAddCallback (pb, XmNactivateCallback, make_error, (void*)2);

    pb = XtVaCreateManagedWidget ("Xt Warning",
        xmPushButtonGadgetClass, rowcol,
        NULL);
    XtAddCallback (pb, XmNactivateCallback, make_error, (void*)3);

    /* Create output_text as a ScrolledText window */
    n = 0;
    XtSetArg(args[n], XmNrows,             6); n++;
    XtSetArg(args[n], XmNcolumns,          80); n++;
    XtSetArg(args[n], XmNeditable,         False); n++;
    XtSetArg(args[n], XmNeditMode,         XmMULTI_LINE_EDIT); n++;
    XtSetArg(args[n], XmNwordWrap,         True); n++;
    XtSetArg(args[n], XmNscrollHorizontal, False); n++;
    XtSetArg(args[n], XmNcursorPositionVisible, False); n++;
    text_output = XmCreateScrolledText(rowcol, "text_output", args, n);
    XtManageChild (text_output);

    /* catch Xt errors */
    XtAppSetErrorHandler (app, xt_error);
    XtAppSetWarningHandler (app, xt_error);

    /* and Xlib errors */
    XSetErrorHandler (x_error);

    XmMainWindowSetAreas (main_window, NULL, NULL, NULL, NULL, rowcol);

    XtManageChild (rowcol);
    XtManageChild (main_window);
    XtRealizeWidget (toplevel);

    XtAppMainLoop (app);
}

/*VARARGS*/
void
wprint(...)
{
    char msgbuf[256];
    char *fmt;
    static XmTextPosition wpr_position;
    va_list args;

    va_start (args, noarg);
    fmt = va_arg (args, char *);
#ifndef NO_VPRINTF
    (void) vsprintf (msgbuf, fmt, args);
#else /* !NO_VPRINTF */
    {
        FILE foo;
        foo._cnt = 256;
        foo._base = foo._ptr = msgbuf; /* (unsigned char *) ?? */
        foo._flag = _IOWRT+_IOSTRG;
        (void) _doprnt (fmt, args, &foo);
        *foo._ptr = '\0'; /* plant terminating null character */
    }
#endif /* NO_VPRINTF */
    va_end (args);

    XmTextInsert (text_output, wpr_position, msgbuf);
    wpr_position = wpr_position + strlen (msgbuf);
    XtVaSetValues (text_output, XmNcursorPosition, wpr_position, NULL);
    XmTextShowPosition (text_output, wpr_position);
}