[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Jeff Morrill: How the terminal emulator works]



I'll add to what's below that the host you want must be in the namespace. And
(adding to barmar's comment) poking around in telnet.lisp, though confusing
at first (:-) can be quite rewarding.

<j>

------- Forwarded Message

Received: from BBN.COM by DINO.BBN.COM id aa08439; 9 Jun 89 13:06 EDT
Received: from v1.bbn.com by BBN.COM id aa06743; 9 Jun 89 13:04 EDT
Return-path: <@adams.bbn.com:jmorrill@[128.89.0.87]>
Received: from adams.bbn.com by v1.bbn.com via TCP; Fri Jun  9 13:02 EDT
Date: Fri, 9 Jun 89 13:03 EDT
From: Jeff Morrill <jmorrill@[128.89.0.87]>
Subject: How the terminal emulator works
To: kanderson@bbn.com, jmorrill@bbn.com, delatizky@bbn.com
Message-ID: <19890609170354.1.JMORRILL@adams.bbn.com>


;;; The heart of the Symbolics' terminal emulator.

;;; This subject seems to recur, so pass this along to interested parties.

;;; Suppose you want to talk to host "GBUSH":
(let ((host (net:parse-host "GBUSH"))

      You want to see things happen on your-window:
      (telnet:*terminal-stream* your-window)
      (telnet:*viewport-stream* your-window)
      
      typein					; where you will send chars
      typeout					; where you will receive chars
      network)

  Now connect to the host:
  (multiple-value-bind (network-stream typein-flavors typeout-flavors string)
      (net:invoke-service-on-host 
	:login host
	:terminal-simulator (telnet:host-default-terminal-simulator host))

;;; The flavors are to be instantiated and connected end-to-end, forming two rows of 
;;; filters.  One end of the filters is your-window, the other end is the network stream. 
;;; The filters take care of converting binary to ASCII, and they may try to handle
;;; graphics commands (like clear-screen) by sending messages to the current value
;;; of telnet:*terminal-stream* or telnet:*viewport-stream*.

    ;; To connect the filters:
    (let ((network network-stream) (screen your-window) filter)
      (dolist (flavor typeout-flavors)
	(setq filter (make-instance flavor))
	(send filter :set-input-stream network)
	(if (eq network network-stream)
	    nil
	    (send network :set-output-stream filter))
	(setq network filter))
      (setq typeout-filter network)
      (unless (eq network network-stream) (send network :set-output-stream screen))
      ;; Now, lets connect the typein filters.
      (dolist (flavor typein-flavors)
	(setq filter (make-instance flavor))
	(send filter :set-input-stream screen)
	(if (eq screen self)
	    (setq typein-filter filter)
	    (send screen :set-output-stream filter))
	(setq screen filter))
      (unless (eq screen self) (send screen :set-output-stream network-stream))
      (do ((f typeout-filter (send f :input-stream)))
	  ((or (not f) (eq f network-stream))) ; setup the typeout filters
	(send f :setup))
      (do ((f typein-filter (send f :output-stream)))
	  ((or (not f) (eq f network-stream))) ; setup the typein filters
	(send f :setup)))
	
;;;To import a character from the host, (send your-window :tyo
;;;                                           (send typeout-filter :tyi-no-hang))
;;;To export a character to the host,   (progn (send typein-filter :tyo char)
;;;                                            (send typein-filter :force-output))
;;;
;;;The NVT window has one process for each of these operations, waiting with
;;;  :listen and passing characters along as they arrive.

;;;If you are using TCP, that's enough.  If you are using DNA, things can get
;;;  much more hairy.

   ... ))

jeff morrill

------- End of Forwarded Message