;;; -*- Mode:LISP; Package:TAPE; Readtable:CL; Base:10 -*- ;; ;; Copyright LISP Machine, Inc. 1986 ;; See filename "Copyright" for ;; licensing and release information. ;;; ;;; User level lisp code (Primary user interface layer.) ;;; ;;; -dg 10/4/85 ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; device and format selection and defaulting ;;; ;;; (defvar *selected-device* nil "The currently selected tape device.") (defvar *selected-format* nil "The currently selected tape format.") (defvar *available-devices* nil "The list of available tape device flavors.") (defvar *default-device* '(tapemaster-device) "The default tape device to choose at warm boot time.") (defvar *default-format* '(lmfl-format) "The default tape format to choose at warm boot time.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Device parsing ;;; (defun parse-device-string (string) "Should be only used internally by PARSE-DEVICE." (declare (values host device-flavor unit)) (check-arg string (and (stringp string) (string-search-char #\: string)) "a valid tape-device-spec") (let* ((first-colon (string-search-char #\: string)) (second-colon (string-search-char #\: string (add1 first-colon))) (host (when second-colon (si:parse-host (nsubstring string 0 first-colon)))) (device-string (nsubstring string (if second-colon (add1 first-colon) 0) (or second-colon first-colon))) device-flavor unit) (do* ((l *tape-device-alist* (cdr l)) (spec (car l) (car l))) ((null spec) (ferror nil "Invalid device specifier: ~S" device-string)) (when (string-equal (first spec) device-string :end2 (length (first spec))) (setq device-flavor (cadr spec) unit (read-from-string device-string nil nil :start (length (first spec)))) (return nil))) (values host device-flavor unit))) (defun parse-device (device-spec &rest init-options) "Given a DEVICE-SPEC (i.e. \"TR0:\"), a flavor-symbol or a device object, returns a device object initialized according to INIT-OPTIONS." (declare (values device-object)) (check-type device-spec (or string (and symbol (not null)) basic-tape-device) "a valid tape device specifier") (let ((obj (typecase device-spec (basic-tape-device device-spec) (symbol (if (memq device-spec *available-devices*) (make-instance device-spec) (ferror nil "Invalid device flavor specified: ~A" (list device-spec)))) (string (multiple-value-bind (host flavor unit) (parse-device-string device-spec) (if (null host) (let ((ob (make-instance flavor))) (send ob :set-options :unit unit) ob) (ferror nil "remote tape hosts not yet supported."))))))) (lexpr-send obj :initialize init-options) obj)) (defun parse-format (format-spec &rest init-options) "Takes a format name, flavor-symbol, or format object and returns a format object initialized according to INIT-OPTIONS." (declare (values format-object)) (check-type format-spec (or string symbol basic-tape-format) "a valid tape format specifier") (let ((obj (typecase format-spec (basic-tape-format format-spec) (string (let ((thing (ass #'string-equal format-spec *tape-format-alist*))) (if thing (make-instance (cdr thing)) (ferror 'unsupported "Unsupported tape format: ~S" format-spec)))) (symbol (let ((thing (rass #'string-equal format-spec *tape-format-alist*))) (if thing (make-instance (cdr thing)) (ferror nil "Unsupported tape format: ~S" format-spec))))))) (lexpr-send obj :initialize init-options) obj)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; general control ;;; ;;; (defun select-device (&optional device-spec &rest init-options) "Selects a device to be *selected-device*. Device spec must be a device flavor symbol (one of *available-devices*), or NIL in which case a menu of available devices will be popped up. INIT-OPTIONS case be used to setup the initial options of the device." (let ((thing (or device-spec (progn (tv:mouse-warp (floor (send tv:default-screen :width) 2) (floor (send tv:default-screen :height) 2)) (tv:menu-choose *available-devices* '(:string "Tape Devices Available" :font fonts:tr12b) '(:mouse) (cond ((memq (car *default-device*) *available-devices*) (car *available-devices*)))))))) (when thing (typecase thing ((or string symbol) (setq *selected-device* (lexpr-funcall 'parse-device thing init-options))) (basic-tape-device (setq *selected-device* thing))) (unless (and device-spec (not init-options)) (lexpr-send *selected-device* :set-options init-options)) *selected-device*))) (defun set-device-options (&optional options &key (device-spec *selected-device*)) "Set the options of a particular device. Options should be a list of the form ((: