home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2885 < prev    next >
Internet Message Format  |  1991-02-28  |  51KB

  1. From: guido@cwi.nl (Guido van Rossum)
  2. Newsgroups: alt.sources
  3. Subject: STDWIN documentation (report)
  4. Message-ID: <3049@charon.cwi.nl>
  5. Date: 28 Feb 91 13:34:14 GMT
  6.  
  7. .\" Typeset using refer -e -n | (di)troff -ms.
  8. .\" You may have to change the CW (Constant Width) macro define below
  9. .\" if you aren't typesetting on a PostScript printer.
  10. .\" Your best bet is to change ".ft C" by ".ft I" and "\fC" by "\fI".
  11. .\" Each occurs exactly once in the macro definition.
  12. .de CW
  13. .if t .if "\\$1"" .ft C
  14. .if t .if !"\\$1"" \fC\\$1\fP\\$2
  15. .if n .B "\\$1" "\\$2"
  16. ..
  17. .TL
  18. .nr PD 0
  19. .nr PI 2n
  20. .ft H
  21. .ps 14
  22. STDWIN \- A Standard Window System Interface
  23. .ps
  24. .ft
  25. .AU
  26. .ft H
  27. Guido van Rossum
  28. .ft
  29. .AI
  30. .ft HO
  31. .ps 8
  32. .vs 10
  33. Center for Mathematics and Computer Science
  34. P.O. Box 4079, 1009 AB Amsterdam, The Netherlands
  35. E-mail: guido@cwi.nl or mcvax!guido
  36. .vs
  37. .ps
  38. .ft
  39. .AB
  40. .LP
  41. STDWIN is an interface layer placed between an application written in C
  42. and arbitrary window system, making the use of windows both easier and
  43. more portable.
  44. For applications using STDWIN
  45. for their window management requirements, adaptation to a
  46. different window system is as easy as linking with an appropriate
  47. version of the STDWIN library.
  48. So far, STDWIN libraries are available
  49. for the Apple Macintosh,
  50. for the Whitechapel MG-1 (running Oriel),
  51. for MIT's X Window System version 11,
  52. for the Atari ST,
  53. and (subsets) for alphanumeric terminals on
  54. .UX
  55. and MS-DOS.
  56. .FS
  57. .ft H
  58. .sp
  59. Report CS-R8817
  60. .br
  61. Centre for Mathematics and Computer Science
  62. .br
  63. P.O. Box 4079, 1009 AB Amsterdam, The Netherlands
  64. .ft
  65. .FE
  66. New implementations are easily written.
  67. .PP
  68. Like STDIO, C's Standard I/O library, STDWIN's aim is to give
  69. a simple interface, high-level functionality, and portability.
  70. It does not attempt to allow access to all possible features of window
  71. management systems; rather, it provides the programmer with a
  72. model which allows easy construction of that part of the program which
  73. is concerned with window management.
  74. .PP
  75. STDWIN's high-level operations include automatic window positioning
  76. and resizing, scrolling, menus, keyboard shortcuts, and multiple-click
  77. detection.
  78. .sp
  79. .ps 8
  80. .vs 10
  81. .ft HO
  82. 1980 Mathematics Subject Classification:
  83. .ft
  84. .ft H
  85. 68B20.
  86. .ft
  87. .br
  88. .ft HO
  89. 1982 CR Categories:
  90. .ft
  91. .ft H
  92. D.2.2, I.3.4, I.3.6.
  93. .ft
  94. .br
  95. .ft HO
  96. Key Words & Phrases:
  97. .ft
  98. .ft H
  99. window systems, user interfaces, portability.
  100. .ft
  101. .br
  102. .ft HO
  103. Note:
  104. .ft
  105. .ft H
  106. This paper has been submitted for publication elsewhere.
  107. .ft
  108. .vs
  109. .ps
  110. .AE
  111. .LP
  112. .NH
  113. Introduction
  114. .LP
  115. First, some history.
  116. STDWIN's conception was motivated by the desire to add a more modern
  117. user interface (i.e., one using windows and a mouse)
  118. to the programming environment for the language ABC,
  119. developed here at CWI.
  120. .[
  121. %A Leo Geurts, Lambert Meertens, Steven Pemberton
  122. %T The ABC Programmer's Handbook
  123. %I CWI
  124. %C Amsterdam
  125. %D to be published in 1988
  126. .]
  127. The ABC programming environment, consisting of a syntax-directed editor,
  128. an interpreter and a source file manager, is a large body of C
  129. code which, through careful isolation of system-dependent modules, has
  130. proven to be quite portable, both to different versions of
  131. .UX
  132. and to non-\c
  133. .UX
  134. systems such as MS-DOS and the Apple Macintosh.
  135. Naturally, we did not want to lose its portability by tying
  136. it closely to one particular window system.
  137. .PP
  138. Only after having looked closely at a few existing window systems, we
  139. became fully aware of the problems.
  140. Most window systems offer a large range of facilities, apparently
  141. intended to enable programmers to create beautiful user interfaces,
  142. but often resulting in total chaos.
  143. .[
  144. %A Mike O'Dell
  145. %B EUUG Conference Proceedings, September 1987, Dublin, Ireland
  146. %T What They Don't Tell You About Window Systems
  147. .]
  148. One of the problems appears to be the low level of most window system
  149. interfaces.
  150. For example, on the Apple Macintosh, all tools are provided to
  151. work with scroll bars (bit-scrolling operations, routines to draw scroll
  152. bars, routines to detect user interaction with a scroll bar), but the
  153. amount of code needed to glue these together and create a scrollable
  154. view on a document is horrendous.
  155. .[
  156. %T Inside Macintosh
  157. %A Apple Computer
  158. %I Addison-Wesley
  159. %C Reading, Mass.
  160. %D 1985
  161. .]
  162. Similarly, again on the Macintosh, double-clicking the mouse button is
  163. a frequent form of user input, but there is no library routine available
  164. to detects double-clicks, leading to much code duplication and
  165. gratuitous differences between programs.*
  166. .FS
  167. * In all fairness it should be said that the Macintosh is still miles
  168. ahead of most of its competitors, simply because there are at least
  169. standards for many aspects of the interaction between application
  170. and user, such as the placement of scroll bars, the use of double clicks
  171. or the shape of the mouse cursor.
  172. .FE
  173. .PP
  174. With these considerations in mind, we set out to design a `generic'
  175. window system interface.
  176. .sp
  177. .IP \(bu
  178. The interface should be general enough to suit the needs of many
  179. different programs.
  180. Thus, it should be reasonably rich in functionality, e.g., provide both
  181. textual and graphical output, handle keyboard, mouse and menu-based
  182. input, support multiple windows, etc.
  183. .IP \(bu
  184. It should be simple to use.
  185. Including one header file and calling a
  186. small number of routines (with not too many parameters!) should suffice
  187. for the creation of a full-function window and the definition of its
  188. contents.
  189. As much as possible, the programmer should only be bothered with issues
  190. that matter from the program's point of view.
  191. In other words, the interface should be `high level'.
  192. .IP \(bu
  193. And most of all, it should be realistically portable; each potential
  194. feature should be weighed in the light of its implementability using
  195. different systems, including several popular micros.
  196. .sp
  197. .LP
  198. The requirement of portability is necessarily both good and bad.
  199. It is bad because it can sometimes make an elegant solution unfeasible,
  200. imposing seemingly random restrictions.
  201. But it is good because it makes the design stick to reality, and limits
  202. it to the `essence' of window systems, rather than allowing the
  203. designers to invent yet another incompatible paradigm.
  204. And sometimes the `helicopter view' gained from looking at
  205. solutions chosen by vastly different window systems for a particular
  206. problem has shown the way to an entirely new view, simplifying it by
  207. generalization.
  208. .sp
  209. .LP
  210. A large part of the paper is devoted to a detailed description of
  211. STDWIN's functionality from a programmer's point of view.
  212. First the `core' of the package is described, explaining the basic
  213. output and input facilities;
  214. then some extra facilities are briefly discussed.
  215. Interspersed are comments on the rationale for particular solutions,
  216. some hints on the implementation, and warnings about non-portable uses.
  217. At the end the paper returns to the more philosophical issues:
  218. experiences, future developments, food for thought.
  219. .NH
  220. Description
  221. .LP
  222. .NH 2
  223. Header file
  224. .LP
  225. Applications wishing to use STDWIN must place a line saying
  226. .CW "#include <stdwin.h>"
  227. near the top of their source file(s).
  228. All user-visible external names defined in this header file start with
  229. .CW w
  230. or
  231. .CW W .
  232. external names used internally by implementations begin with
  233. .CW _w
  234. or
  235. .CW _W .
  236. .NH 2
  237. Initialization and clean-up
  238. .LP
  239. Before starting to use STDWIN, the initialization routine
  240. .CW "winit()"
  241. must be called.
  242. Before exiting, the application should call
  243. .CW "wdone()"
  244. to perform any necessary clean-up operations.
  245. .PP
  246. These calls can't be repeated; after
  247. .CW "wdone()"
  248. has been called the application cannot call
  249. .CW "winit()"
  250. again and `return to life'.
  251. .NH 2
  252. Creating and destroying windows
  253. .LP
  254. A new window is created by calling
  255. .CW "wopen(title, drawproc)" .
  256. .I Title
  257. is a string identifying the window to the user; it is usually displayed
  258. by STDWIN in the window's border, e.g., in a title bar.
  259. .I Drawproc
  260. is the address of the window's draw procedure (see next section), or
  261. NULL if the window is not to have a draw procedure.
  262. STDWIN windows look like windows in the usual style of the underlying
  263. window system, usually with a title bar, scroll bars etc.
  264. Position, size and other characteristics of the new window are
  265. determined by STDWIN (but see below).
  266. .PP
  267. .CW "Wopen"
  268. returns a
  269. .I "window pointer" ,
  270. of type
  271. .CW "WINDOW *" ,
  272. to be used to identify the window in subsequent operations.
  273. If creation of the window failed, a NULL pointer is returned.
  274. .PP
  275. STDWIN allows an application to have multiple windows open simultaneously.
  276. Implementations usually impose a limit on the number of open
  277. windows; when this limit is reached,
  278. .CW "wopen"
  279. returns NULL, and the application should try to close other windows
  280. (or prompt the end user to close them).
  281. .PP
  282. A window is deleted permanently by calling
  283. .CW "wclose(win)" .
  284. Windows can be deleted only by the application.
  285. The end user can send a request to the application to close a window,
  286. but the application may ignore the request or postpone its execution.
  287. .PP
  288. There is no explicit way to iconize
  289. a window (i.e., to temporarily close it, leaving an icon in its place).
  290. On systems where window iconization is built into the window system,
  291. STDWIN may support it silently; all the application notices is that no
  292. input is received for iconized windows.
  293. .NH 3
  294. Changing defaults
  295. .LP
  296. When a window is opened STDWIN determines
  297. a default size and position for it.
  298. Usually this is convenient for the application (which needn't
  299. have its own algorithm for placing multiple windows, for example),
  300. but sometimes finer control is desirable.
  301. Therefore, a number of default-setting routines are provided:
  302. .LP
  303. .CW "wsetdefwinsize(width, height)"
  304. .IP
  305. Changes the default window size.
  306. This sets the net size, excluding borders, scroll bars etc.
  307. .LP
  308. .CW "wsetdefwinpos(h, v)"
  309. .IP
  310. Changes the default window position.
  311. This default is usually not a constant but a dynamically computed value.
  312. The next opened window will be placed at
  313. .I "(h, v)" ;
  314. the position of windows opened after that may be a more complicated
  315. function of
  316. .I h
  317. and
  318. .I v .
  319. .LP
  320. These routines may be called at any time; they affect only windows
  321. opened after their call.
  322. A negative or zero parameter restores the default for that
  323. dimension.
  324. Other values are clipped or rounded to reasonable and implementable
  325. values; these routines are best seen as giving hints to STDWIN, which
  326. may be ignored by some implementations.
  327. .NH 2
  328. The output model
  329. .LP
  330. A STDWIN window is a view on a possibly much larger area,
  331. a rectangle referred to as its
  332. .I document ,
  333. in which the application draws its output.
  334. The document's size is chosen by the application, and can be changed at
  335. any time by calling
  336. .CW "wsetdocsize(win, width, height)" .
  337. It is not limited by window or screen size, nor indeed by available
  338. memory; the entire document's contents are not stored directly.
  339. The end user has the freedom to `pan' the window over the document's
  340. surface, using scroll bars or a similar mechanism.
  341. When a particular part of the document is to be visible in the window,
  342. STDWIN asks the application to repaint that area.
  343. It is not forbidden to draw outside the document, but the end
  344. user normally can't pan outside the document (unless the window is
  345. larger than the document).
  346. .PP
  347. There are two mechanisms for repainting: a low-level mechanism using
  348. DRAW events, and a higher-level mechanism using a
  349. .I "draw procedure" .
  350. .PP
  351. DRAW events are merged with the general event stream (see below); when
  352. no other events are in the event queue, STDWIN looks to see if
  353. there is any window needing a repaint, and if so, it passes a DRAW event
  354. for that window to the application.
  355. A DRAW event includes as additional information the rectangle
  356. that is to be repainted.
  357. The application should react by erasing and repainting that rectangle
  358. (or a larger part of the document).
  359. .PP
  360. Normally, however, windows have an associated
  361. .I "draw procedure" .
  362. This is a procedure (defined by the application) which knows how to draw
  363. the entire document, or any sub-rectangle of it.
  364. When STDWIN is about to generate a DRAW event for a window with a draw
  365. procedure, it prepares the window for drawing, erases the rectangle
  366. that needs repainting, and calls the draw procedure with the window and
  367. the rectangle as parameters.
  368. The advantage of this mechanism over DRAW events is the possibility for
  369. certain STDWIN implementations to clip the output to a smaller,
  370. non-rectangular area that really needs a repaint; also somewhat simpler
  371. event decoding logic for the application.
  372. .PP
  373. Usually, the end user controls which part of the document is visible in
  374. the window (by manipulating the scroll bars).
  375. However, there are times when an application wants to display a particular
  376. part of the document, e.g. to show the effect of a search operation.
  377. It can then call
  378. .CW "wshow(win, <rectangle>)"
  379. to indicate that the given rectangle should be visible, if at all
  380. possible.
  381. STDWIN will check whether this is already the case, and if not, move
  382. the window with respect to the document to make it visible.
  383. There is also a lower-level call,
  384. .CW "wsetorigin(win, <point>)"
  385. which makes the given point in the document the top left corner of the
  386. window.
  387. .PP
  388. When the application wants to change part of the document, it can
  389. directly paint the changes (after preparing for drawing in that
  390. particular window).
  391. However, it is often more appropriate to delay the actual painting until
  392. after other input has been processed.
  393. It is possible to tell STDWIN that a particular area of the document
  394. needs repainting by calling
  395. .CW "wchange(win, <rectangle>)" .
  396. At the appropriate time, a DRAW event for this rectangle (possibly
  397. merged with other areas that need repainting) will be generated, or the
  398. window's draw procedure will be called.
  399. .PP
  400. When the repaint area is non-rectangular (e.g., it is the union of
  401. several rectangles), the application is asked to repaint the smallest
  402. rectangle that encloses the repaint area.
  403. This may occasionally cause more repainting than absolutely necessary,
  404. resulting in extra delays; since the repainting is limited to the window
  405. size, however, the costs won't be excessive in most cases.
  406. The choice was made here for a simple interface to the draw procedure,
  407. avoiding dynamic data structures.
  408. For the needs of the highest-demanding applications, an enquiry routine
  409. returning the exact repaint area may have to be be added
  410. (or a function telling
  411. whether a particular rectangle intersects the repaint area).
  412. .NH 2
  413. Drawing in a document
  414. .NH 3
  415. The coordinate system
  416. .LP
  417. STDWIN provides a single coordinate system per window.
  418. Coordinates are integers, with the X axis pointing right and the Y axis
  419. pointing down.
  420. In order to avoid confusion with other conventions, the axes
  421. are never called X and Y axis but h and v axis.
  422. H coordinates are always listed first.
  423. The origin (0, 0) is the top left corner of the document.
  424. Unit size equals pixel size on the screen; thus, documents inherit the
  425. screen's aspect ratio.
  426. Pixels on different machines can vastly differ in size; e.g.,
  427. on alphanumerical terminals,
  428. pixel size might well equal character cell size.
  429. Therefore, applications should scale their drawings accordingly.
  430. STDWIN provides enquiry functions to tell the physical size of a pixel.
  431. An alternative approach, suitable for applications that display mostly
  432. text, is to scale the drawing accordingly to the dimensions of
  433. characters drawn on the screen.
  434. Text measuring functions are available for this purpose (see below).
  435. .NH 3
  436. Preparation for drawing
  437. .LP
  438. Since a picture is usually built out of a large number of calls to
  439. primitive drawing operations, it would be annoying to have to specify
  440. a window parameter on each call.
  441. STDWIN requires the application to say in which window it wants to
  442. draw before using any drawing primitives, by calling
  443. .CW "wbegin\%draw\%ing(win)" .
  444. After the drawing is done, the application should call
  445. .CW "wend\%draw\%ing(win)" ,
  446. telling STDWIN to flush the output to the screen.
  447. .PP
  448. In a draw procedure these calls are unnecessary; there, all drawing
  449. operations apply to the given window, and output is flushed when the
  450. draw procedure returns.
  451. .NH 3
  452. Graphical primitives
  453. .LP
  454. STDWIN currently provides a small set of graphical primitives.
  455. This set will be extended when the need arises.
  456. All primitives except
  457. .CW werase
  458. and
  459. .CW winvert
  460. draw in OR mode, i.e., they only add black pixels to the drawing
  461. and never erase pixels.
  462. Note that points are actually given as two integer parameters, h and v;
  463. rectangles are given as four integer parameters:
  464. left, top, right and bottom.
  465. Rectangles always refer to the area enclosed by infinitely thin
  466. boundary lines; e.g., the rectangle (0, 0, 1, 1) encloses a 1 by 1
  467. square whose top left corner is the origin (0, 0).
  468. .PP
  469. Functions currently defined are:
  470. .LP
  471. .CW "wdrawline(<point1>, <point2>)"
  472. .IP
  473. Draws a line from point1 to point2.
  474. .LP
  475. .CW "wdrawbox(<rectangle>)"
  476. .IP
  477. Draws a box (i.e., a rectangle) inside the given rectangle.
  478. .LP
  479. .CW "wdrawcircle(<point>, radius)"
  480. .IP
  481. Draws a circle with the specified radius around the given point as
  482. center.
  483. .LP
  484. .CW "wpaint(<rectangle>)"
  485. .IP
  486. Paints the area inside the given rectangle black.
  487. .LP
  488. .CW "werase(<rectangle>)"
  489. .IP
  490. Erases the area inside the given rectangle.
  491. .LP
  492. .CW "winvert(<rectangle>)"
  493. .IP
  494. Inverts the pixels in the given rectangle.
  495. .LP
  496. .CW "wshade(<rectangle>, percentage)"
  497. .IP
  498. Adds a shading pattern to the given rectangle, approximately making the
  499. given percentage of all pixels black.
  500. Thus, a percentage of 0 has no effect;
  501. a percentage of 50 sets every other pixel;
  502. a percentage of 100 is equivalent to
  503. .CW "wpaint(<rectangle)" .
  504. The exact shading pattern used is implementation-dependent, as are the
  505. values to which percentages are rounded.
  506. .NH 3
  507. Text drawing primitives
  508. .LP
  509. STDWIN supports the drawing of characters in a font which may be
  510. proportionally spaced, depending on the implementation.
  511. The exact shape and size of the characters are implementation-dependent.
  512. STDWIN does not use the notion of a `base line' on which characters are
  513. drawn; rather, when a character or string is to be drawn, the top left
  514. corner of the box around it is given.
  515. All boxes have the same height, and a width appropriate for the
  516. character, so characters drawn in adjacent boxes `look right'.
  517. This approach has the advantage that the application needn't be
  518. concerned with such font parameters as base line, ascent, descent and
  519. leading; it can simply start drawing characters at (0, 0) and they
  520. will come out `right'.
  521. (This advantage for simplistic applications may turn into a disadvantage
  522. for programs wishing precise control over the placement of characters.
  523. In that case, additional enquiry functions will have to be defined
  524. to remedy this situation.)
  525. .PP
  526. The call
  527. .CW "wdrawchar(<point>, character)"
  528. draws the given character with its top left corner at the given point.
  529. It returns the h coordinate of the right edge of the box in which the
  530. character is drawn; this is the `natural' h coordinate for a character
  531. to be drawn next to it.
  532. .PP
  533. The call
  534. .CW "wdrawtext(<point>, string, length)"
  535. draws the characters of the given string starting with the top left
  536. corner at the given point.
  537. .I Length
  538. indicates the number of characters in the string;
  539. if negative, the string ends with a NUL character.
  540. .CW Wdrawtext
  541. returns the h coordinate of the right edge of the box in which the
  542. last character is drawn.
  543. Note that no special interpretation is given to characters like
  544. .CW \&'\en'
  545. or
  546. .CW \&'\et' ;
  547. they may be displayed as spaces or funny graphics.
  548. .NH 3
  549. Text measuring primitives
  550. .LP
  551. The dimensions of characters drawn by the above functions depend on the
  552. font used.
  553. Future versions may implement font and size changes under application
  554. control; currently these are fixed by the implementation.
  555. For applications that want to know in advance how big the strings they
  556. are drawing will be, there are functions to measure text dimensions.
  557. Unlike the drawing primitives,
  558. the text measuring primitives and the style-changing primitives
  559. described in the next section can be called anywhere.
  560. .PP
  561. The following text-measuring functions are defined:
  562. .LP
  563. .CW "wlineheight()"
  564. .IP
  565. Gives the vertical height of the boxes in which characters are drawn.
  566. This is the same for all characters, and the value delivered gives a
  567. `natural-looking' line spacing when lines are drawn at v coordinates
  568. with increments of this value.
  569. .LP
  570. .CW "wcharwidth(character)"
  571. .IP
  572. Computes the width of the box in which the given character will be drawn.
  573. .LP
  574. .CW "wtextwidth(string, length)"
  575. .IP
  576. Computes the width of the box in which the string will be drawn.
  577. .I Length
  578. indicates the number of characters in the string;
  579. if negative, the string ends with a NUL character.
  580. .LP
  581. .CW "wtextbreak(string, length, width)"
  582. .IP
  583. Computes the number of characters from the string that will fit in a box
  584. of the given width (in pixels).
  585. .I Length
  586. is interpreted as above.
  587. .NH 3
  588. Text style
  589. .LP
  590. Future versions of STDWIN will have to worry about mixing fonts,
  591. type sizes and text styles.
  592. Currently applications have no control over the font and size used, and
  593. can only control one aspect of text style;
  594. different window systems differ so much
  595. in their support of font names, font scaling, style combinations and so
  596. on, that it seemed wise to avoid these issues in the
  597. first version (however, some implementations have a way to influence
  598. the font, size or style used at initialization time).
  599. The only calls currently available are those to change between normal,
  600. black on white characters and inverse, white on black characters; this
  601. is needed to display the focus in the text-editing package (see below).
  602. .PP
  603. The call
  604. .CW "wsetinverse()"
  605. sets the text style to inverse characters; the call
  606. .CW "wsetplain()"
  607. reverts the text style back to normal.
  608. The text style is a global attribute, so draw procedures that change it
  609. should reset it to normal before leaving.
  610. .NH 3
  611. Scrolling
  612. .LP
  613. Applications like text editors often have a need for deleting a
  614. horizontal or vertical slice from their document; e.g., after a text
  615. editor has deleted a couple of lines, the remaining lines must be moved
  616. up in the document.
  617. Although it is theoretically possible to do this by calling
  618. .CW "wchange"
  619. for the remaining part of the document (assuming the draw procedure
  620. knows that the v coordinates of the affected lines have changed),
  621. this often involves a lot of drawing which could have been avoided by
  622. applying a `bit copy' operation as available in many systems,
  623. combined with only a little bit of redrawing
  624. (e.g., for lines `scrolled in' from below the window border).
  625. .PP
  626. The call
  627. .CW "wscroll(win, <rectangle>, dh, dv)"
  628. is provided to help in situation.
  629. It should be called outside the drawing procedure,
  630. where the call to
  631. .CW wchange
  632. would otherwise be placed.
  633. If the particular STDWIN implementation supports the requested type of
  634. bit scroll operation, it will scroll the bits inside the given
  635. rectangle by an amount of
  636. .I dh
  637. to the right and by
  638. .I dv
  639. downward.
  640. (Negative values mean scrolling to the left or upward, respectively.)
  641. No bits outside the given rectangle are affected or used:
  642. bits `scrolled out' of the rectangle will simply be thrown away; for
  643. the area that is to be `scrolled in' from outside the rectangle,
  644. .CW wchange
  645. is called internally.
  646. If the particular form of bit scrolling required isn't supported,
  647. the entire call is equivalent to
  648. .CW "wchange(win, <rectangle>)" ,
  649. relying on the normal repaint mechanism to update the window.
  650. .NH 2
  651. The input model
  652. .LP
  653. Interactive input is presented to the application in the form of
  654. .I events .
  655. Examples of events are `a character has been typed' or `the mouse button
  656. has been pressed'.
  657. Some other information generated asynchronously by STDWIN is also passed
  658. in the form of events.
  659. .PP
  660. Events are queued internally; the routine
  661. .CW "wgetevent"
  662. gets the next event from the queue and passes it to the application.
  663. If the queue is empty, it waits until an event arrives first.
  664. (Certain events, like DRAW events, are not really queued but constructed
  665. on the fly when the queue is empty.)
  666. .PP
  667. Some applications don't want to wait when no event is ready, but do want
  668. to process events that are already queued.
  669. For such cases there is the alternative routine
  670. .CW "wpollevent"
  671. which acts like
  672. .CW "wgetevent"
  673. when an event is available from the queue, but returns immediately with
  674. a dummy NULL event when the queue is empty.
  675. .PP
  676. An event always applies to a particular window.
  677. This means that an application which has no window open is blind and deaf.
  678. When an application calls
  679. .CW "wgetevent"
  680. in this state, it is terminated.
  681. Therefore, applications should make sure to always open a window before
  682. calling
  683. .CW wgetevent .
  684. .PP
  685. STDWIN implementations may limit the size of the event queue; when the
  686. queue is filled up events may get lost without notification.
  687. (There is no way to prevent this, since the problem usually occurs in
  688. the underlying operating system.)
  689. .NH 2
  690. Events
  691. .LP
  692. Events are typically read in a `main event loop', which might look
  693. something like this:
  694. .DS
  695. .CW
  696. int stop= 0;
  697. while (!stop) {
  698.     EVENT e;
  699.     wgetevent(&e);
  700.     switch (e.type) {
  701.         ...
  702.     }
  703. }
  704. .R
  705. .DE
  706. The variable
  707. .CW e
  708. is called the
  709. .I "event record" .
  710. The information placed in the event record depends on the event type.
  711. For all event types, the type is available as
  712. .CW "e.type" ,
  713. and the window to which the event applies as
  714. .CW "e.window" ;
  715. additional information is listed with the individual event descriptions.
  716. This additional information is stored in a
  717. union named
  718. .CW e.u ,
  719. e.g.,
  720. .CW e.u.character
  721. for character input events.
  722. .PP
  723. For clarity, events are always referred to by their `informal' names in this
  724. paper, e.g., MOUSE DOWN.
  725. The actual constants defined by STDWIN are derived from the informal
  726. name by prepending
  727. .CW WE_
  728. and replacing spaces by underscores, yielding, e.g.,
  729. .CW WE_MOUSE_DOWN .
  730. .PP
  731. Events can be classified as mouse events, other user input events and
  732. STDWIN-generated events.
  733. .NH 3
  734. Mouse events
  735. .LP
  736. Mouse events are generated when the user presses a mouse button inside
  737. the visible part of a document displayed in a window.
  738. There are separate event types for a press of a button, moves while
  739. a button is held down, and a release of a button.
  740. The position of the mouse cursor at the time the event was generated is
  741. reported in (\c
  742. .CW e.u.where.h ,
  743. .CW e.u.where.v ).
  744. The button number
  745. (1, 2 or 3 on a three-button mouse; always 1 on a one-button mouse)
  746. is reported in
  747. .CW e.u.where.button .
  748. .PP
  749. Mouse events allows easy detection of
  750. .I "multiple clicks" ,
  751. to which many applications want to assign a special meaning.
  752. Successive presses on a mouse button are considered to be part of a
  753. click sequence if they are `close together' in space and time.
  754. When a mouse button is pressed, STDWIN checks whether it is close enough
  755. to the previous press to be considered a continuation of the same click
  756. sequence, and if so, notes the number of the current click in
  757. .CW e.u.where.click .
  758. A click that is unrelated to previous clicks has click number 1;
  759. a following related click has click number 2, the next one has number
  760. 3, and so on, until the mouse is moved too far away or the user waits
  761. too long, in which case the click number is reset to 1 at the next
  762. mouse event.
  763. This way of reporting multiple clicks requires no delay to see whether a
  764. click is part of a multiple-click sequence; mouse events are reported as
  765. soon as they happen.
  766. .PP
  767. Not all STDWIN implementations run on machines whose mouse has more than
  768. one button; it is therefore unwise to write an application which can
  769. perform certain operations only through buttons 2 or 3.
  770. If multiple buttons are held down simultaneously, only events for the
  771. button pressed first are generated.
  772. .PP
  773. The mouse event types are
  774. MOUSE DOWN
  775. for a button press,
  776. MOUSE MOVE
  777. for a move of the mouse cursor while a button is still depressed, and
  778. MOUSE UP for a button release.
  779. The click number for MOUSE MOVE events is always zero.
  780. In order to prevent filling up the event queue, multiple MOUSE MOVE
  781. events may be collapsed to a single event, giving only the last mouse
  782. position.
  783. When the user moves the mouse outside the window with a button held
  784. down, the mouse remains associated with the window, and its position is
  785. reported relative to the origin of the window's document.
  786. The click number for a MOUSE UP event is the same as that of the
  787. corresponding MOUSE DOWN event if the mouse wasn't moved too far from
  788. its original position, or zero if it was moved further (and in this case
  789. this event is the end of its click sequence).
  790. .NH 3
  791. Other user input events
  792. .IP CHAR
  793. .br
  794. The user has typed a character at the keyboard.
  795. Its ASCII value is reported in
  796. .CW e.u.character .
  797. Note that some special keys (like RETURN, TAB, BACKSPACE) do not send
  798. CHAR events but COMMAND events.
  799. .IP COMMAND
  800. .br
  801. .RS
  802. This event is sent for special keys on the keyboard, and for certain
  803. special actions recognized by STDWIN.
  804. Some keys do not generate CHAR events but COMMAND events, because they
  805. do not send the same ASCII code on all keyboards (e.g., Enter), or
  806. because there are no standard ASCII codes for them (e.g., arrows and
  807. function keys).
  808. A code telling which special command was meant is reported in
  809. .CW e.u.command .
  810. Possible values represent the following keys and standard actions:
  811. CANCEL, TAB, RETURN, BACKSPACE, LEFT, RIGHT, UP, DOWN and CLOSE; this
  812. list may be extended in the future.
  813. The constants are actually called
  814. .CW WC_CANCEL
  815. etc.
  816. .PP
  817. CLOSE is to be interpreted as a request to close the window; the key
  818. or other action that generates it is system-dependent.
  819. The application should close the window, possibly after verifying that
  820. any changes the user has made to the file displayed in the window have
  821. been saved, in which case it may ignore the request,
  822. or put up a dialogue box asking what should be done to the file.
  823. .RE
  824. .IP MENU
  825. .br
  826. .RS
  827. A menu item was selected.
  828. The menu id and item number of the selected item are reported in
  829. .CW e.u.m.id
  830. and
  831. .CW e.u.m.item ;
  832. menu items are numbered starting at 0
  833. (see below for the definition of menus).
  834. .PP
  835. The interaction technique used to select menu items is not defined by
  836. STDWIN; a suitable technique is chosen by each implementation, e.g.
  837. pop-up, push-down or permanently present menus.
  838. Keyboard shortcuts are usually also available.
  839. The application cannot distinguish between the various ways of selecting
  840. a particular menu item; all it sees is which item is selected.
  841. .RE
  842. .NH 3
  843. STDWIN-generated events
  844. .IP NULL
  845. .br
  846. Nothing happened.
  847. This is a dummy event reported only by
  848. .CW "wpollevent"
  849. when the event queue is empty.
  850. .IP ACTIVATE
  851. .br
  852. A window has been `activated'.
  853. This is usually caused by the end user selecting an inactive window with
  854. the mouse.
  855. Only one window can be active at any time.
  856. This usually means that all subsequent keyboard input applies to
  857. the active window; some applications want to change the highlighting of
  858. selected objects in a document when its window is active.
  859. (Highlighting of the window's title, etc. is done
  860. automatically by STDWIN.)
  861. After a window is opened, the first event applying to it is
  862. usually an ACTIVATE event (because windows are opened in an unactivated
  863. state).
  864. Applications needn't monitor ACTIVATE events if all they want
  865. is determining to which window keyboard input applies; the relevant
  866. window is reported with each event in
  867. .CW e.window .
  868. .IP DEACTIVATE
  869. .br
  870. A window has been `deactivated'.
  871. This usually occurs just before another window is activated.
  872. In many implementations of STDWIN it is possible for the user to
  873. activate a window not belonging to the current application; in this case
  874. the current application receives only a DEACTIVATE event until one of
  875. its windows is reactivated.
  876. Note that closing a window does not generate a DEACTIVATE event for it,
  877. since the window has already disappeared by the time the application can
  878. call
  879. .CW "wgetevent" .
  880. .IP SIZE
  881. .br
  882. .RS
  883. A window's size has changed.
  884. This is usually done by the user explicitly resizing the window;
  885. in some (`tiling') STDWIN implementations it can also be caused by
  886. opening or closing other windows.
  887. .PP
  888. Some applications want to format their documents to fit exactly in the
  889. window.
  890. SIZE events make it possible for such applications to monitor window
  891. size changes.
  892. The new window size is not reported in the event record; the application
  893. can use the enquiry function
  894. .CW wgetwinzize
  895. for this purpose (see below).
  896. .PP
  897. Note that window moves don't generate events
  898. (except possibly DRAW events).
  899. .RE
  900. .IP DRAW
  901. .br
  902. This event is reported only for windows without an associated draw
  903. procedure.
  904. It means that part of the window needs to be repainted.
  905. The smallest rectangle enclosing the area to be repainted is reported in
  906. .CW e.u.area ,
  907. a struct with four fields
  908. .CW left ,
  909. .CW top ,
  910. .CW right
  911. and
  912. .CW bottom .
  913. .IP TIMER
  914. .br
  915. The window's alarm timer has gone off.
  916. For each window, an alarm may be set with the call
  917. .CW "wsettimer(win, dsecs)" .
  918. The alarm will go off, causing a TIMER event,
  919. aproximately
  920. .I dsecs/10
  921. seconds in the future (\c
  922. .I dsecs
  923. meaning deciseconds).
  924. Only one alarm per window is maintained; a new call overrides the
  925. previously set alarm.
  926. A value of 0 cancels the alarm.
  927. Timer values may be rounded up to whole seconds by some implementations.
  928. The maximum timer value that is guaranteed to be supported is
  929. 32000 dsecs.
  930. .NH 2
  931. Pushing events back
  932. .LP
  933. Occasionally, an application may want to postpone processing of an event
  934. till later.
  935. E.g., a subroutine may be getting events in a loop until it
  936. receives an event which shouldn't be handled locally but in the main
  937. event loop.
  938. The routine
  939. .CW "wungetevent(&eventrecord)"
  940. allows an event to be pushed back onto the event queue; the next
  941. call to
  942. .CW wgetevent
  943. or
  944. .CW wpollevent
  945. will report the event just pushed back.
  946. Only a single event can be pushed back (some implementations save the
  947. pushed back event in a separate buffer).
  948. It is possible to modify the event before pushing it back, or to
  949. synthesize events entirely.
  950. .NH 2
  951. Getting and setting the active window
  952. .LP
  953. A pointer to the active window is returned by the function
  954. .CW "wactive()" .
  955. The application can also make a different window active by calling
  956. .CW "wsetactive(win)" .
  957. This call does not take effect immediately; some time in the future, a
  958. DEACTIVATE event for the currently active window and an ACTIVATE event
  959. for the newly activated will be received.
  960. .NH 2
  961. Menus
  962. .LP
  963. Most window systems provide a simple way to set up and manipulate menus,
  964. in their simplest form lists of text strings which can be selected by
  965. the user by clicking on a string with the mouse.
  966. Menus may `pop up' when a particular mouse button is pressed in a
  967. particular screen area, or be `pulled down' from a `menu bar', etc.
  968. STDWIN provides a consistent, simple way for the application to
  969. interface with standard menus, or with menus defined entirely by the
  970. STDWIN library (if the window system provides no usable menus).
  971. .PP
  972. A
  973. .I menu
  974. contains a number of
  975. .I items ,
  976. numbered starting at 0.
  977. A menu has a
  978. .I title ,
  979. a text string displayed to identify the menu to the user, and a
  980. .I "menu id" ,
  981. a small positive integer identifying the menu to the application.
  982. Each item contains a text string, an optional
  983. .I "check mark"
  984. (which may be set by the application to indicate whether an option
  985. controlled by a menu item is active), and can be
  986. .I enabled
  987. or
  988. .I disabled .
  989. Only enabled items are selectable.
  990. When the user selects an enabled item, a MENU event is queued containing
  991. the menu id and item number in the event record.
  992. Because of the way events are queued, it is possible to receive MENU
  993. events for disabled menu items
  994. (if the selection was made before the menu item was disabled);
  995. applications should be prepared to receive spurious menu selection events.
  996. .PP
  997. A menu is created by a call to
  998. .CW "wmenucreate(id, title)" ;
  999. this returns a
  1000. .I "menu pointer"
  1001. which must be used for all further manipulations with the menu.
  1002. .I Id
  1003. is the menu id, which should be in the range [1..255].
  1004. Menu ids should be unique within an application.
  1005. .PP
  1006. Initially, a menu contains no items.
  1007. Items are added by calling
  1008. .CW "wmenuadditem(mp, text, shortcut)" .
  1009. The new item's number equals the number of items in the menu before this
  1010. call; it is returned as the function value.
  1011. .I Mp
  1012. is the menu pointer;
  1013. .I text
  1014. is the item text.
  1015. The item is initially enabled and unchecked.
  1016. .I Shortcut
  1017. is a character used to construct a `keyboard shortcut' for the
  1018. menu item; \-1 means the item is not to have a shortcut.
  1019. (The interpretation of keyboard shortcuts is implementation-dependent.
  1020. In a typical STDWIN implementation,
  1021. a menu item with shortcut `X' might be selected by typing ESC-X
  1022. or Meta-X (but not Control-X).
  1023. All printable characters are acceptable as shortcuts,
  1024. but on some systems lower case and upper case are indistinguishable.)
  1025. Adding an item with an empty string as text adds a disabled
  1026. `separator' item.
  1027. .PP
  1028. The text of an existing menu item can be changed by calling
  1029. .CW "wmenusetitem(mp, number, text)" .
  1030. Items can be enabled or disabled by calling
  1031. .CW "wmenuenable(mp, number, flag)" .
  1032. The check mark for an item can be set or cleared by calling
  1033. .CW "wmenucheck(mp, number, flag)" .
  1034. .PP
  1035. A menu can be deleted by calling
  1036. .CW "wmenudelete(mp)" .
  1037. Note that individual menu items, once added, cannot be removed, nor can
  1038. new items be inserted in the middle.
  1039. This is due to restrictions in many window systems' menu interfaces;
  1040. usually menus are sufficiently static that it doesn't matter.
  1041. .PP
  1042. For a menu's items to be selectable, the menu must be attached to a
  1043. window and the window must be activated.
  1044. Normally, STDWIN automatically attaches all menus to all windows, so all
  1045. menus become selectable as soon as the first window is activated.
  1046. To change this behaviour, the call
  1047. .CW "wmenusetdeflocal(TRUE)"
  1048. causes subsequently created menus to be `local', requiring
  1049. explicit attachment and detachment.
  1050. The call
  1051. .CW "wmenuattach(win, mp)"
  1052. attaches the menu
  1053. .I mp
  1054. to the window
  1055. .I win .
  1056. The call
  1057. .CW "wmenudetach(win, mp)"
  1058. reverses this effect.
  1059. A menu may be attached to multiple windows; multiple menus may be
  1060. attached to a window.
  1061. After calling
  1062. .CW "wmenusetdeflocal(FALSE)" ,
  1063. future menus will be `global' again, i.e., automatically attached to all
  1064. (existing and new) windows.
  1065. .NH
  1066. Additional facilities
  1067. .LP
  1068. .NH 2
  1069. Enquiry functions
  1070. .LP
  1071. Some enquiry functions are available to interrogate the system state.
  1072. .LP
  1073. .CW "wgetscrsize(&width, &height)"
  1074. .IP
  1075. Returns the screen size measured in pixels into the integer variables
  1076. whose addresses are passed.
  1077. .LP
  1078. .CW "wgetscrmm(&mmwidth, &mmheight)"
  1079. .IP
  1080. Returns the approximate screen size measured in millimeters.
  1081. By combining this information with the outcome of
  1082. .CW wgetscrsize ,
  1083. pixel size and aspect ratio can conveniently be computed.
  1084. In some (most?) implementations, the numbers returned may be
  1085. approximations or guesses.
  1086. .LP
  1087. .CW "wgetwinsize(win, &width, &height)"
  1088. .IP
  1089. Returns the size of the drawable area of a window, measured in pixels.
  1090. (Due to the presence of borders, a maximally-sized window is usually
  1091. smaller than the screen.)
  1092. .NH 2
  1093. The text caret
  1094. .LP
  1095. In documents that deal with text it is often useful to have some form of
  1096. `text cursor', indicating the position where characters typed at the
  1097. keyboard will be inserted.
  1098. The call
  1099. .CW "wsetcaret(win, h, v)"
  1100. causes a `caret' to appear just to the left of the character
  1101. position (\c
  1102. .I h ,
  1103. .I v )
  1104. in the document.
  1105. The caret appears immediately before any character that
  1106. would be drawn by
  1107. .CW "wdrawtext(h, v, ...)" .
  1108. The caret has a system-defined shape; it is often a blinking vertical
  1109. bar.
  1110. .PP
  1111. Each window has its own caret; the caret in the active window may be
  1112. the only one that is visible, or it may blink while the carets in other
  1113. windows are static.
  1114. At any time a window has at most one caret; the old caret is removed
  1115. when a new one is specified.
  1116. The caret can be removed altogether with the call
  1117. .CW "wnocaret(win)" .
  1118. .NH 2
  1119. Dialogue tools
  1120. .LP
  1121. A
  1122. .I "dialogue box"
  1123. is a `mini-window' containing a simple message or question,
  1124. and requiring
  1125. the user to respond, e.g. by pressing a key or clicking the mouse in a
  1126. particular area.
  1127. As long as the dialogue box is present, the application is blocked.
  1128. After answering the question or acknowledging the message, the dialogue
  1129. box disappears and normal interaction with the application continues.
  1130. Dialogue boxes may be presented even when no windows are open yet.
  1131. The following calls put up dialogue boxes and wait for a response:
  1132. .sp
  1133. .LP
  1134. .CW "wmessage(string)"
  1135. .IP
  1136. Displays a message and waits until the user acknowledges it.
  1137. The precise form of acknowledgement required
  1138. is implementation-dependent;
  1139. it could be pressing the Return key or clicking an `OK button' with the
  1140. mouse.
  1141. .LP
  1142. .CW "waskstr(question, replybuf, buflength)"
  1143. .IP
  1144. Displays a question and waits until the user has finished typing a
  1145. reply.
  1146. The initial contents of the reply buffer are used as a default reply.
  1147. The function normally returns TRUE; if the user aborts the dialogue
  1148. (e.g., by pressing the CANCEL button) it returns FALSE.
  1149. .LP
  1150. .CW "waskync(question, dflt)"
  1151. .IP
  1152. Displays a question which gives the user the possibility to answer with
  1153. Yes, No or Cancel only.
  1154. The return value is 1 (Yes), 0 (No) or -1 (Cancel).
  1155. .I Dflt
  1156. is the suggested (default) return value.
  1157. .LP
  1158. .CW "waskfile(prompt, replybuf, buflength, new)"
  1159. .IP
  1160. Displays a dialogue box asking for a file name.
  1161. .I Replybuf
  1162. initially contains a default or suggested file name.
  1163. The boolean parameter
  1164. .I new
  1165. specifies whether a new (not yet existing) or old (existing) file is
  1166. required.
  1167. When a new file is asked for, the user may specify an existing file,
  1168. but in this case explicit permission is asked to overwrite it.
  1169. The function returns TRUE, or FALSE if the user aborts the dialogue.
  1170. The file name is returned in a form acceptable to the STDIO function
  1171. .CW fopen .
  1172. STDWIN implementations may provide additional support, e.g. file name
  1173. completion or file system browsing; the fact that some systems provide
  1174. elaborate standard file-selection dialogues (which is highly appreciated
  1175. by the end users) was a strong motivation to include this function in
  1176. STDWIN.
  1177. .LP
  1178. .CW "wperror(string)"
  1179. .IP
  1180. Displays an error message similar to that printed by the standard C
  1181. function
  1182. .I perror (3),
  1183. and waits for an acknowledgement as for
  1184. .CW wmessage .
  1185. .sp
  1186. .LP
  1187. It should be noted that
  1188. .CW "waskstr"
  1189. is the most general of the above functions; in theory, versions of the
  1190. others can be implemented with the help of
  1191. .CW "waskstr"
  1192. and other existing tools.
  1193. .NH 2
  1194. The text-editing package
  1195. .LP
  1196. The
  1197. .I text-editing
  1198. package is a set of routines implemented entirely `on top of' STDWIN,
  1199. without using any implementation-dependent functions or data structures.
  1200. The availability of this package
  1201. is important because it provides a standard way to tackle the
  1202. non-trivial problem of editing multi-line text blocks.
  1203. It is clearly influenced by the TextEdit routines available in the Apple
  1204. Macintosh's ROM Toolbox (but contains only original code).
  1205. .PP
  1206. The text-editing package displays a paragraph of text in a rectangle of
  1207. a given width, breaking the lines at spaces between words as necessary.
  1208. It gives the application complete control over what happens to the text,
  1209. but provides an easy way to handle user input intended to edit it.
  1210. .PP
  1211. The call
  1212. .CW "tecreate(win, <rectangle>)"
  1213. returns a pointer to a text-editing block at the specified position in
  1214. the given window's document.
  1215. (A text-editing block is not a portion of the document but a data
  1216. structure.)
  1217. Any number of text-editing blocks may be created, although usually at
  1218. most one block per window should be editable at any time.
  1219. .PP
  1220. Initially, the block contains no text.
  1221. The call
  1222. .CW "tesettext(tp, string)"
  1223. sets the text to be edited, replacing any existing text in the block.
  1224. The call
  1225. .CW "tegettext(tp)"
  1226. returns a pointer to the text string (which remains valid only until the
  1227. next call to a text-editing routine).
  1228. .PP
  1229. The text block is not automatically drawn.
  1230. When a text-editing routine changes the edited text (or other aspects of
  1231. its appearance), it calls
  1232. .CW wchange
  1233. for the appropriate area of the window; the window's draw procedure
  1234. should call
  1235. .CW "tedraw(tp)"
  1236. for each block which overlaps the repaint area.
  1237. .PP
  1238. Besides the edited string, a text-editing block contains a
  1239. .I focus ,
  1240. indicating which text is selected
  1241. for deletion or at which position new text will be inserted.
  1242. The focus can be set by the application with the call
  1243. .CW "tesetfocus(tp, first, last)" ,
  1244. telling that the characters in the range [first..last-1] are selected,
  1245. or, if first equals last, that the text insertion point is at that
  1246. position (characters are counted starting at 0).
  1247. If the focus is an insert position, the window's caret is set at that
  1248. position in the document.
  1249. Text can be inserted at the focus (replacing its previous contents) by
  1250. calling
  1251. .CW "tereplace(tp, string)" ;
  1252. specifying an empty string deletes any text in the focus.
  1253. .PP
  1254. The simplest way to let the user edit the text in a text-editing block
  1255. is to call
  1256. .CW "teevent(tp, &event\%record)"
  1257. for each event.
  1258. This call returns TRUE if the event is applicable to the text-editing
  1259. block (e.g., it is a CHAR event, or a mouse click within the block's
  1260. bounding rectangle), and in that case the event is processed by the
  1261. text-editing package (e.g., a character is inserted, or the focus is
  1262. moved to the point where the mouse was clicked).
  1263. If the event is not applicable to the particular block, the function
  1264. does nothing and returns FALSE; in this case the application should
  1265. further decide what to do to the event.
  1266. Of course, the application is free to decide whether to offer an event
  1267. to a text-editing block at all; e.g., it might have a different
  1268. interpretation for the Return key (for which the text-editing package
  1269. inserts a new-line character in the text string).
  1270. .PP
  1271. There are more text-editing calls, e.g. to move a text-editing block to
  1272. a new position, to enquire about the focus, to perform individual
  1273. editing operations, to ask for the height of the rectangle minimally
  1274. needed to display the text entirely, etc.
  1275. .PP
  1276. The following call displays a text string in exactly the same way as
  1277. the text-editing package would do (breaking it into lines at the same
  1278. places, etc.), but without creating a text-editing block, and thus
  1279. without a focus:
  1280. .CW "wdrawpar(<point>, string, width)" .
  1281. It returns the v coordinate of the bottom of the text paragraph.
  1282. To compute the height of a text paragraph thus drawn without actually
  1283. drawing it, one can call
  1284. .CW "wparheight(string, width)" .
  1285. .NH
  1286. A complete example
  1287. .LP
  1288. The program below is a complete STDWIN application.
  1289. It is presented here to give a feel for the use of some of the routines
  1290. described above.
  1291. The program displays a window in which a text-edit block is placed;
  1292. all events recognized by the text-edit package are handled correctly,
  1293. and so are several ways of quitting.
  1294. Other events are ignored.
  1295. .if t .sp .5v
  1296. .DS L
  1297. .CW
  1298. #include <stdwin.h>
  1299.  
  1300. TEXTEDIT *tp; /* Global so drawproc can reference it */
  1301.  
  1302. void drawproc(w, left, top, right, bottom)
  1303.     WINDOW *w;
  1304.     int left, top, right, bottom;
  1305. {
  1306.     tedraw(tp);
  1307. }
  1308. .R
  1309. .DE
  1310. .DS L
  1311. .CW
  1312. main()
  1313. {
  1314.     MENU *m;
  1315.     WINDOW *w;
  1316.     int stop;
  1317.     int width, height;
  1318. .R
  1319. .DE
  1320. .DS L
  1321. .CW
  1322.     winit();
  1323.     
  1324.     m= wmenucreate(1, "Sample");
  1325.     wmenuadditem(m, "Quit", 'Q'); /* Item 0 */
  1326.     
  1327.     w= wopen("Sample window", drawproc);
  1328.     wgetwinsize(w, &width, &height);
  1329.     tp= tecreate(w, 0, 0, width, height);
  1330. .R
  1331. .DE
  1332. .DS L
  1333. .CW
  1334.     stop= 0;
  1335.     while (!stop) {
  1336.         EVENT e;
  1337.         wgetevent(&e);
  1338.         if (teevent(tp, &e))
  1339.             wsetdocsize(w, width, tegetbottom(tp));
  1340.         else {
  1341.             switch (e.type) {
  1342.             case WE_COMMAND:
  1343.                 if (e.u.command == WC_CLOSE || e.u.command == WC_CANCEL)
  1344.                     stop= 1;
  1345.                 break;
  1346.             case WE_MENU:
  1347.                 if (e.u.m.id == 1 && e.u.m.item == 0) /* Quit */
  1348.                     stop= 1;
  1349.                 break;
  1350.             }
  1351.         }
  1352.     }
  1353. .R
  1354. .DE
  1355. .DS L
  1356. .CW
  1357.     wclose(w);
  1358.     wdone();
  1359.     exit(0);
  1360. }
  1361. .R
  1362. .DE
  1363. .if t .sp -.5v
  1364. .NH
  1365. Experiences
  1366. .LP
  1367. Five distinct STDWIN implementations have been created so far:
  1368. for the Apple Macintosh,
  1369. for the Whitechapel MG-1,
  1370. for X version 11,
  1371. for the Atari ST,
  1372. and a subset for alphanumeric displays
  1373. (which runs both under Unix and MS-DOS).
  1374. .PP
  1375. Once a STDWIN version for a target system is available,
  1376. application portability is high.
  1377. Most portability problems that crop up
  1378. (besides the usual problems like word size, byte order,
  1379. data alignment or following NULL pointers)
  1380. have to do with differences in other parts of the operating system
  1381. interface, e.g. use of the file system.
  1382. One portability problem encountered with the STDWIN interface was that
  1383. some programs developed for alphanumeric terminals expected a
  1384. fixed-width font; in general most problems were caused by insufficiently
  1385. precise specification of STDWIN.
  1386. .PP
  1387. The time needed to create a STDWIN version for a particular target
  1388. system is moderate.
  1389. An experienced C programmer who did not know anything about STDWIN or
  1390. the Atari ST in advance
  1391. created a working Atari ST version in two months.
  1392. So far, each version has been created more or less from scratch
  1393. (except for the common parts like the textedit package).
  1394. We have now gained enough experience with different target systems to be
  1395. able to create an intermediate layer containing code which remains more
  1396. or less constant between target systems.
  1397. .NH
  1398. Future developments
  1399. .LP
  1400. To date, the applications that use STDWIN have been mostly text-based.
  1401. Undoubtedly, this has influenced the direction of development of drawing
  1402. facilities in STDWIN.
  1403. It is sufficiently easy to add graphical primitives to an
  1404. implementation, though, that we expect to add several as demand grows,
  1405. e.g., bitblt, clipping, line styles, filling.
  1406. The existing facilities set a sort of standard for the form of future
  1407. ones.
  1408. The requirement that they be implementable on top of a large variety of
  1409. window systems will ensure that only more or less generally accepted
  1410. primitives will be included in STDWIN; a useful sort of conservatism for
  1411. a package that wants to enhance application portability.
  1412. .PP
  1413. Besides the need to add more drawing primitives, there are several areas
  1414. where STDWIN requires, and will probably get, extensions: fonts, sizes
  1415. and styles; the mouse cursor; drawing in off-screen bitmaps (not
  1416. associated with a window); error handling (which is currently virtually
  1417. absent); event queue manipulations and an `event mask'; `clipboard' or
  1418. `cut buffer' operations.
  1419. .PP
  1420. A development in a different direction, independent of the addition of
  1421. graphical primitives, may be the addition of more toolboxes built on
  1422. top of the exiting facilities, like the text editing package.
  1423. Tools are needed
  1424. to manipulate higher-order graphical objects,
  1425. to implement specific interaction techniques,
  1426. to provide `canned applications' like text-editing windows,
  1427. etc.
  1428. .PP
  1429. A third, potentially very useful, extension would be the addition of
  1430. drawable
  1431. `borders' to the window that aren't scrolled together with the document.
  1432. In such borders, interaction tools could be placed like palettes and
  1433. buttons, or rulers around the document.
  1434. The design of such an extension should be the topic of further research,
  1435. in order to achieve the largest possible generality.
  1436. .\" Filter troff input through refer -e -n
  1437. .[
  1438. $LIST$
  1439. .]
  1440.