diff options
author | Aurélien Aptel <aurelien.aptel@gmail.com> | 2010-11-20 22:24:04 +0100 |
---|---|---|
committer | Aurélien Aptel <aurelien.aptel@gmail.com> | 2010-11-20 22:24:04 +0100 |
commit | b61925b5d6fd8af0ad0ccc922db60dff1746cfe2 (patch) | |
tree | 64d4428713c0554937fb5750b2dbe8b483b39e2d /st.c | |
parent | 81a048d6cfda84a06353911130fee029df077c8d (diff) | |
download | st-b61925b5d6fd8af0ad0ccc922db60dff1746cfe2.tar.gz st-b61925b5d6fd8af0ad0ccc922db60dff1746cfe2.zip |
cleanup & bugfix in xdraws().
Diffstat (limited to 'st.c')
-rw-r--r-- | st.c | 251 |
1 files changed, 125 insertions, 126 deletions
@@ -131,20 +131,17 @@ typedef struct { | |||
131 | char s[ESC_BUF_SIZ]; | 131 | char s[ESC_BUF_SIZ]; |
132 | } Key; | 132 | } Key; |
133 | 133 | ||
134 | typedef 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 */ |
143 | typedef struct { | 135 | typedef 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); | |||
222 | static void selcopy(void); | 219 | static void selcopy(void); |
223 | static void selpaste(void); | 220 | static void selpaste(void); |
224 | 221 | ||
225 | static int stou(char *, long *); | 222 | static int utf8decode(char *, long *); |
226 | static int utos(long *, char *); | 223 | static int utf8encode(long *, char *); |
227 | static int slen(char *); | 224 | static int utf8size(char *); |
228 | static int canstou(char *, int); | 225 | static int isfullutf8(char *, int); |
229 | 226 | ||
230 | static void (*handler[LASTEvent])(XEvent *) = { | 227 | static void (*handler[LASTEvent])(XEvent *) = { |
231 | [KeyPress] = kpress, | 228 | [KeyPress] = kpress, |
@@ -254,8 +251,8 @@ static char *opt_cmd = NULL; | |||
254 | static char *opt_title = NULL; | 251 | static char *opt_title = NULL; |
255 | static char *opt_class = NULL; | 252 | static char *opt_class = NULL; |
256 | 253 | ||
257 | /* UTF-8 decode */ | 254 | int |
258 | static int stou(char *s, long *u) { | 255 | utf8decode(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; |
291 | invalid: | 288 | invalid: |
@@ -293,30 +290,30 @@ invalid: | |||
293 | return rtn; | 290 | return rtn; |
294 | } | 291 | } |
295 | 292 | ||
296 | /* UTF-8 encode */ | 293 | int |
297 | static int utos(long *u, char *s) { | 294 | utf8encode(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; |
322 | invalid: | 319 | invalid: |
@@ -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 */ |
332 | static int canstou(char *s, int b) { | 329 | int |
333 | unsigned char c = *s; | 330 | isfullutf8(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 | ||
359 | static int slen(char *s) { | 353 | int |
354 | utf8size(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 | ||
372 | static void selinit(void) { | 367 | void |
368 | selinit(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 | ||
378 | static inline int selected(int x, int y) { | 374 | static inline int |
375 | selected(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 | ||
388 | static void getbuttoninfo(XEvent *e, int *b, int *x, int *y) { | 385 | void |
386 | getbuttoninfo(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 | ||
400 | static void bpress(XEvent *e) { | 398 | void |
399 | bpress(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 | ||
406 | static void selcopy() { | 405 | void |
406 | selcopy(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 | ||
430 | static void selnotify(XEvent *e) { | 430 | void |
431 | selnotify(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 | ||
452 | static void selpaste() { | 453 | void |
454 | selpaste() { | ||
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 | ||
456 | static void selrequest(XEvent *e) | 458 | void |
457 | { | 459 | selrequest(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 | ||
491 | static void xsetsel(char *str) { | 493 | void |
494 | xsetsel(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 */ |
507 | static void brelease(XEvent *e) { | 510 | void |
511 | brelease(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 | ||
522 | static void bmotion(XEvent *e) { | 526 | void |
527 | bmotion(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 | ||
532 | void | ||
533 | tdump(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 | |||
551 | void | 536 | void |
552 | die(const char *errstr, ...) { | 537 | die(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 | ||
1448 | XFontSet | ||
1449 | xinitfont(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 | |||
1463 | void | 1465 | void |
1464 | xsetfontinfo(FontInfo *fi) | 1466 | xgetfontinfo(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 | ||
1489 | void | 1483 | void |
1484 | initfonts(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 | |||
1495 | void | ||
1490 | xinit(void) { | 1496 | xinit(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 | ||
1552 | void | 1551 | void |
1553 | xdraws(char *s, Glyph base, int x, int y, int cl, int sl) { | 1552 | xdraws(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 */ |
1612 | void | 1611 | void |
1613 | xdrawc(int x, int y, Glyph g) { | 1612 | xdrawc(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; |