Dynamic visualizations On ‘non-canonical’ keyboard-input and terminal escape-sequences for visualization effects

advertisement
Dynamic visualizations
On ‘non-canonical’ keyboard-input
and terminal escape-sequences
for visualization effects
Our course’s theme
Using the computer
to study the computer
Two ‘dynamic visualizations’
• Showing the Linux kernel’s algorithm for
setting up ‘permanent kernel mappings’
• Showing the dual-CPUs’ responses to
device-interrupts and CPU-exceptions
Some application tools
• We need to modify the terminal-console’s
normal way of processing keyboard-input
and of displaying its line-at-a-time output
• ANSI terminal escape-sequences allow
page-oriented output (i.e., left-and-right,
up-and-down), control of cursor-visibility
and of character-attributes (e.g., colors)
The ‘tty’ interface
•
•
•
•
‘tty’ is an acronyn for ‘TeleTYpe’ terminal
Such devices have a keyboard and screen
Behavior emulates technology from 1950s
Usually a tty operates in ‘canonical’ mode:
– Each user-keystroke is ‘echoed’ to screen
– Some editing is allowed (e.g., backspace)
– The keyboard-input is internally buffered
– The <ENTER>-key signals an ‘end-of-line’
– Programs receive input one-line-at-a-time
‘tty’ customization
• Sometimes canonical mode isn’t suitable
(an example: animated computer games)
• The terminal’s behavior can be modified!
• UNIX provides a convenient interface:
– #include <termios.h>
– struct termios tty;
– int tcgetattr( int fd, struct termios *tty );
– int tcsetattr( int fd, int flag, struct termios *tty );
How does the ‘tty’ work?
SOFTWARE
application
User space
tty_driver
c_lflag
Kernel space
input handling
c_iflag
c_cc
output handling
c_oflag
terminal_driver
c_cflag
HARDWARE
TeleTYpe display device
struct tty {
c_iflag;
c_oflag;
c_cflag;
c_lflag;
c_line;
c_cc[ ];
};
The ‘c_lflag’ field
•
•
•
•
•
•
This field is just an array of flag bits
Individual bits have symbolic names
Names conform to a POSIX standard
Linux names match other UNIX’s names
Though actual symbol values may differ
Your C/C++ program should use:
#include <termios.h>
for portability to other UNIX environments
ICANON and ECHO
• Normally the ‘c_lflag’ field has these set
• They can be cleared using bitwise logic:
tty.c_lflag &= ~ECHO;
// inhibit echo
tty.c_lflag &= ~ICANON; // no buffering
tty.c_lflag &= ~ISIG;
// no CTRL-C
The ‘c_cc[ ]’ array
•
•
•
•
•
‘struct termios’ objects include an array
The array-indices have symbolic names
Symbol-names are standardized in UNIX
Array entries are ‘tty’ operating parameters
Two useful ones for our purposes are:
tty.c_cc[ VMIN ] and tty.c_cc[ VTIME ]
How to setup ‘raw’ terminal-mode
• Step 1: Use ‘tcgetattr()’ to get a copy of the
current tty’s ‘struct termios’ settings
• Step 2: Make a working copy of that object
• Step 3: Modify its flags and control-codes
• Step 4: Use ‘tcsetattr()’ to install changes
• Step 5: Perform desired ‘raw’ mode input
• Step 6: Use ‘tcsetattr()’ to restore the
terminal to its original default settings
Input-mode needs five settings
• tty.c_cc[ VMIN ] = 0;
– so the ‘read()’ function will return -- even if there is
not at least one new input-character available
• tty.c_cc[ VTIME ] = 0;
– so there will be no time-delay, after each new key
pressed, until the ‘read()’ function returns
• tty.c_lflag &= ~ECHO;
• tty.c_lflag &= ~ICANON;
• tty.c_lflag &= ~ISIG;
// no input-echoing
// no buffering
// no <CTRL>-C
Demo program: ‘noncanon.cpp’
•
•
•
•
•
This program may soon prove useful
It shows the keyboard scancode values
It demonstrates ‘noncanonical’ tty mode
It clears the ISIG bit (in ‘c_lflags’ field)
This prevents <CONTROL>-C from being
used to abort the program: the user must
‘quit’ by hitting the <ESCAPE>-key; so
default terminal-settings will get reinstalled
‘Noncanonical’ terminal i/o
• We’ve now learned how to reprogram the
terminal to allow “raw” keyboard input
#include <termios.h>
struct termios
tty;
tcgetattr( 0, &tty );
// get tty settings
tty.c_lflag &= ~( ICANON | ECHO | ISIG );
tty.c_cc[ VMIN ] = 1; tty.c_cc[ VTIME ] = 0;
tcsetattr( 0, TCSAFLUSH, &tty ); // install
ANSI command-sequences
A look at some terminal emulation
features utilized in the “consoleredirection” mechanism
Clearing the screen
• Here is an ANSI command-sequence that
clears the terminal’s display-screen:
char cmd[] = “\033[2J”;
int
len = strlen( cmd );
write( 1, cmd, len );
Reposition the cursor
• Here is an ANSI command-sequence that
moves the cursor to row 12, column 40:
char cmd[] = “\033[12;40H”;
int
len = strlen( cmd );
write( 1, cmd, len );
ANSI color-codes
0 = black
1 = red
2 = green
3 = brown
4 = blue
5 = magenta
6 = cyan
7 = gray
Setting text attributes
• Here is an ANSI command-sequence that
sets foreground and background colors:
char cmd[] = “\033[32;44m”;
int
len = strlen( cmd );
write( 1, cmd, len );
Cursor visibility commands
• Here are ANSI command-sequences that
will ‘hide’ or ‘show’ the terminal’s cursor:
char hide[] = “\033[?25l”;
// lowercase L
char show[] = “\033[?25h”; // lowercase H
In-class exercise #1
• Modify this simple C++ program so that it
will print its “Hello” message in colors and
be located in the center of the screen:
#include <stdio.h>
int main( void )
{
printf( “Hello, world! \n” );
}
In-class exercise #2
• Compile and install our ‘pkmaps.c’ module
• Then download, compile and execute our
‘mapwatch.cpp’ visualization-application
• While ‘mapwatch’ continues to run in one
window of your graphical desktop, open a
second window nearby and execute some
common commands, for example:
$ ls
$ mmake pkmaps
In-class exercise #3
• Compile and install our ‘smpwatch.c’ LKM
• Then download, compile and execute our
‘smpwatch.cpp’ visualization-application
• In a nearby window, try hitting some keys
and moving the mouse
• Try executing the ‘ping’ command to see if
another machine responds, for example:
$ ping stargate
Download