summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2007-10-24 21:53:48 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2007-10-24 21:53:48 +0000
commit7489d51823a9ae9076727f9c92d746d5f66d78e2 (patch)
tree16d588ab5e7c4502a8d00fb4df5f883a7e4e8930
parent7988fa65fec5a1a84395fad2a92892fd62ba55c0 (diff)
downloadzsh-7489d51823a9ae9076727f9c92d746d5f66d78e2.tar.gz
zsh-7489d51823a9ae9076727f9c92d746d5f66d78e2.zip
24017: fold zcurses color into attr
add some zcurses parameters a bit of tidying
-rw-r--r--ChangeLog7
-rw-r--r--Doc/Zsh/mod_curses.yo59
-rw-r--r--Src/Modules/curses.c262
3 files changed, 240 insertions, 88 deletions
diff --git a/ChangeLog b/ChangeLog
index 9f6e2d0c3..336cd89ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-10-24 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * 24017: Doc/Zsh/mod_curses.yo, Src/Modules/curses.c:
+ fold color support into attr subcommand and improve error
+ handling; add various readonly parameters; replace strtok();
+ tidy some zwarnnam().
+
2007-10-24 Peter Stephenson <pws@csr.com>
* 24016: configure.ac, Src/Modules/curses.c: compilation with
diff --git a/Doc/Zsh/mod_curses.yo b/Doc/Zsh/mod_curses.yo
index e85aa5c67..a7101f543 100644
--- a/Doc/Zsh/mod_curses.yo
+++ b/Doc/Zsh/mod_curses.yo
@@ -1,7 +1,10 @@
COMMENT(!MOD!zsh/curses
curses windowing commands
!MOD!)
-The tt(zsh/curses) module makes available one builtin command:
+The tt(zsh/curses) module makes available one builtin command and
+various parameters.
+
+subsect(Builtin)
startitem()
findex(zcurses)
@@ -15,7 +18,7 @@ xitem(tt(zcurses) tt(move) var(targetwin) var(new_y) var(new_x) )
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) )(
-item(tt(zcurses) tt(addwin) var(targetwin) var({+/-}attribute) [var({+/-}attribute)] [...])(
+item(tt(zcurses) tt(attr) var(targetwin) [ var({+/-}attribute) | var(fg_col)tt(/)var(bg_col) ] [...])(
Manipulate curses windows. All uses of this command should be
bracketed by `tt(zcurses init)' to initialise use of curses, and
`tt(zcurses end)' to end it; omitting `tt(zcurses end)' can cause
@@ -26,7 +29,8 @@ 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(delwin) to delete a window created with tt(addwin).
+Use tt(delwin) to delete a window created with tt(addwin). Note
+that tt(end) does em(not) implicitly delete windows.
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
@@ -41,10 +45,49 @@ respectively.
To draw a border around window var(targetwin), use tt(border).
-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
-tt(underline).
+tt(attr) will set var(targetwin)'s attributes or foreground/background
+color pair for any successive character output. Each var(attribute)
+given on the line may be prepended by a tt(+) to set or a tt(-) to
+unset that attribute; tt(+) is assumed if absent. The attributes
+supported are tt(blink), tt(bold), tt(dim), tt(reverse), tt(standout),
+and tt(underline). Each var(fg_col)tt(/)var(bg_col) (to be read as
+`var(fg_col) on var(bg_col)') sets the foreground and background color
+for character output.
+)
+enditem()
+
+subsect(Parameters)
+
+startitem()
+vindex(ZCURSES_COLORS)
+item(tt(ZCURSES_COLORS))(
+Readonly integer. The maximum number of colors the terminal
+supports. This value is initialised by the curses library and is not
+available until the first time tt(zcurses init) is run.
+)
+vindex(ZCURSES_COLOR_PAIRS)
+item(tt(ZCURSES_COLOR_PAIRS))(
+Readonly integer. The maximum number of color pairs
+var(fg_col)tt(/)var(bg_col) that may be defined in `tt(zcurses attr)'
+commands; note this limit applies to all color pairs that have been
+used whether or not they are currently active. This value is initialised
+by the curses library and is not available until the first time tt(zcurses
+init) is run.
+)
+vindex(zcurses_attrs)
+item(tt(zcurses_attrs))(
+Readonly array. The attributes supported by tt(zsh/curses); available
+as soon as the module is loaded.
+)
+vindex(zcurses_colors)
+item(tt(zcurses_colors))(
+Readonly array. The colors supported by tt(zsh/curses); available
+as soon as the module is loaded.
+)
+vindex(zcurses_windows)
+item(tt(zcurses_windows))(
+Readonly array. The current list of windows, i.e. all windows that
+have been created with `tt(zcurses addwin)' and not removed with
+`tt(zcurses delwin)'.
)
enditem()
diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c
index dd38b5e95..de9173b9e 100644
--- a/Src/Modules/curses.c
+++ b/Src/Modules/curses.c
@@ -94,6 +94,48 @@ static HashTable zcurses_colorpairs = NULL;
static int zc_errno, zc_color_phase=0;
static short next_cp=0;
+static const struct zcurses_namenumberpair zcurses_attributes[] = {
+ {"blink", A_BLINK},
+ {"bold", A_BOLD},
+ {"dim", A_DIM},
+ {"reverse", A_REVERSE},
+ {"standout", A_STANDOUT},
+ {"underline", A_UNDERLINE},
+ {NULL, 0}
+};
+
+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}
+};
+
+static char **
+zcurses_pairs_to_array(const struct zcurses_namenumberpair *nnps)
+{
+ char **arr, **arrptr;
+ int count;
+ const struct zcurses_namenumberpair *nnptr;
+
+ for (nnptr = nnps; nnptr->name; nnptr++)
+ ;
+ count = nnptr - nnps;
+
+ arrptr = arr = (char **)zhalloc((count+1) * sizeof(char *));
+
+ for (nnptr = nnps; nnptr->name; nnptr++)
+ *arrptr++ = dupstring(nnptr->name);
+ *arrptr = NULL;
+
+ return arr;
+}
+
static const char *
zcurses_strerror(int err)
{
@@ -164,16 +206,6 @@ zcurses_attribute(WINDOW *w, char *attr, int op)
{
struct zcurses_namenumberpair *zca;
- static const struct zcurses_namenumberpair 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;
@@ -199,18 +231,6 @@ zcurses_color(const 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 (short)zc->number;
@@ -220,9 +240,9 @@ zcurses_color(const char *color)
}
static int
-zcurses_colorset(WINDOW *w, char *colorpair)
+zcurses_colorset(const char *nam, WINDOW *w, char *colorpair)
{
- char *fg, *bg, *cp;
+ char *bg, *cp;
short f, b;
Colorpairnode cpn;
@@ -230,36 +250,43 @@ zcurses_colorset(WINDOW *w, char *colorpair)
!(cpn = (Colorpairnode) gethashnode(zcurses_colorpairs, colorpair))) {
zc_color_phase = 2;
cp = ztrdup(colorpair);
- fg = strtok(cp, "/");
- bg = strtok(NULL, "/");
+ bg = strchr(cp, '/');
if (bg==NULL) {
zsfree(cp);
return 1;
}
-
- f = zcurses_color(fg);
- b = zcurses_color(bg);
- zsfree(cp);
+ *bg = '\0';
+ f = zcurses_color(cp);
+ b = zcurses_color(bg+1);
- if (f==-1 || b==-1)
+ if (f==-1 || b==-1) {
+ if (f == -1)
+ zwarnnam(nam, "foreground color `%s' not known", cp);
+ if (b == -1)
+ zwarnnam(nam, "background color `%s' not known", bg+1);
+ *bg = '/';
+ zsfree(cp);
return 1;
+ }
+ *bg = '/';
++next_cp;
- if (next_cp >= COLOR_PAIRS)
- return 1;
-
- if (init_pair(next_cp, f, b) == ERR)
+ if (next_cp >= COLOR_PAIRS || init_pair(next_cp, f, b) == ERR) {
+ zsfree(cp);
return 1;
+ }
cpn = (Colorpairnode)zalloc(sizeof(struct colorpairnode));
- if (!cpn)
+ if (!cpn) {
+ zsfree(cp);
return 1;
+ }
cpn->colorpair = next_cp;
- addhashnode(zcurses_colorpairs, ztrdup(colorpair), (void *)cpn);
+ addhashnode(zcurses_colorpairs, cp, (void *)cpn);
}
return (wcolor_set(w, cpn->colorpair, NULL) == ERR);
@@ -353,14 +380,14 @@ zccmd_delwin(const char *nam, char **args)
node = zcurses_validate_window(args[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), args[0]);
return 1;
}
w = (ZCWin)getdata(node);
if (w == NULL) {
- zwarnnam(nam, "record for window `%s' is corrupt", args[0], 0);
+ zwarnnam(nam, "record for window `%s' is corrupt", args[0]);
return 1;
}
if (delwin(w->win)!=OK)
@@ -408,7 +435,7 @@ zccmd_move(const char *nam, char **args)
node = zcurses_validate_window(args[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), args[0]);
return 1;
}
@@ -436,7 +463,7 @@ zccmd_char(const char *nam, char **args)
node = zcurses_validate_window(args[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), args[0]);
return 1;
}
@@ -475,7 +502,7 @@ zccmd_string(const char *nam, char **args)
node = zcurses_validate_window(args[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), args[0]);
return 1;
}
@@ -511,7 +538,7 @@ zccmd_border(const char *nam, char **args)
node = zcurses_validate_window(args[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), args[0]);
return 1;
}
@@ -555,52 +582,44 @@ zccmd_attr(const char *nam, char **args)
node = zcurses_validate_window(args[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), args[0]);
return 1;
}
w = (ZCWin)getdata(node);
for(attrs = args+1; *attrs; attrs++) {
- switch(*attrs[0]) {
- case '-':
- if (zcurses_attribute(w->win, (*attrs)+1, ZCURSES_ATTROFF))
+ if (strchr(*attrs, '/')) {
+ if (zcurses_colorset(nam, w->win, *attrs))
ret = 1;
- break;
- case '+':
- if (zcurses_attribute(w->win, (*attrs)+1, ZCURSES_ATTRON))
+ } else {
+ char *ptr;
+ int onoff;
+
+ switch(*attrs[0]) {
+ case '-':
+ onoff = ZCURSES_ATTROFF;
+ ptr = (*attrs) + 1;
+ break;
+ case '+':
+ onoff = ZCURSES_ATTRON;
+ ptr = (*attrs) + 1;
+ break;
+ default:
+ onoff = ZCURSES_ATTRON;
+ ptr = *attrs;
+ break;
+ }
+ if (zcurses_attribute(w->win, ptr, onoff)) {
+ zwarnnam(nam, "attribute `%s' not known", ptr);
ret = 1;
- break;
- default:
- /* maybe a bad idea to spew warnings here */
- break;
+ }
}
}
return ret;
}
-static int
-zccmd_color(const char *nam, char **args)
-{
- 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]);
-}
-
-
/*********************
Main builtin handler
*********************/
@@ -624,7 +643,6 @@ bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func))
{"border", zccmd_border, 1, 1},
{"end", zccmd_endwin, 0, 0},
{"attr", zccmd_attr, 2, -1},
- {"color", zccmd_color, 2, 2},
{NULL, (zccmd_t)0, 0, 0}
};
@@ -653,19 +671,103 @@ bin_zcurses(char *nam, char **args, Options ops, UNUSED(int func))
return zcsc->cmd(nam, args+1);
}
-/*
- * boot_ is executed when the module is loaded.
- */
static struct builtin bintab[] = {
BUILTIN("zcurses", 0, bin_zcurses, 1, 6, 0, "", NULL),
};
+
+/*******************
+ * Special variables
+ *******************/
+
+static char **
+zcurses_colorsarrgetfn(UNUSED(Param pm))
+{
+ return zcurses_pairs_to_array(zcurses_colors);
+}
+
+static const struct gsu_array zcurses_colorsarr_gsu =
+{ zcurses_colorsarrgetfn, arrsetfn, stdunsetfn };
+
+
+static char **
+zcurses_attrgetfn(UNUSED(Param pm))
+{
+ return zcurses_pairs_to_array(zcurses_attributes);
+}
+
+static const struct gsu_array zcurses_attrs_gsu =
+{ zcurses_attrgetfn, arrsetfn, stdunsetfn };
+
+
+static char **
+zcurses_windowsgetfn(UNUSED(Param pm))
+{
+ LinkNode node;
+ char **arr, **arrptr;
+ int count = countlinknodes(zcurses_windows);
+
+ arrptr = arr = (char **)zhalloc((count+1) * sizeof(char *));
+
+ for (node = firstnode(zcurses_windows); node; incnode(node))
+ *arrptr++ = dupstring(((ZCWin)getdata(node))->name);
+ *arrptr = NULL;
+
+ return arr;
+}
+
+static const struct gsu_array zcurses_windows_gsu =
+{ zcurses_windowsgetfn, arrsetfn, stdunsetfn };
+
+
+static zlong
+zcurses_colorsintgetfn(UNUSED(Param pm))
+{
+ return COLORS;
+}
+
+static const struct gsu_integer zcurses_colorsint_gsu =
+{ zcurses_colorsintgetfn, nullintsetfn, stdunsetfn };
+
+
+static zlong
+zcurses_colorpairsintgetfn(UNUSED(Param pm))
+{
+ return COLOR_PAIRS;
+}
+
+static const struct gsu_integer zcurses_colorpairsint_gsu =
+{ zcurses_colorpairsintgetfn, nullintsetfn, stdunsetfn };
+
+
+static struct paramdef partab[] = {
+ SPECIALPMDEF("zcurses_colors", PM_ARRAY|PM_READONLY,
+ &zcurses_colorsarr_gsu, NULL, NULL),
+ SPECIALPMDEF("zcurses_attrs", PM_ARRAY|PM_READONLY,
+ &zcurses_attrs_gsu, NULL, NULL),
+ SPECIALPMDEF("zcurses_windows", PM_ARRAY|PM_READONLY,
+ &zcurses_windows_gsu, NULL, NULL),
+ SPECIALPMDEF("ZCURSES_COLORS", PM_INTEGER|PM_READONLY,
+ &zcurses_colorsint_gsu, NULL, NULL),
+ SPECIALPMDEF("ZCURSES_COLOR_PAIRS", PM_INTEGER|PM_READONLY,
+ &zcurses_colorpairsint_gsu, NULL, NULL)
+};
+
+/***************************
+ * Standard module interface
+ ***************************/
+
+
+/*
+ * boot_ is executed when the module is loaded.
+ */
+
static struct features module_features = {
bintab, sizeof(bintab)/sizeof(*bintab),
NULL, 0,
NULL, 0,
- NULL, 0,
+ partab, sizeof(partab)/sizeof(*partab),
0
};