diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | Doc/Zsh/mod_curses.yo | 14 | ||||
-rw-r--r-- | Src/Modules/curses.c | 65 |
3 files changed, 69 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog index 0f87e6378..354025af4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2007-10-17 Peter Stephenson <pws@csr.com> + + * 23970 (slightly modified): Doc/Zsh/mod_curses.yo, + Src/Modules/curses.c: fix up deletion of curses windows and add + zcurses -i/-e for initialisation and end to retain terminal + sanity; make "zcurses -r" do a global refresh. + + * Vin Shelton: 23968: Doc/Zsh/mod_curses.yo: overabundance of + enditem(). + 2007-10-15 Clint Adams <clint@zsh.org> * 23965: Completion/Unix/Command/_git: add missing bracket in diff --git a/Doc/Zsh/mod_curses.yo b/Doc/Zsh/mod_curses.yo index 386074cd9..f2b442e98 100644 --- a/Doc/Zsh/mod_curses.yo +++ b/Doc/Zsh/mod_curses.yo @@ -6,14 +6,19 @@ The tt(zsh/curses) module makes available one builtin command: 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) ) +xitem(tt(zcurses) tt(-r) [ var(targetwin) ] ) xitem(tt(zcurses) tt(-m) var(targetwin) var(new_y) var(new_x) ) 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 @@ -24,7 +29,8 @@ Use tt(-d) to delete a window created with tt(-a). The tt(-r) command will refresh window var(targetwin); this is necessary to make any pending changes (such as characters you have prepared for output -with tt(-c)) visible on the screen. +with tt(-c)) visible on the screen. If no argument is given, +all windows are refreshed; this is necessary after deleting a window. tt(-m) moves the cursor position in var(targetwin) to new coordinates var(new_y) and var(new_x). @@ -35,5 +41,3 @@ respectively. To draw a border around window var(targetwin), use tt(-b). ) enditem() - -enditem() diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c index fa1ea8b3b..3edd23c22 100644 --- a/Src/Modules/curses.c +++ b/Src/Modules/curses.c @@ -44,8 +44,10 @@ typedef struct zc_win { 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 @@ zcurses_free_window(ZCWin w) 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,24 +193,31 @@ bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func)) if (w->name) zsfree(w->name); - remnode(zcurses_windows, node); + zfree((ZCWin)remnode(zcurses_windows, node), sizeof(struct zc_win)); return 0; } if (OPT_ISSET(ops,'r')) { - LinkNode node; - ZCWin w; + if (args[0]) { + LinkNode node; + ZCWin w; - node = zcurses_validate_window(OPT_ARG(ops,'r'), ZCURSES_USED); - if (node == NULL) { - zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), OPT_ARG(ops,'r'), 0); - return 1; - } + node = zcurses_validate_window(args[0], ZCURSES_USED); + if (node == NULL) { + zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], + 0); + return 1; + } - w = (ZCWin)getdata(node); + w = (ZCWin)getdata(node); - return (wrefresh(w->win)!=OK) ? 1 : 0; + return (wrefresh(w->win)!=OK) ? 1 : 0; + } + else + { + return (refresh() != OK) ? 1 : 0; + } } if (OPT_ISSET(ops,'m')) { @@ -325,6 +346,22 @@ bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func)) 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 +370,7 @@ bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func)) */ 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:eimrs", NULL), }; static struct features module_features = { @@ -371,7 +408,6 @@ int boot_(Module m) { zcurses_windows = znewlinklist(); - win_zero=initscr(); return 0; } @@ -380,7 +416,6 @@ boot_(Module m) int cleanup_(Module m) { - endwin(); freelinklist(zcurses_windows, (FreeFunc) zcurses_free_window); return setfeatureenables(m, &module_features, NULL); } |