3

I'm using this in my C code:

system("stty -echo -icanon");

This is part of a homework assignment, but this particular part is something I'm working on beyond the requirements of the assignment.

We're implementing a shell, and we've been given a bunch of code to start with. The code doesn't use ncurses (which I'd use if I could) and changing that would require rewriting a lot of the provided code.

When I press my HOME or END key, I get a capital O (that's an o as in Open) and then the HOME and END key. I'm using getchar() to get the character.

It seems that these are the only two keys that do it, but I'm not sure. I'm not 100% if the provided system function call is the only thing that is different (we also set stdout to non-blocking, but that shouldn't matter).

I'm really confused, and I'd like to implement the END and HOME keys because I use them a lot.

I'm sorry if this isn't a lot of information. I don't know enough about system to really understand what the ramifications of -echo and -icanon are for stty. I've looked at the man page, but I still can't figure it out.

EDIT

From Alex Brown's answer, I confirmed that I am getting escaped characters. I have something like the following (in bad pseudo code):

while (TRUE) 
    ch = getchar()
    switch (ch)
        case HOME:
        case END:
            don't print anything...
            break

        default:
            printf(ch);
            break

So it's printing out the O from the escape sequence, but not the [ (I have 0x48 for HOME and 0x46 for END). Still stumped on how to get the real keycode...

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
beatgammit
  • 19,817
  • 19
  • 86
  • 129
  • On many terminals, the HOME and END keys emit escape sequences and not a single character. – Vaughn Cato Aug 30 '12 at 05:13
  • Since you're using `stty`, you're probably on a Unix-like system, and it may well be Linux, but you should probably say because what you're doing (dealing with) is very system-specific. – Jonathan Leffler Aug 30 '12 at 05:13
  • @JonathanLeffler - Yup, I'm on Linux running Bash. My terminal reports $TERM as `xterm`, but it's actually gnome terminal. – beatgammit Aug 30 '12 at 05:16

2 Answers2

4

For a console application, the keys such as Home and End are usually transmitted as an escape sequence. The exact sequence depends on the terminal program you are using and how it is configured. The information is traditionally stored in termcap/terminfo, and ncurses looks it up from there based on your terminal type.

Gnome Terminal sends:

  • ESC O H (0x1b 0x4f 0x48) for Home and
  • ESC O F (0x1b 0x4f 0x46) for End.

KDE Konsole and xterm send:

  • ESC [ H (0x1b 0x5b 0x48) for Home and
  • ESC [ F (0x1b 0x5b 0x46) for End.

If you read an ESC character followed by [ or O, you will need to read an additional character in order to determine which key was pressed.

mark4o
  • 58,919
  • 18
  • 87
  • 102
  • Accepting this answer because it gives examples for Gnome/KDE. I wasn't aware of this. Thanks! I wish I could use ncurses... – beatgammit Sep 01 '12 at 02:29
1

Many meta characters (such as arrow keys, function keys, and home, end etc) are received by the terminal (and hence your application), as escaped characters - the escape code followed by one or more byte values. Since each byte is received by a separate get char call, this is likely to be what you are experiencing. I don't know why you are seeing the escape character as 'O'.

Alex Brown
  • 41,819
  • 10
  • 94
  • 108
  • Hrm, that makes sense. I'm probably getting something like [O. I noticed [A for one of the arrow keys. Do you by chance know of a way to differentiate a HOME key from the escape sequence? Something like getting the keycode instead of two characters? I guess I may need to do some escape code handling... – beatgammit Aug 30 '12 at 05:17
  • The escape character sometimes appears as `[`, and the bytes following the escape character are often printable (like O). Sounds like you have found your problem. – Alex Brown Aug 30 '12 at 05:24
  • The `[` is probably preceded by an escape character, and you are seeing http://en.wikipedia.org/wiki/ANSI_escape_code – Basile Starynkevitch Aug 30 '12 at 05:24
  • 1
    There is no distinction between the Home key and the sequence of characters it generates -- it does not have a single unique character code. If you can, you should try using the readline library for input -- it'll handle this all for you. –  Aug 30 '12 at 06:06
  • Interesting @duskwuff, but then how do international keyboards work? – Alex Brown Aug 30 '12 at 06:11
  • Keys which correspond to non-ASCII characters typically generate the UTF-8 sequence (or byte in the local charset) which corresponds to them. Terminal support for non-ASCII text is flaky on the whole, though -- for instance, I don't think anyone's ever specified how RTL languages work in a terminal. –  Aug 30 '12 at 06:18
  • I disagree-international keyboards can be configured in software so that applications see different characters or codes depending upon the locale. – Alex Brown Aug 30 '12 at 06:20
  • @AlexBrown This question is on a different level. Keyboards issue key codes, the keyboard driver converts keys and key combinations into characters and special key events and the terminal converts the latter into escape sequences. – glglgl Aug 30 '12 at 07:24