From 10539f5afe94d8ff488516ca7f9861af7c800bfb Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sat, 10 Apr 2010 23:46:02 +0000 Subject: [PATCH] ncurses 5.7 - patch 20100410 + improve win_driver.c handling of mouse: + discard motion events + avoid calling _nc_timed_wait when there is a mouse event + handle 4th and "rightmost" buttons. + quote substitutions in CF_RPATH_HACK_2 configure macro, needed for cases where there are embedded blanks in the rpath option. --- NEWS | 10 ++- aclocal.m4 | 8 +-- configure | 8 +-- dist.mk | 4 +- ncurses/base/lib_getch.c | 48 ++++++------- ncurses/curses.priv.h | 6 +- ncurses/tinfo/tinfo_driver.c | 36 +++++++++- ncurses/win32con/win_driver.c | 126 +++++++++++++++++++++++++++------- 8 files changed, 179 insertions(+), 67 deletions(-) diff --git a/NEWS b/NEWS index d6ee1aa7..bc642b32 100644 --- a/NEWS +++ b/NEWS @@ -25,7 +25,7 @@ -- sale, use or other dealings in this Software without prior written -- -- authorization. -- ------------------------------------------------------------------------------- --- $Id: NEWS,v 1.1526 2010/04/03 14:46:26 tom Exp $ +-- $Id: NEWS,v 1.1528 2010/04/10 21:23:37 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,14 @@ See the AUTHORS file for the corresponding full names. Changes through 1.9.9e did not credit all contributions; it is not possible to add this information. +20100410 + + improve win_driver.c handling of mouse: + + discard motion events + + avoid calling _nc_timed_wait when there is a mouse event + + handle 4th and "rightmost" buttons. + + quote substitutions in CF_RPATH_HACK_2 configure macro, needed for + cases where there are embedded blanks in the rpath option. + 20100403 + add configure check for exctags vs ctags, to work around pkgsrc. + simplify logic in _nc_get_screensize() to make it easier to see how diff --git a/aclocal.m4 b/aclocal.m4 index 1efb9e20..670fb776 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -28,7 +28,7 @@ dnl*************************************************************************** dnl dnl Author: Thomas E. Dickey 1995-on dnl -dnl $Id: aclocal.m4,v 1.507 2010/04/04 00:07:57 tom Exp $ +dnl $Id: aclocal.m4,v 1.508 2010/04/06 00:03:50 tom Exp $ dnl Macros used in NCURSES auto-configuration script. dnl dnl These macros are maintained separately from NCURSES. The copyright on @@ -4394,7 +4394,7 @@ fi AC_SUBST(EXTRA_LDFLAGS) ])dnl dnl --------------------------------------------------------------------------- -dnl CF_RPATH_HACK_2 version: 3 updated: 2010/04/02 20:27:47 +dnl CF_RPATH_HACK_2 version: 4 updated: 2010/04/05 20:03:50 dnl --------------- dnl Do one set of substitutions for CF_RPATH_HACK, adding an rpath option to dnl EXTRA_LDFLAGS for each -L option found. @@ -4411,9 +4411,9 @@ do case $cf_rpath_src in #(vi -L*) #(vi if test "$LD_RPATH_OPT" = "-R " ; then - cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e 's%-L%-R %'` + cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e "s%-L%-R %"` else - cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e s%-L%$LD_RPATH_OPT%` + cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e "s%-L%$LD_RPATH_OPT%"` fi CF_VERBOSE(...Filter $cf_rpath_src ->$cf_rpath_tmp) EXTRA_LDFLAGS="$cf_rpath_tmp $EXTRA_LDFLAGS" diff --git a/configure b/configure index edd87f15..65ae7b98 100755 --- a/configure +++ b/configure @@ -18465,9 +18465,9 @@ do case $cf_rpath_src in #(vi -L*) #(vi if test "$LD_RPATH_OPT" = "-R " ; then - cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e 's%-L%-R %'` + cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e "s%-L%-R %"` else - cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e s%-L%$LD_RPATH_OPT%` + cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e "s%-L%$LD_RPATH_OPT%"` fi test -n "$verbose" && echo " ...Filter $cf_rpath_src ->$cf_rpath_tmp" 1>&6 @@ -18494,9 +18494,9 @@ do case $cf_rpath_src in #(vi -L*) #(vi if test "$LD_RPATH_OPT" = "-R " ; then - cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e 's%-L%-R %'` + cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e "s%-L%-R %"` else - cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e s%-L%$LD_RPATH_OPT%` + cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e "s%-L%$LD_RPATH_OPT%"` fi test -n "$verbose" && echo " ...Filter $cf_rpath_src ->$cf_rpath_tmp" 1>&6 diff --git a/dist.mk b/dist.mk index 442a4d61..7ae26288 100644 --- a/dist.mk +++ b/dist.mk @@ -25,7 +25,7 @@ # use or other dealings in this Software without prior written # # authorization. # ############################################################################## -# $Id: dist.mk,v 1.753 2010/03/28 19:31:16 tom Exp $ +# $Id: dist.mk,v 1.754 2010/04/06 00:03:50 tom Exp $ # Makefile for creating ncurses distributions. # # This only needs to be used directly as a makefile by developers, but @@ -37,7 +37,7 @@ SHELL = /bin/sh # These define the major/minor/patch versions of ncurses. NCURSES_MAJOR = 5 NCURSES_MINOR = 7 -NCURSES_PATCH = 20100403 +NCURSES_PATCH = 20100410 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/ncurses/base/lib_getch.c b/ncurses/base/lib_getch.c index e3e4075f..09d4ea1c 100644 --- a/ncurses/base/lib_getch.c +++ b/ncurses/base/lib_getch.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. * + * Copyright (c) 1998-2009,2010 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 * @@ -42,7 +42,7 @@ #include -MODULE_ID("$Id: lib_getch.c,v 1.110 2010/02/06 18:39:16 tom Exp $") +MODULE_ID("$Id: lib_getch.c,v 1.111 2010/04/10 19:08:59 tom Exp $") #include @@ -124,12 +124,6 @@ _nc_use_meta(WINDOW *win) return (sp ? sp->_use_meta : 0); } -#ifdef NCURSES_WGETCH_EVENTS -#define TWAIT_MASK (TW_ANY | TW_EVENT) -#else -#define TWAIT_MASK TW_ANY -#endif - /* * Check for mouse activity, returning nonzero if we find any. */ @@ -138,31 +132,29 @@ check_mouse_activity(SCREEN *sp, int delay EVENTLIST_2nd(_nc_eventlist * evl)) { int rc; +#ifdef USE_TERM_DRIVER + rc = TCBOf(sp)->drv->testmouse(TCBOf(sp), delay); +#else #if USE_SYSMOUSE if ((sp->_mouse_type == M_SYSMOUSE) && (sp->_sysmouse_head < sp->_sysmouse_tail)) { - return TW_MOUSE; - } -#endif -#ifdef USE_TERM_DRIVER - rc = TCBOf(sp)->drv->twait(TCBOf(sp), - TWAIT_MASK, - delay, - (int *) 0 - EVENTLIST_2nd(evl)); -#else - rc = _nc_timed_wait(sp, - TWAIT_MASK, - delay, - (int *) 0 - EVENTLIST_2nd(evl)); + rc = TW_MOUSE; + } else #endif + { + rc = _nc_timed_wait(sp, + TWAIT_MASK, + delay, + (int *) 0 + EVENTLIST_2nd(evl)); #if USE_SYSMOUSE - if ((sp->_mouse_type == M_SYSMOUSE) - && (sp->_sysmouse_head < sp->_sysmouse_tail) - && (rc == 0) - && (errno == EINTR)) { - rc |= TW_MOUSE; + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail) + && (rc == 0) + && (errno == EINTR)) { + rc |= TW_MOUSE; + } +#endif } #endif return rc; diff --git a/ncurses/curses.priv.h b/ncurses/curses.priv.h index 47b3e95e..e465faa3 100644 --- a/ncurses/curses.priv.h +++ b/ncurses/curses.priv.h @@ -35,7 +35,7 @@ /* - * $Id: curses.priv.h,v 1.457 2010/03/31 23:42:32 tom Exp $ + * $Id: curses.priv.h,v 1.458 2010/04/10 19:12:32 tom Exp $ * * curses.priv.h * @@ -1655,10 +1655,12 @@ extern NCURSES_EXPORT(void) name (void); \ #define EVENTLIST_0th(param) param #define EVENTLIST_1st(param) param #define EVENTLIST_2nd(param) , param +#define TWAIT_MASK (TW_ANY | TW_EVENT) #else #define EVENTLIST_0th(param) void #define EVENTLIST_1st(param) /* nothing */ #define EVENTLIST_2nd(param) /* nothing */ +#define TWAIT_MASK TW_ANY #endif #if NCURSES_EXPANDED && NCURSES_EXT_FUNCS @@ -2044,6 +2046,7 @@ typedef struct _termInfo int maxpairs; int nocolorvideo; + int numbuttons; int numlabels; int labelwidth; int labelheight; @@ -2069,6 +2072,7 @@ typedef struct term_driver { void (*initcolor)(struct DriverTCB*,short,short,short,short); void (*docolor)(struct DriverTCB*,short,short,bool,int(*)(SCREEN*,int)); void (*initmouse)(struct DriverTCB*); + int (*testmouse)(struct DriverTCB*,int); void (*setfilter)(struct DriverTCB*); void (*hwlabel)(struct DriverTCB*,int,char*); void (*hwlabelOnOff)(struct DriverTCB*,bool); diff --git a/ncurses/tinfo/tinfo_driver.c b/ncurses/tinfo/tinfo_driver.c index 8c16bf90..d45ef0b6 100644 --- a/ncurses/tinfo/tinfo_driver.c +++ b/ncurses/tinfo/tinfo_driver.c @@ -50,7 +50,7 @@ # endif #endif -MODULE_ID("$Id: tinfo_driver.c,v 1.8 2010/04/03 14:10:56 tom Exp $") +MODULE_ID("$Id: tinfo_driver.c,v 1.9 2010/04/10 16:11:17 tom Exp $") /* * SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS, @@ -876,6 +876,39 @@ drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB) } } +static int +drv_testmouse(TERMINAL_CONTROL_BLOCK * TCB, int delay) +{ + int rc = 0; + SCREEN *sp; + + AssertTCB(); + SetSP(); + +#if USE_SYSMOUSE + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail)) { + rc = TW_MOUSE; + } else +#endif + { + rc = TCBOf(sp)->drv->twait(TCBOf(sp), + TWAIT_MASK, + delay, + (int *) 0 + EVENTLIST_2nd(evl)); +#if USE_SYSMOUSE + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail) + && (rc == 0) + && (errno == EINTR)) { + rc |= TW_MOUSE; + } +#endif + } + return rc; +} + static int drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB, int yold, int xold, int ynew, int xnew) { @@ -1308,6 +1341,7 @@ NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_TINFO_DRIVER = { drv_initcolor, /* initcolor */ drv_do_color, /* docolor */ drv_initmouse, /* initmouse */ + drv_testmouse, /* testmouse */ drv_setfilter, /* setfilter */ drv_hwlabel, /* hwlabel */ drv_hwlabelOnOff, /* hwlabelOnOff */ diff --git a/ncurses/win32con/win_driver.c b/ncurses/win32con/win_driver.c index 3beb0b37..2b159b18 100644 --- a/ncurses/win32con/win_driver.c +++ b/ncurses/win32con/win_driver.c @@ -38,7 +38,7 @@ #include -MODULE_ID("$Id: win_driver.c,v 1.7 2010/03/31 23:21:39 tom Exp $") +MODULE_ID("$Id: win_driver.c,v 1.8 2010/04/10 19:42:47 tom Exp $") #define WINMAGIC NCDRV_MAGIC(NCDRV_WINCONSOLE) @@ -568,6 +568,8 @@ drv_release(TERMINAL_CONTROL_BLOCK * TCB) static void drv_init(TERMINAL_CONTROL_BLOCK * TCB) { + DWORD num_buttons; + T((T_CALLED("drv_init(%p)"), TCB)); AssertTCB(); @@ -610,6 +612,13 @@ drv_init(TERMINAL_CONTROL_BLOCK * TCB) TCB->info.nocolorvideo = 1; TCB->info.tabsize = 8; + if (GetNumberOfConsoleMouseButtons(&num_buttons)) { + T(("mouse has %ld buttons", num_buttons)); + TCB->info.numbuttons = num_buttons; + } else { + TCB->info.numbuttons = 1; + } + TCB->info.defaultPalette = _nc_cga_palette; for (i = 0; i < (N_INI + FKEYS); i++) { @@ -690,6 +699,28 @@ drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB) sp->_mouse_type = M_TERM_DRIVER; } +static int +drv_testmouse(TERMINAL_CONTROL_BLOCK * TCB, int delay) +{ + int rc = 0; + SCREEN *sp; + + AssertTCB(); + SetSP(); + + if (sp->_drv_mouse_head < sp->_drv_mouse_tail) { + rc = TW_MOUSE; + } else { + rc = TCBOf(sp)->drv->twait(TCBOf(sp), + TWAIT_MASK, + delay, + (int *) 0 + EVENTLIST_2nd(evl)); + } + + return rc; +} + static int drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB, int yold GCC_UNUSED, int xold GCC_UNUSED, @@ -818,6 +849,50 @@ Adjust(int milliseconds, int diff) return milliseconds; } +#define BUTTON_MASK (FROM_LEFT_1ST_BUTTON_PRESSED | \ + FROM_LEFT_2ND_BUTTON_PRESSED | \ + FROM_LEFT_3RD_BUTTON_PRESSED | \ + FROM_LEFT_4TH_BUTTON_PRESSED | \ + RIGHTMOST_BUTTON_PRESSED) + +static int +decode_mouse(TERMINAL_CONTROL_BLOCK * TCB, int mask) +{ + SCREEN *sp; + int result = 0; + + AssertTCB(); + SetSP(); + + if (mask & FROM_LEFT_1ST_BUTTON_PRESSED) + result |= BUTTON1_PRESSED; + if (mask & FROM_LEFT_2ND_BUTTON_PRESSED) + result |= BUTTON2_PRESSED; + if (mask & FROM_LEFT_3RD_BUTTON_PRESSED) + result |= BUTTON3_PRESSED; + if (mask & FROM_LEFT_4TH_BUTTON_PRESSED) + result |= BUTTON4_PRESSED; + + if (mask & RIGHTMOST_BUTTON_PRESSED) { + switch (TCB->info.numbuttons) { + case 1: + result |= BUTTON1_PRESSED; + break; + case 2: + result |= BUTTON2_PRESSED; + break; + case 3: + result |= BUTTON3_PRESSED; + break; + case 4: + result |= BUTTON4_PRESSED; + break; + } + } + + return result; +} + static int drv_twait(TERMINAL_CONTROL_BLOCK * TCB, int mode, @@ -840,6 +915,9 @@ drv_twait(TERMINAL_CONTROL_BLOCK * TCB, AssertTCB(); SetSP(); + TR(TRACE_IEVENT, ("start twait: %d milliseconds, mode: %d", + milliseconds, mode)); + if (milliseconds < 0) milliseconds = INFINITY; @@ -883,11 +961,15 @@ drv_twait(TERMINAL_CONTROL_BLOCK * TCB, } continue; case MOUSE_EVENT: - if (0 && mode & TW_MOUSE) { + if (decode_mouse(TCB, + (inp.Event.MouseEvent.dwButtonState + & BUTTON_MASK)) == 0) { + CONSUME(); + } else if (mode & TW_MOUSE) { code = TW_MOUSE; goto end; - } else - continue; + } + continue; default: SetConsoleActiveScreenBuffer(!PropOf(TCB)->progMode ? TCB->hdl : TCB->out); @@ -908,22 +990,26 @@ drv_twait(TERMINAL_CONTROL_BLOCK * TCB, } } end: + + TR(TRACE_IEVENT, ("end twait: returned %d (%d), remaining time %d msec", + code, errno, milliseconds)); + if (timeleft) *timeleft = milliseconds; return code; } -#define BUTTON_MASK (FROM_LEFT_1ST_BUTTON_PRESSED | \ - FROM_LEFT_2ND_BUTTON_PRESSED | \ - FROM_LEFT_3RD_BUTTON_PRESSED) - static bool -handle_mouse(SCREEN *sp, MOUSE_EVENT_RECORD mer) +handle_mouse(TERMINAL_CONTROL_BLOCK * TCB, MOUSE_EVENT_RECORD mer) { + SCREEN *sp; MEVENT work; bool result = FALSE; + AssertTCB(); + SetSP(); + sp->_drv_mouse_old_buttons = sp->_drv_mouse_new_buttons; sp->_drv_mouse_new_buttons = mer.dwButtonState & BUTTON_MASK; @@ -937,25 +1023,12 @@ handle_mouse(SCREEN *sp, MOUSE_EVENT_RECORD mer) if (sp->_drv_mouse_new_buttons) { - if (sp->_drv_mouse_new_buttons & FROM_LEFT_1ST_BUTTON_PRESSED) - work.bstate |= BUTTON1_PRESSED; - if (sp->_drv_mouse_new_buttons & FROM_LEFT_2ND_BUTTON_PRESSED) - work.bstate |= BUTTON2_PRESSED; - if (sp->_drv_mouse_new_buttons & FROM_LEFT_3RD_BUTTON_PRESSED) - work.bstate |= BUTTON3_PRESSED; - if (sp->_drv_mouse_new_buttons & FROM_LEFT_4TH_BUTTON_PRESSED) - work.bstate |= BUTTON4_PRESSED; + work.bstate |= decode_mouse(TCB, sp->_drv_mouse_new_buttons); } else { - if (sp->_drv_mouse_old_buttons & FROM_LEFT_1ST_BUTTON_PRESSED) - work.bstate |= BUTTON1_RELEASED; - if (sp->_drv_mouse_old_buttons & FROM_LEFT_2ND_BUTTON_PRESSED) - work.bstate |= BUTTON2_RELEASED; - if (sp->_drv_mouse_old_buttons & FROM_LEFT_3RD_BUTTON_PRESSED) - work.bstate |= BUTTON3_RELEASED; - if (sp->_drv_mouse_old_buttons & FROM_LEFT_4TH_BUTTON_PRESSED) - work.bstate |= BUTTON4_RELEASED; + /* cf: BUTTON_PRESSED, BUTTON_RELEASED */ + work.bstate |= (decode_mouse(TCB, sp->_drv_mouse_old_buttons) >> 1); result = TRUE; } @@ -1009,7 +1082,7 @@ drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf) break; } } else if (inp.EventType == MOUSE_EVENT) { - if (handle_mouse(sp, inp.Event.MouseEvent)) { + if (handle_mouse(TCB, inp.Event.MouseEvent)) { *buf = KEY_MOUSE; break; } @@ -1119,6 +1192,7 @@ NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_WIN_DRIVER = { drv_initcolor, /* initcolor */ drv_do_color, /* docolor */ drv_initmouse, /* initmouse */ + drv_testmouse, /* testmouse */ drv_setfilter, /* setfilter */ drv_hwlabel, /* hwlabel */ drv_hwlabelOnOff, /* hwlabelOnOff */