nuclear@6: Composite Extension nuclear@6: Version 0.4 nuclear@6: 2007-7-3 nuclear@6: Keith Packard nuclear@6: keithp@keithp.com nuclear@6: Deron Johnson nuclear@6: deron.johnson@sun.com nuclear@6: nuclear@6: 1. Introduction nuclear@6: nuclear@6: Many user interface operations would benefit from having pixel contents of nuclear@6: window hierarchies available without respect to sibling and antecedent nuclear@6: clipping. In addition, placing control over the composition of these pixel nuclear@6: contents into a final screen image in an external application will enable nuclear@6: a flexible system for dynamic application content presentation. nuclear@6: nuclear@6: 2. Acknowledgements nuclear@6: nuclear@6: This small extension has been brewing for several years, contributors to nuclear@6: both early prototypes and the final design include: nuclear@6: nuclear@6: + Bill Haneman for motivating the ability to magnify occluded windows nuclear@6: with his work on accessibility nuclear@6: nuclear@6: + Carsten Haitzler for Enlightenment, the original eye-candy window nuclear@6: manager which demonstrated that clever hacks are an awfully nuclear@6: close substitute for changes in the underlying system. nuclear@6: nuclear@6: + Jim Gettys for key insights into the relationship between damage nuclear@6: events and per-window pixmap usage nuclear@6: nuclear@6: + Mike Harris and Owen Taylor for figuring out what to call it. nuclear@6: nuclear@6: + Deron Johnson for the Looking Glass implementation and nuclear@6: a prototype of the coordinate transformation mechanism. nuclear@6: nuclear@6: + Ryan Lortie for helping figure out reasonable parent clipping nuclear@6: semantics in the presense of manual redirected children. nuclear@6: nuclear@6: 3. Architecture nuclear@6: nuclear@6: The composite extension provides three related mechanisms: nuclear@6: nuclear@6: 1. Per-hierarchy storage. The rendering of an entire hierarchy of windows nuclear@6: is redirected to off-screen storage. The pixels of that hierarchy nuclear@6: are available whenever it is viewable. Storage is automatically nuclear@6: reallocated when the top level window changes size. Contents beyond nuclear@6: the geometry of the top window are not preserved. nuclear@6: nuclear@6: 2. Automatic shadow update. When a hierarchy is rendered off-screen, nuclear@6: the X server provides an automatic mechanism for presenting those nuclear@6: contents within the parent window. The implementation is free to nuclear@6: make this update lag behind actual rendering operations by an nuclear@6: unspecified amount of time. This automatic update mechanism may nuclear@6: be disabled so that the parent window contents can be completely nuclear@6: determined by an external application. nuclear@6: nuclear@6: 3. External parent - child pointer coordinate transformation. nuclear@6: When a hierarchy is under manual compositing, the relationship nuclear@6: of coordinates within the parent to those in the child may nuclear@6: not be known within the X server. This mechanism provides nuclear@6: for redirection of these transformations through a client. nuclear@6: nuclear@6: Per-hierarchy storage may be created for individual windows or for all nuclear@6: children of a window. Manual shadow update may be selected by only a single nuclear@6: application for each window; manual update may also be selected on a nuclear@6: per-window basis or for each child of a window. Detecting when to update nuclear@6: may be done with the Damage extension. nuclear@6: nuclear@6: The off-screen storage includes the window contents, its borders and the nuclear@6: contents of all descendants. nuclear@6: nuclear@6: 3.1 NameWindowPixmap nuclear@6: nuclear@6: Version 0.2 of the protocol introduces a mechanism for associating an XID nuclear@6: with the off-screen pixmap used to store these contents. This can be used nuclear@6: to hold onto window contents after the window is unmapped (and hence animate nuclear@6: it's disappearance), and also to access the border of the window, which is nuclear@6: not reachable through the Window ID itself. A new pixmap is created each nuclear@6: time the window is mapped or resized; as these events are nicely signalled nuclear@6: with existing events, no additional notification is needed. The old pixmap nuclear@6: will remain allocated as long as the Pixmap ID is left valid, it is nuclear@6: important that the client use the FreePixmap request when it is done with nuclear@6: the contents and to create a new name for the newly allocated pixmap. nuclear@6: nuclear@6: In automatic update mode, the X server is itself responsible for presenting nuclear@6: the child window contents within the parent. It seems reasonable, then, for nuclear@6: rendering to the parent window to be clipped so as not to interfere with any nuclear@6: child window content. In an environment with a mixure of manual and nuclear@6: automatic updating windows, rendering to the parent in the area nominally nuclear@6: occupied by a manual update window should be able to affect parent pixel nuclear@6: values in those areas, but such rendering should be clipped to automatic nuclear@6: update windows, and presumably to other manual update windows managed by nuclear@6: other applications. In any of these cases, it should be easy to ensure that nuclear@6: rendering has no effect on any non-redirected windows. nuclear@6: nuclear@6: Instead of attempting to define new clipping modes for rendering, the nuclear@6: Composite extension instead defines ClipByChildren rendering to the parent nuclear@6: to exclude regions occupied by redirected windows (either automatic or nuclear@6: manual). The CreateRegionFromBorderClip request can be used along with nuclear@6: IncludeInferiors clipping modes to restrict manual shadow updates to the nuclear@6: apporpriate region of the screen. Bracketing operations with nuclear@6: GrabServer/UngrabServer will permit atomic sequences that can update the nuclear@6: screen without artifact. As all of these operations are asynchronous, nuclear@6: network latency should not adversely affect update latency. nuclear@6: nuclear@6: 3.2 Composite Overlay Window nuclear@6: nuclear@6: Version 0.3 of the protocol adds the Composite Overlay Window, which nuclear@6: provides compositing managers with a surface on which to draw without nuclear@6: interference. This window is always above normal windows and is always nuclear@6: below the screen saver window. It is an InputOutput window whose width nuclear@6: and height are the screen dimensions. Its visual is the root visual nuclear@6: and its border width is zero. Attempts to redirect it using the nuclear@6: composite extension are ignored. This window does not appear in the nuclear@6: reply of the QueryTree request. It is also an override redirect window. nuclear@6: These last two features make it invisible to window managers and other X11 nuclear@6: clients. The only way to access the XID of this window is via the nuclear@6: CompositeGetOverlayWindow request. Initially, the Composite Overlay nuclear@6: Window is unmapped. nuclear@6: nuclear@6: CompositeGetOverlayWindow returns the XID of the Composite Overlay nuclear@6: Window. If the window has not yet been mapped, it is mapped by this nuclear@6: request. When all clients who have called this request have terminated nuclear@6: their X11 connections the window is unmapped. nuclear@6: nuclear@6: Composite managers may render directly to the Composite Overlay nuclear@6: Window, or they may reparent other windows to be children of this nuclear@6: window and render to these. Multiple clients may render to the nuclear@6: Composite Overlay Window, create child windows of it, reshape it, and nuclear@6: redefine its input region, but the specific arbitration rules followed nuclear@6: by these clients is not defined by this specification; these policies nuclear@6: should be defined by the clients themselves. nuclear@6: nuclear@6: 3.3 Clipping semantics redefined nuclear@6: nuclear@6: Version 0.4 of the protocol changes the semantics of clipping in the nuclear@6: presense of manual redirect children. In version 0.3, a parent was always nuclear@6: clipped to child windows, independent of the kind of redirection going on. nuclear@6: With version 0.4, the parent is no longer clipped to child windows which are nuclear@6: manually redirected. This means the parent can draw in the child region without using nuclear@6: IncludeInferiors mode, and (perhaps more importantly), it will receive nuclear@6: expose events in those regions caused by other actions. This new behaviour nuclear@6: is not selectable. nuclear@6: nuclear@6: 4. Errors nuclear@6: nuclear@6: The composite extension does not define any new errors. nuclear@6: nuclear@6: 5. Types nuclear@6: nuclear@6: UPDATETYPE { Automatic, Manual } nuclear@6: nuclear@6: CompositeCoordinate nuclear@6: child: Window nuclear@6: x, y: CARD16 nuclear@6: nuclear@6: 7. Extension Initialization nuclear@6: nuclear@6: The client must negotiate the version of the extension before executing nuclear@6: extension requests. Otherwise, the server will return BadRequest for any nuclear@6: operations other than QueryVersion. nuclear@6: nuclear@6: QueryVersion nuclear@6: nuclear@6: client-major-version: CARD32 nuclear@6: client-minor-version: CARD32 nuclear@6: nuclear@6: -> nuclear@6: nuclear@6: major-version: CARD32 nuclear@6: minor-version: CARD32 nuclear@6: nuclear@6: The client sends the highest supported version to the server and nuclear@6: the server sends the highest version it supports, but no higher than nuclear@6: the requested version. Major versions changes can introduce nuclear@6: incompatibilities in existing functionality, minor version nuclear@6: changes introduce only backward compatible changes. It is nuclear@6: the client's responsibility to ensure that the server supports nuclear@6: a version which is compatible with its expectations. Servers nuclear@6: are encouraged to support multiple versions of the extension. nuclear@6: nuclear@6: 8. Hierarchy Redirection nuclear@6: nuclear@6: RedirectWindow nuclear@6: nuclear@6: window: Window nuclear@6: update: UPDATETYPE nuclear@6: nuclear@6: errors: Window, Access, Match nuclear@6: nuclear@6: The hierarchy starting at 'window' is directed to off-screen nuclear@6: storage. 'update' specifies whether the contents are mirrored to nuclear@6: the parent window automatically or not. Only one client may specify nuclear@6: an update type of Manual, another attempt will result in an nuclear@6: Access error. When all clients enabling redirection terminate, nuclear@6: the redirection will automatically be disabled. nuclear@6: nuclear@6: The root window may not be redirected. Doing so results in a Match nuclear@6: error. nuclear@6: nuclear@6: RedirectSubwindows nuclear@6: nuclear@6: window: Window nuclear@6: update UPDATETYPE nuclear@6: nuclear@6: errors: Window, Access nuclear@6: nuclear@6: Hierarchies starting at all current and future children of window nuclear@6: will be redirected as in RedirectWindow. If update is Manual, nuclear@6: then painting of the window background during window manipulation nuclear@6: and ClearArea requests is inhibited. nuclear@6: nuclear@6: UnredirectWindow: nuclear@6: nuclear@6: window: Window nuclear@6: nuclear@6: errors: Window, Value nuclear@6: nuclear@6: Redirection of the specified window will be terminated. If nuclear@6: the specified window was not selected for redirection by the nuclear@6: current client, a 'Value' error results. nuclear@6: nuclear@6: UnredirectWindows: nuclear@6: nuclear@6: window: Window nuclear@6: nuclear@6: errors: Window, Value nuclear@6: nuclear@6: Redirection of all children of window will be terminated. If nuclear@6: the specified window was not selected for sub-redirection by the nuclear@6: current client, a 'Value' error results. nuclear@6: nuclear@6: 9. Clip lists nuclear@6: nuclear@6: CreateRegionFromBorderClip nuclear@6: nuclear@6: region: Region nuclear@6: window: Window nuclear@6: nuclear@6: errors: Window, IDChoice nuclear@6: nuclear@6: This request creates a region containing the "usual" border clip nuclear@6: value; that is the area of the window clipped against siblings and nuclear@6: the parent. This region can be used to restrict rendering to nuclear@6: suitable areas while updating only a single window. The region nuclear@6: is copied at the moment the request is executed; future changes nuclear@6: to the window hierarchy will not be reflected in this region. nuclear@6: nuclear@6: 10. Associating a Pixmap ID with the off-screen storage (0.2 and later) nuclear@6: nuclear@6: NameWindowPixmap nuclear@6: nuclear@6: window: Window nuclear@6: pixmap: Pixmap nuclear@6: nuclear@6: errors: Window, Match, IDChoice nuclear@6: nuclear@6: This request makes 'pixmap' a reference to the off-screen storage nuclear@6: for 'window'. This pixmap will remain allocated until freed, even nuclear@6: if 'window' is unmapped, reconfigured or destroyed. However, nuclear@6: 'window' will get a new pixmap allocated each time it is nuclear@6: mapped or resized, so this request will need to be reinvoked for nuclear@6: the client to continue to refer to the storage holding the current nuclear@6: window contents. Generates a 'Match' error if 'window' is not nuclear@6: redirected or is not visible. nuclear@6: nuclear@6: 11. Composite Overlay Window (0.3 and later) nuclear@6: nuclear@6: CompositeGetOverlayWindow nuclear@6: nuclear@6: window: Window nuclear@6: nuclear@6: -> nuclear@6: nuclear@6: overlayWin: Window nuclear@6: nuclear@6: This request returns the XID of the Composite Overlay Window for nuclear@6: the screen specified by the argument 'window'. This request nuclear@6: indicates that the client wishes to use the Composite Overlay nuclear@6: Window of this screen. If this Composite Overlay Window has not nuclear@6: yet been mapped, it is mapped by this request. nuclear@6: nuclear@6: The Composite Overlay Window for a particular screen will be nuclear@6: unmapped when all clients who have invoked this request have nuclear@6: also invoked CompositeReleaseOverlayWindow for that screen. Also, nuclear@6: CompositeReleaseOverlayWindow for a screen will be implicitly nuclear@6: called when a client using the Composite Overlay Window on that nuclear@6: screen terminates its X11 connection. nuclear@6: nuclear@6: nuclear@6: CompositeReleaseOverlayWindow nuclear@6: nuclear@6: window: Window nuclear@6: nuclear@6: This request specifies that the client is no longer using the nuclear@6: Composite Overlay Window on the screen specified by the nuclear@6: argument 'window'. A screen's Composite Overlay Window is nuclear@6: unmapped when there are no longer any clients using it. nuclear@6: nuclear@6: 12. External coordinate transformation (0.4 and later) nuclear@6: nuclear@6: RedirectCoordinate nuclear@6: nuclear@6: window: Window nuclear@6: redirect: BOOL nuclear@6: nuclear@6: errors: Window, Access nuclear@6: nuclear@6: If 'redirect' is TRUE, the requesting client is placed in charge of nuclear@6: coordinate transformations between 'window' and its children. If nuclear@6: 'redirect' is FALSE, any such redirection is disabled. Any nuclear@6: transformations needed by the server will be delivered to the nuclear@6: requesting client in TransformCoordinateNotify events and the nuclear@6: requesting client must reply with matching TransformCoordinate nuclear@6: requests for the server to continue with the operation. nuclear@6: nuclear@6: Generates an 'Access' error if another client has nuclear@6: redirected coordinates for 'window'. nuclear@6: nuclear@6: TransformCoordinate nuclear@6: nuclear@6: window: Window nuclear@6: serialNumber: CARD32 nuclear@6: x, y: INT16 nuclear@6: coordinates: LISTofCompositeCoordinate nuclear@6: nuclear@6: This provides the transformation data needed by the server for a nuclear@6: single TransformCoordinateNotify event. 'serialNumber' must match nuclear@6: the serial number delivered in the event. 'x' and 'y' represent the nuclear@6: coordinate from the event relative to the 'window'. 'coordinates' nuclear@6: represent the coordinate from the event relative to each child nuclear@6: listed. Any children not listed in 'coordinates' are given the nuclear@6: default transformation using the child window position within the nuclear@6: parent as a simple translation. nuclear@6: nuclear@6: The result of this is that any pointer data seen by means of nuclear@6: the protocol will appear to reflect the transformation nuclear@6: performed by this request.