push
This commit is contained in:
822
keys.c
Normal file
822
keys.c
Normal file
@@ -0,0 +1,822 @@
|
||||
/*
|
||||
* Copyright 2008-2013 Various Authors
|
||||
* Copyright 2004-2006 Timo Hirvonen
|
||||
*
|
||||
* keys.[ch] by Frank Terbeck <ft@bewatermyfriend.org>
|
||||
* heavily modified by Timo Hirvonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "keys.h"
|
||||
#include "help.h"
|
||||
#include "ui_curses.h"
|
||||
#include "command_mode.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#include "window.h"
|
||||
#include "options.h"
|
||||
#include "editable.h"
|
||||
#include "lib.h"
|
||||
#include "pl.h"
|
||||
|
||||
const char * const key_context_names[NR_CTXS + 1] = {
|
||||
"browser",
|
||||
"common",
|
||||
"filters",
|
||||
"library",
|
||||
"playlist",
|
||||
"queue",
|
||||
"settings",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct binding *key_bindings[NR_CTXS] = { NULL, };
|
||||
|
||||
static const enum key_context view_to_context[] = {
|
||||
CTX_LIBRARY,
|
||||
CTX_LIBRARY,
|
||||
CTX_PLAYLIST,
|
||||
CTX_QUEUE,
|
||||
CTX_BROWSER,
|
||||
CTX_FILTERS,
|
||||
CTX_SETTINGS,
|
||||
};
|
||||
|
||||
#define KEY_IS_CHAR -255
|
||||
|
||||
#define KEY_M_TYPE_NONE (0<<3)
|
||||
#define KEY_M_TYPE_SEL (1<<3)
|
||||
#define KEY_M_TYPE_BAR (2<<3)
|
||||
#define KEY_M_TYPE_TIT (3<<3)
|
||||
#define KEY_M_TYPE_BAR_R (4<<3)
|
||||
|
||||
#define KEY_MLB_CLICK 0
|
||||
#define KEY_MRB_CLICK 1
|
||||
#define KEY_MSCRL_UP 2
|
||||
#define KEY_MSCRL_DOWN 3
|
||||
#define KEY_MLB_CLICK_SEL (KEY_MLB_CLICK|KEY_M_TYPE_SEL)
|
||||
#define KEY_MRB_CLICK_SEL (KEY_MRB_CLICK|KEY_M_TYPE_SEL)
|
||||
#define KEY_MLB_CLICK_BAR (KEY_MLB_CLICK|KEY_M_TYPE_BAR)
|
||||
#define KEY_MRB_CLICK_BAR (KEY_MRB_CLICK|KEY_M_TYPE_BAR)
|
||||
#define KEY_MSCRL_UP_BAR (KEY_MSCRL_UP|KEY_M_TYPE_BAR)
|
||||
#define KEY_MSCRL_DOWN_BAR (KEY_MSCRL_DOWN|KEY_M_TYPE_BAR)
|
||||
#define KEY_MLB_CLICK_BAR_R (KEY_MLB_CLICK|KEY_M_TYPE_BAR_R)
|
||||
#define KEY_MRB_CLICK_BAR_R (KEY_MRB_CLICK|KEY_M_TYPE_BAR_R)
|
||||
#define KEY_MSCRL_UP_BAR_R (KEY_MSCRL_UP|KEY_M_TYPE_BAR_R)
|
||||
#define KEY_MSCRL_DOWN_BAR_R (KEY_MSCRL_DOWN|KEY_M_TYPE_BAR_R)
|
||||
#define KEY_MLB_CLICK_TIT (KEY_MLB_CLICK|KEY_M_TYPE_TIT)
|
||||
#define KEY_MRB_CLICK_TIT (KEY_MRB_CLICK|KEY_M_TYPE_TIT)
|
||||
#define KEY_MSCRL_UP_TIT (KEY_MSCRL_UP|KEY_M_TYPE_TIT)
|
||||
#define KEY_MSCRL_DOWN_TIT (KEY_MSCRL_DOWN|KEY_M_TYPE_TIT)
|
||||
|
||||
/* key_table {{{
|
||||
*
|
||||
* key: KEY_IS_CHAR, not a key
|
||||
* ch: 0, not a char
|
||||
* key: KEY_MOUSE, neither key, nor char
|
||||
*/
|
||||
const struct key key_table[] = {
|
||||
{ "!", KEY_IS_CHAR, 33 },
|
||||
{ "\"", KEY_IS_CHAR, 34 },
|
||||
{ "#", KEY_IS_CHAR, 35 },
|
||||
{ "$", KEY_IS_CHAR, 36 },
|
||||
{ "%", KEY_IS_CHAR, 37 },
|
||||
{ "&", KEY_IS_CHAR, 38 },
|
||||
{ "'", KEY_IS_CHAR, 39 },
|
||||
{ "(", KEY_IS_CHAR, 40 },
|
||||
{ ")", KEY_IS_CHAR, 41 },
|
||||
{ "*", KEY_IS_CHAR, 42 },
|
||||
{ "+", KEY_IS_CHAR, 43 },
|
||||
{ ",", KEY_IS_CHAR, 44 },
|
||||
{ "-", KEY_IS_CHAR, 45 },
|
||||
{ ".", KEY_IS_CHAR, 46 },
|
||||
{ "/", KEY_IS_CHAR, 47 },
|
||||
{ "0", KEY_IS_CHAR, 48 },
|
||||
{ "1", KEY_IS_CHAR, 49 },
|
||||
{ "2", KEY_IS_CHAR, 50 },
|
||||
{ "3", KEY_IS_CHAR, 51 },
|
||||
{ "4", KEY_IS_CHAR, 52 },
|
||||
{ "5", KEY_IS_CHAR, 53 },
|
||||
{ "6", KEY_IS_CHAR, 54 },
|
||||
{ "7", KEY_IS_CHAR, 55 },
|
||||
{ "8", KEY_IS_CHAR, 56 },
|
||||
{ "9", KEY_IS_CHAR, 57 },
|
||||
{ ":", KEY_IS_CHAR, 58 },
|
||||
{ ";", KEY_IS_CHAR, 59 },
|
||||
{ "<", KEY_IS_CHAR, 60 },
|
||||
{ "=", KEY_IS_CHAR, 61 },
|
||||
{ ">", KEY_IS_CHAR, 62 },
|
||||
{ "?", KEY_IS_CHAR, 63 },
|
||||
{ "@", KEY_IS_CHAR, 64 },
|
||||
{ "A", KEY_IS_CHAR, 65 },
|
||||
{ "B", KEY_IS_CHAR, 66 },
|
||||
{ "C", KEY_IS_CHAR, 67 },
|
||||
{ "D", KEY_IS_CHAR, 68 },
|
||||
{ "E", KEY_IS_CHAR, 69 },
|
||||
{ "F", KEY_IS_CHAR, 70 },
|
||||
{ "F1", KEY_F(1), 0 },
|
||||
{ "F10", KEY_F(10), 0 },
|
||||
{ "F11", KEY_F(11), 0 },
|
||||
{ "F12", KEY_F(12), 0 },
|
||||
{ "F2", KEY_F(2), 0 },
|
||||
{ "F3", KEY_F(3), 0 },
|
||||
{ "F4", KEY_F(4), 0 },
|
||||
{ "F5", KEY_F(5), 0 },
|
||||
{ "F6", KEY_F(6), 0 },
|
||||
{ "F7", KEY_F(7), 0 },
|
||||
{ "F8", KEY_F(8), 0 },
|
||||
{ "F9", KEY_F(9), 0 },
|
||||
{ "G", KEY_IS_CHAR, 71 },
|
||||
{ "H", KEY_IS_CHAR, 72 },
|
||||
{ "I", KEY_IS_CHAR, 73 },
|
||||
{ "J", KEY_IS_CHAR, 74 },
|
||||
{ "K", KEY_IS_CHAR, 75 },
|
||||
{ "KP_center", KEY_B2, 0 },
|
||||
{ "KP_lower_left", KEY_C1, 0 },
|
||||
{ "KP_lower_right", KEY_C3, 0 },
|
||||
{ "KP_upper_left", KEY_A1, 0 },
|
||||
{ "KP_upper_right", KEY_A3, 0 },
|
||||
{ "L", KEY_IS_CHAR, 76 },
|
||||
{ "M", KEY_IS_CHAR, 77 },
|
||||
{ "M-!", KEY_IS_CHAR, 161 },
|
||||
{ "M-\"", KEY_IS_CHAR, 162 },
|
||||
{ "M-#", KEY_IS_CHAR, 163 },
|
||||
{ "M-$", KEY_IS_CHAR, 164 },
|
||||
{ "M-%", KEY_IS_CHAR, 165 },
|
||||
{ "M-&", KEY_IS_CHAR, 166 },
|
||||
{ "M-'", KEY_IS_CHAR, 167 },
|
||||
{ "M-(", KEY_IS_CHAR, 168 },
|
||||
{ "M-)", KEY_IS_CHAR, 169 },
|
||||
{ "M-*", KEY_IS_CHAR, 170 },
|
||||
{ "M-+", KEY_IS_CHAR, 171 },
|
||||
{ "M-,", KEY_IS_CHAR, 172 },
|
||||
{ "M--", KEY_IS_CHAR, 173 },
|
||||
{ "M-.", KEY_IS_CHAR, 174 },
|
||||
{ "M-/", KEY_IS_CHAR, 175 },
|
||||
{ "M-0", KEY_IS_CHAR, 176 },
|
||||
{ "M-1", KEY_IS_CHAR, 177 },
|
||||
{ "M-2", KEY_IS_CHAR, 178 },
|
||||
{ "M-3", KEY_IS_CHAR, 179 },
|
||||
{ "M-4", KEY_IS_CHAR, 180 },
|
||||
{ "M-5", KEY_IS_CHAR, 181 },
|
||||
{ "M-6", KEY_IS_CHAR, 182 },
|
||||
{ "M-7", KEY_IS_CHAR, 183 },
|
||||
{ "M-8", KEY_IS_CHAR, 184 },
|
||||
{ "M-9", KEY_IS_CHAR, 185 },
|
||||
{ "M-:", KEY_IS_CHAR, 186 },
|
||||
{ "M-;", KEY_IS_CHAR, 187 },
|
||||
{ "M-<", KEY_IS_CHAR, 188 },
|
||||
{ "M-=", KEY_IS_CHAR, 189 },
|
||||
{ "M->", KEY_IS_CHAR, 190 },
|
||||
{ "M-?", KEY_IS_CHAR, 191 },
|
||||
{ "M-@", KEY_IS_CHAR, 192 },
|
||||
{ "M-A", KEY_IS_CHAR, 193 },
|
||||
{ "M-B", KEY_IS_CHAR, 194 },
|
||||
{ "M-C", KEY_IS_CHAR, 195 },
|
||||
{ "M-D", KEY_IS_CHAR, 196 },
|
||||
{ "M-E", KEY_IS_CHAR, 197 },
|
||||
{ "M-F", KEY_IS_CHAR, 198 },
|
||||
{ "M-G", KEY_IS_CHAR, 199 },
|
||||
{ "M-H", KEY_IS_CHAR, 200 },
|
||||
{ "M-I", KEY_IS_CHAR, 201 },
|
||||
{ "M-J", KEY_IS_CHAR, 202 },
|
||||
{ "M-K", KEY_IS_CHAR, 203 },
|
||||
{ "M-L", KEY_IS_CHAR, 204 },
|
||||
{ "M-M", KEY_IS_CHAR, 205 },
|
||||
{ "M-N", KEY_IS_CHAR, 206 },
|
||||
{ "M-O", KEY_IS_CHAR, 207 },
|
||||
{ "M-P", KEY_IS_CHAR, 208 },
|
||||
{ "M-Q", KEY_IS_CHAR, 209 },
|
||||
{ "M-R", KEY_IS_CHAR, 210 },
|
||||
{ "M-S", KEY_IS_CHAR, 211 },
|
||||
{ "M-T", KEY_IS_CHAR, 212 },
|
||||
{ "M-U", KEY_IS_CHAR, 213 },
|
||||
{ "M-V", KEY_IS_CHAR, 214 },
|
||||
{ "M-W", KEY_IS_CHAR, 215 },
|
||||
{ "M-X", KEY_IS_CHAR, 216 },
|
||||
{ "M-Y", KEY_IS_CHAR, 217 },
|
||||
{ "M-Z", KEY_IS_CHAR, 218 },
|
||||
{ "M-[", KEY_IS_CHAR, 219 },
|
||||
{ "M-\\", KEY_IS_CHAR, 220 },
|
||||
{ "M-]", KEY_IS_CHAR, 221 },
|
||||
{ "M-^", KEY_IS_CHAR, 222 },
|
||||
{ "M-^?", KEY_IS_CHAR, 255 },
|
||||
{ "M-^@", KEY_IS_CHAR, 128 },
|
||||
{ "M-^A", KEY_IS_CHAR, 129 },
|
||||
{ "M-^B", KEY_IS_CHAR, 130 },
|
||||
{ "M-^C", KEY_IS_CHAR, 131 },
|
||||
{ "M-^D", KEY_IS_CHAR, 132 },
|
||||
{ "M-^E", KEY_IS_CHAR, 133 },
|
||||
{ "M-^F", KEY_IS_CHAR, 134 },
|
||||
{ "M-^G", KEY_IS_CHAR, 135 },
|
||||
{ "M-^H", KEY_IS_CHAR, 136 },
|
||||
{ "M-^I", KEY_IS_CHAR, 137 },
|
||||
{ "M-^J", KEY_IS_CHAR, 138 },
|
||||
{ "M-^K", KEY_IS_CHAR, 139 },
|
||||
{ "M-^L", KEY_IS_CHAR, 140 },
|
||||
{ "M-^M", KEY_IS_CHAR, 141 },
|
||||
{ "M-^N", KEY_IS_CHAR, 142 },
|
||||
{ "M-^O", KEY_IS_CHAR, 143 },
|
||||
{ "M-^P", KEY_IS_CHAR, 144 },
|
||||
{ "M-^Q", KEY_IS_CHAR, 145 },
|
||||
{ "M-^R", KEY_IS_CHAR, 146 },
|
||||
{ "M-^S", KEY_IS_CHAR, 147 },
|
||||
{ "M-^T", KEY_IS_CHAR, 148 },
|
||||
{ "M-^U", KEY_IS_CHAR, 149 },
|
||||
{ "M-^V", KEY_IS_CHAR, 150 },
|
||||
{ "M-^W", KEY_IS_CHAR, 151 },
|
||||
{ "M-^X", KEY_IS_CHAR, 152 },
|
||||
{ "M-^Y", KEY_IS_CHAR, 153 },
|
||||
{ "M-^Z", KEY_IS_CHAR, 154 },
|
||||
{ "M-^[", KEY_IS_CHAR, 155 },
|
||||
{ "M-^\\", KEY_IS_CHAR, 156 },
|
||||
{ "M-^]", KEY_IS_CHAR, 157 },
|
||||
{ "M-^^", KEY_IS_CHAR, 158 },
|
||||
{ "M-^_", KEY_IS_CHAR, 159 },
|
||||
{ "M-_", KEY_IS_CHAR, 223 },
|
||||
{ "M-`", KEY_IS_CHAR, 224 },
|
||||
{ "M-a", KEY_IS_CHAR, 225 },
|
||||
{ "M-b", KEY_IS_CHAR, 226 },
|
||||
{ "M-c", KEY_IS_CHAR, 227 },
|
||||
{ "M-d", KEY_IS_CHAR, 228 },
|
||||
{ "M-e", KEY_IS_CHAR, 229 },
|
||||
{ "M-f", KEY_IS_CHAR, 230 },
|
||||
{ "M-g", KEY_IS_CHAR, 231 },
|
||||
{ "M-h", KEY_IS_CHAR, 232 },
|
||||
{ "M-i", KEY_IS_CHAR, 233 },
|
||||
{ "M-j", KEY_IS_CHAR, 234 },
|
||||
{ "M-k", KEY_IS_CHAR, 235 },
|
||||
{ "M-l", KEY_IS_CHAR, 236 },
|
||||
{ "M-m", KEY_IS_CHAR, 237 },
|
||||
{ "M-n", KEY_IS_CHAR, 238 },
|
||||
{ "M-o", KEY_IS_CHAR, 239 },
|
||||
{ "M-p", KEY_IS_CHAR, 240 },
|
||||
{ "M-q", KEY_IS_CHAR, 241 },
|
||||
{ "M-r", KEY_IS_CHAR, 242 },
|
||||
{ "M-s", KEY_IS_CHAR, 243 },
|
||||
{ "M-space", KEY_IS_CHAR, 160 },
|
||||
{ "M-t", KEY_IS_CHAR, 244 },
|
||||
{ "M-u", KEY_IS_CHAR, 245 },
|
||||
{ "M-v", KEY_IS_CHAR, 246 },
|
||||
{ "M-w", KEY_IS_CHAR, 247 },
|
||||
{ "M-x", KEY_IS_CHAR, 248 },
|
||||
{ "M-y", KEY_IS_CHAR, 249 },
|
||||
{ "M-z", KEY_IS_CHAR, 250 },
|
||||
{ "M-{", KEY_IS_CHAR, 251 },
|
||||
{ "M-|", KEY_IS_CHAR, 252 },
|
||||
{ "M-}", KEY_IS_CHAR, 253 },
|
||||
{ "M-~", KEY_IS_CHAR, 254 },
|
||||
{ "N", KEY_IS_CHAR, 78 },
|
||||
{ "O", KEY_IS_CHAR, 79 },
|
||||
{ "P", KEY_IS_CHAR, 80 },
|
||||
{ "Q", KEY_IS_CHAR, 81 },
|
||||
{ "R", KEY_IS_CHAR, 82 },
|
||||
{ "S", KEY_IS_CHAR, 83 },
|
||||
{ "S-begin", KEY_SBEG, 0 },
|
||||
{ "S-cancel", KEY_SCANCEL, 0 },
|
||||
{ "S-command", KEY_SCOMMAND, 0 },
|
||||
{ "S-copy", KEY_SCOPY, 0 },
|
||||
{ "S-create", KEY_SCREATE, 0 },
|
||||
{ "S-del_line", KEY_SDL, 0 },
|
||||
{ "S-delete", KEY_SDC, 0 },
|
||||
{ "S-eol", KEY_SEOL, 0 },
|
||||
{ "S-exit", KEY_SEXIT, 0 },
|
||||
{ "S-find", KEY_SFIND, 0 },
|
||||
{ "S-help", KEY_SHELP, 0 },
|
||||
{ "S-home", KEY_SHOME, 0 },
|
||||
{ "S-insert", KEY_SIC, 0 },
|
||||
{ "S-left", KEY_SLEFT, 0 },
|
||||
{ "S-message", KEY_SMESSAGE, 0 },
|
||||
{ "S-move", KEY_SMOVE, 0 },
|
||||
{ "S-next", KEY_SNEXT, 0 },
|
||||
{ "S-options", KEY_SOPTIONS, 0 },
|
||||
{ "S-previous", KEY_SPREVIOUS, 0 },
|
||||
{ "S-print", KEY_SPRINT, 0 },
|
||||
{ "S-redo", KEY_SREDO, 0 },
|
||||
{ "S-replace", KEY_SREPLACE, 0 },
|
||||
{ "S-resume", KEY_SRSUME, 0 },
|
||||
{ "S-right", KEY_SRIGHT, 0 },
|
||||
{ "S-save", KEY_SSAVE, 0 },
|
||||
{ "S-suspend", KEY_SSUSPEND, 0 },
|
||||
{ "S-undo", KEY_SUNDO, 0 },
|
||||
{ "T", KEY_IS_CHAR, 84 },
|
||||
{ "U", KEY_IS_CHAR, 85 },
|
||||
{ "V", KEY_IS_CHAR, 86 },
|
||||
{ "W", KEY_IS_CHAR, 87 },
|
||||
{ "X", KEY_IS_CHAR, 88 },
|
||||
{ "Y", KEY_IS_CHAR, 89 },
|
||||
{ "Z", KEY_IS_CHAR, 90 },
|
||||
{ "[", KEY_IS_CHAR, 91 },
|
||||
{ "\\", KEY_IS_CHAR, 92 },
|
||||
{ "]", KEY_IS_CHAR, 93 },
|
||||
{ "^", KEY_IS_CHAR, 94 },
|
||||
{ "^A", KEY_IS_CHAR, 1 },
|
||||
{ "^B", KEY_IS_CHAR, 2 },
|
||||
{ "^C", KEY_IS_CHAR, 3 },
|
||||
{ "^D", KEY_IS_CHAR, 4 },
|
||||
{ "^E", KEY_IS_CHAR, 5 },
|
||||
{ "^F", KEY_IS_CHAR, 6 },
|
||||
{ "^G", KEY_IS_CHAR, 7 },
|
||||
{ "^H", KEY_IS_CHAR, 8 },
|
||||
{ "^K", KEY_IS_CHAR, 11 },
|
||||
{ "^L", KEY_IS_CHAR, 12 },
|
||||
{ "^M", KEY_IS_CHAR, 13 },
|
||||
{ "^N", KEY_IS_CHAR, 14 },
|
||||
{ "^O", KEY_IS_CHAR, 15 },
|
||||
{ "^P", KEY_IS_CHAR, 16 },
|
||||
{ "^Q", KEY_IS_CHAR, 17 },
|
||||
{ "^R", KEY_IS_CHAR, 18 },
|
||||
{ "^S", KEY_IS_CHAR, 19 },
|
||||
{ "^T", KEY_IS_CHAR, 20 },
|
||||
{ "^U", KEY_IS_CHAR, 21 },
|
||||
{ "^V", KEY_IS_CHAR, 22 },
|
||||
{ "^W", KEY_IS_CHAR, 23 },
|
||||
{ "^X", KEY_IS_CHAR, 24 },
|
||||
{ "^Y", KEY_IS_CHAR, 25 },
|
||||
{ "^Z", KEY_IS_CHAR, 26 },
|
||||
{ "^\\", KEY_IS_CHAR, 28 },
|
||||
{ "^]", KEY_IS_CHAR, 29 },
|
||||
{ "^^", KEY_IS_CHAR, 30 },
|
||||
{ "^_", KEY_IS_CHAR, 31 },
|
||||
{ "_", KEY_IS_CHAR, 95 },
|
||||
{ "`", KEY_IS_CHAR, 96 },
|
||||
{ "a", KEY_IS_CHAR, 97 },
|
||||
{ "b", KEY_IS_CHAR, 98 },
|
||||
{ "back_tab", KEY_BTAB, 0 },
|
||||
{ "backspace", KEY_BACKSPACE, 127 }, /* NOTE: both key and ch */
|
||||
{ "begin", KEY_BEG, 0 },
|
||||
{ "c", KEY_IS_CHAR, 99 },
|
||||
{ "cancel", KEY_CANCEL, 0 },
|
||||
{ "clear", KEY_CLEAR, 0 },
|
||||
{ "clear_all_tabs", KEY_CATAB, 0 },
|
||||
{ "clear_tab", KEY_CTAB, 0 },
|
||||
{ "close", KEY_CLOSE, 0 },
|
||||
{ "command", KEY_COMMAND, 0 },
|
||||
{ "copy", KEY_COPY, 0 },
|
||||
{ "create", KEY_CREATE, 0 },
|
||||
{ "d", KEY_IS_CHAR, 100 },
|
||||
{ "del_line", KEY_DL, 0 },
|
||||
{ "delete", KEY_DC, 0 },
|
||||
{ "down", KEY_DOWN, 0 },
|
||||
{ "e", KEY_IS_CHAR, 101 },
|
||||
{ "eic", KEY_EIC, 0 },
|
||||
{ "end", KEY_END, 0 },
|
||||
{ "enter", KEY_IS_CHAR, 10 },
|
||||
{ "eol", KEY_EOL, 0 },
|
||||
{ "eos", KEY_EOS, 0 },
|
||||
{ "exit", KEY_EXIT, 0 },
|
||||
{ "f", KEY_IS_CHAR, 102 },
|
||||
{ "find", KEY_FIND, 0 },
|
||||
{ "g", KEY_IS_CHAR, 103 },
|
||||
{ "h", KEY_IS_CHAR, 104 },
|
||||
{ "help", KEY_HELP, 0 },
|
||||
{ "home", KEY_HOME, 0 },
|
||||
{ "i", KEY_IS_CHAR, 105 },
|
||||
{ "ins_line", KEY_IL, 0 },
|
||||
{ "insert", KEY_IC, 0 },
|
||||
{ "j", KEY_IS_CHAR, 106 },
|
||||
{ "k", KEY_IS_CHAR, 107 },
|
||||
{ "l", KEY_IS_CHAR, 108 },
|
||||
{ "left", KEY_LEFT, 0 },
|
||||
{ "lower_left", KEY_LL, 0 },
|
||||
{ "m", KEY_IS_CHAR, 109 },
|
||||
{ "mark", KEY_MARK, 0 },
|
||||
{ "message", KEY_MESSAGE, 0 },
|
||||
{ "move", KEY_MOVE, 0 },
|
||||
{ "n", KEY_IS_CHAR, 110 },
|
||||
{ "next", KEY_NEXT, 0 },
|
||||
{ "o", KEY_IS_CHAR, 111 },
|
||||
{ "open", KEY_OPEN, 0 },
|
||||
{ "options", KEY_OPTIONS, 0 },
|
||||
{ "p", KEY_IS_CHAR, 112 },
|
||||
{ "page_down", KEY_NPAGE, 0 },
|
||||
{ "page_up", KEY_PPAGE, 0 },
|
||||
{ "previous", KEY_PREVIOUS, 0 },
|
||||
{ "print", KEY_PRINT, 0 },
|
||||
{ "q", KEY_IS_CHAR, 113 },
|
||||
{ "r", KEY_IS_CHAR, 114 },
|
||||
{ "redo", KEY_REDO, 0 },
|
||||
{ "reference", KEY_REFERENCE, 0 },
|
||||
{ "refresh", KEY_REFRESH, 0 },
|
||||
{ "replace", KEY_REPLACE, 0 },
|
||||
{ "restart", KEY_RESTART, 0 },
|
||||
{ "resume", KEY_RESUME, 0 },
|
||||
{ "right", KEY_RIGHT, 0 },
|
||||
{ "s", KEY_IS_CHAR, 115 },
|
||||
{ "save", KEY_SAVE, 0 },
|
||||
{ "scroll_b", KEY_SR, 0 },
|
||||
{ "scroll_f", KEY_SF, 0 },
|
||||
{ "select", KEY_SELECT, 0 },
|
||||
{ "send", KEY_SEND, 0 },
|
||||
{ "set_tab", KEY_STAB, 0 },
|
||||
{ "space", KEY_IS_CHAR, 32 },
|
||||
{ "suspend", KEY_SUSPEND, 0 },
|
||||
{ "t", KEY_IS_CHAR, 116 },
|
||||
{ "tab", KEY_IS_CHAR, 9 },
|
||||
{ "u", KEY_IS_CHAR, 117 },
|
||||
{ "undo", KEY_UNDO, 0 },
|
||||
{ "up", KEY_UP, 0 },
|
||||
{ "v", KEY_IS_CHAR, 118 },
|
||||
{ "w", KEY_IS_CHAR, 119 },
|
||||
{ "x", KEY_IS_CHAR, 120 },
|
||||
{ "y", KEY_IS_CHAR, 121 },
|
||||
{ "z", KEY_IS_CHAR, 122 },
|
||||
{ "{", KEY_IS_CHAR, 123 },
|
||||
{ "|", KEY_IS_CHAR, 124 },
|
||||
{ "}", KEY_IS_CHAR, 125 },
|
||||
{ "~", KEY_IS_CHAR, 126 },
|
||||
{ "mlb_click", KEY_MOUSE, KEY_MLB_CLICK },
|
||||
{ "mlb_click_selected", KEY_MOUSE, KEY_MLB_CLICK_SEL },
|
||||
{ "mlb_click_bar", KEY_MOUSE, KEY_MLB_CLICK_BAR },
|
||||
{ "mlb_click_bar_right", KEY_MOUSE, KEY_MLB_CLICK_BAR_R },
|
||||
{ "mlb_click_title", KEY_MOUSE, KEY_MLB_CLICK_TIT },
|
||||
{ "mrb_click", KEY_MOUSE, KEY_MRB_CLICK },
|
||||
{ "mrb_click_selected", KEY_MOUSE, KEY_MRB_CLICK_SEL },
|
||||
{ "mrb_click_bar", KEY_MOUSE, KEY_MRB_CLICK_BAR },
|
||||
{ "mrb_click_bar_right", KEY_MOUSE, KEY_MRB_CLICK_BAR_R },
|
||||
{ "mrb_click_title", KEY_MOUSE, KEY_MRB_CLICK_TIT },
|
||||
{ "mouse_scroll_up", KEY_MOUSE, KEY_MSCRL_UP },
|
||||
{ "mouse_scroll_up_bar", KEY_MOUSE, KEY_MSCRL_UP_BAR },
|
||||
{ "mouse_scroll_up_bar_right", KEY_MOUSE, KEY_MSCRL_UP_BAR_R },
|
||||
{ "mouse_scroll_up_title", KEY_MOUSE, KEY_MSCRL_UP_TIT },
|
||||
{ "mouse_scroll_down", KEY_MOUSE, KEY_MSCRL_DOWN },
|
||||
{ "mouse_scroll_down_bar", KEY_MOUSE, KEY_MSCRL_DOWN_BAR },
|
||||
{ "mouse_scroll_down_bar_right", KEY_MOUSE, KEY_MSCRL_DOWN_BAR_R },
|
||||
{ "mouse_scroll_down_title", KEY_MOUSE, KEY_MSCRL_DOWN_TIT },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
static int find_context(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NR_CTXS; i++) {
|
||||
if (strcmp(name, key_context_names[i]) == 0)
|
||||
return i;
|
||||
}
|
||||
error_msg("invalid context '%s'", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct key *find_key(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; key_table[i].name; i++) {
|
||||
if (strcmp(name, key_table[i].name) == 0)
|
||||
return &key_table[i];
|
||||
}
|
||||
error_msg("invalid key '%s'", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct binding *find_binding(enum key_context c, const struct key *k)
|
||||
{
|
||||
struct binding *b = key_bindings[c];
|
||||
|
||||
while (b) {
|
||||
if (b->key == k)
|
||||
break;
|
||||
b = b->next;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void show_binding(const char *context, const char *key)
|
||||
{
|
||||
const struct key *k;
|
||||
const struct binding *b;
|
||||
int c;
|
||||
|
||||
c = find_context(context);
|
||||
if (c < 0)
|
||||
return;
|
||||
|
||||
k = find_key(key);
|
||||
if (k == NULL)
|
||||
return;
|
||||
|
||||
b = find_binding(c, k);
|
||||
if (b == NULL) {
|
||||
info_msg("No such binding");
|
||||
} else {
|
||||
info_msg("bind %s %s %s", context, key, b->cmd);
|
||||
}
|
||||
}
|
||||
|
||||
int key_bind(const char *context, const char *key, const char *cmd, int force)
|
||||
{
|
||||
const struct key *k;
|
||||
struct binding *b, *ptr, *prev;
|
||||
struct command *command;
|
||||
int c, size;
|
||||
|
||||
c = find_context(context);
|
||||
if (c < 0)
|
||||
return -1;
|
||||
|
||||
k = find_key(key);
|
||||
if (k == NULL)
|
||||
return -1;
|
||||
|
||||
/* check if already bound */
|
||||
b = find_binding(c, k);
|
||||
if (b) {
|
||||
if (!force)
|
||||
goto bound;
|
||||
key_unbind(context, key, 0);
|
||||
}
|
||||
|
||||
if (*cmd == ':')
|
||||
cmd++;
|
||||
size = strlen(cmd) + 1;
|
||||
|
||||
b = xmalloc(sizeof(struct binding) + size);
|
||||
b->key = k;
|
||||
b->ctx = c;
|
||||
memcpy(b->cmd, cmd, size);
|
||||
|
||||
/* insert keeping sorted by key */
|
||||
prev = NULL;
|
||||
ptr = key_bindings[c];
|
||||
while (ptr) {
|
||||
if (strcmp(b->key->name, ptr->key->name) < 0)
|
||||
break;
|
||||
prev = ptr;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
b->next = ptr;
|
||||
if (prev) {
|
||||
prev->next = b;
|
||||
} else {
|
||||
key_bindings[c] = b;
|
||||
}
|
||||
command = get_command(cmd);
|
||||
if (command && !command->bc++)
|
||||
help_remove_unbound(command);
|
||||
help_add_bound(b);
|
||||
return 0;
|
||||
bound:
|
||||
error_msg("key %s already bound in context %s", key, key_context_names[c]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int key_unbind(const char *context, const char *key, int force)
|
||||
{
|
||||
int c;
|
||||
const struct key *k;
|
||||
struct binding *b, *prev;
|
||||
struct command *command;
|
||||
|
||||
c = find_context(context);
|
||||
if (c < 0)
|
||||
return -1;
|
||||
|
||||
k = find_key(key);
|
||||
if (k == NULL)
|
||||
return -1;
|
||||
|
||||
prev = NULL;
|
||||
b = key_bindings[c];
|
||||
while (b) {
|
||||
if (b->key == k) {
|
||||
if (prev) {
|
||||
prev->next = b->next;
|
||||
} else {
|
||||
key_bindings[c] = b->next;
|
||||
}
|
||||
command = get_command(b->cmd);
|
||||
if (command && !--command->bc)
|
||||
help_add_unbound(command);
|
||||
help_remove_bound(b);
|
||||
free(b);
|
||||
return 0;
|
||||
}
|
||||
prev = b;
|
||||
b = b->next;
|
||||
}
|
||||
if (!force) {
|
||||
error_msg("key %s not bound in context %s", key, context);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_key(const struct binding *b, const struct key *k)
|
||||
{
|
||||
while (b) {
|
||||
if (b->key == k) {
|
||||
run_command(b->cmd);
|
||||
return 1;
|
||||
}
|
||||
b = b->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct key *ch_to_key(uchar ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; key_table[i].name; i++) {
|
||||
if (key_table[i].key != KEY_MOUSE && key_table[i].ch == ch)
|
||||
return &key_table[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct key *keycode_to_key(int key)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; key_table[i].name; i++) {
|
||||
if (key_table[i].key != KEY_IS_CHAR &&
|
||||
key_table[i].key != KEY_MOUSE && key_table[i].key == key)
|
||||
return &key_table[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define DEF_ME_START if (event->bstate == 0) { return NULL; }
|
||||
#define DEF_ME_KEY(s, k) else if (event->bstate & s) { key = k | type; }
|
||||
#define DEF_ME_END else { return NULL; }
|
||||
|
||||
static const struct key *mevent_to_key(MEVENT *event, int type)
|
||||
{
|
||||
int i, key = -255;
|
||||
|
||||
DEF_ME_START
|
||||
DEF_ME_KEY(BUTTON1_CLICKED, KEY_MLB_CLICK)
|
||||
DEF_ME_KEY(BUTTON1_PRESSED, KEY_MLB_CLICK)
|
||||
DEF_ME_KEY(BUTTON3_CLICKED, KEY_MRB_CLICK)
|
||||
DEF_ME_KEY(BUTTON3_PRESSED, KEY_MRB_CLICK)
|
||||
DEF_ME_KEY(BUTTON4_PRESSED, KEY_MSCRL_UP)
|
||||
DEF_ME_KEY(BUTTON5_PRESSED, KEY_MSCRL_DOWN)
|
||||
DEF_ME_END
|
||||
|
||||
for (i = 0; key_table[i].name; i++) {
|
||||
if (key_table[i].key == KEY_MOUSE && key_table[i].ch == key)
|
||||
return &key_table[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef DEF_ME_START
|
||||
#undef DEF_ME_KEY
|
||||
#undef DEF_ME_END
|
||||
|
||||
void normal_mode_ch(uchar ch)
|
||||
{
|
||||
enum key_context c;
|
||||
const struct key *k;
|
||||
|
||||
c = view_to_context[cur_view];
|
||||
k = ch_to_key(ch);
|
||||
|
||||
if (k == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* view-specific ch */
|
||||
if (handle_key(key_bindings[c], k))
|
||||
return;
|
||||
|
||||
/* common ch */
|
||||
if (handle_key(key_bindings[CTX_COMMON], k))
|
||||
return;
|
||||
|
||||
/* these can be overridden but have default magic */
|
||||
switch (ch) {
|
||||
case ':':
|
||||
enter_command_mode();
|
||||
return;
|
||||
case '/':
|
||||
enter_search_mode();
|
||||
return;
|
||||
case '?':
|
||||
enter_search_backward_mode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void normal_mode_key(int key)
|
||||
{
|
||||
enum key_context c = view_to_context[cur_view];
|
||||
const struct key *k = keycode_to_key(key);
|
||||
|
||||
if (k == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* view-specific key */
|
||||
if (handle_key(key_bindings[c], k))
|
||||
return;
|
||||
|
||||
/* common key */
|
||||
handle_key(key_bindings[CTX_COMMON], k);
|
||||
}
|
||||
|
||||
static const struct key *normal_mode_mouse_handle(MEVENT* event)
|
||||
{
|
||||
int track_win_x = get_track_win_x(), i = event->y - 1, need_sel, type;
|
||||
struct window* win = NULL;
|
||||
struct iter it, sel;
|
||||
|
||||
if (event->y == 0) {
|
||||
need_sel = 0;
|
||||
type = KEY_M_TYPE_TIT;
|
||||
} else if (event->y == LINES - 2) {
|
||||
need_sel = 0;
|
||||
type = event->x >= (COLS - COLS/3)
|
||||
? KEY_M_TYPE_BAR_R
|
||||
: KEY_M_TYPE_BAR;
|
||||
} else {
|
||||
if (cur_view == TREE_VIEW) {
|
||||
if (event->x >= track_win_x)
|
||||
win = lib_track_win;
|
||||
else if (event->x < track_win_x - 1)
|
||||
win = lib_tree_win;
|
||||
else
|
||||
return NULL;
|
||||
type = (lib_cur_win == win) ? KEY_M_TYPE_SEL : KEY_M_TYPE_NONE;
|
||||
} else if (cur_view == PLAYLIST_VIEW) {
|
||||
if (event->x >= track_win_x)
|
||||
win = pl_editable_shared.win;
|
||||
else if (event->x < track_win_x)
|
||||
win = pl_list_win;
|
||||
else
|
||||
return NULL;
|
||||
type = (pl_cursor_win() == win) ? KEY_M_TYPE_SEL : KEY_M_TYPE_NONE;
|
||||
} else {
|
||||
win = current_win();
|
||||
type = KEY_M_TYPE_SEL;
|
||||
}
|
||||
|
||||
if ((event->bstate & BUTTON4_PRESSED) || (event->bstate & BUTTON5_PRESSED)) {
|
||||
need_sel = 0;
|
||||
type = KEY_M_TYPE_NONE;
|
||||
if (event->y < 1 || event->y >= LINES - 3)
|
||||
return NULL;
|
||||
if (cur_view == TREE_VIEW && lib_cur_win != win)
|
||||
tree_toggle_active_window();
|
||||
if (cur_view == PLAYLIST_VIEW && pl_cursor_win() != win)
|
||||
pl_win_next();
|
||||
} else {
|
||||
if (event->y < 1 || event->y > window_get_nr_rows(win))
|
||||
return NULL;
|
||||
if (cur_view == TREE_VIEW && lib_cur_win != win)
|
||||
tree_toggle_active_window();
|
||||
if (cur_view == PLAYLIST_VIEW && pl_cursor_win() != win)
|
||||
pl_win_next();
|
||||
if (!window_get_top(win, &it) || !window_get_sel(win, &sel))
|
||||
return NULL;
|
||||
while (i-- > 0)
|
||||
if (!window_get_next(win, &it))
|
||||
return NULL;
|
||||
while (win->selectable && !win->selectable(&it))
|
||||
if (!window_get_next(win, &it))
|
||||
return NULL;
|
||||
|
||||
type = (type == KEY_M_TYPE_SEL && iters_equal(&sel, &it)) ? KEY_M_TYPE_SEL : KEY_M_TYPE_NONE;
|
||||
need_sel = !iters_equal(&sel, &it);
|
||||
}
|
||||
}
|
||||
|
||||
const struct key *k = mevent_to_key(event, type);
|
||||
if (k == NULL)
|
||||
return NULL;
|
||||
|
||||
if (need_sel)
|
||||
window_set_sel(win, &it);
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
void normal_mode_mouse(MEVENT *event)
|
||||
{
|
||||
enum key_context c = view_to_context[cur_view];
|
||||
const struct key *k = normal_mode_mouse_handle(event);
|
||||
|
||||
if (k == NULL)
|
||||
return;
|
||||
|
||||
/* view-specific key */
|
||||
if (handle_key(key_bindings[c], k))
|
||||
return;
|
||||
|
||||
/* common key */
|
||||
handle_key(key_bindings[CTX_COMMON], k);
|
||||
}
|
||||
Reference in New Issue
Block a user