From:	SMTP%"RELAY-INFO-VAX@CRVAX.SRI.COM" 30-MAY-1994 13:18:45.25
To:	EVERHART
CC:	
Subj:	Re: Cursor ...

Date: Sat, 28 May 1994 11:49:20 +0100
From: Arne Vajhoej <ARNE@kopc.hhs.dk>
Subject: Re: Cursor ...
To: loreti@FNALV.FNAL.GOV, INFO-VAX@SRI.COM
Message-Id: <01HCVDNDCMPE8WW8IP@kopc.hhs.dk>
X-Vms-To: KOPC::IN%"loreti@FNALV.FNAL.GOV"
X-Vms-Cc: IN::"INFO-VAX@SRI.COM"
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; CHARSET=ISO-8859-1
Content-Transfer-Encoding: 8BIT

> My question is: is it possible to a program to get the line and
> column of the cursor?  I have tried looking at $getdvi, at the $qio
> status request, and played with CSI 6 n without any result.  I am
> programming in C, and I need an answer that works on VAXstations
> as well as on VTxxx terminals - without using the smg$ package for
> a (very) small program.

"<CSI>6n" is the rigth sequence !

Below are a MACRO routine that does it. It works with the
following small C program:

#include <stdio.h>

void scr_where();
void scr_exit();

main()
{
   int r,c;
   scr_where(&r,&c);
   scr_exit();
   printf("row=%d col=%d\n",r,c);
}

Notes:
  - the routine are cut out of a bigger package and that is why it looks
    a little overly complex
  - to compile on AXP outcomment the .JSB_ENTRY macro
  - remember to call the SCR_EXIT because else the terminal will
    not be reset

                                                          Arne

Arne Vajhxj                             local DECNET:  KO::ARNE
Computer Department                     PSI:           PSI%238310013040::ARNE
Business School of Southern Denmark     Internet:      ARNE@KO.HHS.DK

================================================================================

        .title  scr
        $DSCDEF
        $IODEF
        $TTDEF
        $TT2DEF
        $SSDEF
TRUE=-1
FALSE=0
        .macro  fixdesc,l,a
        .word   l
        .byte   DSC$K_DTYPE_T
        .byte   DSC$K_CLASS_S
        .address a
        .endm
        .macro  ascstr,s
        .ascii  "s"
        .align  long
        .endm
        .macro  .jsb_entry input,output
        .endm
        .psect  $PDATA quad,pic,con,lcl,shr,noexe,nowrt
argl_assign:                            ; argumentlist SYS$ASSIGN
        .long   4
        .address trmdes                 ; device name
        .address ttchan                 ; channel
        .long   0                       ; access-mode
        .long   0                       ; mailbox name
trmdes: fixdesc 2,trmadr                ; terminal-descriptor
trmadr: ascstr  <TT>                    ; terminal-name
        .psect  $LOCAL quad,pic,con,lcl,noshr,noexe,wrt
argl_qio:                               ; argumentlist SYS$QIOW
        .long   12
        .long   0                       ; efn
        .blkl   1                       ; channel
        .blkl   1                       ; function
        .address stat                   ; IOSB
        .long   0                       ; AST address
        .long   0                       ; AST parameter
        .blkl   1                       ; P1
        .blkl   1                       ; P2
        .blkl   1                       ; P3
        .long   0                       ; P4
        .blkl   1                       ; P5
        .blkl   1                       ; P6
argl_dassgn:                            ; argumentlist SYS$DASSGN
        .long   1
        .blkl   1                       ; channel
stat:   .blkq   1                       ; IO status block
char1:  .blkq   1                       ; terminal characteristics (old)
char2:  .blkq   1                       ; terminal characteristics (new)
char3:  .blkl   3                       ; terminal characteristics (old)
char4:  .blkl   3                       ; terminal characteristics (new)
typah:  .blkl   2                       ; type-ahead buffer
keybuf: .blkb   1                       ; keystroke buffer
ttchan: .blkw   1                       ; terminal channel
wrtbuf_siz=2048
wrtbuf_lim=1532
wrtpnt: .long   0                       ; writebuffer pointer
wrtbuf: .blkb   wrtbuf_siz              ; writebuffer
        .psect  $CODE quad,pic,con,lcl,shr,exe,nowrt
;***************************************
;
;  SCR_EXIT
;
;  exit
;
;***************************************
        .entry  scr_exit,^m<r9,r10>
        tstl    wrtpnt                  ; test if flush buffer
        bleq    100$
        jsb     flu_buf
100$:   jsb     dsg_trm                 ; deassign terminal
        ret
;***************************************
;
;  SCR_WHERE ( ROW , COL )
;
;  where on screen are we
;
;***************************************
        .entry  scr_where,^m<r9,r10>
        moval   wrtbuf,r0
        addl2   wrtpnt,r0
        movl    #^x006E369B,(r0)        ; write "<CSI>6n"
        addl2   #3,wrtpnt
        jsb     flu_buf                 ; flush buffer
100$:   clrl    r10
        jsb     get_1                   ; try to read "<ESC>"
        cmpb    r10,#^x1B
        bneq    100$
200$:   clrl    r10
        jsb     get_1                   ; try to read "["
        cmpb    r10,#^x5B
        bneq    200$
300$:   clrl    r10
        jsb     get_1                   ; try to read "row"
        cmpb    r10,#48
        blss    300$
        cmpb    r10,#57
        bgtr    300$
        subl2   #48,r10
        movl    r10,@B^4(ap)
500$:   clrl    r10
        jsb     get_1                   ; try to read "row"
        cmpb    r10,#^x3B
        beql    900$
        cmpb    r10,#48
        blss    500$
        cmpb    r10,#57
        bgtr    500$
        mull2   #10,@B^4(ap)
        subl2   #48,r10
        addl2   r10,@B^4(ap)
700$:   clrl    r10
        jsb     get_1                   ; try to read ";"
        cmpb    r10,#^x3B
        bneq    700$
900$:   clrl    r10
        jsb     get_1                   ; try to read "col"
        cmpb    r10,#48
        blss    900$
        cmpb    r10,#57
        bgtr    900$
        subl2   #48,r10
        movl    r10,@B^8(ap)
1100$:  clrl    r10
        jsb     get_1                   ; try to read "col"
        cmpb    r10,#^x52
        beql    1500$
        cmpb    r10,#48
        blss    1100$
        cmpb    r10,#57
        bgtr    1100$
        mull2   #10,@B^8(ap)
        subl2   #48,r10
        addl2   r10,@B^8(ap)
1300$:  clrl    r10
        jsb     get_1                   ; try to read "R"
        cmpb    r10,#^x52
        bneq    1300$
1500$:  ret
;***************************************
;
;  asg_trm
;
;***************************************
asg_trm: .jsb_entry
        callg   argl_assign,G^SYS$ASSIGN; assign terminal
        movw    ttchan,argl_qio+8
        movw    #IO$_SENSEMODE,argl_qio+12
        moval   char1,argl_qio+28
        movl    #8,argl_qio+32
        movl    #0,argl_qio+36
        movl    #0,argl_qio+44
        movl    #0,argl_qio+48
        callg   argl_qio,G^SYS$QIOW     ; read old characteristics
        movl    char1,char2
        movl    char1+4,char2+4
        movw    #511,char2+2
        movw    ttchan,argl_qio+8
        movw    #IO$_SETMODE,argl_qio+12
        moval   char2,argl_qio+28
        movl    #8,argl_qio+32
        movl    #0,argl_qio+36
        movl    #0,argl_qio+44
        movl    #0,argl_qio+48
        callg   argl_qio,G^SYS$QIOW     ; write new characteristics
        rsb
;***************************************
;
;  dsg_trm
;
;***************************************
dsg_trm: .jsb_entry
        movw    ttchan,argl_qio+8
        movw    #IO$_SETMODE,argl_qio+12
        moval   char1,argl_qio+28
        movl    #8,argl_qio+32
        movl    #0,argl_qio+36
        movl    #0,argl_qio+44
        movl    #0,argl_qio+48
        callg   argl_qio,G^SYS$QIOW     ; write old characteristics
        movw    ttchan,argl_dassgn+4
        callg   argl_dassgn,G^SYS$DASSGN; deassign terminal
        clrw    ttchan
        rsb
;***************************************
;
;  flu_buf
;
;***************************************
flu_buf: .jsb_entry
        movl    wrtpnt,r9
        moval   wrtbuf,r10
        jsb     put_n                   ; write buffer
        movl    #0,wrtpnt
        rsb
;***************************************
;
;  get_1, r10=code
;
;***************************************
get_1: .jsb_entry output=<r10>
        tstw    ttchan                  ; test if channel assigned
        bneq    100$
        jsb     asg_trm
100$:   movw    ttchan,argl_qio+8
        movw    #IO$_READVBLK!IO$M_NOECHO!IO$M_NOFILTR,argl_qio+12
        moval   keybuf,argl_qio+28
        movl    #1,argl_qio+32
        movl    #0,argl_qio+36
        movl    #0,argl_qio+44
        movl    #0,argl_qio+48
        callg   argl_qio,G^SYS$QIOW     ; perform IO read operation
        movb    keybuf,r10
        rsb
;***************************************
;
;  put_n, r10=stradr, r9=strlen
;
;***************************************
put_n: .jsb_entry input=<r9,r10>
        tstw    ttchan                  ; test if terminal assigned
        bneq    200$
        jsb     asg_trm
200$:   movw    ttchan,argl_qio+8
        movw    #IO$_WRITEVBLK,argl_qio+12
        movl    r10,argl_qio+28
        movl    r9,argl_qio+32
        movl    #0,argl_qio+36
        movl    #0,argl_qio+44
        movl    #0,argl_qio+48
        callg   argl_qio,G^SYS$QIOW     ; perform IO write operation
        rsb
        .end

