123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Shared-Physical-Screen.SL
- %
- % Author: Alan Snyder
- % Hewlett-Packard/CRC
- % Date: 17 August 1982
- % Revised: 16 February 1983
- %
- % Inspired by Will Galway's EMODE Virtual Screen package.
- %
- % A shared-physical-screen is a rectangular character display whose display
- % area is shared by a number of different owners. An owner can be any object
- % that supports the following operations:
- %
- % Assert-Ownership () - assert ownership of all desired screen locations
- % Send-Changes (break-ok) - send all changed contents to the shared screen
- % Send-Contents (break-ok) - send entire contents to the shared screen
- % Screen-Cursor-Position () - return desired cursor position on screen
- %
- % Each character position on the physical screen is owned by a single owner.
- % Each owner is responsible for asserting ownership of those character
- % positions it wishes to be able to write on. The actual ownership of each
- % character position is determined by a prioritized list of owners. Owners
- % assert ownership in reverse order of priority; the highest priority owner
- % therefore appears to "overlap" all other owners.
- %
- % A shared physical screen object provides an opaque interface: no access to
- % the underlying physical screen object should be required.
- %
- % 16-Feb-83 Alan Snyder
- % Declare -> Declare-Flavor.
- % 27-Dec-82 Alan Snyder
- % Changed SELECT-PRIMARY-OWNER and REMOVE-OWNER to avoid redundant
- % recomputation (and screen rewriting).
- % 21-Dec-82 Alan Snyder
- % Efficiency hacks: Special tests for owners that are virtual-screens.
- % Added methods: &GET-OWNER-CHANGES, &GET-OWNER-CONTENTS, and
- % &ASSERT-OWNERSHIP.
- % 16-Dec-82 Alan Snyder
- % Bug fix: SET-SCREEN failed to update size (invoked the wrong method).
- %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- (BothTimes (load objects))
- (CompileTime (load fast-int fast-vectors))
-
- (de create-shared-physical-screen (physical-screen)
- (make-instance 'shared-physical-screen 'screen physical-screen))
- (defflavor shared-physical-screen (
- height % number of rows (0 indexed)
- maxrow % highest numbered row
- width % number of columns (0 indexed)
- maxcol % highest numbered column
- (owner-list NIL) % prioritized list of owners (lowest priority first)
- (recalculate T) % T => must recalculate ownership
- owner-map % maps screen location to owner (or NIL)
- screen % the physical-screen
- )
- ()
- (gettable-instance-variables height width)
- (initable-instance-variables screen)
- )
- (declare-flavor physical-screen screen)
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Private Macros:
- (defmacro map-fetch (map row col)
- `(vector-fetch (vector-fetch ,map ,row) ,col))
- (defmacro map-store (map row col value)
- `(vector-store (vector-fetch ,map ,row) ,col ,value))
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Public methods:
- (defmethod (shared-physical-screen ring-bell) ()
- (=> screen ring-bell))
- (defmethod (shared-physical-screen enter-raw-mode) ()
- (=> screen enter-raw-mode))
- (defmethod (shared-physical-screen leave-raw-mode) ()
- (=> screen leave-raw-mode))
- (defmethod (shared-physical-screen get-character) ()
- (=> screen get-character))
- (defmethod (shared-physical-screen convert-character) (ch)
- (=> screen convert-character ch))
- (defmethod (shared-physical-screen normal-enhancement) ()
- (=> screen normal-enhancement))
- (defmethod (shared-physical-screen highlighted-enhancement) ()
- (=> screen highlighted-enhancement))
- (defmethod (shared-physical-screen supported-enhancements) ()
- (=> screen supported-enhancements))
- (defmethod (shared-physical-screen write-to-stream) (s)
- (=> screen write-to-stream s))
- (defmethod (shared-physical-screen set-screen) (new-screen)
- (setf screen new-screen)
- (=> self &new-screen)
- )
- (defmethod (shared-physical-screen owner) (row col)
- % Return the current owner of the specified screen location.
- (if recalculate (=> self &recalculate-ownership))
- (if (and (>= row 0) (<= row maxrow) (>= col 0) (<= col maxcol))
- (map-fetch owner-map row col)))
- (defmethod (shared-physical-screen select-primary-owner) (owner)
- % Make the specified OWNER the primary owner (adding it to the list of owners,
- % if not already there).
- (when (not (eq (lastcar owner-list) owner)) % redundancy check
- (setf owner-list (DelQIP owner owner-list))
- (setf owner-list (aconc owner-list owner))
- (when (not recalculate)
- (=> self &assert-ownership owner)
- (=> self &get-owner-contents owner nil)
- (=> self &update-cursor owner)
- )))
- (defmethod (shared-physical-screen remove-owner) (owner)
- % Remove the specified owner from the list of owners. The owner will lose
- % ownership of his screen area. Screen ownership will be recalculated in its
- % entirety when necessary (to determine the new ownership of the screen area).
- (when (memq owner owner-list) % redundancy check
- (setf owner-list (DelQIP owner owner-list))
- (setf recalculate T)
- ))
- (defmethod (shared-physical-screen refresh) (breakout-allowed)
- % Update the screen: obtain changed contents from the owners,
- % send it to the screen, refresh the screen.
- (if recalculate
- (=> self &recalculate-ownership)
- (=> self &get-owners-changes breakout-allowed)
- )
- (=> screen refresh breakout-allowed))
- (defmethod (shared-physical-screen full-refresh) (breakout-allowed)
- % Just like REFRESH, except that the screen is cleared first. This operation
- % should be used to initialize the state of the screen when the program
- % starts or when uncontrolled output may have occured.
- (if recalculate
- (=> self &recalculate-ownership)
- (=> self &get-owners-changes breakout-allowed)
- )
- (=> screen full-refresh breakout-allowed))
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Semi-Private methods
- % The following methods are for use only by owners to perform the
- % AssertOwnership operation when invoked by this object:
- (defmethod (shared-physical-screen set-owner) (row col owner)
- (if (and (>= row 0) (<= row maxrow) (>= col 0) (<= col maxcol))
- (map-store owner-map row col owner)))
- (defmethod (shared-physical-screen set-owner-region) (row col h w owner)
- % This method provided for convenience and efficiency.
- (let ((last-row (+ row (- h 1)))
- (last-col (+ col (- w 1)))
- (map owner-map)
- )
- (cond ((and (<= row maxrow) (<= col maxcol) (>= last-row 0) (>= last-col 0))
- (if (< row 0) (setf row 0))
- (if (< col 0) (setf col 0))
- (if (> last-row maxrow) (setf last-row maxrow))
- (if (> last-col maxcol) (setf last-col maxcol))
- (for (from r row last-row)
- (do (for (from c col last-col)
- (do
- (map-store map r c owner))
- )))))))
- % The following method is for use only by owners:
- (defmethod (shared-physical-screen write) (ch row col owner)
- % Conditional write: write the specified character to the specified location
- % only if that location is owned by the specified owner. The actual display
- % will not be updated until REFRESH or FULL-REFRESH is performed.
- (if (and (>= row 0) (<= row maxrow) (>= col 0) (<= col maxcol))
- (progn
- (if recalculate (=> self &recalculate-ownership))
- (if (eq owner (map-fetch owner-map row col))
- (=> screen write ch row col)))))
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Private methods:
- (defmethod (shared-physical-screen init) (init-plist)
- (=> self &new-screen)
- )
- (defmethod (shared-physical-screen &new-screen) ()
- (setf height (=> screen height))
- (setf width (=> screen width))
- (=> self &new-size)
- )
- (defmethod (shared-physical-screen &new-size) ()
- (if (< height 0) (setf height 0))
- (if (< width 0) (setf width 0))
- (setf maxrow (- height 1))
- (setf maxcol (- width 1))
- (setf owner-map (mkvect maxrow))
- (for (from row 0 maxrow)
- (do (iputv owner-map row (mkvect maxcol))))
- (setf recalculate t))
- (defmethod (shared-physical-screen &recalculate-ownership) ()
- % Reset ownership to NIL, then ask all OWNERS to assert ownership.
- % Then ask all OWNERS to send all contents.
- (let ((map owner-map))
- (for (from r 0 maxrow)
- (do (for (from c 0 maxcol)
- (do (map-store map r c NIL))))))
- (for (in owner owner-list)
- (do (=> self &assert-ownership owner)))
- (setf recalculate NIL)
- (=> self &get-owners-contents))
- (defmethod (shared-physical-screen &get-owners-changes) (breakout-allowed)
- % Ask all OWNERS to send any changed contents.
- (for (in owner owner-list)
- (with last-owner)
- (do (=> self &get-owner-changes owner breakout-allowed)
- (setf last-owner owner))
- (finally
- (if last-owner (=> self &update-cursor last-owner)))
- )
- )
- (defmethod (shared-physical-screen &get-owner-changes) (owner breakout-allowed)
- (if (eq (object-type owner) 'virtual-screen) % hack for efficiency
- (virtual-screen$send-changes owner breakout-allowed)
- (=> owner send-changes breakout-allowed)
- ))
-
- (defmethod (shared-physical-screen &get-owners-contents) (breakout-allowed)
- % Ask all OWNERS to send all of their contents; unowned screen area
- % is blanked.
- (let ((map owner-map))
- (for (from r 0 maxrow)
- (do (for (from c 0 maxcol)
- (do (if (null (map-fetch map r c))
- (=> screen write #\space r c)))))))
- (for (in owner owner-list)
- (with last-owner)
- (do (=> self &get-owner-contents owner breakout-allowed)
- (setf last-owner owner))
- (finally
- (if last-owner (=> self &update-cursor last-owner)))
- )
- )
- (defmethod (shared-physical-screen &get-owner-contents) (owner breakout-allowed)
- (if (eq (object-type owner) 'virtual-screen) % hack for efficiency
- (virtual-screen$send-contents owner breakout-allowed)
- (=> owner send-contents breakout-allowed)
- ))
-
- (defmethod (shared-physical-screen &assert-ownership) (owner)
- (if (eq (object-type owner) 'virtual-screen) % hack for efficiency
- (virtual-screen$assert-ownership owner)
- (=> owner assert-ownership)
- ))
-
- (defmethod (shared-physical-screen &update-cursor) (owner)
- (let ((pair (if (eq (object-type owner) 'virtual-screen)
- (virtual-screen$screen-cursor-position owner)
- (=> owner screen-cursor-position)
- )))
- (if (PairP pair)
- (=> screen set-cursor-position (car pair) (cdr pair)))))
-
- (undeclare-flavor screen)
|