|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.