shared-physical-screen.sl 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %
  3. % Shared-Physical-Screen.SL
  4. %
  5. % Author: Alan Snyder
  6. % Hewlett-Packard/CRC
  7. % Date: 17 August 1982
  8. % Revised: 22 February 1983
  9. %
  10. % Inspired by Will Galway's EMODE Virtual Screen package.
  11. %
  12. % A shared-physical-screen is a rectangular character display whose display
  13. % area is shared by a number of different owners. An owner can be any object
  14. % that supports the following operations:
  15. %
  16. % Assert-Ownership () - assert ownership of all desired screen locations
  17. % Send-Changes (break-ok) - send all changed contents to the shared screen
  18. % Send-Contents (break-ok) - send entire contents to the shared screen
  19. % Screen-Cursor-Position () - return desired cursor position on screen
  20. %
  21. % Each character position on the physical screen is owned by a single owner.
  22. % Each owner is responsible for asserting ownership of those character
  23. % positions it wishes to be able to write on. The actual ownership of each
  24. % character position is determined by a prioritized list of owners. Owners
  25. % assert ownership in reverse order of priority; the highest priority owner
  26. % therefore appears to "overlap" all other owners.
  27. %
  28. % A shared physical screen object provides an opaque interface: no access to
  29. % the underlying physical screen object should be required.
  30. %
  31. % 22-Feb-83 Alan Snyder
  32. % Declare -> Declare-Flavor.
  33. % 27-Dec-82 Alan Snyder
  34. % Changed SELECT-PRIMARY-OWNER and REMOVE-OWNER to avoid redundant
  35. % recomputation (and screen rewriting).
  36. % 21-Dec-82 Alan Snyder
  37. % Efficiency hacks: Special tests for owners that are virtual-screens.
  38. % Added methods: &GET-OWNER-CHANGES, &GET-OWNER-CONTENTS, and
  39. % &ASSERT-OWNERSHIP.
  40. % 16-Dec-82 Alan Snyder
  41. % Bug fix: SET-SCREEN failed to update size (invoked the wrong method).
  42. %
  43. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  44. (BothTimes (load objects))
  45. (CompileTime (load fast-int fast-vectors))
  46. (de create-shared-physical-screen (physical-screen)
  47. (make-instance 'shared-physical-screen 'screen physical-screen))
  48. (defflavor shared-physical-screen (
  49. height % number of rows (0 indexed)
  50. maxrow % highest numbered row
  51. width % number of columns (0 indexed)
  52. maxcol % highest numbered column
  53. (owner-list NIL) % prioritized list of owners (lowest priority first)
  54. (recalculate T) % T => must recalculate ownership
  55. owner-map % maps screen location to owner (or NIL)
  56. screen % the physical-screen
  57. )
  58. ()
  59. (gettable-instance-variables height width)
  60. (initable-instance-variables screen)
  61. )
  62. (declare-flavor physical-screen screen)
  63. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  64. % Private Macros:
  65. (defmacro map-fetch (map row col)
  66. `(vector-fetch (vector-fetch ,map ,row) ,col))
  67. (defmacro map-store (map row col value)
  68. `(vector-store (vector-fetch ,map ,row) ,col ,value))
  69. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  70. % Public methods:
  71. (defmethod (shared-physical-screen ring-bell) ()
  72. (=> screen ring-bell))
  73. (defmethod (shared-physical-screen enter-raw-mode) ()
  74. (=> screen enter-raw-mode))
  75. (defmethod (shared-physical-screen leave-raw-mode) ()
  76. (=> screen leave-raw-mode))
  77. (defmethod (shared-physical-screen get-character) ()
  78. (=> screen get-character))
  79. (defmethod (shared-physical-screen convert-character) (ch)
  80. (=> screen convert-character ch))
  81. (defmethod (shared-physical-screen normal-enhancement) ()
  82. (=> screen normal-enhancement))
  83. (defmethod (shared-physical-screen highlighted-enhancement) ()
  84. (=> screen highlighted-enhancement))
  85. (defmethod (shared-physical-screen supported-enhancements) ()
  86. (=> screen supported-enhancements))
  87. (defmethod (shared-physical-screen write-to-stream) (s)
  88. (=> screen write-to-stream s))
  89. (defmethod (shared-physical-screen set-screen) (new-screen)
  90. (setf screen new-screen)
  91. (=> self &new-screen)
  92. )
  93. (defmethod (shared-physical-screen owner) (row col)
  94. % Return the current owner of the specified screen location.
  95. (if recalculate (=> self &recalculate-ownership))
  96. (if (and (>= row 0) (<= row maxrow) (>= col 0) (<= col maxcol))
  97. (map-fetch owner-map row col)))
  98. (defmethod (shared-physical-screen select-primary-owner) (owner)
  99. % Make the specified OWNER the primary owner (adding it to the list of owners,
  100. % if not already there).
  101. (when (not (eq (lastcar owner-list) owner)) % redundancy check
  102. (setf owner-list (DelQIP owner owner-list))
  103. (setf owner-list (aconc owner-list owner))
  104. (when (not recalculate)
  105. (=> self &assert-ownership owner)
  106. (=> self &get-owner-contents owner nil)
  107. (=> self &update-cursor owner)
  108. )))
  109. (defmethod (shared-physical-screen remove-owner) (owner)
  110. % Remove the specified owner from the list of owners. The owner will lose
  111. % ownership of his screen area. Screen ownership will be recalculated in its
  112. % entirety when necessary (to determine the new ownership of the screen area).
  113. (when (memq owner owner-list) % redundancy check
  114. (setf owner-list (DelQIP owner owner-list))
  115. (setf recalculate T)
  116. ))
  117. (defmethod (shared-physical-screen refresh) (breakout-allowed)
  118. % Update the screen: obtain changed contents from the owners,
  119. % send it to the screen, refresh the screen.
  120. (if recalculate
  121. (=> self &recalculate-ownership)
  122. (=> self &get-owners-changes breakout-allowed)
  123. )
  124. (=> screen refresh breakout-allowed))
  125. (defmethod (shared-physical-screen full-refresh) (breakout-allowed)
  126. % Just like REFRESH, except that the screen is cleared first. This operation
  127. % should be used to initialize the state of the screen when the program
  128. % starts or when uncontrolled output may have occured.
  129. (if recalculate
  130. (=> self &recalculate-ownership)
  131. (=> self &get-owners-changes breakout-allowed)
  132. )
  133. (=> screen full-refresh breakout-allowed))
  134. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  135. % Semi-Private methods
  136. % The following methods are for use only by owners to perform the
  137. % AssertOwnership operation when invoked by this object:
  138. (defmethod (shared-physical-screen set-owner) (row col owner)
  139. (if (and (>= row 0) (<= row maxrow) (>= col 0) (<= col maxcol))
  140. (map-store owner-map row col owner)))
  141. (defmethod (shared-physical-screen set-owner-region) (row col h w owner)
  142. % This method provided for convenience and efficiency.
  143. (let ((last-row (+ row (- h 1)))
  144. (last-col (+ col (- w 1)))
  145. (map owner-map)
  146. )
  147. (cond ((and (<= row maxrow) (<= col maxcol) (>= last-row 0) (>= last-col 0))
  148. (if (< row 0) (setf row 0))
  149. (if (< col 0) (setf col 0))
  150. (if (> last-row maxrow) (setf last-row maxrow))
  151. (if (> last-col maxcol) (setf last-col maxcol))
  152. (for (from r row last-row)
  153. (do (for (from c col last-col)
  154. (do
  155. (map-store map r c owner))
  156. )))))))
  157. % The following method is for use only by owners:
  158. (defmethod (shared-physical-screen write) (ch row col owner)
  159. % Conditional write: write the specified character to the specified location
  160. % only if that location is owned by the specified owner. The actual display
  161. % will not be updated until REFRESH or FULL-REFRESH is performed.
  162. (if (and (>= row 0) (<= row maxrow) (>= col 0) (<= col maxcol))
  163. (progn
  164. (if recalculate (=> self &recalculate-ownership))
  165. (if (eq owner (map-fetch owner-map row col))
  166. (=> screen write ch row col)))))
  167. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  168. % Private methods:
  169. (defmethod (shared-physical-screen init) (init-plist)
  170. (=> self &new-screen)
  171. )
  172. (defmethod (shared-physical-screen &new-screen) ()
  173. (setf height (=> screen height))
  174. (setf width (=> screen width))
  175. (=> self &new-size)
  176. )
  177. (defmethod (shared-physical-screen &new-size) ()
  178. (if (< height 0) (setf height 0))
  179. (if (< width 0) (setf width 0))
  180. (setf maxrow (- height 1))
  181. (setf maxcol (- width 1))
  182. (setf owner-map (mkvect maxrow))
  183. (for (from row 0 maxrow)
  184. (do (iputv owner-map row (mkvect maxcol))))
  185. (setf recalculate t))
  186. (defmethod (shared-physical-screen &recalculate-ownership) ()
  187. % Reset ownership to NIL, then ask all OWNERS to assert ownership.
  188. % Then ask all OWNERS to send all contents.
  189. (let ((map owner-map))
  190. (for (from r 0 maxrow)
  191. (do (for (from c 0 maxcol)
  192. (do (map-store map r c NIL))))))
  193. (for (in owner owner-list)
  194. (do (=> self &assert-ownership owner)))
  195. (setf recalculate NIL)
  196. (=> self &get-owners-contents))
  197. (defmethod (shared-physical-screen &get-owners-changes) (breakout-allowed)
  198. % Ask all OWNERS to send any changed contents.
  199. (for (in owner owner-list)
  200. (with last-owner)
  201. (do (=> self &get-owner-changes owner breakout-allowed)
  202. (setf last-owner owner))
  203. (finally
  204. (if last-owner (=> self &update-cursor last-owner)))
  205. )
  206. )
  207. (defmethod (shared-physical-screen &get-owner-changes) (owner breakout-allowed)
  208. (if (eq (object-type owner) 'virtual-screen) % hack for efficiency
  209. (virtual-screen$send-changes owner breakout-allowed)
  210. (=> owner send-changes breakout-allowed)
  211. ))
  212. (defmethod (shared-physical-screen &get-owners-contents) (breakout-allowed)
  213. % Ask all OWNERS to send all of their contents; unowned screen area
  214. % is blanked.
  215. (let ((map owner-map))
  216. (for (from r 0 maxrow)
  217. (do (for (from c 0 maxcol)
  218. (do (if (null (map-fetch map r c))
  219. (=> screen write #\space r c)))))))
  220. (for (in owner owner-list)
  221. (with last-owner)
  222. (do (=> self &get-owner-contents owner breakout-allowed)
  223. (setf last-owner owner))
  224. (finally
  225. (if last-owner (=> self &update-cursor last-owner)))
  226. )
  227. )
  228. (defmethod (shared-physical-screen &get-owner-contents) (owner breakout-allowed)
  229. (if (eq (object-type owner) 'virtual-screen) % hack for efficiency
  230. (virtual-screen$send-contents owner breakout-allowed)
  231. (=> owner send-contents breakout-allowed)
  232. ))
  233. (defmethod (shared-physical-screen &assert-ownership) (owner)
  234. (if (eq (object-type owner) 'virtual-screen) % hack for efficiency
  235. (virtual-screen$assert-ownership owner)
  236. (=> owner assert-ownership)
  237. ))
  238. (defmethod (shared-physical-screen &update-cursor) (owner)
  239. (let ((pair (if (eq (object-type owner) 'virtual-screen)
  240. (virtual-screen$screen-cursor-position owner)
  241. (=> owner screen-cursor-position)
  242. )))
  243. (if (PairP pair)
  244. (=> screen set-cursor-position (car pair) (cdr pair)))))
  245. (undeclare-flavor screen)