]> pd.if.org Git - pd_readline/blob - pdmenu3.c
Very good progress.
[pd_readline] / pdmenu3.c
1 \r
2 \r
3 /*  pdmenu.c                                                */  \r
4 /*  This code is aimed at helping those who would like to   */ \r
5 /*  create menus without using the curses library.          */ \r
6 /*  It creates a count variable (which could be used to     */ \r
7 /*  keep track of which item is highlighted). Using the     */ \r
8 /*  up and down arrow keys increments and decrements the    */ \r
9 /*  count variable. Finally, when you press Enter, the      */ \r
10 /*  value of the count variable is printed and the program  */ \r
11 /*  exits.                                                  */       \r
12 /*  This code is released to the public domain.             */ \r
13 /*  "Share and enjoy...."  ;)                               */  \r
14 \r
15 \r
16 #include <string.h>   \r
17 #include <stdio.h> \r
18 #include <termios.h>  /* For getch()  */  \r
19 \r
20 /* This implementation of getch() is from here - */ \r
21 /* http://wesley.vidiqatch.org/                  */ \r
22 /* Thanks, Wesley!                               */  \r
23 static struct termios old, new;\r
24 \r
25 /* Initialize new terminal i/o settings */\r
26 void initTermios(int echo) {\r
27     tcgetattr(0, &old); /* grab old terminal i/o settings */\r
28     new = old; /* make new settings same as old settings */\r
29     new.c_lflag &= ~ICANON; /* disable buffered i/o */\r
30     new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */\r
31     tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */\r
32 }\r
33 \r
34 \r
35 /* Restore old terminal i/o settings */\r
36 void resetTermios(void) {\r
37     tcsetattr(0, TCSANOW, &old);\r
38 }\r
39 \r
40 \r
41 /* Read 1 character - echo defines echo mode */\r
42 char getch_(int echo) {\r
43     char ch;\r
44     initTermios(echo);\r
45     ch = getchar();\r
46     resetTermios();\r
47     return ch;\r
48 }\r
49 \r
50 \r
51 /* Read 1 character without echo */\r
52 char getch(void) {\r
53     return getch_(0);\r
54 }\r
55 \r
56 \r
57 /* Read 1 character with echo */\r
58 char getche(void) {\r
59     return getch_(1);\r
60\r
61 \r
62 \r
63 \r
64 /*  Helper function, to let us see if a .history file */ \r
65 /*  exists in the current directory.  */ \r
66 int fexists(char *fname)\r
67 {  \r
68 \r
69    FILE *fptr ;         \r
70         \r
71    fptr = fopen(fname, "r") ;  \r
72    \r
73    if ( !fptr )  return -1 ;  /* File does not exist in dir. */         \r
74          \r
75    fclose(fptr);  \r
76    return 0;    /* File DOES exist in dir.  */          \r
77 \r
78\r
79 \r
80 \r
81  /* Struct to store key sequences */ \r
82 typedef struct { \r
83            int fnkey; \r
84            int ctrl; \r
85            int alt ; \r
86        int shf ; \r
87        int esc ; \r
88        int lbr ;  /* For left-bracket ([) of escape sequences */ \r
89        int key; \r
90    } keyseq ;         \r
91 \r
92 \r
93 \r
94 \r
95 \r
96 int main(void)\r
97 {\r
98         \r
99   printf("Public Domain Menu Program \n");              \r
100  \r
101     \r
102   keyseq myseq;      \r
103        \r
104   \r
105   /* Buffer */  \r
106   keyseq buffer[80] ;   \r
107   \r
108   /* Buffer "pointer"  */ \r
109   int bufpnt = 0; \r
110   \r
111   \r
112   /* Test for existence of history file. */  \r
113   int exists;  \r
114   exists = fexists(".history"); \r
115   printf("Result: %d \n", exists);  \r
116   \r
117   while(1) \r
118     {  \r
119                    \r
120       int key = getch(); \r
121        \r
122       /* Printable chars. */  \r
123       if ( (key >= 32)  && (key <= 126) ) \r
124       { \r
125                 myseq.key = key;   \r
126         buffer[bufpnt] = myseq;  \r
127         bufpnt += 1; \r
128       }  \r
129                                                                        \r
130       /* Up arrow is 27, 91, 65.    ( ESC [ A )   */   \r
131       /* Down arrow is 27, 91, 66.  ( ESC [ B )   */ \r
132       /* Right arrow is 27, 91, 67. ( ESC [ C )   */ \r
133       /* Left arrow is 27, 91, 68.  ( ESC [ D )   */    \r
134       /* Function keys.     */ \r
135       /* F2 is 27, 79, 81.  */  \r
136       /* F3 is 27, 79, 82.  */  \r
137       /* F4 is 27, 79, 83.  */  \r
138            \r
139                 \r
140       else if(key == 27)        \r
141           {  \r
142                           myseq.key = key; \r
143                           buffer[bufpnt] = myseq; \r
144                           bufpnt += 1; \r
145                           key = getch(); \r
146               if(key == 91) \r
147               myseq.key = key; \r
148               buffer[bufpnt] = myseq;  \r
149               bufpnt += 1;                                      \r
150               key = getch(); \r
151               if( (key >= 65) && (key <= 68) )  \r
152                { \r
153                                  myseq.key = key;   \r
154                                  buffer[bufpnt] = myseq;  \r
155                  bufpnt += 1;   \r
156                }                                  \r
157           }\r
158               \r
159                                           \r
160                                                  \r
161     /* The Enter key exits. Enter is 10 decimal */        \r
162         else if(key == 10)  \r
163                 { \r
164                          int j ; \r
165                    /* Print the array of structs. */ \r
166                      for (j=0; j<10; 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