diff options
| author | Aurélien Aptel <aurelien.aptel@gmail.com> | 2010-08-30 16:48:18 +0200 |
|---|---|---|
| committer | Aurélien Aptel <aurelien.aptel@gmail.com> | 2010-08-30 16:48:18 +0200 |
| commit | 12c25bcea973ced6e3b3b03f05cdb3f45fcd9f7f (patch) | |
| tree | 6cbef1a973033a4da18daef5942b3a30d8a70cad | |
| parent | cursor is hid when unfocused. (diff) | |
| download | st-12c25bcea973ced6e3b3b03f05cdb3f45fcd9f7f.tar.gz st-12c25bcea973ced6e3b3b03f05cdb3f45fcd9f7f.zip | |
added support for alternate screen.
| -rw-r--r-- | st.c | 70 |
1 files changed, 56 insertions, 14 deletions
| @@ -50,7 +50,7 @@ enum { CURSOR_UP, CURSOR_DOWN, CURSOR_LEFT, CURSOR_RIGHT, | |||
| 50 | CURSOR_SAVE, CURSOR_LOAD }; | 50 | CURSOR_SAVE, CURSOR_LOAD }; |
| 51 | enum { CURSOR_DEFAULT = 0, CURSOR_HIDE = 1, CURSOR_WRAPNEXT = 2 }; | 51 | enum { CURSOR_DEFAULT = 0, CURSOR_HIDE = 1, CURSOR_WRAPNEXT = 2 }; |
| 52 | enum { GLYPH_SET=1, GLYPH_DIRTY=2 }; | 52 | enum { GLYPH_SET=1, GLYPH_DIRTY=2 }; |
| 53 | enum { MODE_WRAP=1, MODE_INSERT=2, MODE_APPKEYPAD=4 }; | 53 | enum { MODE_WRAP=1, MODE_INSERT=2, MODE_APPKEYPAD=4, MODE_ALTSCREEN=8 }; |
| 54 | enum { ESC_START=1, ESC_CSI=2, ESC_OSC=4, ESC_TITLE=8, ESC_ALTCHARSET=16 }; | 54 | enum { ESC_START=1, ESC_CSI=2, ESC_OSC=4, ESC_TITLE=8, ESC_ALTCHARSET=16 }; |
| 55 | enum { SCREEN_UPDATE, SCREEN_REDRAW }; | 55 | enum { SCREEN_UPDATE, SCREEN_REDRAW }; |
| 56 | 56 | ||
| @@ -86,7 +86,8 @@ typedef struct { | |||
| 86 | typedef struct { | 86 | typedef struct { |
| 87 | int row; /* nb row */ | 87 | int row; /* nb row */ |
| 88 | int col; /* nb col */ | 88 | int col; /* nb col */ |
| 89 | Line* line; /* screen */ | 89 | Line* line; /* screen */ |
| 90 | Line* alt; /* alternate screen */ | ||
| 90 | TCursor c; /* cursor */ | 91 | TCursor c; /* cursor */ |
| 91 | int top; /* top scroll limit */ | 92 | int top; /* top scroll limit */ |
| 92 | int bot; /* bottom scroll limit */ | 93 | int bot; /* bottom scroll limit */ |
| @@ -156,6 +157,7 @@ static void tscrolldown(int); | |||
| 156 | static void tsetattr(int*, int); | 157 | static void tsetattr(int*, int); |
| 157 | static void tsetchar(char); | 158 | static void tsetchar(char); |
| 158 | static void tsetscroll(int, int); | 159 | static void tsetscroll(int, int); |
| 160 | static void tswapscreen(void); | ||
| 159 | 161 | ||
| 160 | static void ttynew(void); | 162 | static void ttynew(void); |
| 161 | static void ttyread(void); | 163 | static void ttyread(void); |
| @@ -337,13 +339,24 @@ tnew(int col, int row) { | |||
| 337 | /* set screen size */ | 339 | /* set screen size */ |
| 338 | term.row = row, term.col = col; | 340 | term.row = row, term.col = col; |
| 339 | term.line = malloc(term.row * sizeof(Line)); | 341 | term.line = malloc(term.row * sizeof(Line)); |
| 340 | for(row = 0 ; row < term.row; row++) | 342 | term.alt = malloc(term.row * sizeof(Line)); |
| 343 | for(row = 0 ; row < term.row; row++) { | ||
| 341 | term.line[row] = malloc(term.col * sizeof(Glyph)); | 344 | term.line[row] = malloc(term.col * sizeof(Glyph)); |
| 345 | term.alt [row] = malloc(term.col * sizeof(Glyph)); | ||
| 346 | } | ||
| 342 | /* setup screen */ | 347 | /* setup screen */ |
| 343 | treset(); | 348 | treset(); |
| 344 | } | 349 | } |
| 345 | 350 | ||
| 346 | void | 351 | void |
| 352 | tswapscreen(void) { | ||
| 353 | Line* tmp = term.line; | ||
| 354 | term.line = term.alt; | ||
| 355 | term.alt = tmp; | ||
| 356 | term.mode ^= MODE_ALTSCREEN; | ||
| 357 | } | ||
| 358 | |||
| 359 | void | ||
| 347 | tscrolldown (int n) { | 360 | tscrolldown (int n) { |
| 348 | int i; | 361 | int i; |
| 349 | Line temp; | 362 | Line temp; |
| @@ -712,10 +725,21 @@ csihandle(void) { | |||
| 712 | case 25: | 725 | case 25: |
| 713 | term.c.state |= CURSOR_HIDE; | 726 | term.c.state |= CURSOR_HIDE; |
| 714 | break; | 727 | break; |
| 715 | case 1048: /* XXX: no alt. screen to erase/save */ | 728 | case 1047: |
| 729 | if(IS_SET(MODE_ALTSCREEN)) { | ||
| 730 | tclearregion(0, 0, term.col-1, term.row-1); | ||
| 731 | tswapscreen(); | ||
| 732 | } | ||
| 733 | break; | ||
| 734 | case 1048: | ||
| 735 | tcursor(CURSOR_LOAD); | ||
| 736 | break; | ||
| 716 | case 1049: | 737 | case 1049: |
| 717 | tcursor(CURSOR_LOAD); | 738 | tcursor(CURSOR_LOAD); |
| 718 | tclearregion(0, 0, term.col-1, term.row-1); | 739 | if(IS_SET(MODE_ALTSCREEN)) { |
| 740 | tclearregion(0, 0, term.col-1, term.row-1); | ||
| 741 | tswapscreen(); | ||
| 742 | } | ||
| 719 | break; | 743 | break; |
| 720 | default: | 744 | default: |
| 721 | goto unknown; | 745 | goto unknown; |
| @@ -761,10 +785,21 @@ csihandle(void) { | |||
| 761 | case 25: | 785 | case 25: |
| 762 | term.c.state &= ~CURSOR_HIDE; | 786 | term.c.state &= ~CURSOR_HIDE; |
| 763 | break; | 787 | break; |
| 764 | case 1048: | 788 | case 1047: |
| 765 | case 1049: /* XXX: no alt. screen to erase/save */ | 789 | if(IS_SET(MODE_ALTSCREEN)) |
| 790 | tclearregion(0, 0, term.col-1, term.row-1); | ||
| 791 | else | ||
| 792 | tswapscreen(); | ||
| 793 | break; | ||
| 794 | case 1048: | ||
| 795 | tcursor(CURSOR_SAVE); | ||
| 796 | break; | ||
| 797 | case 1049: | ||
| 766 | tcursor(CURSOR_SAVE); | 798 | tcursor(CURSOR_SAVE); |
| 767 | tclearregion(0, 0, term.col-1, term.row-1); | 799 | if(IS_SET(MODE_ALTSCREEN)) |
| 800 | tclearregion(0, 0, term.col-1, term.row-1); | ||
| 801 | else | ||
| 802 | tswapscreen(); | ||
| 768 | break; | 803 | break; |
| 769 | default: goto unknown; | 804 | default: goto unknown; |
| 770 | } | 805 | } |
| @@ -889,19 +924,19 @@ tputc(char c) { | |||
| 889 | treset(); | 924 | treset(); |
| 890 | term.esc = 0; | 925 | term.esc = 0; |
| 891 | break; | 926 | break; |
| 892 | case '=': /* DECPAM */ | 927 | case '=': /* DECPAM -- Application keypad */ |
| 893 | term.mode |= MODE_APPKEYPAD; | 928 | term.mode |= MODE_APPKEYPAD; |
| 894 | term.esc = 0; | 929 | term.esc = 0; |
| 895 | break; | 930 | break; |
| 896 | case '>': /* DECPNM */ | 931 | case '>': /* DECPNM -- Normal keypad */ |
| 897 | term.mode &= ~MODE_APPKEYPAD; | 932 | term.mode &= ~MODE_APPKEYPAD; |
| 898 | term.esc = 0; | 933 | term.esc = 0; |
| 899 | break; | 934 | break; |
| 900 | case '7': | 935 | case '7': /* DECSC -- Save Cursor*/ |
| 901 | tcursor(CURSOR_SAVE); | 936 | tcursor(CURSOR_SAVE); |
| 902 | term.esc = 0; | 937 | term.esc = 0; |
| 903 | break; | 938 | break; |
| 904 | case '8': | 939 | case '8': /* DECRC -- Restore Cursor */ |
| 905 | tcursor(CURSOR_LOAD); | 940 | tcursor(CURSOR_LOAD); |
| 906 | term.esc = 0; | 941 | term.esc = 0; |
| 907 | break; | 942 | break; |
| @@ -961,21 +996,28 @@ tresize(int col, int row) { | |||
| 961 | return; | 996 | return; |
| 962 | 997 | ||
| 963 | /* free uneeded rows */ | 998 | /* free uneeded rows */ |
| 964 | for(i = row; i < term.row; i++) | 999 | for(i = row; i < term.row; i++) { |
| 965 | free(term.line[i]); | 1000 | free(term.line[i]); |
| 1001 | free(term.alt[i]); | ||
| 1002 | } | ||
| 966 | 1003 | ||
| 967 | /* resize to new height */ | 1004 | /* resize to new height */ |
| 968 | term.line = realloc(term.line, row * sizeof(Line)); | 1005 | term.line = realloc(term.line, row * sizeof(Line)); |
| 1006 | term.line = realloc(term.alt, row * sizeof(Line)); | ||
| 969 | 1007 | ||
| 970 | /* resize each row to new width, zero-pad if needed */ | 1008 | /* resize each row to new width, zero-pad if needed */ |
| 971 | for(i = 0; i < minrow; i++) { | 1009 | for(i = 0; i < minrow; i++) { |
| 972 | term.line[i] = realloc(term.line[i], col * sizeof(Glyph)); | 1010 | term.line[i] = realloc(term.line[i], col * sizeof(Glyph)); |
| 1011 | term.alt[i] = realloc(term.alt[i], col * sizeof(Glyph)); | ||
| 973 | memset(term.line[i] + mincol, 0, (col - mincol) * sizeof(Glyph)); | 1012 | memset(term.line[i] + mincol, 0, (col - mincol) * sizeof(Glyph)); |
| 1013 | memset(term.alt[i] + mincol, 0, (col - mincol) * sizeof(Glyph)); | ||
| 974 | } | 1014 | } |
| 975 | 1015 | ||
| 976 | /* allocate any new rows */ | 1016 | /* allocate any new rows */ |
| 977 | for(/* i == minrow */; i < row; i++) | 1017 | for(/* i == minrow */; i < row; i++) { |
| 978 | term.line[i] = calloc(col, sizeof(Glyph)); | 1018 | term.line[i] = calloc(col, sizeof(Glyph)); |
| 1019 | term.alt [i] = calloc(col, sizeof(Glyph)); | ||
| 1020 | } | ||
| 979 | 1021 | ||
| 980 | /* update terminal size */ | 1022 | /* update terminal size */ |
| 981 | term.col = col, term.row = row; | 1023 | term.col = col, term.row = row; |
