Download - Dynamic visualizations
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?
TeleTYpe display deviceHARDWARE
SOFTWARE
application
tty_driverc_lflag
input handlingc_iflagc_cc
output handlingc_oflag
terminal_driverc_cflag
User space
Kernel space
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 echotty.c_lflag &= ~ICANON; // no bufferingtty.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; // no input-echoing• tty.c_lflag &= ~ICANON; // no buffering• tty.c_lflag &= ~ISIG; // 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 settingstty.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 “console-
redirection” 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 = black1 = red2 = green3 = brown4 = blue5 = magenta6 = cyan7 = 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