aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
Diffstat (limited to 'st.c')
-rw-r--r--st.c82
1 files changed, 55 insertions, 27 deletions
diff --git a/st.c b/st.c
index 84f9abb..77ea0c8 100644
--- a/st.c
+++ b/st.c
@@ -137,6 +137,16 @@ enum term_mode {
137 |MODE_MOUSEMANY, 137 |MODE_MOUSEMANY,
138}; 138};
139 139
140enum charset {
141 CS_GRAPHIC0,
142 CS_GRAPHIC1,
143 CS_UK,
144 CS_USA,
145 CS_MULTI,
146 CS_GER,
147 CS_FIN
148};
149
140enum escape_state { 150enum escape_state {
141 ESC_START = 1, 151 ESC_START = 1,
142 ESC_CSI = 2, 152 ESC_CSI = 2,
@@ -216,6 +226,9 @@ typedef struct {
216 int bot; /* bottom scroll limit */ 226 int bot; /* bottom scroll limit */
217 int mode; /* terminal mode flags */ 227 int mode; /* terminal mode flags */
218 int esc; /* escape state flags */ 228 int esc; /* escape state flags */
229 char trantbl[4]; /* charset table translation */
230 int charset; /* current charset */
231 int icharset; /* selected charset for sequence */
219 bool numlock; /* lock numbers in keyboard */ 232 bool numlock; /* lock numbers in keyboard */
220 bool *tabs; 233 bool *tabs;
221} Term; 234} Term;
@@ -367,6 +380,8 @@ static void tsetmode(bool, bool, int *, int);
367static void tfulldirt(void); 380static void tfulldirt(void);
368static void techo(char *, int); 381static void techo(char *, int);
369static long tdefcolor(int *, int *, int); 382static long tdefcolor(int *, int *, int);
383static void tselcs(void);
384static void tdeftran(char);
370static inline bool match(uint, uint); 385static inline bool match(uint, uint);
371static void ttynew(void); 386static void ttynew(void);
372static void ttyread(void); 387static void ttyread(void);
@@ -1369,6 +1384,8 @@ treset(void) {
1369 term.top = 0; 1384 term.top = 0;
1370 term.bot = term.row - 1; 1385 term.bot = term.row - 1;
1371 term.mode = MODE_WRAP; 1386 term.mode = MODE_WRAP;
1387 memset(term.trantbl, sizeof(term.trantbl), CS_USA);
1388 term.charset = 0;
1372 1389
1373 tclearregion(0, 0, term.col-1, term.row-1); 1390 tclearregion(0, 0, term.col-1, term.row-1);
1374 tmoveto(0, 0); 1391 tmoveto(0, 0);
@@ -2260,6 +2277,33 @@ techo(char *buf, int len) {
2260} 2277}
2261 2278
2262void 2279void
2280tdeftran(char ascii) {
2281 char c, (*bp)[2];
2282 static char tbl[][2] = {
2283 {'0', CS_GRAPHIC0}, {'1', CS_GRAPHIC1}, {'A', CS_UK},
2284 {'B', CS_USA}, {'<', CS_MULTI}, {'K', CS_GER},
2285 {'5', CS_FIN}, {'C', CS_FIN},
2286 {0, 0}
2287 };
2288
2289 for (bp = &tbl[0]; (c = (*bp)[0]) && c != ascii; ++bp)
2290 /* nothing */;
2291
2292 if (c == 0)
2293 fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
2294 else
2295 term.trantbl[term.icharset] = (*bp)[1];
2296}
2297
2298void
2299tselcs(void) {
2300 if (term.trantbl[term.charset] == CS_GRAPHIC0)
2301 term.c.attr.mode |= ATTR_GFX;
2302 else
2303 term.c.attr.mode &= ~ATTR_GFX;
2304}
2305
2306void
2263tputc(char *c, int len) { 2307tputc(char *c, int len) {
2264 uchar ascii = *c; 2308 uchar ascii = *c;
2265 bool control = ascii < '\x20' || ascii == 0177; 2309 bool control = ascii < '\x20' || ascii == 0177;
@@ -2351,13 +2395,12 @@ tputc(char *c, int len) {
2351 term.esc = ESC_START; 2395 term.esc = ESC_START;
2352 return; 2396 return;
2353 case '\016': /* SO */ 2397 case '\016': /* SO */
2398 term.charset = 0;
2399 tselcs();
2400 return;
2354 case '\017': /* SI */ 2401 case '\017': /* SI */
2355 /* 2402 term.charset = 1;
2356 * Different charsets are hard to handle. Applications 2403 tselcs();
2357 * should use the right alt charset escapes for the
2358 * only reason they still exist: line drawing. The
2359 * rest is incompatible history st should not support.
2360 */
2361 return; 2404 return;
2362 case '\032': /* SUB */ 2405 case '\032': /* SUB */
2363 case '\030': /* CAN */ 2406 case '\030': /* CAN */
@@ -2385,22 +2428,8 @@ tputc(char *c, int len) {
2385 if(ascii == '\\') 2428 if(ascii == '\\')
2386 strhandle(); 2429 strhandle();
2387 } else if(term.esc & ESC_ALTCHARSET) { 2430 } else if(term.esc & ESC_ALTCHARSET) {
2388 switch(ascii) { 2431 tdeftran(ascii);
2389 case '0': /* Line drawing set */ 2432 tselcs();
2390 term.c.attr.mode |= ATTR_GFX;
2391 break;
2392 case 'B': /* USASCII */
2393 term.c.attr.mode &= ~ATTR_GFX;
2394 break;
2395 case 'A': /* UK (IGNORED) */
2396 case '<': /* multinational charset (IGNORED) */
2397 case '5': /* Finnish (IGNORED) */
2398 case 'C': /* Finnish (IGNORED) */
2399 case 'K': /* German (IGNORED) */
2400 break;
2401 default:
2402 fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
2403 }
2404 term.esc = 0; 2433 term.esc = 0;
2405 } else if(term.esc & ESC_TEST) { 2434 } else if(term.esc & ESC_TEST) {
2406 if(ascii == '8') { /* DEC screen alignment test. */ 2435 if(ascii == '8') { /* DEC screen alignment test. */
@@ -2431,13 +2460,12 @@ tputc(char *c, int len) {
2431 term.esc |= ESC_STR; 2460 term.esc |= ESC_STR;
2432 break; 2461 break;
2433 case '(': /* set primary charset G0 */ 2462 case '(': /* set primary charset G0 */
2463 case ')': /* set secondary charset G1 */
2464 case '*': /* set tertiary charset G2 */
2465 case '+': /* set quaternary charset G3 */
2466 term.icharset = ascii - '(';
2434 term.esc |= ESC_ALTCHARSET; 2467 term.esc |= ESC_ALTCHARSET;
2435 break; 2468 break;
2436 case ')': /* set secondary charset G1 (IGNORED) */
2437 case '*': /* set tertiary charset G2 (IGNORED) */
2438 case '+': /* set quaternary charset G3 (IGNORED) */
2439 term.esc = 0;
2440 break;
2441 case 'D': /* IND -- Linefeed */ 2469 case 'D': /* IND -- Linefeed */
2442 if(term.c.y == term.bot) { 2470 if(term.c.y == term.bot) {
2443 tscrollup(term.top, 1); 2471 tscrollup(term.top, 1);