From: Thomas E. Dickey Date: Sun, 8 May 2022 00:52:05 +0000 (+0000) Subject: ncurses 6.3 - patch 20220507 X-Git-Tag: v6.4~35 X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=commitdiff_plain;h=f8401f5e8669eadd551fde12da7de661c18fa4f2 ncurses 6.3 - patch 20220507 + add test/test_mouse.c (patch by Leonid S Usov). + add a few debug-traces for tic, fix a couple of memory-leaks. --- diff --git a/MANIFEST b/MANIFEST index ff14eb8e..8c3a1dc1 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1220,6 +1220,7 @@ ./test/test_getstr.c ./test/test_instr.c ./test/test_inwstr.c +./test/test_mouse.c ./test/test_opaque.c ./test/test_setupterm.c ./test/test_sgr.c diff --git a/NEWS b/NEWS index aad5f0d4..bc881eb7 100644 --- a/NEWS +++ b/NEWS @@ -26,7 +26,7 @@ -- sale, use or other dealings in this Software without prior written -- -- authorization. -- ------------------------------------------------------------------------------- --- $Id: NEWS,v 1.3803 2022/05/01 15:16:36 tom Exp $ +-- $Id: NEWS,v 1.3805 2022/05/07 22:42:19 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -46,6 +46,10 @@ 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. +20220507 + + add test/test_mouse.c (patch by Leonid S Usov). + + add a few debug-traces for tic, fix a couple of memory-leaks. + 20220501 + build-fix for debug-traces (report/patch by Chris Clayton). diff --git a/VERSION b/VERSION index 7996e30d..59123a31 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5:0:10 6.3 20220501 +5:0:10 6.3 20220507 diff --git a/dist.mk b/dist.mk index 85c204db..5c0e01ad 100644 --- a/dist.mk +++ b/dist.mk @@ -26,7 +26,7 @@ # use or other dealings in this Software without prior written # # authorization. # ############################################################################## -# $Id: dist.mk,v 1.1478 2022/05/01 10:28:56 tom Exp $ +# $Id: dist.mk,v 1.1479 2022/05/07 11:09:45 tom Exp $ # Makefile for creating ncurses distributions. # # This only needs to be used directly as a makefile by developers, but @@ -38,7 +38,7 @@ SHELL = /bin/sh # These define the major/minor/patch versions of ncurses. NCURSES_MAJOR = 6 NCURSES_MINOR = 3 -NCURSES_PATCH = 20220501 +NCURSES_PATCH = 20220507 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/ncurses/tinfo/alloc_entry.c b/ncurses/tinfo/alloc_entry.c index 48df0fd6..10c4fc75 100644 --- a/ncurses/tinfo/alloc_entry.c +++ b/ncurses/tinfo/alloc_entry.c @@ -48,7 +48,7 @@ #include -MODULE_ID("$Id: alloc_entry.c,v 1.71 2022/04/30 18:36:01 tom Exp $") +MODULE_ID("$Id: alloc_entry.c,v 1.73 2022/05/08 00:11:44 tom Exp $") #define ABSENT_OFFSET -1 #define CANCELLED_OFFSET -2 @@ -60,7 +60,7 @@ NCURSES_EXPORT(void) _nc_init_entry(ENTRY * const tp) /* initialize a terminal type data block */ { - DEBUG(2, (T_CALLED("_nc_init_entry(tp=%p)"), tp)); + DEBUG(2, (T_CALLED("_nc_init_entry(tp=%p)"), (void *) tp)); if (tp == NULL) { #if NO_LEAKS @@ -88,7 +88,7 @@ _nc_copy_entry(ENTRY * oldp) { ENTRY *newp; - DEBUG(2, (T_CALLED("_nc_copy_entry(oldp=%p)"), oldp)); + DEBUG(2, (T_CALLED("_nc_copy_entry(oldp=%p)"), (void *) oldp)); newp = typeCalloc(ENTRY, 1); if (newp != NULL) { @@ -96,7 +96,7 @@ _nc_copy_entry(ENTRY * oldp) _nc_copy_termtype2(&(newp->tterm), &(oldp->tterm)); } - DEBUG(2, (T_RETURN("%p"), newp)); + DEBUG(2, (T_RETURN("%p"), (void *) newp)); return (newp); } @@ -144,6 +144,8 @@ _nc_wrap_entry(ENTRY * const ep, bool copy_strings) unsigned nuses; TERMTYPE2 *tp; + DEBUG(2, (T_CALLED("_nc_wrap_entry(ep=%p, copy_strings=%d)"), (void *) + ep, copy_strings)); if (ep == NULL || stringbuf == NULL) _nc_err_abort("_nc_wrap_entry called without initialization"); @@ -236,6 +238,7 @@ _nc_wrap_entry(ENTRY * const ep, bool copy_strings) else ep->uses[i].name = (tp->str_table + useoffsets[i]); } + DEBUG(2, (T_RETURN(""))); } NCURSES_EXPORT(void) diff --git a/ncurses/tinfo/alloc_ttype.c b/ncurses/tinfo/alloc_ttype.c index eef8170c..9f866323 100644 --- a/ncurses/tinfo/alloc_ttype.c +++ b/ncurses/tinfo/alloc_ttype.c @@ -43,7 +43,7 @@ #include -MODULE_ID("$Id: alloc_ttype.c,v 1.37 2022/04/30 17:00:05 tom Exp $") +MODULE_ID("$Id: alloc_ttype.c,v 1.40 2022/05/08 00:11:44 tom Exp $") #if NCURSES_XNAMES /* @@ -429,7 +429,7 @@ _nc_align_termtype(TERMTYPE2 *to, TERMTYPE2 *from) na = to ? ((int) NUM_EXT_NAMES(to)) : 0; nb = from ? ((int) NUM_EXT_NAMES(from)) : 0; - DEBUG(2, (T_CALLED("align_termtype to(%d:%s), from(%d:%s)"), + DEBUG(2, (T_CALLED("_nc_align_termtype to(%d:%s), from(%d:%s)"), na, to ? NonNull(to->term_names) : "?", nb, from ? NonNull(from->term_names) : "?")); @@ -450,8 +450,10 @@ _nc_align_termtype(TERMTYPE2 *to, TERMTYPE2 *from) break; } } - if (same) + if (same) { + DEBUG(2, (T_RETURN(""))); return; + } } /* * This is where we pay for having a simple extension representation. @@ -533,7 +535,8 @@ copy_termtype(TERMTYPE2 *dst, const TERMTYPE2 *src, int mode) int *newptr = 0; #endif - DEBUG(2, (T_CALLED("copy_termtype(dst=%p, src=%p, mode=%d)"), dst, src, mode)); + DEBUG(2, (T_CALLED("copy_termtype(dst=%p, src=%p, mode=%d)"), (void *) + dst, (const void *) src, mode)); *dst = *src; /* ...to copy the sizes and string-tables */ TYPE_MALLOC(NCURSES_SBOOL, NUM_BOOLEANS(dst), dst->Booleans); @@ -549,6 +552,11 @@ copy_termtype(TERMTYPE2 *dst, const TERMTYPE2 *src, int mode) new_table = NULL; for (pass = 0; pass < 2; ++pass) { size_t str_size = 0; + if (pass) { + dst->term_names = new_table + str_size; + strcpy(dst->term_names + str_size, src->term_names); + } + str_size += strlen(src->term_names) + 1; for (i = 0; i < NUM_STRINGS(dst); ++i) { if (VALID_STRING(src->Strings[i])) { if (pass) { @@ -646,7 +654,8 @@ copy_termtype(TERMTYPE2 *dst, const TERMTYPE2 *src, int mode) NCURSES_EXPORT(void) _nc_copy_termtype(TERMTYPE *dst, const TERMTYPE *src) { - DEBUG(2, (T_CALLED("_nc_copy_termtype(dst=%p, src=%p)"), dst, src)); + DEBUG(2, (T_CALLED("_nc_copy_termtype(dst=%p, src=%p)"), (void *) dst, + (const void *) src)); copy_termtype((TERMTYPE2 *) dst, (const TERMTYPE2 *) src, 0); DEBUG(2, (T_RETURN(""))); } @@ -655,7 +664,8 @@ _nc_copy_termtype(TERMTYPE *dst, const TERMTYPE *src) NCURSES_EXPORT(void) _nc_copy_termtype2(TERMTYPE2 *dst, const TERMTYPE2 *src) { - DEBUG(2, (T_CALLED("_nc_copy_termtype2(dst=%p, src=%p)"), dst, src)); + DEBUG(2, (T_CALLED("_nc_copy_termtype2(dst=%p, src=%p)"), (void *) dst, + (const void *) src)); copy_termtype(dst, src, srcINT | dstINT); DEBUG(2, (T_RETURN(""))); } @@ -667,7 +677,8 @@ _nc_copy_termtype2(TERMTYPE2 *dst, const TERMTYPE2 *src) NCURSES_EXPORT(void) _nc_export_termtype2(TERMTYPE *dst, const TERMTYPE2 *src) { - DEBUG(2, (T_CALLED("_nc_export_termtype2(dst=%p, src=%p)"), dst, src)); + DEBUG(2, (T_CALLED("_nc_export_termtype2(dst=%p, src=%p)"), (void *) + dst, (const void *) src)); copy_termtype((TERMTYPE2 *) dst, src, srcINT); DEBUG(2, (T_RETURN(""))); } diff --git a/ncurses/tinfo/comp_parse.c b/ncurses/tinfo/comp_parse.c index 82672fa8..52ebac49 100644 --- a/ncurses/tinfo/comp_parse.c +++ b/ncurses/tinfo/comp_parse.c @@ -48,7 +48,7 @@ #include -MODULE_ID("$Id: comp_parse.c,v 1.117 2022/04/30 15:57:27 tom Exp $") +MODULE_ID("$Id: comp_parse.c,v 1.122 2022/05/08 00:11:44 tom Exp $") static void sanity_check2(TERMTYPE2 *, bool); NCURSES_IMPEXP void (NCURSES_API *_nc_check_termtype2) (TERMTYPE2 *, bool) = sanity_check2; @@ -61,7 +61,7 @@ enqueue(ENTRY * ep) { ENTRY *newp; - DEBUG(1, (T_CALLED("enqueue(ep=%p)"), ep)); + DEBUG(1, (T_CALLED("enqueue(ep=%p)"), (void *) ep)); newp = _nc_copy_entry(ep); if (newp == 0) @@ -73,6 +73,7 @@ enqueue(ENTRY * ep) newp->next = 0; if (newp->last) newp->last->next = newp; + DEBUG(1, (T_RETURN(""))); } #define NAMEBUFFER_SIZE (MAX_NAME_SIZE + 2) @@ -222,7 +223,7 @@ _nc_read_entry_source(FILE *fp, char *buf, DEBUG(1, (T_CALLED("_nc_read_entry_source(file=%p, buf=%p, literal=%d, silent=%d, hook=%p)"), - fp, buf, literal, silent, hook)); + (void *) fp, buf, literal, silent, (void *) hook)); if (silent) _nc_suppress_warnings = TRUE; /* shut the lexer up, too */ @@ -253,6 +254,7 @@ _nc_read_entry_source(FILE *fp, char *buf, FreeIfNeeded(thisentry.tterm.Strings); #if NCURSES_XNAMES FreeIfNeeded(thisentry.tterm.ext_Names); + FreeIfNeeded(thisentry.tterm.ext_str_table); #endif } } @@ -583,8 +585,10 @@ _nc_resolve_uses2(bool fullresolve, bool literal) FreeIfNeeded(qp->tterm.Booleans); FreeIfNeeded(qp->tterm.Numbers); FreeIfNeeded(qp->tterm.Strings); + FreeIfNeeded(qp->tterm.str_table); #if NCURSES_XNAMES FreeIfNeeded(qp->tterm.ext_Names); + FreeIfNeeded(qp->tterm.ext_str_table); #endif qp->tterm = merged.tterm; _nc_wrap_entry(qp, TRUE); @@ -745,7 +749,7 @@ sanity_check2(TERMTYPE2 *tp, bool literal) NCURSES_EXPORT(void) _nc_leaks_tic(void) { - T((T_CALLED("_nc_free_tic()"))); + T((T_CALLED("_nc_leaks_tic()"))); _nc_globals.leak_checking = TRUE; _nc_alloc_entry_leaks(); _nc_captoinfo_leaks(); @@ -755,11 +759,13 @@ _nc_leaks_tic(void) _nc_codes_leaks(); #endif _nc_tic_expand(0, FALSE, 0); + T((T_RETURN(""))); } NCURSES_EXPORT(void) _nc_free_tic(int code) { + T((T_CALLED("_nc_free_tic(%d)"), code)); _nc_leaks_tic(); exit_terminfo(code); } diff --git a/ncurses/tinfo/comp_scan.c b/ncurses/tinfo/comp_scan.c index 7f9075c7..1d9a9985 100644 --- a/ncurses/tinfo/comp_scan.c +++ b/ncurses/tinfo/comp_scan.c @@ -51,7 +51,7 @@ #include #include -MODULE_ID("$Id: comp_scan.c,v 1.115 2022/04/30 16:21:01 tom Exp $") +MODULE_ID("$Id: comp_scan.c,v 1.116 2022/05/08 00:11:44 tom Exp $") /* * Maximum length of string capability we'll accept before raising an error. @@ -113,7 +113,7 @@ NCURSES_EXPORT(void) _nc_reset_input(FILE *fp, char *buf) { TR(TRACE_DATABASE, - (T_CALLED("_nc_reset_input(fp=%p, buf=%p)"), fp, buf)); + (T_CALLED("_nc_reset_input(fp=%p, buf=%p)"), (void *) fp, buf)); pushtype = NO_PUSHBACK; if (pushname != 0) diff --git a/ncurses/tinfo/entries.c b/ncurses/tinfo/entries.c index c928f7ec..5f49ece9 100644 --- a/ncurses/tinfo/entries.c +++ b/ncurses/tinfo/entries.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2019-2020,2021 Thomas E. Dickey * + * Copyright 2019-2021,2022 Thomas E. Dickey * * Copyright 2006-2012,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * @@ -38,7 +38,7 @@ #include -MODULE_ID("$Id: entries.c,v 1.32 2021/11/20 23:40:57 tom Exp $") +MODULE_ID("$Id: entries.c,v 1.33 2022/05/07 17:08:11 tom Exp $") /**************************************************************************** * @@ -119,7 +119,7 @@ _nc_leaks_tinfo(void) char *s; #endif - T((T_CALLED("_nc_free_tinfo()"))); + T((T_CALLED("_nc_leaks_tinfo()"))); #if NO_LEAKS _nc_globals.leak_checking = TRUE; _nc_free_tparm(cur_term); @@ -161,6 +161,7 @@ _nc_leaks_tinfo(void) NCURSES_EXPORT(void) _nc_free_tinfo(int code) { + T((T_CALLED("_nc_free_tinfo(%d)"), code)); _nc_leaks_tinfo(); exit(code); } @@ -169,6 +170,7 @@ _nc_free_tinfo(int code) NCURSES_EXPORT(void) exit_terminfo(int code) { + T((T_CALLED("exit_terminfo(%d)"), code)); #if NO_LEAKS _nc_leaks_tinfo(); #endif diff --git a/ncurses/tinfo/parse_entry.c b/ncurses/tinfo/parse_entry.c index e39adade..14bcb67e 100644 --- a/ncurses/tinfo/parse_entry.c +++ b/ncurses/tinfo/parse_entry.c @@ -48,7 +48,7 @@ #include #include -MODULE_ID("$Id: parse_entry.c,v 1.106 2022/04/30 20:50:06 tom Exp $") +MODULE_ID("$Id: parse_entry.c,v 1.107 2022/05/08 00:11:44 tom Exp $") #ifdef LINT static short const parametrized[] = @@ -287,7 +287,7 @@ _nc_parse_entry(ENTRY * entryp, int literal, bool silent) TR(TRACE_DATABASE, (T_CALLED("_nc_parse_entry(entry=%p, literal=%d, silent=%d)"), - entryp, literal, silent)); + (void *) entryp, literal, silent)); token_type = _nc_get_token(silent); @@ -766,7 +766,7 @@ postprocess_termcap(TERMTYPE2 *tp, bool has_base) TR(TRACE_DATABASE, (T_CALLED("postprocess_termcap(tp=%p, has_base=%d)"), - tp, has_base)); + (void *) tp, has_base)); /* * TERMCAP DEFAULTS AND OBSOLETE-CAPABILITY TRANSLATIONS @@ -1062,7 +1062,7 @@ postprocess_terminfo(TERMTYPE2 *tp) { TR(TRACE_DATABASE, (T_CALLED("postprocess_terminfo(tp=%p)"), - tp)); + (void *) tp)); /* * TERMINFO-TO-TERMINFO MAPPINGS FOR SOURCE TRANSLATION diff --git a/ncurses/tinfo/read_entry.c b/ncurses/tinfo/read_entry.c index d61e577b..2b1875ed 100644 --- a/ncurses/tinfo/read_entry.c +++ b/ncurses/tinfo/read_entry.c @@ -42,7 +42,7 @@ #include -MODULE_ID("$Id: read_entry.c,v 1.163 2022/04/30 18:35:46 tom Exp $") +MODULE_ID("$Id: read_entry.c,v 1.164 2022/05/08 00:11:44 tom Exp $") #define MyNumber(n) (short) LOW_MSB(n) @@ -214,7 +214,7 @@ _nc_init_termtype(TERMTYPE2 *const tp) { unsigned i; - DEBUG(2, (T_CALLED("_nc_init_termtype(tp=%p)"), tp)); + DEBUG(2, (T_CALLED("_nc_init_termtype(tp=%p)"), (void *) tp)); #if NCURSES_XNAMES tp->num_Booleans = BOOLCOUNT; diff --git a/package/debian-mingw/changelog b/package/debian-mingw/changelog index ad22e9c4..4a68d709 100644 --- a/package/debian-mingw/changelog +++ b/package/debian-mingw/changelog @@ -1,8 +1,8 @@ -ncurses6 (6.3+20220501) unstable; urgency=low +ncurses6 (6.3+20220507) unstable; urgency=low * latest weekly patch - -- Thomas E. Dickey Sun, 01 May 2022 06:28:56 -0400 + -- Thomas E. Dickey Sat, 07 May 2022 07:09:45 -0400 ncurses6 (5.9-20131005) unstable; urgency=low diff --git a/package/debian-mingw64/changelog b/package/debian-mingw64/changelog index ad22e9c4..4a68d709 100644 --- a/package/debian-mingw64/changelog +++ b/package/debian-mingw64/changelog @@ -1,8 +1,8 @@ -ncurses6 (6.3+20220501) unstable; urgency=low +ncurses6 (6.3+20220507) unstable; urgency=low * latest weekly patch - -- Thomas E. Dickey Sun, 01 May 2022 06:28:56 -0400 + -- Thomas E. Dickey Sat, 07 May 2022 07:09:45 -0400 ncurses6 (5.9-20131005) unstable; urgency=low diff --git a/package/debian/changelog b/package/debian/changelog index b023fe12..1c7bc2e6 100644 --- a/package/debian/changelog +++ b/package/debian/changelog @@ -1,8 +1,8 @@ -ncurses6 (6.3+20220501) unstable; urgency=low +ncurses6 (6.3+20220507) unstable; urgency=low * latest weekly patch - -- Thomas E. Dickey Sun, 01 May 2022 06:28:56 -0400 + -- Thomas E. Dickey Sat, 07 May 2022 07:09:45 -0400 ncurses6 (5.9-20120608) unstable; urgency=low diff --git a/package/mingw-ncurses.nsi b/package/mingw-ncurses.nsi index 2fd68b92..19d5c83e 100644 --- a/package/mingw-ncurses.nsi +++ b/package/mingw-ncurses.nsi @@ -1,4 +1,4 @@ -; $Id: mingw-ncurses.nsi,v 1.518 2022/05/01 10:28:56 tom Exp $ +; $Id: mingw-ncurses.nsi,v 1.519 2022/05/07 11:09:45 tom Exp $ ; TODO add examples ; TODO bump ABI to 6 @@ -10,7 +10,7 @@ !define VERSION_MAJOR "6" !define VERSION_MINOR "3" !define VERSION_YYYY "2022" -!define VERSION_MMDD "0501" +!define VERSION_MMDD "0507" !define VERSION_PATCH ${VERSION_YYYY}${VERSION_MMDD} !define MY_ABI "5" diff --git a/package/mingw-ncurses.spec b/package/mingw-ncurses.spec index 51cb8e61..64364f9a 100644 --- a/package/mingw-ncurses.spec +++ b/package/mingw-ncurses.spec @@ -3,7 +3,7 @@ Summary: shared libraries for terminal handling Name: mingw32-ncurses6 Version: 6.3 -Release: 20220501 +Release: 20220507 License: X11 Group: Development/Libraries Source: ncurses-%{version}-%{release}.tgz diff --git a/package/ncurses.spec b/package/ncurses.spec index 66263223..ad46e5ed 100644 --- a/package/ncurses.spec +++ b/package/ncurses.spec @@ -1,7 +1,7 @@ Summary: shared libraries for terminal handling Name: ncurses6 Version: 6.3 -Release: 20220501 +Release: 20220507 License: X11 Group: Development/Libraries Source: ncurses-%{version}-%{release}.tgz diff --git a/package/ncursest.spec b/package/ncursest.spec index e7d42057..a9be86f2 100644 --- a/package/ncursest.spec +++ b/package/ncursest.spec @@ -1,7 +1,7 @@ Summary: Curses library with POSIX thread support. Name: ncursest6 Version: 6.3 -Release: 20220501 +Release: 20220507 License: X11 Group: Development/Libraries Source: ncurses-%{version}-%{release}.tgz diff --git a/test/modules b/test/modules index 8ade4d7a..6c5125f7 100644 --- a/test/modules +++ b/test/modules @@ -1,4 +1,4 @@ -# $Id: modules,v 1.76 2022/04/09 21:27:31 tom Exp $ +# $Id: modules,v 1.77 2022/05/07 22:39:21 tom Exp $ ############################################################################## # Copyright 2018-2021,2022 Thomas E. Dickey # # Copyright 1998-2016,2017 Free Software Foundation, Inc. # @@ -105,6 +105,7 @@ test_get_wstr progs $(srcdir) $(HEADER_DEPS) test_getstr progs $(srcdir) $(HEADER_DEPS) test_instr progs $(srcdir) $(HEADER_DEPS) test_inwstr progs $(srcdir) $(HEADER_DEPS) +test_mouse progs $(srcdir) $(HEADER_DEPS) test_opaque progs $(srcdir) $(HEADER_DEPS) test_setupterm progs $(srcdir) $(HEADER_DEPS) test_sgr progs $(srcdir) $(HEADER_DEPS) diff --git a/test/programs b/test/programs index 10c879bb..306a1b07 100644 --- a/test/programs +++ b/test/programs @@ -1,4 +1,4 @@ -# $Id: programs,v 1.52 2022/04/09 21:27:24 tom Exp $ +# $Id: programs,v 1.53 2022/05/07 22:39:49 tom Exp $ ############################################################################## # Copyright 2018-2021,2022 Thomas E. Dickey # # Copyright 2006-2016,2017 Free Software Foundation, Inc. # @@ -100,6 +100,7 @@ test_get_wstr $(LDFLAGS_CURSES) $(LOCAL_LIBS) test_get_wstr popup_msg test_getstr $(LDFLAGS_CURSES) $(LOCAL_LIBS) test_getstr popup_msg test_instr $(LDFLAGS_CURSES) $(LOCAL_LIBS) test_instr test_inwstr $(LDFLAGS_CURSES) $(LOCAL_LIBS) test_inwstr +test_mouse $(LDFLAGS_CURSES) $(LOCAL_LIBS) test_mouse test_opaque $(LDFLAGS_CURSES) $(LOCAL_LIBS) test_opaque test_setupterm $(LDFLAGS_CURSES) $(LOCAL_LIBS) test_setupterm test_sgr $(LDFLAGS_TINFO) $(LOCAL_LIBS) test_sgr diff --git a/test/test_mouse.c b/test/test_mouse.c new file mode 100644 index 00000000..f96d658c --- /dev/null +++ b/test/test_mouse.c @@ -0,0 +1,244 @@ +/**************************************************************************** + * Copyright 2022 Leonid S. Usov * + * Copyright 2022 Thomas E. Dickey * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************/ +/* + * $Id: test_mouse.c,v 1.8 2022/05/08 00:36:07 tom Exp $ + * + * Author: Leonid S Usov + * + * Observe mouse events in the raw terminal or parsed ncurses modes + */ + +#include + +#if defined(NCURSES_MOUSE_VERSION) && !defined(_NC_WINDOWS) + +static int logoffset = 0; + +static int +raw_loop(void) +{ + struct termios tty; + struct termios old; + char *xtermcap; + + tcgetattr(0, &old); + cfmakeraw(&tty); + + setupterm(NULL, 0, 0); + xtermcap = tigetstr("XM"); + if (xtermcap == 0 || xtermcap == (char *) -1) { + fprintf(stderr, "couldn't get XM terminfo"); + return 1; + } + + putp(tparm(xtermcap, 1)); + fflush(stdout); + + tcsetattr(0, TCSANOW, &tty); + + while (true) { + int c = getc(stdin); + const char *pretty; + + if (c == ERR || c == '\003') { + break; + } else if (c == '\033') { + printf("\r\n"); + } else if ((pretty = unctrl((chtype) c)) != NULL) { + printf("%s", pretty); + } else if (isprint(c)) { + printf("%c", c); + } else { + printf("{%x}", c); + } + } + + putp(tparm(xtermcap, 0)); + fflush(stdout); + tcsetattr(0, TCSANOW, &old); + return 0; +} + +static int logw(int line, const char *fmt, ...) GCC_PRINTFLIKE(2, 3); + +static int +logw(int line, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + wmove(stdscr, line++, 0); + vw_printw(stdscr, fmt, args); + clrtoeol(); + + line %= (getmaxy(stdscr) - logoffset); + if (line < logoffset) { + line = logoffset; + } + + wmove(stdscr, line, 0); + wprintw(stdscr, ">"); + clrtoeol(); + return line; +} + +static void +usage(void) +{ + static const char *msg[] = + { + "Usage: test_mouse [options]", + "", + "Test mouse events. These examples for $TERM demonstrate xterm" + "features:", + " xterm", + " xterm-1002", + " xterm-1003", + "", + "Options:", + " -r show raw input stream, injecting a new line before every ESC", + " -i n set mouse interval to n; default is 0", + " -h show this message", + " -T term use terminal description other than $TERM" + }; + unsigned n; + for (n = 0; n < sizeof(msg) / sizeof(char *); ++n) { + fprintf(stderr, "%s\n", msg[n]); + } +} + +int +main(int argc, char *argv[]) +{ + bool rawmode = FALSE; + int interval = 0; + int curline; + int c; + MEVENT event; + char *my_environ; + const char *term_format = "TERM=%s"; + + while ((c = getopt(argc, argv, "hi:rT:")) != -1) { + switch (c) { + case 'h': + usage(); + ExitProgram(EXIT_SUCCESS); + case 'i': + interval = atoi(optarg); + break; + case 'r': + rawmode = TRUE; + break; + case 'T': + my_environ = malloc(strlen(term_format) + strlen(optarg)); + sprintf(my_environ, term_format, optarg); + putenv(my_environ); + break; + default: + usage(); + ExitProgram(EXIT_FAILURE); + } + } + if (optind < argc) { + usage(); + ExitProgram(EXIT_FAILURE); + } + + if (rawmode) { + printf("Entering raw mode. Ctrl-c to quit.\n"); + return raw_loop(); + } + + initscr(); + clear(); + noecho(); + cbreak(); /* Line buffering disabled; pass everything */ + nonl(); + keypad(stdscr, TRUE); + + /* Get all the mouse events */ + mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL); + mouseinterval(interval); + + logoffset = logw(logoffset, "Ctrl-c to quit"); + logoffset = logw(logoffset, "--------------"); + + curline = logoffset; + + while (1) { + c = getch(); + + switch (c) { + case KEY_MOUSE: + if (getmouse(&event) == OK) { + unsigned btn; + mmask_t events; +#if NCURSES_MOUSE_VERSION > 1 + const int max_btn = 5; +#else + const int max_btn = 4; +#endif + for (btn = 1; btn <= max_btn; btn++) { + events = (mmask_t) (event.bstate + & NCURSES_MOUSE_MASK(btn, + NCURSES_BUTTON_RELEASED | + NCURSES_BUTTON_PRESSED | + NCURSES_BUTTON_CLICKED | + NCURSES_DOUBLE_CLICKED | + NCURSES_TRIPLE_CLICKED)); + if (events == 0) + continue; +#define Show(btn,name) ((event.bstate & NCURSES_MOUSE_MASK(btn, name)) != 0) ? #name : "" + curline = logw(curline, + "button %d %s %s %s %s %s %d[%x] @ %d, %d", + btn, + Show(btn, NCURSES_BUTTON_RELEASED), + Show(btn, NCURSES_BUTTON_PRESSED), + Show(btn, NCURSES_BUTTON_CLICKED), + Show(btn, NCURSES_DOUBLE_CLICKED), + Show(btn, NCURSES_TRIPLE_CLICKED), + (event.bstate & REPORT_MOUSE_POSITION) != 0, + events, + event.y, event.x); + } + } + break; + case '\003': + goto end; + default: + curline = logw(curline, "got another char: 0x%x", c); + } + refresh(); + } + end: + endwin(); + ExitProgram(EXIT_SUCCESS); +} +#else +int +main(void) +{ + printf("This program requires the ncurses library\n"); + ExitProgram(EXIT_FAILURE); +} +#endif