virtual-screen.sl 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %
  3. % Virtual-Screen.SL
  4. %
  5. % Author: Alan Snyder
  6. % Hewlett-Packard/CRC
  7. % Date: 18 August 1982
  8. % Revised: 16 February 1983
  9. %
  10. % Inspired by Will Galway's EMODE Virtual Screen package.
  11. %
  12. % A virtual screen is an object that can be used as independent rectangular
  13. % character display, but in fact shares a physical screen with other objects. A
  14. % virtual screen object maintains a stored representation of the image on the
  15. % virtual screen, which is used to update the physical screen when new areas of
  16. % the virtual screen become "exposed". A virtual screen does not itself
  17. % maintain any information about changes to its contents. It sends all changes
  18. % directly to the physical screen as they are made, and sends the entire screen
  19. % contents to the physical screen upon its request.
  20. %
  21. % A virtual screen is a legitimate "owner" for a shared physical screen, in that
  22. % it satisfies the required interface.
  23. %
  24. % 16-Feb-83 Alan Snyder
  25. % Declare -> Declare-Flavor.
  26. % 28-Dec-82 Alan Snyder
  27. % Avoid writing to shared screen when virtual screen is not exposed. Add
  28. % WRITE-STRING and WRITE-VECTOR methods. Improve efficiency of CLEAR-TO-EOL
  29. % method. Remove patch that avoided old compiler bug. Reformat.
  30. %
  31. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  32. (BothTimes (load objects))
  33. (CompileTime (load fast-int fast-vectors display-char))
  34. (de create-virtual-screen (shared-physical-screen)
  35. (make-instance 'virtual-screen 'screen shared-physical-screen))
  36. (defflavor virtual-screen
  37. ((height (=> screen height)) % number of rows (0 indexed)
  38. maxrow % highest numbered row
  39. (width (=> screen width)) % number of columns (0 indexed)
  40. maxcol % highest numbered column
  41. (row-origin 0) % position of upper left on the shared screen
  42. (column-origin 0) % position of upper left on the shared screen
  43. (default-enhancement (=> screen normal-enhancement))
  44. (cursor-row 0) % the virtual cursor position
  45. (cursor-column 0) % the virtual cursor position
  46. (exposed? NIL)
  47. image % the virtual image
  48. screen % the shared-physical-screen
  49. )
  50. ()
  51. (gettable-instance-variables height width row-origin column-origin screen
  52. exposed?)
  53. (settable-instance-variables default-enhancement)
  54. (initable-instance-variables height width row-origin column-origin screen
  55. default-enhancement)
  56. )
  57. (declare-flavor shared-physical-screen screen)
  58. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  59. % Private Macros:
  60. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  61. (defmacro image-fetch (image row col)
  62. `(vector-fetch (vector-fetch ,image ,row) ,col))
  63. (defmacro image-store (image row col value)
  64. `(vector-store (vector-fetch ,image ,row) ,col ,value))
  65. (dm for-all-positions (form)
  66. % Executes the body repeatedly with the following variables
  67. % bound: ROW, COL, SCREEN-ROW, SCREEN-COL.
  68. `(for (from row 0 maxrow)
  69. (with screen-row)
  70. (do (setf screen-row (+ row-origin row))
  71. (for (from col 0 maxcol)
  72. (with screen-col ch)
  73. (do (setf screen-col (+ column-origin col))
  74. ,@(cdr form)
  75. )))))
  76. (dm for-all-columns (form)
  77. % Executes the body repeatedly with the following variables
  78. % bound: COL, SCREEN-COL.
  79. `(for (from col 0 maxcol)
  80. (with screen-col ch)
  81. (do (setf screen-col (+ column-origin col))
  82. ,@(cdr form)
  83. )))
  84. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  85. % Public methods:
  86. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  87. (defmethod (virtual-screen set-size) (new-height new-width)
  88. % Change the size of the screen. The screen is first DeExposed. The contents
  89. % are cleared. You must Expose the screen yourself if you want it to be
  90. % displayed.
  91. (=> self deexpose)
  92. (setf height new-height)
  93. (setf width new-width)
  94. (=> self &new-size)
  95. )
  96. (defmethod (virtual-screen set-origin) (new-row new-column)
  97. % Change the location of the screen. The screen is first DeExposed. You must
  98. % Expose the screen yourself if you want it to be displayed.
  99. (=> self deexpose)
  100. (setf row-origin new-row)
  101. (setf column-origin new-column)
  102. )
  103. (defmethod (virtual-screen set-cursor-position) (row column)
  104. (cond ((< row 0) (setf row 0))
  105. ((> row maxrow) (setf row maxrow)))
  106. (cond ((< column 0) (setf column 0))
  107. ((> column maxcol) (setf column maxcol)))
  108. (setf cursor-row row)
  109. (setf cursor-column column)
  110. )
  111. (defmethod (virtual-screen write) (ch row column)
  112. % Write one character using the default enhancement.
  113. (if (and (>= row 0) (<= row maxrow) (>= column 0) (<= column maxcol))
  114. (let ((dc (display-character-cons default-enhancement 0 (& ch 16#FF)))
  115. (screen-row (+ row row-origin))
  116. )
  117. (setq dc (=> screen convert-character dc))
  118. (image-store image row column dc)
  119. (if exposed?
  120. (=> screen write dc screen-row (+ column column-origin) self))
  121. )))
  122. (defmethod (virtual-screen write-range) (ch row left-column right-column)
  123. % Write repeatedly.
  124. (when (and (>= row 0)
  125. (<= row maxrow)
  126. (<= left-column maxcol)
  127. (>= right-column 0)
  128. )
  129. (if (< left-column 0) (setf left-column 0))
  130. (if (> right-column maxcol) (setf right-column maxcol))
  131. (let ((dc (display-character-cons default-enhancement 0 (& ch 16#FF)))
  132. (screen-row (+ row row-origin))
  133. )
  134. (setq dc (=> screen convert-character dc))
  135. (for (from col left-column right-column)
  136. (do (image-store image row col dc)
  137. (if exposed?
  138. (=> screen write dc screen-row (+ col column-origin) self))
  139. )))))
  140. (defmethod (virtual-screen write-display-character) (dc row column)
  141. % Write one character (explicit enhancement)
  142. (when (and (>= row 0) (<= row maxrow) (>= column 0) (<= column maxcol))
  143. (setq dc (=> screen convert-character dc))
  144. (image-store image row column dc)
  145. (if exposed?
  146. (=> screen write dc (+ row row-origin) (+ column column-origin) self))
  147. ))
  148. (defmethod (virtual-screen write-string) (row left-column s count)
  149. % S is a string of characters. Write S[0..COUNT-1] using the default
  150. % enhancement to the specified row, starting at the specified column.
  151. (when (and (> count 0)
  152. (>= row 0)
  153. (<= row maxrow)
  154. (<= left-column maxcol)
  155. (> (+ left-column count) 0)
  156. )
  157. (let ((smax (- count 1))
  158. (image-row (vector-fetch image row))
  159. (screen-row (+ row row-origin))
  160. )
  161. (if (< left-column 0) (setf left-column 0))
  162. (if (> (+ left-column smax) maxcol)
  163. (setf smax (- maxcol left-column)))
  164. (for (from i 0 smax)
  165. (for col left-column (+ col 1))
  166. (for screen-col (+ left-column column-origin) (+ screen-col 1))
  167. (do
  168. (let ((ch (string-fetch s i)))
  169. (setf ch (display-character-cons default-enhancement 0 ch))
  170. (setf ch (=> screen convert-character ch))
  171. (vector-store image-row col ch)
  172. (if exposed?
  173. (=> screen write ch screen-row screen-col self))
  174. ))))))
  175. (defmethod (virtual-screen write-vector) (row left-column v count)
  176. % V is a vector of display-characters. Write V[0..COUNT-1] to the specified
  177. % row, starting at the specified column.
  178. (when (and (> count 0)
  179. (>= row 0)
  180. (<= row maxrow)
  181. (<= left-column maxcol)
  182. (> (+ left-column count) 0)
  183. )
  184. (let ((vmax (- count 1))
  185. (image-row (vector-fetch image row))
  186. (screen-row (+ row row-origin))
  187. )
  188. (if (< left-column 0) (setf left-column 0))
  189. (if (> (+ left-column vmax) maxcol)
  190. (setf vmax (- maxcol left-column)))
  191. (for (from i 0 vmax)
  192. (for col left-column (+ col 1))
  193. (for screen-col (+ left-column column-origin) (+ screen-col 1))
  194. (do
  195. (let ((ch (vector-fetch v i)))
  196. (vector-store image-row col ch)
  197. (if exposed?
  198. (=> screen write ch screen-row screen-col self))
  199. ))))))
  200. (defmethod (virtual-screen clear) ()
  201. (let ((dc (display-character-cons default-enhancement 0 #\space)))
  202. (setq dc (=> screen convert-character dc))
  203. (for-all-positions
  204. (image-store image row col dc)
  205. )
  206. (if exposed?
  207. (for-all-positions
  208. (=> screen write dc screen-row screen-col self)
  209. ))
  210. ))
  211. (defmethod (virtual-screen clear-to-end) (first-row)
  212. (if (< first-row 0) (setf first-row 0))
  213. (let ((dc (display-character-cons default-enhancement 0 #\space)))
  214. (setq dc (=> screen convert-character dc))
  215. (for (from row first-row maxrow)
  216. (with screen-row)
  217. (do (setf screen-row (+ row-origin row))
  218. (for-all-columns
  219. (image-store image row col dc)
  220. )
  221. (if exposed?
  222. (for-all-columns
  223. (=> screen write dc screen-row screen-col self)
  224. ))
  225. ))))
  226. (defmethod (virtual-screen clear-to-eol) (row first-column)
  227. (when (and (>= row 0) (<= row maxrow))
  228. (if (< first-column 0) (setf first-column 0))
  229. (let ((dc (display-character-cons default-enhancement 0 #\space))
  230. (image-row (vector-fetch image row))
  231. )
  232. (setq dc (=> screen convert-character dc))
  233. (for (from col first-column maxcol)
  234. (do (vector-store image-row col dc)))
  235. (if exposed?
  236. (let ((screen-row (+ row row-origin)))
  237. (for
  238. (from col (+ first-column column-origin) (+ maxcol column-origin))
  239. (do (=> screen write dc screen-row col self)))))
  240. )))
  241. (defmethod (virtual-screen expose) ()
  242. % Expose the screen. Make it overlap all other screens.
  243. (=> screen select-primary-owner self)
  244. (setf exposed? T)
  245. )
  246. (defmethod (virtual-screen deexpose) ()
  247. % Remove the screen from the display.
  248. (when exposed?
  249. (=> screen remove-owner self)
  250. (setf exposed? NIL)
  251. ))
  252. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  253. % Semi-Private methods:
  254. % The following methods are for use ONLY by the shared physical screen.
  255. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  256. (defmethod (virtual-screen send-changes) (breakout-allowed)
  257. % This method is invoked by the shared physical screen to obtain any buffered
  258. % changes to the virtual screen image. Since the virtual screen does not
  259. % buffer any changes, this method does nothing.
  260. )
  261. (defmethod (virtual-screen send-contents) (breakout-allowed)
  262. % This method is invoked by the shared physical screen to obtain the entire
  263. % virtual screen image.
  264. (for-all-positions
  265. (let ((ch (image-fetch image row col)))
  266. (=> screen write ch screen-row screen-col self)
  267. )))
  268. (defmethod (virtual-screen assert-ownership) ()
  269. % This method is invoked by the shared physical screen to obtain the desired
  270. % area for the virtual screen.
  271. (=> screen set-owner-region row-origin column-origin height width self)
  272. )
  273. (defmethod (virtual-screen screen-cursor-position) ()
  274. % This method is invoked by the shared physical screen to obtain the desired
  275. % cursor position for the virtual screen.
  276. (cons
  277. (+ cursor-row row-origin)
  278. (+ cursor-column column-origin)
  279. ))
  280. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  281. % Private methods:
  282. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  283. (defmethod (virtual-screen init) (init-plist)
  284. (=> self &new-size)
  285. )
  286. (defmethod (virtual-screen &new-size) ()
  287. (if (< height 0) (setf height 0))
  288. (if (< width 0) (setf width 0))
  289. (setf maxrow (- height 1))
  290. (setf maxcol (- width 1))
  291. (setf image (make-vector maxrow NIL))
  292. (let ((line (make-vector maxcol #\space)))
  293. (for (from row 0 maxrow)
  294. (do (vector-store image row (copyvector line))))
  295. )
  296. )
  297. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  298. (undeclare-flavor screen)