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