cwin.tex 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. \documentclass[a4paper,11pt]{article}
  2. \title{The CWIN-2 Windows Interface Code}
  3. \author{A C Norman}
  4. \begin{document}
  5. \maketitle
  6. \section{Introduction}
  7. This document is not too concerned about internal data structures or
  8. programming issues, but will attempt to document the behaviour I will
  9. implement and in some cases explain why I did things that way. The
  10. explanation is needed because while writing the code (and its predecessors)
  11. I found it hard to make scrolling, selection, cut \& paste operations,
  12. font changes, user input and program output all interact properly.
  13. First the fundamentals. I will support a window that always has both
  14. horizontal and vertical scroll bars visible.
  15. To start with it will contain just text, but parts of that will be
  16. shown in differing colours to mark out where there are prompts. I will
  17. allow for the possibility that in a later version the text in the buffer
  18. can be displayed in various fonts, sizes and with various effects.
  19. The unit of display will be a ``line'' which is represented as a block
  20. of characters and all effects withing the block will be indicated by
  21. embedding control sequences within it. Each line will start off in
  22. a standard font configuration.
  23. The user types in characters, uses the DELETE key, activates scroll bars,
  24. uses the mouse to re-position the caret and/or establish a selection
  25. region, and invoked CUT and PASTE operations.
  26. There is a program running that will, from time to time, request characters
  27. from the user. Before doing so it can select the prompt that should be used.
  28. It can also generate output. There is no automatic supposition about how
  29. long the program delays between I/O requests and how it interleaves reads
  30. and writes.
  31. The stored text lives in a buffer that has finite size, and so after a
  32. program has done enough the buffer will fill up and parts of it will need to
  33. need to be recycled.
  34. \section{Scrolling under user control}
  35. If the whole of the text buffer can fit on within the window vertically
  36. the the vertical scroll bar has no effect, and any attempt to position
  37. it to anywhere other than the ``top'' position has no effect. If there are
  38. more lines of text than will fit on the screen at once the vertical
  39. scroll bar (and related short-cut keys, viz page-up, page-down, home and
  40. end) cause the window to scroll. Scrolling is limited so that at one
  41. extreme the first line of input text is visible at the top of the
  42. window and at the other extreme the final line of text is just fully visible
  43. at the bottom of the window.
  44. If the collection of lines displayed in the window are all short enough
  45. to fit completely across it then the horizontal scroll position is forced
  46. to its home (leftmost) position and attempts to move it have no effect.
  47. Otherwise the user may scroll horizontally up to an extreme where the
  48. longest line that lies within the window comes just half way across the
  49. window.
  50. If the window size of font is changed scrolling can be activated to keep
  51. the conditions described above true. In particular this means that when
  52. the window is enlarged it will scroll to keep the last line of the text
  53. visible as the last line in the window, and to keep horizontally scrolled
  54. information visible at least half way across the window. Resizing the
  55. window will update the position the the scroll-bar thumbs to reflect
  56. what has happened. There can also be scrolling caused by input and output
  57. operations, but that is discussed in a moment under the heading AUTO-
  58. SCROLLING.
  59. The END operation moves the caret to an extreme end of the
  60. text and scroll the window to make it visible. HOME scrolls the window
  61. to show the very top of the text, but does not re-position the caret.
  62. \section{Use of the mouse to select regions of text}
  63. The caret is considered to lie between a pair of characters (or right at
  64. the very start or very end of the text). Text forming a ``prompt'' is treated
  65. as representing a single item, and so the mouse can not select a position
  66. within the prompt text. Pressing the left mouse button causes the caret to
  67. be moved to the gap nearest to the mouse position. The place where the mouse
  68. button was depressed becomes the root of a possible selection region.
  69. From when the mouse button was depressed to when it is released the mouse
  70. is captured by the window, in the sense that even if the mouse moves outside
  71. the window's borders its activity is still tracked. If the mouse is moved
  72. with the button down a region of text becomes selected. The text in that
  73. region is displayed in a form of inverse video (exact details depend on the
  74. windows colour scheme in force). If the mouse is dragged above or below the
  75. window while making a selection the window is scrolled in the relevant
  76. direction, and the speed of scrolling increases if the mouse remains outside
  77. the window for a while. If the mouse moves to the left of the window and
  78. the window has already been scrolled horizontally it will be gradually
  79. restored. If the mouse goes to the right of the window scrolling will be
  80. activated if the line that the mouse is on extends beyond the right hand
  81. border of the current window.
  82. Pressing the (left) mouse button with SHIFT held down results in a selection
  83. being extended from its original root to the new mouse position. Thus
  84. clicking in one place and then shift-clicking in another sets up a selection
  85. from the first to second place.
  86. The shift-click operation relies upon a previously set selection root. If none
  87. has been established before then shift-click behaves just like an ordinary
  88. click. Once set by an initial click a selection root remains valid until
  89. another mouse click (which re-positions it) or until buffer wrapping deletes
  90. some characters from the buffer (eventually almost any input or output
  91. operation will cause this) or until the user deletes a character from the
  92. text using the DELETE key. CUT operations can leave a selection root
  93. set at the place where the removed material used to be.
  94. The COPY operation copies all characters from the selection to the clipboard.
  95. If control characters are present they are sent to the clipboard without
  96. adjustment. Lines sent to the clipboard have CR/LF at their end as
  97. termination. CUT acts as COPY but then the selected region is deleted.
  98. RE-INPUT performs a COPY and then PASTEs the material into the input
  99. buffer(but because it uses COPY it places the selected text into the clipboard
  100. on the way). SELECT-ALL does what it says (and does not move the caret).
  101. CLEAR throws away all text in the display buffer. Immediately after a CUT
  102. operation the UNDO\footnote{For a first version of this interface I will
  103. not implement UNDO.} button will re-position the caret to the place where
  104. material was deleted and will perform a PASTE. Only one level of CUT can
  105. be UNDOne.
  106. A DELETE when a selection has been set up will delete the selection (but not
  107. do the COPY operation that a CUT would). Part of an effect will be that
  108. a DELETE may not keep quite so much stuff for UNDO as would a CUT.
  109. COPY operations can fail if the clipboard can not be opened or if it
  110. proves impossible to allocate windows global memory for the text that was to
  111. be copied. In such cases the fact that the COPY failed will not be indicated
  112. to the user, and in the case of a CUT it will not be possible to UNDO the CUT.
  113. \section{Program-generated output}
  114. This is always inserted at the end of the buffer. If the caret is at the end
  115. of the text it moves as new text is inserted, and in this case if the caret
  116. starts off visible the screen is scrolled automatically to keep the caret
  117. position visible. This may involve horizontal as well as vertical scrolling,
  118. but an attempt will be made to delay auto-scrolling so that it does not happen
  119. too often.
  120. Action has to be taken when the buffer becomes full. The buffer can be ``full''
  121. either because the maximum number of characters have been stored in it or
  122. because it holds the maximum number of lines that it is configured for
  123. (at present I will allow for 64K characters and 2K lines). In normal
  124. circumstances when the buffer overflows the oldest whole line of text
  125. stored in it is discarded. This policy is modified in various circumstances:
  126. \begin{enumerate}
  127. \item If the buffer contains only one (incomplete) line of text then the
  128. system throws the entire buffer contents away. If there were unbalanced
  129. control sequences in the buffer the subsequent display may be mangled,
  130. for instance by being in the wrong colour or font.
  131. This case can only arise if the program being run keeps
  132. printing large numbers of characters without an intervening newline.
  133. I really hope this circumstance does not arise! I specify this extreme
  134. behaviour because it is hard to indicate a safe way of abandoning a
  135. part-line if I intend in due course to put elaborately interpreted
  136. in the buffer. A possible safer refinement here would be to discard any
  137. further characters inserted into the buffer until a newline. But at
  138. present it does not seem worth while legislating for such a desparate
  139. and (I hope) unusual situation.
  140. \item If the line that is to be discarded overlaps with a region of text that
  141. has been selected the system pauses, changing the title bar of the window
  142. to alert the user to what has happened. This delay is so that the user can
  143. complete a COPY operation to preserve line that is about to be lost, or
  144. a PRINT (for the same reason). When the selection is cancelled for any
  145. reason the line will become vulnerable and output can continue.
  146. \item If the line for that is to be deleted is not involved in a selection
  147. but it is visible on the screen and the end of the text (ie the insertion
  148. point) is not visible, then again the system pauses. This allows for the
  149. case where a user has scrolled up the display to inspect an early part of
  150. a transaction, and would not like it to vanish untill the scroll back down
  151. to the end. I allow the line to be deleted anyway in the case that all
  152. the lines of input are visible on the screen: this case can only arise
  153. when at least one of the lines of output is amazingly long. This is
  154. because the user could not then scroll the window to give the system a
  155. hint that it should proceed.
  156. \end{enumerate}
  157. If output is generated and after it has been put on the screen the window
  158. is not scrolled down as far as it will go then output will need to update the
  159. vertical scroll thumb's position. For instance if before the output was
  160. generated the scrollbar thumb was at the 50\% position, afterwards it will
  161. typically be higher up. Discarding old text can also influence the
  162. position where the thumb should be shown.
  163. \section{Keyboard and PASTE input}
  164. If there is a selection active then DELETE or BACK\footnote{On my keyboard
  165. this is a key marked with a left-arrow, positioned above the ENTER key, and
  166. is the one that I usually use to delete characters.} deletes it, and has no
  167. other effect. Otherwise BACK deletes the character before the caret, or if that is the end of a
  168. prompt it deletes the whole prompt. DELETE deletes the character (or prompt)
  169. after the caret. If the caret is at the start of the text then BACK does
  170. nothing, while if it is at the end DELETE does nothing.
  171. After a consecutive series of DELETE operations an UNDO will re-insert the
  172. whole block of deleted characters, but there will be
  173. a limit to the number of characters that will be stored, so this can only
  174. be relied upon for small operations.
  175. The effect of keyboard input depends on whether the caret is at the
  176. end of the text or within the buffer. To a more minor extent it also
  177. depends on whether the caret (while within the text as a whole) identifies
  178. a position within a currently active input line.
  179. When the caret is not at the end of the text, normal characters are inserted
  180. before the caret. The region covered by an insert is recorded so that after
  181. a PASTE operation UNDO will discard what was inserted, while after
  182. individually typed characters each UNDO will delete either a block of
  183. characters typed without repositioning the caret or a block of characters
  184. that end at a newline. As usual there will be a limit to how much undoing can
  185. be done, and the exact rule for where that limit is is not documented and
  186. nobody should ever rely on it.
  187. Inserting characters into the middle of the text like this might overfill the
  188. buffer, and in that case the first line of the buffer gets discarded to make
  189. space. There will be no delay in this even if the first line forms part of
  190. a selection (the starting point of the selection will move to the start of the
  191. next line, and maybe the selection will vanish totally). There will be a
  192. special case if the caret is in the first line when the user tries to insert
  193. more - in this case the insertion will fail. If it is from the keyboard
  194. the system beeps and discards the single offending character. If it is
  195. part of a PASTE then characters are ignored up to the next newline in the
  196. pasted text, which is notionally inserted and then the resulting first line
  197. is then thrown away. I guess in this case it means that if the caret is right
  198. at the start of the buffer all the inserted stuff gets abandoned.
  199. Characters inserted at (or in some cases near) the end of the text can be
  200. used as program input. If the caret is at the end of the text typed-in
  201. chaarcters are placed in a type-ahead buffer until the program requests
  202. a line of input. When that happens characters are accepted from the type-ahead
  203. buffer (and/or the PASTE source) and echoed to the screen until a newline is
  204. seen. If the user types a newline at the end of the input line the characters
  205. in it are moved to a program-input-buffer which is where the program reads
  206. them from. If the user re-positions the caret and inserts a newline into the
  207. middle of the input line then pre-typed characters in the line but after
  208. where the newline was get pushed back into the type-ahead buffer (and if that
  209. overflows they are lost with a beep). The effect is that the program gets
  210. one line at once and when that line is placed in its input buffer it will just
  211. have been echoed to the screen. The program-input-buffer will have limited
  212. length and truly ridiculously long input will be silently truncated when
  213. moved into it. I will feel entitled to reject input activity that I notice
  214. creating an input line that is longer then that limit.
  215. An elaboration on this explanation is that part of the final line in the
  216. text buffer can be an incomplete input line. This can start part way along
  217. the line (eg it will tend to start after the displayed prompt). After various
  218. CUT and DELETE operations or when the program requests input after printing
  219. a line that was not terminated it can start well along the final line. An
  220. incomplete line is created when the program requests a line of input. When
  221. the user inserts a newline into the incomplete line it becomes complete, its
  222. contents are moved elsewhere and there is no longer an incomplete line.
  223. When a PASTE operation copies material into the middle of a document any
  224. prompts are inserted. But if then some of that line is moved out to the
  225. program-input-buffer prompts are discarded during the move. If PASTE puts
  226. stuff right at the end of the buffer it omits any prompts in the pasted
  227. stuff. But the start of each line of input that is echoed will get a fresh
  228. prompt displayed on it.
  229. When the program that is being run is halted waiting for input and the
  230. screen has been scrolled such that the end of the buffer the window title is
  231. changed to ``waiting for input''.
  232. Pressing any key or performing a PASTE operation always scrolls the window
  233. to make the caret visible. The caret can only have become invisible as a
  234. result of a user-initiated scroll request (or HOME) since except when such a
  235. request has hidden it the window scrolls automatically to keep it visible.
  236. Note that the rules given here indicate that characters are only inserted into
  237. the buffer at two distinct places: where the caret is and at the end of the
  238. buffer. So the implementation can survive if it just caches information about
  239. those two positions.
  240. \section{UNDO --- a summary}
  241. There is an undo buffer that can store a limited number of characters
  242. and a limited number of transactions. A transaction identifies a caret
  243. position or a range within the text, an possibly a sequence of associated
  244. characters:
  245. \begin{enumerate}
  246. \item After a PASTE that happened within the body of the text and did not
  247. terminate an input line an UNDO discards the inserted material;
  248. \item After a PASTE that put one or more newlines into the input area no
  249. UNDO will be possible (because some of the inserted text has been passed
  250. on to the appication code to process);
  251. \item After a CUT followed possibly by operations that move the caret an UNDO
  252. re-positions the caret and does inserts characters as for a PASTE (but
  253. that paste is not itself undoable);
  254. \item After a sequence of DELETE keys have been pressed an UNDO will re-insert
  255. the deleted characters. It can re-instate deleted prompts.
  256. \item Sequences of non-delete characters are collected up to the point of
  257. a newline. If the newline causes transmission of the characters to
  258. the program no UNDO is possible. Otherwise each block up to a newline
  259. is an UNDO unit.
  260. \item Previously stored UNDO operations can become invalid if they overlap
  261. with a non-undo-able operation or if the text that they relate to gets
  262. abandoned as the main text buffer rolls, or if the undo stack becomes
  263. over-full. [Is this hard to implement reliably?]
  264. \end{enumerate}
  265. \section{Auto-scrolling --- a summary}
  266. If the user never re-positions the caret it will remain at the extreme end of
  267. the text buffer. And scrolling will occus to keep it visible because
  268. \begin{enumerate}
  269. \item Program output will occurs with the caret at the end and visible;
  270. \item Input requests will be handled with the caret at the end of the buffer.
  271. \end{enumerate}
  272. If the user scrolls the window back (using the scroll bars) so that the caret
  273. becomes invisible then scrolling on output will cease, but the screen will
  274. jump to make the insertion point visible if a key is pressed and the
  275. program is requesting input (if the program is NOT requesting input yet the
  276. key-stroke just goes in a type-ahead buffer and nothing special happens).
  277. If the user has moved the caret to other than at the end of the buffer
  278. then the window is never scrolled by cwin, but in cases when it might
  279. be interesting to scroll it the title text of the window is updated to
  280. give the user a clue to that fact.
  281. \section{Print and other operations}
  282. The regular PRINT item on the menu should just print the whole of the
  283. contents of the text buffer. It will apply a fixed with limit and truncate
  284. any material that spills off to the right. It will pack lines onto pages
  285. in a simple-minded manner. PRINT-SELECTION behaves the same way but
  286. only processes text within the selected region of text.
  287. The READ menu operation will insert text of the form
  288. \begin{verbatim}
  289. IN "<filename>";
  290. \end{verbatim}
  291. into the type-ahead buffer.
  292. \section{Implementation status}
  293. \begin{description}
  294. \item{User-controlled scrolling:} OK
  295. \item{Selection using the mouse:} OK
  296. \item{CUT:} OK
  297. \item{Program output:} OK, but optimisation and find control over
  298. when the screen gets re-painted will need further work, I expect.
  299. \item{Keyboard input:} DELETE OK. Input OK.
  300. \item{Paste:} Paste clumsy in middle of text (works character by character
  301. because multi-char inserts seem to be bug-ridden). Paste at end seems
  302. OK.
  303. \item{UNDO:} Nothing done at all yet, and will need re-work of other buffer
  304. update operations to preserve information.
  305. \item{Print:} Nothing done yet, and the issue of line width of the paper used
  306. relative to the current window size is unclear.
  307. \item{Other operations:} READ is not done yet, but is probably easy.
  308. \end{description}
  309. \end{document}