[vox-tech] backspace keycode in C: xterm vs console

Jeff Newmiller vox-tech@lists.lugod.org
Tue, 25 Dec 2001 16:58:32 -0800 (PST)


On Tue, 25 Dec 2001, Peter Jay Salzman wrote:

> /* #define BACKSPACE   127 */
> #define BACKSPACE   8
> 
> while((c=wgetch(w3)) != NEWLINE) {
> 	wmove(w3, W3LEN-1, input->len + 1);
> 	if (c == BACKSPACE && input->len > 2) {
> 		g_string_truncate(input, input->len - 1);
> 		wmove(w3, W3LEN-1, input->len + 1);
> 	} else if (c == CONTROL_U) {
> 		g_string_assign(input, "> ");
> 		wmove(w3, W3LEN-1, input->len );
> 	}
> 
> 
> for X11/xterms, the backspace key is keycode 8.  for console it's 127.
> i'd like for this program to work in console as well as xterm without
> changing the #define and recompiling the program.

This is not an xterm/console issue... it is a terminal emulation mode
issue.  Ordinarily, the superior computer geek will say "change your
terminal emulation settings", but avoiding the problem is the kinder,
gentler approach. 

To bypass the problem, you can set up your own "get keycode" routine, or
an "is_backspace" routine.  Since 8 is CTRL-H (traditionally used for
nondestructive backspace) and 127 is DEL (destructive backspace), your
application may be able to treat either as a destructive backspace without
loss of functionality.  This particularly true if you are supporting the
KEY_LEFT keycode 260 (which is not ASCII) which is a more general solution
to the cursor control problem than CTRL-H anyway.

> is there any way to deal with this other than making the backspace
> keycode into a global variable (or worse, passing its value to every
> function that needs it)?

The general solution is to abstract the concept into a separate object or
function, and locate your potentially duplicative solution in one place.  
Then, even if you do use "global variables" to resolve the problem, they
can be "module static" and you retain control over where they are used.

There are two reasons why global variables are "bad": surprising
interactions and maintenance headaches.  Surprises can manifest as "side
effects" where calling a routine one time yields surprisingly different
behavior than the last time.  Defining the "finite state machine" behavior
of an "object" properly can control the surprise factor in many cases, but
reusability/thread safety can suffer anyway.  The maintenance headache
arises when variables like "errno" are defined, and everyone uses them,
and when someone comes up with a better answer, you can't use it because
you would have to change millions of lines of code. Using "module static"
variables can control access, so you can be assured that only certain
routines can access the data if you decide to change the implementation
later.

---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<jdnewmil@dcn.davis.ca.us>        Basics: ##.#.       ##.#.  Live Go...
                                      Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...2k
---------------------------------------------------------------------------