Changeset 4077 for neercs/trunk
- Timestamp:
- Nov 30, 2009, 12:14:21 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
neercs/trunk/src/ansi.c
r4076 r4077 25 25 switch (uc) 26 26 { 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 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 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 565 566 567 568 569 570 571 572 573 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 582 583 584 585 586 587 588 589 590 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 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 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 699 700 701 702 703 704 705 706 707 708 709 710 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.