* PATCH: curses tweaks, maybe @ 2007-10-16 8:40 Peter Stephenson 2007-10-17 3:29 ` Clint Adams 0 siblings, 1 reply; 18+ messages in thread From: Peter Stephenson @ 2007-10-16 8:40 UTC (permalink / raw) To: Zsh Hackers' List I had a short play with zcurses. Well, it started off as a short play. By the way, I have ncurses-devel-5.6-6.20070303.fc7 ncurses-5.6-6.20070303.fc7 We need to free up the linked list data element after use, on zcurses -d. Also, a refresh() is needed after deleting a window, otherwise nothing works when you add a new one. It's not clear where this should be, however. If the intent is that the user can stack up commands before refreshing we would need that as a user command, but we might well need to ensure that it got called anyway before things got too hopefully messed up (e.g. it would probably need to be called just before, or presumably in place of, a wrefresh() for a new window). So this will do for now. Also, something very screwy was happening with stty onlcr on my terminal, which keeps being turned off when running the updated test function, curses_test() { zmodload zsh/curses 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 } I think I've tracked it down to this: if zsh/curses gets loaded here, onclr is turned off; if zsh/curses was already loaded then it's OK. Presumably the difference is that from the command line zsh is doing it's sanity checks (but I don't quite understand why they don't happen after the above). This is from initscr(). The functions nonl() / nl() seem to control this in curses, but they docs suggest the setting isn't changed automatically, which seems to be wrong. Perhaps to be safe we should be requiring all use of curses to be between commands such as zcurses -i and zcurses -e, as below? After all, it's reasonable to suppose this doesn't fit in with normal shell line-by-line character handling. This fixes Bart's gripe about clearing the screen. Even with this code I only got it to work by both saving the terminal state from before zcurses -i, and when I restore it on zcurses -e ensuring that shttyinfo is the same---this seems a bit hairy. (I had a panic attack that shttyinfo.winsize would be screwed up, too, but settyinfo() doesn't alter that.) The test now becomes: curses_test() { zmodload zsh/curses 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 -e } This seemed to work. Probably zcurses -e, if it stays, should do more work, such as deleting any remaining windows. (That could fix up the refresh() issue mentioned at the top in the case where we delete all windows.) zcurses -i could be implicit, but it's nice to be clear. Maybe it should return an error if win_zero is already set, or allow nested -i/-e pairs, or something. I'm not sure how convinced I am by all of this. 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 15 Oct 2007 18:28:15 -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 15 Oct 2007 18:28:15 -0000 @@ -44,8 +44,9 @@ char *name; } *ZCWin; -WINDOW *win_zero; -LinkList zcurses_windows; +static WINDOW *win_zero; +static struct ttyinfo saved_tty_state; +static LinkList zcurses_windows; #define ZCURSES_ERANGE 1 #define ZCURSES_EDEFINED 2 @@ -125,6 +126,15 @@ 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(); + } + return 0; + } + if (OPT_ISSET(ops,'a')) { int nlines, ncols, begin_y, begin_x; ZCWin w; @@ -179,7 +189,8 @@ if (w->name) zsfree(w->name); - remnode(zcurses_windows, node); + zfree((ZCWin)remnode(zcurses_windows, node), sizeof(struct zc_win)); + refresh(); return 0; } @@ -325,6 +336,24 @@ return 0; } + /* Finish using curses */ + if (OPT_ISSET(ops,'e')) { + if (win_zero) { + endwin(); + /* TODO: do we free win_zero? Manual doesn't say. */ + win_zero = NULL; + /* 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 +362,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 +400,6 @@ boot_(Module m) { zcurses_windows = znewlinklist(); - win_zero=initscr(); return 0; } @@ -380,7 +408,6 @@ int cleanup_(Module m) { - endwin(); freelinklist(zcurses_windows, (FreeFunc) zcurses_free_window); return setfeatureenables(m, &module_features, NULL); } -- Peter Stephenson <pws@csr.com> Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-16 8:40 PATCH: curses tweaks, maybe Peter Stephenson @ 2007-10-17 3:29 ` Clint Adams 2007-10-17 8:57 ` Peter Stephenson 0 siblings, 1 reply; 18+ messages in thread From: Clint Adams @ 2007-10-17 3:29 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh Hackers' List On Tue, Oct 16, 2007 at 09:40:40AM +0100, Peter Stephenson wrote: > Also, a refresh() is needed after deleting a window, otherwise nothing > works when you add a new one. It's not clear where this should be, > however. If the intent is that the user can stack up commands before > refreshing we would need that as a user command, but we might well > need to ensure that it got called anyway before things got too hopefully > messed up (e.g. it would probably need to be called just before, or > presumably in place of, a wrefresh() for a new window). So this will do > for now. I think we should provide refresh() as zcurses -R. 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. > I think I've tracked it down to this: if zsh/curses gets loaded here, > onclr is turned off; if zsh/curses was already loaded then it's OK. > Presumably the difference is that from the command line zsh is doing it's > sanity checks (but I don't quite understand why they don't happen after the > above). This is from initscr(). The functions nonl() / nl() seem to > control this in curses, but they docs suggest the setting isn't changed > automatically, which seems to be wrong. 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. > Perhaps to be safe we should be requiring all use of curses to be between > commands such as zcurses -i and zcurses -e, as below? After all, it's > reasonable to suppose this doesn't fit in with normal shell line-by-line > character handling. This fixes Bart's gripe about clearing the screen. We could; maybe they could take arguments and initialize/delete multiple terminals/screens if we want to support that as well (and skip initscr() altogether). > Even with this code I only got it to work by both saving the terminal state > from before zcurses -i, and when I restore it on zcurses -e ensuring that > shttyinfo is the same---this seems a bit hairy. (I had a panic attack that > shttyinfo.winsize would be screwed up, too, but > settyinfo() doesn't alter that.) I wonder why this is necessary. > This seemed to work. Probably zcurses -e, if it stays, should do more > work, such as deleting any remaining windows. (That could fix up the > refresh() issue mentioned at the top in the case where we delete all > windows.) Maybe zcurses -d with no arguments could delete all, or we could have a separate endwin()-only command for use in the endwin()/refresh() trick described up top. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 3:29 ` Clint Adams @ 2007-10-17 8:57 ` Peter Stephenson 2007-10-17 9:14 ` Peter Stephenson 0 siblings, 1 reply; 18+ messages in thread From: Peter Stephenson @ 2007-10-17 8:57 UTC (permalink / raw) To: Zsh Hackers' List On Tue, 16 Oct 2007 23:29:55 -0400 Clint Adams <clint@zsh.org> 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@csr.com> Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 8:57 ` Peter Stephenson @ 2007-10-17 9:14 ` Peter Stephenson 2007-10-17 13:01 ` Clint Adams 2007-10-17 14:57 ` Bart Schaefer 0 siblings, 2 replies; 18+ messages in thread From: Peter Stephenson @ 2007-10-17 9:14 UTC (permalink / raw) To: Zsh Hackers' List Peter Stephenson wrote: > On Tue, 16 Oct 2007 23:29:55 -0400 > Clint Adams <clint@zsh.org> wrote: > > I think we should provide refresh() as zcurses -R. > > That's easy. Actually, wouldn't it be simpler to use "zcurses -r" with no argument for this? (Also I forgot to document the change.) If I commit anything I'll incorporate Vin's patch. -- Peter Stephenson <pws@csr.com> Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 9:14 ` Peter Stephenson @ 2007-10-17 13:01 ` Clint Adams 2007-10-17 14:57 ` Bart Schaefer 1 sibling, 0 replies; 18+ messages in thread From: Clint Adams @ 2007-10-17 13:01 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh Hackers' List On Wed, Oct 17, 2007 at 10:14:44AM +0100, Peter Stephenson wrote: > Actually, wouldn't it be simpler to use "zcurses -r" with no argument > for this? (Also I forgot to document the change.) Yes, I imagine so. We could also special-case the window name "stdscr". ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 9:14 ` Peter Stephenson 2007-10-17 13:01 ` Clint Adams @ 2007-10-17 14:57 ` Bart Schaefer 2007-10-17 15:05 ` Peter Stephenson 1 sibling, 1 reply; 18+ messages in thread From: Bart Schaefer @ 2007-10-17 14:57 UTC (permalink / raw) To: Zsh Hackers' List On Oct 17, 10:14am, Peter Stephenson wrote: } } Peter Stephenson wrote: } > On Tue, 16 Oct 2007 23:29:55 -0400 } > Clint Adams <clint@zsh.org> wrote: } > > I think we should provide refresh() as zcurses -R. } > } > That's easy. } } Actually, wouldn't it be simpler to use "zcurses -r" with no argument } for this? (Also I forgot to document the change.) Maybe lower-case options should require a window name and upper case should require that there NOT be a window name? Then there'd be -R -I and -E for refresh/initscr/endwin. I don't feel strongly, just suggesting. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 14:57 ` Bart Schaefer @ 2007-10-17 15:05 ` Peter Stephenson 2007-10-17 15:25 ` Clint Adams 0 siblings, 1 reply; 18+ messages in thread From: Peter Stephenson @ 2007-10-17 15:05 UTC (permalink / raw) To: Zsh Hackers' List Bart Schaefer wrote: > Maybe lower-case options should require a window name and upper case > should require that there NOT be a window name? > > Then there'd be -R -I and -E for refresh/initscr/endwin. I had this horrible feeling we'd be running out of letters if we tried to do anything too clever too early, but it's really just raw paranoia. -- Peter Stephenson <pws@csr.com> Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 15:05 ` Peter Stephenson @ 2007-10-17 15:25 ` Clint Adams 2007-10-17 15:39 ` Peter Stephenson 2007-10-17 17:09 ` Bart Schaefer 0 siblings, 2 replies; 18+ messages in thread From: Clint Adams @ 2007-10-17 15:25 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh Hackers' List On Wed, Oct 17, 2007 at 04:05:44PM +0100, Peter Stephenson wrote: > I had this horrible feeling we'd be running out of letters if we tried > to do anything too clever too early, but it's really just raw paranoia. Well, there's plenty of the curses API that we haven't touched yet. Next I'll be needing attributes and colors; does anyone have UI preferences for wattrset() and wcolor_set()? ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 15:25 ` Clint Adams @ 2007-10-17 15:39 ` Peter Stephenson 2007-10-17 18:58 ` Clint Adams 2007-10-18 20:40 ` Clint Adams 2007-10-17 17:09 ` Bart Schaefer 1 sibling, 2 replies; 18+ messages in thread From: Peter Stephenson @ 2007-10-17 15:39 UTC (permalink / raw) To: Zsh Hackers' List Clint Adams wrote: > Next I'll be needing attributes and colors; does anyone have UI > preferences for wattrset() and wcolor_set()? Probably something like zcurses -A window +standout with +/- to enable and disable options which correspond to attributes that we can either parse out of the header or hardcode as { A_STANDOUT, "standout"} etc. zcurses -C window black/red (for black on red, obviously---I prefer it with the / since unlike with a space it's obvious what the foreground is) to which similar arguments apply. We need to think about any modifications we might want to "read" to make this more useful. -- Peter Stephenson <pws@csr.com> Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 15:39 ` Peter Stephenson @ 2007-10-17 18:58 ` Clint Adams 2007-10-17 19:19 ` Clint Adams 2007-10-18 20:40 ` Clint Adams 1 sibling, 1 reply; 18+ messages in thread From: Clint Adams @ 2007-10-17 18:58 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh Hackers' List On Wed, Oct 17, 2007 at 04:39:19PM +0100, Peter Stephenson wrote: > zcurses -A window +standout > > with +/- to enable and disable options which correspond to attributes > that we can either parse out of the header or hardcode as { A_STANDOUT, > "standout"} etc. Here goes, and here's my current test script: -8<- zcurses -i zcurses -a tw $(( LINES - 10 )) $(( COLUMNS - 20 )) 5 10 zcurses -b tw zcurses -m tw 1 1 zcurses -c tw B zcurses -c tw l zcurses -c tw a zcurses -c tw h zcurses -r tw zcurses -m tw 2 2 zcurses -s tw String zcurses -m tw 3 3 zcurses -A tw +bold +underline zcurses -s tw BoLD zcurses -r tw sleep 5 zcurses -e -8<- Index: Src/Modules/curses.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Modules/curses.c,v retrieving revision 1.9 diff -u -r1.9 curses.c --- Src/Modules/curses.c 17 Oct 2007 13:11:11 -0000 1.9 +++ Src/Modules/curses.c 17 Oct 2007 18:56:28 -0000 @@ -44,6 +44,11 @@ char *name; } *ZCWin; +struct zcurses_attribute { + char *name; + int number; +}; + static WINDOW *win_zero; static struct ttyinfo saved_tty_state; static struct ttyinfo curses_tty_state; @@ -56,6 +61,9 @@ #define ZCURSES_UNUSED 1 #define ZCURSES_USED 2 +#define ZCURSES_ATTRON 1 +#define ZCURSES_ATTROFF 2 + static int zc_errno; static const char * @@ -123,6 +131,41 @@ return 0; } +static int +zcurses_attribute(WINDOW *w, char *attr, int op) +{ + struct zcurses_attribute *zca; + + static const struct zcurses_attribute zcurses_attributes[] = { + {"blink", A_BLINK}, + {"bold", A_BOLD}, + {"dim", A_DIM}, + {"reverse", A_REVERSE}, + {"standout", A_STANDOUT}, + {"underline", A_UNDERLINE}, + {NULL, 0} + }; + + if (!attr) + return 1; + + for(zca=(struct zcurses_attribute *)zcurses_attributes;zca->name;zca++) + if (!strcmp(attr, zca->name)) { + switch(op) { + case ZCURSES_ATTRON: + wattron(w, zca->number); + break; + case ZCURSES_ATTROFF: + wattroff(w, zca->number); + break; + } + + return 0; + } + + return 1; +} + /**/ static int bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func)) @@ -141,7 +184,7 @@ if (OPT_ISSET(ops,'a')) { int nlines, ncols, begin_y, begin_x; - ZCWin w; + ZCWin w; if (zcurses_validate_window(args[0], ZCURSES_UNUSED) == NULL && zc_errno) { zerrnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], 0); @@ -153,11 +196,11 @@ begin_y = atoi(args[3]); begin_x = atoi(args[4]); - w = (ZCWin)zshcalloc(sizeof(struct zc_win)); - if (!w) + w = (ZCWin)zshcalloc(sizeof(struct zc_win)); + if (!w) return 1; - w->name = ztrdup(args[0]); + w->name = ztrdup(args[0]); w->win = newwin(nlines, ncols, begin_y, begin_x); if (w->win == NULL) { @@ -166,7 +209,7 @@ return 1; } - zinsertlinknode(zcurses_windows, lastnode(zcurses_windows), (void *)w); + zinsertlinknode(zcurses_windows, lastnode(zcurses_windows), (void *)w); return 0; } @@ -193,7 +236,7 @@ if (w->name) zsfree(w->name); - zfree((ZCWin)remnode(zcurses_windows, node), sizeof(struct zc_win)); + zfree((ZCWin)remnode(zcurses_windows, node), sizeof(struct zc_win)); return 0; } @@ -206,7 +249,7 @@ node = zcurses_validate_window(args[0], ZCURSES_USED); if (node == NULL) { zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], - 0); + 0); return 1; } @@ -361,6 +404,37 @@ } return 0; } + if (OPT_ISSET(ops,'A')) { + LinkNode node; + ZCWin w; + char **attrs; + + if (!args[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); + + for(attrs = args+1; *attrs; attrs++) { + switch(*attrs[0]) { + case '-': + zcurses_attribute(w->win, (*attrs)+1, ZCURSES_ATTROFF); + break; + case '+': + zcurses_attribute(w->win, (*attrs)+1, ZCURSES_ATTRON); + break; + default: + /* maybe a bad idea to spew warnings here */ + break; + } + } + return 0; + } return 0; } @@ -370,7 +444,7 @@ */ static struct builtin bintab[] = { - BUILTIN("zcurses", 0, bin_zcurses, 0, 5, 0, "ab:cd:eimrs", NULL), + BUILTIN("zcurses", 0, bin_zcurses, 0, 5, 0, "Aab:cd:eimrs", NULL), }; static struct features module_features = { ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 18:58 ` Clint Adams @ 2007-10-17 19:19 ` Clint Adams 0 siblings, 0 replies; 18+ messages in thread From: Clint Adams @ 2007-10-17 19:19 UTC (permalink / raw) To: Zsh Hackers' List On Wed, Oct 17, 2007 at 02:58:27PM -0400, Clint Adams wrote: > zcurses -A tw +bold +underline Some possibly-unclear docs to match. Index: Doc/Zsh/mod_curses.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/mod_curses.yo,v retrieving revision 1.5 diff -u -r1.5 mod_curses.yo --- Doc/Zsh/mod_curses.yo 17 Oct 2007 13:11:11 -0000 1.5 +++ Doc/Zsh/mod_curses.yo 17 Oct 2007 19:17:43 -0000 @@ -14,7 +14,8 @@ 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) )( +xitem(tt(zcurses) tt(-b) var(targetwin) var(border) )( +item(tt(zcurses) tt(-A) var(targetwin) var({+/-}attribute) [var({+/-}attribute)] [...])( 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 @@ -39,5 +40,11 @@ respectively. To draw a border around window var(targetwin), use tt(-b). + +tt(-A) will set var(targetwin)'s attributes for any successive character +output. Each var(attribute) given on the line should be prepended by a +tt(+) to set or a tt(-) to unset that attribute. The attributes supported +are tt(blink), tt(bold), tt(dim), tt(reverse), tt(standout), and +tt(underline). ) enditem() ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 15:39 ` Peter Stephenson 2007-10-17 18:58 ` Clint Adams @ 2007-10-18 20:40 ` Clint Adams 2007-10-20 12:12 ` Peter Stephenson 1 sibling, 1 reply; 18+ messages in thread From: Clint Adams @ 2007-10-18 20:40 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh Hackers' List On Wed, Oct 17, 2007 at 04:39:19PM +0100, Peter Stephenson wrote: > zcurses -C window black/red I don't know why this doesn't work; perhaps another man page I'm misreading. Index: Src/Modules/curses.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Modules/curses.c,v retrieving revision 1.11 diff -u -r1.11 curses.c --- Src/Modules/curses.c 18 Oct 2007 08:29:34 -0000 1.11 +++ Src/Modules/curses.c 18 Oct 2007 20:16:02 -0000 @@ -49,7 +49,7 @@ char *name; } *ZCWin; -struct zcurses_attribute { +struct zcurses_namenumberpair { char *name; int number; }; @@ -58,6 +58,7 @@ static struct ttyinfo saved_tty_state; static struct ttyinfo curses_tty_state; static LinkList zcurses_windows; +static HashTable zcurses_colorpairs; #define ZCURSES_ERANGE 1 #define ZCURSES_EDEFINED 2 @@ -69,7 +70,7 @@ #define ZCURSES_ATTRON 1 #define ZCURSES_ATTROFF 2 -static int zc_errno; +static int zc_errno, zc_color_phase=0, next_cp=0; static const char * zcurses_strerror(int err) @@ -139,9 +140,9 @@ static int zcurses_attribute(WINDOW *w, char *attr, int op) { - struct zcurses_attribute *zca; + struct zcurses_namenumberpair *zca; - static const struct zcurses_attribute zcurses_attributes[] = { + static const struct zcurses_namenumberpair zcurses_attributes[] = { {"blink", A_BLINK}, {"bold", A_BOLD}, {"dim", A_DIM}, @@ -154,7 +155,7 @@ if (!attr) return 1; - for(zca=(struct zcurses_attribute *)zcurses_attributes;zca->name;zca++) + for(zca=(struct zcurses_namenumberpair *)zcurses_attributes;zca->name;zca++) if (!strcmp(attr, zca->name)) { switch(op) { case ZCURSES_ATTRON: @@ -171,6 +172,85 @@ return 1; } +static int +zcurses_color(char *color) +{ + struct zcurses_namenumberpair *zc; + + static const struct zcurses_namenumberpair zcurses_colors[] = { + {"black", COLOR_BLACK}, + {"red", COLOR_RED}, + {"green", COLOR_GREEN}, + {"yellow", COLOR_YELLOW}, + {"blue", COLOR_BLUE}, + {"magenta", COLOR_MAGENTA}, + {"cyan", COLOR_CYAN}, + {"white", COLOR_WHITE}, + {NULL, 0} + }; + + for(zc=(struct zcurses_namenumberpair *)zcurses_colors;zc->name;zc++) + if (!strcmp(color, zc->name)) { + return zc->number; + } + + return -1; +} + +static int +zcurses_colorset(WINDOW *w, char *colorpair) +{ + char *fg, *bg, *cp; + int *c, f, b; + + if (zc_color_phase==1 || !(c = (int *) gethashnode(zcurses_colorpairs, colorpair))) { + zc_color_phase = 2; + cp = ztrdup(colorpair); + fg = strtok(cp, "/"); + bg = strtok(NULL, "/"); + + if (bg==NULL) { + zsfree(cp); + return 1; + } + + f = zcurses_color(fg); + b = zcurses_color(bg); + + zsfree(cp); + + if (f==-1 || b==-1) + return 1; + + ++next_cp; + if (next_cp >= COLOR_PAIRS) + return 1; + + if (init_pair(next_cp, f, b) == ERR) + return 1; + + c = (int *)zalloc(sizeof(int *)); + + if(!c) + return 1; + + *c = next_cp; + addhashnode(zcurses_colorpairs, colorpair, (void *)c); + } + + fprintf(stderr, "%d\n", *c); + + return (wcolor_set(w, *c, NULL) == ERR); +} + +static void +freecolornode(HashNode hn) +{ + int *i = (int *) hn; + + zfree(i, sizeof(int)); +} + /**/ static int bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func)) @@ -180,6 +260,25 @@ if (!win_zero) { gettyinfo(&saved_tty_state); win_zero = initscr(); + if (start_color() != ERR) { + if(!zc_color_phase) + zc_color_phase = 1; + zcurses_colorpairs = newhashtable(8, "zc_colorpairs", NULL); + + zcurses_colorpairs->hash = hasher; + zcurses_colorpairs->emptytable = emptyhashtable; + zcurses_colorpairs->filltable = NULL; + zcurses_colorpairs->cmpnodes = strcmp; + zcurses_colorpairs->addnode = addhashnode; + zcurses_colorpairs->getnode = gethashnode2; + zcurses_colorpairs->getnode2 = gethashnode2; + zcurses_colorpairs->removenode = removehashnode; + zcurses_colorpairs->disablenode = NULL; + zcurses_colorpairs->enablenode = NULL; + zcurses_colorpairs->freenode = freecolornode; + zcurses_colorpairs->printnode = NULL; + + } gettyinfo(&curses_tty_state); } else { settyinfo(&curses_tty_state); @@ -427,6 +526,23 @@ } return 0; } + if (OPT_ISSET(ops,'C')) { + LinkNode node; + ZCWin w; + + if (!args[0] || !args[1] || !zc_color_phase) + 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); + + return zcurses_colorset(w->win, args[1]); + } return 0; } @@ -436,7 +552,7 @@ */ static struct builtin bintab[] = { - BUILTIN("zcurses", 0, bin_zcurses, 0, 5, 0, "Aab:cd:eimrs", NULL), + BUILTIN("zcurses", 0, bin_zcurses, 0, 5, 0, "Aab:Ccd:eimrs", NULL), }; static struct features module_features = { @@ -483,6 +599,7 @@ cleanup_(Module m) { freelinklist(zcurses_windows, (FreeFunc) zcurses_free_window); + deletehashtable(zcurses_colorpairs); return setfeatureenables(m, &module_features, NULL); } ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-18 20:40 ` Clint Adams @ 2007-10-20 12:12 ` Peter Stephenson 2007-10-20 13:37 ` Clint Adams 0 siblings, 1 reply; 18+ messages in thread From: Peter Stephenson @ 2007-10-20 12:12 UTC (permalink / raw) To: Zsh Hackers' List On Thu, 18 Oct 2007 16:40:16 -0400 Clint Adams <clint@zsh.org> wrote: > On Wed, Oct 17, 2007 at 04:39:19PM +0100, Peter Stephenson wrote: > > zcurses -C window black/red > > I don't know why this doesn't work; perhaps another man page I'm > misreading. This fixes up some problems with hash table usage. I hope there aren't any leaks, it probably wants some looking over. I've also used shorts where the manual page says it needs them; this shouldn't actually be a problem since presumably the prototypes are OK. We may want a more informative message if we run out of color pairs. Otherwise it seems to be working... I'm just using a trivially modified script. If I get a chance I may look at turning the options into names in a table as suggested by Bart. This will also give us a way of doing better argument length and other checking. I've also got a patch necessary for compilation with curses instead of ncurses, but that's at work so will have to wait till Monday. zmodload zsh/curses zcurses -i zcurses -a tw $(( LINES - 10 )) $(( COLUMNS - 20 )) 5 10 zcurses -b tw zcurses -m tw 1 1 zcurses -c tw B zcurses -c tw l zcurses -c tw a zcurses -c tw h zcurses -r tw zcurses -m tw 2 2 zcurses -s tw String zcurses -m tw 3 3 zcurses -C tw blue/red zcurses -A tw +bold +underline zcurses -s tw BoLD zcurses -r tw sleep 5 zcurses -d tw zcurses -e Index: Src/Modules/curses.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Modules/curses.c,v retrieving revision 1.13 diff -u -r1.13 curses.c --- Src/Modules/curses.c 19 Oct 2007 20:21:29 -0000 1.13 +++ Src/Modules/curses.c 20 Oct 2007 12:05:11 -0000 @@ -54,6 +54,12 @@ int number; }; +struct colorpairnode { + struct hashnode node; + short colorpair; +}; +typedef struct colorpairnode *Colorpairnode; + static WINDOW *win_zero; static struct ttyinfo saved_tty_state; static struct ttyinfo curses_tty_state; @@ -70,7 +76,8 @@ #define ZCURSES_ATTRON 1 #define ZCURSES_ATTROFF 2 -static int zc_errno, zc_color_phase=0, next_cp=0; +static int zc_errno, zc_color_phase=0; +static short next_cp=0; static const char * zcurses_strerror(int err) @@ -172,7 +179,7 @@ return 1; } -static int +static short zcurses_color(char *color) { struct zcurses_namenumberpair *zc; @@ -191,19 +198,21 @@ for(zc=(struct zcurses_namenumberpair *)zcurses_colors;zc->name;zc++) if (!strcmp(color, zc->name)) { - return zc->number; + return (short)zc->number; } - return -1; + return (short)-1; } static int zcurses_colorset(WINDOW *w, char *colorpair) { char *fg, *bg, *cp; - int *c, f, b; + short f, b; + Colorpairnode cpn; - if (zc_color_phase==1 || !(c = (int *) gethashnode(zcurses_colorpairs, colorpair))) { + if (zc_color_phase==1 || + !(cpn = (Colorpairnode) gethashnode(zcurses_colorpairs, colorpair))) { zc_color_phase = 2; cp = ztrdup(colorpair); fg = strtok(cp, "/"); @@ -229,26 +238,23 @@ if (init_pair(next_cp, f, b) == ERR) return 1; - c = (int *)zalloc(sizeof(int *)); + cpn = (Colorpairnode)zalloc(sizeof(struct colorpairnode)); - if(!c) + if (!cpn) return 1; - *c = next_cp; - addhashnode(zcurses_colorpairs, colorpair, (void *)c); - } - - fprintf(stderr, "%d\n", *c); + cpn->colorpair = next_cp; + addhashnode(zcurses_colorpairs, ztrdup(colorpair), (void *)cpn); + } - return (wcolor_set(w, *c, NULL) == ERR); + return (wcolor_set(w, cpn->colorpair, NULL) == ERR); } static void -freecolornode(HashNode hn) +freecolorpairnode(HashNode hn) { - int *i = (int *) hn; - - zfree(i, sizeof(int)); + zsfree(hn->nam); + zfree(hn, sizeof(struct colorpairnode)); } /**/ @@ -275,7 +281,7 @@ zcurses_colorpairs->removenode = removehashnode; zcurses_colorpairs->disablenode = NULL; zcurses_colorpairs->enablenode = NULL; - zcurses_colorpairs->freenode = freecolornode; + zcurses_colorpairs->freenode = freecolorpairnode; zcurses_colorpairs->printnode = NULL; } -- Peter Stephenson <p.w.stephenson@ntlworld.com> Web page now at http://homepage.ntlworld.com/p.w.stephenson/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-20 12:12 ` Peter Stephenson @ 2007-10-20 13:37 ` Clint Adams 2007-10-21 19:50 ` Clint Adams 2007-10-21 21:13 ` Clint Adams 0 siblings, 2 replies; 18+ messages in thread From: Clint Adams @ 2007-10-20 13:37 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh Hackers' List On Sat, Oct 20, 2007 at 01:12:46PM +0100, Peter Stephenson wrote: > If I get a chance I may look at turning the options into names in a > table as suggested by Bart. This will also give us a way of doing > better argument length and other checking. This needs the checking bit and a doc update. zcurses init zcurses addwin tw $(( LINES - 10 )) $(( COLUMNS - 20 )) 5 10 zcurses border tw zcurses move tw 1 1 zcurses c tw B zcurses c tw l zcurses c tw a zcurses c tw h zcurses refresh tw zcurses move tw 2 2 zcurses s tw String zcurses move tw 3 3 zcurses attr tw +bold +underline zcurses s tw BoLD zcurses move tw 4 4 zcurses attr tw -bold -underline zcurses color tw green/black zcurses s tw Green zcurses refresh tw sleep 5 zcurses delwin tw zcurses endwin Index: Src/Modules/curses.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Modules/curses.c,v retrieving revision 1.14 diff -u -r1.14 curses.c --- Src/Modules/curses.c 20 Oct 2007 12:15:17 -0000 1.14 +++ Src/Modules/curses.c 20 Oct 2007 13:33:44 -0000 @@ -60,6 +60,12 @@ }; typedef struct colorpairnode *Colorpairnode; +struct zcurses_subcommand { + struct zcurses_namenumberpair nn; + int minargs; + int maxargs; +}; + static WINDOW *win_zero; static struct ttyinfo saved_tty_state; static struct ttyinfo curses_tty_state; @@ -76,6 +82,18 @@ #define ZCURSES_ATTRON 1 #define ZCURSES_ATTROFF 2 +#define ZCURSES_SC_INIT 1 +#define ZCURSES_SC_ADDWIN 2 +#define ZCURSES_SC_DELWIN 3 +#define ZCURSES_SC_REFRESH 4 +#define ZCURSES_SC_MOVE 5 +#define ZCURSES_SC_CHAR 6 +#define ZCURSES_SC_STRING 7 +#define ZCURSES_SC_BORDER 8 +#define ZCURSES_SC_ENDWIN 9 +#define ZCURSES_SC_ATTR 10 +#define ZCURSES_SC_COLOR 11 + static int zc_errno, zc_color_phase=0; static short next_cp=0; @@ -261,8 +279,42 @@ static int bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func)) { + char **saargs; + struct zcurses_subcommand *zcsc; + int sc; + + struct zcurses_subcommand scs[] = { + {{"init", ZCURSES_SC_INIT}, 0, 0}, + {{"addwin", ZCURSES_SC_ADDWIN}, 5, 5}, + {{"delwin", ZCURSES_SC_DELWIN}, 1, 1}, + {{"refresh", ZCURSES_SC_REFRESH}, 0, 1}, + {{"move", ZCURSES_SC_MOVE}, 3, 3}, + {{"c", ZCURSES_SC_CHAR}, 2, 2}, + {{"s", ZCURSES_SC_STRING}, 2, 2}, + {{"border", ZCURSES_SC_BORDER}, 1, 5}, + {{"endwin", ZCURSES_SC_ENDWIN}, 1, 1}, + {{"attr", ZCURSES_SC_ATTR}, 2, 2}, + {{"color", ZCURSES_SC_COLOR}, 2, 2}, + {{NULL, -1}, 0, 0} + }; + + for(zcsc = scs; zcsc->nn.name; zcsc++) { + if(!strcmp(args[0], zcsc->nn.name)) + break; + } + + sc = zcsc->nn.number; + + if (sc == -1) { + zwarnnam(nam, "unknown subcommand: %s", args[0], 0); + return 1; + } + + /* here would be a good place to validate number of args */ + saargs = args + 1; + /* Initialise curses */ - if (OPT_ISSET(ops,'i')) { + if (sc == ZCURSES_SC_INIT) { if (!win_zero) { gettyinfo(&saved_tty_state); win_zero = initscr(); @@ -272,8 +324,8 @@ zcurses_colorpairs = newhashtable(8, "zc_colorpairs", NULL); zcurses_colorpairs->hash = hasher; - zcurses_colorpairs->emptytable = emptyhashtable; - zcurses_colorpairs->filltable = NULL; + zcurses_colorpairs->emptytable = emptyhashtable; + zcurses_colorpairs->filltable = NULL; zcurses_colorpairs->cmpnodes = strcmp; zcurses_colorpairs->addnode = addhashnode; zcurses_colorpairs->getnode = gethashnode2; @@ -290,27 +342,26 @@ settyinfo(&curses_tty_state); } return 0; - } - - if (OPT_ISSET(ops,'a')) { + } else + if (sc == ZCURSES_SC_ADDWIN) { int nlines, ncols, begin_y, begin_x; ZCWin w; - if (zcurses_validate_window(args[0], ZCURSES_UNUSED) == NULL && zc_errno) { - zerrnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], 0); + if (zcurses_validate_window(saargs[0], ZCURSES_UNUSED) == NULL && zc_errno) { + zerrnam(nam, "%s: %s", zcurses_strerror(zc_errno), saargs[0], 0); return 1; } - nlines = atoi(args[1]); - ncols = atoi(args[2]); - begin_y = atoi(args[3]); - begin_x = atoi(args[4]); + nlines = atoi(saargs[1]); + ncols = atoi(saargs[2]); + begin_y = atoi(saargs[3]); + begin_x = atoi(saargs[4]); w = (ZCWin)zshcalloc(sizeof(struct zc_win)); if (!w) return 1; - w->name = ztrdup(args[0]); + w->name = ztrdup(saargs[0]); w->win = newwin(nlines, ncols, begin_y, begin_x); if (w->win == NULL) { @@ -322,22 +373,21 @@ zinsertlinknode(zcurses_windows, lastnode(zcurses_windows), (void *)w); return 0; - } - - if (OPT_ISSET(ops,'d')) { + } else + if (sc == ZCURSES_SC_DELWIN) { LinkNode node; ZCWin w; - node = zcurses_validate_window(OPT_ARG(ops,'d'), ZCURSES_USED); + node = zcurses_validate_window(saargs[0], ZCURSES_USED); if (node == NULL) { - zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), OPT_ARG(ops,'d'), 0); + zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), saargs[0], 0); return 1; } w = (ZCWin)getdata(node); if (w == NULL) { - zwarnnam(nam, "record for window `%s' is corrupt", OPT_ARG(ops, 'd'), 0); + zwarnnam(nam, "record for window `%s' is corrupt", saargs[0], 0); return 1; } if (delwin(w->win)!=OK) @@ -349,16 +399,15 @@ zfree((ZCWin)remnode(zcurses_windows, node), sizeof(struct zc_win)); return 0; - } - - if (OPT_ISSET(ops,'r')) { - if (args[0]) { + } else + if (sc == ZCURSES_SC_REFRESH) { + if (saargs[0]) { LinkNode node; ZCWin w; - node = zcurses_validate_window(args[0], ZCURSES_USED); + node = zcurses_validate_window(saargs[0], ZCURSES_USED); if (node == NULL) { - zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], + zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), saargs[0], 0); return 1; } @@ -371,21 +420,20 @@ { return (refresh() != OK) ? 1 : 0; } - } - - if (OPT_ISSET(ops,'m')) { + } else + if (sc == ZCURSES_SC_MOVE) { int y, x; LinkNode node; ZCWin w; - node = zcurses_validate_window(args[0], ZCURSES_USED); + node = zcurses_validate_window(saargs[0], ZCURSES_USED); if (node == NULL) { - zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], 0); + zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), saargs[0], 0); return 1; } - y = atoi(args[1]); - x = atoi(args[2]); + y = atoi(saargs[1]); + x = atoi(saargs[2]); w = (ZCWin)getdata(node); @@ -393,9 +441,8 @@ return 1; return 0; - } - - if (OPT_ISSET(ops,'c')) { + } else + if (sc == ZCURSES_SC_CHAR) { LinkNode node; ZCWin w; #ifdef HAVE_SETCCHAR @@ -403,16 +450,16 @@ cchar_t cc; #endif - node = zcurses_validate_window(args[0], ZCURSES_USED); + node = zcurses_validate_window(saargs[0], ZCURSES_USED); if (node == NULL) { - zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], 0); + zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), saargs[0], 0); return 1; } w = (ZCWin)getdata(node); #ifdef HAVE_SETCCHAR - if (mbrtowc(&c, args[1], MB_CUR_MAX, NULL) < 1) + if (mbrtowc(&c, saargs[1], MB_CUR_MAX, NULL) < 1) return 1; if (setcchar(&cc, &c, A_NORMAL, 0, NULL)==ERR) @@ -421,14 +468,13 @@ if (wadd_wch(w->win, &cc)!=OK) return 1; #else - if (waddch(w->win, (chtype)args[1][0])!=OK) + if (waddch(w->win, (chtype)saargs[1][0])!=OK) return 1; #endif return 0; - } - - if (OPT_ISSET(ops,'s')) { + } else + if (sc == ZCURSES_SC_STRING) { LinkNode node; ZCWin w; @@ -436,10 +482,10 @@ int clen; wint_t wc; wchar_t *wstr, *wptr; - char *str = args[1]; + char *str = saargs[1]; #endif - node = zcurses_validate_window(args[0], ZCURSES_USED); + node = zcurses_validate_window(saargs[0], ZCURSES_USED); if (node == NULL) { zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], 0); return 1; @@ -462,19 +508,18 @@ return 1; } #else - if (waddstr(w->win, args[1])!=OK) + if (waddstr(w->win, saargs[1])!=OK) return 1; #endif return 0; - } - - if (OPT_ISSET(ops,'b')) { + } else + if (sc == ZCURSES_SC_BORDER) { LinkNode node; ZCWin w; - node = zcurses_validate_window(OPT_ARG(ops,'b'), ZCURSES_USED); + node = zcurses_validate_window(saargs[0], ZCURSES_USED); if (node == NULL) { - zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), OPT_ARG(ops,'b'), 0); + zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), saargs[0], 0); return 1; } @@ -484,10 +529,9 @@ return 1; return 0; - } - + } else /* Finish using curses */ - if (OPT_ISSET(ops,'e')) { + if (sc == ZCURSES_SC_ENDWIN) { if (win_zero) { endwin(); /* Restore TTY as it was before zcurses -i */ @@ -500,24 +544,24 @@ gettyinfo(&shttyinfo); } return 0; - } - if (OPT_ISSET(ops,'A')) { + } else + if (sc == ZCURSES_SC_ATTR) { LinkNode node; ZCWin w; char **attrs; - if (!args[0]) + if (!saargs[0]) return 1; - node = zcurses_validate_window(args[0], ZCURSES_USED); + node = zcurses_validate_window(saargs[0], ZCURSES_USED); if (node == NULL) { - zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], 0); + zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), saargs[0], 0); return 1; } w = (ZCWin)getdata(node); - for(attrs = args+1; *attrs; attrs++) { + for(attrs = saargs+1; *attrs; attrs++) { switch(*attrs[0]) { case '-': zcurses_attribute(w->win, (*attrs)+1, ZCURSES_ATTROFF); @@ -531,23 +575,23 @@ } } return 0; - } - if (OPT_ISSET(ops,'C')) { + } else + if (sc == ZCURSES_SC_COLOR) { LinkNode node; ZCWin w; - if (!args[0] || !args[1] || !zc_color_phase) + if (!saargs[0] || !saargs[1] || !zc_color_phase) return 1; - node = zcurses_validate_window(args[0], ZCURSES_USED); + node = zcurses_validate_window(saargs[0], ZCURSES_USED); if (node == NULL) { - zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0], 0); + zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), saargs[0], 0); return 1; } w = (ZCWin)getdata(node); - return zcurses_colorset(w->win, args[1]); + return zcurses_colorset(w->win, saargs[1]); } return 0; @@ -558,7 +602,7 @@ */ static struct builtin bintab[] = { - BUILTIN("zcurses", 0, bin_zcurses, 0, 5, 0, "Aab:Ccd:eimrs", NULL), + BUILTIN("zcurses", 0, bin_zcurses, 1, 6, 0, "", NULL), }; static struct features module_features = { ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-20 13:37 ` Clint Adams @ 2007-10-21 19:50 ` Clint Adams 2007-10-21 21:13 ` Clint Adams 1 sibling, 0 replies; 18+ messages in thread From: Clint Adams @ 2007-10-21 19:50 UTC (permalink / raw) To: Zsh Hackers' List On Sat, Oct 20, 2007 at 09:37:09AM -0400, Clint Adams wrote: > This needs the checking bit and a doc update. Index: Doc/Zsh/mod_curses.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/mod_curses.yo,v retrieving revision 1.6 diff -u -r1.6 mod_curses.yo --- Doc/Zsh/mod_curses.yo 17 Oct 2007 20:27:26 -0000 1.6 +++ Doc/Zsh/mod_curses.yo 21 Oct 2007 19:49:18 -0000 @@ -6,42 +6,42 @@ 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(-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) ) -xitem(tt(zcurses) tt(-b) var(targetwin) var(border) )( -item(tt(zcurses) tt(-A) var(targetwin) var({+/-}attribute) [var({+/-}attribute)] [...])( +xitem(tt(zcurses) tt(init)) +xitem(tt(zcurses) tt(endwin)) +xitem(tt(zcurses) tt(addwin) var(targetwin) var(nlines) var(ncols) var(begin_y) var(begin_x) ) +xitem(tt(zcurses) tt(delwin) var(targetwin) ) +xitem(tt(zcurses) tt(refresh) [ var(targetwin) ] ) +xitem(tt(zcurses) tt(move) 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) ) +xitem(tt(zcurses) tt(border) var(targetwin) var(border) )( +item(tt(zcurses) tt(addwin) var(targetwin) var({+/-}attribute) [var({+/-}attribute)] [...])( 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 +bracketed by `tt(zcurses init)' to initialise use of curses, and +`tt(zcurses endwin)' to end it; omitting `tt(zcurses endwin)' can cause the terminal to be in an unwanted state. -With tt(-a), create a window with var(nlines) lines and var(ncols) columns. +With tt(addwin), 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 var(begin_x) of the screen. var(targetwin) is a string and refers to the name of a window that is not currently assigned. -Use tt(-d) to delete a window created with tt(-a). +Use tt(delwin) to delete a window created with tt(addwin). -The tt(-r) command will refresh window var(targetwin); this is necessary to +The tt(refresh) 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. If no argument is given, +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 +tt(move) moves the cursor position in var(targetwin) to new coordinates var(new_y) and var(new_x). -Outputting characters and strings are achieved by tt(-c) and tt(-s) +Outputting characters and strings are achieved by tt(c) and tt(s) respectively. -To draw a border around window var(targetwin), use tt(-b). +To draw a border around window var(targetwin), use tt(border). -tt(-A) will set var(targetwin)'s attributes for any successive character +tt(addwin) will set var(targetwin)'s attributes for any successive character output. Each var(attribute) given on the line should be prepended by a tt(+) to set or a tt(-) to unset that attribute. The attributes supported are tt(blink), tt(bold), tt(dim), tt(reverse), tt(standout), and ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-20 13:37 ` Clint Adams 2007-10-21 19:50 ` Clint Adams @ 2007-10-21 21:13 ` Clint Adams 1 sibling, 0 replies; 18+ messages in thread From: Clint Adams @ 2007-10-21 21:13 UTC (permalink / raw) To: Zsh Hackers' List On Sat, Oct 20, 2007 at 09:37:09AM -0400, Clint Adams wrote: > This needs the checking bit and a doc update. This is probably not the most efficient. Index: Src/Modules/curses.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Modules/curses.c,v retrieving revision 1.15 diff -u -r1.15 curses.c --- Src/Modules/curses.c 20 Oct 2007 13:40:02 -0000 1.15 +++ Src/Modules/curses.c 21 Oct 2007 21:08:54 -0000 @@ -281,7 +281,7 @@ { char **saargs; struct zcurses_subcommand *zcsc; - int sc; + int sc, num_args; struct zcurses_subcommand scs[] = { {{"init", ZCURSES_SC_INIT}, 0, 0}, @@ -310,7 +310,13 @@ return 1; } - /* here would be a good place to validate number of args */ + saargs = args; + while (*saargs++); + num_args = saargs - (args + 2); + + if (num_args < zcsc->minargs || num_args > zcsc->maxargs) + return 1; + saargs = args + 1; /* Initialise curses */ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 15:25 ` Clint Adams 2007-10-17 15:39 ` Peter Stephenson @ 2007-10-17 17:09 ` Bart Schaefer 2007-10-17 17:53 ` Peter Stephenson 1 sibling, 1 reply; 18+ messages in thread From: Bart Schaefer @ 2007-10-17 17:09 UTC (permalink / raw) To: Zsh Hackers' List On Oct 17, 11:25am, Clint Adams wrote: } Subject: Re: PATCH: curses tweaks, maybe } } On Wed, Oct 17, 2007 at 04:05:44PM +0100, Peter Stephenson wrote: } > I had this horrible feeling we'd be running out of letters if we tried } > to do anything too clever too early, but it's really just raw paranoia. } } Well, there's plenty of the curses API that we haven't touched yet. } Next I'll be needing attributes and colors; does anyone have UI } preferences for wattrset() and wcolor_set()? In that case maybe option letters are completely out and we ought to be doing zcurses addwin targetwinname ... zcurses refresh zcurses endwin etc. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: PATCH: curses tweaks, maybe 2007-10-17 17:09 ` Bart Schaefer @ 2007-10-17 17:53 ` Peter Stephenson 0 siblings, 0 replies; 18+ messages in thread From: Peter Stephenson @ 2007-10-17 17:53 UTC (permalink / raw) To: Zsh Hackers' List Bart Schaefer wrote: > In that case maybe option letters are completely out and we ought to be > doing > > zcurses addwin targetwinname ... > zcurses refresh > zcurses endwin That does make a lot of sense, though we wouldn't want to adopt curses naming throughout, since that's horrific, as I've just been finding out. -- Peter Stephenson <pws@csr.com> Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2007-10-21 23:00 UTC | newest] Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-10-16 8:40 PATCH: curses tweaks, maybe Peter Stephenson 2007-10-17 3:29 ` Clint Adams 2007-10-17 8:57 ` Peter Stephenson 2007-10-17 9:14 ` Peter Stephenson 2007-10-17 13:01 ` Clint Adams 2007-10-17 14:57 ` Bart Schaefer 2007-10-17 15:05 ` Peter Stephenson 2007-10-17 15:25 ` Clint Adams 2007-10-17 15:39 ` Peter Stephenson 2007-10-17 18:58 ` Clint Adams 2007-10-17 19:19 ` Clint Adams 2007-10-18 20:40 ` Clint Adams 2007-10-20 12:12 ` Peter Stephenson 2007-10-20 13:37 ` Clint Adams 2007-10-21 19:50 ` Clint Adams 2007-10-21 21:13 ` Clint Adams 2007-10-17 17:09 ` Bart Schaefer 2007-10-17 17:53 ` Peter Stephenson
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).