home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / shell / csh548src.lha / rawcon.c < prev    next >
C/C++ Source or Header  |  1995-05-05  |  25KB  |  1,165 lines

  1. /* rawcon.c
  2.  *
  3.  * Shell 2.07M  17-Jun-87
  4.  * console handling, command line editing support for Shell
  5.  * using new console packets from 1.2.
  6.  * Written by Steve Drew. (c) 14-Oct-86.
  7.  * 16-Dec-86 Slight mods to rawgets() for Disktrashing.
  8.  *
  9.  * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  10.  * Version 5.00L by Urban Mueller 17-Feb-91
  11.  * Version 5.20L by Andreas M. Kirchwitz (Fri, 13 Mar 1992)
  12.  *
  13.  */
  14.  
  15. #include "shell.h"
  16.  
  17. void setrawcon( long flag, int ievent );
  18.  
  19. #define LINELEN 255
  20.  
  21. int w_width=80, w_height=24;
  22.  
  23. #if RAW_CONSOLE
  24.  
  25. static int myget( void );
  26. static void myunget(int c);
  27. static int get_seq( long *param );
  28.  
  29. static void back( int n );
  30. static void left( int n );
  31. static void right( int n );
  32. static int  leftwordlen( void );
  33. static int  rightwordlen( void );
  34. static void delete( int i );
  35. static void history( int hnum );
  36. static void display( char *str );
  37. static void redraw( void );
  38. static void abbrev( char *buf, char **eav, int eac );
  39. static void quote( char *buf, char *sep );
  40. static void getword( char *buf );
  41. static void delword( void );
  42. static int  getkey(void);
  43.  
  44. static char *tyahdptr;
  45. static int unget;
  46.  
  47. #define SETRAW setrawcon(-1,1);
  48. #define SETCON setrawcon( 0,1);
  49.  
  50. extern char *MenuCommand[MAXMENUS][MAXMENUITEMS];
  51.  
  52. #define CTRL  -64
  53. #define SHIFT 512
  54. #define ESC   1024
  55.  
  56. #define CUP   256
  57. #define CDN   257
  58. #define CRT   258
  59. #define CLT   259
  60. #define TAB   9
  61.  
  62. static int Curmap;
  63. static USHORT *Keymap[8];
  64. static USHORT DefKeymap0[]={
  65.        CLT,  0, /* CursLt = Move.Left  */
  66.        CRT,  1, /* CursRt = Move.Right */
  67.  SHIFT+CLT,  2, /* SCursLt= Move.WordL */
  68.  SHIFT+CRT,  3, /* SCursRt= Move.WordR */
  69.    ESC+CLT,  4, /* ESC-CLt= Move.SOL   */
  70.    ESC+CRT,  5, /* ESC-CRt= Move.EOL   */
  71.   CTRL+'A',  4, /* ^A     = Move.SOL   */
  72.   CTRL+'E',  5, /* ^E     = Move.EOL   */
  73.   CTRL+'Z',  4, /* ^Z     = Move.SOL   */
  74.          8, 10, /* BackSp = Del.BackSp */
  75.        127, 11, /* Delete = Del.Delete */
  76.    ESC+  8, 12, /* ESC-BkS= Del.WordL  */
  77.    ESC+127, 13, /* ESC-Del= Del.WordR  */
  78.   CTRL+'W', 12, /* ^W     = Del.WordL  */
  79.   CTRL+'B', 14, /* ^B     = Del.SOL    */
  80.   CTRL+'K', 15, /* ^K     = Del.EOL    */
  81.    ESC+'x',513, /* ESC-x  = Setmap 1   */
  82.    ESC+'d', 16, /* ESC-d  = Del.Line   */
  83.   CTRL+'X', 16, /* ^X     = Del.Line   */
  84.        CUP, 20, /* CursUp = Hist.Back  */
  85.        CDN, 21, /* CursDn = Hist.Forw  */
  86.    ESC+CUP, 22, /* ECursUp= Hist.Beg   */
  87.    ESC+CDN, 23, /* ECursDn= Hist.End   */
  88.  SHIFT+CUP, 24, /* SCursUp= Hist.Compl */
  89.    ESC+'!', 24, /* ESC-!  = Hist.Compl */
  90.    ESC+ 13, 25, /* ESC-Ret= Hist.Exec  */
  91.   CTRL+'T', 26, /* ^T     = Hist.Tail  */
  92.  SHIFT+CDN, 27, /* SCursDn= Hist.Clr   */
  93.   CTRL+'P', 28, /* ^P     = Hist.DupWrd*/
  94.        TAB, 30, /* Tab    = Comp.Norm  */
  95.  SHIFT+TAB, 31, /* STab   = Comp.Part  */
  96.    ESC+TAB, 32, /* ESC-TAB= Comp.All   */
  97.    ESC+'*', 32, /* ESC-*  = Comp.All   */
  98.    ESC+'c', 33, /* ESC-c  = Comp.CD    */
  99.    ESC+'~', 34, /* ESC-~  = Comp.LastCD*/
  100.   CTRL+'D', 35, /* CTRL-D = Comp.Dir   */
  101.    ESC+'=', 35, /* ESC-=  = Comp.Dir   */
  102.    ESC+'p', 36, /* ESC-p  = Comp.Prg1  */
  103.    ESC+'P', 37, /* ESC-P  = Comp.PrgAll*/
  104.    ESC+'i', 40, /* ESC-i  = Spec.Insert*/
  105.   CTRL+'L', 43, /* ^L     = Spec.Refr  */
  106.         10, 44, /* Enter  = Spec.Accept*/
  107.         13, 44, /* ^Enter = Spec.Accept*/
  108.   CTRL+'N', 45, /* ^N     = Spec.Next  */
  109.   CTRL+'O', 48, /* ^O     = Spec.EchoO */
  110.  CTRL+'\\', 46, /* ^\     = Spec.EOF   */
  111.        260, 42, /* Help   = Spec.Help  */
  112.        271, 51, /* Menu   = Misc.Menu  */
  113.   CTRL+'U', 52, /* ^U     = Misc.Undo  */
  114.   CTRL+'R', 53, /* ^R     = Misc.Repeat*/
  115.    ESC+'s', 54, /* ESC-s  = Misc.Swap  */
  116.   CTRL+'V', 55, /* CTRL-V = Misc.Quote */
  117.          0,  0
  118. };
  119.  
  120. static USHORT DefKeymap1[]={
  121.          8, 14,
  122.        127, 15,
  123.          0, 0
  124. };
  125.  
  126. static int  Pos, Len;
  127. static char *Line, *Prompt;
  128. static char LastDir[128];
  129. static char Undo[256];
  130. static int  LastFn = -99, LastKey = -99;
  131. long   Param[10];
  132.  
  133.  
  134.  
  135. void initmap(void)
  136. {
  137.     if( !Keymap[0] )
  138.         Keymap[0]=DefKeymap0, Keymap[1]=DefKeymap1;
  139. }
  140.  
  141.  
  142.  
  143. char *ffgets(char *line,long length,FILE *fp)
  144. {
  145.     if (fgets(line,length-1,fp)) {
  146.         if (!strchr(line,'\n')) {
  147.             int c;
  148.             do {
  149.                 c = fgetc(fp);
  150.             }
  151.             while (c!=EOF && c!='\n');
  152.             strcat(line,"\n");
  153.         }
  154.         return(line);
  155.     }
  156.     else
  157.         return(NULL);
  158. }
  159.  
  160.  
  161.  
  162. char *rawgets( char line[], char prompt[] )
  163. {
  164.     static int HNum = -1;
  165.  
  166.     int  key, fn, old, hnum = -1, olen=0, inslen=0;
  167.     int  insert, undo_pos=0, undo_len=0;
  168.     int  eac, eactr=0;
  169.     char typeahd[LINELEN], **eav=NULL, *ret=line;
  170.     char *prghash_hit;
  171.     char prghash_pat[LINELEN];
  172.  
  173.     char *prio_set;
  174.     long oldprio,prio;
  175.  
  176.     if ( o_noraw || !IsInteractive(Input()) ) {
  177.         if (IsInteractive(Input())) {
  178.             printf("%s",prompt);
  179.             fflush(stdout);
  180.         }
  181.         return( ffgets(line,LINELEN-1,stdin) );
  182.     }
  183.  
  184.     if (WaitForChar(Input(), 100L) || CHARSWAIT(stdin))    /* don't switch to 1 */
  185.         return( ffgets(line,LINELEN-1,stdin) );
  186.  
  187.     SETRAW;
  188.  
  189.     if (prio_set = get_var(LEVEL_SET,v_clipri)) {
  190.         prio=atol(prio_set);
  191.         if (!isnum(prio_set)) {
  192.             printf("error: variable _clipri (%s) is not a number\n",prio_set);
  193.             prio_set = NULL;
  194.         }
  195.         else if (prio<-128 || prio>127) {
  196.             printf("error: variable _clipri (%s) is out of range (-128,127)\n",prio_set);
  197.             prio_set = NULL;
  198.         }
  199.         else {
  200.             oldprio = SetTaskPri((struct Task *)Myprocess,prio);
  201.         }
  202.     }
  203.  
  204.     tyahdptr=typeahd;
  205.     typeahd[0]=0;
  206.     Flush(Output());
  207.  
  208.     /*
  209.      *  If internal variable o_vt100 is set, Cshell sends no longer
  210.      *  "\033[ p" (special Amiga control sequence to turn on cursor)
  211.      *  which confused some terminal programs.
  212.      */
  213.  
  214.     fprintf(stdout,"\015\017%s%s",
  215.             o_vt100 ? "" : "\033[ p",
  216.             prompt);
  217.     fflush(stdout);
  218.  
  219.     Line= line; Prompt= prompt;
  220.     line[ Len=Pos=0 ]=0;
  221.     insert= o_insert;
  222.  
  223.     if( LastFn!=25 )
  224.         LastFn = -1;
  225.  
  226.     if( HNum>=0 ) {
  227.         history( hnum=HNum );
  228.         HNum = -1;
  229.     }
  230.  
  231.     while( (key=getkey()) != -1) {
  232.         USHORT *p;
  233.         int    t;
  234.         char   c, *s, *src, *sep;
  235.  
  236.         for( fn = -1, p=Keymap[Curmap]; *p; p+=2 )
  237.             if( *p==key )
  238.                 { fn=p[1]; break; }
  239.         if( fn == -1 && (key>=261 && key<=270 || key>=261+SHIFT && key<=270+SHIFT))
  240.             fn=50;
  241.         if( fn == -1 && tyahdptr )
  242.             fn = -2;
  243.         if( fn!=52 && fn != -2 ) {
  244.             memcpy( Undo, line, Len+1 );
  245.             undo_pos=Pos; undo_len=Len;
  246.         }
  247.  
  248.         switch( fn/512 ) {
  249.         case 1:
  250.             fn&=511;
  251.             if( fn<8 && Keymap[fn] ) Curmap=fn;
  252.             fn = -3;
  253.             break;
  254.         case 2:
  255.             key=fn&511, fn = -1;
  256.             break;
  257.         }
  258.  
  259.         if( fn != -3 )
  260.             Curmap=0;
  261.  
  262.         if( fn == 53 )
  263.             fn=LastFn, key=LastKey;
  264.  
  265.         switch( fn ) {
  266.         case -3:                                /* change keymap */
  267.             break;
  268.         case -2:                                /* auto insert   */
  269.         case -1:                                /* insert key    */
  270.             key&=255;
  271.             if (key < 31 || (insert?Len:Pos) >= LINELEN-1 )
  272.                 break;
  273.             putchar(key);
  274.             if (Pos < Len && insert) {
  275.                 memmove( line+Pos+1, line+Pos, Len-Pos+1);
  276.                 printf("%s",line+Pos+1);
  277.                 back(Len-Pos);
  278.                 Len++;
  279.             }
  280.             line[Pos++] = key;
  281.             if (Len < Pos) Len = Pos;
  282.             line[Len] = 0;
  283.             break;
  284.  
  285.         case 0:                                 /* cursor left  */
  286.             left(1);
  287.             break;
  288.         case 1:                                 /* cursor right */
  289.             right(1);
  290.             break;
  291.         case 2:                                 /* word left    */
  292.             left( leftwordlen() );
  293.             break;
  294.         case 3:                                 /* word right   */
  295.             right( rightwordlen() );
  296.             break;
  297.         case 4:                                 /* beg of line  */
  298.             left(Pos);
  299.             break;
  300.         case 5:                                 /* end of line  */
  301.             right(Len-Pos);
  302.             break;
  303.  
  304.         case 10:                                /* backspace    */
  305.             if (Pos==0)
  306.                 break;
  307.             left(1);
  308.         case 11:                                /* delete       */
  309.             if (Pos==Len)
  310.                 break;
  311.             delete(1);
  312.             break;
  313.         case 12:                                /* bkspc word     */
  314.             if( !leftwordlen() )
  315.                 break;
  316.             left( leftwordlen() );
  317.         case 13:                                /* del word       */
  318.             delete( rightwordlen() );
  319.             break;
  320.         case 14:                                /* del to SOL     */
  321.             left( old=Pos );
  322.             delete( old );
  323.             break;
  324.         case 16:                                /* delete line    */
  325.             left( Pos );
  326.         case 15:                                /* delete to EOL  */
  327.             delete( Len-Pos );
  328.             break;
  329.  
  330.         case 17: /* AMK */                      /* clear screen + refresh */
  331.             fprintf(stdout,"\033c\017");
  332.             fflush(stdout);
  333.             redraw();
  334.             break;
  335.  
  336.         case 20:                                /* history up   */
  337.             if( hnum>=H_len-1 )
  338.                 hnum=H_len-1;
  339.             history( ++hnum );
  340.             break;
  341.         case 21:                                /* history down */
  342.             if( hnum<=0 )
  343.                 hnum=0;
  344.             history( --hnum );
  345.             break;
  346.         case 22:                                /* beg of hist */
  347.             history( hnum=H_len-1 );
  348.             break;
  349.         case 23:                                /* end of hist */
  350.             history( hnum=0 );
  351.             break;
  352.         case 24:                                /* complete hist */
  353.             if( LastFn!=fn )
  354.                 hnum = -1, olen=Len;
  355.             line[Len=olen]=0;
  356.             if((hnum=find_history( line, ++hnum )) == -1)
  357.                 display(line);
  358.             else
  359.                 history(hnum);
  360.             break;
  361.         case 25:                                /* exec hist  */
  362.             HNum= hnum;
  363.             LastFn= fn;
  364.             goto done;
  365.         case 26:                                /* tail of prev */
  366.             if( H_head && (s=H_head->line) && (s=index(s,' ')))
  367.                 tyahdptr=s;
  368.             break;
  369.         case 27:                                /* bottom   */
  370.             history( hnum = -1 );
  371.             break;
  372.         case 28:                                /* duplicate word */
  373.             for( s=line+Pos,t=0; s>line && s[-1]==' '; s--,t++ ) ;
  374.             left(t);
  375.             *(tyahdptr=typeahd)=' ';
  376.             getword( typeahd+(t?0:1) );
  377.             right(t);
  378.             break;
  379.         case 29: /* AMK */                      /* last word of prev */
  380.             if( H_head && (s=H_head->line)) {
  381.                 int l = strlen(s) - 1;
  382.                 while (l>=0 && s[l]==' ')    /* skip spaces */
  383.                     --l;
  384.                 while (l>=0 && s[l]!=' ')    /* find next space */
  385.                     --l;
  386.                 if (l>=0)
  387.                     tyahdptr = &s[l];
  388.             }
  389.             break;
  390.  
  391.         case 32:                                /* complete all  */
  392.         case 35: LastFn = -1;                     /* show files    */
  393.         case 30:                                /* complete      */
  394.         case 31:                                /* complete part */
  395.         case 33:                                /* qcd           */
  396.             sep=" ";
  397.             if( fn!=LastFn ) {
  398.                 getword( typeahd );
  399.                 filemap( typeahd, 1 );
  400.                 if( eav    ) free_expand( eav ), eav=NULL;
  401.                 eac=0;
  402.                 breakreset();
  403.                 if( fn==35 ) {
  404.                     int tmp=o_scroll;
  405.                     int old_Pos=Pos;
  406.                     right(Len-Pos);
  407.                     putchar('\n');
  408.                     if (isdir( typeahd )) {
  409.                         /* show contents of directory */
  410.                         memmove( typeahd+8, typeahd, strlen(typeahd)+1);
  411.                         /*
  412.                            we need to escape "dir" here in
  413.                            such a way that it works even if
  414.                            a user aliased "dir" to something
  415.                            completely else
  416.                         */
  417.                         memcpy ( typeahd, "\\dir -s ", 8);
  418.                     }
  419.                     else {
  420.                         /* show matching files */
  421.                         memmove( typeahd+8, typeahd, strlen(typeahd)+1);
  422.                         /*
  423.                            we need to escape "dir" here in
  424.                            such a way that it works even if
  425.                            a user aliased "dir" to something
  426.                            completely else
  427.                         */
  428.                         memcpy ( typeahd, "\\dir -s ", 8);
  429.                         strcat ( typeahd, "*");
  430.                     }
  431.                     o_scroll=0;
  432.                     execute( typeahd );
  433.                     o_scroll=tmp;
  434.                     printf("\033[J%s%s",Prompt,Line);
  435.                     back(Len-old_Pos);
  436.                     Pos = old_Pos;
  437.                     break;
  438.                 }
  439.                 if( fn!=33 ) {
  440.                     if (strlen(o_complete)>0)
  441.                         strcat( typeahd, o_complete);
  442.                     else
  443.                         strcat( typeahd, "*");
  444.                     if( !index(typeahd,'&' ))
  445.                         eav =expand(typeahd,&eac);
  446.                     if( eac==0 ) {
  447.                         putchar(7);
  448.                         break;
  449.                     }
  450.                 }
  451.                 if( fn==30 )
  452.                     s=eav[ eactr=0 ];
  453.                 else if( fn==31 )
  454.                     abbrev(s=typeahd,eav,eac), eactr = -1, sep= eac==1?" ":"";
  455.                 else if( fn==32 ) {
  456.                     strncpy(s=typeahd, src=compile_av(eav,0,eac,' ',1),LINELEN);
  457.                     typeahd[LINELEN-1]=0;
  458.                     free(src);
  459.                 } else if( fn==33 ) {     /* 33 */
  460.                     strncpy(LastDir,typeahd,128);
  461.                     if( !quick_cd( s=typeahd+128, LastDir, 0)) {
  462.                         putchar(7);
  463.                         break;
  464.                     }
  465.                 }
  466.                 delword();
  467.             } else {
  468.                 if( fn==33 )
  469.                     quick_cd( s=typeahd+128, LastDir, 1);
  470.                 else { /* 30,31 */
  471.                     if( eac==0 ) {
  472.                         putchar(7);
  473.                         break;
  474.                     }
  475.                     s=eav[eactr = ++eactr % eac];
  476.                 }
  477.                 left(inslen);
  478.                 delete(inslen);
  479.             }
  480.             strcpy( tyahdptr=typeahd, s );
  481.             if( fn!=32 )
  482.                 quote( typeahd, sep );
  483.             inslen=strlen(typeahd);
  484.             break;
  485.         case 34:                      /* last CD */
  486.             strncpy(typeahd,get_var( LEVEL_SET, v_lcd ),230);
  487.             appendslash(tyahdptr=typeahd);
  488.             break;
  489.         case 36:
  490.             if( fn!=LastFn ) {
  491.                 getword( typeahd );
  492.                 filemap( typeahd, 1 );
  493.                 strcpy(prghash_pat,typeahd);
  494.                 if (prghash_hit=get_rehash_prog(NULL,prghash_pat)) {
  495.                     delword();
  496.                     strcpy(tyahdptr=typeahd,prghash_hit);
  497.                     /*quote(typeahd," ");*/
  498.                     inslen=strlen(typeahd);
  499.                 }
  500.                 else
  501.                     putchar(7);
  502.             }
  503.             else {
  504.                 if (prghash_hit) {
  505.                     if (prghash_hit=get_rehash_prog(prghash_hit,prghash_pat)) {
  506.                         left(inslen);
  507.                         delete(inslen);
  508.                         strcpy(tyahdptr=typeahd,prghash_hit);
  509.                         /*quote(typeahd," ");*/
  510.                         inslen=strlen(typeahd);
  511.                     }
  512.                     else
  513.                         putchar(7);
  514.                 }
  515.                 else
  516.                     putchar(7);
  517.             }
  518.             break;
  519.         case 37:
  520.             {
  521.             char *firsthit;
  522.             int tmp=o_scroll;
  523.             int old_Pos=Pos;
  524.             int cnt = 0;
  525.  
  526.             getword( typeahd );
  527.             filemap( typeahd, 1 );
  528.  
  529.             prghash_hit = NULL;
  530.             if (firsthit=get_rehash_prog(NULL,typeahd)) {
  531.                 right(Len-Pos);
  532.                 putchar('\n');
  533.                 o_scroll=0;
  534.                 printf(" %d. %s\n",++cnt,firsthit);
  535.                 prghash_hit = firsthit;
  536.                 breakreset();
  537.                 while ( !dobreak() && (prghash_hit=get_rehash_prog(prghash_hit,typeahd)) && prghash_hit!=firsthit ) {
  538.                     printf(" %d. %s\n",++cnt,prghash_hit);
  539.                 }
  540.                 breakreset();
  541.                 o_scroll=tmp;
  542.                 printf("\033[J%s%s",Prompt,Line);
  543.                 back(Len-old_Pos);
  544.                 Pos = old_Pos;
  545.             }
  546.             else
  547.                 putchar(7);
  548.  
  549.             break;
  550.             }
  551.  
  552.         case 40:                      /* ins/ovr */
  553.             insert ^= 1;
  554.             break;
  555.         case 41:                      /* quit    */
  556.             strcpy(line,"quit");
  557.             goto done;
  558.         case 42:                      /* help    */
  559.             strcpy(line,"help");
  560.             goto done;
  561.         case 43:                      /* refresh */
  562.             redraw();
  563.             break;
  564.         case 44:                      /* exec    */
  565.             goto done;
  566.         case 45:                      /* leave   */
  567.             add_history( line );
  568.             right(Len-Pos);
  569.             putchar('\n');
  570.             line[Len=Pos=0]=0;
  571.             update_sys_var(v_prompt);
  572.             update_sys_var(v_titlebar);
  573.             redraw();
  574.             hnum = -1;
  575.             break;
  576.         case 46:                      /* EOF */
  577.             ret=NULL;
  578.             goto done;
  579.         case 47:                      /* NOP */
  580.             break;
  581.         case 48:                      /* ^O  */
  582.             /*putchar( CTRL+'O' );*/
  583.             putchar( '\017' );
  584.             redraw();
  585.             break;
  586.         case 49:                      /* ^G  */
  587.             /*putchar( CTRL+'G' );*/
  588.             putchar( '\007' );
  589.             break;
  590.  
  591.         case 50:                      /* FKey */
  592.             sprintf(typeahd,"%c%d",Param[0]>=10?'F':'f',Param[0]%10+1);
  593.             if (s = get_var(LEVEL_SET, typeahd)) {
  594.                 tyahdptr = strcpy(typeahd,s);
  595.                 a0tospace( tyahdptr );
  596.             }
  597.             break;
  598.         case 51:                      /* RawRaw */
  599.             if( Param[0]==10 ) {   /* P0=class P2=code */
  600.                 int num=MENUNUM( Param[2] ), item=ITEMNUM( Param[2] );
  601.                 tyahdptr="";
  602.                 if( num>=0 && num<MAXMENUS && item>=0 && item<MAXMENUITEMS )
  603.                     tyahdptr=MenuCommand[num][item];
  604.             }
  605.             if( Param[0]==11 ) {
  606.                 strcpy(line,"quit");
  607.                 goto done;
  608.             }
  609.             break;
  610.         case 52:                      /* Undo   */
  611.             back(Pos);
  612.             t=Len; Len=undo_len; undo_len=t;
  613.             t=Pos; Pos=undo_pos; undo_pos=t;
  614.             swapmem( Undo, line, MAX( Len, undo_len)+1 );
  615.             printf("\033[J%s",line);
  616.             back(Len-Pos);
  617.             break;
  618.         case 53:                      /* repeat */
  619.             break;
  620.         case 54:                      /* swap   */
  621.             if( (t=Pos==Len?Pos-1:Pos)>0 )
  622.                 c=line[t-1], line[t-1]=line[t], line[t]=c;
  623.             redraw();
  624.             break;
  625.         case 55:                      /* quote char */
  626.             {
  627.             int qkey = getkey();
  628.             if (qkey>=0 && qkey<=255)
  629.                 sprintf(tyahdptr=typeahd,"\\%03.3o",qkey);
  630.             }
  631.             break;
  632.         }
  633.         if( fn != -2 )
  634.             LastFn=fn, LastKey=key;
  635.     }
  636.     ret=NULL;
  637. done:
  638.     if( ret )
  639.         printf("\033[%dC\n", Len-Pos );
  640.     newwidth();
  641.     if( eav ) free_expand(eav);
  642.     SETCON;
  643.  
  644.     if (prio_set)
  645.         SetTaskPri((struct Task *)Myprocess,oldprio);
  646.  
  647.     return ret;
  648. }
  649.  
  650. static int
  651. getkey(void)
  652. {
  653.     int esc=0, key, c;
  654.     long *par;
  655.  
  656.     key = -1;
  657.  
  658. rbabelhack:
  659.     if ( (c=myget()) == 27 ) {        /* ESC */
  660.         esc=ESC;
  661.         if ( (c=myget()) == '[')    /* CSI */
  662.             c=155, esc=0;
  663.     }
  664.  
  665.     /* siehe RKM:Devs, Seite 399 fuer einen GUTEN ISO-Parser */
  666.     if (c == -1)
  667.         return -1;
  668.  
  669.     if (c == 155) {                /* CSI */
  670.         switch ( c=myget() ) {
  671.         case 'A': key=256;       break; /* CursUp */
  672.         case 'B': key=257;       break; /* CursDn */
  673.         case 'C': key=258;       break; /* CursRt */
  674.         case 'D': key=259;       break; /* CursLt */
  675.         case 'T': key=256+SHIFT; break; /* SCursUp */
  676.         case 'S': key=257+SHIFT; break; /* SCursDn */
  677.         case ' ':
  678.             switch( myget() ) {
  679.             case '@': key=258+SHIFT; break; /* SCursRt */
  680.             case 'A': key=259+SHIFT; break; /* SCursLt */
  681.             }
  682.             break;
  683.         case 'Z': key= 9+SHIFT;       break; /* STab    */
  684.         case '?': key= 260; myget();  break; /* Help    */
  685.         case -1 : return -99;
  686.         default :
  687.             if( c>='0' && c<='9' ) {
  688.                 myunget(c);
  689.                 par=Param;
  690.                 do {
  691.                     for( *par=0; (c=myget())>='0' && c<='9';  )
  692.                         *par=10* *par + c-'0';
  693.                     par++;
  694.                 } while( c==';' );
  695.                 if( c=='~' ) {
  696.                     key=Param[0]+261;
  697.                     if( key>270 ) key+=SHIFT-10;
  698.                 }
  699.                 else if ( c=='|' ) key=271;
  700.                 else {
  701.                     while ( c>=' ' && c<='?' && c != -1 )
  702.                         c=myget();
  703.                     /* now: c>='@' && c<='~' */
  704.                 }
  705.             } else {
  706.                 key = c;
  707.             }
  708.         }
  709.     }
  710.     else
  711.         key = c;    /* normal char (no ESC, no CSI) */
  712.  
  713.     if (key == -1 && c != -1)    /* really EOF ? */
  714.         goto rbabelhack;
  715.  
  716.     return key+esc;
  717. }
  718.  
  719. static void
  720. back(int n)
  721. {
  722.     if( n>0 ) printf("\033[%dD",n);
  723. }
  724.  
  725. static void
  726. left(int n)
  727. {
  728.     if( n>Pos ) n=Pos;
  729.     if( n<=0  ) return;
  730.     back(n);
  731.     Pos-=n;
  732. }
  733.  
  734. static void
  735. right(int n)
  736. {
  737.     if( n+Pos>Len ) n=Len-Pos;
  738.     if( n<=0      ) return;
  739.     printf("\033[%dC",n);
  740.     Pos+=n;
  741. }
  742.  
  743. static int
  744. leftwordlen( void )
  745. {
  746.     char  *ptr= Line+Pos;
  747.     while( ptr>Line && *(ptr-1) == ' ' ) ptr--;
  748.     while( ptr>Line && *(ptr-1) != ' ' ) ptr--;
  749.     return (Line+Pos)-ptr;
  750. }
  751.  
  752. static int
  753. rightwordlen( void )
  754. {
  755.     char  *ptr= Line+Pos;
  756.     while( ptr<Line+Len && *ptr != ' ' ) ptr++;
  757.     while( ptr<Line+Len && *ptr == ' ' ) ptr++;
  758.     return ptr-(Line+Pos);
  759. }
  760.  
  761. static void
  762. delete( int cnt )
  763. {
  764.     if( !cnt ) return;
  765.     memmove( Line+Pos, Line+Pos+cnt, Len-Pos-cnt );
  766.     memset ( Line+Len-cnt, ' ', cnt );
  767.     printf("%s",Line+Pos);
  768.     back(Len-Pos);
  769.     Line[ Len-=cnt ]=0;
  770. }
  771.  
  772. static void
  773. history( int hnum )
  774. {
  775.     HIST *hist;
  776.  
  777.     for( hist=H_head; hist && hnum--; hist=hist->next) ;
  778.     display( hist ? hist->line : "");
  779. }
  780.  
  781. static void 
  782. display( char *str )
  783. {
  784.     left(Pos);
  785.     strcpy(Line,str);
  786.     printf("\033[J%s",str);
  787.     Pos= Len= strlen(str);
  788. }
  789.  
  790. static void
  791. redraw( void )
  792. {
  793.     back(Pos);
  794.     printf("\015\033[J%s%s",Prompt,Line);
  795.     back(Len-Pos);
  796. }
  797.  
  798. static int wleft, wdel;
  799.  
  800. static void
  801. getword( char *buf )
  802. {
  803.     char *beg, *end, *l=Line;
  804.  
  805.     for( end=l+Pos; *end  && *end!=' '; ++end ) ;
  806.     for( beg=l+Pos; beg>l && !index(" <>;",*(beg-1)) ; beg-- ) ;
  807.     memcpy( buf, beg, end-beg );
  808.     buf[end-beg]=0;
  809.     wleft= (l+Pos)-beg;
  810.     wdel = end-beg;
  811. }
  812.  
  813. static void
  814. delword()
  815. {
  816.     left( wleft);
  817.     delete( wdel );
  818. }
  819.  
  820.  
  821.  
  822. static void
  823. abbrev( char *buf, char **eav, int eac )
  824. {
  825.     int i, j, radlen=9999;
  826.  
  827.     /*if( eac>1 ) putchar( CTRL+'G' );*/
  828.     if( eac>1 ) putchar( '\007' );    /* ^G */
  829.  
  830.     strcpy( buf, eav[0] );
  831.     for( i=0; i<eac; i++ ) {
  832.         if ( (j=strlen(eav[i])) < radlen ) radlen=j;
  833.         for( j=0; j<radlen && tolower(eav[0][j])==tolower(eav[i][j]); j++ ) ;
  834.         if ( j<radlen ) radlen=j;
  835.     }
  836.     buf[radlen]=0;
  837. }
  838.  
  839.  
  840.  
  841. static int must_be_quoted(char *s)
  842. {
  843.     if (!*s)
  844.         return 1;
  845.     for ( ; *s; s++)
  846.         if (ISSPACE(*s) || *s==';' || *s=='|' || *s=='#' || *s=='^'
  847.              || *s=='?' || *s=='*' || *s=='&' || *s=='$' || *s=='!'
  848.              || *s=='~' || *s=='`' || *s=='\'')
  849.            return 1;
  850.     return 0;
  851. }
  852.  
  853. static void quote( char *buf, char *sep )
  854. {
  855.     int len=strlen(buf), dir=isdir(buf);
  856.  
  857.     if (must_be_quoted(buf)) {
  858.         memmove(buf+1,buf,len);
  859.         buf[0]=buf[++len]='\"';
  860.         buf[++len]=0;
  861.     }
  862.     strcat(buf,dir?"/":sep);
  863. }
  864.  
  865.  
  866.  
  867. void
  868. setrawcon( long flag, int ievent ) /* -1L=RAW:, 0L=CON: */
  869. {
  870.     struct FileHandle *fh;
  871.     static char menuon, button;
  872.  
  873.     if( !o_vt100 && !o_nowindow && ievent && flag==0 && menuon)
  874.         printf("\033[10}"), menuon=0;
  875.  
  876.     if (fh = BADDR( Input() )) {
  877.         if ( fh->fh_Type )
  878.             DoPkt( (void *)fh->fh_Type, ACTION_SCREEN_MODE, flag,  NULL,NULL,NULL,NULL );
  879.             /*DoPkt( (void *)Myprocess->pr_ConsoleTask, ACTION_SCREEN_MODE, flag,  NULL,NULL,NULL,NULL );*/
  880.     }
  881.  
  882.     if( !o_vt100 && !o_nowindow && ievent && flag == -1 ) {
  883.         if( !menuon )
  884.             printf("\033[10{"), menuon=1;
  885.         if( !button )
  886.             printf("\033[11{"), button=1;
  887.     }
  888.  
  889.     fflush(stdout);
  890. }
  891.  
  892.  
  893. static int row, height, cnt;
  894. static char scrollstr[10];
  895. static int noquick=1;
  896.  
  897.  
  898. extern BPTR OldCin;
  899.  
  900. static int FromTee;
  901.  
  902. static UBYTE
  903. mygetchar(void)
  904. {
  905.     UBYTE c;
  906.     Read( Input(), &c, 1 );
  907.     return c;
  908. }
  909.  
  910. #if 0
  911. void
  912. prepscroll( int fromtee )
  913. {
  914.     BPTR truecin=0;
  915.     long param[8];
  916.  
  917.     row=height=0;
  918.     FromTee=fromtee;
  919.  
  920.     if(( noquick=!o_scroll || o_noraw || o_nofastscr || o_vt100 ))
  921.         return;
  922.  
  923.     if(( noquick=!IsInteractive(Myprocess->pr_COS) && !fromtee ))
  924.         return;
  925.  
  926.     if( !IsInteractive(Myprocess->pr_CIS)) {
  927.         truecin=Myprocess->pr_CIS;
  928.  
  929.         if( noquick=!IsInteractive(OldCin) )
  930.             return;
  931.  
  932.         Myprocess->pr_CIS = DEVTAB(stdin) = OldCin;
  933.     }
  934.  
  935.     if( !CHARSWAIT(stdin) ) {
  936.         SETRAW;
  937.         Write(OldCin,"\033[ q",4);
  938.         get_seq( param );
  939.         height=param[2];
  940.         while( mygetchar()!='r') ;
  941.  
  942.         Write(OldCin,"\033[6n",4);
  943.         get_seq( param );
  944.         row=param[0];
  945.  
  946.         SETCON;
  947.  
  948.         cnt= height-row+1;
  949.         noquick= height<o_minrows;
  950.     }
  951.  
  952.     sprintf(scrollstr,"\033[%cS\033[%cA", o_scroll+'0', o_scroll+'0');
  953.  
  954.     if( truecin )
  955.         Myprocess->pr_CIS = DEVTAB(stdin) = truecin;
  956. }
  957. #else
  958. /* old prepscroll() with isconsole() instead of just IsInteractive() */
  959. void
  960. prepscroll( int fromtee )
  961. {
  962.     BPTR truecin=0;
  963.     long param[8];
  964.  
  965.     row=height=0;
  966.     FromTee=fromtee;
  967.  
  968.     if(( noquick=!o_scroll || o_noraw || o_nofastscr || o_vt100))
  969.         return;
  970.  
  971.     if(( noquick=!isconsole(Myprocess->pr_COS) && !fromtee ))
  972.         return;
  973.  
  974.     if( !isconsole(Myprocess->pr_CIS)) {
  975.         truecin=Myprocess->pr_CIS;
  976.  
  977.         if( noquick=!isconsole(OldCin) )
  978.             return;
  979.  
  980.         Myprocess->pr_CIS = DEVTAB(stdin) = OldCin;
  981.     }
  982.  
  983.     if( !CHARSWAIT(stdin) ) {
  984.         SETRAW;
  985.         Write(OldCin,"\033[ q",4);
  986.         get_seq( param );
  987.         height=param[2];
  988.         while( mygetchar()!='r') ;
  989.  
  990.         Write(OldCin,"\033[6n",4);
  991.         get_seq( param );
  992.         row=param[0];
  993.  
  994.         SETCON;
  995.  
  996.         cnt= height-row+1;
  997.         noquick= height<o_minrows;
  998.     }
  999.  
  1000.     sprintf(scrollstr,"\033[%cS\033[%cA", o_scroll+'0', o_scroll+'0');
  1001.  
  1002.     if( truecin )
  1003.         Myprocess->pr_CIS = DEVTAB(stdin) = truecin;
  1004. }
  1005. #endif
  1006.  
  1007. static int
  1008. get_seq( long *param )
  1009. {
  1010.     int c;
  1011.  
  1012.     while( (c=mygetchar())!=155 ) ;
  1013.     do {
  1014.         *param=0;
  1015.         while( (c=mygetchar())>='0' && c<='9' )
  1016.             *param=10* *param + c-'0';
  1017.         param++;
  1018.     } while( c==';' );
  1019.  
  1020.     return c;
  1021. }
  1022.  
  1023.  
  1024. void
  1025. quickscroll( void )
  1026. {
  1027.     if( noquick ) return;
  1028.  
  1029.     if( --cnt<=0 ) {
  1030.         cnt=o_scroll;
  1031.         fprintf( FromTee ? stderr : stdout, "%s",scrollstr);
  1032.     }
  1033. }
  1034.  
  1035. int
  1036. do_keymap( void )
  1037. {
  1038.     int i, n, len;
  1039.     USHORT *tmp, *put, *get, *map;
  1040.     char   *ind;
  1041.  
  1042. #if 0
  1043.     if( ac==1 ) {
  1044.         for( get=Keymap[0]; *get; get+=2 )
  1045.             printf("%4d %4d\n",get[0],get[1]);
  1046.         return 0;
  1047.     }
  1048. #endif
  1049.  
  1050.     n=myatoi(av[1],0,7);
  1051.     if( atoierr ) return 20;
  1052.  
  1053.     map=Keymap[n]; len=0;
  1054.     if( map )
  1055.         for( len=0; map[2*len]; len++ ) ;
  1056.  
  1057.     put=tmp=salloc((len+ac)*2*sizeof(USHORT));
  1058.     for( i=2; i<ac; i++ ) {
  1059.         if( !(ind=index(av[i],'='))) {
  1060.             ierror( av[i],500);
  1061.             free( tmp );
  1062.             return 20;
  1063.         }
  1064.         *put++=atoi(av[i]);
  1065.         *put++=atoi(ind+1);
  1066.     }
  1067.  
  1068.     for( i=0; i<len; i++ ) {
  1069.         for( get=tmp; get<put; get+=2 )
  1070.             if( *get==map[2*i] )
  1071.                 break;
  1072.         if( get==put ) {
  1073.             *put++=map[2*i];
  1074.             *put++=map[2*i+1];
  1075.         }
  1076.     }
  1077.     *put++=0;
  1078.     *put  =0;
  1079.  
  1080.     if( map && map!=DefKeymap0 && map!=DefKeymap1 )
  1081.         free( map );
  1082.     Keymap[n]=tmp;
  1083.     Curmap=0;
  1084.  
  1085.     return 0;
  1086. }
  1087.  
  1088. static int
  1089. myget( void )
  1090. {
  1091.     int c;
  1092.     UBYTE uc;
  1093.  
  1094.     if( unget )
  1095.         c=unget, unget=0;
  1096.     else if( tyahdptr && *tyahdptr ) {
  1097.         c = *tyahdptr++;
  1098.     } else {
  1099.         tyahdptr=NULL;
  1100.         fflush(stdout);
  1101.         /* replacement for c=getchar() */
  1102.         if (Read( Input(), &uc, 1) != 1)
  1103.             c = -1;
  1104.         else
  1105.             c = uc;
  1106.     }
  1107.  
  1108.     return c;
  1109. }
  1110.  
  1111. static void
  1112. myunget(int c)
  1113. {
  1114.     unget=c;
  1115. }
  1116.  
  1117. int
  1118. newwidth( void )
  1119. {
  1120.     get_WindowBounds_def(&w_width,&w_height);    /* 80 x 24 */
  1121.     if (!get_WindowBounds_env(&w_width,&w_height)) {
  1122.         if ( !o_nowindow && Mywindow ) {
  1123.             w_width =(Mywindow->Width - Mywindow->BorderLeft - Mywindow->BorderRight)/
  1124.                       Mywindow->RPort->TxWidth;
  1125.             w_height=(Mywindow->Height- Mywindow->BorderTop  - Mywindow->BorderBottom)/
  1126.                       Mywindow->RPort->TxHeight;
  1127.         }
  1128.         else if ( !o_noraw && !o_vt100 ) {
  1129.             get_WindowBounds_Output(&w_width,&w_height,o_timeout);
  1130.         }
  1131.     }
  1132.     /* kprintf("newwidth:  %ld ╫ %ld  (timeout %ld)\n",w_width,w_height,o_timeout); */
  1133.     if( w_width<1 ) w_width=1;    /* crash after resizing was reported */
  1134.     return w_width;
  1135. }
  1136.  
  1137.  
  1138.  
  1139. #else
  1140.  
  1141. void prepscroll(int fromtee) {}
  1142. void quickscroll(void) {}
  1143. int  do_keymap( void ) {}
  1144. void setrawcon( long flag, int ievent ) {}
  1145. int  newwidth( void ) {}
  1146. void initmap(void) {}
  1147.  
  1148. #endif
  1149.  
  1150. extern struct MsgPort *Console;
  1151.  
  1152. #if 0
  1153. int isconsole( BPTR fh )
  1154. {
  1155.     return( IsInteractive(fh) );
  1156. }
  1157. #else
  1158. int isconsole( BPTR fh )
  1159. {
  1160.     return ((struct FileHandle *)(4*fh))->fh_Type==Console &&
  1161.         IsInteractive(fh);
  1162. }
  1163. #endif
  1164.  
  1165.