Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:19

0001 /*
0002  *
0003  *  Handle keys for the shell.
0004  *
0005  *  Author:
0006  *
0007  *   Chris Johns (chrisj@rtems.org)
0008  *
0009  *  The license and distribution terms for this file may be
0010  *  found in the file LICENSE in this distribution or at
0011  *  http://www.rtems.org/license/LICENSE.
0012  */
0013 
0014 #ifdef HAVE_CONFIG_H
0015 #include "config.h"
0016 #endif
0017 
0018 #include <stdio.h>
0019 #include <time.h>
0020 
0021 #include <rtems.h>
0022 #include <rtems/error.h>
0023 #include <rtems/shell.h>
0024 #include <rtems/shellconfig.h>
0025 #include "internal.h"
0026 
0027 /*
0028  * Taken from the monitor code.
0029  */
0030 
0031 /*
0032  * Translation tables. Not sure if this is the best way to
0033  * handle this, how-ever I wish to avoid the overhead of
0034  * including a more complete and standard environment such
0035  * as ncurses.
0036  */
0037 
0038 struct translation_table
0039 {
0040   char                     expecting;
0041   const struct translation_table *branch;
0042   unsigned int             key;
0043 };
0044 
0045 static const struct translation_table trans_one[] =
0046 {
0047   { '\x7e', 0, RTEMS_SHELL_KEYS_HOME },
0048   { 0,      0, 0 }
0049 };
0050 
0051 static const struct translation_table trans_two[] =
0052 {
0053   { '~', 0, RTEMS_SHELL_KEYS_INS },
0054   { 0,   0, 0 }
0055 };
0056 
0057 static const struct translation_table trans_three[] =
0058 {
0059   { '~', 0, RTEMS_SHELL_KEYS_DEL },
0060   { 0,   0, 0 }
0061 };
0062 
0063 static const struct translation_table trans_tab_csi[] =
0064 {
0065   { '1', trans_one,   0 },
0066   { '2', trans_two,   0 },
0067   { '3', trans_three, 0 },
0068   { 'A', 0,           RTEMS_SHELL_KEYS_UARROW },
0069   { 'B', 0,           RTEMS_SHELL_KEYS_DARROW },
0070   { 'D', 0,           RTEMS_SHELL_KEYS_LARROW },
0071   { 'C', 0,           RTEMS_SHELL_KEYS_RARROW },
0072   { 'F', 0,           RTEMS_SHELL_KEYS_END },
0073   { 'H', 0,           RTEMS_SHELL_KEYS_HOME },
0074   { 0,   0,           0 }
0075 };
0076 
0077 static const struct translation_table trans_tab_O[] =
0078 {
0079   { '1', 0, RTEMS_SHELL_KEYS_F1 },
0080   { '2', 0, RTEMS_SHELL_KEYS_F2 },
0081   { '3', 0, RTEMS_SHELL_KEYS_F3 },
0082   { '4', 0, RTEMS_SHELL_KEYS_F4 },
0083   { '5', 0, RTEMS_SHELL_KEYS_F5 },
0084   { '6', 0, RTEMS_SHELL_KEYS_F6 },
0085   { '7', 0, RTEMS_SHELL_KEYS_F7 },
0086   { '8', 0, RTEMS_SHELL_KEYS_F8 },
0087   { '9', 0, RTEMS_SHELL_KEYS_F9 },
0088   { ':', 0, RTEMS_SHELL_KEYS_F10 },
0089   { 'F', 0, RTEMS_SHELL_KEYS_END },
0090   { 'P', 0, RTEMS_SHELL_KEYS_F1 },
0091   { 'Q', 0, RTEMS_SHELL_KEYS_F2 },
0092   { 'R', 0, RTEMS_SHELL_KEYS_F3 },
0093   { 'S', 0, RTEMS_SHELL_KEYS_F4 },
0094   { 'T', 0, RTEMS_SHELL_KEYS_F5 },
0095   { 'U', 0, RTEMS_SHELL_KEYS_F6 },
0096   { 'V', 0, RTEMS_SHELL_KEYS_F7 },
0097   { 'W', 0, RTEMS_SHELL_KEYS_F8 },
0098   { 'X', 0, RTEMS_SHELL_KEYS_F9 },
0099   { 'Y', 0, RTEMS_SHELL_KEYS_F10 },
0100   { 0,   0, 0 }
0101 };
0102 
0103 static const struct translation_table trans_tab[] =
0104 {
0105   { '[', trans_tab_csi, 0 },    /* CSI command sequences */
0106   { 'O', trans_tab_O,   0 },    /* O are the fuction keys */
0107   { 0,   0,             0 }
0108 };
0109 
0110 /*
0111  * Perform a basic tranlation for some ANSI/VT100 key codes.
0112  * This code could do with a timeout on the ESC as it is
0113  * now lost from the input stream. It is not* used by the
0114  * line editor below so considiered not worth the effort.
0115  */
0116 
0117 unsigned int
0118 rtems_shell_getchar (FILE *in)
0119 {
0120   const struct translation_table *translation = 0;
0121   for (;;)
0122   {
0123     int c = fgetc (in);
0124     if (c == EOF)
0125       return EOF;
0126     if (c == 27)
0127       translation = trans_tab;
0128     else
0129     {
0130       /*
0131        * If no translation happing just pass through
0132        * and return the key.
0133        */
0134       if (translation)
0135       {
0136         /*
0137          * Scan the current table for the key, and if found
0138          * see if this key is a fork. If so follow it and
0139          * wait else return the extended key.
0140          */
0141         int index    = 0;
0142         int branched = 0;
0143         while ((translation[index].expecting != '\0') ||
0144                (translation[index].key != '\0'))
0145         {
0146           if (translation[index].expecting == c)
0147           {
0148             /*
0149              * A branch is take if more keys are to come.
0150              */
0151             if (translation[index].branch == 0)
0152               return RTEMS_SHELL_KEYS_EXTENDED | translation[index].key;
0153             else
0154             {
0155               translation = translation[index].branch;
0156               branched    = 1;
0157               break;
0158             }
0159           }
0160           index++;
0161         }
0162         /*
0163          * Who knows what these keys are, just drop them.
0164          */
0165         if (!branched)
0166           translation = 0;
0167       }
0168       else
0169         return c;
0170     }
0171   }
0172 }
0173