Annotation of sbbs/conio/ansi_cio.c, revision 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.