;;; -*- Mode: LISP; Package: TV; Base: 8 -*- ;;; ** (c) Copyright 1981 Massachusetts Institute of Technology ** ;;; Hairier who-line system (DEFFLAVOR WHO-LINE-SCREEN () (SCREEN)) (DEFMETHOD (WHO-LINE-SCREEN :USER-VISIBLE) () NIL) (DEFFLAVOR WHO-LINE-MIXIN ((WHO-LINE-ITEM-STATE NIL)) () ;WHO-LINE-ITEM-STATE is NIL if the contents of the window ;is unknown and needs to be redrawn. If non-NIL it ;represents the current contents, to avoid extra redisplay. (:INCLUDED-FLAVORS MINIMUM-WINDOW) (:DEFAULT-INIT-PLIST :MORE-P NIL :BLINKER-P NIL) (:REQUIRED-METHODS :UPDATE) (:SELECT-METHOD-ORDER :UPDATE) (:INIT-KEYWORDS :FLAVOR) :INITABLE-INSTANCE-VARIABLES :SETTABLE-INSTANCE-VARIABLES :GETTABLE-INSTANCE-VARIABLES) (DEFWRAPPER (WHO-LINE-MIXIN :UPDATE) (IGNORE . BODY) `(WITHOUT-INTERRUPTS (AND (SHEET-CAN-GET-LOCK SELF) (NOT (SHEET-OUTPUT-HELD-P SELF)) (PROGN . ,BODY)))) (DEFMETHOD (WHO-LINE-MIXIN :AFTER :REFRESH) (&OPTIONAL TYPE) (COND ((NOT (AND RESTORED-BITS-P (NEQ TYPE ':SIZE-CHANGED))) (FUNCALL-SELF ':CLOBBERED) (FUNCALL-SELF ':UPDATE)))) ;;; Should this actually do the updates here?? (DEFMETHOD (WHO-LINE-MIXIN :CLOBBERED) () (SETQ WHO-LINE-ITEM-STATE NIL)) (DEFFLAVOR WHO-LINE-SHEET ((WHO-LINE-UPDATE-FUNCTION NIL) (WHO-LINE-EXTRA-STATE NIL)) (WHO-LINE-MIXIN MINIMUM-WINDOW) :INITABLE-INSTANCE-VARIABLES :SETTABLE-INSTANCE-VARIABLES :GETTABLE-INSTANCE-VARIABLES) (DEFMETHOD (WHO-LINE-SHEET :BEFORE :INIT) (PLIST) (PUTPROP PLIST (GET PLIST ':WHO-LINE-UPDATE-FUNCTION) ':NAME)) (DEFMETHOD (WHO-LINE-SHEET :UPDATE) () (AND WHO-LINE-UPDATE-FUNCTION (FUNCALL WHO-LINE-UPDATE-FUNCTION SELF))) (DEFUN WHO-LINE-SETUP () (COND ((NULL WHO-LINE-SCREEN) (LET ((SHEET-AREA WHO-LINE-AREA)) (SETQ WHO-LINE-SCREEN (DEFINE-SCREEN 'WHO-LINE-SCREEN "Who Line Screen" ':DEFAULT-FONT FONTS:CPTFONT ':BUFFER (LSH 77 18.) ':CONTROL-ADDRESS 377760 ':PROPERTY-LIST '(:VIDEO :BLACK-AND-WHITE :CONTROLLER :SIMPLE :WHO-LINE T) ':WIDTH MAIN-SCREEN-WIDTH ':CHARACTER-HEIGHT 2 ':VSP 0 ':Y NIL ;Force this to be calculated ':BOTTOM MAIN-SCREEN-HEIGHT))) ;; 18 characters of the date and time (SETQ NWATCH-WHO-LINE-SHEET (WHO-LINE-FIELD ':FLAVOR 'WHO-LINE-SHEET ':WHO-LINE-UPDATE-FUNCTION 'NWATCH-WHO-FUNCTION ':HEIGHT (SHEET-LINE-HEIGHT WHO-LINE-SCREEN) ':LEFT 0 ':RIGHT 144. ':BOTTOM (SHEET-HEIGHT WHO-LINE-SCREEN))) ;; 13 characters of user id or process (WHO-LINE-FIELD ':FLAVOR 'WHO-LINE-SHEET ':WHO-LINE-UPDATE-FUNCTION 'WHO-LINE-USER-OR-PROCESS ':HEIGHT (SHEET-LINE-HEIGHT WHO-LINE-SCREEN) ':LEFT 144. ':RIGHT 248. ':BOTTOM (SHEET-HEIGHT WHO-LINE-SCREEN)) ;; 18 characters of package (WHO-LINE-FIELD ':FLAVOR 'WHO-LINE-SHEET ':WHO-LINE-UPDATE-FUNCTION 'WHO-LINE-PACKAGE ':HEIGHT (SHEET-LINE-HEIGHT WHO-LINE-SCREEN) ':LEFT 248. ':RIGHT 392. ':BOTTOM (SHEET-HEIGHT WHO-LINE-SCREEN)) ;; 11 characters of process state (SETQ WHO-LINE-RUN-STATE-SHEET (WHO-LINE-FIELD ':FLAVOR 'WHO-LINE-SHEET ':WHO-LINE-UPDATE-FUNCTION 'WHO-LINE-RUN-STATE ':LEFT 392. ':RIGHT 480. ':HEIGHT (SHEET-LINE-HEIGHT WHO-LINE-SCREEN) ':BOTTOM (SHEET-HEIGHT WHO-LINE-SCREEN))) ;; The remaining 36 characters go to the file/idle/boot state (SETQ WHO-LINE-FILE-STATE-SHEET (WHO-LINE-FIELD ':FLAVOR 'WHO-LINE-FILE-SHEET ':LEFT 480. ':RIGHT 768. ':HEIGHT (SHEET-LINE-HEIGHT WHO-LINE-SCREEN) ':BOTTOM (SHEET-HEIGHT WHO-LINE-SCREEN))) ;; Above those windows is a full line of mouse button documentation (SETQ WHO-LINE-DOCUMENTATION-WINDOW (WHO-LINE-FIELD ':FLAVOR 'WHO-LINE-SHEET ':WHO-LINE-UPDATE-FUNCTION 'WHO-LINE-DOCUMENTATION-FUNCTION ':HEIGHT (SHEET-LINE-HEIGHT WHO-LINE-SCREEN) ':TOP 0 ':REVERSE-VIDEO-P T))))) (DEFUN WHO-LINE-UPDATE (&OPTIONAL RUN-STATE-ONLY-P &AUX RL) (OR INHIBIT-WHO-LINE (NULL WHO-LINE-SCREEN) (WITHOUT-INTERRUPTS (SETQ RL (%XBUS-READ WHO-LINE-RUN-LIGHT-LOC)) ;Don't clobber run light (IF RUN-STATE-ONLY-P ;; The reason this is here is that this function conspires to do some ;; minor nice things for you. This note is here to remind HIC not to ;; clean up this code. --HIC (AND WHO-LINE-RUN-STATE-SHEET (FUNCALL WHO-LINE-RUN-STATE-SHEET ':UPDATE)) (DOLIST (I (SHEET-EXPOSED-INFERIORS WHO-LINE-SCREEN)) (AND (TYPEP I 'WHO-LINE-MIXIN) (FUNCALL I ':UPDATE)))) (%XBUS-WRITE WHO-LINE-RUN-LIGHT-LOC RL))) T) (DEFUN WHO-LINE-CLOBBERED () (AND WHO-LINE-SCREEN (DOLIST (I (SHEET-INFERIORS WHO-LINE-SCREEN)) (AND (TYPEP I 'WHO-LINE-MIXIN) (FUNCALL I ':CLOBBERED))))) (ADD-INITIALIZATION "Who Line" '(AND WHO-LINE-SCREEN (FUNCALL WHO-LINE-SCREEN ':REFRESH)) '(:WARM)) (DECLARE-FLAVOR-INSTANCE-VARIABLES (WHO-LINE-SHEET) (DEFUN WHO-LINE-STRING (WHO-SHEET NEW-STRING) (COND ((NEQ WHO-LINE-ITEM-STATE NEW-STRING) (PREPARE-SHEET (WHO-SHEET) (SHEET-CLEAR WHO-SHEET) (SHEET-STRING-OUT WHO-SHEET NEW-STRING 0 (MIN (STRING-LENGTH NEW-STRING) (// (SHEET-INSIDE-WIDTH WHO-SHEET) (SHEET-CHAR-WIDTH WHO-SHEET))))) (SETQ WHO-LINE-ITEM-STATE NEW-STRING))))) (DEFUN WHO-LINE-USER-OR-PROCESS (WHO-SHEET) (WHO-LINE-STRING WHO-SHEET (IF WHO-LINE-PROCESS (PROCESS-NAME WHO-LINE-PROCESS) USER-ID))) (REMPROP 'WHO-LINE-RUN-STATE 'SOURCE-FILE-NAME) ;Conflicts with variable in TVDEFS (DEFUN WHO-LINE-RUN-STATE (WHO-SHEET) (WHO-LINE-STRING WHO-SHEET WHO-LINE-RUN-STATE)) (DECLARE-FLAVOR-INSTANCE-VARIABLES (WHO-LINE-SHEET) (DEFUN WHO-LINE-PACKAGE (WHO-SHEET &AUX VAL SG) (LET ((PKG (COND ((SETQ LAST-WHO-LINE-PROCESS (OR WHO-LINE-PROCESS (AND SELECTED-IO-BUFFER (IO-BUFFER-LAST-OUTPUT-PROCESS SELECTED-IO-BUFFER)))) (SETQ SG (PROCESS-STACK-GROUP LAST-WHO-LINE-PROCESS)) (COND ((EQ SG %CURRENT-STACK-GROUP) PACKAGE) ((TYPEP SG ':STACK-GROUP) (SYMEVAL-IN-STACK-GROUP 'PACKAGE SG)) (T PACKAGE)))))) (COND ((AND PKG (ARRAYP PKG) (NEQ WHO-LINE-ITEM-STATE (SETQ VAL (PKG-NAME PKG)))) (PREPARE-SHEET (WHO-SHEET) (SHEET-CLEAR WHO-SHEET) (SHEET-STRING-OUT WHO-SHEET VAL 0 (MIN (STRING-LENGTH VAL) (1- (// (SHEET-INSIDE-WIDTH WHO-SHEET) (SHEET-CHAR-WIDTH WHO-SHEET)))))) (SHEET-TYO WHO-SHEET #/:) (SETQ WHO-LINE-ITEM-STATE VAL)))))) (DEFUN WHO-LINE-RUN-STATE-UPDATE (&AUX P) ;Separate variable since other can be setq'ed ;asynchronously by other processes (SETQ LAST-WHO-LINE-PROCESS (SETQ P (OR WHO-LINE-PROCESS (PROGN (AND (NULL SELECTED-IO-BUFFER) (NOT (NULL SELECTED-WINDOW)) ;This can happen (SETQ SELECTED-IO-BUFFER (FUNCALL SELECTED-WINDOW ':IO-BUFFER))) (AND SELECTED-IO-BUFFER (IO-BUFFER-LAST-OUTPUT-PROCESS SELECTED-IO-BUFFER)))))) (SETQ WHO-LINE-RUN-STATE (COND ((NULL P) "NIL") ((ASSQ P ACTIVE-PROCESSES) (PROCESS-WHOSTATE P)) ((NOT (NULL (SI:PROCESS-ARREST-REASONS P))) "ARREST") (T "STOP"))) (WHO-LINE-UPDATE T)) (DEFUN WHO-LINE-FIELD (&REST ARGS &AUX W) (LET ((SHEET-AREA WHO-LINE-AREA)) ;; Do sheet type consing in special area to increase locality (SETQ W (LEXPR-FUNCALL #'WINDOW-CREATE (GET (LOCF ARGS) ':FLAVOR) ':SUPERIOR WHO-LINE-SCREEN ':VSP 0 ARGS)) (FUNCALL W ':ACTIVATE) (FUNCALL W ':EXPOSE) W)) (DEFFLAVOR WHO-LINE-FILE-SHEET ((CURRENT-STREAM NIL) ;The one being displayed (OPEN-STREAM-LIST NIL) ;Possibilities to display DISPLAYED-PERCENT DISPLAYED-COUNT) (WHO-LINE-MIXIN MINIMUM-WINDOW)) (DEFMETHOD (WHO-LINE-FILE-SHEET :ADD-STREAM) (STREAM &OPTIONAL (UPDATE-P T)) (PUSH STREAM OPEN-STREAM-LIST) (WHO-LINE-FILE-SHEET-COMPUTE-CURRENT-STREAM UPDATE-P)) (DEFMETHOD (WHO-LINE-FILE-SHEET :DELETE-STREAM) (STREAM) (SETQ OPEN-STREAM-LIST (DELQ STREAM OPEN-STREAM-LIST)) (AND (EQ STREAM CURRENT-STREAM) (WHO-LINE-FILE-SHEET-COMPUTE-CURRENT-STREAM))) (DEFMETHOD (WHO-LINE-FILE-SHEET :DELETE-ALL-STREAMS) () (SETQ OPEN-STREAM-LIST NIL CURRENT-STREAM NIL)) ;Take the most recently opened input stream if there is one. Otherwise ;take the most recently opened output stream. (DECLARE-FLAVOR-INSTANCE-VARIABLES (WHO-LINE-FILE-SHEET) (DEFUN WHO-LINE-FILE-SHEET-COMPUTE-CURRENT-STREAM (&OPTIONAL (UPDATE-P T)) (DO ((L OPEN-STREAM-LIST (CDR L)) (OUTPUT-WINNER NIL) (STREAM) (DIRECTION)) ((NULL L) (SETQ CURRENT-STREAM OUTPUT-WINNER)) (SETQ STREAM (CAR L)) (MULTIPLE-VALUE (NIL DIRECTION) (FUNCALL STREAM ':WHO-LINE-INFORMATION)) (SELECTQ DIRECTION (:INPUT (RETURN (SETQ CURRENT-STREAM STREAM))) (:OUTPUT (OR OUTPUT-WINNER (SETQ OUTPUT-WINNER STREAM))))) (AND UPDATE-P (WHO-LINE-UPDATE)))) (DEFMETHOD (WHO-LINE-FILE-SHEET :UPDATE) (&AUX (MAX-CHARS (// (SHEET-INSIDE-WIDTH) CHAR-WIDTH)) IDLE) (COND (CURRENT-STREAM (LET ((OLD-STREAM WHO-LINE-ITEM-STATE) (PATHNAME) (DIRECTION) (PERCENT) (COUNT) (FILE-NAME) (STRING) (SP-POS) (FNTRUNC)) (MULTIPLE-VALUE (PATHNAME DIRECTION COUNT PERCENT) (FUNCALL CURRENT-STREAM ':WHO-LINE-INFORMATION)) (SHEET-HOME SELF) (COND ((AND (EQ OLD-STREAM CURRENT-STREAM) (EQ PERCENT DISPLAYED-PERCENT) (EQ COUNT DISPLAYED-COUNT))) (T (OR (EQ OLD-STREAM CURRENT-STREAM) (SHEET-CLEAR-EOL SELF)) (SETQ WHO-LINE-ITEM-STATE CURRENT-STREAM DISPLAYED-PERCENT PERCENT DISPLAYED-COUNT COUNT) (SHEET-STRING-OUT SELF (SELECTQ DIRECTION (:INPUT " ") (:OUTPUT " "))) (SETQ FILE-NAME (FUNCALL PATHNAME ':STRING-FOR-WHOLINE)) (AND ( (STRING-LENGTH FILE-NAME) (- MAX-CHARS 4)) ;; If not enough room for filename, then truncate (SETQ FNTRUNC (- MAX-CHARS 7))) (SHEET-STRING-OUT SELF FILE-NAME 0 FNTRUNC) (SHEET-STRING-OUT SELF (IF FNTRUNC " " " ")) (SETQ SP-POS (+ 4 (OR FNTRUNC (STRING-LENGTH FILE-NAME)))) (SHEET-CLEAR-EOL SELF) (COND ((AND PERCENT ( (+ SP-POS (STRING-LENGTH (SETQ STRING (FORMAT NIL "~D% ~D" PERCENT COUNT)))) MAX-CHARS))) (PERCENT (WITHOUT-INTERRUPTS (RETURN-ARRAY STRING) (SETQ STRING (FORMAT NIL "~D%" PERCENT)))) (T (WITHOUT-INTERRUPTS (AND STRING (RETURN-ARRAY STRING)) (SETQ STRING (FORMAT NIL "~D" COUNT))))) (SHEET-STRING-OUT SELF STRING 0 (MIN (- MAX-CHARS SP-POS) (STRING-LENGTH STRING))) (WITHOUT-INTERRUPTS (RETURN-ARRAY STRING) (SETQ STRING NIL)))))) (SI:WHO-LINE-JUST-COLD-BOOTED-P (COND ((NEQ WHO-LINE-ITEM-STATE 'COLD) (SHEET-CLEAR SELF) (SETQ WHO-LINE-ITEM-STATE 'COLD) (SHEET-STRING-OUT SELF "Cold-booted")))) ((> (SETQ IDLE (// (TIME-DIFFERENCE (TIME) TV:KBD-LAST-ACTIVITY-TIME) 3600.)) 4) ;Display keyboard idle time (LET ((OLD-IDLE WHO-LINE-ITEM-STATE)) (COND ((OR (NOT (NUMBERP OLD-IDLE)) ( OLD-IDLE IDLE)) (SHEET-CLEAR SELF) (WITHOUT-INTERRUPTS (LET ((STRING (FORMAT NIL "Console idle ~D minute~P" IDLE IDLE))) (SHEET-STRING-OUT SELF STRING) (RETURN-ARRAY STRING))) (SETQ WHO-LINE-ITEM-STATE IDLE))))) ((NEQ WHO-LINE-ITEM-STATE 'NULL) (SHEET-CLEAR SELF) (SETQ WHO-LINE-ITEM-STATE 'NULL)))) ;;; Date and time in the who-line, continuously updating. ;;; Find out the time and start displaying it in the who-line (DEFUN NWATCH-ON () (NWATCH-OFF) ;Remove obsolete information from the who-line saved state (COND ((TIME:INITIALIZE-TIMEBASE) (FUNCALL NWATCH-WHO-LINE-SHEET ':EXPOSE) (ADD-INITIALIZATION "NWATCH" '(NWATCH-ON) '(:WARM))))) (ADD-INITIALIZATION "NWATCH" '(NWATCH-ON) '(:WARM)) (DEFUN NWATCH-OFF () (DELETE-INITIALIZATION "NWATCH" '(:WARM)) (FUNCALL NWATCH-WHO-LINE-SHEET ':DEACTIVATE)) (DEFUN NWATCH-LOGIN () (NWATCH-ON) '(NWATCH-OFF)) (DECLARE-FLAVOR-INSTANCE-VARIABLES (WHO-LINE-SHEET) (DEFUN NWATCH-WHO-FUNCTION (WHO-SHEET) (OR WHO-LINE-EXTRA-STATE (LET ((DEFAULT-CONS-AREA WHO-LINE-AREA)) (SETQ WHO-LINE-EXTRA-STATE (STRING-APPEND "MM//DD//YY HH:MM:SS")))) (LET (YEAR MONTH DAY HOURS MINUTES SECONDS LEFTX) (MULTIPLE-VALUE (SECONDS MINUTES HOURS DAY MONTH YEAR) (TIME:GET-TIME)) (COND ((NOT (NULL SECONDS)) (SETQ LEFTX (MIN (NWATCH-N MONTH WHO-LINE-EXTRA-STATE 0) (NWATCH-N DAY WHO-LINE-EXTRA-STATE 3) (NWATCH-N YEAR WHO-LINE-EXTRA-STATE 6) (NWATCH-N HOURS WHO-LINE-EXTRA-STATE 9) (NWATCH-N MINUTES WHO-LINE-EXTRA-STATE 12.) (NWATCH-N SECONDS WHO-LINE-EXTRA-STATE 15.))) (OR WHO-LINE-ITEM-STATE (SETQ LEFTX 0)) ;was clobbered, redisplay all (SHEET-SET-CURSORPOS WHO-SHEET (* LEFTX CHAR-WIDTH) 0) (SHEET-CLEAR-EOL WHO-SHEET) (SHEET-STRING-OUT WHO-SHEET WHO-LINE-EXTRA-STATE LEFTX) (SETQ WHO-LINE-ITEM-STATE T)))))) ;Returns first character position changed (DEFUN NWATCH-N (N STR I) (LET ((DIG1 (+ (// N 10.) #/0)) (DIG2 (+ (\ N 10.) #/0))) (PROG1 (COND ((NOT (= (AREF STR I) DIG1)) I) ((NOT (= (AREF STR (1+ I)) DIG2)) (1+ I)) (T (ARRAY-LENGTH STR))) (ASET DIG1 STR I) (ASET DIG2 STR (1+ I))))) ;;; Support for documentation in the who line (DEFMETHOD (SHEET :WHO-LINE-DOCUMENTATION-STRING) () NIL) (DEFUN WHO-LINE-DOCUMENTATION (&OPTIONAL (ON-P T)) (COND ((AND ON-P (NOT (SHEET-EXPOSED-P WHO-LINE-DOCUMENTATION-WINDOW))) (SET-WHO-LINE-LINES (1+ (// (SHEET-INSIDE-HEIGHT WHO-LINE-SCREEN) (SHEET-LINE-HEIGHT WHO-LINE-SCREEN)))) (FUNCALL WHO-LINE-DOCUMENTATION-WINDOW ':DEACTIVATE) (DOLIST (I (COPYLIST (SHEET-INFERIORS WHO-LINE-SCREEN))) (AND ( (SHEET-Y-OFFSET I) (SHEET-Y-OFFSET WHO-LINE-DOCUMENTATION-WINDOW)) (FUNCALL I ':SET-POSITION (SHEET-X-OFFSET I) (+ (SHEET-Y-OFFSET I) (SHEET-Y-OFFSET WHO-LINE-DOCUMENTATION-WINDOW) (SHEET-HEIGHT WHO-LINE-DOCUMENTATION-WINDOW))))) (FUNCALL WHO-LINE-DOCUMENTATION-WINDOW ':EXPOSE)) ((AND (NOT ON-P) WHO-LINE-DOCUMENTATION-WINDOW) (COND ((SHEET-EXPOSED-P WHO-LINE-DOCUMENTATION-WINDOW) (FUNCALL WHO-LINE-DOCUMENTATION-WINDOW ':DEACTIVATE) (SET-WHO-LINE-LINES (1- (// (SHEET-INSIDE-HEIGHT WHO-LINE-SCREEN) (SHEET-LINE-HEIGHT WHO-LINE-SCREEN)))) (DOLIST (I (COPYLIST (SHEET-INFERIORS WHO-LINE-SCREEN))) (AND ( (SHEET-Y-OFFSET I) (SHEET-Y-OFFSET WHO-LINE-DOCUMENTATION-WINDOW)) (FUNCALL I ':SET-POSITION (SHEET-X-OFFSET I) (- (SHEET-Y-OFFSET I) (SHEET-Y-OFFSET WHO-LINE-DOCUMENTATION-WINDOW) (SHEET-HEIGHT WHO-LINE-DOCUMENTATION-WINDOW)))))))))) (DECLARE-FLAVOR-INSTANCE-VARIABLES (WHO-LINE-SHEET) (DEFUN WHO-LINE-DOCUMENTATION-FUNCTION (WHO-SHEET) (LET* ((W MOUSE-WINDOW) (NEW-STATE (COND ((SYMBOLP W) (AND W WHO-LINE-MOUSE-GRABBED-DOCUMENTATION)) (T (MULTIPLE-VALUE-BIND (DOC ERROR) (CATCH-ERROR (FUNCALL W ':WHO-LINE-DOCUMENTATION-STRING) NIL) (IF ERROR "Error getting documentation string" DOC)))))) (COND ((NEQ WHO-LINE-ITEM-STATE NEW-STATE) (SETQ WHO-LINE-ITEM-STATE NEW-STATE) (SHEET-CLEAR WHO-SHEET) (AND (TYPEP NEW-STATE 'STRING) (SHEET-STRING-OUT WHO-SHEET NEW-STATE 0 (MIN (OR (STRING-SEARCH-CHAR #\NEWLINE NEW-STATE) (STRING-LENGTH NEW-STATE)) (// (SHEET-INSIDE-WIDTH WHO-SHEET) (SHEET-CHAR-WIDTH WHO-SHEET))))))))))