|
|
1.1 ! root 1: /* $Id: cterm.c,v 1.89 2006/09/02 08:25:24 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 2006 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 <ctype.h> ! 35: #include <stdlib.h> ! 36: #include <string.h> ! 37: #if defined(_WIN32) ! 38: #include <malloc.h> /* alloca() on Win32 */ ! 39: #endif ! 40: ! 41: #include <genwrap.h> ! 42: #include <xpbeep.h> ! 43: #include <link_list.h> ! 44: #ifdef __unix__ ! 45: #include <xpsem.h> ! 46: #endif ! 47: #include <threadwrap.h> ! 48: ! 49: #if (defined CIOLIB_IMPORTS) ! 50: #undef CIOLIB_IMPORTS ! 51: #endif ! 52: #if (defined CIOLIB_EXPORTS) ! 53: #undef CIOLIB_EXPORTS ! 54: #endif ! 55: ! 56: #include "ciolib.h" ! 57: #include "keys.h" ! 58: ! 59: #include "cterm.h" ! 60: #include "allfonts.h" ! 61: ! 62: #define BUFSIZE 2048 ! 63: ! 64: struct cterminal cterm; ! 65: ! 66: /* const int tabs[11]={1,8,16,24,32,40,48,56,64,72,80}; */ ! 67: const int cterm_tabs[11]={9,17,25,33,41,49,57,65,73,80,80}; ! 68: ! 69: const char *octave="C#D#EF#G#A#B"; ! 70: ! 71: /* Characters allowed in music strings... if one that is NOT in here is ! 72: * found, CTerm leaves music capture mode and tosses the buffer away */ ! 73: const char *musicchars="aAbBcCdDeEfFgGlLmMnNoOpPsStT0123456789.-+#<> "; ! 74: const uint note_frequency[]={ /* Hz*1000 */ ! 75: /* Octave 0 (Note 1) */ ! 76: 65406 ! 77: ,69296 ! 78: ,73416 ! 79: ,77782 ! 80: ,82407 ! 81: ,87307 ! 82: ,92499 ! 83: ,97999 ! 84: ,103820 ! 85: ,110000 ! 86: ,116540 ! 87: ,123470 ! 88: /* Octave 1 */ ! 89: ,130810 ! 90: ,138590 ! 91: ,146830 ! 92: ,155560 ! 93: ,164810 ! 94: ,174610 ! 95: ,185000 ! 96: ,196000 ! 97: ,207650 ! 98: ,220000 ! 99: ,233080 ! 100: ,246940 ! 101: /* Octave 2 */ ! 102: ,261620 ! 103: ,277180 ! 104: ,293660 ! 105: ,311130 ! 106: ,329630 ! 107: ,349230 ! 108: ,369990 ! 109: ,392000 ! 110: ,415300 ! 111: ,440000 ! 112: ,466160 ! 113: ,493880 ! 114: /* Octave 3 */ ! 115: ,523250 ! 116: ,554370 ! 117: ,587330 ! 118: ,622250 ! 119: ,659260 ! 120: ,698460 ! 121: ,739990 ! 122: ,783990 ! 123: ,830610 ! 124: ,880000 ! 125: ,932330 ! 126: ,987770 ! 127: /* Octave 4 */ ! 128: ,1046500 ! 129: ,1108700 ! 130: ,1174700 ! 131: ,1244500 ! 132: ,1318500 ! 133: ,1396900 ! 134: ,1480000 ! 135: ,1568000 ! 136: ,1661200 ! 137: ,1760000 ! 138: ,1864600 ! 139: ,1975500 ! 140: /* Octave 5 */ ! 141: ,2093000 ! 142: ,2217500 ! 143: ,2349300 ! 144: ,2489000 ! 145: ,2637000 ! 146: ,2793800 ! 147: ,2959900 ! 148: ,3136000 ! 149: ,3322400 ! 150: ,3520000 ! 151: ,3729300 ! 152: ,3951100 ! 153: /* Octave 6 */ ! 154: ,4186000 ! 155: ,4435000 ! 156: ,4698600 ! 157: ,4978000 ! 158: ,5274000 ! 159: ,5587000 ! 160: ,5920000 ! 161: ,6272000 ! 162: ,6644000 ! 163: ,7040000 ! 164: ,7458600 ! 165: ,7902200 ! 166: }; ! 167: ! 168: struct note_params { ! 169: int notenum; ! 170: int notelen; ! 171: int dotted; ! 172: int tempo; ! 173: int noteshape; ! 174: int foreground; ! 175: }; ! 176: ! 177: static int playnote_thread_running=FALSE; ! 178: static link_list_t notes; ! 179: sem_t playnote_thread_terminated; ! 180: sem_t note_completed_sem; ! 181: ! 182: void playnote_thread(void *args) ! 183: { ! 184: /* Tempo is quarter notes per minute */ ! 185: int duration; ! 186: int pauselen; ! 187: struct note_params *note; ! 188: int device_open=FALSE; ! 189: ! 190: playnote_thread_running=TRUE; ! 191: while(1) { ! 192: if(device_open) { ! 193: if(!listSemTryWaitBlock(¬es,5000)) { ! 194: xptone_close(); ! 195: device_open=FALSE; ! 196: listSemWait(¬es); ! 197: } ! 198: } ! 199: else ! 200: listSemWait(¬es); ! 201: xptone_open(); ! 202: device_open=TRUE; ! 203: note=listShiftNode(¬es); ! 204: if(note==NULL) ! 205: break; ! 206: if(note->dotted) ! 207: duration=360000/note->tempo; ! 208: else ! 209: duration=240000/note->tempo; ! 210: duration/=note->notelen; ! 211: switch(note->noteshape) { ! 212: case CTERM_MUSIC_STACATTO: ! 213: pauselen=duration/4; ! 214: break; ! 215: case CTERM_MUSIC_LEGATO: ! 216: pauselen=0; ! 217: break; ! 218: case CTERM_MUSIC_NORMAL: ! 219: default: ! 220: pauselen=duration/8; ! 221: break; ! 222: } ! 223: duration-=pauselen; ! 224: if(note->notenum < 72 && note->notenum >= 0) ! 225: xptone(((double)note_frequency[note->notenum])/1000,duration,WAVE_SHAPE_SINE_SAW_HARM); ! 226: else ! 227: SLEEP(duration); ! 228: SLEEP(pauselen); ! 229: if(note->foreground) ! 230: sem_post(¬e_completed_sem); ! 231: free(note); ! 232: } ! 233: playnote_thread_running=FALSE; ! 234: sem_post(&playnote_thread_terminated); ! 235: } ! 236: ! 237: void play_music(void) ! 238: { ! 239: int i; ! 240: char *p; ! 241: char *out; ! 242: int offset; ! 243: char note; ! 244: int notelen; ! 245: char numbuf[10]; ! 246: int dotted; ! 247: int notenum; ! 248: struct note_params *np; ! 249: int fore_count; ! 250: ! 251: p=cterm.musicbuf; ! 252: fore_count=0; ! 253: if(cterm.music==1) { ! 254: switch(toupper(*p)) { ! 255: case 'F': ! 256: cterm.musicfore=TRUE; ! 257: p++; ! 258: break; ! 259: case 'B': ! 260: cterm.musicfore=FALSE; ! 261: p++; ! 262: break; ! 263: case 'N': ! 264: if(!isdigit(*(p+1))) { ! 265: cterm.noteshape=CTERM_MUSIC_NORMAL; ! 266: p++; ! 267: } ! 268: break; ! 269: case 'L': ! 270: cterm.noteshape=CTERM_MUSIC_LEGATO; ! 271: p++; ! 272: break; ! 273: case 'S': ! 274: cterm.noteshape=CTERM_MUSIC_STACATTO; ! 275: p++; ! 276: break; ! 277: } ! 278: } ! 279: for(;*p;p++) { ! 280: notenum=0; ! 281: offset=0; ! 282: switch(toupper(*p)) { ! 283: case 'M': ! 284: p++; ! 285: switch(toupper(*p)) { ! 286: case 'F': ! 287: cterm.musicfore=TRUE; ! 288: break; ! 289: case 'B': ! 290: cterm.musicfore=FALSE; ! 291: break; ! 292: case 'N': ! 293: cterm.noteshape=CTERM_MUSIC_NORMAL; ! 294: break; ! 295: case 'L': ! 296: cterm.noteshape=CTERM_MUSIC_LEGATO; ! 297: break; ! 298: case 'S': ! 299: cterm.noteshape=CTERM_MUSIC_STACATTO; ! 300: break; ! 301: default: ! 302: p--; ! 303: } ! 304: break; ! 305: case 'T': /* Tempo */ ! 306: out=numbuf; ! 307: while(isdigit(*(p+1))) ! 308: *(out++)=*(++p); ! 309: *out=0; ! 310: cterm.tempo=atoi(numbuf); ! 311: if(cterm.tempo>255) ! 312: cterm.tempo=255; ! 313: if(cterm.tempo<32) ! 314: cterm.tempo=32; ! 315: break; ! 316: case 'O': /* Octave */ ! 317: out=numbuf; ! 318: while(isdigit(*(p+1))) ! 319: *(out++)=*(++p); ! 320: *out=0; ! 321: cterm.octave=atoi(numbuf); ! 322: if(cterm.octave>6) ! 323: cterm.octave=6; ! 324: break; ! 325: case 'L': ! 326: out=numbuf; ! 327: while(isdigit(*(p+1))) ! 328: *(out++)=*(++p); ! 329: *out=0; ! 330: cterm.notelen=atoi(numbuf); ! 331: if(cterm.notelen<1) ! 332: cterm.notelen=1; ! 333: if(cterm.notelen>64) ! 334: cterm.notelen=64; ! 335: break; ! 336: case 'N': /* Note by number */ ! 337: if(isdigit(*(p+1))) { ! 338: out=numbuf; ! 339: while(isdigit(*(p+1))) { ! 340: *(out++)=*(p+1); ! 341: p++; ! 342: } ! 343: *out=0; ! 344: notenum=atoi(numbuf); ! 345: } ! 346: if(notenum==0) { ! 347: notenum=-1; ! 348: offset=1; ! 349: } ! 350: /* Fall-through */ ! 351: case 'A': /* Notes in current octave by letter */ ! 352: case 'B': ! 353: case 'C': ! 354: case 'D': ! 355: case 'E': ! 356: case 'F': ! 357: case 'G': ! 358: case 'P': ! 359: note=toupper(*p); ! 360: notelen=cterm.notelen; ! 361: dotted=0; ! 362: i=1; ! 363: while(i) { ! 364: i=0; ! 365: if(*(p+1)=='+' || *(p+1)=='#') { /* SHARP */ ! 366: offset+=1; ! 367: p++; ! 368: i=1; ! 369: } ! 370: if(*(p+1)=='-') { /* FLAT */ ! 371: offset-=1; ! 372: p++; ! 373: i=1; ! 374: } ! 375: if(*(p+1)=='.') { /* Dotted note (1.5*notelen) */ ! 376: dotted=1; ! 377: p++; ! 378: i=1; ! 379: } ! 380: if(isdigit(*(p+1))) { ! 381: out=numbuf; ! 382: while(isdigit(*(p+1))) { ! 383: *(out++)=*(p+1); ! 384: p++; ! 385: } ! 386: *out=0; ! 387: notelen=atoi(numbuf); ! 388: i=1; ! 389: } ! 390: } ! 391: if(note=='P') { ! 392: notenum=-1; ! 393: offset=0; ! 394: } ! 395: if(notenum==0) { ! 396: out=strchr(octave,note); ! 397: if(out==NULL) { ! 398: notenum=-1; ! 399: offset=1; ! 400: } ! 401: else { ! 402: notenum=cterm.octave*12+1; ! 403: notenum+=(out-octave); ! 404: } ! 405: } ! 406: notenum+=offset; ! 407: np=(struct note_params *)malloc(sizeof(struct note_params)); ! 408: if(np!=NULL) { ! 409: np->notenum=notenum; ! 410: np->notelen=notelen; ! 411: np->dotted=dotted; ! 412: np->tempo=cterm.tempo; ! 413: np->noteshape=cterm.noteshape; ! 414: np->foreground=cterm.musicfore; ! 415: listPushNode(¬es, np); ! 416: if(cterm.musicfore) ! 417: fore_count++; ! 418: } ! 419: break; ! 420: case '<': /* Down one octave */ ! 421: cterm.octave--; ! 422: if(cterm.octave<0) ! 423: cterm.octave=0; ! 424: break; ! 425: case '>': /* Up one octave */ ! 426: cterm.octave++; ! 427: if(cterm.octave>6) ! 428: cterm.octave=6; ! 429: break; ! 430: } ! 431: } ! 432: cterm.music=0; ! 433: cterm.musicbuf[0]=0; ! 434: while(fore_count) { ! 435: sem_wait(¬e_completed_sem); ! 436: fore_count--; ! 437: } ! 438: } ! 439: ! 440: void scrolldown(void) ! 441: { ! 442: char *buf; ! 443: int i,j; ! 444: ! 445: buf=(char *)alloca(cterm.width*(cterm.height-1)*2); ! 446: gettext(cterm.x,cterm.y,cterm.x+cterm.width-1,cterm.y+cterm.height-2,buf); ! 447: puttext(cterm.x,cterm.y+1,cterm.x+cterm.width-1,cterm.y+cterm.height-1,buf); ! 448: j=0; ! 449: for(i=0;i<cterm.width;i++) { ! 450: buf[j++]=' '; ! 451: buf[j++]=cterm.attr; ! 452: } ! 453: puttext(cterm.x,cterm.y,cterm.x+cterm.width-1,cterm.y,buf); ! 454: } ! 455: ! 456: void scrollup(void) ! 457: { ! 458: char *buf; ! 459: int i,j; ! 460: ! 461: cterm.backpos++; ! 462: if(cterm.scrollback!=NULL) { ! 463: if(cterm.backpos>cterm.backlines) { ! 464: memmove(cterm.scrollback,cterm.scrollback+cterm.width*2,cterm.width*2*(cterm.backlines-1)); ! 465: cterm.backpos--; ! 466: } ! 467: gettext(cterm.x,cterm.y,cterm.x+cterm.width-1,cterm.y,cterm.scrollback+(cterm.backpos-1)*cterm.width*2); ! 468: } ! 469: buf=(char *)alloca(cterm.width*(cterm.height-1)*2); ! 470: gettext(cterm.x,cterm.y+1,cterm.x+cterm.width-1,cterm.y+cterm.height-1,buf); ! 471: puttext(cterm.x,cterm.y,cterm.x+cterm.width-1,cterm.y+cterm.height-2,buf); ! 472: j=0; ! 473: for(i=0;i<cterm.width;i++) { ! 474: buf[j++]=' '; ! 475: buf[j++]=cterm.attr; ! 476: } ! 477: puttext(cterm.x,cterm.y+cterm.height-1,cterm.x+cterm.width-1,cterm.y+cterm.height-1,buf); ! 478: } ! 479: ! 480: void dellines(int lines) ! 481: { ! 482: char *buf; ! 483: int i,j,k; ! 484: int linestomove; ! 485: ! 486: if(lines<1) ! 487: return; ! 488: linestomove=cterm.height-wherey(); ! 489: buf=(char *)alloca(cterm.width*(linestomove>lines?linestomove:lines)*2); ! 490: gettext(cterm.x,cterm.y+wherey()-1+lines,cterm.x+cterm.width-1,cterm.y+cterm.height-1,buf); ! 491: puttext(cterm.x,cterm.y+wherey()-1,cterm.x+cterm.width-1,cterm.y+cterm.height-1-lines,buf); ! 492: j=0; ! 493: k=cterm.width*lines; ! 494: for(i=0;i<k;i++) { ! 495: buf[j++]=' '; ! 496: buf[j++]=cterm.attr; ! 497: } ! 498: puttext(cterm.x,cterm.y+cterm.height-lines,cterm.x+cterm.width-1,cterm.y+cterm.height-1,buf); ! 499: } ! 500: ! 501: void clear2bol(void) ! 502: { ! 503: char *buf; ! 504: int i,j,k; ! 505: ! 506: k=wherex(); ! 507: buf=(char *)alloca(k*2); ! 508: j=0; ! 509: for(i=0;i<k;i++) { ! 510: buf[j++]=' '; ! 511: buf[j++]=cterm.attr; ! 512: } ! 513: puttext(cterm.x,cterm.y+wherey()-1,cterm.x+wherex()-1,cterm.y+wherey()-1,buf); ! 514: } ! 515: ! 516: void clear2eol(void) ! 517: { ! 518: clreol(); ! 519: } ! 520: ! 521: void clearscreen(char attr) ! 522: { ! 523: if(cterm.scrollback!=NULL) { ! 524: cterm.backpos+=cterm.height; ! 525: if(cterm.backpos>cterm.backlines) { ! 526: memmove(cterm.scrollback,cterm.scrollback+cterm.width*2*(cterm.backpos-cterm.backlines),cterm.width*2*(cterm.backlines-(cterm.backpos-cterm.backlines))); ! 527: cterm.backpos=cterm.backlines; ! 528: } ! 529: gettext(cterm.x,cterm.y,cterm.x+cterm.width-1,cterm.y+cterm.height-1,cterm.scrollback+(cterm.backpos-cterm.height)*cterm.width*2); ! 530: } ! 531: clrscr(); ! 532: } ! 533: ! 534: void do_ansi(char *retbuf, size_t retsize, int *speed) ! 535: { ! 536: char *p; ! 537: char *p2; ! 538: char tmp[1024]; ! 539: int i,j,k,l; ! 540: int row,col; ! 541: ! 542: switch(cterm.escbuf[0]) { ! 543: case '[': ! 544: /* ANSI stuff */ ! 545: p=cterm.escbuf+strlen(cterm.escbuf)-1; ! 546: if(cterm.escbuf[1]>=60 && cterm.escbuf[1] <= 63) { /* Private extenstions */ ! 547: switch(*p) { ! 548: case 'M': ! 549: if(cterm.escbuf[1] == '=') { /* ANSI Music setup */ ! 550: i=atoi(cterm.escbuf+2); ! 551: switch(i) { ! 552: case 1: /* BANSI (ESC[N) music only) */ ! 553: cterm.music_enable=CTERM_MUSIC_BANSI; ! 554: break; ! 555: case 2: /* ESC[M ANSI music */ ! 556: cterm.music_enable=CTERM_MUSIC_ENABLED; ! 557: break; ! 558: default: /* Disable ANSI Music */ ! 559: cterm.music_enable=CTERM_MUSIC_SYNCTERM; ! 560: break; ! 561: } ! 562: } ! 563: break; ! 564: case '{': ! 565: if(cterm.escbuf[1] == '=') { /* Font loading */ ! 566: i=255; ! 567: j=0; ! 568: if(strlen(cterm.escbuf)>2) { ! 569: if((p=strtok(cterm.escbuf+2,";"))!=NULL) { ! 570: i=atoi(p); ! 571: if(!i && cterm.escbuf[2] != '0') ! 572: i=255; ! 573: if((p=strtok(NULL,";"))!=NULL) { ! 574: j=atoi(p); ! 575: } ! 576: } ! 577: } ! 578: if(i>255) ! 579: break; ! 580: cterm.font_start_time=time(NULL); ! 581: cterm.font_read=0; ! 582: cterm.font_slot=i; ! 583: switch(j) { ! 584: case 0: ! 585: cterm.font_size=4096; ! 586: break; ! 587: case 1: ! 588: cterm.font_size=3586; ! 589: break; ! 590: case 2: ! 591: cterm.font_size=2048; ! 592: break; ! 593: default: ! 594: cterm.font_size=0; ! 595: break; ! 596: } ! 597: } ! 598: break; ! 599: } ! 600: break; ! 601: } ! 602: switch(*p) { ! 603: case '@': /* Insert Char */ ! 604: i=wherex(); ! 605: j=wherey(); ! 606: k=atoi(cterm.escbuf+1); ! 607: if(k<1) ! 608: k=1; ! 609: if(k>cterm.width - j) ! 610: k=cterm.width - j; ! 611: gettext(cterm.x+i-1,cterm.y+j-1,cterm.x+cterm.width-1-k,cterm.y+j-1,tmp); ! 612: for(l=0; l< k; l++) ! 613: putch(' '); ! 614: puttext(cterm.x+i-1+k,cterm.y+j-1,cterm.x+cterm.width-1,cterm.y+j-1,tmp); ! 615: gotoxy(i,j); ! 616: break; ! 617: case 'A': /* Cursor Up */ ! 618: i=atoi(cterm.escbuf+1); ! 619: if(i==0) ! 620: i=1; ! 621: i=wherey()-i; ! 622: if(i<1) ! 623: i=1; ! 624: gotoxy(wherex(),i); ! 625: break; ! 626: case 'B': /* Cursor Down */ ! 627: i=atoi(cterm.escbuf+1); ! 628: if(i==0) ! 629: i=1; ! 630: i=wherey()+i; ! 631: if(i>cterm.height) ! 632: i=cterm.height; ! 633: gotoxy(wherex(),i); ! 634: break; ! 635: case 'C': /* Cursor Right */ ! 636: i=atoi(cterm.escbuf+1); ! 637: if(i==0) ! 638: i=1; ! 639: i=wherex()+i; ! 640: if(i>cterm.width) ! 641: i=cterm.width; ! 642: gotoxy(i,wherey()); ! 643: break; ! 644: case 'D': /* Cursor Left and Font Select */ ! 645: if(*(p-1)==' ') { /* Font Select */ ! 646: i=0; ! 647: j=0; ! 648: if(strlen(cterm.escbuf)>2) { ! 649: if((p=strtok(cterm.escbuf+1,";"))!=NULL) { ! 650: i=atoi(p); ! 651: if((p=strtok(NULL,";"))!=NULL) { ! 652: j=atoi(p); ! 653: } ! 654: } ! 655: if(i==0) { /* Only the primary font is currently supported */ ! 656: setfont(j,FALSE); ! 657: } ! 658: } ! 659: } ! 660: else { ! 661: i=atoi(cterm.escbuf+1); ! 662: if(i==0) ! 663: i=1; ! 664: i=wherex()-i; ! 665: if(i<1) ! 666: i=1; ! 667: gotoxy(i,wherey()); ! 668: } ! 669: break; ! 670: case 'E': /* Cursor next line */ ! 671: i=atoi(cterm.escbuf+1); ! 672: if(i==0) ! 673: i=1; ! 674: i=wherey()+i; ! 675: if(i>cterm.height) ! 676: i=cterm.height; ! 677: gotoxy(1,i); ! 678: break; ! 679: case 'F': /* Cursor preceding line */ ! 680: i=atoi(cterm.escbuf+1); ! 681: if(i==0) ! 682: i=1; ! 683: i=wherey()-i; ! 684: if(i<1) ! 685: i=1; ! 686: gotoxy(1,i); ! 687: break; ! 688: case 'f': ! 689: case 'H': ! 690: row=1; ! 691: col=1; ! 692: *p=0; ! 693: if(strlen(cterm.escbuf)>1) { ! 694: if((p=strtok(cterm.escbuf+1,";"))!=NULL) { ! 695: row=atoi(p); ! 696: if((p=strtok(NULL,";"))!=NULL) { ! 697: col=atoi(p); ! 698: } ! 699: } ! 700: } ! 701: if(row<1) ! 702: row=1; ! 703: if(col<1) ! 704: col=1; ! 705: if(row>cterm.height) ! 706: row=cterm.height; ! 707: if(col>cterm.width) ! 708: col=cterm.width; ! 709: gotoxy(col,row); ! 710: break; ! 711: case 'J': ! 712: i=atoi(cterm.escbuf+1); ! 713: switch(i) { ! 714: case 0: ! 715: clear2eol(); ! 716: p2=(char *)alloca(cterm.width*2); ! 717: j=0; ! 718: for(i=0;i<cterm.width;i++) { ! 719: p2[j++]=' '; ! 720: p2[j++]=cterm.attr; ! 721: } ! 722: for(i=wherey()+1;i<=cterm.height;i++) { ! 723: puttext(cterm.x,cterm.y+i-1,cterm.x+cterm.width-1,cterm.y+i-1,p2); ! 724: } ! 725: break; ! 726: case 1: ! 727: clear2bol(); ! 728: p2=(char *)alloca(cterm.width*2); ! 729: j=0; ! 730: for(i=0;i<cterm.width;i++) { ! 731: p2[j++]=' '; ! 732: p2[j++]=cterm.attr; ! 733: } ! 734: for(i=wherey()-1;i>=1;i--) { ! 735: puttext(cterm.x,cterm.y+i-1,cterm.x+cterm.width-1,cterm.y+i-1,p2); ! 736: } ! 737: break; ! 738: case 2: ! 739: clearscreen((char)cterm.attr); ! 740: gotoxy(1,1); ! 741: break; ! 742: } ! 743: break; ! 744: case 'K': ! 745: i=atoi(cterm.escbuf+1); ! 746: switch(i) { ! 747: case 0: ! 748: clear2eol(); ! 749: break; ! 750: case 1: ! 751: clear2bol(); ! 752: break; ! 753: case 2: ! 754: p2=(char *)alloca(cterm.width*2); ! 755: j=0; ! 756: for(i=0;i<cterm.width;i++) { ! 757: p2[j++]=' '; ! 758: p2[j++]=cterm.attr; ! 759: } ! 760: puttext(cterm.x,cterm.y+wherey()-1,cterm.x+cterm.width-1,cterm.y+wherey()-1,p2); ! 761: break; ! 762: } ! 763: break; ! 764: case 'L': /* Insert line */ ! 765: i=atoi(cterm.escbuf+1); ! 766: if(i==0) ! 767: i=1; ! 768: if(i>cterm.height-wherey()) ! 769: i=cterm.height-wherey(); ! 770: if(i) { ! 771: p2=(char *)alloca((cterm.height-wherey()-i+1)*cterm.width*2); ! 772: gettext(cterm.x,cterm.y+wherey()-1,cterm.x+cterm.width-1,cterm.y+cterm.height-1-i,p2); ! 773: puttext(cterm.x,cterm.y+wherey()-1+i,cterm.x+cterm.width-1,cterm.y+cterm.height-1,p2); ! 774: } ! 775: else { ! 776: p2=(char *)alloca(cterm.width*2); ! 777: } ! 778: j=0; ! 779: for(k=0;k<cterm.width;k++) { ! 780: p2[j++]=' '; ! 781: p2[j++]=cterm.attr; ! 782: } ! 783: for(j=0;j<i;j++) { ! 784: puttext(cterm.x,cterm.y+wherey()-1+j,cterm.x+cterm.width-1,cterm.y+wherey()-1+j,p2); ! 785: } ! 786: break; ! 787: case 'M': /* ANSI music and also supposed to be delete line! */ ! 788: if(cterm.music_enable==CTERM_MUSIC_ENABLED) { ! 789: cterm.music=1; ! 790: } ! 791: else { ! 792: i=atoi(cterm.escbuf+1); ! 793: if(i<1) ! 794: i=1; ! 795: dellines(i); ! 796: } ! 797: break; ! 798: case 'N': ! 799: /* BananANSI style... does NOT start with MF or MB */ ! 800: /* This still conflicts (ANSI erase field) */ ! 801: if(cterm.music_enable >= CTERM_MUSIC_BANSI) ! 802: cterm.music=2; ! 803: break; ! 804: case 'P': /* Delete char */ ! 805: i=atoi(cterm.escbuf+1); ! 806: if(i==0) ! 807: i=1; ! 808: if(i>cterm.width-wherex()+1) ! 809: i=cterm.width-wherex()+1; ! 810: p2=(char *)alloca((cterm.width-wherex()+1)*2); ! 811: gettext(cterm.x+wherex(),cterm.y+wherey()-1,cterm.x+cterm.width-1,cterm.y+wherey()-1,p2); ! 812: j=(cterm.width-wherex())*2; ! 813: for(k=0;k<0;k++) { ! 814: p2[j++]=' '; ! 815: p2[j++]=cterm.attr; ! 816: } ! 817: puttext(cterm.x+wherex()-1,cterm.y+wherey()-1,cterm.x+cterm.width-1,cterm.y+wherey()-1,p2); ! 818: break; ! 819: case 'S': ! 820: i=atoi(cterm.escbuf+1); ! 821: if(i==0 && cterm.escbuf[1] != '0') ! 822: i=1; ! 823: for(j=0; j<i; j++) ! 824: scrollup(); ! 825: break; ! 826: case 'T': ! 827: i=atoi(cterm.escbuf+1); ! 828: if(i==0 && cterm.escbuf[1] != '0') ! 829: i=1; ! 830: for(j=0; j<i; j++) ! 831: scrolldown(); ! 832: break; ! 833: #if 0 ! 834: case 'U': ! 835: clearscreen(7); ! 836: gotoxy(1,1); ! 837: break; ! 838: #endif ! 839: case 'X': ! 840: i=atoi(cterm.escbuf+1); ! 841: if(i<1) ! 842: i=1; ! 843: if(i>cterm.width-wherex()) ! 844: i=cterm.width-wherex(); ! 845: p2=alloca(i*2); ! 846: j=0; ! 847: for(k=0;k<i;k++) { ! 848: p2[j++]=' '; ! 849: p2[j++]=cterm.attr; ! 850: } ! 851: puttext(cterm.x+wherex()-1,cterm.y+wherey()-1,cterm.x+wherex()-1+i-1,cterm.y+wherey()-1,p2); ! 852: break; ! 853: case 'Z': ! 854: i=atoi(cterm.escbuf+1); ! 855: if(i==0 && cterm.escbuf[0] != '0') ! 856: i=1; ! 857: for(j=10;j>=0;j--) { ! 858: if(cterm_tabs[j]<wherex()) { ! 859: k=j-i+1; ! 860: if(k<0) ! 861: k=0; ! 862: gotoxy(cterm_tabs[k],wherey()); ! 863: break; ! 864: } ! 865: } ! 866: break; ! 867: case 'b': /* ToDo? Banana ANSI */ ! 868: break; ! 869: case 'c': /* Device Attributes */ ! 870: i=atoi(cterm.escbuf+1); ! 871: if(!i) { ! 872: if(retbuf!=NULL) { ! 873: if(strlen(retbuf)+strlen(cterm.DA) < retsize) ! 874: strcat(retbuf,cterm.DA); ! 875: } ! 876: } ! 877: break; ! 878: case 'g': /* ToDo? VT100 Tabs */ ! 879: break; ! 880: case 'h': /* ToDo? Scrolling regeion, word-wrap, doorway mode */ ! 881: break; ! 882: case 'i': /* ToDo? Printing */ ! 883: break; ! 884: case 'l': /* ToDo? Scrolling regeion, word-wrap, doorway mode */ ! 885: break; ! 886: case 'm': ! 887: *(p--)=0; ! 888: p2=cterm.escbuf+1; ! 889: if(p2>p) { ! 890: cterm.attr=7; ! 891: break; ! 892: } ! 893: while((p=strtok(p2,";"))!=NULL) { ! 894: p2=NULL; ! 895: switch(atoi(p)) { ! 896: case 0: ! 897: cterm.attr=7; ! 898: break; ! 899: case 1: ! 900: cterm.attr|=8; ! 901: break; ! 902: case 2: ! 903: cterm.attr&=247; ! 904: break; ! 905: case 4: /* Underscore */ ! 906: break; ! 907: case 5: ! 908: case 6: ! 909: cterm.attr|=128; ! 910: break; ! 911: case 7: ! 912: case 27: ! 913: i=cterm.attr&7; ! 914: j=cterm.attr&112; ! 915: cterm.attr &= 136; ! 916: cterm.attr |= j>>4; ! 917: cterm.attr |= i<<4; ! 918: break; ! 919: case 8: ! 920: j=cterm.attr&112; ! 921: cterm.attr&=112; ! 922: cterm.attr |= j>>4; ! 923: break; ! 924: case 22: ! 925: cterm.attr &= 0xf7; ! 926: break; ! 927: case 25: ! 928: cterm.attr &= 0x7f; ! 929: break; ! 930: case 30: ! 931: cterm.attr&=248; ! 932: break; ! 933: case 31: ! 934: cterm.attr&=248; ! 935: cterm.attr|=4; ! 936: break; ! 937: case 32: ! 938: cterm.attr&=248; ! 939: cterm.attr|=2; ! 940: break; ! 941: case 33: ! 942: cterm.attr&=248; ! 943: cterm.attr|=6; ! 944: break; ! 945: case 34: ! 946: cterm.attr&=248; ! 947: cterm.attr|=1; ! 948: break; ! 949: case 35: ! 950: cterm.attr&=248; ! 951: cterm.attr|=5; ! 952: break; ! 953: case 36: ! 954: cterm.attr&=248; ! 955: cterm.attr|=3; ! 956: break; ! 957: case 37: ! 958: case 39: ! 959: cterm.attr&=248; ! 960: cterm.attr|=7; ! 961: break; ! 962: case 40: ! 963: cterm.attr&=143; ! 964: break; ! 965: case 41: ! 966: cterm.attr&=143; ! 967: cterm.attr|=4<<4; ! 968: break; ! 969: case 42: ! 970: cterm.attr&=143; ! 971: cterm.attr|=2<<4; ! 972: break; ! 973: case 43: ! 974: cterm.attr&=143; ! 975: cterm.attr|=6<<4; ! 976: break; ! 977: case 44: ! 978: cterm.attr&=143; ! 979: cterm.attr|=1<<4; ! 980: break; ! 981: case 45: ! 982: cterm.attr&=143; ! 983: cterm.attr|=5<<4; ! 984: break; ! 985: case 46: ! 986: cterm.attr&=143; ! 987: cterm.attr|=3<<4; ! 988: break; ! 989: case 47: ! 990: case 49: ! 991: cterm.attr&=143; ! 992: cterm.attr|=7<<4; ! 993: break; ! 994: } ! 995: } ! 996: textattr(cterm.attr); ! 997: break; ! 998: case 'n': ! 999: i=atoi(cterm.escbuf+1); ! 1000: switch(i) { ! 1001: case 5: ! 1002: if(retbuf!=NULL) { ! 1003: strcpy(tmp,"\x1b[0n"); ! 1004: if(strlen(retbuf)+strlen(tmp) < retsize) ! 1005: strcat(retbuf,tmp); ! 1006: } ! 1007: break; ! 1008: case 6: ! 1009: if(retbuf!=NULL) { ! 1010: sprintf(tmp,"%c[%d;%dR",27,wherey(),wherex()); ! 1011: if(strlen(retbuf)+strlen(tmp) < retsize) ! 1012: strcat(retbuf,tmp); ! 1013: } ! 1014: break; ! 1015: case 255: ! 1016: if(retbuf!=NULL) { ! 1017: sprintf(tmp,"%c[%d;%dR",27,cterm.height,cterm.width); ! 1018: if(strlen(retbuf)+strlen(tmp) < retsize) ! 1019: strcat(retbuf,tmp); ! 1020: } ! 1021: break; ! 1022: } ! 1023: break; ! 1024: case 'p': /* ToDo? ANSI keyboard reassignment */ ! 1025: break; ! 1026: case 'q': /* ToDo? VT100 keyboard lights */ ! 1027: break; ! 1028: case 'r': /* ToDo? Scrolling reigon */ ! 1029: /* Set communication speed (if has a * before it) */ ! 1030: if(*(p-1) == '*' && speed != NULL) { ! 1031: /* ! 1032: * Ps1 Comm Line Ps2 Communication Speed ! 1033: * none, 0, 1 Host Transmit none, 0 Use default speed. ! 1034: * 2 Host Receive 1 300 ! 1035: * 3 Printer 2 600 ! 1036: * 4 Modem Hi 3 1200 ! 1037: * 5 Modem Lo 4 2400 ! 1038: * 5 4800 ! 1039: * 6 9600 ! 1040: * 7 19200 ! 1041: * 8 38400 ! 1042: * 9 57600 ! 1043: * 10 76800 ! 1044: * 11 115200 ! 1045: */ ! 1046: int newspeed=0; ! 1047: ! 1048: *(--p)=0; ! 1049: if(cterm.escbuf[1]) { ! 1050: p=strtok(cterm.escbuf+1,";"); ! 1051: if(p!=NULL) { ! 1052: if(p!=cterm.escbuf+1 || atoi(p)<2) { ! 1053: if(p==cterm.escbuf+1) ! 1054: p=strtok(NULL,";"); ! 1055: if(p!=NULL) { ! 1056: switch(atoi(p)) { ! 1057: case 0: ! 1058: newspeed=0; ! 1059: break; ! 1060: case 1: ! 1061: newspeed=300; ! 1062: break; ! 1063: case 2: ! 1064: newspeed=600; ! 1065: break; ! 1066: case 3: ! 1067: newspeed=1200; ! 1068: break; ! 1069: case 4: ! 1070: newspeed=2400; ! 1071: break; ! 1072: case 5: ! 1073: newspeed=4800; ! 1074: break; ! 1075: case 6: ! 1076: newspeed=9600; ! 1077: break; ! 1078: case 7: ! 1079: newspeed=19200; ! 1080: break; ! 1081: case 8: ! 1082: newspeed=38400; ! 1083: break; ! 1084: case 9: ! 1085: newspeed=57600; ! 1086: break; ! 1087: case 10: ! 1088: newspeed=76800; ! 1089: break; ! 1090: case 11: ! 1091: newspeed=115200; ! 1092: break; ! 1093: default: ! 1094: newspeed=-1; ! 1095: break; ! 1096: } ! 1097: } ! 1098: } ! 1099: else ! 1100: newspeed = -1; ! 1101: } ! 1102: } ! 1103: if(newspeed >= 0) ! 1104: *speed = newspeed; ! 1105: } ! 1106: break; ! 1107: case 's': ! 1108: cterm.save_xpos=wherex(); ! 1109: cterm.save_ypos=wherey(); ! 1110: break; ! 1111: case 'u': ! 1112: if(cterm.save_ypos>0 && cterm.save_ypos<=cterm.height ! 1113: && cterm.save_xpos>0 && cterm.save_xpos<=cterm.width) { ! 1114: gotoxy(cterm.save_xpos,cterm.save_ypos); ! 1115: } ! 1116: break; ! 1117: case 'y': /* ToDo? VT100 Tests */ ! 1118: break; ! 1119: case 'z': /* ToDo? Reset */ ! 1120: break; ! 1121: case '|': /* SyncTERM ANSI Music */ ! 1122: break; ! 1123: } ! 1124: break; ! 1125: #if 0 ! 1126: case 'D': ! 1127: scrollup(); ! 1128: break; ! 1129: case 'M': ! 1130: scrolldown(); ! 1131: break; ! 1132: #endif ! 1133: case 'c': ! 1134: /* ToDo: Reset Terminal */ ! 1135: break; ! 1136: } ! 1137: cterm.escbuf[0]=0; ! 1138: cterm.sequence=0; ! 1139: } ! 1140: ! 1141: void cterm_init(int height, int width, int xpos, int ypos, int backlines, unsigned char *scrollback) ! 1142: { ! 1143: char *revision="$Revision: 1.89 $"; ! 1144: char *in; ! 1145: char *out; ! 1146: ! 1147: memset(&cterm, 0, sizeof(cterm)); ! 1148: cterm.x=xpos; ! 1149: cterm.y=ypos; ! 1150: cterm.height=height; ! 1151: cterm.width=width; ! 1152: cterm.attr=7; ! 1153: cterm.save_xpos=0; ! 1154: cterm.save_ypos=0; ! 1155: cterm.escbuf[0]=0; ! 1156: cterm.sequence=0; ! 1157: cterm.music_enable=CTERM_MUSIC_BANSI; ! 1158: cterm.music=0; ! 1159: cterm.tempo=120; ! 1160: cterm.octave=4; ! 1161: cterm.notelen=4; ! 1162: cterm.noteshape=CTERM_MUSIC_NORMAL; ! 1163: cterm.musicfore=TRUE; ! 1164: cterm.backpos=0; ! 1165: cterm.backlines=backlines; ! 1166: cterm.scrollback=scrollback; ! 1167: cterm.log=CTERM_LOG_NONE; ! 1168: cterm.logfile=NULL; ! 1169: if(cterm.scrollback!=NULL) ! 1170: memset(cterm.scrollback,0,cterm.width*2*cterm.backlines); ! 1171: textattr(cterm.attr); ! 1172: _setcursortype(_NORMALCURSOR); ! 1173: window(cterm.x,cterm.y,cterm.x+cterm.width-1,cterm.y+cterm.height-1); ! 1174: clrscr(); ! 1175: gotoxy(1,1); ! 1176: strcpy(cterm.DA,"\x1b[=67;84;101;114;109;"); ! 1177: out=strchr(cterm.DA, 0); ! 1178: if(out != NULL) { ! 1179: for(in=revision; *in; in++) { ! 1180: if(isdigit(*in)) ! 1181: *(out++)=*in; ! 1182: if(*in=='.') ! 1183: *(out++)=';'; ! 1184: } ! 1185: *out=0; ! 1186: } ! 1187: strcat(cterm.DA,"c"); ! 1188: /* Did someone call _init() without calling _end()? */ ! 1189: if(playnote_thread_running) { ! 1190: if(sem_trywait(&playnote_thread_terminated)==-1) { ! 1191: listSemPost(¬es); ! 1192: sem_wait(&playnote_thread_terminated); ! 1193: } ! 1194: sem_destroy(&playnote_thread_terminated); ! 1195: sem_destroy(¬e_completed_sem); ! 1196: listFree(¬es); ! 1197: } ! 1198: /* Fire up note playing thread */ ! 1199: if(!playnote_thread_running) { ! 1200: listInit(¬es, LINK_LIST_SEMAPHORE|LINK_LIST_MUTEX); ! 1201: sem_init(¬e_completed_sem,0,0); ! 1202: sem_init(&playnote_thread_terminated,0,0); ! 1203: _beginthread(playnote_thread, 0, NULL); ! 1204: } ! 1205: } ! 1206: ! 1207: void ctputs(char *buf) ! 1208: { ! 1209: char *outp; ! 1210: char *p; ! 1211: int oldscroll; ! 1212: int cx; ! 1213: int cy; ! 1214: int i; ! 1215: ! 1216: outp=buf; ! 1217: oldscroll=_wscroll; ! 1218: _wscroll=0; ! 1219: cx=wherex(); ! 1220: cy=wherey(); ! 1221: if(cterm.log==CTERM_LOG_ASCII && cterm.logfile != NULL) ! 1222: fputs(buf, cterm.logfile); ! 1223: for(p=buf;*p;p++) { ! 1224: switch(*p) { ! 1225: case '\r': ! 1226: cx=1; ! 1227: break; ! 1228: case '\n': ! 1229: *p=0; ! 1230: cputs(outp); ! 1231: outp=p+1; ! 1232: if(cy==cterm.height) ! 1233: scrollup(); ! 1234: else ! 1235: cy++; ! 1236: gotoxy(cx,cy); ! 1237: break; ! 1238: case '\b': ! 1239: *p=0; ! 1240: cputs(outp); ! 1241: outp=p+1; ! 1242: if(cx>0) ! 1243: cx--; ! 1244: gotoxy(cx,cy); ! 1245: break; ! 1246: case 7: /* Bell */ ! 1247: break; ! 1248: case '\t': ! 1249: for(i=0;i<10;i++) { ! 1250: if(cterm_tabs[i]>cx) { ! 1251: while(cx<cterm_tabs[i]) { ! 1252: cx++; ! 1253: } ! 1254: break; ! 1255: } ! 1256: } ! 1257: if(i==10) { ! 1258: cx=1; ! 1259: if(cy==cterm.height) { ! 1260: *p=0; ! 1261: cputs(outp); ! 1262: outp=p+1; ! 1263: scrollup(); ! 1264: gotoxy(cx,cy); ! 1265: } ! 1266: else ! 1267: cy++; ! 1268: } ! 1269: break; ! 1270: default: ! 1271: if(cy==cterm.height ! 1272: && cx==cterm.width) { ! 1273: char ch; ! 1274: ch=*p; ! 1275: *p=0; ! 1276: cputs(outp); ! 1277: *p=ch; ! 1278: outp=p; ! 1279: scrollup(); ! 1280: cx=1; ! 1281: gotoxy(cx,cy); ! 1282: } ! 1283: else { ! 1284: if(cx==cterm.width) { ! 1285: cx=1; ! 1286: cy++; ! 1287: } ! 1288: else { ! 1289: cx++; ! 1290: } ! 1291: } ! 1292: break; ! 1293: } ! 1294: } ! 1295: cputs(outp); ! 1296: _wscroll=oldscroll; ! 1297: } ! 1298: ! 1299: char *cterm_write(unsigned char *buf, int buflen, char *retbuf, size_t retsize, int *speed) ! 1300: { ! 1301: unsigned char ch[2]; ! 1302: unsigned char prn[BUFSIZE]; ! 1303: int j,k; ! 1304: struct text_info ti; ! 1305: int olddmc; ! 1306: int oldptnm; ! 1307: ! 1308: oldptnm=puttext_can_move; ! 1309: puttext_can_move=1; ! 1310: olddmc=hold_update; ! 1311: hold_update=1; ! 1312: if(retbuf!=NULL) ! 1313: retbuf[0]=0; ! 1314: gettextinfo(&ti); ! 1315: window(cterm.x,cterm.y,cterm.x+cterm.width-1,cterm.y+cterm.height-1); ! 1316: gotoxy(cterm.xpos,cterm.ypos); ! 1317: textattr(cterm.attr); ! 1318: ch[1]=0; ! 1319: switch(buflen) { ! 1320: case 0: ! 1321: break; ! 1322: default: ! 1323: if(cterm.log==CTERM_LOG_RAW && cterm.logfile != NULL) ! 1324: fwrite(buf, buflen, 1, cterm.logfile); ! 1325: prn[0]=0; ! 1326: for(j=0;j<buflen;j++) { ! 1327: ch[0]=buf[j]; ! 1328: if(cterm.font_size) { ! 1329: cterm.fontbuf[cterm.font_read++]=ch[0]; ! 1330: if(cterm.font_read == cterm.font_size) { ! 1331: char *buf; ! 1332: ! 1333: if((buf=(char *)malloc(cterm.font_size))!=NULL) { ! 1334: memcpy(buf,cterm.fontbuf,cterm.font_size); ! 1335: if(cterm.font_slot >= CONIO_FIRST_FREE_FONT) { ! 1336: switch(cterm.font_size) { ! 1337: case 4096: ! 1338: FREE_AND_NULL(conio_fontdata[cterm.font_slot].eight_by_sixteen); ! 1339: conio_fontdata[cterm.font_slot].eight_by_sixteen=buf; ! 1340: FREE_AND_NULL(conio_fontdata[cterm.font_slot].desc); ! 1341: conio_fontdata[cterm.font_slot].desc=strdup("Remote Defined Font"); ! 1342: break; ! 1343: case 3586: ! 1344: FREE_AND_NULL(conio_fontdata[cterm.font_slot].eight_by_fourteen); ! 1345: conio_fontdata[cterm.font_slot].eight_by_fourteen=buf; ! 1346: FREE_AND_NULL(conio_fontdata[cterm.font_slot].desc); ! 1347: conio_fontdata[cterm.font_slot].desc=strdup("Remote Defined Font"); ! 1348: break; ! 1349: case 2048: ! 1350: FREE_AND_NULL(conio_fontdata[cterm.font_slot].eight_by_eight); ! 1351: conio_fontdata[cterm.font_slot].eight_by_eight=buf; ! 1352: FREE_AND_NULL(conio_fontdata[cterm.font_slot].desc); ! 1353: conio_fontdata[cterm.font_slot].desc=strdup("Remote Defined Font"); ! 1354: break; ! 1355: } ! 1356: } ! 1357: else ! 1358: FREE_AND_NULL(buf); ! 1359: } ! 1360: cterm.font_size=0; ! 1361: } ! 1362: } ! 1363: else if(cterm.sequence) { ! 1364: k=strlen(cterm.escbuf); ! 1365: strcat(cterm.escbuf,ch); ! 1366: if(k) { ! 1367: if(cterm.escbuf[0] != '[') { /* Not a CSI code. */ ! 1368: /* ANSI control characters */ ! 1369: if(ch[0] >= 32 && ch[0] <= 47) { ! 1370: /* Legal intermediate character */ ! 1371: } ! 1372: else if(ch[0] >= 48 && ch[0] <= 126) { ! 1373: /* Terminating character */ ! 1374: do_ansi(retbuf, retsize, speed); ! 1375: } ! 1376: else { ! 1377: /* Broken sequence detected */ ! 1378: strcat(prn,"\033"); ! 1379: strcat(prn,cterm.escbuf); ! 1380: cterm.escbuf[0]=0; ! 1381: cterm.sequence=0; ! 1382: } ! 1383: } ! 1384: else { ! 1385: /* We know that it was a CSI at this point */ ! 1386: /* Here's where we get funky! */ ! 1387: /* the last character defines the set of legal next characters */ ! 1388: if(ch[0] >= 48 && ch[0] <= 63) { ! 1389: /* Parameter character. Only legal after '[' and other param chars */ ! 1390: if(cterm.escbuf[k]!='[' ! 1391: && (cterm.escbuf[k] < 48 || cterm.escbuf[k] > 63)) { ! 1392: /* Broken sequence detected */ ! 1393: strcat(prn,"\033"); ! 1394: strcat(prn,cterm.escbuf); ! 1395: cterm.escbuf[0]=0; ! 1396: cterm.sequence=0; ! 1397: } ! 1398: } ! 1399: else if(ch[0] >= 32 && ch[0] <= 47) { ! 1400: /* Intermediate character. Legal after '[', param, or intermetiate chars */ ! 1401: if(cterm.escbuf[k]!='[' ! 1402: && (cterm.escbuf[k] < 48 || cterm.escbuf[k] > 63) ! 1403: && (cterm.escbuf[k] < 32 || cterm.escbuf[k] > 47)) { ! 1404: /* Broken sequence detected */ ! 1405: strcat(prn,"\033"); ! 1406: strcat(prn,cterm.escbuf); ! 1407: cterm.escbuf[0]=0; ! 1408: cterm.sequence=0; ! 1409: } ! 1410: } ! 1411: else if(ch[0] >= 64 && ch[0] <= 126) { ! 1412: /* Terminating character. Always legal at this point. */ ! 1413: do_ansi(retbuf, retsize, speed); ! 1414: } ! 1415: else { ! 1416: /* Broken sequence detected */ ! 1417: strcat(prn,"\033"); ! 1418: strcat(prn,cterm.escbuf); ! 1419: cterm.escbuf[0]=0; ! 1420: cterm.sequence=0; ! 1421: } ! 1422: } ! 1423: } ! 1424: else { ! 1425: /* First char after the ESC */ ! 1426: if(ch[0] >= 32 && ch[0] <= 47) { ! 1427: /* Legal intermediate character */ ! 1428: /* No CSI then */ ! 1429: } ! 1430: else if(ch[0]=='[') { ! 1431: /* CSI received */ ! 1432: } ! 1433: else if(ch[0] >= 48 && ch[0] <= 126) { ! 1434: /* Terminating character */ ! 1435: do_ansi(retbuf, retsize, speed); ! 1436: } ! 1437: else { ! 1438: /* Broken sequence detected */ ! 1439: strcat(prn,"\033"); ! 1440: strcat(prn,cterm.escbuf); ! 1441: cterm.escbuf[0]=0; ! 1442: cterm.sequence=0; ! 1443: } ! 1444: } ! 1445: if(ch[0]=='\033') { /* Broken sequence followed by a legal one! */ ! 1446: if(prn[0]) /* Don't display the ESC */ ! 1447: prn[strlen(prn)-1]=0; ! 1448: ctputs(prn); ! 1449: prn[0]=0; ! 1450: cterm.sequence=1; ! 1451: } ! 1452: } ! 1453: else if (cterm.music) { ! 1454: if(ch[0]==14) ! 1455: play_music(); ! 1456: else { ! 1457: if(strchr(musicchars,ch[0])!=NULL) ! 1458: strcat(cterm.musicbuf,ch); ! 1459: else { ! 1460: /* Kill non-music strings */ ! 1461: cterm.music=0; ! 1462: cterm.musicbuf[0]=0; ! 1463: } ! 1464: } ! 1465: } ! 1466: else { ! 1467: switch(buf[j]) { ! 1468: case 0: ! 1469: break; ! 1470: case 7: /* Beep */ ! 1471: ctputs(prn); ! 1472: prn[0]=0; ! 1473: if(cterm.log==CTERM_LOG_ASCII && cterm.logfile != NULL) ! 1474: fputs("\t", cterm.logfile); ! 1475: #ifdef __unix__ ! 1476: putch(7); ! 1477: #else ! 1478: MessageBeep(MB_OK); ! 1479: #endif ! 1480: break; ! 1481: case 12: /* ^L - Clear screen */ ! 1482: ctputs(prn); ! 1483: prn[0]=0; ! 1484: if(cterm.log==CTERM_LOG_ASCII && cterm.logfile != NULL) ! 1485: fputs("\t", cterm.logfile); ! 1486: clearscreen((char)cterm.attr); ! 1487: gotoxy(1,1); ! 1488: break; ! 1489: case 27: /* ESC */ ! 1490: ctputs(prn); ! 1491: prn[0]=0; ! 1492: cterm.sequence=1; ! 1493: break; ! 1494: case '\t': ! 1495: ctputs(prn); ! 1496: prn[0]=0; ! 1497: if(cterm.log==CTERM_LOG_ASCII && cterm.logfile != NULL) ! 1498: fputs("\t", cterm.logfile); ! 1499: for(k=0;k<11;k++) { ! 1500: if(cterm_tabs[k]>wherex()) { ! 1501: gotoxy(cterm_tabs[k],wherey()); ! 1502: break; ! 1503: } ! 1504: } ! 1505: break; ! 1506: default: ! 1507: strcat(prn,ch); ! 1508: } ! 1509: } ! 1510: } ! 1511: ctputs(prn); ! 1512: prn[0]=0; ! 1513: break; ! 1514: } ! 1515: cterm.xpos=wherex(); ! 1516: cterm.ypos=wherey(); ! 1517: #if 0 ! 1518: window(ti.winleft,ti.wintop,ti.winright,ti.winbottom); ! 1519: gotoxy(ti.curx,ti.cury); ! 1520: textattr(ti.attribute); ! 1521: #endif ! 1522: ! 1523: hold_update=olddmc; ! 1524: puttext_can_move=oldptnm; ! 1525: gotoxy(wherex(),wherey()); ! 1526: return(retbuf); ! 1527: } ! 1528: ! 1529: int cterm_openlog(char *logfile, int logtype) ! 1530: { ! 1531: cterm.logfile=fopen(logfile, "a"); ! 1532: if(cterm.logfile==NULL) ! 1533: return(0); ! 1534: cterm.log=logtype; ! 1535: return(1); ! 1536: } ! 1537: ! 1538: void cterm_closelog() ! 1539: { ! 1540: if(cterm.logfile != NULL) ! 1541: fclose(cterm.logfile); ! 1542: cterm.logfile=NULL; ! 1543: cterm.log=CTERM_LOG_NONE; ! 1544: } ! 1545: ! 1546: void cterm_end(void) ! 1547: { ! 1548: int i; ! 1549: ! 1550: cterm_closelog(); ! 1551: for(i=CONIO_FIRST_FREE_FONT; i < 256; i++) { ! 1552: FREE_AND_NULL(conio_fontdata[i].eight_by_sixteen); ! 1553: FREE_AND_NULL(conio_fontdata[i].eight_by_fourteen); ! 1554: FREE_AND_NULL(conio_fontdata[i].eight_by_eight); ! 1555: FREE_AND_NULL(conio_fontdata[i].desc); ! 1556: } ! 1557: if(playnote_thread_running) { ! 1558: if(sem_trywait(&playnote_thread_terminated)==-1) { ! 1559: listSemPost(¬es); ! 1560: sem_wait(&playnote_thread_terminated); ! 1561: } ! 1562: sem_destroy(&playnote_thread_terminated); ! 1563: sem_destroy(¬e_completed_sem); ! 1564: listFree(¬es); ! 1565: } ! 1566: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.