
;; -*- Mode: Lisp; Package: System-Internals -*-

;; Lisp Machine Editor Stream

;; The rubout handler implemented here is a crock since it duplicates
;; the functions of ZWEI.  However, this editor is implemented in terms of stream
;; operations, and thus can be used from consoles other than the
;; local Lisp Machine console.  This file makes use of the definitions
;; in LMMAX;UTILS. 

;; There are a couple ideas here:
;; The editor stream itself is separated from the underlying console
;; stream.  This is nice since the console stream need know nothing about
;; the rubout handler, and thus rubout handlers can be changed easily
;; without having to duplicate the code for the entire console stream.
;; In addition, it makes it easy to have one editor stream work for
;; different console streams.

;; Another thought would be to split the bare console stream into
;; an input stream from a keyboard and an output stream to a window
;; on a given monitor.  The editor stream would then bind these two
;; streams together into a single interactive i/o stream.  I can't see
;; much use for this, unless somebody wanted a keyboard stream without
;; having a window, or there were multiple keyboard types in use.

;; Terminology:

;; CONSOLE-STREAM -- a bi-directional stream to some console.  This stream
;;		     knows nothing about rubout handling.
;; EDITOR-STREAM -- a bi-directional stream connected to some console stream.
;;		    It handles both the :RUBOUT-HANDLER and :UNTYI stream operations.
;; TV-STREAM -- a bi-directional stream to the Lisp Machine console.  Special
;;		case of a console stream.
;; SUPDUP-STREAM -- a bi-directional stream to a console connected via the
;;		    Chaos net.  Special case of a console stream.

;; MAKE-TV-STREAM takes a piece of paper, and returns a
;; stream which talks to the TV terminal of the Lisp Machine.  For input,
;; it uses the keyboard.  For output, it types on the piece of paper. 

(DECLARE (SPECIAL TV-STREAM-PC-PPR))

(DEFUN MAKE-TV-STREAM (TV-STREAM-PC-PPR)
  (CLOSURE '(TV-STREAM-PC-PPR) #'TV-STREAM))

(DEFSELECT (TV-STREAM TV-STREAM-DEFAULT-HANDLER)
  
  ;; Input operations
  (:TYI 	() (KBD-TYI))
  (:TYI-NO-HANG () (KBD-TYI-NO-HANG))
  (:LISTEN 	() (KBD-CHAR-AVAILABLE))
  (:CLEAR-INPUT ()
    (DO () ((NOT (KBD-CHAR-AVAILABLE)))	      ;Clear hardware/firmware buffers
      (KBD-TYI)))
  
  ;; Output operations
  ;; TV-TYO doesn't print "control" characters.
  (:TYO (CHAR)
    (TV-TYO TV-STREAM-PC-PPR CHAR))
  (:STRING-OUT (STRING &OPTIONAL (BEGIN 0) END)
    (TV-STRING-OUT TV-STREAM-PC-PPR STRING BEGIN END))
  (:LINE-OUT (STRING &OPTIONAL (BEGIN 0) END)
    (TV-STRING-OUT TV-STREAM-PC-PPR STRING BEGIN END)
    (TV-CRLF TV-STREAM-PC-PPR))
  ;; If at the beginning of a line, clear it.  Otherwise, go
  ;; to the beginning of the next line and clear it.
  (:FRESH-LINE ()
    (COND ((= (PC-PPR-CURRENT-X TV-STREAM-PC-PPR)
	      (PC-PPR-LEFT-MARGIN TV-STREAM-PC-PPR))
	   (TV-CLEAR-EOL TV-STREAM-PC-PPR))
	  (T (TV-CRLF TV-STREAM-PC-PPR))))
  (:TRIGGER-MORE ()
    (OR (ZEROP (PC-PPR-EXCEPTIONS TV-STREAM-PC-PPR))
	(TV-EXCEPTION TV-STREAM-PC-PPR)))
  (:BEEP (&OPTIONAL (WAVELENGTH TV-BEEP-WAVELENGTH) (DURATION TV-BEEP-DURATION))
	 (%BEEP WAVELENGTH DURATION))
  
  ;; If no unit is specified, then the "preferred" unit is used.  This is the
  ;; unit that :SET-CURSORPOS defaults to and that :COMPUTE-MOTION uses.
  ;; The :CHARACTER unit of these operations is useless with variable width fonts.
  (:READ-CURSORPOS (&OPTIONAL (UNIT ':PIXEL))
    (MULTIPLE-VALUE-BIND (X Y)
	(TV-READ-CURSORPOS TV-STREAM-PC-PPR)
      (SELECTQ UNIT
	(:PIXEL)
	(:CHARACTER (SETQ X (// X (PC-PPR-CHAR-WIDTH TV-STREAM-PC-PPR)))
		    (SETQ Y (// Y (PC-PPR-LINE-HEIGHT TV-STREAM-PC-PPR))))
	(:OTHERWISE (FERROR NIL "~S is not a known unit." UNIT)))
      (MVRETURN X Y)))
  (:SET-CURSORPOS (X Y &OPTIONAL (UNIT ':PIXEL))
    ;; For compatibility
    (IF (FIXP UNIT) (PSETQ UNIT X X Y Y UNIT))
    (SELECTQ UNIT
      (:PIXEL)
      (:CHARACTER (SETQ X (* X (PC-PPR-CHAR-WIDTH TV-STREAM-PC-PPR)))
		  (SETQ Y (* Y (PC-PPR-LINE-HEIGHT TV-STREAM-PC-PPR))))
      (:OTHERWISE (FERROR NIL "~S is not a known unit." UNIT)))
    (TV-SET-CURSORPOS TV-STREAM-PC-PPR X Y))
  (:SET-CURSORPOS-RELATIVE (X Y &OPTIONAL (UNIT ':PIXEL))
    (SELECTQ UNIT
