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