/* Public Domain Curses */

#include <curspriv.h>

RCSID("$Id: mouse.c,v 1.45 2008/07/13 16:08:18 wmcbrine Exp $")

/*man-start**************************************************************

  Name:                                                         mouse

  Synopsis:
        int mouse_set(unsigned long mbe);
        int mouse_on(unsigned long mbe);
        int mouse_off(unsigned long mbe);
        int request_mouse_pos(void);
        int map_button(unsigned long button);
        void wmouse_position(WINDOW *win, int *y, int *x);
        unsigned long getmouse(void);
        unsigned long getbmap(void);

        int mouseinterval(int wait);
        bool wenclose(const WINDOW *win, int y, int x);
        bool wmouse_trafo(const WINDOW *win, int *y, int *x, bool to_screen);
        bool mouse_trafo(int *y, int *x, bool to_screen);
        mmask_t mousemask(mmask_t mask, mmask_t *oldmask);
        int nc_getmouse(MEVENT *event);
        int ungetmouse(MEVENT *event);

  Description:
        As of PDCurses 3.0, there are two separate mouse interfaces: the
        classic interface, which is based on the undocumented Sys V
        mouse functions; and an ncurses-compatible interface. Both are
        active at all times, and you can mix and match functions from
        each, though it's not recommended. The ncurses interface is
        essentially an emulation layer built on top of the classic
        interface; it's here to allow easier porting of ncurses apps.

        The classic interface: mouse_set(), mouse_on(), mouse_off(),
        request_mouse_pos(), map_button(), wmouse_position(),
        getmouse(), and getbmap(). An application using this interface
        would start by calling mouse_set() or mouse_on() with a non-zero
        value, often ALL_MOUSE_EVENTS. Then it would check for a
        KEY_MOUSE return from getch(). If found, it would call
        request_mouse_pos() to get the current mouse status.

        mouse_set(), mouse_on() and mouse_off() are analagous to
        attrset(), attron() and attroff().  These functions set the
        mouse button events to trap.  The button masks used in these
        functions are defined in curses.h and can be or'ed together.
        They are the group of masks starting with BUTTON1_RELEASED.

        request_mouse_pos() requests curses to fill in the Mouse_status
        structure with the current state of the mouse.

        map_button() enables the specified mouse action to activate the
        Soft Label Keys if the action occurs over the area of the screen
        where the Soft Label Keys are displayed.  The mouse actions are
        defined in curses.h in the group that starts with BUTTON_RELEASED.

        wmouse_position() determines if the current mouse position is
        within the window passed as an argument.  If the mouse is
        outside the current window, -1 is returned in the y and x
        arguments; otherwise the y and x coordinates of the mouse
        (relative to the top left corner of the window) are returned in
        y and x.

        getmouse() returns the current status of the trapped mouse
        buttons as set by mouse_set() or mouse_on().

        getbmap() returns the current status of the button action used
        to map a mouse action to the Soft Label Keys as set by the
        map_button() function.

        The ncurses interface: mouseinterval(), wenclose(),
        wmouse_trafo(), mouse_trafo(), mousemask(), nc_getmouse(), and
        ungetmouse(). A typical application using this interface would
        start by calling mousemask() with a non-zero value, often
        ALL_MOUSE_EVENTS. Then it would check for a KEY_MOUSE return
        from getch(). If found, it would call nc_getmouse() to get the
        current mouse status.

        mouseinterval() sets the timeout for a mouse click. On all
        current platforms, PDCurses receives mouse button press and
        release events, but must synthesize click events. It does this
        by checking whether a release event is queued up after a press
        event. If it gets a press event, and there are no more events
        waiting, it will wait for the timeout interval, then check again
        for a release. A press followed by a release is reported as
        BUTTON_CLICKED; otherwise it's passed through as BUTTON_PRESSED.
        The default timeout is 150ms; valid values are 0 (no clicks
        reported) through 1000ms. In x11, the timeout can also be set
        via the clickPeriod resource. The return value from
        mouseinterval() is the old timeout. To check the old value
        without setting a new one, call it with a parameter of -1. Note
        that although there's no classic equivalent for this function
        (apart from the clickPeriod resource), the value set applies in
        both interfaces.

        wenclose() reports whether the given screen-relative y, x
        coordinates fall within the given window.

        wmouse_trafo() converts between screen-relative and window-
        relative coordinates. A to_screen parameter of TRUE means to
        convert from window to screen; otherwise the reverse. The
        function returns FALSE if the coordinates aren't within the
        window, or if any of the parameters are NULL. The coordinates
        have been converted when the function returns TRUE.

        mouse_trafo() is the stdscr version of wmouse_trafo().

        mousemask() is nearly equivalent to mouse_set(), but instead of
        OK/ERR, it returns the value of the mask after setting it. (This
        isn't necessarily the same value passed in, since the mask could
        be altered on some platforms.) And if the second parameter is a
        non-null pointer, mousemask() stores the previous mask value
        there. Also, since the ncurses interface doesn't work with
        PDCurses' BUTTON_MOVED events, mousemask() filters them out.

        nc_getmouse() returns the current mouse status in an MEVENT
        struct. This is equivalent to ncurses' getmouse(), renamed to
        avoid conflict with PDCurses' getmouse(). But if you define
        NCURSES_MOUSE_VERSION (preferably as 2) before including
        curses.h, it defines getmouse() to nc_getmouse(), along with a
        few other redefintions needed for compatibility with ncurses
        code. nc_getmouse() calls request_mouse_pos(), which (not
        getmouse()) is the classic equivalent.

        ungetmouse() is the mouse equivalent of ungetch(). However,
        PDCurses doesn't maintain a queue of mouse events; only one can
        be pushed back, and it can overwrite or be overwritten by real
        mouse events.

  Portability                                X/Open    BSD    SYS V
        mouse_set                               -       -      4.0
        mouse_on                                -       -      4.0
        mouse_off                               -       -      4.0
        request_mouse_pos                       -       -      4.0
        map_button                              -       -      4.0
        wmouse_position                         -       -      4.0
        getmouse                                -       -      4.0
        getbmap                                 -       -      4.0
        mouseinterval                           -       -       -
        wenclose                                -       -       -
        wmouse_trafo                            -       -       -
        mouse_trafo                             -       -       -
        mousemask                               -       -       -
        nc_getmouse                             -       -       -
        ungetmouse                              -       -       -

**man-end****************************************************************/

#include <string.h>

static bool ungot = FALSE;

int mouse_set(unsigned long mbe)
{
    PDC_LOG(("mouse_set() - called: event %x\n", mbe));

    SP->_trap_mbe = mbe;
    return PDC_mouse_set();
}

int mouse_on(unsigned long mbe)
{
    PDC_LOG(("mouse_on() - called: event %x\n", mbe));

    SP->_trap_mbe |= mbe;
    return PDC_mouse_set();
}

int mouse_off(unsigned long mbe)
{
    PDC_LOG(("mouse_off() - called: event %x\n", mbe));

    SP->_trap_mbe &= ~mbe;
    return PDC_mouse_set();
}

int map_button(unsigned long button)
{
    PDC_LOG(("map_button() - called: button %x\n", button));

/****************** this does nothing at the moment ***************/
    SP->_map_mbe_to_key = button;

    return OK;
}

int request_mouse_pos(void)
{
    PDC_LOG(("request_mouse_pos() - called\n"));

    Mouse_status = pdc_mouse_status;

    return OK;
}

void wmouse_position(WINDOW *win, int *y, int *x)
{
    PDC_LOG(("wmouse_position() - called\n"));

    if (win && wenclose(win, MOUSE_Y_POS, MOUSE_X_POS))
    {
        if (y)
            *y = MOUSE_Y_POS - win->_begy;
        if (x)
            *x = MOUSE_X_POS - win->_begx;
    }
    else
    {
        if (y)
            *y = -1;
        if (x)
            *x = -1;
    }
}

unsigned long getmouse(void)
{
    PDC_LOG(("getmouse() - called\n"));

    return SP->_trap_mbe;
}

unsigned long getbmap(void)
{
    PDC_LOG(("getbmap() - called\n"));

    return SP->_map_mbe_to_key;
}

/* ncurses mouse interface */

int mouseinterval(int wait)
{
    int old_wait;

    PDC_LOG(("mouseinterval() - called: %d\n", wait));

    old_wait = SP->mouse_wait;

    if (wait >= 0 && wait <= 1000)
        SP->mouse_wait = wait;

    return old_wait;
}

bool wenclose(const WINDOW *win, int y, int x)
{
    PDC_LOG(("wenclose() - called: %p %d %d\n", win, y, x));

    return (win && y >= win->_begy && y < win->_begy + win->_maxy
                && x >= win->_begx && x < win->_begx + win->_maxx);
}

bool wmouse_trafo(const WINDOW *win, int *y, int *x, bool to_screen)
{
    int newy, newx;

    PDC_LOG(("wmouse_trafo() - called\n"));

    if (!win || !y || !x)
        return FALSE;

    newy = *y;
    newx = *x;

    if (to_screen)
    {
        newy += win->_begy;
        newx += win->_begx;

        if (!wenclose(win, newy, newx))
            return FALSE;
    }
    else
    {
        if (wenclose(win, newy, newx))
        {
            newy -= win->_begy;
            newx -= win->_begx;
        }
        else
            return FALSE;
    }

    *y = newy;
    *x = newx;

    return TRUE;
}

bool mouse_trafo(int *y, int *x, bool to_screen)
{
    PDC_LOG(("mouse_trafo() - called\n"));

    return wmouse_trafo(stdscr, y, x, to_screen);
}

mmask_t mousemask(mmask_t mask, mmask_t *oldmask)
{
    PDC_LOG(("mousemask() - called\n"));

    if (oldmask)
        *oldmask = SP->_trap_mbe;

    /* The ncurses interface doesn't work with our move events, so
       filter them here */

    mask &= ~(BUTTON1_MOVED | BUTTON2_MOVED | BUTTON3_MOVED);

    mouse_set(mask);

    return SP->_trap_mbe;
}

int nc_getmouse(MEVENT *event)
{
    int i;
    mmask_t bstate = 0;

    PDC_LOG(("nc_getmouse() - called\n"));

    if (!event)
        return ERR;

    ungot = FALSE;

    request_mouse_pos();

    event->id = 0;

    event->x = Mouse_status.x;
    event->y = Mouse_status.y;
    event->z = 0;

    for (i = 0; i < 3; i++)
    {
        if (Mouse_status.changes & (1 << i))
        {
            int shf = i * 5;
            short button = Mouse_status.button[i] & BUTTON_ACTION_MASK;

            if (button == BUTTON_RELEASED)
                bstate |= (BUTTON1_RELEASED << shf);
            else if (button == BUTTON_PRESSED)
                bstate |= (BUTTON1_PRESSED << shf);
            else if (button == BUTTON_CLICKED)
                bstate |= (BUTTON1_CLICKED << shf);
            else if (button == BUTTON_DOUBLE_CLICKED)
                bstate |= (BUTTON1_DOUBLE_CLICKED << shf);

            button = Mouse_status.button[i] & BUTTON_MODIFIER_MASK;

            if (button & PDC_BUTTON_SHIFT)
                bstate |= BUTTON_MODIFIER_SHIFT;
            if (button & PDC_BUTTON_CONTROL)
                bstate |= BUTTON_MODIFIER_CONTROL;
            if (button & PDC_BUTTON_ALT)
                bstate |= BUTTON_MODIFIER_ALT;
        }
    }

    if (MOUSE_WHEEL_UP)
        bstate |= BUTTON4_PRESSED;
    else if (MOUSE_WHEEL_DOWN)
        bstate |= BUTTON5_PRESSED;

    /* extra filter pass -- mainly for button modifiers */

    event->bstate = bstate & SP->_trap_mbe;

    return OK;
}

int ungetmouse(MEVENT *event)
{
    int i;
    unsigned long bstate;

    PDC_LOG(("ungetmouse() - called\n"));

    if (!event || ungot)
        return ERR;

    ungot = TRUE;

    pdc_mouse_status.x = event->x;
    pdc_mouse_status.y = event->y;

    pdc_mouse_status.changes = 0;
    bstate = event->bstate;

    for (i = 0; i < 3; i++)
    {
        int shf = i * 5;
        short button = 0;

        if (bstate & ((BUTTON1_RELEASED | BUTTON1_PRESSED |
            BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED) << shf))
        {
            pdc_mouse_status.changes |= 1 << i;

            if (bstate & (BUTTON1_PRESSED << shf))
                button = BUTTON_PRESSED;
            if (bstate & (BUTTON1_CLICKED << shf))
                button = BUTTON_CLICKED;
            if (bstate & (BUTTON1_DOUBLE_CLICKED << shf))
                button = BUTTON_DOUBLE_CLICKED;

            if (bstate & BUTTON_MODIFIER_SHIFT)
                button |= PDC_BUTTON_SHIFT;
            if (bstate & BUTTON_MODIFIER_CONTROL)
                button |= PDC_BUTTON_CONTROL;
            if (bstate & BUTTON_MODIFIER_ALT)
                button |= PDC_BUTTON_ALT;
        }

        pdc_mouse_status.button[i] = button;
    }

    if (bstate & BUTTON4_PRESSED)
        pdc_mouse_status.changes |= PDC_MOUSE_WHEEL_UP;
    else if (bstate & BUTTON5_PRESSED)
        pdc_mouse_status.changes |= PDC_MOUSE_WHEEL_DOWN;

    return ungetch(KEY_MOUSE);
}
