Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: curses tweaks, maybe



On Tue, 16 Oct 2007 23:29:55 -0400
Clint Adams <clint@xxxxxxx> wrote:
> I think we should provide refresh() as zcurses -R.

That's easy.

> Apparently (at least
> according to http://invisible-island.net/ncurses/ncurses-intro.html ;
> I've not tried it) we can do an endwin() with zcurses -e, mess around with
> normal shell output, then redraw with refresh() and resume where we've
> left off.

Presumably that means we still need -i and -e to swap the terminal
settings, but it should save the values from curses mode, too, as below.
However, this didn't work for me:  the window didn't get redrawn.  Do we
need initscr() again, or something else?

The previous test script, which still works, is now

  zmodload zsh/curses

  integer win=6

  zcurses -i

  zcurses -a $win 10 10 10 10
  zcurses -b $win
  zcurses -m $win 1 1
  zcurses -c $win B
  zcurses -c $win l
  zcurses -c $win a
  zcurses -c $win h
  zcurses -r $win
  sleep 5
  zcurses -d $win
  zcurses -R

  zcurses -e

> I think I just read somewhere (though I can't find it now) that nl() is
> the default and that nonl() provides speed benefits if you don't need
> the translation.  Maybe we should unconditionally run nonl() after
> initscr(), since we don't support (yet?) any curses input functionality
> and anyone passing a literal newline to zcurses -s (does this work for
> you either?) can probably be bothered to pass a CR too.

That's probably fine, but I don't suppose it matters all that much.  I
haven't got around to zcurses -s yet.

I haven't changed anything else from the previous version of the patch, but
obviously many further enhancements are possible.

Index: Doc/Zsh/mod_curses.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/mod_curses.yo,v
retrieving revision 1.4
diff -u -r1.4 mod_curses.yo
--- Doc/Zsh/mod_curses.yo	15 Oct 2007 16:49:50 -0000	1.4
+++ Doc/Zsh/mod_curses.yo	17 Oct 2007 08:37:02 -0000
@@ -6,6 +6,8 @@
 startitem()
 findex(zcurses)
 cindex(windows, curses)
+xitem(tt(zcurses) tt(-i))
+xitem(tt(zcurses) tt(-e))
 xitem(tt(zcurses) tt(-a) var(targetwin) var(nlines) var(ncols) var(begin_y) var(begin_x) )
 xitem(tt(zcurses) tt(-d) var(targetwin) )
 xitem(tt(zcurses) tt(-r) var(targetwin) )
@@ -13,7 +15,10 @@
 xitem(tt(zcurses) tt(-c) var(targetwin) var(character) )
 xitem(tt(zcurses) tt(-s) var(targetwin) var(string) )
 item(tt(zcurses) tt(-b) var(targetwin) var(border) )(
-Manipulate curses windows.
+Manipulate curses windows.  All uses of this command should be
+bracketed by `tt(zcurses -i)' to initialise use of curses, and
+`tt(zcurses -e)' to end it; omitting `tt(zcurses -e)' can cause
+the terminal to be in an unwanted state.

 With tt(-a), create a window with var(nlines) lines and var(ncols) columns.
 Its upper left corner will be placed at row var(begin_y) and column
Index: Src/Modules/curses.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/curses.c,v
retrieving revision 1.8
diff -u -r1.8 curses.c
--- Src/Modules/curses.c	15 Oct 2007 16:57:48 -0000	1.8
+++ Src/Modules/curses.c	17 Oct 2007 08:37:02 -0000
@@ -44,8 +44,10 @@
     char *name;
 } *ZCWin;

-WINDOW *win_zero;
-LinkList zcurses_windows;
+static WINDOW *win_zero;
+static struct ttyinfo saved_tty_state;
+static struct ttyinfo curses_tty_state;
+static LinkList zcurses_windows;

 #define ZCURSES_ERANGE 1
 #define ZCURSES_EDEFINED 2
@@ -125,6 +127,18 @@
 static int
 bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func))
 {
+    /* Initialise curses */
+    if (OPT_ISSET(ops,'i')) {
+	if (!win_zero) {
+	    gettyinfo(&saved_tty_state);
+	    win_zero = initscr();
+	    gettyinfo(&curses_tty_state);
+	} else {
+	    settyinfo(&curses_tty_state);
+	}
+	return 0;
+    }
+
     if (OPT_ISSET(ops,'a')) {
 	int nlines, ncols, begin_y, begin_x;
         ZCWin w;
@@ -179,7 +193,7 @@
 	if (w->name)
 	    zsfree(w->name);

-        remnode(zcurses_windows, node);
+        zfree((ZCWin)remnode(zcurses_windows, node), sizeof(struct zc_win));

 	return 0;
     }
@@ -199,6 +213,11 @@
 	return (wrefresh(w->win)!=OK) ? 1 : 0;
     }

+    if (OPT_ISSET(ops,'R')) {
+	refresh();
+	return 0;
+    }
+
     if (OPT_ISSET(ops,'m')) {
 	int y, x;
 	LinkNode node;
@@ -325,6 +344,22 @@
 	return 0;
     }

+    /* Finish using curses */
+    if (OPT_ISSET(ops,'e')) {
+	if (win_zero) {
+	    endwin();
+	    /* Restore TTY as it was before zcurses -i */
+	    settyinfo(&saved_tty_state);
+	    /*
+	     * TODO: should I need the following?  Without it
+	     * the screen stays messed up.  Presumably we are
+	     * doing stuff with shttyinfo when we shouldn't really be.
+	     */
+	    gettyinfo(&shttyinfo);
+	}
+	return 0;
+    }
+
     return 0;
 }

@@ -333,7 +368,7 @@
  */

 static struct builtin bintab[] = {
-    BUILTIN("zcurses", 0, bin_zcurses, 0, 5, 0, "ab:cd:mr:rs", NULL),
+    BUILTIN("zcurses", 0, bin_zcurses, 0, 5, 0, "ab:cd:eimr:Rs", NULL),
 };

 static struct features module_features = {
@@ -371,7 +406,6 @@
 boot_(Module m)
 {
     zcurses_windows = znewlinklist();
-    win_zero=initscr();

     return 0;
 }
@@ -380,7 +414,6 @@
 int
 cleanup_(Module m)
 {
-    endwin();
     freelinklist(zcurses_windows, (FreeFunc) zcurses_free_window);
     return setfeatureenables(m, &module_features, NULL);
 }


--
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



Messages sorted by: Reverse Date, Date, Thread, Author