X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fbase%2Flib_mouse.c;h=f4151b815bec87722f4f7dd33a0e9144aeeb02b7;hp=72a99ce7922de9b071f471b77c383df5560411c0;hb=HEAD;hpb=def73dda3feef55f48cc205a763c06ba1ea70e78 diff --git a/ncurses/base/lib_mouse.c b/ncurses/base/lib_mouse.c index 72a99ce7..a03d8b8e 100644 --- a/ncurses/base/lib_mouse.c +++ b/ncurses/base/lib_mouse.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2014,2015 Free Software Foundation, Inc. * + * Copyright 2018-2023,2024 Thomas E. Dickey * + * Copyright 1998-2016,2017 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 +85,7 @@ #define CUR SP_TERMTYPE #endif -MODULE_ID("$Id: lib_mouse.c,v 1.167 2015/10/17 22:08:05 KO.Myung-Hun Exp $") +MODULE_ID("$Id: lib_mouse.c,v 1.200 2024/02/17 21:13:01 tom Exp $") #include @@ -141,19 +142,29 @@ make an error #define MASK_RESERVED_EVENT(x) (mmask_t) NCURSES_MOUSE_MASK(x, 040) #if NCURSES_MOUSE_VERSION == 1 + #define BUTTON_CLICKED (BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED | BUTTON4_CLICKED) #define BUTTON_PRESSED (BUTTON1_PRESSED | BUTTON2_PRESSED | BUTTON3_PRESSED | BUTTON4_PRESSED) #define BUTTON_RELEASED (BUTTON1_RELEASED | BUTTON2_RELEASED | BUTTON3_RELEASED | BUTTON4_RELEASED) #define BUTTON_DOUBLE_CLICKED (BUTTON1_DOUBLE_CLICKED | BUTTON2_DOUBLE_CLICKED | BUTTON3_DOUBLE_CLICKED | BUTTON4_DOUBLE_CLICKED) #define BUTTON_TRIPLE_CLICKED (BUTTON1_TRIPLE_CLICKED | BUTTON2_TRIPLE_CLICKED | BUTTON3_TRIPLE_CLICKED | BUTTON4_TRIPLE_CLICKED) + #define MAX_BUTTONS 4 + #else + #define BUTTON_CLICKED (BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED | BUTTON4_CLICKED | BUTTON5_CLICKED) #define BUTTON_PRESSED (BUTTON1_PRESSED | BUTTON2_PRESSED | BUTTON3_PRESSED | BUTTON4_PRESSED | BUTTON5_PRESSED) #define BUTTON_RELEASED (BUTTON1_RELEASED | BUTTON2_RELEASED | BUTTON3_RELEASED | BUTTON4_RELEASED | BUTTON5_RELEASED) #define BUTTON_DOUBLE_CLICKED (BUTTON1_DOUBLE_CLICKED | BUTTON2_DOUBLE_CLICKED | BUTTON3_DOUBLE_CLICKED | BUTTON4_DOUBLE_CLICKED | BUTTON5_DOUBLE_CLICKED) #define BUTTON_TRIPLE_CLICKED (BUTTON1_TRIPLE_CLICKED | BUTTON2_TRIPLE_CLICKED | BUTTON3_TRIPLE_CLICKED | BUTTON4_TRIPLE_CLICKED | BUTTON5_TRIPLE_CLICKED) + +#if NCURSES_MOUSE_VERSION == 2 #define MAX_BUTTONS 5 +#else +#define MAX_BUTTONS 11 +#endif + #endif #define INVALID_EVENT -1 @@ -225,7 +236,7 @@ write_event(SCREEN *sp, int down, int button, int x, int y) char buf[6]; unsigned long ignore; - strcpy(buf, "\033[M"); /* should be the same as key_mouse */ + _nc_STRCPY(buf, "\033[M", sizeof(buf)); /* 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; @@ -369,7 +380,7 @@ handle_sysmouse(int sig GCC_UNUSED) } #endif /* USE_SYSMOUSE */ -#ifndef USE_TERM_DRIVER +#if !defined(USE_TERM_DRIVER) || defined(EXP_WIN32_DRIVER) #define xterm_kmous "\033[M" static void @@ -408,13 +419,22 @@ init_xterm_mouse(SCREEN *sp) } else { int code = tigetnum("XM"); switch (code) { +#ifdef EXP_XTERM_1005 + case 1005: + /* see "xterm+sm+1005" */ + sp->_mouse_xtermcap = "\033[?1005;1000%?%p1%{1}%=%th%el%;"; + sp->_mouse_format = MF_XTERM_1005; + break; +#endif case 1006: + /* see "xterm+sm+1006" */ + sp->_mouse_xtermcap = "\033[?1006;1000%?%p1%{1}%=%th%el%;"; + sp->_mouse_format = MF_SGR1006; break; default: - code = 1000; + sp->_mouse_xtermcap = "\033[?1000%?%p1%{1}%=%th%el%;"; break; } - sp->_mouse_xtermcap = "\033[?1000%?%p1%{1}%=%th%el%;"; } } #endif @@ -422,14 +442,29 @@ init_xterm_mouse(SCREEN *sp) static void enable_xterm_mouse(SCREEN *sp, int enable) { + TPUTS_TRACE(enable + ? "xterm mouse initialization" + : "xterm mouse deinitialization"); #if USE_EMX_MOUSE sp->_emxmouse_activated = enable; #else - NCURSES_PUTP2("xterm-mouse", TPARM_1(sp->_mouse_xtermcap, enable)); + NCURSES_PUTP2("xterm-mouse", TIPARM_1(sp->_mouse_xtermcap, enable)); #endif sp->_mouse_active = enable; } +#if defined(USE_TERM_DRIVER) +static void +enable_win32_mouse(SCREEN *sp, int enable) +{ +#if defined(EXP_WIN32_DRIVER) + enable_xterm_mouse(sp, enable); +#else + sp->_mouse_active = enable; +#endif +} +#endif + #if USE_GPM_SUPPORT static bool allow_gpm_mouse(SCREEN *sp GCC_UNUSED) @@ -438,7 +473,7 @@ allow_gpm_mouse(SCREEN *sp GCC_UNUSED) #if USE_WEAK_SYMBOLS /* Danger Robinson: do not use dlopen for libgpm if already loaded */ - if ((Gpm_Wgetch)) { + if ((Gpm_Wgetch) != 0) { if (!sp->_mouse_gpm_loaded) { T(("GPM library was already dlopen'd, not by us")); } @@ -476,8 +511,6 @@ unload_gpm_library(SCREEN *sp) T(("unload GPM library")); sp->_mouse_gpm_loaded = FALSE; sp->_mouse_fd = -1; - dlclose(sp->_dlopen_gpm); - sp->_dlopen_gpm = 0; } } @@ -485,20 +518,36 @@ static void load_gpm_library(SCREEN *sp) { sp->_mouse_gpm_found = FALSE; - if ((sp->_dlopen_gpm = dlopen(LIBGPM_SONAME, my_RTLD)) != 0) { + + /* + * If we already had a successful dlopen, reuse it. + */ + if (sp->_dlopen_gpm != 0) { + sp->_mouse_gpm_found = TRUE; + sp->_mouse_gpm_loaded = TRUE; + } else if ((sp->_dlopen_gpm = dlopen(LIBGPM_SONAME, my_RTLD)) != 0) { +#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 (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; } else { sp->_mouse_gpm_found = TRUE; sp->_mouse_gpm_loaded = TRUE; } } } -#endif +#endif /* HAVE_LIBDL */ static bool enable_gpm_mouse(SCREEN *sp, bool enable) @@ -597,8 +646,8 @@ initialize_mousetype(SCREEN *sp) /* OS/2 VIO */ #if USE_EMX_MOUSE if (!sp->_emxmouse_thread - && strstr(TerminalOf(sp)->type.term_names, "xterm") == 0 - && key_mouse) { + && strstr(SP_TERMTYPE term_names, "xterm") == 0 + && NonEmpty(key_mouse)) { int handles[2]; if (pipe(handles) < 0) { @@ -641,13 +690,14 @@ initialize_mousetype(SCREEN *sp) #if USE_SYSMOUSE { + static char dev_tty[] = "/dev/tty"; struct mouse_info the_mouse; char *the_device = 0; if (NC_ISATTY(sp->_ifd)) the_device = ttyname(sp->_ifd); if (the_device == 0) - the_device = "/dev/tty"; + the_device = dev_tty; sp->_mouse_fd = open(the_device, O_RDWR); @@ -706,14 +756,12 @@ initialize_mousetype(SCREEN *sp) #ifdef USE_TERM_DRIVER CallDriver(sp, td_initmouse); -#else +#endif +#if !defined(USE_TERM_DRIVER) || defined(EXP_WIN32_DRIVER) /* we know how to recognize mouse events under "xterm" */ - if (key_mouse != 0) { - if (!strcmp(key_mouse, xterm_kmous) - || strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { - init_xterm_mouse(sp); - } - } else if (strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { + if (NonEmpty(key_mouse)) { + init_xterm_mouse(sp); + } else if (strstr(SP_TERMTYPE term_names, "xterm") != 0) { if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK) init_xterm_mouse(sp); } @@ -727,13 +775,16 @@ _nc_mouse_init(SCREEN *sp) /* initialize the mouse */ { bool result = FALSE; - int i; + + T((T_CALLED("_nc_mouse_init(%p)"), (void *) sp)); if (sp != 0) { if (!sp->_mouse_initialized) { + int i; + sp->_mouse_initialized = TRUE; - TR(MY_TRACE, ("_nc_mouse_init() called")); + TR(MY_TRACE, ("set _mouse_initialized")); sp->_mouse_eventp = FirstEV(sp); for (i = 0; i < EV_MAX; i++) @@ -741,11 +792,11 @@ _nc_mouse_init(SCREEN *sp) initialize_mousetype(sp); - T(("_nc_mouse_init() set mousetype to %d", sp->_mouse_type)); + T(("set _mouse_type to %d", sp->_mouse_type)); } result = sp->_mouse_initialized; } - return result; + returnCode(result); } /* @@ -896,7 +947,7 @@ _nc_mouse_event(SCREEN *sp) #else #define PRESS_POSITION(n) \ do { \ - eventp->bstate = (mmask_t) (sp->_mouse_bstate & MASK_PRESS(n) \ + eventp->bstate = (mmask_t) ((sp->_mouse_bstate & MASK_PRESS(n)) \ ? REPORT_MOUSE_POSITION \ : MASK_PRESS(n)); \ sp->_mouse_bstate |= MASK_PRESS(n); \ @@ -921,7 +972,7 @@ handle_wheel(SCREEN *sp, MEVENT * eventp, int button, int wheel) break; case 1: if (wheel) { -#if NCURSES_MOUSE_VERSION == 2 +#if NCURSES_MOUSE_VERSION >= 2 eventp->bstate = MASK_PRESS(5); /* See comment above for button 4 */ #else @@ -936,6 +987,17 @@ handle_wheel(SCREEN *sp, MEVENT * eventp, int button, int wheel) PRESS_POSITION(3); break; default: + /* + * case 3 is sent when the mouse buttons are released. + * + * If the terminal uses xterm mode 1003, a continuous series of + * button-release events is sent as the mouse moves around the screen, + * or as the wheel mouse is rotated. + * + * Return false in this case, so that when running in X10 mode, we will + * recalculate bstate. + */ + eventp->bstate = REPORT_MOUSE_POSITION; result = FALSE; break; } @@ -946,11 +1008,25 @@ static bool decode_X10_bstate(SCREEN *sp, MEVENT * eventp, unsigned intro) { bool result; - int b; + int button = 0; + int wheel = (intro & 96) == 96; eventp->bstate = 0; - if (!handle_wheel(sp, eventp, (int) intro, (intro & 96) == 96)) { + if (intro >= 96) { + if (intro >= 160) { + button = (int) (intro - 152); /* buttons 8-11 */ + } else { + button = (int) (intro - 92); /* buttons 4-7 */ + } + } else { + button = (intro & 3); + } + + if (button > MAX_BUTTONS) { + eventp->bstate = REPORT_MOUSE_POSITION; + } else if (!handle_wheel(sp, eventp, (int) intro, wheel)) { + /* * Release events aren't reported for individual buttons, just for * the button set as a whole. However, because there are normally @@ -959,6 +1035,8 @@ decode_X10_bstate(SCREEN *sp, MEVENT * eventp, unsigned intro) * the previous event. */ if (sp->_mouse_bstate & BUTTON_PRESSED) { + int b; + eventp->bstate = BUTTON_RELEASED; for (b = 1; b <= MAX_BUTTONS; ++b) { if (!(sp->_mouse_bstate & MASK_PRESS(b))) @@ -1019,18 +1097,14 @@ decode_X10_bstate(SCREEN *sp, MEVENT * eventp, unsigned intro) static bool decode_xterm_X10(SCREEN *sp, MEVENT * eventp) { - unsigned char kbuf[4]; +#define MAX_KBUF 3 + unsigned char kbuf[MAX_KBUF + 1]; size_t grabbed; int res; bool result; -# if USE_PTHREADS_EINTR -# if USE_WEAK_SYMBOLS - if ((pthread_self) && (pthread_kill) && (pthread_equal)) -# endif - _nc_globals.read_thread = pthread_self(); -# endif - for (grabbed = 0; grabbed < 3; grabbed += (size_t) res) { + _nc_set_read_thread(TRUE); + for (grabbed = 0; grabbed < MAX_KBUF; grabbed += (size_t) res) { /* For VIO mouse we add extra bit 64 to disambiguate button-up. */ res = (int) read( @@ -1039,14 +1113,12 @@ decode_xterm_X10(SCREEN *sp, MEVENT * eventp) #else sp->_ifd, #endif - kbuf + grabbed, 3 - grabbed); + kbuf + grabbed, (size_t) (MAX_KBUF - (int) grabbed)); if (res == -1) break; } -#if USE_PTHREADS_EINTR - _nc_globals.read_thread = 0; -#endif - kbuf[3] = '\0'; + _nc_set_read_thread(FALSE); + kbuf[MAX_KBUF] = '\0'; TR(TRACE_IEVENT, ("_nc_mouse_inline sees the following xterm data: '%s'", kbuf)); @@ -1074,19 +1146,14 @@ decode_xterm_1005(SCREEN *sp, MEVENT * eventp) size_t grabbed; size_t limit = (sizeof(kbuf) - 1); unsigned coords[2]; - int res; bool result; coords[0] = 0; coords[1] = 0; -# if USE_PTHREADS_EINTR -# if USE_WEAK_SYMBOLS - if ((pthread_self) && (pthread_kill) && (pthread_equal)) -# endif - _nc_globals.read_thread = pthread_self(); -# endif + _nc_set_read_thread(TRUE); for (grabbed = 0; grabbed < limit;) { + int res; res = (int) read( #if USE_EMX_MOUSE @@ -1094,15 +1161,17 @@ decode_xterm_1005(SCREEN *sp, MEVENT * eventp) #else sp->_ifd, #endif - kbuf + grabbed, 1); + (kbuf + grabbed), (size_t) 1); if (res == -1) break; grabbed += (size_t) res; if (grabbed > 1) { size_t check = 1; int n; - int rc; + for (n = 0; n < 2; ++n) { + int rc; + if (check >= grabbed) break; rc = _nc_conv_to_utf32(&coords[n], kbuf + check, (unsigned) @@ -1115,9 +1184,7 @@ decode_xterm_1005(SCREEN *sp, MEVENT * eventp) break; } } -#if USE_PTHREADS_EINTR - _nc_globals.read_thread = 0; -#endif + _nc_set_read_thread(FALSE); TR(TRACE_IEVENT, ("_nc_mouse_inline sees the following xterm data: %s", @@ -1156,29 +1223,26 @@ read_SGR(SCREEN *sp, SGR_DATA * result) { char kbuf[80]; /* bigger than any possible mouse response */ int grabbed = 0; - int res; int ch = 0; int now = -1; int marker = 1; memset(result, 0, sizeof(*result)); -# if USE_PTHREADS_EINTR -# if USE_WEAK_SYMBOLS - if ((pthread_self) && (pthread_kill) && (pthread_equal)) -# endif - _nc_globals.read_thread = pthread_self(); -# endif + _nc_set_read_thread(TRUE); + do { + int res; + res = (int) read( #if USE_EMX_MOUSE (M_FD(sp) >= 0) ? M_FD(sp) : sp->_ifd, #else sp->_ifd, #endif - kbuf + grabbed, 1); + (kbuf + grabbed), (size_t) 1); if (res == -1) break; - if ((grabbed + 3) >= (int) sizeof(kbuf)) { + if ((grabbed + MAX_KBUF) >= (int) sizeof(kbuf)) { result->nerror++; break; } @@ -1229,9 +1293,7 @@ read_SGR(SCREEN *sp, SGR_DATA * result) } ++grabbed; } while (!isFinal(ch)); -#if USE_PTHREADS_EINTR - _nc_globals.read_thread = 0; -#endif + _nc_set_read_thread(FALSE); kbuf[++grabbed] = 0; TR(TRACE_IEVENT, @@ -1247,10 +1309,21 @@ decode_xterm_SGR1006(SCREEN *sp, MEVENT * eventp) if (read_SGR(sp, &data)) { int b = data.params[0]; int b3 = 1 + (b & 3); + int wheel = ((b & 64) == 64); + + if (b >= 132) { + b3 = MAX_BUTTONS + 1; + } else if (b >= 128) { + b3 = (b - 120); /* buttons 8-11 */ + } else if (b >= 64) { + b3 = (b - 60); /* buttons 6-7 */ + } eventp->id = NORMAL_EVENT; if (data.final == 'M') { - (void) handle_wheel(sp, eventp, b, (b & 64) == 64); + (void) handle_wheel(sp, eventp, b, wheel); + } else if (b3 > MAX_BUTTONS) { + eventp->bstate = REPORT_MOUSE_POSITION; } else { mmask_t pressed = (mmask_t) NCURSES_MOUSE_MASK(b3, NCURSES_BUTTON_PRESSED); mmask_t release = (mmask_t) NCURSES_MOUSE_MASK(b3, NCURSES_BUTTON_RELEASED); @@ -1261,6 +1334,15 @@ decode_xterm_SGR1006(SCREEN *sp, MEVENT * eventp) eventp->bstate = REPORT_MOUSE_POSITION; } } + if (b & 4) { + eventp->bstate |= BUTTON_SHIFT; + } + if (b & 8) { + eventp->bstate |= BUTTON_ALT; + } + if (b & 16) { + eventp->bstate |= BUTTON_CTRL; + } result = (eventp->bstate & REPORT_MOUSE_POSITION) ? TRUE : FALSE; eventp->x = (data.params[1] ? (data.params[1] - 1) : 0); eventp->y = (data.params[2] ? (data.params[2] - 1) : 0); @@ -1324,11 +1406,14 @@ _nc_mouse_inline(SCREEN *sp) static void mouse_activate(SCREEN *sp, int on) { + T((T_CALLED("mouse_activate(%p,%s)"), + (void *) SP_PARM, on ? "on" : "off")); + if (!on && !sp->_mouse_initialized) - return; + returnVoid; if (!_nc_mouse_init(sp)) - return; + returnVoid; if (on) { sp->_mouse_bstate = 0; @@ -1337,7 +1422,6 @@ mouse_activate(SCREEN *sp, int on) #if NCURSES_EXT_FUNCS NCURSES_SP_NAME(keyok) (NCURSES_SP_ARGx KEY_MOUSE, on); #endif - TPUTS_TRACE("xterm mouse initialization"); enable_xterm_mouse(sp, 1); break; #if USE_GPM_SUPPORT @@ -1356,25 +1440,28 @@ mouse_activate(SCREEN *sp, int on) #endif #ifdef USE_TERM_DRIVER case M_TERM_DRIVER: - sp->_mouse_active = TRUE; + enable_win32_mouse(sp, TRUE); break; #endif case M_NONE: - return; + returnVoid; + default: + T(("unexpected mouse mode")); + break; } /* Make runtime binding to cut down on object size of applications that * do not use the mouse (e.g., 'clear'). */ - sp->_mouse_event = _nc_mouse_event; + /* *INDENT-EQLS* */ + sp->_mouse_event = _nc_mouse_event; sp->_mouse_inline = _nc_mouse_inline; - sp->_mouse_parse = _nc_mouse_parse; + sp->_mouse_parse = _nc_mouse_parse; sp->_mouse_resume = _nc_mouse_resume; - sp->_mouse_wrap = _nc_mouse_wrap; + sp->_mouse_wrap = _nc_mouse_wrap; } else { switch (sp->_mouse_type) { case M_XTERM: - TPUTS_TRACE("xterm mouse deinitialization"); enable_xterm_mouse(sp, 0); break; #if USE_GPM_SUPPORT @@ -1390,14 +1477,18 @@ mouse_activate(SCREEN *sp, int on) #endif #ifdef USE_TERM_DRIVER case M_TERM_DRIVER: - sp->_mouse_active = FALSE; + enable_win32_mouse(sp, FALSE); break; #endif case M_NONE: - return; + returnVoid; + default: + T(("unexpected mouse mode")); + break; } } NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG); + returnVoid; } /************************************************************************** @@ -1495,7 +1586,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) if (changed) { merge = FALSE; for (b = 1; b <= MAX_BUTTONS; ++b) { - if ((sp->_mouse_mask & MASK_CLICK(b)) + if ((sp->_mouse_mask2 & MASK_CLICK(b)) && (ep->bstate & MASK_PRESS(b))) { next->bstate &= ~MASK_RELEASE(b); next->bstate |= MASK_CLICK(b); @@ -1576,7 +1667,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) && (next->bstate & BUTTON_CLICKED)) { merge = FALSE; for (b = 1; b <= MAX_BUTTONS; ++b) { - if ((sp->_mouse_mask & MASK_DOUBLE_CLICK(b)) + if ((sp->_mouse_mask2 & MASK_DOUBLE_CLICK(b)) && (ep->bstate & MASK_CLICK(b)) && (next->bstate & MASK_CLICK(b))) { next->bstate &= ~MASK_CLICK(b); @@ -1594,7 +1685,7 @@ _nc_mouse_parse(SCREEN *sp, int runcount) && (next->bstate & BUTTON_CLICKED)) { merge = FALSE; for (b = 1; b <= MAX_BUTTONS; ++b) { - if ((sp->_mouse_mask & MASK_TRIPLE_CLICK(b)) + if ((sp->_mouse_mask2 & MASK_TRIPLE_CLICK(b)) && (ep->bstate & MASK_DOUBLE_CLICK(b)) && (next->bstate & MASK_CLICK(b))) { next->bstate &= ~MASK_CLICK(b); @@ -1654,7 +1745,8 @@ _nc_mouse_parse(SCREEN *sp, int runcount) #endif /* TRACE */ /* after all this, do we have a valid event? */ - return ValidEvent(PREV(first_invalid)); + ep = PREV(first_invalid); + return ValidEvent(ep) && ((ep->bstate & sp->_mouse_mask) != 0); } static void @@ -1738,11 +1830,14 @@ NCURSES_EXPORT(int) NCURSES_SP_NAME(getmouse) (NCURSES_SP_DCLx MEVENT * aevent) { int result = ERR; + MEVENT *eventp; T((T_CALLED("getmouse(%p,%p)"), (void *) SP_PARM, (void *) aevent)); - if ((aevent != 0) && (SP_PARM != 0) && (SP_PARM->_mouse_type != M_NONE)) { - MEVENT *eventp = SP_PARM->_mouse_eventp; + if ((aevent != 0) && + (SP_PARM != 0) && + (SP_PARM->_mouse_type != M_NONE) && + (eventp = SP_PARM->_mouse_eventp) != 0) { /* compute the current-event pointer */ MEVENT *prev = PREV(eventp); @@ -1791,11 +1886,13 @@ NCURSES_EXPORT(int) NCURSES_SP_NAME(ungetmouse) (NCURSES_SP_DCLx MEVENT * aevent) { int result = ERR; + MEVENT *eventp; T((T_CALLED("ungetmouse(%p,%p)"), (void *) SP_PARM, (void *) aevent)); - if (aevent != 0 && SP_PARM != 0) { - MEVENT *eventp = SP_PARM->_mouse_eventp; + if (aevent != 0 && + SP_PARM != 0 && + (eventp = SP_PARM->_mouse_eventp) != 0) { /* stick the given event in the next-free slot */ *eventp = *aevent; @@ -1823,7 +1920,6 @@ 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, @@ -1836,7 +1932,10 @@ NCURSES_SP_NAME(mousemask) (NCURSES_SP_DCLx mmask_t newmask, mmask_t * oldmask) if (newmask || SP_PARM->_mouse_initialized) { _nc_mouse_init(SP_PARM); + if (SP_PARM->_mouse_type != M_NONE) { + int b; + result = newmask & (REPORT_MOUSE_POSITION | BUTTON_ALT @@ -1891,10 +1990,24 @@ wenclose(const WINDOW *win, int y, int x) if (win != 0) { y -= win->_yoffset; - result = ((win->_begy <= y && - win->_begx <= x && - (win->_begx + win->_maxx) >= x && - (win->_begy + win->_maxy) >= y) ? TRUE : FALSE); + if (IS_PAD(win)) { + if (win->_pad._pad_y >= 0 && + win->_pad._pad_x >= 0 && + win->_pad._pad_top >= 0 && + win->_pad._pad_left >= 0 && + win->_pad._pad_right >= 0 && + win->_pad._pad_bottom >= 0) { + result = ((win->_pad._pad_top <= y && + win->_pad._pad_left <= x && + win->_pad._pad_right >= x && + win->_pad._pad_bottom >= y) ? TRUE : FALSE); + } + } else { + result = ((win->_begy <= y && + win->_begx <= x && + (win->_begx + win->_maxx) >= x && + (win->_begy + win->_maxy) >= y) ? TRUE : FALSE); + } } returnBool(result); } @@ -1963,6 +2076,7 @@ wmouse_trafo(const WINDOW *win, int *pY, int *pX, bool to_screen) int y = *pY; int x = *pX; + T(("transform input %d,%d", y, x)); if (to_screen) { y += win->_begy + win->_yoffset; x += win->_begx; @@ -1978,6 +2092,7 @@ wmouse_trafo(const WINDOW *win, int *pY, int *pX, bool to_screen) if (result) { *pX = x; *pY = y; + T(("output transform %d,%d", y, x)); } } returnBool(result);