Top Banner
Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum
26

Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

Jan 18, 2016

Download

Documents

Stuart Cook
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

Keyboard and Screens

The user interface in unix: simple text based terminals using TERMIOS and

CURSES libraries.

Ian McCrum

Page 2: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 2 of 26

The Terminal Driver (/dev/tty)

• Line editing: Backspace, home,end, ins etc.,

• Buffering: Read data a line at a time or not

• Echo: When reading passwords do not echo!

• CR/LF: Unix only uses linefeeds, Windows uses a two character combination CR/LF

• Line speeds (if using a serial port, /dev/ttys0)

• Modem control signals (flow control etc)

Page 3: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 3 of 26

Termios: A POSIX standard

• Uses a simple struct and a few function calls• Link code with the curses library -lcurses• Five areas: input, output, control, local, special• Minimum termios structure has 4 sets of flags

and a char array, we just set or clear bits of flags• Then call the tcsetattr() function• Though it’s better to call tcgetattr() first; this

allows resetting the terminal back when finished.

Page 4: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 4 of 26

INPUT MODES• BRKINT or IGNBRK: respond to “breaks”• ICRNL, INLCR: convert cr->nl or vice versa• IGNCR,IGNPAR: ignore CRs or Parity error• IXON: enable software flow control (cntl-S/Q)• IXOFF: disable software flow control • ISTRIP: strip incoming chars to 7 bits

– The flag bits above are within the c_iflag of the termios struct

Page 5: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 5 of 26

OUTPUT MODES• OPOST: Turn on output processing• ONLCR: Convert nl->cr/lf• OCRNL: Convert cr->nl• NLDLY, CRDLY, FFDLY nl,cr,ff delay

If OPOST is off then the other flag bits are ignored.

The flag bits above are within the c_oflag of the termios struct

Page 6: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 6 of 26

CONTROL MODES• CLOCAL: ignore any modem status lines• CREAD: Enable receipt of characters• CS8,7,6,5: set number of bits in chars (I/O)• HUPCL: Hang up modem on close

– The flag bits above are within the c_cflag of the termios struct

Page 7: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 7 of 26

LOCAL MODES• ECHO: Perform local echoing of typed chars.• ECHOE: Do a <backspace> <space> <backspace>

when erase is typed• ISIG: Enable signals• ICANON: Enable canonical input processing

– Canonical mode is when input is input a line at a time

• ECHONL: Echo incoming newlines

– The flag bits above are within the c_lflag of the termios struct

Page 8: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 8 of 26

CONTROL CHARACTERS(a collection of characters treated in a special way: done by filling

the c_cc array, each position has the meanings below)

If in CANONICAL mode

• VEOF:• VEOL:• VERASE:• VINTR: SIGINT signal• VKILL: (entire line)• VQUIT:SIGQUIT signal• VSUSP: SIGSUP signal• VSTART:usually <cntl-q>• VSTOP:usually <cntl-s>

If in NON-CANONICAL mode

• VINTR• VMIN: how many chars to

wait for• VQUIT• VTIME: How long to wait for• VSTART• VSTOP

The uppercase words are the indices into the c_cc array, run $stty –a to see them

Page 9: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 9 of 26

TERMIOS and the shell

• $ stty –a ;this lists 10 lines of settings• $ stty sane ; reset the terminal to defaults• $ stty –g >save_stty ; remember all settings• $…. Experiment and try stty settings …• $ stty $(cat save_stty) ;reloads stty with old

– If your terminal is totally screwed up login on another terminal and “kill” that process, terminal parameters are reset on login.

Page 10: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 10 of 26

Example C programs using TERMIOS#include <stdio.h>#include <termios.h>struct termios old_settings, new_settings;int main(){

tcgetattr(fileno(stdin), &old_settings);new_settings=old_settings;new_settings.lflag &= ~ICANON;// AND old with 11111011… // resets bit 2.new_settings.c_cc[VMIN]=0; // return when any input occursnew_settings. c_cc[VTIME]=20; //wait 2 seconds for input…tcsetattr(fileno(stdin), TCSNOW, &new_settings);… // you can now use the getchar() function to read the keybdexit(0);

}

Page 11: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 11 of 26

Screen outputSeveral ways exist, for historical reasons. Originally there were

many type of “terminal” and these accessed a few mainframe computers over serial lines. The special attributes of a terminal were accessed in non-standard ways… bold, underline and the use of colo(u)r and cursor movement and control sequences all differed between manufacturers, the cheaper terminals did not possess all the capabilities of the more expensive terminals. Some terminals were so common as to be ubiquitous. The DEC VT100 family, more typically the VT102 was very common. And some standardisation was attempted by the ANSI committee.

The TERMCAP and TERMINFO databases are one solution, the CURSES C library was another

Page 12: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 12 of 26

Managing Text-Based Screens with CURSES.

• Curses is a powerful device independent way of accessing good functionality on a text based terminal.

• The graphics capability of X-windows is more sophisticated and there are many tools to support use of graphical widgets… we will not cover X programming here, but have a look at tk/tcl if interested. (there is a bonus chapter from the course text on the www.wrox.com website)

Page 13: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 13 of 26

Compiling with curses• Curses is a library, so in C we must include a header

file and also inform the linker to include the actual code when compiling

• #include <curses.h>• gcc myprogram.c –lcurses …or• #include <ncurses.h>• gcc –I/usr/include/ncurses myprogram.c -lncurses

Some linux distributions use ncurses, but provide links to curses and the first two lines above are ok (e.g on Redhat 9.0)

Page 14: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 14 of 26

Curses concepts• Curses routines work on screens, windows and

subwindows.. A screen is the terminal screen (or xterm window if in X). There is always at least one curses window that is the same size as the screen: the stdscr window.

• You can create additional windows that are smaller than the screen. Windows can overlap each other and have many subwindows, each subwindow must be 100% within its parent window.

• Curses maintains stdscr and curscr. Curses moves the contents of stdscr to curscr when you call the refresh() function, you can see the curscr

Page 15: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 15 of 26

Curses concepts continued• The co-ordinate system uses 0,0 for top

lefthand side

• Cursor functions always use line,column as the order in their paramters, i.e move(y.x)

• Available attributes differ, you’ll always get bold and underline but linux terminals will usually allow, blink/flash and color

• Each window can scroll independently of each other - a very powerful capability for UI!

Reverse video

Page 16: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 16 of 26

A simple curses program#include <unistd.h>#include <stdlib.h>#include <curses.h>int main(){

initscr();

endwin();Exit(EXIT_SUCCESS);

}

move(5,15); // 6th line down, 16th char in

printw(“%s”,”Hello world”); // bit like printf….

refresh(); // needed to update screen

sleep(4); // let the user see it (for 4 secs!)

Page 17: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 17 of 26

Curses functions to output to screen

• int addch(const chtype, char_to_add);

• int addchstr(chtype *const string_to_add);

• int printw(char *format,…);

• int refresh(void); // to draw a box use chars ACS_VLINE,HLINE

• int box(WINDOW *win_ptr, chtype vert_ch,chtype, horiz_ch);

• int insch(chtype char_to_insert); //chtype is a bit bigger than int

• int insertln(void); // linux chtype is unsigned long

• int delch(void);

• int deleteln(void);

• int beep(void); // if terminal can’t make sounds the screen flashes

• int flash(void);// if terminal can’t flash it will beep!

Page 18: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 18 of 26

Reading from the screen (don’t!)• chtype inch(void);

• int instr(char *string);

• int innstr(char *string, int number_of_chars);

Clearing the screen• int erase(void); //blanks every screen location

• int clear(void); // does a smart clear if poss.

• int clrtobot(void);

• int clrtoeol(void);

Page 19: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 19 of 26

Character Atrributes• int attron(chtype attribute); // use A_BLINK, A_BOLD, A_DIM

• int attroff(chtype attribute); // A_REVERSE, A_STANDOUT

• int attrset(chtype attribute); // A_UNDERLINE

• int standout(void);

• int standend(void);

Moving the Cursor• int move(int new_y, int new_y); //maximums are LINES or

// COLUMNS, two extern integers… the physical screen size

Page 20: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 20 of 26

Keyboard Modes• int echo(void); and int noecho (void);

• int cbreak(void); and int nocbreak(void);

• int raw(void); and int noraw(void);• Cbreak is like non-canonical, characters are available as soon as they

are typed, there is no need to hit RETURN. Curses distinguishes between “cooked” mode and “raw” mode. Cbreak mode still allows special characters are enabled apart from backspace (erase) and kill characters.

• Raw mode is similar to cbreak mode except interrupt, quit, suspend and flow control characters are passed straight through to the reading routine without generating a signal

• There are other interesting routines listed in $info pages … try $info ncurses and $info curs_inopts. E.g functions called halfdelay() and timeout() and wtimeout(). These allow blocking, non-blocking and timed blocking capability… similar to TERMIOS’s but easier to use.

Page 21: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 21 of 26

Keyboard Input• int getch(void);

• int getstr(char *string); // DO NOT USE… LEAKS!

• int getnstr(char *string, int number_of_characters);

• int scanw(char *format,…);//I personally never use scanf

These act very like the non-curses equivalent, getchar,gets and scanf. But their exact behaviour is set by altering the modes on the previous screen.

Page 22: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 22 of 26

Windows… Multiple windows per screen

• We use stdscr as the standard screen and all simple functions assume this is the screen we want. It is possible to declare new windows and use similar functions with them. This uses the WINDOW structure and we use pointers to these, just like we use FILE pointers to use file functions.

• WINDOW *newwin(int no_of_lines, int no_of_cols \

int start_y, int start_x);

• int delwin(WINDOW *window_to_delete);

These functions create or destroy windows; newwin() will return either a pointer to theWINDOW or null.

All windows must fit (totally) within the current screen and these functions are not available on all versions of curses

Page 23: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 23 of 26

Generalised Functions• int addch(const chtype char);• int waddch(WINDOW *ptr, const chtype char);• int mvaddch(int y, int x, const chtype char);• int mvwaddch(WINDOW *ptr, int y,int x , const chtype char);

Note for the mvw prefix you give the WINDOW *ptr first in the argument list, some eejit got it wrong <sigh>. Also the y,x are within the window.

• int printw(char *format,….); // just like printf on screen (after refresh();)

• int wprintw(WINDOW *ptr, char *format,….);

• int mvprintw(int y, int x, char *format,….);

• int mvwprintw(WINDOW *ptr, int y,int x , char *format,….);

Note for the mvw prefix you give the WINDOW *ptr first in the argument list, some eejit got it wrong <sigh>. Also the y,x are within the window.

Page 24: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 24 of 26

Windows: moving and updating• int mvwin(WINDOW *ptr, int new_y, int new_x);• int wrefresh(WINDOW *ptr); // generalised versions• int wclear(WINDOW *ptr); // of the functions we met• int werase(WINDOW *ptr); // earlier.• int touchwin(WINDOW *ptr); // next wrefresh will rewrite• int scrollok(WINDOW *ptr, bool scroll_flag); // default is scroll is false• int scroll(WINDOW *ptr); // scroll up one line. • int scrl(int n); // scroll the stdscr by n lines, positive or negative• int wscrl(WINDOW *ptr, int n); // as above, cursor does not move…

Not all versions of ncurses provide the last two functions, see $info ncurses of $info curs_scroll

There are other things in ncurses; SUBWINDOWS put inside a parent… handy for scrolling part of a parent. Also PADS and KEYPADS. See the manual for these, or the book is excellent is this area (chapter 6)

Note the misprint on page 219(3rd ed) wsctl() should be wscrl()

Page 25: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 25 of 26

Keypads: the function keys• Hitting function keys (and pgup, home, ins, and arrow keys etc., generates a

string of charatcters prefixed by the ESC code.• Do not use the ESC key in your programs although it is (just) possible to

cope with it because of very clever “timed” sequences it is difficult to use• In curses, each key sequence is stored in the TERMINFO database and

named with a KEY_ prefix.• You have to turn on the translation of function keys to TERMINFO

sequences by using the keypad() function• int keypad(WINDOW *ptr, bool keypad_on); // returns OK or ERR• There are restrictions, the escape sequences must be sent together within a

certain number of milliseconds; some networks might give trouble if a sequence is split over two packets and a packet delay occurs

• If you do hit the actual ESCAPE key, the system freezes for x milliseconds• If you have two keys generating the same sequences it ignores them all!• Try the program in chapter 6 if you want to experiment. It uses getch and

tests with a case statement against KEY_END, KEY_BEG, KEY_UP etc.,

Page 26: Keyboard and Screens The user interface in unix: simple text based terminals using TERMIOS and CURSES libraries. Ian McCrum.

21st March 2004 522J2 OS and Networks By Ian McCrum www.EEJ.ulst.ac.uk Slide 26 of 26

COLO(U)R• You setup COLOR_PAIRs and give each a number. You can

use constants such as COLOR_RED and you can have 64 pairs

• You interrogate the system to see if it has_color()

• If it has you give a start_color() call

• You then use the attrset() or wattron() calls to set a pair

bool has_colors(void);

int start_color(void);// it should returns OK

int init_pair(short pair_number, short foreground, short background);

int COLOR_PAIR(int pair_number);