about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/mod_curses.yo13
-rw-r--r--Src/Modules/curses.c128
3 files changed, 121 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 757821aff..c7c76c3ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-10-30  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 24038: Doc/Zsh/mod_curses.yo, Src/Modules/curses.c: add
+	"zcurses bg".
+
 2007-10-30  Peter Stephenson  <pws@csr.com>
 
 	* users/12149: Doc/Zsh/expn.yo, Src/subst.c,
diff --git a/Doc/Zsh/mod_curses.yo b/Doc/Zsh/mod_curses.yo
index b88c7979b..f83951de3 100644
--- a/Doc/Zsh/mod_curses.yo
+++ b/Doc/Zsh/mod_curses.yo
@@ -22,6 +22,7 @@ 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) )(
 xitem(tt(zcurses) tt(attr) var(targetwin) [ var({+/-}attribute) | var(fg_col)tt(/)var(bg_col) ] [...])
+xitem(tt(zcurses) tt(bg) var(targetwin) [ var({+/-}attribute) | var(fg_col)tt(/)var(bg_col) | tt(@)var(char) ] [...])
 xitem(tt(zcurses) tt(scroll) [ tt(on) | tt(off) | {+/-}var(lines) ])
 xitem(tt(zcurses) tt(input) var(targetwin) [ var(param) [ var(kpparm) ] ])
 item(tt(zcurses) tt(timeout) var(targetwin) var(intval))(
@@ -42,7 +43,7 @@ window is created as a subwindow of var(parentwin).  This differs from an
 ordinary new window in that the memory of the window contents is shared
 with the parent's memory.  Subwindows must be deleted before their parent.
 Note that the coordinates of subwindows are relative to the screen, not
-the parent, as with other windows
+the parent, as with other windows.
 
 Use tt(delwin) to delete a window created with tt(addwin).  Note
 that tt(end) does em(not) implicitly delete windows, and that
@@ -106,6 +107,16 @@ for character output.  The color tt(default) is sometimes available
 or background color with which the terminal started.  The color pair
 tt(default/default) is always available.
 
+tt(bg) overrides the color and other attributes of all characters in the
+window.  Its usual use is to set the background initially, but it will
+overwrite the attributes of any characters at the time when it is called.
+In addition to the arguments allowed with tt(attr), an argument tt(@)var(char)
+specifies a character to be shown in otherwise blank areas of the window.
+Owing to limitations of curses this cannot be a multibyte character
+(use of ASCII characters only is recommended).  As the specified set
+of attributes override the existing background, turning attributes
+off in the arguments is not useful, though this does not cause an error.
+
 tt(scroll) can be used with tt(on) or tt(off) to enabled or disable
 scrolling of a window when the cursor would otherwise move below the
 window due to typing or output.  It can also be used with a positive
diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c
index ae8859726..c9e4ec134 100644
--- a/Src/Modules/curses.c
+++ b/Src/Modules/curses.c
@@ -223,29 +223,20 @@ zcurses_free_window(ZCWin w)
     return 0;
 }
 
-static int
-zcurses_attribute(WINDOW *w, char *attr, int op)
+static struct zcurses_namenumberpair *
+zcurses_attrget(WINDOW *w, char *attr)
 {
     struct zcurses_namenumberpair *zca;
 
     if (!attr)
-	return 1;
+	return NULL;
 
     for(zca=(struct zcurses_namenumberpair *)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 zca;
 	}
 
-    return 1;
+    return NULL;
 }
 
 static short
@@ -261,8 +252,8 @@ zcurses_color(const char *color)
     return (short)-1;
 }
 
-static int
-zcurses_colorset(const char *nam, WINDOW *w, char *colorpair)
+static Colorpairnode
+zcurses_colorget(const char *nam, char *colorpair)
 {
     char *bg, *cp;
     short f, b;
@@ -270,7 +261,7 @@ zcurses_colorset(const char *nam, WINDOW *w, char *colorpair)
 
     /* zcurses_colorpairs is only initialised if color is supported */
     if (!zcurses_colorpairs)
-	return 1;
+	return NULL;
 
     if (zc_color_phase==1 ||
 	!(cpn = (Colorpairnode) gethashnode(zcurses_colorpairs, colorpair))) {
@@ -280,7 +271,7 @@ zcurses_colorset(const char *nam, WINDOW *w, char *colorpair)
 	bg = strchr(cp, '/');
 	if (bg==NULL) {
 	    zsfree(cp);
-	    return 1;
+	    return NULL;
 	}
 
 	*bg = '\0';        
@@ -294,28 +285,28 @@ zcurses_colorset(const char *nam, WINDOW *w, char *colorpair)
 		zwarnnam(nam, "background color `%s' not known", bg+1);
 	    *bg = '/';
 	    zsfree(cp);
-	    return 1;
+	    return NULL;
 	}
 	*bg = '/';
 
 	++next_cp;
 	if (next_cp >= COLOR_PAIRS || init_pair(next_cp, f, b) == ERR)  {
 	    zsfree(cp);
-	    return 1;
+	    return NULL;
 	}
 
 	cpn = (Colorpairnode)zalloc(sizeof(struct colorpairnode));
 	
 	if (!cpn) {
 	    zsfree(cp);
-	    return 1;
+	    return NULL;
 	}
 
 	cpn->colorpair = next_cp;
 	addhashnode(zcurses_colorpairs, cp, (void *)cpn);
     }
 
-    return (wcolor_set(w, cpn->colorpair, NULL) == ERR);
+    return cpn;
 }
 
 static void
@@ -760,11 +751,14 @@ zccmd_attr(const char *nam, char **args)
 
     for(attrs = args+1; *attrs; attrs++) {
 	if (strchr(*attrs, '/')) {
-	    if (zcurses_colorset(nam, w->win, *attrs))
+	    Colorpairnode cpn;
+	    if ((cpn = zcurses_colorget(nam, *attrs)) == NULL ||
+		wcolor_set(w->win, cpn->colorpair, NULL) == ERR)
 		ret = 1;
 	} else {
 	    char *ptr;
 	    int onoff;
+	    struct zcurses_namenumberpair *zca;
 
 	    switch(*attrs[0]) {
 	    case '-':
@@ -780,10 +774,20 @@ zccmd_attr(const char *nam, char **args)
 		ptr = *attrs;
 		break;
 	    }
-	    if (zcurses_attribute(w->win, ptr, onoff)) {
+	    if ((zca = zcurses_attrget(w->win, ptr)) == NULL) {
 		zwarnnam(nam, "attribute `%s' not known", ptr);
 		ret = 1;
 	    }
+	    switch(onoff) {
+		case ZCURSES_ATTRON:
+		    if (wattron(w->win, zca->number) == ERR)
+			ret = 1;
+		    break;
+		case ZCURSES_ATTROFF:
+		    if (wattroff(w->win, zca->number) == ERR)
+			ret = 1;
+		    break;
+	    }
 	}
     }
     return ret;
@@ -791,6 +795,81 @@ zccmd_attr(const char *nam, char **args)
 
 
 static int
+zccmd_bg(const char *nam, char **args)
+{
+    LinkNode node;
+    ZCWin w;
+    char **attrs;
+    int ret = 0;
+    chtype ch = 0;
+
+    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]);
+	return 1;
+    }
+
+    w = (ZCWin)getdata(node);
+
+    for(attrs = args+1; *attrs; attrs++) {
+	if (strchr(*attrs, '/')) {
+	    Colorpairnode cpn;
+	    if ((cpn = zcurses_colorget(nam, *attrs)) == NULL)
+		ret = 1;
+	    else if (cpn->colorpair >= 256) {
+		/* pretty unlikely, but... */
+		zwarnnam(nam, "bg color pair %s has index (%d) too large (max 255)",
+			 cpn->node.nam, cpn->colorpair);
+		ret = 1;
+	    } else {
+		ch |= COLOR_PAIR(cpn->colorpair);
+	    }
+	} else if (**attrs == '@') {
+	    ch |= (*attrs)[1] == Meta ? (*attrs)[2] ^ 32 : (*attrs)[1];
+	} else {
+	    char *ptr;
+	    int onoff;
+	    struct zcurses_namenumberpair *zca;
+
+	    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 ((zca = zcurses_attrget(w->win, ptr)) == NULL) {
+		zwarnnam(nam, "attribute `%s' not known", ptr);
+		ret = 1;
+	    }
+	    switch(onoff) {
+		case ZCURSES_ATTRON:
+		    ch |= zca->number;
+		    break;
+		case ZCURSES_ATTROFF:
+		    ch &= ~zca->number;
+		    break;
+	    }
+	}
+    }
+
+    if (ret == 0)
+	return wbkgd(w->win, ch) != OK;
+    return ret;
+}
+
+
+static int
 zccmd_scroll(const char *nam, char **args)
 {
     LinkNode node;
@@ -1060,6 +1139,7 @@ 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},
+	{"bg", zccmd_bg, 2, -1},
 	{"scroll", zccmd_scroll, 2, 2},
 	{"input", zccmd_input, 1, 3},
 	{"timeout", zccmd_timeout, 2, 2},