aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorAurélien Aptel <aurelien.aptel@gmail.com>2010-11-20 22:24:04 +0100
committerAurélien Aptel <aurelien.aptel@gmail.com>2010-11-20 22:24:04 +0100
commitb61925b5d6fd8af0ad0ccc922db60dff1746cfe2 (patch)
tree64d4428713c0554937fb5750b2dbe8b483b39e2d /st.c
parent81a048d6cfda84a06353911130fee029df077c8d (diff)
downloadst-b61925b5d6fd8af0ad0ccc922db60dff1746cfe2.tar.gz
st-b61925b5d6fd8af0ad0ccc922db60dff1746cfe2.zip
cleanup & bugfix in xdraws().
Diffstat (limited to 'st.c')
-rw-r--r--st.c251
1 files changed, 125 insertions, 126 deletions
diff --git a/st.c b/st.c
index 38c8658..e7e292f 100644
--- a/st.c
+++ b/st.c
@@ -131,20 +131,17 @@ typedef struct {
131 char s[ESC_BUF_SIZ]; 131 char s[ESC_BUF_SIZ];
132} Key; 132} Key;
133 133
134typedef struct {
135 XFontSet fs;
136 short lbearing;
137 short rbearing;
138 int ascent;
139 int descent;
140} FontInfo;
141
142/* Drawing Context */ 134/* Drawing Context */
143typedef struct { 135typedef struct {
144 unsigned long col[256]; 136 unsigned long col[256];
145 FontInfo font;
146 FontInfo bfont;
147 GC gc; 137 GC gc;
138 struct {
139 int ascent;
140 int descent;
141 short lbearing;
142 short rbearing;
143 XFontSet set;
144 } font, bfont;
148} DC; 145} DC;
149 146
150/* TODO: use better name for vars... */ 147/* TODO: use better name for vars... */
@@ -222,10 +219,10 @@ static inline int selected(int, int);
222static void selcopy(void); 219static void selcopy(void);
223static void selpaste(void); 220static void selpaste(void);
224 221
225static int stou(char *, long *); 222static int utf8decode(char *, long *);
226static int utos(long *, char *); 223static int utf8encode(long *, char *);
227static int slen(char *); 224static int utf8size(char *);
228static int canstou(char *, int); 225static int isfullutf8(char *, int);
229 226
230static void (*handler[LASTEvent])(XEvent *) = { 227static void (*handler[LASTEvent])(XEvent *) = {
231 [KeyPress] = kpress, 228 [KeyPress] = kpress,
@@ -254,8 +251,8 @@ static char *opt_cmd = NULL;
254static char *opt_title = NULL; 251static char *opt_title = NULL;
255static char *opt_class = NULL; 252static char *opt_class = NULL;
256 253
257/* UTF-8 decode */ 254int
258static int stou(char *s, long *u) { 255utf8decode(char *s, long *u) {
259 unsigned char c; 256 unsigned char c;
260 int i, n, rtn; 257 int i, n, rtn;
261 258
@@ -264,28 +261,28 @@ static int stou(char *s, long *u) {
264 if(~c&B7) { /* 0xxxxxxx */ 261 if(~c&B7) { /* 0xxxxxxx */
265 *u = c; 262 *u = c;
266 return rtn; 263 return rtn;
267 } else if ((c&(B7|B6|B5)) == (B7|B6)) { /* 110xxxxx */ 264 } else if((c&(B7|B6|B5)) == (B7|B6)) { /* 110xxxxx */
268 *u = c&(B4|B3|B2|B1|B0); 265 *u = c&(B4|B3|B2|B1|B0);
269 n = 1; 266 n = 1;
270 } else if ((c&(B7|B6|B5|B4)) == (B7|B6|B5)) { /* 1110xxxx */ 267 } else if((c&(B7|B6|B5|B4)) == (B7|B6|B5)) { /* 1110xxxx */
271 *u = c&(B3|B2|B1|B0); 268 *u = c&(B3|B2|B1|B0);
272 n = 2; 269 n = 2;
273 } else if ((c&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4)) { /* 11110xxx */ 270 } else if((c&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4)) { /* 11110xxx */
274 *u = c&(B2|B1|B0); 271 *u = c&(B2|B1|B0);
275 n = 3; 272 n = 3;
276 } else 273 } else
277 goto invalid; 274 goto invalid;
278 for (i=n,++s; i>0; --i,++rtn,++s) { 275 for(i=n,++s; i>0; --i,++rtn,++s) {
279 c = *s; 276 c = *s;
280 if ((c&(B7|B6)) != B7) /* 10xxxxxx */ 277 if((c&(B7|B6)) != B7) /* 10xxxxxx */
281 goto invalid; 278 goto invalid;
282 *u <<= 6; 279 *u <<= 6;
283 *u |= c&(B5|B4|B3|B2|B1|B0); 280 *u |= c&(B5|B4|B3|B2|B1|B0);
284 } 281 }
285 if ((n == 1 && *u < 0x80) || 282 if((n == 1 && *u < 0x80) ||
286 (n == 2 && *u < 0x800) || 283 (n == 2 && *u < 0x800) ||
287 (n == 3 && *u < 0x10000) || 284 (n == 3 && *u < 0x10000) ||
288 (*u >= 0xD800 && *u <= 0xDFFF)) 285 (*u >= 0xD800 && *u <= 0xDFFF))
289 goto invalid; 286 goto invalid;
290 return rtn; 287 return rtn;
291invalid: 288invalid:
@@ -293,30 +290,30 @@ invalid:
293 return rtn; 290 return rtn;
294} 291}
295 292
296/* UTF-8 encode */ 293int
297static int utos(long *u, char *s) { 294utf8encode(long *u, char *s) {
298 unsigned char *sp; 295 unsigned char *sp;
299 unsigned long uc; 296 unsigned long uc;
300 int i, n; 297 int i, n;
301 298
302 sp = (unsigned char*) s; 299 sp = (unsigned char*) s;
303 uc = *u; 300 uc = *u;
304 if (uc < 0x80) { 301 if(uc < 0x80) {
305 *sp = uc; /* 0xxxxxxx */ 302 *sp = uc; /* 0xxxxxxx */
306 return 1; 303 return 1;
307 } else if (*u < 0x800) { 304 } else if(*u < 0x800) {
308 *sp = (uc >> 6) | (B7|B6); /* 110xxxxx */ 305 *sp = (uc >> 6) | (B7|B6); /* 110xxxxx */
309 n = 1; 306 n = 1;
310 } else if (uc < 0x10000) { 307 } else if(uc < 0x10000) {
311 *sp = (uc >> 12) | (B7|B6|B5); /* 1110xxxx */ 308 *sp = (uc >> 12) | (B7|B6|B5); /* 1110xxxx */
312 n = 2; 309 n = 2;
313 } else if (uc <= 0x10FFFF) { 310 } else if(uc <= 0x10FFFF) {
314 *sp = (uc >> 18) | (B7|B6|B5|B4); /* 11110xxx */ 311 *sp = (uc >> 18) | (B7|B6|B5|B4); /* 11110xxx */
315 n = 3; 312 n = 3;
316 } else { 313 } else {
317 goto invalid; 314 goto invalid;
318 } 315 }
319 for (i=n,++sp; i>0; --i,++sp) 316 for(i=n,++sp; i>0; --i,++sp)
320 *sp = ((uc >> 6*(i-1)) & (B5|B4|B3|B2|B1|B0)) | B7; /* 10xxxxxx */ 317 *sp = ((uc >> 6*(i-1)) & (B5|B4|B3|B2|B1|B0)) | B7; /* 10xxxxxx */
321 return n+1; 318 return n+1;
322invalid: 319invalid:
@@ -329,34 +326,32 @@ invalid:
329 326
330/* use this if your buffer is less than UTF_SIZ, it returns 1 if you can decode 327/* use this if your buffer is less than UTF_SIZ, it returns 1 if you can decode
331 UTF-8 otherwise return 0 */ 328 UTF-8 otherwise return 0 */
332static int canstou(char *s, int b) { 329int
333 unsigned char c = *s; 330isfullutf8(char *s, int b) {
334 int n; 331 unsigned char *c1, *c2, *c3;
335 332
336 if (b < 1) 333 c1 = (unsigned char *) s;
334 c2 = (unsigned char *) ++s;
335 c3 = (unsigned char *) ++s;
336 if(b < 1)
337 return 0; 337 return 0;
338 else if (~c&B7) 338 else if((*c1&(B7|B6|B5)) == (B7|B6) && b == 1)
339 return 1; 339 return 0;
340 else if ((c&(B7|B6|B5)) == (B7|B6)) 340 else if((*c1&(B7|B6|B5|B4)) == (B7|B6|B5) &&
341 n = 1; 341 ((b == 1) ||
342 else if ((c&(B7|B6|B5|B4)) == (B7|B6|B5)) 342 ((b == 2) && (*c2&(B7|B6)) == B7)))
343 n = 2; 343 return 0;
344 else if ((c&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4)) 344 else if((*c1&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4) &&
345 n = 3; 345 ((b == 1) ||
346 else 346 ((b == 2) && (*c2&(B7|B6)) == B7) ||
347 return 1; 347 ((b == 3) && (*c2&(B7|B6)) == B7 && (*c3&(B7|B6)) == B7)))
348 for (--b,++s; n>0&&b>0; --n,--b,++s) {
349 c = *s;
350 if ((c&(B7|B6)) != B7)
351 break;
352 }
353 if (n > 0 && b == 0)
354 return 0; 348 return 0;
355 else 349 else
356 return 1; 350 return 1;
357} 351}
358 352
359static int slen(char *s) { 353int
354utf8size(char *s) {
360 unsigned char c = *s; 355 unsigned char c = *s;
361 356
362 if (~c&B7) 357 if (~c&B7)
@@ -369,13 +364,15 @@ static int slen(char *s) {
369 return 4; 364 return 4;
370} 365}
371 366
372static void selinit(void) { 367void
368selinit(void) {
373 sel.mode = 0; 369 sel.mode = 0;
374 sel.bx = -1; 370 sel.bx = -1;
375 sel.clip = NULL; 371 sel.clip = NULL;
376} 372}
377 373
378static inline int selected(int x, int y) { 374static inline int
375selected(int x, int y) {
379 if(sel.ey == y && sel.by == y) { 376 if(sel.ey == y && sel.by == y) {
380 int bx = MIN(sel.bx, sel.ex); 377 int bx = MIN(sel.bx, sel.ex);
381 int ex = MAX(sel.bx, sel.ex); 378 int ex = MAX(sel.bx, sel.ex);
@@ -385,7 +382,8 @@ static inline int selected(int x, int y) {
385 || (y==sel.b.y && x>=sel.b.x && (x<=sel.e.x || sel.b.y!=sel.e.y)); 382 || (y==sel.b.y && x>=sel.b.x && (x<=sel.e.x || sel.b.y!=sel.e.y));
386} 383}
387 384
388static void getbuttoninfo(XEvent *e, int *b, int *x, int *y) { 385void
386getbuttoninfo(XEvent *e, int *b, int *x, int *y) {
389 if(b) 387 if(b)
390 *b = e->xbutton.button; 388 *b = e->xbutton.button;
391 389
@@ -397,13 +395,15 @@ static void getbuttoninfo(XEvent *e, int *b, int *x, int *y) {
397 sel.e.y = MAX(sel.by, sel.ey); 395 sel.e.y = MAX(sel.by, sel.ey);
398} 396}
399 397
400static void bpress(XEvent *e) { 398void
399bpress(XEvent *e) {
401 sel.mode = 1; 400 sel.mode = 1;
402 sel.ex = sel.bx = e->xbutton.x/xw.cw; 401 sel.ex = sel.bx = e->xbutton.x/xw.cw;
403 sel.ey = sel.by = e->xbutton.y/xw.ch; 402 sel.ey = sel.by = e->xbutton.y/xw.ch;
404} 403}
405 404
406static void selcopy() { 405void
406selcopy(void) {
407 char *str, *ptr; 407 char *str, *ptr;
408 int ls, x, y, sz, sl; 408 int ls, x, y, sz, sl;
409 409
@@ -415,7 +415,7 @@ static void selcopy() {
415 for(y = 0; y < term.row; y++) { 415 for(y = 0; y < term.row; y++) {
416 for(x = 0; x < term.col; x++) 416 for(x = 0; x < term.col; x++)
417 if(term.line[y][x].state & GLYPH_SET && (ls = selected(x, y))) { 417 if(term.line[y][x].state & GLYPH_SET && (ls = selected(x, y))) {
418 sl = slen(term.line[y][x].c); 418 sl = utf8size(term.line[y][x].c);
419 memcpy(ptr, term.line[y][x].c, sl); 419 memcpy(ptr, term.line[y][x].c, sl);
420 ptr += sl; 420 ptr += sl;
421 } 421 }
@@ -427,7 +427,8 @@ static void selcopy() {
427 xsetsel(str); 427 xsetsel(str);
428} 428}
429 429
430static void selnotify(XEvent *e) { 430void
431selnotify(XEvent *e) {
431 unsigned long nitems; 432 unsigned long nitems;
432 unsigned long ofs, rem; 433 unsigned long ofs, rem;
433 int format; 434 int format;
@@ -449,12 +450,13 @@ static void selnotify(XEvent *e) {
449 } while(rem > 0); 450 } while(rem > 0);
450} 451}
451 452
452static void selpaste() { 453void
454selpaste() {
453 XConvertSelection(xw.dis, XA_PRIMARY, XA_STRING, XA_PRIMARY, xw.win, CurrentTime); 455 XConvertSelection(xw.dis, XA_PRIMARY, XA_STRING, XA_PRIMARY, xw.win, CurrentTime);
454} 456}
455 457
456static void selrequest(XEvent *e) 458void
457{ 459selrequest(XEvent *e) {
458 XSelectionRequestEvent *xsre; 460 XSelectionRequestEvent *xsre;
459 XSelectionEvent xev; 461 XSelectionEvent xev;
460 Atom xa_targets; 462 Atom xa_targets;
@@ -488,7 +490,8 @@ static void selrequest(XEvent *e)
488 fprintf(stderr, "Error sending SelectionNotify event\n"); 490 fprintf(stderr, "Error sending SelectionNotify event\n");
489} 491}
490 492
491static void xsetsel(char *str) { 493void
494xsetsel(char *str) {
492 /* register the selection for both the clipboard and the primary */ 495 /* register the selection for both the clipboard and the primary */
493 Atom clipboard; 496 Atom clipboard;
494 497
@@ -504,7 +507,8 @@ static void xsetsel(char *str) {
504} 507}
505 508
506/* TODO: doubleclick to select word */ 509/* TODO: doubleclick to select word */
507static void brelease(XEvent *e) { 510void
511brelease(XEvent *e) {
508 int b; 512 int b;
509 sel.mode = 0; 513 sel.mode = 0;
510 getbuttoninfo(e, &b, &sel.ex, &sel.ey); 514 getbuttoninfo(e, &b, &sel.ex, &sel.ey);
@@ -519,7 +523,8 @@ static void brelease(XEvent *e) {
519 draw(1); 523 draw(1);
520} 524}
521 525
522static void bmotion(XEvent *e) { 526void
527bmotion(XEvent *e) {
523 if (sel.mode) { 528 if (sel.mode) {
524 getbuttoninfo(e, NULL, &sel.ex, &sel.ey); 529 getbuttoninfo(e, NULL, &sel.ex, &sel.ey);
525 /* XXX: draw() can't keep up, disabled for now. 530 /* XXX: draw() can't keep up, disabled for now.
@@ -528,26 +533,6 @@ static void bmotion(XEvent *e) {
528 } 533 }
529} 534}
530 535
531#ifdef DEBUG
532void
533tdump(void) {
534 int row, col;
535 Glyph c;
536
537 for(row = 0; row < term.row; row++) {
538 for(col = 0; col < term.col; col++) {
539 if(col == term.c.x && row == term.c.y)
540 putchar('#');
541 else {
542 c = term.line[row][col];
543 putchar(c.state & GLYPH_SET ? c.c : '.');
544 }
545 }
546 putchar('\n');
547 }
548}
549#endif
550
551void 536void
552die(const char *errstr, ...) { 537die(const char *errstr, ...) {
553 va_list ap; 538 va_list ap;
@@ -631,9 +616,9 @@ ttyread(void) {
631 die("Couldn't read from shell: %s\n", SERRNO); 616 die("Couldn't read from shell: %s\n", SERRNO);
632 else { 617 else {
633 buflen += ret; 618 buflen += ret;
634 for(ptr=buf; buflen>=UTF_SIZ||canstou(ptr,buflen); buflen-=br) { 619 for(ptr=buf; buflen>=UTF_SIZ||isfullutf8(ptr,buflen); buflen-=br) {
635 br = stou(ptr, &u); 620 br = utf8decode(ptr, &u);
636 utos(&u, s); 621 utf8encode(&u, s);
637 tputc(s); 622 tputc(s);
638 ptr += br; 623 ptr += br;
639 } 624 }
@@ -1460,49 +1445,63 @@ xhints(void)
1460 XSetWMProperties(xw.dis, xw.win, NULL, NULL, NULL, 0, &size, &wm, &class); 1445 XSetWMProperties(xw.dis, xw.win, NULL, NULL, NULL, 0, &size, &wm, &class);
1461} 1446}
1462 1447
1448XFontSet
1449xinitfont(char *fontstr)
1450{
1451 XFontSet set;
1452 char *def, **missing;
1453 int n;
1454
1455 missing = NULL;
1456 set = XCreateFontSet(xw.dis, fontstr, &missing, &n, &def);
1457 if(missing) {
1458 while(n--)
1459 fprintf(stderr, "st: missing fontset: %s\n", missing[n]);
1460 XFreeStringList(missing);
1461 }
1462 return set;
1463}
1464
1463void 1465void
1464xsetfontinfo(FontInfo *fi) 1466xgetfontinfo(XFontSet set, int *ascent, int *descent, short *lbearing, short *rbearing)
1465{ 1467{
1466 XFontStruct **xfonts; 1468 XFontStruct **xfonts;
1467 int fnum; 1469 char **font_names;
1468 int i; 1470 int i, n;
1469 char **fontnames; 1471
1470 1472 *ascent = *descent = *lbearing = *rbearing = 0;
1471 fi->lbearing = 0; 1473 n = XFontsOfFontSet(set, &xfonts, &font_names);
1472 fi->rbearing = 0; 1474 for(i = 0; i < n; i++) {
1473 fi->ascent = 0; 1475 *ascent = MAX(*ascent, (*xfonts)->ascent);
1474 fi->descent = 0; 1476 *descent = MAX(*descent, (*xfonts)->descent);
1475 fnum = XFontsOfFontSet(fi->fs, &xfonts, &fontnames); 1477 *lbearing = MAX(*lbearing, (*xfonts)->min_bounds.lbearing);
1476 for(i=0; i<fnum; i++,xfonts++,fontnames++) { 1478 *rbearing = MAX(*rbearing, (*xfonts)->max_bounds.rbearing);
1477 puts(*fontnames); 1479 xfonts++;
1478 if(fi->ascent < (*xfonts)->ascent)
1479 fi->ascent = (*xfonts)->ascent;
1480 if(fi->descent < (*xfonts)->descent)
1481 fi->descent = (*xfonts)->descent;
1482 if(fi->rbearing < (*xfonts)->max_bounds.rbearing)
1483 fi->rbearing = (*xfonts)->max_bounds.rbearing;
1484 if(fi->lbearing < (*xfonts)->min_bounds.lbearing)
1485 fi->lbearing = (*xfonts)->min_bounds.lbearing;
1486 } 1480 }
1487} 1481}
1488 1482
1489void 1483void
1484initfonts(char *fontstr, char *bfontstr)
1485{
1486 if((dc.font.set = xinitfont(fontstr)) == NULL ||
1487 (dc.bfont.set = xinitfont(bfontstr)) == NULL)
1488 die("Can't load font %s\n", dc.font.set ? BOLDFONT : FONT);
1489 xgetfontinfo(dc.font.set, &dc.font.ascent, &dc.font.descent,
1490 &dc.font.lbearing, &dc.font.rbearing);
1491 xgetfontinfo(dc.bfont.set, &dc.bfont.ascent, &dc.bfont.descent,
1492 &dc.bfont.lbearing, &dc.bfont.rbearing);
1493}
1494
1495void
1490xinit(void) { 1496xinit(void) {
1491 XSetWindowAttributes attrs; 1497 XSetWindowAttributes attrs;
1492 char **mc;
1493 char *ds;
1494 int nmc;
1495 1498
1496 if(!(xw.dis = XOpenDisplay(NULL))) 1499 if(!(xw.dis = XOpenDisplay(NULL)))
1497 die("Can't open display\n"); 1500 die("Can't open display\n");
1498 xw.scr = XDefaultScreen(xw.dis); 1501 xw.scr = XDefaultScreen(xw.dis);
1499 1502
1500 /* font */ 1503 /* font */
1501 if ((dc.font.fs = XCreateFontSet(xw.dis, FONT, &mc, &nmc, &ds)) == NULL || 1504 initfonts(FONT, BOLDFONT);
1502 (dc.bfont.fs = XCreateFontSet(xw.dis, BOLDFONT, &mc, &nmc, &ds)) == NULL)
1503 die("Can't load font %s\n", dc.font.fs ? BOLDFONT : FONT);
1504 xsetfontinfo(&dc.font);
1505 xsetfontinfo(&dc.bfont);
1506 1505
1507 /* XXX: Assuming same size for bold font */ 1506 /* XXX: Assuming same size for bold font */
1508 xw.cw = dc.font.rbearing - dc.font.lbearing; 1507 xw.cw = dc.font.rbearing - dc.font.lbearing;
@@ -1550,9 +1549,9 @@ xinit(void) {
1550} 1549}
1551 1550
1552void 1551void
1553xdraws(char *s, Glyph base, int x, int y, int cl, int sl) { 1552xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
1554 unsigned long xfg, xbg; 1553 unsigned long xfg, xbg;
1555 int winx = x*xw.cw, winy = y*xw.ch + dc.font.ascent, width = cl*xw.cw; 1554 int winx = x*xw.cw, winy = y*xw.ch + dc.font.ascent, width = charlen*xw.cw;
1556 int i; 1555 int i;
1557 1556
1558 if(base.mode & ATTR_REVERSE) 1557 if(base.mode & ATTR_REVERSE)
@@ -1564,7 +1563,7 @@ xdraws(char *s, Glyph base, int x, int y, int cl, int sl) {
1564 XSetForeground(xw.dis, dc.gc, xfg); 1563 XSetForeground(xw.dis, dc.gc, xfg);
1565 1564
1566 if(base.mode & ATTR_GFX) 1565 if(base.mode & ATTR_GFX)
1567 for(i = 0; i < cl; i++) { 1566 for(i = 0; i < bytelen; i++) {
1568 char c = gfx[(unsigned int)s[i] % 256]; 1567 char c = gfx[(unsigned int)s[i] % 256];
1569 if(c) 1568 if(c)
1570 s[i] = c; 1569 s[i] = c;
@@ -1572,8 +1571,8 @@ xdraws(char *s, Glyph base, int x, int y, int cl, int sl) {
1572 s[i] -= 0x5f; 1571 s[i] -= 0x5f;
1573 } 1572 }
1574 1573
1575 XmbDrawImageString(xw.dis, xw.buf, base.mode & ATTR_BOLD ? dc.bfont.fs : dc.font.fs, 1574 XmbDrawImageString(xw.dis, xw.buf, base.mode & ATTR_BOLD ? dc.bfont.set : dc.font.set,
1576 dc.gc, winx, winy, s, sl); 1575 dc.gc, winx, winy, s, bytelen);
1577 1576
1578 if(base.mode & ATTR_UNDERLINE) 1577 if(base.mode & ATTR_UNDERLINE)
1579 XDrawLine(xw.dis, xw.buf, dc.gc, winx, winy+1, winx+width-1, winy+1); 1578 XDrawLine(xw.dis, xw.buf, dc.gc, winx, winy+1, winx+width-1, winy+1);
@@ -1594,14 +1593,14 @@ xdrawcursor(void) {
1594 1593
1595 /* remove the old cursor */ 1594 /* remove the old cursor */
1596 if(term.line[oldy][oldx].state & GLYPH_SET) { 1595 if(term.line[oldy][oldx].state & GLYPH_SET) {
1597 sl = slen(term.line[oldy][oldx].c); 1596 sl = utf8size(term.line[oldy][oldx].c);
1598 xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, oldy, 1, sl); 1597 xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, oldy, 1, sl);
1599 } else 1598 } else
1600 xclear(oldx, oldy, oldx, oldy); 1599 xclear(oldx, oldy, oldx, oldy);
1601 1600
1602 /* draw the new one */ 1601 /* draw the new one */
1603 if(!(term.c.state & CURSOR_HIDE) && (xw.state & WIN_FOCUSED)) { 1602 if(!(term.c.state & CURSOR_HIDE) && (xw.state & WIN_FOCUSED)) {
1604 sl = slen(g.c); 1603 sl = utf8size(g.c);
1605 xdraws(g.c, g, term.c.x, term.c.y, 1, sl); 1604 xdraws(g.c, g, term.c.x, term.c.y, 1, sl);
1606 oldx = term.c.x, oldy = term.c.y; 1605 oldx = term.c.x, oldy = term.c.y;
1607 } 1606 }
@@ -1611,7 +1610,7 @@ xdrawcursor(void) {
1611/* basic drawing routines */ 1610/* basic drawing routines */
1612void 1611void
1613xdrawc(int x, int y, Glyph g) { 1612xdrawc(int x, int y, Glyph g) {
1614 int sl = slen(g.c); 1613 int sl = utf8size(g.c);
1615 XRectangle r = { x * xw.cw, y * xw.ch, xw.cw, xw.ch }; 1614 XRectangle r = { x * xw.cw, y * xw.ch, xw.cw, xw.ch };
1616 XSetBackground(xw.dis, dc.gc, dc.col[g.bg]); 1615 XSetBackground(xw.dis, dc.gc, dc.col[g.bg]);
1617 XSetForeground(xw.dis, dc.gc, dc.col[g.fg]); 1616 XSetForeground(xw.dis, dc.gc, dc.col[g.fg]);
@@ -1663,7 +1662,7 @@ draw(int redraw_all) {
1663 ox = x; 1662 ox = x;
1664 base = new; 1663 base = new;
1665 } 1664 }
1666 sl = slen(new.c); 1665 sl = utf8size(new.c);
1667 memcpy(buf+ib, new.c, sl); 1666 memcpy(buf+ib, new.c, sl);
1668 ib += sl; 1667 ib += sl;
1669 ++ic; 1668 ++ic;