Affine Transformations Contents Index Drawing Options




6 Overview of Window Facilities

6.1 Introduction

A central notion in organizing user interfaces is allocating screen regions to particular tasks and recursively subdividing these regions into subregions. The windowing layer of CLIM defines an extensible framework for constructing, using, and managing such hierarchies of interactive regions . This framework allows uniform treatment of the following things:

From the perspective of most CLIM users, CLIM's windowing layer plays the role of a window system. However, CLIM will usually use the services of a window system platform to provide efficient windowing, input, and output facilities. In this specification, such window system platforms will be referred to as host window systems or as display servers.

The fundamental window abstraction defined by CLIM is called a sheet . A sheet can participate in a relationship called a windowing relationship . This relationship is one in which one sheet called the parent provides space to a number of other sheets called children . Support for establishing and maintaining this kind of relationship is the essence of what window systems provide. At any point in time, CLIM allows a sheet to be a child in one relationship called its youth windowing relationship and a parent in another relationship called its adult windowing relationship .

Programmers can manipulate unrooted hierarchies of sheets (those without a connection to any particular display server). However, a sheet hierarchy must be attached to a display server to make it visible. Ports and grafts provide the functionality for managing this capability. A port is an abstract connection to a display service that is responsible for managing host display server resources and for processing input events received from the host display server. A graft is a special kind of sheet that represents a host window, typically a root window (that is, a screen-level window). A sheet is attached to a display by making it a child of a graft, which represents an appropriate host window. The sheet will then appear to be a child of that host window. So, a sheet is put onto a particular screen by making it a child of an appropriate graft and enabling it. Ports and grafts are described in detail in Chapter Ports, Grafts, and Mirrored Sheets .

6.2 Properties of Sheets

Sheets have the following properties:

6.3 Sheet Protocols

A sheet is a participant in a number of protocols. Every sheet must provide methods for the generic functions that make up these protocols. These protocols are:

These protocols may be handled directly by a sheet, queued for later processing by some other agent, or passed on to a delegate sheet for further processing.


7 Properties of Sheets

7.1 Basic Sheet Classes

Note that there are no standard sheet classes in CLIM, and no pre-packaged way to create sheets in general. If a programmer needs to create an instance of some class of sheet, make-instance must be used. For most purposes, calling make-pane is how application programmers will make sheets.

sheet[Protocol Class]
The protocol class that corresponds to a sheet. This and the next chapter describe all of the sheet protocols. If you want to create a new class that behaves like a sheet, it should be a subclass of sheet. Subclasses of sheet must obey the sheet protocol.All of the subclasses of sheet are mutable.

sheetpobject[Predicate]
Returns true if object is a sheet , otherwise returns false .

basic-sheet[Class]
The basic class on which all CLIM sheets are built, a subclass of sheet .

7.2 Relationships Between Sheets

Sheets are arranged in a tree-structured, acyclic, top-down hierarchy. Thus, in general, a sheet has one parent (or no parent) and zero or more children. A sheet may have zero or more siblings (that is, other sheets that share the same parent). In order to describe the relationships between sheets, we need to define some terms.

7.2.1 Sheet Relationship Functions

The generic functions in this section comprise the sheet protocol. All sheet objects must implement or inherit methods for each of these generic functions.

sheet-parentsheet[Generic function]
Returns the parent of the sheet sheet , or nil if the sheet has no parent.

sheet-childrensheet[Generic function]
Returns a list of sheets that are the children of the sheet sheet . Some sheet classes support only a single child; in this case, the result of sheet-children will be a list of one element. This function returns objects that reveal CLIM's internal state; do not modify those objects.
sheet-adopt-childsheet child[Generic function]
Adds the child sheet child to the set of children of the sheet sheet , and makes the sheet the child's parent. If child already has a parent, the sheet-already-has-parent error will be signalled.

Some sheet classes support only a single child. For such sheets, attempting to adopt more than a single child will cause the sheet-supports-only-one-child error to be signalled.

sheet-disown-childsheet child &key (errorp t )[Generic function]
Removes the child sheet child from the set of children of the sheet sheet , and makes the parent of the child be nil . If child is not actually a child of sheet and errorp is true , then the sheet-is-not-child error will be signalled.

sheet-siblingssheet[Generic function]
Returns a list of all of the siblings of the sheet sheet . The sibling are all of the children of sheet 's parent excluding sheet itself. This function returns fresh objects that may be modified.
sheet-enabled-childrensheet[Generic function]
Returns a list of those children of the sheet sheet that are enabled. This function returns fresh objects that may be modified.
sheet-ancestor-psheet putative-ancestor[Generic function]
Returns true if the the sheet putative-ancestor is in fact an ancestor of the sheet sheet , otherwise returns false .

raise-sheetsheet[Generic function]
bury-sheetsheet[Generic function]
These functions reorder the children of a sheet by raising the sheet sheet to the top or burying it at the bottom. Raising a sheet puts it at the beginning of the ordering; burying it puts it at the end. If sheets overlap, the one that appears ``on top'' on the display device is earlier in the ordering than the one underneath.

This may change which parts of which sheets are visible on the display device.

reorder-sheetssheet new-ordering[Generic function]
Reorders the children of the sheet sheet to have the new ordering specified by new-ordering . new-ordering is an ordered list of the child sheets; elements at the front of new-ordering are ``on top'' of elements at the rear.

If new-ordering does not contain all of the children of sheet , the sheet-ordering-underspecified error will be signalled. If new-ordering contains a sheet that is not a child of sheet , the sheet-is-not-child error will be signalled.

sheet-enabled-psheet[Generic function]
Returns true if the the sheet sheet is enabled by its parent, otherwise returns false . Note that all of a sheet's ancestors must be enabled before the sheet is viewable.

(setf sheet-enabled-p)enabled-p sheet[Generic function]
When enabled-p is true , this enables the the sheet sheet . When enabled-p is false , this disables the sheet.

Note that a sheet is not visible unless it and all of its ancestors are enabled.

sheet-viewable-psheet[Generic function]
Returns true if the sheet sheet and all its ancestors are enabled, and if one of its ancestors is a graft. See Chapter Ports, Grafts, and Mirrored Sheets for further information.

sheet-occluding-sheetssheet child[Generic function]
Returns a list of the sheet child 's siblings that occlude part or all of the region of the child . In general, these are the siblings that are enabled and appear earlier in the sheet sheet 's children. If sheet does not permit overlapping among its children, sheet-occluding-sheets will return nil .

This function returns fresh objects that may be modified.
map-over-sheetsfunction sheet[Generic function]
Applies the function function to the sheet sheet , and then applies function to all of the descendents (the children, the children's children, and so forth) of sheet .

Function is a function of one argument, the sheet; it has dynamic extent.

7.2.2 Sheet Genealogy Classes

Different ``mixin'' classes are provided that implement the relationship protocol. None of the four following classes is instantiable.

sheet-parent-mixin[Class]
This class is mixed into sheet classes that have a parent.

sheet-leaf-mixin[Class]
This class is mixed into sheet classes that will never have children.

sheet-single-child-mixin[Class]
This class is mixed into sheet classes that have at most a single child.

sheet-multiple-child-mixin[Class]
This class is mixed into sheet classes that may have zero or more children.

7.3 Sheet Geometry

Every sheet has a region and a coordinate system. A sheet's region refers to its position and extent on the display device, and is represented by some sort of a region object, frequently a rectangle. A sheet's coordinate system is represented by a coordinate transformation that converts coordinates in its coordinate system to coordinates in its parent's coordinate system.

7.3.1 Sheet Geometry Functions

sheet-transformationsheet[Generic function]
(setf sheet-transformation)transformation sheet[Generic function]
Returns a transformation that converts coordinates in the sheet sheet 's coordinate system into coordinates in its parent's coordinate system. Using setf on this accessor will modify the sheet's coordinate system, including moving its region in its parent's coordinate system.

When the sheet's transformation is changed, note-sheet-transformation-changed is called on the to notify the sheet of the change.

sheet-regionsheet[Generic function]
(setf sheet-region)region sheet[Generic function]
Returns a region object that represents the set of points to which the sheet sheet refers. The region is in the sheet's coordinate system. Using setf on this accessor modifies the sheet's region.

When the sheet's region is changed, note-sheet-region-region is called on sheet to notify the sheet of the change.


Issue: RSL
To reshape and move a region, you generally have to manipulate both of the above. Maybe there should be a single function that takes either or both of a new transformation or region? Maybe region coordinates should be expressed in parents' coordinates, since that's easier to set only one?

Issue: RSL
I'm not convinced I like this business of requesting a change by modifying an accessor. It might be better to have a request- function, so it would be clear that there might be some delay before the region or transformation was modified. Currently, using setf on mirrored sheets requests that the server move or resize the sheet; the accessor will continue to return the old value until the notification comes in from the display server that says that the mirror has been moved.
move-sheetsheet x y[Generic function]
Moves the sheet sheet to the new position (x,y). x and y are expressed in the coordinate system of sheet 's parent.

move-sheet simply modifies sheet 's transformation, and could be implemented as follows:

(defmethod move-sheet ((sheet basic-sheet) x y)
  (let ((transform (sheet-transformation sheet)))
    (multiple-value-bind (old-x old-y)
        (transform-position transform 0 0)
      (setf (sheet-transformation sheet)
            (compose-translation-with-transformation
              transform (- x old-x) (- y old-y))))))
resize-sheetsheet width height[Generic function]
Resizes the sheet sheet to have a new width width and a new height height . width and height are real numbers.

resize-sheet simply modifies sheet 's region, and could be implemented as follows:

(defmethod resize-sheet ((sheet basic-sheet) width height)
  (setf (sheet-region sheet)
        (make-bounding-rectangle 0 0 width height)))
move-and-resize-sheetsheet x y width height[Generic function]
Moves the sheet sheet to the new position (x,y), and changes its size to the new width width and the new height height . x and y are expressed in the coordinate system of sheet 's parent. width and height are real numbers.

move-and-resize-sheet could be implemented as follows:

(defmethod move-and-resize-sheet ((sheet basic-sheet) x y width height)
  (move-sheet sheet x y)
  (resize-sheet sheet width height))
map-sheet-position-to-parentsheet x y[Generic function]
Applies the sheet sheet 's transformation to the point (x,y), returning the coordinates of that point in sheet 's parent's coordinate system.

map-sheet-position-to-childsheet x y[Generic function]
Applies the inverse of the sheet sheet 's transformation to the point (x,y) (represented in sheet 's parent's coordinate system), returning the coordinates of that same point in sheet coordinate system.

map-sheet-rectangle*-to-parentsheet x1 y1 x2 y2[Generic function]
Applies the sheet sheet 's transformation to the bounding rectangle specified by the corner points (x1,y1) and (x2,y2), returning the bounding rectangle of the transformed region as four values, min-x , min-y , max-x , and max-y . The arguments x1 , y1 , x2 , and y1 are canonicalized in the same way as for make-bounding-rectangle .

map-sheet-rectangle*-to-childsheet x1 y1 x2 y2[Generic function]
Applies the inverse of the sheet sheet 's transformation to the bounding rectangle delimited by the corner points (x1,y1) and (x2,y2) (represented in sheet 's parent's coordinate system), returning the bounding rectangle of the transformed region as four values, min-x , min-y , max-x , and max-y . The arguments x1 , y1 , x2 , and y1 are canonicalized in the same way as for make-bounding-rectangle .


Issue: SWM
I now think that map- in these names is misleading; maybe convert- is better?
map-over-sheets-containing-positionfunction sheet x y[Generic function]
Applies the function function to all of the children of the sheet sheet that contain the position (x,y). x and y are expressed in sheet 's coordinate system.

Function is a function of one argument, the sheet; it has dynamic extent.

map-over-sheets-overlapping-regionfunction sheet region[Generic function]
Applies the function function to all of the children of the sheet sheet that overlap the region region . region is expressed in sheet 's coordinate system.

Function is a function of one argument, the sheet; it has dynamic extent.

child-containing-positionsheet x y[Generic function]
Returns the topmost enabled direct child of the sheet sheet whose region contains the position (x,y). The position is expressed in sheet 's coordinate system.

children-overlapping-regionsheet region[Generic function]
children-overlapping-rectangle*sheet x1 y1 x2 y2[Generic function]
Returns the list of enabled direct children of the sheet sheet whose region overlaps the region region . children-overlapping-rectangle* is a special case of children-overlapping-region in which the region is a bounding rectangle whose corner points are (x1,y1) and (x2,y2). The region is expressed in sheet 's coordinate system. This function returns fresh objects that may be modified.
sheet-delta-transformationsheet ancestor[Generic function]
Returns a transformation that is the composition of all of the sheet transformations between the sheets sheet and ancestor . If ancestor is nil , sheet-delta-transformation will return the transformation to the root of the sheet hierarchy. If ancestor is not an ancestor of sheet, the sheet-is-not-ancestor error will be signalled.

The computation of the delta transformation is likely to be cached.

sheet-allocated-regionsheet child[Generic function]
Returns the visible region of the sheet child in the sheet sheet 's coordinate system. If child is occluded by any of its siblings, those siblings' regions are subtracted (using region-difference ) from child 's actual region.

7.3.2 Sheet Geometry Classes

Each of the following implements the sheet geometry protocol in a different manner, according to the sheet's requirements. None of the four following classes is instantiable.

sheet-identity-transformation-mixin[Class]
This class is mixed into sheet classes whose coordinate system is identical to that of its parent.

sheet-translation-mixin[Class]
This class is mixed into sheet classes whose coordinate system is related to that of its parent by a simple translation.

sheet-y-inverting-transformation-mixin[Class]
This class is mixed into sheet classes whose coordinate system is related to that of its parent by inverting the y coordinate system, and optionally translating by some amount in x and y.

sheet-transformation-mixin[Class]
This class is mixed into sheet classes whose coordinate system is related to that of its parent by an arbitrary affine transformation. CLIM implementations are allowed to restrict these transformations to just rectilinear ones.


8 Sheet Protocols

8.1 Input Protocol

CLIM's windowing substrate provides an input architecture and standard functionality for notifying clients of input that is distributed to their sheets. Input includes such events as the pointer entering and exiting sheets, pointer motion (whose granularity is defined by performance limitations), and pointer button and keyboard events. At this level, input is represented as event objects.

Sheets either participate fully in the input protocol or are mute for input. If any functions in the input protocol are called on a sheet that is mute for input, the sheet-is-mute-for-input error will be signalled.

In addition to handling input event, a sheet is also responsible for providing other input services, such as controlling the pointer's appearance, and polling for current pointer and keyboard state.

Input is processed on a per-port basis by the function process-next-event . In multiprocessing environments, a process that calls process-next-event in a loop is created for each port. In single-process Lisps, process-next-event is called whenever the user would go blocked for input.

process-next-event has three main tasks when it receives an event. First, it must determine to which client the event is addressed; this process is called distributing . Typically, the client is a sheet, but there are other special-purpose clients to which events can also be dispatched. Next, process-next-event formats the event into a standard format, and finally it dispatches the event to the client. A client may then either handle the event synchronously, or it may queue it for later handling by another process.

Input events can be broadly categorized into pointer events and keyboard events . By default, pointer events are dispatched to the lowest sheet in the hierarchy whose region contains the location of the pointer. Keyboard events are dispatched to the port's keyboard input focus; the accessor port-keyboard-input-focus contains the event client that receives the port's keyboard events.

8.1.1 Input Protocol Functions

In the functions below, the client argument is typically a sheet, but it may be another object that supports event distribution, dispatching, and handling.

sheet-event-queuesheet[Generic function]
Any sheet that can process events will have an event queue from which the events are gotten. sheet-event-queue returns the object that acts as the event queue. The exact representation of an event queue is explicitly unspecified.

process-next-eventport &key wait-function timeout[Generic function]
This function provides a standard interface for one pass through a port's event processing loop. wait-function is either nil or a function of no arguments that acts as a predicate; it has dynamic extent. The predicate should wait until one of three conditions occurs:

A port implementation must provide a method for this function that reads the next window server-specific device event, blocking if necessary, and then invokes the event distributor.

port-keyboard-input-focusport[Generic function]
(setf port-keyboard-input-focus)focus port[Generic function]
Returns the client to which keyboard events are to be dispatched.


Issue: RSL
Should this accessor be called keyboard-input-focus ? It may be that we want to be able to call it on a frame in order to implement some sort of per-frame input focus.
distribute-eventport event[Generic function]
The event is distributed to the port 's proper client. In general, this will be the keyboard input focus for keyboard events, and the lowest sheet under the pointer for pointer events.


Issue: RSL
Do we just want to call this function dispatch-event and have it called on the port first?
dispatch-eventclient event[Generic function]
This function is called by process-next-event to inform a client about an event of interest. It is invoked synchronously by whatever process called process-next-event , so many methods for this function will simply queue the event for later handling. Certain classes of clients and events may cause this function immediately to call either queue-event or handle-event , or to ignore the event entirely.

queue-eventclient event[Generic function]
Places the event event into the queue of events for the client client .

handle-eventclient event[Generic function]
Implements the client's policy with respect to the event. For example, if the programmer wishes to highlight a sheet in response to an event that informs it that the pointer has entered its territory, there would be a method to carry out the policy that specializes the appropriate sheet and event classes.

In addition to queue-event , the queued input protocol handles the following generic functions. The client argument to these functions is typically a sheet.

event-readclient[Generic function]
Takes the next event out of the queue of events for this client.

event-read-no-hangclient[Generic function]
Takes the next event out of the queue of events for this client. It returns nil if there are no events in the queue.

event-peekclient &optional event-type[Generic function]
Returns the next event in the queue without removing it from the queue. If event-type is supplied, events that are not of that type are first removed and discarded.

event-unreadclient event[Generic function]
Places the event at the head of the client 's event queue, so as to be the next event read.

event-listenclient[Generic function]
Returns true if there are any events queued for client , otherwise returns false .

8.1.2 Input Protocol Classes

Most classes of sheets will have one of the following input protocol classes mixed in. Of course, a sheet can always have a specialized method for a specific class of event that will override the default. For example, a sheet may need to have only pointer click events dispatched to itself, and may delegate all other events to some other input client. Such a sheet should have delegate-sheet-input-mixin as a superclass, and have a more specific method for dispatch-event on its class and pointer-button-click-event .

None of the five following classes is instantiable.

standard-sheet-input-mixin[Class]
This class of sheet provides a method for dispatch-event that calls queue-event on each device event. Note that configuration events invoke handle-event immediately.

The standard-sheet-input-mixin class will also provide a sheet-event-queue method, describe above.

immediate-sheet-input-mixin[Class]
This class of sheet provides a method for dispatch-event that calls handle-event immediately for all events.

The immediate-sheet-input-mixin class will also provide a sheet-event-queue method, describe above.

sheet-mute-input-mixin[Class]
This is mixed in to any sheet class the does not handle any input events.

delegate-sheet-input-mixin[Class]
This class of sheet provides a method for dispatch-event that calls dispatch-event on a designated substitute recipient and the event. The initarg :delegate or the accessor delegate-sheet-delegate may be used to set the recipient of dispatched events.

delegate-sheet-delegatesheet[Generic function]
(setf delegate-sheet-delegate)delegate sheet[Generic function]
This may be set to another recipient of events dispatched to a sheet of class delegate-sheet-input-mixin . delegate is the object to which events will be dispatched, and is usually another sheet. If the delegate is nil , events are discarded.

8.2 Standard Device Events

An event is a CLIM object that represents some sort of user gesture (such as moving the pointer or pressing a key on the keyboard) or that corresponds to some sort of notification from the display server. Event objects store such things as the sheet associated with the event, the x and y bposition of the pointer within that sheet, the key name or character corresponding to a key on the keyboard, and so forth.

Figure 8.1 shows all the event classes.


event 
device-event
keyboard-event
key-press-event
key-release-event
pointer-event
pointer-button-event
pointer-button-press-event
pointer-button-release-event
pointer-button-hold-event
pointer-motion-event
pointer-boundary-event
pointer-enter-event
pointer-exit-event
window-event
window-configuration-event
window-repaint-event
window-manager-event
window-manager-delete--event
timer-event
Figure 8.1: CLIM event classes. All classes that appear at a given indentation are subclasses of the class that appears above and at a lesser indentation.



event[Protocol Class]
The protocol class that corresponds to any sort of ``event''. If you want to create a new class that behaves like an event, it should be a subclass of event. Subclasses of event must obey the event protocol.All of the event classes are immutable. CLIM implementations may choose to keep a resource of the device event classes, but this must be invisible at the API level. That is, any event visible at the level of the API must act as though it is immutable.

eventpobject[Predicate]
Returns true if object is an event , otherwise returns false .

:timestamp[Init arg]
All subclasses of event must take a :timestamp initarg, which is used to specify the timestamp for the event.

event-timestampevent[Generic function]
Returns an integer that is a monotonically increasing timestamp for the the event event . The timestamp must have at least as many bits of precision as a fixnum.

event-typeevent[Generic function]
For the event event , returns a keyword with the same name as the class name, except stripped of the ``-event'' ending. For example, the keyword :key-press is returned by event-type for an event whose class is key-press-event .

All event classes must implement methods for event-type and event-timestamp .

device-event[Class]
:sheet[Init arg]
:modifier-state[Init arg]
The instantiable class that corresponds to any sort of device event. This is a subclass of event .

All subclasses of device-event must take the :sheet and :modifier-state initargs, which are used to specify the sheet and modifier state components for the event.

event-sheetdevice-event[Generic function]
Returns the sheet associated with the event device-event .

event-modifier-statedevice-event[Generic function]
Returns an integer value that encodes the state of all the modifier keys on the keyboard. This will be a mask consisting of the logior of +shift-key+ , +control-key+ , +meta-key+ , +super-key+ , and +hyper-key+ .

All device event classes must implement methods for event-sheet and event-modifier-state .

keyboard-event[Class]
:key-name[Init arg]
The instantiable class that corresponds to any sort of keyboard event. This is a subclass of device-event .

All subclasses of keyboard-event must take the :key-name initarg, which is used to specify the key name component for the event.

keyboard-event-key-namekeyboard-event[Generic function]
Returns the name of the key that was pressed or released in a keyboard event. This will be a symbol whose value is port-specific. Key names corresponding to the set of ``standard'' characters (such as the alphanumerics) will be a symbol in the keyword package.

keyboard-event-characterkeyboard-event[Generic function]
Returns the character associated with the event keyboard-event , if there is any.

All keyboard event classes must implement methods for keyboard-event-key-name and keyboard-event-character .

key-press-event[Class]
key-release-event[Class]
The instantiable classes that correspond to a key press or release event. This is a subclass of keyboard-event .

pointer-event[Class]
:pointer[Init arg]
:button[Init arg]
:x[Init arg]
:y[Init arg]
The instantiable class that corresponds to any sort of pointer event. This is a subclass of device-event .

All subclasses of pointer-event must take the :pointer , :button , :x , and :y initargs, which are used to specify the pointer object, pointer button, and native x and y position of the pointer at the time of the event. The sheet's x and y positions are derived from the supplied native x and y positions and the sheet itself.

pointer-event-xpointer-event[Generic function]
pointer-event-ypointer-event[Generic function]
Returns the x and y position of the pointer at the time the event occurred, in the coordinate system of the sheet that received the event. All pointer events must implement a method for these generic functions.

pointer-event-native-xpointer-event[Generic function]
pointer-event-native-ypointer-event[Generic function]
Returns the x and y position of the pointer at the time the event occurred, in the pointer's native coordinate system. All pointer events must implement a method for these generic functions.

pointer-event-pointerpointer-event[Generic function]
Returns the pointer object to which this event refers.

All pointer event classes must implement methods for pointer-event-x , pointer-event-y , pointer-event-native-x , pointer-event-native-y , and pointer-event-pointer .

pointer-button-event[Class]
The instantiable class that corresponds to any sort of pointer button event. This is a subclass of pointer-event .

pointer-event-buttonpointer-button-event[Generic function]
Returns the an integer corresponding to the pointer button that was pressed or released, which will be one of +pointer-left-button+ , +pointer-middle-button+ , or +pointer-right-button+ .

pointer-button-press-event[Class]
pointer-button-release-event[Class]
pointer-button-hold-event[Class]
The instantiable classes that correspond to a pointer button press, button release, and click-and-hold events. These are subclasses of pointer-button-event .

pointer-click-event[Class]
pointer-double-click-event[Class]
pointer-click-and-hold-event[Class]
The instantiable classes that correspond to a pointer button press, followed immediately by (respectively) a button release, another button press, or pointer motion. These are subclasses of pointer-button-event . Ports are not required to generate these events.

pointer-motion-event[Class]
The instantiable class that corresponds to any sort of pointer motion event. This is a subclass of pointer-event .

pointer-boundary-event[Class]
The instantiable class that corresponds to a pointer motion event that crosses some sort of sheet boundary. This is a subclass of pointer-motion-event .

pointer-boundary-event-kindpointer-boundary-event[Generic function]
Returns the ``kind'' of boundary event, which will be one of :ancestor , :virtual , :inferior , :nonlinear , :nonlinear-virtual , or nil . These event kinds correspond to the detail members for X11 enter and exit events.

pointer-enter-event[Class]
pointer-exit-event[Class]
The instantiable classes that correspond to a pointer enter or exit event. These are subclasses of pointer-boundary-event .

window-event[Class]
:region[Init arg]
The instantiable class that corresponds to any sort of windowing event. This is a subclass of event .

All subclasses of window-event must take a :region initarg, which is used to specify the damage region associated with the event.

window-event-regionwindow-event[Generic function]
Returns the region of the sheet that is affected by a window event.

window-event-native-regionwindow-event[Generic function]
Returns the region of the sheet in native coordinates.

window-event-mirrored-sheetwindow-event[Generic function]
Returns the mirrored sheet that is attached to the mirror on which the event occurred.

All window event classes must implement methods for window-event-region , window-event-native-region , and window-event-mirrored-sheet .

window-configuration-event[Class]
The instantiable class that corresponds to a window changing its size or position. This is a subclass of window-event .

window-repaint-event[Class]
The instantiable class that corresponds to a request to repaint the window. This is a subclass of window-event .

window-manager-event[Class]
:sheet[Init arg]
The instantiable class that corresponds to any sort of window manager event. This is a subclass of event .

All subclasses of window-manager-event must take a :sheet initarg, which is used to specify the sheet on which the window manager acted.

window-manager-delete-event[Class]
The instantiable class that corresponds to window manager event that causes a host window to be deleted. This is a subclass of window-manager-event .

timer-event[Class]
The instantiable class that corresponds to a timeout event. This is a subclass of event .

+pointer-left-button+[Constant]
+pointer-middle-button+[Constant]
+pointer-right-button+[Constant]
Constants that correspond to the left, middle, and right button on a pointing device. pointer-event-button will returns one of these three values.

These constants are powers of 2 so that they can be combined with logior and tested with logtest .

+shift-key+[Constant]
+control-key+[Constant]
+meta-key+[Constant]
+super-key+[Constant]
+hyper-key+[Constant]
Constants that correspond to the shift, control, meta, super, and hyper modifier keys being held down on the keyboard. These constants are powers of 2 that are disjoint from the pointer button constants, so that they can be combined with logior and tested with logtest .

event-modifier-state will return some combination of these values.

Implementations must support at least shift, control, and meta modifiers. Control and meta might correspond to the control and option or command shift keys on a Macintosh keyboard, for example.

8.3 Output Protocol

The output protocol is concerned with the appearance of displayed output on the window associated with a sheet. The sheet output protocol is responsible for providing a means of doing output to a sheet, and for delivering repaint requests to the sheet's client.

Sheets either participate fully in the output protocol or are mute for output. If any functions in the output protocol are called on a sheet that is mute for output, the sheet-is-mute-for-output error will be signalled.

8.3.1 Output Properties

Each sheet retains some output state that logically describes how output is to be rendered on its window. Such information as the foreground and background ink, line thickness, and transformation to be used during drawing are provided by this state. This state may be stored in a medium associated with the sheet itself, be derived from a parent, or may have some global default, depending on the sheet itself.

If a sheet is mute for output, it is an error to set any of these values.

medium[Protocol Class]
The protocol class that corresponds to the output state for some kind of sheet. There is no single advertised standard medium class. If you want to create a new class that behaves like a medium, it should be a subclass of medium. Subclasses of medium must obey the medium protocol.
mediumpobject[Predicate]
Returns true if object is a medium , otherwise returns false .

basic-medium[Class]
The basic class on which all CLIM mediums are built, a subclass of medium .

The following generic functions comprise the basic medium protocol. All mediums must implement methods for these generic functions. Often, a sheet class that supports the output protocol will implement a ``trampoline'' method that passes the operation on to sheet-medium of the sheet.

medium-foregroundmedium[Generic function]
(setf medium-foreground)design medium[Generic function]
Returns (and, with setf , sets) the current foreground ink for the medium medium . This is described in detail in Chapter Drawing Options .

medium-backgroundmedium[Generic function]
(setf medium-background)design medium[Generic function]
Returns (and, with setf , sets) the current background ink for the medium medium . This is described in detail in Chapter Drawing Options .

medium-inkmedium[Generic function]
(setf medium-ink)design medium[Generic function]
Returns (and, with setf , sets) the current drawing ink for the medium medium . This is described in detail in Chapter Drawing Options .

medium-transformationmedium[Generic function]
(setf medium-transformation)transformation medium[Generic function]
Returns (and, with setf , sets) the ``user'' transformation that converts the coordinates presented to the drawing functions by the programmer to the medium medium 's coordinate system. By default, it is the identity transformation. This is described in detail in Chapter Drawing Options .

medium-clipping-regionmedium[Generic function]
(setf medium-clipping-region)region medium[Generic function]
Returns (and, with setf , sets) the clipping region that encloses all output performed on the medium medium . It is returned and set in user coordinates. That is, to convert the user clipping region to medium coordinates, it must be transformed by the value of medium-transformation . For example, the values returned by

(let (cr1 cr2)
  ;; Ensure that the sheet's clipping region and transformation will be reset:
  (with-drawing-options (sheet :transformation +identity-transformation+
                               :clipping-region +everywhere+)
    (setf (medium-clipping-region sheet) (make-rectangle* 0 0 10 10))
    (setf (medium-transformation sheet) (clim:make-scaling-transformation 2 2))
    (setf cr1 (medium-clipping-region sheet))
    (setf (medium-clipping-region sheet) (make-rectangle* 0 0 10 10))
    (setf (medium-transformation sheet) +identity-transformation+)
    (setf cr2 (medium-clipping-region sheet))
    (values cr1 cr2)))
are two rectangles. The first one has edges of (0,0,5,5), while the second one has edges of (0,0,20,20).

By default, the user clipping region is the value of +everywhere+ .


Issue: SWM
What exactly are ``user coordinates''? We need to define all of the coordinate systems in one place: device, window, stream, etc.
medium-line-stylemedium[Generic function]
(setf medium-line-style)line-style medium[Generic function]
Returns (and, with setf , sets) the current line style for the medium medium . This is described in detail in Chapter Drawing Options and Section Line Styles .

medium-text-stylemedium[Generic function]
(setf medium-text-style)text-style medium[Generic function]
Returns (and, with setf , sets) the current text style for the medium medium of any textual output that may be displayed on the window. This is described in detail in Chapter Drawing Options .

medium-default-text-stylemedium[Generic function]
(setf medium-default-text-style)text-style medium[Generic function]
Returns (and, with setf , sets) the default text style for output on the medium medium . This is described in detail in Chapter Drawing Options .

medium-merged-text-stylemedium[Generic function]
Returns the actual text style used in rendering text on the medium medium . It returns the result of

(merge-text-styles (medium-text-style medium)
                   (medium-default-text-style medium))
Thus, those components of the current text style that are not nil will replace the defaults from medium's default text style. Unlike the preceding text style function, medium-merged-text-style is read-only.

8.3.2 Output Protocol Functions

The output protocol functions on mediums (and sheets that support the standard output protocol) include those functions described in Section Graphics Protocols .


Issue: SWM
We need to do a little better than this.

8.3.3 Output Protocol Classes

The following classes implement the standard output protocols. None of the five following classes is instantiable.

standard-sheet-output-mixin[Class]
This class is mixed in to any sheet that provides the standard output protocol, such as repainting and graphics.

sheet-mute-output-mixin[Class]
This class is mixed in to any sheet that provides none of the output protocol.

sheet-with-medium-mixin[Class]
This class is used for any sheet that has either a permanent or a temporary medium.

permanent-medium-sheet-output-mixin[Class]
This class is mixed in to any sheet that always has a medium associated with it. It is a subclass of sheet-with-medium-mixin .

temporary-medium-sheet-output-mixin[Class]
This class is mixed in to any sheet that may have a medium associated with it, but does not necessarily have a medium at any given instant. It is a subclass of sheet-with-medium-mixin .

8.3.4 Associating a Medium with a Sheet

Before a sheet may be used for output, it must be associated with a medium. Some sheets are permanently associated with media for output efficiency; for example, CLIM window stream sheets have a medium that is permanently allocated to the window.

However, many kinds of sheets only perform output infrequently, and therefore do not need to be associated with a medium except when output is actually required. Sheets without a permanently associated medium can be much more lightweight than they otherwise would be. For example, in a program that creates a sheet for the purpose of displaying a border for another sheet, the border sheet receives output only when the window's shape is changed.

To associate a sheet with a medium, the macro with-sheet-medium is used. Only sheets that are subclasses of sheet-with-medium-mixin may have a medium associated with them.

with-sheet-medium(medium sheet) &body body[Macro]
Within the body, the variable medium is bound to the sheet's medium. If the sheet does not have a medium permanently allocated, one will be allocated and associated with the sheet for the duration of the body (by calling engraft-medium ), and then degrafted from the sheet and deallocated when the body has been exited. The values of the last form of the body are returned as the values of with-sheet-medium .

This macro will signal a runtime error if sheet is not a subclass of sheet-with-medium-mixin .

The medium argument is not evaluated, and must be a symbol that is bound to a medium. body may have zero or more declarations as its first forms.

with-sheet-medium-bound(sheet medium) &body body[Macro]
with-sheet-medium-bound is used to associate the specific medium medium with the sheet sheet for the duration of the body body . Typically, a single medium will be allocated an passed to several different sheets that can use the same medium.

If the sheet already has a medium allocated to it, the new medium will not be grafted to the sheet, and with-sheet-medium-bound will simple evaluate the body. If the value of medium is nil , with-sheet-medium-bound is exactly equivalent to with-sheet-medium . The values of the last form of the body are returned as the values of with-sheet-medium-bound .

This macro will signal a runtime error if sheet is not a subclass of sheet-with-medium-mixin .

body may have zero or more declarations as its first forms.

sheet-mediumsheet[Generic function]
Returns the medium associated with the sheet sheet . If sheet does not have a medium allocated to it, sheet-medium returns nil .

This function will signal an error if sheet is not a subclass of sheet-with-medium-mixin .

medium-sheetmedium[Generic function]
Returns the sheet associated with the medium medium . If medium is not grafted to a sheet, medium-sheet returns nil .

medium-drawablemedium[Generic function]
Returns an implementation-dependent object that corresponds to the actual host window that will be drawn on when the medium medium is drawn on. If medium is not grafted to a sheet or the medium's sheet is not currently mirrored on a display server, medium-drawable returns nil .

Programmers can use this function to get a host window system object that can be manipulated using the functions of the host window system. This might be done in order to explicitly trade of performance against portability.

port(medium basic-medium )[Method]
If medium is both grafted to a sheet and the sheet is currently mirrored on a display server, this returns the port with which medium is associated. Otherwise it returns nil .

8.3.4.1 Grafting and Degrafting of Mediums

The following generic functions are the protocol-level functions responsible for the allocating, deallocating, grafting, and degrafting of mediums. They are not intended for general use by programmers.

allocate-mediumport sheet[Generic function]
Allocates a medium from the port port 's medium resource, or calls make-medium on the port to create a new medium if the resource is empty or the port does not maintain a resource of mediums. The resulting medium will have its default characteristics determined by sheet .

deallocate-mediumport medium[Generic function]
Returns the medium medium to port 's medium resource.

make-mediumport sheet[Generic function]
Creates a new medium for the port port . The new medium will have its default characteristics determined by sheet .

engraft-mediummedium port sheet[Generic function]
Grafts the medium medium to the sheet sheet on the port port .

The default method on basic-medium will set medium-sheet on medium to point to the sheet, and will set up the medium state (foreground ink, background ink, and so forth) from the defaults gotten from sheet. Each implementation may specialize this generic function in order to set up such things as per-medium ink caches, and so forth.

degraft-mediummedium port sheet[Generic function]
Degrafts the medium medium from the sheet sheet on the port port .

The default method on basic-medium will set medium-sheet back to nil . Each implementation may specialize this generic function in order to clear any caches it has set up, and so forth.

8.4 Repaint Protocol

The repaint protocol is the mechanism whereby a program keeps the display up-to-date, reflecting the results of both synchronous and asynchronous events. The repaint mechanism may be invoked by user programs each time through their top-level command loop. It may also be invoked directly or indirectly as a result of events received from the display server host. For example, if a window is on display with another window overlapping it, and the second window is buried, a ``damage notification'' event may be sent by the server; CLIM would cause a repaint to be executed for the newly-exposed region.

8.4.1 Repaint Protocol Functions

queue-repaintsheet repaint-event[Generic function]
Requests that the repaint event repaint-event be placed in the input queue of the sheet sheet . A program that reads events out of the queue will be expected to call handle-event for the sheet using the repaint region gotten from repaint-event .

handle-repaintsheet region[Generic function]
Implements repainting for a given sheet class. sheet is the sheet to repaint and region is the region to repaint.

repaint-sheetsheet region[Generic function]
Recursively causes repainting of the sheet sheet and any of its descendants that overlap the region region .

All CLIM implementations must support repainting for regions that are rectangles or region sets composed entirely of rectangles.

8.4.2 Repaint Protocol Classes

The following classes implement the standard repaint protocols. None of the three following classes is instantiable.

standard-repainting-mixin[Class]
Defines a dispatch-repaint method that calls queue-repaint .

immediate-repainting-mixin[Class]
Defines a dispatch-repaint method that calls handle-repaint .

sheet-mute-repainting-mixin[Class]
Defines a dispatch-repaint method that calls queue-repaint , and a method on repaint-sheet that does nothing. This means that its children will be recursively repainted when the repaint event is handled.

8.5 Sheet Notification Protocol

The notification protocol allows sheet clients to be notified when a sheet hierarchy is changed. Sheet clients can observe modification events by providing :after methods for functions defined by this protocol.

8.5.1 Relationship to Window System Change Notifications


Issue: RSL
More to be written.
note-sheet-graftedsheet[Generic function]
note-sheet-degraftedsheet[Generic function]
note-sheet-adoptedsheet[Generic function]
note-sheet-disownedsheet[Generic function]
note-sheet-enabledsheet[Generic function]
note-sheet-disabledsheet[Generic function]
These notification functions are invoked when the state change has been made to the sheet sheet .

8.5.2 Sheet Geometry Notifications


Issue: RSL
More to be written.
note-sheet-region-changedsheet[Generic function]
note-sheet-transformation-changedsheet[Generic function]
These notification functions are invoked when the region or transformation of the sheet sheet has been changed. When the regions and transformations of a sheet are changed directly, the client is required to call note-sheet-region-changed or note-sheet-transformation-changed .


9 Ports, Grafts, and Mirrored Sheets

9.1 Introduction

A sheet hierarchy must be attached to a display server so as to permit input and output. This is managed by the use of ports and grafts .

9.2 Ports

A port is a logical connection to a display server. It is responsible for managing display output and server resources, and for handling incoming input events. Typically, the programmer will create a single port that will manage all of the windows on the display.

A port is described with a server path . A server path is a list whose first element is a keyword that selects the kind of port. The remainder of the server path is a list of alternating keywords and values whose interpretation is port type-specific.

port[Protocol Class]
The protocol class that corresponds to a port. If you want to create a new class that behaves like a port, it should be a subclass of port. Subclasses of port must obey the port protocol.All of the subclasses of port are mutable.

portpobject[Predicate]
Returns true if object is a port , otherwise returns false .

basic-port[Class]
The basic class on which all CLIM ports are built, a subclass of port .

find-port&rest initargs &key (server-path *default-server-path* ) &allow-other-keys [Function]
Finds a port that provides a connection to the window server addressed by server-path . If no such connection exists, a new connection will be constructed and returned. The initargs in initargs will be passed to the function that constructed the new port.

*default-server-path*[Variable]
This special variable is used by find-port and its callers to default the choice of a display service to locate. Binding this variable in a dynamic context will affect the defaulting of this argument to these functions. This variable will be defaulted according to the environment. In the Unix environment, for example, CLIM will attempt to set this variable based on the value of the DISPLAY environment variable.

The value of *default-server-path* is a cons of a port type followed by a list of initargs.

The following are the recommendations for port types and their initargs. This list is not intended to be comprehensive, nor is it required that a CLIM implementation support any of these port types.

:clx &key host display-id screen-id
Given this server path, find-port finds a port for the X server on the given host , using the display-id and screen-id .

On a Unix host, if these values are not supplied, the defaults come from the DISPLAY environment variable. Each CLIM implementation must describe how it uses such environment variables.

:motif &key host display-id screen-id
Given this server path, find-port finds a port for a Motif X server on the given host , using the display-id and screen-id .

On a Unix host, if these values are not supplied, the defaults come from the DISPLAY environment variable.

:openlook &key host display-id screen-id
Given this server path, find-port finds a port for an OpenLook X server on the given host , using the display-id and screen-id .

On a Unix host, if these values are not supplied, the defaults come from the DISPLAY environment variable.

:genera &key screen
Given this server path, find-port finds a port for local Genera platform on the screen object screen . screen defaults to tv:main-screen , but could also be an object return from color:find-color-screen .

portobject[Generic function]
Returns the port associated with object . port is defined for all sheet classes (including grafts and streams that support the CLIM graphics protocol), mediums, and application frames. For degrafted sheets or other objects that aren't currently associated with particular ports, port will return nil .

with-port-locked(port) &body body[Macro]
Executes body after grabbing a lock associated with the port port , which may be a port or any object on which the function port works. If object currently has no port, body will be executed without locking.

body may have zero or more declarations as its first forms.

map-over-portsfunction[Function]
Invokes function on each existing port. Function is a function of one argument, the port; it has dynamic extent.

port-server-pathport[Generic function]
Returns the server path associated with the port port .

port-nameport[Generic function]
Returns an implementation-dependent string that is the name of the port. For example, a :clx port might have a name of "summer:0.0" .

port-typeport[Generic function]
Returns the type of the port, that is, the first element of the server path spec.

port-propertiesport indicator[Generic function]
(setf port-properties)property port indicator[Generic function]
These functions provide a port-based property list. They are primarily intended to support users of CLIM that may need to associate certain information with ports. For example, the implementor of a special graphics package may need to maintain resource tables for each port on which it is used.

restart-portport[Generic function]
In a multi-process Lisp, restart-port restarts the global input processing loop associated with the port port . All pending input events are discarded. Server resources may or may not be released and reallocated during or after this action.

destroy-portport[Generic function]
Destroys the connection with the window server represented by the port port . All sheet hierarchies that are associated with port are forcibly degrafted by disowning the children of grafts on port using sheet-disown-child . All server resources utilized by such hierarchies or by any graphics objects on port are released as part of the connection shutdown.

9.3 Grafts

A graft is a special sheet that is directly connected to a display server. Typically, a graft is the CLIM sheet that represents the root window of the display. There may be several grafts that are all attached to the same root window; these grafts may have differing coordinate systems.

To display a sheet on a display, it must have a graft for an ancestor. In addition, the sheet and all of its ancestors must be enabled, including the graft. In general, a sheet becomes grafted when it (or one of its ancestors) is adopted by a graft.

sheet-grafted-psheet[Generic function]
Returns true if any of the sheet's ancestors is a graft, otherwise returns false .

find-graft&key (server-path *default-server-path* ) (port (find-port :server-path server-path) ) (orientation :default ) (units :device )[Function]
Finds a graft that represents the display device on the port port that also matches the other supplied parameters. If no such graft exists, a new graft is constructed and returned.

If server-path is supplied, find-graft finds a graft whose port provides a connection to the window server addressed by server-path .

It is an error to provide both port and server-path in a call to find-graft .

orientation specifies the orientation of the graft's coordinate system. Supported values are :default and :graphics , which have the meanings describe below:

units specifies the units of the coordinate system and defaults to :device , which means the device units of the host window system (such as pixels). Other supported values include :inches , :millimeters , and :screen-sized , which means that one unit in each direction is the width and height of the display device.


Issue: RSL
I don't know how much of this is obsolete.
graftobject[Generic function]
Returns the graft currently associated with object . graft is defined for all sheet classes (including streams that support the CLIM graphics protocol), mediums, and application frames. For degrafted sheets or other objects that aren't currently associated with a particular graft, graft will return nil .

map-over-graftsfunction port[Function]
Invokes function on each existing graft associated with the port port . function is a function of one argument, the graft; it has dynamic extent.

with-graft-locked(graft) &body body[Macro]
Executes body after grabbing a lock associated with the graft graft , which may be a graft or any object on which the function graft works. If object currently has no graft, body will be executed without locking.

body may have zero or more declarations as its first forms.

graft-orientationgraft[Generic function]
Returns the orientation of the graft graft 's coordinate system. The returned value will be either :default or :graphics . The meanings of these values are the same as described for the orientation argument to find-graft .

graft-unitsgraft[Generic function]
Returns the units of the graft graft 's coordinate system. The returned value will be one of :device , :inches , :millimeters , or :screen-sized . The meanings of these values are the same as described for the units argument to find-graft .

graft-widthgraft &key (units :device )[Generic function]
graft-heightgraft &key (units :device )[Generic function]
Returns the width and height of the graft graft (and by extension the associated host window) in the units indicated. Units may be any of :device , :inches , :millimeters , or :screen-sized . The meanings of these values are the same as described for the units argument to find-graft . Note if a unit of :screen-sized is specified, both of these functions will return a value of 1 .

graft-pixels-per-millimetergraft[Function]
graft-pixels-per-inchgraft[Function]
Returns the number of pixels per millimeter or inch of the graft graft . These functions are provided as a convenience to programmers and can be easily written in terms of graft-width or graft-height .


Issue: Rao
Do we want to support non-square pixels? If so, these functions aren't sufficient.

9.4 Mirrors and Mirrored Sheets

A mirrored sheet is a special class of sheet that is attached directly to a window on a display server. Grafts, for example, are always mirrored sheets. However, any sheet anywhere in a sheet hierarchy may be a mirrored sheet. A mirrored sheet will usually contain a reference to a window system object, called a mirror. For example, a mirrored sheet attached to an X11 server might have an X window system object stored in one of its slots. Allowing mirrored sheets at any point in the hierarchy enables the adaptive toolkit facilities.

Since not all she