CS 3210 - Lab 12 - Terminal Handling with S-Lang

This lab is all about how to write to the screen in text mode using pretty colors.

The chapter correponding to this lab is Chapter 22.

All programs that use S-Lang must be compiled with -lslang so that the linker will link it with the appropriate library.

Using Readline

Before we delve into S-Lang, I'll show you an easy way to read a line of input from a user using GNU readline. This is germane to the discussion of S-Lang, because we will see how to read input in a similar way.

Example Program: rl-ex.c - This program reads a line of input using readline. Note that we #included <readline/readline.h> and that we link with -lreadline.

It's a handy library / function. There's a man page on it too. (man readline).

Tip: readline and S-Lang do not mix very well. You have been warned. Readline is best used in command-line driven apps like ftp, gdb, nslookup, etc.

Input with S-Lang

S-Lang makes it a little easier to get input from the keyboard.

Initializing

Before you can read keys, you need to call SLang_init_tty to initialize the display for input.

Example Program: sl-in-init.c - This tiny skeleton initializes SLang for input. (See p. 416-418)

Reading One Character at a Time

You can read one character at a time using SLang_getkey. This is referred to as "raw" mode.

Example Program: slecho.c - A program that uses SLang_getkey and echoes the characters to the screen. Note that you must use SLang_init_tty to initialize and SLang_reset_tty to clean up. You can see that this reads each character of multi-byte escape sequences. (Try hitting a function key or an arrow.)

You can also timeout if you don't receive a character with N microseconds (10th of a second) using SLang_input_pending. (p. 418-419)

Example Program: slecho-pend.c - As above, but exits if it doesn't receive input within 2 seconds.

A Better Way to Read Function / Arrow Keys

To make it a little easier to read multi-byte escape keys, such as function keys, arrow keys, insert, home, delete, pageup/down, etc. you can use SLkp_getkey to read either a normal single-byte key (such as a 'j' or a RETURN), or an extended, multi-byte character (such as F2 or Insert).

Example Program: slkp.c - This program uses SLkp_getkey to read a character. Note that it produces weird behavior when you hit an escape key. This is because all multi-byte keys begin with an escape. To see a fix for that, look at...

Example Program: slkp-improved.c - This program uses a wrapper function around SLkp_getkey to handle the special-case Esc key. Look at the comments in the code for further enlightenment.

Output with S-Lang

S-Lang lets you draw purty colorful stuff on the screen.

Initializing

Before you can draw output with SLang, you need to call SLtt_get_terminfo to get the terminal information and SLsmg_init_smg to initialize high-level screen management routines.

Example Program: sl-out-init.c - This program shows how you initialize S-Lang for output at the beginning of a program and then reset the terminal at the end. Observe that you have the two global variables SLtt_Screen_Rows and SLtt_Screen_Cols representing the number of rows and columns on the terminal; these are set when you call SLtt_get_terminfo. Also, note that it's a good idea to move the cursor to the lower right-hand corner and call SLsmg_refresh to make sure that the screen gets updated. (See pgs. 420-421) If you don't call SLsmg_refresh, nothing will get drawn.

If the screen size changes in mid program (which you can find out if you install a SIGWINCH handler) you can call SLsmg_reinit_smg to update the global rows / cols variables.

Switching Character Sets

A "character set" is a group of characters delimited by a set of character codes that map to a symbol. Most Unix terminals support (at least) two character sets: "normal" (alphanumerics - like the ones on your keyboard), and "alternate" (lines and symbols mostly used for drawing). You can use SLsmg_set_char_set (p. 422) to switch from one to the other.

Example Program: slcharset.c - Displays two boxes containing both the Normal and Alternate character sets.

Note: If you hit Cntrl-C to break out of the above program (instead of just typing 'q' to quit), you will notice that your terminal now displays gibberish. To cure this problem, typ Cntrl-V, followed by Cntrl-O, then RETURN.

Printing Strings to the Screen

Page 423 lists a variety of printing functions you can use to output strings to the screen. Some of these are cognates to C library routines (SLsmg_printf, e.g.). These are all documented in your book on p. 424.

To draw a line at a particular location, you can use SLsmg_gotorc to position the cursor to a row / column coordinate. (p. 421)

Drawing Lines & Boxes

If you don't feel like drawing all your boxes by hand, you can use the SLsmg_draw_hline (horizontal line), SLsmg_draw_vline (vertical line), and SLsmg_draw_box to get it done more quickly. (See pg. 425)

Example Program: slbox.c - Draws a box on the screen and waits for a keypress before exiting. It also turns off / on the cursor.

Using Colors

To set the color, you first call SLtt_set_color with string constants to modify a palette entry (there are 256 palette entries you can play with). You can then call SLsmg_set_color to set the current palette entry that you will use for output. See p.428 for a list of colors.

If you do not first set the palette colors using SLtt_set_color, you will end up using whatever default colors are set for the particular palette.

Example Program: slcolor.c - Draws two lines of text, one with color, one without.

Note: If colors do not show up in your terminal, try typing export TERM=ansi at the shell prompt and then run the color program.

Further Study

S-Lang Library Information Page - The offical site.

Writing Programs Using NEWT - "NEWT" is short for Not Erik's Windowing Toolkit. Newt is a windowing toolkit for text mode built from the slang library. It allows color text mode applications to easily use stackable windows, push buttons, check boxes, radio buttons, lists, entry fields, labels, and displayable text. Scrollbars are supported, and forms may be nested to provide extra functionality.

Your book, Chapter 22

Big Example Programs

Here are some large-scale examples. These came from /usr/share/doc/slang1-dev/examples. Both of these use demolib.c and config.h.

pager.c - An example of a "less"-style program, it displays a file and allows you to scroll through its contents.

smgtest.c - A program that tests all of the various SLsmg_* functions.

Type "aafire" on Gautama to see a funky example.

Lab 12

This will be a lab using S-Lang. You will draw a box on the screen that contains the text:

Hit 'r' for red   
Hit 'y' for yellow
Hit 'b' for blue  
Hit 'q' to quit   

Hitting the various color keys will cause the box to change color.

Some steps to help you:

Save this in a file called slanglab.c. The whole file should be about 60 or so lines long. Be sure to have a Makefile as well. Put both files in a lab12/ directory.

Sample Output

The HTML representation isn't exactly the same as the text representation, but it should look something like this:

Hit 'r' for red
Hit 'y' for yellow
Hit 'b' for blue
Hit 'q' to quit

Tip

You might find that your box shows up with little black holes in it. To cure this, just padd the end of your strings with spaces.

Files

Here is a list of the files created in this lab.

Please turn in just the slanglab.c file with your name, lab # and class # at the top.