Ambiguities
Ambiguities

Reputation: 415

Ncurses reading numpad keys and escaping

I am trying to use ESC to escape from a program using getch(). I created a small program to demonstrate my problem.

#include <ncurses.h>

int main(void) {

    int key = 0;

    initscr();
    noecho();
    keypad(stdscr, TRUE);

    do {

        key = getch();
        clear();
        mvprintw(0, 0, "Key = %d\n", key);
        refresh();

    } while (key != 27); 

    clear();
    refresh();
    endwin();
    return 0;

}

I am trying to allow a user to use either the arrow keys or keypad (whichever is more convenient)

the issue lies within the keypad (whether numlock is on or not). When I compile and run the program and try and use the numpad keys in this simple test it exits as soon as I touch a numpad key. If I remove the while (key != 27) (esc being 27) condition it reads the keys and displays their numbers. Why does it exit the loop when the numpad keys register as

ENTER   343
UP      120
DOWN    114
LEFT    116
RIGHT   118

Any help is much appreciated!

Upvotes: 4

Views: 5058

Answers (2)

SystemRaen
SystemRaen

Reputation: 855

I found a fix in the source for Dungeon Crawl Stone Soup. It basically sets the keycodes for those.

{DCSS-dir}/source/libunix.cc (333)

define_key("\033Op", 1000);
define_key("\033Oq", 1001);
define_key("\033Or", 1002);
define_key("\033Os", 1003);
define_key("\033Ot", 1004);
define_key("\033Ou", 1005);
define_key("\033Ov", 1006);
define_key("\033Ow", 1007);
define_key("\033Ox", 1008);
define_key("\033Oy", 1009);

// non-arrow keypad keys (for macros)
define_key("\033OM", 1010); // Enter
define_key("\033OP", 1011); // NumLock
define_key("\033OQ", 1012); // /
define_key("\033OR", 1013); // *
define_key("\033OS", 1014); // -
define_key("\033Oj", 1015); // *
define_key("\033Ok", 1016); // +
define_key("\033Ol", 1017); // +
define_key("\033Om", 1018); // .
define_key("\033On", 1019); // .
define_key("\033Oo", 1020); // -

// variants.  Ugly curses won't allow us to return the same code...
define_key("\033[1~", 1031); // Home
define_key("\033[4~", 1034); // End
define_key("\033[E",  1040); // center arrow

Upvotes: 5

Alex V
Alex V

Reputation: 3654

The XTERM terminal emulator sends an escape for certain numpad keys if Num Lock is off.

You can turn on Num Lock, use something other than the numpad, use something other than ESC to break your loop, or try to find a terminal emulator that doesn't do this. There is no way for your program to distinguish between ESC and certain numpad characters when Num Lock is off within the confines of your terminal emulator.

Upvotes: 2

Related Questions