Received: from UCB-VAX.ARPA by MIT-MC.ARPA; 23 APR 85 23:27:15 EST Received: by UCB-VAX.ARPA (4.24/4.45) id AA03671; Fri, 19 Apr 85 22:31:07 pst From: decvax!encore!babel!rms@Berkeley Received: by encore.UUCP (4.12/4.7) id AA20483; Fri, 19 Apr 85 18:20:31 est Received: by babel.UUCP (4.12/4.7) id AA17510; Fri, 19 Apr 85 18:13:16 est Date: Fri, 19 Apr 85 18:13:16 est Message-Id: <8504192313.AA17510@babel.UUCP> To: decvax!ucbvax!rms@Berkeley For now, I will give commands long names for clarity. Actually they will be represented by one- or two-character codes. Since there are currently only 80 or so commands, one-character codes are possible. Each user process assigns numbers to the windows it creates. It refers to the windows by those numbers. Normally it can refer only to the windows it has created. It should usually try to keep the window numbers small, as that will reduce the overhead in the window manager process. Window numbers and all other numeric arguments are passed in some uniform way yet to be decided. Options include: 1) decimal or hex digits with a space to terminate 2) modified hex using 16 consecutive character codes, so that one instruction can combine two of them into a byte of the number. 3) as in 2, but a fixed number of digits, needing no terminator. This makes decoding even faster. Some commands require arguments that are multiplicative factors for positions. They should not have to be integers. Rational numbers are ok as a format for this, and so are fixed point numbers with eight or more fraction bits. Plain text to be output will not appear in the window command stream. Text must always be the argument to a suitable command such as WC_DRAW_TEXT. Window types: The window manager implements a fixed set of window types. Each window type has its own set of parameters and operations. A window-type argument is passed as a single character. The types are: W_PICTURE W_BITMAP W_CORKBOARD W_STREAM W_FRAME (may not be needed; see below) Everything that the Macintosh does can be done using picture, bitmap and corkboard windows. Wait Command: WC_WAIT *time* prevents any further commands from this user program from taking effect until *time*. This is used to provide precisely timed blinks regardless of the effect of system load on the user program. Selecting a window: At any time, for each user process, one of its windows is selected for commands. All commands apply to that window. WC_SELECT *n* selects window *n* for commands. WC_SELECT_PUSH *n* selects window *n* for commands, saving the identity of the previously selected window on a stack. WC_SELECT_POP reselects the last previously-selected-window recorded by WC_SELECT_PUSH. Pushes and pops can be nested to many levels (at least 20). WC_SELECT_DESK *s* selects the desktop window, which is a corkboard, so that windows inferior to it can be created. The desktop has inferiors belonging to various programs, and each program can in general modify only the desk inferiors that were created by it. A desktop window keeps a separate set of draw parameters for each user program, so that each user program can use the commands to change these parameters. A user program can also modify items that it had created. This is how it can temporarily hide or permanently destroy its windows. *s* specifies the screen whose desktop window should be used, in case there are several screens. Separate user programs have separate spaces of item numbers for the desktop window, so that they cannot interfere with each other. It is recommended to use the window number of a desktop inferior as its item number. WC_SELECT_DESK_PICTURE *s* selects a special picture window which is an inferior of the desktop window of screen *s*, and the full size of the desktop. It works like the desktop window except that items drawn are picture items rather than windows. "ior" is the only alu-function' allowed, so that the order of items does not matter (this is important since no program can specify the relative ordering of its own items versus those of other programs.) This is how programs display icons on the desk. Separate user programs have separate spaces of item numbers for the desktop window, so that they cannot interfere with each other. It is recommended to use the window number of a desktop inferior as its item number, for an item that is an icon representing a currently non-visible window. WC_SELECT_NULL selects the "null window", a desk-like window that is not displayed. Make a window the inferior of the null window if you do not want it to appear on the screen ever. This is useful for bitmap windows that are used for cursors or fill patterns, and for picture windows that are used for specifying regions used in drawing other windows or specifying shapes of windows. Like the desk, the null window's inferiors at any time were made by different programs, and each program can affect only its own. When an application program is started, the desktop is selected. Creating a window: A window is always created as an inferior of the selected window. Once created, the new window is selected. The previous selected window is saved on a stack as by WC_SELECT_PUSH. WC_CREATE *n* *type* Create a window number *n* of type *type*, as an inferior of the selected window. That window is recorded on the stack as a previously selected window and the newly created window becomes selected for commands. Killing a window: A window can be killed by deleting the item in its superior which holds onto the window. Any inferiors of the window thus killed are automatically killed too. When a user process terminates, the system kills all items it created in desktops, desktop picture windows, and the null window. This is guaranteed to kill all the windows the process created. Mouse cursors: WC_SET_MOUSE_CURSOR *cursortype* Select one of the standard types of mouse cursor for use in this window. Zero means that this window says nothing about the mouse cursor, so that the containing window's specification will apply. Standard cursor types are probably implemented by a special case mechanism, for time efficiency, since they will (if chosen well) be in use most of the time. WC_SET_MOUSE_CURSOR_WINDOW *w* *xoff* *yoff* Specify window *w* to be used as the image of the mouse cursor while the mouse is in the window now selected. *w* should be a bitmap window. Typically it is an inferior of the null window. Its current contents are copied whenever that is convenient for the window manager, so changes in the contents of *w* do not affect the shape of the mouse cursor until an unpredictable amount of time later. Mouse-click reporting: Every mouse click is assigned to some window. This is the smallest or most inferior window that contains the position where the click happened and that wants to report mouse clicks. If no containing window wants to report clicks, the click is not reported. WC_SET_REPORT_CLICK *bool* Specifies whether the selected window wants to report clicks. Window Sizes and Shapes: Every window specifies its size and shape, but not in any sense a position. Positioning of a window is controlled by its superior. WC_SET_SIZE *h* *w* Specifies the height and width of the selected window. WC_SET_SHAPE *n* Specifies the shape of the selected window as coming from the contents of window *n*, a picture window. The picture in that window is used to compute a region, which becomes the bounding region of the selected window. The further history of window *n* has no effect on the window whose shape is specified this way. By default, a window has a rectangular shape: the full extent of the rectangle specified as its size. If a window is given a nonrectangular shape, then any further changes in the rectangular size cause the shape to be scaled along with the size. Operations on W_PICTURE windows: A W_PICTURE window displays a portion of an infinite plane. The picture in the infinite plane is specified by various picture items--points, lines, circles, etc. The window's rectangle of visibility can scroll across the infinite plane under control of WC_SET_ORIGIN. It can zoom under control of WC_SET_ZOOM. Each item is associated with an alu function, which is "set bits" (ior), "clear bits" (bic) or "toggle bits" (xor). Each item gets its alu function when the item is drawn, from the current alu function setting of the window. This setting is set with the command WC_SET_DRAW_ALU. Item numbers can be assigned in any order when defining the window's display list. However, the meaning of the display list at any time is defined by assuming that the items are drawn in numeric order. This makes combinations of different alu functions unambiguously meaningful. Each item has a 16-bit visibility mask, which controls the circumstances under which the item is displayed, as a function of four visibility conditions. The four conditions are combined into a number to index into the visibility mask, so that the mask can specify visibility or not independently for each combination of conditions. The four visibility conditions are: 1) This window is marked active by the user ("active window" in Macintosh terms; "selected window" in Lisp Machine). 2) The mouse is in this window. 3) This window is marked enabled for use ("active control" in Macintosh terms.) 4) This window's "datum" bit. The window has one "current" visibility mask which is assigned to all items that are created or changed. This "current" mask is initially all ones, and can be changed by commands. The window can also be enabled or disabled by commands, and its datum can be set. Items other than text use a pen, which has a rectangular shape and a specified height and width. The pen draws from a replicated pattern which can be specified also. The pen size and pattern are assigned to an item when it is created, from values that are current in the window at that time. Item numbers should be at least 16 bits, so that they can be assigned conveniently with gaps for insertion of later items. WC_SET_DRAW_ALU *function* Specifies whether to set, clear or toggle bits with drawing commands, in items created subsequently. WC_SET_VISIBILITY_MASK *16bits* Specifies the visibility mask for subsequently created items. WC_SET_WINDOW_ENABLE *bool* Specifies whether this window is now enabled. This controls the visibility of existing items according to their visibility masks. WC_SET_WINDOW_DATUM *bool* Specifies this window's datum bit. This controls the visibility of existing items according to their visibility masks. The difference between the datum and the enable bit is just a matter of conventional use. WC_SET_ITEM_VISIBILITY_MASK *n* *16bits* Alters the visibility mask of existing item number *n*. This can be used to show and hide individual items at any time. WC_SET_DRAW_PATTERN *p* Specifies the gray pattern to use in drawing with the pen as one of a standard set of such. The default is solid black. WC_SET_DRAW_PATTERN_WINDOW *n* Specifies the gray pattern to use in drawing with the pen as the contents of window *n* (a bitmap window). Use of a window as a pattern is an alternative to use of a standard pattern. Unpredictable results follow if the contents of that window are changed while there is an item which has it as a pen pattern. WC_SET_DRAW_PEN_SIZE *h* *w* Specifies the height and width of pen to use in drawing lines and shapes. The default is one pixel. WC_SET_DRAW_FONT *fontfamily* *size* *style* Specifies the font for output of text. *** Note: either the *style* parameter or some additional parameter must make it possible to specify display of "dimmed" text a la Macintosh, if you want that feature. *** WC_SET_DRAW_ORIGIN *x* *y* Specifies the amounts to add to all coordinates specified in draw commands. WC_SET_DRAW_ZOOM *xfactor* *yfactor* Specifies the scaling to be applied to all coordinates specified, to the sizes of all regions and text, and to bitmaps drawn if scaling bitmaps is defined. WC_OFFSET_DRAW_ORIGIN *x* *y* Adds *x* and *y* to the amounts to add to all coordinates specified in draw commands. WC_OFFSET_DRAW_ZOOM *xfactor* *yfactor* Multiplies *xfactor* and *yfactor* into the scaling for draw commands. WC_PUSH_DRAW_PARAMS WC_POP_DRAW_PARAMS Save and restore the current settings of the window's drawing parameters, including origin, zoom, pen size, pen pattern, font, visibility mask, and alu function. Saved settings are lost if the selected window is changed. You must restore them before that if you wish to restore them ever. One exception is if you push, change, and then pop the selection; that does not lose pushed draw settings. WC_DELETE_ITEM *n* Removes item *n* from the display list. WC_DRAW_TEXT *n* *x* *y* *string* *space-adjust* Adds an item numbered *n* consisting of the text *string* to the window. The left end of the baseline of the first character appears at *x*, *y*. Spaces are increased in width by *space-adjust*. These parameters are recorded in the item, as are the current font parameters at the time of drawing the text. WC_DRAW_POINT *n* *x* *y* Add a single dot picture item number *n* to the display list. WC_DRAW_LINE *n* *x1* *y1* *x2* *y2* Add a single line picture item number *n* to the display list. WC_DRAW_RECTANGLE *n* *x1* *y1* *x2* *y2* Makes picture item number *n* be a solid rectangle with two opposite corners at specified positions, and with horizontal and vertical edges. WC_FRAME_RECTANGLE *n* *x1* *y1* *x2* *y2* Makes picture item number *n* be a rectangular outline with two opposite corners at specified positions, and with horizontal and vertical edges. WC_DRAW_OVAL *n* *x* *y* *xr* *yr* WC_FRAME_OVAL *n* *x* *y* *xr* *yr* WC_DRAW_ROUND_RECTANGLE *n* *x1* *y1* *x2* y2* *xr* *yr* WC_FRAME_ROUND_RECTANGLE *n* *x1* *y1* *x2* y2* *xr* *yr* WC_DRAW_ARC *n* *x* *y* *xr* *yr* *a1* *a2* WC_FRAME_ARC *n* *x* *y* *xr* *yr* *a1* *a2* more drawing operations. WC_DRAW_POLYGON *n* *x* *y* *dx1* *dy1* *dx2* *dy2* ... WC_FRAME_POLYGON *n* *x* *y* *dx1* *dy1* *dx2* *dy2* ... draw a polygon specified as a starting point followed by offsets. WC_DRAW_REGION *n* *x* *y* *w* WC_FRAME_REGION *n* *x* *y* *w* More drawing commands, in which *w* is the number of a picture window which specifies the region to be drawn. WC_DRAW_BITMAP *n* *x* *y* *w* *w* is the number of a bitmap window which contains the bitmap to be drawn. Its contents are copied when the item is drawn. WC_SET_ORIGIN *x* *y* Set the point of the infinite plane which is displayed at the upper left corner of the window. WC_OFFSET_ORIGIN *x* *y* Increase by *x* and *y* the coordinates of the point of the infinite plane which is displayed at the upper left corner of the window. WC_SET_GROWTH_TRANSLATION_RATE *xfactor* *yfactor* Specifies that a change in size of *x* dots should offset the origin by *xfactor* times *x* dots, and likewise for y size changes and *yfactor*. This can be used to cause the image to remain centered in either dimension as the size changes, or to be fixed to either edge, or various other effects. More complicated effects of change of size on the image have to be done by the application program by hand, because there are so many possible desired effects that it is not clear to me what simply specified options would be worth including. WC_SET_ITEM_REPORT_CLICK *n* Make item *n* report mouse clicks inside it. It will do so only when it is visible according to its visibility mask. A click "reported by" a picture item is really reported for the window containing the item, but with the item number as additional information. If the window itself is set to report clicks in general, then any click inside the window is reported for that window, with or without an item number. If the window itself is not set to report clicks, then it reports clicks anyway if they are in an item that is set to report clicks, but if the click is not inside such an item, the window allows its superiors to handle the click. If an item is small and you want to report clicks for it in a larger area, what you should do is make a larger item that has no actual effect on the display (blank pen-pattern) and have it report clicks instead. Notes on W_PICTURE windows: Zooming when there are bitmaps or text drawn on the window is problematical. Zoom could be defined to have no effect on them. Alternately, scaling of bitmaps and text could be defined. A compromise would be to support scaling by various simple fractions and use the closest supported fraction to the actual scale specified. Computing text size: There is a function, which can run as a subroutine in the application program, that accepts commands WC_SET_DRAW_etc and a text string, and reports the width that the text string will occupy. Operations on W_BITMAP windows: Picture windows keep display lists recording the items drawn in them. Bitmap windows do not keep display lists; they only keep the bitmaps resulting from the drawing. The operations on bitmap windows are the same as on picture windows, except that a few operations are not supported at all and some others are supported only in restricted ways: WC_SET_ORIGIN and WC_OFFSET_ORIGIN are not supported. Item numbers are ignored. Drawing is done in the order of receipt of draw commands. WC_DELETE_ITEM is not supported. Visibility masks are not supported. Anything drawn is visible and remains so (but it can be overwritten by subsequent drawing). WC_SET_ITEM_REPORT_CLICK is not supported. Operations on W_CORKBOARD windows: These windows are much like picture windows. The difference is that corkboard windows have an infinite plane on which other windows are pinned. Picture windows contain only picture items, which are not windows, while corkboard windows contain only windows. If you want a display containing windows and picture items, use a corkboard which has a full-width picture window as the lowest window in it. Put windows on the corkboard and picture items in that picture window. WC_SET_VISIBILITY_MASK *16bits* WC_SET_WINDOW_ENABLE *bool* WC_SET_WINDOW_DATUM *bool* WC_SET_ITEM_VISIBILITY_MASK *n* *16bits* WC_SET_DRAW_ORIGIN *x* *y* WC_SET_DRAW_ZOOM *xfactor* *yfactor* WC_SET_ORIGIN *x* *y* WC_SET_GROWTH_TRANSLATION_RATE *xfactor* *yfactor* WC_OFFSET_ORIGIN *x* *y* WC_DELETE_ITEM *n* Just as in picture windows. WC_PUSH_DRAW_PARAMS WC_POP_DRAW_PARAMS Just as in picture windows, except that the only parameters that exist are the drawing origin, drawing zoom, and visibility mask. WC_DRAW_WINDOW *n* *x* *y* Pins a new inferior window to the corkboard. It is given item number *n* on the corkboard. The inferior window is created by the following command, which must be a WC_CREATE command. That window is positioned with its upper left corner at position *x* *y* in the coordinate system of the corkboard's plane. WC_SET_ITEM_PRIORITY *n* *pri* Set the priority of item *n* to *pri*. The priority is used to determine which inferior is visible when items overlap. The higher priority inferior window lies on top of the lower priority one. For windows of the same priority, the most recently operated on one wins. A window is considered operated on when it is created and when WC_SET_ITEM_PRIORITY is done on it. By default the priority of an item is zero. WC_SET_ITEM_POSITION *n* *x* *y* Alter the position at which the upper left corner of the window for item *n* is displayed. Activation: Corkboard windows optionally support "activation" of their inferiors. Each corkboard has a bit saying whether activation among its inferiors is desired. This bit is set for the desktop, and is clear for most other corkboards. When the bit is set, at most one item in the corkboard is potentially active at any time; the corkboard remembers which item that is. When the bit is clear, all items in the corkboard are potentially active. Activeness starts with the desktop corkboard, which is always active, and propagates from each active window to all of its potentially active subwindows. Thus, in a typical corkboard, all subwindows are active when the corkboard is, but in a corkboard that supports activation among its inferiors, only one inferior is active (along with some or all inferiors of that inferior, etc). Each item in a corkboard has a bit saying whether the window is a candidate for activation. This bit is set from a draw parameter. Only if an item says it is a candidate can it be the potentially active item in a corkboard that supports activation processing. If the mouse is clicked within a corkboard inferior that is a candidate for activation but is not active, that inferior is immediately made the one potentially active inferior in its superior. This happens at all levels of corkboard that the mouse is in, including the desk, for each click, instead of the normal processing of the click. The consequence is that the window clicked in becomes active, together with all containing windows and the appropriate set of windows contained in it. WC_SET_ACTIVATION_PROCESSING *bool* Specifies whether the selected window supports activation processing among its immediate inferiors. WC_SET_ACTIVATION_CANDIDATE *bool* Specifies whether newly created items should be candidates for activation. This is a draw parameter and it is saved and restored with the other draw parameters. WC_SET_ITEM_ACTIVATION_CANDIDATE *n* *bool* Specifies whether previously created item number *n* should be considered a candidate for activation. Activation is not reported to the user program as an event. It is not needed to be. Whether a window is active serves as one of the visibility conditions that the visibility mask can test. So if the user program wants a window to look different when active, it can just specify the active appearance and the inactive appearance when drawing the window initially. It need not do anything when the window becomes active or becomes inactive. Activation of a window should not cause any other immediate effect, so no event report is needed. Activation has an effect on the reporting of keyboard input, however. It follows from the specs above that all active windows on any one desk belong to a single user program. Keyboard input goes to that program. I strongly recommend against the use of the design idea where keyboard input goes to the window that the mouse is in (as on the Sun). That requires people to use the mouse when they wish to switch programs. On the Lisp machine, this can be done with keyboard commands, which is much more convenient when the programs being switched between are to be used with the keyboard. The user program can make a candidate be preferred within its superior, to support keyboard commands that switch the user to a different window. WC_ACTIVATE *n* Makes item *n* in the selected window be the potentially active inferior in that window. Has no effect if item *n* is not marked as a candidate for activation, or if the selected window does not enable activation processing among its inferiors. It may be permitted to use WC_ACTIVATE on items in the desktop. Also, it is useful for program interaction on the desktop to have the desktop record a priority order for windows to become active, so that the following command can be supported: WC_DEACTIVATE *n* Makes item *n* cease to be the potentially active inferior of the desktop, and the highest priority candidate then becomes active. Item *n* is put at the end of the priority queue so that this command causes all candidates to become active a cyclic order. When the window active in the desktop becomes inactive for any other reason, it is put at the front of the queue of inactive candidates. So the order candidates are reached by WC_DEACTIVATE is that off most recent last use first. Of course, a user program can only deactivate its own windows. There may be a standard system command that deactivates the active desktop inferior whatever it is. Operations on W_STREAM windows: Stream windows contain text and subwindows output as a sequential stream. The output is filled as it is sent, breaking lines at the margin. In principle, the text should be refilled if the width of the stream window is changed. Subwindows can be output "in line" or "separated". An in-line subwindow should have the same height as a line of text. It appears in a line of text, or possibly part of it appears at the end of one line and part at the beginning of the next line. A separated subwindow takes up one or more entire text lines. Stream windows in the initial design support only a single fixed-width font for text. Programs can find out the height and width of this font (as constants, or returned by a library call for the sake of extension later to variable fonts), so that they can tell the height and width of the window in characters from its size in pixels. WC_OUTPUT_TEXT *string* Output text to the window at its current cursor position. Stream windows, unlike picture windows, support the formatting characters newline and tab. such as newline, tab, Newline characters, tab characters, etc. are all supported as text output in stream windows, by contrast with picture windows. WC_OUTPUT_SEQUENTIAL Switch to sequential output, in which all text is added at the end of the accumulated text. If random-access output was being done, all the text thus output becomes frozen and is regarded as having been output sequentially in its final form. New sequential output goes at the end of it. In sequential mode, all ASCII control characters other than newline and tab, and all characters 0200 and above, are output as sequences of printing characters to show the user what character was output. Perhaps this should be done in random access mode too, but it matters less, because programs using random access mode presumably keep track of the cursor position and therefore must already detect control characters in their data and handle them specially. WC_OUTPUT_RANDOM_ACCESS Switch to random access output. First scrolls all existing text "off the top of the screen". Then establishes an area to hold the random-access text. All output in random access mode works by altering that text. Previously output sequential text is never affected. WC_SET_CURSOR *x* *line* WC_OUTPUT_ERASE_LINES *n* WC_OUTPUT_ERASE_CHARS *n* WC_OUTPUT_INSERT_SPACES *n* WC_OUTPUT_DELETE_CHARS *n* WC_OUTPUT_INSERT_LINES *n* WC_OUTPUT_DELETE_LINES *n* ...any others you want... Typical display-terminal operations, allowed only in random-access. They work by moving and setting the characters in the fixed array established for random-access use. Note that moving to a new line (such as outputting newline) in random access mode should CLEAR THE LINE REACHED. Yes, Unix does not do this. Unix is broken. WC_OUTPUT_WINDOW_INLINE *breakable* Prepare to output a subwindow to this window, to be put into lines along with the text. Should be followed by a WC_CREATE command to make the subwindow. *breakable* is a boolean; true means that it is ok to put part of the subwindow at the end of one line and the rest at the beginning of the next line. False for *breakable* means start a new line with this subwindow if it does not fit in the current line. WC_OUTPUT_WINDOW_SEPARATED *hposition* *nlines* Prepare to output a subwindow as *nlines* entire lines. It is centered vertically within the space of *nlines* lines. *hposition* is either "center", "left *offset*" or "right *offset*", controlling how the window is positioned horizontally. Should be followed by a WC_CREATE command to make the subwindow. WC_SET_FOLLOW_OUTPUT *bool* Specifies whether the stream window should display the most recent output sent to it, or should freeze at a particular point in its display list. Scrolling (WC_SET_ORIGIN) has an effect only when the window is frozen (*bool* = 0). This command with *bool* = 0 sets the origin so that output does not shift in the window as a result of this command itself. All scroll-bar commands will want to start by setting follow- -output to zero when scrolling a stream window. For the sake of modularity in scroll bar implementations, it might be best for this command to be allowed and ignored on all other types of windows. WC_SET_ORIGIN WC_OFFSET_ORIGIN As for W_PICTURE windows, but using whichever origin-edge has been specified with WC_SET_ORIGIN_EDGE WC_SET_FREEZE_INTERVAL Specify that the window should change from following to frozen after a full window height worth of output has been sent to it following this command. If another WC_SET_FREEZE_INTERVAL command is sent in the meanwhile, it resets the count. If the window is unfrozen after having received such a command and it is then scrolled to the end and unfrozen, a freeze is scheduled to happen after enough lines of output to make up a full window height together with the lines already on the screen at the time of unfreezing. Normally, programs will send a new WC_SET_FREEZE_INTERVAL each time they block for input. This is so that programs generating small amounts of output for interactive commands never freeze the screen. It may be a little hard to arrange the pty-handling program to find out when the controlled program waits for input, but I'm sure it can be done with a little kernel change, since the pty-handling program can already find out when the controlled program changes its start/stop characters or switches to raw mode. Changing the size of a stream window does not change its output-following mode or the origin it uses if frozen. W_FRAME windows: A frame is intended to be a window whose size can be changed and which propagates size changes to its subwindows according to constraints or other specifications. Some subwindows would keep a constant size in one or both dimensions; others would take a fraction of the available space, etc. A window's size will change only because of events in the application program except on two occasions: 1) the user uses a size box to specify a new size 2) the superior is a frame and its size changes. It follows that the only application for automatic change of size of a window is due to size boxes. But if size boxes are just picture windows reporting clicks to the application program, and it is really the application which requests the change in the size of the frame, then it might as well be up to the application program to specify the size of the subwindows too. Then it can use a corkboard window to hold the subwindows; it does not need a special type of window called "frame" but just a library for conveniently computing and specifying the new sizes of the subwindows. Reporting of Events: Events such as mouse clicks are reported with command sequences in essentially the same language as is used for commands to the window system. I say "essentially" because it is not clear whether the command codes should be kept disjoint between the two directions. Might as well keep them disjoint if that doesn't cost anything. For now, I give the commands sent by the window system names starting with WR (window reply). WR_MOUSE_DOWN *w* *n* *b* *x* *y* WR_MOUSE_UP *w* *n* *b* *x* *y* Reports a click in window *w*, on item number *n* (may be zero if no item or not on any sensitive item), with button *b*, at cursor position *x*, *y* in the window. WR_MOUSE_MOTION *w* *n* *x* *y* Similar but reports only that the mouse has moved. *** It is not clear how often to generate these reports. *** Error Reporting: The WC command language is designed so that a given sequence of commands is either always valid or always erroneous. The validity does not depend on any conditions outside of the user program's control. Therefore, a debugged program will never cause an error condition to exist. When an error condition exists, it is reported as an event. WR_ERROR *count* *code* Reports receipt of erroneous WC command data, with *code* describing the type of error, and *count* stating the number of characters sent to the window system in the WC command stream up to the point of error. If the user program keeps a log of all its window output, this is enough to find the erroneous command. Rubber Banding: It is necessary to provide special commands to allow programs to request special kinds of mouse tracking, such as drawing a rectangular box which moves with the mouse or one of whose corners moves with the mouse. These commands can easily be added ad lib, but have certain things in common. A special mouse tracking command is permitted only from a program to which a mouse click was just reported, and only as long as the mouse button that was pushed then is still down. If the command is not accepted, a negative reply is sent immediately. If the command is accepted, the mouse is tracked and a reply is sent when the button is released. Both kinds of replies echo a transaction number that was included in the command. WR_COMMAND_REJECTED *trans* The request *trans* was not acceptable. Either the program is erroneous or the user has released the mouse button already. WR_MOUSE_TRACKED *trans* *x* *y* *w* *dx* *dy* The request *trans* was accepted and the mouse was tracked until the button was released at position *x*, *y* and over window number *w*. *w* is zero if the mouse was not ultimately over any window belonging to the requesting program. *dx* and *dy* are the total mouse motion during tracking. Sample mouse tracking commands: WC_TRACK_WITH_RECTANGLE *trans* *x1* *y1* *x2* *y2* draws a rectangle initially at the specified position and then moves it as the mouse moves. When the button is released, a WR_MOUSE_TRACKED reply is sent. The *dx* and *dy* in that reply tell how much motion was specified by the mouse tracking operation. WC_TRACK_WITH_RECTANGLE_CORNER *trans* *corners* *x1* *y1* *x2* *y2* is similar except that only some corner of the rectangle moves with the mouse. *corners* specifies which corners (4 bits of information). The *dx* and *dy* in that reply tell how much motion was specified by the mouse tracking operation. Possible other useful candidates: Draw line from fixed point to mouse position. Draw pair of lines, one horizontal and one vertical, from fixed point to mouse position. Draw rectangle that moves in one dimension only, following the mouse in that dimension. Draw circle with fixed center through mouse position, or with fixed radius and center at mouse position. Draw a bitmap window as a second cursor and move it with the mouse. Specify a picture item or sequence of picture items and give, for certain coordinates, a code meaning "use the mouse position" instead of a number.