Question

Basically, I have key detection for my console application, for some reason it's not detecting function keys.

Here is my code, I'm using GNU compiler on linux. Any help or ideas would be greatly appreciated.

        refresh();
        key = getch();
        switch(key) {
            case KEY_HOME:      key = HOME;   break;
            case KEY_END:       key = END;    break;
            case KEY_UP:        key = UP;     break;
            case KEY_DOWN:      key = DOWN;   break;
            case KEY_LEFT:      key = LEFT;   break;
            case KEY_RIGHT:     key = RIGHT;  break;
            case KEY_NPAGE:     key = PGDN;   break;
            case KEY_PPAGE:     key = PGUP;   break;
            case KEY_DC:        key = DEL;    break;
            case KEY_IC:        key = INSERT; break;
            case KEY_F(1):      key = F(1);   break;
            case KEY_F(2):      key = F(2);   break;
            case KEY_F(3):      key = F(3);   break;
            case KEY_F(4):      key = F(4);   break;
            case KEY_F(5):      key = F(5);   break;
            case KEY_F(6):      key = F(6);   break;
            case KEY_F(7):      key = F(7);   break;
            case KEY_F(8):      key = F(8);   break;
            case KEY_F(9):      key = F(9);   break;
            case KEY_F(10):     key = F(10);  break;
            case KEY_F(11):     key = F(11);  break;
            case KEY_F(12):     key = F(12);  break;
            case KEY_ENTER:     key = ENTER;  break;
            case KEY_BACKSPACE: key = BACKSPACE; break;
            default:
                //key = F(2); //For any function keypress, it jumps to default
                if (NON_ASCII(key) != 0)
                    key = UNKNOWN;
        }    
Was it helpful?

Solution

I'm not a curses expert, but a bit of reading man pages netted me this program:

#include <curses.h>

int main()
{
    int key;

    initscr(); cbreak(); noecho();

    while (1)
    {

        key = getch();
        printw ("%u\n", key);
    }

    return 0;
}

When I press an F key, I get a 3-character sequence: 27, 79, (80 + N-1) where N is the number of the F key. I think your switch will have to recognize that the key is an escape sequence and handle it specially.

Edit: That pattern holds only for F1-F4. F5 changes it up. You'll probably want to incorporate the F(n) macros from curses.

OTHER TIPS

Having the same issue, personally.

Casting the F(n) macro to a char type magically cleared the issue for me;

cmd = getch();
    switch(cmd){
        case 'r':
            addch('r');
            break;
        case 'w':
            addch('x');
            break;
        default:
            if(cmd == (char)KEY_F(2)){ endwin(); exit(0); }
    }

and the like. Worked for F2 through F10 plus F12. F's 1, 10 and 11 are "occupied" for lack of a better word on my xterm. (F1 opens the help window, F11 toggles fullscreen mode, etc.) Again, I can't emphasize enough that I couldn't begin to guess why that works.

You may need to enable the "keypad" functionality of the terminal using the keypad function. From the keypad(3x) manual page:

int keypad(WINDOW *win, bool bf);

The keypad option enables the keypad of the user's terminal. If enabled (bf is TRUE), the user can press a function key (such as an arrow key) and wgetch returns a single value representing the function key, as in KEY_LEFT. If disabled (bf is FALSE), curses does not treat function keys specially and the program has to interpret the escape sequences itself. If the keypad in the terminal can be turned on (made to transmit) and off (made to work locally), turning on this option causes the terminal keypad to be turned on when wgetch is called. The default value for keypad is false.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top