Annotation of sbbs/conio/ansi_cio.c, revision 1.1.1.1

1.1       root        1: /* $Id: ansi_cio.c,v 1.37 2004/12/22 11:06:46 deuce Exp $ */
                      2: 
                      3: /****************************************************************************
                      4:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      5:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                      6:  *                                                                                                                                                     *
                      7:  * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html         *
                      8:  *                                                                                                                                                     *
                      9:  * This library is free software; you can redistribute it and/or                       *
                     10:  * modify it under the terms of the GNU Lesser General Public License          *
                     11:  * as published by the Free Software Foundation; either version 2                      *
                     12:  * of the License, or (at your option) any later version.                                      *
                     13:  * See the GNU Lesser General Public License for more details: lgpl.txt or     *
                     14:  * http://www.fsf.org/copyleft/lesser.html                                                                     *
                     15:  *                                                                                                                                                     *
                     16:  * Anonymous FTP access to the most recent released source is available at     *
                     17:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     18:  *                                                                                                                                                     *
                     19:  * Anonymous CVS access to the development source and modification history     *
                     20:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     21:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     22:  *     (just hit return, no password is necessary)                                                     *
                     23:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     24:  *                                                                                                                                                     *
                     25:  * For Synchronet coding style and modification guidelines, see                                *
                     26:  * http://www.synchro.net/source.html                                                                          *
                     27:  *                                                                                                                                                     *
                     28:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     29:  * format) via e-mail to [email protected]                                                                      *
                     30:  *                                                                                                                                                     *
                     31:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     32:  ****************************************************************************/
                     33: 
                     34: #include <fcntl.h>
                     35: #include <stdarg.h>
                     36: #include <stdlib.h>    /* malloc */
                     37: 
                     38: #include <genwrap.h>
                     39: #include <threadwrap.h>
                     40: #include <semwrap.h>
                     41: 
                     42: #ifdef __unix__
                     43:        #include <termios.h>
                     44:        struct termios tio_default;                             /* Initial term settings */
                     45: #endif
                     46: 
                     47: #include "ciolib.h"
                     48: #include "ansi_cio.h"
                     49: 
                     50: #define        ANSI_TIMEOUT    500
                     51: 
                     52: sem_t  got_key;
                     53: sem_t  got_input;
                     54: sem_t  used_input;
                     55: sem_t  goahead;
                     56: sem_t  need_key;
                     57: static BOOL    sent_ga=FALSE;
                     58: WORD   ansi_curr_attr=0x07<<8;
                     59: 
                     60: int ansi_rows=24;
                     61: int ansi_cols=80;
                     62: int ansi_got_row=0;
                     63: int ansi_got_col=0;
                     64: int ansi_esc_delay=25;
                     65: int puttext_no_move=0;
                     66: 
                     67: const int      ansi_tabs[10]={9,17,25,33,41,49,57,65,73,80};
                     68: const int      ansi_colours[8]={0,4,2,6,1,5,3,7};
                     69: static WORD            ansi_inch;
                     70: static unsigned char           ansi_raw_inch;
                     71: WORD   *vmem;
                     72: int            ansi_row=0;
                     73: int            ansi_col=0;
                     74: int            force_move=1;
                     75: 
                     76: /* Control sequence table definitions. */
                     77: typedef struct
                     78: {
                     79:    char *pszSequence;
                     80:    int chExtendedKey;
                     81: } tODKeySequence;
                     82: 
                     83: #define ANSI_KEY_UP            72<<8
                     84: #define ANSI_KEY_DOWN  80<<8
                     85: #define ANSI_KEY_RIGHT 0x4d<<8
                     86: #define ANSI_KEY_LEFT  0x4b<<8
                     87: #define ANSI_KEY_HOME  0x47<<8
                     88: #define ANSI_KEY_END   0x4f<<8
                     89: #define ANSI_KEY_F1            0x3b<<8
                     90: #define ANSI_KEY_F2            0x3c<<8
                     91: #define ANSI_KEY_F3            0x3d<<8
                     92: #define ANSI_KEY_F4            0x3e<<8
                     93: #define ANSI_KEY_F5            0x3f<<8
                     94: #define ANSI_KEY_F6            0x40<<8
                     95: #define ANSI_KEY_F7            0x41<<8
                     96: #define ANSI_KEY_F8            0x42<<8
                     97: #define ANSI_KEY_F9            0x43<<8
                     98: #define ANSI_KEY_F10   0x44<<8
                     99: #define ANSI_KEY_PGUP  0x49<<8
                    100: #define ANSI_KEY_PGDN  0x51<<8
                    101: #define ANSI_KEY_INSERT        0x52<<8
                    102: #define ANSI_KEY_DELETE        0x53<<8
                    103: 
                    104: tODKeySequence aKeySequences[] =
                    105: {
                    106:    /* VT-52 control sequences. */
                    107:    {"\033A", ANSI_KEY_UP},
                    108:    {"\033B", ANSI_KEY_DOWN},
                    109:    {"\033C", ANSI_KEY_RIGHT},
                    110:    {"\033D", ANSI_KEY_LEFT},
                    111:    {"\033H", ANSI_KEY_HOME},
                    112:    {"\033K", ANSI_KEY_END},
                    113:    {"\033P", ANSI_KEY_F1},
                    114:    {"\033Q", ANSI_KEY_F2},
                    115:    {"\033?w", ANSI_KEY_F3},
                    116:    {"\033?x", ANSI_KEY_F4},
                    117:    {"\033?t", ANSI_KEY_F5},
                    118:    {"\033?u", ANSI_KEY_F6},
                    119:    {"\033?q", ANSI_KEY_F7},
                    120:    {"\033?r", ANSI_KEY_F8},
                    121:    {"\033?p", ANSI_KEY_F9},
                    122: 
                    123:    /* Control sequences common to VT-100/VT-102/VT-220/VT-320/ANSI. */
                    124:    {"\033[A", ANSI_KEY_UP},
                    125:    {"\033[B", ANSI_KEY_DOWN},
                    126:    {"\033[C", ANSI_KEY_RIGHT},
                    127:    {"\033[D", ANSI_KEY_LEFT},
                    128:    {"\033[M", ANSI_KEY_PGUP},
                    129:    {"\033[H\x1b[2J", ANSI_KEY_PGDN},
                    130:    {"\033[H", ANSI_KEY_HOME},
                    131:    {"\033[K", ANSI_KEY_END},
                    132:    {"\033OP", ANSI_KEY_F1},
                    133:    {"\033OQ", ANSI_KEY_F2},
                    134:    {"\033OR", ANSI_KEY_F3},
                    135:    {"\033OS", ANSI_KEY_F4},
                    136: 
                    137:    /* VT-220/VT-320 specific control sequences. */
                    138:    {"\033[17~", ANSI_KEY_F6},
                    139:    {"\033[18~", ANSI_KEY_F7},
                    140:    {"\033[19~", ANSI_KEY_F8},
                    141:    {"\033[20~", ANSI_KEY_F9},
                    142:    {"\033[21~", ANSI_KEY_F10},
                    143: 
                    144:    /* ANSI-specific control sequences. */
                    145:    {"\033[L", ANSI_KEY_HOME},
                    146:    {"\033Ow", ANSI_KEY_F3},
                    147:    {"\033Ox", ANSI_KEY_F4},
                    148:    {"\033Ot", ANSI_KEY_F5},
                    149:    {"\033Ou", ANSI_KEY_F6},
                    150:    {"\033Oq", ANSI_KEY_F7},
                    151:    {"\033Or", ANSI_KEY_F8},
                    152:    {"\033Op", ANSI_KEY_F9},
                    153: 
                    154:    /* PROCOMM-specific control sequences (non-keypad alternatives). */
                    155:    {"\033OA", ANSI_KEY_UP},
                    156:    {"\033OB", ANSI_KEY_DOWN},
                    157:    {"\033OC", ANSI_KEY_RIGHT},
                    158:    {"\033OD", ANSI_KEY_LEFT},
                    159:    {"\033OH", ANSI_KEY_HOME},
                    160:    {"\033OK", ANSI_KEY_END},
                    161: 
                    162:    /* Terminator */
                    163:    {"",0}
                    164: };
                    165: 
                    166: void ansi_sendch(char ch)
                    167: {
                    168:        if(!ch)
                    169:                ch=' ';
                    170:        if(ansi_row<ansi_rows-1 || (ansi_row==ansi_rows-1 && ansi_col<ansi_cols-1)) {
                    171:                ansi_col++;
                    172:                if(ansi_col>=ansi_cols) {
                    173:                        ansi_col=0;
                    174:                        ansi_row++;
                    175:                        if(ansi_row>=ansi_rows) {
                    176:                                ansi_col=ansi_cols-1;
                    177:                                ansi_row=ansi_rows-1;
                    178:                        }
                    179:                }
                    180:                fwrite(&ch,1,1,stdout);
                    181:                if(ch<' ')
                    182:                        force_move=1;
                    183:        }
                    184: }
                    185: 
                    186: void ansi_sendstr(char *str,int len)
                    187: {
                    188:        if(len==-1)
                    189:                len=strlen(str);
                    190:        if(len) {
                    191:                fwrite(str,len,1,stdout);
                    192:        }
                    193: }
                    194: 
                    195: int ansi_puttext(int sx, int sy, int ex, int ey, void* buf)
                    196: {
                    197:        int x,y;
                    198:        unsigned char *out;
                    199:        WORD    sch;
                    200:        struct text_info        ti;
                    201:        int             attrib;
                    202:        unsigned char *fill = (unsigned char*)buf;
                    203: 
                    204:        gettextinfo(&ti);
                    205: 
                    206:        if(                sx < 1
                    207:                        || sy < 1
                    208:                        || ex < 1
                    209:                        || ey < 1
                    210:                        || sx > ti.screenwidth
                    211:                        || sy > ti.screenheight
                    212:                        || sx > ex
                    213:                        || sy > ey
                    214:                        || ex > ti.screenwidth
                    215:                        || ey > ti.screenheight
                    216:                        || fill==NULL)
                    217:                return(0);
                    218: 
                    219:        out=fill;
                    220:        attrib=ti.attribute;
                    221:        for(y=sy-1;y<ey;y++) {
                    222:                for(x=sx-1;x<ex;x++) {
                    223:                        sch=*(out++);
                    224:                        if(sch==27)
                    225:                                sch=' ';
                    226:                        if(sch==0)
                    227:                                sch=' ';
                    228:                        sch |= (*(out++))<<8;
                    229:                        if(vmem[y*ansi_cols+x]==sch)
                    230:                                continue;
                    231:                        vmem[y*ansi_cols+x]=sch;
                    232:                        ansi_gotoxy(x+1,y+1);
                    233:                        if(attrib!=sch>>8) {
                    234:                                textattr(sch>>8);
                    235:                                attrib=sch>>8;
                    236:                        }
                    237:                        ansi_sendch((char)(sch&0xff));
                    238:                }
                    239:        }
                    240: 
                    241:        if(!puttext_no_move)
                    242:                gotoxy(ti.curx,ti.cury);
                    243:        if(attrib!=ti.attribute)
                    244:                textattr(ti.attribute);
                    245:        return(1);
                    246: }
                    247: 
                    248: int ansi_gettext(int sx, int sy, int ex, int ey, void* buf)
                    249: {
                    250:        int x,y;
                    251:        unsigned char *out;
                    252:        WORD    sch;
                    253:        struct text_info        ti;
                    254:        unsigned char *fill = (unsigned char*)buf;
                    255: 
                    256:        gettextinfo(&ti);
                    257: 
                    258:        if(                sx < 1
                    259:                        || sy < 1
                    260:                        || ex < 1
                    261:                        || ey < 1
                    262:                        || sx > ti.screenwidth
                    263:                        || sy > ti.screenheight
                    264:                        || sx > ex
                    265:                        || sy > ey
                    266:                        || ex > ti.screenwidth
                    267:                        || ey > ti.screenheight
                    268:                        || fill==NULL)
                    269:                return(0);
                    270: 
                    271:        out=fill;
                    272:        for(y=sy-1;y<ey;y++) {
                    273:                for(x=sx-1;x<ex;x++) {
                    274:                        sch=vmem[y*ansi_cols+x];
                    275:                        *(out++)=sch & 0xff;
                    276:                        *(out++)=sch >> 8;
                    277:                }
                    278:        }
                    279:        return(1);
                    280: }
                    281: 
                    282: void ansi_textattr(int attr)
                    283: {
                    284:        char str[16];
                    285:        int fg,ofg;
                    286:        int bg,obg;
                    287:        int bl,obl;
                    288:        int br,obr;
                    289:        int oa;
                    290: 
                    291:        str[0]=0;
                    292:        if(ansi_curr_attr==attr<<8)
                    293:                return;
                    294: 
                    295:        bl=attr&0x80;
                    296:        bg=(attr>>4)&0x7;
                    297:        fg=attr&0x07;
                    298:        br=attr&0x04;
                    299: 
                    300:        oa=ansi_curr_attr>>8;
                    301:        obl=oa>>7;
                    302:        obg=(oa>>4)&0x7;
                    303:        ofg=oa&0x07;
                    304:        obr=(oa>>3)&0x01;
                    305: 
                    306:        ansi_curr_attr=attr<<8;
                    307: 
                    308:        strcpy(str,"\033[");
                    309:        if(obl!=bl) {
                    310:                if(!bl) {
                    311:                        strcat(str,"0;");
                    312:                        ofg=7;
                    313:                        obg=0;
                    314:                        obr=0;
                    315:                }
                    316:                else
                    317:                        strcat(str,"5;");
                    318:        }
                    319:        if(br!=obr) {
                    320:                if(br)
                    321:                        strcat(str,"1;");
                    322:                else
                    323: #if 0
                    324:                        strcat(str,"2;");
                    325: #else
                    326:                {
                    327:                        strcat(str,"0;");
                    328:                        ofg=7;
                    329:                        obg=0;
                    330:                }
                    331: #endif
                    332:        }
                    333:        if(fg!=ofg)
                    334:                sprintf(str+strlen(str),"3%d;",ansi_colours[fg]);
                    335:        if(bg!=obg)
                    336:                sprintf(str+strlen(str),"4%d;",ansi_colours[bg]);
                    337:        str[strlen(str)-1]='m';
                    338:        ansi_sendstr(str,-1);
                    339: }
                    340: 
                    341: #if defined(__BORLANDC__)
                    342:         #pragma argsused
                    343: #endif
                    344: static void ansi_keyparse(void *par)
                    345: {
                    346:        int             gotesc=0;
                    347:        char    seq[64];
                    348:        int             ch;
                    349:        int             i;
                    350:        char    *p;
                    351:        int             timeout=0;
                    352:        int             timedout=0;
                    353:        int             sval;
                    354:        int             unknown=0;
                    355: 
                    356:        seq[0]=0;
                    357:        for(;;) {
                    358:                sem_wait(&goahead);
                    359:                if(timedout || unknown) {
                    360:                        for(p=seq;*p;p++) {
                    361:                                ansi_inch=*p;
                    362:                                sem_post(&got_input);
                    363:                                sem_wait(&used_input);
                    364:                                sem_wait(&goahead);
                    365:                        }
                    366:                        gotesc=0;
                    367:                        timeout=0;
                    368:                        seq[0]=0;
                    369:                }
                    370:                if(!timedout)
                    371:                        sem_post(&need_key);
                    372:                timedout=0;
                    373:                unknown=0;
                    374:                if(timeout) {
                    375:                        if(sem_trywait_block(&got_key,timeout)) {
                    376:                                timedout=1;
                    377:                                sem_post(&goahead);
                    378:                                continue;
                    379:                        }
                    380:                }
                    381:                else
                    382:                        sem_wait(&got_key);
                    383: 
                    384:                ch=ansi_raw_inch;
                    385: 
                    386:                switch(gotesc) {
                    387:                        case 1: /* Escape Sequence */
                    388:                                timeout=ANSI_TIMEOUT;
                    389:                                seq[strlen(seq)+1]=0;
                    390:                                seq[strlen(seq)]=ch;
                    391:                                if(strlen(seq)>=sizeof(seq)-2) {
                    392:                                        gotesc=0;
                    393:                                        break;
                    394:                                }
                    395:                                if((ch<'0' || ch>'9')           /* End of ESC sequence */
                    396:                                                && ch!=';'
                    397:                                                && ch!='?'
                    398:                                                && (strlen(seq)==2?ch != '[':1)
                    399:                                                && (strlen(seq)==2?ch != 'O':1)) {
                    400:                                        unknown=1;
                    401:                                        gotesc=0;
                    402:                                        timeout=0;
                    403:                                        for(i=0;aKeySequences[i].pszSequence[0];i++) {
                    404:                                                if(!strcmp(seq,aKeySequences[i].pszSequence)) {
                    405:                                                        ansi_inch=aKeySequences[i].chExtendedKey;
                    406:                                                        sem_post(&got_input);
                    407:                                                        /* Two-byte code, need to post twice and wait for one to
                    408:                                                           be received */
                    409:                                                        sem_wait(&used_input);
                    410:                                                        sem_wait(&goahead);
                    411:                                                        sem_post(&got_input);
                    412:                                                        sem_wait(&used_input);
                    413:                                                        unknown=0;
                    414:                                                        seq[0]=0;
                    415:                                                        break;
                    416:                                                }
                    417:                                        }
                    418:                                        if(unknown) {
                    419:                                                sem_post(&goahead);
                    420:                                                continue;
                    421:                                        }
                    422:                                }
                    423:                                else {
                    424:                                        /* Need more keys... keep looping */
                    425:                                        sem_post(&goahead);
                    426:                                }
                    427:                                break;
                    428:                        default:
                    429:                                if(ch==27) {
                    430:                                        seq[0]=27;
                    431:                                        seq[1]=0;
                    432:                                        gotesc=1;
                    433:                                        timeout=ANSI_TIMEOUT;
                    434:                                        /* Need more keys... keep going... */
                    435:                                        sem_post(&goahead);
                    436:                                        break;
                    437:                                }
                    438:                                if(ch==10) {
                    439:                                        /* The \n that goes with the prev \r (hopefully) */
                    440:                                        /* Eat it and keep chuggin' */
                    441:                                        sem_post(&goahead);
                    442:                                        break;
                    443:                                }
                    444:                                ansi_inch=ch;
                    445:                                sem_post(&got_input);
                    446:                                sem_wait(&used_input);
                    447:                                break;
                    448:                }
                    449:        }
                    450: }
                    451: 
                    452: #if defined(__BORLANDC__)
                    453:         #pragma argsused
                    454: #endif
                    455: static void ansi_keythread(void *params)
                    456: {
                    457:        int     sval=1;
                    458: 
                    459:        _beginthread(ansi_keyparse,1024,NULL);
                    460: 
                    461:        for(;;) {
                    462:                sem_wait(&need_key);
                    463:                /* If you already have a key, don't get another */
                    464:                sem_getvalue(&got_key,&sval);
                    465:                if((!sval) && fread(&ansi_raw_inch,1,1,stdin)==1)
                    466:                        sem_post(&got_key);
                    467:                else
                    468:                        SLEEP(1);
                    469:        }
                    470: }
                    471: 
                    472: int ansi_kbhit(void)
                    473: {
                    474:        int     sval=1;
                    475: 
                    476:        if(!sent_ga) {
                    477:                sem_post(&goahead);
                    478:                sent_ga=TRUE;
                    479:        }
                    480:        sem_getvalue(&got_input,&sval);
                    481:        return(sval);
                    482: }
                    483: 
                    484: void ansi_delay(long msec)
                    485: {
                    486:        SLEEP(msec);
                    487: }
                    488: 
                    489: int ansi_wherey(void)
                    490: {
                    491:        return(ansi_row+1);
                    492: }
                    493: 
                    494: int ansi_wherex(void)
                    495: {
                    496:        return(ansi_col+1);
                    497: }
                    498: 
                    499: /* Put the character _c on the screen at the current cursor position. 
                    500:  * The special characters return, linefeed, bell, and backspace are handled
                    501:  * properly, as is line wrap and scrolling. The cursor position is updated. 
                    502:  */
                    503: int ansi_putch(int ch)
                    504: {
                    505:        struct text_info ti;
                    506:        int i;
                    507:        unsigned char buf[2];
                    508: 
                    509:        buf[0]=ch;
                    510:        buf[1]=ansi_curr_attr>>8;
                    511: 
                    512:        gettextinfo(&ti);
                    513:        puttext_no_move=1;
                    514: 
                    515:        switch(ch) {
                    516:                case '\r':
                    517:                        gotoxy(1,wherey());
                    518:                        break;
                    519:                case '\n':
                    520:                        if(wherey()==ti.winbottom-ti.wintop+1)
                    521:                                wscroll();
                    522:                        else
                    523:                                gotoxy(wherex(),wherey()+1);
                    524:                        break;
                    525:                case '\b':
                    526:                        if(ansi_col>ti.winleft-1) {
                    527:                                buf[0]=' ';
                    528:                                gotoxy(wherex()-1,wherey());
                    529:                                puttext(ansi_col+1,ansi_row+1,ansi_col+1,ansi_row+1,buf);
                    530:                        }
                    531:                        break;
                    532:                case 7:         /* Bell */
                    533:                        ansi_sendch(7);
                    534:                        break;
                    535:                case '\t':
                    536:                        for(i=0;i<10;i++) {
                    537:                                if(ansi_tabs[i]>ansi_col+1) {
                    538:                                        while(ansi_col+1<ansi_tabs[i]) {
                    539:                                                putch(' ');
                    540:                                        }
                    541:                                        break;
                    542:                                }
                    543:                        }
                    544:                        if(i==10) {
                    545:                                putch('\r');
                    546:                                putch('\n');
                    547:                        }
                    548:                        break;
                    549:                default:
                    550:                        if(wherey()==ti.winbottom-ti.wintop+1
                    551:                                        && wherex()==ti.winright-ti.winleft+1) {
                    552:                                gotoxy(1,wherey());
                    553:                                puttext(ansi_col+1,ansi_row+1,ansi_col+1,ansi_row+1,buf);
                    554:                                wscroll();
                    555:                        }
                    556:                        else {
                    557:                                if(wherex()==ti.winright-ti.winleft+1) {
                    558:                                        gotoxy(1,ti.cury+1);
                    559:                                        puttext(ansi_col+1,ansi_row+1,ansi_col+1,ansi_row+1,buf);
                    560:                                }
                    561:                                else {
                    562:                                        puttext(ansi_col+1,ansi_row+1,ansi_col+1,ansi_row+1,buf);
                    563:                                        gotoxy(ti.curx+1,ti.cury);
                    564:                                }
                    565:                        }
                    566:                        break;
                    567:        }
                    568: 
                    569:        puttext_no_move=0;
                    570:        return(ch);
                    571: }
                    572: 
                    573: void ansi_gotoxy(int x, int y)
                    574: {
                    575:        char str[16];
                    576: 
                    577:        if(x < 1
                    578:                || x > ansi_cols
                    579:                || y < 1
                    580:                || y > ansi_rows)
                    581:                return;
                    582:        if(force_move) {
                    583:                force_move=0;
                    584:                sprintf(str,"\033[%d;%dH",y,x);
                    585:        }
                    586:        else {
                    587:                if(x==1 && ansi_col != 0 && ansi_row<ansi_row-1) {
                    588:                        ansi_sendch('\r');
                    589:                        force_move=0;
                    590:                        ansi_col=0;
                    591:                }
                    592:                if(x==ansi_col+1) {
                    593:                        if(y==ansi_row+1) {
                    594:                                str[0]=0;
                    595:                        }
                    596:                        else {
                    597:                                if(y<ansi_row+1) {
                    598:                                        if(y==ansi_row)
                    599:                                                strcpy(str,"\033[A");
                    600:                                        else
                    601:                                                sprintf(str,"\033[%dA",ansi_row+1-y);
                    602:                                }
                    603:                                else {
                    604:                                        if(y==ansi_row+2)
                    605:                                                strcpy(str,"\033[B");
                    606:                                        else
                    607:                                                sprintf(str,"\033[%dB",y-ansi_row-1);
                    608:                                }
                    609:                        }
                    610:                }
                    611:                else {
                    612:                        if(y==ansi_row+1) {
                    613:                                if(x<ansi_col+1) {
                    614:                                        if(x==ansi_col)
                    615:                                                strcpy(str,"\033[D");
                    616:                                        else
                    617:                                                sprintf(str,"\033[%dD",ansi_col+1-x);
                    618:                                }
                    619:                                else {
                    620:                                        if(x==ansi_col+2)
                    621:                                                strcpy(str,"\033[C");
                    622:                                        else
                    623:                                                sprintf(str,"\033[%dC",x-ansi_col-1);
                    624:                                }
                    625:                        }
                    626:                        else {
                    627:                                sprintf(str,"\033[%d;%dH",y,x);
                    628:                        }
                    629:                }
                    630:        }
                    631: 
                    632:        ansi_sendstr(str,-1);
                    633:        ansi_row=y-1;
                    634:        ansi_col=x-1;
                    635: }
                    636: 
                    637: void ansi_gettextinfo(struct text_info *info)
                    638: {
                    639:        info->currmode=3;
                    640:        info->screenheight=ansi_rows;
                    641:        info->screenwidth=ansi_cols;
                    642:        info->curx=wherex();
                    643:        info->cury=wherey();
                    644:        info->attribute=ansi_curr_attr>>8;
                    645: }
                    646: 
                    647: void ansi_setcursortype(int type)
                    648: {
                    649:        switch(type) {
                    650:                case _NOCURSOR:
                    651:                case _SOLIDCURSOR:
                    652:                default:
                    653:                        break;
                    654:        }
                    655: }
                    656: 
                    657: int ansi_getch(void)
                    658: {
                    659:        int ch;
                    660: 
                    661:        if(!sent_ga) {
                    662:                sem_post(&goahead);
                    663:                sent_ga=TRUE;
                    664:        }
                    665:        sem_wait(&got_input);
                    666:        ch=ansi_inch&0xff;
                    667:        ansi_inch=ansi_inch>>8;
                    668:        sem_post(&used_input);
                    669:        sent_ga=FALSE;
                    670:        return(ch);
                    671: }
                    672: 
                    673: int ansi_getche(void)
                    674: {
                    675:        int ch;
                    676: 
                    677:        ch=ansi_getch();
                    678:        if(ch)
                    679:                putch(ch);
                    680:        return(ch);
                    681: }
                    682: 
                    683: int ansi_beep(void)
                    684: {
                    685:        putch(7);
                    686:        return(0);
                    687: }
                    688: 
                    689: #if defined(__BORLANDC__)
                    690:         #pragma argsused
                    691: #endif
                    692: void ansi_textmode(int mode)
                    693: {
                    694: }
                    695: 
                    696: #ifdef __unix__
                    697: void ansi_fixterm(void)
                    698: {
                    699:        tcsetattr(STDIN_FILENO,TCSANOW,&tio_default);
                    700: }
                    701: #endif
                    702: 
                    703: #ifndef ENABLE_EXTENDED_FLAGS
                    704: #define ENABLE_INSERT_MODE             0x0020
                    705: #define ENABLE_QUICK_EDIT_MODE 0x0040
                    706: #define ENABLE_EXTENDED_FLAGS  0x0080
                    707: #define ENABLE_AUTO_POSITION   0x0100
                    708: #endif
                    709: 
                    710: #if defined(__BORLANDC__)
                    711:         #pragma argsused
                    712: #endif
                    713: int ansi_initciolib(long inmode)
                    714: {
                    715:        int i;
                    716:        char *init="\033[0m\033[2J\033[1;1H";
                    717: 
                    718: #ifdef _WIN32
                    719:        if(isatty(fileno(stdin))) {
                    720:                if(!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0))
                    721:                        return(0);
                    722: 
                    723:                if(!SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), 0))
                    724:                        return(0);
                    725:        }
                    726:        setmode(fileno(stdout),_O_BINARY);
                    727:        setmode(fileno(stdin),_O_BINARY);
                    728:        setvbuf(stdout, NULL, _IONBF, 0);
                    729: #else
                    730:        struct termios tio_raw;
                    731: 
                    732:        if (isatty(STDIN_FILENO))  {
                    733:                tcgetattr(STDIN_FILENO,&tio_default);
                    734:                tio_raw = tio_default;
                    735:                cfmakeraw(&tio_raw);
                    736:                tcsetattr(STDIN_FILENO,TCSANOW,&tio_raw);
                    737:                setvbuf(stdout, NULL, _IONBF, 0);
                    738:                atexit(ansi_fixterm);
                    739:        }
                    740: #endif
                    741: 
                    742:        sem_init(&got_key,0,0);
                    743:        sem_init(&got_input,0,0);
                    744:        sem_init(&used_input,0,0);
                    745:        sem_init(&goahead,0,0);
                    746:        sem_init(&need_key,0,0);
                    747: 
                    748:        vmem=(WORD *)malloc(ansi_rows*ansi_cols*sizeof(WORD));
                    749:        ansi_sendstr(init,-1);
                    750:        for(i=0;i<ansi_rows*ansi_cols;i++)
                    751:                vmem[i]=0x0720;
                    752:        _beginthread(ansi_keythread,1024,NULL);
                    753:        return(1);
                    754: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.