X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fbase%2Flib_mouse.c;h=6f62120904a0824f80e959bc18ba905631f03f28;hp=8b807cce948c24c19df7edb8dfeabb4093468611;hb=173dd870810c8b85baa31f9a272d15f96a8f9ff4;hpb=22fd3b236834311f1682b09d16eacec0d17f8683 diff --git a/ncurses/base/lib_mouse.c b/ncurses/base/lib_mouse.c index 8b807cce..6f621209 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-2011,2012 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.139 2012/07/21 23:30:50 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); @@ -376,11 +397,19 @@ enable_xterm_mouse(SCREEN *sp, int 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 +535,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 +702,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 +1031,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 +1162,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 +1188,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 +1211,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 +1228,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 +1277,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 +1293,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 +1311,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 +1331,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 +1353,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 +1363,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 +1460,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 +1472,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 +1532,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 +1560,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)); + } } } }