home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK5 / DOS_50 / PVIC.ZIP / TERMIN.C < prev    next >
C/C++ Source or Header  |  1993-04-21  |  9KB  |  490 lines

  1. #include <stdio.h>
  2. #include "pvic.h"
  3. #include "locdefs.h"
  4.  
  5.  
  6. /* Translate table provides translations for escape sequences. In
  7. is the original escape sequence. Out[0] is the replacement for this
  8. escape sequence while in command mode. Out[1] is the replacement
  9. while in insert mode. */
  10. static struct {
  11.     char *in;
  12.     char *out[2];
  13. } translate_table[] = {
  14.     LOCAL_BACKSPACE_KEY,
  15.     {
  16.         "\010",
  17.         "\010"
  18.     },
  19.     LOCAL_TAB_KEY,
  20.     {
  21.         "\011",
  22.         "\011"
  23.     },
  24.     LOCAL_RETURN_KEY,
  25.     {
  26.         "\015",
  27.         "\015"
  28.     },
  29.     LOCAL_ESC_KEY,
  30.     {
  31.         "\033",
  32.         "\033"
  33.     },
  34.     LOCAL_DEL_KEY,
  35.     {
  36.         "\010",
  37.         "\010"
  38.     },
  39.     DEFAULT_TERMCAP_KEY_F1, 
  40.     {
  41.         ":help\n",
  42.         "\033:help\n"
  43.     },
  44.     DEFAULT_TERMCAP_KEY_F2, 
  45.     {
  46.         ":help\n",
  47.         "\033:help\n"
  48.     },
  49.     DEFAULT_TERMCAP_KEY_IC, 
  50.     {
  51.         "i",
  52.         "\033"
  53.     },
  54.     DEFAULT_TERMCAP_KEY_DC, 
  55.     {
  56.         "\010",
  57.         "\010"
  58.     },
  59.     DEFAULT_TERMCAP_KEY_HOME, 
  60.     {
  61.         "0",
  62.         "\0330"
  63.     },
  64.     DEFAULT_TERMCAP_KEY_EOL, 
  65.     {
  66.         "$",
  67.         "\033$"
  68.     },
  69.     DEFAULT_TERMCAP_KEY_PPAGE, 
  70.     {
  71.         "\025",
  72.         "\033\025"
  73.     },
  74.     DEFAULT_TERMCAP_KEY_NPAGE, 
  75.     {
  76.         "\004",
  77.         "\033\004"
  78.     },
  79.     DEFAULT_TERMCAP_KEY_UP, 
  80.     {
  81.         "k",
  82.         "\033k"
  83.     },
  84.     DEFAULT_TERMCAP_KEY_DOWN, 
  85.     {
  86.         "j",
  87.         "\033j"
  88.     },
  89.     DEFAULT_TERMCAP_KEY_LEFT, 
  90.     {
  91.         "h",
  92.         "\033h"
  93.     },
  94.     DEFAULT_TERMCAP_KEY_RIGHT, 
  95.     {
  96.         "l",
  97.         "\033l"
  98.     },
  99.     DEFAULT_TERMCAP_KEY_BACKSPACE, 
  100.     {
  101.         "\010",
  102.         "\010"
  103.     },
  104.     ALT_TERMCAP_KEY_F1, 
  105.     {
  106.         ":help\n",
  107.         "\033:help\n",
  108.     },
  109.     ALT_TERMCAP_KEY_F2, 
  110.     {
  111.         ":help\n",
  112.         "\033:help\n"
  113.     },
  114.     ALT_TERMCAP_KEY_IC, 
  115.     {
  116.         "i",
  117.         "\033"
  118.     },
  119.     ALT_TERMCAP_KEY_DC, 
  120.     {
  121.         "\010",
  122.         "\010"
  123.     },
  124.     ALT_TERMCAP_KEY_HOME, 
  125.     {
  126.         "0",
  127.         "\0330"
  128.     },
  129.     ALT_TERMCAP_KEY_EOL, 
  130.     {
  131.         "$",
  132.         "\033$"
  133.     },
  134.     ALT_TERMCAP_KEY_PPAGE, 
  135.     {
  136.         "\025",
  137.         "\033\025"
  138.     },
  139.     ALT_TERMCAP_KEY_NPAGE, 
  140.     {
  141.         "\004",
  142.         "\033\004"
  143.     },
  144.     ALT_TERMCAP_KEY_UP, 
  145.     {
  146.         "k",
  147.         "\033k"
  148.     },
  149.     ALT_TERMCAP_KEY_DOWN, 
  150.     {
  151.         "j",
  152.         "\033j"
  153.     },
  154.     ALT_TERMCAP_KEY_LEFT, 
  155.     {
  156.         "h",
  157.         "\033h"
  158.     },
  159.     ALT_TERMCAP_KEY_RIGHT, 
  160.     {
  161.         "l",
  162.         "\033l"
  163.     },
  164.     ALT_TERMCAP_KEY_BACKSPACE, 
  165.     {
  166.         "\010",
  167.         "\010"
  168.     },
  169.     NULL,
  170.     {
  171.         NULL, NULL
  172.     }
  173. };
  174.  
  175.  
  176. /* Initialize the translation table used by read_input(). */
  177. void init_translate_table()
  178. {
  179.     translate_table[5].in=termcap_key_f1;
  180.     translate_table[6].in=termcap_key_f2;
  181.     translate_table[7].in=termcap_key_ic;
  182.     translate_table[8].in=termcap_key_dc;
  183.     translate_table[9].in=termcap_key_home;
  184.     translate_table[10].in=termcap_key_eol;
  185.     translate_table[11].in=termcap_key_ppage;
  186.     translate_table[12].in=termcap_key_npage;
  187.     translate_table[13].in=termcap_key_up;
  188.     translate_table[14].in=termcap_key_down;
  189.     translate_table[15].in=termcap_key_left;
  190.     translate_table[16].in=termcap_key_right;
  191.     translate_table[17].in=termcap_key_backspace;
  192. }
  193.  
  194.  
  195.  
  196. /* Read characters from the input, and translate incomming escape sequences. */
  197. void read_input()
  198. {
  199.     static char c_buffer[32]="";
  200.     static char c_buffer_count=0;
  201.     int c;
  202.     int i,j;
  203.         int found;
  204.     int found_length;
  205.  
  206.     if(need_redraw)update_screen(0);
  207.     fflush(stdout);
  208.  
  209.     /* If nothing in c_buffer, get a character and put it in c_buffer.
  210.     If the character read is '\0' it is translated into a '\200',
  211.     because a '\0' can not apear in a string. */
  212.     if(c_buffer_count==0)
  213.     {
  214.         c=local_get_character();
  215.         if(c=='\0')c='\200';
  216.         c_buffer[c_buffer_count]=c;
  217.         c_buffer_count++;
  218.         c_buffer[c_buffer_count]='\0';
  219.     }
  220.  
  221.     /* Set found to -1 to indicate we have not yet found a translation
  222.     for the characters in c_buffer. */
  223.     found=-1;
  224.  
  225. check_input:
  226.  
  227.     /* Try to find a translation for the characters in c_buffer. */
  228.     for(i=0;translate_table[i].in!=NULL;i++)
  229.     {
  230.         /* Compare c_buffer with translate_table[i].in. */
  231.         for(j=0;j<=c_buffer_count;j++)
  232.         {
  233.             /* If difference between c_buffer and 
  234.             translate_table[i].in are found, we can stop 
  235.             comparing. */
  236.             if(c_buffer[j]!=translate_table[i].in[j])break;
  237.  
  238.             /* If all characters up to the terminating '\0' are
  239.             equal, we found a matching entry in translate
  240.             table. */
  241.             if(c_buffer[j]=='\0' && 
  242.                 translate_table[i].in[j]=='\0')
  243.             {
  244.  
  245.                 /* If we haven't yet found an entry of
  246.                 this length, rember it. */
  247.                 if(found==-1 || found_length<j)
  248.                 {
  249.                     found=i;
  250.                     found_length=j;
  251.                 }
  252.  
  253.                 /* Continue serching. Perhaps there is 
  254.                 an longer entry of witch the first part is
  255.                 matching. */
  256.                 goto next_entry;
  257.             }
  258.  
  259.         }
  260.  
  261.         /* If c_buffer[j]=='\0', we have stopped comparing because we
  262.         found an escape sequence of which the first part did match
  263.         with the characters in c_buffer. More characters have to be
  264.         read. */
  265.         if(c_buffer[j]=='\0')
  266.         {
  267.             /* If there is nothing to be read from the terminal,
  268.             or if we do dot know whether there is something to
  269.             be read (local_is_input_pending()==-1), test for
  270.             for new input during one second. */
  271.             if(local_is_input_pending()<=0)
  272.                 test_n_seconds_for_input(1);
  273.  
  274.             /* If there is something to be read from the terminal,
  275.             or if we do dot know whether there is something to
  276.             be read (local_is_input_pending()==-1), read the next
  277.             character, and put it into c_buffer. If the character 
  278.             read is '\0' it is translated into a '\200', because 
  279.             a '\0' can not apear in a string. */
  280.             if(local_is_input_pending()!=0)
  281.             {
  282.                 c=local_get_character();
  283.                 if(c=='\0')c='\200';
  284.                 c_buffer[c_buffer_count]=c;
  285.                 c_buffer_count++;
  286.                 c_buffer[c_buffer_count]='\0';
  287.                 goto check_input;
  288.             }
  289.  
  290.             /* If a translation is found, the translation is 
  291.             put into the input buffer, and we return to
  292.             the calling routine. */
  293.             else if(found!=-1)
  294.             {
  295.                 /* Translation depends on command or insert 
  296.                 mode. */
  297.                 if(current_status==STATUS_NORMAL)
  298.                 {
  299.                     put_string_into_input_buffer(
  300.                         translate_table[found].out[0]);
  301.                 }
  302.                 else 
  303.                 {
  304.                     put_string_into_input_buffer(
  305.                         translate_table[found].out[1]);
  306.                 }
  307.  
  308.                 /* Remove the original characters from 
  309.                 c_buffer. */
  310.                 c_buffer_count-=found_length;
  311.                 for(i=0;i<c_buffer_count;i++)
  312.                 {
  313.                     c_buffer[i]=c_buffer[i+found_length];
  314.                 }
  315.  
  316.                 /* Return. The calling routine will process 
  317.                 the characters put in the input buffer. */
  318.                 return;
  319.  
  320.             }
  321.             else
  322.             {
  323.                 /* Put the first character from c_buffer into 
  324.                 the input buffer. */
  325.                 put_char_into_input_buffer(c_buffer[0]);
  326.  
  327.                 /* And remove it from c_buffer. */
  328.                 c_buffer_count--;
  329.                 for(i=0;i<=c_buffer_count;i++)
  330.                 {
  331.                     c_buffer[i]=c_buffer[i+1];
  332.                 }
  333.  
  334.                 /* Return. The calling routine will process 
  335.                 the characters put in the input buffer. */
  336.                 return;
  337.             }
  338.         }
  339. next_entry:;
  340.     }
  341.  
  342.     /* If a translation is found, the translation is put into
  343.     the input buffer. */
  344.     if(found!=-1)
  345.     {
  346.         /* Translation depends on command or insert mode. */
  347.         if(current_status==STATUS_NORMAL)
  348.         {
  349.             put_string_into_input_buffer(
  350.                 translate_table[found].out[0]);
  351.         }
  352.         else 
  353.         {
  354.             put_string_into_input_buffer(
  355.                 translate_table[found].out[1]);
  356.         }
  357.  
  358.         /* Remove the original characters from c_buffer. */
  359.         c_buffer_count-=found_length;
  360.         for(i=0;i<=c_buffer_count;i++)
  361.         {
  362.             c_buffer[i]=c_buffer[i+found_length];
  363.         }
  364.  
  365.         /* Return. The calling routine will process the characters 
  366.         put in the input buffer. */
  367.         return;
  368.  
  369.     }
  370.  
  371.     /* Put the first character from c_buffer into the input buffer. */
  372.     put_char_into_input_buffer(c_buffer[0]);
  373.  
  374.     /* And remove it from c_buffer. */
  375.     c_buffer_count--;
  376.     for(i=0;i<=c_buffer_count;i++)
  377.     {
  378.         c_buffer[i]=c_buffer[i+1];
  379.     }
  380.  
  381.     /* Return. The calling routine will process the characters 
  382.     put in the input buffer. */
  383.     return;
  384. }
  385.  
  386.  
  387.  
  388.  
  389. #define    RBSIZE    1024
  390. static char input_buffer[RBSIZE];
  391. static char *pointer_into_input_buffer = NULL;
  392.  
  393. void put_string_into_input_buffer(s)
  394. char *s;
  395. {
  396.     if (s == NULL) {        /* clear the stuff buffer */
  397.         pointer_into_input_buffer = NULL;
  398.         return;
  399.     }
  400.  
  401.     if (pointer_into_input_buffer == NULL) {
  402.         strcpy(input_buffer,s);
  403.         pointer_into_input_buffer = input_buffer;
  404.     } else
  405.         strcat(input_buffer,s);
  406. }
  407.  
  408.  
  409.  
  410. void put_char_into_input_buffer(c)
  411. char c;
  412. {
  413.     int i;
  414.  
  415.     if (pointer_into_input_buffer == NULL) 
  416.     {
  417.         input_buffer[0]=c;
  418.         input_buffer[1]='\0';
  419.         pointer_into_input_buffer = input_buffer;
  420.     } 
  421.     else 
  422.     {
  423.         for(i=0;input_buffer[i]!='\0';i++);
  424.         input_buffer[i]=c;
  425.         input_buffer[i+1]='\0';
  426.     }
  427. }
  428.  
  429.  
  430.  
  431. void put_int_into_input_buffer(n)
  432. int n;
  433. {
  434.     char buffer[32];
  435.  
  436.     sprintf(buffer,"%d",n);
  437.     put_string_into_input_buffer(buffer);
  438. }
  439.  
  440.  
  441.  
  442. int get_char_from_input_buffer()
  443. {
  444.     int c;
  445.  
  446.     for(;;)
  447.     {
  448.         if ( pointer_into_input_buffer != NULL ) 
  449.         {
  450.             c = *pointer_into_input_buffer++;
  451.             if ( *pointer_into_input_buffer == '\0' ) 
  452.             {
  453.                 input_buffer[0] = '\0';
  454.                 pointer_into_input_buffer = NULL;
  455.             }
  456.             return(c);
  457.         }
  458.         read_input();
  459.     } 
  460. }
  461.  
  462.  
  463.  
  464. /*
  465.  * Return non-zero if input is pending.
  466.  */
  467. int is_input_pending()
  468. {
  469.     return (pointer_into_input_buffer != NULL) || 
  470.         local_is_input_pending()>0;
  471. }
  472.  
  473.  
  474.  
  475.  
  476. /* Loop for a while testing for new input. */
  477. void test_n_seconds_for_input(seconds)
  478. int seconds;
  479. {
  480.     long t;
  481.  
  482.     fflush(stdout);
  483.  
  484.     t=time(NULL);
  485.     while(time(NULL)<t+1+seconds && local_is_input_pending()<=0);
  486. }
  487.  
  488.  
  489.  
  490.