static Parser.Error parse_prefs_c(Parser p) { int mode; prefs_data d = p.priv as prefs_data; Misc.assert(d != null); if (d.bypass) { return(Parser.Error.NONE); } mode = p.getint("mode"); if (mode < 0 || mode >= (int)Keymap.Mode.MAX) { return(Parser.Error.OUT_OF_BOUNDS); } ui_event[] temp = UIEvent.keypress_from_text(p.getstr("key")); if (temp[0].type != ui_event_type.EVT_KBRD || temp.Length > 1) { return(Parser.Error.FIELD_TOO_LONG); } Keymap.add(mode, temp[0].key, d.keymap_buffer, d.user); return(Parser.Error.NONE); }
/** * Remove a keymap. Return true if one was removed. */ public static bool remove(int keymap, keypress trigger) { Keymap k; Keymap prev = null; Misc.assert(keymap >= 0 && keymap < (int)Mode.MAX); for (k = keymaps[keymap]; k != null; k = k.next) { if (k.key.code == trigger.code && k.key.mods == trigger.mods) { if (prev != null) { prev.next = k.next; } else { keymaps[keymap] = k.next; } return(true); } prev = k; } return(false); }
/** * Add a keymap to the mappings table. */ public static void add(int keymap, keypress trigger, keypress[] actions, bool user) { Keymap k = new Keymap(); Misc.assert(keymap >= 0 && keymap < (int)Mode.MAX); remove(keymap, trigger); k.key = trigger; k.actions = make(actions); k.user = user; k.next = keymaps[keymap]; keymaps[keymap] = k; return; }
/* * Request a command from the user. * * Note that "caret" ("^") is treated specially, and is used to * allow manual input of control characters. This can be used * on many machines to request repeated tunneling (Ctrl-H) and * on the Macintosh to request "Control-Caret". * * Note that "backslash" is treated specially, and is used to bypass any * keymap entry for the following character. This is useful for macros. */ static ui_event get_command() { int mode = (int)(Option.rogue_like_commands.value ? Keymap.Mode.ROGUE : Keymap.Mode.ORIG); keypress[] tmp = new keypress[2] { new keypress(), new keypress() }; ui_event ke = new ui_event(); //ui_event ret = ke; keypress[] act = null; /* Get command */ while (true) { /* Hack -- no flush needed */ Term.msg_flag = false; /* Activate "command mode" */ Utilities.inkey_flag = true; /* Get a command */ ke = Utilities.inkey_ex(); if (ke.type == ui_event_type.EVT_KBRD) { bool keymap_ok = true; switch ((char)ke.key.code) { case '0': { int count = TextUI.get_count(); throw new NotImplementedException(); //if (count == -1 || !get_com_ex("Command: ", &ke)) // continue; //else // p_ptr.command_arg = count; //break; } case '\\': { /* Allow keymaps to be bypassed */ throw new NotImplementedException(); //(void)get_com_ex("Command: ", &ke); //keymap_ok = false; //break; } case '^': { throw new NotImplementedException(); ///* Allow "control chars" to be entered */ //if (get_com("Control: ", &ke.key)) // ke.key.code = KTRL(ke.key.code); //break; } } /* Find any relevant keymap */ if (keymap_ok) { act = Keymap.find(mode, ke.key); //if (act == null) { // ret = ke; //} } } /* Erase the message line */ Utilities.prt("", 0, 0); if (ke.type == ui_event_type.EVT_BUTTON) { /* Buttons are always specified in standard keyset */ act = tmp; tmp[0] = ke.key; } /* Apply keymap if not inside a keymap already */ if (ke.key.code != (keycode_t)0 && act != null && Utilities.inkey_next == null) { //int n = 0; //while (n < act.Length && act[n] != null)//act[n].type // n++; ///* Make room for the terminator */ //n += 1; /* Install the keymap */ for (int q = 0; q < act.Length; q++) //It used to check for q < n instead { request_command_buffer[q] = act[q]; //memcpy(request_command_buffer, act, n); } /* Start using the buffer */ Utilities.inkey_next = new List <keypress>(request_command_buffer); /* Continue */ //ret.type = ke.type; //ret.mouse = ke.mouse; //ret.key = act[0]; continue; } /* Done */ break; } return(ke); }