physical-screen.sl 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %
  3. % Physical-Screen.SL
  4. %
  5. % Author: Alan Snyder
  6. % Hewlett-Packard/CRC
  7. % Date: 17 August 1982
  8. % Revised: 20 December 1982
  9. %
  10. % Adapted from Will Galway's EMODE Virtual Screen package.
  11. %
  12. % A physical screen is a rectangular character display. Changes to the physical
  13. % screen are made using the Write operation. These changes are saved and sent
  14. % to the actual display only when REFRESH or FULL-REFRESH is performed.
  15. % FULL-REFRESH should be called to initialize the state of the display.
  16. %
  17. % 20-Dec-82 Alan Snyder
  18. % Added cached terminal methods to improve efficiency.
  19. %
  20. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  21. (BothTimes (load objects))
  22. (CompileTime (load fast-int fast-vectors display-char))
  23. (de create-physical-screen (display-terminal)
  24. (make-instance 'physical-screen 'terminal display-terminal))
  25. (defflavor physical-screen
  26. (height % number of rows (0 indexed)
  27. maxrow % highest numbered row
  28. width % number of columns (0 indexed)
  29. maxcol % highest numbered column
  30. cursor-row % desired cursor position after refresh
  31. cursor-column % desired cursor position after refresh
  32. changed-row-range % bounds on rows where new-image differs from display
  33. changed-column-ranges % bounds on columns in each row
  34. terminal % the display terminal
  35. new-image % new image (after refresh)
  36. displayed-image % image on the display terminal
  37. update-line-method % terminal's update-line method
  38. move-cursor-method % terminal's move-cursor method
  39. get-char-method % terminal's get-character method
  40. convert-char-method % terminal's convert-character method
  41. )
  42. ()
  43. (gettable-instance-variables height width cursor-row cursor-column)
  44. (initable-instance-variables terminal)
  45. )
  46. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  47. % Private Macros:
  48. (defmacro image-fetch (image row col)
  49. `(vector-fetch (vector-fetch ,image ,row) ,col))
  50. (defmacro image-store (image row col value)
  51. `(vector-store (vector-fetch ,image ,row) ,col ,value))
  52. (defmacro range-create ()
  53. `(cons 10000 0))
  54. (defmacro range-cons (min max)
  55. `(cons ,min ,max))
  56. (defmacro range-min (r)
  57. `(car ,r))
  58. (defmacro range-max (r)
  59. `(cdr ,r))
  60. (defmacro range-set-min (r x)
  61. `(rplaca ,r ,x))
  62. (defmacro range-set-max (r x)
  63. `(rplacd ,r ,x))
  64. (defmacro range-reset (r)
  65. `(let ((*r* ,r))
  66. (rplaca *r* 10000) (rplacd *r* 0)))
  67. (defmacro range-empty? (r)
  68. `(< (range-max ,r) (range-min ,r)))
  69. (defmacro range-within? (r x)
  70. `(and (<= (range-min ,r) ,x) (<= ,x (range-max ,r))))
  71. (defmacro range-extend (r x)
  72. `(let ((*r* ,r) (*x* ,x))
  73. % New minimum if x < old minimum
  74. (if (< *x* (range-min *r*)) (range-set-min *r* *x*))
  75. % New maximum if x > old maximum.
  76. (if (> *x* (range-max *r*)) (range-set-max *r* *x*))
  77. ))
  78. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  79. % Public methods:
  80. (defmethod (physical-screen ring-bell) ()
  81. (=> terminal ring-bell))
  82. (defmethod (physical-screen enter-raw-mode) ()
  83. (=> terminal enter-raw-mode))
  84. (defmethod (physical-screen leave-raw-mode) ()
  85. (=> terminal leave-raw-mode))
  86. (defmethod (physical-screen get-character) ()
  87. (apply get-char-method (list terminal)))
  88. (defmethod (physical-screen convert-character) (ch)
  89. (apply convert-char-method (list terminal ch)))
  90. (defmethod (physical-screen normal-enhancement) ()
  91. (=> terminal normal-enhancement))
  92. (defmethod (physical-screen highlighted-enhancement) ()
  93. (=> terminal highlighted-enhancement))
  94. (defmethod (physical-screen supported-enhancements) ()
  95. (=> terminal supported-enhancements))
  96. (defmethod (physical-screen write) (ch row col)
  97. (when (~= ch (image-fetch new-image row col))
  98. (image-store new-image row col ch)
  99. (range-extend changed-row-range row)
  100. (range-extend (vector-fetch changed-column-ranges row) col)
  101. ))
  102. (defmethod (physical-screen set-cursor-position) (row col)
  103. (setf cursor-row row)
  104. (setf cursor-column col))
  105. (defmethod (physical-screen refresh) (breakout-allowed)
  106. (for (from row (range-min changed-row-range)
  107. (range-max changed-row-range))
  108. (for break-count 0 (+ break-count 1))
  109. (with changed-columns breakout)
  110. (until (and breakout-allowed
  111. (= (& break-count 3) 0) % test every 4 lines
  112. (input-available?)
  113. (setf breakout T)))
  114. (do
  115. (setf changed-columns (vector-fetch changed-column-ranges row))
  116. (when (not (range-empty? changed-columns))
  117. (apply update-line-method
  118. (list terminal
  119. row
  120. (vector-fetch displayed-image row)
  121. (vector-fetch new-image row)
  122. changed-columns
  123. ))
  124. (range-reset changed-columns)))
  125. (finally
  126. (range-set-min changed-row-range row)
  127. (if (range-empty? changed-row-range)
  128. (range-reset changed-row-range))
  129. (if (not (or breakout
  130. (and breakout-allowed (input-available?))))
  131. (apply move-cursor-method
  132. (list terminal cursor-row cursor-column)))
  133. )
  134. ))
  135. (defmethod (physical-screen full-refresh) (breakout-allowed)
  136. (=> terminal erase)
  137. (for (from row 0 maxrow)
  138. (with line range)
  139. (do (setq range (vector-fetch changed-column-ranges row))
  140. (range-set-min range 0)
  141. (range-set-max range maxcol)
  142. (setf line (vector-fetch displayed-image row))
  143. (for (from col 0 maxcol)
  144. (do (vector-store line col (char space)))
  145. )
  146. ))
  147. (range-set-min changed-row-range 0)
  148. (range-set-max changed-row-range maxrow)
  149. (=> self refresh breakout-allowed)
  150. )
  151. (defmethod (physical-screen write-to-stream) (s)
  152. (for (from row 0 maxrow)
  153. (with line)
  154. (do (setf line (vector-fetch displayed-image row))
  155. (for (from col 0 maxcol)
  156. (do (=> s putc (dc-character-code (vector-fetch line col))))
  157. )
  158. (=> s put-newline)
  159. ))
  160. )
  161. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  162. % Private methods:
  163. (defmethod (physical-screen init) (init-plist) % For internal use only!
  164. (setf height (=> terminal height))
  165. (setf maxrow (- height 1))
  166. (setf width (=> terminal width))
  167. (setf maxcol (- width 1))
  168. (setf cursor-row 0)
  169. (setf cursor-column 0)
  170. (setf displayed-image (=> self create-image))
  171. (setf new-image (=> self create-image))
  172. (setf changed-row-range (range-create))
  173. (setf changed-column-ranges (MkVect maxrow))
  174. (for (from row 0 maxrow)
  175. (do (vector-store changed-column-ranges row (range-create))))
  176. (setf update-line-method (object-get-handler terminal 'update-line))
  177. (setf move-cursor-method (object-get-handler terminal 'move-cursor))
  178. (setf get-char-method (object-get-handler terminal 'get-character))
  179. (setf convert-char-method (object-get-handler terminal 'convert-character))
  180. )
  181. (defmethod (physical-screen create-image) ()
  182. (let ((image (MkVect maxrow))
  183. (line (MkVect maxcol))
  184. )
  185. (for (from col 0 maxcol)
  186. (do (vector-store line col (char space)))
  187. )
  188. (for (from row 0 maxrow)
  189. (do (vector-store image row (copyvector line)))
  190. )
  191. image))