Date: 23 Jul 1982 1117-PDT From: SIM at SU-AI To: info-vax at SANDIA, h19-people cc: SIM at SU-AI Re: Reading Escape Sequences with VAX/VMS The following FORTRAN-77 subroutine allows VAX/VMS users to read escape sequences. This is useful for reading keypad and special function keys on terminals, reported cursor positions, etc. The subroutine sets then unsets (using an exit handler) the terminal characteristic ESCAPE so that you don't have too. To call ReadEscape from Pascal, declare it as follows: type StringTyp = packed array[1..?] of char; procedure ReadEscape( %STDESCR string : StringTyp; var StrLen,EscLen : integer); FORTRAN; For those of you interested, I have also written routines for single character input (using QIO reads in PASSALL mode with buffer length equal to one), and several Heathkit H19 dependent routines: one to display process status, priority, terminal name, cpu time, image name, data and time, and current default directory on the 25th line dynamically while running other things; another to save everything you see on your screen, including graphics characters, into a file which can then be edited, printed or typed out (VERY HANDY!). -Stuart McDonald C Subroutine ReadEscape C returns an input string terminated by a or any valid escape C sequence; StrLen is the number of characters before the terminator and C EscLen is the number of characters in the terminator. The total C length of the inputed string is StrLen + EscLen. -S.McD. 6/6/82 function ReadEscape( string,StrLen,EscLen ) implicit integer (a-z) character*(*) string integer ReadEscape,StrLen,EscLen character sys$input*9/'SYS$INPUT'/,terminal*63 external io$_readvblk,io$_setmode,tt$m_escape,ToggleEsc logical first/.true./ integer iosb*2(4) common /stu_escape/cchan ! common used by ToggleEsc save first,func_code,chan if (first) then ! Define ToggleEsc as an exit handler (see Users Guide) call userex(ToggleEsc) ! Find lowest logical name translation of SYS$INPUT call trnlog(sys$input,terminal,name_len) ! lowest log status = sys$assign( terminal, chan,, ) ! open terminal if (.not.status) call lib$stop( %VAL(status) ) ! check status cchan = chan ! load common call ToggleEsc ! allow esc seq ! Ready function code for read of escape sequence func_code = %LOC(io$_readvblk) ! ordinary read first = .false. endif ! Read in line and/or escape sequence status = sys$qiow( ,%VAL(chan),%VAL(func_code),iosb,,, 1 %REF(string),%VAL(len(string)),,,,) ! read esc seq if (.not.status) call lib$stop( %VAL(status) ) ! check status ReadEscape = iosb(1) ! rtn i/o stat StrLen = iosb(2) ! # chars before terminator EscLen = iosb(4) ! # chars in terminator return end ! This came from "Prog. VMS in FORT/MAC",p.83 subroutine trnlog( old_log,new_log,new_len ) implicit integer (a-z) byte esc_null_int(2) /'1B'X,0/ character*2 esc_null character*(*) old_log,new_log external ss$_notran equivalence (esc_null,esc_null_int) ! Translate name once status = sys$trnlog( old_log,new_len,new_log,,, ) if (status.eq. %LOC(ss$_notran)) stop 'Logical name has no translation' ! Repeat translation until unsuccessful do while (status.ne.%LOC(ss$_notran)) old_log(1:new_len) = new_log status = sys$trnlog( old_log(1:new_len),new_len,new_log,,, ) enddo ! Check if process permanent file if (new_log(1:2).eq.esc_null) then new_log(1:new_len) = new_log(5:new_len) new_len = new_len - 4 endif return end subroutine ToggleEsc ! Toggles Escape Recognition for Terminals implicit integer (a-z) integer mode_buf(2) external tt$m_escape,io$_setmode,io$_sensemode common /stu_escape/chan ! Channel passed in my common func_code = %LOC(io$_sensemode) ! Get terminal characteristics status = sys$qiow( ,%VAL(chan),%VAL(func_code),,,,mode_buf,,,,,) if (.not.status) call lib$stop( %VAL(status) ) ! check status mode_buf(2) = mode_buf(2) .xor. %LOC(tt$m_escape) ! toggle bits func_code = %LOC(io$_setmode) ! Set terminal characteristics status = sys$qiow( ,%VAL(chan),%VAL(func_code),,,,mode_buf,,,,,) if (.not.status) call lib$stop( %VAL(status) ) ! check status return end