Changeset 3991


Ignore:
Timestamp:
11/21/09 16:34:04 (4 years ago)
Author:
jylam
Message:
  • Indentation / comments
File:
1 edited

Legend:

Unmodified
Added
Removed
  • neercs/trunk/src/term.c

    r3990 r3991  
    126126 
    127127static int handle_single_char(unsigned char c, int *x, int *y, 
    128                                struct screen_list *screen_list, 
    129                                struct screen *sc); 
     128                              struct screen_list *screen_list, 
     129                              struct screen *sc); 
    130130 
    131131static int handle_single_char(unsigned char c, int *x, int *y, 
    132                                struct screen_list *screen_list, 
    133                                struct screen *sc) 
     132                              struct screen_list *screen_list, 
     133                              struct screen *sc) 
    134134{ 
    135135    if (c == '\r') 
     
    160160            *x = *x - 1; 
    161161    } 
    162     else if (c == '\x0b') /* Vertical tab */ 
    163     { 
     162    else if (c == '\x0b') 
     163    { 
     164        /* Vertical tab */ 
     165        /* Not sure about the real meaning of it, just y++ for now */ 
    164166        if (*y < caca_get_canvas_height(sc->cv)) 
    165             *y = *y + 1;  
    166     }     
     167            *y = *y + 1; 
     168    } 
    167169    else if (c == '\x0e') 
    168170    { 
     
    178180        sc->conv_state.glr[0] = 0; 
    179181    } 
    180     else  
    181     { 
    182         return 1;     
    183     } 
    184         return 0; 
     182    else 
     183    { 
     184        return 1; 
     185    } 
     186    return 0; 
    185187 
    186188} 
     
    237239        } 
    238240 
    239         if(!handle_single_char(buffer[i], &x, &y, screen_list, sc))  
    240         {} 
     241        if (!handle_single_char(buffer[i], &x, &y, screen_list, sc)) 
     242        { 
     243        } 
    241244 
    242245 
    243246        /* If there are not enough characters to parse the escape sequence, 
    244247           wait until the next try. We require 3. */ 
    245          
    246     else if (buffer[i] == '\033' && i + 2 >= size) 
    247         break; 
     248 
     249        else if (buffer[i] == '\033' && i + 2 >= size) 
     250            break; 
    248251 
    249252        /* Single Shift Select of G2 Character Set (SS2: 0x8e): affects next 
    250253           character only */ 
    251     else if (buffer[i] == '\033' && buffer[i + 1] == 'N') 
    252     { 
    253         sc->conv_state.ss = 2; 
    254         skip += 1; 
    255     } 
     254        else if (buffer[i] == '\033' && buffer[i + 1] == 'N') 
     255        { 
     256            sc->conv_state.ss = 2; 
     257            skip += 1; 
     258        } 
    256259        /* Reverse Index (RI) go up one line, reverse scroll if necessary */ 
    257     else if (buffer[i] == '\033' && buffer[i + 1] == 'M') 
    258     { 
    259         /* FIXME : not sure about the meaning of 'go up one line' and 'if 
    260            necessary' words. Implemented as a scroller only. */ 
    261         for (j = bottom - 1; j > top; j--) 
    262         { 
    263             for (k = 0; k < width; k++) 
    264             { 
    265                 caca_put_char(sc->cv, k, j, caca_get_char(sc->cv, k, j - 1)); 
    266                 caca_put_attr(sc->cv, k, j, caca_get_attr(sc->cv, k, j - 1)); 
    267             } 
    268         } 
    269         caca_draw_line(sc->cv, 0, top - 1, width - 1, top - 1, ' '); 
    270         skip += 1; 
    271     } 
     260        else if (buffer[i] == '\033' && buffer[i + 1] == 'M') 
     261        { 
     262            /* FIXME : not sure about the meaning of 'go up one line' and 'if 
     263               necessary' words. Implemented as a scroller only. */ 
     264            for (j = bottom - 1; j > top; j--) 
     265            { 
     266                for (k = 0; k < width; k++) 
     267                { 
     268                    caca_put_char(sc->cv, k, j, 
     269                                  caca_get_char(sc->cv, k, j - 1)); 
     270                    caca_put_attr(sc->cv, k, j, 
     271                                  caca_get_attr(sc->cv, k, j - 1)); 
     272                } 
     273            } 
     274            caca_draw_line(sc->cv, 0, top - 1, width - 1, top - 1, ' '); 
     275            skip += 1; 
     276        } 
    272277 
    273278        /* Single Shift Select of G3 Character Set (SS2: 0x8f): affects next 
    274279           character only */ 
    275     else if (buffer[i] == '\033' && buffer[i + 1] == 'O') 
    276     { 
    277         sc->conv_state.ss = 3; 
    278         skip += 1; 
    279     } 
     280        else if (buffer[i] == '\033' && buffer[i + 1] == 'O') 
     281        { 
     282            sc->conv_state.ss = 3; 
     283            skip += 1; 
     284        } 
    280285 
    281286        /* LOCKING-SHIFT TWO (LS2), ISO 2022, ECMA-48 (1986), ISO 6429 : 1988 */ 
    282     else if (buffer[i] == '\033' && buffer[i + 1] == 'n') 
    283     { 
    284         sc->conv_state.glr[0] = 2; 
    285         skip += 1; 
    286     } 
     287        else if (buffer[i] == '\033' && buffer[i + 1] == 'n') 
     288        { 
     289            sc->conv_state.glr[0] = 2; 
     290            skip += 1; 
     291        } 
    287292 
    288293        /* LOCKING-SHIFT THREE (LS3) ISO 2022, ECMA-48 (1986), ISO 6429 : 1988  
    289294         */ 
    290     else if (buffer[i] == '\033' && buffer[i + 1] == 'o') 
    291     { 
    292         sc->conv_state.glr[0] = 3; 
    293         skip += 1; 
    294     } 
     295        else if (buffer[i] == '\033' && buffer[i + 1] == 'o') 
     296        { 
     297            sc->conv_state.glr[0] = 3; 
     298            skip += 1; 
     299        } 
    295300 
    296301        /* RESET TO INITIAL STATE (RIS), ECMA-48 (1986), ISO 6429 : 1988 */ 
    297     else if (buffer[i] == '\033' && buffer[i + 1] == 'c') 
    298     { 
    299         sc->dfg = CACA_DEFAULT; 
    300         sc->dbg = CACA_DEFAULT; 
    301  
    302         caca_set_color_ansi(sc->cv, sc->dfg, sc->dbg); 
    303         sc->clearattr = caca_get_attr(sc->cv, -1, -1); 
    304         ansi_parse_grcm(sc, 1, &dummy); 
    305  
    306         reset_conv_state(sc); 
    307         skip += 1; 
    308     } 
     302        else if (buffer[i] == '\033' && buffer[i + 1] == 'c') 
     303        { 
     304            sc->dfg = CACA_DEFAULT; 
     305            sc->dbg = CACA_DEFAULT; 
     306 
     307            caca_set_color_ansi(sc->cv, sc->dfg, sc->dbg); 
     308            sc->clearattr = caca_get_attr(sc->cv, -1, -1); 
     309            ansi_parse_grcm(sc, 1, &dummy); 
     310 
     311            reset_conv_state(sc); 
     312            skip += 1; 
     313        } 
    309314 
    310315        /* Coding Method Delimiter (CMD), ECMA-48 (1991), ISO/IEC 6429:1992 
    311316           (ISO IR 189) */ 
    312     else if (buffer[i] == '\033' && buffer[i + 1] == 'd') 
    313     { 
    314         reset_conv_state(sc); 
    315         skip += 1; 
    316     } 
     317        else if (buffer[i] == '\033' && buffer[i + 1] == 'd') 
     318        { 
     319            reset_conv_state(sc); 
     320            skip += 1; 
     321        } 
    317322 
    318323        /* GZDM4, G0-Designators, multi, 94^n chars [grandfathered short form 
    319324           from ISO 2022:1986] */ 
    320     else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
    321              && (buffer[i + 2] >= '@') && (buffer[i + 2] <= 'C')) 
    322     { 
    323         sc->conv_state.gn[0] = LITERAL2CHAR('$', buffer[i + 2]); 
    324         skip += 2; 
    325     } 
     325        else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
     326                 && (buffer[i + 2] >= '@') && (buffer[i + 2] <= 'C')) 
     327        { 
     328            sc->conv_state.gn[0] = LITERAL2CHAR('$', buffer[i + 2]); 
     329            skip += 2; 
     330        } 
    326331 
    327332        /* GnDMx Gn-Designators, 9x^n chars; need one more char to distinguish  
    328333           these */ 
    329     else if (buffer[i] == '\033' && buffer[i + 1] == '$' && (i + 3 >= size)) 
    330         break; 
     334        else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
     335                 && (i + 3 >= size)) 
     336            break; 
    331337 
    332338        /* GZD4 G0-Designator, 94 chars */ 
    333     else if (buffer[i] == '\033' && buffer[i + 1] == '(') 
    334     { 
    335         sc->conv_state.gn[0] = buffer[i + 2]; 
    336         skip += 2; 
    337     } 
     339        else if (buffer[i] == '\033' && buffer[i + 1] == '(') 
     340        { 
     341            sc->conv_state.gn[0] = buffer[i + 2]; 
     342            skip += 2; 
     343        } 
    338344 
    339345        /* G1D4 G1-Designator, 94 chars */ 
    340     else if (buffer[i] == '\033' && buffer[i + 1] == ')') 
    341     { 
    342         sc->conv_state.gn[1] = buffer[i + 2]; 
    343         skip += 2; 
    344     } 
     346        else if (buffer[i] == '\033' && buffer[i + 1] == ')') 
     347        { 
     348            sc->conv_state.gn[1] = buffer[i + 2]; 
     349            skip += 2; 
     350        } 
    345351 
    346352        /* G2D4 G2-Designator, 94 chars */ 
    347     else if (buffer[i] == '\033' && buffer[i + 1] == '*') 
    348     { 
    349         sc->conv_state.gn[2] = buffer[i + 2]; 
    350         skip += 2; 
    351     } 
     353        else if (buffer[i] == '\033' && buffer[i + 1] == '*') 
     354        { 
     355            sc->conv_state.gn[2] = buffer[i + 2]; 
     356            skip += 2; 
     357        } 
    352358 
    353359        /* G3D4 G3-Designator, 94 chars */ 
    354     else if (buffer[i] == '\033' && buffer[i + 1] == '+') 
    355     { 
    356         sc->conv_state.gn[3] = buffer[i + 2]; 
    357         skip += 2; 
    358     } 
     360        else if (buffer[i] == '\033' && buffer[i + 1] == '+') 
     361        { 
     362            sc->conv_state.gn[3] = buffer[i + 2]; 
     363            skip += 2; 
     364        } 
    359365 
    360366        /* G2D6 G2-Designator, 96 chars */ 
    361     else if (buffer[i] == '\033' && buffer[i + 1] == '.') 
    362     { 
    363         sc->conv_state.gn[2] = LITERAL2CHAR('.', buffer[i + 2]); 
    364         skip += 2; 
    365     } 
     367        else if (buffer[i] == '\033' && buffer[i + 1] == '.') 
     368        { 
     369            sc->conv_state.gn[2] = LITERAL2CHAR('.', buffer[i + 2]); 
     370            skip += 2; 
     371        } 
    366372 
    367373        /* G3D6 G3-Designator, 96 chars */ 
    368     else if (buffer[i] == '\033' && buffer[i + 1] == '/') 
    369     { 
    370         sc->conv_state.gn[3] = LITERAL2CHAR('.', buffer[i + 2]); 
    371         skip += 2; 
    372     } 
     374        else if (buffer[i] == '\033' && buffer[i + 1] == '/') 
     375        { 
     376            sc->conv_state.gn[3] = LITERAL2CHAR('.', buffer[i + 2]); 
     377            skip += 2; 
     378        } 
    373379 
    374380        /* GZDM4 G0-Designator, 94^n chars */ 
    375     else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
    376              && buffer[i + 2] == '(') 
    377     { 
    378         sc->conv_state.gn[0] = LITERAL2CHAR('$', buffer[i + 3]); 
    379         skip += 3; 
    380     } 
     381        else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
     382                 && buffer[i + 2] == '(') 
     383        { 
     384            sc->conv_state.gn[0] = LITERAL2CHAR('$', buffer[i + 3]); 
     385            skip += 3; 
     386        } 
    381387 
    382388        /* G1DM4 G1-Designator, 94^n chars */ 
    383     else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
    384              && buffer[i + 2] == ')') 
    385     { 
    386         sc->conv_state.gn[1] = LITERAL2CHAR('$', buffer[i + 3]); 
    387         skip += 3; 
    388     } 
     389        else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
     390                 && buffer[i + 2] == ')') 
     391        { 
     392            sc->conv_state.gn[1] = LITERAL2CHAR('$', buffer[i + 3]); 
     393            skip += 3; 
     394        } 
    389395 
    390396        /* G2DM4 G2-Designator, 94^n chars */ 
    391     else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
    392              && buffer[i + 2] == '*') 
    393     { 
    394         sc->conv_state.gn[2] = LITERAL2CHAR('$', buffer[i + 3]); 
    395         skip += 3; 
    396     } 
     397        else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
     398                 && buffer[i + 2] == '*') 
     399        { 
     400            sc->conv_state.gn[2] = LITERAL2CHAR('$', buffer[i + 3]); 
     401            skip += 3; 
     402        } 
    397403 
    398404        /* G3DM4 G3-Designator, 94^n chars */ 
    399     else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
    400              && buffer[i + 2] == '+') 
    401     { 
    402         sc->conv_state.gn[3] = LITERAL2CHAR('$', buffer[i + 3]); 
    403         skip += 3; 
    404     } 
     405        else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
     406                 && buffer[i + 2] == '+') 
     407        { 
     408            sc->conv_state.gn[3] = LITERAL2CHAR('$', buffer[i + 3]); 
     409            skip += 3; 
     410        } 
    405411 
    406412        /* G2DM6 G2-Designator, 96^n chars */ 
    407     else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
    408              && buffer[i + 2] == '.') 
    409     { 
    410         sc->conv_state.gn[2] = LITERAL3CHAR('$', '.', buffer[i + 3]); 
    411         skip += 3; 
    412     } 
     413        else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
     414                 && buffer[i + 2] == '.') 
     415        { 
     416            sc->conv_state.gn[2] = LITERAL3CHAR('$', '.', buffer[i + 3]); 
     417            skip += 3; 
     418        } 
    413419 
    414420        /* G3DM6 G3-Designator, 96^n chars */ 
    415     else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
    416              && buffer[i + 2] == '/') 
    417     { 
    418         sc->conv_state.gn[3] = LITERAL3CHAR('$', '.', buffer[i + 3]); 
    419         skip += 3; 
    420     } 
    421     else if (buffer[i] == '\033' && buffer[i + 1] == '#') 
    422     { 
    423         debug("ansi private '#' sequence\n"); 
    424  
    425         switch (buffer[i + 2]) 
    426         { 
    427         case '8':              /* DECALN Fills the entire screen area with 
     421        else if (buffer[i] == '\033' && buffer[i + 1] == '$' 
     422                 && buffer[i + 2] == '/') 
     423        { 
     424            sc->conv_state.gn[3] = LITERAL3CHAR('$', '.', buffer[i + 3]); 
     425            skip += 3; 
     426        } 
     427        else if (buffer[i] == '\033' && buffer[i + 1] == '#') 
     428        { 
     429            debug("ansi private '#' sequence\n"); 
     430 
     431            switch (buffer[i + 2]) 
     432            { 
     433            case '8':          /* DECALN Fills the entire screen area with 
    428434                                   uppercase Es for screen focus and 
    429435                                   alignment. */ 
    430             for (j = 0; j < height; j++) 
    431             { 
    432                 for (k = 0; k < width; k++) 
    433                 { 
    434                     caca_put_char(sc->cv, k, j, 'E'); 
    435                 } 
    436             } 
    437             skip += 2; 
    438             break; 
    439  
    440         default: 
    441             debug("Unknow private sequence 'ESC#%c'\n", buffer[i + 2]); 
    442             continue; 
    443         } 
    444  
    445     } 
     436                for (j = 0; j < height; j++) 
     437                { 
     438                    for (k = 0; k < width; k++) 
     439                    { 
     440                        caca_put_char(sc->cv, k, j, 'E'); 
     441                    } 
     442                } 
     443                skip += 2; 
     444                break; 
     445 
     446            default: 
     447                debug("Unknow private sequence 'ESC#%c'\n", buffer[i + 2]); 
     448                continue; 
     449            } 
     450 
     451        } 
    446452        /* Interpret escape commands, as per Standard ECMA-48 "Control 
    447453           Functions for Coded Character Sets", 5.4. Control sequences. */ 
    448     else if (buffer[i] == '\033' && buffer[i + 1] == '[') 
    449     { 
    450         unsigned int argc = 0, argv[101]; 
    451         unsigned int param, inter, junk, final; 
    452  
    453  
    454         /* Compute offsets to parameter bytes, intermediate bytes and to the 
    455            final byte. Only the final byte is mandatory, there can be zero of 
    456            the others. 0 param=2 inter final final+1 
    457            +-----+------------------+---------------------+-----------------+ 
    458            | CSI | parameter bytes | intermediate bytes | final byte | | | 
    459            0x30 - 0x3f | 0x20 - 0x2f | 0x40 - 0x7e | | ^[[ | 0123456789:;<=>? 
    460            | SPC !"#$%&'()*+,-./ | azAZ@[\]^_`{|}~ | 
    461            +-----+------------------+---------------------+-----------------+ */ 
    462         param = 2; 
    463  
    464         /* vttest use to interleave normal characters (\014 CR or \010 BS) 
    465            into CSI sequences, either directly after ESC[ or after param. 
    466            Can't find anything related to this in any documentation nor XTerm 
    467            sources, thought. */ 
    468  
    469         for (junk = param; i + junk < size; junk++) 
    470             if (buffer[i + junk] < 0x20) 
    471             { 
    472                 handle_single_char(buffer[i + junk], &x, &y, screen_list, sc); 
    473             } 
    474             else 
    475             { 
    476                 break; 
    477             } 
    478  
    479         /* Intermediate offset */ 
    480         for (inter = junk; i + inter < size; inter++) 
    481             if (buffer[i + inter] < 0x30 || buffer[i + inter] > 0x3f) 
    482             { 
    483                 break; 
    484             } 
    485         /* Interleaved character */ 
    486         for (junk = inter; i + junk < size; junk++) 
    487             if (buffer[i + junk] < 0x20) 
    488             { 
    489                 handle_single_char(buffer[i + junk], &x, &y, screen_list, sc); 
    490             } 
    491             else 
    492             { 
    493                 break; 
    494             } 
    495  
    496         /* Final Byte offset */ 
    497         for (final = junk; i + final < size; final++) 
    498             if (buffer[i + final] < 0x20 || buffer[i + final] > 0x2f) 
    499             { 
    500                 break; 
    501             } 
    502         if (i + final >= size 
    503             || buffer[i + final] < 0x40 || buffer[i + final] > 0x7e) 
    504         { 
    505             debug("ansi Invalid Final Byte (%d %c)\n", buffer[i + final], 
    506                   buffer[i + final]); 
    507             break;              /* Invalid Final Byte */ 
    508         } 
    509  
    510         skip += final; 
    511  
    512         /* Sanity checks */ 
    513         if (param < inter && buffer[i + param] >= 0x3c) 
    514         { 
    515             /* Private sequence, only parse what we know */ 
    516             debug("ansi import: private sequence \"^[[%.*s\"", 
    517                   final - param + 1, buffer + i + param); 
    518             continue;           /* Private sequence, skip it entirely */ 
    519         } 
    520  
    521         if (final - param > 100) 
    522             continue;           /* Suspiciously long sequence, skip it */ 
    523  
    524         /* Parse parameter bytes as per ECMA-48 5.4.2: Parameter string format  
    525          */ 
    526         if (param < inter) 
    527         { 
    528             argv[0] = 0; 
    529             for (j = param; j < inter; j++) 
    530             { 
    531                 if (buffer[i + j] == ';') 
    532                     argv[++argc] = 0; 
    533                 else if (buffer[i + j] >= '0' && buffer[i + j] <= '9') 
    534                     argv[argc] = 10 * argv[argc] + (buffer[i + j] - '0'); 
    535             } 
    536             argc++; 
    537         } 
    538  
    539         /* Interpret final byte. The code representations are given in ECMA-48  
    540            5.4: Control sequences, and the code definitions are given in 
    541            ECMA-48 8.3: Definition of control functions. */ 
    542         debug("ansi import: command '%c'", buffer[i + final]); 
    543         switch (buffer[i + final]) 
    544         { 
    545         case 'A':              /* CUU (0x41) - Cursor Up */ 
    546             y -= argc ? argv[0] : 1; 
    547             if (y < 0) 
    548                 y = 0; 
    549             break; 
    550         case 'B':              /* CUD (0x42) - Cursor Down */ 
    551             y += argc ? argv[0] : 1; 
    552             break; 
    553         case 'C':              /* CUF (0x43) - Cursor Right */ 
    554             x += argc ? argv[0] : 1; 
    555             break; 
    556         case 'D':              /* CUB (0x44) - Cursor Left */ 
    557             x -= argc ? argv[0] : 1; 
    558             if (x < 0) 
    559                 x = 0; 
    560             break; 
    561         case 'G':              /* CHA (0x47) - Cursor Character Absolute */ 
    562             x = (argc && argv[0] > 0) ? argv[0] - 1 : 0; 
    563             break; 
    564         case 'H':              /* CUP (0x48) - Cursor Position */ 
    565             x = (argc > 1 && argv[1] > 0) ? argv[1] - 1 : 0; 
    566             y = (argc > 0 && argv[0] > 0) ? argv[0] - 1 : 0; 
    567             debug("ansi CUP : Cursor at %dx%d\n", x, y); 
    568             break; 
    569         case 'J':              /* ED (0x4a) - Erase In Page */ 
    570             savedattr = caca_get_attr(sc->cv, -1, -1); 
    571             caca_set_attr(sc->cv, sc->clearattr); 
    572             if (!argc || argv[0] == 0) 
    573             { 
    574                 caca_draw_line(sc->cv, x, y, width, y, ' '); 
    575                 caca_fill_box(sc->cv, 0, y + 1, width, height - 1, ' '); 
    576             } 
    577             else if (argv[0] == 1) 
    578             { 
    579                 caca_fill_box(sc->cv, 0, 0, width, y, ' '); 
    580                 caca_draw_line(sc->cv, 0, y, x, y, ' '); 
    581             } 
    582             else if (argv[0] == 2) 
    583             { 
    584                 // x = y = 0; 
    585                 caca_fill_box(sc->cv, 0, 0, width, height, ' '); 
    586             } 
    587             caca_set_attr(sc->cv, savedattr); 
    588             break; 
    589         case 'K':              /* EL (0x4b) - Erase In Line */ 
    590             debug("ansi EL : cursor at %dx%d\n", x, y); 
    591             if (!argc || argv[0] == 0) 
    592             { 
    593                 caca_draw_line(sc->cv, x, y, width, y, ' '); 
    594             } 
    595             else if (argv[0] == 1) 
    596             { 
    597                 caca_draw_line(sc->cv, 0, y, x, y, ' '); 
    598             } 
    599             else if (argv[0] == 2) 
    600             { 
    601                 caca_draw_line(sc->cv, 0, y, width, y, ' '); 
    602             } 
    603             break; 
    604         case 'L':              /* IL - Insert line */ 
    605             { 
    606                 unsigned int nb_lines = argc ? argv[0] : 1; 
    607                 for (j = bottom - 1; j >= (unsigned int)y + nb_lines; j--) 
    608                 { 
    609                     for (k = 0; k < width; k++) 
    610                     { 
    611                         caca_put_char(sc->cv, k, j, 
    612                                       caca_get_char(sc->cv, k, j - nb_lines)); 
    613                         caca_put_attr(sc->cv, k, j, 
    614                                       caca_get_attr(sc->cv, k, j - nb_lines)); 
    615                     } 
    616                     caca_draw_line(sc->cv, 0, j - nb_lines, width, 
    617                                    j - nb_lines, ' '); 
    618                 } 
    619             } 
    620             break; 
    621         case 'P':              /* DCH (0x50) - Delete Character */ 
    622             if (!argc || argv[0] == 0) 
    623                 argv[0] = 1;    /* echo -ne 'foobar\r\e[0P\n' */ 
    624             /* Jylam : Start from x, not 0 */ 
    625             for (j = x; (unsigned int)(j + argv[0]) < width; j++) 
    626             { 
    627                 caca_put_char(sc->cv, j, y, 
    628                               caca_get_char(sc->cv, j + argv[0], y)); 
    629                 caca_put_attr(sc->cv, j, y, 
    630                               caca_get_attr(sc->cv, j + argv[0], y)); 
    631             } 
    632             break;              /* Jylam: this one was missing I guess */ 
    633 #if 0 
    634             savedattr = caca_get_attr(sc->cv, -1, -1); 
    635             caca_set_attr(sc->cv, sc->clearattr); 
    636             for (; (unsigned int)j < width; j++) 
    637                 caca_put_char(sc->cv, j, y, ' '); 
    638             caca_set_attr(sc->cv, savedattr); 
    639 #endif 
    640         case 'X':              /* ECH (0x58) - Erase Character */ 
    641             if (argc && argv[0]) 
    642             { 
     454        else if (buffer[i] == '\033' && buffer[i + 1] == '[') 
     455        { 
     456            unsigned int argc = 0, argv[101]; 
     457            unsigned int param, inter, junk, final; 
     458 
     459 
     460            /* Compute offsets to parameter bytes, intermediate bytes and to 
     461               the final byte. Only the final byte is mandatory, there can be 
     462               zero of the others. 0 param=2 inter final final+1 
     463               +-----+------------------+---------------------+-----------------+ 
     464               | CSI | parameter bytes | intermediate bytes | final byte | | | 
     465               0x30 - 0x3f | 0x20 - 0x2f | 0x40 - 0x7e | | ^[[ | 0123456789:;<=>? 
     466               | SPC !"#$%&'()*+,-./ | azAZ@[\]^_`{|}~ | 
     467               +-----+------------------+---------------------+-----------------+ */ 
     468            param = 2; 
     469 
     470            /* vttest use to interleave normal characters (\014 CR or \010 BS) 
     471               into CSI sequences, either directly after ESC[ or after param. 
     472               Can't find anything related to this in any documentation nor 
     473               XTerm sources, thought. */ 
     474 
     475            for (junk = param; i + junk < size; junk++) 
     476                if (buffer[i + junk] < 0x20) 
     477                { 
     478                    handle_single_char(buffer[i + junk], &x, &y, screen_list, 
     479                                       sc); 
     480                } 
     481                else 
     482                { 
     483                    break; 
     484                } 
     485 
     486            /* Intermediate offset */ 
     487            for (inter = junk; i + inter < size; inter++) 
     488                if (buffer[i + inter] < 0x30 || buffer[i + inter] > 0x3f) 
     489                { 
     490                    break; 
     491                } 
     492            /* Interleaved character */ 
     493            for (junk = inter; i + junk < size; junk++) 
     494                if (buffer[i + junk] < 0x20) 
     495                { 
     496                    handle_single_char(buffer[i + junk], &x, &y, screen_list, 
     497                                       sc); 
     498                } 
     499                else 
     500                { 
     501                    break; 
     502                } 
     503 
     504            /* Final Byte offset */ 
     505            for (final = junk; i + final < size; final++) 
     506                if (buffer[i + final] < 0x20 || buffer[i + final] > 0x2f) 
     507                { 
     508                    break; 
     509                } 
     510            if (i + final >= size 
     511                || buffer[i + final] < 0x40 || buffer[i + final] > 0x7e) 
     512            { 
     513                debug("ansi Invalid Final Byte (%d %c)\n", buffer[i + final], 
     514                      buffer[i + final]); 
     515                break;          /* Invalid Final Byte */ 
     516            } 
     517 
     518            skip += final; 
     519 
     520            /* Sanity checks */ 
     521            if (param < inter && buffer[i + param] >= 0x3c) 
     522            { 
     523                /* Private sequence, only parse what we know */ 
     524                debug("ansi import: private sequence \"^[[%.*s\"", 
     525                      final - param + 1, buffer + i + param); 
     526                continue;       /* Private sequence, skip it entirely */ 
     527            } 
     528 
     529            if (final - param > 100) 
     530                continue;       /* Suspiciously long sequence, skip it */ 
     531 
     532            /* Parse parameter bytes as per ECMA-48 5.4.2: Parameter string 
     533               format */ 
     534            if (param < inter) 
     535            { 
     536                argv[0] = 0; 
     537                for (j = param; j < inter; j++) 
     538                { 
     539                    if (buffer[i + j] == ';') 
     540                        argv[++argc] = 0; 
     541                    else if (buffer[i + j] >= '0' && buffer[i + j] <= '9') 
     542                        argv[argc] = 10 * argv[argc] + (buffer[i + j] - '0'); 
     543                } 
     544                argc++; 
     545            } 
     546 
     547            /* Interpret final byte. The code representations are given in 
     548               ECMA-48 5.4: Control sequences, and the code definitions are 
     549               given in ECMA-48 8.3: Definition of control functions. */ 
     550            debug("ansi import: command '%c'", buffer[i + final]); 
     551            switch (buffer[i + final]) 
     552            { 
     553            case 'A':          /* CUU (0x41) - Cursor Up */ 
     554                y -= argc ? argv[0] : 1; 
     555                if (y < 0) 
     556                    y = 0; 
     557                break; 
     558            case 'B':          /* CUD (0x42) - Cursor Down */ 
     559                y += argc ? argv[0] : 1; 
     560                break; 
     561            case 'C':          /* CUF (0x43) - Cursor Right */ 
     562                x += argc ? argv[0] : 1; 
     563                break; 
     564            case 'D':          /* CUB (0x44) - Cursor Left */ 
     565                x -= argc ? argv[0] : 1; 
     566                if (x < 0) 
     567                    x = 0; 
     568                break; 
     569            case 'G':          /* CHA (0x47) - Cursor Character Absolute */ 
     570                x = (argc && argv[0] > 0) ? argv[0] - 1 : 0; 
     571                break; 
     572            case 'H':          /* CUP (0x48) - Cursor Position */ 
     573                x = (argc > 1 && argv[1] > 0) ? argv[1] - 1 : 0; 
     574                y = (argc > 0 && argv[0] > 0) ? argv[0] - 1 : 0; 
     575                debug("ansi CUP : Cursor at %dx%d\n", x, y); 
     576                break; 
     577            case 'J':          /* ED (0x4a) - Erase In Page */ 
    643578                savedattr = caca_get_attr(sc->cv, -1, -1); 
    644579                caca_set_attr(sc->cv, sc->clearattr); 
    645                 caca_draw_line(sc->cv, x, y, x + argv[0] - 1, y, ' '); 
     580                if (!argc || argv[0] == 0) 
     581                { 
     582                    caca_draw_line(sc->cv, x, y, width, y, ' '); 
     583                    caca_fill_box(sc->cv, 0, y + 1, width, height - 1, ' '); 
     584                } 
     585                else if (argv[0] == 1) 
     586                { 
     587                    caca_fill_box(sc->cv, 0, 0, width, y, ' '); 
     588                    caca_draw_line(sc->cv, 0, y, x, y, ' '); 
     589                } 
     590                else if (argv[0] == 2) 
     591                { 
     592                    // x = y = 0; 
     593                    caca_fill_box(sc->cv, 0, 0, width, height, ' '); 
     594                } 
    646595                caca_set_attr(sc->cv, savedattr); 
    647             } 
    648         case 'd':              /* VPA (0x64) - Line Position Absolute */ 
    649             y = (argc && argv[0] > 0) ? argv[0] - 1 : 0; 
    650             break; 
    651         case 'f':              /* HVP (0x66) - Character And Line Position */ 
    652             x = (argc > 1 && argv[1] > 0) ? argv[1] - 1 : 0; 
    653             y = (argc > 0 && argv[0] > 0) ? argv[0] - 1 : 0; 
    654             break; 
    655         case 'r':              /* FIXME */ 
    656             if (argc == 2)      /* DCSTBM - Set top and bottom margin */ 
    657             { 
    658                 debug("DCSTBM %d %d", argv[0], argv[1]); 
    659                 top = argv[0]; 
    660                 bottom = argv[1]; 
     596                break; 
     597            case 'K':          /* EL (0x4b) - Erase In Line */ 
     598                debug("ansi EL : cursor at %dx%d\n", x, y); 
     599                if (!argc || argv[0] == 0) 
     600                { 
     601                    caca_draw_line(sc->cv, x, y, width, y, ' '); 
     602                } 
     603                else if (argv[0] == 1) 
     604                { 
     605                    caca_draw_line(sc->cv, 0, y, x, y, ' '); 
     606                } 
     607                else if (argv[0] == 2) 
     608                { 
     609                    caca_draw_line(sc->cv, 0, y, width, y, ' '); 
     610                } 
     611                break; 
     612            case 'L':          /* IL - Insert line */ 
     613                { 
     614                    unsigned int nb_lines = argc ? argv[0] : 1; 
     615                    for (j = bottom - 1; j >= (unsigned int)y + nb_lines; j--) 
     616                    { 
     617                        for (k = 0; k < width; k++) 
     618                        { 
     619                            caca_put_char(sc->cv, k, j, 
     620                                          caca_get_char(sc->cv, k, 
     621                                                        j - nb_lines)); 
     622                            caca_put_attr(sc->cv, k, j, 
     623                                          caca_get_attr(sc->cv, k, 
     624                                                        j - nb_lines)); 
     625                        } 
     626                        caca_draw_line(sc->cv, 0, j - nb_lines, width, 
     627                                       j - nb_lines, ' '); 
     628                    } 
     629                } 
     630                break; 
     631            case 'P':          /* DCH (0x50) - Delete Character */ 
     632                if (!argc || argv[0] == 0) 
     633                    argv[0] = 1;        /* echo -ne 'foobar\r\e[0P\n' */ 
     634                /* Jylam : Start from x, not 0 */ 
     635                for (j = x; (unsigned int)(j + argv[0]) < width; j++) 
     636                { 
     637                    caca_put_char(sc->cv, j, y, 
     638                                  caca_get_char(sc->cv, j + argv[0], y)); 
     639                    caca_put_attr(sc->cv, j, y, 
     640                                  caca_get_attr(sc->cv, j + argv[0], y)); 
     641                } 
     642                break;          /* Jylam: this one was missing I guess */ 
     643#if 0 
     644                savedattr = caca_get_attr(sc->cv, -1, -1); 
     645                caca_set_attr(sc->cv, sc->clearattr); 
     646                for (; (unsigned int)j < width; j++) 
     647                    caca_put_char(sc->cv, j, y, ' '); 
     648                caca_set_attr(sc->cv, savedattr); 
     649#endif 
     650            case 'X':          /* ECH (0x58) - Erase Character */ 
     651                if (argc && argv[0]) 
     652                { 
     653                    savedattr = caca_get_attr(sc->cv, -1, -1); 
     654                    caca_set_attr(sc->cv, sc->clearattr); 
     655                    caca_draw_line(sc->cv, x, y, x + argv[0] - 1, y, ' '); 
     656                    caca_set_attr(sc->cv, savedattr); 
     657                } 
     658            case 'd':          /* VPA (0x64) - Line Position Absolute */ 
     659                y = (argc && argv[0] > 0) ? argv[0] - 1 : 0; 
     660                break; 
     661            case 'f':          /* HVP (0x66) - Character And Line Position */ 
     662                x = (argc > 1 && argv[1] > 0) ? argv[1] - 1 : 0; 
     663                y = (argc > 0 && argv[0] > 0) ? argv[0] - 1 : 0; 
     664                break; 
     665            case 'r':          /* FIXME */ 
     666                if (argc == 2)  /* DCSTBM - Set top and bottom margin */ 
     667                { 
     668                    debug("DCSTBM %d %d", argv[0], argv[1]); 
     669                    top = argv[0]; 
     670                    bottom = argv[1]; 
     671                } 
     672                else 
     673                    debug("ansi import: command r with %d params", argc); 
     674                break; 
     675            case 'h':          /* SM (0x68) - FIXME */ 
     676                debug("ansi import: set mode %i", argc ? (int)argv[0] : -1); 
     677                break; 
     678            case 'l':          /* RM (0x6c) - FIXME */ 
     679                debug("ansi import: reset mode %i", argc ? (int)argv[0] : -1); 
     680                break; 
     681            case 'm':          /* SGR (0x6d) - Select Graphic Rendition */ 
     682                if (argc) 
     683                    ansi_parse_grcm(sc, argc, argv); 
     684                else 
     685                    ansi_parse_grcm(sc, 1, &dummy); 
     686                break; 
     687            case 's':          /* Private (save cursor position) */ 
     688                save_x = x; 
     689                save_y = y; 
     690                break; 
     691            case 'u':          /* Private (reload cursor position) */ 
     692                x = save_x; 
     693                y = save_y; 
     694                break; 
     695            default: 
     696                debug("ansi import: unknown command \"^[[%.*s\"", 
     697                      final - param + 1, buffer + i + param); 
     698                break; 
     699            } 
     700        } 
     701 
     702        /* Parse OSC stuff. */ 
     703        else if (buffer[i] == '\033' && buffer[i + 1] == ']') 
     704        { 
     705            char *string; 
     706            unsigned int command = 0; 
     707            unsigned int mode = 2, semicolon, final; 
     708 
     709            for (semicolon = mode; i + semicolon < size; semicolon++) 
     710            { 
     711                if (buffer[i + semicolon] < '0' || buffer[i + semicolon] > '9') 
     712                    break; 
     713                command = 10 * command + (buffer[i + semicolon] - '0'); 
     714            } 
     715 
     716            if (i + semicolon >= size || buffer[i + semicolon] != ';') 
     717                break;          /* Invalid Mode */ 
     718 
     719            for (final = semicolon + 1; i + final < size; final++) 
     720                if (buffer[i + final] < 0x20) 
     721                    break; 
     722 
     723            if (i + final >= size || buffer[i + final] != '\a') 
     724                break;          /* Not enough data or no bell found */ 
     725            /* FIXME: XTerm also reacts to <ESC><backslash> and <ST> */ 
     726            /* FIXME: differenciate between not enough data (try again) and 
     727               invalid data (print shit) */ 
     728 
     729            skip += final; 
     730 
     731            string = malloc(final - (semicolon + 1) + 1); 
     732            memcpy(string, buffer + i + (semicolon + 1), 
     733                   final - (semicolon + 1)); 
     734            string[final - (semicolon + 1)] = '\0'; 
     735            debug("ansi import: got OSC command %i string '%s'", command, 
     736                  string); 
     737            if (command == 0 || command == 2) 
     738            { 
     739                if (sc->title) 
     740                    free(sc->title); 
     741                sc->title = string; 
    661742            } 
    662743            else 
    663                 debug("ansi import: command r with %d params", argc); 
    664             break; 
    665         case 'h':              /* SM (0x68) - FIXME */ 
    666             debug("ansi import: set mode %i", argc ? (int)argv[0] : -1); 
    667             break; 
    668         case 'l':              /* RM (0x6c) - FIXME */ 
    669             debug("ansi import: reset mode %i", argc ? (int)argv[0] : -1); 
    670             break; 
    671         case 'm':              /* SGR (0x6d) - Select Graphic Rendition */ 
    672             if (argc) 
    673                 ansi_parse_grcm(sc, argc, argv); 
     744                free(string); 
     745        } 
     746 
     747        /* Get the character we’re going to paste */ 
     748        else 
     749        { 
     750            size_t bytes; 
     751 
     752            if (i + 6 < size) 
     753            { 
     754                ch = caca_utf8_to_utf32((char const *)(buffer + i), &bytes); 
     755            } 
    674756            else 
    675                 ansi_parse_grcm(sc, 1, &dummy); 
    676             break; 
    677         case 's':              /* Private (save cursor position) */ 
    678             save_x = x; 
    679             save_y = y; 
    680             break; 
    681         case 'u':              /* Private (reload cursor position) */ 
    682             x = save_x; 
    683             y = save_y; 
    684             break; 
    685         default: 
    686             debug("ansi import: unknown command \"^[[%.*s\"", 
    687                   final - param + 1, buffer + i + param); 
    688             break; 
    689         } 
    690     } 
    691  
    692         /* Parse OSC stuff. */ 
    693     else if (buffer[i] == '\033' && buffer[i + 1] == ']') 
    694     { 
    695         char *string; 
    696         unsigned int command = 0; 
    697         unsigned int mode = 2, semicolon, final; 
    698  
    699         for (semicolon = mode; i + semicolon < size; semicolon++) 
    700         { 
    701             if (buffer[i + semicolon] < '0' || buffer[i + semicolon] > '9') 
    702                 break; 
    703             command = 10 * command + (buffer[i + semicolon] - '0'); 
    704         } 
    705  
    706         if (i + semicolon >= size || buffer[i + semicolon] != ';') 
    707             break;              /* Invalid Mode */ 
    708  
    709         for (final = semicolon + 1; i + final < size; final++) 
    710             if (buffer[i + final] < 0x20) 
    711                 break; 
    712  
    713         if (i + final >= size || buffer[i + final] != '\a') 
    714             break;              /* Not enough data or no bell found */ 
    715         /* FIXME: XTerm also reacts to <ESC><backslash> and <ST> */ 
    716         /* FIXME: differenciate between not enough data (try again) and 
    717            invalid data (print shit) */ 
    718  
    719         skip += final; 
    720  
    721         string = malloc(final - (semicolon + 1) + 1); 
    722         memcpy(string, buffer + i + (semicolon + 1), final - (semicolon + 1)); 
    723         string[final - (semicolon + 1)] = '\0'; 
    724         debug("ansi import: got OSC command %i string '%s'", command, string); 
    725         if (command == 0 || command == 2) 
    726         { 
    727             if (sc->title) 
    728                 free(sc->title); 
    729             sc->title = string; 
    730         } 
    731         else 
    732             free(string); 
    733     } 
    734  
    735         /* Get the character we’re going to paste */ 
    736     else 
    737     { 
    738         size_t bytes; 
    739  
    740         if (i + 6 < size) 
    741         { 
    742             ch = caca_utf8_to_utf32((char const *)(buffer + i), &bytes); 
    743         } 
    744         else 
    745         { 
    746             /* Add a trailing zero to what we're going to read */ 
    747             char tmp[7]; 
    748             memcpy(tmp, buffer + i, size - i); 
    749             tmp[size - i] = '\0'; 
    750             ch = caca_utf8_to_utf32(tmp, &bytes); 
    751         } 
    752  
    753         if (!bytes) 
    754         { 
    755             /* If the Unicode is invalid, assume it was latin1. */ 
    756             ch = buffer[i]; 
    757             bytes = 1; 
    758         } 
    759  
    760         /* very incomplete ISO-2022 implementation tailored to DEC ACS */ 
    761         if (sc->conv_state.cs == '@') 
    762         { 
    763             if (((ch > ' ') && (ch <= '~')) 
    764                 && 
    765                 (sc->conv_state. 
    766                  gn[sc->conv_state.ss ? sc->conv_state. 
    767                     gn[sc->conv_state.ss] : sc->conv_state.glr[0]] == '0')) 
    768             { 
    769                 ch = dec_acs(ch); 
    770             } 
    771             else if (((ch > 0x80) && (ch < 0xff)) 
    772                      && (sc->conv_state.gn[sc->conv_state.glr[1]] == '0')) 
    773             { 
    774                 ch = dec_acs(ch + ' ' - 0x80); 
    775             } 
    776         } 
    777         sc->conv_state.ss = 0;  /* no single-shift (GL) */ 
    778  
    779         wch = caca_utf32_is_fullwidth(ch) ? 2 : 1; 
    780  
    781         skip += bytes - 1; 
    782     } 
    783  
    784     /* Wrap long lines or grow horizontally */ 
    785     while ((unsigned int)x + wch > width) 
    786     { 
    787         x -= width; 
    788         y++; 
    789     } 
    790  
    791     /* Scroll or grow vertically */ 
    792     if ((unsigned int)y >= bottom) 
    793     { 
    794         int lines = (y - bottom) + 1; 
    795  
    796         savedattr = caca_get_attr(sc->cv, -1, -1); 
    797  
    798         for (j = top - 1; j + lines < bottom; j++) 
    799         { 
    800             for (k = 0; k < width; k++) 
    801             { 
    802                 caca_put_char(sc->cv, k, j, 
    803                               caca_get_char(sc->cv, k, j + lines)); 
    804                 caca_put_attr(sc->cv, k, j, 
    805                               caca_get_attr(sc->cv, k, j + lines)); 
    806             } 
    807         } 
    808         caca_set_attr(sc->cv, sc->clearattr); 
    809         caca_fill_box(sc->cv, 0, bottom - lines, width, bottom - 1, ' '); 
    810         y -= lines; 
    811         caca_set_attr(sc->cv, savedattr); 
    812     } 
     757            { 
     758                /* Add a trailing zero to what we're going to read */ 
     759                char tmp[7]; 
     760                memcpy(tmp, buffer + i, size - i); 
     761                tmp[size - i] = '\0'; 
     762                ch = caca_utf8_to_utf32(tmp, &bytes); 
     763            } 
     764 
     765            if (!bytes) 
     766            { 
     767                /* If the Unicode is invalid, assume it was latin1. */ 
     768                ch = buffer[i]; 
     769                bytes = 1; 
     770            } 
     771 
     772            /* very incomplete ISO-2022 implementation tailored to DEC ACS */ 
     773            if (sc->conv_state.cs == '@') 
     774            { 
     775                if (((ch > ' ') && (ch <= '~')) 
     776                    && 
     777                    (sc-> 
     778                     conv_state.gn[sc->conv_state.ss ? sc-> 
     779                                   conv_state.gn[sc->conv_state.ss] : sc-> 
     780                                   conv_state.glr[0]] == '0')) 
     781                { 
     782                    ch = dec_acs(ch); 
     783                } 
     784                else if (((ch > 0x80) && (ch < 0xff)) 
     785                         && (sc->conv_state.gn[sc->conv_state.glr[1]] == '0')) 
     786                { 
     787                    ch = dec_acs(ch + ' ' - 0x80); 
     788                } 
     789            } 
     790            sc->conv_state.ss = 0;      /* no single-shift (GL) */ 
     791 
     792            wch = caca_utf32_is_fullwidth(ch) ? 2 : 1; 
     793 
     794            skip += bytes - 1; 
     795        } 
     796 
     797        /* Wrap long lines or grow horizontally */ 
     798        while ((unsigned int)x + wch > width) 
     799        { 
     800            x -= width; 
     801            y++; 
     802        } 
     803 
     804        /* Scroll or grow vertically */ 
     805        if ((unsigned int)y >= bottom) 
     806        { 
     807            int lines = (y - bottom) + 1; 
     808 
     809            savedattr = caca_get_attr(sc->cv, -1, -1); 
     810 
     811            for (j = top - 1; j + lines < bottom; j++) 
     812            { 
     813                for (k = 0; k < width; k++) 
     814                { 
     815                    caca_put_char(sc->cv, k, j, 
     816                                  caca_get_char(sc->cv, k, j + lines)); 
     817                    caca_put_attr(sc->cv, k, j, 
     818                                  caca_get_attr(sc->cv, k, j + lines)); 
     819                } 
     820            } 
     821            caca_set_attr(sc->cv, sc->clearattr); 
     822            caca_fill_box(sc->cv, 0, bottom - lines, width, bottom - 1, ' '); 
     823            y -= lines; 
     824            caca_set_attr(sc->cv, savedattr); 
     825        } 
    813826 
    814827        /* Now paste our character, if any */ 
Note: See TracChangeset for help on using the changeset viewer.