diff --git a/src/conio/cterm.c b/src/conio/cterm.c index 0fbe79751d58d99ecabcd114011452fc3862649f..bc7f7091e213c4bd39a84098da3e376f02ca47f7 100644 --- a/src/conio/cterm.c +++ b/src/conio/cterm.c @@ -1940,12 +1940,81 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int * cterm->strbuflen = 0; break; case '\\': - if (cterm->string) { - // TODO: Handle the string... - FREE_AND_NULL(cterm->strbuf); - cterm->strbufsize = cterm->strbuflen = 0; - cterm->string = 0; + if (cterm->strbuf) { + if (cterm->strbufsize == cterm->strbuflen-1) { + p = realloc(cterm->strbuf, cterm->strbufsize+1); + if (p == NULL) { + // SO CLOSE! + cterm->string = 0; + } + else { + cterm->strbuf = p; + cterm->strbufsize++; + } + } + cterm->strbuf[cterm->strbuflen] = 0; + } + switch (cterm->string) { + case CTERM_STRING_OSC: + /* Is this an xterm Change Color(s)? */ + if (cterm->strbuf[0] == '4' && cterm->strbuf[1] == ';') { + uint32_t index = UINT32_MAX; + char *seqlast; + + p2 = &cterm->strbuf[2]; + while ((p = strtok_r(p2, ";", &seqlast)) != NULL) { + p2=NULL; + if (index == UINT32_MAX) { + index = strtoull(p, NULL, 10); + if (index == UINT32_MAX || index > 13200) + break; + } + else { + + if (strncmp(p, "rgb:", 4)) + break; + char *p3; + char *p4; + char *collast; + uint16_t rgb[3]; + int ccount = 0; + + p4 = &p[4]; + while (ccount < 3 && (p3 = strtok_r(p4, "/", &collast))!=NULL) { + p4 = NULL; + unsigned long v; + v = strtoul(p3, NULL, 16); + if (v > UINT16_MAX) + break; + switch(strlen(p3)) { + case 1: // 4-bit colour + rgb[ccount] = v | (v<<4) | (v<<8) | (v<<12); + break; + case 2: // 8-bit colour + rgb[ccount] = v | (v<<8); + break; + case 3: // 12-bit colour + rgb[ccount] = (v & 0x0f) | (v<<4); + break; + case 4: + rgb[ccount] = v; + break; + } + ccount++; + } + if (ccount == 3) + setpalette(index, rgb[0], rgb[1], rgb[2]); + } + } + } + else if (strncmp("104", cterm->strbuf, 3)==0) { + // TODO reset color(s) + } } + // TODO: Handle the string... + FREE_AND_NULL(cterm->strbuf); + cterm->strbufsize = cterm->strbuflen = 0; + cterm->string = 0; break; case 'c': /* ToDo: Reset Terminal */ @@ -2211,7 +2280,7 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * prn[0]=0; } ch[0]=buf[j]; - if (cterm->string) { + if (cterm->string && !cterm->sequence) { switch (cterm->string) { case CTERM_STRING_APC: /* 0x08-0x0d, 0x20-0x7e */ @@ -2222,10 +2291,18 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * case CTERM_STRING_PM: /* 0x08-0x0d, 0x20-0x7e */ if (ch[0] < 8 || (ch[0] > 0x0d && ch[0] < 0x20) || ch[0] > 0x7e) { - cterm->string = 0; - // TODO: Detect correct string termination... - FREE_AND_NULL(cterm->strbuf); - cterm->strbuflen = cterm->strbufsize = 0; + if (ch[0] == 27) { + ctputs(cterm, prn); + prn[0]=0; + cterm->sequence=1; + break; + } + else { + cterm->string = 0; + /* Just toss out the string and this char */ + FREE_AND_NULL(cterm->strbuf); + cterm->strbuflen = cterm->strbufsize = 0; + } } else { if (cterm->strbuf) { @@ -2255,6 +2332,7 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * FREE_AND_NULL(cterm->strbuf); cterm->strbuflen = cterm->strbufsize = 0; cterm_write(cterm, "\e", 1, retbuf+strlen(retbuf), retsize-strlen(retbuf), speed); + cterm_write(cterm, ch[0], 1, retbuf+strlen(retbuf), retsize-strlen(retbuf), speed); } else { if (cterm->strbuf == NULL) { @@ -2280,69 +2358,83 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * break; } } - if (!cterm->string) { - if(cterm->font_size) { - cterm->fontbuf[cterm->font_read++]=ch[0]; - if(cterm->font_read == cterm->font_size) { + else if(cterm->font_size) { + cterm->fontbuf[cterm->font_read++]=ch[0]; + if(cterm->font_read == cterm->font_size) { #ifndef CTERM_WITHOUT_CONIO - char *buf2; - - if((buf2=(char *)malloc(cterm->font_size))!=NULL) { - memcpy(buf2,cterm->fontbuf,cterm->font_size); - if(cterm->font_slot >= CONIO_FIRST_FREE_FONT) { - switch(cterm->font_size) { - case 4096: - FREE_AND_NULL(conio_fontdata[cterm->font_slot].eight_by_sixteen); - conio_fontdata[cterm->font_slot].eight_by_sixteen=buf2; - FREE_AND_NULL(conio_fontdata[cterm->font_slot].desc); - conio_fontdata[cterm->font_slot].desc=strdup("Remote Defined Font"); - break; - case 3586: - FREE_AND_NULL(conio_fontdata[cterm->font_slot].eight_by_fourteen); - conio_fontdata[cterm->font_slot].eight_by_fourteen=buf2; - FREE_AND_NULL(conio_fontdata[cterm->font_slot].desc); - conio_fontdata[cterm->font_slot].desc=strdup("Remote Defined Font"); - break; - case 2048: - FREE_AND_NULL(conio_fontdata[cterm->font_slot].eight_by_eight); - conio_fontdata[cterm->font_slot].eight_by_eight=buf2; - FREE_AND_NULL(conio_fontdata[cterm->font_slot].desc); - conio_fontdata[cterm->font_slot].desc=strdup("Remote Defined Font"); - break; - default: - FREE_AND_NULL(buf2); - break; - } + char *buf2; + + if((buf2=(char *)malloc(cterm->font_size))!=NULL) { + memcpy(buf2,cterm->fontbuf,cterm->font_size); + if(cterm->font_slot >= CONIO_FIRST_FREE_FONT) { + switch(cterm->font_size) { + case 4096: + FREE_AND_NULL(conio_fontdata[cterm->font_slot].eight_by_sixteen); + conio_fontdata[cterm->font_slot].eight_by_sixteen=buf2; + FREE_AND_NULL(conio_fontdata[cterm->font_slot].desc); + conio_fontdata[cterm->font_slot].desc=strdup("Remote Defined Font"); + break; + case 3586: + FREE_AND_NULL(conio_fontdata[cterm->font_slot].eight_by_fourteen); + conio_fontdata[cterm->font_slot].eight_by_fourteen=buf2; + FREE_AND_NULL(conio_fontdata[cterm->font_slot].desc); + conio_fontdata[cterm->font_slot].desc=strdup("Remote Defined Font"); + break; + case 2048: + FREE_AND_NULL(conio_fontdata[cterm->font_slot].eight_by_eight); + conio_fontdata[cterm->font_slot].eight_by_eight=buf2; + FREE_AND_NULL(conio_fontdata[cterm->font_slot].desc); + conio_fontdata[cterm->font_slot].desc=strdup("Remote Defined Font"); + break; + default: + FREE_AND_NULL(buf2); + break; } - else - FREE_AND_NULL(buf2); } -#endif - cterm->font_size=0; + else + FREE_AND_NULL(buf2); } +#endif + cterm->font_size=0; } - else if(cterm->sequence) { - k=strlen(cterm->escbuf); - if(k+1 >= sizeof(cterm->escbuf)) { - /* Broken sequence detected */ - strcat(prn,"\033"); - strcat(prn,cterm->escbuf); - cterm->escbuf[0]=0; - cterm->sequence=0; - } - else { - strcat(cterm->escbuf,ch); - if(k) { - if(cterm->escbuf[0] != '[') { /* Not a CSI code. */ - /* ANSI control characters */ - if(ch[0] >= 32 && ch[0] <= 47) { - /* Legal intermediate character */ - } - else if(ch[0] >= 48 && ch[0] <= 126) { - /* Terminating character */ - do_ansi(cterm, retbuf, retsize, speed); - } - else { + } + else if(cterm->sequence) { + k=strlen(cterm->escbuf); + if(k+1 >= sizeof(cterm->escbuf)) { + /* Broken sequence detected */ + strcat(prn,"\033"); + strcat(prn,cterm->escbuf); + cterm->escbuf[0]=0; + cterm->sequence=0; + } + else { + strcat(cterm->escbuf,ch); + if(k) { + if(cterm->escbuf[0] != '[') { /* Not a CSI code. */ + /* ANSI control characters */ + if(ch[0] >= 32 && ch[0] <= 47) { + /* Legal intermediate character */ + } + else if(ch[0] >= 48 && ch[0] <= 126) { + /* Terminating character */ + do_ansi(cterm, retbuf, retsize, speed); + } + else { + /* Broken sequence detected */ + strcat(prn,"\033"); + strcat(prn,cterm->escbuf); + cterm->escbuf[0]=0; + cterm->sequence=0; + } + } + else { + /* We know that it was a CSI at this point */ + /* Here's where we get funky! */ + /* the last character defines the set of legal next characters */ + if(ch[0] >= 48 && ch[0] <= 63) { + /* Parameter character. Only legal after '[' and other param chars */ + if(cterm->escbuf[k]!='[' + && (cterm->escbuf[k] < 48 || cterm->escbuf[k] > 63)) { /* Broken sequence detected */ strcat(prn,"\033"); strcat(prn,cterm->escbuf); @@ -2350,38 +2442,11 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * cterm->sequence=0; } } - else { - /* We know that it was a CSI at this point */ - /* Here's where we get funky! */ - /* the last character defines the set of legal next characters */ - if(ch[0] >= 48 && ch[0] <= 63) { - /* Parameter character. Only legal after '[' and other param chars */ - if(cterm->escbuf[k]!='[' - && (cterm->escbuf[k] < 48 || cterm->escbuf[k] > 63)) { - /* Broken sequence detected */ - strcat(prn,"\033"); - strcat(prn,cterm->escbuf); - cterm->escbuf[0]=0; - cterm->sequence=0; - } - } - else if(ch[0] >= 32 && ch[0] <= 47) { - /* Intermediate character. Legal after '[', param, or intermetiate chars */ - if(cterm->escbuf[k]!='[' - && (cterm->escbuf[k] < 48 || cterm->escbuf[k] > 63) - && (cterm->escbuf[k] < 32 || cterm->escbuf[k] > 47)) { - /* Broken sequence detected */ - strcat(prn,"\033"); - strcat(prn,cterm->escbuf); - cterm->escbuf[0]=0; - cterm->sequence=0; - } - } - else if(ch[0] >= 64 && ch[0] <= 126) { - /* Terminating character. Always legal at this point. */ - do_ansi(cterm, retbuf, retsize, speed); - } - else { + else if(ch[0] >= 32 && ch[0] <= 47) { + /* Intermediate character. Legal after '[', param, or intermetiate chars */ + if(cterm->escbuf[k]!='[' + && (cterm->escbuf[k] < 48 || cterm->escbuf[k] > 63) + && (cterm->escbuf[k] < 32 || cterm->escbuf[k] > 47)) { /* Broken sequence detected */ strcat(prn,"\033"); strcat(prn,cterm->escbuf); @@ -2389,18 +2454,8 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * cterm->sequence=0; } } - } - else { - /* First char after the ESC */ - if(ch[0] >= 32 && ch[0] <= 47) { - /* Legal intermediate character */ - /* No CSI then */ - } - else if(ch[0]=='[') { - /* CSI received */ - } - else if(ch[0] >= 48 && ch[0] <= 126) { - /* Terminating character */ + else if(ch[0] >= 64 && ch[0] <= 126) { + /* Terminating character. Always legal at this point. */ do_ansi(cterm, retbuf, retsize, speed); } else { @@ -2411,418 +2466,156 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * cterm->sequence=0; } } - if(ch[0]=='\033') { /* Broken sequence followed by a legal one! */ - if(prn[0]) /* Don't display the ESC */ - prn[strlen(prn)-1]=0; - ctputs(cterm, prn); - prn[0]=0; - cterm->sequence=1; - } - } - } - else if (cterm->music) { - if(ch[0]==14) { - *cterm->hold_update=0; - *cterm->puttext_can_move=0; - GOTOXY(WHEREX(),WHEREY()); - SETCURSORTYPE(cterm->cursor); - *cterm->hold_update=1; - *cterm->puttext_can_move=1; - play_music(cterm); } else { - if(strchr(musicchars,ch[0])!=NULL) - strcat(cterm->musicbuf,ch); + /* First char after the ESC */ + if(ch[0] >= 32 && ch[0] <= 47) { + /* Legal intermediate character */ + /* No CSI then */ + } + else if(ch[0]=='[') { + /* CSI received */ + } + else if(ch[0] >= 48 && ch[0] <= 126) { + /* Terminating character */ + do_ansi(cterm, retbuf, retsize, speed); + } else { - /* Kill non-music strings */ - cterm->music=0; - cterm->musicbuf[0]=0; + /* Broken sequence detected */ + strcat(prn,"\033"); + strcat(prn,cterm->escbuf); + cterm->escbuf[0]=0; + cterm->sequence=0; } } + if(ch[0]=='\033') { /* Broken sequence followed by a legal one! */ + if(prn[0]) /* Don't display the ESC */ + prn[strlen(prn)-1]=0; + ctputs(cterm, prn); + prn[0]=0; + cterm->sequence=1; + } + } + } + else if (cterm->music) { + if(ch[0]==14) { + *cterm->hold_update=0; + *cterm->puttext_can_move=0; + GOTOXY(WHEREX(),WHEREY()); + SETCURSORTYPE(cterm->cursor); + *cterm->hold_update=1; + *cterm->puttext_can_move=1; + play_music(cterm); } else { - if(cterm->emulation == CTERM_EMULATION_ATASCII) { - if(cterm->attr==7) { - switch(buf[j]) { - case 27: /* ESC */ - cterm->attr=1; - break; - case 28: /* Up (TODO: Wraps??) */ - l=WHEREY()-1; - if(l<1) - l=cterm->height; - GOTOXY(WHEREX(),l); - break; - case 29: /* Down (TODO: Wraps??) */ - l=WHEREY()+1; - if(l>cterm->height) - l=1; - GOTOXY(WHEREX(),l); - break; - case 30: /* Left (TODO: Wraps around to same line?) */ - l=WHEREX()-1; - if(l<1) - l=cterm->width; - GOTOXY(l,WHEREY()); - break; - case 31: /* Right (TODO: Wraps around to same line?) */ - l=WHEREX()+1; - if(l>cterm->width) - l=1; - GOTOXY(l,WHEREY()); - break; - case 125: /* Clear Screen */ - cterm_clearscreen(cterm, cterm->attr); - break; - case 126: /* Backspace (TODO: Wraps around to previous line?) */ - /* DOES NOT delete char, merely erases */ - k=WHEREY(); - l=WHEREX()-1; - - if(l<1) { - k--; - if(k<1) - break; - l=cterm->width; - } - GOTOXY(l,k); - PUTCH(0); - GOTOXY(l,k); - break; - /* We abuse the ESC buffer for tab stops */ - case 127: /* Tab (Wraps around to next line) */ - l=WHEREX(); - for(k=l+1; k<=cterm->width; k++) { - if(cterm->escbuf[k]) { - l=k; - break; - } - } - if(k>cterm->width) { - l=1; - k=WHEREY()+1; - if(k>cterm->height) { - scrollup(cterm); - k=cterm->height; - } - GOTOXY(l,k); - } - else - GOTOXY(l,WHEREY()); - break; - case 155: /* Return */ - k=WHEREY(); - if(k==cterm->height) - scrollup(cterm); - else - k++; - GOTOXY(1,k); - break; - case 156: /* Delete Line */ - dellines(cterm, 1); - GOTOXY(1,WHEREY()); - break; - case 157: /* Insert Line */ - l=WHEREX(); - k=WHEREY(); - if(k<cterm->height) - MOVETEXT(cterm->x,cterm->y+k-1 - ,cterm->x+cterm->width-1,cterm->y+cterm->height-2 - ,cterm->x,cterm->y+k); - GOTOXY(1,k); - CLREOL(); - break; - case 158: /* Clear Tab */ - cterm->escbuf[WHEREX()]=0; - break; - case 159: /* Set Tab */ - cterm->escbuf[WHEREX()]=1; - break; - case 253: /* Beep */ - if(!cterm->quiet) { - #ifdef __unix__ - PUTCH(7); - #else - MessageBeep(MB_OK); - #endif - } - break; - case 254: /* Delete Char */ - l=WHEREX(); - k=WHEREY(); - if(l<cterm->width) - MOVETEXT(cterm->x+l,cterm->y+k-1 - ,cterm->x+cterm->width-1,cterm->y+k-1 - ,cterm->x+l-1,cterm->y+k-1); - GOTOXY(cterm->width,k); - CLREOL(); - GOTOXY(l,k); - break; - case 255: /* Insert Char */ - l=WHEREX(); - k=WHEREY(); - if(l<cterm->width) - MOVETEXT(cterm->x+l-1,cterm->y+k-1 - ,cterm->x+cterm->width-2,cterm->y+k-1 - ,cterm->x+l,cterm->y+k-1); - PUTCH(0); - GOTOXY(l,k); - break; - default: - /* Translate to screen codes */ - k=buf[j]; - if(k < 32) { - k +=64; - } - else if(k < 96) { - k -= 32; - } - else if(k < 128) { - /* No translation */ - } - else if(k < 160) { - k +=64; - } - else if(k < 224) { - k -= 32; - } - else if(k < 256) { - /* No translation */ - } - ch[0] = k; - ch[1] = cterm->attr; - PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); - ch[1]=0; - if(WHEREX()==cterm->width) { - if(WHEREY()==cterm->height) { - scrollup(cterm); - GOTOXY(1,WHEREY()); - } - else - GOTOXY(1,WHEREY()+1); - } - else - GOTOXY(WHEREX()+1,WHEREY()); - break; - } - } - else { - switch(buf[j]) { - case 155: /* Return */ - k=WHEREY(); - if(k==cterm->height) - scrollup(cterm); - else - k++; - GOTOXY(1,k); - break; - default: - /* Translate to screen codes */ - k=buf[j]; - if(k < 32) { - k +=64; - } - else if(k < 96) { - k -= 32; - } - else if(k < 128) { - /* No translation */ - } - else if(k < 160) { - k +=64; - } - else if(k < 224) { - k -= 32; - } - else if(k < 256) { - /* No translation */ - } - ch[0] = k; - ch[1] = cterm->attr; - PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); - ch[1]=0; - if(WHEREX()==cterm->width) { - if(WHEREY()==cterm->height) { - scrollup(cterm); - GOTOXY(1,cterm->height); - } - else - GOTOXY(1,WHEREY()+1); - } - else - GOTOXY(WHEREX()+1,WHEREY()); - break; - } - cterm->attr=7; - } + if(strchr(musicchars,ch[0])!=NULL) + strcat(cterm->musicbuf,ch); + else { + /* Kill non-music strings */ + cterm->music=0; + cterm->musicbuf[0]=0; } - else if(cterm->emulation == CTERM_EMULATION_PETASCII) { + } + } + else { + if(cterm->emulation == CTERM_EMULATION_ATASCII) { + if(cterm->attr==7) { switch(buf[j]) { - case 5: /* White */ - case 28: /* Red */ - case 30: /* Green */ - case 31: /* Blue */ - case 129: /* Orange */ - case 144: /* Black */ - case 149: /* Brown */ - case 150: /* Light Red */ - case 151: /* Dark Gray */ - case 152: /* Grey */ - case 153: /* Light Green */ - case 154: /* Light Blue */ - case 155: /* Light Gray */ - case 156: /* Purple */ - case 158: /* Yellow */ - case 159: /* Cyan */ - cterm->attr &= 0xf0; - switch(buf[j]) { - case 5: /* White */ - cterm->attr |= 1; - break; - case 28: /* Red */ - cterm->attr |= 2; - break; - case 30: /* Green */ - cterm->attr |= 5; - break; - case 31: /* Blue */ - cterm->attr |= 6; - break; - case 129: /* Orange */ - cterm->attr |= 8; - break; - case 144: /* Black */ - cterm->attr |= 0; - break; - case 149: /* Brown */ - cterm->attr |= 9; - break; - case 150: /* Light Red */ - cterm->attr |= 10; - break; - case 151: /* Dark Gray */ - cterm->attr |= 11; - break; - case 152: /* Grey */ - cterm->attr |= 12; - break; - case 153: /* Light Green */ - cterm->attr |= 13; - break; - case 154: /* Light Blue */ - cterm->attr |= 14; - break; - case 155: /* Light Gray */ - cterm->attr |= 15; - break; - case 156: /* Purple */ - cterm->attr |= 4; - break; - case 158: /* Yellow */ - cterm->attr |= 7; - break; - case 159: /* Cyan */ - cterm->attr |= 3; - break; - } - TEXTATTR(cterm->attr); + case 27: /* ESC */ + cterm->attr=1; break; - - /* Movement */ - case 13: /* "\r\n" and disabled reverse. */ - case 141: - GOTOXY(1, WHEREY()); - /* Fall-through */ - case 17: - if(WHEREY()==cterm->height) - scrollup(cterm); - else - GOTOXY(WHEREX(), WHEREY()+1); + case 28: /* Up (TODO: Wraps??) */ + l=WHEREY()-1; + if(l<1) + l=cterm->height; + GOTOXY(WHEREX(),l); break; - case 147: + case 29: /* Down (TODO: Wraps??) */ + l=WHEREY()+1; + if(l>cterm->height) + l=1; + GOTOXY(WHEREX(),l); + break; + case 30: /* Left (TODO: Wraps around to same line?) */ + l=WHEREX()-1; + if(l<1) + l=cterm->width; + GOTOXY(l,WHEREY()); + break; + case 31: /* Right (TODO: Wraps around to same line?) */ + l=WHEREX()+1; + if(l>cterm->width) + l=1; + GOTOXY(l,WHEREY()); + break; + case 125: /* Clear Screen */ cterm_clearscreen(cterm, cterm->attr); - /* Fall through */ - case 19: - GOTOXY(1,1); break; - case 20: /* Delete (Wrapping backspace) */ + case 126: /* Backspace (TODO: Wraps around to previous line?) */ + /* DOES NOT delete char, merely erases */ k=WHEREY(); - l=WHEREX(); + l=WHEREX()-1; - if(l==1) { - if(k==1) + if(l<1) { + k--; + if(k<1) break; - GOTOXY((l=cterm->width), k-1); + l=cterm->width; } - else - GOTOXY(--l, k); - if(l<cterm->width) - MOVETEXT(cterm->x+l,cterm->y+k-1 - ,cterm->x+cterm->width-1,cterm->y+k-1 - ,cterm->x+l-1,cterm->y+k-1); - GOTOXY(cterm->width,k); - CLREOL(); + GOTOXY(l,k); + PUTCH(0); GOTOXY(l,k); break; - case 157: /* Cursor Left (wraps) */ - if(WHEREX()==1) { - if(WHEREY() > 1) - GOTOXY(cterm->width, WHEREY()-1); + /* We abuse the ESC buffer for tab stops */ + case 127: /* Tab (Wraps around to next line) */ + l=WHEREX(); + for(k=l+1; k<=cterm->width; k++) { + if(cterm->escbuf[k]) { + l=k; + break; + } } - else - GOTOXY(WHEREX()-1, WHEREY()); - break; - case 29: /* Cursor Right (wraps) */ - if(WHEREX()==cterm->width) { - if(WHEREY()==cterm->height) { + if(k>cterm->width) { + l=1; + k=WHEREY()+1; + if(k>cterm->height) { scrollup(cterm); - GOTOXY(1,WHEREY()); + k=cterm->height; } - else - GOTOXY(1,WHEREY()+1); + GOTOXY(l,k); } else - GOTOXY(WHEREX()+1,WHEREY()); - break; - case 145: /* Cursor Up (No scroll */ - if(WHEREY()>1) - GOTOXY(WHEREX(),WHEREY()-1); + GOTOXY(l,WHEREY()); break; - case 148: /* Insert TODO verify last column */ - /* CGTerm does nothing there... we */ - /* Erase under cursor. */ - l=WHEREX(); + case 155: /* Return */ k=WHEREY(); - if(l<=cterm->width) - MOVETEXT(cterm->x+l-1,cterm->y+k-1 - ,cterm->x+cterm->width-2,cterm->y+k-1 - ,cterm->x+l,cterm->y+k-1); - PUTCH(' '); - GOTOXY(l,k); + if(k==cterm->height) + scrollup(cterm); + else + k++; + GOTOXY(1,k); break; - - /* Font change... whee! */ - case 14: /* Lower case font */ - if(ti.currmode == C64_40X25) - SETFONT(33,FALSE,1); - else /* Assume C128 */ - SETFONT(35,FALSE,1); + case 156: /* Delete Line */ + dellines(cterm, 1); + GOTOXY(1,WHEREY()); break; - case 142: /* Upper case font */ - if(ti.currmode == C64_40X25) - SETFONT(32,FALSE,1); - else /* Assume C128 */ - SETFONT(34,FALSE,1); + case 157: /* Insert Line */ + l=WHEREX(); + k=WHEREY(); + if(k<cterm->height) + MOVETEXT(cterm->x,cterm->y+k-1 + ,cterm->x+cterm->width-1,cterm->y+cterm->height-2 + ,cterm->x,cterm->y+k); + GOTOXY(1,k); + CLREOL(); break; - case 18: /* Reverse mode on */ - cterm->c64reversemode = 1; + case 158: /* Clear Tab */ + cterm->escbuf[WHEREX()]=0; break; - case 146: /* Reverse mode off */ - cterm->c64reversemode = 0; + case 159: /* Set Tab */ + cterm->escbuf[WHEREX()]=1; break; - - /* Extras */ - case 7: /* Beep */ + case 253: /* Beep */ if(!cterm->quiet) { #ifdef __unix__ PUTCH(7); @@ -2831,39 +2624,96 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * #endif } break; - - /* Translate to screen codes */ + case 254: /* Delete Char */ + l=WHEREX(); + k=WHEREY(); + if(l<cterm->width) + MOVETEXT(cterm->x+l,cterm->y+k-1 + ,cterm->x+cterm->width-1,cterm->y+k-1 + ,cterm->x+l-1,cterm->y+k-1); + GOTOXY(cterm->width,k); + CLREOL(); + GOTOXY(l,k); + break; + case 255: /* Insert Char */ + l=WHEREX(); + k=WHEREY(); + if(l<cterm->width) + MOVETEXT(cterm->x+l-1,cterm->y+k-1 + ,cterm->x+cterm->width-2,cterm->y+k-1 + ,cterm->x+l,cterm->y+k-1); + PUTCH(0); + GOTOXY(l,k); + break; default: + /* Translate to screen codes */ k=buf[j]; - if(k<32) { - break; + if(k < 32) { + k +=64; + } + else if(k < 96) { + k -= 32; } - else if(k<64) { + else if(k < 128) { /* No translation */ } - else if(k<96) { - k -= 64; + else if(k < 160) { + k +=64; } - else if(k<128) { + else if(k < 224) { k -= 32; } - else if(k<160) { - break; + else if(k < 256) { + /* No translation */ } - else if(k<192) { - k -= 64; + ch[0] = k; + ch[1] = cterm->attr; + PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); + ch[1]=0; + if(WHEREX()==cterm->width) { + if(WHEREY()==cterm->height) { + scrollup(cterm); + GOTOXY(1,WHEREY()); + } + else + GOTOXY(1,WHEREY()+1); } - else if(k<224) { - k -= 128; + else + GOTOXY(WHEREX()+1,WHEREY()); + break; + } + } + else { + switch(buf[j]) { + case 155: /* Return */ + k=WHEREY(); + if(k==cterm->height) + scrollup(cterm); + else + k++; + GOTOXY(1,k); + break; + default: + /* Translate to screen codes */ + k=buf[j]; + if(k < 32) { + k +=64; } - else { - if(k==255) - k = 94; - else - k -= 128; + else if(k < 96) { + k -= 32; + } + else if(k < 128) { + /* No translation */ + } + else if(k < 160) { + k +=64; + } + else if(k < 224) { + k -= 32; + } + else if(k < 256) { + /* No translation */ } - if(cterm->c64reversemode) - k+=128; ch[0] = k; ch[1] = cterm->attr; PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); @@ -2871,7 +2721,7 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * if(WHEREX()==cterm->width) { if(WHEREY()==cterm->height) { scrollup(cterm); - GOTOXY(1,WHEREY()); + GOTOXY(1,cterm->height); } else GOTOXY(1,WHEREY()+1); @@ -2880,65 +2730,291 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void * GOTOXY(WHEREX()+1,WHEREY()); break; } + cterm->attr=7; } - else { /* ANSI-BBS */ - if(cterm->doorway_char) { - ctputs(cterm, prn); - ch[1]=cterm->attr; + } + else if(cterm->emulation == CTERM_EMULATION_PETASCII) { + switch(buf[j]) { + case 5: /* White */ + case 28: /* Red */ + case 30: /* Green */ + case 31: /* Blue */ + case 129: /* Orange */ + case 144: /* Black */ + case 149: /* Brown */ + case 150: /* Light Red */ + case 151: /* Dark Gray */ + case 152: /* Grey */ + case 153: /* Light Green */ + case 154: /* Light Blue */ + case 155: /* Light Gray */ + case 156: /* Purple */ + case 158: /* Yellow */ + case 159: /* Cyan */ + cterm->attr &= 0xf0; + switch(buf[j]) { + case 5: /* White */ + cterm->attr |= 1; + break; + case 28: /* Red */ + cterm->attr |= 2; + break; + case 30: /* Green */ + cterm->attr |= 5; + break; + case 31: /* Blue */ + cterm->attr |= 6; + break; + case 129: /* Orange */ + cterm->attr |= 8; + break; + case 144: /* Black */ + cterm->attr |= 0; + break; + case 149: /* Brown */ + cterm->attr |= 9; + break; + case 150: /* Light Red */ + cterm->attr |= 10; + break; + case 151: /* Dark Gray */ + cterm->attr |= 11; + break; + case 152: /* Grey */ + cterm->attr |= 12; + break; + case 153: /* Light Green */ + cterm->attr |= 13; + break; + case 154: /* Light Blue */ + cterm->attr |= 14; + break; + case 155: /* Light Gray */ + cterm->attr |= 15; + break; + case 156: /* Purple */ + cterm->attr |= 4; + break; + case 158: /* Yellow */ + cterm->attr |= 7; + break; + case 159: /* Cyan */ + cterm->attr |= 3; + break; + } + TEXTATTR(cterm->attr); + break; + + /* Movement */ + case 13: /* "\r\n" and disabled reverse. */ + case 141: + GOTOXY(1, WHEREY()); + /* Fall-through */ + case 17: + if(WHEREY()==cterm->height) + scrollup(cterm); + else + GOTOXY(WHEREX(), WHEREY()+1); + break; + case 147: + cterm_clearscreen(cterm, cterm->attr); + /* Fall through */ + case 19: + GOTOXY(1,1); + break; + case 20: /* Delete (Wrapping backspace) */ + k=WHEREY(); + l=WHEREX(); + + if(l==1) { + if(k==1) + break; + GOTOXY((l=cterm->width), k-1); + } + else + GOTOXY(--l, k); + if(l<cterm->width) + MOVETEXT(cterm->x+l,cterm->y+k-1 + ,cterm->x+cterm->width-1,cterm->y+k-1 + ,cterm->x+l-1,cterm->y+k-1); + GOTOXY(cterm->width,k); + CLREOL(); + GOTOXY(l,k); + break; + case 157: /* Cursor Left (wraps) */ + if(WHEREX()==1) { + if(WHEREY() > 1) + GOTOXY(cterm->width, WHEREY()-1); + } + else + GOTOXY(WHEREX()-1, WHEREY()); + break; + case 29: /* Cursor Right (wraps) */ + if(WHEREX()==cterm->width) { + if(WHEREY()==cterm->height) { + scrollup(cterm); + GOTOXY(1,WHEREY()); + } + else + GOTOXY(1,WHEREY()+1); + } + else + GOTOXY(WHEREX()+1,WHEREY()); + break; + case 145: /* Cursor Up (No scroll */ + if(WHEREY()>1) + GOTOXY(WHEREX(),WHEREY()-1); + break; + case 148: /* Insert TODO verify last column */ + /* CGTerm does nothing there... we */ + /* Erase under cursor. */ + l=WHEREX(); + k=WHEREY(); + if(l<=cterm->width) + MOVETEXT(cterm->x+l-1,cterm->y+k-1 + ,cterm->x+cterm->width-2,cterm->y+k-1 + ,cterm->x+l,cterm->y+k-1); + PUTCH(' '); + GOTOXY(l,k); + break; + + /* Font change... whee! */ + case 14: /* Lower case font */ + if(ti.currmode == C64_40X25) + SETFONT(33,FALSE,1); + else /* Assume C128 */ + SETFONT(35,FALSE,1); + break; + case 142: /* Upper case font */ + if(ti.currmode == C64_40X25) + SETFONT(32,FALSE,1); + else /* Assume C128 */ + SETFONT(34,FALSE,1); + break; + case 18: /* Reverse mode on */ + cterm->c64reversemode = 1; + break; + case 146: /* Reverse mode off */ + cterm->c64reversemode = 0; + break; + + /* Extras */ + case 7: /* Beep */ + if(!cterm->quiet) { + #ifdef __unix__ + PUTCH(7); + #else + MessageBeep(MB_OK); + #endif + } + break; + + /* Translate to screen codes */ + default: + k=buf[j]; + if(k<32) { + break; + } + else if(k<64) { + /* No translation */ + } + else if(k<96) { + k -= 64; + } + else if(k<128) { + k -= 32; + } + else if(k<160) { + break; + } + else if(k<192) { + k -= 64; + } + else if(k<224) { + k -= 128; + } + else { + if(k==255) + k = 94; + else + k -= 128; + } + if(cterm->c64reversemode) + k+=128; + ch[0] = k; + ch[1] = cterm->attr; PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); ch[1]=0; if(WHEREX()==cterm->width) { - if(WHEREY()==cterm->bottom_margin) { + if(WHEREY()==cterm->height) { scrollup(cterm); GOTOXY(1,WHEREY()); } - else if(WHEREY()==cterm->height) - GOTOXY(1,WHEREY()); else GOTOXY(1,WHEREY()+1); } else GOTOXY(WHEREX()+1,WHEREY()); - cterm->doorway_char=0; - } - else { - switch(buf[j]) { - case 0: - if(cterm->doorway_mode) - cterm->doorway_char=1; - break; - case 7: /* Beep */ - ctputs(cterm, prn); - prn[0]=0; - if(cterm->log==CTERM_LOG_ASCII && cterm->logfile != NULL) - fputs("\x07", cterm->logfile); - if(!cterm->quiet) { - #ifdef __unix__ - PUTCH(7); - #else - MessageBeep(MB_OK); - #endif - } - break; - case 12: /* ^L - Clear screen */ - ctputs(cterm, prn); - prn[0]=0; - if(cterm->log==CTERM_LOG_ASCII && cterm->logfile != NULL) - fputs("\x0c", cterm->logfile); - cterm_clearscreen(cterm, (char)cterm->attr); - if(cterm->origin_mode) - GOTOXY(1,cterm->top_margin); - else - GOTOXY(1,1); - break; - case 27: /* ESC */ - ctputs(cterm, prn); - prn[0]=0; - cterm->sequence=1; - break; - default: - strcat(prn,ch); + break; + } + } + else { /* ANSI-BBS */ + if(cterm->doorway_char) { + ctputs(cterm, prn); + ch[1]=cterm->attr; + PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); + ch[1]=0; + if(WHEREX()==cterm->width) { + if(WHEREY()==cterm->bottom_margin) { + scrollup(cterm); + GOTOXY(1,WHEREY()); } + else if(WHEREY()==cterm->height) + GOTOXY(1,WHEREY()); + else + GOTOXY(1,WHEREY()+1); + } + else + GOTOXY(WHEREX()+1,WHEREY()); + cterm->doorway_char=0; + } + else { + switch(buf[j]) { + case 0: + if(cterm->doorway_mode) + cterm->doorway_char=1; + break; + case 7: /* Beep */ + ctputs(cterm, prn); + prn[0]=0; + if(cterm->log==CTERM_LOG_ASCII && cterm->logfile != NULL) + fputs("\x07", cterm->logfile); + if(!cterm->quiet) { + #ifdef __unix__ + PUTCH(7); + #else + MessageBeep(MB_OK); + #endif + } + break; + case 12: /* ^L - Clear screen */ + ctputs(cterm, prn); + prn[0]=0; + if(cterm->log==CTERM_LOG_ASCII && cterm->logfile != NULL) + fputs("\x0c", cterm->logfile); + cterm_clearscreen(cterm, (char)cterm->attr); + if(cterm->origin_mode) + GOTOXY(1,cterm->top_margin); + else + GOTOXY(1,1); + break; + case 27: /* ESC */ + ctputs(cterm, prn); + prn[0]=0; + cterm->sequence=1; + break; + default: + strcat(prn,ch); } } } diff --git a/src/conio/cterm.txt b/src/conio/cterm.txt index 7df41f0317301f03ce65d0f39092a37f50b10a3d..149d66876ba67e84fe50c158adec03ce23b37bc7 100644 --- a/src/conio/cterm.txt +++ b/src/conio/cterm.txt @@ -65,15 +65,29 @@ ESC M (Disabled in current code) ESC _ Application Program String ESC P Device Control String -ESC ] Operating System Command ESC ^ Privacy Message Begins a string consisting of the characters 0x08 - 0x0d and 0x20-0x7e, terminated by a String Terminator (ST) The string is currently ignored. +ESC ] Operating System Command + Begins a string consisting of the characters 0x08 - 0x0d and + 0x20-0x7e, terminated by a String Terminator (ST) + Supported OSC values: + 4;(pX;pY)... + Specifies one or more palette redefinitions. + pX is the palette index, and pY is the colour definition + Color format: + rgb:R/G/B + Where R, G, and B are a sequence of one to four + hex digits representing the value of the + red, green, and blue channels respectively. + + SOURCE: xterm ESC X Start Of String As the above strings, but may contain any characters except a Start Of String sequence or a String Terminator sequence. + The string is currently ignored. ESC \ String Terminator