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