diff options
Diffstat (limited to 'ncurses/base/lib_mouse.c')
| -rw-r--r-- | ncurses/base/lib_mouse.c | 170 |
1 files changed, 90 insertions, 80 deletions
diff --git a/ncurses/base/lib_mouse.c b/ncurses/base/lib_mouse.c index a03d8b8e1ab0..eb36ad2da817 100644 --- a/ncurses/base/lib_mouse.c +++ b/ncurses/base/lib_mouse.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2018-2023,2024 Thomas E. Dickey * + * Copyright 2018-2024,2025 Thomas E. Dickey * * Copyright 1998-2016,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * @@ -44,7 +44,7 @@ * sysmouse (FreeBSD) * special-purpose mouse interface for OS/2 EMX. * - * Notes for implementors of new mouse-interface methods: + * Notes for implementers of new mouse-interface methods: * * The code is logically split into a lower level that accepts event reports * in a device-dependent format and an upper level that parses mouse gestures @@ -70,7 +70,6 @@ */ #ifdef __EMX__ -# include <io.h> # define INCL_DOS # define INCL_VIO # define INCL_KBD @@ -85,7 +84,7 @@ #define CUR SP_TERMTYPE #endif -MODULE_ID("$Id: lib_mouse.c,v 1.200 2024/02/17 21:13:01 tom Exp $") +MODULE_ID("$Id: lib_mouse.c,v 1.219 2025/12/30 17:23:24 tom Exp $") #include <tic.h> @@ -380,7 +379,7 @@ handle_sysmouse(int sig GCC_UNUSED) } #endif /* USE_SYSMOUSE */ -#if !defined(USE_TERM_DRIVER) || defined(EXP_WIN32_DRIVER) +#if !defined(_NC_WINDOWS_NATIVE) || USE_NAMED_PIPES #define xterm_kmous "\033[M" static void @@ -388,10 +387,10 @@ init_xterm_mouse(SCREEN *sp) { sp->_mouse_type = M_XTERM; sp->_mouse_format = MF_X10; - sp->_mouse_xtermcap = tigetstr("XM"); + sp->_mouse_xtermcap = tigetstr(UserCap(XM)); if (VALID_STRING(sp->_mouse_xtermcap)) { char *code = strstr(sp->_mouse_xtermcap, "[?"); - if (code != 0) { + if (code != NULL) { code += 2; while ((*code >= '0') && (*code <= '9')) { char *next = code; @@ -417,7 +416,7 @@ init_xterm_mouse(SCREEN *sp) } } } else { - int code = tigetnum("XM"); + int code = tigetnum(UserCap(XM)); switch (code) { #ifdef EXP_XTERM_1005 case 1005: @@ -440,7 +439,7 @@ init_xterm_mouse(SCREEN *sp) #endif static void -enable_xterm_mouse(SCREEN *sp, int enable) +enable_xterm_mouse(SCREEN *sp, bool enable) { TPUTS_TRACE(enable ? "xterm mouse initialization" @@ -453,11 +452,11 @@ enable_xterm_mouse(SCREEN *sp, int enable) sp->_mouse_active = enable; } -#if defined(USE_TERM_DRIVER) +#if USE_TERM_DRIVER static void -enable_win32_mouse(SCREEN *sp, int enable) +enable_win32_mouse(SCREEN *sp, bool enable) { -#if defined(EXP_WIN32_DRIVER) +#if USE_NAMED_PIPES enable_xterm_mouse(sp, enable); #else sp->_mouse_active = enable; @@ -483,9 +482,9 @@ allow_gpm_mouse(SCREEN *sp GCC_UNUSED) if (NC_ISATTY(fileno(stdout))) { const char *list = getenv("NCURSES_GPM_TERMS"); const char *env = getenv("TERM"); - if (list != 0) { - if (env != 0) { - result = _nc_name_match(list, env, "|:"); + if (list != NULL) { + if (env != NULL) { + result = _nc_name_match(list, env, "|:") ? TRUE : FALSE; } } else { /* GPM checks the beginning of the $TERM variable to decide if it @@ -495,7 +494,7 @@ allow_gpm_mouse(SCREEN *sp GCC_UNUSED) * capability. Perhaps that works for someone. If so, they can * set the environment variable (above). */ - if (env != 0 && strstr(env, "linux") != 0) { + if (env != NULL && strstr(env, "linux") != NULL) { result = TRUE; } } @@ -507,7 +506,7 @@ allow_gpm_mouse(SCREEN *sp GCC_UNUSED) static void unload_gpm_library(SCREEN *sp) { - if (sp->_dlopen_gpm != 0) { + if (sp->_dlopen_gpm != NULL) { T(("unload GPM library")); sp->_mouse_gpm_loaded = FALSE; sp->_mouse_fd = -1; @@ -522,25 +521,25 @@ load_gpm_library(SCREEN *sp) /* * If we already had a successful dlopen, reuse it. */ - if (sp->_dlopen_gpm != 0) { + if (sp->_dlopen_gpm != NULL) { sp->_mouse_gpm_found = TRUE; sp->_mouse_gpm_loaded = TRUE; - } else if ((sp->_dlopen_gpm = dlopen(LIBGPM_SONAME, my_RTLD)) != 0) { + } else if ((sp->_dlopen_gpm = dlopen(LIBGPM_SONAME, my_RTLD)) != NULL) { #if (defined(__GNUC__) && (__GNUC__ >= 5)) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #endif - if (GET_DLSYM(gpm_fd) == 0 || - GET_DLSYM(Gpm_Open) == 0 || - GET_DLSYM(Gpm_Close) == 0 || - GET_DLSYM(Gpm_GetEvent) == 0) { + if (GET_DLSYM(gpm_fd) == NULL || + GET_DLSYM(Gpm_Open) == NULL || + GET_DLSYM(Gpm_Close) == NULL || + GET_DLSYM(Gpm_GetEvent) == NULL) { #if (defined(__GNUC__) && (__GNUC__ >= 5)) || defined(__clang__) #pragma GCC diagnostic pop #endif T(("GPM initialization failed: %s", dlerror())); unload_gpm_library(sp); dlclose(sp->_dlopen_gpm); - sp->_dlopen_gpm = 0; + sp->_dlopen_gpm = NULL; } else { sp->_mouse_gpm_found = TRUE; sp->_mouse_gpm_loaded = TRUE; @@ -754,14 +753,15 @@ initialize_mousetype(SCREEN *sp) } #endif /* USE_SYSMOUSE */ -#ifdef USE_TERM_DRIVER +#if USE_TERM_DRIVER CallDriver(sp, td_initmouse); #endif -#if !defined(USE_TERM_DRIVER) || defined(EXP_WIN32_DRIVER) +#if !defined(_NC_WINDOWS_NATIVE) || USE_NAMED_PIPES /* we know how to recognize mouse events under "xterm" */ if (NonEmpty(key_mouse)) { init_xterm_mouse(sp); - } else if (strstr(SP_TERMTYPE term_names, "xterm") != 0) { + } else if (SP_TERMTYPE term_names != NULL + && strstr(SP_TERMTYPE term_names, "xterm") != NULL) { if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK) init_xterm_mouse(sp); } @@ -778,7 +778,7 @@ _nc_mouse_init(SCREEN *sp) T((T_CALLED("_nc_mouse_init(%p)"), (void *) sp)); - if (sp != 0) { + if (sp != NULL) { if (!sp->_mouse_initialized) { int i; @@ -786,7 +786,7 @@ _nc_mouse_init(SCREEN *sp) TR(MY_TRACE, ("set _mouse_initialized")); - sp->_mouse_eventp = FirstEV(sp); + sp->_mouse_readp = sp->_mouse_writep = FirstEV(sp); for (i = 0; i < EV_MAX; i++) Invalidate(sp->_mouse_events + i); @@ -796,7 +796,7 @@ _nc_mouse_init(SCREEN *sp) } result = sp->_mouse_initialized; } - returnCode(result); + returnBool(result); } /* @@ -806,7 +806,7 @@ _nc_mouse_init(SCREEN *sp) static bool _nc_mouse_event(SCREEN *sp) { - MEVENT *eventp = sp->_mouse_eventp; + MEVENT *eventp = sp->_mouse_writep; bool result = FALSE; (void) eventp; @@ -874,7 +874,7 @@ _nc_mouse_event(SCREEN *sp) eventp->z = 0; /* bump the next-free pointer into the circular list */ - sp->_mouse_eventp = NEXT(eventp); + sp->_mouse_writep = NEXT(eventp); result = TRUE; break; } @@ -899,13 +899,13 @@ _nc_mouse_event(SCREEN *sp) } /* bump the next-free pointer into the circular list */ - sp->_mouse_eventp = eventp = NEXT(eventp); + sp->_mouse_writep = eventp = NEXT(eventp); result = TRUE; } break; #endif /* USE_SYSMOUSE */ -#ifdef USE_TERM_DRIVER +#if USE_TERM_DRIVER case M_TERM_DRIVER: while (sp->_drv_mouse_head < sp->_drv_mouse_tail) { *eventp = sp->_drv_mouse_fifo[sp->_drv_mouse_head]; @@ -921,7 +921,7 @@ _nc_mouse_event(SCREEN *sp) } /* bump the next-free pointer into the circular list */ - sp->_mouse_eventp = eventp = NEXT(eventp); + sp->_mouse_writep = eventp = NEXT(eventp); result = TRUE; } break; @@ -984,7 +984,12 @@ handle_wheel(SCREEN *sp, MEVENT * eventp, int button, int wheel) } break; case 2: - PRESS_POSITION(3); + if (wheel) { + /* Ignore this event as it is not a true press of the button */ + eventp->bstate = REPORT_MOUSE_POSITION; + } else { + PRESS_POSITION(3); + } break; default: /* @@ -1114,7 +1119,7 @@ decode_xterm_X10(SCREEN *sp, MEVENT * eventp) sp->_ifd, #endif kbuf + grabbed, (size_t) (MAX_KBUF - (int) grabbed)); - if (res == -1) + if (res < 0) break; } _nc_set_read_thread(FALSE); @@ -1162,7 +1167,7 @@ decode_xterm_1005(SCREEN *sp, MEVENT * eventp) sp->_ifd, #endif (kbuf + grabbed), (size_t) 1); - if (res == -1) + if (res < 0) break; grabbed += (size_t) res; if (grabbed > 1) { @@ -1219,7 +1224,7 @@ typedef struct { } SGR_DATA; static bool -read_SGR(SCREEN *sp, SGR_DATA * result) +read_SGR(const SCREEN *sp, SGR_DATA * result) { char kbuf[80]; /* bigger than any possible mouse response */ int grabbed = 0; @@ -1240,7 +1245,7 @@ read_SGR(SCREEN *sp, SGR_DATA * result) sp->_ifd, #endif (kbuf + grabbed), (size_t) 1); - if (res == -1) + if (res < 0) break; if ((grabbed + MAX_KBUF) >= (int) sizeof(kbuf)) { result->nerror++; @@ -1355,9 +1360,9 @@ _nc_mouse_inline(SCREEN *sp) /* mouse report received in the keyboard stream -- parse its info */ { bool result = FALSE; - MEVENT *eventp = sp->_mouse_eventp; + MEVENT *eventp = sp->_mouse_writep; - TR(MY_TRACE, ("_nc_mouse_inline() called")); + TR(MY_TRACE, (T_CALLED("_nc_mouse_inline(%p)"), (void *) sp)); if (sp->_mouse_type == M_XTERM) { switch (sp->_mouse_format) { @@ -1380,7 +1385,7 @@ _nc_mouse_inline(SCREEN *sp) (long) IndexEV(sp, eventp))); /* bump the next-free pointer into the circular list */ - sp->_mouse_eventp = NEXT(eventp); + sp->_mouse_writep = NEXT(eventp); if (!result) { /* If this event is from a wheel-mouse, treat it like position @@ -1400,11 +1405,11 @@ _nc_mouse_inline(SCREEN *sp) } } - return (result); + returnCode(result); } static void -mouse_activate(SCREEN *sp, int on) +mouse_activate(SCREEN *sp, bool on) { T((T_CALLED("mouse_activate(%p,%s)"), (void *) SP_PARM, on ? "on" : "off")); @@ -1422,7 +1427,7 @@ mouse_activate(SCREEN *sp, int on) #if NCURSES_EXT_FUNCS NCURSES_SP_NAME(keyok) (NCURSES_SP_ARGx KEY_MOUSE, on); #endif - enable_xterm_mouse(sp, 1); + enable_xterm_mouse(sp, TRUE); break; #if USE_GPM_SUPPORT case M_GPM: @@ -1438,7 +1443,7 @@ mouse_activate(SCREEN *sp, int on) sp->_mouse_active = TRUE; break; #endif -#ifdef USE_TERM_DRIVER +#if USE_TERM_DRIVER case M_TERM_DRIVER: enable_win32_mouse(sp, TRUE); break; @@ -1462,7 +1467,7 @@ mouse_activate(SCREEN *sp, int on) switch (sp->_mouse_type) { case M_XTERM: - enable_xterm_mouse(sp, 0); + enable_xterm_mouse(sp, FALSE); break; #if USE_GPM_SUPPORT case M_GPM: @@ -1475,7 +1480,7 @@ mouse_activate(SCREEN *sp, int on) sp->_mouse_active = FALSE; break; #endif -#ifdef USE_TERM_DRIVER +#if USE_TERM_DRIVER case M_TERM_DRIVER: enable_win32_mouse(sp, FALSE); break; @@ -1501,7 +1506,7 @@ static bool _nc_mouse_parse(SCREEN *sp, int runcount) /* parse a run of atomic mouse events into a gesture */ { - MEVENT *eventp = sp->_mouse_eventp; + MEVENT *eventp = sp->_mouse_writep; MEVENT *next, *ep; MEVENT *first_valid = NULL; MEVENT *first_invalid = NULL; @@ -1510,7 +1515,14 @@ _nc_mouse_parse(SCREEN *sp, int runcount) bool merge; bool endLoop; - TR(MY_TRACE, ("_nc_mouse_parse(%d) called", runcount)); + TR(MY_TRACE, (T_CALLED("_nc_mouse_parse(%d)"), runcount)); + + if (!sp->_maxclick + && sp->_mouse_readp != NULL + && ValidEvent(sp->_mouse_readp) + && ((sp->_mouse_readp->bstate & sp->_mouse_mask) != 0)) { + returnCode(1); + } /* * When we enter this routine, the event list next-free pointer @@ -1723,7 +1735,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) if (first_invalid == NULL) { first_invalid = eventp; } - sp->_mouse_eventp = first_invalid; + sp->_mouse_writep = first_invalid; #ifdef TRACE if (first_valid != NULL) { @@ -1746,7 +1758,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) /* after all this, do we have a valid event? */ ep = PREV(first_invalid); - return ValidEvent(ep) && ((ep->bstate & sp->_mouse_mask) != 0); + returnCode(ValidEvent(ep) && ((ep->bstate & sp->_mouse_mask) != 0)); } static void @@ -1772,7 +1784,7 @@ _nc_mouse_wrap(SCREEN *sp) mouse_activate(sp, FALSE); break; #endif -#ifdef USE_TERM_DRIVER +#if USE_TERM_DRIVER case M_TERM_DRIVER: mouse_activate(sp, FALSE); break; @@ -1809,7 +1821,7 @@ _nc_mouse_resume(SCREEN *sp) break; #endif -#ifdef USE_TERM_DRIVER +#if USE_TERM_DRIVER case M_TERM_DRIVER: mouse_activate(sp, TRUE); break; @@ -1830,36 +1842,34 @@ NCURSES_EXPORT(int) NCURSES_SP_NAME(getmouse) (NCURSES_SP_DCLx MEVENT * aevent) { int result = ERR; - MEVENT *eventp; + MEVENT *readp; T((T_CALLED("getmouse(%p,%p)"), (void *) SP_PARM, (void *) aevent)); - if ((aevent != 0) && - (SP_PARM != 0) && + if ((aevent != NULL) && + (SP_PARM != NULL) && (SP_PARM->_mouse_type != M_NONE) && - (eventp = SP_PARM->_mouse_eventp) != 0) { - /* compute the current-event pointer */ - MEVENT *prev = PREV(eventp); - + (readp = SP_PARM->_mouse_readp) != NULL) { /* * Discard events not matching mask (there could be still some if * _nc_mouse_parse was not called, e.g., when _nc_mouse_inline returns * false). */ - while (ValidEvent(prev) && (!(prev->bstate & SP_PARM->_mouse_mask2))) { - Invalidate(prev); - prev = PREV(prev); + while (readp != SP_PARM->_mouse_writep && + (!ValidEvent(readp) || !(readp->bstate & SP_PARM->_mouse_mask2))) { + Invalidate(readp); + readp = NEXT(readp); } - if (ValidEvent(prev)) { + if (readp != SP_PARM->_mouse_writep && ValidEvent(readp)) { /* copy the event we find there */ - *aevent = *prev; + *aevent = *readp; TR(TRACE_IEVENT, ("getmouse: returning event %s from slot %ld", - _nc_tracemouse(SP_PARM, prev), - (long) IndexEV(SP_PARM, prev))); + _nc_tracemouse(SP_PARM, readp), + (long) IndexEV(SP_PARM, readp))); - Invalidate(prev); /* so the queue slot becomes free */ - SP_PARM->_mouse_eventp = prev; + Invalidate(readp); /* so the queue slot becomes free */ + SP_PARM->_mouse_readp = NEXT(readp); result = OK; } else { /* Reset the provided event */ @@ -1890,15 +1900,15 @@ NCURSES_SP_NAME(ungetmouse) (NCURSES_SP_DCLx MEVENT * aevent) T((T_CALLED("ungetmouse(%p,%p)"), (void *) SP_PARM, (void *) aevent)); - if (aevent != 0 && - SP_PARM != 0 && - (eventp = SP_PARM->_mouse_eventp) != 0) { + if (aevent != NULL && + SP_PARM != NULL && + (eventp = SP_PARM->_mouse_writep) != NULL) { /* stick the given event in the next-free slot */ *eventp = *aevent; /* bump the next-free pointer into the circular list */ - SP_PARM->_mouse_eventp = NEXT(eventp); + SP_PARM->_mouse_writep = NEXT(eventp); /* push back the notification event on the keyboard queue */ result = NCURSES_SP_NAME(ungetch) (NCURSES_SP_ARGx KEY_MOUSE); @@ -1926,7 +1936,7 @@ NCURSES_SP_NAME(mousemask) (NCURSES_SP_DCLx mmask_t newmask, mmask_t * oldmask) (unsigned long) newmask, (void *) oldmask)); - if (SP_PARM != 0) { + if (SP_PARM != NULL) { if (oldmask) *oldmask = SP_PARM->_mouse_mask; @@ -1988,7 +1998,7 @@ wenclose(const WINDOW *win, int y, int x) T((T_CALLED("wenclose(%p,%d,%d)"), (const void *) win, y, x)); - if (win != 0) { + if (win != NULL) { y -= win->_yoffset; if (IS_PAD(win)) { if (win->_pad._pad_y >= 0 && @@ -2020,7 +2030,7 @@ NCURSES_SP_NAME(mouseinterval) (NCURSES_SP_DCLx int maxclick) T((T_CALLED("mouseinterval(%p,%d)"), (void *) SP_PARM, maxclick)); - if (SP_PARM != 0) { + if (SP_PARM != NULL) { oldval = SP_PARM->_maxclick; if (maxclick >= 0) SP_PARM->_maxclick = maxclick; @@ -2042,9 +2052,9 @@ mouseinterval(int maxclick) /* This may be used by other routines to ask for the existence of mouse support */ NCURSES_EXPORT(bool) -_nc_has_mouse(SCREEN *sp) +_nc_has_mouse(const SCREEN *sp) { - return (((0 == sp) || (sp->_mouse_type == M_NONE)) ? FALSE : TRUE); + return (((NULL == sp) || (sp->_mouse_type == M_NONE)) ? FALSE : TRUE); } NCURSES_EXPORT(bool) |
