diff options
| author | Aurélien Aptel <aurelien.aptel@gmail.com> | 2010-02-03 16:18:04 +0100 |
|---|---|---|
| committer | Aurélien Aptel <aurelien.aptel@gmail.com> | 2010-02-03 16:18:04 +0100 |
| commit | e6b3f5c755349ba7a339dd43958870e4cceb57bf (patch) | |
| tree | 7d30fc28a52ba6b2a739e62045a2dd15b26740c7 | |
| parent | 0981437524b64579cc656f60b0108abdcdf8a0cd (diff) | |
| download | st-e6b3f5c755349ba7a339dd43958870e4cceb57bf.tar.gz st-e6b3f5c755349ba7a339dd43958870e4cceb57bf.zip | |
graphic charset and a few more escapes.
| -rw-r--r-- | config.h | 35 | ||||
| -rw-r--r-- | st.c | 91 |
2 files changed, 110 insertions, 16 deletions
| @@ -36,3 +36,38 @@ static Key key[] = { | |||
| 36 | { XK_Up, "\033[A" }, | 36 | { XK_Up, "\033[A" }, |
| 37 | { XK_Down, "\033[B" }, | 37 | { XK_Down, "\033[B" }, |
| 38 | }; | 38 | }; |
| 39 | |||
| 40 | static char gfx[] = { | ||
| 41 | ['}'] = 'f', | ||
| 42 | ['.'] = 'v', | ||
| 43 | [','] = '<', | ||
| 44 | ['+'] = '>', | ||
| 45 | ['-'] = '^', | ||
| 46 | ['h'] = '#', | ||
| 47 | ['~'] = 'o', | ||
| 48 | ['a'] = ':', | ||
| 49 | ['f'] = '\\', | ||
| 50 | ['`'] = '+', | ||
| 51 | ['z'] = '>', | ||
| 52 | ['{'] = '*', | ||
| 53 | ['q'] = '-', | ||
| 54 | ['i'] = '#', | ||
| 55 | ['n'] = '+', | ||
| 56 | ['y'] = '<', | ||
| 57 | ['m'] = '+', | ||
| 58 | ['j'] = '+', | ||
| 59 | ['|'] = '!', | ||
| 60 | ['g'] = '#', | ||
| 61 | ['o'] = '~', | ||
| 62 | ['p'] = '-', | ||
| 63 | ['r'] = '-', | ||
| 64 | ['s'] = '_', | ||
| 65 | ['0'] = '#', | ||
| 66 | ['w'] = '+', | ||
| 67 | ['u'] = '+', | ||
| 68 | ['t'] = '+', | ||
| 69 | ['v'] = '+', | ||
| 70 | ['l'] = '+', | ||
| 71 | ['k'] = '+', | ||
| 72 | ['x'] = '|', | ||
| 73 | }; | ||
| @@ -38,11 +38,11 @@ | |||
| 38 | #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) | 38 | #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) |
| 39 | 39 | ||
| 40 | /* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */ | 40 | /* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */ |
| 41 | enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4 }; | 41 | enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4, ATgfx=8 }; |
| 42 | enum { CSup, CSdown, CSright, CSleft, CShide, CSdraw, CSwrap, CSsave, CSload }; | 42 | enum { CSup, CSdown, CSright, CSleft, CShide, CSdraw, CSsave, CSload }; |
| 43 | enum { CRset=1, CRupdate=2 }; | 43 | enum { CRset=1, CRupdate=2 }; |
| 44 | enum { TMwrap=1, TMinsert=2, TMtitle=4 }; | 44 | enum { TMwrap=1, TMinsert=2 }; |
| 45 | enum { ESCin = 1, ESCcsi = 2, ESCosc = 4, ESCtitle = 8 }; | 45 | enum { ESCin=1, ESCcsi=2, ESCosc=4, ESCtitle=8, ESCcharset=16 }; |
| 46 | enum { SCupdate, SCredraw }; | 46 | enum { SCupdate, SCredraw }; |
| 47 | 47 | ||
| 48 | typedef int Color; | 48 | typedef int Color; |
| @@ -68,7 +68,7 @@ typedef struct { | |||
| 68 | /* ESC '[' [[ [<priv>] <arg> [;]] <mode>] */ | 68 | /* ESC '[' [[ [<priv>] <arg> [;]] <mode>] */ |
| 69 | typedef struct { | 69 | typedef struct { |
| 70 | char buf[ESCSIZ]; /* raw string */ | 70 | char buf[ESCSIZ]; /* raw string */ |
| 71 | int len; /* raw string length */ | 71 | int len; /* raw string length */ |
| 72 | char priv; | 72 | char priv; |
| 73 | int arg[ESCARGSIZ]; | 73 | int arg[ESCARGSIZ]; |
| 74 | int narg; /* nb of args */ | 74 | int narg; /* nb of args */ |
| @@ -389,7 +389,7 @@ tmoveto(int x, int y) { | |||
| 389 | void | 389 | void |
| 390 | tcursor(int dir) { | 390 | tcursor(int dir) { |
| 391 | int xf = term.c.x, yf = term.c.y; | 391 | int xf = term.c.x, yf = term.c.y; |
| 392 | 392 | ||
| 393 | switch(dir) { | 393 | switch(dir) { |
| 394 | case CSup: | 394 | case CSup: |
| 395 | yf--; | 395 | yf--; |
| @@ -399,7 +399,7 @@ tcursor(int dir) { | |||
| 399 | break; | 399 | break; |
| 400 | case CSleft: | 400 | case CSleft: |
| 401 | xf--; | 401 | xf--; |
| 402 | if(xf < 0) { | 402 | if(term.mode & TMwrap && xf < 0) { |
| 403 | xf = term.col-1, yf--; | 403 | xf = term.col-1, yf--; |
| 404 | if(yf < term.top) | 404 | if(yf < term.top) |
| 405 | yf = term.top, xf = 0; | 405 | yf = term.top, xf = 0; |
| @@ -407,7 +407,7 @@ tcursor(int dir) { | |||
| 407 | break; | 407 | break; |
| 408 | case CSright: | 408 | case CSright: |
| 409 | xf++; | 409 | xf++; |
| 410 | if(xf >= term.col) { | 410 | if(term.mode & TMwrap && xf >= term.col) { |
| 411 | xf = 0, yf++; | 411 | xf = 0, yf++; |
| 412 | if(yf > term.bot) | 412 | if(yf > term.bot) |
| 413 | yf = term.bot, tscroll(); | 413 | yf = term.bot, tscroll(); |
| @@ -416,7 +416,7 @@ tcursor(int dir) { | |||
| 416 | } | 416 | } |
| 417 | tmoveto(xf, yf); | 417 | tmoveto(xf, yf); |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | void | 420 | void |
| 421 | tsetchar(char c) { | 421 | tsetchar(char c) { |
| 422 | term.line[term.c.y][term.c.x] = term.c.attr; | 422 | term.line[term.c.y][term.c.x] = term.c.attr; |
| @@ -535,7 +535,7 @@ tsetattr(int *attr, int l) { | |||
| 535 | for(i = 0; i < l; i++) { | 535 | for(i = 0; i < l; i++) { |
| 536 | switch(attr[i]) { | 536 | switch(attr[i]) { |
| 537 | case 0: | 537 | case 0: |
| 538 | memset(&term.c.attr, 0, sizeof(term.c.attr)); | 538 | term.c.attr.mode &= ~(ATreverse | ATunderline | ATbold); |
| 539 | term.c.attr.fg = DefaultFG; | 539 | term.c.attr.fg = DefaultFG; |
| 540 | term.c.attr.bg = DefaultBG; | 540 | term.c.attr.bg = DefaultBG; |
| 541 | break; | 541 | break; |
| @@ -593,7 +593,10 @@ tsetscroll(int t, int b) { | |||
| 593 | 593 | ||
| 594 | void | 594 | void |
| 595 | csihandle(void) { | 595 | csihandle(void) { |
| 596 | if(escseq.priv) | ||
| 597 | csidump(); | ||
| 596 | switch(escseq.mode) { | 598 | switch(escseq.mode) { |
| 599 | unknown: | ||
| 597 | default: | 600 | default: |
| 598 | fprintf(stderr, "erresc: unknown sequence\n"); | 601 | fprintf(stderr, "erresc: unknown sequence\n"); |
| 599 | csidump(); | 602 | csidump(); |
| @@ -672,8 +675,16 @@ csihandle(void) { | |||
| 672 | tinsertblankline(escseq.arg[0]); | 675 | tinsertblankline(escseq.arg[0]); |
| 673 | break; | 676 | break; |
| 674 | case 'l': | 677 | case 'l': |
| 675 | if(escseq.priv && escseq.arg[0] == 25) | 678 | if(escseq.priv) { |
| 679 | switch(escseq.arg[0]) { | ||
| 680 | case 7: | ||
| 681 | term.mode &= ~TMwrap; | ||
| 682 | break; | ||
| 683 | case 25: | ||
| 676 | term.c.hidden = 1; | 684 | term.c.hidden = 1; |
| 685 | break; | ||
| 686 | } | ||
| 687 | } | ||
| 677 | break; | 688 | break; |
| 678 | case 'M': /* Delete <n> lines */ | 689 | case 'M': /* Delete <n> lines */ |
| 679 | DEFAULT(escseq.arg[0], 1); | 690 | DEFAULT(escseq.arg[0], 1); |
| @@ -689,15 +700,25 @@ csihandle(void) { | |||
| 689 | tmoveto(term.c.x, escseq.arg[0]-1); | 700 | tmoveto(term.c.x, escseq.arg[0]-1); |
| 690 | break; | 701 | break; |
| 691 | case 'h': /* Set terminal mode */ | 702 | case 'h': /* Set terminal mode */ |
| 692 | if(escseq.priv && escseq.arg[0] == 25) | 703 | if(escseq.priv) |
| 693 | term.c.hidden = 0; | 704 | switch(escseq.arg[0]) { |
| 705 | case 7: | ||
| 706 | term.mode |= TMwrap; | ||
| 707 | break; | ||
| 708 | case 25: | ||
| 709 | term.c.hidden = 0; | ||
| 710 | break; | ||
| 711 | case 1034: | ||
| 712 | /* XXX: Interpret "meta" key, sets eighth bit. */ | ||
| 713 | break; | ||
| 714 | } | ||
| 694 | break; | 715 | break; |
| 695 | case 'm': /* Terminal attribute (color) */ | 716 | case 'm': /* Terminal attribute (color) */ |
| 696 | tsetattr(escseq.arg, escseq.narg); | 717 | tsetattr(escseq.arg, escseq.narg); |
| 697 | break; | 718 | break; |
| 698 | case 'r': | 719 | case 'r': |
| 699 | if(escseq.priv) | 720 | if(escseq.priv) |
| 700 | ; | 721 | goto unknown; |
| 701 | else { | 722 | else { |
| 702 | DEFAULT(escseq.arg[0], 1); | 723 | DEFAULT(escseq.arg[0], 1); |
| 703 | DEFAULT(escseq.arg[1], term.row); | 724 | DEFAULT(escseq.arg[1], term.row); |
| @@ -766,6 +787,17 @@ tputc(char c) { | |||
| 766 | } else { | 787 | } else { |
| 767 | term.title[term.titlelen++] = c; | 788 | term.title[term.titlelen++] = c; |
| 768 | } | 789 | } |
| 790 | } else if(term.esc & ESCcharset) { | ||
| 791 | printf("ESC ( %c\n", c); | ||
| 792 | switch(c) { | ||
| 793 | case '0': /* Line drawing crap */ | ||
| 794 | term.c.attr.mode |= ATgfx; | ||
| 795 | break; | ||
| 796 | case 'B': /* Back to regular text */ | ||
| 797 | term.c.attr.mode &= ~ATgfx; | ||
| 798 | break; | ||
| 799 | } | ||
| 800 | term.esc = 0; | ||
| 769 | } else { | 801 | } else { |
| 770 | switch(c) { | 802 | switch(c) { |
| 771 | case '[': | 803 | case '[': |
| @@ -774,6 +806,23 @@ tputc(char c) { | |||
| 774 | case ']': | 806 | case ']': |
| 775 | term.esc |= ESCosc; | 807 | term.esc |= ESCosc; |
| 776 | break; | 808 | break; |
| 809 | case '(': | ||
| 810 | term.esc |= ESCcharset; | ||
| 811 | break; | ||
| 812 | case 'A': | ||
| 813 | tmoveto(term.c.x, term.c.y-1); | ||
| 814 | break; | ||
| 815 | case 'B': | ||
| 816 | tmoveto(term.c.x, term.c.y+1); | ||
| 817 | break; | ||
| 818 | case 'C': | ||
| 819 | tmoveto(term.c.x+1, term.c.y); | ||
| 820 | break; | ||
| 821 | case 'D': | ||
| 822 | tmoveto(term.c.x-1, term.c.y); | ||
| 823 | break; | ||
| 824 | default: | ||
| 825 | fprintf(stderr, "erresc: unknown sequence ESC %02X '%c'\n", c, isprint(c)?c:'.'); | ||
| 777 | } | 826 | } |
| 778 | } | 827 | } |
| 779 | } else { | 828 | } else { |
| @@ -931,6 +980,8 @@ void | |||
| 931 | xdraws (char *s, Glyph base, int x, int y, int len) { | 980 | xdraws (char *s, Glyph base, int x, int y, int len) { |
| 932 | unsigned long xfg, xbg; | 981 | unsigned long xfg, xbg; |
| 933 | int winx = x*xw.cw, winy = y*xw.ch + dc.font->ascent, width = len*xw.cw; | 982 | int winx = x*xw.cw, winy = y*xw.ch + dc.font->ascent, width = len*xw.cw; |
| 983 | int i; | ||
| 984 | |||
| 934 | if(base.mode & ATreverse) | 985 | if(base.mode & ATreverse) |
| 935 | xfg = dc.col[base.bg], xbg = dc.col[base.fg]; | 986 | xfg = dc.col[base.bg], xbg = dc.col[base.fg]; |
| 936 | else | 987 | else |
| @@ -938,6 +989,13 @@ xdraws (char *s, Glyph base, int x, int y, int len) { | |||
| 938 | 989 | ||
| 939 | XSetBackground(xw.dis, dc.gc, xbg); | 990 | XSetBackground(xw.dis, dc.gc, xbg); |
| 940 | XSetForeground(xw.dis, dc.gc, xfg); | 991 | XSetForeground(xw.dis, dc.gc, xfg); |
| 992 | |||
| 993 | if(base.mode & ATgfx) { | ||
| 994 | |||
| 995 | for(i = 0; i < len; i++) | ||
| 996 | s[i] = gfx[s[i]]; | ||
| 997 | } | ||
| 998 | |||
| 941 | XDrawImageString(xw.dis, xw.win, dc.gc, winx, winy, s, len); | 999 | XDrawImageString(xw.dis, xw.win, dc.gc, winx, winy, s, len); |
| 942 | 1000 | ||
| 943 | if(base.mode & ATunderline) | 1001 | if(base.mode & ATunderline) |
| @@ -1006,7 +1064,8 @@ draw(int redraw_all) { | |||
| 1006 | } | 1064 | } |
| 1007 | xdraws(buf, base, ox, y, i); | 1065 | xdraws(buf, base, ox, y, i); |
| 1008 | } | 1066 | } |
| 1009 | xcursor(CSdraw); | 1067 | if(!term.c.hidden) |
| 1068 | xcursor(CSdraw); | ||
| 1010 | } | 1069 | } |
| 1011 | 1070 | ||
| 1012 | void | 1071 | void |
| @@ -1014,7 +1073,7 @@ expose(XEvent *ev) { | |||
| 1014 | draw(SCredraw); | 1073 | draw(SCredraw); |
| 1015 | } | 1074 | } |
| 1016 | 1075 | ||
| 1017 | char * | 1076 | char* |
| 1018 | kmap(KeySym k) { | 1077 | kmap(KeySym k) { |
| 1019 | int i; | 1078 | int i; |
| 1020 | for(i = 0; i < LEN(key); i++) | 1079 | for(i = 0; i < LEN(key); i++) |
