summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--Doc/Zsh/mod_curses.yo14
-rw-r--r--Src/Modules/curses.c65
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);
}