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 */ 19static void 20log_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 */ 45static char * 46visichar(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 */ 68static char * 69visible(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 95static void 96really_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 150static void 151duplicate(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 171static void 172redefine(WINDOW *win, char *string, int code) 173{ 174 really_define_key(win, string, code); 175} 176 177static void 178remove_definition(WINDOW *win, int code) 179{ 180 really_define_key(win, 0, code); 181} 182 183int 184main(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 244int 245main(void) 246{ 247 printf("This program requires the ncurses library\n"); 248 ExitProgram(EXIT_FAILURE); 249} 250#endif 251