1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-01-01 05:16:05 +01:00

24025: new zcurses "clear" and "location" subcommands

zcurses window "stdscr"
various minor zcurses tweaks
This commit is contained in:
Peter Stephenson 2007-10-27 23:42:47 +00:00
parent 4540478d69
commit 4f3e414a64
4 changed files with 164 additions and 27 deletions

View file

@ -1,12 +1,18 @@
2007-10-28 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 24025: Doc/Zsh/mod_curses.yo, Src/Modules/curses.c,
Src/Modules/curses_keys.awk: new zcurses subcommands
"clear" and "position"; "stdscr" window; numerous other tweaks.
2007-10-26 Peter Stephenson <p.w.stephenson@ntlworld.com>
* unposted: Src/curses.c: zcurses input oops.
* 24024: configure.ac, Doc/Zsh/mod_curses.yo,
Src/Modules/curses.c: add "zcurses input" for single character
raw input without echoing. Test for wget_wch for wide
character input. Add handling for keypad() mode by
scanning header.
Src/Modules/curses.c, Src/Modules/curses_keys.awk: add "zcurses
input" for single character raw input without echoing. Test for
wget_wch for wide character input. Add handling for keypad()
mode by scanning header.
2007-10-26 Clint Adams <clint@zsh.org>

View file

@ -15,6 +15,8 @@ xitem(tt(zcurses) tt(addwin) var(targetwin) var(nlines) var(ncols) var(begin_y)
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(clear) var(targetwin) [ tt(redraw) | tt(eol) | tt(bot) ])
xitem(tt(location) var(targetwin) var(array))
xitem(tt(zcurses) tt(char) var(targetwin) var(character) )
xitem(tt(zcurses) tt(string) var(targetwin) var(string) )
xitem(tt(zcurses) tt(border) var(targetwin) var(border) )(
@ -29,19 +31,46 @@ the terminal to be in an unwanted state.
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.
to the name of a window that is not currently assigned. Note
in particular the curses convention that vertical values appear
before horizontal values.
Use tt(delwin) to delete a window created with tt(addwin). Note
that tt(end) does em(not) implicitly delete windows.
that tt(end) does em(not) implicitly delete windows, and that
tt(delwin) does not erase the screen image of the window.
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(char)) visible on the screen. If no argument is given,
all windows are refreshed; this is necessary after deleting a window.
The window corresponding to the full visible screen is called
tt(stdscr); it always exists after `tt(zcurses init)' and cannot
be delete with tt(delwin).
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(char)) visible on the screen. tt(refresh)
without an argument causes the screen to be cleared and redrawn.
tt(move) moves the cursor position in var(targetwin) to new coordinates
var(new_y) and var(new_x).
tt(clear) erases the contents of var(targetwin). One (and no more than one)
of three options may be specified. With the option tt(redraw),
in addition the next tt(refresh) of var(targetwin) will cause the screen to be
cleared and repainted. With the option tt(eol), var(targetwin) is only
cleared to the end of the current cursor line. With the option
tt(bot), var(targetwin) is cleared to the end of the window, i.e
everything to the right and below the cursor is cleared.
tt(location) writes various positions associated with var(targetwin)
into the array named var(array).
These are, in order:
startsitem()
sitem()(The y and x coordinates of the cursor relative to the top left
of var(targetwin))
sitem()(The y and x coordinates of the top left of var(targetwin) on the
screen)
sitem()(The y and x coordinates of the bottom right of var(targetwin)
on the screen.)
endsitem()
Outputting characters and strings are achieved by tt(char) and tt(string)
respectively.

View file

@ -53,8 +53,10 @@
#include <stdio.h>
enum zc_win_flags {
/* Window is permanent (probably "stdscr") */
ZCWF_PERMANENT = 0x0001,
/* Scrolling enabled */
ZCWF_SCROLL = 0x0001
ZCWF_SCROLL = 0x0002
};
typedef struct zc_win {
@ -82,13 +84,12 @@ struct zcurses_subcommand {
int maxargs;
};
static WINDOW *win_zero;
static struct ttyinfo saved_tty_state;
static struct ttyinfo curses_tty_state;
static LinkList zcurses_windows;
static HashTable zcurses_colorpairs = NULL;
#define ZCURSES_ERANGE 1
#define ZCURSES_EINVALID 1
#define ZCURSES_EDEFINED 2
#define ZCURSES_EUNDEFINED 3
@ -151,11 +152,12 @@ zcurses_strerror(int err)
{
static const char *errs[] = {
"unknown error",
"window number out of range",
"window name invalid",
"window already defined",
"window undefined",
NULL };
return errs[(err < 1 || err > 2) ? 0 : err];
return errs[(err < 1 || err > 3) ? 0 : err];
}
static LinkNode
@ -177,7 +179,7 @@ zcurses_validate_window(char *win, int criteria)
LinkNode target;
if (win==NULL || strlen(win) < 1) {
zc_errno = ZCURSES_ERANGE;
zc_errno = ZCURSES_EINVALID;
return NULL;
}
@ -200,7 +202,7 @@ zcurses_validate_window(char *win, int criteria)
static int
zcurses_free_window(ZCWin w)
{
if (delwin(w->win)!=OK)
if (!(w->flags & ZCWF_PERMANENT) && delwin(w->win)!=OK)
return 1;
if (w->name)
@ -317,9 +319,23 @@ freecolorpairnode(HashNode hn)
static int
zccmd_init(const char *nam, char **args)
{
if (!win_zero) {
LinkNode stdscr_win = zcurses_getwindowbyname("stdscr");
if (!stdscr_win) {
ZCWin w = (ZCWin)zshcalloc(sizeof(struct zc_win));
if (!w)
return 1;
gettyinfo(&saved_tty_state);
win_zero = initscr();
w->name = ztrdup("stdscr");
w->win = initscr();
if (w->win == NULL) {
zsfree(w->name);
zfree(w, sizeof(struct zc_win));
return 1;
}
w->flags = ZCWF_PERMANENT;
zinsertlinknode(zcurses_windows, lastnode(zcurses_windows), (void *)w);
if (start_color() != ERR) {
if(!zc_color_phase)
zc_color_phase = 1;
@ -410,6 +426,10 @@ zccmd_delwin(const char *nam, char **args)
zwarnnam(nam, "record for window `%s' is corrupt", args[0]);
return 1;
}
if (w->flags & ZCWF_PERMANENT) {
zwarnnam(nam, "window `%s' can't be deleted", args[0]);
return 1;
}
if (delwin(w->win)!=OK)
return 1;
@ -421,6 +441,7 @@ zccmd_delwin(const char *nam, char **args)
return 0;
}
static int
zccmd_refresh(const char *nam, char **args)
{
@ -441,7 +462,7 @@ zccmd_refresh(const char *nam, char **args)
}
else
{
return (refresh() != OK) ? 1 : 0;
return (wrefresh(curscr) != OK) ? 1 : 0;
}
}
@ -471,6 +492,35 @@ zccmd_move(const char *nam, char **args)
}
static int
zccmd_clear(const char *nam, char **args)
{
LinkNode node;
ZCWin w;
node = zcurses_validate_window(args[0], ZCURSES_USED);
if (node == NULL) {
zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0]);
return 1;
}
w = (ZCWin)getdata(node);
if (!args[1]) {
return werase(w->win) != OK;
} else if (!strcmp(args[1], "redraw")) {
return wclear(w->win) != OK;
} else if (!strcmp(args[1], "eol")) {
return wclrtoeol(w->win) != OK;
} else if (!strmp(args[1], "bot")) {
return wclrtobot(w->win) != OK;
} else {
zwarnnam(nam, "`clear' expects `redraw', `eol' or `bot'");
return 1;
}
}
static int
zccmd_char(const char *nam, char **args)
{
@ -574,7 +624,9 @@ zccmd_border(const char *nam, char **args)
static int
zccmd_endwin(const char *nam, char **args)
{
if (win_zero) {
LinkNode stdscr_win = zcurses_getwindowbyname("stdscr");
if (stdscr_win) {
endwin();
/* Restore TTY as it was before zcurses -i */
settyinfo(&saved_tty_state);
@ -727,6 +779,7 @@ zccmd_input(const char *nam, char **args)
break;
case KEY_CODE_YES:
*instr = '\0';
keypadnum = (int)wi;
break;
@ -736,8 +789,11 @@ zccmd_input(const char *nam, char **args)
}
#else
ci = wgetch(w->win);
if (ci == ERR)
return 1;
if (ci >= 256) {
keypadnum = ci;
*instr = '\0';
} else {
if (imeta(ci)) {
instr[0] = Meta;
@ -753,16 +809,17 @@ zccmd_input(const char *nam, char **args)
var = args[1];
else
var = "REPLY";
if (!setsparam(var, ztrdup(keypadnum > 0 ? "" : instr)))
if (!setsparam(var, ztrdup(instr)))
return 1;
if (args[2]) {
if (args[1] && args[2]) {
if (keypadnum > 0) {
const struct zcurses_namenumberpair *nnptr;
char fbuf[DIGBUFSIZE+1];
for (nnptr = keypad_names; nnptr->name; nnptr++) {
if (keypadnum == nnptr->number) {
setsparam(args[2], ztrdup(nnptr->name));
if (!setsparam(args[2], ztrdup(nnptr->name)))
return 1;
return 0;
}
}
@ -773,15 +830,51 @@ zccmd_input(const char *nam, char **args)
/* print raw number */
sprintf(fbuf, "%d", keypadnum);
}
setsparam(args[2], ztrdup(fbuf));
if (!setsparam(args[2], ztrdup(fbuf)))
return 1;
} else {
setsparam(args[2], ztrdup(""));
if (!setsparam(args[2], ztrdup("")))
return 1;
}
}
return 0;
}
static int
zccmd_position(const char *nam, char **args)
{
LinkNode node;
ZCWin w;
int i, intarr[6];
char **array, dbuf[DIGBUFSIZE];
node = zcurses_validate_window(args[0], ZCURSES_USED);
if (node == NULL) {
zwarnnam(nam, "%s: %s", zcurses_strerror(zc_errno), args[0]);
return 1;
}
w = (ZCWin)getdata(node);
/* Look no pointers: these are macros. */
if (getyx(w->win, intarr[0], intarr[1]) == ERR ||
getbegyx(w->win, intarr[2], intarr[3]) == ERR ||
getmaxyx(w->win, intarr[4], intarr[5]) == ERR)
return 1;
array = (char **)zalloc(7*sizeof(char *));
for (i = 0; i < 6; i++) {
sprintf(dbuf, "%d", intarr[i]);
array[i] = ztrdup(dbuf);
}
array[6] = NULL;
setaparam(args[1], array);
return 0;
}
/*********************
Main builtin handler
*********************/
@ -800,6 +893,8 @@ bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func))
{"delwin", zccmd_delwin, 1, 1},
{"refresh", zccmd_refresh, 0, 1},
{"move", zccmd_move, 3, 3},
{"clear", zccmd_clear, 1, 2},
{"position", zccmd_position, 2, 2},
{"char", zccmd_char, 2, 2},
{"string", zccmd_string, 2, 2},
{"border", zccmd_border, 1, 1},
@ -832,6 +927,13 @@ bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func))
return 1;
}
if (zcsc->cmd != zccmd_init && zcsc->cmd != zccmd_endwin &&
!zcurses_getwindowbyname("stdscr")) {
zwarnnam(nam, "command `%s' can't be used before `zcurses init'",
zcsc->name);
return 1;
}
return zcsc->cmd(nam, args+1);
}

View file

@ -5,7 +5,7 @@ BEGIN {nkeydefs = 0}
keytail = substr($0, keyindex, 80)
split(keytail, tmp)
keynam = substr(tmp[1], 5, 30)
if (keynam != "MIN" && keynam != "MAX") {
if (keynam != "MIN" && keynam != "MAX" && keynam != "CODE_YES") {
name[nkeydefs++] = keynam
}
}