Xinqi Bao's Git
projects
/
st.git
/ blobdiff
summary
|
log
|
commit
|
diff
|
tree
raw
|
inline
| side by side
Change internal character representation.
[st.git]
/
st.c
diff --git
a/st.c
b/st.c
index
6371a85
..
2788746
100644
(file)
--- a/
st.c
+++ b/
st.c
@@
-72,6
+72,7
@@
char *argv0;
#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
+#define ISDELIM(u) (BETWEEN(u, 0, 127) && strchr(worddelimiters, u) != NULL)
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
#define IS_SET(flag) ((term.mode & (flag)) != 0)
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
#define IS_SET(flag) ((term.mode & (flag)) != 0)
@@
-180,7
+181,7
@@
typedef XftDraw *Draw;
typedef XftColor Color;
typedef struct {
typedef XftColor Color;
typedef struct {
-
char c[UTF_SIZ];
/* character code */
+
long u;
/* character code */
ushort mode; /* attribute flags */
uint32_t fg; /* foreground */
uint32_t bg; /* background */
ushort mode; /* attribute flags */
uint32_t fg; /* foreground */
uint32_t bg; /* background */
@@
-410,6
+411,7
@@
static void tstrsequence(uchar);
static inline ushort sixd_to_16bit(int);
static void xdraws(char *, Glyph, int, int, int, int);
static inline ushort sixd_to_16bit(int);
static void xdraws(char *, Glyph, int, int, int, int);
+static void xdrawglyph(Glyph, int, int);
static void xhints(void);
static void xclear(int, int, int, int);
static void xdrawcursor(void);
static void xhints(void);
static void xclear(int, int, int, int);
static void xdrawcursor(void);
@@
-459,9
+461,8
@@
static void mousereport(XEvent *);
static size_t utf8decode(char *, long *, size_t);
static long utf8decodebyte(char, size_t *);
static size_t utf8decode(char *, long *, size_t);
static long utf8decodebyte(char, size_t *);
-static size_t utf8encode(long, char *
, size_t
);
+static size_t utf8encode(long, char *);
static char utf8encodebyte(long, size_t);
static char utf8encodebyte(long, size_t);
-static size_t utf8len(char *);
static size_t utf8validate(long *, size_t);
static ssize_t xwrite(int, const char *, size_t);
static size_t utf8validate(long *, size_t);
static ssize_t xwrite(int, const char *, size_t);
@@
-610,11
+611,11
@@
utf8decodebyte(char c, size_t *i) {
}
size_t
}
size_t
-utf8encode(long u, char *c
, size_t clen
) {
+utf8encode(long u, char *c) {
size_t len, i;
len = utf8validate(&u, 0);
size_t len, i;
len = utf8validate(&u, 0);
- if(
clen < len
)
+ if(
len > UTF_SIZ
)
return 0;
for(i = len - 1; i != 0; --i) {
c[i] = utf8encodebyte(u, 0);
return 0;
for(i = len - 1; i != 0; --i) {
c[i] = utf8encodebyte(u, 0);
@@
-629,11
+630,6
@@
utf8encodebyte(long u, size_t i) {
return utfbyte[i] | (u & ~utfmask[i]);
}
return utfbyte[i] | (u & ~utfmask[i]);
}
-size_t
-utf8len(char *c) {
- return utf8decode(c, &(long){0}, UTF_SIZ);
-}
-
size_t
utf8validate(long *u, size_t i) {
if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
size_t
utf8validate(long *u, size_t i) {
if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
@@
-679,7
+675,7
@@
tlinelen(int y) {
if(term.line[y][i - 1].mode & ATTR_WRAP)
return i;
if(term.line[y][i - 1].mode & ATTR_WRAP)
return i;
- while(i > 0 && term.line[y][i - 1].
c[0]
== ' ')
+ while(i > 0 && term.line[y][i - 1].
u
== ' ')
--i;
return i;
--i;
return i;
@@
-736,7
+732,7
@@
selsnap(int mode, int *x, int *y, int direction) {
* beginning of a line.
*/
prevgp = &term.line[*y][*x];
* beginning of a line.
*/
prevgp = &term.line[*y][*x];
- prevdelim =
strchr(worddelimiters, prevgp->c[0]) != NULL
;
+ prevdelim =
ISDELIM(prevgp->u)
;
for(;;) {
newx = *x + direction;
newy = *y;
for(;;) {
newx = *x + direction;
newy = *y;
@@
-758,9
+754,9
@@
selsnap(int mode, int *x, int *y, int direction) {
break;
gp = &term.line[newy][newx];
break;
gp = &term.line[newy][newx];
- delim =
strchr(worddelimiters, gp->c[0]) != NULL
;
+ delim =
ISDELIM(gp->u)
;
if(!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
if(!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
- || (delim && gp->
c[0] != prevgp->c[0]
)))
+ || (delim && gp->
u != prevgp->u
)))
break;
*x = newx;
break;
*x = newx;
@@
-936,7
+932,7
@@
bpress(XEvent *e) {
char *
getsel(void) {
char *str, *ptr;
char *
getsel(void) {
char *str, *ptr;
- int y, bufsize,
size,
lastx, linelen;
+ int y, bufsize, lastx, linelen;
Glyph *gp, *last;
if(sel.ob.x == -1)
Glyph *gp, *last;
if(sel.ob.x == -1)
@@
-957,16
+953,14
@@
getsel(void) {
lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
}
last = &term.line[y][MIN(lastx, linelen-1)];
lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
}
last = &term.line[y][MIN(lastx, linelen-1)];
- while(last >= gp && last->
c[0]
== ' ')
+ while(last >= gp && last->
u
== ' ')
--last;
for( ; gp <= last; ++gp) {
if(gp->mode & ATTR_WDUMMY)
continue;
--last;
for( ; gp <= last; ++gp) {
if(gp->mode & ATTR_WDUMMY)
continue;
- size = utf8len(gp->c);
- memcpy(ptr, gp->c, size);
- ptr += size;
+ ptr += utf8encode(gp->u, ptr);
}
/*
}
/*
@@
-1351,7
+1345,7
@@
ttyread(void) {
buflen += ret;
ptr = buf;
while((charsize = utf8decode(ptr, &unicodep, buflen))) {
buflen += ret;
ptr = buf;
while((charsize = utf8decode(ptr, &unicodep, buflen))) {
- utf8encode(unicodep, s
, UTF_SIZ
);
+ utf8encode(unicodep, s);
tputc(s, charsize);
ptr += charsize;
buflen -= charsize;
tputc(s, charsize);
ptr += charsize;
buflen -= charsize;
@@
-1643,17
+1637,17
@@
tsetchar(char *c, Glyph *attr, int x, int y) {
if(term.line[y][x].mode & ATTR_WIDE) {
if(x+1 < term.col) {
if(term.line[y][x].mode & ATTR_WIDE) {
if(x+1 < term.col) {
- term.line[y][x+1].
c[0]
= ' ';
+ term.line[y][x+1].
u
= ' ';
term.line[y][x+1].mode &= ~ATTR_WDUMMY;
}
} else if(term.line[y][x].mode & ATTR_WDUMMY) {
term.line[y][x+1].mode &= ~ATTR_WDUMMY;
}
} else if(term.line[y][x].mode & ATTR_WDUMMY) {
- term.line[y][x-1].
c[0]
= ' ';
+ term.line[y][x-1].
u
= ' ';
term.line[y][x-1].mode &= ~ATTR_WIDE;
}
term.dirty[y] = 1;
term.line[y][x] = *attr;
term.line[y][x-1].mode &= ~ATTR_WIDE;
}
term.dirty[y] = 1;
term.line[y][x] = *attr;
-
memcpy(term.line[y][x].c, c
, UTF_SIZ);
+
utf8decode(c, &term.line[y][x].u
, UTF_SIZ);
}
void
}
void
@@
-1680,7
+1674,7
@@
tclearregion(int x1, int y1, int x2, int y2) {
gp->fg = term.c.attr.fg;
gp->bg = term.c.attr.bg;
gp->mode = 0;
gp->fg = term.c.attr.fg;
gp->bg = term.c.attr.bg;
gp->mode = 0;
-
memcpy(gp->c, " ", 2)
;
+
gp->u = ' '
;
}
}
}
}
}
}
@@
-2400,13
+2394,14
@@
tdumpsel(void) {
void
tdumpline(int n) {
void
tdumpline(int n) {
+ char buf[UTF_SIZ];
Glyph *bp, *end;
bp = &term.line[n][0];
end = &bp[MIN(tlinelen(n), term.col) - 1];
Glyph *bp, *end;
bp = &term.line[n][0];
end = &bp[MIN(tlinelen(n), term.col) - 1];
- if(bp != end || bp->
c[0]
!= ' ') {
+ if(bp != end || bp->
u
!= ' ') {
for( ;bp <= end; ++bp)
for( ;bp <= end; ++bp)
- tprinter(b
p->c, utf8len(bp->c
));
+ tprinter(b
uf, utf8encode(bp->u, buf
));
}
tprinter("\n", 1);
}
}
tprinter("\n", 1);
}
@@
-2789,7
+2784,7
@@
tputc(char *c, int len) {
if(width == 2) {
gp->mode |= ATTR_WIDE;
if(term.c.x+1 < term.col) {
if(width == 2) {
gp->mode |= ATTR_WIDE;
if(term.c.x+1 < term.col) {
- gp[1].
c[0]
= '\0';
+ gp[1].
u
= '\0';
gp[1].mode = ATTR_WDUMMY;
}
}
gp[1].mode = ATTR_WDUMMY;
}
}
@@
-3552,11
+3547,20
@@
xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
XftDrawSetClip(xw.draw, 0);
}
XftDrawSetClip(xw.draw, 0);
}
+void
+xdrawglyph(Glyph g, int x, int y) {
+ static char buf[UTF_SIZ];
+ size_t len = utf8encode(g.u, buf);
+ int width = g.mode & ATTR_WIDE ? 2 : 1;
+
+ xdraws(buf, g, x, y, width, len);
+}
+
void
xdrawcursor(void) {
static int oldx = 0, oldy = 0;
void
xdrawcursor(void) {
static int oldx = 0, oldy = 0;
- int
sl, width,
curx;
- Glyph g = {
{' '}
, ATTR_NULL, defaultbg, defaultcs};
+ int curx;
+ Glyph g = {
' '
, ATTR_NULL, defaultbg, defaultcs};
LIMIT(oldx, 0, term.col-1);
LIMIT(oldy, 0, term.row-1);
LIMIT(oldx, 0, term.col-1);
LIMIT(oldy, 0, term.row-1);
@@
-3569,13
+3573,10
@@
xdrawcursor(void) {
if(term.line[term.c.y][curx].mode & ATTR_WDUMMY)
curx--;
if(term.line[term.c.y][curx].mode & ATTR_WDUMMY)
curx--;
-
memcpy(g.c, term.line[term.c.y][term.c.x].c, UTF_SIZ)
;
+
g.u = term.line[term.c.y][term.c.x].u
;
/* remove the old cursor */
/* remove the old cursor */
- sl = utf8len(term.line[oldy][oldx].c);
- width = (term.line[oldy][oldx].mode & ATTR_WIDE)? 2 : 1;
- xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx,
- oldy, width, sl);
+ xdrawglyph(term.line[oldy][oldx], oldx, oldy);
if(IS_SET(MODE_HIDE))
return;
if(IS_SET(MODE_HIDE))
return;
@@
-3592,10
+3593,8
@@
xdrawcursor(void) {
g.bg = defaultfg;
}
g.bg = defaultfg;
}
- sl = utf8len(g.c);
- width = (term.line[term.c.y][curx].mode & ATTR_WIDE)\
- ? 2 : 1;
- xdraws(g.c, g, term.c.x, term.c.y, width, sl);
+ g.mode |= term.line[term.c.y][curx].mode & ATTR_WIDE;
+ xdrawglyph(g, term.c.x, term.c.y);
break;
case 3: /* Blinking Underline */
case 4: /* Steady Underline */
break;
case 3: /* Blinking Underline */
case 4: /* Steady Underline */
@@
-3668,7
+3667,7
@@
draw(void) {
void
drawregion(int x1, int y1, int x2, int y2) {
void
drawregion(int x1, int y1, int x2, int y2) {
- int ic, ib, x, y, ox
, sl
;
+ int ic, ib, x, y, ox;
Glyph base, new;
char buf[DRAW_BUF_SIZ];
bool ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN);
Glyph base, new;
char buf[DRAW_BUF_SIZ];
bool ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN);
@@
-3700,9
+3699,7
@@
drawregion(int x1, int y1, int x2, int y2) {
base = new;
}
base = new;
}
- sl = utf8len(new.c);
- memcpy(buf+ib, new.c, sl);
- ib += sl;
+ ib += utf8encode(new.u, buf+ib);
ic += (new.mode & ATTR_WIDE)? 2 : 1;
}
if(ib > 0)
ic += (new.mode & ATTR_WIDE)? 2 : 1;
}
if(ib > 0)
@@
-3848,7
+3845,7
@@
kpress(XEvent *ev) {
if(IS_SET(MODE_8BIT)) {
if(*buf < 0177) {
c = *buf | 0x80;
if(IS_SET(MODE_8BIT)) {
if(*buf < 0177) {
c = *buf | 0x80;
- len = utf8encode(c, buf
, UTF_SIZ
);
+ len = utf8encode(c, buf);
}
} else {
buf[1] = buf[0];
}
} else {
buf[1] = buf[0];