Commit cb54cb0b authored by rswindell's avatar rswindell
Browse files

Added sbbs_t::getstr_offset member variable, used with getstr(K_USEOFFSET)

for full-screen editor functionality.
Added support for CON_DOWNARROW, CON_LEFTARROW, and CON_BACKSPACE console
status bits, used in combination with getstr(K_LEFTEXIT)  for full-screen
editor functionality.
Insert mode (^V) still needs work.
parent 5309c010
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* * * *
* Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License * * modify it under the terms of the GNU General Public License *
...@@ -53,16 +53,18 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -53,16 +53,18 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
uchar ch; uchar ch;
uchar ins=0,atr; uchar ins=0,atr;
console&=~CON_UPARROW; console&=~(CON_UPARROW|CON_LEFTARROW|CON_BACKSPACE);
sys_status&=~SS_ABORT; sys_status&=~SS_ABORT;
if(mode&K_LINE && useron.misc&ANSI && !(mode&K_NOECHO)) { if(mode&K_LINE && useron.misc&ANSI && !(mode&K_NOECHO)) {
attr(cfg.color[clr_inputline]); attr(cfg.color[clr_inputline]);
for(i=0;i<maxlen;i++) for(i=0;i<maxlen;i++)
outchar(SP); outchar(SP);
bprintf("\x1b[%dD",maxlen); } bprintf("\x1b[%dD",maxlen);
}
if(wordwrap[0]) { if(wordwrap[0]) {
strcpy(str1,wordwrap); strcpy(str1,wordwrap);
wordwrap[0]=0; } wordwrap[0]=0;
}
else str1[0]=0; else str1[0]=0;
if(mode&K_EDIT) if(mode&K_EDIT)
strcat(str1,strout); strcat(str1,strout);
...@@ -75,10 +77,12 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -75,10 +77,12 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
if(mode&K_AUTODEL && str1[0]) { if(mode&K_AUTODEL && str1[0]) {
i=(cfg.color[clr_inputline]&0x77)<<4; i=(cfg.color[clr_inputline]&0x77)<<4;
i|=(cfg.color[clr_inputline]&0x77)>>4; i|=(cfg.color[clr_inputline]&0x77)>>4;
attr(i); } attr(i);
}
rputs(str1); rputs(str1);
if(mode&K_EDIT && !(mode&(K_LINE|K_AUTODEL)) && useron.misc&ANSI) if(mode&K_EDIT && !(mode&(K_LINE|K_AUTODEL)) && useron.misc&ANSI)
bputs("\x1b[K"); /* destroy to eol */ } bputs("\x1b[K"); /* destroy to eol */
}
i=l=strlen(str1); i=l=strlen(str1);
if(mode&K_AUTODEL && str1[0] && !(mode&K_NOECHO)) { if(mode&K_AUTODEL && str1[0] && !(mode&K_NOECHO)) {
...@@ -87,22 +91,42 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -87,22 +91,42 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
if(isprint(ch) || ch==DEL) { if(isprint(ch) || ch==DEL) {
for(i=0;i<l;i++) for(i=0;i<l;i++)
bputs("\b \b"); bputs("\b \b");
i=l=0; } i=l=0;
}
else { else {
for(i=0;i<l;i++) for(i=0;i<l;i++)
outchar(BS); outchar(BS);
rputs(str1); rputs(str1);
i=l; } i=l;
}
if(ch!=SP && ch!=TAB) if(ch!=SP && ch!=TAB)
ungetkey(ch); } ungetkey(ch);
}
while(!(sys_status&SS_ABORT) && (ch=getkey(mode|K_GETSTR))!=CR && online) { if(mode&K_USEOFFSET) {
if(!input_thread_running) i=getstr_offset;
if(i>l)
i=l;
if(l-i) {
if(useron.misc&ANSI)
bprintf("\x1b[%dD",l-i);
else
for(i=0;i<l-i;i++)
outchar(BS);
}
}
while(!(sys_status&SS_ABORT) && online && input_thread_running) {
if(console&(CON_UPARROW|CON_LEFTARROW|CON_BACKSPACE))
break;
if((ch=getkey(mode|K_GETSTR))==CR)
break; break;
if(sys_status&SS_ABORT) if(sys_status&SS_ABORT || !online)
break; break;
if(ch==LF && mode&K_MSG) /* Down-arrow same as CR */ if(ch==LF && mode&K_MSG) { /* Down-arrow same as CR */
console|=CON_DOWNARROW;
break; break;
}
if(ch==TAB && (mode&K_TAB || !(mode&K_WRAP))) /* TAB same as CR */ if(ch==TAB && (mode&K_TAB || !(mode&K_WRAP))) /* TAB same as CR */
break; break;
if(!i && mode&K_UPRLWR && (ch==SP || ch==TAB)) if(!i && mode&K_UPRLWR && (ch==SP || ch==TAB))
...@@ -111,7 +135,10 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -111,7 +135,10 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
if(strstr(str1,"")) { if(strstr(str1,"")) {
bputs("\r\n\r\nYou must set your terminal to NO PARITY, " bputs("\r\n\r\nYou must set your terminal to NO PARITY, "
"8 DATA BITS, and 1 STOP BIT (N-8-1).\7\r\n"); "8 DATA BITS, and 1 STOP BIT (N-8-1).\7\r\n");
return(0); } } return(0);
}
}
getstr_offset=i;
switch(ch) { switch(ch) {
case CTRL_A: /* Ctrl-A for ANSI */ case CTRL_A: /* Ctrl-A for ANSI */
if(!(mode&K_MSG) || useron.rest&FLAG('A') || i>maxlen-3) if(!(mode&K_MSG) || useron.rest&FLAG('A') || i>maxlen-3)
...@@ -124,43 +151,52 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -124,43 +151,52 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
rprintf("%.*s",l-i,str1+i); rprintf("%.*s",l-i,str1+i);
rprintf("\x1b[%dD",l-i); rprintf("\x1b[%dD",l-i);
if(i==maxlen-1) if(i==maxlen-1)
ins=0; } ins=0;
}
outchar(str1[i++]=1); outchar(str1[i++]=1);
break; break;
case CTRL_B: /* Ctrl-B Beginning of Line */ case CTRL_B: /* Ctrl-B Beginning of Line */
if(useron.misc&ANSI && i && !(mode&K_NOECHO)) { if(useron.misc&ANSI && i && !(mode&K_NOECHO)) {
bprintf("\x1b[%dD",i); bprintf("\x1b[%dD",i);
i=0; } i=0;
}
break; break;
case CTRL_D: /* Ctrl-D Delete word right */ case CTRL_D: /* Ctrl-D Delete word right */
if(i<l) { if(i<l) {
x=i; x=i;
while(x<l && str1[x]!=SP) { while(x<l && str1[x]!=SP) {
outchar(SP); outchar(SP);
x++; } x++;
}
while(x<l && str1[x]==SP) { while(x<l && str1[x]==SP) {
outchar(SP); outchar(SP);
x++; } x++;
}
bprintf("\x1b[%dD",x-i); /* move cursor back */ bprintf("\x1b[%dD",x-i); /* move cursor back */
z=i; z=i;
while(z<l-(x-i)) { /* move chars in string */ while(z<l-(x-i)) { /* move chars in string */
outchar(str1[z]=str1[z+(x-i)]); outchar(str1[z]=str1[z+(x-i)]);
z++; } z++;
}
while(z<l) { /* write over extra chars */ while(z<l) { /* write over extra chars */
outchar(SP); outchar(SP);
z++; } z++;
}
bprintf("\x1b[%dD",z-i); bprintf("\x1b[%dD",z-i);
l-=x-i; } /* l=new length */ l-=x-i; /* l=new length */
}
break; break;
case CTRL_E: /* Ctrl-E End of line */ case CTRL_E: /* Ctrl-E End of line */
if(useron.misc&ANSI && i<l) { if(useron.misc&ANSI && i<l) {
bprintf("\x1b[%dC",l-i); /* move cursor to eol */ bprintf("\x1b[%dC",l-i); /* move cursor to eol */
i=l; } i=l;
}
break; break;
case CTRL_F: /* Ctrl-F move cursor forewards */ case CTRL_F: /* Ctrl-F move cursor forewards */
if(i<l && (useron.misc&ANSI)) { if(i<l && (useron.misc&ANSI)) {
bputs("\x1b[C"); /* move cursor right one */ bputs("\x1b[C"); /* move cursor right one */
i++; } i++;
}
break; break;
case CTRL_G: /* Bell */ case CTRL_G: /* Bell */
if(!(mode&K_MSG)) if(!(mode&K_MSG))
...@@ -173,7 +209,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -173,7 +209,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
if(l+5<maxlen) if(l+5<maxlen)
l+=6; l+=6;
if(i==maxlen-1) if(i==maxlen-1)
ins=0; } ins=0;
}
str1[i++]='('; str1[i++]='(';
str1[i++]='b'; str1[i++]='b';
str1[i++]='e'; str1[i++]='e';
...@@ -181,25 +218,32 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -181,25 +218,32 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
str1[i++]='p'; str1[i++]='p';
str1[i++]=')'; str1[i++]=')';
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
bputs("(beep)"); } bputs("(beep)");
}
if(ins) if(ins)
redrwstr(str1,i,l,0); redrwstr(str1,i,l,0);
break; } break;
if(ins) { }
if(ins) {
if(l<maxlen) if(l<maxlen)
l++; l++;
for(x=l;x>i;x--) for(x=l;x>i;x--)
str1[x]=str1[x-1]; str1[x]=str1[x-1];
if(i==maxlen-1) if(i==maxlen-1)
ins=0; } ins=0;
if(i<maxlen) { }
if(i<maxlen) {
str1[i++]=BEL; str1[i++]=BEL;
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
outchar(BEL); } outchar(BEL);
break; }
break;
case CTRL_H: /* Ctrl-H/Backspace */ case CTRL_H: /* Ctrl-H/Backspace */
if(!i) if(i==0) {
if(mode&K_LEFTEXIT)
console|=CON_BACKSPACE;
break; break;
}
i--; i--;
l--; l--;
if(i!=l) { /* Deleting char in middle of line */ if(i!=l) { /* Deleting char in middle of line */
...@@ -207,9 +251,11 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -207,9 +251,11 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
z=i; z=i;
while(z<l) { /* move the characters in the line */ while(z<l) { /* move the characters in the line */
outchar(str1[z]=str1[z+1]); outchar(str1[z]=str1[z+1]);
z++; } z++;
}
outchar(SP); /* write over the last char */ outchar(SP); /* write over the last char */
bprintf("\x1b[%dD",(l-i)+1); } bprintf("\x1b[%dD",(l-i)+1);
}
else if(!(mode&K_NOECHO)) else if(!(mode&K_NOECHO))
bputs("\b \b"); bputs("\b \b");
break; break;
...@@ -221,10 +267,12 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -221,10 +267,12 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
for(x=l;x>i;x--) for(x=l;x>i;x--)
str1[x]=str1[x-1]; str1[x]=str1[x-1];
if(i==maxlen-1) if(i==maxlen-1)
ins=0; } ins=0;
}
str1[i++]=SP; str1[i++]=SP;
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
outchar(SP); } outchar(SP);
}
while(i<maxlen && i%EDIT_TABSIZE) { while(i<maxlen && i%EDIT_TABSIZE) {
if(ins) { if(ins) {
if(l<maxlen) if(l<maxlen)
...@@ -232,10 +280,12 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -232,10 +280,12 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
for(x=l;x>i;x--) for(x=l;x>i;x--)
str1[x]=str1[x-1]; str1[x]=str1[x-1];
if(i==maxlen-1) if(i==maxlen-1)
ins=0; } ins=0;
}
str1[i++]=SP; str1[i++]=SP;
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
outchar(SP); } outchar(SP);
}
if(ins && !(mode&K_NOECHO)) if(ins && !(mode&K_NOECHO))
redrwstr(str1,i,l,0); redrwstr(str1,i,l,0);
break; break;
...@@ -259,7 +309,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -259,7 +309,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
bputs("\b"); bputs("\b");
bputs(strout); bputs(strout);
if(mode&K_LINE) if(mode&K_LINE)
attr(LIGHTGRAY); } attr(LIGHTGRAY);
}
CRLF; CRLF;
return(l); return(l);
...@@ -270,7 +321,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -270,7 +321,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
i++; i++;
while(str1[i]==SP && i<l) while(str1[i]==SP && i<l)
i++; i++;
bprintf("\x1b[%dC",i-x); } bprintf("\x1b[%dC",i-x);
}
break; break;
case CTRL_R: /* Ctrl-R Redraw Line */ case CTRL_R: /* Ctrl-R Redraw Line */
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
...@@ -281,7 +333,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -281,7 +333,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
break; break;
if(ins) { if(ins) {
ins=0; ins=0;
redrwstr(str1,i,l,0); } redrwstr(str1,i,l,0);
}
else if(i<l) { else if(i<l) {
ins=1; ins=1;
bprintf("\x1b[s\x1b[79C"); /* save pos */ bprintf("\x1b[s\x1b[79C"); /* save pos */
...@@ -289,37 +342,45 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -289,37 +342,45 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
attr(z|BLINK|HIGH); attr(z|BLINK|HIGH);
outchar(''); outchar('');
attr(z); attr(z);
bputs("\x1b[u"); } /* restore pos */ bputs("\x1b[u"); /* restore pos */
}
break; break;
case CTRL_W: /* Ctrl-W Delete word left */ case CTRL_W: /* Ctrl-W Delete word left */
if(i<l) { if(i<l) {
x=i; /* x=original offset */ x=i; /* x=original offset */
while(i && str1[i-1]==SP) { while(i && str1[i-1]==SP) {
outchar(BS); outchar(BS);
i--; } i--;
}
while(i && str1[i-1]!=SP) { while(i && str1[i-1]!=SP) {
outchar(BS); outchar(BS);
i--; } i--;
}
z=i; /* i=z=new offset */ z=i; /* i=z=new offset */
while(z<l-(x-i)) { /* move chars in string */ while(z<l-(x-i)) { /* move chars in string */
outchar(str1[z]=str1[z+(x-i)]); outchar(str1[z]=str1[z+(x-i)]);
z++; } z++;
}
while(z<l) { /* write over extra chars */ while(z<l) { /* write over extra chars */
outchar(SP); outchar(SP);
z++; } z++;
}
bprintf("\x1b[%dD",z-i); /* back to new x corridnant */ bprintf("\x1b[%dD",z-i); /* back to new x corridnant */
l-=x-i; } /* l=new length */ l-=x-i; /* l=new length */
else { } else {
while(i && str1[i-1]==SP) { while(i && str1[i-1]==SP) {
i--; i--;
l--; l--;
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
bputs("\b \b"); } bputs("\b \b");
}
while(i && str1[i-1]!=SP) { while(i && str1[i-1]!=SP) {
i--; i--;
l--; l--;
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
bputs("\b \b"); } } bputs("\b \b");
}
}
break; break;
case CTRL_X: /* Ctrl-X Delete entire line */ case CTRL_X: /* Ctrl-X Delete entire line */
if(mode&K_NOECHO) if(mode&K_NOECHO)
...@@ -327,16 +388,20 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -327,16 +388,20 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
else { else {
while(i<l) { while(i<l) {
outchar(SP); outchar(SP);
i++; } i++;
}
while(l) { while(l) {
l--; l--;
bputs("\b \b"); } } bputs("\b \b");
}
}
i=0; i=0;
break; break;
case CTRL_Y: /* Ctrl-Y Delete to end of line */ case CTRL_Y: /* Ctrl-Y Delete to end of line */
if(useron.misc&ANSI && !(mode&K_NOECHO)) { if(useron.misc&ANSI && !(mode&K_NOECHO)) {
bputs("\x1b[K"); bputs("\x1b[K");
l=i; } l=i;
}
break; break;
case 28: /* Ctrl-\ Previous word */ case 28: /* Ctrl-\ Previous word */
if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) { if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) {
...@@ -345,16 +410,24 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -345,16 +410,24 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
i--; i--;
while(str1[i-1]!=SP && i) while(str1[i-1]!=SP && i)
i--; i--;
bprintf("\x1b[%dD",x-i); } bprintf("\x1b[%dD",x-i);
}
break; break;
case 29: /* Ctrl-]/Left Arrow Reverse Cursor Movement */ case 29: /* Ctrl-]/Left Arrow Reverse Cursor Movement */
if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) { if(i==0) {
if(mode&K_LEFTEXIT)
console|=CON_LEFTARROW;
break;
}
if((useron.misc&ANSI) && !(mode&K_NOECHO)) {
bputs("\x1b[D"); /* move cursor left one */ bputs("\x1b[D"); /* move cursor left one */
i--; } i--;
}
break; break;
case 30: /* Ctrl-^/Up Arrow */ case 30: /* Ctrl-^/Up Arrow */
if(!(mode&K_EDIT)) if(!(mode&K_EDIT))
break; break;
#if 0
if(i>l) if(i>l)
l=i; l=i;
str1[l]=0; str1[l]=0;
...@@ -365,6 +438,10 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -365,6 +438,10 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
attr(LIGHTGRAY); attr(LIGHTGRAY);
console|=CON_UPARROW; console|=CON_UPARROW;
return(l); return(l);
#else
console|=CON_UPARROW;
break;
#endif
case DEL: /* Ctrl-BkSpc (DEL) Delete current char */ case DEL: /* Ctrl-BkSpc (DEL) Delete current char */
if(i==l) { /* Backspace if end of line */ if(i==l) { /* Backspace if end of line */
if(i) { if(i) {
...@@ -379,7 +456,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -379,7 +456,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
z=i; z=i;
while(z<l) { /* move the characters in the line */ while(z<l) { /* move the characters in the line */
outchar(str1[z]=str1[z+1]); outchar(str1[z]=str1[z+1]);
z++; } z++;
}
outchar(SP); /* write over the last char */ outchar(SP); /* write over the last char */
bprintf("\x1b[%dD",(l-i)+1); bprintf("\x1b[%dD",(l-i)+1);
break; break;
...@@ -392,7 +470,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -392,7 +470,8 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
redrwstr(strout,i,l,K_MSG); redrwstr(strout,i,l,K_MSG);
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
CRLF; CRLF;
return(i); } return(i);
}
x=i-1; x=i-1;
z=1; z=1;
wordwrap[0]=ch; wordwrap[0]=ch;
...@@ -405,12 +484,14 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode) ...@@ -405,12 +484,14 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
redrwstr(strout,i,l,K_MSG); redrwstr(strout,i,l,K_MSG);
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
CRLF; CRLF;
return(i); } return(i);
}
wordwrap[z]=0; wordwrap[z]=0;
if(!(mode&K_NOECHO)) if(!(mode&K_NOECHO))
while(z--) { while(z--) {
bputs("\b \b"); bputs("\b \b");
i--; } i--;
}
strrev(wordwrap); strrev(wordwrap);
str1[x]=0;