/* * 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 textui_get_command(int *count) { int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; struct keypress tmp[2] = { { 0 }, { 0 } }; ui_event ke = EVENT_EMPTY; const struct keypress *act = NULL; /* Get command */ while (1) { /* Hack -- no flush needed */ msg_flag = FALSE; /* Activate "command mode" */ inkey_flag = TRUE; /* Get a command */ ke = inkey_ex(); if (ke.type == EVT_KBRD) { bool keymap_ok = TRUE; switch (ke.key.code) { case '0': { int c = textui_get_count(); if (c == -1 || !get_com_ex("Command: ", &ke)) continue; else *count = c; break; } case '\\': { /* Allow keymaps to be bypassed */ (void)get_com_ex("Command: ", &ke); keymap_ok = FALSE; break; } case '^': { /* 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); } /* Erase the message line */ prt("", 0, 0); if (ke.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 && act && !inkey_next) { size_t n = 0; while (act[n].type) n++; /* Make room for the terminator */ n += 1; /* Install the keymap */ memcpy(request_command_buffer, act, n * sizeof(struct keypress)); /* Start using the buffer */ inkey_next = request_command_buffer; /* Continue */ continue; } /* Done */ break; } return ke; }
/* * 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_data textui_get_command(void) { int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; char tmp[2] = { '\0', '\0' }; ui_event_data ke = EVENT_EMPTY; cptr act = NULL; /* Get command */ while (1) { /* Hack -- no flush needed */ msg_flag = FALSE; /* Activate "command mode" */ inkey_flag = TRUE; /* Get a command */ ke = inkey_ex(); /* Command Count */ if (ke.key == '0') { int count = textui_get_count(); if (count == -1 || !get_com_ex("Command: ", &ke)) continue; else p_ptr->command_arg = count; } /* Allow "keymaps" to be bypassed */ else if (ke.key == '\\') { /* Get a real command */ (void)get_com("Command: ", &ke.key); /* Hack -- bypass keymaps */ if (!inkey_next) inkey_next = ""; } /* Allow "control chars" to be entered */ else if (ke.key == '^') { /* Get a new command and controlify it */ if (get_com("Control: ", &ke.key)) ke.key = KTRL(ke.key); } /* Special case for the arrow keys */ else if (isarrow(ke.key)) { switch (ke.key) { case ARROW_DOWN: ke.key = '2'; break; case ARROW_LEFT: ke.key = '4'; break; case ARROW_RIGHT: ke.key = '6'; break; case ARROW_UP: ke.key = '8'; break; } } /* Erase the message line */ prt("", 0, 0); if (ke.type == EVT_BUTTON) { /* Buttons are always specified in standard keyset */ act = tmp; tmp[0] = ke.key; } else if (ke.type == EVT_KBRD) { /* Look up applicable keymap */ act = keymap_act[mode][(byte)(ke.key)]; } /* Apply keymap if not inside a keymap already */ if (ke.key && act && !inkey_next) { /* Install the keymap */ my_strcpy(request_command_buffer, act, sizeof(request_command_buffer)); /* Start using the buffer */ inkey_next = request_command_buffer; /* Continue */ continue; } /* Done */ break; } return ke; }