From ed530db2c5b10aa19d06104dfe82cf248a813860 Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sun, 4 May 2008 00:48:16 +0000 Subject: [PATCH] ncurses 5.6 - patch 20080503 + modify screen.* terminfo entries using new screen+fkeys to fix overridden keys in screen.rxvt (Debian #478094) -TD + modify internal interfaces to reduce wgetch()'s dependency on the global SP. + simplify some loops with macros each_screen(), each_window() and each_ripoff(). + continue modifying test/ditto.c toward making it demonstrate multithreaded use_screen(), using fifos to pass data between screens. + fix typo in form.3x (report by Mike Gran). --- NEWS | 15 ++- dist.mk | 4 +- man/form.3x | 6 +- misc/terminfo.src | 34 +++-- ncurses/base/lib_delwin.c | 6 +- ncurses/base/lib_freeall.c | 8 +- ncurses/base/lib_getch.c | 165 ++++++++++++------------ ncurses/base/lib_newwin.c | 24 ++-- ncurses/base/lib_restart.c | 6 +- ncurses/base/lib_set_term.c | 39 ++++-- ncurses/base/lib_ungetch.c | 49 +++++--- ncurses/base/resizeterm.c | 16 +-- ncurses/base/use_window.c | 6 +- ncurses/base/wresize.c | 6 +- ncurses/curses.priv.h | 29 +++-- ncurses/fifo_defs.h | 10 +- ncurses/tinfo/init_keytry.c | 18 +-- ncurses/tinfo/lib_napms.c | 6 +- ncurses/tinfo/lib_options.c | 20 +-- ncurses/tinfo/lib_setup.c | 37 +++--- ncurses/tinfo/lib_ttyflags.c | 8 +- ncurses/tty/lib_tstp.c | 18 ++- ncurses/tty/lib_twait.c | 19 +-- ncurses/tty/tty_update.c | 8 +- test/ditto.c | 238 +++++++++++++++++++++++++---------- 25 files changed, 474 insertions(+), 321 deletions(-) diff --git a/NEWS b/NEWS index 0a2f4b81..c5126da0 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.1228 2008/04/19 23:03:52 tom Exp $ +-- $Id: NEWS,v 1.1233 2008/05/03 23:14:39 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,19 @@ 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. +20080503 + + modify screen.* terminfo entries using new screen+fkeys to fix + overridden keys in screen.rxvt (Debian #478094) -TD + + modify internal interfaces to reduce wgetch()'s dependency on the + global SP. + + simplify some loops with macros each_screen(), each_window() and + each_ripoff(). + +20080426 + + continue modifying test/ditto.c toward making it demonstrate + multithreaded use_screen(), using fifos to pass data between screens. + + fix typo in form.3x (report by Mike Gran). + 20080419 + add screen.rxvt terminfo entry -TD + modify tic -f option to format spaces as \s to prevent them from diff --git a/dist.mk b/dist.mk index d2923b7e..f4becd9b 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.639 2008/04/19 16:27:47 tom Exp $ +# $Id: dist.mk,v 1.641 2008/05/03 12:31:08 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 = 6 -NCURSES_PATCH = 20080419 +NCURSES_PATCH = 20080503 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/man/form.3x b/man/form.3x index 264662e6..75fc78ae 100644 --- a/man/form.3x +++ b/man/form.3x @@ -1,6 +1,6 @@ '\" t .\"*************************************************************************** -.\" Copyright (c) 1998-2002,2006 Free Software Foundation, Inc. * +.\" Copyright (c) 1998-2006,2008 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 * @@ -27,7 +27,7 @@ .\" authorization. * .\"*************************************************************************** .\" -.\" $Id: form.3x,v 1.20 2006/11/04 18:50:09 tom Exp $ +.\" $Id: form.3x,v 1.21 2008/04/26 17:11:52 tom Exp $ .TH form 3X "" .SH NAME \fBform\fR - curses extension for programming forms @@ -69,7 +69,7 @@ current_field \fBform_page\fR(3X) data_ahead \fBform_data\fR(3X) data_behind \fBform_data\fR(3X) dup_field \fBform_field_new\fR(3X) -dynamic_fieldinfo \fBform_field_info\fR(3X) +dynamic_field_info \fBform_field_info\fR(3X) field_arg \fBform_field_validation\fR(3X) field_back \fBform_field_attributes\fR(3X) field_buffer \fBform_field_buffer\fR(3X) diff --git a/misc/terminfo.src b/misc/terminfo.src index e86848f2..8627cece 100644 --- a/misc/terminfo.src +++ b/misc/terminfo.src @@ -6,8 +6,8 @@ # Report bugs and new terminal descriptions to # bug-ncurses@gnu.org # -# $Revision: 1.327 $ -# $Date: 2008/04/19 22:51:50 $ +# $Revision: 1.328 $ +# $Date: 2008/04/29 00:49:41 $ # # The original header is preserved below for reference. It is noted that there # is a "newer" version which differs in some cosmetic details (but actually @@ -4359,13 +4359,20 @@ screen-256color-bce-s|GNU Screen with 256 colors, BCE, and status line, # if the terminal is wide (132 cols or more)). If even this # entry cannot be found, "vt100" is used as a substitute. # +# Notwithstanding the manpage, screen uses its own notion of the termcap +# and some keys from "screen." are ignored. Here is an entry which +# covers those (tested with screen 4.00.02) -TD +screen+fkeys|function-keys according to screen, + kend=\E[4~, kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, kfnd@, + khome=\E[1~, kslt@, +# # Here are a few customized entries which are useful -TD # # Notes: # (a) screen does not support invis. # (b) screen's implementation of bw is incorrect according to tack. # (c) screen appears to hardcode the strings for khome/kend, making it -# necessary to override the "use=" clause's values. +# necessary to override the "use=" clause's values (screen+fkeys). # (d) screen sets $TERMCAP to a termcap-formatted copy of the 'screen' entry, # which is NOT the same as the terminfo screen.. # (e) when screen finds one of these customized entries, it sets $TERM to @@ -4377,31 +4384,29 @@ screen-256color-bce-s|GNU Screen with 256 colors, BCE, and status line, # translation. They are suppressed here to show what is tested by tack. screen.xterm-xfree86|screen.xterm-new|screen customized for modern xterm, bce@, bw, - invis@, kIC@, kNXT@, kPRV@, kend=\E[4~, khome=\E[1~, meml@, - memu@, + invis@, kIC@, kNXT@, kPRV@, meml@, memu@, sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m, - use=xterm-new, + use=screen+fkeys, use=xterm-new, # xterm-r6 does not really support khome/kend unless it is propped up by # the translations resource. screen.xterm-r6|screen customized for X11R6 xterm, - bw, use=xterm-r6, + bw, use=screen+fkeys, use=xterm-r6, # Color applications running in screen and TeraTerm do not play well together # on Solaris because Sun's curses implementation gets confused. screen.teraterm|disable ncv in teraterm, ncv#127, acsc=+\020\,\021-\030.^Y0\333`\004a\261f\370g\361h\260i\316j\331k\277l\332m\300n\305o~p\304q\304r\304s_t\303u\264v\301w\302x\263y\363z\362{\343|\330}\234~\376, - use=screen, + use=screen+fkeys, use=screen, # Other terminals screen.rxvt|screen in rxvt, bw, cvvis@, flash@, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, - kcuu1=\EOA, kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, - use=vt100+enq, use=rxvt+pcfkeys, use=vt220+keypad, - use=screen, + kcuu1=\EOA, use=screen+fkeys, use=vt100+enq, + use=rxvt+pcfkeys, use=vt220+keypad, use=screen, # fix the backspace key screen.linux|screen in linux console, bw, - kbs=\177, kcbt@, use=screen, + kbs=\177, kcbt@, use=screen+fkeys, use=screen, screen-w|VT 100/ANSI X3.64 virtual terminal with 132 cols, cols#132, use=screen, @@ -21668,9 +21673,12 @@ v3220|LANPAR Vision II model 3220/3221/3222, # * add xterm+app, xterm+noapp, from xterm #230 -TD # * add/use xterm+pce2 from xterm #230, in xterm+pcfkeys -TD # -# 2007-04-19 +# 2008-04-19 # * add screen.rxvt -TD # +# 2008-04-28 +# * add screen+fkeys (prompted by Debian # 478094) -TD +# # The following sets edit modes for GNU EMACS. # Local Variables: # fill-prefix:"\t" diff --git a/ncurses/base/lib_delwin.c b/ncurses/base/lib_delwin.c index fc68f9d6..ba5f180d 100644 --- a/ncurses/base/lib_delwin.c +++ b/ncurses/base/lib_delwin.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2001,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 * @@ -40,7 +40,7 @@ #include -MODULE_ID("$Id: lib_delwin.c,v 1.15 2007/12/22 23:34:26 tom Exp $") +MODULE_ID("$Id: lib_delwin.c,v 1.16 2008/05/03 14:13:51 tom Exp $") static bool cannot_delete(WINDOW *win) @@ -48,7 +48,7 @@ cannot_delete(WINDOW *win) WINDOWLIST *p; bool result = TRUE; - for (p = _nc_windows; p != 0; p = p->next) { + for (each_window(p)) { if (&(p->win) == win) { result = FALSE; } else if ((p->win._flags & _SUBWIN) != 0 diff --git a/ncurses/base/lib_freeall.c b/ncurses/base/lib_freeall.c index dbf0483f..4bb7ccc7 100644 --- a/ncurses/base/lib_freeall.c +++ b/ncurses/base/lib_freeall.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 * @@ -40,7 +40,7 @@ extern int malloc_errfd; /* FIXME */ #endif -MODULE_ID("$Id: lib_freeall.c,v 1.45 2007/12/22 23:29:37 tom Exp $") +MODULE_ID("$Id: lib_freeall.c,v 1.46 2008/05/03 14:13:51 tom Exp $") /* * Free all ncurses data. This is used for testing only (there's no practical @@ -67,10 +67,10 @@ _nc_freeall(void) bool deleted = FALSE; /* Delete only windows that're not a parent */ - for (p = _nc_windows; p != 0; p = p->next) { + for (each_window(p)) { bool found = FALSE; - for (q = _nc_windows; q != 0; q = q->next) { + for (each_window(q)) { if ((p != q) && (q->win._flags & _SUBWIN) && (&(p->win) == q->win._parent)) { diff --git a/ncurses/base/lib_getch.c b/ncurses/base/lib_getch.c index 11e8052a..d9f6b179 100644 --- a/ncurses/base/lib_getch.c +++ b/ncurses/base/lib_getch.c @@ -41,17 +41,19 @@ #include -MODULE_ID("$Id: lib_getch.c,v 1.82 2008/01/19 21:07:30 tom Exp $") +MODULE_ID("$Id: lib_getch.c,v 1.87 2008/05/03 22:42:10 tom Exp $") #include #if USE_REENTRANT +#define GetEscdelay(sp) (sp)->_ESCDELAY NCURSES_EXPORT(int) NCURSES_PUBLIC_VAR(ESCDELAY) (void) { - return SP ? SP->_ESCDELAY : 1000; + return SP ? GetEscdelay(SP) : 1000; } #else +#define GetEscdelay(sp) ESCDELAY NCURSES_EXPORT_VAR(int) ESCDELAY = 1000; /* max interval betw. chars in funkeys, in millisecs */ #endif @@ -84,20 +86,20 @@ set_escdelay(int value) * Check for mouse activity, returning nonzero if we find any. */ static int -check_mouse_activity(int delay EVENTLIST_2nd(_nc_eventlist * evl)) +check_mouse_activity(SCREEN *sp, int delay EVENTLIST_2nd(_nc_eventlist * evl)) { int rc; #if USE_SYSMOUSE - if ((SP->_mouse_type == M_SYSMOUSE) - && (SP->_sysmouse_head < SP->_sysmouse_tail)) { + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail)) { return 2; } #endif - rc = _nc_timed_wait(TWAIT_MASK, delay, (int *) 0 EVENTLIST_2nd(evl)); + 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) + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail) && (rc == 0) && (errno == EINTR)) { rc |= 2; @@ -107,9 +109,9 @@ check_mouse_activity(int delay EVENTLIST_2nd(_nc_eventlist * evl)) } static NCURSES_INLINE int -fifo_peek(void) +fifo_peek(SCREEN *sp) { - int ch = SP->_fifo[peek]; + int ch = sp->_fifo[peek]; TR(TRACE_IEVENT, ("peeking at %d", peek)); p_inc(); @@ -117,10 +119,10 @@ fifo_peek(void) } static NCURSES_INLINE int -fifo_pull(void) +fifo_pull(SCREEN *sp) { int ch; - ch = SP->_fifo[head]; + ch = sp->_fifo[head]; TR(TRACE_IEVENT, ("pulling %s from %d", _tracechar(ch), head)); if (peek == head) { @@ -131,7 +133,7 @@ fifo_pull(void) #ifdef TRACE if (USE_TRACEF(TRACE_IEVENT)) { - _nc_fifo_dump(); + _nc_fifo_dump(sp); _nc_unlock_global(tracef); } #endif @@ -139,7 +141,7 @@ fifo_pull(void) } static NCURSES_INLINE int -fifo_push(EVENTLIST_0th(_nc_eventlist * evl)) +fifo_push(SCREEN *sp EVENTLIST_2nd(_nc_eventlist * evl)) { int n; int ch = 0; @@ -157,47 +159,47 @@ fifo_push(EVENTLIST_0th(_nc_eventlist * evl)) #ifdef NCURSES_WGETCH_EVENTS if (evl #if USE_GPM_SUPPORT || USE_EMX_MOUSE || USE_SYSMOUSE - || (SP->_mouse_fd >= 0) + || (sp->_mouse_fd >= 0) #endif ) { - mask = check_mouse_activity(-1 EVENTLIST_2nd(evl)); + mask = check_mouse_activity(sp, -1 EVENTLIST_2nd(evl)); } else mask = 0; if (mask & 4) { T(("fifo_push: ungetch KEY_EVENT")); - ungetch(KEY_EVENT); + _nc_ungetch(sp, KEY_EVENT); return KEY_EVENT; } #elif USE_GPM_SUPPORT || USE_EMX_MOUSE || USE_SYSMOUSE - if (SP->_mouse_fd >= 0) { - mask = check_mouse_activity(-1 EVENTLIST_2nd(evl)); + if (sp->_mouse_fd >= 0) { + mask = check_mouse_activity(sp, -1 EVENTLIST_2nd(evl)); } #endif #if USE_GPM_SUPPORT || USE_EMX_MOUSE - if ((SP->_mouse_fd >= 0) && (mask & 2)) { - SP->_mouse_event(SP); + if ((sp->_mouse_fd >= 0) && (mask & 2)) { + sp->_mouse_event(sp); ch = KEY_MOUSE; n = 1; } else #endif #if USE_SYSMOUSE - if ((SP->_mouse_type == M_SYSMOUSE) - && (SP->_sysmouse_head < SP->_sysmouse_tail)) { - SP->_mouse_event(SP); + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail)) { + sp->_mouse_event(sp); ch = KEY_MOUSE; n = 1; - } else if ((SP->_mouse_type == M_SYSMOUSE) + } else if ((sp->_mouse_type == M_SYSMOUSE) && (mask <= 0) && errno == EINTR) { - SP->_mouse_event(SP); + sp->_mouse_event(sp); ch = KEY_MOUSE; n = 1; } else #endif { /* Can block... */ unsigned char c2 = 0; - n = read(SP->_ifd, &c2, 1); + n = read(sp->_ifd, &c2, 1); ch = c2; } @@ -216,20 +218,20 @@ fifo_push(EVENTLIST_0th(_nc_eventlist * evl)) #endif if ((n == -1) || (n == 0)) { - TR(TRACE_IEVENT, ("read(%d,&ch,1)=%d, errno=%d", SP->_ifd, n, errno)); + TR(TRACE_IEVENT, ("read(%d,&ch,1)=%d, errno=%d", sp->_ifd, n, errno)); ch = ERR; } TR(TRACE_IEVENT, ("read %d characters", n)); - SP->_fifo[tail] = ch; - SP->_fifohold = 0; + sp->_fifo[tail] = ch; + sp->_fifohold = 0; if (head == -1) head = peek = tail; t_inc(); TR(TRACE_IEVENT, ("pushed %s at %d", _tracechar(ch), tail)); #ifdef TRACE if (USE_TRACEF(TRACE_IEVENT)) { - _nc_fifo_dump(); + _nc_fifo_dump(sp); _nc_unlock_global(tracef); } #endif @@ -237,14 +239,14 @@ fifo_push(EVENTLIST_0th(_nc_eventlist * evl)) } static NCURSES_INLINE void -fifo_clear(void) +fifo_clear(SCREEN *sp) { - memset(SP->_fifo, 0, sizeof(SP->_fifo)); + memset(sp->_fifo, 0, sizeof(sp->_fifo)); head = -1; tail = peek = 0; } -static int kgetch(EVENTLIST_0th(_nc_eventlist * evl)); +static int kgetch(SCREEN *EVENTLIST_2nd(_nc_eventlist * evl)); #define wgetch_should_refresh(win) (\ (is_wintouched(win) || (win->_flags & _HASMOVED)) \ @@ -256,6 +258,7 @@ _nc_wgetch(WINDOW *win, int use_meta EVENTLIST_2nd(_nc_eventlist * evl)) { + SCREEN *sp = SP; int ch; #ifdef NCURSES_WGETCH_EVENTS long event_delay = -1; @@ -264,7 +267,7 @@ _nc_wgetch(WINDOW *win, T((T_CALLED("_nc_wgetch(%p)"), win)); *result = 0; - if (win == 0 || SP == 0) { + if (win == 0 || sp == 0) { returnCode(ERR); } @@ -272,7 +275,7 @@ _nc_wgetch(WINDOW *win, if (wgetch_should_refresh(win)) wrefresh(win); - *result = fifo_pull(); + *result = fifo_pull(sp); returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK); } #ifdef NCURSES_WGETCH_EVENTS @@ -287,26 +290,26 @@ _nc_wgetch(WINDOW *win, * the first character to return it. */ if (head == -1 && - !SP->_notty && - !SP->_raw && - !SP->_cbreak && - !SP->_called_wgetch) { - char buf[MAXCOLUMNS], *sp; + !sp->_notty && + !sp->_raw && + !sp->_cbreak && + !sp->_called_wgetch) { + char buf[MAXCOLUMNS], *bufp; int rc; TR(TRACE_IEVENT, ("filling queue in cooked mode")); - SP->_called_wgetch = TRUE; + sp->_called_wgetch = TRUE; rc = wgetnstr(win, buf, MAXCOLUMNS); - SP->_called_wgetch = FALSE; + sp->_called_wgetch = FALSE; /* ungetch in reverse order */ #ifdef NCURSES_WGETCH_EVENTS if (rc != KEY_EVENT) #endif - ungetch('\n'); - for (sp = buf + strlen(buf); sp > buf; sp--) - ungetch(sp[-1]); + _nc_ungetch(sp, '\n'); + for (bufp = buf + strlen(buf); bufp > buf; bufp--) + _nc_ungetch(sp, bufp[-1]); #ifdef NCURSES_WGETCH_EVENTS /* Return it first */ @@ -314,24 +317,24 @@ _nc_wgetch(WINDOW *win, *result = rc; } else #endif - *result = fifo_pull(); + *result = fifo_pull(sp); returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK); } - if (win->_use_keypad != SP->_keypad_on) - _nc_keypad(win->_use_keypad); + if (win->_use_keypad != sp->_keypad_on) + _nc_keypad(sp, win->_use_keypad); if (wgetch_should_refresh(win)) wrefresh(win); - if (!win->_notimeout && (win->_delay >= 0 || SP->_cbreak > 1)) { + if (!win->_notimeout && (win->_delay >= 0 || sp->_cbreak > 1)) { if (head == -1) { /* fifo is empty */ int delay; int rc; TR(TRACE_IEVENT, ("timed delay in wgetch()")); - if (SP->_cbreak > 1) - delay = (SP->_cbreak - 1) * 100; + if (sp->_cbreak > 1) + delay = (sp->_cbreak - 1) * 100; else delay = win->_delay; @@ -342,7 +345,7 @@ _nc_wgetch(WINDOW *win, TR(TRACE_IEVENT, ("delay is %d milliseconds", delay)); - rc = check_mouse_activity(delay EVENTLIST_2nd(evl)); + rc = check_mouse_activity(sp, delay EVENTLIST_2nd(evl)); #ifdef NCURSES_WGETCH_EVENTS if (rc & 4) { @@ -372,23 +375,23 @@ _nc_wgetch(WINDOW *win, int rc; do { - ch = kgetch(EVENTLIST_1st(evl)); + ch = kgetch(sp EVENTLIST_2nd(evl)); if (ch == KEY_MOUSE) { ++runcount; - if (SP->_mouse_inline(SP)) + if (sp->_mouse_inline(sp)) break; } - if (SP->_maxclick < 0) + if (sp->_maxclick < 0) break; } while (ch == KEY_MOUSE - && (((rc = check_mouse_activity(SP->_maxclick + && (((rc = check_mouse_activity(sp, sp->_maxclick EVENTLIST_2nd(evl))) != 0 && !(rc & 4)) - || !SP->_mouse_parse(runcount))); + || !sp->_mouse_parse(runcount))); #ifdef NCURSES_WGETCH_EVENTS if ((rc & 4) && !ch == KEY_EVENT) { - ungetch(ch); + _nc_ungetch(sp, ch); ch = KEY_EVENT; } #endif @@ -396,28 +399,28 @@ _nc_wgetch(WINDOW *win, #ifdef NCURSES_WGETCH_EVENTS /* mouse event sequence ended by an event, report event */ if (ch == KEY_EVENT) { - ungetch(KEY_MOUSE); /* FIXME This interrupts a gesture... */ + _nc_ungetch(sp, KEY_MOUSE); /* FIXME This interrupts a gesture... */ } else #endif { /* mouse event sequence ended by keystroke, store keystroke */ - ungetch(ch); + _nc_ungetch(sp, ch); ch = KEY_MOUSE; } } } else { if (head == -1) - fifo_push(EVENTLIST_1st(evl)); - ch = fifo_pull(); + fifo_push(sp EVENTLIST_2nd(evl)); + ch = fifo_pull(sp); } if (ch == ERR) { #if USE_SIZECHANGE - if (_nc_handle_sigwinch(FALSE)) { - _nc_update_screensize(); + if (_nc_handle_sigwinch(sp)) { + _nc_update_screensize(sp); /* resizeterm can push KEY_RESIZE */ if (cooked_key_in_fifo()) { - *result = fifo_pull(); + *result = fifo_pull(sp); returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK); } } @@ -443,7 +446,7 @@ _nc_wgetch(WINDOW *win, * However, we provide the same visual result as Solaris, moving the * cursor to the left. */ - if (SP->_echo && !(win->_flags & _ISPAD)) { + if (sp->_echo && !(win->_flags & _ISPAD)) { chtype backup = (ch == KEY_BACKSPACE) ? '\b' : ch; if (backup < KEY_MIN) wechochar(win, backup); @@ -452,7 +455,7 @@ _nc_wgetch(WINDOW *win, /* * Simulate ICRNL mode */ - if ((ch == '\r') && SP->_nl) + if ((ch == '\r') && sp->_nl) ch = '\n'; /* Strip 8th-bit if so desired. We do this only for characters that @@ -474,13 +477,14 @@ _nc_wgetch(WINDOW *win, NCURSES_EXPORT(int) wgetch_events(WINDOW *win, _nc_eventlist * evl) { + SCREEN *sp = SP; int code; unsigned long value; T((T_CALLED("wgetch_events(%p,%p)"), win, evl)); code = _nc_wgetch(win, &value, - SP->_use_meta + sp->_use_meta EVENTLIST_2nd(evl)); if (code != ERR) code = value; @@ -491,13 +495,14 @@ wgetch_events(WINDOW *win, _nc_eventlist * evl) NCURSES_EXPORT(int) wgetch(WINDOW *win) { + SCREEN *sp = SP; int code; unsigned long value; T((T_CALLED("wgetch(%p)"), win)); code = _nc_wgetch(win, &value, - (SP ? SP->_use_meta : 0) + (sp ? sp->_use_meta : 0) EVENTLIST_2nd((_nc_eventlist *) 0)); if (code != ERR) code = value; @@ -520,21 +525,21 @@ wgetch(WINDOW *win) */ static int -kgetch(EVENTLIST_0th(_nc_eventlist * evl)) +kgetch(SCREEN *sp EVENTLIST_2nd(_nc_eventlist * evl)) { TRIES *ptr; int ch = 0; - int timeleft = ESCDELAY; + int timeleft = GetEscdelay(sp); TR(TRACE_IEVENT, ("kgetch() called")); - ptr = SP->_keytry; + ptr = sp->_keytry; for (;;) { - if (cooked_key_in_fifo() && SP->_fifo[head] >= KEY_MIN) { + if (cooked_key_in_fifo() && sp->_fifo[head] >= KEY_MIN) { break; } else if (!raw_key_in_fifo()) { - ch = fifo_push(EVENTLIST_1st(evl)); + ch = fifo_push(sp EVENTLIST_2nd(evl)); if (ch == ERR) { peek = head; /* the keys stay uninterpreted */ return ERR; @@ -542,12 +547,12 @@ kgetch(EVENTLIST_0th(_nc_eventlist * evl)) #ifdef NCURSES_WGETCH_EVENTS else if (ch == KEY_EVENT) { peek = head; /* the keys stay uninterpreted */ - return fifo_pull(); /* Remove KEY_EVENT from the queue */ + return fifo_pull(sp); /* Remove KEY_EVENT from the queue */ } #endif } - ch = fifo_peek(); + ch = fifo_peek(sp); if (ch >= KEY_MIN) { /* If not first in queue, somebody put this key there on purpose in * emergency. Consider it higher priority than the unfinished @@ -573,7 +578,7 @@ kgetch(EVENTLIST_0th(_nc_eventlist * evl)) if (ptr->value != 0) { /* sequence terminated */ TR(TRACE_IEVENT, ("end of sequence")); if (peek == tail) - fifo_clear(); + fifo_clear(sp); else head = peek; return (ptr->value); @@ -585,7 +590,7 @@ kgetch(EVENTLIST_0th(_nc_eventlist * evl)) int rc; TR(TRACE_IEVENT, ("waiting for rest of sequence")); - rc = check_mouse_activity(timeleft EVENTLIST_2nd(evl)); + rc = check_mouse_activity(sp, timeleft EVENTLIST_2nd(evl)); #ifdef NCURSES_WGETCH_EVENTS if (rc & 4) { TR(TRACE_IEVENT, ("interrupted by a user event")); @@ -600,7 +605,7 @@ kgetch(EVENTLIST_0th(_nc_eventlist * evl)) } } } - ch = fifo_pull(); + ch = fifo_pull(sp); peek = head; return ch; } diff --git a/ncurses/base/lib_newwin.c b/ncurses/base/lib_newwin.c index 84763c93..7f7aa3e0 100644 --- a/ncurses/base/lib_newwin.c +++ b/ncurses/base/lib_newwin.c @@ -42,9 +42,9 @@ #include #include -MODULE_ID("$Id: lib_newwin.c,v 1.46 2008/04/05 19:16:42 tom Exp $") +MODULE_ID("$Id: lib_newwin.c,v 1.50 2008/05/03 16:36:39 tom Exp $") -#define window_is(name) (sp->_##name == win) +#define window_is(name) ((sp)->_##name == win) #if USE_REENTRANT #define remove_window(name) \ @@ -56,27 +56,23 @@ MODULE_ID("$Id: lib_newwin.c,v 1.46 2008/04/05 19:16:42 tom Exp $") name = 0 #endif -static WINDOW * +static void remove_window_from_screen(WINDOW *win) { - SCREEN **scan = &_nc_screen_chain; + SCREEN *sp; - while (*scan) { - SCREEN *sp = *scan; + for (each_screen(sp)) { if (window_is(curscr)) { remove_window(curscr); + break; } else if (window_is(stdscr)) { remove_window(stdscr); + break; } else if (window_is(newscr)) { remove_window(newscr); - } else { - scan = &(*scan)->_next_screen; - continue; + break; } - break; } - - return 0; } NCURSES_EXPORT(int) @@ -90,7 +86,8 @@ _nc_freewin(WINDOW *win) if (win != 0) { if (_nc_try_global(windowlist) == 0) { - for (p = _nc_windows, q = 0; p != 0; q = p, p = p->next) { + q = 0; + for (each_window(p)) { if (&(p->win) == win) { remove_window_from_screen(win); if (q == 0) @@ -109,6 +106,7 @@ _nc_freewin(WINDOW *win) T(("...deleted win=%p", win)); break; } + q = p; } _nc_unlock_global(windowlist); } diff --git a/ncurses/base/lib_restart.c b/ncurses/base/lib_restart.c index 858ef65a..9742ff62 100644 --- a/ncurses/base/lib_restart.c +++ b/ncurses/base/lib_restart.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 * @@ -48,7 +48,7 @@ #include /* lines, columns, cur_term */ -MODULE_ID("$Id: lib_restart.c,v 1.8 2007/10/13 19:59:47 tom Exp $") +MODULE_ID("$Id: lib_restart.c,v 1.9 2008/05/03 22:43:52 tom Exp $") NCURSES_EXPORT(int) restartterm(NCURSES_CONST char *termp, int filenum, int *errret) @@ -88,7 +88,7 @@ restartterm(NCURSES_CONST char *termp, int filenum, int *errret) reset_prog_mode(); #if USE_SIZECHANGE - _nc_update_screensize(); + _nc_update_screensize(SP); #endif result = OK; diff --git a/ncurses/base/lib_set_term.c b/ncurses/base/lib_set_term.c index 3f847060..eee1cfc7 100644 --- a/ncurses/base/lib_set_term.c +++ b/ncurses/base/lib_set_term.c @@ -44,7 +44,7 @@ #include /* cur_term */ #include -MODULE_ID("$Id: lib_set_term.c,v 1.106 2008/03/29 22:47:24 tom Exp $") +MODULE_ID("$Id: lib_set_term.c,v 1.108 2008/05/03 22:42:43 tom Exp $") NCURSES_EXPORT(SCREEN *) set_term(SCREEN *screenp) @@ -94,26 +94,39 @@ _nc_free_keytry(TRIES * kt) } } +static bool +delink_screen(SCREEN *sp) +{ + SCREEN *last = 0; + SCREEN *temp; + bool result = FALSE; + + for (each_screen(temp)) { + if (temp == sp) { + if (last) + last = sp->_next_screen; + else + _nc_screen_chain = sp->_next_screen; + result = TRUE; + break; + } + last = temp; + } + return result; +} + /* * Free the storage associated with the given SCREEN sp. */ NCURSES_EXPORT(void) delscreen(SCREEN *sp) { - SCREEN **scan = &_nc_screen_chain; int i; T((T_CALLED("delscreen(%p)"), sp)); - if (sp != 0) { - _nc_lock_global(set_SP); - while (*scan) { - if (*scan == sp) { - *scan = sp->_next_screen; - break; - } - scan = &(*scan)->_next_screen; - } + _nc_lock_global(set_SP); + if (delink_screen(sp)) { (void) _nc_freewin(sp->_curscr); (void) _nc_freewin(sp->_newscr); @@ -180,8 +193,8 @@ delscreen(SCREEN *sp) #endif _nc_set_screen(0); } - _nc_unlock_global(set_SP); } + _nc_unlock_global(set_SP); returnVoid; } @@ -267,7 +280,7 @@ _nc_setupscreen(int slines GCC_UNUSED, /* * We should always check the screensize, just in case. */ - _nc_get_screensize(&slines, &scolumns); + _nc_get_screensize(SP, &slines, &scolumns); SET_LINES(slines); SET_COLS(scolumns); T((T_CREATE("screen %s %dx%d"), termname(), LINES, COLS)); diff --git a/ncurses/base/lib_ungetch.c b/ncurses/base/lib_ungetch.c index 9570a33e..2eda9901 100644 --- a/ncurses/base/lib_ungetch.c +++ b/ncurses/base/lib_ungetch.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2002,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 * @@ -29,6 +29,7 @@ /**************************************************************************** * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * + * and: Thomas E. Dickey 1996-on * ****************************************************************************/ /* @@ -40,42 +41,50 @@ #include -MODULE_ID("$Id: lib_ungetch.c,v 1.9 2007/09/29 21:49:56 tom Exp $") +MODULE_ID("$Id: lib_ungetch.c,v 1.10 2008/05/03 20:20:58 tom Exp $") #include #ifdef TRACE NCURSES_EXPORT(void) -_nc_fifo_dump(void) +_nc_fifo_dump(SCREEN *sp) { int i; T(("head = %d, tail = %d, peek = %d", head, tail, peek)); for (i = 0; i < 10; i++) - T(("char %d = %s", i, _tracechar(SP->_fifo[i]))); + T(("char %d = %s", i, _tracechar(sp->_fifo[i]))); } #endif /* TRACE */ NCURSES_EXPORT(int) -ungetch(int ch) +_nc_ungetch(SCREEN *sp, int ch) { - T((T_CALLED("ungetch(%s)"), _tracechar(ch))); + int rc = ERR; - if (tail == -1) - returnCode(ERR); - if (head == -1) { - head = 0; - t_inc() + if (tail != -1) { + if (head == -1) { + head = 0; + t_inc(); peek = tail; /* no raw keys */ - } else - h_dec(); + } else + h_dec(); - SP->_fifo[head] = ch; - T(("ungetch %s ok", _tracechar(ch))); + sp->_fifo[head] = ch; + T(("ungetch %s ok", _tracechar(ch))); #ifdef TRACE - if (USE_TRACEF(TRACE_IEVENT)) { - _nc_fifo_dump(); - _nc_unlock_global(tracef); - } + if (USE_TRACEF(TRACE_IEVENT)) { + _nc_fifo_dump(sp); + _nc_unlock_global(tracef); + } #endif - returnCode(OK); + rc = OK; + } + return rc; +} + +NCURSES_EXPORT(int) +ungetch(int ch) +{ + T((T_CALLED("ungetch(%s)"), _tracechar(ch))); + returnCode(_nc_ungetch(SP, ch)); } diff --git a/ncurses/base/resizeterm.c b/ncurses/base/resizeterm.c index eb2dd737..cf2c998e 100644 --- a/ncurses/base/resizeterm.c +++ b/ncurses/base/resizeterm.c @@ -41,7 +41,7 @@ #include #include -MODULE_ID("$Id: resizeterm.c,v 1.30 2008/01/12 22:26:56 tom Exp $") +MODULE_ID("$Id: resizeterm.c,v 1.32 2008/05/03 14:28:55 tom Exp $") #define stolen_lines (screen_lines - SP->_lines_avail) @@ -69,7 +69,7 @@ show_window_sizes(const char *name) _nc_lock_global(windowlist); _tracef("%s resizing: %2d x %2d (%2d x %2d)", name, LINES, COLS, screen_lines, screen_columns); - for (wp = _nc_windows; wp != 0; wp = wp->next) { + for (each_window(wp)) { _tracef(" window %p is %2ld x %2ld at %2ld,%2ld", &(wp->win), (long) wp->win._maxy + 1, @@ -104,7 +104,7 @@ ripped_window(WINDOW *win) ripoff_t *rop; if (win != 0) { - for (rop = ripoff_stack; (rop - ripoff_stack) < N_RIPS; rop++) { + for (each_ripoff(rop)) { if (rop->win == win && rop->line != 0) { result = rop; break; @@ -125,7 +125,7 @@ ripped_bottom(WINDOW *win) ripoff_t *rop; if (win != 0) { - for (rop = ripoff_stack; (rop - ripoff_stack) < N_RIPS; rop++) { + for (each_ripoff(rop)) { if (rop->line < 0) { result -= rop->line; if (rop->win == win) { @@ -148,7 +148,7 @@ child_depth(WINDOW *cmp) if (cmp != 0) { WINDOWLIST *wp; - for (wp = _nc_windows; wp != 0; wp = wp->next) { + for (each_window(wp)) { WINDOW *tst = &(wp->win); if (tst->_parent == cmp) { depth = 1 + child_depth(tst); @@ -251,7 +251,7 @@ decrease_size(int ToLines, int ToCols, int stolen EXTRA_DCLS) found = FALSE; TR(TRACE_UPDATE, ("decreasing size of windows to %dx%d, depth=%d", ToLines, ToCols, depth)); - for (wp = _nc_windows; wp != 0; wp = wp->next) { + for (each_window(wp)) { WINDOW *win = &(wp->win); if (!(win->_flags & _ISPAD)) { @@ -285,7 +285,7 @@ increase_size(int ToLines, int ToCols, int stolen EXTRA_DCLS) found = FALSE; TR(TRACE_UPDATE, ("increasing size of windows to %dx%d, depth=%d", ToLines, ToCols, depth)); - for (wp = _nc_windows; wp != 0; wp = wp->next) { + for (each_window(wp)) { WINDOW *win = &(wp->win); if (!(win->_flags & _ISPAD)) { @@ -428,7 +428,7 @@ resizeterm(int ToLines, int ToCols) * decide which to repaint, since without panels, ncurses does * not know which are really on top. */ - for (rop = ripoff_stack; (rop - ripoff_stack) < N_RIPS; rop++) { + for (each_ripoff(rop)) { if (rop->win != stdscr && rop->win != 0 && rop->line < 0) { diff --git a/ncurses/base/use_window.c b/ncurses/base/use_window.c index 4d2c1366..4d0fdf67 100644 --- a/ncurses/base/use_window.c +++ b/ncurses/base/use_window.c @@ -32,7 +32,7 @@ #include -MODULE_ID("$Id: use_window.c,v 1.6 2008/04/12 17:16:05 tom Exp $") +MODULE_ID("$Id: use_window.c,v 1.7 2008/05/03 14:09:38 tom Exp $") #ifdef USE_PTHREADS NCURSES_EXPORT(void) @@ -41,7 +41,7 @@ _nc_lock_window(const WINDOW *win) WINDOWLIST *p; _nc_lock_global(windowlist); - for (p = _nc_windows; p != 0; p = p->next) { + for (each_window(p)) { if (&(p->win) == win) { _nc_mutex_lock(&(p->mutex_use_window)); break; @@ -54,7 +54,7 @@ _nc_unlock_window(const WINDOW *win) { WINDOWLIST *p; - for (p = _nc_windows; p != 0; p = p->next) { + for (each_window(p)) { if (&(p->win) == win) { _nc_mutex_unlock(&(p->mutex_use_window)); break; diff --git a/ncurses/base/wresize.c b/ncurses/base/wresize.c index f756f0f2..ac808c4d 100644 --- a/ncurses/base/wresize.c +++ b/ncurses/base/wresize.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 * @@ -32,7 +32,7 @@ #include -MODULE_ID("$Id: wresize.c,v 1.27 2007/12/22 23:20:53 tom Exp $") +MODULE_ID("$Id: wresize.c,v 1.28 2008/05/03 14:13:51 tom Exp $") static int cleanup_lines(struct ldat *data, int length) @@ -56,7 +56,7 @@ repair_subwindows(WINDOW *cmp) _nc_lock_global(windowlist); - for (wp = _nc_windows; wp != 0; wp = wp->next) { + for (each_window(wp)) { WINDOW *tst = &(wp->win); if (tst->_parent == cmp) { diff --git a/ncurses/curses.priv.h b/ncurses/curses.priv.h index b4345602..422c74cb 100644 --- a/ncurses/curses.priv.h +++ b/ncurses/curses.priv.h @@ -34,7 +34,7 @@ /* - * $Id: curses.priv.h,v 1.363 2008/04/12 17:16:26 tom Exp $ + * $Id: curses.priv.h,v 1.373 2008/05/03 23:30:35 tom Exp $ * * curses.priv.h * @@ -348,9 +348,6 @@ extern NCURSES_EXPORT(void) _nc_unlock_window(const WINDOW *); #endif /* USE_PTHREADS */ -#define _nc_lock_screen(name) /* nothing */ -#define _nc_unlock_screen(name) /* nothing */ - #if HAVE_GETTIMEOFDAY # define PRECISE_GETTIME 1 # define TimeType struct timeval @@ -1167,6 +1164,13 @@ extern NCURSES_EXPORT_VAR(SIG_ATOMIC_T) _nc_have_sigwinch; # endif #endif +/* + * Standardize/simplify common loops + */ +#define each_screen(p) p = _nc_screen_chain; p != 0; p = (p)->_next_screen +#define each_window(p) p = _nc_windows; p != 0; p = (p)->next +#define each_ripoff(p) p = ripoff_stack; (p - ripoff_stack) < N_RIPS; ++p + /* * Prefixes for call/return points of library function traces. We use these to * instrument the public functions so that the traces can be easily transformed @@ -1235,7 +1239,7 @@ extern NCURSES_EXPORT(const char *) _nc_retrace_cptr (const char *); extern NCURSES_EXPORT(int) _nc_retrace_int (int); extern NCURSES_EXPORT(unsigned) _nc_retrace_unsigned (unsigned); extern NCURSES_EXPORT(void *) _nc_retrace_void_ptr (void *); -extern NCURSES_EXPORT(void) _nc_fifo_dump (void); +extern NCURSES_EXPORT(void) _nc_fifo_dump (SCREEN *); #if USE_REENTRANT NCURSES_WRAPPED_VAR(long, _nc_outchars); @@ -1476,15 +1480,18 @@ extern NCURSES_EXPORT(char *) _nc_get_locale(void); extern NCURSES_EXPORT(int) _nc_unicode_locale(void); extern NCURSES_EXPORT(int) _nc_locale_breaks_acs(void); extern NCURSES_EXPORT(int) _nc_setupterm(NCURSES_CONST char *, int, int *, bool); -extern NCURSES_EXPORT(void) _nc_get_screensize(int *, int *); +extern NCURSES_EXPORT(void) _nc_get_screensize(SCREEN *, int *, int *); /* lib_tstp.c */ #if USE_SIGWINCH -extern NCURSES_EXPORT(int) _nc_handle_sigwinch(int); +extern NCURSES_EXPORT(int) _nc_handle_sigwinch(SCREEN *); #else #define _nc_handle_sigwinch(a) /* nothing */ #endif +/* lib_ungetch.c */ +extern NCURSES_EXPORT(int) _nc_ungetch (SCREEN *, int); + /* lib_wacs.c */ #if USE_WIDEC_SUPPORT extern NCURSES_EXPORT(void) _nc_init_wacs(void); @@ -1527,18 +1534,18 @@ extern NCURSES_EXPORT(int) _nc_access (const char *, int); extern NCURSES_EXPORT(int) _nc_baudrate (int); extern NCURSES_EXPORT(int) _nc_freewin (WINDOW *); extern NCURSES_EXPORT(int) _nc_getenv_num (const char *); -extern NCURSES_EXPORT(int) _nc_keypad (bool); +extern NCURSES_EXPORT(int) _nc_keypad (SCREEN *, bool); extern NCURSES_EXPORT(int) _nc_ospeed (int); extern NCURSES_EXPORT(int) _nc_outch (int); extern NCURSES_EXPORT(int) _nc_read_termcap_entry (const char *const, TERMTYPE *const); extern NCURSES_EXPORT(int) _nc_setupscreen (int, int, FILE *, bool, int); -extern NCURSES_EXPORT(int) _nc_timed_wait(int, int, int * EVENTLIST_2nd(_nc_eventlist *)); +extern NCURSES_EXPORT(int) _nc_timed_wait(SCREEN *, int, int, int * EVENTLIST_2nd(_nc_eventlist *)); extern NCURSES_EXPORT(void) _nc_do_color (short, short, bool, int (*)(int)); extern NCURSES_EXPORT(void) _nc_flush (void); extern NCURSES_EXPORT(void) _nc_free_entry(ENTRY *, TERMTYPE *); extern NCURSES_EXPORT(void) _nc_freeall (void); extern NCURSES_EXPORT(void) _nc_hash_map (void); -extern NCURSES_EXPORT(void) _nc_init_keytry (void); +extern NCURSES_EXPORT(void) _nc_init_keytry (SCREEN *); extern NCURSES_EXPORT(void) _nc_keep_tic_dir (const char *); extern NCURSES_EXPORT(void) _nc_make_oldhash (int i); extern NCURSES_EXPORT(void) _nc_scroll_oldhash (int n, int top, int bot); @@ -1570,7 +1577,7 @@ extern NCURSES_EXPORT(size_t) _nc_wcrtomb (char *, wchar_t, mbstate_t *); #endif #if USE_SIZECHANGE -extern NCURSES_EXPORT(void) _nc_update_screensize (void); +extern NCURSES_EXPORT(void) _nc_update_screensize (SCREEN *); #endif #if HAVE_RESIZETERM diff --git a/ncurses/fifo_defs.h b/ncurses/fifo_defs.h index 67799577..9655b417 100644 --- a/ncurses/fifo_defs.h +++ b/ncurses/fifo_defs.h @@ -34,21 +34,21 @@ /* * Common macros for lib_getch.c, lib_ungetch.c * - * $Id: fifo_defs.h,v 1.4 2002/03/16 20:47:50 tom Exp $ + * $Id: fifo_defs.h,v 1.5 2008/05/03 20:08:16 tom Exp $ */ #ifndef FIFO_DEFS_H #define FIFO_DEFS_H 1 -#define head SP->_fifohead -#define tail SP->_fifotail +#define head sp->_fifohead +#define tail sp->_fifotail /* peek points to next uninterpreted character */ -#define peek SP->_fifopeek +#define peek sp->_fifopeek #define h_inc() { head == FIFO_SIZE-1 ? head = 0 : head++; if (head == tail) head = -1, tail = 0;} #define h_dec() { head == 0 ? head = FIFO_SIZE-1 : head--; if (head == tail) tail = -1;} #define t_inc() { tail == FIFO_SIZE-1 ? tail = 0 : tail++; if (tail == head) tail = -1;} -#define t_dec() { tail == 0 ? tail = FIFO_SIZE-1 : tail--; if (head == tail) fifo_clear();} +#define t_dec() { tail == 0 ? tail = FIFO_SIZE-1 : tail--; if (head == tail) fifo_clear(sp);} #define p_inc() { peek == FIFO_SIZE-1 ? peek = 0 : peek++;} #define cooked_key_in_fifo() ((head != -1) && (peek != head)) diff --git a/ncurses/tinfo/init_keytry.c b/ncurses/tinfo/init_keytry.c index d2032106..d30d3ed1 100644 --- a/ncurses/tinfo/init_keytry.c +++ b/ncurses/tinfo/init_keytry.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1999-2005,2006 Free Software Foundation, Inc. * + * Copyright (c) 1999-2006,2008 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 * @@ -36,7 +36,7 @@ #include -MODULE_ID("$Id: init_keytry.c,v 1.10 2007/04/29 22:57:50 tom Exp $") +MODULE_ID("$Id: init_keytry.c,v 1.11 2008/05/03 23:09:15 tom Exp $") /* ** _nc_init_keytry() @@ -64,19 +64,19 @@ _nc_tinfo_fkeysf(void) #endif NCURSES_EXPORT(void) -_nc_init_keytry(void) +_nc_init_keytry(SCREEN *sp) { size_t n; - /* The SP->_keytry value is initialized in newterm(), where the SP + /* The sp->_keytry value is initialized in newterm(), where the sp * structure is created, because we can not tell where keypad() or * mouse_activate() (which will call keyok()) are first called. */ - if (SP != 0) { + if (sp != 0) { for (n = 0; _nc_tinfo_fkeys[n].code; n++) { if (_nc_tinfo_fkeys[n].offset < STRCOUNT) { - (void) _nc_add_to_try(&(SP->_keytry), + (void) _nc_add_to_try(&(sp->_keytry), CUR Strings[_nc_tinfo_fkeys[n].offset], _nc_tinfo_fkeys[n].code); } @@ -88,7 +88,7 @@ _nc_init_keytry(void) * names. */ { - TERMTYPE *tp = &(SP->_term->type); + TERMTYPE *tp = &(sp->_term->type); for (n = STRCOUNT; n < NUM_STRINGS(tp); ++n) { const char *name = ExtStrname(tp, n, strnames); char *value = tp->Strings[n]; @@ -96,7 +96,7 @@ _nc_init_keytry(void) && *name == 'k' && value != 0 && key_defined(value) == 0) { - (void) _nc_add_to_try(&(SP->_keytry), + (void) _nc_add_to_try(&(sp->_keytry), value, n - STRCOUNT + KEY_MAX); } @@ -104,7 +104,7 @@ _nc_init_keytry(void) } #endif #ifdef TRACE - _nc_trace_tries(SP->_keytry); + _nc_trace_tries(sp->_keytry); #endif } } diff --git a/ncurses/tinfo/lib_napms.c b/ncurses/tinfo/lib_napms.c index 926afa83..417b3b4b 100644 --- a/ncurses/tinfo/lib_napms.c +++ b/ncurses/tinfo/lib_napms.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc. * + * Copyright (c) 1998-2005,2008 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 * @@ -49,7 +49,7 @@ #endif #endif -MODULE_ID("$Id: lib_napms.c,v 1.15 2005/04/03 13:58:14 tom Exp $") +MODULE_ID("$Id: lib_napms.c,v 1.17 2008/05/03 21:34:13 tom Exp $") NCURSES_EXPORT(int) napms(int ms) @@ -67,7 +67,7 @@ napms(int ms) } } #else - _nc_timed_wait(0, ms, (int *) 0 EVENTLIST_2nd(0)); + _nc_timed_wait(0, 0, ms, (int *) 0 EVENTLIST_2nd(0)); #endif returnCode(OK); diff --git a/ncurses/tinfo/lib_options.c b/ncurses/tinfo/lib_options.c index 5cdd1d46..98aae24b 100644 --- a/ncurses/tinfo/lib_options.c +++ b/ncurses/tinfo/lib_options.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. * + * Copyright (c) 1998-2006,2008 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 * @@ -43,7 +43,7 @@ #include -MODULE_ID("$Id: lib_options.c,v 1.50 2006/12/30 16:03:27 tom Exp $") +MODULE_ID("$Id: lib_options.c,v 1.52 2008/05/03 23:09:20 tom Exp $") NCURSES_EXPORT(int) idlok(WINDOW *win, bool flag) @@ -126,7 +126,7 @@ keypad(WINDOW *win, bool flag) if (win) { win->_use_keypad = flag; - returnCode(_nc_keypad(flag)); + returnCode(_nc_keypad(SP, flag)); } else returnCode(ERR); } @@ -220,7 +220,7 @@ typeahead(int fd) #if NCURSES_EXT_FUNCS static int -has_key_internal(int keycode, TRIES *tp) +has_key_internal(int keycode, TRIES * tp) { if (tp == 0) return (FALSE); @@ -247,7 +247,7 @@ has_key(int keycode) * the terminal state _before_ switching modes. */ NCURSES_EXPORT(int) -_nc_keypad(bool flag) +_nc_keypad(SCREEN *sp, bool flag) { if (flag && keypad_xmit) { TPUTS_TRACE("keypad_xmit"); @@ -259,12 +259,12 @@ _nc_keypad(bool flag) _nc_flush(); } - if (SP != 0) { - if (flag && !SP->_tried) { - _nc_init_keytry(); - SP->_tried = TRUE; + if (sp != 0) { + if (flag && !sp->_tried) { + _nc_init_keytry(sp); + sp->_tried = TRUE; } - SP->_keypad_on = flag; + sp->_keypad_on = flag; } return (OK); } diff --git a/ncurses/tinfo/lib_setup.c b/ncurses/tinfo/lib_setup.c index a376fc60..08cb783c 100644 --- a/ncurses/tinfo/lib_setup.c +++ b/ncurses/tinfo/lib_setup.c @@ -53,7 +53,7 @@ #include /* lines, columns, cur_term */ -MODULE_ID("$Id: lib_setup.c,v 1.102 2008/01/19 21:07:45 tom Exp $") +MODULE_ID("$Id: lib_setup.c,v 1.105 2008/05/03 22:41:42 tom Exp $") /**************************************************************************** * @@ -154,23 +154,19 @@ set_tabsize(int value) * If we have a pending SIGWINCH, set the flag in each screen. */ NCURSES_EXPORT(int) -_nc_handle_sigwinch(int update) +_nc_handle_sigwinch(SCREEN *sp) { SCREEN *scan; - (void) update; /* no longer used */ - if (_nc_globals.have_sigwinch) { _nc_globals.have_sigwinch = 0; - scan = _nc_screen_chain; - while (scan) { + for (each_screen(scan)) { scan->_sig_winch = TRUE; - scan = scan->_next_screen; } } - return (SP ? SP->_sig_winch : 0); + return (sp ? sp->_sig_winch : 0); } #endif @@ -184,7 +180,7 @@ use_env(bool f) } NCURSES_EXPORT(void) -_nc_get_screensize(int *linep, int *colp) +_nc_get_screensize(SCREEN *sp, int *linep, int *colp) /* Obtain lines/columns values from the environment and/or terminfo entry */ { int my_tabsize; @@ -238,7 +234,7 @@ _nc_get_screensize(int *linep, int *colp) * environment variable. */ if (*linep <= 0) - *linep = (SP != 0 && SP->_filtered) ? 1 : WINSIZE_ROWS(size); + *linep = (sp != 0 && sp->_filtered) ? 1 : WINSIZE_ROWS(size); if (*colp <= 0) *colp = WINSIZE_COLS(size); } @@ -279,8 +275,8 @@ _nc_get_screensize(int *linep, int *colp) my_tabsize = 8; #if USE_REENTRANT - if (SP != 0) - SP->_TABSIZE = my_tabsize; + if (sp != 0) + sp->_TABSIZE = my_tabsize; #else TABSIZE = my_tabsize; #endif @@ -289,25 +285,25 @@ _nc_get_screensize(int *linep, int *colp) #if USE_SIZECHANGE NCURSES_EXPORT(void) -_nc_update_screensize(void) +_nc_update_screensize(SCREEN *sp) { int old_lines = lines; int new_lines; int old_cols = columns; int new_cols; - _nc_get_screensize(&new_lines, &new_cols); + _nc_get_screensize(sp, &new_lines, &new_cols); /* * See is_term_resized() and resizeterm(). * We're doing it this way because those functions belong to the upper * ncurses library, while this resides in the lower terminfo library. */ - if (SP != 0 - && SP->_resize != 0) { + if (sp != 0 + && sp->_resize != 0) { if ((new_lines != old_lines) || (new_cols != old_cols)) - SP->_resize(new_lines, new_cols); - SP->_sig_winch = FALSE; + sp->_resize(new_lines, new_cols); + sp->_sig_winch = FALSE; } } #endif @@ -590,10 +586,11 @@ _nc_setupterm(NCURSES_CONST char *tname, int Filedes, int *errret, bool reuse) * We should always check the screensize, just in case. */ #if USE_REENTRANT - _nc_get_screensize(SP ? &(SP->_LINES) : &(_nc_prescreen._LINES), + _nc_get_screensize(SP, + SP ? &(SP->_LINES) : &(_nc_prescreen._LINES), SP ? &(SP->_COLS) : &(_nc_prescreen._COLS)); #else - _nc_get_screensize(&LINES, &COLS); + _nc_get_screensize(SP, &LINES, &COLS); #endif if (errret) diff --git a/ncurses/tinfo/lib_ttyflags.c b/ncurses/tinfo/lib_ttyflags.c index 4cbbf504..2cb9fd67 100644 --- a/ncurses/tinfo/lib_ttyflags.c +++ b/ncurses/tinfo/lib_ttyflags.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 * @@ -38,7 +38,7 @@ #include #include /* cur_term */ -MODULE_ID("$Id: lib_ttyflags.c,v 1.15 2007/05/26 18:54:25 tom Exp $") +MODULE_ID("$Id: lib_ttyflags.c,v 1.16 2008/05/03 22:39:03 tom Exp $") NCURSES_EXPORT(int) _nc_get_tty_mode(TTY * buf) @@ -147,7 +147,7 @@ reset_prog_mode(void) if (_nc_set_tty_mode(&cur_term->Nttyb) == OK) { if (SP) { if (SP->_keypad_on) - _nc_keypad(TRUE); + _nc_keypad(SP, TRUE); NC_BUFFERED(TRUE); } returnCode(OK); @@ -163,7 +163,7 @@ reset_shell_mode(void) if (cur_term != 0) { if (SP) { - _nc_keypad(FALSE); + _nc_keypad(SP, FALSE); _nc_flush(); NC_BUFFERED(FALSE); } diff --git a/ncurses/tty/lib_tstp.c b/ncurses/tty/lib_tstp.c index 2a341fa6..06c8411c 100644 --- a/ncurses/tty/lib_tstp.c +++ b/ncurses/tty/lib_tstp.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 * @@ -46,7 +46,7 @@ #define _POSIX_SOURCE #endif -MODULE_ID("$Id: lib_tstp.c,v 1.36 2007/04/21 19:51:29 tom Exp $") +MODULE_ID("$Id: lib_tstp.c,v 1.37 2008/05/03 16:24:56 tom Exp $") #if defined(SIGTSTP) && (HAVE_SIGACTION || HAVE_SIGVEC) #define USE_SIGTSTP 1 @@ -252,19 +252,17 @@ cleanup(int sig) if (signal(sig, SIG_IGN) != SIG_ERR) #endif { - SCREEN *scan = _nc_screen_chain; - while (scan) { - if (SP != 0 - && SP->_ofp != 0 - && isatty(fileno(SP->_ofp))) { - SP->_cleanup = TRUE; - SP->_outch = _nc_outch; + SCREEN *scan; + for (each_screen(scan)) { + if (scan->_ofp != 0 + && isatty(fileno(scan->_ofp))) { + scan->_cleanup = TRUE; + scan->_outch = _nc_outch; } set_term(scan); endwin(); if (SP) SP->_endwin = FALSE; /* in case we have an atexit! */ - scan = scan->_next_screen; } } } diff --git a/ncurses/tty/lib_twait.c b/ncurses/tty/lib_twait.c index ec9daae8..6d460818 100644 --- a/ncurses/tty/lib_twait.c +++ b/ncurses/tty/lib_twait.c @@ -62,7 +62,7 @@ # endif #endif -MODULE_ID("$Id: lib_twait.c,v 1.55 2008/03/01 22:08:31 tom Exp $") +MODULE_ID("$Id: lib_twait.c,v 1.57 2008/05/03 21:35:57 tom Exp $") static long _nc_gettime(TimeType * t0, bool first) @@ -137,7 +137,8 @@ _nc_eventlist_timeout(_nc_eventlist * evl) * descriptors. */ NCURSES_EXPORT(int) -_nc_timed_wait(int mode, +_nc_timed_wait(SCREEN *sp, + int mode, int milliseconds, int *timeleft EVENTLIST_2nd(_nc_eventlist * evl)) @@ -199,12 +200,12 @@ _nc_timed_wait(int mode, #endif if (mode & 1) { - fds[count].fd = SP->_ifd; + fds[count].fd = sp->_ifd; fds[count].events = POLLIN; count++; } if ((mode & 2) - && (fd = SP->_mouse_fd) >= 0) { + && (fd = sp->_mouse_fd) >= 0) { fds[count].fd = fd; fds[count].events = POLLIN; count++; @@ -307,11 +308,11 @@ _nc_timed_wait(int mode, FD_ZERO(&set); if (mode & 1) { - FD_SET(SP->_ifd, &set); - count = SP->_ifd + 1; + FD_SET(sp->_ifd, &set); + count = sp->_ifd + 1; } if ((mode & 2) - && (fd = SP->_mouse_fd) >= 0) { + && (fd = sp->_mouse_fd) >= 0) { FD_SET(fd, &set); count = max(fd, count) + 1; } @@ -424,11 +425,11 @@ _nc_timed_wait(int mode, result = 1; /* redundant, but simple */ #elif HAVE_SELECT if ((mode & 2) - && (fd = SP->_mouse_fd) >= 0 + && (fd = sp->_mouse_fd) >= 0 && FD_ISSET(fd, &set)) result |= 2; if ((mode & 1) - && FD_ISSET(SP->_ifd, &set)) + && FD_ISSET(sp->_ifd, &set)) result |= 1; #endif } else diff --git a/ncurses/tty/tty_update.c b/ncurses/tty/tty_update.c index 86668136..16fc17d2 100644 --- a/ncurses/tty/tty_update.c +++ b/ncurses/tty/tty_update.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2007,2008 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 * @@ -74,7 +74,7 @@ #include #include -MODULE_ID("$Id: tty_update.c,v 1.243 2007/10/13 20:03:32 tom Exp $") +MODULE_ID("$Id: tty_update.c,v 1.245 2008/05/03 22:43:04 tom Exp $") /* * This define controls the line-breakout optimization. Every once in a @@ -645,7 +645,7 @@ doupdate(void) SP->_fifohold--; #if USE_SIZECHANGE - if (SP->_endwin || _nc_handle_sigwinch(FALSE)) { + if (SP->_endwin || _nc_handle_sigwinch(SP)) { /* * This is a transparent extension: XSI does not address it, * and applications need not know that ncurses can do it. @@ -654,7 +654,7 @@ doupdate(void) * (this can happen in an xterm, for example), and resize the * ncurses data structures accordingly. */ - _nc_update_screensize(); + _nc_update_screensize(SP); } #endif diff --git a/test/ditto.c b/test/ditto.c index 17a883dd..4873d0d9 100644 --- a/test/ditto.c +++ b/test/ditto.c @@ -27,13 +27,18 @@ ****************************************************************************/ /* - * Author: Thomas E. Dickey 1998 + * Author: Thomas E. Dickey (1998-on) * - * $Id: ditto.c,v 1.21 2008/04/19 20:08:45 tom Exp $ + * $Id: ditto.c,v 1.26 2008/04/26 23:42:39 tom Exp $ * * The program illustrates how to set up multiple screens from a single - * program. Invoke the program by specifying another terminal on the same - * machine by specifying its device, e.g., + * program. + * + * If openpty() is supported, the command line parameters are titles for + * the windows showing each screen's data. + * + * If openpty() is not supported, you must invoke the program by specifying + * another terminal on the same machine by specifying its device, e.g., * ditto /dev/ttyp1 */ #include @@ -44,18 +49,46 @@ #include USE_OPENPTY_HEADER #endif +#define MAX_FIFO 256 + +#define THIS_FIFO(n) ((n) % MAX_FIFO) +#define NEXT_FIFO(n) THIS_FIFO((n) + 1) + +typedef struct { + unsigned long sequence; + int head; + int tail; + int data[MAX_FIFO]; +} FIFO; + +typedef struct { + unsigned long sequence; +} PEEK; + +/* + * Data "owned" for a single screen. Each screen is divided into windows that + * show the text read from each terminal. Input from a given screen will also + * be read into one window per screen. + */ typedef struct { FILE *input; FILE *output; - SCREEN *screen; - WINDOW **windows; + SCREEN *screen; /* this screen - curses internal data */ + int length; /* length of windows[] and peeks[] */ + char **titles; /* per-window titles */ + WINDOW **windows; /* display data from each screen */ + PEEK *peeks; /* indices for each screen's fifo */ + FIFO fifo; /* fifo for this screen */ } DITTO; +/* + * Structure used to pass multiple parameters via the use_screen() + * single-parameter interface. + */ typedef struct { - int value; /* the actual data */ - int source; /* which screen did data come from */ - int target; /* which screen is data going to */ - DITTO *ditto; + int source; /* which screen did character come from */ + int target; /* which screen is character going to */ + DITTO *ditto; /* data for all screens */ } DDATA; static void @@ -72,6 +105,36 @@ usage(void) ExitProgram(EXIT_FAILURE); } +/* Add to the head of the fifo, checking for overflow. */ +static void +put_fifo(FIFO * fifo, int value) +{ + int next = NEXT_FIFO(fifo->head); + if (next == fifo->tail) + fifo->tail = NEXT_FIFO(fifo->tail); + fifo->data[next] = value; + fifo->head = next; + fifo->sequence += 1; +} + +/* Get data from the tail (oldest part) of the fifo, returning -1 if no data. + * Since each screen can peek into the fifo, we do not update the tail index, + * but modify the peek-index. + * + * FIXME - test/workaround for case where fifo gets more than a buffer + * ahead of peek. + */ +static int +peek_fifo(FIFO * fifo, PEEK * peek) +{ + int result = -1; + if (peek->sequence < fifo->sequence) { + peek->sequence += 1; + result = fifo->data[THIS_FIFO(peek->sequence)]; + } + return result; +} + static FILE * open_tty(char *path) { @@ -112,6 +175,64 @@ open_tty(char *path) return fp; } +static void +init_screen(SCREEN *sp GCC_UNUSED, void *arg) +{ + DITTO *target = (DITTO *) arg; + int high, wide; + int k; + + cbreak(); + noecho(); + scrollok(stdscr, TRUE); + nodelay(stdscr, TRUE); + box(stdscr, 0, 0); + + target->windows = typeCalloc(WINDOW *, target->length); + target->peeks = typeCalloc(PEEK, target->length); + + high = (LINES - 2) / target->length; + wide = (COLS - 2); + for (k = 0; k < target->length; ++k) { + WINDOW *outer = newwin(high, wide, 1 + (high * k), 1); + WINDOW *inner = derwin(outer, high - 2, wide - 2, 1, 1); + + box(outer, 0, 0); + mvwaddstr(outer, 0, 2, target->titles[k]); + wnoutrefresh(outer); + + scrollok(inner, TRUE); + nodelay(inner, TRUE); + keypad(inner, TRUE); + + target->windows[k] = inner; + } + doupdate(); +} + +static void +open_screen(DITTO * target, char **source, int length, int which) +{ + if (which != 0) { + target->input = + target->output = open_tty(source[which]); + } else { + target->input = stdin; + target->output = stdout; + } + + target->titles = source; + target->length = length; + target->screen = newterm((char *) 0, /* assume $TERM is the same */ + target->output, + target->input); + + if (target->screen == 0) + failed("newterm"); + + (void) USING_SCREEN(target->screen, init_screen, target); +} + static int close_screen(SCREEN *sp GCC_UNUSED, void *arg GCC_UNUSED) { @@ -120,24 +241,52 @@ close_screen(SCREEN *sp GCC_UNUSED, void *arg GCC_UNUSED) return endwin(); } +/* + * Read data from the 'source' screen. + */ static int read_screen(SCREEN *sp GCC_UNUSED, void *arg) { DDATA *data = (DDATA *) arg; - WINDOW *win = data->ditto[data->source].windows[data->source]; + DITTO *ditto = &(data->ditto[data->source]); + WINDOW *win = ditto->windows[data->source]; + int ch = wgetch(win); - return wgetch(win); + if (ch > 0 && ch < 256) + put_fifo(&(ditto->fifo), ch); + else + ch = ERR; + + return ch; } +/* + * Write all of the data that's in fifos for the 'target' screen. + */ static int write_screen(SCREEN *sp GCC_UNUSED, void *arg GCC_UNUSED) { DDATA *data = (DDATA *) arg; - WINDOW *win = data->ditto[data->target].windows[data->source]; + DITTO *ditto = &(data->ditto[data->target]); + bool changed = FALSE; + int which; + + for (which = 0; which < ditto->length; ++which) { + WINDOW *win = ditto->windows[which]; + FIFO *fifo = &(data->ditto[which].fifo); + PEEK *peek = &(ditto->peeks[which]); + int ch; - waddch(win, data->value); - wnoutrefresh(win); - doupdate(); + while ((ch = peek_fifo(fifo, peek)) > 0) { + changed = TRUE; + + waddch(win, ch); + wnoutrefresh(win); + } + } + + if (changed) + doupdate(); return OK; } @@ -156,7 +305,7 @@ int main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) { - int j, k; + int j; int count; DITTO *data; @@ -166,50 +315,8 @@ main(int argc GCC_UNUSED, if ((data = typeCalloc(DITTO, argc)) == 0) failed("calloc data"); - data[0].input = stdin; - data[0].output = stdout; - for (j = 1; j < argc; j++) { - data[j].input = - data[j].output = open_tty(argv[j]); - } - - /* - * If we got this far, we have open connection(s) to the terminal(s). - * Set up the screens. - */ for (j = 0; j < argc; j++) { - int high, wide; - - data[j].screen = newterm((char *) 0, /* assume $TERM is the same */ - data[j].output, - data[j].input); - - if (data[j].screen == 0) - failed("newterm"); - cbreak(); - noecho(); - scrollok(stdscr, TRUE); - nodelay(stdscr, TRUE); - box(stdscr, 0, 0); - - data[j].windows = typeCalloc(WINDOW *, argc); - - high = (LINES - 2) / argc; - wide = (COLS - 2); - for (k = 0; k < argc; ++k) { - WINDOW *outer = newwin(high, wide, 1 + (high * k), 1); - WINDOW *inner = derwin(outer, high - 2, wide - 2, 1, 1); - - box(outer, 0, 0); - mvwaddstr(outer, 0, 2, argv[k]); - wnoutrefresh(outer); - - scrollok(inner, TRUE); - nodelay(inner, TRUE); - - data[j].windows[k] = inner; - } - doupdate(); + open_screen(&data[j], argv, argc, j); } /* @@ -227,14 +334,11 @@ main(int argc GCC_UNUSED, ddata.ditto = data; ch = USING_SCREEN(data[which].screen, read_screen, &ddata); - if (ch == ERR) { - continue; - } - if (ch == CTRL('D')) + if (ch == CTRL('D')) { break; - - ddata.value = ch; - show_ditto(data, argc, &ddata); + } else if (ch != ERR) { + show_ditto(data, argc, &ddata); + } } /* -- 2.44.0