/*
 * $Id: x11.c,v 1.32 2005/01/14 18:58:03 phil Exp $
 * X11 support for XY display simulator
 * Phil Budne <phil@ultimate.com>
 * September 2003
 *
 * Changes from Douglas A. Gwyn, Jan 8, 2004
 *
 * started from PDP-8/E simulator (vc8e.c & kc8e.c);
 *      This PDP8 Emulator was written by Douglas W. Jones at the
 *      University of Iowa.  It is distributed as freeware, of
 *      uncertain function and uncertain utility.
 */

/*
 * Copyright (c) 2003-2004, Philip L. Budne
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the names of the authors shall
 * not be used in advertising or otherwise to promote the sale, use or
 * other dealings in this Software without prior written authorization
 * from the authors.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ws.h"
#include "display.h"

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Core.h>
#include <X11/Shell.h>
#include <X11/cursorfont.h>

#include <sys/types.h>
#include <sys/time.h>

#ifndef PIX_SIZE
#define PIX_SIZE 1
#endif

/*
 * light pen location
 * see ws.h for full description
 */
int ws_lp_x = -1;
int ws_lp_y = -1;

static XtAppContext app_context; /* the topmost context for everything */
static Display* dpy;            /* its display */
static int      scr;            /* its screen */
static Colormap cmap;           /* its colormap */
static Widget crtshell;         /* the X window shell */
static Widget crt;              /* the X window in which output will plot */
static int xpixels, ypixels;
#ifdef FULL_SCREEN
/* occupy entire screen for vintage computer fan Sellam Ismail */
static int xoffset, yoffset;
#endif

static GC whiteGC;              /* gc with white foreground */
static GC blackGC;              /* gc with black foreground */
static int buttons = 0;         /* tracks state of all buttons */

static int os_pollfd(int, int); /* forward */

/* here on any mouse button down, AND movement when any button down */
static void
handle_button_press(w, d, e, b)
    Widget w;
    XtPointer d;
    XEvent *e;
    Boolean *b;
{
    int x, y;

    x = e->xbutton.x;
    y = e->xbutton.y;
#ifdef FULL_SCREEN
    /* untested! */
    x -= xoffset;
    y -= yoffset;
#endif
#if PIX_SIZE > 1
    x *= PIX_SIZE;
    y *= PIX_SIZE;
#endif

    if (!display_tablet)
        /* crosshair cursor to indicate tip of active pen */
        XDefineCursor(dpy, XtWindow(crt),
                        (Cursor) XCreateFontCursor(dpy, XC_crosshair));

    y = ypixels - y - 1;
    /*printf("lightpen at %d,%d\n", x, y); fflush(stdout);*/
    ws_lp_x = x;
    ws_lp_y = y;

    if (e->type == ButtonPress) {
        buttons |= e->xbutton.button;

        if (e->xbutton.button == 1) {
            display_lp_sw = 1;
            /*printf("tip switch activated\n"); fflush(stdout);*/
        }
    }

    if (b)
        *b = TRUE;
}

static void
handle_button_release(w, d, e, b)
    Widget w;
    XtPointer d;
    XEvent *e;
    Boolean *b;
{
    if ((buttons &= ~e->xbutton.button) == 0) { /* all buttons released */
        if (!display_tablet)
            /* pencil cursor (close to a pen!) to indicate inactive pen posn */
            XDefineCursor(dpy, XtWindow(crt),
                                (Cursor) XCreateFontCursor(dpy, XC_pencil));

        /* XXX change cursor back?? */
        ws_lp_x = ws_lp_y = -1;
    }

    if (e->xbutton.button == 1) {
        display_lp_sw = 0;
        /*printf("tip switch deactivated\n"); fflush(stdout);*/
    }

    if (b)
        *b = TRUE;
}

static void
handle_key_press(w, d, e, b)
    Widget w;
    XtPointer d;
    XEvent *e;
    Boolean *b;
{
    int shift = (ShiftMask & e->xkey.state) != 0;
    KeySym key = XKeycodeToKeysym( dpy, e->xkey.keycode, shift );

    /*printf("key %d down\n", key); fflush(stdout);*/
    if ((key & 0xff00) == 0)
        display_keydown(key);

    if (b)
        *b = TRUE;
}

static void
handle_key_release(w, d, e, b)
    Widget w;
    XtPointer d;
    XEvent *e;
    Boolean *b;
{
    int shift = (ShiftMask & e->xkey.state) != 0;
    KeySym key = XKeycodeToKeysym( dpy, e->xkey.keycode, shift );

    /*printf("key %d up\n", key); fflush(stdout);*/
    if ((key & 0xff00) == 0)
        display_keyup(key);

    if (b)
        *b = TRUE;
}

static void
handle_exposure(w, d, e, b)
    Widget w;
    XtPointer d;
    XEvent *e;
    Boolean *b;
{
    display_repaint();

    if (b)
        *b = TRUE;
}

int
ws_init(const char *crtname,    /* crt type name */
    int xp, int yp,             /* screen size in pixels */
    int colors,                 /* colors to support (not used) */
    void *dptr)
{
    Arg arg[25];
    XGCValues gcvalues;
    unsigned int n;
    int argc;
    char *argv[1];
    int height, width;

    xpixels = xp;               /* save screen size */
    ypixels = yp;

    XtToolkitInitialize();
    app_context = XtCreateApplicationContext();
    argc = 0;
    argv[0] = NULL;
    dpy = XtOpenDisplay( app_context, NULL, NULL, crtname, NULL, 0,
                        &argc, argv);

    scr = DefaultScreen(dpy);

    crtshell = XtAppCreateShell( crtname, /* app name */
                                crtname, /* app class */
                                applicationShellWidgetClass, /* wclass */
                                dpy, /* display */
                                NULL, /* arglist */
                                0);     /* nargs */

    cmap = DefaultColormap(dpy, scr);

    /*
     * Create a drawing area
     */

    n = 0;
#ifdef FULL_SCREEN
    /* center raster in full-screen black window */
    width = DisplayWidth(dpy,scr);
    height = DisplayHeight(dpy,scr);

    xoffset = (width - xpixels*PIX_SIZE)/2;
    yoffset = (height - ypixels*PIX_SIZE)/2;
#else
    width = xpixels*PIX_SIZE;
    height = ypixels*PIX_SIZE;
#endif
    XtSetArg(arg[n], XtNwidth, width);                          n++;
    XtSetArg(arg[n], XtNheight, height);                        n++;
    XtSetArg(arg[n], XtNbackground, BlackPixel( dpy, scr ));    n++;

    crt = XtCreateWidget( crtname, widgetClass, crtshell, arg, n);
    XtManageChild(crt);
    XtPopup(crtshell, XtGrabNonexclusive);
    XtSetKeyboardFocus(crtshell, crt);  /* experimental? */

    /*
     * Create black and white Graphics Contexts
     */

    gcvalues.foreground = BlackPixel( dpy, scr );
    gcvalues.background = BlackPixel( dpy, scr );
    blackGC = XCreateGC(dpy, XtWindow(crt),
                        GCForeground | GCBackground, &gcvalues);

    gcvalues.foreground = WhitePixel( dpy, scr );
    whiteGC = XCreateGC(dpy, XtWindow(crt),
                        GCForeground | GCBackground, &gcvalues);

    if (!display_tablet) {
        /* pencil cursor */
        XDefineCursor(dpy, XtWindow(crt),
                      (Cursor) XCreateFontCursor(dpy, XC_pencil));
    }

    /*
     * Setup to handle events
     */

    XtAddEventHandler(crt, ButtonPressMask|ButtonMotionMask, FALSE,
                      handle_button_press, NULL);
    XtAddEventHandler(crt, ButtonReleaseMask, FALSE,
                      handle_button_release, NULL);
    XtAddEventHandler(crt, KeyPressMask, FALSE,
                      handle_key_press, NULL);
    XtAddEventHandler(crt, KeyReleaseMask, FALSE,
                      handle_key_release, NULL);
    XtAddEventHandler(crt, ExposureMask, FALSE,
                      handle_exposure, NULL);
    return 1;
} /* ws_init */

void ws_shutdown (void)
{
}

void *
ws_color_black(void)
{
    return blackGC;
}

void *
ws_color_white(void)
{
    return whiteGC;
}

void *
ws_color_rgb(int r, int g, int b)
{
    XColor color;

    color.red = r;
    color.green = g;
    color.blue = b;
    /* ignores flags */

    if (XAllocColor(dpy, cmap, &color)) {
        XGCValues gcvalues;
        memset(&gcvalues, 0, sizeof(gcvalues));
        gcvalues.foreground = gcvalues.background = color.pixel;
        return XCreateGC(dpy, XtWindow(crt),
                         GCForeground | GCBackground,
                         &gcvalues);
    }
    /* allocation failed */
    return NULL;
}

/* put a point on the screen */
void
ws_display_point(int x, int y, void *color)
{
    GC gc = (GC) color;

    if (x > xpixels || y > ypixels)
        return;

    y = ypixels - y - 1;                /* X11 coordinate system */

#ifdef FULL_SCREEN
    x += xoffset;
    y += yoffset;
#endif
    if (gc == NULL)
        gc = blackGC;                   /* default to off */
#if PIX_SIZE == 1
    XDrawPoint(dpy, XtWindow(crt), gc, x, y);
#else
    XFillRectangle(dpy, XtWindow(crt), gc,
                   x*PIX_SIZE, y*PIX_SIZE, PIX_SIZE, PIX_SIZE);
#endif
}

void
ws_sync(void)
{
    XFlush(dpy);
}

/*
 * elapsed wall clock time since last call
 * +INF on first call
 */

struct elapsed_state {
    struct timeval tvs[2];
    int new;
};

static unsigned long
elapsed(struct elapsed_state *ep)
{
    unsigned long val;

    gettimeofday(&ep->tvs[ep->new], NULL);
    if (ep->tvs[!ep->new].tv_sec == 0)
        val = ~0L;
    else
        val = ((ep->tvs[ep->new].tv_sec - ep->tvs[!ep->new].tv_sec) * 1000000 +
               (ep->tvs[ep->new].tv_usec - ep->tvs[!ep->new].tv_usec));
    ep->new = !ep->new;
    return val;
}

/* called periodically */
int
ws_poll(int *valp, int maxusec)
{
    static struct elapsed_state es;     /* static to avoid clearing! */

#ifdef WS_POLL_DEBUG
    printf("ws_poll %d\n", maxusec);
    fflush(stdout);
#endif
    elapsed(&es);                       /* start clock */
    do {
        unsigned long e;

        /* tried checking return, but lost on TCP connections? */
        os_pollfd(ConnectionNumber(dpy), maxusec);

        while (XtAppPending(app_context)) {
            XEvent event;

            /* XXX check for connection loss; set *valp? return 0 */
            XtAppNextEvent(app_context, &event );
            XtDispatchEvent( &event );
        }
        e = elapsed(&es);
#ifdef WS_POLL_DEBUG
        printf(" maxusec %d e %d\r\n", maxusec, e);
        fflush(stdout);
#endif
        maxusec -= e;
    } while (maxusec > 10000);  /* 10ms */
    return 1;
}

/* utility: can be called from main program
 * which is willing to cede control
 */
int
ws_loop(void (*func)(void *), void *arg)
{
    int val;

    /* XXX use XtAppAddWorkProc & XtAppMainLoop? */
    while (ws_poll(&val,0))
        (*func)(arg);
    return val;
}

void
ws_beep(void)
{
    XBell(dpy, 0);                      /* ring at base volume */
    XFlush(dpy);
}

/****************
 * could move these to unix.c, if VMS versions needed
 * (or just (GASP!) ifdef)
 */

/* public version, used by delay code */
unsigned long
os_elapsed(void)
{
    static struct elapsed_state es;
    return elapsed(&es);
}

/*
 * select/DisplayNumber works on VMS 7.0+?
 * could move to "unix.c"
 * (I have some nasty VMS code that's supposed to to the job
 * for older systems)
 */

/*
 * sleep for maxus microseconds, returning TRUE sooner if fd is readable
 * used by X11 driver
 */
static int
os_pollfd(int fd, int maxus)
{

    /* use trusty old select (most portable) */
    fd_set rfds;
    struct timeval tv;

    if (maxus >= 1000000) {             /* not bloody likely, avoid divide */
        tv.tv_sec = maxus / 1000000;
        tv.tv_usec = maxus % 1000000;
    }
    else {
        tv.tv_sec = 0;
        tv.tv_usec = maxus;
    }
    FD_ZERO(&rfds);
    FD_SET(fd, &rfds);
    return select(fd+1, &rfds, NULL, NULL, &tv) > 0;
}
