The X Resize, Rotate and Reflect Extension Version 1.0 2002-10-4 Jim Gettys Jim.Gettys@hp.com Keith Packard keithp@xfree86.org Cambridge Research Laboratory HP Labs Hewlett Packard Company 1. Introduction The X Resize, Rotate and Reflect Extension, called RandR for short, brings the ability to resize, rotate and reflect the root window of a screen. It is based on the X Resize and Rotate Extension as specified in the Proceedings of the 2001 Usenix Technical Conference [RANDR]. RandR as implemented and integrated into the XFree86 server differs in one substantial fashion from the design discussed in that paper: that is, RandR 1.0 does not implement the depth switching described in that document, and the support described for that in the protocol in that document and in the XFree86 implementationhas been removed from the protocol described here, as it has been overtaken by events. These events include: o Modern toolkits (in this case, GTK+ 2.x) have progressed to the point of implementing migration between screens of arbitrary depths o The continued advance of Moore's law has made limited amounts of VRAM less of an issue, reducing the pressure to implement depth switching on laptops or desktop systems o The continued decline of legacy toolkits whose design would have required depth switching to support migration o The lack of depth switchin implementation experience in the intervening time, due to events beyond our control Additionally, the requirement to support depth switching might complicate other re-engineering of the device independent part of the X server that is currently being contemplated. Rather than further delaying RandR's widespread deployment for a feature long wanted by the community (resizing of screens, particularly on laptops), or the deployment of a protocol design that might be flawed due to lack of implementation experience, we decided to remove depth switching from the protocol. It may be implementated at a later time if resources and interests permit as a revision to the protocol described here, which will remain a stable base for applications. The protocol described here has been implemented in the main XFree86 server, and more fully in the TinyX implementation in the XFree86 distribution, which fully implements resizing, rotation and reflection. 2. Acknowlegements Our thanks to the contributors to the design found on the xpert mailing list. 2. Screen change model Screens may change dynamically, either under control of this extension, or due to external events. Examples include: monitors being swapped, you pressing a button to switch from internal display to an external monitor on a laptop, or, eventually, the hotplug of a display card entirely on busses such as Cardbus which permit hot-swap (which will require other work in addition to this extension). Since the screen configuration is dynamic and asynchronous to the client and may change at any time RandR provides mechanisms to ensure that your clients view is up to date with the configuration possibilities of the moment and enforces applications that wish to control the configuration to prove that their information is up to date before honoring requests to change the screen configuration (by requiring a timestamp on the request). Interested applications are notified whenever the screen configuration changes, providing the current size of the screen and subpixel order (see the Render extension [RENDER]), to enabel proper rendering of subpixel decimated client text to continue, along with a time stamp of the configuration change. A client must refresh its knowledge of the screen configuration before attempting to change the configuration after a notification, or the request will fail. To avoid multiplicative explosion between orientation, reflection and sizes, the sizes are only those sizes in the normal (0) rotation. Rotation and reflection and how they interact can be confusing. In Randr, the coordinate system is rotated in a counter-clockwise direction relative to the normal orientation. Reflection is along the window system coordinate system, not the physical screen X and Y axis, so that rotation and reflection do not interact. The other way to consider reflection is to is specified in the "normal" orientation, before rotation, if you find the other way confusing. We expect that most clients and toolkits will be oblivious to changes to the screen stucture, as they generally use the values in the connections Display structure directly. By toolkits updating the values on the fly, we believe pop-up menus and other pop up windows will position themselves correctly in the face of screen configuration changes (the issue is ensuring that pop-ups are visible on the reconfigured screen). 3. Data Types The subpixel order is shared with the Render extension, and is documented there. The only datatype defined is the screen size, defined in the normal (0 degree) orientation. 4. Errors There are no new error types defined by this extension. 5. Protocol Types ROTATION { RR_rotate_0 RR_rotate_90 RR_rotate_180 RR_rotate_270 RR-Reflect_X RR_Reflect_Y } RRSELECTMASK { RRScreenChangeNotifyMask } SIZEID { CARD16 } SUBPIXELORDER { SubPixelUnknown The subpixel order uses the Render SubPixelHorizontalRGB extensions definitions; they are here SubPixelHorizontalBGR only for convenience. SubPixelVerticalRGB SubPixelVerticalBGR SubPixelNone } 6. Extension Initialization The name of this extension is "RANDR". RRQueryVersion client-major-version: CARD32 client-minor-version: CARD32 -> major-version: CARD32 minor-version: CARD32 The client sends the highest supported version to the server and the server sends the highest version it supports, but no higher than the requested version. Major versions changes can introduce incompatibilities in existing functionality, minor version changes introduce only backward compatible changes. It is the clients responsibility to ensure that the server supports a version which is compatible with its expectations. 7. Extension Requests RRSelectInput window: WINDOW enable: SETofRRSELECTMASK Errors: BadWindow, BadValue If enable is RRScreenChangeNotifyMask, RRScreenChangeNotify events will be sent anytime the screen configuration changes, either from this protocol extension, or due to detected external screen configuration changes. RRScreenChangeNotify may also be sent immediately if the screen configuration has changed since the client connected, to avoid race conditions. RRSetScreenConfig drawable: DRAWABLE timestamp: TIMESTAMP config-timestamp: TIMESTAMP sizeID: SIZEID rotation: ROTATION rate: CARD16 -> new-timestamp: TIMESTAMP config-timestamp: TIMESTAMP root: WINDOW subpixelOrder: SUBPIXELORDER Errors: BadValue, BadMatch If the timestamp in this request is less than the time when the configuration was last successfully set, the request is ignored and False returned in success. If the config-timestamp in this request is not equal to when the server's screen configurations last changed, the request is ignored and False returned in success. This could occur if the screen changed since you last made a RRGetScreenInfo request, perhaps by a different piece of display hardware being installed. Rather than allowing an incorrect call to be executed based on stale data, the server will ignore the request. If rate is zero, the server selects an appropriate rate. If the request succeeds, this request sets the screen to the specified size, rate, rotation and reflection. If the requests succeeds, the new-time-stamp is returned containing the time when the screen configuration was changed and config-timestamp is returned to indicate when the possible screen configurations were last changed, and success is set to True. The root window for the screen indicated by the drawable argument is also returned, along with the subpixel order, to allow correct subpixel rendering. BadValue errors are generated if the rotation is not an allowed rotation. BadValue errors are generated, if, when the timestamps would allow the operation to succeed, or size-index are not possible (out of range). RRGetScreenInfo window: WINDOW -> rotations: SETofROTATION root: WINDOW timestamp: TIMESTAMP config-timestamp: TIMESTAMP nSizes: CARD16 sizeID: SIZEID rotation: ROTATION rate: CARD16 sizes: LISTofSCREENSIZE refresh: LISTofREFRESH where: SCREENSIZE { widthInPixels, heightInPixels: CARD16 widthInMillimeters, heightInMillimeters: CARD16 } REFRESH { rates: LISTofCARD16 } Errors: BadWindow This event is delivered to clients selecting for notification with RRSelectInput requests using a RRScreenChangeNotifyMask. Size-index indicates which size is active. The returned window is the window requsting notification. This call returns the root window of the screen which has changed. Rotations contains the set of rotations and reflections supported by the screen of the window requested. The root window of that screen is reported. The number of current sizes supported is returned, along with which size rotation and reflection the screen is currently set to. The config-timestamp indicates when the screen configuration information last changed: requests to set the screen will fail unless the timestamp indicates that the information the client is using is up to date, to ensure clients can be well behaved in the face of race conditions. Similarly, timestamp indicates when the configuration was last set, and must both must be up to date in a call to RRSetScreenConfig for it to succeed. Rate is the current refresh rate. This is zero when the refresh rate is unknown or on devices for which refresh is not relevant. Sizes is the list of possible frame buffer sizes (at the normal orientation, each provide both the linear physical size of the screen and the pixel size. Refresh is the list of refresh rates for each size, each element of sizes has a cooresponding element in refresh. An empty list indicates no known rates, or a device for which refresh is not relevant. The default size of the screen (the size that would become the current size when the server resets) is the first size in the list. The potential screen sizes themselves are also returned. Toolkits SHOULD use RRScreenChangeSelectInput to be notified via a RRScreenChangeNotify event, so that they can adapt to screen size changes. 8. Extension Events Clients MAY select for ConfigureNotify on the root window to be informed of screen changes. This may be advantageous if all your clients need to know is the size of the root window, as it avoids round trips to set up the extension. RRScreenChangeNotify is sent if RRSelectInput has requested it whenever properties of the screen change, which may be due to external factors, such as recabling a monitor, etc. RRScreenChangeNotify rotation: ROTATION; new rotation sequenceNumber: CARD16 low 16 bits of request's seq. number timestamp: TIMESTAMP time screen was changed configTimestamp: TIMESTAMP time config data was changed root: WINDOW root window of screen window: WINDOW window requesting notification sizeID: SIZEID new ID of size subpixelOrder: SUBPIXELORDER order of subpixels widthInPixels: INT16 heightInPixels: INT16 widthInMillimeters: INT16 heightInMillimeters: INT16 This event is generated whenever the screen configuration is changed and sent to requesting clients. The timestamp included indicates when the screen configuration was changed, and configTimestamp says when the last time the configuration was changed. The root is the root of the screen the change occurred on, and the event window is also returned. SizeID contains an index indicating which size is current. This event is sent whenever the screen's configuration changes or if a new screen configuration becomes available that was not available in the past. In this case (config-timestamp in the event not being equal to the config-timestamp returned in the last call to RRGetScreenInfo), the client MUST call RRGetScreenInfo to update its view of possible screen configurations to have a correct view of possible screen organizations. Timestamp is set to when the active screen configuration was changed. Clients which select screen change notification events may be sent an event immediately if the screen configuration was changed between when they connected to the X server and selected for notification. This is to prevent a common race that might occur on log-in, where many applications start up just at the time when a display manager or log in script might be changing the screen size or configuration. 9. Extension Versioning The RandR extension was developed in parallel with the implementation to ensure the feasibility of various portions of the design. As portions of the extension are implemented, the version number of the extension has changed to reflect the portions of the standard provied. This document describes the version 1.0 of the specification, the partial implementations have version numbers less than that. Here's a list of what each version before 1.0 implemented: 0.0: This prototype implemented resize and rotation in the TinyX server Used approximately the protocol described in the Usenix paper. Appeared in the TinyX server in XFree86 4.2, but not in the XFree86 main server. 0.1: Added subpixel order, added an event for subpixel order. This version was never checked in to XFree86 CVS. 1.0: Implements resize, rotation, and reflection. Implemented both in the XFree86 main server (size change only at this date), and fully (size change, rotation, and reflection) in XFree86's TinyX server. 1.1: Added refresh rates Compatibility between 0.0 and 1.0 was *NOT* preserved, and 0.0 clients will fail against 1.0 servers. The wire encoding op-codes were changed for GetScreenInfo to ensure this failure in a relatively graceful way. Version 1.1 servers and clients are cross compatible with 1.0. Version 1.1 is considered to be stable and we intend upward compatibility from this point. Appendix A. Protocol Encoding Syntactic Conventions This document uses the same syntactic conventions as the core X protocol encoding document. A.1 Common Types SETofROTATION 0x0001 RR_Rotate_0 0x0002 RR_Rotate_90 0x0004 RR_Rotate_180 0x0008 RR_Rotate_270 0x0010 RR_Reflect_X 0x0020 RR_Reflect_Y SETofRRSELECTMASK 0x0001 RRScreenChangeNotifyMask A.2 Protocol Requests Opcodes 0x1 and 0x3 were used in the 0.0 protocols, and will return errors if used in version 1.0. RRQueryVersion 1 CARD8 major opcode 1 0x01 RandR opcode 2 3 length 4 CARD32 major version 4 CARD32 minor version -> 1 1 Reply 1 unused 2 CARD16 sequence number 4 0 reply length 1 CARD32 major version 1 CARD32 minor version RRSetScreenConfig 1 CARD8 major opcode 1 0x02 RandR opcode 2 5 length 4 DRAWABLE drawable on screen to be configured 4 TIMESTAMP timestamp 2 SIZEID size id 2 ROTATION rotation/reflection 2 CARD16 refresh rate (1.1 only) 2 CARD16 pad -> 1 1 Reply 1 CARD8 status 0x0 RRSetConfigSuccess 0x1 RRSetConfigInvalidConfigTime 0x2 RRSetConfigInvalidTime 0x3 RRSetConfigFailed 2 CARD16 sequence number 4 0 reply length 4 TIMESTAMP new timestamp 4 TIMESTAMP new configuration timestamp 4 WINDOW root 2 SUBPIXELORDER subpixel order defined in Render 2 CARD16 pad4 4 CARD32 pad5 4 CARD32 pad6 RRSelectInput 1 CARD8 major opcode 1 0x04 RandR opcode 2 3 length 4 WINDOW window 2 SETofRRSELECTMASK enable 2 CARD16 pad RRGetScreenInfo 1 CARD8 major opcode 1 0x05 RandR opcode 2 2 length 4 WINDOW window -> 1 1 Reply 1 CARD8 set of Rotations 2 CARD16 sequence number 4 0 reply length 4 WINDOW root window 4 TIMESTAMP timestamp 4 TIMESTAMP config timestamp 2 CARD16 number of SIZE following 2 SIZEID sizeID 2 ROTATION current rotation and reflection 2 CARD16 rate (1.1) 2 CARD16 length of rate info (number of CARD16s) 2 CARD16 pad SIZE 2 CARD16 width in pixels 2 CARD16 height in pixels 2 CARD16 width in millimeters 2 CARD16 height in millimeters REFRESH 2 CARD16 number of rates (n) 2n CARD16 rates A.2 Protocol Event RRScreenChangeNotify 1 Base + 0 code 1 ROTATION new rotation and reflection 2 CARD16 sequence number 4 TIMESTAMP timestamp 4 TIMESTAMP configuration timestamp 4 WINDOW root window 4 WINDOW request window 2 SIZEID size ID 2 SUBPIXELORDER subpixel order defined in Render 2 CARD16 width in pixels 2 CARD16 height in pixels 2 CARD16 width in millimeters 2 CARD16 height in millimeters Bibliography [RANDR] Gettys, Jim and Keith Packard, "The X Resize and Rotate Extension - RandR", Proceedings of the 2001 USENIX Annual Technical Conference, Boston, MA [RENDER] Packard, Keith, "The X Rendering Extension", work in progress, documents found in xc/specs/Render.