1 program keydef !++ ! ! Program : KEYDEF V2.2-1 ! ! Purpose : Define keys on VT200/300 series terminals ! ! Author : Don Stokes ! ! Date : 24 June 1988 ! ! Description : This program allows the use of shifted top-row function keys. ! It should be set up as a foreign command: ! ! $ KEYDEF :== $device:[dir]KEYDEF.EXE ! ! To use KEYDEF, enter: ! ! $ KEYDEF ! ! The parameter specifies which key to define. Any ! of the following keys may be loaded: ! ! F6, F7, F8, F9, F10, F11 (ESC), F12 (BS), F13 (LF), ! F14, F15 (HELP), F16 (DO), F17, F18, F19, F20. ! ! Note that the names in brackets can also be used. ! ! The parameter specifies the string to be loaded ! into the key. It should be enclosed in quotes. To insert ! control character into the string, use caret notation. ! ! Alternatively, keydef can be used to define several keys ! in a command file. If keydef is invoked without any ! parameters, it will enter command mode, allowing multiple ! keys to be defined eg: ! ! $ KEYDEF ! KEY> DO "DIRECTORY^M" ! KEY> HELP "HELP^M" ! KEY> ! $ ! ! The following are some useful codes: ! ! ^M Carriage return ! ^I Tab - often used as field accept ! ^J Line feed (delete word in VMS line editing) ! ^E End of line (in VMS line editing) ! ^U Delete line " " " " ! ^X Purge typeahead " " " " ! ^[ Escape - used for escape sequences eg ! ! ^[[A Up-arrow ! ^[[B Down ! ^[[C Right ! ^[[D Left ! ! ! Ammendments : 27/06/88/dcs/V2.1 ! F1, F3 & F4 keys removed (worked on Esprit terminals, but ! not on LK201 keyboards). ! ! 01/07/88/dcs/V2.2 ! Use QIOW with NOFORMAT to avoid extraneous carriage control. ! Implement 'command mode' if no params entered on command line. ! A few other general cleanups... ! ! 27/10/88/dcs/V2.2-1 ! Correct problem with caret notation ... caret notaion mode ! remained on until next caret read. ! !-- %IDENT "KEYDEF V2.2-0" option type = explicit !+ ! Local and external declarations !- external long function SYS$ASSIGN, & SYS$QIOW, & SYS$DASSGN, & LIB$GET_FOREIGN external long constant SS$_NORMAL, & IO$_WRITEVBLK, & IO$M_NOFORMAT external sub LIB$STOP( long by value ) declare long constant TRUE = -1, & FALSE = 0, & EOF = 11, & ILLNUM = 52 declare string constant start_dcs = esc + "P1;1|", & end_dcs = esc + "\", & hex_digits = "0123456789ABCDEF" declare long sts, & quote_caret_flag, & char_asc, & command_mode, & iochan, & func_code, & n, z declare string command_line, & key_name, & key_number, & key_text, & escape_sequence, & char, & hex_char !+ ! Initialization and main logic !- set no prompt ! ! No question marks on prompts wanted. ! sts = LIB$GET_FOREIGN( command_line ) call LIB$STOP( sts ) unless sts and SS$_NORMAL ! ! Get command line ! func_code = IO$_WRITEVBLK or IO$M_NOFORMAT sts = SYS$ASSIGN("SYS$OUTPUT", iochan by ref,,) call LIB$STOP( sts ) unless sts and SS$_NORMAL ! ! Set up function code ! Assign channel to output device (terminal) ! if command_line = "" then command_mode = TRUE gosub process_key while command_mode else gosub process_key end if ! ! If no key name was specified, then go into command mode ! Else process single key ! sts = SYS$DASSGN( iochan by value ) call LIB$STOP( sts ) unless sts and SS$_NORMAL ! ! Deassign output channel ! exit program !+ ! Subroutine to process one key definition !- process_key: when error in linput "KEY> "; command_line while command_line = "" use exit handler if err <> EOF command_mode = FALSE continue process_key_end end when ! ! If an empty command line is entered: ! get key name (at least) ! if ctrl/Z then exit from command mode ! z = instr(0%, command_line + " ", " ") key_name = edit$(left(command_line, z - 1%), -1%) ! ! Extract key name from command line. ! when error in key_name = "F" + num1$( val%( key_name)) & if instr(0%, "01234567890", left(key_name, 1%)) use exit handler if err <> ILLNUM print "%KEYDEF-W-INVKEY, invalid key name" continue process_key_end end when ! ! If user supplied the number only, convert to Fnn key name ! If the nn was not valid, then say so and exit (back to command ! mode if thats where we are ! select key_name case "F6" \ key_number = "17" case "F7" \ key_number = "18" case "F8" \ key_number = "19" case "F9" \ key_number = "20" case "F10" \ key_number = "21" case "F11", "ESC" \ key_number = "23" case "F12", "BS" \ key_number = "24" case "F13", "LF" \ key_number = "25" case "F14" \ key_number = "26" case "F15", "HELP" \ key_number = "28" case "F16", "DO" \ key_number = "29" case "F17" \ key_number = "31" case "F18" \ key_number = "32" case "F19" \ key_number = "33" case "F20" \ key_number = "34" case else print "%KEYDEF-W-INVKEY, invalid key name" goto process_key_end end select ! ! Get the physical key number from the name supplied ! key_text = right(command_line, z + 1%) when error in linput "_Text: "; key_text while key_text = "" use exit handler if err <> EOF continue process_key_end end when ! ! Extract key text from command line ! If not specified, then ask from keyboard ! Exit if ctrl/Z (back to KEY> if in command mode) ! key_text = left(key_text, len(key_text) - 1%) & if right(key_text, len(key_text)) = '"' and left(key_text, 1%) = '"' key_text = right(key_text, 2%) if left(key_text, 1%) = '"' ! ! Remove leading & trailing quotes. ! escape_sequence = start_dcs + key_number + "/" quote_caret_flag = FALSE ! ! Initialise esc sequence and quoting flag ! translate_loop: for n = 1% to len(key_text) n = n + 1% if mid(key_text,n , 2) = '""' ! ! If two quotes are supplied then just use one ! char = mid(key_text, n, 1) char_asc = ascii(char) ! ! Get character to translate to hex ! if char = "^" then quote_caret_flag = not quote_caret_flag iterate translate_loop if quote_caret_flag else char_asc = char_asc and X"1F"L if quote_caret_flag quote_caret_flag = FALSE end if ! ! If character is a caret then set quote flag ! If not then check quoting flag and use corresponding ! control character. Note that ^^ means a single caret. ! hex_char = mid(hex_digits, (char_asc / 16) + 1%, 1%) & + mid(hex_digits, (char_asc and 15%) + 1%, 1%) escape_sequence = escape_sequence + hex_char ! ! Work out hex value for character ! Add to escape sequence ! next n escape_sequence = escape_sequence + end_dcs ! ! Put DCS terminator on end of string ! sts = SYS$QIOW( , & iochan by value, & func_code by value, & ,,, & escape_sequence by ref, & len(escape_sequence) by value, & ,,,) call LIB$STOP( sts ) unless sts and SS$_NORMAL ! ! $QIO escape sequence (so we don't get any extraneous ! carriage control) ! process_key_end: ! Come here if invalid key etc command_line = "" ! ! Reset command line for multiple keys ! return end program