Changeset 4077 for neercs/trunk/src/ansi.c
- Timestamp:
- 11/30/09 12:14:21 (3 years ago)
- File:
-
- 1 edited
-
neercs/trunk/src/ansi.c (modified) (60 diffs)
Legend:
- Unmodified
- Added
- Removed
-
neercs/trunk/src/ansi.c
r4076 r4077 25 25 switch (uc) 26 26 { 27 case '+':28 return 0x2192; /* RIGHTWARDS ARROW */29 case ',':30 return 0x2190; /* LEFTWARDS ARROW */31 case '-':32 return 0x2191; /* UPWARDS ARROW */33 case '.':34 return 0x2193; /* DOWNWARDS ARROW */35 case '0':36 return 0x25AE; /* BLACK VERTICAL RECTANGLE */37 case '_':38 return 0x25AE; /* BLACK VERTICAL RECTANGLE */39 case '`':40 return 0x25C6; /* BLACK DIAMOND */41 case 'a':42 return 0x2592; /* MEDIUM SHADE */43 case 'b':44 return 0x2409; /* SYMBOL FOR HORIZONTAL TABULATION */45 case 'c':46 return 0x240C; /* SYMBOL FOR FORM FEED */47 case 'd':48 return 0x240D; /* SYMBOL FOR CARRIAGE RETURN */49 case 'e':50 return 0x240A; /* SYMBOL FOR LINE FEED */51 case 'f':52 return 0x00B0; /* DEGREE SIGN */53 case 'g':54 return 0x00B1; /* PLUS-MINUS SIGN */55 case 'h':56 return 0x2424; /* SYMBOL FOR NEWLINE */57 case 'i':58 return 0x240B; /* SYMBOL FOR VERTICAL TABULATION */59 case 'j':60 return 0x2518; /* BOX DRAWINGS LIGHT UP AND LEFT */61 case 'k':62 return 0x2510; /* BOX DRAWINGS LIGHT DOWN AND LEFT */63 case 'l':64 return 0x250C; /* BOX DRAWINGS LIGHT DOWN AND RIGHT */65 case 'm':66 return 0x2514; /* BOX DRAWINGS LIGHT UP AND RIGHT */67 case 'n':68 return 0x253C; /* BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */69 case 'o':70 return 0x23BA; /* HORIZONTAL SCAN LINE-1 */71 case 'p':72 return 0x23BB; /* HORIZONTAL SCAN LINE-3 */73 case 'q':74 return 0x2500; /* BOX DRAWINGS LIGHT HORIZONTAL */75 case 'r':76 return 0x23BC; /* HORIZONTAL SCAN LINE-7 */77 case 's':78 return 0x23BD; /* HORIZONTAL SCAN LINE-9 */79 case 't':80 return 0x251C; /* BOX DRAWINGS LIGHT VERTICAL AND RIGHT */81 case 'u':82 return 0x2524; /* BOX DRAWINGS LIGHT VERTICAL AND LEFT */83 case 'v':84 return 0x2534; /* BOX DRAWINGS LIGHT UP AND HORIZONTAL */85 case 'w':86 return 0x252C; /* BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */87 case 'x':88 return 0x2502; /* BOX DRAWINGS LIGHT VERTICAL */89 case 'y':90 return 0x2264; /* LESS-THAN OR EQUAL TO */91 case 'z':92 return 0x2265; /* GREATER-THAN OR EQUAL TO */93 case '{':94 return 0x03C0; /* GREEK SMALL LETTER PI */95 case '|':96 return 0x2260; /* NOT EQUAL TO */97 case '}':98 return 0x00A3; /* POUND SIGN */99 case '~':100 return 0x00B7; /* MIDDLE DOT */101 default:102 return uc;27 case '+': 28 return 0x2192; /* RIGHTWARDS ARROW */ 29 case ',': 30 return 0x2190; /* LEFTWARDS ARROW */ 31 case '-': 32 return 0x2191; /* UPWARDS ARROW */ 33 case '.': 34 return 0x2193; /* DOWNWARDS ARROW */ 35 case '0': 36 return 0x25AE; /* BLACK VERTICAL RECTANGLE */ 37 case '_': 38 return 0x25AE; /* BLACK VERTICAL RECTANGLE */ 39 case '`': 40 return 0x25C6; /* BLACK DIAMOND */ 41 case 'a': 42 return 0x2592; /* MEDIUM SHADE */ 43 case 'b': 44 return 0x2409; /* SYMBOL FOR HORIZONTAL TABULATION */ 45 case 'c': 46 return 0x240C; /* SYMBOL FOR FORM FEED */ 47 case 'd': 48 return 0x240D; /* SYMBOL FOR CARRIAGE RETURN */ 49 case 'e': 50 return 0x240A; /* SYMBOL FOR LINE FEED */ 51 case 'f': 52 return 0x00B0; /* DEGREE SIGN */ 53 case 'g': 54 return 0x00B1; /* PLUS-MINUS SIGN */ 55 case 'h': 56 return 0x2424; /* SYMBOL FOR NEWLINE */ 57 case 'i': 58 return 0x240B; /* SYMBOL FOR VERTICAL TABULATION */ 59 case 'j': 60 return 0x2518; /* BOX DRAWINGS LIGHT UP AND LEFT */ 61 case 'k': 62 return 0x2510; /* BOX DRAWINGS LIGHT DOWN AND LEFT */ 63 case 'l': 64 return 0x250C; /* BOX DRAWINGS LIGHT DOWN AND RIGHT */ 65 case 'm': 66 return 0x2514; /* BOX DRAWINGS LIGHT UP AND RIGHT */ 67 case 'n': 68 return 0x253C; /* BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ 69 case 'o': 70 return 0x23BA; /* HORIZONTAL SCAN LINE-1 */ 71 case 'p': 72 return 0x23BB; /* HORIZONTAL SCAN LINE-3 */ 73 case 'q': 74 return 0x2500; /* BOX DRAWINGS LIGHT HORIZONTAL */ 75 case 'r': 76 return 0x23BC; /* HORIZONTAL SCAN LINE-7 */ 77 case 's': 78 return 0x23BD; /* HORIZONTAL SCAN LINE-9 */ 79 case 't': 80 return 0x251C; /* BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ 81 case 'u': 82 return 0x2524; /* BOX DRAWINGS LIGHT VERTICAL AND LEFT */ 83 case 'v': 84 return 0x2534; /* BOX DRAWINGS LIGHT UP AND HORIZONTAL */ 85 case 'w': 86 return 0x252C; /* BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ 87 case 'x': 88 return 0x2502; /* BOX DRAWINGS LIGHT VERTICAL */ 89 case 'y': 90 return 0x2264; /* LESS-THAN OR EQUAL TO */ 91 case 'z': 92 return 0x2265; /* GREATER-THAN OR EQUAL TO */ 93 case '{': 94 return 0x03C0; /* GREEK SMALL LETTER PI */ 95 case '|': 96 return 0x2260; /* NOT EQUAL TO */ 97 case '}': 98 return 0x00A3; /* POUND SIGN */ 99 case '~': 100 return 0x00B7; /* MIDDLE DOT */ 101 default: 102 return uc; 103 103 } 104 104 }; … … 116 116 struct screen_list *screen_list, 117 117 struct screen *sc); 118 inline int handle_duplet(unsigned char const *buffer, struct screen *sc, 119 unsigned int *skip, int top, int bottom, int width, int height); 118 inline int handle_duplet(unsigned char const *buffer, struct screen *sc, 119 unsigned int *skip, int top, int bottom, int width, 120 int height); 120 121 121 122 … … 128 129 *x = 0; 129 130 } 130 131 131 132 else if (c == '\n') 132 133 { … … 140 141 sc->bell = 1; 141 142 } 142 143 143 144 else if (c == '\t') 144 145 { 145 146 *x = (*x + 7) & ~7; 146 147 } 147 148 148 149 else if (c == '\x08') 149 150 { … … 161 162 { 162 163 /* Shift Out (Ctrl-N) -> Switch to Alternate Character Set: invokes 163 the G1 character set. */164 the G1 character set. */ 164 165 sc->conv_state.glr[0] = 1; 165 166 } 166 167 167 168 else if (c == '\x0f') 168 169 { 169 170 /* Shift In (Ctrl-O) -> Switch to Standard Character Set: invokes the 170 G0 character set. */171 G0 character set. */ 171 172 sc->conv_state.glr[0] = 0; 172 173 } … … 178 179 } 179 180 180 inline int handle_duplet(unsigned char const *buffer, struct screen *sc, unsigned int *skip, 181 int top, int bottom, int width, int height) 181 inline int handle_duplet(unsigned char const *buffer, struct screen *sc, 182 unsigned int *skip, int top, int bottom, int width, 183 int height) 182 184 { 183 185 int i = 0, j, k; 184 unsigned int dummy =0;185 186 unsigned int dummy = 0; 187 186 188 /* Single Shift Select of G2 Character Set (SS2: 0x8e): affects next 187 character only */189 character only */ 188 190 if (buffer[i] == '\033' && buffer[i + 1] == 'N') 189 191 { … … 195 197 { 196 198 /* FIXME : not sure about the meaning of 'go up one line' and 'if 197 necessary' words. Implemented as a scroller only. */199 necessary' words. Implemented as a scroller only. */ 198 200 for (j = bottom - 1; j > top; j--) 199 201 { 200 202 for (k = 0; k < width; k++) 201 203 { 202 caca_put_char(sc->cv, k, j, 203 caca_get_char(sc->cv, k, j - 1)); 204 caca_put_attr(sc->cv, k, j, 205 caca_get_attr(sc->cv, k, j - 1)); 204 caca_put_char(sc->cv, k, j, caca_get_char(sc->cv, k, j - 1)); 205 caca_put_attr(sc->cv, k, j, caca_get_attr(sc->cv, k, j - 1)); 206 206 } 207 207 } … … 209 209 *skip += 1; 210 210 } 211 211 212 212 /* Single Shift Select of G3 Character Set (SS2: 0x8f): affects next 213 character only */213 character only */ 214 214 else if (buffer[i] == '\033' && buffer[i + 1] == 'O') 215 215 { … … 217 217 *skip += 1; 218 218 } 219 219 220 220 /* LOCKING-SHIFT TWO (LS2), ISO 2022, ECMA-48 (1986), ISO 6429 : 1988 */ 221 221 else if (buffer[i] == '\033' && buffer[i + 1] == 'n') … … 224 224 *skip += 1; 225 225 } 226 227 /* LOCKING-SHIFT THREE (LS3) ISO 2022, ECMA-48 (1986), ISO 6429 : 1988 228 */ 226 227 /* LOCKING-SHIFT THREE (LS3) ISO 2022, ECMA-48 (1986), ISO 6429 : 1988 */ 229 228 else if (buffer[i] == '\033' && buffer[i + 1] == 'o') 230 229 { … … 232 231 *skip += 1; 233 232 } 234 233 235 234 /* RESET TO INITIAL STATE (RIS), ECMA-48 (1986), ISO 6429 : 1988 */ 236 235 else if (buffer[i] == '\033' && buffer[i + 1] == 'c') … … 238 237 sc->dfg = CACA_DEFAULT; 239 238 sc->dbg = CACA_DEFAULT; 240 239 241 240 caca_set_color_ansi(sc->cv, sc->dfg, sc->dbg); 242 241 sc->clearattr = caca_get_attr(sc->cv, -1, -1); 243 242 ansi_parse_grcm(sc, 1, &dummy); 244 243 245 244 reset_conv_state(sc); 246 245 *skip += 1; 247 246 } 248 249 /* Coding Method Delimiter (CMD), ECMA-48 (1991), ISO/IEC 6429:1992 250 (ISOIR 189) */247 248 /* Coding Method Delimiter (CMD), ECMA-48 (1991), ISO/IEC 6429:1992 (ISO 249 IR 189) */ 251 250 else if (buffer[i] == '\033' && buffer[i + 1] == 'd') 252 251 { … … 254 253 *skip += 1; 255 254 } 256 else 257 { 258 return 1;255 else 256 { 257 return 1; 259 258 } 260 259 … … 272 271 int x = 0, y = 0, save_x = 0, save_y = 0; 273 272 char b[100]; 274 273 275 274 debug("ansi : import_term\n"); 276 275 277 276 width = caca_get_canvas_width(sc->cv); 278 277 height = caca_get_canvas_height(sc->cv); … … 281 280 top = 1; 282 281 bottom = height; 283 282 284 283 if (!sc->init) 285 284 { 286 285 sc->dfg = CACA_LIGHTGRAY; 287 286 sc->dbg = CACA_BLACK; 288 287 289 288 caca_set_color_ansi(sc->cv, sc->dfg, sc->dbg); 290 289 sc->clearattr = caca_get_attr(sc->cv, -1, -1); 291 290 292 291 ansi_parse_grcm(sc, 1, &dummy); 293 292 294 293 reset_conv_state(sc); 295 294 296 295 sc->init = 1; 297 296 } 298 297 299 298 for (i = 0; i < size; i += skip) 300 299 { 301 300 uint32_t ch = 0; 302 301 int wch = 0; 303 302 304 303 skip = 1; 305 304 306 305 /* Control codes (ASCII < \x20) */ 307 306 if (!handle_single_char(buffer[i], &x, &y, screen_list, sc)) 308 307 { 309 308 } 310 309 311 310 /* If there are not enough characters to parse the escape sequence, 312 wait until the next try. We require 3. */313 311 wait until the next try. We require 3. */ 312 314 313 else if (buffer[i] == '\033' && i + 2 >= size) 315 314 break; 316 315 317 318 else if(!handle_duplet(&buffer[i], sc, &skip, top, bottom, width, height)) 319 { 320 321 } 322 323 316 317 else if (!handle_duplet 318 (&buffer[i], sc, &skip, top, bottom, width, height)) 319 { 320 321 } 322 323 324 324 /* GZDM4, G0-Designators, multi, 94^n chars [grandfathered short form 325 from ISO 2022:1986] */325 from ISO 2022:1986] */ 326 326 else if (buffer[i] == '\033' && buffer[i + 1] == '$' 327 327 && (buffer[i + 2] >= '@') && (buffer[i + 2] <= 'C')) … … 330 330 skip += 2; 331 331 } 332 332 333 333 /* GnDMx Gn-Designators, 9x^n chars; need one more char to distinguish 334 these */334 these */ 335 335 else if (buffer[i] == '\033' && buffer[i + 1] == '$' 336 336 && (i + 3 >= size)) 337 337 break; 338 338 339 339 /* GZD4 G0-Designator, 94 chars */ 340 340 else if (buffer[i] == '\033' && buffer[i + 1] == '(') … … 343 343 skip += 2; 344 344 } 345 345 346 346 /* G1D4 G1-Designator, 94 chars */ 347 347 else if (buffer[i] == '\033' && buffer[i + 1] == ')') … … 350 350 skip += 2; 351 351 } 352 352 353 353 /* G2D4 G2-Designator, 94 chars */ 354 354 else if (buffer[i] == '\033' && buffer[i + 1] == '*') … … 357 357 skip += 2; 358 358 } 359 359 360 360 /* G3D4 G3-Designator, 94 chars */ 361 361 else if (buffer[i] == '\033' && buffer[i + 1] == '+') … … 364 364 skip += 2; 365 365 } 366 366 367 367 /* G2D6 G2-Designator, 96 chars */ 368 368 else if (buffer[i] == '\033' && buffer[i + 1] == '.') … … 371 371 skip += 2; 372 372 } 373 373 374 374 /* G3D6 G3-Designator, 96 chars */ 375 375 else if (buffer[i] == '\033' && buffer[i + 1] == '/') … … 378 378 skip += 2; 379 379 } 380 380 381 381 /* GZDM4 G0-Designator, 94^n chars */ 382 382 else if (buffer[i] == '\033' && buffer[i + 1] == '$' … … 386 386 skip += 3; 387 387 } 388 388 389 389 /* G1DM4 G1-Designator, 94^n chars */ 390 390 else if (buffer[i] == '\033' && buffer[i + 1] == '$' … … 394 394 skip += 3; 395 395 } 396 396 397 397 /* G2DM4 G2-Designator, 94^n chars */ 398 398 else if (buffer[i] == '\033' && buffer[i + 1] == '$' … … 402 402 skip += 3; 403 403 } 404 404 405 405 /* G3DM4 G3-Designator, 94^n chars */ 406 406 else if (buffer[i] == '\033' && buffer[i + 1] == '$' … … 410 410 skip += 3; 411 411 } 412 412 413 413 /* G2DM6 G2-Designator, 96^n chars */ 414 414 else if (buffer[i] == '\033' && buffer[i + 1] == '$' … … 418 418 skip += 3; 419 419 } 420 420 421 421 /* G3DM6 G3-Designator, 96^n chars */ 422 422 else if (buffer[i] == '\033' && buffer[i + 1] == '$' … … 429 429 { 430 430 debug("ansi private '#' sequence\n"); 431 431 432 432 switch (buffer[i + 2]) 433 433 { 434 case '8': /* DECALN Fills the entire screen area with 435 uppercase Es for screen focus and 436 alignment. */ 437 for (j = 0; j < height; j++) 434 case '8': /* DECALN Fills the entire screen area with 435 uppercase Es for screen focus and 436 alignment. */ 437 for (j = 0; j < height; j++) 438 { 439 for (k = 0; k < width; k++) 438 440 { 439 for (k = 0; k < width; k++) 440 { 441 caca_put_char(sc->cv, k, j, 'E'); 442 } 441 caca_put_char(sc->cv, k, j, 'E'); 443 442 } 444 x = 0; 445 y = 0; 446 skip += 2; 447 break; 448 449 default: 450 debug("Unknow private sequence 'ESC#%c'\n", buffer[i + 2]); 451 continue; 452 } 453 443 } 444 x = 0; 445 y = 0; 446 skip += 2; 447 break; 448 449 default: 450 debug("Unknow private sequence 'ESC#%c'\n", buffer[i + 2]); 451 continue; 452 } 453 454 454 } 455 455 /* Interpret escape commands, as per Standard ECMA-48 "Control 456 Functions for Coded Character Sets", 5.4. Control sequences. */456 Functions for Coded Character Sets", 5.4. Control sequences. */ 457 457 else if (buffer[i] == '\033' && buffer[i + 1] == '[') 458 458 { 459 459 unsigned int argc = 0, argv[101]; 460 460 unsigned int param, inter, junk, final; 461 461 462 462 if (buffer[i + 2] == '?') 463 463 { … … 466 466 buffer[i + 6], buffer[i + 7]); 467 467 } 468 468 469 469 /* Compute offsets to parameter bytes, intermediate bytes and to 470 the final byte. Only the final byte is mandatory, there can be471 zero of the others. 0 param=2 inter final final+1472 +-----+------------------+---------------------+-----------------+473 | CSI | parameter bytes | intermediate bytes | final byte | | |474 0x30 - 0x3f | 0x20 - 0x2f | 0x40 - 0x7e | | ^[[ | 0123456789:;<=>?475 | SPC !"#$%&'()*+,-./ | azAZ@[\]^_`{|}~ |476 +-----+------------------+---------------------+-----------------+ */470 the final byte. Only the final byte is mandatory, there can be 471 zero of the others. 0 param=2 inter final final+1 472 +-----+------------------+---------------------+-----------------+ 473 | CSI | parameter bytes | intermediate bytes | final byte | | | 474 0x30 - 0x3f | 0x20 - 0x2f | 0x40 - 0x7e | | ^[[ | 0123456789:;<=>? 475 | SPC !"#$%&'()*+,-./ | azAZ@[\]^_`{|}~ | 476 +-----+------------------+---------------------+-----------------+ */ 477 477 param = 2; 478 478 479 479 /* vttest use to interleave control characters (\014 CR or \010 480 BS) into CSI sequences, either directly after ESC[ or after481 param. Can't find anything related to this in any documentation482 nor XTerm sources, thought. */483 480 BS) into CSI sequences, either directly after ESC[ or after 481 param. Can't find anything related to this in any documentation 482 nor XTerm sources, thought. */ 483 484 484 for (junk = param; i + junk < size; junk++) 485 485 if (buffer[i + junk] < 0x20) … … 492 492 break; 493 493 } 494 494 495 495 /* Intermediate offset */ 496 496 for (inter = junk; i + inter < size; inter++) … … 510 510 break; 511 511 } 512 512 513 513 /* Final Byte offset */ 514 514 for (final = junk; i + final < size; final++) … … 524 524 break; /* Invalid Final Byte */ 525 525 } 526 526 527 527 skip += final; 528 528 529 529 /* Sanity checks */ 530 530 if (param < inter && buffer[i + param] >= 0x3c) … … 533 533 debug("ansi import: private sequence \"^[[%.*s\"", 534 534 final - param + 1, buffer + i + param); 535 /* FIXME better parsing */535 /* FIXME better parsing */ 536 536 if (buffer[i + 2] == '?') 537 537 { … … 559 559 if (c == 'h') /* DECSET DEC Private Mode Set */ 560 560 { 561 561 562 562 switch (Pm) 563 563 { 564 /* FIXME Handle different modes */565 case 1000: /* Send Mouse X & Y on button press566 and release. */567 case 1001: /* Use Hilite Mouse Tracking. */568 case 1002: /* Use Cell Motion Mouse Tracking. */569 case 1003: /* Use All Motion Mouse Tracking. */570 sc->report_mouse = 1;571 break;572 default:573 break;564 /* FIXME Handle different modes */ 565 case 1000: /* Send Mouse X & Y on button press 566 and release. */ 567 case 1001: /* Use Hilite Mouse Tracking. */ 568 case 1002: /* Use Cell Motion Mouse Tracking. */ 569 case 1003: /* Use All Motion Mouse Tracking. */ 570 sc->report_mouse = 1; 571 break; 572 default: 573 break; 574 574 } 575 575 } … … 579 579 switch (Pm) 580 580 { 581 /* FIXME Handle different modes */582 case 1000: /* Send Mouse X & Y on button press583 and release. */584 case 1001: /* Use Hilite Mouse Tracking. */585 case 1002: /* Use Cell Motion Mouse Tracking. */586 case 1003: /* Use All Motion Mouse Tracking. */587 sc->report_mouse = 0;588 break;589 default:590 break;581 /* FIXME Handle different modes */ 582 case 1000: /* Send Mouse X & Y on button press 583 and release. */ 584 case 1001: /* Use Hilite Mouse Tracking. */ 585 case 1002: /* Use Cell Motion Mouse Tracking. */ 586 case 1003: /* Use All Motion Mouse Tracking. */ 587 sc->report_mouse = 0; 588 break; 589 default: 590 break; 591 591 } 592 592 } … … 594 594 continue; /* Private sequence, skip it entirely */ 595 595 } 596 596 597 597 if (final - param > 100) 598 598 continue; /* Suspiciously long sequence, skip it */ 599 599 600 600 /* Parse parameter bytes as per ECMA-48 5.4.2: Parameter string 601 format */601 format */ 602 602 if (param < inter) 603 603 { … … 612 612 argc++; 613 613 } 614 614 615 615 /* Interpret final byte. The code representations are given in 616 ECMA-48 5.4: Control sequences, and the code definitions are617 given in ECMA-48 8.3: Definition of control functions. */616 ECMA-48 5.4: Control sequences, and the code definitions are 617 given in ECMA-48 8.3: Definition of control functions. */ 618 618 debug("ansi import: command '%c'", buffer[i + final]); 619 619 switch (buffer[i + final]) 620 620 { 621 case 'A': /* CUU (0x41) - Cursor Up */622 y -= argc ? argv[0] : 1;623 if (y < 0)624 y = 0;625 break;626 case 'B': /* CUD (0x42) - Cursor Down */627 y += argc ? argv[0] : 1;628 break;629 case 'C': /* CUF (0x43) - Cursor Right */630 x += argc ? argv[0] : 1;631 break;632 case 'D': /* CUB (0x44) - Cursor Left */633 x -= argc ? argv[0] : 1;634 if (x < 0)635 x = 0;636 break;637 case 'G': /* CHA (0x47) - Cursor Character Absolute */638 x = (argc && argv[0] > 0) ? argv[0] - 1 : 0;639 break;640 case 'H': /* CUP (0x48) - Cursor Position */641 x = (argc > 1 && argv[1] > 0) ? argv[1] - 1 : 0;642 y = (argc > 0 && argv[0] > 0) ? argv[0] - 1 : 0;643 debug("ansi CUP : Cursor at %dx%d\n", x, y);644 break;645 case 'J': /* ED (0x4a) - Erase In Page */646 savedattr = caca_get_attr(sc->cv, -1, -1);647 caca_set_attr(sc->cv, sc->clearattr);648 if (!argc || argv[0] == 0)649 {650 caca_draw_line(sc->cv, x, y, width, y, ' ');651 caca_fill_box(sc->cv, 0, y + 1, width, height - 1, ' ');652 }653 else if (argv[0] == 1)654 {655 caca_fill_box(sc->cv, 0, 0, width, y, ' ');656 caca_draw_line(sc->cv, 0, y, x, y, ' ');657 }658 else if (argv[0] == 2)659 {660 // x = y = 0;661 caca_fill_box(sc->cv, 0, 0, width, height, ' ');662 }663 caca_set_attr(sc->cv, savedattr);664 break;665 case 'K': /* EL (0x4b) - Erase In Line */666 debug("ansi EL : cursor at %dx%d\n", x, y);667 if (!argc || argv[0] == 0)668 {669 caca_draw_line(sc->cv, x, y, width, y, ' ');670 }671 else if (argv[0] == 1)672 {673 caca_draw_line(sc->cv, 0, y, x, y, ' ');674 }675 else if (argv[0] == 2)676 {677 caca_draw_line(sc->cv, 0, y, width, y, ' ');678 }679 break;680 case 'L': /* IL - Insert line */621 case 'A': /* CUU (0x41) - Cursor Up */ 622 y -= argc ? argv[0] : 1; 623 if (y < 0) 624 y = 0; 625 break; 626 case 'B': /* CUD (0x42) - Cursor Down */ 627 y += argc ? argv[0] : 1; 628 break; 629 case 'C': /* CUF (0x43) - Cursor Right */ 630 x += argc ? argv[0] : 1; 631 break; 632 case 'D': /* CUB (0x44) - Cursor Left */ 633 x -= argc ? argv[0] : 1; 634 if (x < 0) 635 x = 0; 636 break; 637 case 'G': /* CHA (0x47) - Cursor Character Absolute */ 638 x = (argc && argv[0] > 0) ? argv[0] - 1 : 0; 639 break; 640 case 'H': /* CUP (0x48) - Cursor Position */ 641 x = (argc > 1 && argv[1] > 0) ? argv[1] - 1 : 0; 642 y = (argc > 0 && argv[0] > 0) ? argv[0] - 1 : 0; 643 debug("ansi CUP : Cursor at %dx%d\n", x, y); 644 break; 645 case 'J': /* ED (0x4a) - Erase In Page */ 646 savedattr = caca_get_attr(sc->cv, -1, -1); 647 caca_set_attr(sc->cv, sc->clearattr); 648 if (!argc || argv[0] == 0) 649 { 650 caca_draw_line(sc->cv, x, y, width, y, ' '); 651 caca_fill_box(sc->cv, 0, y + 1, width, height - 1, ' '); 652 } 653 else if (argv[0] == 1) 654 { 655 caca_fill_box(sc->cv, 0, 0, width, y, ' '); 656 caca_draw_line(sc->cv, 0, y, x, y, ' '); 657 } 658 else if (argv[0] == 2) 659 { 660 // x = y = 0; 661 caca_fill_box(sc->cv, 0, 0, width, height, ' '); 662 } 663 caca_set_attr(sc->cv, savedattr); 664 break; 665 case 'K': /* EL (0x4b) - Erase In Line */ 666 debug("ansi EL : cursor at %dx%d\n", x, y); 667 if (!argc || argv[0] == 0) 668 { 669 caca_draw_line(sc->cv, x, y, width, y, ' '); 670 } 671 else if (argv[0] == 1) 672 { 673 caca_draw_line(sc->cv, 0, y, x, y, ' '); 674 } 675 else if (argv[0] == 2) 676 { 677 caca_draw_line(sc->cv, 0, y, width, y, ' '); 678 } 679 break; 680 case 'L': /* IL - Insert line */ 681 681 { 682 682 unsigned int nb_lines = argc ? argv[0] : 1; … … 696 696 } 697 697 } 698 break;699 case 'P': /* DCH (0x50) - Delete Character */700 if (!argc || argv[0] == 0)701 argv[0] = 1; /* echo -ne 'foobar\r\e[0P\n' */702 703 for (j = x; (unsigned int)(j + argv[0]) < width; j++)704 {705 caca_put_char(sc->cv, j, y,706 caca_get_char(sc->cv, j + argv[0], y));707 caca_put_attr(sc->cv, j, y,708 caca_get_attr(sc->cv, j + argv[0], y));709 }710 break;698 break; 699 case 'P': /* DCH (0x50) - Delete Character */ 700 if (!argc || argv[0] == 0) 701 argv[0] = 1; /* echo -ne 'foobar\r\e[0P\n' */ 702 703 for (j = x; (unsigned int)(j + argv[0]) < width; j++) 704 { 705 caca_put_char(sc->cv, j, y, 706 caca_get_char(sc->cv, j + argv[0], y)); 707 caca_put_attr(sc->cv, j, y, 708 caca_get_attr(sc->cv, j + argv[0], y)); 709 } 710 break; 711 711 #if 0 712 savedattr = caca_get_attr(sc->cv, -1, -1); 713 caca_set_attr(sc->cv, sc->clearattr); 714 for (; (unsigned int)j < width; j++) 715 caca_put_char(sc->cv, j, y, ' '); 716 caca_set_attr(sc->cv, savedattr); 717 #endif 718 case 'X': /* ECH (0x58) - Erase Character */ 719 if (argc && argv[0]) 720 { 712 721 savedattr = caca_get_attr(sc->cv, -1, -1); 713 722 caca_set_attr(sc->cv, sc->clearattr); 714 for (; (unsigned int)j < width; j++) 715 caca_put_char(sc->cv, j, y, ' '); 723 caca_draw_line(sc->cv, x, y, x + argv[0] - 1, y, ' '); 716 724 caca_set_attr(sc->cv, savedattr); 717 #endif 718 case 'X': /* ECH (0x58) - Erase Character */ 719 if (argc && argv[0]) 725 } 726 case 'c': /* DA -- Device Attributes */ 727 /* 728 0 Base VT100, no options 1 Processor options (STP) 2 729 Advanced video option (AVO) 3 AVO and STP 4 Graphics 730 processor option (GPO) 5 GPO and STP 6 GPO and AVO 7 GPO, 731 STP, and AVO */ 732 /* Warning, argument is Pn */ 733 debug("ansi Got command c, argc %d, argv[0] (%d)\n", argc, 734 argv[0], argv[0]); 735 if (!argc || argv[0] == 0) 736 { 737 send_ansi_sequence(screen_list, "\x1b[?1;0c"); 738 } 739 else 740 { 741 switch (argv[0]) 720 742 { 721 savedattr = caca_get_attr(sc->cv, -1, -1); 722 caca_set_attr(sc->cv, sc->clearattr); 723 caca_draw_line(sc->cv, x, y, x + argv[0] - 1, y, ' '); 724 caca_set_attr(sc->cv, savedattr); 725 } 726 case 'c': /* DA -- Device Attributes */ 727 /* 728 0 Base VT100, no options 1 Processor options (STP) 2 729 Advanced video option (AVO) 3 AVO and STP 4 Graphics 730 processor option (GPO) 5 GPO and STP 6 GPO and AVO 7 GPO, 731 STP, and AVO */ 732 /* Warning, argument is Pn */ 733 debug("ansi Got command c, argc %d, argv[0] (%d)\n", argc, 734 argv[0], argv[0]); 735 if (!argc || argv[0] == 0) 736 { 737 send_ansi_sequence(screen_list, "\x1b[?1;0c"); 738 } 739 else 740 { 741 switch (argv[0]) 742 { 743 case 1: 744 send_ansi_sequence(screen_list, "\x1b[?\x1;\x1c"); 745 break; 746 case 2: 747 send_ansi_sequence(screen_list, "\x1b[?\x1;\x2c"); 748 break; 749 case 3: 750 send_ansi_sequence(screen_list, "\x1b[?\x1;\x3c"); 751 break; 752 case 4: 753 send_ansi_sequence(screen_list, "\x1b[?\x1;\x4c"); 754 break; 755 case 5: 756 send_ansi_sequence(screen_list, "\x1b[?\x1;\x5c"); 757 break; 758 case 6: 759 send_ansi_sequence(screen_list, "\x1b[?\x1;\x6c"); 760 break; 761 case 7: 762 send_ansi_sequence(screen_list, "\x1b[?\x1;\x7c"); 763 break; 764 default: 765 debug("Unsupported DA option '%d'\n", argv[0]); 766 break; 767 } 768 } 769 break; 770 case 'd': /* VPA (0x64) - Line Position Absolute */ 771 y = (argc && argv[0] > 0) ? argv[0] - 1 : 0; 772 break; 773 case 'f': /* HVP (0x66) - Character And Line Position */ 774 x = (argc > 1 && argv[1] > 0) ? argv[1] - 1 : 0; 775 y = (argc > 0 && argv[0] > 0) ? argv[0] - 1 : 0; 776 break; 777 case 'g': /* TBC -- Tabulation Clear */ 778 break; 779 case 'r': /* FIXME */ 780 if (argc == 2) /* DCSTBM - Set top and bottom margin */ 781 { 782 debug("DCSTBM %d %d", argv[0], argv[1]); 783 top = argv[0]; 784 bottom = argv[1]; 785 } 786 else 787 debug("ansi import: command r with %d params", argc); 788 break; 789 case 'h': /* SM (0x68) - FIXME */ 790 debug("ansi import: set mode %i", argc ? (int)argv[0] : -1); 791 break; 792 case 'l': /* RM (0x6c) - FIXME */ 793 debug("ansi import: reset mode %i", argc ? (int)argv[0] : -1); 794 break; 795 case 'm': /* SGR (0x6d) - Select Graphic Rendition */ 796 if (argc) 797 ansi_parse_grcm(sc, argc, argv); 798 else 799 ansi_parse_grcm(sc, 1, &dummy); 800 break; 801 case 'n': 802 debug("ansi command n, argc %d, argv[0] %d\n", argc, argv[0]); 803 if (!argc) 743 case 1: 744 send_ansi_sequence(screen_list, "\x1b[?\x1;\x1c"); 804 745 break; 805 806 switch (argv[0]) 807 { 746 case 2: 747 send_ansi_sequence(screen_list, "\x1b[?\x1;\x2c"); 748 break; 749 case 3: 750 send_ansi_sequence(screen_list, "\x1b[?\x1;\x3c"); 751 break; 752 case 4: 753 send_ansi_sequence(screen_list, "\x1b[?\x1;\x4c"); 754 break; 808 755 case 5: 809 /* Term ok */ 810 send_ansi_sequence(screen_list, "\x1b[0n"); 756 send_ansi_sequence(screen_list, "\x1b[?\x1;\x5c"); 811 757 break; 812 758 case 6: 813 /* Cursor Position */ 814 sprintf(b, "\x1b[%d;%dR", y + 1, x + 1); 815 send_ansi_sequence(screen_list, b); 759 send_ansi_sequence(screen_list, "\x1b[?\x1;\x6c"); 816 760 break; 817 } 818 761 case 7: 762 send_ansi_sequence(screen_list, "\x1b[?\x1;\x7c"); 763 break; 764 default: 765 debug("Unsupported DA option '%d'\n", argv[0]); 766 break; 767 } 768 } 769 break; 770 case 'd': /* VPA (0x64) - Line Position Absolute */ 771 y = (argc && argv[0] > 0) ? argv[0] - 1 : 0; 772 break; 773 case 'f': /* HVP (0x66) - Character And Line Position */ 774 x = (argc > 1 && argv[1] > 0) ? argv[1] - 1 : 0; 775 y = (argc > 0 && argv[0] > 0) ? argv[0] - 1 : 0; 776 break; 777 case 'g': /* TBC -- Tabulation Clear */ 778 break; 779 case 'r': /* FIXME */ 780 if (argc == 2) /* DCSTBM - Set top and bottom margin */ 781 { 782 debug("DCSTBM %d %d", argv[0], argv[1]); 783 top = argv[0]; 784 bottom = argv[1]; 785 } 786 else 787 debug("ansi import: command r with %d params", argc); 788 break; 789 case 'h': /* SM (0x68) - FIXME */ 790 debug("ansi import: set mode %i", argc ? (int)argv[0] : -1); 791 break; 792 case 'l': /* RM (0x6c) - FIXME */ 793 debug("ansi import: reset mode %i", argc ? (int)argv[0] : -1); 794 break; 795 case 'm': /* SGR (0x6d) - Select Graphic Rendition */ 796 if (argc) 797 ansi_parse_grcm(sc, argc, argv); 798 else 799 ansi_parse_grcm(sc, 1, &dummy); 800 break; 801 case 'n': 802 debug("ansi command n, argc %d, argv[0] %d\n", argc, argv[0]); 803 if (!argc) 819 804 break; 820 case 's': /* Private (save cursor position) */ 821 save_x = x; 822 save_y = y; 805 806 switch (argv[0]) 807 { 808 case 5: 809 /* Term ok */ 810 send_ansi_sequence(screen_list, "\x1b[0n"); 823 811 break; 824 case 'u': /* Private (reload cursor position) */ 825 x = save_x; 826 y = save_y; 812 case 6: 813 /* Cursor Position */ 814 sprintf(b, "\x1b[%d;%dR", y + 1, x + 1); 815 send_ansi_sequence(screen_list, b); 827 816 break; 828 default: 829 debug("ansi import: unknown command \"^[%.*s\"", 830 final - param + 1, buffer + i + param); 831 break; 832 } 833 } 834 817 } 818 819 break; 820 case 's': /* Private (save cursor position) */ 821 save_x = x; 822 save_y = y; 823 break; 824 case 'u': /* Private (reload cursor position) */ 825 x = save_x; 826 y = save_y; 827 break; 828 default: 829 debug("ansi import: unknown command \"^[%.*s\"", 830 final - param + 1, buffer + i + param); 831 break; 832 } 833 } 834 835 835 /* Parse OSC stuff. */ 836 836 else if (buffer[i] == '\033' && buffer[i + 1] == ']') … … 839 839 unsigned int command = 0; 840 840 unsigned int mode = 2, semicolon, final; 841 841 842 842 for (semicolon = mode; i + semicolon < size; semicolon++) 843 843 { … … 846 846 command = 10 * command + (buffer[i + semicolon] - '0'); 847 847 } 848 848 849 849 if (i + semicolon >= size || buffer[i + semicolon] != ';') 850 850 break; /* Invalid Mode */ 851 851 852 852 for (final = semicolon + 1; i + final < size; final++) 853 853 if (buffer[i + final] < 0x20) 854 854 break; 855 855 856 856 if (i + final >= size || buffer[i + final] != '\a') 857 857 break; /* Not enough data or no bell found */ 858 858 /* FIXME: XTerm also reacts to <ESC><backslash> and <ST> */ 859 859 /* FIXME: differenciate between not enough data (try again) and 860 invalid data (print shit) */861 860 invalid data (print shit) */ 861 862 862 skip += final; 863 863 864 864 string = malloc(final - (semicolon + 1) + 1); 865 865 memcpy(string, buffer + i + (semicolon + 1), … … 877 877 free(string); 878 878 } 879 879 880 880 /* Get the character we’re going to paste */ 881 881 else 882 882 { 883 883 size_t bytes; 884 884 885 885 if (i + 6 < size) 886 886 { … … 895 895 ch = caca_utf8_to_utf32(tmp, &bytes); 896 896 } 897 897 898 898 if (!bytes) 899 899 { … … 902 902 bytes = 1; 903 903 } 904 904 905 905 /* very incomplete ISO-2022 implementation tailored to DEC ACS */ 906 906 if (sc->conv_state.cs == '@') … … 908 908 if (((ch > ' ') && (ch <= '~')) 909 909 && 910 (sc-> 911 conv_state.gn[sc->conv_state.ss ? sc-> 912 conv_state.gn[sc->conv_state.ss] : sc-> 913 conv_state.glr[0]] == '0')) 910 (sc->conv_state. 911 gn[sc->conv_state.ss ? sc->conv_state. 912 gn[sc->conv_state.ss] : sc->conv_state.glr[0]] == '0')) 914 913 { 915 914 ch = dec_acs(ch); … … 922 921 } 923 922 sc->conv_state.ss = 0; /* no single-shift (GL) */ 924 923 925 924 wch = caca_utf32_is_fullwidth(ch) ? 2 : 1; 926 925 927 926 skip += bytes - 1; 928 927 } 929 928 930 929 /* Wrap long lines or grow horizontally */ 931 930 while ((unsigned int)x + wch > width) … … 934 933 y++; 935 934 } 936 935 937 936 /* Scroll or grow vertically */ 938 937 if ((unsigned int)y >= bottom) 939 938 { 940 939 int lines = (y - bottom) + 1; 941 940 942 941 savedattr = caca_get_attr(sc->cv, -1, -1); 943 942 944 943 for (j = top - 1; j + lines < bottom; j++) 945 944 { … … 957 956 caca_set_attr(sc->cv, savedattr); 958 957 } 959 958 960 959 /* Now paste our character, if any */ 961 960 if (wch) … … 965 964 } 966 965 } 967 966 968 967 caca_gotoxy(sc->cv, x, y); 969 968 970 969 if (i) 971 970 sc->changed = 1; … … 974 973 975 974 /* Coding Method Delimiter (CMD), ECMA-48 (1991), ISO/IEC 6429:1992 (ISO IR 976 189) */975 189) */ 977 976 978 977 static void reset_conv_state(struct screen *sc) … … 986 985 sc->conv_state.gn[1] = '0'; /* DEC ACS G1 charset */ 987 986 sc->conv_state.gn[2] = LITERAL2CHAR('.', 'A'); /* ISO 8859-1 G2 988 charset */987 charset */ 989 988 sc->conv_state.gn[3] = LITERAL2CHAR('.', 'A'); /* ISO 8859-1 G3 990 charset */989 charset */ 991 990 sc->conv_state.ss = 0; /* no single-shift (GL) */ 992 991 sc->conv_state.ctrl8bit = 1; … … 1002 1001 CACA_BLUE, CACA_MAGENTA, CACA_CYAN, CACA_LIGHTGRAY 1003 1002 }; 1004 1003 1005 1004 unsigned int j; 1006 1005 uint8_t efg, ebg; /* Effective (libcaca) fg/bg */ 1007 1006 1008 1007 for (j = 0; j < argc; j++) 1009 1008 { … … 1019 1018 else 1020 1019 switch (argv[j]) 1021 {1020 { 1022 1021 case 0: /* default rendition */ 1023 1022 sc->fg = sc->dfg; 1024 1023 sc->bg = sc->dbg; 1025 1024 sc->bold = sc->blink = sc->italics = sc->negative 1026 = sc->concealed = sc->underline = sc->faint = sc->strike1027 = sc->proportional = 0;1025 = sc->concealed = sc->underline = sc->faint = sc->strike 1026 = sc->proportional = 0; 1028 1027 break; 1029 1028 case 1: /* bold or increased intensity */ … … 1031 1030 break; 1032 1031 case 2: /* faint, decreased intensity or second colour 1033 */1032 */ 1034 1033 sc->faint = 1; 1035 1034 break; … … 1051 1050 break; 1052 1051 case 9: /* crossed-out (characters still legible but 1053 marked as to be deleted */1052 marked as to be deleted */ 1054 1053 sc->strike = 1; 1055 1054 break; … … 1058 1057 break; 1059 1058 case 22: /* normal colour or normal intensity (neither 1060 bold nor faint) */1059 bold nor faint) */ 1061 1060 sc->bold = sc->faint = 0; 1062 1061 break; … … 1071 1070 break; 1072 1071 case 26: /* (reserved for proportional spacing as 1073 specified in CCITT Recommendation T.61) */1072 specified in CCITT Recommendation T.61) */ 1074 1073 sc->proportional = 1; 1075 1074 break; … … 1084 1083 break; 1085 1084 case 38: /* (reserved for future standardization, 1086 intended for setting character foreground1087 colour as specified in ISO 8613-6 [CCITT1088 Recommendation T.416]) */1085 intended for setting character foreground 1086 colour as specified in ISO 8613-6 [CCITT 1087 Recommendation T.416]) */ 1089 1088 break; 1090 1089 case 39: /* default display colour 1091 (implementation-defined) */1090 (implementation-defined) */ 1092 1091 sc->fg = sc->dfg; 1093 1092 break; 1094 1093 case 48: /* (reserved for future standardization, 1095 intended for setting character background1096 colour as specified in ISO 8613-6 [CCITT1097 Recommendation T.416]) */1094 intended for setting character background 1095 colour as specified in ISO 8613-6 [CCITT 1096 Recommendation T.416]) */ 1098 1097 break; 1099 1098 case 49: /* default background colour 1100 (implementation-defined) */1099 (implementation-defined) */ 1101 1100 sc->bg = sc->dbg; 1102 1101 break; 1103 1102 case 50: /* (reserved for cancelling the effect of the 1104 rendering aspect established by parameter1105 value 26) */1103 rendering aspect established by parameter 1104 value 26) */ 1106 1105 sc->proportional = 0; 1107 1106 break; … … 1109 1108 debug("ansi import: unknown sgr %i", argv[j]); 1110 1109 break; 1111 }1112 } 1113 1110 } 1111 } 1112 1114 1113 if (sc->concealed) 1115 1114 { … … 1120 1119 efg = sc->negative ? sc->bg : sc->fg; 1121 1120 ebg = sc->negative ? sc->fg : sc->bg; 1122 1121 1123 1122 if (sc->bold) 1124 1123 { … … 1129 1128 } 1130 1129 } 1131 1130 1132 1131 caca_set_color_ansi(sc->cv, efg, ebg); 1133 1132 }
Note: See TracChangeset
for help on using the changeset viewer.
