From: Thomas E. Dickey Date: Sun, 8 Jun 2008 00:40:16 +0000 (+0000) Subject: ncurses 5.6 - patch 20080607 X-Git-Tag: v5.7~23 X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=commitdiff_plain;h=1078c0231b8a58fbd2dd56b6e0a81b19d6b07f77;ds=sidebyside ncurses 5.6 - patch 20080607 + finish changes to wgetch(), making it switch as needed to the window's actual screen when calling wrefresh() and wgetnstr(). That allows wgetch() to get used concurrently in different threads with some minor restrictions, e.g., the application should not delete a window which is being used in a wgetch(). + simplify mutex's, combining the window- and screen-mutex's. --- diff --git a/NEWS b/NEWS index 06f7b566..6e04e9e3 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.1241 2008/05/31 21:52:48 tom Exp $ +-- $Id: NEWS,v 1.1243 2008/06/07 15:48:17 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. +20080607 + + finish changes to wgetch(), making it switch as needed to the + window's actual screen when calling wrefresh() and wgetnstr(). That + allows wgetch() to get used concurrently in different threads with + some minor restrictions, e.g., the application should not delete a + window which is being used in a wgetch(). + + simplify mutex's, combining the window- and screen-mutex's. + 20080531 + modify wgetch() to use the screen which corresponds to its window parameter rather than relying on SP; some dependent functions still diff --git a/dist.mk b/dist.mk index a78cde3d..aa568f5a 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.644 2008/05/31 14:47:34 tom Exp $ +# $Id: dist.mk,v 1.645 2008/06/07 13:41:24 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 = 20080531 +NCURSES_PATCH = 20080607 # 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_delwin.c b/ncurses/base/lib_delwin.c index ba5f180d..b92c4033 100644 --- a/ncurses/base/lib_delwin.c +++ b/ncurses/base/lib_delwin.c @@ -40,7 +40,7 @@ #include -MODULE_ID("$Id: lib_delwin.c,v 1.16 2008/05/03 14:13:51 tom Exp $") +MODULE_ID("$Id: lib_delwin.c,v 1.17 2008/06/07 14:10:56 tom Exp $") static bool cannot_delete(WINDOW *win) @@ -67,12 +67,10 @@ delwin(WINDOW *win) T((T_CALLED("delwin(%p)"), win)); - if (_nc_try_global(windowlist) == 0) { - _nc_lock_window(win); + if (_nc_try_global(curses) == 0) { if (win == 0 || cannot_delete(win)) { result = ERR; - _nc_unlock_window(win); } else { if (win->_flags & _SUBWIN) @@ -80,10 +78,9 @@ delwin(WINDOW *win) else if (curscr != 0) touchwin(curscr); - _nc_unlock_window(win); result = _nc_freewin(win); } - _nc_unlock_global(windowlist); + _nc_unlock_global(curses); } returnCode(result); } diff --git a/ncurses/base/lib_freeall.c b/ncurses/base/lib_freeall.c index 4bb7ccc7..8ec3f279 100644 --- a/ncurses/base/lib_freeall.c +++ b/ncurses/base/lib_freeall.c @@ -40,7 +40,7 @@ extern int malloc_errfd; /* FIXME */ #endif -MODULE_ID("$Id: lib_freeall.c,v 1.46 2008/05/03 14:13:51 tom Exp $") +MODULE_ID("$Id: lib_freeall.c,v 1.47 2008/06/07 13:58:29 tom Exp $") /* * Free all ncurses data. This is used for testing only (there's no practical @@ -61,7 +61,7 @@ _nc_freeall(void) } #endif if (SP != 0) { - _nc_lock_global(windowlist); + _nc_lock_global(curses); while (_nc_windows != 0) { bool deleted = FALSE; @@ -93,7 +93,7 @@ _nc_freeall(void) break; } delscreen(SP); - _nc_unlock_global(windowlist); + _nc_unlock_global(curses); } if (cur_term != 0) del_curterm(cur_term); diff --git a/ncurses/base/lib_getch.c b/ncurses/base/lib_getch.c index f77df69e..372d4ac7 100644 --- a/ncurses/base/lib_getch.c +++ b/ncurses/base/lib_getch.c @@ -41,7 +41,7 @@ #include -MODULE_ID("$Id: lib_getch.c,v 1.91 2008/05/31 21:47:48 tom Exp $") +MODULE_ID("$Id: lib_getch.c,v 1.95 2008/06/07 15:52:51 tom Exp $") #include @@ -76,6 +76,13 @@ set_escdelay(int value) } #endif +static int +_nc_use_meta(WINDOW *win) +{ + SCREEN *sp = _nc_screen_of(win); + return (sp ? sp->_use_meta : 0); +} + #ifdef NCURSES_WGETCH_EVENTS #define TWAIT_MASK 7 #else @@ -249,21 +256,62 @@ fifo_clear(SCREEN *sp) static int kgetch(SCREEN *EVENTLIST_2nd(_nc_eventlist * evl)); static void -refresh_if_needed(WINDOW *win) +recur_wrefresh(WINDOW *win) { - if ((is_wintouched(win) || (win->_flags & _HASMOVED)) - && !(win->_flags & _ISPAD)) { +#ifdef USE_PTHREADS + SCREEN *sp = _nc_screen_of(win); + if (sp != SP) { + SCREEN *save_SP; + + /* temporarily switch to the window's screen to check/refresh */ + _nc_lock_global(curses); + save_SP = SP; + SP = sp; + recur_wrefresh(win); + SP = save_SP; + _nc_unlock_global(curses); + } else +#endif + if ((is_wintouched(win) || (win->_flags & _HASMOVED)) + && !(win->_flags & _ISPAD)) { wrefresh(win); } } +static int +recur_wgetnstr(WINDOW *win, char *buf) +{ + SCREEN *sp = _nc_screen_of(win); + int rc; + +#ifdef USE_PTHREADS + if (sp != SP) { + SCREEN *save_SP; + + /* temporarily switch to the window's screen to get cooked input */ + _nc_lock_global(curses); + save_SP = SP; + SP = sp; + rc = recur_wgetnstr(win, buf); + SP = save_SP; + _nc_unlock_global(curses); + } else +#endif + { + sp->_called_wgetch = TRUE; + rc = wgetnstr(win, buf, MAXCOLUMNS); + sp->_called_wgetch = FALSE; + } + return rc; +} + NCURSES_EXPORT(int) _nc_wgetch(WINDOW *win, unsigned long *result, int use_meta EVENTLIST_2nd(_nc_eventlist * evl)) { - SCREEN *sp = _nc_screen_of(win); + SCREEN *sp; int ch; #ifdef NCURSES_WGETCH_EVENTS long event_delay = -1; @@ -272,12 +320,14 @@ _nc_wgetch(WINDOW *win, T((T_CALLED("_nc_wgetch(%p)"), win)); *result = 0; + + sp = _nc_screen_of(win); if (win == 0 || sp == 0) { returnCode(ERR); } if (cooked_key_in_fifo()) { - refresh_if_needed(win); + recur_wrefresh(win); *result = fifo_pull(sp); returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK); } @@ -302,9 +352,7 @@ _nc_wgetch(WINDOW *win, TR(TRACE_IEVENT, ("filling queue in cooked mode")); - sp->_called_wgetch = TRUE; - rc = wgetnstr(win, buf, MAXCOLUMNS); - sp->_called_wgetch = FALSE; + rc = recur_wgetnstr(win, buf); /* ungetch in reverse order */ #ifdef NCURSES_WGETCH_EVENTS @@ -327,7 +375,7 @@ _nc_wgetch(WINDOW *win, if (win->_use_keypad != sp->_keypad_on) _nc_keypad(sp, win->_use_keypad); - refresh_if_needed(win); + recur_wrefresh(win); if (!win->_notimeout && (win->_delay >= 0 || sp->_cbreak > 1)) { if (head == -1) { /* fifo is empty */ @@ -355,8 +403,9 @@ _nc_wgetch(WINDOW *win, returnCode(KEY_CODE_YES); } #endif - if (!rc) + if (!rc) { returnCode(ERR); + } } /* else go on to read data available */ } @@ -479,14 +528,13 @@ _nc_wgetch(WINDOW *win, NCURSES_EXPORT(int) wgetch_events(WINDOW *win, _nc_eventlist * evl) { - SCREEN *sp = _nc_screen_of(win); int code; unsigned long value; T((T_CALLED("wgetch_events(%p,%p)"), win, evl)); code = _nc_wgetch(win, &value, - sp->_use_meta + _nc_use_meta(win) EVENTLIST_2nd(evl)); if (code != ERR) code = value; @@ -497,14 +545,13 @@ wgetch_events(WINDOW *win, _nc_eventlist * evl) NCURSES_EXPORT(int) wgetch(WINDOW *win) { - SCREEN *sp = _nc_screen_of(win); int code; unsigned long value; T((T_CALLED("wgetch(%p)"), win)); code = _nc_wgetch(win, &value, - (sp ? sp->_use_meta : 0) + _nc_use_meta(win) EVENTLIST_2nd((_nc_eventlist *) 0)); if (code != ERR) code = value; diff --git a/ncurses/base/lib_initscr.c b/ncurses/base/lib_initscr.c index ef360c03..6fc2fb0a 100644 --- a/ncurses/base/lib_initscr.c +++ b/ncurses/base/lib_initscr.c @@ -45,7 +45,7 @@ #include /* needed for ISC */ #endif -MODULE_ID("$Id: lib_initscr.c,v 1.36 2008/04/12 18:11:36 tom Exp $") +MODULE_ID("$Id: lib_initscr.c,v 1.37 2008/06/07 14:00:12 tom Exp $") NCURSES_EXPORT(WINDOW *) initscr(void) @@ -57,7 +57,7 @@ initscr(void) START_TRACE(); T((T_CALLED("initscr()"))); - _nc_lock_global(set_SP); + _nc_lock_global(curses); /* Portable applications must not call initscr() more than once */ if (!_nc_globals.init_screen) { _nc_globals.init_screen = TRUE; @@ -91,7 +91,7 @@ initscr(void) def_prog_mode(); } result = stdscr; - _nc_unlock_global(set_SP); + _nc_unlock_global(curses); returnWin(result); } diff --git a/ncurses/base/lib_newterm.c b/ncurses/base/lib_newterm.c index 3620a3fd..29bf9a74 100644 --- a/ncurses/base/lib_newterm.c +++ b/ncurses/base/lib_newterm.c @@ -48,7 +48,7 @@ #include /* clear_screen, cup & friends, cur_term */ #include -MODULE_ID("$Id: lib_newterm.c,v 1.69 2008/04/12 18:15:04 tom Exp $") +MODULE_ID("$Id: lib_newterm.c,v 1.70 2008/06/07 14:00:23 tom Exp $") #ifndef ONLCR /* Allows compilation under the QNX 4.2 OS */ #define ONLCR 0 @@ -129,7 +129,7 @@ newterm(NCURSES_CONST char *name, FILE *ofp, FILE *ifp) START_TRACE(); T((T_CALLED("newterm(\"%s\",%p,%p)"), name, ofp, ifp)); - _nc_lock_global(set_SP); + _nc_lock_global(curses); /* this loads the capability entry, then sets LINES and COLS */ if (setupterm(name, fileno(ofp), &errret) != ERR) { int slk_format = _nc_globals.slk_format; @@ -212,6 +212,6 @@ newterm(NCURSES_CONST char *name, FILE *ofp, FILE *ifp) result = SP; } } - _nc_unlock_global(set_SP); + _nc_unlock_global(curses); returnSP(result); } diff --git a/ncurses/base/lib_newwin.c b/ncurses/base/lib_newwin.c index 78a18b88..587e83a9 100644 --- a/ncurses/base/lib_newwin.c +++ b/ncurses/base/lib_newwin.c @@ -42,7 +42,7 @@ #include #include -MODULE_ID("$Id: lib_newwin.c,v 1.51 2008/05/31 21:50:09 tom Exp $") +MODULE_ID("$Id: lib_newwin.c,v 1.52 2008/06/07 13:58:09 tom Exp $") #define window_is(name) ((sp)->_##name == win) @@ -85,7 +85,7 @@ _nc_freewin(WINDOW *win) T((T_CALLED("_nc_freewin(%p)"), win)); if (win != 0) { - if (_nc_try_global(windowlist) == 0) { + if (_nc_try_global(curses) == 0) { q = 0; for (each_window(p)) { if (&(p->win) == win) { @@ -108,7 +108,7 @@ _nc_freewin(WINDOW *win) } q = p; } - _nc_unlock_global(windowlist); + _nc_unlock_global(curses); } } returnCode(result); @@ -229,8 +229,6 @@ _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) if ((wp = typeCalloc(WINDOWLIST, 1)) == 0) returnWin(0); - _nc_mutex_init(&(wp->mutex_use_window)); - win = &(wp->win); if ((win->_line = typeCalloc(struct ldat, ((unsigned) num_lines))) == 0) { @@ -238,7 +236,7 @@ _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) returnWin(0); } - _nc_lock_global(windowlist); + _nc_lock_global(curses); win->_curx = 0; win->_cury = 0; @@ -318,7 +316,7 @@ _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) T((T_CREATE("window %p"), win)); - _nc_unlock_global(windowlist); + _nc_unlock_global(curses); returnWin(win); } diff --git a/ncurses/base/lib_overlay.c b/ncurses/base/lib_overlay.c index 26314de5..669e8e72 100644 --- a/ncurses/base/lib_overlay.c +++ b/ncurses/base/lib_overlay.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 @@ #include -MODULE_ID("$Id: lib_overlay.c,v 1.25 2008/04/12 17:21:59 tom Exp $") +MODULE_ID("$Id: lib_overlay.c,v 1.27 2008/06/07 23:30:34 tom Exp $") static int overlap(const WINDOW *const src, WINDOW *const dst, int const flag) @@ -55,8 +55,7 @@ overlap(const WINDOW *const src, WINDOW *const dst, int const flag) T((T_CALLED("overlap(%p,%p,%d)"), src, dst, flag)); if (src != 0 && dst != 0) { - _nc_lock_window(src); - _nc_lock_window(dst); + _nc_lock_global(curses); T(("src : begy %ld, begx %ld, maxy %ld, maxx %ld", (long) src->_begy, @@ -93,8 +92,7 @@ overlap(const WINDOW *const src, WINDOW *const dst, int const flag) dmaxrow, dmaxcol, flag); } - _nc_unlock_window(dst); - _nc_unlock_window(src); + _nc_unlock_global(curses); } returnCode(rc); } @@ -150,9 +148,7 @@ copywin(const WINDOW *src, WINDOW *dst, src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, over)); if (src && dst) { - - _nc_lock_window(src); - _nc_lock_window(dst); + _nc_lock_global(curses); bk = AttrOf(dst->_nc_bkgd); mask = ~(attr_t) ((bk & A_COLOR) ? A_COLOR : 0); @@ -204,8 +200,7 @@ copywin(const WINDOW *src, WINDOW *dst, rc = OK; } } - _nc_unlock_window(dst); - _nc_unlock_window(src); + _nc_unlock_global(curses); } returnCode(rc); } diff --git a/ncurses/base/lib_set_term.c b/ncurses/base/lib_set_term.c index 2403044d..24f90d1b 100644 --- a/ncurses/base/lib_set_term.c +++ b/ncurses/base/lib_set_term.c @@ -44,28 +44,30 @@ #include /* cur_term */ #include -MODULE_ID("$Id: lib_set_term.c,v 1.109 2008/05/31 20:11:26 tom Exp $") +MODULE_ID("$Id: lib_set_term.c,v 1.112 2008/06/07 22:29:07 tom Exp $") NCURSES_EXPORT(SCREEN *) set_term(SCREEN *screenp) { SCREEN *oldSP; + SCREEN *newSP; T((T_CALLED("set_term(%p)"), screenp)); - _nc_lock_global(set_SP); + _nc_lock_global(curses); oldSP = SP; _nc_set_screen(screenp); + newSP = SP; - if (SP != 0) { - set_curterm(SP->_term); + if (newSP != 0) { + set_curterm(newSP->_term); #if !USE_REENTRANT - curscr = SP->_curscr; - newscr = SP->_newscr; - stdscr = SP->_stdscr; - COLORS = SP->_color_count; - COLOR_PAIRS = SP->_pair_count; + curscr = newSP->_curscr; + newscr = newSP->_newscr; + stdscr = newSP->_stdscr; + COLORS = newSP->_color_count; + COLOR_PAIRS = newSP->_pair_count; #endif } else { set_curterm(0); @@ -78,7 +80,7 @@ set_term(SCREEN *screenp) #endif } - _nc_unlock_global(set_SP); + _nc_unlock_global(curses); T((T_RETURN("%p"), oldSP)); return (oldSP); @@ -125,7 +127,7 @@ delscreen(SCREEN *sp) T((T_CALLED("delscreen(%p)"), sp)); - _nc_lock_global(set_SP); + _nc_lock_global(curses); if (delink_screen(sp)) { (void) _nc_freewin(sp->_curscr); @@ -162,7 +164,10 @@ delscreen(SCREEN *sp) FreeIfNeeded(sp->_acs_map); FreeIfNeeded(sp->_screen_acs_map); +#if 0 + /* FIXME - this should be a copy of the struct, not a pointer */ del_curterm(sp->_term); +#endif /* * If the associated output stream has been closed, we can discard the @@ -194,7 +199,7 @@ delscreen(SCREEN *sp) _nc_set_screen(0); } } - _nc_unlock_global(set_SP); + _nc_unlock_global(curses); returnVoid; } diff --git a/ncurses/base/lib_window.c b/ncurses/base/lib_window.c index ac61cb01..a3236e20 100644 --- a/ncurses/base/lib_window.c +++ b/ncurses/base/lib_window.c @@ -39,7 +39,7 @@ #include -MODULE_ID("$Id: lib_window.c,v 1.24 2008/04/12 22:40:21 tom Exp $") +MODULE_ID("$Id: lib_window.c,v 1.25 2008/06/07 14:12:56 tom Exp $") NCURSES_EXPORT(void) _nc_synchook(WINDOW *win) @@ -186,7 +186,7 @@ dupwin(WINDOW *win) if (win != 0) { - _nc_lock_window(win); + _nc_lock_global(curses); if (win->_flags & _ISPAD) { nwin = newpad(win->_maxy + 1, win->_maxx + 1); @@ -244,7 +244,7 @@ dupwin(WINDOW *win) nwin->_line[i].lastchar = win->_line[i].lastchar; } } - _nc_unlock_window(win); + _nc_unlock_global(curses); } returnWin(nwin); } diff --git a/ncurses/base/resizeterm.c b/ncurses/base/resizeterm.c index f7ef2042..a94cfc3a 100644 --- a/ncurses/base/resizeterm.c +++ b/ncurses/base/resizeterm.c @@ -41,7 +41,7 @@ #include #include -MODULE_ID("$Id: resizeterm.c,v 1.33 2008/05/31 16:51:12 tom Exp $") +MODULE_ID("$Id: resizeterm.c,v 1.34 2008/06/07 13:58:40 tom Exp $") #define stolen_lines (screen_lines - SP->_lines_avail) @@ -66,7 +66,7 @@ show_window_sizes(const char *name) { WINDOWLIST *wp; - _nc_lock_global(windowlist); + _nc_lock_global(curses); _tracef("%s resizing: %2d x %2d (%2d x %2d)", name, LINES, COLS, screen_lines, screen_columns); for (each_window(wp)) { @@ -77,7 +77,7 @@ show_window_sizes(const char *name) (long) wp->win._begy, (long) wp->win._begx); } - _nc_unlock_global(windowlist); + _nc_unlock_global(curses); } #endif @@ -320,7 +320,7 @@ resize_term(int ToLines, int ToCols) returnCode(ERR); } - _nc_lock_global(windowlist); + _nc_lock_global(curses); was_stolen = (screen_lines - SP->_lines_avail); if (is_term_resized(ToLines, ToCols)) { @@ -378,7 +378,7 @@ resize_term(int ToLines, int ToCols) SET_LINES(ToLines - was_stolen); SET_COLS(ToCols); - _nc_unlock_global(windowlist); + _nc_unlock_global(curses); returnCode(result); } diff --git a/ncurses/base/use_window.c b/ncurses/base/use_window.c index 4d0fdf67..f6408c37 100644 --- a/ncurses/base/use_window.c +++ b/ncurses/base/use_window.c @@ -32,37 +32,7 @@ #include -MODULE_ID("$Id: use_window.c,v 1.7 2008/05/03 14:09:38 tom Exp $") - -#ifdef USE_PTHREADS -NCURSES_EXPORT(void) -_nc_lock_window(const WINDOW *win) -{ - WINDOWLIST *p; - - _nc_lock_global(windowlist); - for (each_window(p)) { - if (&(p->win) == win) { - _nc_mutex_lock(&(p->mutex_use_window)); - break; - } - } -} - -NCURSES_EXPORT(void) -_nc_unlock_window(const WINDOW *win) -{ - WINDOWLIST *p; - - for (each_window(p)) { - if (&(p->win) == win) { - _nc_mutex_unlock(&(p->mutex_use_window)); - break; - } - } - _nc_unlock_global(windowlist); -} -#endif +MODULE_ID("$Id: use_window.c,v 1.8 2008/06/07 14:13:46 tom Exp $") NCURSES_EXPORT(int) use_window(WINDOW *win, NCURSES_WINDOW_CB func, void *data) @@ -70,9 +40,9 @@ use_window(WINDOW *win, NCURSES_WINDOW_CB func, void *data) int code = OK; T((T_CALLED("use_window(%p,%p,%p)"), win, func, data)); - _nc_lock_window(win); + _nc_lock_global(curses); code = func(win, data); - _nc_unlock_window(win); + _nc_unlock_global(curses); returnCode(code); } diff --git a/ncurses/base/wresize.c b/ncurses/base/wresize.c index ac808c4d..f46085af 100644 --- a/ncurses/base/wresize.c +++ b/ncurses/base/wresize.c @@ -32,7 +32,7 @@ #include -MODULE_ID("$Id: wresize.c,v 1.28 2008/05/03 14:13:51 tom Exp $") +MODULE_ID("$Id: wresize.c,v 1.29 2008/06/07 13:59:01 tom Exp $") static int cleanup_lines(struct ldat *data, int length) @@ -54,7 +54,7 @@ repair_subwindows(WINDOW *cmp) struct ldat *pline = cmp->_line; int row; - _nc_lock_global(windowlist); + _nc_lock_global(curses); for (each_window(wp)) { WINDOW *tst = &(wp->win); @@ -77,7 +77,7 @@ repair_subwindows(WINDOW *cmp) repair_subwindows(tst); } } - _nc_unlock_global(windowlist); + _nc_unlock_global(curses); } /* diff --git a/ncurses/curses.priv.h b/ncurses/curses.priv.h index 3d152456..e609c133 100644 --- a/ncurses/curses.priv.h +++ b/ncurses/curses.priv.h @@ -34,7 +34,7 @@ /* - * $Id: curses.priv.h,v 1.382 2008/05/31 21:41:41 tom Exp $ + * $Id: curses.priv.h,v 1.383 2008/06/07 14:13:19 tom Exp $ * * curses.priv.h * @@ -329,9 +329,6 @@ extern NCURSES_EXPORT(int) _nc_mutex_unlock(pthread_mutex_t *); #define _nc_try_global(name) _nc_mutex_trylock(&_nc_globals.mutex_##name) #define _nc_unlock_global(name) _nc_mutex_unlock(&_nc_globals.mutex_##name) -extern NCURSES_EXPORT(void) _nc_lock_window(const WINDOW *); -extern NCURSES_EXPORT(void) _nc_unlock_window(const WINDOW *); - #else #error POSIX threads requires --enable-reentrant option #endif @@ -349,9 +346,6 @@ extern NCURSES_EXPORT(void) _nc_unlock_window(const WINDOW *); #define _nc_try_global(name) 0 #define _nc_unlock_global(name) /* nothing */ -#define _nc_lock_window(name) (void) TRUE -#define _nc_unlock_window(name) /* nothing */ - #endif /* USE_PTHREADS */ #if HAVE_GETTIMEOFDAY @@ -613,10 +607,7 @@ typedef struct { #endif /* TRACE */ #ifdef USE_PTHREADS - pthread_mutex_t mutex_set_SP; - pthread_mutex_t mutex_use_screen; - pthread_mutex_t mutex_use_window; - pthread_mutex_t mutex_windowlist; + pthread_mutex_t mutex_curses; pthread_mutex_t mutex_tst_tracef; pthread_mutex_t mutex_tracef; int nested_tracef; @@ -901,9 +892,6 @@ extern NCURSES_EXPORT_VAR(SIG_ATOMIC_T) _nc_have_sigwinch; int addch_x; /* x-position for addch_work[] */ int addch_y; /* y-position for addch_work[] */ #endif -#ifdef USE_PTHREADS - pthread_mutex_t mutex_use_window; -#endif }; #define WINDOW_EXT(win,field) (((WINDOWLIST *)(win))->field) diff --git a/ncurses/llib-lncursest b/ncurses/llib-lncursest index 48acb8c5..906da606 100644 --- a/ncurses/llib-lncursest +++ b/ncurses/llib-lncursest @@ -1151,7 +1151,14 @@ int set_escdelay( int _nc_wgetch( WINDOW *win, unsigned long *result, - int use_meta) + int use_meta, + _nc_eventlist *evl) + { return(*(int *)0); } + +#undef wgetch_events +int wgetch_events( + WINDOW *win, + _nc_eventlist *evl) { return(*(int *)0); } #undef wgetch @@ -1161,6 +1168,14 @@ int wgetch( /* ./base/lib_getstr.c */ +#undef wgetnstr_events +int wgetnstr_events( + WINDOW *win, + char *str, + int maxlen, + _nc_eventlist *evl) + { return(*(int *)0); } + #undef wgetnstr int wgetnstr( WINDOW *win, @@ -1404,6 +1419,11 @@ WINDOW *_nc_makenew( int flags) { return(*(WINDOW **)0); } +#undef _nc_screen_of +SCREEN *_nc_screen_of( + WINDOW *win) + { return(*(SCREEN **)0); } + /* ./base/lib_nl.c */ #undef nl @@ -1832,6 +1852,12 @@ void _tracedump( /* ./trace/lib_tracemse.c */ +#undef _nc_tracemouse +char *_nc_tracemouse( + SCREEN *sp, + MEVENT const *ep) + { return(*(char **)0); } + #undef _tracemouse char *_tracemouse( MEVENT const *ep) @@ -1849,9 +1875,16 @@ void _nc_signal_handler( /* ./base/lib_ungetch.c */ #undef _nc_fifo_dump -void _nc_fifo_dump(void) +void _nc_fifo_dump( + SCREEN *sp) { /* void */ } +#undef _nc_ungetch +int _nc_ungetch( + SCREEN *sp, + int ch) + { return(*(int *)0); } + #undef ungetch int ungetch( int ch) @@ -1992,6 +2025,11 @@ void _nc_screen_init(void) void _nc_screen_wrap(void) { /* void */ } +#undef _nc_do_xmc_glitch +void _nc_do_xmc_glitch( + attr_t previous) + { /* void */ } + /* ./trace/varargs.c */ typedef enum { @@ -2094,26 +2132,16 @@ void _nc_trace_xnames( #undef use_screen int use_screen( SCREEN *screen, - NCURSES_CALLBACK func, + NCURSES_SCREEN_CB func, void *data) { return(*(int *)0); } /* ./base/use_window.c */ -#undef _nc_lock_window -void _nc_lock_window( - WINDOW *win) - { /* void */ } - -#undef _nc_unlock_window -void _nc_unlock_window( - WINDOW *win) - { /* void */ } - #undef use_window int use_window( WINDOW *win, - NCURSES_CALLBACK func, + NCURSES_WINDOW_CB func, void *data) { return(*(int *)0); } @@ -2370,7 +2398,8 @@ const struct tinfo_fkeys _nc_tinfo_fkeys[] = {0}; #endif #undef _nc_init_keytry -void _nc_init_keytry(void) +void _nc_init_keytry( + SCREEN *sp) { /* void */ } /* ./tinfo/lib_acs.c */ @@ -2408,8 +2437,9 @@ int baudrate(void) /* ./tinfo/lib_cur_term.c */ -#undef cur_term -TERMINAL *cur_term; +#undef _nc_cur_term +TERMINAL *_nc_cur_term(void) + { return(*(TERMINAL **)0); } #undef set_curterm TERMINAL *set_curterm( @@ -2444,6 +2474,11 @@ NCURSES_GLOBALS _nc_globals; #undef _nc_prescreen NCURSES_PRESCREEN _nc_prescreen; +#undef _nc_mutex_init +void _nc_mutex_init( + pthread_mutex_t *obj) + { /* void */ } + #undef _nc_mutex_lock int _nc_mutex_lock( pthread_mutex_t *obj) @@ -2487,6 +2522,12 @@ int flushinp(void) struct kn { short offset; int code; }; +#undef _nc_keyname +const char *_nc_keyname( + SCREEN *sp, + int c) + { return(*(const char **)0); } + #undef keyname const char *keyname( int c) @@ -2504,8 +2545,6 @@ char *longname(void) /* ./tinfo/lib_napms.c */ -#include - #undef napms int napms( int ms) @@ -2577,6 +2616,7 @@ int has_key( #undef _nc_keypad int _nc_keypad( + SCREEN *sp, NCURSES_BOOL flag) { return(*(int *)0); } @@ -2622,10 +2662,18 @@ int intrflush( char *_nc_ttytype(void) { return(*(char **)0); } +#undef _nc_ptr_Lines +int *_nc_ptr_Lines(void) + { return(*(int **)0); } + #undef _nc_LINES int _nc_LINES(void) { return(*(int *)0); } +#undef _nc_ptr_Cols +int *_nc_ptr_Cols(void) + { return(*(int **)0); } + #undef _nc_COLS int _nc_COLS(void) { return(*(int *)0); } @@ -2641,7 +2689,7 @@ int set_tabsize( #undef _nc_handle_sigwinch int _nc_handle_sigwinch( - int update) + SCREEN *sp) { return(*(int *)0); } #undef use_env @@ -2651,12 +2699,14 @@ void use_env( #undef _nc_get_screensize void _nc_get_screensize( + SCREEN *sp, int *linep, int *colp) { /* void */ } #undef _nc_update_screensize -void _nc_update_screensize(void) +void _nc_update_screensize( + SCREEN *sp) { /* void */ } #undef _nc_get_locale @@ -2963,6 +3013,12 @@ char *_nc_tracebits(void) /* ./trace/lib_tracechr.c */ +#undef _nc_tracechar +char *_nc_tracechar( + SCREEN *sp, + int ch) + { return(*(char **)0); } + #undef _tracechar char *_tracechar( int ch) @@ -3006,11 +3062,18 @@ int resetty(void) /* ./tty/lib_twait.c */ +#undef _nc_eventlist_timeout +int _nc_eventlist_timeout( + _nc_eventlist *evl) + { return(*(int *)0); } + #undef _nc_timed_wait int _nc_timed_wait( + SCREEN *sp, int mode, int milliseconds, - int *timeleft) + int *timeleft, + _nc_eventlist *evl) { return(*(int *)0); } /* ./tinfo/name_match.c */ @@ -3182,9 +3245,15 @@ char *_nc_trim_sgr0( /* ./unctrl.c */ +#undef _nc_unctrl +const char *_nc_unctrl( + SCREEN *sp, + chtype ch) + { return(*(const char **)0); } + #undef unctrl const char *unctrl( - chtype ch) + chtype ch) { return(*(const char **)0); } /* ./trace/visbuf.c */ diff --git a/ncurses/tinfo/lib_cur_term.c b/ncurses/tinfo/lib_cur_term.c index e1b4f942..d0aad633 100644 --- a/ncurses/tinfo/lib_cur_term.c +++ b/ncurses/tinfo/lib_cur_term.c @@ -40,7 +40,10 @@ #include /* TTY, cur_term */ #include /* ospeed */ -MODULE_ID("$Id: lib_cur_term.c,v 1.15 2008/05/24 23:11:18 tom Exp $") +MODULE_ID("$Id: lib_cur_term.c,v 1.16 2008/06/07 22:22:16 tom Exp $") + +#undef CUR +#define CUR termp->type. #if USE_REENTRANT NCURSES_EXPORT(TERMINAL *) @@ -55,10 +58,12 @@ NCURSES_EXPORT_VAR(TERMINAL *) cur_term = 0; NCURSES_EXPORT(TERMINAL *) set_curterm(TERMINAL * termp) { - TERMINAL *oldterm = cur_term; + TERMINAL *oldterm; T((T_CALLED("set_curterm(%p)"), termp)); + _nc_lock_global(curses); + oldterm = cur_term; if (SP) SP->_term = termp; #if USE_REENTRANT @@ -68,8 +73,11 @@ set_curterm(TERMINAL * termp) #endif if (termp != 0) { ospeed = _nc_ospeed(termp->_baudrate); - PC = (pad_char != NULL) ? pad_char[0] : 0; + if (termp->type.Strings) { + PC = (pad_char != NULL) ? pad_char[0] : 0; + } } + _nc_unlock_global(curses); T((T_RETURN("%p"), oldterm)); return (oldterm); @@ -78,15 +86,20 @@ set_curterm(TERMINAL * termp) NCURSES_EXPORT(int) del_curterm(TERMINAL * termp) { + int rc = ERR; + T((T_CALLED("del_curterm(%p)"), termp)); + _nc_lock_global(curses); if (termp != 0) { _nc_free_termtype(&(termp->type)); FreeIfNeeded(termp->_termname); free(termp); if (termp == cur_term) set_curterm(0); - returnCode(OK); + rc = OK; } - returnCode(ERR); + _nc_unlock_global(curses); + + returnCode(rc); } diff --git a/ncurses/tinfo/lib_data.c b/ncurses/tinfo/lib_data.c index ae8cd16e..f09ad226 100644 --- a/ncurses/tinfo/lib_data.c +++ b/ncurses/tinfo/lib_data.c @@ -41,7 +41,7 @@ #include -MODULE_ID("$Id: lib_data.c,v 1.47 2008/05/31 19:44:36 tom Exp $") +MODULE_ID("$Id: lib_data.c,v 1.48 2008/06/07 14:03:15 tom Exp $") /* * OS/2's native linker complains if we don't initialize public data when @@ -177,10 +177,7 @@ NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = { #endif /* TRACE */ #ifdef USE_PTHREADS - PTHREAD_MUTEX_INITIALIZER, /* mutex_set_SP */ - PTHREAD_MUTEX_INITIALIZER, /* mutex_use_screen */ - PTHREAD_MUTEX_INITIALIZER, /* mutex_use_window */ - PTHREAD_MUTEX_INITIALIZER, /* mutex_windowlist */ + PTHREAD_MUTEX_INITIALIZER, /* mutex_curses */ PTHREAD_MUTEX_INITIALIZER, /* mutex_tst_tracef */ PTHREAD_MUTEX_INITIALIZER, /* mutex_tracef */ 0, /* nested_tracef */ @@ -242,10 +239,7 @@ init_global_mutexes(void) if (!initialized) { initialized = TRUE; - _nc_mutex_init(&_nc_globals.mutex_set_SP); - _nc_mutex_init(&_nc_globals.mutex_use_screen); - _nc_mutex_init(&_nc_globals.mutex_use_window); - _nc_mutex_init(&_nc_globals.mutex_windowlist); + _nc_mutex_init(&_nc_globals.mutex_curses); _nc_mutex_init(&_nc_globals.mutex_tst_tracef); _nc_mutex_init(&_nc_globals.mutex_tracef); } diff --git a/ncurses/tinfo/lib_options.c b/ncurses/tinfo/lib_options.c index ae6b2c5b..c633d468 100644 --- a/ncurses/tinfo/lib_options.c +++ b/ncurses/tinfo/lib_options.c @@ -43,7 +43,7 @@ #include -MODULE_ID("$Id: lib_options.c,v 1.55 2008/05/25 00:32:17 tom Exp $") +MODULE_ID("$Id: lib_options.c,v 1.56 2008/06/07 14:01:46 tom Exp $") static int _nc_curs_set(SCREEN *, int); static int _nc_meta(SCREEN *, bool); @@ -249,12 +249,12 @@ _nc_keypad(SCREEN *sp, bool flag) SCREEN *save_sp; /* cannot use use_screen(), since that is not in tinfo library */ - _nc_lock_global(use_screen); + _nc_lock_global(curses); save_sp = SP; SP = sp; rc = _nc_keypad(sp, flag); SP = save_sp; - _nc_unlock_global(use_screen); + _nc_unlock_global(curses); } else #endif { diff --git a/ncurses/tinfo/lib_setup.c b/ncurses/tinfo/lib_setup.c index 21318eb0..0b104ab9 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.106 2008/05/17 21:35:36 tom Exp $") +MODULE_ID("$Id: lib_setup.c,v 1.107 2008/06/07 22:22:58 tom Exp $") /**************************************************************************** * @@ -566,20 +566,19 @@ _nc_setupterm(NCURSES_CONST char *tname, int Filedes, int *errret, bool reuse) ret_error(status, "'%s': unknown terminal type.\n", tname); } } +#if !USE_REENTRANT + strncpy(ttytype, term_ptr->type.term_names, NAMESIZE - 1); + ttytype[NAMESIZE - 1] = '\0'; +#endif + + term_ptr->Filedes = Filedes; + term_ptr->_termname = strdup(tname); set_curterm(term_ptr); if (command_character && getenv("CC")) do_prototype(); -#if !USE_REENTRANT - strncpy(ttytype, cur_term->type.term_names, NAMESIZE - 1); - ttytype[NAMESIZE - 1] = '\0'; -#endif - - cur_term->Filedes = Filedes; - cur_term->_termname = strdup(tname); - /* * If an application calls setupterm() rather than initscr() or * newterm(), we will not have the def_prog_mode() call in diff --git a/ncurses/tinfo/use_screen.c b/ncurses/tinfo/use_screen.c index a4f34c0e..6c3b12fb 100644 --- a/ncurses/tinfo/use_screen.c +++ b/ncurses/tinfo/use_screen.c @@ -32,7 +32,7 @@ #include -MODULE_ID("$Id: use_screen.c,v 1.4 2008/03/29 21:19:58 tom Exp $") +MODULE_ID("$Id: use_screen.c,v 1.6 2008/06/07 19:16:56 tom Exp $") NCURSES_EXPORT(int) use_screen(SCREEN *screen, NCURSES_SCREEN_CB func, void *data) @@ -46,15 +46,13 @@ use_screen(SCREEN *screen, NCURSES_SCREEN_CB func, void *data) * FIXME - add a flag so a given thread can check if _it_ has already * recurred through this point, return an error if so. */ - _nc_lock_global(use_screen); + _nc_lock_global(curses); save_SP = SP; set_term(screen); code = func(screen, data); set_term(save_SP); - _nc_unlock_global(use_screen); + _nc_unlock_global(curses); returnCode(code); - - return 0; } diff --git a/ncurses/trace/lib_trace.c b/ncurses/trace/lib_trace.c index 03acb16c..00a570e8 100644 --- a/ncurses/trace/lib_trace.c +++ b/ncurses/trace/lib_trace.c @@ -46,7 +46,7 @@ #include -MODULE_ID("$Id: lib_trace.c,v 1.66 2008/03/22 16:56:48 tom Exp $") +MODULE_ID("$Id: lib_trace.c,v 1.67 2008/06/07 20:49:56 tom Exp $") NCURSES_EXPORT_VAR(unsigned) _nc_tracing = 0; /* always define this */ @@ -292,9 +292,9 @@ _nc_use_tracef(unsigned mask) _nc_lock_global(tst_tracef); if (!_nc_globals.nested_tracef++) { - if ((result = (_nc_tracing & (mask))) != 0) { + if ((result = (_nc_tracing & (mask))) != 0 + && _nc_try_global(tracef) == 0) { /* we will call _nc_locked_tracef(), no nesting so far */ - _nc_lock_global(tracef); } else { /* we will not call _nc_locked_tracef() */ _nc_globals.nested_tracef = 0; diff --git a/ncurses/widechar/lib_get_wch.c b/ncurses/widechar/lib_get_wch.c index 7985df25..149d3bad 100644 --- a/ncurses/widechar/lib_get_wch.c +++ b/ncurses/widechar/lib_get_wch.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2002-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 2002-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 #include -MODULE_ID("$Id: lib_get_wch.c,v 1.14 2007/05/12 19:03:16 tom Exp $") +MODULE_ID("$Id: lib_get_wch.c,v 1.16 2008/06/07 15:14:33 tom Exp $") #if HAVE_MBTOWC && HAVE_MBLEN #define reset_mbytes(state) mblen(NULL, 0), mbtowc(NULL, NULL, 0) @@ -60,6 +60,7 @@ make an error NCURSES_EXPORT(int) wget_wch(WINDOW *win, wint_t *result) { + SCREEN *sp; int code; char buffer[(MB_LEN_MAX * 9) + 1]; /* allow some redundant shifts */ int status; @@ -76,44 +77,52 @@ wget_wch(WINDOW *win, wint_t *result) * We can get a stream of single-byte characters and KEY_xxx codes from * _nc_wgetch(), while we want to return a wide character or KEY_xxx code. */ - for (;;) { - T(("reading %d of %d", (int) count + 1, (int) sizeof(buffer))); - code = _nc_wgetch(win, &value, TRUE EVENTLIST_2nd((_nc_eventlist *) 0)); - if (code == ERR) { - break; - } else if (code == KEY_CODE_YES) { - /* - * If we were processing an incomplete multibyte character, return - * an error since we have a KEY_xxx code which interrupts it. For - * some cases, we could improve this by writing a new version of - * lib_getch.c(!), but it is not clear whether the improvement - * would be worth the effort. - */ - if (count != 0) { - ungetch((int) value); + _nc_lock_global(curses); + sp = _nc_screen_of(win); + if (sp != 0) { + for (;;) { + T(("reading %d of %d", (int) count + 1, (int) sizeof(buffer))); + code = _nc_wgetch(win, &value, TRUE EVENTLIST_2nd((_nc_eventlist + *) 0)); + if (code == ERR) { + break; + } else if (code == KEY_CODE_YES) { + /* + * If we were processing an incomplete multibyte character, + * return an error since we have a KEY_xxx code which + * interrupts it. For some cases, we could improve this by + * writing a new version of lib_getch.c(!), but it is not clear + * whether the improvement would be worth the effort. + */ + if (count != 0) { + _nc_ungetch(sp, (int) value); + code = ERR; + } + break; + } else if (count + 1 >= sizeof(buffer)) { + _nc_ungetch(sp, (int) value); code = ERR; - } - break; - } else if (count + 1 >= sizeof(buffer)) { - ungetch((int) value); - code = ERR; - break; - } else { - buffer[count++] = UChar(value); - reset_mbytes(state); - status = count_mbytes(buffer, count, state); - if (status >= 0) { + break; + } else { + buffer[count++] = UChar(value); reset_mbytes(state); - if (check_mbytes(wch, buffer, count, state) != status) { - code = ERR; /* the two calls should match */ - ungetch((int) value); + status = count_mbytes(buffer, count, state); + if (status >= 0) { + reset_mbytes(state); + if (check_mbytes(wch, buffer, count, state) != status) { + code = ERR; /* the two calls should match */ + _nc_ungetch(sp, (int) value); + } + value = wch; + break; } - value = wch; - break; } } + } else { + code = ERR; } *result = value; + _nc_unlock_global(curses); T(("result %#lo", value)); returnCode(code); } diff --git a/ncurses/widechar/lib_get_wstr.c b/ncurses/widechar/lib_get_wstr.c index bf39aa1a..513cd284 100644 --- a/ncurses/widechar/lib_get_wstr.c +++ b/ncurses/widechar/lib_get_wstr.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2002-2003,2004 Free Software Foundation, Inc. * + * Copyright (c) 2002-2004,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 #include -MODULE_ID("$Id: lib_get_wstr.c,v 1.8 2004/10/16 21:55:36 tom Exp $") +MODULE_ID("$Id: lib_get_wstr.c,v 1.9 2008/06/07 14:50:11 tom Exp $") static int wadd_wint(WINDOW *win, wint_t *src) @@ -86,6 +86,7 @@ WipeOut(WINDOW *win, int y, int x, wint_t *first, wint_t *last, bool echoed) NCURSES_EXPORT(int) wgetn_wstr(WINDOW *win, wint_t *str, int maxlen) { + SCREEN *sp = _nc_screen_of(win); TTY buf; bool oldnl, oldecho, oldraw, oldcbreak; wint_t erasec; @@ -102,10 +103,10 @@ wgetn_wstr(WINDOW *win, wint_t *str, int maxlen) _nc_get_tty_mode(&buf); - oldnl = SP->_nl; - oldecho = SP->_echo; - oldraw = SP->_raw; - oldcbreak = SP->_cbreak; + oldnl = sp->_nl; + oldecho = sp->_echo; + oldraw = sp->_raw; + oldcbreak = sp->_cbreak; nl(); noecho(); noraw(); @@ -209,10 +210,10 @@ wgetn_wstr(WINDOW *win, wint_t *str, int maxlen) /* Restore with a single I/O call, to fix minor asymmetry between * raw/noraw, etc. */ - SP->_nl = oldnl; - SP->_echo = oldecho; - SP->_raw = oldraw; - SP->_cbreak = oldcbreak; + sp->_nl = oldnl; + sp->_echo = oldecho; + sp->_raw = oldraw; + sp->_cbreak = oldcbreak; (void) _nc_set_tty_mode(&buf); diff --git a/ncurses/widechar/lib_unget_wch.c b/ncurses/widechar/lib_unget_wch.c index b2dc7ff9..bb2c4a08 100644 --- a/ncurses/widechar/lib_unget_wch.c +++ b/ncurses/widechar/lib_unget_wch.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2002-2004,2007 Free Software Foundation, Inc. * + * Copyright (c) 2002-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 * @@ -39,7 +39,7 @@ #include -MODULE_ID("$Id: lib_unget_wch.c,v 1.9 2007/11/25 00:57:00 tom Exp $") +MODULE_ID("$Id: lib_unget_wch.c,v 1.10 2008/06/07 14:50:37 tom Exp $") /* * Wrapper for wcrtomb() which obtains the length needed for the given @@ -86,7 +86,7 @@ unget_wch(const wchar_t wch) wcrtomb(string, wch, &state); for (n = (int) (length - 1); n >= 0; --n) { - if (ungetch(string[n]) != OK) { + if (_nc_ungetch(SP, string[n]) != OK) { result = ERR; break; } diff --git a/test/ditto.c b/test/ditto.c index 4873d0d9..06cdcc66 100644 --- a/test/ditto.c +++ b/test/ditto.c @@ -29,7 +29,7 @@ /* * Author: Thomas E. Dickey (1998-on) * - * $Id: ditto.c,v 1.26 2008/04/26 23:42:39 tom Exp $ + * $Id: ditto.c,v 1.28 2008/06/07 22:35:58 tom Exp $ * * The program illustrates how to set up multiple screens from a single * program. @@ -44,6 +44,11 @@ #include #include #include +#undef USE_PTHREADS + +#ifdef USE_PTHREADS +#include +#endif #ifdef USE_XTERM_PTY #include USE_OPENPTY_HEADER @@ -74,11 +79,15 @@ typedef struct { FILE *input; FILE *output; SCREEN *screen; /* this screen - curses internal data */ + int which1; /* this screen's index in DITTO[] array */ 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 */ +#ifdef USE_PTHREADS + pthread_t thread; +#endif } DITTO; /* @@ -185,7 +194,6 @@ init_screen(SCREEN *sp GCC_UNUSED, void *arg) cbreak(); noecho(); scrollok(stdscr, TRUE); - nodelay(stdscr, TRUE); box(stdscr, 0, 0); target->windows = typeCalloc(WINDOW *, target->length); @@ -202,8 +210,10 @@ init_screen(SCREEN *sp GCC_UNUSED, void *arg) wnoutrefresh(outer); scrollok(inner, TRUE); - nodelay(inner, TRUE); keypad(inner, TRUE); +#ifndef USE_PTHREADS + nodelay(inner, TRUE); +#endif target->windows[k] = inner; } @@ -211,16 +221,17 @@ init_screen(SCREEN *sp GCC_UNUSED, void *arg) } static void -open_screen(DITTO * target, char **source, int length, int which) +open_screen(DITTO * target, char **source, int length, int which1) { - if (which != 0) { + if (which1 != 0) { target->input = - target->output = open_tty(source[which]); + target->output = open_tty(source[which1]); } else { target->input = stdin; target->output = stdout; } + target->which1 = which1; target->titles = source; target->length = length; target->screen = newterm((char *) 0, /* assume $TERM is the same */ @@ -301,13 +312,33 @@ show_ditto(DITTO * data, int count, DDATA * ddata) } } +#ifdef USE_PTHREADS +static void * +handle_screen(void *arg) +{ + DDATA ddata; + int ch; + + ddata.ditto = (DITTO *) arg; + ddata.source = ddata.ditto->which1; + for (;;) { + ch = read_screen(ddata.ditto->screen, &ddata); + if (ch == CTRL('D')) + break; + show_ditto(ddata.ditto, ddata.ditto->length, &ddata); + } + return NULL; +} +#endif + int -main(int argc GCC_UNUSED, - char *argv[]GCC_UNUSED) +main(int argc, char *argv[]) { int j; - int count; DITTO *data; +#ifndef USE_PTHREADS + int count; +#endif if (argc <= 1) usage(); @@ -319,6 +350,16 @@ main(int argc GCC_UNUSED, open_screen(&data[j], argv, argc, j); } +#ifdef USE_PTHREADS + /* + * For multi-threaded operation, set up a reader for each of the screens. + * That uses blocking I/O rather than polling for input, so no calls to + * napms() are needed. + */ + for (j = 0; j < argc; j++) { + (void) pthread_create(&(data[j].thread), NULL, handle_screen, &data[j]); + } +#else /* * Loop, reading characters from any of the inputs and writing to all * of the screens. @@ -340,6 +381,7 @@ main(int argc GCC_UNUSED, show_ditto(data, argc, &ddata); } } +#endif /* * Cleanup and exit