.sh 1 "Cursor Motion Optimization: Standing Alone" .pp It is possible to use the cursor optimization functions of this screen package without the overhead and additional size of the screen updating functions. The screen updating functions are designed for uses where parts of the screen are changed, but the overall image remains the same. This includes such programs as .b eye and .b vi \**. .(f \** .b Eye actually uses these functions, .b vi does not. .)f Certain other programs will find it difficult to use these functions in this manner without considerable unnecessary program overhead. For such applications, such as some .q "\fIcrt hacks\fR\|" \** .(f \** Graphics programs designed to run on character-oriented terminals. I could name many, but they come and go, so the list would be quickly out of date. Recently, there have been programs such as .b rocket and .b gun . .)f and optimizing .b cat (1)-type programs, all that is needed is the motion optimizations. This, therefore, is a description of what some of what goes on at the lower levels of this screen package. The descriptions assume a certain amount of familiarity with programming problems and some finer points of C. None of it is terribly difficult, but you should be forewarned. .sh 2 "Terminal Information" .pp In order to use a terminal's features to the best of a program's abilities, it must first know what they are\**. .(f \** If this comes as any surprise to you, there's this tower in Paris they're thinking of junking that I can let you have for a song. .)f The \*(tc \*(db describes these, but a certain amount of decoding is necessary, and there are, of course, both efficient and inefficient ways of reading them in. The algorithm that the uses is taken from .b vi and is hideously efficient. It reads them in a tight loop into a set of variables whose names are two uppercase letters with some mnemonic value. For example, .Vn HO is a string which moves the cursor to the "home" position\**. .(f \** These names are identical to those variables used in the .b /etc/termcap \*(db to describe each capability. See Appendix A for a complete list of those read, and .b termcap (5) for a full description. .)f As there are two types of variables involving ttys, there are two routines. The first, .Fn gettmode , sets some variables based upon the tty modes accessed by .b gtty (2) and .b stty (2) . The second, .Fn setterm , a larger task by reading in the descriptions from the \*(tc \*(db. This is the way these routines are used by .Fn initscr : .(b .(l I \*fif\fP (isatty(0)) { gettmode(); \*fif\fP (sp=getenv("TERM")) setterm(sp); } \*felse\fP setterm(Def\*_term); \*_puts(TI); \*_puts(VS); .)l .)b .pp .Fn isatty checks to see if file descriptor 0 is a terminal\**. .(f \** .Fn isatty is defined in the default C library function routines. It does a .b gtty (2) on the descriptor and checks the return value. .)f If it is, .Fn gettmode sets the terminal description modes from a .b gtty (2) . .Fn getenv is then called to get the name of the terminal, and that value (if there is one) is passed to .Fn setterm , which reads in the variables from \*(tc associated with that terminal. .Fn getenv "" ( returns a pointer to a string containing the name of the terminal, which we save in the character pointer .Vn sp .) If .Fn isatty returns false, the default terminal .Vn Def\*_term is used. The .Vn TI and .Vn VS sequences initialize the terminal .Fn \*_puts "" ( is a macro which uses .Fn tputs (see .b termcap (3)) to put out a string). It is these things which .Fn endwin undoes. .sh 2 "Movement Optimizations, or, Getting Over Yonder" .pp Now that we have all this useful information, it would be nice to do something with it\**. .(f \** Actually, it .i can be emotionally fulfilling just to get the information. This is usually only true, however, if you have the social life of a kumquat. .)f The most difficult thing to do properly is motion optimization. When you consider how many different features various terminals have (tabs, backtabs, non-destructive space, home sequences, absolute tabs, .....) you can see that deciding how to get from here to there can be a decidedly non-trivial task. The editor .b vi uses many of these features, and the routines it uses to do this take up many pages of code. Fortunately, I was able to liberate them with the author's permission, and use them here. .pp After using .Fn gettmode and .Fn setterm to get the terminal descriptions, the function .Fn mvcur deals with this task. It usage is simple: you simply tell it where you are now and where you want to go. For example .(l mvcur(0\*,0\*,LINES/2\*,COLS/2) .)l .lp would move the cursor from the home position (0\*,0) to the middle of the screen. If you wish to force absolute addressing, you can use the function .Fn tgoto from the .b termlib (7) routines, or you can tell .Fn mvcur that you are impossibly far away, like Cleveland. For example, to absolutely address the lower left hand corner of the screen from anywhere just claim that you are in the upper right hand corner: .(l mvcur(0\*,COLS\-1\*,LINES\-1\*,0) .)l