(FILECREATED " 5-Sep-85 17:36:43" {DSK}<LISPFILES>TEK4010CHAT.;6 26671  

      changes to:  (FNS TEK4010.CLEAR TEK4010CHAT.INIT TEK4010.RESHAPEFN TEK4010.CLOSEFN 
			TEK4010.CTRLCHAR)
		   (VARS TEK4010CHATCOMS)

      previous date: " 5-Sep-85 11:54:39" {DSK}<LISPFILES>TEK4010CHAT.;2)


(* Copyright (c) 1985 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT TEK4010CHATCOMS)

(RPAQQ TEK4010CHATCOMS [(RECORDS TEK4010.STATE)
	(FNS TEK4010.ALPHASTATE TEK4010.CLEAR TEK4010.CLOSEFN TEK4010.CROSSHAIR TEK4010CHAT.INIT 
	     TEK4010.NEXTSTATE TEK4010.RELMOVETO TEK4010.SCALE TEK4010.SENDCOORD TEK4010CHAT.BUTTONFN 
	     TEK4010.RESHAPEFN TEK4010CHAT.HANDLECHAR TEK4010CHAT.MENUFN TEK4010.GRAPHICSSTATE 
	     TEK4010.CTRLCHAR TEK4010.ESCAPECHAR TEK4010.UNSCALE TEK4010.GLOMHI&LO TEK4010.MOVETO 
	     TEK4010.DRAWTO)
	(INITVARS (TEK4010CHAT.MENU NIL))
	(VARS TEK4010CHAT.MENUITEMS)
	(ADDVARS (CHAT.DRIVERTYPES (TEK4010 TEK4010CHAT.HANDLECHAR TEK4010CHAT.INIT])
[DECLARE: EVAL@COMPILE 

(DATATYPE TEK4010.STATE (CURRENTSTATE PREVSTATE (HIX INTEGER)
				      (LOX INTEGER)
				      (HIY INTEGER)
				      (LOY INTEGER)
				      (INBYTE BITS 8)
				      (HI2BITS BITS 2)
				      (LO5BITS BITS 5)
				      BYTESTATE
				      (DRAWP FLAG)
				      (ROW INTEGER)
				      (MARGIN INTEGER))
			CURRENTSTATE ←(QUOTE TEK4010.ALPHASTATE)
			HIX ← 0 LOX ← 0 HIY ← 0 LOY ← 0 INBYTE ← 0 HI2BITS ← 0 LO5BITS ← 0 ROW ← 1 
			MARGIN ← 0)
]
(/DECLAREDATATYPE (QUOTE TEK4010.STATE)
		  (QUOTE (POINTER POINTER FIXP FIXP FIXP FIXP (BITS 8)
				  (BITS 2)
				  (BITS 5)
				  POINTER FLAG FIXP FIXP))
		  (QUOTE ((TEK4010.STATE 0 POINTER)
			  (TEK4010.STATE 2 POINTER)
			  (TEK4010.STATE 4 FIXP)
			  (TEK4010.STATE 6 FIXP)
			  (TEK4010.STATE 8 FIXP)
			  (TEK4010.STATE 10 FIXP)
			  (TEK4010.STATE 2 (BITS . 7))
			  (TEK4010.STATE 0 (BITS . 1))
			  (TEK4010.STATE 0 (BITS . 36))
			  (TEK4010.STATE 12 POINTER)
			  (TEK4010.STATE 12 (FLAGBITS . 0))
			  (TEK4010.STATE 14 FIXP)
			  (TEK4010.STATE 16 FIXP)))
		  (QUOTE 18))
(DEFINEQ

(TEK4010.ALPHASTATE
  [LAMBDA (CHAT.STATE STATE)                                 (* jds " 5-Sep-85 11:41")

          (* This function resets the DRAWP and BYTESTATE fields to NIL such that the next time GRAPHICSSTATE is entered, it 
	  will be clean, and then either outputs the alpha character or calls the control char routine if the high 2 bits are 
	  zero.)


    (replace (TEK4010.STATE DRAWP) of STATE with NIL)
    (replace BYTESTATE of STATE with NIL)
    (COND
      ((ZEROP (fetch (TEK4010.STATE HI2BITS) of STATE))
	(TEK4010.CTRLCHAR CHAT.STATE STATE))
      (T (BOUT (fetch (CHAT.STATE DSP) of CHAT.STATE)
	       (fetch (TEK4010.STATE INBYTE) of STATE])

(TEK4010.CLEAR
  [LAMBDA (CHAT.STATE WINDOW)                                (* AJB " 5-Sep-85 17:36")
                                                             (* This functions clears the screen and resets the 
							     cursor to the top left corner)
    (LET ((OUTSTREAM (fetch (CHAT.STATE DSP) of CHAT.STATE))
	  (STATE (fetch (CHAT.STATE TERM.STATE) of CHAT.STATE)))
         (CARET (QUOTE OFF))
         (DSPRESET OUTSTREAM)
         (CARET T)
         (replace (TEK4010.STATE ROW) of STATE with 1)
         (replace (TEK4010.STATE MARGIN) of STATE with 0)
         (TEK4010.NEXTSTATE STATE (QUOTE TEK4010.ALPHASTATE))
         (replace BYTESTATE of STATE with NIL)
         (replace (TEK4010.STATE DRAWP) of STATE with NIL)
         (DSPLEFTMARGIN 0 OUTSTREAM)                         (* Set the right margin to the width of the window)
         (DSPRIGHTMARGIN (FETCH WIDTH OF (DSPCLIPPINGREGION NIL OUTSTREAM))
			 OUTSTREAM])

(TEK4010.CLOSEFN
  [LAMBDA (WINDOW)                                           (* AJB " 5-Sep-85 15:36")
                                                             (* This function resets the window back to a default 
							     state)
    (WINDOWDELPROP WINDOW (QUOTE RESHAPEFN)
		   (FUNCTION TEK4010.RESHAPEFN))             (* remove reshape function from window prop)
    (WINDOWDELPROP WINDOW (QUOTE CLOSEFN)
		   (FUNCTION TEK4010.CLOSEFN))               (* Remove this close function so it doesn't get called 
							     again)
    (DSPOPERATION (QUOTE REPLACE)
		  WINDOW)                                    (* Restore REPLACE mode for BITBLT)
                                                             (* Turn scrolling back on)
    (DSPSCROLL (QUOTE ON)
	       WINDOW])

(TEK4010.CROSSHAIR
  [LAMBDA (WINDOW)                                           (* edited: "26-Apr-85 16:14")
                                                             (* Moves crosshair around screen until anykey is struct
							     and then returns X Y location)
    (PROG [(WIDTH (WINDOWPROP WINDOW (QUOTE WIDTH)))
	   (HEIGHT (WINDOWPROP WINDOW (QUOTE HEIGHT)))
	   (REGION (WINDOWPROP WINDOW (QUOTE REGION)))
	   (OUTSTREAM (WINDOWPROP WINDOW (QUOTE DSP]
          (LET* [(LEFT 0)
		 (RIGHT (PLUS LEFT WIDTH))
		 (BOTTOM 0)
		 (TOP (PLUS BOTTOM HEIGHT))
		 (LASTY (LASTMOUSEY WINDOW))
		 (LASTX (LASTMOUSEX WINDOW))
		 (CROSSHAIRX (WINDOWPROP WINDOW (QUOTE CROSSHAIRX)))
		 (CROSSHAIRY (WINDOWPROP WINDOW (QUOTE CROSSHAIRY]
	        (COND
		  [CROSSHAIRX (COND
				((NEQ CROSSHAIRX LASTX)
				  (BLTVLINE CROSSHAIRX 0 HEIGHT WINDOW GRAYSHADE)
				  (BLTVLINE LASTX 0 HEIGHT WINDOW GRAYSHADE]
		  (T (SETQ LASTX (COND
			 ((LESSP LASTX LEFT)
			   LEFT)
			 ((GREATERP LASTX RIGHT)
			   (DIFFERENCE RIGHT 2))
			 (T LASTX)))
		     (BLTVLINE LASTX 0 HEIGHT WINDOW GRAYSHADE)))
	        (WINDOWPROP WINDOW (QUOTE CROSSHAIRX)
			    LASTX)
	        (COND
		  [CROSSHAIRY (COND
				((NEQ CROSSHAIRY LASTY)
				  (BLTHLINE CROSSHAIRY 0 WIDTH WINDOW GRAYSHADE)
				  (BLTHLINE LASTY 0 WIDTH WINDOW GRAYSHADE]
		  (T (SETQ LASTY (COND
			 ((LESSP LASTY BOTTOM)
			   BOTTOM)
			 ((GREATERP LASTY TOP)
			   (DIFFERENCE TOP 2))
			 (T LASTY)))
		     (BLTHLINE LASTY 0 WIDTH WINDOW GRAYSHADE)))
	        (WINDOWPROP WINDOW (QUOTE CROSSHAIRY)
			    LASTY])

(TEK4010CHAT.INIT
  [LAMBDA (CHAT.STATE)                                       (* AJB " 5-Sep-85 17:30")
                                                             (* Initialize a CHAT connection using the TEKtronix 
							     4010 emulator for display)
    (PROG* ((OUTSTREAM (fetch (CHAT.STATE DSP) of CHAT.STATE))
	    (WINDOW (WFROMDS OUTSTREAM))
	    (XSCALE (FQUOTIENT (fetch WIDTH of (DSPCLIPPINGREGION NIL OUTSTREAM))
			       1024))
	    (YSCALE (FQUOTIENT (fetch HEIGHT of (DSPCLIPPINGREGION NIL OUTSTREAM))
			       768)))
           (DSPFONT (QUOTE (GACHA 10 MRR))
		    OUTSTREAM)
           (WINDOWADDPROP WINDOW (QUOTE RESHAPEFN)
			  (FUNCTION TEK4010.RESHAPEFN))      (* Add reshape window function to rescale X,Y coords to
							     new window size)
           (WINDOWADDPROP WINDOW (QUOTE CLOSEFN)
			  (FUNCTION TEK4010.CLOSEFN)
			  T)                                 (* Add close function to restore state back)
                                                             (* NOTE: CLOSE function must be put at beginning of 
							     property list for CLOSEFN WINDOWPROP)
           (WINDOWPROP WINDOW (QUOTE CURSORMOVEDFN)
		       NIL)                                  (* Make sure crosshair function is disabled)
           (WINDOWPROP WINDOW (QUOTE CROSSHAIRX)
		       NIL)
           (WINDOWPROP WINDOW (QUOTE CROSSHAIRY)
		       NIL)
           (DSPLEFTMARGIN 0 OUTSTREAM)
           (DSPRIGHTMARGIN (FETCH WIDTH OF (DSPCLIPPINGREGION NIL OUTSTREAM)))
                                                             (* Set the right margin to the width of the window)
           (DSPOPERATION (QUOTE PAINT)
			 OUTSTREAM)                          (* Set BITBLT to OR bits since this is emulating a 
							     storage tube device)
           (STREAMPROP OUTSTREAM (QUOTE TEK4010.SCALE)
		       (MIN XSCALE YSCALE))                  (* Set the scale on the output stream so that the 
							     entire screen image will fit into the CHAT window)
           (SETQ CHAT.EMULATORTYPE (QUOTE TEK4010))
           (WINDOWPROP WINDOW (QUOTE BUTTONEVENTFN)
		       (FUNCTION TEK4010CHAT.BUTTONFN))
           (RETURN (create TEK4010.STATE])

(TEK4010.NEXTSTATE
  [LAMBDA (STATE NEXTSTATE)                                  (* jds " 5-Sep-85 11:38")
                                                             (* This function replaces the state of the emulator 
							     which is either ALPHASTATE or GRAPHICSSTATE in the 
							     STATE instance of the TEK4010.STATE datatype)
    (replace PREVSTATE of STATE with (fetch (TEK4010.STATE CURRENTSTATE) of STATE))
    (replace (TEK4010.STATE CURRENTSTATE) of STATE with NEXTSTATE])

(TEK4010.RELMOVETO
  [LAMBDA (RELX RELY STREAM)                                 (* jds " 5-Sep-85 11:23")
                                                             (* Given RELX, RELY in TEK4010 units, move STREAM to 
							     the corresponding relative location.)
    (RELMOVETO (TEK4010.SCALE RELX STREAM)
	       (TEK4010.SCALE RELY STREAM)
	       STREAM])

(TEK4010.SCALE
  [LAMBDA (COORD STREAM)                                     (* jds " 5-Sep-85 11:20")

          (* Given an X or Y coordinate in TEK4010 units, scale it to fit inside STREAM's clipping region.
	  The TEK4010.SCALE STREAMPROP has to be set up by the output-stream opener, usually TEK4010CHAT.INIT)


    (FIXR (FTIMES COORD (OR (STREAMPROP STREAM (QUOTE TEK4010.SCALE))
			    1.0])

(TEK4010.SENDCOORD
  [LAMBDA (STREAM COORD SENDINGY)                            (* jds " 5-Sep-85 11:36")
                                                             (* Send X or Y crosshair coordinate back to computer)
    (BOUT STREAM (IPLUS (LRSH (OR (NUMBERP COORD)
				  0)
			      5)
			32))                                 (* Send the hi half of the coordinate)
    (BOUT STREAM (IPLUS (LOGAND (OR (NUMBERP COORD)
				    0)
				31)
			(COND
			  (SENDINGY                          (* The low-Y coord gets bumped by 96)
				    96)
			  (T                                 (* The low-X coord gets bumped by 64)
			     64])

(TEK4010CHAT.BUTTONFN
  [LAMBDA (WINDOW)                                           (* AJB "24-May-85 15:27")
    (COND
      ((LASTMOUSESTATE LEFT)
	(CHAT.HOLD WINDOW))
      ((LASTMOUSESTATE MIDDLE)
	(TEK4010CHAT.MENUFN WINDOW])

(TEK4010.RESHAPEFN
  [LAMBDA (WINDOW OLDIMAGE IMAGEREGION OLDSCREENREGION)      (* AJB " 5-Sep-85 15:51")

          (* * This reshape window function is necessary to rescale the TEK4010 coordinates to the new window size)


    (PROG* ((CHAT.STATE (WINDOWPROP WINDOW (QUOTE CHATSTATE)))
	    (OUTSTREAM (fetch (CHAT.STATE DSP) of CHAT.STATE))
	    (XSCALE (FQUOTIENT (fetch WIDTH of (DSPCLIPPINGREGION NIL OUTSTREAM))
			       1024))
	    (YSCALE (FQUOTIENT (fetch HEIGHT of (DSPCLIPPINGREGION NIL OUTSTREAM))
			       768)))
           (STREAMPROP OUTSTREAM (QUOTE TEK4010.SCALE)
		       (MIN XSCALE YSCALE))                  (* Set the scale on the output stream so that the 
							     entire screen image will fit into the CHAT window)
           (WINDOWPROP WINDOW (QUOTE CROSSHAIRX)
		       NIL)                                  (* Make sure crosshair function is disabled)
           (WINDOWPROP WINDOW (QUOTE CROSSHAIRY)
		       NIL)
           (TEK4010.CLEAR CHAT.STATE WINDOW)                 (* Clear the window and reset display stream 
							     coordinates)
       ])

(TEK4010CHAT.HANDLECHAR
  [LAMBDA (CH CHAT.STATE STATE)                              (* jds " 5-Sep-85 11:40")

          (* This function is called by CHAT to handle a single char from the input stream ; stores the char in INBYTE, the 
	  high 2 bits in HI2BITS, and the lower 5 bits in LO5BITS in the instance of the TEK4010.STATE DATATYPE parameter 
	  called STATE It then fetches the current state of the emulator (GRAPHICSSTATE or ALPHASTATE) and executes the 
	  corresponding named function. Currently the initialization is triggered from here, since CHAT has no initialize hook
	  for other emulators.)


    (replace (TEK4010.STATE INBYTE) of STATE with CH)
    (replace (TEK4010.STATE HI2BITS) of STATE with (LRSH (fetch (TEK4010.STATE INBYTE) of STATE)
							 5))
    (replace (TEK4010.STATE LO5BITS) of STATE with (LOGAND (fetch (TEK4010.STATE INBYTE)
							      of STATE)
							   31))
    (APPLY* (fetch (TEK4010.STATE CURRENTSTATE) of STATE)
	    CHAT.STATE STATE])

(TEK4010CHAT.MENUFN
  [LAMBDA (WINDOW)                                           (* AJB "24-May-85 15:33")
    (DECLARE (GLOBALVARS TEK4010CHAT.MENU)
	     (SPECVARS WINDOW STATE))                        (* Called by YELLOW)
    (PROG ((STATE (WINDOWPROP WINDOW (QUOTE CHATSTATE)))
	   COMMAND)
          [COND
	    ((NOT STATE)                                     (* No Connection here; try to reestablish)
	      (RETURN (COND
			((LASTMOUSESTATE MIDDLE)
			  (CHAT.RECONNECT WINDOW))
			(T (TOTOPW WINDOW]
          (replace (CHAT.STATE HELD) of STATE with T)
          (\CHECKCARET WINDOW)
          (SELECTQ [SETQ COMMAND (MENU (OR TEK4010CHAT.MENU (SETQ TEK4010CHAT.MENU
					     (create MENU
						     ITEMS ← TEK4010CHAT.MENUITEMS]
		   (Close (replace (CHAT.STATE RUNNING?) of STATE with (QUOTE CLOSE))
                                                             (* Ask CHAT.TYPEIN to shut things down.)
			  )
		   (New (replace (CHAT.STATE RUNNING?) of STATE with (QUOTE CLOSE))
			(WINDOWPROP WINDOW (QUOTE KEEPCHAT)
				    (QUOTE NEW)))
		   (Suspend (replace (CHAT.STATE RUNNING?) of STATE with (QUOTE CLOSE))
			    (WINDOWPROP WINDOW (QUOTE KEEPCHAT)
					T))
		   (Freeze                                   (* Leave in HELD state)
			   (RETURN))
		   (NIL)
		   (APPLY* COMMAND STATE WINDOW))
          (replace (CHAT.STATE HELD) of STATE with NIL])

(TEK4010.GRAPHICSSTATE
  [LAMBDA (CHAT.STATE STATE)                                 (* jds " 5-Sep-85 11:41")

          (* This function collects up to 4 bytes of XY position, ie, HIX, HIY, LOY, LOX and does a MOVETO or DRAWTO when the 
	  last byte is received which is always LOX. The previous values of HIX, HIY, & LOY may be used to move or draw, Only 
	  a new LOX is required to evoke the operation.)



          (* The high 2 bits of the byte are used to indicate which byte is being received, however if it is zero, then it is 
	  a control char and handled by the CTRLCHAR routine. The other bytes are determined as follows: 1 => HIY or HIX;
	  2 => LOX; 3 => LOY Notice there are 2 possibilities for the high 2 bits=1. The proper byte is determined by which 
	  byte was collected the last time. So to keep track of this a field called BYTESTATE is maintained in the STATE 
	  record to remember the previous byte)



          (* When the state goes from ALPHAMODE to GRAPHICSMODE, the first set of bytes are used to do a MOVETO, and 
	  subsequent sets of bytes are used to do DRAWTOs. The only way to do a subsequent MOVETO is reenter GRAPHICSMODE 
	  using a control character such as 29 which enters GRAPHICSMODE. This is the way that positioning text must be done)


    (LET ((HI2BITS (fetch (TEK4010.STATE HI2BITS) of STATE))
	  (LO5BITS (fetch (TEK4010.STATE LO5BITS) of STATE))
	  (BYTESTATE (fetch BYTESTATE of STATE))
	  (INSTREAM (fetch (CHAT.STATE INSTREAM) of CHAT.STATE))
	  (OUTSTREAM (fetch (CHAT.STATE DSP) of CHAT.STATE)))
         (SELECTQ HI2BITS
		  (0 (TEK4010.CTRLCHAR CHAT.STATE STATE))
		  [1 (COND
		       ((EQUAL BYTESTATE (QUOTE LOY))
			 (replace (TEK4010.STATE HIX) of STATE with LO5BITS)
			 (replace BYTESTATE of STATE with (QUOTE HIX)))
		       (T (replace (TEK4010.STATE HIY) of STATE with LO5BITS)
			  (replace BYTESTATE of STATE with (QUOTE HIY]
		  [2 (replace (TEK4010.STATE LOX) of STATE with LO5BITS)
		     (replace BYTESTATE of STATE with (QUOTE LOX))
		     (COND
		       ((fetch (TEK4010.STATE DRAWP) of STATE)
			 (TEK4010.DRAWTO (TEK4010.GLOMHI&LO (fetch (TEK4010.STATE HIX) of STATE)
							    (fetch (TEK4010.STATE LOX) of STATE))
					 (TEK4010.GLOMHI&LO (fetch (TEK4010.STATE HIY) of STATE)
							    (fetch (TEK4010.STATE LOY) of STATE))
					 1 NIL OUTSTREAM))
		       (T (TEK4010.MOVETO (TEK4010.GLOMHI&LO (fetch (TEK4010.STATE HIX) of STATE)
							     (fetch (TEK4010.STATE LOX) of STATE))
					  (TEK4010.GLOMHI&LO (fetch (TEK4010.STATE HIY) of STATE)
							     (fetch (TEK4010.STATE LOY) of STATE))
					  OUTSTREAM)
			  (replace (TEK4010.STATE DRAWP) of STATE with T]
		  (3 (replace (TEK4010.STATE LOY) of STATE with LO5BITS)
		     (replace BYTESTATE of STATE with (QUOTE LOY)))
		  (SHOULDNT])

(TEK4010.CTRLCHAR
  [LAMBDA (CHAT.STATE STATE)                                 (* AJB " 5-Sep-85 15:13")
                                                             (* This function performs various control char 
							     functions such as CR, LF, enter GRAPHICSSTATE or 
							     ALPHASTATE, ring the bell, clear the screen, etc.)
    (LET* ((INSTREAM (fetch (CHAT.STATE INSTREAM) of CHAT.STATE))
	   (OUTSTREAM (fetch (CHAT.STATE DSP) of CHAT.STATE))
	   (LO5BITS (fetch (TEK4010.STATE LO5BITS) of STATE))
	   (HI2BITS (fetch (TEK4010.STATE HI2BITS) of STATE))
	   (SPACEWIDTH (CHARWIDTH (CHARCODE SPACE)
				  OUTSTREAM))
	   (SPACEHEIGHT 22))
          (SELCHARQ LO5BITS
		    (↑D (TEK4010.NEXTSTATE STATE (FUNCTION TEK4010.ALPHASTATE)))
		    (↑G (replace (TEK4010.STATE DRAWP) of STATE with NIL)
			(replace BYTESTATE of STATE with NIL)
			(RINGBELLS 1))
		    (BS (RELMOVETO (IMINUS SPACEWIDTH)
				   0 OUTSTREAM)
			(replace (TEK4010.STATE DRAWP) of STATE with NIL)
			(replace BYTESTATE of STATE with NIL))
		    (TAB (RELMOVETO SPACEWIDTH 0 OUTSTREAM)
			 (replace (TEK4010.STATE DRAWP) of STATE with NIL)
			 (replace BYTESTATE of STATE with NIL))
		    [LF (RELMOVETO 0 (IMINUS SPACEHEIGHT)
				   OUTSTREAM)
			(replace (TEK4010.STATE DRAWP) of STATE with NIL)
			(replace BYTESTATE of STATE with NIL)
			(add (fetch (TEK4010.STATE ROW) of STATE)
			     1)
			(COND
			  ((GREATERP (fetch (TEK4010.STATE ROW) of STATE)
				     (TEK4010.SCALE 35 OUTSTREAM))
			    (replace (TEK4010.STATE ROW) of STATE with 1)
                                                             (* at bottom of screen, clear screen and pos to top -
							     no scrolling)
                                                             (* Determine whether to goto margin 1 
							     (top/middle of screen) or margin 0 
							     (top/left) of screen)
			    (COND
			      ((NEQ (fetch (TEK4010.STATE MARGIN) of STATE)
				    0)
				(replace (TEK4010.STATE MARGIN) of STATE with 0)
				(DSPLEFTMARGIN 0 OUTSTREAM)
				(MOVETO 0 (IDIFFERENCE (WINDOWPROP (WFROMDS OUTSTREAM)
								   (QUOTE HEIGHT))
						       (FONTPROP OUTSTREAM (QUOTE HEIGHT)))
					OUTSTREAM))
			      (T (replace (TEK4010.STATE MARGIN) of STATE with (TEK4010.SCALE 512 
											OUTSTREAM))
				 (DSPXPOSITION (TEK4010.SCALE 512 OUTSTREAM)
					       OUTSTREAM)
				 (DSPLEFTMARGIN (TEK4010.SCALE 512 OUTSTREAM)
						OUTSTREAM)
				 (DSPYPOSITION (WINDOWPROP (WFROMDS OUTSTREAM)
							   (QUOTE HEIGHT))
					       OUTSTREAM]
		    (↑K (TEK4010.RELMOVETO 0 SPACEHEIGHT OUTSTREAM)
			(replace (TEK4010.STATE DRAWP) of STATE with NIL)
			(replace BYTESTATE of STATE with NIL))
		    (ESC (TEK4010.ESCAPECHAR CHAT.STATE STATE))
		    (↑                                      (* 29)
			(replace (TEK4010.STATE DRAWP) of STATE with NIL)
			(replace BYTESTATE of STATE with NIL)
			(TEK4010.NEXTSTATE STATE (FUNCTION TEK4010.GRAPHICSSTATE)))
		    (CR (MOVETO (fetch (TEK4010.STATE MARGIN) of STATE)
				(DSPYPOSITION NIL OUTSTREAM)
				OUTSTREAM)
			(TEK4010.NEXTSTATE STATE (FUNCTION TEK4010.ALPHASTATE)))
		    (↑←                                      (* 31)
			(TEK4010.NEXTSTATE STATE (FUNCTION TEK4010.ALPHASTATE)))
		    NIL])

(TEK4010.ESCAPECHAR
  [LAMBDA (CHAT.STATE STATE)                                 (* jds " 5-Sep-85 11:36")
                                                             (* Handles ESCAPE sequences.)
    (LET* ((INSTREAM (fetch (CHAT.STATE INSTREAM) of CHAT.STATE))
	   (OUTSTREAM (fetch (CHAT.STATE DSP) of CHAT.STATE))
	   (CHAR (LOGAND (BIN INSTREAM)
			 127))
	   (WINDOW (WFROMDS OUTSTREAM))
	   (SSTREAM (fetch (CHAT.STATE OUTSTREAM) of CHAT.STATE))
	   (WIDTH (WINDOWPROP WINDOW (QUOTE WIDTH)))
	   (HEIGHT (WINDOWPROP WINDOW (QUOTE HEIGHT)))
	   PREVPROC PREVDS CROSSHAIRX CROSSHAIRY)
          (COND
	    ((EQ CHAR (CHARCODE FF))                         (* ESC FF clears screen and resets cursor to top, and 
							     switches to (if not already in) alphamode)
	      (DSPRESET OUTSTREAM)
	      (TEK4010.NEXTSTATE STATE (FUNCTION TEK4010.ALPHASTATE)))
	    ((EQ CHAR (CHARCODE ↑Z))

          (* Go into Graphic Input Mode. Display crosshairs while tracking mouse, until 1st keyboard character is entered.
	  Then send character plus location of crosshair back to computer)


	      (TEK4010.CROSSHAIR WINDOW)                     (* DISPLAY CROSSHAIR)
	      (RESETLST (RESETSAVE (WINDOWPROP WINDOW (QUOTE CURSORMOVEDFN)
					       (FUNCTION TEK4010.CROSSHAIR))
				   (LIST (FUNCTION WINDOWPROP)
					 WINDOW
					 (QUOTE CURSORMOVEDFN)
					 NIL))

          (* Setup TEK4010.CROSSHAIR routine to track mouse, and setup TTYPROCESS to come to this process instead of the 
	  chat.input process. RESETRESTORE will put everything back when character is struck from keyboard)


			(SETQ PREVPROC (WINDOWPROP WINDOW (QUOTE PROCESS)))
			(RESETSAVE (WINDOWPROP WINDOW (QUOTE PROCESS)
					       (THIS.PROCESS))
				   (LIST (FUNCTION WINDOWPROP)
					 WINDOW
					 (QUOTE PROCESS)
					 PREVPROC))
			(RESETSAVE [COND
				     ((TTY.PROCESSP PREVPROC)
				       (TTY.PROCESS (THIS.PROCESS]
				   (LIST (FUNCTION TTY.PROCESS)
					 PREVPROC))
			(SETQ PREVDS (TTYDISPLAYSTREAM))
			(RESETSAVE (TTYDISPLAYSTREAM OUTSTREAM)
				   (LIST (FUNCTION TTYDISPLAYSTREAM)
					 PREVDS))
			(PAGEHEIGHT 0)                       (* Prevent full page prompt hold up)
			(DSPSCROLL (QUOTE OFF)
				   OUTSTREAM)                (* Turn off scrolling which TTYDISPLAYSTREAM fn turns 
							     on)
			(SETQ CHAR (\GETKEY)))               (* Wait for keyboard input)
	      (SETQ CROSSHAIRX (WINDOWPROP WINDOW (QUOTE CROSSHAIRX)))
	      (SETQ CROSSHAIRY (WINDOWPROP WINDOW (QUOTE CROSSHAIRY)))
	      (BLTHLINE CROSSHAIRY 0 WIDTH WINDOW GRAYSHADE)
                                                             (* Erase Crosshair)
	      (BLTVLINE CROSSHAIRX 0 HEIGHT WINDOW GRAYSHADE)
	      (BOUT SSTREAM CHAR)                            (* Send keyboard char first)
	      (TEK4010.SENDCOORD SSTREAM (TEK4010.UNSCALE CROSSHAIRX OUTSTREAM))
                                                             (* send X coord)
	      (TEK4010.SENDCOORD SSTREAM (TEK4010.UNSCALE CROSSHAIRY OUTSTREAM)
				 T)                          (* Send Y coord)
	      (BOUT SSTREAM (CHARCODE CR))
	      (WINDOWPROP WINDOW (QUOTE CROSSHAIRX)
			  NIL)
	      (WINDOWPROP WINDOW (QUOTE CROSSHAIRY)
			  NIL])

(TEK4010.UNSCALE
  [LAMBDA (COORD STREAM)                                     (* jds " 5-Sep-85 11:34")

          (* Given an X or Y coordinate in STREAM's units, scale it to TEK4010 units The TEK4010.UNSCALE STREAMPROP has to be 
	  set up by the output-stream opener, usually TEK4010CHAT.INIT)


    (FIXR (FQUOTIENT COORD (OR (STREAMPROP STREAM (QUOTE TEK4010.UNSCALE))
			       1.0])

(TEK4010.GLOMHI&LO
  [LAMBDA (HIBYTE LOBYTE)                                    (* hdj "10-Sep-84 14:32")
    (IPLUS LOBYTE (LLSH HIBYTE 5])

(TEK4010.MOVETO
  [LAMBDA (X Y STREAM)                                       (* jds " 5-Sep-85 11:21")
                                                             (* Given an X,Y coordinate pair in TEK4010 units, move 
							     the output stream's location to the equivalent stream 
							     point.)
    (MOVETO (TEK4010.SCALE X STREAM)
	    (TEK4010.SCALE Y STREAM)
	    STREAM])

(TEK4010.DRAWTO
  [LAMBDA (X Y WIDTH OPERATION STREAM)                       (* jds " 5-Sep-85 11:20")
                                                             (* DRAWTO on the TEK4010 emulator display stream 
							     STREAM. Scale the coordinates by the stream's 
							     TEK4010.SCALE, if any.)
    (DRAWTO (TEK4010.SCALE X STREAM)
	    (TEK4010.SCALE Y STREAM)
	    WIDTH OPERATION STREAM])
)

(RPAQ? TEK4010CHAT.MENU NIL)

(RPAQQ TEK4010CHAT.MENUITEMS ((Close (QUOTE Close)
				     "Closes the connection and returns")
			      (Suspend (QUOTE Suspend)
				       "Closes the connection but leaves window up")
			      (New (QUOTE New)
				   "Closes this connection and prompts for a new host")
			      (Freeze (QUOTE Freeze)
				      "Holds typeout in this window until you bug it again")
			      ("Input" (FUNCTION CHAT.TAKE.INPUT)
				       "Allows input from a file")
			      ("Dribble" (FUNCTION CHAT.TYPESCRIPT)
					 "Starts a typescript of window typeout")
			      (Clear (FUNCTION TEK4010.CLEAR)
				     "Clears window and resets to ALPHAMODE column 1, row 1")))

(ADDTOVAR CHAT.DRIVERTYPES (TEK4010 TEK4010CHAT.HANDLECHAR TEK4010CHAT.INIT))
(PUTPROPS TEK4010CHAT COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (2051 25809 (TEK4010.ALPHASTATE 2061 . 2801) (TEK4010.CLEAR 2803 . 3839) (
TEK4010.CLOSEFN 3841 . 4662) (TEK4010.CROSSHAIR 4664 . 6239) (TEK4010CHAT.INIT 6241 . 8512) (
TEK4010.NEXTSTATE 8514 . 9059) (TEK4010.RELMOVETO 9061 . 9451) (TEK4010.SCALE 9453 . 9867) (
TEK4010.SENDCOORD 9869 . 10524) (TEK4010CHAT.BUTTONFN 10526 . 10767) (TEK4010.RESHAPEFN 10769 . 11919)
 (TEK4010CHAT.HANDLECHAR 11921 . 12994) (TEK4010CHAT.MENUFN 12996 . 14458) (TEK4010.GRAPHICSSTATE 
14460 . 17539) (TEK4010.CTRLCHAR 17541 . 21091) (TEK4010.ESCAPECHAR 21093 . 24398) (TEK4010.UNSCALE 
24400 . 24805) (TEK4010.GLOMHI&LO 24807 . 24955) (TEK4010.MOVETO 24957 . 25372) (TEK4010.DRAWTO 25374
 . 25807)))))
STOP