11

I currently have a chat client that communicates successfully with a server. I am supposed to modify the behavior so that the prompt moves down when another chat message is received (i.e. the messages are printed "above" the prompt by printing \b to erase the prompt, printing the message, and then re-printing the prompt).

We were given a test client and test server for testing this functionality, and currently when the user has a prompt but nothing typed in, they can receive messages from other users. When they start typing, the buffer doesn't flush until they type their whole message and hit ENTER.

I am supposed to replicate this behavior, but I am very confused about what raw mode actually is.

Can anyone tell me how to control input/output via raw mode, or why the behavior of the test programs I described above occurs from using raw mode?

DallaRosa
  • 5,737
  • 2
  • 35
  • 53
theeggman85
  • 1,745
  • 6
  • 23
  • 36

2 Answers2

22

By default, Unix-style tty (i.e. console) drivers will take input in "cooked mode". In this mode, it provides a certain amount of command-line editing. The user can type in a line of input, possibly deleting and retyping some of it (but that doesn't always work) and the program won't see it until the user hits enter.

This probably harkens back to the days of hardware terminals connected to the computer via a serial line; if the terminal handles some of the low-level editing, the computer doesn't have to. It also gives trivial C programs some basic input editing for free.

In contrast, raw mode sets up the TTY driver to pass every character to the program as it is typed. Programs (on Unixish operating systems) are started in cooked mode by default and need to enable raw mode.

How to do this used to vary wildly between operating systems, although POSIX has standardized this stuff these days. On Linux, you can read the "termios" and "tty_ioctl" man pages for the documentation. Basically, you get a data structure containing the tty settings, modify the parts you care about (specifically, enabling raw mode) and then pass it back.

Another possibility is to just use the ncurses library. It abstracts away all of that stuff for you.

Chris Reuter
  • 1,458
  • 10
  • 8
  • 1
    Thanks for the description! We were provided with libraries to switch between raw and cooked mode, so luckily we don't have to worry about the termios stuff. One thing that confused me is when switching to raw, I could no longer see the input of my program, only the messages from the server. Do I have to explicitly show the input as it comes in, and if so, how? – theeggman85 Oct 27 '12 at 22:38
  • 1
    @theeggman85: Yes, in raw mode it is the application's job to echo the characters typed. (They may not be meant to appear on the screen after all -- for all the terminal driver knows, they could be vi navigation commands). – hmakholm left over Monica Oct 27 '12 at 22:42
  • Do you know of any good tutorials or examples of how to print out the input? Also, I am still confused about why the testclient will print messages only when nothing is currently typed in. – theeggman85 Oct 27 '12 at 22:50
  • Unfortunately, no. The code I was looking at uses some ancient emulation layer, so not much help there. But it's pretty simple--just read the character, then print it. – Chris Reuter Oct 28 '12 at 06:27
7

In raw mode, characters are passed directly to your program. For example, when you type in a terminal in cooked mode, the characters you type are instantly echoed on the screen. In raw mode, the characters are ignored by the terminal (that is, not echoed) and your program has the option of whether or not to echo it.

EDIT: Wikipedia has a good article on cooked mode. http://en.wikipedia.com/wiki/Cooked_Mode Also, note that in raw mode, even and similar characters are handed directly to your program.

BenjiWiebe
  • 2,116
  • 5
  • 22
  • 41