ab120636b7ff6dd82206f51667a068a912c02513
[ncurses.git] / test / demo_defkey.c
1 /*
2  * $Id: demo_defkey.c,v 1.13 2004/01/04 00:01:13 tom Exp $
3  *
4  * Demonstrate the define_key() function.
5  * Thomas Dickey - 2002/11/23
6  */
7
8 #include <test.priv.h>
9
10 #if defined(NCURSES_VERSION) && NCURSES_EXT_FUNCS
11
12 #include <term.h>
13
14 #define MY_LOGFILE "demo_defkey.log"
15
16 /*
17  * Log the most recently-written line to our logfile
18  */
19 static void
20 log_last_line(WINDOW *win)
21 {
22     FILE *fp;
23     int y, x, n;
24     char temp[256];
25
26     if ((fp = fopen(MY_LOGFILE, "a")) != 0) {
27         getyx(win, y, x);
28         wmove(win, y - 1, 0);
29         n = winnstr(win, temp, sizeof(temp));
30         while (n-- > 0) {
31             if (isspace(UChar(temp[n])))
32                 temp[n] = '\0';
33             else
34                 break;
35         }
36         wmove(win, y, x);
37         fprintf(fp, "%s\n", temp);
38         fclose(fp);
39     }
40 }
41
42 /*
43  * Convert a character to visible form.
44  */
45 static char *
46 visichar(int ch)
47 {
48     static char temp[10];
49
50     ch = UChar(ch);
51     if (ch == '\\') {
52         strcpy(temp, "\\\\");
53     } else if (ch == '\033') {
54         strcpy(temp, "\\E");
55     } else if (ch < ' ') {
56         sprintf(temp, "\\%03o", ch);
57     } else if (ch >= 127) {
58         sprintf(temp, "\\%03o", ch);
59     } else {
60         sprintf(temp, "%c", ch);
61     }
62     return temp;
63 }
64
65 /*
66  * Convert a string to visible form.
67  */
68 static char *
69 visible(const char *string)
70 {
71     char *result = 0;
72     unsigned need = 1;
73     int pass;
74     int n;
75
76     if (string != 0 && *string != '\0') {
77         for (pass = 0; pass < 2; ++pass) {
78             for (n = 0; string[n] != '\0'; ++n) {
79                 char temp[80];
80                 strcpy(temp, visichar(string[n]));
81                 if (pass)
82                     strcat(result, temp);
83                 else
84                     need += strlen(temp);
85             }
86             if (!pass)
87                 result = (char *) calloc(need, 1);
88         }
89     } else {
90         result = (char *) calloc(1, 1);
91     }
92     return result;
93 }
94
95 static void
96 really_define_key(WINDOW *win, const char *new_string, int code)
97 {
98     int rc;
99     const char *code_name = keyname(code);
100     char *old_string;
101     char *vis_string = 0;
102     char temp[80];
103
104     if (code_name == 0) {
105         sprintf(temp, "Keycode %d", code);
106         code_name = temp;
107     }
108
109     if ((old_string = keybound(code, 0)) != 0) {
110         wprintw(win, "%s is %s\n",
111                 code_name,
112                 vis_string = visible(old_string));
113     } else {
114         wprintw(win, "%s is not bound\n",
115                 code_name);
116     }
117     log_last_line(win);
118     if (vis_string != 0) {
119         free(vis_string);
120         vis_string = 0;
121     }
122
123     vis_string = visible(new_string);
124     if ((rc = key_defined(new_string)) > 0) {
125         wprintw(win, "%s was bound to %s\n", vis_string, keyname(rc));
126         log_last_line(win);
127     } else if (new_string != 0 && rc < 0) {
128         wprintw(win, "%s conflicts with longer strings\n", vis_string);
129         log_last_line(win);
130     }
131     rc = define_key(new_string, code);
132     if (rc == ERR) {
133         wprintw(win, "%s unchanged\n", code_name);
134         log_last_line(win);
135     } else if (new_string != 0) {
136         wprintw(win, "%s is now bound to %s\n",
137                 vis_string,
138                 code_name);
139         log_last_line(win);
140     } else if (old_string != 0) {
141         wprintw(win, "%s deleted\n", code_name);
142         log_last_line(win);
143     }
144     if (vis_string != 0 && *vis_string != 0)
145         free(vis_string);
146     if (old_string != 0)
147         free(old_string);
148 }
149
150 static void
151 duplicate(WINDOW *win, NCURSES_CONST char *name, int code)
152 {
153     char *value = tigetstr(name);
154
155     if (value != 0) {
156         const char *prefix = 0;
157         char temp[BUFSIZ];
158
159         if (!strncmp(value, "\033[", 2)) {
160             prefix = "\033O";
161         } else if (!strncmp(value, "\033O", 2)) {
162             prefix = "\033[";
163         }
164         if (prefix != 0) {
165             sprintf(temp, "%s%s", prefix, value + 2);
166             really_define_key(win, temp, code);
167         }
168     }
169 }
170
171 static void
172 redefine(WINDOW *win, char *string, int code)
173 {
174     really_define_key(win, string, code);
175 }
176
177 static void
178 remove_definition(WINDOW *win, int code)
179 {
180     really_define_key(win, 0, code);
181 }
182
183 int
184 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
185 {
186     char *fkeys[12];
187     int n;
188     int ch;
189     WINDOW *win;
190
191     unlink(MY_LOGFILE);
192
193     initscr();
194     (void) cbreak();            /* take input chars one at a time, no wait for \n */
195     (void) noecho();            /* don't echo input */
196
197     printw("This demo is best on xterm: it reverses the definitions for f1-f12,\n");
198     printw("adds duplicate definitions for cursor application and normal modes,\n");
199     printw("and removes any definitions for the mini keypad.  Type any of those:\n");
200     refresh();
201
202     win = newwin(LINES - 3, COLS, 3, 0);
203     scrollok(win, TRUE);
204     keypad(win, TRUE);
205     wmove(win, 0, 0);
206
207     /* we do the define_key() calls after keypad(), since the first call to
208      * keypad() initializes the corresponding data.
209      */
210     for (n = 0; n < 12; ++n) {
211         char name[10];
212         sprintf(name, "kf%d", n + 1);
213         fkeys[n] = tigetstr(name);
214     }
215     for (n = 0; n < 12; ++n) {
216         redefine(win, fkeys[11 - n], KEY_F(n + 1));
217     }
218
219     duplicate(win, "kcub1", KEY_LEFT);
220     duplicate(win, "kcuu1", KEY_UP);
221     duplicate(win, "kcud1", KEY_DOWN);
222     duplicate(win, "kcuf1", KEY_RIGHT);
223
224     remove_definition(win, KEY_A1);
225     remove_definition(win, KEY_A3);
226     remove_definition(win, KEY_B2);
227     remove_definition(win, KEY_C1);
228     remove_definition(win, KEY_C3);
229
230     really_define_key(win, "\033O", 1023);
231
232     while ((ch = wgetch(win)) != ERR) {
233         const char *name = keyname(ch);
234         wprintw(win, "Keycode %d, name %s\n",
235                 ch,
236                 name != 0 ? name : "<null>");
237         log_last_line(win);
238         wclrtoeol(win);
239     }
240     endwin();
241     return EXIT_SUCCESS;
242 }
243 #else
244 int
245 main(void)
246 {
247     printf("This program requires the ncurses library\n");
248     ExitProgram(EXIT_FAILURE);
249 }
250 #endif