]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/base/lib_getch.c
ncurses 5.7 - patch 20090214
[ncurses.git] / ncurses / base / lib_getch.c
index f77df69e77255f09ee64a1ee27e1890bd90c70f6..22173242852452310b403dc4166abfb5e69e4766 100644 (file)
@@ -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 <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                         2009                    *
  ****************************************************************************/
 
 /*
@@ -41,7 +42,7 @@
 
 #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.100 2009/02/15 00:36:00 tom Exp $")
 
 #include <fifo_defs.h>
 
@@ -54,27 +55,43 @@ NCURSES_PUBLIC_VAR(ESCDELAY) (void)
 }
 #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
@@ -249,21 +266,66 @@ 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 (_nc_use_pthreads && sp != SP) {
+       SCREEN *save_SP;
+
+       /* temporarily switch to the window's screen to check/refresh */
+       _nc_lock_global(curses);
+       save_SP = SP;
+       _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 != SP) {
+           SCREEN *save_SP;
+
+           /* temporarily switch to the window's screen to get cooked input */
+           _nc_lock_global(curses);
+           save_SP = SP;
+           _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;
@@ -272,12 +334,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 +366,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,9 +389,9 @@ _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 (win->_notimeout || (win->_delay >= 0) || (sp->_cbreak > 1)) {
        if (head == -1) {       /* fifo is empty */
            int delay;
            int rc;
@@ -355,8 +417,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 +542,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 +559,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;