-- 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
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
# 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
# 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)
#include <curses.priv.h>
-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)
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)
else if (curscr != 0)
touchwin(curscr);
- _nc_unlock_window(win);
result = _nc_freewin(win);
}
- _nc_unlock_global(windowlist);
+ _nc_unlock_global(curses);
}
returnCode(result);
}
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
}
#endif
if (SP != 0) {
- _nc_lock_global(windowlist);
+ _nc_lock_global(curses);
while (_nc_windows != 0) {
bool deleted = FALSE;
break;
}
delscreen(SP);
- _nc_unlock_global(windowlist);
+ _nc_unlock_global(curses);
}
if (cur_term != 0)
del_curterm(cur_term);
#include <curses.priv.h>
-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 <fifo_defs.h>
}
#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
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;
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);
}
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
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 */
returnCode(KEY_CODE_YES);
}
#endif
- if (!rc)
+ if (!rc) {
returnCode(ERR);
+ }
}
/* else go on to read data available */
}
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;
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;
#include <sys/termio.h> /* 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)
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;
def_prog_mode();
}
result = stdscr;
- _nc_unlock_global(set_SP);
+ _nc_unlock_global(curses);
returnWin(result);
}
#include <term.h> /* clear_screen, cup & friends, cur_term */
#include <tic.h>
-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
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;
result = SP;
}
}
- _nc_unlock_global(set_SP);
+ _nc_unlock_global(curses);
returnSP(result);
}
#include <curses.priv.h>
#include <stddef.h>
-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)
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) {
}
q = p;
}
- _nc_unlock_global(windowlist);
+ _nc_unlock_global(curses);
}
}
returnCode(result);
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) {
returnWin(0);
}
- _nc_lock_global(windowlist);
+ _nc_lock_global(curses);
win->_curx = 0;
win->_cury = 0;
T((T_CREATE("window %p"), win));
- _nc_unlock_global(windowlist);
+ _nc_unlock_global(curses);
returnWin(win);
}
/****************************************************************************
- * 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 *
#include <curses.priv.h>
-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)
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,
dmaxrow, dmaxcol,
flag);
}
- _nc_unlock_window(dst);
- _nc_unlock_window(src);
+ _nc_unlock_global(curses);
}
returnCode(rc);
}
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);
rc = OK;
}
}
- _nc_unlock_window(dst);
- _nc_unlock_window(src);
+ _nc_unlock_global(curses);
}
returnCode(rc);
}
#include <term.h> /* cur_term */
#include <tic.h>
-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);
#endif
}
- _nc_unlock_global(set_SP);
+ _nc_unlock_global(curses);
T((T_RETURN("%p"), oldSP));
return (oldSP);
T((T_CALLED("delscreen(%p)"), sp));
- _nc_lock_global(set_SP);
+ _nc_lock_global(curses);
if (delink_screen(sp)) {
(void) _nc_freewin(sp->_curscr);
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
_nc_set_screen(0);
}
}
- _nc_unlock_global(set_SP);
+ _nc_unlock_global(curses);
returnVoid;
}
#include <curses.priv.h>
-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)
if (win != 0) {
- _nc_lock_window(win);
+ _nc_lock_global(curses);
if (win->_flags & _ISPAD) {
nwin = newpad(win->_maxy + 1,
win->_maxx + 1);
nwin->_line[i].lastchar = win->_line[i].lastchar;
}
}
- _nc_unlock_window(win);
+ _nc_unlock_global(curses);
}
returnWin(nwin);
}
#include <curses.priv.h>
#include <term.h>
-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)
{
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)) {
(long) wp->win._begy,
(long) wp->win._begx);
}
- _nc_unlock_global(windowlist);
+ _nc_unlock_global(curses);
}
#endif
returnCode(ERR);
}
- _nc_lock_global(windowlist);
+ _nc_lock_global(curses);
was_stolen = (screen_lines - SP->_lines_avail);
if (is_term_resized(ToLines, ToCols)) {
SET_LINES(ToLines - was_stolen);
SET_COLS(ToCols);
- _nc_unlock_global(windowlist);
+ _nc_unlock_global(curses);
returnCode(result);
}
#include <curses.priv.h>
-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)
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);
}
#include <curses.priv.h>
-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)
struct ldat *pline = cmp->_line;
int row;
- _nc_lock_global(windowlist);
+ _nc_lock_global(curses);
for (each_window(wp)) {
WINDOW *tst = &(wp->win);
repair_subwindows(tst);
}
}
- _nc_unlock_global(windowlist);
+ _nc_unlock_global(curses);
}
/*
/*
- * $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
*
#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
#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
#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;
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)
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
/* ./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,
int flags)
{ return(*(WINDOW **)0); }
+#undef _nc_screen_of
+SCREEN *_nc_screen_of(
+ WINDOW *win)
+ { return(*(SCREEN **)0); }
+
/* ./base/lib_nl.c */
#undef nl
/* ./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)
/* ./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)
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 {
#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); }
#endif
#undef _nc_init_keytry
-void _nc_init_keytry(void)
+void _nc_init_keytry(
+ SCREEN *sp)
{ /* void */ }
/* ./tinfo/lib_acs.c */
/* ./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(
#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)
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)
/* ./tinfo/lib_napms.c */
-#include <time.h>
-
#undef napms
int napms(
int ms)
#undef _nc_keypad
int _nc_keypad(
+ SCREEN *sp,
NCURSES_BOOL flag)
{ return(*(int *)0); }
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); }
#undef _nc_handle_sigwinch
int _nc_handle_sigwinch(
- int update)
+ SCREEN *sp)
{ return(*(int *)0); }
#undef 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
/* ./trace/lib_tracechr.c */
+#undef _nc_tracechar
+char *_nc_tracechar(
+ SCREEN *sp,
+ int ch)
+ { return(*(char **)0); }
+
#undef _tracechar
char *_tracechar(
int ch)
/* ./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 */
/* ./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 */
#include <term_entry.h> /* TTY, cur_term */
#include <termcap.h> /* 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 *)
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
#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);
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);
}
#include <curses.priv.h>
-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
#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 */
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);
}
#include <term.h>
-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);
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
{
#include <term.h> /* 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 $")
/****************************************************************************
*
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
#include <curses.priv.h>
-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)
* 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;
}
#include <ctype.h>
-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 */
_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;
/****************************************************************************
- * 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 *
#include <curses.priv.h>
#include <ctype.h>
-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)
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;
* 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);
}
/****************************************************************************
- * 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 *
#include <curses.priv.h>
#include <term.h>
-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)
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;
_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();
/* 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);
/****************************************************************************
- * 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 *
#include <curses.priv.h>
-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
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;
}
/*
* 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.
#include <test.priv.h>
#include <sys/stat.h>
#include <errno.h>
+#undef USE_PTHREADS
+
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif
#ifdef USE_XTERM_PTY
#include USE_OPENPTY_HEADER
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;
/*
cbreak();
noecho();
scrollok(stdscr, TRUE);
- nodelay(stdscr, TRUE);
box(stdscr, 0, 0);
target->windows = typeCalloc(WINDOW *, target->length);
wnoutrefresh(outer);
scrollok(inner, TRUE);
- nodelay(inner, TRUE);
keypad(inner, TRUE);
+#ifndef USE_PTHREADS
+ nodelay(inner, TRUE);
+#endif
target->windows[k] = inner;
}
}
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 */
}
}
+#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();
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.
show_ditto(data, argc, &ddata);
}
}
+#endif
/*
* Cleanup and exit