home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d512 / csh.lha / Csh / Csh515s.lzh / rawcon.c < prev    next >
C/C++ Source or Header  |  1991-06-23  |  19KB  |  857 lines

  1. /*
  2.  * rawcon.c
  3.  *
  4.  * Shell 2.07M  17-Jun-87
  5.  * console handling, command line editing support for Shell
  6.  * using new console packets from 1.2.
  7.  * Written by Steve Drew. (c) 14-Oct-86.
  8.  * 16-Dec-86 Slight mods to rawgets() for Disktrashing.
  9.  *
  10.  * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  11.  * Version 5.00L by Urban Mueller 17-Feb-91
  12.  *
  13.  */
  14.  
  15. #include "shell.h"
  16.  
  17. static int myget( void );
  18. static void myunget(int c);
  19. static void setrawcon( long flag, int ievent );
  20. static int get_seq( long *param );
  21. static int bkspcword( int i, int max, int cnt );
  22.  
  23.  
  24. #if RAW_CONSOLE
  25.  
  26. static char *tyahdptr, *lasttya;
  27. static int tabctr, qcdctr, histctr, occurctr, unget, oldmax;
  28.  
  29. #define SETRAW setrawcon(-1L,1);
  30. #define SETCON setrawcon( 0L,1);
  31.  
  32. int w_width;
  33. extern char *MenuCommand[MAXMENUS][MAXITEMS];
  34.  
  35. #define CTRL  -64
  36. #define SHIFT 512
  37. #define ESC   1024
  38.  
  39. #define CUP   256
  40. #define CDN   257
  41. #define CRT   258
  42. #define CLT   259
  43. #define TAB   9
  44.  
  45. static int Curmap;
  46. static USHORT *Keymap[8];
  47. static USHORT DefKeymap0[]={
  48.        CLT,  0, /* CursLt = Move.Left  */
  49.        CRT,  1, /* CursRt = Move.Right */
  50.  SHIFT+CLT,  2, /* SCursLt= Move.WordL */
  51.  SHIFT+CRT,  3, /* SCursRt= Move.WordR */
  52.    ESC+CLT,  4, /* ESC-CLt= Move.SOL   */
  53.    ESC+CRT,  5, /* ESC-CRt= Move.EOL   */
  54.   CTRL+'A',  4, /* ^A     = Move.SOL   */
  55.   CTRL+'E',  5, /* ^E     = Move.EOL   */
  56.   CTRL+'Z',  4, /* ^Z     = Move.SOL   */
  57.          8, 10, /* BackSp = Del.BackSp */
  58.        127, 11, /* Delete = Del.Delete */
  59.    ESC+  8, 12, /* ESC-BkS= Del.WordL  */
  60.    ESC+127, 13, /* ESC-Del= Del.WordR  */
  61.   CTRL+'W', 12, /* ^W     = Del.WordL  */
  62.   CTRL+'B', 14, /* ^B     = Del.SOL    */
  63.   CTRL+'K', 15, /* ^K     = Del.EOL    */
  64.    ESC+'x',513, /* ESC-x  = Setmap 1   */
  65.    ESC+'d', 16, /* ESC-d  = Del.Line   */
  66.   CTRL+'X', 16, /* ^X     = Del.Line   */
  67.        CUP, 20, /* CursUp = Hist.Back  */
  68.        CDN, 21, /* CursDn = Hist.Forw  */
  69.    ESC+CUP, 22, /* ECursUp= Hist.Beg   */
  70.    ESC+CDN, 23, /* ECursDn= Hist.End   */
  71.  SHIFT+CUP, 24, /* SCursUp= Hist.Compl */
  72.    ESC+CUP, 24, /* ESC-!  = Hist.Compl */
  73.    ESC+ 13, 25, /* ESC-Ret= Hist.Exec  */
  74.   CTRL+'T', 26, /* ^T     = Hist.Tail  */
  75.  SHIFT+CDN, 27, /* SCursDn= Hist.Clr   */
  76.   CTRL+'P', 28, /* ^P     = Hist.DupWrd*/
  77.        TAB, 30, /* Tab    = Comp.Norm  */
  78.  SHIFT+TAB, 31, /* STab   = Comp.Part  */
  79.    ESC+TAB, 32, /* ESC-TAB= Comp.All   */
  80.    ESC+'*', 32, /* ESC-*  = Comp.All   */
  81.    ESC+'c', 33, /* ESC-c  = Comp.CD    */
  82.    ESC+'~', 34, /* ESC-~  = Comp.LastCD*/
  83.   CTRL+'D', 35, /* CTRL-D = Comp.Dir   */
  84.    ESC+'=', 35, /* ESC-=  = Comp.Dir   */
  85.    ESC+'i', 40, /* ESC-i  = Spec.Insert*/
  86.   CTRL+'L', 43, /* ^L     = Spec.Refr  */
  87.         10, 44, /* Enter  = Spec.Accept*/
  88.         13, 44, /* ^Enter = Spec.Accept*/
  89.   CTRL+'N', 45, /* ^N     = Spec.Next  */
  90.   CTRL+'O', 48, /* ^O     = Spec.EchoO */
  91.  CTRL+'\\', 46, /* ^\     = Spec.EOF   */
  92.        260, 42, /* Help   = Misc.Help  */
  93.        271, 51, /* Menu   = Menu       */
  94.   CTRL+'U', 52, /* Undo   = Spec.Undo  */
  95.   CTRL+'R', 53, /* Repeat = Spec.Repeat*/
  96.          0,  0
  97. };
  98.  
  99. static USHORT DefKeymap1[]={
  100.          8, 14,
  101.        127, 15
  102. };
  103.  
  104. static char *Line, *Prompt;
  105. static int Pl;
  106. static char LastDir[128];
  107. static char Undo[256];
  108.  
  109. void
  110. initmap(void)
  111. {
  112.     if( !Keymap[0] )
  113.         Keymap[0]=DefKeymap0, Keymap[1]=DefKeymap1;
  114. }
  115.  
  116. char *
  117. rawgets( char line[], char prompt[] )
  118. {
  119.     static int inslen, lastrecall=-1;
  120.     static int lastfn, lastkey;
  121.  
  122.     int    n, pl, max, i, c, key, fn, cnt;
  123.     USHORT *p;
  124.     char   *s, *ps, typeahd[256], *src, tmp;
  125.     int    savn, insert=1, recall, undo_i, undo_max;
  126.     struct HIST *hist;
  127.     char   **eav=NULL, *ret, fake;
  128.     int    eac, eactr=0;
  129.     long   param[10], *par;
  130.  
  131.     typeahd[0]=0;
  132.     tyahdptr=lasttya=typeahd;
  133.  
  134.     newwidth();
  135.  
  136.     if ( o_noraw || !isconsole(Input()) ) {
  137.         if( isconsole(Input())) {
  138.             printf("%s",prompt);
  139.             fflush(stdout);
  140.         }
  141.         return(gets(line));
  142.     }
  143.  
  144.     if (WaitForChar((long)Input(), 100L) ||   /* don't switch to 1L ...*/
  145.             CHARSWAIT(stdin)) {               /* else causes read err's*/
  146.         gets(line);
  147.         return(line);
  148.     }
  149.  
  150.     SETRAW;
  151. begin:
  152.     printf("\015%s\033[6n",prompt);
  153.     fake= savn = pl = n = 0;
  154.     tyahdptr = typeahd;
  155.  
  156.     while( (typeahd[n]=getchar()) != 'R') {
  157.         if (typeahd[n] == 155) savn = n;
  158.         if (typeahd[n] == 27 && getchar()=='[')
  159.             typeahd[n] =155, savn=n;
  160.         n++;
  161.     }
  162.     /* typeahd now contains possible type a head chars
  163.        followed by <CSI> cursor position report. */
  164.  
  165.     if (typeahd[n-2] != ';') pl = (typeahd[n-2] -'0') * 10;
  166.     pl += typeahd[n-1] - 49;
  167.     ps = line + pl;
  168.     typeahd[savn ] = 0;
  169.     line[max=i=pl] = 0;
  170.     undo_i=undo_max=pl;
  171.  
  172.     Line=line; Prompt=prompt; Pl=pl;
  173.  
  174.     if (s = get_var (LEVEL_SET, "_insert")) insert = atoi(s) ? 1 : 0;
  175.  
  176.     if( (recall=lastrecall)>=0 ) {
  177.         lastrecall=-1;
  178.         goto recallh;
  179.     }
  180.  
  181.     while( (c=myget()) != -1) {
  182.         int esc=0;
  183.         key=-1;
  184.         if( c==27 ) {
  185.             esc=ESC;
  186.             if((c=myget())=='[')
  187.                 c=155,esc=0;
  188.         }
  189.         switch(c) {
  190.         case 155:
  191.             switch(c=myget()) {
  192.             case 'A': key=256;       break; /* CursUp */
  193.             case 'B': key=257;       break; /* CursDn */
  194.             case 'C': key=258;       break; /* CursRt */
  195.             case 'D': key=259;       break; /* CursLt */
  196.             case 'T': key=256+SHIFT; break; /* SCursUp */
  197.             case 'S': key=257+SHIFT; break; /* SCursDn */
  198.             case ' ':
  199.                 switch( myget() ) {
  200.                 case '@': key=258+SHIFT; break; /* SCursRt */
  201.                 case 'A': key=259+SHIFT; break; /* SCursLt */
  202.                 }
  203.                 break;
  204.             case 'Z': key= 9+SHIFT;       break; /* STab    */
  205.             case '?': key= 260; myget();  break; /* Help    */
  206.             default :
  207.                 myunget(c);
  208.                 par=param;
  209.                 do {
  210.                     for( *par=0; (c=myget())>='0' && c<='9';  )
  211.                         *par=10* *par + c-'0';
  212.                     par++;
  213.                 } while( c==';' );
  214.                 if( c=='~' ) {
  215.                     key=param[0]+261;
  216.                     if( key>270 ) key+=SHIFT-10;
  217.                 }
  218.                 if( c=='|' ) key=271;
  219.             } break;
  220.         default: key=c; break;
  221.         }
  222.         key+=esc;
  223.  
  224.         for( fn=-1, p=Keymap[Curmap]; *p; p+=2 )
  225.             if( *p==key )
  226.                 { fn=p[1]; break; }
  227.         if( fn==-1 && key>=261 && key<=270 || key>=261+SHIFT && key<=270+SHIFT )
  228.             fn=50;
  229.  
  230.         if( fn!=52 && !*lasttya) {
  231.             memcpy( Undo+pl, line+pl, max-pl );
  232.             undo_i=i; undo_max=max;
  233.         }
  234.  
  235.         switch( fn/512 ) {
  236.         case 1:
  237.             fn&=511;
  238.             if( fn<8 && Keymap[fn] ) Curmap=fn;
  239.             fn=-2;
  240.             break;
  241.         case 2:
  242.             key=fn&511, fn=-1;
  243.             break;
  244.         }
  245.  
  246.         if( fn!=-2 )
  247.             Curmap=0;
  248.  
  249.         if( fn!=53 && !*lasttya )
  250.             lastfn=fn, lastkey=key;
  251.  
  252. dofn:
  253.         switch( fn ) {
  254.         case -2:
  255.             break;
  256.  
  257.         case 0:                                 /* cursor left  */
  258.             if (i > pl) 
  259.                 i--, printf("\033[D");
  260.             break;
  261.         case 1:                                 /* cursor right */
  262.             if (i < max)
  263.                 i++, printf("\033[C");
  264.             break;
  265.         case 2:                                 /* word left    */
  266.             for (cnt=0; i>pl && line[i-1] == ' '; cnt++,i--); 
  267.             for (     ; i>pl && line[i-1] != ' '; cnt++,i--);
  268.             if( cnt ) printf("\033[%dD",cnt);
  269.             break;
  270.         case 3:                                 /* word right   */
  271.             for( cnt=0; i<max && line[i] != ' '; i++,cnt++) ;
  272.             for(      ; i<max && line[i] == ' '; i++,cnt++) ;
  273.             if( cnt ) printf("\033[%dC",cnt);
  274.             break;
  275.         case 4:                                 /* beg of line  */
  276.             if (i>pl) printf("\033[%dD",i-pl);
  277.             i = pl;
  278.             break;
  279.         case 5:                                 /* end of line  */
  280.             if (i!=max) printf("\033[%dC",max - i);
  281.             i = max;
  282.             break;
  283.  
  284.         case 10:                                /* backspace    */
  285.             if (i > pl) {
  286.                 i--;
  287.                 printf("\010");
  288.             } else break;
  289.         case 11:                                /* delete       */
  290.             if (i < max) {
  291.                 int j,t,l = 0;
  292.                 memmove(&line[i],&line[i+1],max-i);
  293.                 --max;
  294.                 printf("\033[P");
  295.                 j = w_width - i % w_width - 1;  /* amount to end */
  296.                 t = max/w_width - i/w_width;    /* no of lines   */
  297.                 for(n = 0; n < t; n++) {
  298.                     l += j;                     /* # of char moved*/
  299.                     if (j) printf("\033[%dC",j);/* goto eol       */
  300.                     printf("%c\033[P",line[w_width*(i/w_width+n+1)-1]);
  301.                     j = w_width-1;
  302.                 }
  303.                 if (t)
  304.                     printf("\033[%dD",l+t);     /* get back       */
  305.             }
  306.             break;
  307.         case 12:                                /* bkspc word     */
  308.             cnt= bkspcword(i,max,-1);
  309.             max-=cnt; i-=cnt;
  310.             break;
  311.         case 13:
  312.             for( cnt=0; i<max && line[i]!=' '; i++,cnt++ ) ;
  313.             for(      ; i<max && line[i]==' '; i++,cnt++ ) ;
  314.             if ( cnt ) printf("\033[%dC",cnt);
  315.             cnt=bkspcword(i,max,cnt);
  316.             i-=cnt; max-=cnt;
  317.             break;
  318.         case 14:
  319.             cnt=bkspcword(i,max,i-pl);
  320.             i-=cnt; max-=cnt;
  321.             break;
  322.         case 16:                                /* delete line    */
  323.             if (i>pl) printf("\033[%dD",i-pl);
  324.             i = pl;
  325.         case 15:                                /* delete to EOL  */
  326.             printf("\033[J");
  327.             max = i;
  328.             line[i] = '\0';
  329.             break;
  330.  
  331.  
  332.         case 20:                                /* history up   */
  333.             ++recall;
  334.         case 21:                                /* history down */
  335. recallh:
  336.             line[pl] = '\0';
  337.             if (recall >= 0 || fn==20) {
  338.                 if ( fn==21 ) --recall;
  339.                 n=recall;
  340.                 if (recall >= 0) {
  341.                     for(hist = H_head; hist && n--;
  342.                     hist = hist->next);
  343.                     if (hist) strcpy(&line[pl],hist->line);
  344.                     else recall = H_len;
  345.                 }
  346.             }
  347.             if (i != pl)
  348.                 printf("\033[%dD",i-pl);
  349.             printf("\033[J%s",ps);
  350.             i = max = strlen(ps) + pl;
  351.             break;
  352.         case 22:                                /* beg of hist */
  353.             recall = H_len-1;
  354.         case 23:                                /* end of hist */
  355.             line[pl] = '\0';
  356.             if (fn == 23) {
  357.                 recall = 0;
  358.                 if (H_head) strcpy(&line[pl], H_head->line);
  359.             } else if (H_tail)
  360.                 strcpy(&line[pl], H_tail->line);
  361.             printf("\015\033[J%s%s", prompt, ps);
  362.             i = max = strlen(ps) + pl;
  363.             break;
  364.         case 24:                                /* complete hist */
  365.             if( histctr )
  366.                 occurctr=0, oldmax=max;
  367.             occurctr++, histctr=1, max=oldmax;
  368.             line[max]=0;
  369.             if( s=get_history(&line[pl-1],2,occurctr )) {
  370.                 if (i>pl) printf("\033[%dD\033[J",i-pl);
  371.                 line[i=max=pl]=0;
  372.                 strncpy(typeahd,s,256);
  373.                 tyahdptr=typeahd;
  374.             }
  375.             break;
  376.         case 25:                                /* exec hist  */
  377.             lastrecall= recall;
  378.             goto done;
  379.         case 26:                                /* tail of prev */
  380.             if( H_head && (s=H_head->line) && (s=index(s,' ')) )
  381.                 tyahdptr=s;
  382.             break;
  383.         case 27:                                /* botton   */
  384.             recall=-1;
  385.             goto recallh;
  386.         case 28:                                /* duplicate word */
  387.             for(s=line+i; s>ps && *(s-1)==' '; --s ) ;
  388.             tmp=*s; *s=0;
  389.             if( !(src=rindex(ps,' '))) src="";
  390.             strcpy(tyahdptr=typeahd,src);
  391.             *s=tmp;
  392.             break;
  393.  
  394.         case 32:                                /* complete all     */
  395.         case 35: tabctr=1;                      /* show files       */
  396.         case 30:                                /* complete         */
  397.         case 31:                                /* complete partial */
  398.         case 33: {                              /* do quick cd      */
  399.             static int lastcompl;
  400.             int j, k, n, e, cnt, len, radlen;
  401.             char *name, q, abbrev;
  402.  
  403.             abbrev= fn==31;
  404. complete:
  405.             tyahdptr="";
  406.             if( tabctr!=0 ) {
  407.                 char *dest=typeahd, *lcd;
  408.  
  409.                 lastcompl=fn;
  410.                 for( cnt=0; i<max && line[i]!=' '; ++i, ++cnt ) ;
  411.                 if(cnt) printf("\033[%dC",cnt);
  412.                 for( e=i, j=i-1, cnt=0; j>=pl && line[j]!=' ' && line[j]!='<' &&
  413.                                  line[j]!='>' && line[j]!=';' ; --j ) cnt++;
  414.                 ++j;
  415.  
  416.                 if( line[j]=='~' && (lcd=get_var(LEVEL_SET,v_lcd))) {
  417.                     strcpy(dest,lcd);
  418.                     dest+=strlen(dest);
  419.                     j++;
  420.                 }
  421.                 memcpy(dest,&line[j],e-j);
  422.                 dest+=e-j;
  423.                 if( fn!=33 )
  424.                     *dest++='*';
  425.                 *dest=0;
  426.                 if( eav ) free_expand( eav ), eav=NULL;
  427.                 breakreset();
  428.                 tabctr=1;
  429.                 if( fn==33 ) {
  430.                     strncpy(LastDir,typeahd,128);
  431.                     if( !quick_cd( name=typeahd+128, LastDir, 0))
  432.                         { putchar(7); break; }
  433.                 } else {
  434.                     eav =expand(typeahd,&eac);
  435.                     if( eac==0 ) { putchar(7); break; }
  436.                     QuickSort(eav, eac);
  437.                     if( fn==30 )
  438.                         name=eav[ eactr=0 ];
  439.                     else
  440.                         name=compile_av(eav,0,eac,' ',1), tabctr=0;
  441.                 } 
  442.                 inslen=cnt;
  443.             } else {
  444.                 abbrev=0, tabctr=1;
  445.                 if( lastcompl==33 ) {
  446.                     quick_cd( name=typeahd+128, LastDir, 1);
  447.                 } else {
  448.                     if( !eac ) break;
  449.                     name=eav[eactr=++eactr % eac];
  450.                 }
  451.             }
  452.             if( fn==35 ) {
  453.                 if (i!=max) printf("\033[%dC",max - i);
  454.                 putchar('\n');
  455.                 for( j=0; j<eac; j++ )
  456.                     printf("%s ",BaseName(eav[j]));
  457.                 putchar('\n');
  458.                 goto refresh;
  459.             }
  460.             len=bkspcword(i,max,inslen);
  461.             i-=len; max-=len;
  462.             if( abbrev && eac>1) {
  463.                 strcpy( typeahd, eav[0] );
  464.                 radlen= 9999;
  465.                 for( k=0; k<eac; k++ ) {
  466.                     if ( (n=strlen(eav[k])) < radlen ) radlen=n;
  467.                     for( n=0; n<radlen&& tolower(eav[0][n])==tolower(eav[k][n]);
  468.                          n++ ) ;
  469.                     if ( n<radlen ) radlen=n;
  470.                 }
  471.                 typeahd[radlen]=0;
  472.                 eactr--;
  473.             } else {
  474.                 if( lastcompl==32 ) {
  475.                     strncpy( typeahd,name,250 );
  476.                     name[250]=0;
  477.                 } else {
  478.                     strcpy(typeahd,(q=hasspace(name)) ? "\"" : "" );
  479.                     strcat(typeahd,name);
  480.                     if( q ) strcat(typeahd,"\"");
  481.                     if( lastcompl==33 || isdir(name) )
  482.                         appendslash( typeahd );
  483.                     else 
  484.                         strcat( typeahd, " " );
  485.                 }
  486.             }
  487.             tyahdptr=typeahd;
  488.             inslen=strlen(typeahd);
  489.             }
  490.             break;
  491.         case 34:
  492.             strncpy(typeahd,get_var( LEVEL_SET, v_lcd ),230);
  493.             appendslash(tyahdptr=typeahd);
  494.             break;
  495.  
  496.         case 40:                      /* ins/ovr */
  497.             insert ^= 1;
  498.             break;
  499.         case 41:                      /* quit */
  500.             strcpy(ps,"quit");
  501.             goto done;
  502.         case 42:                      /* help */
  503.             strcpy(ps,"help");
  504.             goto done;
  505.         case 43:                      /* refresh   */
  506. refresh:
  507.             if ((n = i/w_width)) printf("\033[%dF",n);
  508.             printf("\015\033[J%s%s",prompt,ps);
  509.             if( fn!=54 ) i= max;
  510.             else if(i!=max) printf("\033[%dD",max-i);
  511.             break;
  512.         case 44:
  513.             line[max] = '\0';
  514. done:        printf("\033[%dC\n",max - i);
  515.             strcpy(line, ps);
  516.             ret=line;
  517.             if( fake ) goto begin;
  518.             goto end;
  519.         case 45:                      /* leave   */
  520.             line[max] = '\0';
  521.             add_history( ps );
  522.             fake=1;
  523.             goto done;
  524.         case 46:                      /* EOF */
  525.             ret=NULL;
  526.             goto end;
  527.         case 47:
  528.             break;
  529.         case 48:
  530.             printf("\017");
  531.             break;
  532.         case 49:
  533.             printf("\07");
  534.             break;
  535.  
  536.         case 50: {
  537.             char fkeys[8];
  538.             sprintf(fkeys,"%c%d",param[0]>=10?'F':'f',param[0]%10+1);
  539.             if (s = get_var(LEVEL_SET, fkeys)) {
  540.                 tyahdptr = strcpy(typeahd,s);
  541.                 a0tospace( tyahdptr );
  542.             }
  543.             break;
  544.             }
  545.         case 51: {
  546.             int class=param[0], code=param[2];
  547.             if( class==10 ) {
  548.                 int num=MENUNUM( code ), item=ITEMNUM( code );
  549.                 tyahdptr="";
  550.                 if( num>=0 && num<MAXMENUS && item>=0 && item<=MAXITEMS )
  551.                     tyahdptr=MenuCommand[num][item];                                 
  552.             }
  553.             if( class==11 ) {
  554.                 strcpy(ps,"quit");
  555.                 goto done;
  556.             }
  557.             }
  558.         case 52: {
  559.             int t;
  560.  
  561.             if ((n = i/w_width)) printf("\033[%dF",n);
  562.             swapmem( Undo+pl, line+pl, MAX( max, undo_max)-pl );
  563.             t=max; max=undo_max; undo_max=t;
  564.             t=i;   i  =undo_i;   undo_i  =t;
  565.             line[max]=0;
  566.             printf("\015\033[J%s%s",prompt,ps);
  567.             if( i<max ) printf("\033[%dD",max-i);
  568.             }
  569.             break;
  570.         case 53:
  571.             fn=lastfn; key=lastkey;
  572.             goto dofn;
  573.         case 54:
  574.             if( i>pl+1 ) {
  575.                 char t;
  576.                 t=line[i-2]; line[i-2]=line[i-1]; line[i-1]=t;
  577.             }
  578.             goto refresh;
  579.  
  580.         default:
  581.             key&=255;
  582.             if (key == 9) key = 32;
  583.             if (key > 31 && (insert?max:i) < 256) {
  584.                 if (i < max && insert) {
  585.                     int j,t,l = 0;
  586.                     memmove(&line[i+1], &line[i], max - i);
  587.                     printf("\033[@%c",key);
  588.                     t = max/w_width - i/w_width;
  589.                     j = w_width - i % w_width - 1;
  590.                     for(n = 0; n < t; n++) {
  591.                         l += j;
  592.                         if (j) printf("\033[%dC",j);
  593.                         printf("\033[@%c",line[w_width*(i/w_width+n+1)]);
  594.                         j = w_width-1;
  595.                     }
  596.                     if (t) printf("\033[%dD",l + t);
  597.                     ++max;
  598.                 }
  599.                 else {
  600.                     if(i == pl && max == i) printf("\015%s%s",prompt,ps);
  601.                     putchar(key);
  602.                 }
  603.                 line[i++] = key;
  604.                 if (max < i) max = i;
  605.                 line[max] = '\0';
  606.             }
  607.         }
  608.     }
  609.     ret=NULL;
  610. end:
  611.     newwidth();
  612.     if( eav ) free_expand(eav);
  613.     SETCON;
  614.     return ret;
  615. }
  616.  
  617. int
  618. bkspcword( int i, int max, int cnt )
  619. {
  620.     int o=i;
  621.  
  622.     if( !cnt ) return 0;
  623.  
  624.     if( cnt==-1 ) {
  625.         cnt=0;
  626.         while( i>Pl && Line[i-1]==' ' )  i--, cnt++;
  627.         while( i>Pl && Line[i-1]!=' ' )  i--, cnt++;
  628.     } else 
  629.         i-=cnt;
  630.  
  631.     if( cnt ) printf("\033[%dD",cnt);
  632.     memmove( Line+i, Line+o, max-o );
  633.     memset ( Line+max-cnt, ' ', cnt  );
  634.     
  635.     printf("%s",Line+i);
  636.     
  637.     if( max-i ) printf("\033[%dD", max-i );
  638.     fflush(stdout);
  639.     Line[max-=cnt]=0;
  640.  
  641.     return cnt;
  642. }
  643.  
  644. void
  645. setrawcon( long flag, int ievent ) /* -1L=RAW:, 0L=CON: */
  646. {
  647.     static char menuon, button;
  648.     long packargs[8];
  649.  
  650.     if( !o_nowindow && ievent && flag==0 && menuon)
  651.         printf("\033[10}"), menuon=0;
  652.  
  653.     packargs[0]=flag;
  654.     SendPacket(994L, packargs, (void *)Myprocess->pr_ConsoleTask);
  655.  
  656.     if( !o_nowindow && ievent && flag==-1 ) {
  657.         if( !menuon )
  658.             printf("\033[10{"), menuon=1;
  659.         if( !button )
  660.             printf("\033[11{"), button=1;
  661.     }
  662.     fflush(stdout);
  663. }
  664.  
  665.  
  666.  
  667. static int row, height, cnt, noquick=1;
  668. static char scrollstr[10];
  669.  
  670.  
  671. extern BPTR OldCin;
  672.  
  673. static int FromTee;
  674.  
  675. extern struct MsgPort *Console;
  676.  
  677. int
  678. isconsole( BPTR fh )
  679. {
  680.     return ((struct FileHandle *)(4*fh))->fh_Type == Console;
  681. }
  682.  
  683.  
  684. static UBYTE
  685. mygetchar(void)
  686. {
  687.     UBYTE c;
  688.     Read( Input(), &c, 1 );
  689.     return c;
  690. }
  691.  
  692. void
  693. prepscroll( int fromtee )
  694. {
  695.     BPTR truecin=0;
  696.     long param[8];
  697.  
  698.     row=height=0;
  699.     FromTee=fromtee;
  700.  
  701.     if(( noquick=!o_scroll || o_noraw || o_nofastscr))
  702.         return;
  703.     if(( noquick=!isconsole(Myprocess->pr_COS) && !fromtee ))
  704.         return;
  705.     if( !isconsole(Myprocess->pr_CIS)) {
  706.         truecin=Myprocess->pr_CIS;
  707.  
  708.         if( noquick=!isconsole(OldCin) )
  709.             return;
  710.  
  711.         Myprocess->pr_CIS = DEVTAB(stdin) = OldCin;
  712.     }
  713.  
  714.     if( !CHARSWAIT(stdin) ) {
  715.         SETRAW;
  716.         Write(OldCin,"\033[ q",4);
  717.         get_seq( param );
  718.         height=param[2];
  719.         while( mygetchar()!='r') ;
  720.  
  721.         Write(OldCin,"\033[6n",4);
  722.         get_seq( param );
  723.         row=param[0];
  724.  
  725.         SETCON;
  726.  
  727.         cnt= height-row+1;
  728.         noquick= height<o_minrows;
  729.     }
  730.  
  731.     sprintf(scrollstr,"\033[%cS\033[%cA", o_scroll+'0', o_scroll+'0');
  732.  
  733.     if( truecin )
  734.         Myprocess->pr_CIS = DEVTAB(stdin) = truecin;
  735. }
  736.  
  737. static int
  738. get_seq( long *param )
  739. {
  740.     int c;
  741.  
  742.     while( (c=mygetchar())!=155 ) ;
  743.     do {
  744.         *param=0;
  745.         while( (c=mygetchar())>='0' && c<='9' )
  746.             *param=10* *param + c-'0';
  747.         param++;
  748.     } while( c==';' );
  749.  
  750.     return c;
  751. }
  752.  
  753.  
  754. void
  755. quickscroll( void )
  756. {
  757.     if( noquick ) return;
  758.  
  759.     if( --cnt<=0 ) {
  760.         cnt=o_scroll;
  761.         fprintf( FromTee ? stderr : stdout, "%s",scrollstr);
  762.     }
  763. }
  764.  
  765. int
  766. do_keymap( void )
  767. {
  768.     int i, n, len;
  769.     USHORT *tmp, *put, *get, *map;
  770.     char   *ind;
  771.  
  772.     n=myatoi(av[1],0,7);
  773.     if( atoierr ) return 20;
  774.  
  775.     map=Keymap[n]; len=0;
  776.     if( map )
  777.         for( len=0; map[2*len]; len++ ) ;
  778.  
  779.     put=tmp=salloc((len+ac)*2*sizeof(USHORT));
  780.     for( i=2; i<ac; i++ ) {
  781.         if( !(ind=index(av[i],'='))) {
  782.             ierror( av[i],500);
  783.             free( tmp );
  784.             return 20;
  785.         }
  786.         *put++=atoi(av[i]);
  787.         *put++=atoi(ind+1);
  788.     }
  789.  
  790.     for( i=0; i<len; i++ ) {
  791.         for( get=tmp; get<put; get+=2 )
  792.             if( *get==map[2*i] )
  793.                 break;
  794.         if( get==put ) {
  795.             *put++=map[2*i];
  796.             *put++=map[2*i+1];
  797.         }
  798.     }
  799.  
  800.     if( map && map!=DefKeymap0 && map!=DefKeymap1 )
  801.         free( map );
  802.     Keymap[n]=tmp;
  803.     Curmap=0;
  804.  
  805.     return 0;
  806. }
  807.  
  808. static int
  809. myget( void )
  810. {
  811.     int c;
  812.  
  813.     lasttya=tyahdptr;
  814.     if( unget )
  815.         c=unget, unget=0;
  816.     else if( tyahdptr && *tyahdptr)
  817.         c=*tyahdptr++;
  818.     else {
  819. #ifndef AZTEC_C
  820.         fflush(stdout);
  821. #endif
  822.         if( (c=getchar())!=155 )
  823.             tabctr--, qcdctr--, histctr--;
  824.     }
  825.  
  826.     return c;
  827. }
  828.  
  829. static void
  830. myunget(int c)
  831. {
  832.     unget=c;
  833. }
  834.  
  835. int
  836. newwidth( void )
  837. {
  838.     extern struct Window *Win;
  839.  
  840.     w_width=80;
  841.     if( !o_nowindow && Win )
  842.         w_width=(Win->Width-(Win->BorderLeft+Win->BorderRight))/
  843.                  Win->RPort->TxWidth;
  844.     if( w_width<1 ) w_width=1;          /* crash after resizing was reported */
  845.     return w_width;
  846. }
  847.  
  848.  
  849.  
  850. #else
  851.  
  852. prepscroll(){}
  853. quickscroll(){}
  854.  
  855. #endif
  856.  
  857.