Add support for different background colors. - sam - An updated version of the sam text editor.
(HTM) git clone git://vernunftzentrum.de/sam.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) LICENSE
---
(DIR) commit 633439bcbcf35eaaf0f3ba743049f29f72d08bea
(DIR) parent 632c20a10fb43613d36dee2b577208779e9582e1
(HTM) Author: Rob King <jking@deadpixi.com>
Date: Sun, 14 Aug 2016 23:02:35 -0500
Add support for different background colors.
Diffstat:
include/frame.h | 10 +++++++---
include/libg.h | 1 +
libXg/balloc.c | 1 -
libXg/bitblt.c | 11 ++++++++++-
libXg/gcs.c | 28 ++++++++++++++++++++--------
libXg/libgint.h | 2 ++
libXg/string.c | 1 -
libXg/xtbinit.c | 16 ++++++++++++----
libframe/frdelete.c | 8 ++++----
libframe/frinit.c | 3 ++-
libframe/frinsert.c | 12 ++++++------
libframe/frselect.c | 12 ++++++------
samterm/flayer.c | 23 +++++++++++++----------
samterm/flayer.h | 7 ++++++-
samterm/main.c | 6 ++++--
samterm/menu.c | 4 +++-
16 files changed, 96 insertions(+), 49 deletions(-)
---
(DIR) diff --git a/include/frame.h b/include/frame.h
@@ -16,11 +16,15 @@ struct Frbox
} a;
};
+/* note that we track background color, but not foreground
+ * this is because the foreground color is the same for all frames
+ */
struct Frame
{
+ unsigned long bg; /* background color */
XftFont *font; /* of chars in the frame */
- Bitmap *b; /* on which frame appears */
- Rectangle r; /* in which text appears */
+ Bitmap *b; /* on which frame appears */
+ Rectangle r; /* in which text appears */
Rectangle entire; /* of full frame */
Frbox *box;
ulong p0, p1; /* selection */
@@ -42,7 +46,7 @@ void frinsert(Frame*, Rune*, Rune*, ulong);
void frselect(Frame*, Mouse*);
void frselectp(Frame*, Fcode);
void frselectf(Frame*, Point, Point, Fcode);
-void frinit(Frame*, Rectangle, XftFont*, Bitmap*);
+void frinit(Frame*, Rectangle, XftFont*, Bitmap*, unsigned long);
void frsetrects(Frame*, Rectangle, Bitmap*);
void frclear(Frame*);
void frgetmouse(void);
(DIR) diff --git a/include/libg.h b/include/libg.h
@@ -155,6 +155,7 @@ extern int rectclip(Rectangle*, Rectangle);
extern void xtbinit(Errfunc, char*, int*, char**, char**);
extern void bclose(void);
extern void berror(char*);
+extern void bitblt2(Bitmap*, Point, Bitmap*, Rectangle, Fcode, unsigned long);
extern void bitblt(Bitmap*, Point, Bitmap*, Rectangle, Fcode);
extern void copymasked(Bitmap*, Point, Bitmap*, Bitmap*, Rectangle);
extern int bitbltclip(void*);
(DIR) diff --git a/libXg/balloc.c b/libXg/balloc.c
@@ -57,7 +57,6 @@ bfree(Bitmap *b)
{
if (b->fd)
XftDrawDestroy(b->fd);
-
XFreePixmap(_dpy, (Pixmap)b->id);
free(b);
}
(DIR) diff --git a/libXg/bitblt.c b/libXg/bitblt.c
@@ -7,11 +7,20 @@
void
bitblt(Bitmap *d, Point p, Bitmap *s, Rectangle r, Fcode f)
{
+ bitblt2(d, p, s, r, f, _bgpixel);
+}
+
+void
+bitblt2(Bitmap *d, Point p, Bitmap *s, Rectangle r, Fcode f, unsigned long bg)
+{
int sx, sy, dx, dy, bfunc;
GC g;
unsigned long plane;
Bitmap *btmp;
+ if (bg == 0)
+ bg = _bgpixel;
+
if(Dx(r)<=0 || Dy(r)<=0)
return;
sx = r.min.x;
@@ -26,7 +35,7 @@ bitblt(Bitmap *d, Point p, Bitmap *s, Rectangle r, Fcode f)
dx -= d->r.min.x;
dy -= d->r.min.y;
}
- g = _getcopygc(f, d, s, &bfunc);
+ g = _getcopygc2(f, d, s, &bfunc, bg);
if(bfunc == UseCopyArea)
XCopyArea(_dpy, (Drawable)s->id, (Drawable)d->id, g,
sx, sy, Dx(r), Dy(r), dx, dy);
(DIR) diff --git a/libXg/gcs.c b/libXg/gcs.c
@@ -201,10 +201,18 @@ _getgc(Bitmap *b, unsigned long gcvm, XGCValues *pgcv)
GC
_getfillgc(Fcode f, Bitmap *b, unsigned long val)
{
+ return _getfillgc2(f, b, val, _bgpixel);
+}
+
+GC
+_getfillgc2(Fcode f, Bitmap *b, unsigned long val, unsigned long bg)
+{
int xf, m;
- unsigned long v, fg, bg, spix, vmax;
+ unsigned long v, spix, vmax;
XGCValues gcv;
+ unsigned long fg = _fgpixel;
+
f &= F;
vmax = _ld2dmask[b->ldepth];
v = val & vmax;
@@ -214,8 +222,6 @@ _getfillgc(Fcode f, Bitmap *b, unsigned long val)
if(m & DP1){
xf = (m&BL1)? gx[f] : d0s1gx[f];
}else{
- fg = _fgpixel;
- bg = _bgpixel;
switch(f){
case Zero:
labZero:
@@ -297,19 +303,26 @@ _getfillgc(Fcode f, Bitmap *b, unsigned long val)
GC
_getcopygc(Fcode f, Bitmap *db, Bitmap *sb, int *bltfunc)
{
- unsigned long spix, bg, fg, df, sf;
+ return _getcopygc2(f, db, sb, bltfunc, _bgpixel);
+}
+
+GC
+_getcopygc2(Fcode f, Bitmap *db, Bitmap *sb, int *bltfunc, unsigned long bg)
+{
+ unsigned long spix, df, sf;
int xf, c;
XGCValues gcv;
unsigned long gcvm;
+ unsigned long fg = _fgpixel;
+
f &= F;
gcvm = 0;
df = db->flag;
if(degengc[f]){
*bltfunc = UseFillRectangle;
if(df&SCR || !(df&DP1)){
- fg = _fgpixel;
- bg = _bgpixel;
+ // nothing XXX
}else{
/* must be DP1 and BL1 */
fg = 1;
@@ -373,8 +386,7 @@ _getcopygc(Fcode f, Bitmap *db, Bitmap *sb, int *bltfunc)
case code(0,DP1|BL1):
case code(BL1,DP1|BL1):
- fg = _fgpixel;
- bg = _bgpixel;
+ // nothing XXX
break;
case code(DP1|BL1,0):
fg = 0;
(DIR) diff --git a/libXg/libgint.h b/libXg/libgint.h
@@ -34,6 +34,8 @@ typedef char* caddr_t;
/* Return a GCs for solid filling/strings/etc., segments/points, and tiling */
extern GC _getfillgc(Fcode, Bitmap*, unsigned long);
extern GC _getcopygc(Fcode, Bitmap*, Bitmap*, int*);
+extern GC _getfillgc2(Fcode, Bitmap*, unsigned long, unsigned long);
+extern GC _getcopygc2(Fcode, Bitmap*, Bitmap*, int*, unsigned long);
extern GC _getgc(Bitmap*, unsigned long, XGCValues *);
/* convert between different bitmap depths */
(DIR) diff --git a/libXg/string.c b/libXg/string.c
@@ -27,7 +27,6 @@ string(Bitmap *b, Point p, XftFont *ft, char *s, Fcode f)
if (!b->fd)
b->fd = XftDrawCreate(_dpy, (Drawable)(b->id), DefaultVisual(_dpy, DefaultScreen(_dpy)), DefaultColormap(_dpy, DefaultScreen(_dpy)));
-
XftDrawStringUtf8(b->fd, &fontcolor, ft, x, y, s, length);
x += extents.xOff;
(DIR) diff --git a/libXg/xtbinit.c b/libXg/xtbinit.c
@@ -41,8 +41,8 @@ XftColor bgcolor;
extern char *machine;
Display *_dpy;
Widget _toplevel;
-unsigned long _fgpixel, _bgpixel;
-XColor _fgcolor, _bgcolor;
+unsigned long _fgpixel, _bgpixel, _cmdbgpixel;
+XColor _fgcolor, _bgcolor, _cmdbgcolor;
int _ld2d[6] = { 1, 2, 4, 8, 16, 24 };
unsigned long _ld2dmask[6] = { 0x1, 0x3, 0xF, 0xFF, 0xFFFF, 0x00FFFFFF };
Colormap _libg_cmap;
@@ -162,9 +162,17 @@ xtbinit(Errfunc f, char *class, int *pargc, char **argv, char **fallbacks)
XtSetArg(args[n], XtNgotmouse, gotmouse); n++;
widg = XtCreateManagedWidget("gwin", gwinWidgetClass, _toplevel, args, n);
+ char bgspec[512] = {0};
+ snprintf(bgspec, sizeof(bgspec) - 1, "%s", getenv("BACKGROUND") ? getenv("BACKGROUND") : "#ffffff");
+
+ char tbg[512], cbg[512];
+ if (sscanf(bgspec, "%511[^:]:%s", &tbg, &cbg) == 1)
+ strncpy(cbg, tbg, sizeof(cbg) - 1);
+
_dpy = XtDisplay(widg);
XAllocNamedColor(_dpy, DefaultColormap(_dpy, DefaultScreen(_dpy)), getenv("FOREGROUND") ? getenv("FOREGROUND") : "#000000", &_fgcolor, &_fgcolor);
- XAllocNamedColor(_dpy, DefaultColormap(_dpy, DefaultScreen(_dpy)), getenv("BACKGROUND") ? getenv("BACKGROUND") : "#ffffff", &_bgcolor, &_bgcolor);
+ XAllocNamedColor(_dpy, DefaultColormap(_dpy, DefaultScreen(_dpy)), tbg, &_bgcolor, &_bgcolor);
+ XAllocNamedColor(_dpy, DefaultColormap(_dpy, DefaultScreen(_dpy)), cbg, &_cmdbgcolor, &_cmdbgcolor);
n = 0;
XtSetArg(args[n], XtNdepth, &depth); n++;
@@ -181,12 +189,12 @@ xtbinit(Errfunc f, char *class, int *pargc, char **argv, char **fallbacks)
screen.id = 0;
XtRealizeWidget(_toplevel);
-
pid_t pid = getpid();
XChangeProperty(_dpy, XtWindow(_toplevel), XInternAtom(_dpy, "_NET_WM_PID", False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1);
_fgpixel = _fgcolor.pixel;
_bgpixel = _bgcolor.pixel;
+ _cmdbgpixel = _cmdbgcolor.pixel;
XRenderColor xrcolor = {0};
xrcolor.red = _fgcolor.red;
(DIR) diff --git a/libframe/frdelete.c b/libframe/frdelete.c
@@ -53,10 +53,10 @@ frdelete(Frame *f, ulong p0, ulong p1)
r.max = pt1;
r.max.x += b->wid;
r.max.y += f->fheight;
- bitblt(f->b, pt0, f->b, r, S);
+ bitblt2(f->b, pt0, f->b, r, S, f->bg);
if(pt0.y == pt1.y)
r.min.x = r.max.x-(pt1.x-pt0.x);
- bitblt(f->b, r.min, f->b, r, 0);
+ bitblt2(f->b, r.min, f->b, r, 0, f->bg);
}
_fradvance(f, &pt1, b);
pt0.x += _frnewwid(f, pt0, b);
@@ -75,8 +75,8 @@ frdelete(Frame *f, ulong p0, ulong p1)
q0 = pt0.y+f->fheight;
q1 = pt1.y+f->fheight;
q2 = pt2.y+f->fheight;
- bitblt(f->b, pt0, f->b, Rect(pt1.x, pt1.y, f->r.max.x, q1), S);
- bitblt(f->b, Pt(f->r.min.x, q0), f->b, Rect(f->r.min.x, q1, f->r.max.x, q2), S);
+ bitblt2(f->b, pt0, f->b, Rect(pt1.x, pt1.y, f->r.max.x, q1), S, f->bg);
+ bitblt2(f->b, Pt(f->r.min.x, q0), f->b, Rect(f->r.min.x, q1, f->r.max.x, q2), S, f->bg);
frselectf(f, Pt(pt2.x, pt2.y-(pt1.y-pt0.y)), pt2, 0);
}else
frselectf(f, pt0, pt2, 0);
(DIR) diff --git a/libframe/frinit.c b/libframe/frinit.c
@@ -8,7 +8,7 @@ int tabwidth = 8;
extern int expandtabs;
void
-frinit(Frame *f, Rectangle r, XftFont *ft, Bitmap *b)
+frinit(Frame *f, Rectangle r, XftFont *ft, Bitmap *b, unsigned long bg)
{
int tabs = atoi(getenv("TABS") ? getenv("TABS") : "");
if (tabs < 0){
@@ -32,6 +32,7 @@ frinit(Frame *f, Rectangle r, XftFont *ft, Bitmap *b)
f->p1 = 0;
f->box = 0;
f->lastlinefull = 0;
+ f->bg = bg;
frsetrects(f, r, b);
}
(DIR) diff --git a/libframe/frinsert.c b/libframe/frinsert.c
@@ -185,16 +185,16 @@ frinsert(Frame *f, Rune *sp, Rune *ep, ulong p0)
r.min.y = q0;
r.max.y = y-(q1-q0);
if(q1 < y)
- bitblt(f->b, Pt(f->r.min.x, q1), f->b, r, S);
+ bitblt2(f->b, Pt(f->r.min.x, q1), f->b, r, S, f->bg);
r.min = pt0;
r.max.y = q0;
- bitblt(f->b, pt1, f->b, r, S);
+ bitblt2(f->b, pt1, f->b, r, S, f->bg);
}
}
/*
* Move the old stuff down to make room. The loop will move the stuff
* between the insertion and the point where the x's lined up.
- * The bitblts above moved everything down after the point they lined up.
+ * The bitblt2 above moved everything down after the point they lined up.
*/
for((y=pt1.y==f->r.max.y?pt1.y:0),b = &f->box[n0-1]; --npts>=0; --b){
pt = pts[npts].pt1;
@@ -203,14 +203,14 @@ frinsert(Frame *f, Rune *sp, Rune *ep, ulong p0)
r.max = r.min;
r.max.x += b->wid;
r.max.y += f->fheight;
- bitblt(f->b, pt, f->b, r, S);
+ bitblt2(f->b, pt, f->b, r, S, f->bg);
if(pt.y < y){ /* clear bit hanging off right */
r.min = pt;
r.max = pt;
r.min.x += b->wid;
r.max.x = f->r.max.x;
r.max.y += f->fheight;
- bitblt(f->b, r.min, f->b, r, 0);
+ bitblt2(f->b, r.min, f->b, r, 0, f->bg);
}
y = pt.y;
}else{
@@ -220,7 +220,7 @@ frinsert(Frame *f, Rune *sp, Rune *ep, ulong p0)
r.max.y += f->fheight;
if(r.max.x >= f->r.max.x)
r.max.x = f->r.max.x;
- bitblt(f->b, r.min, f->b, r, 0);
+ bitblt2(f->b, r.min, f->b, r, 0, f->bg);
y = (pt.x == f->left)? pt.y : 0;
}
}
(DIR) diff --git a/libframe/frselect.c b/libframe/frselect.c
@@ -70,16 +70,16 @@ frselectf(Frame *f, Point p0, Point p1, Fcode c)
q1.x++;
else
p0.x--;
- bitblt(f->b, p0, f->b, Rpt(p0, q1), c);
+ bitblt2(f->b, p0, f->b, Rpt(p0, q1), c, f->bg);
}else{
if(p0.x >= f->r.max.x)
p0.x = f->r.max.x-1;
- bitblt(f->b, p0, f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), c);
+ bitblt2(f->b, p0, f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), c, f->bg);
if(n > 1)
- bitblt(f->b, Pt(f->r.min.x, q0.y),
- f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y), c);
- bitblt(f->b, Pt(f->r.min.x, p1.y),
- f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y), c);
+ bitblt2(f->b, Pt(f->r.min.x, q0.y),
+ f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y), c, f->bg);
+ bitblt2(f->b, Pt(f->r.min.x, p1.y),
+ f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y), c, f->bg);
}
}
(DIR) diff --git a/samterm/flayer.c b/samterm/flayer.c
@@ -16,6 +16,8 @@ static Rectangle lDrect;
extern Bitmap screen;
extern Mouse mouse;
+extern unsigned long _bgpixel;
+
Vis visibility(Flayer *);
void newvisibilities(int);
void llinsert(Flayer*);
@@ -39,6 +41,7 @@ flnew(Flayer *l, Rune *(*fn)(Flayer*, long, ulong*), int u0, void *u1)
l->textfn = fn;
l->user0 = u0;
l->user1 = u1;
+ l->bg = _bgpixel;
llinsert(l);
}
@@ -54,15 +57,15 @@ flrect(Flayer *l, Rectangle r)
}
void
-flinit(Flayer *l, Rectangle r, XftFont *ft)
+flinit(Flayer *l, Rectangle r, XftFont *ft, unsigned long bg)
{
lldelete(l);
llinsert(l);
l->visible = All;
l->origin = l->p0 = l->p1 = 0;
- frinit(&l->f, inset(flrect(l, r), FLMARGIN), ft, &screen);
+ frinit(&l->f, inset(flrect(l, r), FLMARGIN), ft, &screen, bg);
newvisibilities(1);
- bitblt(&screen, l->entire.min, &screen, l->entire, 0);
+ bitblt2(&screen, l->entire.min, &screen, l->entire, 0, l->bg);
scrdraw(l, 0L);
flborder(l, 0);
}
@@ -71,12 +74,12 @@ void
flclose(Flayer *l)
{
if(l->visible == All)
- bitblt(&screen, l->entire.min, &screen, l->entire, 0);
+ bitblt2(&screen, l->entire.min, &screen, l->entire, 0, l->bg);
else if(l->visible == Some){
if(l->f.b == 0)
l->f.b = balloc(l->entire, screen.ldepth);
if(l->f.b){
- bitblt(l->f.b, l->entire.min, l->f.b, l->entire, 0);
+ bitblt2(l->f.b, l->entire.min, l->f.b, l->entire, 0, l->bg);
flrefresh(l, l->entire, 0);
}
}
@@ -163,7 +166,7 @@ newvisibilities(int redraw)
case V(Some, All):
if(l->f.b){
- bitblt(&screen, l->entire.min, l->f.b, l->entire, S);
+ bitblt2(&screen, l->entire.min, l->f.b, l->entire, S, l->bg);
bfree(l->f.b);
l->f.b = &screen;
break;
@@ -316,7 +319,7 @@ flreshape(Rectangle dr)
lDrect = dr;
move = 0;
/* no moving on rio; must repaint */
- bitblt(&screen, lDrect.min, &screen, lDrect, 0);
+ bitblt2(&screen, lDrect.min, &screen, lDrect, 0, l->bg);
for(i=0; i<nllist; i++){
l = llist[i];
f = &l->f;
@@ -368,10 +371,10 @@ flprepare(Flayer *l)
f->b = &screen;
else if((f->b = balloc(l->entire, screen.ldepth))==0)
return 0;
- bitblt(f->b, l->entire.min, f->b, l->entire, 0);
+ bitblt2(f->b, l->entire.min, f->b, l->entire, 0, l->bg);
border(f->b, l->entire, l==llist[0]? FLMARGIN : 1, F&~D);
n = f->nchars;
- frinit(f, f->entire, f->font, f->b);
+ frinit(f, f->entire, f->font, f->b, l->bg);
r = (*l->textfn)(l, n, &n);
frinsert(f, r, r+n, (ulong)0);
frselectp(f, F&~D);
@@ -407,7 +410,7 @@ flrefresh(Flayer *l, Rectangle r, int i)
Top:
if((t=llist[i++]) == l){
if(!justvis)
- bitblt(&screen, r.min, l->f.b, r, S);
+ bitblt2(&screen, r.min, l->f.b, r, S, l->bg);
somevis = 1;
}else{
if(!rectXrect(t->entire, r))
(DIR) diff --git a/samterm/flayer.h b/samterm/flayer.h
@@ -12,8 +12,13 @@ enum{
typedef struct Flayer Flayer;
+/* note that we track background color, but not foreground
+ * all layers have the same foreground color, but they may have different
+ * background colors.
+ */
struct Flayer
{
+ unsigned long bg;
Frame f;
long origin; /* offset of first char in flayer */
long p0, p1;
@@ -30,7 +35,7 @@ void flborder(Flayer*, int);
void flclose(Flayer*);
void fldelete(Flayer*, long, long);
void flfp0p1(Flayer*, ulong*, ulong*);
-void flinit(Flayer*, Rectangle, XftFont*);
+void flinit(Flayer*, Rectangle, XftFont*, unsigned long bg);
void flinsert(Flayer*, Rune*, Rune*, long);
void flnew(Flayer*, Rune *(*fn)(Flayer*, long, ulong*), int, void*);
int flprepare(Flayer*);
(DIR) diff --git a/samterm/main.c b/samterm/main.c
@@ -8,6 +8,7 @@
#include "samterm.h"
#include <commands.h>
+extern unsigned long _bgpixel, _cmdbgpixel;
Text cmd;
Rune *scratch;
long nscralloc;
@@ -65,7 +66,8 @@ main(int argc, char *argv[])
flstart(screen.clipr);
rinit(&cmd.rasp);
flnew(&cmd.l[0], stgettext, 1, &cmd);
- flinit(&cmd.l[0], r, font);
+ cmd.l[0].bg = _cmdbgpixel;
+ flinit(&cmd.l[0], r, font, cmd.l[0].bg);
cmd.nwin = 1;
which = &cmd.l[0];
cmd.tag = Untagged;
@@ -239,7 +241,7 @@ duplicate(Flayer *l, Rectangle r, XftFont *f, int close)
if(nl){
flnew(nl, stgettext, l->user0, (char *)t);
- flinit(nl, r, f);
+ flinit(nl, r, f, l->bg);
nl->origin = l->origin;
rp = (*l->textfn)(l, l->f.nchars, &n);
flinsert(nl, rp, rp+n, l->origin);
(DIR) diff --git a/samterm/menu.c b/samterm/menu.c
@@ -16,6 +16,8 @@ char *genmenu3(int);
char *genmenu2(int);
char *genmenu2c(int);
+extern unsigned long _bgpixel;
+
enum Menu2
{
Cut,
@@ -196,7 +198,7 @@ sweeptext(int new, int tag)
memset((void*)t, 0, sizeof(Text));
current((Flayer *)0);
flnew(&t->l[0], stgettext, 0, (char *)t);
- flinit(&t->l[0], r, font); /*bnl*/
+ flinit(&t->l[0], r, font, _bgpixel); /*bnl*/
t->nwin = 1;
rinit(&t->rasp);
if(new)