14c8945a0SNathan Whitehorn /* 2*2a3e3873SBaptiste Daroussin * $Id: dlg_keys.c,v 1.34 2011/10/14 00:41:08 tom Exp $ 34c8945a0SNathan Whitehorn * 44c8945a0SNathan Whitehorn * dlg_keys.c -- runtime binding support for dialog 54c8945a0SNathan Whitehorn * 6*2a3e3873SBaptiste Daroussin * Copyright 2006-2009,2011 Thomas E. Dickey 74c8945a0SNathan Whitehorn * 84c8945a0SNathan Whitehorn * This program is free software; you can redistribute it and/or modify 94c8945a0SNathan Whitehorn * it under the terms of the GNU Lesser General Public License, version 2.1 104c8945a0SNathan Whitehorn * as published by the Free Software Foundation. 114c8945a0SNathan Whitehorn * 124c8945a0SNathan Whitehorn * This program is distributed in the hope that it will be useful, but 134c8945a0SNathan Whitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 144c8945a0SNathan Whitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 154c8945a0SNathan Whitehorn * Lesser General Public License for more details. 164c8945a0SNathan Whitehorn * 174c8945a0SNathan Whitehorn * You should have received a copy of the GNU Lesser General Public 184c8945a0SNathan Whitehorn * License along with this program; if not, write to 194c8945a0SNathan Whitehorn * Free Software Foundation, Inc. 204c8945a0SNathan Whitehorn * 51 Franklin St., Fifth Floor 214c8945a0SNathan Whitehorn * Boston, MA 02110, USA. 224c8945a0SNathan Whitehorn */ 234c8945a0SNathan Whitehorn 244c8945a0SNathan Whitehorn #include <dialog.h> 254c8945a0SNathan Whitehorn #include <dlg_keys.h> 264c8945a0SNathan Whitehorn 274c8945a0SNathan Whitehorn #define LIST_BINDINGS struct _list_bindings 284c8945a0SNathan Whitehorn 294c8945a0SNathan Whitehorn LIST_BINDINGS { 304c8945a0SNathan Whitehorn LIST_BINDINGS *link; 314c8945a0SNathan Whitehorn WINDOW *win; /* window on which widget gets input */ 324c8945a0SNathan Whitehorn const char *name; /* widget name */ 334c8945a0SNathan Whitehorn bool buttons; /* true only for dlg_register_buttons() */ 344c8945a0SNathan Whitehorn DLG_KEYS_BINDING *binding; /* list of bindings */ 354c8945a0SNathan Whitehorn }; 364c8945a0SNathan Whitehorn 37*2a3e3873SBaptiste Daroussin #define WILDNAME "*" 384c8945a0SNathan Whitehorn static LIST_BINDINGS *all_bindings; 394c8945a0SNathan Whitehorn static const DLG_KEYS_BINDING end_keys_binding = END_KEYS_BINDING; 404c8945a0SNathan Whitehorn 414c8945a0SNathan Whitehorn /* 424c8945a0SNathan Whitehorn * For a given named widget's window, associate a binding table. 434c8945a0SNathan Whitehorn */ 444c8945a0SNathan Whitehorn void 454c8945a0SNathan Whitehorn dlg_register_window(WINDOW *win, const char *name, DLG_KEYS_BINDING * binding) 464c8945a0SNathan Whitehorn { 474c8945a0SNathan Whitehorn LIST_BINDINGS *p, *q; 484c8945a0SNathan Whitehorn 494c8945a0SNathan Whitehorn for (p = all_bindings, q = 0; p != 0; q = p, p = p->link) { 504c8945a0SNathan Whitehorn if (p->win == win && !strcmp(p->name, name)) { 514c8945a0SNathan Whitehorn p->binding = binding; 524c8945a0SNathan Whitehorn return; 534c8945a0SNathan Whitehorn } 544c8945a0SNathan Whitehorn } 554c8945a0SNathan Whitehorn /* add built-in bindings at the end of the list (see compare_bindings). */ 564c8945a0SNathan Whitehorn if ((p = dlg_calloc(LIST_BINDINGS, 1)) != 0) { 574c8945a0SNathan Whitehorn p->win = win; 584c8945a0SNathan Whitehorn p->name = name; 594c8945a0SNathan Whitehorn p->binding = binding; 604c8945a0SNathan Whitehorn if (q != 0) 614c8945a0SNathan Whitehorn q->link = p; 624c8945a0SNathan Whitehorn else 634c8945a0SNathan Whitehorn all_bindings = p; 644c8945a0SNathan Whitehorn } 65*2a3e3873SBaptiste Daroussin #if defined(HAVE_DLG_TRACE) && defined(HAVE_RC_FILE) 66*2a3e3873SBaptiste Daroussin /* 67*2a3e3873SBaptiste Daroussin * Trace the binding information assigned to this window. For most widgets 68*2a3e3873SBaptiste Daroussin * there is only one binding table. forms have two, so the trace will be 69*2a3e3873SBaptiste Daroussin * longer. Since compiled-in bindings are only visible when the widget is 70*2a3e3873SBaptiste Daroussin * registered, there is no other way to see what bindings are available, 71*2a3e3873SBaptiste Daroussin * than by running dialog and tracing it. 72*2a3e3873SBaptiste Daroussin */ 73*2a3e3873SBaptiste Daroussin dlg_trace_msg("# dlg_register_window %s\n", name); 74*2a3e3873SBaptiste Daroussin dlg_dump_window_keys(dialog_state.trace_output, win); 75*2a3e3873SBaptiste Daroussin #endif 764c8945a0SNathan Whitehorn } 774c8945a0SNathan Whitehorn 784c8945a0SNathan Whitehorn /* 794c8945a0SNathan Whitehorn * Unlike dlg_lookup_key(), this looks for either widget-builtin or rc-file 804c8945a0SNathan Whitehorn * definitions, depending on whether 'win' is null. 814c8945a0SNathan Whitehorn */ 824c8945a0SNathan Whitehorn static int 834c8945a0SNathan Whitehorn key_is_bound(WINDOW *win, const char *name, int curses_key, int function_key) 844c8945a0SNathan Whitehorn { 854c8945a0SNathan Whitehorn LIST_BINDINGS *p; 864c8945a0SNathan Whitehorn 874c8945a0SNathan Whitehorn for (p = all_bindings; p != 0; p = p->link) { 884c8945a0SNathan Whitehorn if (p->win == win && !dlg_strcmp(p->name, name)) { 894c8945a0SNathan Whitehorn int n; 904c8945a0SNathan Whitehorn for (n = 0; p->binding[n].is_function_key >= 0; ++n) { 914c8945a0SNathan Whitehorn if (p->binding[n].curses_key == curses_key 924c8945a0SNathan Whitehorn && p->binding[n].is_function_key == function_key) { 934c8945a0SNathan Whitehorn return TRUE; 944c8945a0SNathan Whitehorn } 954c8945a0SNathan Whitehorn } 964c8945a0SNathan Whitehorn } 974c8945a0SNathan Whitehorn } 984c8945a0SNathan Whitehorn return FALSE; 994c8945a0SNathan Whitehorn } 1004c8945a0SNathan Whitehorn 1014c8945a0SNathan Whitehorn /* 1024c8945a0SNathan Whitehorn * Call this function after dlg_register_window(), for the list of button 1034c8945a0SNathan Whitehorn * labels associated with the widget. 1044c8945a0SNathan Whitehorn * 1054c8945a0SNathan Whitehorn * Ensure that dlg_lookup_key() will not accidentally translate a key that 1064c8945a0SNathan Whitehorn * we would like to use for a button abbreviation to some other key, e.g., 1074c8945a0SNathan Whitehorn * h/j/k/l for navigation into a cursor key. Do this by binding the key 1084c8945a0SNathan Whitehorn * to itself. 1094c8945a0SNathan Whitehorn * 1104c8945a0SNathan Whitehorn * See dlg_char_to_button(). 1114c8945a0SNathan Whitehorn */ 1124c8945a0SNathan Whitehorn void 1134c8945a0SNathan Whitehorn dlg_register_buttons(WINDOW *win, const char *name, const char **buttons) 1144c8945a0SNathan Whitehorn { 1154c8945a0SNathan Whitehorn int n; 1164c8945a0SNathan Whitehorn LIST_BINDINGS *p; 1174c8945a0SNathan Whitehorn DLG_KEYS_BINDING *q; 1184c8945a0SNathan Whitehorn 1194c8945a0SNathan Whitehorn if (buttons == 0) 1204c8945a0SNathan Whitehorn return; 1214c8945a0SNathan Whitehorn 1224c8945a0SNathan Whitehorn for (n = 0; buttons[n] != 0; ++n) { 1234c8945a0SNathan Whitehorn int curses_key = dlg_button_to_char(buttons[n]); 1244c8945a0SNathan Whitehorn 1254c8945a0SNathan Whitehorn /* ignore multibyte characters */ 1264c8945a0SNathan Whitehorn if (curses_key >= KEY_MIN) 1274c8945a0SNathan Whitehorn continue; 1284c8945a0SNathan Whitehorn 1294c8945a0SNathan Whitehorn /* if it is not bound in the widget, skip it (no conflicts) */ 1304c8945a0SNathan Whitehorn if (!key_is_bound(win, name, curses_key, FALSE)) 1314c8945a0SNathan Whitehorn continue; 1324c8945a0SNathan Whitehorn 1334c8945a0SNathan Whitehorn #ifdef HAVE_RC_FILE 1344c8945a0SNathan Whitehorn /* if it is bound in the rc-file, skip it */ 1354c8945a0SNathan Whitehorn if (key_is_bound(0, name, curses_key, FALSE)) 1364c8945a0SNathan Whitehorn continue; 1374c8945a0SNathan Whitehorn #endif 1384c8945a0SNathan Whitehorn 1394c8945a0SNathan Whitehorn if ((p = dlg_calloc(LIST_BINDINGS, 1)) != 0) { 1404c8945a0SNathan Whitehorn if ((q = dlg_calloc(DLG_KEYS_BINDING, 2)) != 0) { 1414c8945a0SNathan Whitehorn q[0].is_function_key = 0; 1424c8945a0SNathan Whitehorn q[0].curses_key = curses_key; 1434c8945a0SNathan Whitehorn q[0].dialog_key = curses_key; 1444c8945a0SNathan Whitehorn q[1] = end_keys_binding; 1454c8945a0SNathan Whitehorn 1464c8945a0SNathan Whitehorn p->win = win; 1474c8945a0SNathan Whitehorn p->name = name; 1484c8945a0SNathan Whitehorn p->buttons = TRUE; 1494c8945a0SNathan Whitehorn p->binding = q; 1504c8945a0SNathan Whitehorn 1514c8945a0SNathan Whitehorn /* put these at the beginning, to override the widget's table */ 1524c8945a0SNathan Whitehorn p->link = all_bindings; 1534c8945a0SNathan Whitehorn all_bindings = p; 1544c8945a0SNathan Whitehorn } else { 1554c8945a0SNathan Whitehorn free(p); 1564c8945a0SNathan Whitehorn } 1574c8945a0SNathan Whitehorn } 1584c8945a0SNathan Whitehorn } 1594c8945a0SNathan Whitehorn } 1604c8945a0SNathan Whitehorn 1614c8945a0SNathan Whitehorn /* 1624c8945a0SNathan Whitehorn * Remove the bindings for a given window. 1634c8945a0SNathan Whitehorn */ 1644c8945a0SNathan Whitehorn void 1654c8945a0SNathan Whitehorn dlg_unregister_window(WINDOW *win) 1664c8945a0SNathan Whitehorn { 1674c8945a0SNathan Whitehorn LIST_BINDINGS *p, *q; 1684c8945a0SNathan Whitehorn 1694c8945a0SNathan Whitehorn for (p = all_bindings, q = 0; p != 0; p = p->link) { 1704c8945a0SNathan Whitehorn if (p->win == win) { 1714c8945a0SNathan Whitehorn if (q != 0) { 1724c8945a0SNathan Whitehorn q->link = p->link; 1734c8945a0SNathan Whitehorn } else { 1744c8945a0SNathan Whitehorn all_bindings = p->link; 1754c8945a0SNathan Whitehorn } 1764c8945a0SNathan Whitehorn /* the user-defined and buttons-bindings all are length=1 */ 1774c8945a0SNathan Whitehorn if (p->binding[1].is_function_key < 0) 1784c8945a0SNathan Whitehorn free(p->binding); 1794c8945a0SNathan Whitehorn free(p); 1804c8945a0SNathan Whitehorn dlg_unregister_window(win); 1814c8945a0SNathan Whitehorn break; 1824c8945a0SNathan Whitehorn } 1834c8945a0SNathan Whitehorn q = p; 1844c8945a0SNathan Whitehorn } 1854c8945a0SNathan Whitehorn } 1864c8945a0SNathan Whitehorn 1874c8945a0SNathan Whitehorn /* 1884c8945a0SNathan Whitehorn * Call this after wgetch(), using the same window pointer and passing 1894c8945a0SNathan Whitehorn * the curses-key. 1904c8945a0SNathan Whitehorn * 1914c8945a0SNathan Whitehorn * If there is no binding associated with the widget, it simply returns 1924c8945a0SNathan Whitehorn * the given curses-key. 1934c8945a0SNathan Whitehorn * 1944c8945a0SNathan Whitehorn * Parameters: 1954c8945a0SNathan Whitehorn * win is the window on which the wgetch() was done. 1964c8945a0SNathan Whitehorn * curses_key is the value returned by wgetch(). 1974c8945a0SNathan Whitehorn * fkey in/out (on input, it is true if curses_key is a function key, 1984c8945a0SNathan Whitehorn * and on output, it is true if the result is a function key). 1994c8945a0SNathan Whitehorn */ 2004c8945a0SNathan Whitehorn int 2014c8945a0SNathan Whitehorn dlg_lookup_key(WINDOW *win, int curses_key, int *fkey) 2024c8945a0SNathan Whitehorn { 2034c8945a0SNathan Whitehorn LIST_BINDINGS *p; 204*2a3e3873SBaptiste Daroussin DLG_KEYS_BINDING *q; 2054c8945a0SNathan Whitehorn 2064c8945a0SNathan Whitehorn /* 2074c8945a0SNathan Whitehorn * Ignore mouse clicks, since they are already encoded properly. 2084c8945a0SNathan Whitehorn */ 2094c8945a0SNathan Whitehorn #ifdef KEY_MOUSE 2104c8945a0SNathan Whitehorn if (*fkey != 0 && curses_key == KEY_MOUSE) { 2114c8945a0SNathan Whitehorn ; 2124c8945a0SNathan Whitehorn } else 2134c8945a0SNathan Whitehorn #endif 2144c8945a0SNathan Whitehorn /* 2154c8945a0SNathan Whitehorn * Ignore resize events, since they are already encoded properly. 2164c8945a0SNathan Whitehorn */ 2174c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 2184c8945a0SNathan Whitehorn if (*fkey != 0 && curses_key == KEY_RESIZE) { 2194c8945a0SNathan Whitehorn ; 2204c8945a0SNathan Whitehorn } else 2214c8945a0SNathan Whitehorn #endif 2224c8945a0SNathan Whitehorn if (*fkey == 0 || curses_key < KEY_MAX) { 223*2a3e3873SBaptiste Daroussin const char *name = WILDNAME; 224*2a3e3873SBaptiste Daroussin if (win != 0) { 2254c8945a0SNathan Whitehorn for (p = all_bindings; p != 0; p = p->link) { 226*2a3e3873SBaptiste Daroussin if (p->win == win) { 227*2a3e3873SBaptiste Daroussin name = p->name; 228*2a3e3873SBaptiste Daroussin break; 229*2a3e3873SBaptiste Daroussin } 230*2a3e3873SBaptiste Daroussin } 231*2a3e3873SBaptiste Daroussin } 232*2a3e3873SBaptiste Daroussin for (p = all_bindings; p != 0; p = p->link) { 233*2a3e3873SBaptiste Daroussin if (p->win == win || (p->win == 0 && !strcmp(p->name, name))) { 2344c8945a0SNathan Whitehorn int function_key = (*fkey != 0); 235*2a3e3873SBaptiste Daroussin for (q = p->binding; q->is_function_key >= 0; ++q) { 2364c8945a0SNathan Whitehorn if (p->buttons 2374c8945a0SNathan Whitehorn && !function_key 238*2a3e3873SBaptiste Daroussin && q->curses_key == (int) dlg_toupper(curses_key)) { 2394c8945a0SNathan Whitehorn *fkey = 0; 240*2a3e3873SBaptiste Daroussin return q->dialog_key; 2414c8945a0SNathan Whitehorn } 242*2a3e3873SBaptiste Daroussin if (q->curses_key == curses_key 243*2a3e3873SBaptiste Daroussin && q->is_function_key == function_key) { 244*2a3e3873SBaptiste Daroussin *fkey = q->dialog_key; 2454c8945a0SNathan Whitehorn return *fkey; 2464c8945a0SNathan Whitehorn } 2474c8945a0SNathan Whitehorn } 2484c8945a0SNathan Whitehorn } 2494c8945a0SNathan Whitehorn } 2504c8945a0SNathan Whitehorn } 2514c8945a0SNathan Whitehorn return curses_key; 2524c8945a0SNathan Whitehorn } 2534c8945a0SNathan Whitehorn 2544c8945a0SNathan Whitehorn /* 2554c8945a0SNathan Whitehorn * Test a dialog internal keycode to see if it corresponds to one of the push 2564c8945a0SNathan Whitehorn * buttons on the widget such as "OK". 2574c8945a0SNathan Whitehorn * 2584c8945a0SNathan Whitehorn * This is only useful if there are user-defined key bindings, since there are 2594c8945a0SNathan Whitehorn * no built-in bindings that map directly to DLGK_OK, etc. 2604c8945a0SNathan Whitehorn * 2614c8945a0SNathan Whitehorn * See also dlg_ok_buttoncode(). 2624c8945a0SNathan Whitehorn */ 2634c8945a0SNathan Whitehorn int 2644c8945a0SNathan Whitehorn dlg_result_key(int dialog_key, int fkey GCC_UNUSED, int *resultp) 2654c8945a0SNathan Whitehorn { 2664c8945a0SNathan Whitehorn int done = FALSE; 2674c8945a0SNathan Whitehorn 2684c8945a0SNathan Whitehorn #ifdef HAVE_RC_FILE 2694c8945a0SNathan Whitehorn if (fkey) { 2704c8945a0SNathan Whitehorn switch ((DLG_KEYS_ENUM) dialog_key) { 2714c8945a0SNathan Whitehorn case DLGK_OK: 2724c8945a0SNathan Whitehorn *resultp = DLG_EXIT_OK; 2734c8945a0SNathan Whitehorn done = TRUE; 2744c8945a0SNathan Whitehorn break; 2754c8945a0SNathan Whitehorn case DLGK_CANCEL: 2764c8945a0SNathan Whitehorn if (!dialog_vars.nocancel) { 2774c8945a0SNathan Whitehorn *resultp = DLG_EXIT_CANCEL; 2784c8945a0SNathan Whitehorn done = TRUE; 2794c8945a0SNathan Whitehorn } 2804c8945a0SNathan Whitehorn break; 2814c8945a0SNathan Whitehorn case DLGK_EXTRA: 2824c8945a0SNathan Whitehorn if (dialog_vars.extra_button) { 2834c8945a0SNathan Whitehorn *resultp = DLG_EXIT_EXTRA; 2844c8945a0SNathan Whitehorn done = TRUE; 2854c8945a0SNathan Whitehorn } 2864c8945a0SNathan Whitehorn break; 2874c8945a0SNathan Whitehorn case DLGK_HELP: 2884c8945a0SNathan Whitehorn if (dialog_vars.help_button) { 2894c8945a0SNathan Whitehorn *resultp = DLG_EXIT_HELP; 2904c8945a0SNathan Whitehorn done = TRUE; 2914c8945a0SNathan Whitehorn } 2924c8945a0SNathan Whitehorn break; 2934c8945a0SNathan Whitehorn case DLGK_ESC: 2944c8945a0SNathan Whitehorn *resultp = DLG_EXIT_ESC; 2954c8945a0SNathan Whitehorn done = TRUE; 2964c8945a0SNathan Whitehorn break; 2974c8945a0SNathan Whitehorn default: 2984c8945a0SNathan Whitehorn break; 2994c8945a0SNathan Whitehorn } 3004c8945a0SNathan Whitehorn } else 3014c8945a0SNathan Whitehorn #endif 3024c8945a0SNathan Whitehorn if (dialog_key == ESC) { 3034c8945a0SNathan Whitehorn *resultp = DLG_EXIT_ESC; 3044c8945a0SNathan Whitehorn done = TRUE; 3054c8945a0SNathan Whitehorn } else if (dialog_key == ERR) { 3064c8945a0SNathan Whitehorn *resultp = DLG_EXIT_ERROR; 3074c8945a0SNathan Whitehorn done = TRUE; 3084c8945a0SNathan Whitehorn } 3094c8945a0SNathan Whitehorn 3104c8945a0SNathan Whitehorn return done; 3114c8945a0SNathan Whitehorn } 3124c8945a0SNathan Whitehorn 3134c8945a0SNathan Whitehorn #ifdef HAVE_RC_FILE 3144c8945a0SNathan Whitehorn typedef struct { 3154c8945a0SNathan Whitehorn const char *name; 3164c8945a0SNathan Whitehorn int code; 3174c8945a0SNathan Whitehorn } CODENAME; 3184c8945a0SNathan Whitehorn 319*2a3e3873SBaptiste Daroussin #define ASCII_NAME(name,code) { #name, code } 3204c8945a0SNathan Whitehorn #define CURSES_NAME(upper) { #upper, KEY_ ## upper } 3214c8945a0SNathan Whitehorn #define COUNT_CURSES sizeof(curses_names)/sizeof(curses_names[0]) 3224c8945a0SNathan Whitehorn static const CODENAME curses_names[] = 3234c8945a0SNathan Whitehorn { 324*2a3e3873SBaptiste Daroussin ASCII_NAME(ESC, '\033'), 325*2a3e3873SBaptiste Daroussin ASCII_NAME(CR, '\r'), 326*2a3e3873SBaptiste Daroussin ASCII_NAME(LF, '\n'), 327*2a3e3873SBaptiste Daroussin ASCII_NAME(FF, '\f'), 328*2a3e3873SBaptiste Daroussin ASCII_NAME(TAB, '\t'), 329*2a3e3873SBaptiste Daroussin ASCII_NAME(DEL, '\177'), 330*2a3e3873SBaptiste Daroussin 3314c8945a0SNathan Whitehorn CURSES_NAME(DOWN), 3324c8945a0SNathan Whitehorn CURSES_NAME(UP), 3334c8945a0SNathan Whitehorn CURSES_NAME(LEFT), 3344c8945a0SNathan Whitehorn CURSES_NAME(RIGHT), 3354c8945a0SNathan Whitehorn CURSES_NAME(HOME), 3364c8945a0SNathan Whitehorn CURSES_NAME(BACKSPACE), 3374c8945a0SNathan Whitehorn CURSES_NAME(F0), 3384c8945a0SNathan Whitehorn CURSES_NAME(DL), 3394c8945a0SNathan Whitehorn CURSES_NAME(IL), 3404c8945a0SNathan Whitehorn CURSES_NAME(DC), 3414c8945a0SNathan Whitehorn CURSES_NAME(IC), 3424c8945a0SNathan Whitehorn CURSES_NAME(EIC), 3434c8945a0SNathan Whitehorn CURSES_NAME(CLEAR), 3444c8945a0SNathan Whitehorn CURSES_NAME(EOS), 3454c8945a0SNathan Whitehorn CURSES_NAME(EOL), 3464c8945a0SNathan Whitehorn CURSES_NAME(SF), 3474c8945a0SNathan Whitehorn CURSES_NAME(SR), 3484c8945a0SNathan Whitehorn CURSES_NAME(NPAGE), 3494c8945a0SNathan Whitehorn CURSES_NAME(PPAGE), 3504c8945a0SNathan Whitehorn CURSES_NAME(STAB), 3514c8945a0SNathan Whitehorn CURSES_NAME(CTAB), 3524c8945a0SNathan Whitehorn CURSES_NAME(CATAB), 3534c8945a0SNathan Whitehorn CURSES_NAME(ENTER), 3544c8945a0SNathan Whitehorn CURSES_NAME(PRINT), 3554c8945a0SNathan Whitehorn CURSES_NAME(LL), 3564c8945a0SNathan Whitehorn CURSES_NAME(A1), 3574c8945a0SNathan Whitehorn CURSES_NAME(A3), 3584c8945a0SNathan Whitehorn CURSES_NAME(B2), 3594c8945a0SNathan Whitehorn CURSES_NAME(C1), 3604c8945a0SNathan Whitehorn CURSES_NAME(C3), 3614c8945a0SNathan Whitehorn CURSES_NAME(BTAB), 3624c8945a0SNathan Whitehorn CURSES_NAME(BEG), 3634c8945a0SNathan Whitehorn CURSES_NAME(CANCEL), 3644c8945a0SNathan Whitehorn CURSES_NAME(CLOSE), 3654c8945a0SNathan Whitehorn CURSES_NAME(COMMAND), 3664c8945a0SNathan Whitehorn CURSES_NAME(COPY), 3674c8945a0SNathan Whitehorn CURSES_NAME(CREATE), 3684c8945a0SNathan Whitehorn CURSES_NAME(END), 3694c8945a0SNathan Whitehorn CURSES_NAME(EXIT), 3704c8945a0SNathan Whitehorn CURSES_NAME(FIND), 3714c8945a0SNathan Whitehorn CURSES_NAME(HELP), 3724c8945a0SNathan Whitehorn CURSES_NAME(MARK), 3734c8945a0SNathan Whitehorn CURSES_NAME(MESSAGE), 3744c8945a0SNathan Whitehorn CURSES_NAME(MOVE), 3754c8945a0SNathan Whitehorn CURSES_NAME(NEXT), 3764c8945a0SNathan Whitehorn CURSES_NAME(OPEN), 3774c8945a0SNathan Whitehorn CURSES_NAME(OPTIONS), 3784c8945a0SNathan Whitehorn CURSES_NAME(PREVIOUS), 3794c8945a0SNathan Whitehorn CURSES_NAME(REDO), 3804c8945a0SNathan Whitehorn CURSES_NAME(REFERENCE), 3814c8945a0SNathan Whitehorn CURSES_NAME(REFRESH), 3824c8945a0SNathan Whitehorn CURSES_NAME(REPLACE), 3834c8945a0SNathan Whitehorn CURSES_NAME(RESTART), 3844c8945a0SNathan Whitehorn CURSES_NAME(RESUME), 3854c8945a0SNathan Whitehorn CURSES_NAME(SAVE), 3864c8945a0SNathan Whitehorn CURSES_NAME(SBEG), 3874c8945a0SNathan Whitehorn CURSES_NAME(SCANCEL), 3884c8945a0SNathan Whitehorn CURSES_NAME(SCOMMAND), 3894c8945a0SNathan Whitehorn CURSES_NAME(SCOPY), 3904c8945a0SNathan Whitehorn CURSES_NAME(SCREATE), 3914c8945a0SNathan Whitehorn CURSES_NAME(SDC), 3924c8945a0SNathan Whitehorn CURSES_NAME(SDL), 3934c8945a0SNathan Whitehorn CURSES_NAME(SELECT), 3944c8945a0SNathan Whitehorn CURSES_NAME(SEND), 3954c8945a0SNathan Whitehorn CURSES_NAME(SEOL), 3964c8945a0SNathan Whitehorn CURSES_NAME(SEXIT), 3974c8945a0SNathan Whitehorn CURSES_NAME(SFIND), 3984c8945a0SNathan Whitehorn CURSES_NAME(SHELP), 3994c8945a0SNathan Whitehorn CURSES_NAME(SHOME), 4004c8945a0SNathan Whitehorn CURSES_NAME(SIC), 4014c8945a0SNathan Whitehorn CURSES_NAME(SLEFT), 4024c8945a0SNathan Whitehorn CURSES_NAME(SMESSAGE), 4034c8945a0SNathan Whitehorn CURSES_NAME(SMOVE), 4044c8945a0SNathan Whitehorn CURSES_NAME(SNEXT), 4054c8945a0SNathan Whitehorn CURSES_NAME(SOPTIONS), 4064c8945a0SNathan Whitehorn CURSES_NAME(SPREVIOUS), 4074c8945a0SNathan Whitehorn CURSES_NAME(SPRINT), 4084c8945a0SNathan Whitehorn CURSES_NAME(SREDO), 4094c8945a0SNathan Whitehorn CURSES_NAME(SREPLACE), 4104c8945a0SNathan Whitehorn CURSES_NAME(SRIGHT), 4114c8945a0SNathan Whitehorn CURSES_NAME(SRSUME), 4124c8945a0SNathan Whitehorn CURSES_NAME(SSAVE), 4134c8945a0SNathan Whitehorn CURSES_NAME(SSUSPEND), 4144c8945a0SNathan Whitehorn CURSES_NAME(SUNDO), 4154c8945a0SNathan Whitehorn CURSES_NAME(SUSPEND), 4164c8945a0SNathan Whitehorn CURSES_NAME(UNDO), 4174c8945a0SNathan Whitehorn }; 4184c8945a0SNathan Whitehorn 4194c8945a0SNathan Whitehorn #define DIALOG_NAME(upper) { #upper, DLGK_ ## upper } 4204c8945a0SNathan Whitehorn #define COUNT_DIALOG sizeof(dialog_names)/sizeof(dialog_names[0]) 4214c8945a0SNathan Whitehorn static const CODENAME dialog_names[] = 4224c8945a0SNathan Whitehorn { 4234c8945a0SNathan Whitehorn DIALOG_NAME(OK), 4244c8945a0SNathan Whitehorn DIALOG_NAME(CANCEL), 4254c8945a0SNathan Whitehorn DIALOG_NAME(EXTRA), 4264c8945a0SNathan Whitehorn DIALOG_NAME(HELP), 4274c8945a0SNathan Whitehorn DIALOG_NAME(ESC), 4284c8945a0SNathan Whitehorn DIALOG_NAME(PAGE_FIRST), 4294c8945a0SNathan Whitehorn DIALOG_NAME(PAGE_LAST), 4304c8945a0SNathan Whitehorn DIALOG_NAME(PAGE_NEXT), 4314c8945a0SNathan Whitehorn DIALOG_NAME(PAGE_PREV), 4324c8945a0SNathan Whitehorn DIALOG_NAME(ITEM_FIRST), 4334c8945a0SNathan Whitehorn DIALOG_NAME(ITEM_LAST), 4344c8945a0SNathan Whitehorn DIALOG_NAME(ITEM_NEXT), 4354c8945a0SNathan Whitehorn DIALOG_NAME(ITEM_PREV), 4364c8945a0SNathan Whitehorn DIALOG_NAME(FIELD_FIRST), 4374c8945a0SNathan Whitehorn DIALOG_NAME(FIELD_LAST), 4384c8945a0SNathan Whitehorn DIALOG_NAME(FIELD_NEXT), 4394c8945a0SNathan Whitehorn DIALOG_NAME(FIELD_PREV), 440*2a3e3873SBaptiste Daroussin DIALOG_NAME(FORM_FIRST), 441*2a3e3873SBaptiste Daroussin DIALOG_NAME(FORM_LAST), 442*2a3e3873SBaptiste Daroussin DIALOG_NAME(FORM_NEXT), 443*2a3e3873SBaptiste Daroussin DIALOG_NAME(FORM_PREV), 4444c8945a0SNathan Whitehorn DIALOG_NAME(GRID_UP), 4454c8945a0SNathan Whitehorn DIALOG_NAME(GRID_DOWN), 4464c8945a0SNathan Whitehorn DIALOG_NAME(GRID_LEFT), 4474c8945a0SNathan Whitehorn DIALOG_NAME(GRID_RIGHT), 4484c8945a0SNathan Whitehorn DIALOG_NAME(DELETE_LEFT), 4494c8945a0SNathan Whitehorn DIALOG_NAME(DELETE_RIGHT), 4504c8945a0SNathan Whitehorn DIALOG_NAME(DELETE_ALL), 4514c8945a0SNathan Whitehorn DIALOG_NAME(ENTER), 4524c8945a0SNathan Whitehorn DIALOG_NAME(BEGIN), 4534c8945a0SNathan Whitehorn DIALOG_NAME(FINAL), 454*2a3e3873SBaptiste Daroussin DIALOG_NAME(SELECT), 455*2a3e3873SBaptiste Daroussin DIALOG_NAME(HELPFILE), 456*2a3e3873SBaptiste Daroussin DIALOG_NAME(TRACE) 4574c8945a0SNathan Whitehorn }; 4584c8945a0SNathan Whitehorn 4594c8945a0SNathan Whitehorn static char * 4604c8945a0SNathan Whitehorn skip_white(char *s) 4614c8945a0SNathan Whitehorn { 4624c8945a0SNathan Whitehorn while (*s != '\0' && isspace(UCH(*s))) 4634c8945a0SNathan Whitehorn ++s; 4644c8945a0SNathan Whitehorn return s; 4654c8945a0SNathan Whitehorn } 4664c8945a0SNathan Whitehorn 4674c8945a0SNathan Whitehorn static char * 4684c8945a0SNathan Whitehorn skip_black(char *s) 4694c8945a0SNathan Whitehorn { 4704c8945a0SNathan Whitehorn while (*s != '\0' && !isspace(UCH(*s))) 4714c8945a0SNathan Whitehorn ++s; 4724c8945a0SNathan Whitehorn return s; 4734c8945a0SNathan Whitehorn } 4744c8945a0SNathan Whitehorn 4754c8945a0SNathan Whitehorn /* 4764c8945a0SNathan Whitehorn * Find a user-defined binding, given the curses key code. 4774c8945a0SNathan Whitehorn */ 4784c8945a0SNathan Whitehorn static DLG_KEYS_BINDING * 4794c8945a0SNathan Whitehorn find_binding(char *widget, int curses_key) 4804c8945a0SNathan Whitehorn { 4814c8945a0SNathan Whitehorn LIST_BINDINGS *p; 4824c8945a0SNathan Whitehorn DLG_KEYS_BINDING *result = 0; 4834c8945a0SNathan Whitehorn 4844c8945a0SNathan Whitehorn for (p = all_bindings; p != 0; p = p->link) { 4854c8945a0SNathan Whitehorn if (p->win == 0 4864c8945a0SNathan Whitehorn && !dlg_strcmp(p->name, widget) 4874c8945a0SNathan Whitehorn && p->binding->curses_key == curses_key) { 4884c8945a0SNathan Whitehorn result = p->binding; 4894c8945a0SNathan Whitehorn break; 4904c8945a0SNathan Whitehorn } 4914c8945a0SNathan Whitehorn } 4924c8945a0SNathan Whitehorn return result; 4934c8945a0SNathan Whitehorn } 4944c8945a0SNathan Whitehorn 4954c8945a0SNathan Whitehorn /* 4964c8945a0SNathan Whitehorn * Built-in bindings have a nonzero "win" member, and the associated binding 4974c8945a0SNathan Whitehorn * table can have more than one entry. We keep those last, since lookups will 4984c8945a0SNathan Whitehorn * find the user-defined bindings first and use those. 4994c8945a0SNathan Whitehorn * 5004c8945a0SNathan Whitehorn * Sort "*" (all-widgets) entries past named widgets, since those are less 5014c8945a0SNathan Whitehorn * specific. 5024c8945a0SNathan Whitehorn */ 5034c8945a0SNathan Whitehorn static int 5044c8945a0SNathan Whitehorn compare_bindings(LIST_BINDINGS * a, LIST_BINDINGS * b) 5054c8945a0SNathan Whitehorn { 5064c8945a0SNathan Whitehorn int result = 0; 5074c8945a0SNathan Whitehorn if (a->win == b->win) { 5084c8945a0SNathan Whitehorn if (!strcmp(a->name, b->name)) { 5094c8945a0SNathan Whitehorn result = a->binding[0].curses_key - b->binding[0].curses_key; 510*2a3e3873SBaptiste Daroussin } else if (!strcmp(b->name, WILDNAME)) { 5114c8945a0SNathan Whitehorn result = -1; 512*2a3e3873SBaptiste Daroussin } else if (!strcmp(a->name, WILDNAME)) { 5134c8945a0SNathan Whitehorn result = 1; 5144c8945a0SNathan Whitehorn } else { 5154c8945a0SNathan Whitehorn result = dlg_strcmp(a->name, b->name); 5164c8945a0SNathan Whitehorn } 5174c8945a0SNathan Whitehorn } else if (b->win) { 5184c8945a0SNathan Whitehorn result = -1; 5194c8945a0SNathan Whitehorn } else { 5204c8945a0SNathan Whitehorn result = 1; 5214c8945a0SNathan Whitehorn } 5224c8945a0SNathan Whitehorn return result; 5234c8945a0SNathan Whitehorn } 5244c8945a0SNathan Whitehorn 5254c8945a0SNathan Whitehorn /* 5264c8945a0SNathan Whitehorn * Find a user-defined binding, given the curses key code. If it does not 5274c8945a0SNathan Whitehorn * exist, create a new one, inserting it into the linked list, keeping it 5284c8945a0SNathan Whitehorn * sorted to simplify lookups for user-defined bindings that can override 5294c8945a0SNathan Whitehorn * the built-in bindings. 5304c8945a0SNathan Whitehorn */ 5314c8945a0SNathan Whitehorn static DLG_KEYS_BINDING * 5324c8945a0SNathan Whitehorn make_binding(char *widget, int curses_key, int is_function, int dialog_key) 5334c8945a0SNathan Whitehorn { 5344c8945a0SNathan Whitehorn LIST_BINDINGS *entry = 0; 5354c8945a0SNathan Whitehorn DLG_KEYS_BINDING *data = 0; 5364c8945a0SNathan Whitehorn char *name; 5374c8945a0SNathan Whitehorn LIST_BINDINGS *p, *q; 5384c8945a0SNathan Whitehorn DLG_KEYS_BINDING *result = find_binding(widget, curses_key); 5394c8945a0SNathan Whitehorn 5404c8945a0SNathan Whitehorn if (result == 0 5414c8945a0SNathan Whitehorn && (entry = dlg_calloc(LIST_BINDINGS, 1)) != 0 5424c8945a0SNathan Whitehorn && (data = dlg_calloc(DLG_KEYS_BINDING, 2)) != 0 5434c8945a0SNathan Whitehorn && (name = dlg_strclone(widget)) != 0) { 5444c8945a0SNathan Whitehorn 5454c8945a0SNathan Whitehorn entry->name = name; 5464c8945a0SNathan Whitehorn entry->binding = data; 5474c8945a0SNathan Whitehorn 5484c8945a0SNathan Whitehorn data[0].is_function_key = is_function; 5494c8945a0SNathan Whitehorn data[0].curses_key = curses_key; 5504c8945a0SNathan Whitehorn data[0].dialog_key = dialog_key; 5514c8945a0SNathan Whitehorn 5524c8945a0SNathan Whitehorn data[1] = end_keys_binding; 5534c8945a0SNathan Whitehorn 5544c8945a0SNathan Whitehorn for (p = all_bindings, q = 0; p != 0; q = p, p = p->link) { 5554c8945a0SNathan Whitehorn if (compare_bindings(entry, p) < 0) { 5564c8945a0SNathan Whitehorn break; 5574c8945a0SNathan Whitehorn } 5584c8945a0SNathan Whitehorn } 5594c8945a0SNathan Whitehorn if (q != 0) { 5604c8945a0SNathan Whitehorn q->link = entry; 5614c8945a0SNathan Whitehorn } else { 5624c8945a0SNathan Whitehorn all_bindings = entry; 5634c8945a0SNathan Whitehorn } 5644c8945a0SNathan Whitehorn if (p != 0) { 5654c8945a0SNathan Whitehorn entry->link = p; 5664c8945a0SNathan Whitehorn } 5674c8945a0SNathan Whitehorn result = data; 5684c8945a0SNathan Whitehorn } else if (entry != 0) { 5694c8945a0SNathan Whitehorn free(entry); 5704c8945a0SNathan Whitehorn if (data) 5714c8945a0SNathan Whitehorn free(data); 5724c8945a0SNathan Whitehorn } 5734c8945a0SNathan Whitehorn 5744c8945a0SNathan Whitehorn return result; 5754c8945a0SNathan Whitehorn } 5764c8945a0SNathan Whitehorn 5774c8945a0SNathan Whitehorn /* 5784c8945a0SNathan Whitehorn * Parse the parameters of the "bindkeys" configuration-file entry. This 5794c8945a0SNathan Whitehorn * expects widget name which may be "*", followed by curses key definition and 5804c8945a0SNathan Whitehorn * then dialog key definition. 5814c8945a0SNathan Whitehorn * 5824c8945a0SNathan Whitehorn * The curses key "should" be one of the names (ignoring case) from 5834c8945a0SNathan Whitehorn * curses_names[], but may also be a single control character (prefix "^" or 5844c8945a0SNathan Whitehorn * "~" depending on whether it is C0 or C1), or an escaped single character. 5854c8945a0SNathan Whitehorn * Binding a printable character with dialog is possible but not useful. 5864c8945a0SNathan Whitehorn * 5874c8945a0SNathan Whitehorn * The dialog key must be one of the names from dialog_names[]. 5884c8945a0SNathan Whitehorn */ 5894c8945a0SNathan Whitehorn int 5904c8945a0SNathan Whitehorn dlg_parse_bindkey(char *params) 5914c8945a0SNathan Whitehorn { 5924c8945a0SNathan Whitehorn char *p = skip_white(params); 5934c8945a0SNathan Whitehorn char *q; 5944c8945a0SNathan Whitehorn bool escaped = FALSE; 5954c8945a0SNathan Whitehorn int modified = 0; 5964c8945a0SNathan Whitehorn int result = FALSE; 5974c8945a0SNathan Whitehorn unsigned xx; 5984c8945a0SNathan Whitehorn char *widget; 5994c8945a0SNathan Whitehorn int is_function = FALSE; 6004c8945a0SNathan Whitehorn int curses_key; 6014c8945a0SNathan Whitehorn int dialog_key; 6024c8945a0SNathan Whitehorn 6034c8945a0SNathan Whitehorn curses_key = -1; 6044c8945a0SNathan Whitehorn dialog_key = -1; 6054c8945a0SNathan Whitehorn widget = p; 6064c8945a0SNathan Whitehorn 6074c8945a0SNathan Whitehorn p = skip_black(p); 6084c8945a0SNathan Whitehorn if (p != widget && *p != '\0') { 6094c8945a0SNathan Whitehorn *p++ = '\0'; 610*2a3e3873SBaptiste Daroussin p = skip_white(p); 6114c8945a0SNathan Whitehorn q = p; 6124c8945a0SNathan Whitehorn while (*p != '\0' && curses_key < 0) { 6134c8945a0SNathan Whitehorn if (escaped) { 6144c8945a0SNathan Whitehorn escaped = FALSE; 6154c8945a0SNathan Whitehorn curses_key = *p; 6164c8945a0SNathan Whitehorn } else if (*p == '\\') { 6174c8945a0SNathan Whitehorn escaped = TRUE; 6184c8945a0SNathan Whitehorn } else if (modified) { 6194c8945a0SNathan Whitehorn if (*p == '?') { 6204c8945a0SNathan Whitehorn curses_key = ((modified == '^') 6214c8945a0SNathan Whitehorn ? 127 6224c8945a0SNathan Whitehorn : 255); 6234c8945a0SNathan Whitehorn } else { 6244c8945a0SNathan Whitehorn curses_key = ((modified == '^') 6254c8945a0SNathan Whitehorn ? (*p & 0x1f) 6264c8945a0SNathan Whitehorn : ((*p & 0x1f) | 0x80)); 6274c8945a0SNathan Whitehorn } 6284c8945a0SNathan Whitehorn } else if (*p == '^') { 6294c8945a0SNathan Whitehorn modified = *p; 6304c8945a0SNathan Whitehorn } else if (*p == '~') { 6314c8945a0SNathan Whitehorn modified = *p; 6324c8945a0SNathan Whitehorn } else if (isspace(UCH(*p))) { 6334c8945a0SNathan Whitehorn break; 6344c8945a0SNathan Whitehorn } 6354c8945a0SNathan Whitehorn ++p; 6364c8945a0SNathan Whitehorn } 6374c8945a0SNathan Whitehorn if (!isspace(UCH(*p))) { 6384c8945a0SNathan Whitehorn ; 6394c8945a0SNathan Whitehorn } else { 6404c8945a0SNathan Whitehorn *p++ = '\0'; 6414c8945a0SNathan Whitehorn if (curses_key < 0) { 6424c8945a0SNathan Whitehorn char fprefix[2]; 6434c8945a0SNathan Whitehorn char check[2]; 6444c8945a0SNathan Whitehorn int keynumber; 6454c8945a0SNathan Whitehorn if (sscanf(q, "%[Ff]%d%c", fprefix, &keynumber, check) == 2) { 6464c8945a0SNathan Whitehorn curses_key = KEY_F(keynumber); 6474c8945a0SNathan Whitehorn is_function = TRUE; 6484c8945a0SNathan Whitehorn } else { 6494c8945a0SNathan Whitehorn for (xx = 0; xx < COUNT_CURSES; ++xx) { 6504c8945a0SNathan Whitehorn if (!dlg_strcmp(curses_names[xx].name, q)) { 6514c8945a0SNathan Whitehorn curses_key = curses_names[xx].code; 652*2a3e3873SBaptiste Daroussin is_function = (curses_key >= KEY_MIN); 6534c8945a0SNathan Whitehorn break; 6544c8945a0SNathan Whitehorn } 6554c8945a0SNathan Whitehorn } 6564c8945a0SNathan Whitehorn } 6574c8945a0SNathan Whitehorn } 6584c8945a0SNathan Whitehorn } 6594c8945a0SNathan Whitehorn q = skip_white(p); 6604c8945a0SNathan Whitehorn p = skip_black(q); 6614c8945a0SNathan Whitehorn if (p != q) { 6624c8945a0SNathan Whitehorn for (xx = 0; xx < COUNT_DIALOG; ++xx) { 6634c8945a0SNathan Whitehorn if (!dlg_strcmp(dialog_names[xx].name, q)) { 6644c8945a0SNathan Whitehorn dialog_key = dialog_names[xx].code; 6654c8945a0SNathan Whitehorn break; 6664c8945a0SNathan Whitehorn } 6674c8945a0SNathan Whitehorn } 6684c8945a0SNathan Whitehorn } 6694c8945a0SNathan Whitehorn if (*widget != '\0' 6704c8945a0SNathan Whitehorn && curses_key >= 0 6714c8945a0SNathan Whitehorn && dialog_key >= 0 6724c8945a0SNathan Whitehorn && make_binding(widget, curses_key, is_function, dialog_key) != 0) { 6734c8945a0SNathan Whitehorn result = TRUE; 6744c8945a0SNathan Whitehorn } 6754c8945a0SNathan Whitehorn } 6764c8945a0SNathan Whitehorn return result; 6774c8945a0SNathan Whitehorn } 6784c8945a0SNathan Whitehorn 6794c8945a0SNathan Whitehorn static void 6804c8945a0SNathan Whitehorn dump_curses_key(FILE *fp, int curses_key) 6814c8945a0SNathan Whitehorn { 6824c8945a0SNathan Whitehorn if (curses_key > KEY_MIN) { 6834c8945a0SNathan Whitehorn unsigned n; 6844c8945a0SNathan Whitehorn bool found = FALSE; 6854c8945a0SNathan Whitehorn for (n = 0; n < COUNT_CURSES; ++n) { 6864c8945a0SNathan Whitehorn if (curses_names[n].code == curses_key) { 6874c8945a0SNathan Whitehorn fprintf(fp, "%s", curses_names[n].name); 6884c8945a0SNathan Whitehorn found = TRUE; 6894c8945a0SNathan Whitehorn break; 6904c8945a0SNathan Whitehorn } 6914c8945a0SNathan Whitehorn } 6924c8945a0SNathan Whitehorn if (!found) { 6934c8945a0SNathan Whitehorn if (curses_key >= KEY_F(0)) { 6944c8945a0SNathan Whitehorn fprintf(fp, "F%d", curses_key - KEY_F(0)); 6954c8945a0SNathan Whitehorn } else { 6964c8945a0SNathan Whitehorn fprintf(fp, "curses%d", curses_key); 6974c8945a0SNathan Whitehorn } 6984c8945a0SNathan Whitehorn } 6994c8945a0SNathan Whitehorn } else if (curses_key >= 0 && curses_key < 32) { 7004c8945a0SNathan Whitehorn fprintf(fp, "^%c", curses_key + 64); 7014c8945a0SNathan Whitehorn } else if (curses_key == 127) { 7024c8945a0SNathan Whitehorn fprintf(fp, "^?"); 7034c8945a0SNathan Whitehorn } else if (curses_key >= 128 && curses_key < 160) { 7044c8945a0SNathan Whitehorn fprintf(fp, "~%c", curses_key - 64); 7054c8945a0SNathan Whitehorn } else if (curses_key == 255) { 7064c8945a0SNathan Whitehorn fprintf(fp, "~?"); 7074c8945a0SNathan Whitehorn } else { 7084c8945a0SNathan Whitehorn fprintf(fp, "\\%c", curses_key); 7094c8945a0SNathan Whitehorn } 7104c8945a0SNathan Whitehorn } 7114c8945a0SNathan Whitehorn 7124c8945a0SNathan Whitehorn static void 7134c8945a0SNathan Whitehorn dump_dialog_key(FILE *fp, int dialog_key) 7144c8945a0SNathan Whitehorn { 7154c8945a0SNathan Whitehorn unsigned n; 7164c8945a0SNathan Whitehorn bool found = FALSE; 7174c8945a0SNathan Whitehorn for (n = 0; n < COUNT_DIALOG; ++n) { 7184c8945a0SNathan Whitehorn if (dialog_names[n].code == dialog_key) { 7194c8945a0SNathan Whitehorn fputs(dialog_names[n].name, fp); 7204c8945a0SNathan Whitehorn found = TRUE; 7214c8945a0SNathan Whitehorn break; 7224c8945a0SNathan Whitehorn } 7234c8945a0SNathan Whitehorn } 7244c8945a0SNathan Whitehorn if (!found) { 7254c8945a0SNathan Whitehorn fprintf(fp, "dialog%d", dialog_key); 7264c8945a0SNathan Whitehorn } 7274c8945a0SNathan Whitehorn } 7284c8945a0SNathan Whitehorn 7294c8945a0SNathan Whitehorn static void 7304c8945a0SNathan Whitehorn dump_one_binding(FILE *fp, const char *widget, DLG_KEYS_BINDING * binding) 7314c8945a0SNathan Whitehorn { 7324c8945a0SNathan Whitehorn fprintf(fp, "bindkey %s ", widget); 7334c8945a0SNathan Whitehorn dump_curses_key(fp, binding->curses_key); 7344c8945a0SNathan Whitehorn fputc(' ', fp); 7354c8945a0SNathan Whitehorn dump_dialog_key(fp, binding->dialog_key); 7364c8945a0SNathan Whitehorn fputc('\n', fp); 7374c8945a0SNathan Whitehorn } 7384c8945a0SNathan Whitehorn 739*2a3e3873SBaptiste Daroussin /* 740*2a3e3873SBaptiste Daroussin * Dump bindings for the given window. If it is a null, then this dumps the 741*2a3e3873SBaptiste Daroussin * initial bindings which were loaded from the rc-file that are used as 742*2a3e3873SBaptiste Daroussin * overall defaults. 743*2a3e3873SBaptiste Daroussin */ 744*2a3e3873SBaptiste Daroussin void 745*2a3e3873SBaptiste Daroussin dlg_dump_window_keys(FILE *fp, WINDOW *win) 746*2a3e3873SBaptiste Daroussin { 747*2a3e3873SBaptiste Daroussin if (fp != 0) { 748*2a3e3873SBaptiste Daroussin LIST_BINDINGS *p; 749*2a3e3873SBaptiste Daroussin DLG_KEYS_BINDING *q; 750*2a3e3873SBaptiste Daroussin const char *last = ""; 751*2a3e3873SBaptiste Daroussin 752*2a3e3873SBaptiste Daroussin for (p = all_bindings; p != 0; p = p->link) { 753*2a3e3873SBaptiste Daroussin if (p->win == win) { 754*2a3e3873SBaptiste Daroussin if (dlg_strcmp(last, p->name)) { 755*2a3e3873SBaptiste Daroussin fprintf(fp, "\n# key bindings for %s widgets\n", 756*2a3e3873SBaptiste Daroussin !strcmp(p->name, WILDNAME) ? "all" : p->name); 757*2a3e3873SBaptiste Daroussin last = p->name; 758*2a3e3873SBaptiste Daroussin } 759*2a3e3873SBaptiste Daroussin for (q = p->binding; q->is_function_key >= 0; ++q) { 760*2a3e3873SBaptiste Daroussin dump_one_binding(fp, p->name, q); 761*2a3e3873SBaptiste Daroussin } 762*2a3e3873SBaptiste Daroussin } 763*2a3e3873SBaptiste Daroussin } 764*2a3e3873SBaptiste Daroussin } 765*2a3e3873SBaptiste Daroussin } 766*2a3e3873SBaptiste Daroussin 767*2a3e3873SBaptiste Daroussin /* 768*2a3e3873SBaptiste Daroussin * Dump all of the bindings which are not specific to a given widget, i.e., 769*2a3e3873SBaptiste Daroussin * the "win" member is null. 770*2a3e3873SBaptiste Daroussin */ 7714c8945a0SNathan Whitehorn void 7724c8945a0SNathan Whitehorn dlg_dump_keys(FILE *fp) 7734c8945a0SNathan Whitehorn { 774*2a3e3873SBaptiste Daroussin if (fp != 0) { 7754c8945a0SNathan Whitehorn LIST_BINDINGS *p; 7764c8945a0SNathan Whitehorn unsigned count = 0; 7774c8945a0SNathan Whitehorn 7784c8945a0SNathan Whitehorn for (p = all_bindings; p != 0; p = p->link) { 7794c8945a0SNathan Whitehorn if (p->win == 0) { 7804c8945a0SNathan Whitehorn ++count; 7814c8945a0SNathan Whitehorn } 7824c8945a0SNathan Whitehorn } 7834c8945a0SNathan Whitehorn if (count != 0) { 784*2a3e3873SBaptiste Daroussin dlg_dump_window_keys(fp, 0); 7854c8945a0SNathan Whitehorn } 7864c8945a0SNathan Whitehorn } 7874c8945a0SNathan Whitehorn } 7884c8945a0SNathan Whitehorn #endif /* HAVE_RC_FILE */ 789