/****************************************************************************
- * 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 *
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
* and: Thomas E. Dickey 1996-on *
+ * and: Juergen Pfeifer 2009 *
****************************************************************************/
/*
#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.102 2009/04/18 20:32:33 tom Exp $")
#include <fifo_defs.h>
}
#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
/*
&& (sp->_sysmouse_head < sp->_sysmouse_tail)
&& (rc == 0)
&& (errno == EINTR)) {
- rc |= 2;
+ rc |= TW_MOUSE;
}
#endif
return rc;
} 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
#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;
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 (_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,
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 (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 */
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 (win->_notimeout || (win->_delay >= 0) || (sp->_cbreak > 1)) {
if (head == -1) { /* fifo is empty */
int delay;
int rc;
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 */
}
* increase the wait with mouseinterval().
*/
int runcount = 0;
- int rc;
+ int rc = 0;
do {
ch = kgetch(sp EVENTLIST_2nd(evl));
(ch == KEY_MOUSE
&& (((rc = check_mouse_activity(sp, sp->_maxclick
EVENTLIST_2nd(evl))) != 0
- && !(rc & 4))
+ && !(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
#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;
}
}
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;
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 */