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:
parent
4540478d69
commit
4f3e414a64
4 changed files with 164 additions and 27 deletions
14
ChangeLog
14
ChangeLog
|
@ -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>
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue