nuclear@6: The XFIXES Extension nuclear@6: Version 4.0 nuclear@6: Document Revision 2 nuclear@6: 2006-12-14 nuclear@6: Keith Packard nuclear@6: keithp@keithp.com nuclear@6: nuclear@6: 1. Introduction nuclear@6: nuclear@6: X applications have often needed to work around various shortcomings in the nuclear@6: core X window system. This extension is designed to provide the minimal nuclear@6: server-side support necessary to eliminate problems caused by these nuclear@6: workarounds. nuclear@6: nuclear@6: 2. Acknowledgements nuclear@6: nuclear@6: This extension is a direct result of requests made by application nuclear@6: developers, in particular, nuclear@6: nuclear@6: + Owen Taylor for describing the issues raised with the XEMBED nuclear@6: mechanisms and SaveSet processing and his initial extension nuclear@6: to handle this issue. nuclear@6: nuclear@6: + Bill Haneman for the design for cursor image tracking. nuclear@6: nuclear@6: + Havoc Pennington nuclear@6: nuclear@6: + Fredrik Höglund for cursor names nuclear@6: nuclear@6: + Deron Johnson for cursor visibility nuclear@6: nuclear@6: 3. Basic Premise nuclear@6: nuclear@6: Requests in this extension may seem to wander all over the map of X server nuclear@6: capabilities, but they are tied by a simple rule -- resolving issues raised nuclear@6: by application interaction with core protocol mechanisms that cannot be nuclear@6: adequately worked around on the client side of the wire. nuclear@6: nuclear@6: 4. Extension initialization nuclear@6: nuclear@6: The client must negotiate the version of the extension before executing nuclear@6: extension requests. Behavior of the server is undefined otherwise. 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: new requests, minor version changes introduce only adjustments to nuclear@6: existing requests or backward compatible changes. It is nuclear@6: the clients responsibility to ensure that the server supports nuclear@6: a version which is compatible with its expectations. nuclear@6: nuclear@6: ************* XFIXES VERSION 1 OR BETTER *********** nuclear@6: nuclear@6: 5. Save Set processing changes nuclear@6: nuclear@6: Embedding one application within another provides a way of unifying nuclear@6: disparate documents and views within a single framework. From the X nuclear@6: protocol perspective, this appears similar to nested window managers; the nuclear@6: embedding application "manages" the embedded windows much as a window nuclear@6: manager does for top-level windows. To protect the embedded application nuclear@6: from embedding application failure, it is reasonable to use the core SaveSet nuclear@6: mechanism so that embedding application failure causes embedded windows to nuclear@6: be preserved instead of destroyed. nuclear@6: nuclear@6: The core save set mechanism defines the target for each save set member nuclear@6: window as the nearest enclosing window not owned by the terminating client. nuclear@6: For embedding applications, this nearest window is usually the window nuclear@6: manager frame. The problem here is that the window manager will not nuclear@6: generally expect to receive and correctly manage new windows appearing within nuclear@6: that window by the save set mechanism, and will instead destroy the frame nuclear@6: window in response to the client window destruction. This causes the nuclear@6: embedded window to be destroyed. nuclear@6: nuclear@6: An easy fix for this problem is to change the target of the save set member nuclear@6: to a window which won't be affected by the underlying window destruction. nuclear@6: XFIXES chooses the root window as the target. nuclear@6: nuclear@6: Having embedded windows suddenly appear at the top level can confuse users, nuclear@6: so XFIXES also lets the client select whether the window should end up nuclear@6: unmapped after the save set processing instead of unconditionally making nuclear@6: them be mapped. nuclear@6: nuclear@6: 5.1 Requests nuclear@6: nuclear@6: ChangeSaveSet nuclear@6: nuclear@6: window: Window nuclear@6: mode: { Insert, Delete } nuclear@6: target: { Nearest, Root } nuclear@6: map: { Map, Unmap } nuclear@6: nuclear@6: ChangeSaveSet is an extension of the core protocol ChangeSaveSet nuclear@6: request. As in that request, mode specifies whether the indicated nuclear@6: window is inserted or deleted from the save-set. Target specifies nuclear@6: whether the window is reparented to the nearest non-client window as nuclear@6: in the core protocol, or reparented to the root window. Map nuclear@6: specifies whether the window is mapped as in the core protocol or nuclear@6: unmapped. nuclear@6: nuclear@6: 6. Selection Tracking nuclear@6: nuclear@6: Applications wishing to monitor the contents of current selections must nuclear@6: poll for selection changes. XFIXES improves this by providing an event nuclear@6: delivered whenever the selection ownership changes. nuclear@6: nuclear@6: 6.1 Types nuclear@6: nuclear@6: SELECTIONEVENT { SetSelectionOwner, nuclear@6: SelectionWindowDestroy, nuclear@6: SelectionClientClose } nuclear@6: nuclear@6: 6.1 Events nuclear@6: nuclear@6: SelectionNotify nuclear@6: nuclear@6: subtype: SELECTIONEVENT nuclear@6: window: Window nuclear@6: owner: Window nuclear@6: selection: Atom nuclear@6: timestamp: Timestamp nuclear@6: selection-timestamp: Timestamp nuclear@6: nuclear@6: 6.2 Requests nuclear@6: nuclear@6: SelectSelectionInput nuclear@6: nuclear@6: window: Window nuclear@6: selection: Atom nuclear@6: event-mask: SETofSELECTIONEVENT nuclear@6: nuclear@6: Selects for events to be delivered to window when various causes of nuclear@6: ownership of selection occur. Subtype indicates the cause of the nuclear@6: selection ownership change. Owner is set to the current selection nuclear@6: owner, or None. Timestamp indicates the time the event was nuclear@6: generated while selection-timestamp indicates the timestamp used to nuclear@6: own the selection. nuclear@6: nuclear@6: 7. Cursor Image Monitoring nuclear@6: nuclear@6: Mirroring the screen contents is easily done with the core protocol or VNC nuclear@6: addons, except for the current cursor image. There is no way using the core nuclear@6: protocol to discover which cursor image is currently displayed. The nuclear@6: cursor image often contains significant semantic content about the user nuclear@6: interface. XFIXES provides a simple mechanism to discover when the cursor nuclear@6: image changes and to fetch the current cursor image. nuclear@6: nuclear@6: As the current cursor may or may not have any XID associated with it, there nuclear@6: is no stable name available. Instead, XFIXES returns only the image of the nuclear@6: current cursor and provides a way to identify cursor images to avoid nuclear@6: refetching the image each time it changes to a previously seen cursor. nuclear@6: nuclear@6: 7.1 Types nuclear@6: CURSOREVENT { DisplayCursor } nuclear@6: nuclear@6: 7.2 Events nuclear@6: nuclear@6: CursorNotify nuclear@6: nuclear@6: subtype: CURSOREVENT nuclear@6: window: Window nuclear@6: cursor-serial: CARD32 nuclear@6: timestamp: Timestamp nuclear@6: name: Atom (Version 2 only) nuclear@6: nuclear@6: 7.3 Requests nuclear@6: nuclear@6: SelectCursorInput nuclear@6: nuclear@6: window: Window nuclear@6: event-mask: SETofCURSOREVENT nuclear@6: nuclear@6: This request directs cursor change events to the named window. nuclear@6: Events will be delivered irrespective of the screen on which they nuclear@6: occur. Subtype indicates the cause of the cursor image change nuclear@6: (there is only one subtype at present). Cursor-serial is a number nuclear@6: assigned to the cursor image which identifies the image. Cursors nuclear@6: with different serial numbers may have different images. Timestamp nuclear@6: is the time of the cursor change. nuclear@6: nuclear@6: Servers supporting the X Input Extension Version 2.0 or higher only nuclear@6: notify the clients of cursor change events for the ClientPointer, not nuclear@6: of any other master pointer (see Section 4.4. in the XI2 protocol nuclear@6: specificiation). nuclear@6: nuclear@6: GetCursorImage nuclear@6: nuclear@6: -> nuclear@6: nuclear@6: x: INT16 nuclear@6: y: INT16 nuclear@6: width: CARD16 nuclear@6: height: CARD16 nuclear@6: x-hot: CARD16 nuclear@6: y-hot: CARD16 nuclear@6: cursor-serial: CARD32 nuclear@6: cursor-image: LISTofCARD32 nuclear@6: nuclear@6: GetCursorImage returns the image of the current cursor. X and y are nuclear@6: the current cursor position. Width and height are the size of the nuclear@6: cursor image. X-hot and y-hot mark the hotspot within the cursor nuclear@6: image. Cursor-serial provides the number assigned to this cursor nuclear@6: image, this same serial number will be reported in a CursorNotify nuclear@6: event if this cursor image is redisplayed in the future. nuclear@6: nuclear@6: The cursor image itself is returned as a single image at 32 bits per nuclear@6: pixel with 8 bits of alpha in the most significant 8 bits of the nuclear@6: pixel followed by 8 bits each of red, green and finally 8 bits of nuclear@6: blue in the least significant 8 bits. The color components are nuclear@6: pre-multiplied with the alpha component. nuclear@6: nuclear@6: ************* XFIXES VERSION 2 OR BETTER *********** nuclear@6: nuclear@6: 8. Region Objects nuclear@6: nuclear@6: The core protocol doesn't expose regions as a primitive object and this nuclear@6: makes many operations more complicated than they really need to be. Adding nuclear@6: region objects simplifies expose handling, the Shape extension and other nuclear@6: operations. These operations are also designed to support a separate nuclear@6: extension, the X Damage Extension. nuclear@6: nuclear@6: 8.1 Types nuclear@6: nuclear@6: Region: XID nuclear@6: WINDOW_REGION_KIND: { Bounding, Clip } nuclear@6: nuclear@6: 8.2 Errors nuclear@6: nuclear@6: Region The specified region is invalid nuclear@6: nuclear@6: 8.3 Requests nuclear@6: nuclear@6: CreateRegion nuclear@6: nuclear@6: region: REGION nuclear@6: rects: LISTofRECTANGLE nuclear@6: nuclear@6: Creates a region initialized to the specified list of rectangles. nuclear@6: The rectangles may be specified in any order, their union becomes nuclear@6: the region. The core protocol allows applications to specify an nuclear@6: order for the rectangles, but it turns out to be just as hard to nuclear@6: verify the rectangles are actually in that order as it is to simply nuclear@6: ignore the ordering information and union them together. Hence, nuclear@6: this request dispenses with the ordering information. nuclear@6: nuclear@6: Errors: IDChoice nuclear@6: nuclear@6: CreateRegionFromBitmap nuclear@6: nuclear@6: region: REGION nuclear@6: bitmap: PIXMAP nuclear@6: nuclear@6: Creates a region initialized to the set of 'one' pixels in bitmap nuclear@6: (which must be depth 1, else Match error). nuclear@6: nuclear@6: Errors: Pixmap, IDChoice, Match nuclear@6: nuclear@6: CreateRegionFromWindow nuclear@6: nuclear@6: window: Window nuclear@6: kind: WINDOW_REGION_KIND nuclear@6: region: Region nuclear@6: nuclear@6: Creates a region initialized to the specified window region. See the nuclear@6: Shape extension for the definition of Bounding and Clip regions. nuclear@6: nuclear@6: Errors: Window, IDChoice, Value nuclear@6: nuclear@6: CreateRegionFromGC nuclear@6: nuclear@6: gc: GContext nuclear@6: region: Region nuclear@6: nuclear@6: Creates a region initialized from the clip list of the specified nuclear@6: GContext. nuclear@6: nuclear@6: Errors: GContext, IDChoice nuclear@6: nuclear@6: CreateRegionFromPicture nuclear@6: nuclear@6: picture: Picture nuclear@6: region: Region nuclear@6: nuclear@6: nuclear@6: Creates a region initialized from the clip list of the specified nuclear@6: Picture. nuclear@6: nuclear@6: Errors: Picture, IDChoice nuclear@6: nuclear@6: DestroyRegion nuclear@6: nuclear@6: region: Region nuclear@6: nuclear@6: Destroys the specified region. nuclear@6: nuclear@6: Errors: Region nuclear@6: nuclear@6: SetRegion nuclear@6: nuclear@6: region: Region nuclear@6: rects: LISTofRECTANGLE nuclear@6: nuclear@6: This replaces the current contents of region with the region formed nuclear@6: by the union of rects. nuclear@6: nuclear@6: CopyRegion nuclear@6: source: Region nuclear@6: destination: Region nuclear@6: nuclear@6: This replaces the contents of destination with the contents of nuclear@6: source. nuclear@6: nuclear@6: UnionRegion nuclear@6: IntersectRegion nuclear@6: SubtractRegion nuclear@6: nuclear@6: source1: Region nuclear@6: source2: Region nuclear@6: destination: Region nuclear@6: nuclear@6: Combines source1 and source2, placing the result in destination. nuclear@6: Destination may be the same as either source1 or source2. nuclear@6: nuclear@6: Errors: Region, Value nuclear@6: nuclear@6: InvertRegion nuclear@6: nuclear@6: source: Region nuclear@6: bounds: RECTANGLE nuclear@6: destination: Region nuclear@6: nuclear@6: The source region is subtracted from the region specified by nuclear@6: bounds. The result is placed in destination, replacing its contents. nuclear@6: nuclear@6: Errors: Region nuclear@6: nuclear@6: TranslateRegion nuclear@6: nuclear@6: region: Region nuclear@6: dx, dy: INT16 nuclear@6: nuclear@6: The region is translated by dx, dy in place. nuclear@6: nuclear@6: Errors: Region nuclear@6: nuclear@6: RegionExtents nuclear@6: nuclear@6: source: Region nuclear@6: destination: Region nuclear@6: nuclear@6: The extents of the source region are placed in the destination nuclear@6: nuclear@6: FetchRegion nuclear@6: nuclear@6: region: Region nuclear@6: -> nuclear@6: extents: RECTANGLE nuclear@6: rectangles: LISTofRECTANGLE nuclear@6: nuclear@6: The region is returned as a list of rectangles in YX-banded order. nuclear@6: nuclear@6: Errors: Region nuclear@6: nuclear@6: SetGCClipRegion nuclear@6: nuclear@6: gc: GCONTEXT nuclear@6: clip-x-origin, clip-y-origin: INT16 nuclear@6: region: Region or None nuclear@6: nuclear@6: This request changes clip-mask in gc to the specified region and nuclear@6: sets the clip origin. Output will be clipped to remain contained nuclear@6: within the region. The clip origin is interpreted relative to the nuclear@6: origin of whatever destination drawable is specified in a graphics nuclear@6: request. The region is interpreted relative to the clip origin. nuclear@6: Future changes to region have no effect on the gc clip-mask. nuclear@6: nuclear@6: Errors: GContext, Region nuclear@6: nuclear@6: SetWindowShapeRegion nuclear@6: nuclear@6: dest: Window nuclear@6: destKind: SHAPE_KIND nuclear@6: xOff, yOff: INT16 nuclear@6: region: Region or None nuclear@6: nuclear@6: This request sets the specified (by destKind) Shape extension region nuclear@6: of the window to region, offset by xOff and yOff. Future changes to nuclear@6: region have no effect on the window shape. nuclear@6: nuclear@6: Errors: Window, Value, Region nuclear@6: nuclear@6: SetPictureClipRegion nuclear@6: nuclear@6: picture: Picture nuclear@6: clip-x-origin, clip-y-origin: INT16 nuclear@6: region: Region or None nuclear@6: nuclear@6: This request changes clip-mask in picture to the specified region nuclear@6: and sets the clip origin. Input and output will be clipped to nuclear@6: remain contained within the region. The clip origin is interpreted nuclear@6: relative to the origin of the drawable associated with picture. The nuclear@6: region is interpreted relative to the clip origin. Future changes nuclear@6: to region have no effect on the picture clip-mask. nuclear@6: nuclear@6: Errors: Picture, Region nuclear@6: nuclear@6: 9. Cursor Names nuclear@6: nuclear@6: Attaching names to cursors permits some abstract semantic content to be nuclear@6: associated with specific cursor images. Reflecting those names back to nuclear@6: applications allows that semantic content to be related to the user through nuclear@6: non-visual means. nuclear@6: nuclear@6: 9.1 Events nuclear@6: nuclear@6: CursorNotify nuclear@6: nuclear@6: subtype: CURSOREVENT nuclear@6: window: Window nuclear@6: cursor-serial: CARD32 nuclear@6: timestamp: Timestamp nuclear@6: name: Atom or None nuclear@6: nuclear@6: In Version 2 of the XFIXES protocol, this event adds the atom nuclear@6: of any name associated with the current cursor (else None). nuclear@6: nuclear@6: 9.2 Requests nuclear@6: nuclear@6: SetCursorName nuclear@6: nuclear@6: cursor: CURSOR nuclear@6: name: LISTofCARD8 nuclear@6: nuclear@6: This request interns name as an atom and sets that atom as the name nuclear@6: of cursor. nuclear@6: nuclear@6: Errors: Cursor nuclear@6: nuclear@6: GetCursorName nuclear@6: nuclear@6: cursor: CURSOR nuclear@6: -> nuclear@6: atom: ATOM or None nuclear@6: name: LISTofCARD8 nuclear@6: nuclear@6: This request returns the name and atom of cursor. If no name is nuclear@6: set, atom is None and name is empty. nuclear@6: nuclear@6: Errors: Cursor nuclear@6: nuclear@6: GetCursorImageAndName nuclear@6: nuclear@6: -> nuclear@6: nuclear@6: x: INT16 nuclear@6: y: INT16 nuclear@6: width: CARD16 nuclear@6: height: CARD16 nuclear@6: x-hot: CARD16 nuclear@6: y-hot: CARD16 nuclear@6: cursor-serial: CARD32 nuclear@6: cursor-atom: ATOM nuclear@6: cursor-name: LISTofCARD8 nuclear@6: cursor-image: LISTofCARD32 nuclear@6: nuclear@6: This is similar to GetCursorImage except for including both nuclear@6: the atom and name of the current cursor. nuclear@6: nuclear@6: ChangeCursor nuclear@6: nuclear@6: source, destination: CURSOR nuclear@6: nuclear@6: This request replaces all references to the destination with a nuclear@6: reference to source. Any existing uses of the destination cursor nuclear@6: object will now show the source cursor image. nuclear@6: nuclear@6: ChangeCursorByName nuclear@6: nuclear@6: src: CURSOR nuclear@6: name: LISTofCARD8 nuclear@6: nuclear@6: This request replaces the contents of all cursors with the specified nuclear@6: name with the src cursor. nuclear@6: nuclear@6: ************* XFIXES VERSION 3 OR BETTER *********** nuclear@6: nuclear@6: 10. Region Expansion nuclear@6: nuclear@6: This update provides another operation on the region objects defined in nuclear@6: Section 8 of this document. nuclear@6: nuclear@6: 10.1 Requests nuclear@6: nuclear@6: ExpandRegion nuclear@6: source: REGION nuclear@6: destination: REGION nuclear@6: left, right, top, bottom: CARD16 nuclear@6: nuclear@6: Creates destination region containing the area specified by nuclear@6: expanding each rectangle in the source region by the specified nuclear@6: number of pixels to the left, right, top and bottom. nuclear@6: nuclear@6: ************* XFIXES VERSION 4 OR BETTER *********** nuclear@6: nuclear@6: 11. Cursor Visibility nuclear@6: nuclear@6: Composite managers may want to render the cursor themselves instead of nuclear@6: relying on the X server sprite drawing, this provides a way for them to nuclear@6: do so without getting a double cursor image. nuclear@6: nuclear@6: 11.1 Requests nuclear@6: nuclear@6: HideCursor nuclear@6: nuclear@6: window: WINDOW nuclear@6: nuclear@6: A client sends this request to indicate that it wants the nuclear@6: cursor image to be hidden (i.e. to not be displayed) when nuclear@6: the sprite is inside the specified window, or one of its nuclear@6: subwindows. If the sprite is inside a window for which one nuclear@6: or more active clients have requested cursor hiding then the nuclear@6: cursor image will not be displayed. nuclear@6: nuclear@6: Note that even though cursor hiding causes the cursor image nuclear@6: to be invisible, CursorNotify events will still be sent nuclear@6: normally, as if the cursor image were visible. nuclear@6: nuclear@6: If, during a grab, one or more active clients have requested nuclear@6: cursor hiding for grab window, or one of its ancestors, the nuclear@6: cursor image of the grab cursor will not be displayed during nuclear@6: the lifetime of that grab. nuclear@6: nuclear@6: When a client with outstanding cursor hiding requests nuclear@6: terminates its connection these requests will be deleted. nuclear@6: nuclear@6: Servers supporting the X Input Extension Version 2.0 or higher hide nuclear@6: all visible cursors in response to a HideCursor request. If a master nuclear@6: pointer is created while the cursors are hidden, this master pointer's nuclear@6: cursor will be hidden as well. nuclear@6: nuclear@6: ShowCursor nuclear@6: nuclear@6: window: WINDOW nuclear@6: nuclear@6: A client sends this request to indicate that it wants the nuclear@6: cursor image to be displayed when the sprite is inside the nuclear@6: specified window, or one of its subwindows. If the sprite nuclear@6: is inside a window for which no active clients have requested nuclear@6: cursor hiding then the cursor image for that window will be nuclear@6: displayed. In other words, if a client calls HideCursor for nuclear@6: a specified window, or window subtree, this request reverses nuclear@6: the effects of the HideCursor request. nuclear@6: nuclear@6: If the client has made no outstanding HideCursor requests nuclear@6: a BadMatch error is generated. nuclear@6: nuclear@6: Servers supporting the X Input Extension Version 2.0 or higher show nuclear@6: all visible cursors in response to a ShowCursor request. nuclear@6: nuclear@6: 99. Future compatibility nuclear@6: nuclear@6: This extension is not expected to remain fixed. Future changes will nuclear@6: strive to remain compatible if at all possible. The X server will always nuclear@6: support version 1 of the extension protocol if requested by a client. nuclear@6: nuclear@6: Additions to the protocol will always by marked by minor version number nuclear@6: changes so that applications will be able to detect what requests are nuclear@6: supported.