]> pd.if.org Git - pd_readline/blob - pdmenu7.c
More good progress.
[pd_readline] / pdmenu7.c
1 \r
2 \r
3 /*  pd_readline2.c                                          */  \r
4 /*  Status (as at 26th Aug 2012) : useful progress.         */ \r
5 /*  Keystroke sequences (along with the special flags       */ \r
6 /*  like Esc, Ctrl, Alt etc are now stored in a buffer      */ \r
7 /*  ( an array of structs ).                                */    \r
8 \r
9 /*  The code can now distinguish between a printable key    */ \r
10 /*  and a key that should not be printed.                   */ \r
11 \r
12 /*  It will still be some time before this is a REAL        */ \r
13 /*  readline, but we are "on the way"......                 */     \r
14 /*  This code is released to the public domain.             */ \r
15 /*  "Share and enjoy...."  ;)                               */  \r
16 \r
17 \r
18 #include <string.h>   \r
19 #include <stdio.h> \r
20 #include <termios.h>  /* For getch()  */  \r
21 \r
22 /* This implementation of getch() is from here - */ \r
23 /* http://wesley.vidiqatch.org/                  */ \r
24 /* Thanks, Wesley!                               */  \r
25 static struct termios old, new;\r
26 \r
27 /* Initialize new terminal i/o settings */\r
28 void initTermios(int echo) {\r
29     tcgetattr(0, &old); /* grab old terminal i/o settings */\r
30     new = old; /* make new settings same as old settings */\r
31     new.c_lflag &= ~ICANON; /* disable buffered i/o */\r
32     new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */\r
33     tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */\r
34 }\r
35 \r
36 \r
37 /* Restore old terminal i/o settings */\r
38 void resetTermios(void) {\r
39     tcsetattr(0, TCSANOW, &old);\r
40 }\r
41 \r
42 \r
43 /* Read 1 character - echo defines echo mode */\r
44 char getch_(int echo) {\r
45     char ch;\r
46     initTermios(echo);\r
47     ch = getchar();\r
48     resetTermios();\r
49     return ch;\r
50 }\r
51 \r
52 \r
53 /* Read 1 character without echo */\r
54 char getch(void) {\r
55     return getch_(0);\r
56 }\r
57 \r
58 \r
59 /* Read 1 character with echo */\r
60 char getche(void) {\r
61     return getch_(1);\r
62\r
63 \r
64 \r
65 \r
66 /*  Helper function, to let us see if a .history file */ \r
67 /*  exists in the current directory.  */ \r
68 int fexists(char *fname)\r
69 {  \r
70 \r
71    FILE *fptr ;         \r
72         \r
73    fptr = fopen(fname, "r") ;  \r
74    \r
75    if ( !fptr )  return -1 ;  /* File does not exist in dir. */         \r
76          \r
77    fclose(fptr);  \r
78    return 0;    /* File DOES exist in dir.  */          \r
79 \r
80\r
81 \r
82 \r
83  /* Struct to store key sequences */ \r
84 typedef struct { \r
85            int fnkey; \r
86            int ctrl; \r
87            int alt ; \r
88        int shf ; \r
89        int esc ; \r
90        int lbr ;  /* For left-bracket ([) of escape sequences */ \r
91        int key; \r
92    } keyseq ;         \r
93 \r
94 \r
95 \r
96 \r
97 \r
98 int main(void)\r
99 {\r
100         \r
101   printf("Public Domain Readline \n");              \r
102       \r
103   /* Buffer - an array of keyseq structs.                     */  \r
104   /* Note - now that we store the keystrokes in here,         */ \r
105   /* we can look at the various flags and decide whether to   */ \r
106   /* "echo" the key (as normal) or suppress it (as with an    */ \r
107   /* arrow key).                                              */    \r
108   keyseq buffer[80] ;   \r
109   \r
110   /* Buffer "pointer"  */ \r
111   int bufpnt = 0; \r
112   \r
113   \r
114   /* Test for existence of history file. */  \r
115   int exists;  \r
116   exists = fexists(".history"); \r
117   printf("Result: %d \n", exists);  \r
118   \r
119   while(1) \r
120     {  \r
121                    \r
122       int key = getch(); \r
123        \r
124       /* Printable chars. */  \r
125       if ( (key >= 32)  && (key <= 126) ) \r
126       { \r
127                 /* We have a printable key so print it. */   \r
128                 putchar(key);                   \r
129         buffer[bufpnt].key = key;  \r
130         bufpnt += 1; \r
131       }  \r
132                                                                        \r
133       /* Up arrow is 27, 91, 65.    ( ESC [ A )   */   \r
134       /* Down arrow is 27, 91, 66.  ( ESC [ B )   */ \r
135       /* Right arrow is 27, 91, 67. ( ESC [ C )   */ \r
136       /* Left arrow is 27, 91, 68.  ( ESC [ D )   */    \r
137       /* Function keys.     */ \r
138       /* F2 is 27, 79, 81.  */  \r
139       /* F3 is 27, 79, 82.  */  \r
140       /* F4 is 27, 79, 83.  */  \r
141            \r
142                 \r
143       else if(key == 27)        \r
144           {  \r
145                           \r
146                           buffer[bufpnt].esc = 1;                        \r
147                           key = getch(); \r
148               if(key == 91)               \r
149               buffer[bufpnt].lbr = 1;                \r
150               key = getch(); \r
151               if( (key >= 65) && (key <= 68) )  \r
152                {                                 \r
153                                  buffer[bufpnt].key = key;                  \r
154                }                                  \r
155             bufpnt += 1;            \r
156           } \r
157               \r
158                                           \r
159                                                  \r
160     /* The Enter key exits. Enter is 10 decimal */        \r
161         else if(key == 10)  \r
162                 { \r
163                          puts("\n");  \r
164                          int j ; \r
165                    /* Print the array of structs. */ \r
166                      for (j=0; j<20; j++)       \r
167                      { \r
168                             printf("Fnkey: %d ", buffer[j].fnkey  ) ; \r
169                             printf("Ctrl:  %d ", buffer[j].ctrl   ) ;   \r
170                             printf("Alt:   %d ", buffer[j].alt    ) ; \r
171                             printf("Shf:   %d ", buffer[j].shf    ) ; \r
172                             printf("Esc:   %d ", buffer[j].esc    ) ; \r
173                             printf("Lbr:   %d ", buffer[j].lbr    ) ;  \r
174                     printf("Key:   %d \n", buffer[j].key  ) ; \r
175                  }                      \r
176                                           \r
177              break;           \r
178          }  /* Key = Enter */   \r
179     }                \r
180                                       \r
181         return 0;\r
182 }  \r
183 \r
184 \r
185 \r
186 \r