summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2007-10-27 23:42:47 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2007-10-27 23:42:47 +0000
commit4f3e414a645b35382457f77e4310dabe8b93dbae (patch)
tree29cbe249d716cc4e78347b98d4a8c48a7cbe2d53 /Src
parent4540478d691e397f903c6425957d38d5b0c676b6 (diff)
downloadzsh-4f3e414a645b35382457f77e4310dabe8b93dbae.tar.gz
zsh-4f3e414a645b35382457f77e4310dabe8b93dbae.zip
24025: new zcurses "clear" and "location" subcommands
zcurses window "stdscr" various minor zcurses tweaks
Diffstat (limited to 'Src')
-rw-r--r--Src/Modules/curses.c134
-rw-r--r--Src/Modules/curses_keys.awk2
2 files changed, 119 insertions, 17 deletions
diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c
index 0ea43f1c1..92d906aee 100644
--- a/Src/Modules/curses.c
+++ b/Src/Modules/curses.c
@@ -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;
}
}
@@ -472,6 +493,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)
{
LinkNode node;
@@ -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);
}
diff --git a/Src/Modules/curses_keys.awk b/Src/Modules/curses_keys.awk
index 55a786521..ffb182c35 100644
--- a/Src/Modules/curses_keys.awk
+++ b/Src/Modules/curses_keys.awk
@@ -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
}
}