Subject: v13i064: Generic user interface kit, Part02/02 Newsgroups: comp.sources.unix Sender: sources Approved: rsalz@uunet.UU.NET Submitted-by: Marc Majka Posting-number: Volume 13, Issue 64 Archive-name: iface/part02 Here is a manual for iface, the generic user interface. The program is intended to be hacked by programmers who want to use the it for the front end of an application. The manual focuses on the programming aspects of iface. Those reading the manual are encouraged to have a copy of the sources on their screens. --- Marc Majka - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - : This is a shar archive. Extract with sh, not csh. : This archive ends with exit, so do not worry about trailing junk. echo 'Extracting iface.1' sed 's/^X//' > iface.1 << '+ END-OF-FILE iface.1' X.TH IFACE 1 X.SH NAME Xiface - generic user interface X.SH SYNOPSIS X.B iface X.SH DESCRIPTION X.I iface Xis a program shell which is useful as a basis for writing other programs. XIt provides several user interface features: X.sp X.in +4 X\- CBREAK mode (single character) Input / Output X.br X\- Keystroke based function invocation X.br X\- User definable keybindings X.br X\- Input word completion X.br X\- Interrupt handling X.in -4 X.sp XThis program is in the public domain. I hope it can be useful to you. XYou should find that you can add the functions you want for an application Xprogram without fighting the interface code too much. Look carefully Xat the code for X.B do-something Xand X.B do-nothing. XThey are models of application-level functions. Keep a clean copy of X.I iface Xsomewhere, and modify copies. If you want clarification on how it works, Xfeel free to drop me a message. Please pass the code on to others if you Xthink it deserves distribution. X.sp XMarc Majka X.in +4 X.br X X.br X X.br X X.br X X.in -4 X.SH KEYBINDINGS XWhen X.I iface Xis invoked, it waits for character input from the user. An input character Xis used as an index in a table, which itself stores an index into a Xsymbol table. An entry exists in the symbol table for each function, Xand includes the function's name and yet another index into a table Xof pointers to functions. The appropriate function is invoked. Keys Xare associated by default with the function X.B BOGUS, Xwhich rings the terminal bell and does Xnothing else. X.sp XThree characters are bound to functions which repeat the process of Xreading an input character and invoking an associated function. These are Xthe ESC (escape) CTL-X (control x) and CTL-Y (control y) characters. Thus Xthese characters act as prefix keys, allowing functions to be invoked by Xa sequence of keystrokes such as (ESC x) or (CTL-X 1). X.sp XNew bindings of functions to keys may be accomplished with the X.B bind-key Xcommand. Keys may be \*(lqunbound\*(rq be binding them to the X.B BOGUS Xcommand. The X.B describe-key Xcommand prints the name of the function bound to a key or key sequence. X.SH "NAME COMPLETION" XSome functions other than X.B BOGUS Xare associated (bound) with keys. The Xkey sequence ESC-x (escape, then x) is bound by default to the function X.B extended-command. XThis function prompts the user with a colon, and allows the user to type Xthe name of a function, which will then be invoked. A list of all possible Xinputs is maintained by the program, which allows X.B extended-command Xto help the user. At any point while the user is entering a word, typing a Xquestion mark (?) will cause a list of all possible words which match the Xinput so far to be printed, along with a little help message explaining the Xinput word completion mechanism. Typing a space will cause the current word Xto be expanded (completed) as much as possible. X.sp XFor example, typing X.sp X.in +4 XESC-x X.br Xdes X.sp X.in -4 Xwould result in the input being expanded to X.sp X.in +4 Xdescribe- X.sp X.in -4 XTyping ? at this point would result in the message: X.sp X.in +4 X.sp X? choose one of the following X.sp Xdescribe-bindings describe-key X.sp X? ? for command list X.br X? ^D, ^G or ESC to exit, ^U to clear X.br X? , or to complete X.br X? to insist on first choice X.br X.sp X: describe- X.sp X.in -4 XTyping b would cause the input to be completed to X.sp X.in +4 X: describe-bindings X.in -4 X.sp Xand the X.B describe-bindings Xfunction would be invoked. Try this to get a list of default bindings. X.SH "NAME COMPLETION - INTERNALS" XThe name completion routine X.I getcom X(get command) takes a list of Xwords, the number of words in the list, and a prompt string as arguments. XIt picks up characters and appends them to a string. Special characters, Xsuch as a space, are dealt with individually. Space, tab and return character s Xcause getcom to call a matching routine. The matching routine works by Xmoving a pair of pointers together from the ends of the list. One Xpointer points at the first possible match for the input string, one for the Xlast possible match. If these pointers meet, then only one word matches the Xuser's input. The word can be \*(lqcompleted\*(rq by the routine appending Xthe tail end of the string for the user. If the pointers do not meet, it Xstill may be the case that all the words between them contain one or more Xcommon characters following the given string. The user's word is appended Xwith these common characters. Be careful about modifying the code in the X.I try_match Xroutine - it is a bit tricky. X.SH "ADDING FUNCTIONS" XTwo sample functions are included in the distribution version of X.I iface. XThese are X.B do-something Xand X.B do-nothing. XIt is instructive to look through the sources to see how these functions Xwork as part of X.I iface. X.sp XThe function X.B do-nothing, Xfor example, is defined in the file fns.c. The definition is: X.sp X.in +4 Xdo_nothing() {printf(\*(lqDone!\\n\*(rq);} X.in -4 X.sp XThe function is tied into the interface in the file init.c. In the Xroutine X.I init_symbols, Xthere is the call: X.sp X.in +4 Xaddcom(\*(lqdo-nothing\*(rq); X.in -4 X.sp XThis adds the string \*(lqdo-nothing\*(rq to the list of commands used by the Xword completion routine, and it creates a symbol table entry for the Xcommand. (Note that the names must be sorted in the word list for Xthe completion routine. This version insists that the names be added Xin sorted order. Writing an insertion sort is left as an exercise for Xthe programmer who wishes it otherwise.) The addcom routine also Xputs a pointer to the X.I do_nothing Xroutine in a table, and stores its index in the symbol table. X.sp XThe X.I command_ptr Xroutine links names with pointers to functions. The X.I do_nothing Xroutine is declared: X.sp X.in +4 Xint do_nothing(); X.in -4 X.sp XThe pointer value is returned in the test: X.sp X.in +4 Xif (!strcmp(str,\*(lqdo-nothing\*(rq)) return(do_nothing); X.in -4 X.sp XAlthough there are faster ways to do the name - pointer linking, this Xroutine is only called once for each function at startup time, and this Xscheme is easy and flexible. X.sp XThe X.B do-nothing Xcommand is bound to the \*(lqn\*(rq key in the X.I init_bindings Xroutine: X.sp X.in +4 Xbinding['n'][0] = sym_ref(\*(lqdo-nothing\*(rq); X.in -4 X.SH "SYMBOL TABLE" XThe symbol table contains names and values. As already mentioned, function Xnames are stored there, along with an index into a table of function pointers. XThe symbol table may also contain other information which may be useful to Xthe application. In the distribution, two \*(lqvariables\*(rq have been Xadded to the symbol table. These are initialized in the X.I init_variables Xroutine: X.sp X.in +4 Xaddvar(\*(lqdummy\*(rq,\*(lq\*(rq,0); X.br Xaddvar(\*(lqversion\*(rq,\*(lq0.0\*(rq,0); X.in -4 X.sp XVariables have a name, a string value, and an integer value. Objects Xin the symbol table may be found by name using the X.I sym_ref Xroutine. XFor example, the X.I print_version Xfunction prints the string value stored Xunder the \*(lqversion\*(rq variable using the code: X.sp X.in +4 Xref = sym_ref(\*(lqversion\*(rq); X.br Xprintf(\*(lqversion %s\\n\*(rq,symbol[ref].strval); X.in -4 X.sp XThe contents of the symbol table may be examined with X.B dump-symbol-table. X.SH INTERRUPTS X.I iface Xcatches interrupt and hangup signals in the sigtrap routine. Interrupts Xcause execution to jump back to the top level loop in the X.I user_level Xroutine. XNote that one could easily add a X.B user-level Xcommand, thereby making the Xinterface recursive. X.SH "CBREAK I/O" XThis is the only place where X.I iface Xreally is hooked to UNIX. The terminal is placed in CBREAK mode Xwith the ioctl calls in newterm, and restored to its initial mode Xin oldterm, both in exec.c. Since X.I iface Xdoes its own I/O with X.I get_string Xand X.I put_char Xin io.c, character echo is turned off. X.SH AUTHOR XMarc Majka + END-OF-FILE iface.1 chmod 'u=rw,g=r,o=r' 'iface.1' echo ' -rw-r--r-- 1 majka 7952 Nov 4 13:08 iface.1 (as sent)' echo -n ' ' /bin/ls -l iface.1 exit 0