X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fbase%2Flib_getch.c;h=e228355a019ea38a9bd1aaac92a471a0698ff4f9;hp=d9f6b1795c77d83b7579db9a01026b06b40f858f;hb=26522e4669dbf45cba32138b5d81c6c292e88e60;hpb=ed530db2c5b10aa19d06104dfe82cf248a813860 diff --git a/ncurses/base/lib_getch.c b/ncurses/base/lib_getch.c index d9f6b179..e228355a 100644 --- a/ncurses/base/lib_getch.c +++ b/ncurses/base/lib_getch.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * + * Copyright (c) 1998-2008,2009 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 * @@ -30,6 +30,7 @@ * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * * and: Thomas E. Dickey 1996-on * + * and: Juergen Pfeifer 2009 * ****************************************************************************/ /* @@ -41,45 +42,66 @@ #include -MODULE_ID("$Id: lib_getch.c,v 1.87 2008/05/03 22:42:10 tom Exp $") +MODULE_ID("$Id: lib_getch.c,v 1.103 2009/05/30 15:50:47 tom Exp $") #include #if USE_REENTRANT #define GetEscdelay(sp) (sp)->_ESCDELAY +NCURSES_EXPORT(int *) +_nc_ptr_Escdelay(SCREEN *sp) +{ + return ptrEscdelay(sp); +} NCURSES_EXPORT(int) NCURSES_PUBLIC_VAR(ESCDELAY) (void) { - return SP ? GetEscdelay(SP) : 1000; + return *_nc_ptr_Escdelay(CURRENT_SCREEN); } #else #define GetEscdelay(sp) ESCDELAY -NCURSES_EXPORT_VAR(int) -ESCDELAY = 1000; /* max interval betw. chars in funkeys, in millisecs */ +NCURSES_EXPORT_VAR (int) + ESCDELAY = 1000; /* max interval betw. chars in funkeys, in millisecs */ #endif #if NCURSES_EXT_FUNCS NCURSES_EXPORT(int) -set_escdelay(int value) +NCURSES_SP_NAME(set_escdelay) (NCURSES_SP_DCLx int value) { int code = OK; #if USE_REENTRANT - if (SP) { - SP->_ESCDELAY = value; + if (SP_PARM) { + SP_PARM->_ESCDELAY = value; } else { code = ERR; } #else + (void) SP_PARM; ESCDELAY = value; #endif return code; } + +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(int) +set_escdelay(int value) +{ + return NCURSES_SP_NAME(set_escdelay) (CURRENT_SCREEN, value); +} #endif +#endif /* NCURSES_EXT_FUNCS */ + +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 +#define TWAIT_MASK (TW_ANY | TW_EVENT) #else -#define TWAIT_MASK 3 +#define TWAIT_MASK TW_ANY #endif /* @@ -102,7 +124,7 @@ check_mouse_activity(SCREEN *sp, int delay EVENTLIST_2nd(_nc_eventlist * evl)) && (sp->_sysmouse_head < sp->_sysmouse_tail) && (rc == 0) && (errno == EINTR)) { - rc |= 2; + rc |= TW_MOUSE; } #endif return rc; @@ -123,7 +145,7 @@ fifo_pull(SCREEN *sp) { int ch; ch = sp->_fifo[head]; - TR(TRACE_IEVENT, ("pulling %s from %d", _tracechar(ch), head)); + TR(TRACE_IEVENT, ("pulling %s from %d", _nc_tracechar(sp, ch), head)); if (peek == head) { h_inc(); @@ -166,9 +188,9 @@ fifo_push(SCREEN *sp EVENTLIST_2nd(_nc_eventlist * evl)) } else mask = 0; - if (mask & 4) { + if (mask & TW_EVENT) { T(("fifo_push: ungetch KEY_EVENT")); - _nc_ungetch(sp, KEY_EVENT); + safe_ungetch(sp, KEY_EVENT); return KEY_EVENT; } #elif USE_GPM_SUPPORT || USE_EMX_MOUSE || USE_SYSMOUSE @@ -178,7 +200,7 @@ fifo_push(SCREEN *sp EVENTLIST_2nd(_nc_eventlist * evl)) #endif #if USE_GPM_SUPPORT || USE_EMX_MOUSE - if ((sp->_mouse_fd >= 0) && (mask & 2)) { + if ((sp->_mouse_fd >= 0) && (mask & TW_MOUSE)) { sp->_mouse_event(sp); ch = KEY_MOUSE; n = 1; @@ -228,7 +250,7 @@ fifo_push(SCREEN *sp EVENTLIST_2nd(_nc_eventlist * evl)) if (head == -1) head = peek = tail; t_inc(); - TR(TRACE_IEVENT, ("pushed %s at %d", _tracechar(ch), tail)); + TR(TRACE_IEVENT, ("pushed %s at %d", _nc_tracechar(sp, ch), tail)); #ifdef TRACE if (USE_TRACEF(TRACE_IEVENT)) { _nc_fifo_dump(sp); @@ -248,9 +270,59 @@ fifo_clear(SCREEN *sp) static int kgetch(SCREEN *EVENTLIST_2nd(_nc_eventlist * evl)); -#define wgetch_should_refresh(win) (\ - (is_wintouched(win) || (win->_flags & _HASMOVED)) \ - && !(win->_flags & _ISPAD)) +static void +recur_wrefresh(WINDOW *win) +{ +#ifdef USE_PTHREADS + SCREEN *sp = _nc_screen_of(win); + if (_nc_use_pthreads && sp != CURRENT_SCREEN) { + SCREEN *save_SP; + + /* temporarily switch to the window's screen to check/refresh */ + _nc_lock_global(curses); + save_SP = CURRENT_SCREEN; + _nc_set_screen(sp); + recur_wrefresh(win); + _nc_set_screen(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; + + if (sp != 0) { +#ifdef USE_PTHREADS + if (_nc_use_pthreads && sp != CURRENT_SCREEN) { + SCREEN *save_SP; + + /* temporarily switch to the window's screen to get cooked input */ + _nc_lock_global(curses); + save_SP = CURRENT_SCREEN; + _nc_set_screen(sp); + rc = recur_wgetnstr(win, buf); + _nc_set_screen(save_SP); + _nc_unlock_global(curses); + } else +#endif + { + sp->_called_wgetch = TRUE; + rc = wgetnstr(win, buf, MAXCOLUMNS); + sp->_called_wgetch = FALSE; + } + } else { + rc = ERR; + } + return rc; +} NCURSES_EXPORT(int) _nc_wgetch(WINDOW *win, @@ -258,7 +330,7 @@ _nc_wgetch(WINDOW *win, int use_meta EVENTLIST_2nd(_nc_eventlist * evl)) { - SCREEN *sp = SP; + SCREEN *sp; int ch; #ifdef NCURSES_WGETCH_EVENTS long event_delay = -1; @@ -267,14 +339,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()) { - if (wgetch_should_refresh(win)) - wrefresh(win); - + recur_wrefresh(win); *result = fifo_pull(sp); returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK); } @@ -299,17 +371,15 @@ _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 if (rc != KEY_EVENT) #endif - _nc_ungetch(sp, '\n'); + safe_ungetch(sp, '\n'); for (bufp = buf + strlen(buf); bufp > buf; bufp--) - _nc_ungetch(sp, bufp[-1]); + safe_ungetch(sp, bufp[-1]); #ifdef NCURSES_WGETCH_EVENTS /* Return it first */ @@ -324,10 +394,9 @@ _nc_wgetch(WINDOW *win, if (win->_use_keypad != sp->_keypad_on) _nc_keypad(sp, win->_use_keypad); - if (wgetch_should_refresh(win)) - wrefresh(win); + recur_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; @@ -348,13 +417,14 @@ _nc_wgetch(WINDOW *win, rc = check_mouse_activity(sp, delay EVENTLIST_2nd(evl)); #ifdef NCURSES_WGETCH_EVENTS - if (rc & 4) { + if (rc & TW_EVENT) { *result = KEY_EVENT; returnCode(KEY_CODE_YES); } #endif - if (!rc) + if (!rc) { returnCode(ERR); + } } /* else go on to read data available */ } @@ -372,7 +442,7 @@ _nc_wgetch(WINDOW *win, * increase the wait with mouseinterval(). */ int runcount = 0; - int rc; + int rc = 0; do { ch = kgetch(sp EVENTLIST_2nd(evl)); @@ -387,11 +457,11 @@ _nc_wgetch(WINDOW *win, (ch == KEY_MOUSE && (((rc = check_mouse_activity(sp, sp->_maxclick EVENTLIST_2nd(evl))) != 0 - && !(rc & 4)) - || !sp->_mouse_parse(runcount))); + && !(rc & TW_EVENT)) + || !sp->_mouse_parse(sp, runcount))); #ifdef NCURSES_WGETCH_EVENTS - if ((rc & 4) && !ch == KEY_EVENT) { - _nc_ungetch(sp, ch); + if ((rc & TW_EVENT) && !(ch == KEY_EVENT)) { + safe_ungetch(sp, ch); ch = KEY_EVENT; } #endif @@ -399,12 +469,12 @@ _nc_wgetch(WINDOW *win, #ifdef NCURSES_WGETCH_EVENTS /* mouse event sequence ended by an event, report event */ if (ch == KEY_EVENT) { - _nc_ungetch(sp, KEY_MOUSE); /* FIXME This interrupts a gesture... */ + safe_ungetch(sp, KEY_MOUSE); /* FIXME This interrupts a gesture... */ } else #endif { /* mouse event sequence ended by keystroke, store keystroke */ - _nc_ungetch(sp, ch); + safe_ungetch(sp, ch); ch = KEY_MOUSE; } } @@ -467,7 +537,7 @@ _nc_wgetch(WINDOW *win, if ((ch < KEY_MIN) && (ch & 0x80)) ch &= 0x7f; - T(("wgetch returning : %s", _tracechar(ch))); + T(("wgetch returning : %s", _nc_tracechar(sp, ch))); *result = ch; returnCode(ch >= KEY_MIN ? KEY_CODE_YES : OK); @@ -477,14 +547,13 @@ _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 + _nc_use_meta(win) EVENTLIST_2nd(evl)); if (code != ERR) code = value; @@ -495,14 +564,13 @@ 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) + _nc_use_meta(win) EVENTLIST_2nd((_nc_eventlist *) 0)); if (code != ERR) code = value; @@ -564,7 +632,7 @@ kgetch(SCREEN *sp EVENTLIST_2nd(_nc_eventlist * evl)) return ch; } - TR(TRACE_IEVENT, ("ch: %s", _tracechar((unsigned char) ch))); + TR(TRACE_IEVENT, ("ch: %s", _nc_tracechar(sp, (unsigned char) ch))); while ((ptr != NULL) && (ptr->ch != (unsigned char) ch)) ptr = ptr->sibling; @@ -592,7 +660,7 @@ kgetch(SCREEN *sp EVENTLIST_2nd(_nc_eventlist * evl)) TR(TRACE_IEVENT, ("waiting for rest of sequence")); rc = check_mouse_activity(sp, timeleft EVENTLIST_2nd(evl)); #ifdef NCURSES_WGETCH_EVENTS - if (rc & 4) { + if (rc & TW_EVENT) { TR(TRACE_IEVENT, ("interrupted by a user event")); /* FIXME Should have preserved remainder timeleft for reuse... */ peek = head; /* Restart interpreting later */