;;; -*- Mode:Lisp; Readtable:ZL; Package:USER; Base:8; Patch-File:T -*-
;;; Patch file for Kermit version 35.4
;;; Reason:
;;;  Kermit had these nice status messages, and they weren't showing up.
;;; Written 19-Jul-88 00:42:11 by keith (Keith Corbett) at site Gigamos Cambridge
;;; while running on Breaking Glass from band 3
;;; with System 125.6, ZWEI 125.2, ZMail 73.0, Local-File 75.0, File-Server 24.0, Unix-Interface 13.0, Tape 24.0, Lambda-Diag 17.0, Experimental Kermit 35.1, microcode 1761, SDU Boot Tape 3.14, SDU ROM 103.



; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:42:23
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "


(defconst status-pane-label
	  `(:string "Kermit Status"		;this is just the top level
						;waiting for a command label!
		     ,@(if (boundp 'fonts:hl12bi) (list :font fonts:hl12bi))
		    :centered))


;;;; scrolling mixin
;;; this should be part of the general system, but alot of people flame
;;; at the idea, so...

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:42:27
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "


(defparameter label-font
	      (loop for font-spec in '("CPTFONT" "TR12")
		    as font = (intern-soft font-spec "FONTS")
		    when font (return font)))

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:42:29
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "


(defflavor kermit-status-pane ()
	   (tv:list-mouse-buttons-mixin
	    tv:top-label-mixin
  	    tv:window)
  (:documentation
    :special-purpose
    "kermit status pane")
  (:default-init-plist
    :borders 3					; 3 on frame + 3 on each pane
    :font-map (ncons label-font)
    :vsp 3					; 5 pixels between lines
    :more-p nil
    :deexposed-typeout-action :permit
    :save-bits :delayed
    :reverse-video-p t
    :label status-pane-label
    :blinker-p nil				; no blinker
    ))


))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:42:52
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "


(defmacro within-status (status-pane-format-string &rest format-args?)
  `(let ((maxlen (- (send status-pane :size-in-characters) 2))
	 (str (format nil ,status-pane-format-string ,@format-args?)))
     (if (<= (string-length str) maxlen) str
       (string-append (substring str 0 (- maxlen 2)) " "))))

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:42:53
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "


(defmacro with-status ((status-pane-format-string . format-args?) &body body)
  `(let ((*--old-label--*
	   (send status-pane :label)))
     (unwind-protect
	 (progn
	   (send status-pane
		 :set-label			;which may be multi lines.
		 (list
		   :string (format nil
				   ,status-pane-format-string
				   . ,format-args?)
		   :font label-font))
	   . ,body)
       (send status-pane ':clear-screen)
       (send status-pane :set-label *--old-label--*))))


))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:43:00
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "

(defun kermit-interactive-help ()
  "Get help interactively; just click on the command to document.
The documentation is then displayed in the interaction pane."
  (with-status ("~&Help with Commands.~A~A"
		(format nil "~%Please mouse any command")
		(format nil "~%to see its documentation.~%"))
    (let ((blip? (send terminal-io :any-tyi)))
      (cond ((and (not (atom blip?))
		  (eq (car blip?) :menu))
	     (let* ((menu-item-name (car (cadr blip?)))
		    (menu-item-function
		      (get (cadr blip?) :funcall))
		    (documentation?
		      (or (documentation menu-item-function)	;long doc?
			  (get (cadr blip?) :documentation))	;short doc?
		      ))
	       (cond (documentation?
		      (format interaction-pane "~&~A:~%  ~A~%"
			      menu-item-name
			      documentation?))
		     (t (format interaction-pane "~&Sorry, ~A is not documented.~%"
				menu-item-name)))))
	    (t (beep-at-user))))))

;;;Server interaction

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:43:02
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "


(defun receive-files ()
  (with-status ("Receive:~A ~A ~A"
		kermit-serial-stream
		(format nil "~%Transfer started: ~\time\"
			(setq *kermit-beginning-time* (time:get-universal-time)))
		(let ((baud-rate?
			(lexpr-send
			  kermit-serial-stream
			  :send-if-handles
			  (select-processor
			    ((:lambda :explorer) (list :baud-rate))
			    (:cadr (list :get :baud))))))
		  (if baud-rate?
		      (format nil "~%Baud Rate: ~D." baud-rate?)
		    "")))
    (send kstate
	  ':simple-receive
	  kermit-serial-stream)))


))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:43:04
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "


(defun be-a-server ()
  (with-status ("Login Server ~%Stream: ~A ~A"
		kermit-serial-stream
		(let ((current-baud-rate? (current-baud-rate)))
		  (if current-baud-rate?
		      (format nil			       
			      "~%Baud Rate: ~D.~%"
			      current-baud-rate?)
		    "")))
    (let ((pst (make-instance 's-terminal:ps-terminal
			      :serial kermit-serial-stream
			      :peek-chars nil
			      :read-ahead-chars nil
			      :ttysync t)))
      (s-terminal:ps-kermit-login pst))))


;;;; Close connection.
;;; This shuts off the connection in the same way as the user would:
;;; by "typing in" the escape sequence (<network>c).

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:43:08
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "


(defun close-connection ()
  (with-status ("Turning off Terminal Connection.")
    (cond (kermit-connected-flag
	   (send terminal-pane :force-kbd-input
		 #\network)
	   (send terminal-pane :force-kbd-input
		 #\C)
	   (setf kermit-connected-flag nil))
	  (t (beep-at-user "You are not connected")))))

;;;; Make connection
;;; This is the call to the code in the TERMinal file for terminal emulation.
;;; Note that the terminal emulator will intercept and execute command menu mouse
;;; blips.

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:43:11
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "


(defun make-connection ()
  (cond (kermit-connected-flag
	 (beep-at-user "~&You are already connected: do <network>c to disconnect"))
	(kermit-serial-stream
	 (with-status ("Connection started: ~\time\~%~A~%~@[~A~]~%~A"
		       (setq *kermit-beginning-time* (time:get-universal-time))
		       (within-status "~A" kermit-serial-stream)
		       (let ((baud-rate?
			       (lexpr-send
				 kermit-serial-stream
				 :send-if-handles
				 (select-processor
				   ((:lambda :explorer) (list :baud-rate))
				   (:cadr (list :get :baud))))))
			 (if baud-rate? (format nil "Baud Rate: ~D." baud-rate?)))
		       (format nil "Escape Character: ~:@C" #\network))
	   (unwind-protect
	       (progn (setf kermit-connected-flag t)
		      (tv:with-selection-substitute (terminal-pane kermit-frame)
			(send kterm-state
			      ':make-connection
			      kermit-serial-stream
			      terminal-pane)))
	     (setf kermit-connected-flag nil))))
	(t (ferror nil "kermit-serial-stream is NIL."))))


;;;; Bye

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:47:35
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "

(defconst all-kermit-command-pane-items
      '(("Connect" :funcall make-connection
	 :documentation "Establish a virtual terminal or Kermit connection with remote host.")

	("Disconnect" :funcall close-connection
	   :documentation "Interrupt the connection made by Connect.")

	("Send files" :funcall send-files
	   :documentation "Send files to a remote Kermit that's in receive mode.")

	("Receive files" :funcall receive-files
	   :documentation "Receive files from a remote Kermit that's in receive mode.")

	("Server//send" :funcall send-files
	   :documentation "Send files to a remote Kermit that's in Server mode.")

	("Server//receive" :funcall receive-files-from-server
	   :documentation "Receive files from a remote Kermit that's in Server mode.")

	("Server//finish" :funcall finish-server
	   :documentation "Finish with Kermit that's in Server mode, not logging out.")

	("Server//bye" :funcall bye-server
	   :documentation "Finish and be logged out by remote Kermit that's in Server mode.")

	("Serial Port" :funcall set-baud-rate
	   :documentation "Set parameters for serial port.")

;	("Restart Program" :funcall restart-program
;	   :documentation "Abandon everything  and start Kermit from scratch.")

	("Review Parameters" :funcall review-parameters
	   :documentation "Review, and maybe modify, global Kermit parameters.")


;	("Refresh Windows" :funcall refresh-windows
;	   :documentation "Refresh all the windows in this display.")

;	("List directory" :funcall list-user-directory
;	   :documentation "List the default directory in the interaction pane.")

	("Help" :funcall kermit-interactive-help
	 :documentation "Interactive Help for Kermit.")

	("Remote Login Server"
	 :funcall be-a-server
	 :documentation "Put Kermit in mode to process remote logins and file transfers.")

	("Remote kermit Server"
	 :funcall be-a-kermit-server-only
	 :documentation "Put Kermit directly into Kermit SERVER mode (wait for Kermit commands).")

	))

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:47:57
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "

(defsubst beep-at-user (&optional message-format-string? &rest format-args?)
  (beep)
  (cond
    (message-format-string?
     (let ((old-mode (send status-pane ':reverse-video-p)))
       (unwind-protect
	   (progn
	     (send status-pane
		   ':set-reverse-video-p
		   (not old-mode))
	     (with-status ((lexpr-funcall #'format nil message-format-string? format-args?))
	       (process-sleep (* 60. 2)
			      "Beep!")))
	 (send status-pane ':set-reverse-video-p old-mode))))))

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:48:35
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "

(defun kermit-interactive-help ()
  "Get help interactively; just click on the command to document.
The documentation is then displayed in the interaction pane."
  (with-status ("~&Help with Commands.~A~A"
		(format nil "~%Please mouse any command")
		(format nil "~%to see its documentation.~%"))
    (let ((blip? (send terminal-io :any-tyi)))
      (cond ((and (not (atom blip?))
		  (eq (car blip?) :menu))
	     (let* ((menu-item-name (car (cadr blip?)))
		    (menu-item-function
		      (get (cadr blip?) :funcall))
		    (documentation?
		      (or (documentation menu-item-function)	;long doc?
			  (get (cadr blip?) :documentation))	;short doc?
		      ))
	       (cond (documentation?
		      (format interaction-pane "~&~A:~%  ~A~%"
			      menu-item-name
			      documentation?))
		     (t (format interaction-pane "~&Sorry, ~A is not documented.~%"
				menu-item-name)))))
	    (t (beep-at-user))))))

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:48:50
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "

(defun receive-files-from-server ()
  (let* ((default-pathname (send kstate ':kermit-default-pathname))
	 (filename				;don't merge with anything
	   (prompt-and-read
	     ':string-trim
	     "~%Receive file:"))
	 (as-filename
	   (fs:merge-pathname-defaults
	     (prompt-and-read
	       ':string-trim
	       "~%Merging with (default: ~A):"
	       (fs:merge-pathname-defaults filename default-pathname))
	     default-pathname)))
    (with-status ("Receive:~A ~A ~A"
		  kermit-serial-stream
		  (format nil "~%Transfer started: ~\time\"
			  (setq *kermit-beginning-time* (time:get-universal-time)))
		  (let ((baud-rate?
			  (lexpr-send
			    kermit-serial-stream
			    :send-if-handles
			    (select-processor
			      ((:lambda :explorer) (list :baud-rate))
			      (:cadr (list :get :baud))))))
		    (if baud-rate?
			(format nil "~%Baud Rate: ~D." baud-rate?)
		      "")))
      (send kstate
	    ':server-receive
	    kermit-serial-stream
	    filename
	    as-filename))))

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:50:03
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "

(defun be-a-kermit-server-only ()
  (with-status ("Remote kermit Server~A~A~A"
		(format nil "~%Stream: ~A" kermit-serial-stream)
		(let ((current-baud-rate? (current-baud-rate)))
		  (if current-baud-rate?
		      (format nil			       
			      "~%Baud Rate: ~D.~%"
			      current-baud-rate?)
		    ""))
		(format nil "~%Use Control-abort key to quit locally."))
    (send kstate
	  ':remote-server
	  kermit-serial-stream)))

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:50:37
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "

(defun bye-server ()
  (with-status ("Bye Server")
    (send kstate
	  ':bye-server
	  kermit-serial-stream)))

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:50:42
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "

(defun finish-server ()
  (with-status ("Finish Server")
    (send kstate
	  ':finish-server
	  kermit-serial-stream)))

))

; From modified file DJ: L.NETWORK.KERMIT; WINDOW.LISP#75 at 19-Jul-88 00:50:51
#8R KERMIT#: 
(COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "KERMIT")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; KERMIT; WINDOW  "

(defun set-baud-rate ()
  (let ((base 10.) (*nopoint nil))		;just for printing
    (cond
      (kermit-serial-stream
       (let ((old-baud (current-baud-rate)))
	 (with-status ("Change Baud~%Old Baud Rate: ~S" old-baud)
	   (let ((new-baud
		   (tv:menu-choose
		     all-baud-choices-items-alist
		     "Choose the Baud Rate:"
		     '(:mouse)
		     nil
		     terminal-pane)))
	     (cond ((and new-baud (zerop new-baud))
		    (extended-set-baud-rate))
		   ((and new-baud		; nil if they move out of the window
			 (not (= old-baud new-baud)))	;really have to change it
		    (set-current-baud-rate new-baud)
		    (format t "~&New Baud Rate: ~S~%" new-baud)))))))
      (t (ferror nil "kermit-serial-stream is NIL.")))))

))
