Introduction
Introduction Statistics Contact Development Disclaimer Help
tcleanup & bugfix in xdraws(). - st - [fork] customized build of st, the simple…
git clone git://src.adamsgaard.dk/st
Log
Files
Refs
README
LICENSE
---
commit b61925b5d6fd8af0ad0ccc922db60dff1746cfe2
parent 81a048d6cfda84a06353911130fee029df077c8d
Author: AurĂ©lien Aptel <[email protected]>
Date: Sat, 20 Nov 2010 22:24:04 +0100
cleanup & bugfix in xdraws().
Diffstat:
M st.c | 251 +++++++++++++++--------------…
1 file changed, 125 insertions(+), 126 deletions(-)
---
diff --git a/st.c b/st.c
t@@ -131,20 +131,17 @@ typedef struct {
char s[ESC_BUF_SIZ];
} Key;
-typedef struct {
- XFontSet fs;
- short lbearing;
- short rbearing;
- int ascent;
- int descent;
-} FontInfo;
-
/* Drawing Context */
typedef struct {
unsigned long col[256];
- FontInfo font;
- FontInfo bfont;
GC gc;
+ struct {
+ int ascent;
+ int descent;
+ short lbearing;
+ short rbearing;
+ XFontSet set;
+ } font, bfont;
} DC;
/* TODO: use better name for vars... */
t@@ -222,10 +219,10 @@ static inline int selected(int, int);
static void selcopy(void);
static void selpaste(void);
-static int stou(char *, long *);
-static int utos(long *, char *);
-static int slen(char *);
-static int canstou(char *, int);
+static int utf8decode(char *, long *);
+static int utf8encode(long *, char *);
+static int utf8size(char *);
+static int isfullutf8(char *, int);
static void (*handler[LASTEvent])(XEvent *) = {
[KeyPress] = kpress,
t@@ -254,8 +251,8 @@ static char *opt_cmd = NULL;
static char *opt_title = NULL;
static char *opt_class = NULL;
-/* UTF-8 decode */
-static int stou(char *s, long *u) {
+int
+utf8decode(char *s, long *u) {
unsigned char c;
int i, n, rtn;
t@@ -264,28 +261,28 @@ static int stou(char *s, long *u) {
if(~c&B7) { /* 0xxxxxxx */
*u = c;
return rtn;
- } else if ((c&(B7|B6|B5)) == (B7|B6)) { /* 110xxxxx */
+ } else if((c&(B7|B6|B5)) == (B7|B6)) { /* 110xxxxx */
*u = c&(B4|B3|B2|B1|B0);
n = 1;
- } else if ((c&(B7|B6|B5|B4)) == (B7|B6|B5)) { /* 1110xxxx */
+ } else if((c&(B7|B6|B5|B4)) == (B7|B6|B5)) { /* 1110xxxx */
*u = c&(B3|B2|B1|B0);
n = 2;
- } else if ((c&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4)) { /* 11110xxx */
+ } else if((c&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4)) { /* 11110xxx */
*u = c&(B2|B1|B0);
n = 3;
} else
goto invalid;
- for (i=n,++s; i>0; --i,++rtn,++s) {
+ for(i=n,++s; i>0; --i,++rtn,++s) {
c = *s;
- if ((c&(B7|B6)) != B7) /* 10xxxxxx */
+ if((c&(B7|B6)) != B7) /* 10xxxxxx */
goto invalid;
*u <<= 6;
*u |= c&(B5|B4|B3|B2|B1|B0);
}
- if ((n == 1 && *u < 0x80) ||
- (n == 2 && *u < 0x800) ||
- (n == 3 && *u < 0x10000) ||
- (*u >= 0xD800 && *u <= 0xDFFF))
+ if((n == 1 && *u < 0x80) ||
+ (n == 2 && *u < 0x800) ||
+ (n == 3 && *u < 0x10000) ||
+ (*u >= 0xD800 && *u <= 0xDFFF))
goto invalid;
return rtn;
invalid:
t@@ -293,30 +290,30 @@ invalid:
return rtn;
}
-/* UTF-8 encode */
-static int utos(long *u, char *s) {
+int
+utf8encode(long *u, char *s) {
unsigned char *sp;
unsigned long uc;
int i, n;
sp = (unsigned char*) s;
uc = *u;
- if (uc < 0x80) {
+ if(uc < 0x80) {
*sp = uc; /* 0xxxxxxx */
return 1;
- } else if (*u < 0x800) {
+ } else if(*u < 0x800) {
*sp = (uc >> 6) | (B7|B6); /* 110xxxxx */
n = 1;
- } else if (uc < 0x10000) {
+ } else if(uc < 0x10000) {
*sp = (uc >> 12) | (B7|B6|B5); /* 1110xxxx */
n = 2;
- } else if (uc <= 0x10FFFF) {
+ } else if(uc <= 0x10FFFF) {
*sp = (uc >> 18) | (B7|B6|B5|B4); /* 11110xxx */
n = 3;
} else {
goto invalid;
}
- for (i=n,++sp; i>0; --i,++sp)
+ for(i=n,++sp; i>0; --i,++sp)
*sp = ((uc >> 6*(i-1)) & (B5|B4|B3|B2|B1|B0)) | B7; /* 10xxxxx…
return n+1;
invalid:
t@@ -329,34 +326,32 @@ invalid:
/* use this if your buffer is less than UTF_SIZ, it returns 1 if you can decode
UTF-8 otherwise return 0 */
-static int canstou(char *s, int b) {
- unsigned char c = *s;
- int n;
+int
+isfullutf8(char *s, int b) {
+ unsigned char *c1, *c2, *c3;
- if (b < 1)
+ c1 = (unsigned char *) s;
+ c2 = (unsigned char *) ++s;
+ c3 = (unsigned char *) ++s;
+ if(b < 1)
return 0;
- else if (~c&B7)
- return 1;
- else if ((c&(B7|B6|B5)) == (B7|B6))
- n = 1;
- else if ((c&(B7|B6|B5|B4)) == (B7|B6|B5))
- n = 2;
- else if ((c&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4))
- n = 3;
- else
- return 1;
- for (--b,++s; n>0&&b>0; --n,--b,++s) {
- c = *s;
- if ((c&(B7|B6)) != B7)
- break;
- }
- if (n > 0 && b == 0)
+ else if((*c1&(B7|B6|B5)) == (B7|B6) && b == 1)
+ return 0;
+ else if((*c1&(B7|B6|B5|B4)) == (B7|B6|B5) &&
+ ((b == 1) ||
+ ((b == 2) && (*c2&(B7|B6)) == B7)))
+ return 0;
+ else if((*c1&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4) &&
+ ((b == 1) ||
+ ((b == 2) && (*c2&(B7|B6)) == B7) ||
+ ((b == 3) && (*c2&(B7|B6)) == B7 && (*c3&(B7|B6)) == B7)))
return 0;
else
return 1;
}
-static int slen(char *s) {
+int
+utf8size(char *s) {
unsigned char c = *s;
if (~c&B7)
t@@ -369,13 +364,15 @@ static int slen(char *s) {
return 4;
}
-static void selinit(void) {
+void
+selinit(void) {
sel.mode = 0;
sel.bx = -1;
sel.clip = NULL;
}
-static inline int selected(int x, int y) {
+static inline int
+selected(int x, int y) {
if(sel.ey == y && sel.by == y) {
int bx = MIN(sel.bx, sel.ex);
int ex = MAX(sel.bx, sel.ex);
t@@ -385,7 +382,8 @@ static inline int selected(int x, int y) {
|| (y==sel.b.y && x>=sel.b.x && (x<=sel.e.x || sel.b.y!=sel.e.…
}
-static void getbuttoninfo(XEvent *e, int *b, int *x, int *y) {
+void
+getbuttoninfo(XEvent *e, int *b, int *x, int *y) {
if(b)
*b = e->xbutton.button;
t@@ -397,13 +395,15 @@ static void getbuttoninfo(XEvent *e, int *b, int *x, int…
sel.e.y = MAX(sel.by, sel.ey);
}
-static void bpress(XEvent *e) {
+void
+bpress(XEvent *e) {
sel.mode = 1;
sel.ex = sel.bx = e->xbutton.x/xw.cw;
sel.ey = sel.by = e->xbutton.y/xw.ch;
}
-static void selcopy() {
+void
+selcopy(void) {
char *str, *ptr;
int ls, x, y, sz, sl;
t@@ -415,7 +415,7 @@ static void selcopy() {
for(y = 0; y < term.row; y++) {
for(x = 0; x < term.col; x++)
if(term.line[y][x].state & GLYPH_SET && (ls = …
- sl = slen(term.line[y][x].c);
+ sl = utf8size(term.line[y][x].c);
memcpy(ptr, term.line[y][x].c, sl);
ptr += sl;
}
t@@ -427,7 +427,8 @@ static void selcopy() {
xsetsel(str);
}
-static void selnotify(XEvent *e) {
+void
+selnotify(XEvent *e) {
unsigned long nitems;
unsigned long ofs, rem;
int format;
t@@ -449,12 +450,13 @@ static void selnotify(XEvent *e) {
} while(rem > 0);
}
-static void selpaste() {
+void
+selpaste() {
XConvertSelection(xw.dis, XA_PRIMARY, XA_STRING, XA_PRIMARY, xw.win, C…
}
-static void selrequest(XEvent *e)
-{
+void
+selrequest(XEvent *e) {
XSelectionRequestEvent *xsre;
XSelectionEvent xev;
Atom xa_targets;
t@@ -488,7 +490,8 @@ static void selrequest(XEvent *e)
fprintf(stderr, "Error sending SelectionNotify event\n");
}
-static void xsetsel(char *str) {
+void
+xsetsel(char *str) {
/* register the selection for both the clipboard and the primary */
Atom clipboard;
t@@ -504,7 +507,8 @@ static void xsetsel(char *str) {
}
/* TODO: doubleclick to select word */
-static void brelease(XEvent *e) {
+void
+brelease(XEvent *e) {
int b;
sel.mode = 0;
getbuttoninfo(e, &b, &sel.ex, &sel.ey);
t@@ -519,7 +523,8 @@ static void brelease(XEvent *e) {
draw(1);
}
-static void bmotion(XEvent *e) {
+void
+bmotion(XEvent *e) {
if (sel.mode) {
getbuttoninfo(e, NULL, &sel.ex, &sel.ey);
/* XXX: draw() can't keep up, disabled for now.
t@@ -528,26 +533,6 @@ static void bmotion(XEvent *e) {
}
}
-#ifdef DEBUG
-void
-tdump(void) {
- int row, col;
- Glyph c;
-
- for(row = 0; row < term.row; row++) {
- for(col = 0; col < term.col; col++) {
- if(col == term.c.x && row == term.c.y)
- putchar('#');
- else {
- c = term.line[row][col];
- putchar(c.state & GLYPH_SET ? c.c : '.');
- }
- }
- putchar('\n');
- }
-}
-#endif
-
void
die(const char *errstr, ...) {
va_list ap;
t@@ -631,9 +616,9 @@ ttyread(void) {
die("Couldn't read from shell: %s\n", SERRNO);
else {
buflen += ret;
- for(ptr=buf; buflen>=UTF_SIZ||canstou(ptr,buflen); buflen-=br)…
- br = stou(ptr, &u);
- utos(&u, s);
+ for(ptr=buf; buflen>=UTF_SIZ||isfullutf8(ptr,buflen); buflen-=…
+ br = utf8decode(ptr, &u);
+ utf8encode(&u, s);
tputc(s);
ptr += br;
}
t@@ -1460,49 +1445,63 @@ xhints(void)
XSetWMProperties(xw.dis, xw.win, NULL, NULL, NULL, 0, &size, &wm, &cla…
}
+XFontSet
+xinitfont(char *fontstr)
+{
+ XFontSet set;
+ char *def, **missing;
+ int n;
+
+ missing = NULL;
+ set = XCreateFontSet(xw.dis, fontstr, &missing, &n, &def);
+ if(missing) {
+ while(n--)
+ fprintf(stderr, "st: missing fontset: %s\n", missing[n…
+ XFreeStringList(missing);
+ }
+ return set;
+}
+
void
-xsetfontinfo(FontInfo *fi)
+xgetfontinfo(XFontSet set, int *ascent, int *descent, short *lbearing, short *…
{
XFontStruct **xfonts;
- int fnum;
- int i;
- char **fontnames;
-
- fi->lbearing = 0;
- fi->rbearing = 0;
- fi->ascent = 0;
- fi->descent = 0;
- fnum = XFontsOfFontSet(fi->fs, &xfonts, &fontnames);
- for(i=0; i<fnum; i++,xfonts++,fontnames++) {
- puts(*fontnames);
- if(fi->ascent < (*xfonts)->ascent)
- fi->ascent = (*xfonts)->ascent;
- if(fi->descent < (*xfonts)->descent)
- fi->descent = (*xfonts)->descent;
- if(fi->rbearing < (*xfonts)->max_bounds.rbearing)
- fi->rbearing = (*xfonts)->max_bounds.rbearing;
- if(fi->lbearing < (*xfonts)->min_bounds.lbearing)
- fi->lbearing = (*xfonts)->min_bounds.lbearing;
+ char **font_names;
+ int i, n;
+
+ *ascent = *descent = *lbearing = *rbearing = 0;
+ n = XFontsOfFontSet(set, &xfonts, &font_names);
+ for(i = 0; i < n; i++) {
+ *ascent = MAX(*ascent, (*xfonts)->ascent);
+ *descent = MAX(*descent, (*xfonts)->descent);
+ *lbearing = MAX(*lbearing, (*xfonts)->min_bounds.lbearing);
+ *rbearing = MAX(*rbearing, (*xfonts)->max_bounds.rbearing);
+ xfonts++;
}
}
void
+initfonts(char *fontstr, char *bfontstr)
+{
+ if((dc.font.set = xinitfont(fontstr)) == NULL ||
+ (dc.bfont.set = xinitfont(bfontstr)) == NULL)
+ die("Can't load font %s\n", dc.font.set ? BOLDFONT : FONT);
+ xgetfontinfo(dc.font.set, &dc.font.ascent, &dc.font.descent,
+ &dc.font.lbearing, &dc.font.rbearing);
+ xgetfontinfo(dc.bfont.set, &dc.bfont.ascent, &dc.bfont.descent,
+ &dc.bfont.lbearing, &dc.bfont.rbearing);
+}
+
+void
xinit(void) {
XSetWindowAttributes attrs;
- char **mc;
- char *ds;
- int nmc;
if(!(xw.dis = XOpenDisplay(NULL)))
die("Can't open display\n");
xw.scr = XDefaultScreen(xw.dis);
/* font */
- if ((dc.font.fs = XCreateFontSet(xw.dis, FONT, &mc, &nmc, &ds)) == NUL…
- (dc.bfont.fs = XCreateFontSet(xw.dis, BOLDFONT, &mc, &nmc, &ds)) =…
- die("Can't load font %s\n", dc.font.fs ? BOLDFONT : FONT);
- xsetfontinfo(&dc.font);
- xsetfontinfo(&dc.bfont);
+ initfonts(FONT, BOLDFONT);
/* XXX: Assuming same size for bold font */
xw.cw = dc.font.rbearing - dc.font.lbearing;
t@@ -1550,9 +1549,9 @@ xinit(void) {
}
void
-xdraws(char *s, Glyph base, int x, int y, int cl, int sl) {
+xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
unsigned long xfg, xbg;
- int winx = x*xw.cw, winy = y*xw.ch + dc.font.ascent, width = cl*xw.cw;
+ int winx = x*xw.cw, winy = y*xw.ch + dc.font.ascent, width = charlen*x…
int i;
if(base.mode & ATTR_REVERSE)
t@@ -1564,7 +1563,7 @@ xdraws(char *s, Glyph base, int x, int y, int cl, int sl…
XSetForeground(xw.dis, dc.gc, xfg);
if(base.mode & ATTR_GFX)
- for(i = 0; i < cl; i++) {
+ for(i = 0; i < bytelen; i++) {
char c = gfx[(unsigned int)s[i] % 256];
if(c)
s[i] = c;
t@@ -1572,8 +1571,8 @@ xdraws(char *s, Glyph base, int x, int y, int cl, int sl…
s[i] -= 0x5f;
}
- XmbDrawImageString(xw.dis, xw.buf, base.mode & ATTR_BOLD ? dc.bfont.fs…
- dc.gc, winx, winy, s, sl);
+ XmbDrawImageString(xw.dis, xw.buf, base.mode & ATTR_BOLD ? dc.bfont.se…
+ dc.gc, winx, winy, s, bytelen);
if(base.mode & ATTR_UNDERLINE)
XDrawLine(xw.dis, xw.buf, dc.gc, winx, winy+1, winx+width-1, w…
t@@ -1594,14 +1593,14 @@ xdrawcursor(void) {
/* remove the old cursor */
if(term.line[oldy][oldx].state & GLYPH_SET) {
- sl = slen(term.line[oldy][oldx].c);
+ sl = utf8size(term.line[oldy][oldx].c);
xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, o…
} else
xclear(oldx, oldy, oldx, oldy);
/* draw the new one */
if(!(term.c.state & CURSOR_HIDE) && (xw.state & WIN_FOCUSED)) {
- sl = slen(g.c);
+ sl = utf8size(g.c);
xdraws(g.c, g, term.c.x, term.c.y, 1, sl);
oldx = term.c.x, oldy = term.c.y;
}
t@@ -1611,7 +1610,7 @@ xdrawcursor(void) {
/* basic drawing routines */
void
xdrawc(int x, int y, Glyph g) {
- int sl = slen(g.c);
+ int sl = utf8size(g.c);
XRectangle r = { x * xw.cw, y * xw.ch, xw.cw, xw.ch };
XSetBackground(xw.dis, dc.gc, dc.col[g.bg]);
XSetForeground(xw.dis, dc.gc, dc.col[g.fg]);
t@@ -1663,7 +1662,7 @@ draw(int redraw_all) {
ox = x;
base = new;
}
- sl = slen(new.c);
+ sl = utf8size(new.c);
memcpy(buf+ib, new.c, sl);
ib += sl;
++ic;
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.