summaryrefslogtreecommitdiffstats
path: root/st.c
diff options
context:
space:
mode:
Diffstat (limited to 'st.c')
-rw-r--r--st.c70
1 files changed, 56 insertions, 14 deletions
diff --git a/st.c b/st.c
index 73121ef..d928f0d 100644
--- a/st.c
+++ b/st.c
@@ -50,7 +50,7 @@ enum { CURSOR_UP, CURSOR_DOWN, CURSOR_LEFT, CURSOR_RIGHT,
50 CURSOR_SAVE, CURSOR_LOAD }; 50 CURSOR_SAVE, CURSOR_LOAD };
51enum { CURSOR_DEFAULT = 0, CURSOR_HIDE = 1, CURSOR_WRAPNEXT = 2 }; 51enum { CURSOR_DEFAULT = 0, CURSOR_HIDE = 1, CURSOR_WRAPNEXT = 2 };
52enum { GLYPH_SET=1, GLYPH_DIRTY=2 }; 52enum { GLYPH_SET=1, GLYPH_DIRTY=2 };
53enum { MODE_WRAP=1, MODE_INSERT=2, MODE_APPKEYPAD=4 }; 53enum { MODE_WRAP=1, MODE_INSERT=2, MODE_APPKEYPAD=4, MODE_ALTSCREEN=8 };
54enum { ESC_START=1, ESC_CSI=2, ESC_OSC=4, ESC_TITLE=8, ESC_ALTCHARSET=16 }; 54enum { ESC_START=1, ESC_CSI=2, ESC_OSC=4, ESC_TITLE=8, ESC_ALTCHARSET=16 };
55enum { SCREEN_UPDATE, SCREEN_REDRAW }; 55enum { SCREEN_UPDATE, SCREEN_REDRAW };
56 56
@@ -86,7 +86,8 @@ typedef struct {
86typedef struct { 86typedef 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);
156static void tsetattr(int*, int); 157static void tsetattr(int*, int);
157static void tsetchar(char); 158static void tsetchar(char);
158static void tsetscroll(int, int); 159static void tsetscroll(int, int);
160static void tswapscreen(void);
159 161
160static void ttynew(void); 162static void ttynew(void);
161static void ttyread(void); 163static 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
346void 351void
352tswapscreen(void) {
353 Line* tmp = term.line;
354 term.line = term.alt;
355 term.alt = tmp;
356 term.mode ^= MODE_ALTSCREEN;
357}
358
359void
347tscrolldown (int n) { 360tscrolldown (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;