X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fbase%2Flib_mouse.c;h=e84a964c1ccd63b8920518a3abf472b8ceb9cc9a;hp=8b807cce948c24c19df7edb8dfeabb4093468611;hb=a1e63be290fce9e589bc57c9f753be09e8ac0cc7;hpb=22fd3b236834311f1682b09d16eacec0d17f8683;ds=sidebyside diff --git a/ncurses/base/lib_mouse.c b/ncurses/base/lib_mouse.c index 8b807cce..e84a964c 100644 --- a/ncurses/base/lib_mouse.c +++ b/ncurses/base/lib_mouse.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * + * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -84,7 +84,7 @@ #define CUR SP_TERMTYPE #endif -MODULE_ID("$Id: lib_mouse.c,v 1.130 2011/09/24 00:42:25 tom Exp $") +MODULE_ID("$Id: lib_mouse.c,v 1.140 2013/01/12 16:35:34 tom Exp $") #include @@ -120,6 +120,17 @@ make an error #endif #endif /* use_SYSMOUSE */ +#if USE_KLIBC_MOUSE +#include +#define pipe(handles) socketpair(AF_LOCAL, SOCK_STREAM, 0, handles) +#define DosWrite(hfile, pbuffer, cbwrite, pcbactual) \ + write(hfile, pbuffer, cbwrite) +#define DosExit(action, result ) /* do nothing */ +#define DosCreateThread(ptid, pfn, param, flag, cbStack) \ + (*(ptid) = _beginthread(pfn, NULL, cbStack, \ + (void *)param), (*(ptid) == -1)) +#endif + #define MY_TRACE TRACE_ICALLS|TRACE_IEVENT #define MASK_RELEASE(x) (mmask_t) NCURSES_MOUSE_MASK(x, 001) @@ -148,6 +159,9 @@ make an error #define INVALID_EVENT -1 #define NORMAL_EVENT 0 +#define ValidEvent(ep) ((ep)->id != INVALID_EVENT) +#define Invalidate(ep) (ep)->id = INVALID_EVENT + #if USE_GPM_SUPPORT #ifndef LIBGPM_SONAME @@ -211,7 +225,7 @@ write_event(SCREEN *sp, int down, int button, int x, int y) char buf[6]; unsigned long ignore; - strncpy(buf, key_mouse, 3); /* should be "\033[M" */ + strcpy(buf, "\033[M"); /* should be the same as key_mouse */ buf[3] = ' ' + (button - 1) + (down ? 0 : 0x40); buf[4] = ' ' + x - LEFT_COL + 1; buf[5] = ' ' + y - TOP_ROW + 1; @@ -219,7 +233,11 @@ write_event(SCREEN *sp, int down, int button, int x, int y) } static void +#if USE_KLIBC_MOUSE +mouse_server(void *param) +#else mouse_server(unsigned long param) +#endif { SCREEN *sp = (SCREEN *) param; unsigned short fWait = MOU_WAIT; @@ -245,7 +263,8 @@ mouse_server(unsigned long param) /* sit and wait on the event queue */ rc = MouReadEventQue(&mouev, &fWait, hmou); if (rc) { - sprintf(err, "Error reading mouse queue, rc=%lu.\r\n", rc); + _nc_SPRINTF(err, _nc_SLIMIT(sizeof(err)) + "Error reading mouse queue, rc=%lu.\r\n", rc); break; } if (!sp->_emxmouse_activated) @@ -271,9 +290,11 @@ mouse_server(unsigned long param) finish: oldstate = mouev.fs; } - } else - sprintf(err, "Error setting event mask, buttons=%d, rc=%lu.\r\n", - nbuttons, rc); + } else { + _nc_SPRINTF(err, _nc_SLIMIT(sizeof(err)) + "Error setting event mask, buttons=%d, rc=%lu.\r\n", + nbuttons, rc); + } DosWrite(2, err, strlen(err), &rc); MouClose(hmou); @@ -367,20 +388,26 @@ enable_xterm_mouse(SCREEN *sp, int enable) #if USE_EMX_MOUSE sp->_emxmouse_activated = enable; #else - NCURSES_SP_NAME(_nc_putp) (NCURSES_SP_ARGx - "xterm-mouse", - TPARM_1(sp->_mouse_xtermcap, enable)); + NCURSES_PUTP2("xterm-mouse", TPARM_1(sp->_mouse_xtermcap, enable)); #endif sp->_mouse_active = enable; } #if USE_GPM_SUPPORT static bool -allow_gpm_mouse(void) +allow_gpm_mouse(SCREEN *sp) { bool result = FALSE; - /* GPM does printf's without checking if stdout is a terminal */ +#if USE_WEAK_SYMBOLS + /* Danger Robinson: do not use dlopen for libgpm if already loaded */ + if ((Gpm_Wgetch)) { + if (!sp->_mouse_gpm_loaded) { + T(("GPM library was already dlopen'd, not by us")); + } + } else +#endif + /* GPM does printf's without checking if stdout is a terminal */ if (isatty(fileno(stdout))) { char *list = getenv("NCURSES_GPM_TERMS"); char *env = getenv("TERM"); @@ -506,7 +533,7 @@ initialize_mousetype(SCREEN *sp) /* Try gpm first, because gpm may be configured to run in xterm */ #if USE_GPM_SUPPORT - if (allow_gpm_mouse()) { + if (allow_gpm_mouse(sp)) { if (!sp->_mouse_gpm_loaded) { #ifdef HAVE_LIBDL load_gpm_library(sp); @@ -673,7 +700,7 @@ _nc_mouse_init(SCREEN *sp) sp->_mouse_eventp = FirstEV(sp); for (i = 0; i < EV_MAX; i++) - sp->_mouse_events[i].id = INVALID_EVENT; + Invalidate(sp->_mouse_events + i); initialize_mousetype(sp); @@ -1002,7 +1029,7 @@ _nc_mouse_inline(SCREEN *sp) } static void -mouse_activate(SCREEN *sp, bool on) +mouse_activate(SCREEN *sp, int on) { if (!on && !sp->_mouse_initialized) return; @@ -1133,7 +1160,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) */ ep = eventp; for (n = runcount; n < EV_MAX; n++) { - ep->id = INVALID_EVENT; + Invalidate(ep); ep = NEXT(ep); } @@ -1159,7 +1186,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) #define MASK_CHANGED(x) (!(ep->bstate & MASK_PRESS(x)) \ == !(next->bstate & MASK_RELEASE(x))) - if (ep->id != INVALID_EVENT && next->id != INVALID_EVENT + if (ValidEvent(ep) && ValidEvent(next) && ep->x == next->x && ep->y == next->y && (ep->bstate & BUTTON_PRESSED) && (!(next->bstate & BUTTON_PRESSED))) { @@ -1182,14 +1209,15 @@ _nc_mouse_parse(SCREEN *sp, int runcount) merge = TRUE; } } - if (merge) - ep->id = INVALID_EVENT; + if (merge) { + Invalidate(ep); + } } } } /* Compact valid events */ - if (ep->id == INVALID_EVENT) { + if (!ValidEvent(ep)) { if ((first_valid != NULL) && (first_invalid == NULL)) { first_invalid = ep; } @@ -1198,7 +1226,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) first_valid = ep; } else if (first_invalid != NULL) { *first_invalid = *ep; - ep->id = INVALID_EVENT; + Invalidate(ep); first_invalid = NEXT(first_invalid); } } @@ -1247,6 +1275,8 @@ _nc_mouse_parse(SCREEN *sp, int runcount) if (next == eventp) { /* Will end the loop, but check event type and compact before */ endLoop = TRUE; + } else if (!ValidEvent(next)) { + continue; } else { /* merge click events forward */ if ((ep->bstate & BUTTON_CLICKED) @@ -1261,8 +1291,9 @@ _nc_mouse_parse(SCREEN *sp, int runcount) merge = TRUE; } } - if (merge) - ep->id = INVALID_EVENT; + if (merge) { + Invalidate(ep); + } } /* merge double-click events forward */ @@ -1278,18 +1309,19 @@ _nc_mouse_parse(SCREEN *sp, int runcount) merge = TRUE; } } - if (merge) - ep->id = INVALID_EVENT; + if (merge) { + Invalidate(ep); + } } } /* Discard event if it does not match event mask */ - if (!(ep->bstate & sp->_mouse_mask)) { - ep->id = INVALID_EVENT; + if (!(ep->bstate & sp->_mouse_mask2)) { + Invalidate(ep); } /* Compact valid events */ - if (ep->id == INVALID_EVENT) { + if (!ValidEvent(ep)) { if (ep == first_valid) { first_valid = next; } else if (first_invalid == NULL) { @@ -1297,7 +1329,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) } } else if (first_invalid != NULL) { *first_invalid = *ep; - ep->id = INVALID_EVENT; + Invalidate(ep); first_invalid = NEXT(first_invalid); } @@ -1319,7 +1351,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) _nc_unlock_global(tracef); } for (ep = first_valid; ep != first_invalid; ep = NEXT(ep)) { - if (ep->id != INVALID_EVENT) + if (ValidEvent(ep)) TR(MY_TRACE, ("_nc_mouse_parse: returning composite mouse event %s at slot %ld", _nc_tracemouse(sp, ep), @@ -1329,7 +1361,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) #endif /* TRACE */ /* after all this, do we have a valid event? */ - return (PREV(first_invalid)->id != INVALID_EVENT); + return ValidEvent(PREV(first_invalid)); } static void @@ -1426,11 +1458,11 @@ NCURSES_SP_NAME(getmouse) (NCURSES_SP_DCLx MEVENT * aevent) * _nc_mouse_parse was not called, e.g., when _nc_mouse_inline returns * false). */ - while ((prev->id != INVALID_EVENT) && (!(prev->bstate & SP_PARM->_mouse_mask))) { - prev->id = INVALID_EVENT; + while (ValidEvent(prev) && (!(prev->bstate & SP_PARM->_mouse_mask2))) { + Invalidate(prev); prev = PREV(prev); } - if (prev->id != INVALID_EVENT) { + if (ValidEvent(prev)) { /* copy the event we find there */ *aevent = *prev; @@ -1438,13 +1470,13 @@ NCURSES_SP_NAME(getmouse) (NCURSES_SP_DCLx MEVENT * aevent) _nc_tracemouse(SP_PARM, prev), (long) IndexEV(SP_PARM, prev))); - prev->id = INVALID_EVENT; /* so the queue slot becomes free */ + Invalidate(prev); /* so the queue slot becomes free */ SP_PARM->_mouse_eventp = prev; result = OK; } else { /* Reset the provided event */ aevent->bstate = 0; - aevent->id = INVALID_EVENT; + Invalidate(aevent); aevent->x = 0; aevent->y = 0; aevent->z = 0; @@ -1498,6 +1530,7 @@ NCURSES_SP_NAME(mousemask) (NCURSES_SP_DCLx mmask_t newmask, mmask_t * oldmask) /* set the mouse event mask */ { mmask_t result = 0; + int b; T((T_CALLED("mousemask(%p,%#lx,%p)"), (void *) SP_PARM, @@ -1525,6 +1558,22 @@ NCURSES_SP_NAME(mousemask) (NCURSES_SP_DCLx mmask_t newmask, mmask_t * oldmask) mouse_activate(SP_PARM, (bool) (result != 0)); SP_PARM->_mouse_mask = result; + SP_PARM->_mouse_mask2 = result; + + /* + * Make a mask corresponding to the states we will need to + * retain (temporarily) while building up the state that the + * user asked for. + */ + for (b = 1; b <= MAX_BUTTONS; ++b) { + if (SP_PARM->_mouse_mask2 & MASK_TRIPLE_CLICK(b)) + SP_PARM->_mouse_mask2 |= MASK_DOUBLE_CLICK(b); + if (SP_PARM->_mouse_mask2 & MASK_DOUBLE_CLICK(b)) + SP_PARM->_mouse_mask2 |= MASK_CLICK(b); + if (SP_PARM->_mouse_mask2 & MASK_CLICK(b)) + SP_PARM->_mouse_mask2 |= (MASK_PRESS(b) | + MASK_RELEASE(b)); + } } } }