From 9b009a8bdb31d08e3d07f68416373b9aa6f85724 Mon Sep 17 00:00:00 2001 From: marha Date: Thu, 4 Aug 2011 16:44:35 +0200 Subject: randrproto mesa xserver git update 4 aug 2011 --- X11/extensions/randrproto.txt | 5252 +++++++++++---------- mesalib/src/gallium/auxiliary/util/u_format.c | 834 ++-- mesalib/src/gallium/auxiliary/util/u_format.h | 1663 +++---- mesalib/src/glsl/ir_function.cpp | 8 - mesalib/src/glsl/ir_function_detect_recursion.cpp | 5 +- mesalib/src/glsl/link_functions.cpp | 4 +- mesalib/src/glsl/linker.cpp | 193 +- mesalib/src/glsl/linker.h | 3 - mesalib/src/glsl/main.cpp | 1 + mesalib/src/glsl/program.h | 62 +- mesalib/src/mesa/main/shaderobj.c | 829 ++-- mesalib/src/mesa/program/ir_to_mesa.cpp | 79 +- xorg-server/composite/compalloc.c | 12 +- xorg-server/configure.ac | 4 +- xorg-server/hw/xquartz/X11Application.m | 2 +- xorg-server/hw/xquartz/bundle/Makefile.am | 9 + xorg-server/hw/xquartz/xpr/xprFrame.c | 9 +- xorg-server/include/windowstr.h | 443 +- xorg-server/mi/miexpose.c | 1398 +++--- 19 files changed, 5462 insertions(+), 5348 deletions(-) diff --git a/X11/extensions/randrproto.txt b/X11/extensions/randrproto.txt index 746342046..f0181416d 100644 --- a/X11/extensions/randrproto.txt +++ b/X11/extensions/randrproto.txt @@ -1,2618 +1,2634 @@ - The X Resize, Rotate and Reflect Extension - Version 1.4.0 - 2009-10-5 - - Jim Gettys - Jim.Gettys@hp.com - Cambridge Research Laboratory - HP Labs - Hewlett Packard Company - - Keith Packard - keith.packard@intel.com - Open Source Technology Center - Intel Corporation - -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 X 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 implementation has been removed from the -protocol described here, as it has been overtaken by events. - -These events include: - ► Modern toolkits (in this case, GTK+ 2.x) have progressed to the point - of implementing migration between screens of arbitrary depths - ► 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 - ► The continued decline of legacy toolkits whose design would have - required depth switching to support migration - ► The lack of depth switching 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 implemented 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 X.org server, and more fully in the hw/kdrive -implementation in the distribution, which fully implements resizing, -rotation and reflection. - -1.2 Introduction to version 1.2 of the extension - -One of the significant limitations found in version 1.1 of the RandR -protocol was the inability to deal with the Xinerama model where multiple -monitors display portions of a common underlying screen. In this environment, -zero or more video outputs are associated with each CRT controller which -defines both a set of video timings and a 'viewport' within the larger -screen. This viewport is independent of the overall size of the screen, and -may be located anywhere within the screen. - -The effect is to decouple the reported size of the screen from the size -presented by each video output, and to permit multiple outputs to present -information for a single screen. - -To extend RandR for this model, we separate out the output, CRTC and screen -configuration information and permit them to be configured separately. For -compatibility with the 1.1 version of the protocol, we make the 1.1 requests -simultaneously affect both the screen and the (presumably sole) CRTC and -output. The set of available outputs are presented with UTF-8 encoded names -and may be connected to CRTCs as permitted by the underlying hardware. CRTC -configuration is now done with full mode information instead of just size -and refresh rate, and these modes have names. These names also use UTF-8 -encoding. New modes may also be added by the user. - -Additional requests and events are provided for this new functionality. - - ┌────────────────────────────────┬──────────┐ - ┏━━━━━━━┳───────────────┐ ╔════════╗ ╔════════╗ - ┃ 1 ┃ │ ║ A ║ ║ B ║ - ┃ ┏━━━╋━━━━━━━━━━━━━━━┫ ║ ║ ║ ║ - ┣━━━╋━━━┛ ┃ ╚════════╝ ╚════════╝ - │ ┃ 2 ┃─────────────────┐ - │ ┃ ┃ ╔═══════════════════╗ - │ ┃ ┃ ║ ║ - │ ┗━━━━━━━━━━━━━━━━━━━┫ ║ C ║ - └───────────────────────┘ ║ ║ - ┌──────┐ ┏━━━━┓ ╔══════╗ ║ ║ - │screen│ ┃CRTC┃ ║output║ ╚═══════════════════╝ - └──────┘ ┗━━━━┛ ╚══════╝ - -In this picture, the screen is covered (incompletely) by two CRTCs. CRTC1 -is connected to two outputs, A and B. CRTC2 is connected to output C. -Outputs A and B will present exactly the same region of the screen using -the same mode line. Output C will present a different (larger) region of -the screen using a different mode line. - -RandR provides information about each available CRTC and output; the -connection between CRTC and output is under application control, although -the hardware will probably impose restrictions on the possible -configurations. The protocol doesn't try to describe these restrictions, -instead it provides a mechanism to find out what combinations are supported. - -1.3 Introduction to version 1.3 of the extension - -Version 1.3 builds on the changes made with version 1.2 and adds some new -capabilities without fundmentally changing the extension again. The -following features are added in this version: - - • Projective Transforms. The implementation work for general rotation - support made it trivial to add full projective transformations. These - can be used to scale the screen up/down as well as perform projector - keystone correct or other effects. - - • Panning. It was removed with RandR 1.2 because the old semantics didn't - fit any longer. With RandR 1.3 panning can be specified per crtc. - -1.4 Introduction to version 1.4 of the extension - -Version 1.4 adds a couple more capabilities to further expose the -underlying hardware to clients - - • Per-crtc pixmaps. This provides for multiple scan-out buffers - which applications can create and assign to arbitrary collections - of crtcs. - - • Sprite position and image transforms. These provide a projective - transform for both the hot spot location and the sprite image - itself for each CRTC. - - • RRSetCrtcConfigs request. This supplies a set of - crtc configurations to the server that must be applied together - or not at all. This can reduce screen flicker while also - providing the server a complete configuration for appropriate - resource management. - -The first two additions, per-crtc pixmaps and sprite transforms are -designed to solve two problems: - - 1) Screen transforms. The software transform code in the X server - uses a shadow frame buffer, adding another copy to every graphics - operation. Worse, the server has no idea about when clients are - done drawing a frame, so the user gets additional latency and - judder. - - The goal is to move this operation out to the compositing manager - which already deals with an extra copy of the frame buffer for - many operations. Have the compositing manager create and draw to a - separate pixmap for scanout. It can perform whatever transforms - are required to get the image in the right orientation for the - user. - - 2) Hardware scanout engine size limits. With a single scanout buffer - for the entire screen, it's possible for the user to ask for a - configuration which requires that scanout buffer to be larger than - the hardware is capable of scanning out from. Again, having the - compositing manager create a pixmap for each CRTC will allow for - any configuration where monitor position within the virtual space - isn't limited by the scanout limits. - -In both of these cases, the Sprite transforms are necessary to ensure -that the sprite appears at the desired spot on each CRTC and with the -right shape. - -1.99 Acknowledgements - -Our thanks to the contributors to the design found on the xpert mailing -list, in particular: - -Alan Hourihane for work on the early implementation -Andrew C. Aitchison for help with the XFree86 DDX implementation -Andy Ritger for early questions about how mergefb/Xinerama work with RandR -Carl Worth for editing the specification and Usenix paper -David Dawes for XFree86 DDX integration work -Thomas Winischhofer for the hardware-accelerated SiS rotation implementation -Matthew Tippett and Kevin Martin for splitting outputs and CRTCs to more -fully expose what video hardware can do - - ❧❧❧❧❧❧❧❧❧❧❧ - -2. Screen change model - -Screens may change dynamically, either under control of this extension, or -due to external events. Examples include: monitors being swapped, 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 or Express Card 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 enable 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 structure, 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 - -Errors are sent using core X error reports. - -Output - A value for an OUTPUT argument does not name a defined OUTPUT. -CRTC - A value for a CRTC argument does not name a defined CRTC. -Mode - A value for a MODE argument does not name a defined MODE. - - ❧❧❧❧❧❧❧❧❧❧❧ - -5. Protocol Types - -RRCONFIGSTATUS { Success - InvalidConfigTime - InvalidTime - Failed } - - A value of type RRCONFIGSTATUS returned when manipulating the output - configuration or querying information from the server that has some - time-dependency. - - InvalidConfigTime indicates that the supplied configuration - timestamp does not match the current X server configuration - timestamp. Usually this means that the output configuration has - changed since the timestamp was received by the application. - - InvalidTime indicates that the supplied output reconfiguration time - is earlier than the most recent output reconfiguration request. - Generally this indicates that another application has reconfigured - the output using a later timestamp. - - Failed is returned whenever the operation is unsuccessful for some - other reason. This generally indicates that the requested output - configuration is unsupported by the hardware. The goal is to make - these limitations expressed by the protocol, but when that isn't - possible it is correct to return this error value. If, as a - implentor, you find this error code required, please submit the - hardware constraints that exist so that a future version of the - extension can correctly capture the configuration constraints in - your system. - -ROTATION { Rotate_0 - Rotate_90 - Rotate_180 - Rotate_270 - Reflect_X - Reflect_Y } - - These values are used both to indicate a set of allowed rotations - and reflections as well as to indicate a specific rotation and - reflection combination. - -RRSELECTMASK { RRScreenChangeNotifyMask - RRCrtcChangeNotifyMask (New in version 1.2) - RROutputChangeNotifyMask (New in version 1.2) - RROutputPropertyNotifyMask (New in version 1.2) } - -SIZEID { CARD16 } - -MODE { XID or None } - -CRTC { XID } - -OUTPUT { XID } - -CONNECTION { Connected, Disconnected, UnknownConnection } - - This value provides an indication of whether an output is actually - connected to a monitor or other presentation device. - -SUBPIXELORDER { SubPixelUnknown The subpixel order uses the Render - SubPixelHorizontalRGB extensions definitions; they are here - SubPixelHorizontalBGR only for convenience. - SubPixelVerticalRGB - SubPixelVerticalBGR - SubPixelNone } - -SCREENSIZE { widthInPixels, heightInPixels: CARD16 - widthInMillimeters, heightInMillimeters: CARD16 } - -MODEFLAG { HSyncPositive - HSyncNegative - VSyncPositive - VSyncNegative - Interlace - DoubleScan - CSync - CSyncPositive - CSyncNegative - HSkewPresent - BCast - PixelMultiplex - DoubleClock - ClockDivideBy2 } - -MODEINFO { id: MODE - name: STRING - width, height: CARD16 - dotClock: CARD32 - hSyncStart, hSyncEnd, hTotal, hSkew: CARD16 - vSyncStart, vSyncEnd, vTotal: CARD16 - modeFlags: SETofMODEFLAG } - -REFRESH { rates: LISTofCARD16 } - - ❧❧❧❧❧❧❧❧❧❧❧ - -5.4. Protocol Types added in version 1.4 of the extension - -SCANOUTPIXMAPINFO { format: PICTFORMAT - maxWidth, maxHeight: CARD16 - rotations: SETofROTATION } - - 'format' is the format of the pixels within the scanout - pixmap. Only 'Direct' formats are supported, this will never - be an 'Indexed' format. - - 'maxWidth' and 'maxHeight' define the largest supported - scanout pixmap. There is no minimum size; scanout pixmaps down - to 1x1 may be created. - - 'rotations' lists the set of rotations which can be provided - without additional latency or memory usage within the - environment. This typically means that they are supported - directly by the hardware. It is expected that a compositing - manager will perform other transforms as a part of the - compositing process in conjunction with the sprite transforms - described in this extension. - -SCREENFLAG { SetScreenPixmapSize - SetScreenSize - SetScreenSizeInMillimeters - SetScreenCrtcs } - -CRTCFLAG { SetCrtcPosition - SetCrtcMode - SetCrtcRotation - SetCrtcOutputs - SetCrtcSpritePositionTransform - SetCrtcSpriteImageTransform - SetCrtcPixmap - SetCrtcPixmapPosition } - -CRTCCONFIG { crtc: CRTC - set: SETofCRTCFLAG - x, y: INT16 - mode: MODE - rotation: ROTATION - sprite-position-transform: TRANSFORM - sprite-image-transform: TRANSFORM - outputs: LISTofOUTPUT - pixmap: PIXMAP or None - pixmap-x, pixmap-y: INT16 } - - If 'set' includes SetCrtcSpritePositionTransform, then - sprite-position-transform is used as in the - RRSetCrtcSpriteTransform request position-transform parameter. - - If 'set' includes SetCrtcSpriteImageTransform, then - sprite-image-transform is used as in the - RRSetCrtcSpriteTransform request image-transform parameter. - - If 'set' includes SetCrtcPixmap, then 'pixmap' specifies the - origin of the pixel data to be presented on 'crtc'. If - 'pixmap' is None, then data will be presented from the screen - pixmap. - - If 'set' includes SetCrtcPixmapPosition, then 'pixmap-x' and - 'pixmap-y' specify the origin of the scanout data within the - pixmap, the area from that location to pixmap-x + - width-of(mode), pixmap-y + height-of(mode) is what will be - seen on the connected outputs. - - If 'set' includes SetCrtcPixmap, then 'pixmap' must specify a - scanout pixmap as created by RRCreateScanoutPixmap or - None. Otherwise a Match error results. Furthermore: - - * 'pixmap' must be at least as large as the area to be - scanned out, or a Match error results. - - * If 'pixmap' is destroyed while still being used as a - scanout pixmap, then the associated CRTC will have its - scanout pixmap set back to None, the CRTC origin set back - to 0,0 (to make sure it fits) and the screen pixmap width - and height increased to be at least as big as the current - CRTC mode. - - * Future crtc changes that do not change the scanout pixmap - will cause an existing scanout pixmap to be resized to be - large enough to hold the new mode at the then-current - pixmap-x/pixmap-y location. - - If 'set' includes SetCrtcRotation then: - - * Any new or existing scanout pixmap must have had the - specified 'rotation' included as a part of its creation - parameters, or a Match error results. - - * If no scanout pixmap is in use, then the crtc must support - 'rotation' else a Value error results. - - ❧❧❧❧❧❧❧❧❧❧❧ - -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: Window, Value - - If 'enable' is RRScreenChangeNotifyMask, RRScreenChangeNotify events - will be sent when the screen configuration changes, either from - this protocol extension, or due to detected external screen - configuration changes. RRScreenChangeNotify may also be sent when - this request executes if the screen configuration has changed since - the client connected, to avoid race conditions. - - New for version 1.2: - - If 'enable' contains RRCrtcChangeMask, RRCrtcChangeNotify events - will be sent when a the configuration for a CRTC associated with the - screen changes, either through this protocol extension or due to - detected external changes. RRCrtcChangeNotify may also be sent when - this request executes if the CRTC configuration has changed since - the client connected, to avoid race conditions. - - If 'enable' contains RROutputChangeMask, RROutputChangeNotify events - will be sent when a the configuration for an output associated with - the screen changes, either through this protocol extension or due to - detected external changes. RROutputChangeNotify may also be sent - when this request executes if the output configuration has changed - since the client connected, to avoid race conditions. - - If 'enable' contains RROutputPropertyNotifyMask, - RROutputPropertyNotify events will be sent when properties change on - this output. - -┌─── - RRSetScreenConfig - window: WINDOW - timestamp: TIMESTAMP - config-timestamp: TIMESTAMP - size-id: SIZEID - rotation: ROTATION - rate: CARD16 - ▶ - status: RRCONFIGSTATUS - new-timestamp: TIMESTAMP - config-timestamp: TIMESTAMP - root: WINDOW - subpixelOrder: SUBPIXELORDER -└─── - Errors: Value, Match - - If 'timestamp' is less than the time when the configuration was last - successfully set, the request is ignored and InvalidTime returned in - status. - - If 'config-timestamp' is not equal to when the server's screen - configurations last changed, the request is ignored and - InvalidConfigTime returned in status. 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. - - 'rate' contains the desired refresh rate. If it is zero, the server - selects an appropriate rate. - - This request may fail for other indeterminate reasons, in which case - 'status' will be set to Failed and no configuration change will be - made. - - This request sets the screen to the specified size, rate, rotation - and reflection. - - When this request succeeds, 'status' contains Success and the - requested changes to configuration will have been made. - - 'new-time-stamp' contains the time at which this request was - executed. - - 'config-timestamp' contains the time when the possible screen - configurations were last changed. - - 'root' contains the root window for the screen indicated by the - window. - - 'subpixelOrder' contains the resulting subpixel order of the screen - to allow correct subpixel rendering. - - Value errors are generated when 'rotation', 'rate' or 'size-id' - are invalid. - -┌─── - RRGetScreenInfo - window: WINDOW - ▶ - rotations: SETofROTATION - root: WINDOW - timestamp: TIMESTAMP - config-timestamp: TIMESTAMP - size-id: SIZEID - rotation: ROTATION - rate: CARD16 - sizes: LISTofSCREENSIZE - refresh: LISTofREFRESH -└─── - - Errors: Window - - RRGetScreenInfo returns information about the current and available - configurations for the screen associated with 'window'. - - 'rotations' contains the set of rotations and reflections supported - by the screen. - - 'root' is the root window of the screen. - - '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. - - 'timestamp' indicates when the configuration was last set. - - 'size-id' indicates which size is active. - - '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 size indicates 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 corresponding 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. - -7.1. Extension Requests added in version 1.2 of the extension - -As introduced above, version 1.2 of the extension splits the screen size -from the crtc and output configuration, permitting the subset of the screen -presented by multiple outputs to be configured. As a separate notion, the -size of the screen itself may be arbitrarily configured within a defined -range. As crtcs and outputs are added and removed from the system, the set -returned by the extension will change so that applications can detect -dynamic changes in the display environment. - -┌─── - RRGetScreenSizeRange - window: WINDOW - ▶ - CARD16 minWidth, minHeight - CARD16 maxWidth, maxHeight -└─── - Errors: Window - - Returns the range of possible screen sizes. The screen may be set to - any size within this range. - -┌─── - RRSetScreenSize - window: WINDOW - width: CARD16 - height: CARD16 - width-in-millimeters: CARD32 - height-in-millimeters: CARD32 -└─── - Errors: Window, Match, Value - - Sets the screen to the specified size. 'width' and 'height' must be - within the range allowed by GetScreenSizeRanges, otherwise a Value - error results. All active monitors must be configured to display a - subset of the specified size, else a Match error results. - - 'width-in-millimeters' and 'height-in-millimeters' can be set to - reflect the physical size of the screen reported both through this - extension and the core protocol. They must be non-zero, or Value - error results. - - If panning is enabled, the width and height of the panning and the - tracking areas are adapted to the new size and clamped afterwards. - Disabled panning axes remain disabled. - Panning borders are disabled if their requirements are no longer met - (see RRSetPanning). - -┌─── - RRGetScreenResources - window: WINDOW - ▶ - timestamp: TIMESTAMP - config-timestamp: TIMESTAMP - crtcs: LISTofCRTC - outputs: LISTofOUTPUT - modes: LISTofMODEINFO -└─── - Errors: Window - - RRGetScreenResources returns the list of outputs and crtcs connected - to the screen associated with 'window'. - - 'timestamp' indicates when the configuration was last set. - - 'config-timestamp' indicates when the configuration information last - changed. Requests to configure the output 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. - - 'crtcs' contains the list of CRTCs associated with the screen. - - 'outputs' contains the list of outputs associated with the screen. - - 'modes' contains the list of modes associated with the screen - - This request explicitly asks the server to ensure that the - configuration data is up-to-date wrt the hardware. If that requires - polling, this is when such polling would take place. If the - current configuration is all that's required, use - RRGetScreenResourcesCurrent instead. - -┌─── - RRGetOutputInfo - output: OUTPUT - config-timestamp: TIMESTAMP - ▶ - status: RRCONFIGSTATUS - timestamp: TIMESTAMP - crtc: CRTC - - name: STRING - connection: CONNECTION - subpixel-order: SUBPIXELORDER - widthInMillimeters, heightInMillimeters: CARD32 - crtcs: LISTofCRTC - clones: LISTofOUTPUT - modes: LISTofMODE - num-preferred: CARD16 -└─── - Errors: Output - - RRGetOutputInfo returns information about the current and available - configurations 'output'. - - If 'config-timestamp' does not match the current configuration - timestamp (as returned by RRGetScreenResources), 'status' is set to - InvalidConfigTime and the remaining reply data is empty. Otherwise, - 'status' is set to Success. - - 'timestamp' indicates when the configuration was last set. - - 'crtc' is the current source CRTC for video data, or Disabled if the - output is not connected to any CRTC. - - 'name' is a UTF-8 encoded string designed to be presented to the - user to indicate which output this is. E.g. "S-Video" or "DVI". - - 'connection' indicates whether the hardware was able to detect a - device connected to this output. If the hardware cannot determine - whether something is connected, it will set this to - UnknownConnection. - - 'subpixel-order' contains the resulting subpixel order of the - connected device to allow correct subpixel rendering. - - 'widthInMillimeters' and 'heightInMillimeters' report the physical - size of the displayed area. If unknown, or not really fixed (e.g., - for a projector), these values are both zero. - - 'crtcs' is the list of CRTCs that this output may be connected to. - Attempting to connect this output to a different CRTC results in a - Match error. - - 'clones' is the list of outputs which may be simultaneously - connected to the same CRTC along with this output. Attempting to - connect this output with an output not in the 'clones' list - results in a Match error. - - 'modes' is the list of modes supported by this output. Attempting to - connect this output to a CRTC not using one of these modes results - in a Match error. - - The first 'num-preferred' modes in 'modes' are preferred by the - monitor in some way; for fixed-pixel devices, this would generally - indicate which modes match the resolution of the output device. - -┌─── - RRListOutputProperties - output:OUTPUT - ▶ - atoms: LISTof ATOM -└─── - Errors: Output - - This request returns the atoms of properties currently defined on - the output. - -┌─── - RRQueryOutputProperty - output: OUTPUT - property: ATOM - ▶ - pending: BOOL - range: BOOL - immutable: BOOL - valid-values: LISTofINT32 -└─── - Errors: Name, Atom, Output - - If the specified property does not exist for the specified output, - then a Name error is returned. - - If 'pending' is TRUE, changes made to property values with - RRChangeOutputProperty will be saved in the pending property value - and be automatically copied to the current value on the next - RRSetCrtcConfig request involving the named output. If 'pending' is - FALSE, changes are copied immediately. - - If 'range' is TRUE, then the valid-values list will contain - precisely two values indicating the minimum and maximum allowed - values. If 'range' is FALSE, then the valid-values list will contain - the list of possible values; attempts to set other values will - result in a Value error. - - If 'immutable' is TRUE, then the property configuration cannot be - changed by clients. Immutable properties are interpreted by the X - server. - -┌─── - RRConfigureOutputProperty - output: OUTPUT - property: ATOM - pending: BOOL - range: BOOL - valid-values: LISTofINT32 -└─── - Errors: Access, Name, Atom, Output - - If the specified property is 'immutable', an Access error is - returned. - - Otherwise, the configuration of the specified property is changed to - the values provided in this request. - - If the specified property does not exist for the specified output, - it is created with an empty value and None type. - -┌─── - RRChangeOutputProperty - output: OUTPUT - property, type: ATOM - format: {8, 16, 32} - mode: { Replace, Prepend, Append } - data: LISTofINT8 or LISTofINT16 or LISTofINT32 -└─── - Errors: Alloc, Atom, Match, Value, Output - - This request alters the value of the property for the specified - output. If the property is marked as a 'pending' property, only the - pending value of the property is changed. Otherwise, changes are - reflected in both the pending and current values of the property. - The type is uninterpreted by the server. The format specifies - whether the data should be viewed as a list of 8-bit, 16-bit, or - 32-bit quantities so that the server can correctly byte-swap as - necessary. - - If the mode is Replace, the previous property value is discarded. - If the mode is Prepend or Append, then the type and format must - match the existing property value (or a Match error results). If - the property is undefined, it is treated as defined with the correct - type and format with zero-length data. - - For Prepend, the data is tacked on to the beginning of the existing - data, and for Append, it is tacked on to the end of the existing data. - - This request generates a OutputPropertyNotify - - The lifetime of a property is not tied to the storing client. - Properties remain until explicitly deleted, until the output is - destroyed, or until server reset (see section 10). - - The maximum size of a property is server-dependent and may vary - dynamically. - -┌─── - RRDeleteOutputProperty - output: OUTPUT - property: ATOM -└─── - Errors: Atom, Output - - This request deletes the property from the specified window if the - property exists and generates a OutputPropertyNotify event unless - the property does not exist. - -┌─── - RRGetOutputProperty - output: OUTPUT - property: ATOM - type: ATOM or AnyPropertyType - long-offset, long-length: CARD32 - delete: BOOL - pending: BOOL - ▶ - type: ATOM or None - format: {0, 8, 16, 32} - bytes-after: CARD32 - value: LISTofINT8 or LISTofINT16 or LISTofINT32 -└─── - Errors: Atom, Value, Output - - If the specified property does not exist for the specified output, - then the return type is None, the format and bytes-after are zero, - and the value is empty. The delete argument is ignored in this - case. - - If the specified property exists but its type does not match the - specified type, then the return type is the actual type of the - property, the format is the actual format of the property (never - zero), the bytes-after is the length of the property in bytes (even - if the format is 16 or 32), and the value is empty. The delete - argument is ignored in this case. - - If the specified property exists and either AnyPropertyType is - specified or the specified type matches the actual type of the - property, then the return type is the actual type of the property, - the format is the actual format of the property (never zero), and - the bytes-after and value are as follows, given: - - N = actual length of the stored property in bytes - (even if the format is 16 or 32) - I = 4 × offset - T = N - I - L = MINIMUM(T, 4 × long-length) - A = N - (I + L) - - If 'pending' is true, and if the property holds a pending value, - then the value returned will be the pending value of the property - rather than the current value. The returned value starts at byte - index I in the property (indexing from 0), and its length in bytes - is L. However, it is a Value error if long-offset is given such - that L is negative. The value of bytes-after is A, giving the - number of trailing unread bytes in the stored property. If delete - is True and the bytes-after is zero, the property is also deleted - from the output, and a RROutputPropertyNotify event is generated. - -┌─── - RRCreateMode - window: WINDOW - modeinfo: MODEINFO - ▶ - mode: MODE -└─── - Errors: Window, Name, Value - - 'modeinfo' provides a new mode for outputs on the screen - associated with 'window'. If the name of 'modeinfo' names an - existing mode, a Name error is returned. If some parameter of the - mode is not valid in some other way, a Value error is returned. - - The returned 'mode' provides the id for the mode. - -┌─── - RRDestroyMode - mode: MODE -└─── - Errors: Mode, Access - - The user-defined 'mode' is destroyed. 'mode' must name a mode - defined with RRCreateMode, else an Match error is returned. If - 'mode' is in use by some CRTC or Output, then an Access error is - returned. - -┌─── - RRAddOutputMode - output: OUTPUT - mode: MODE -└─── - Errors: Output, Mode, Match - - 'output' indicates which output is to be configured. - - 'mode' specifies which mode to add. If 'mode' is not valid for - 'output', then a Match error is generated. - - This request generates OutputChangeNotify events. - -┌─── - RRDeleteOutputMode - output: OUTPUT - mode: MODE -└─── - Errors: Output, Mode - - 'output' indicates which output is to be configured. - - 'mode' specifies which mode to delete. 'mode' must have been added - with RRAddOutputMode, else an Access error is returned. 'mode' must - not be active, else a Match error is returned. - - This request generates OutputChangeNotify events. - -┌─── - RRGetCrtcInfo - crtc: CRTC - config-timestamp: TIMESTAMP - ▶ - status: RRCONFIGSTATUS - timestamp: TIMESTAMP - x, y: INT16 - width, height: CARD16 - mode: MODE - rotation: ROTATION - outputs: LISTofOUTPUT - - rotations: SETofROTATION - possible-outputs: LISTofOUTPUT -└─── - - Errors: Window - - RRGetCrtcModes returns information about the current and available - configurations for the specified crtc connected to the screen - associated with 'window'. - - If 'config-timestamp' does not match the current configuration - timestamp (as returned by RRGetScreenResources), 'status' is set to - InvalidConfigTime and the remaining reply data is empty. Otherwise, - 'status' is set to Success. - - 'timestamp' indicates when the configuration was last set. - - 'x' and 'y' indicate the position of this CRTC within the screen - region. They will be set to 0 when the CRTC is disabled. - - 'width' and 'height' indicate the size of the area within the screen - presented by this CRTC. This may be different than the size of the - mode due to rotation. They will be set to 0 when the CRTC - is disabled. - - 'mode' indicates which mode is active, or None indicating that the - CRTC has been disabled and is not displaying the screen contents. - - 'rotation' indicates the active rotation. It is set to Rotate_0 - when the CRTC is disabled. - - 'outputs' is the list of outputs currently connected to this CRTC - and is empty when the CRTC is disabled. - - 'rotations' contains the set of rotations and reflections supported - by the CRTC. - - 'possible-outputs' lists all of the outputs which may be connected - to this CRTC. - -┌─── - RRSetCrtcConfig - crtc: CRTC - timestamp: TIMESTAMP - config-timestamp: TIMESTAMP - x, y: INT16 - mode: MODE - rotation: ROTATION - outputs: LISTofOUTPUT - ▶ - status: RRCONFIGSTATUS - new-timestamp: TIMESTAMP -└─── - Errors: Value, Match - - If 'timestamp' is less than the time when the configuration was last - successfully set, the request is ignored and InvalidTime returned in - status. - - If 'config-timestamp' is not equal to when the monitor's - configuration last changed, the request is ignored and - InvalidConfigTime returned in status. This could occur if the - monitor changed since you last made a RRGetScreenInfo request, - perhaps by a different monitor being connected to the machine. - Rather than allowing an incorrect call to be executed based on stale - data, the server will ignore the request. - - 'x' and 'y' contain the desired location within the screen for this - monitor's content. 'x' and 'y' must be within the screen size, else - a Value error results. - - 'mode' is either the desired mode or None indicating the CRTC should - be disabled. If 'mode' is not one of these values, a Value - error results. 'mode' must be valid for all of the configured outputs, - else a Match error. - - 'rotation' contains the desired rotation along with which - reflections should be enabled. The rotation and reflection values - must be among those allowed for this monitor, else a Value error - results. - - 'outputs' contains the set of outputs that this CRTC should be - connected to. The set must be among the list of acceptable output - sets for this CRTC or a Match error results. - - If 'mode' is None, then 'outputs' must be empty, else a Match error - results. Conversely, if 'mode' is not None, then 'outputs' must not be - empty, else a Match error results. - - This request may fail for other indeterminate reasons, in which case - 'status' will be set to Failed and no configuration change will be - made. - - This request sets the CRTC to the specified position, mode, rotation - and reflection. The entire area of the CRTC must fit within the - screen size, else a Match error results. As an example, rotating the - screen so that a single CRTC fills the entire screen before and - after may necessitate disabling the CRTC, resizing the screen, - then re-enabling the CRTC at the new configuration to avoid an - invalid intermediate configuration. - - If panning is enabled, the width and height of the panning and the - tracking areas are clamped to the new mode size. - Disabled panning axes remain disabled. - Panning borders are disabled if their requirements are no longer met - (see RRSetPanning). - - When this request succeeds, 'status' contains Success and the - requested changes to configuration will have been made. - - 'new-time-stamp' contains the time at which this request was - executed. - -┌─── - RRGetCrtcGammaSize - crtc: CRTC - ▶ - size: CARD16 -└─── - Errors: Crtc - - This request returns the size of the gamma ramps used by 'crtc'. - -┌─── - RRGetCrtcGamma - crtc: CRTC - ▶ - red: LISTofCARD16 - green: LISTofCARD16 - blue: LISTofCARD16 -└─── - Errors: Crtc - - This request returns the currently set gamma ramps for 'crtc'. All - three lists will be the size returned by the RRGetCrtcGammaSize - request. - -┌─── - RRSetCrtcGamma - crtc: CRTC - red: LISTofCARD16 - green: LISTofCARD16 - blue: LISTofCARD16 -└─── - Errors: Crtc, Match - - This request sets the gamma ramps for 'crtc'. All three lists - must be the size returned by RRGetCrtcGammaSize else a Value error - results. - -7.2. Extension Requests added in version 1.3 of the extension - -┌─── - RRGetScreenResourcesCurrent - window: WINDOW - ▶ - timestamp: TIMESTAMP - config-timestamp: TIMESTAMP - crtcs: LISTofCRTC - outputs: LISTofOUTPUT - modes: LISTofMODEINFO -└─── - Errors: Window - - RRGetScreenResourcesCurrent returns the list of outputs and crtcs - connected to the screen associated with 'window'. - - 'timestamp' indicates when the configuration was last set. - - 'config-timestamp' indicates when the configuration information last - changed. Requests to configure the output 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. - - 'crtcs' contains the list of CRTCs associated with the screen. - - 'outputs' contains the list of outputs associated with the screen. - - 'modes' contains the list of modes associated with the screen. - - Unlike RRGetScreenResources, this merely returns the current - configuration, and does not poll for hardware changes. - -┌─── - RRSetCrtcTransform - crtc: CRTC - transform: TRANSFORM - filter: STRING8 - values: LISTofFIXED -└─── - Errors: Crtc, Match - - This request provides a mechanism that is more general than the - existing rotation and reflection values for describing the - transformation from frame buffer image to crtc presentation. - 'transform' is a full 2D projective transformation from screen - coordinate space to crtc coordinate space. This transformation is - applied before the rotation and reflection values to compute the - complete transform. - - 'filter' and 'values' specify a Render filter that may be used by the - server when transforming data from frame buffer to crtc. - - This request sets the transform to be used at the next - RRSetCrtcConfig request execution; it does not cause any change to - occur in the current configuration. - - When a non-identity transformation is in use, the rectangle returned - by RRGetCrtcInfo defines the bounding rectangle of the screen that is - projected to the crtc. It is this projected rectangle which must be - within the area of the screen when the mode is set. - -┌─── - RRGetCrtcTransform - crtc: CRTC - ▶ - pending-transform: TRANSFORM - pending-filter: STRING8 - pending-values: LISTofFIXED - current-transform: TRANSFORM - current-filter: STRING8 - current-values: LISTofFIXED -└─── - - This request returns the pending and current transforms for the - specified CRTC. The pending transform will be the same as the current - transform if no new pending transform has been set since the last call - to RRSetCrtcConfig. - -┌─── - RRGetPanning - crtc: CRTC - ▶ - status: RRCONFIGSTATUS - timestamp: TIMESTAMP - left, top, width, height: CARD16 - track_left, track_top, track_width, track_height: CARD16 - border_left, border_top, border_right, border_bottom: INT16 -└─── - - Errors: Crtc - - Version 1.3 adds panning support again. If multiple crtcs are active - the panning behavior can be defined per crtc individually. - RRGetPanning returns information about the currently set panning - configuration for the specified crtc. If the CRTC does not support - panning, all fields (except timestamp) will be 0. - - 'timestamp' indicates when the configuration was last set. - - All other entries are explained for RRSetPanning. - -┌─── - RRSetPanning - crtc: CRTC - timestamp: TIMESTAMP - left, top, width, height: CARD16 - track_left, track_top, track_width, track_height: CARD16 - border_left, border_top, border_right, border_bottom: INT16 - ▶ - status: RRCONFIGSTATUS - new-timestamp: TIMESTAMP -└─── - Errors: Crtc, Match - - This request sets the panning parameters. As soon as panning is - enabled, the CRTC position can change with every pointer move. - RRCrtcChangeNotify events are sent to the clients requesting those. - - If 'timestamp' is less than the time when the configuration was last - successfully set, the request is ignored and InvalidTime returned in - status. - - ┌──┳━━━━━━━━━━━━━━┳─────┬ ─ ─ ─ ─ ─ ┐ - │ ┃ CRTC ┃ │ - │ ┃ ┃ │ │ - │ ┃ X┃→ │ - │ ┃ ┃ │ │ framebuffer - │ ┗━━━━━━━━━━━━━━┛ │ - │ │ │ - │panning area │ - └───────────────────────┴ ─ ─ ─ ─ ─ ┘ - - 'left', 'top', 'width', and 'height' contain the total panning area - for this CRTC. 'width' has to be larger than or equal to the CRTC's - width or 0, and 'left'+'width' must be within the screen size, else a - Match error results. Equivalent restrictions for the height exist. - 'width' or 'height' set to 0 indicate that panning should be disabled - on the according axis. Setting 'width'/'height' to the CRTC's - width/height will disable panning on the X/Y axis as well, but - RRSetScreenSize will silently enable panning if the screen size is - increased. This does not happen if set to 0. - - ┌────────┳━━━━━━━━━━━━━━┳ ─ ─ ─ ─ ─ ┐ - │ ┃ CRTC ┃ - │ ┃ ┃ │ - │ ┃ ┃ - │ ┃ ┃ │ tracking area - │ ┗━━━━━━━━━━━━━━┫ X - │ ↓ │ ↓ │ - │panning area │ - └───────────────────────┴ ─ ─ ─ ─ ─ ┘ - - 'track_left', 'track_top', 'track_width', and 'track_height' contain - the pointer area for which the panning region is updated. For normal - use cases it should enclose the panning area minus borders, and is - typically set to either the panning area minus borders, or to the - total screen size. If set to the total screen size, the CRTC will pan - in the remaining axis even if the pointer is outside the panning area - on a different CRTC, as shown in the figure above. If the pointer is - outside the tracking area, the CRTC will not pan. Zero can be used as - an alias for the total screen size. - - ┌──┳━━━━━━━━━━━━━━┳────────────┐ - │ ┃ CRTC ┃ │ - │ ┃ ┃ │ - │ ┃ ┃→ │ - │ ┃ X←→┃ │ - │ ┃ border_right │ - │ ┗━━━━━━━━━━━━━━┛ │ - │ │ - │panning area │ - └──────────────────────────────┘ - - 'border_left', 'border_top', 'border_right', and 'border_bottom' - define the distances from the CRTC borders that will activate panning - if the pointer hits them. If the borders are 0, the screen will pan - when the pointer hits the CRTC borders (behavior of pre-RandR Xserver - panning). If the borders are positive, the screen will pan when the - pointer gets close to the CRTC borders, if they are negative, the - screen will only pan when the pointer is already way past the CRTC - borders. Negative values might confuse users and disable panning to - the very edges of the screen. Thus they are discouraged. - border_left + border_right has to be lower or equal than the CRTC's - width, else a Match error results. An equivalent restriction for the - height exists. - - Screen size changes update the panning and the tracking areas to the - new size. Both screen size changes and mode changes clamp these areas - to the current CRTC size. In these cases panning borders are disabled - if their requirements are no longer met. - - When this request succeeds, 'status' contains Success and the - requested changes to configuration will have been made. - - 'new-time-stamp' contains the time at which this request was - executed. - -┌─── - RRSetOutputPrimary - window: WINDOW - output: OUTPUT -└─── - Errors: Match, Output, Window - - RRSetOutputPrimary marks 'output' as the primary output for the - screen with the same root window as 'window'. This output's CRTC - will be sorted to the front of the list in Xinerama and RANDR - geometry requests for the benefit of older applications. The - default primary output is None, and None is a legal value to pass - to RRSetOutputPrimary. This request is expected to be used by - desktop environments to mark the screen that should hold the primary - menu bar or panel. - - As this changes the logical layout of the screen, ConfigureNotify - and RRScreenChangeNotify will be generated on the appropriate root - window when the primary output is changed by this call. This request - also generates RROutputChangeNotify events on the outputs that gained - and lost primary status. - - If an output is disconnected asynchronously (eg. due to recabling), - the primary status does not change, but RROutputChangeNotify events - will be generated if the hardware is capable of detecting this; - clients are expected to reconfigure if appropriate. - - If an output is deleted (eg. due to device hotplug), the server will - act as though None was passed to RRSetOutputPrimary, including - generating the appropriate events. - -┌─── - RRGetOutputPrimary - window: WINDOW - ▶ - output: OUTPUT -└─── - Errors: Window - - RRGetOutputPrimary returns the primary output for the screen. - - ❧❧❧❧❧❧❧❧❧❧❧ - -7.3. Extension Requests added in version 1.4 of the extension. - -┌─── - RRQueryScanoutPixmaps - window: WINDOW - ▶ - infos: LISTofSCANOUTPIXMAPINFO -└─── - Errors: Window - - This request returns information about the server support for - alternate scanout pixmaps. For each pictformat, there is a set - of rotations and a maximum supported size. The rotations here - are those provided by the scanout hardware itself, not by - software emulation. - -┌─── - RRCreateScanoutPixmap - pixmap: PIXMAP - drawable: DRAWABLE - width, height: CARD16 - format: PICTFORMAT - rotations: SETofROTATION -└─── - Errors: Drawable, Match, Value - - Creates a pixmap which can subsequently be used as a scanout - buffer for the screen associated with 'drawable'. 'rotations' - is the set of rotation values which may be used with the - resulting scanout buffer when it is associated with a CRTC. - - 'format' must be one of the supported scanout formats, or a - Match error results. - - 'width' and 'height' must be within the supported range for - the specified format or a Value error results. - - 'rotations' must be a subset of those supported for the - specified format or a Match error results. - -┌─── - RRSetCrtcSpriteTransform - crtc: CRTC - position-transform: TRANSFORM - image-transform: TRANSFORM -└─── - Sets the sprite transforms for the specified crtc, any sprites - presented on this crtc will have their positions transformed - by the position-transform matrix. Sprite images displayed on the crtc - will be transformed by the image-transform matrix. - -┌─── - RRGetCrtcSpriteTransform - crtc: CRTC - ▶ - position-transform: TRANSFORM - image-transform: TRANSFORM -└─── - Gets the sprite transforms for the specified crtc. - -┌─── - RRSetCrtcConfigs - drawable: DRAWABLE - set: SETofSCREENFLAG - screen-pixmap-width: CARD16 - screen-pixmap-height: CARD16 - screen-width: CARD16 - screen-height: CARD16 - width-in-millimeters: CARD32 - height-in-millimeters: CARD32 - configs: LISTofCRTCCONFIG - ▶ - status: RRCONFIGSTATUS -└─── - Errors: Value, Match - - This works much like RRSetScreenSize followed by a sequence of - RRSetCrtcConfig, except that the entire configuration can be set - in a single operation, either succeeding or failing without - any partial execution. - - If 'set' includes 'SetScreenPixmapSize', then - 'screen-pixmap-width' and 'screen-pixmap-height' specify the - new screen pixmap size. - - If 'set' includes 'SetScreenSize', then 'screen-width' and - 'screen-height' specify the new screen size. - - If 'set' includes 'SetScreenSizeInMillimeters', then - 'width-in-millimeters' and 'height-in-millimeters' specify - the new screen physical size. - - If 'set' includes 'SetScreenCrtcs', then 'configs' includes - the list of new CRTC configurations. - - In addition to the pre-1.4 semantics, this request adds the - ability to specific a scanout pixmap for each crtc, and - integrates the 1.4 sprite transform request as well. - - ❧❧❧❧❧❧❧❧❧❧❧ - -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 -client needs 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 re-cabling a monitor, etc. - -┌─── - RRScreenChangeNotify - - rotation: ROTATION; new rotation - sequenceNumber: CARD16 low 16 bits of request 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 - size-id: SIZEID index of new SCREENSIZE - subpixelOrder: SUBPIXELORDER order of subpixels - widthInPixels: CARD16 width in pixels of the new SCREENSIZE - heightInPixels: CARD16 height in pixels of the new SCREENSIZE - widthInMillimeters: CARD16 width in mm of the new SCREENSIZE - heightInMillimeters: CARD16 height in mm of the new SCREENSIZE -└─── - This event is generated whenever the screen configuration is changed - and sent to requesting clients. 'timestamp' indicates when the - screen configuration was changed. 'configTimestamp' says when the - last time the configuration was changed. 'root' is the root of the - screen the change occurred on, 'window' is window selecting for this - event. 'size-id' contains the index of the current size. - - 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. - - 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. - - Note that the sizes in this event reflect the new SCREENSIZE and - thus will appear rotated by the 'rotation' parameter from the sizes - of the screen itself. In other words, when rotation is 90 or 270, - widthInPixels in this event will be the same as the height value - from a ConfigureNotify that reflects the same size change. This - will probably confuse developers. - -8.1 Events added in version 1.2 of the RandR extension - -┌─── - RROutputChangeNotify: - timestamp: TIMESTAMP time screen was reconfigured - config-timestamp: TIMESTAMP time available config data was changed - window: WINDOW window requesting notification - output: OUTPUT output affected by change - crtc: CRTC connected CRTC or None - mode: MODE mode in use on CRTC or None - connection: CONNECTION connection status -└─── - - This event is generated whenever the available output configurations - have changed and is sent to requesting clients. 'timestamp' - indicates when the crtc configuration was changed by a client. - 'config-timestamp' says when the last time the available - configurations changed. 'root' is the root of the screen the change - occurred on, 'window' is window selecting for this event. The - precise change can be detected by examining the new state of the - system. - -┌─── - RROutputPropertyNotify: - window: WINDOW window requesting notification - output: OUTPUT output affected by change - atom: ATOM affected property - time: TIMESTAMP time property was changed - subpixel-order: SUBPIXELORDER order of subpixels - state: { NewValue, Deleted } new property state -└─── - - This event is reported to clients selecting RROutputPropertyChange - on the window and is generated with state NewValue when a property - of the window is changed using RRChangeOutputProperty even when - adding zero-length data and when replacing all or part of a property - with identical data. It is generated with state Deleted when a - property of the window is deleted using either - RRDeleteOutputProperty or RRGetOutputProperty. The timestamp - indicates the server time when the property was changed. - -┌─── - RRCrtcChangeNotify - timestamp: TIMESTAMP time monitor was changed - window: WINDOW window requesting notification - crtc: CRTC CRTC which changed - mode: MODE new mode - rotation: ROTATION; new rotation - x: INT16 x position of CRTC within screen - y: INT16 y position of CRTC within screen - width: CARD16 width of new mode - height: CARD16 height of new mode -└─── - This event is generated whenever the CRTC configuration is changed - and sent to requesting clients. 'timestamp' indicates when the - CRTC configuration was changed. 'window' is window selecting for this - event. 'mode' is the new mode, or None if the crtc is disabled. - 'x' and 'y' mark the location in the screen where this CRTC - is reading data. 'width' and 'height' indicate the size of the - mode. 'x', 'y, 'width' and 'height' are all zero when 'mode' is None. - - This event is sent whenever the monitor's configuration changes - or if a new monitor configuration becomes available that was - not available in the past. In this case, the client MUST call - RRGetCrtcModes to update its view of possible monitor - configurations to have a correct view of possible monitor - organizations. - - Clients which select monitor change notification events may be - sent an event immediately if the monitor 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 monitor size or configuration. - - ❧❧❧❧❧❧❧❧❧❧❧ - -9. Properties - -Properties are used for output specific parameters, and for announcing -static or rarely changing data. Announced data is typically -immutable. Properties are also used for evaluating new parameters -before adding them to the RandR protocol. - -The following properties are hereby declared official, and drivers SHOULD -prefix driver specific properties with '_', unless they are planned to be -added to this specification. List values, that are not declared by the table -below, and will remain driver specific or are not planned to be added to this -specification, SHOULD be prefixed with "_" as well in order to avoid name -space or semantics clashes with future extensions of these values. - -Beginning with version 1.3 of the RandR extension, certain properties -are mandatory and MUST be provided by implementations. Earlier -versions of the RandR extension MAY provide these properties as well, -as long as the semantics are not altered. Clients SHOULD fall back -gracefully to lower version functionality, though, if the driver -doesn't handle a mandatory property correctly. - -9.1 Known properties - - "Backlight" aka RR_PROPERTY_BACKLIGHT - Type: int32 - Flags: - - Range/List: 0-x (driver specific) - - This property controls the brightness on laptop panels and equivalent - displays with a backlight controller. The driver specific maximum - value MUST turn the backlight to full brightness, 1 SHOULD turn the - backlight to minimum brightness, 0 SHOULD turn the backlight off. - - "CloneList" aka RR_PROPERTY_CLONE_LIST - Type: int32 [2*n] / Atom pairs - Flags: Immutable - Range/List: 0- - - Some combinations of outputs on some cards cannot be served - independently from each other, because they are wired up to the same - encoder outputs. - This property lists all output + signal format pairs that are - driven together with this output, and thus can only be programmed in - clone mode with the same CRTC. - This property MUST be symmetric, but may change with changing signal - format. I.e. if the property for DVI-1/VGA specifies VGA-1/VGA to be - cloned, VGA-1/VGA has to list DVI-1/VGA as well. - Outputs / format pairs listed in this property MUST be included in the - CompatibilityList. - - "CompatibilityList" aka RR_PROPERTY_COMPATIBILITY_LIST - Type: int32 [2*n] / Atom pairs - Flags: Immutable - Range/List: 0- - - Some combinations of outputs on some cards cannot be served at all, - because the according encoder is only capable of driving one output at - a time. - This property lists all output + signal format pairs that can be - driven together with this output. NULL atoms specify any output / any - signal format, respectively. - This property MUST be symmetric, but may change with changing signal - format. I.e. if the property for DVI-1/TMDS specifies VGA-1/VGA to be - available, VGA-1/VGA has to list DVI-1/TMDS as well. - - "ConnectorNumber" aka RR_PROPERTY_CONNECTOR_NUMBER - Type: int32 - Flags: Immutable, Static - Range/List: 0- - - Outputs that route their signal to the same connector MUST - have the same connector number. Outputs with the same - connector number MUST route their signal to the same - connector, except if it is 0, which indicates unknown - connectivity. 1 is called the primary connector, 2 the - secondary. 3 is typically a TV connector, but that is completely - driver / hardware dependent. - Outputs with the same connector number SHOULD have the same - connector type. Meaning and client behavior for mismatching - connector types is undefined at the moment. - - "ConnectorType" aka RR_PROPERTY_CONNECTOR_TYPE - Type: int32 / Atom - Flags: Immutable, Static - Range/List: unknown VGA DVI DVI‐I DVI‐A DVI‐D HDMI Panel - TV TV-Composite TV-SVideo TV-Component - TV-SCART TV-C4 DisplayPort - - Connector type, as far as known to the driver. - Values with dashes (TV‐Composite) describe more specific versions of - the base values (TV). The former SHOULD be used if the connector is - not capable of producing other signal formats. The later SHOULD be - used if the exact connector is unknown, or the connector is a - multi‐format connector that is not described otherwise. DVI, for - instance, SHOULD be handled like a DVI‐I connector, unless additional - information is available to the user agent. PANEL describes - laptop‐internal (normally LVDS) displays. TV, TV‐SCART, TV‐Component, - and TV‐C4 with signal format VGA are valid combinations and describe - RGB TV signals. - - "EDID" aka RR_PROPERTY_RANDR_EDID - Type: int8 [n] - Flags: Immutable - Range/List: - - - Raw EDID data from the device attached to the according - output. Should include main EDID data and all extension - blocks. Previously known as EdidData. - - "SignalFormat" aka RR_PROPERTY_SIGNAL_FORMAT - Type: int32 / Atom - Flags: - - Range/List: unknown VGA TMDS LVDS Composite Composite-PAL - Composite-NTSC Composite-SECAM SVideo - Component DisplayPort - - Signal format / physical protocol format that is used for the - specified output. valid-values lists all possible formats on this - output, which SHOULD be a subset of the list above and MUST be static. - Values with dashes (Composite-PAL) describe more specific versions of - the base values (Composite) and SHOULD be used if known to the driver. - A driver MAY change this property of an output if the underlying - hardware indicates a protocol change (e.g. TV formats). Clients are - allowed to change the signal format in order to select a different - signal format (e.g. Composite etc.) or physical protocol (e.g. VGA or - TMDS on DVI-I). - Laptop panels SHOULD not be detected with this property, but rather by - ConnectorType. - - "SignalProperties" aka RR_PROPERTY_SIGNAL_FORMAT - Type: int32 [n] / Atom - Flags: - - Range/List: For Composite signals: - NTSC NTSC-M NTSC-J NTSC-N NTSC-4.43 NTSC-film - PAL PAL-B PAL-G PAL-H PAL-H PAL-I PAL-M PAL-D - PAL-N PAL-Nc PAL-L PAL-60 - SECAM SECAM-L SECAM-B SECAM-G SECAM-D SECAM-K - SECAM-H SECAM-K - For TMDS signals: - SingleLink DualLink - For DisplayPort signals: - Lane1 Lane2 Lane4 LowSpeed HiSpeed - - Properties of the signal format that is currently used for the - specified output. valid-values lists all possible properties on this - output, which SHOULD be a subset of the list above. It will change if - SignalFormat changes. Multiple properties are allowed. - Values with dashes (PAL-B) describe more specific versions of the base - values (PAL) and SHOULD be used if known to the driver. A driver MAY - change this property of an output if the underlying hardware indicates - a signal change (e.g. TV formats). Clients are allowed to change the - properties in order to select a different signal subformat. - - -9.2 Properties introduced with version 1.2 of the RandR extension - -Property Immutable Mandatory since -──────── ───────── ─────────────── -EDID yes n/a - -EDID is provided by the RandR frontend, thus not driver specific. - - -9.3 Properties introduced with version 1.3 of the RandR extension - -Property Immutable Mandatory since -──────── ───────── ─────────────── -CloneList yes not mandatory -CompatibilityList yes not mandatory -ConnectorNumber yes: static not mandatory -ConnectorType yes: static RandR 1.3 -SignalFormat no RandR 1.3 -SignalProperties no not mandatory - -9.4 Properties introduced with version 1.3.1 of the RandR extension - -Property Immutable Mandatory since -──────── ───────── ─────────────── -Backlight no not mandatory - - ❧❧❧❧❧❧❧❧❧❧❧ - -10. 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 provided. -This document describes the version 1.2 of the specification, the -partial implementations have version numbers less than that. Here's a -list of what each version provided: - - 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 - - 1.2: Separate screens from CRTCs and outputs, switch to full VESA - modes - - 1.3: Added cheap version of RRGetScreenResources. Added CRTC - transformations. Added panning. Added primary outputs. - Added standard properties. - -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. Version 1.2 offers an extended model of the -system with multiple output support. Version 1.3 adds a cheap version of -GetScreenResources to avoid expensive DDC operations, CRTC transformations, -panning, and the primary output concept. 1.2 and 1.3 are backward-compatible -with 1.1. - - ❧❧❧❧❧❧❧❧❧❧❧ - -11. Relationship with other extensions - -Two other extensions have a direct relationship with this extension. This -section attempts to explain how these three are supposed to work together. - -11.1 XFree86-VidModeExtension - -XFree86-VidModeExtension changes the configuration of a single monitor -attached to the screen without changing the configuration of the screen -itself. It provides the ability to specify new mode lines for the server to -use along with selecting among existing mode lines. As it uses screen -numbers instead of window identifiers, it can be used to affect multiple -monitors in a single-screen Xinerama configuration. However, the association -between screen numbers and root windows in a multi-Screen environment is not -defined by the extension. Version 2.0 of this extension added the ability to -adjust the DAC values in a TrueColor server to modify the brightness curves -of the display. - -All of the utility of this extension is subsumed by RandR version 1.2, RandR -should be used in preference to XFree86-VidModeExtension where both are -present. - -11.2 Xinerama - -Xinerama provides a mechanism for describing the relationship between the -overall screen display and monitors placed within that area. As such, it -provides the query functionality of RandR 1.2 without any of the -configuration functionality. Applications using Xinerama to discover -monitor geometry can continue to do so, with the caveat that they will not be -informed of changes when they occur. However, Xinerama configuration data -will be updated, so applications selecting for RandR notification and -re-querying the configuration with the Xinerama extension will get updated -information. It is probably better to view RandR as a superset of Xinerama -at this point and use it in preference to Xinerama where both are present. - - ❧❧❧❧❧❧❧❧❧❧❧ - -Appendix A. Protocol Encoding - -Syntactic Conventions - -This document uses the same syntactic conventions as the core X -protocol encoding document. - -A.1 Common Types - -┌─── - ROTATION - 0x0001 Rotate_0 - 0x0002 Rotate_90 - 0x0004 Rotate_180 - 0x0008 Rotate_270 - 0x0010 Reflect_X - 0x0020 Reflect_Y -└─── - Used to encode both sets of possible rotations and individual - selected rotations. - -┌─── - RRSELECTMASK - 0x0001 ScreenChangeNotifyMask - 0x0002 CrtcChangeNotifyMask Added in version 1.2 - 0x0004 OutputChangeNotifyMask Added in version 1.2 - 0x0008 OutputPropertyNotifyMask Added in version 1.2 -└─── - Event select mask for RRSelectInput - -┌─── - RRCONFIGSTATUS - 0x0 Success - 0x1 InvalidConfigTime - 0x2 InvalidTime - 0x3 Failed -└─── - Return status for requests which depend on time. - -┌─── - MODEINFO (32) Added in version 1.2 - 4 CARD32 id - 2 CARD16 width in pixels - 2 CARD16 height in pixels - 4 CARD32 dot clock - 2 CARD16 h sync start - 2 CARD16 h sync end - 2 CARD16 h total - 2 CARD16 h skew - 2 CARD16 v sync start - 2 CARD16 v sync end - 2 CARD16 v total - 2 CARD16 name length - 4 SETofMODEFLAG mode flags -└─── - - An output mode specifies the complete CRTC timings for - a specific mode. The vertical and horizontal synchronization rates - can be computed given the dot clock and the h total/v total - values. If the dot clock is zero, then all of the timing - parameters and flags are not used, and must be zero as this - indicates that the timings are unknown or otherwise unused. - The name itself will be encoded separately in each usage. - -┌─── - MODEFLAG - 0x00000001 HSyncPositive - 0x00000002 HSyncNegative - 0x00000004 VSyncPositive - 0x00000008 VSyncNegative - 0x00000010 Interlace - 0x00000020 DoubleScan - 0x00000040 CSync - 0x00000080 CSyncPositive - 0x00000100 CSyncNegative - 0x00000200 HSkewPresent - 0x00000400 BCast - 0x00000800 PixelMultiplex - 0x00001000 DoubleClock - 0x00002000 ClockDivideBy2 -└─── -┌─── - CONNECTION - 0 Connected - 1 Disconnected - 2 UnknownConnection -└─── - - -A.2 Protocol Requests - -Opcodes 1 and 3 were used in the 0.0 protocols, and will return -errors if used in version 1.0. - -┌─── - RRQueryVersion - - 1 CARD8 major opcode - 1 0 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 2 RandR opcode - 2 6 length - 4 WINDOW window on screen to be configured - 4 TIMESTAMP timestamp - 4 TIMESTAMP config timestamp - 2 SIZEID size index - 2 ROTATION rotation/reflection - 2 CARD16 refresh rate (1.1 only) - 2 CARD16 pad - ▶ - 1 1 Reply - 1 RRCONFIGSTATUS status - 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 4 RandR opcode - 2 3 length - 4 WINDOW window - 2 SETofRRSELECTMASK enable - 2 CARD16 pad -└─── -┌─── - RRGetScreenInfo - - 1 CARD8 major opcode - 1 5 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 SCREENSIZE following - 2 SIZEID current size index - 2 ROTATION current rotation and reflection - 2 CARD16 current rate (added in version 1.1) - 2 CARD16 length of rate info (number of CARD16s) - 2 CARD16 pad - - SCREENSIZE - 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.1 Protocol Requests added with version 1.2 - -┌─── - RRGetScreenSizeRange - 1 CARD8 major opcode - 1 6 RandR opcode - 2 2 length - 4 WINDOW window - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 0 reply length - 2 CARD16 minWidth - 2 CARD16 minHeight - 2 CARD16 maxWidth - 2 CARD16 maxHeight - 16 unused -└─── -┌─── - RRSetScreenSize - 1 CARD8 major opcode - 1 7 RandR opcode - 2 5 length - 4 WINDOW window - 2 CARD16 width - 2 CARD16 height - 4 CARD32 width in millimeters - 4 CARD32 height in millimeters -└─── -┌─── - RRGetScreenResources - 1 CARD8 major opcode - 1 8 RandR opcode - 2 2 length - 4 WINDOW window - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 c+o+8m+(b+p)/4 reply length - 4 TIMESTAMP timestamp - 4 TIMESTAMP config-timestamp - 2 c number of CRTCs - 2 o number of outputs - 2 m number of modeinfos - 2 b total bytes in mode names - 8 unused - 4c LISTofCRTC crtcs - 4o LISTofOUTPUT outputs - 32m LISTofMODEINFO modeinfos - b STRING8 mode names - p unused, p=pad(b) -└─── -┌─── - RRGetOutputInfo - 1 CARD8 major opcode - 1 9 RandR opcode - 2 3 length - 4 OUTPUT output - 4 TIMESTAMP config-timestamp - ▶ - 1 1 Reply - 1 RRCONFIGSTATUS status - 2 CARD16 sequence number - 4 1+c+m+(n+p)/4 reply length - 4 TIMESTAMP timestamp - 4 CRTC current connected crtc - 4 CARD32 width in millimeters - 4 CARD32 height in millimeters - 1 CONNECTION connection - 1 SUBPIXELORDER subpixel-order - 2 c number of CRTCs - 2 m number of modes - 2 p number of preferred modes - 2 o number of clones - 2 n length of name - 4c LISTofCRTC crtcs - 4m LISTofMODE modes - 4o LISTofOUTPUT clones - n STRING8 name - p unused, p=pad(n) -└─── -┌─── - RRListOutputProperties - 1 CARD8 major opcode - 1 10 RandR opcode - 2 2 length - 4 OUTPUT output - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 n reply length - 2 n number of ATOMs in atoms - 22 unused - 4n LISTofATOM atoms -└─── -┌─── - RRQueryOutputProperty - 1 CARD8 major opcode - 1 11 RandR opcode - 2 3 request length - 4 OUTPUT output - 4 ATOM property - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 n reply length - 1 BOOL pending - 1 BOOL range - 1 BOOL immutable - 21 unused - 4n LISTofINT32 valid values -└─── -┌─── - RRConfigureOutputProperty - 1 CARD8 major opcode - 1 12 RandR opcode - 2 4+n request length - 4 OUTPUT output - 4 ATOM property - 1 BOOL pending - 1 BOOL range - 2 unused - 4n LISTofINT32 valid values -└─── -┌─── - RRChangeOutputProperty - 1 CARD8 major opcode - 1 13 RandR opcode - 2 6+(n+p)/4 request length - 4 OUTPUT output - 4 ATOM property - 4 ATOM type - 1 CARD8 format - 1 mode - 0 Replace - 1 Prepend - 2 Append - 2 unused - 4 CARD32 length of data in format units - (= n for format = 8) - (= n/2 for format = 16) - (= n/4 for format = 32) - n LISTofBYTE data - (n is a multiple of 2 for format = 16) - (n is a multiple of 4 for format = 32) - p unused, p=pad(n) -└─── -┌─── - RRDeleteOutputProperty - 1 CARD8 major opcode - 1 14 RandR opcode - 2 3 request length - 4 OUTPUT output - 4 ATOM property -└─── -┌─── - RRGetOutputProperty - 1 CARD8 major opcode - 1 15 RandR opcode - 2 7 request length - 4 OUTPUT output - 4 ATOM property - 4 ATOM type - 0 AnyPropertyType - 4 CARD32 long-offset - 4 CARD32 long-length - 1 BOOL delete - 1 BOOL pending - 2 unused - ▶ - 1 1 Reply - 1 CARD8 format - 2 CARD16 sequence number - 4 (n+p)/4 reply length - 4 ATOM type - 0 None - 4 CARD32 bytes-after - 4 CARD32 length of value in format units - (= 0 for format = 0) - (= n for format = 8) - (= n/2 for format = 16) - (= n/4 for format = 32) - 12 unused - n LISTofBYTE value - (n is zero for format = 0) - (n is a multiple of 2 for format = 16) - (n is a multiple of 4 for format = 32) - p unused, p=pad(n) -└─── -┌─── - RRCreateMode - 1 CARD8 major opcode - 1 16 RandR opcode - 2 12+(n+p)/4 length - 4 WINDOW window - 32 MODEINFO mode - n STRING8 mode name - p unused, p=pad(n) - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 0 reply length - 4 MODE mode - 20 unused -└─── -┌─── - RRDestroyMode - 1 CARD8 major opcode - 1 17 RandR opcode - 2 2 length - 4 MODE mode -└─── -┌─── - RRAddOutputMode - 1 CARD8 major opcode - 1 18 RandR opcode - 2 3 length - 4 OUTPUT output - 4 MODE mode -└─── -┌─── - RRDeleteOutputMode - 1 CARD8 major opcode - 1 19 RandR opcode - 2 3 length - 4 OUTPUT output - 4 MODE mode -└─── -┌─── - RRGetCrtcInfo - 1 CARD8 major opcode - 1 20 RandR opcode - 2 3 length - 4 CRTC crtc - 4 TIMESTAMP config-timestamp - ▶ - 1 1 Reply - 1 RRCONFIGSTATUS status - 2 CARD16 sequence number - 4 o+p reply length - 4 TIMESTATMP timestamp - 2 INT16 x - 2 INT16 y - 2 CARD16 width - 2 CARD16 height - 4 MODE mode - 2 ROTATION current rotation and reflection - 2 ROTATION set of possible rotations - 2 o number of outputs - 2 p number of possible outputs - 4o LISTofOUTPUT outputs - 4p LISTofOUTPUT possible outputs -└─── -┌─── - RRSetCrtcConfig - 1 CARD8 major opcode - 1 21 RandR opcode - 2 7+2n length - 4 CRTC crtc - 4 TIMESTAMP timestamp - 4 TIMESTAMP config timestamp - 2 INT16 x - 2 INT16 y - 4 MODE mode - 2 ROTATION rotation/reflection - 2 unused - 8n LISTofOUTPUT outputs - ▶ - 1 1 Reply - 1 RRCONFIGSTATUS status - 2 CARD16 sequence number - 4 0 reply length - 4 TIMESTAMP new timestamp - 20 unused -└─── -┌─── - RRGetCrtcGammaSize - 1 CARD8 major opcode - 1 22 RandR opcode - 2 2 length - 4 CRTC crtc - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 0 reply length - 2 CARD16 size - 22 unused -└─── -┌─── - RRGetCrtcGamma - 1 CARD8 major opcode - 1 23 RandR opcode - 2 2 length - 4 CRTC crtc - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 (6n+2)/4 reply length - 2 n size - 20 unused - 2n LISTofCARD16 red - 2n LISTofCARD16 green - 2n LISTofCARD16 blue - p unused, p=pad(6n) -└─── -┌─── - RRSetCrtcGamma - 1 CARD8 major opcode - 1 24 RandR opcode - 2 3+(6n+2)/4 length - 4 CRTC crtc - 2 n size - 2 unused - 2n LISTofCARD16 red - 2n LISTofCARD16 green - 2n LISTofCARD16 blue - p unused, p=pad(6n) -└─── - -A.2.2 Protocol Requests added with version 1.3 - -┌─── - RRGetScreenResourcesCurrent - 1 CARD8 major opcode - 1 25 RandR opcode - 2 2 length - 4 WINDOW window - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 c+o+8m+(b+p)/4 reply length - 4 TIMESTAMP timestamp - 4 TIMESTAMP config-timestamp - 2 c number of CRTCs - 2 o number of outputs - 2 m number of modeinfos - 2 b total bytes in mode names - 8 unused - 4c LISTofCRTC crtcs - 4o LISTofOUTPUT outputs - 32m LISTofMODEINFO modeinfos - b STRING8 mode names - p unused, p=pad(b) -└─── - -┌─── - RRSetCrtcTransform - 1 CARD8 major opcode - 1 26 RandR opcode - 2 12+(n+p)/4+v length - 4 CRTC crtc - 36 TRANSFORM transform - 2 CARD16 filter length - 2 unused - n STRING8 filter name - p unused, p=pad(n) - 4v FIXED filter params -└─── - -┌─── - RRGetCrtcTransform - 1 CARD8 major opcode - 1 27 RandR opcode - 2 2 length - 4 CRTC crtc - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 16+(pn+pnp)/4+(cn+cnp)/4+pf+cf reply length - 36 TRANSFORM pending transform - 1 BOOL has transforms - 3 unused - 36 TRANSFORM current transform - 4 unused - 2 pn pending filter name length - 2 pf pending filter num params - 2 cn current filter name length - 2 cf current filter num params - pn STRING8 pending filter name - pnp unused, pnp=pad(pn) - 4*pf FIXED pending filter params - cn STRING8 current filter name - cnp unused, cnp=pad(cn) - 4*cf FIXED current filter params -└─── - -┌─── - RRGetPanning - 1 CARD8 major opcode - 1 28 RandR opcode - 2 2 length - 4 CRTC crtc - ▶ - 1 1 Reply - 1 RRCONFIGSTATUS status - 2 CARD16 sequence number - 4 1 reply length - 4 TIMESTAMP timestamp - 2 CARD16 left - 2 CARD16 top - 2 CARD16 width - 2 CARD16 height - 2 CARD16 track_left - 2 CARD16 track_top - 2 CARD16 track_width - 2 CARD16 track_height - 2 INT16 border_left - 2 INT16 border_top - 2 INT16 border_right - 2 INT16 border_bottom -└─── -┌─── - RRSetPanning - 1 CARD8 major opcode - 1 29 RandR opcode - 2 9 length - 4 CRTC crtc - 4 TIMESTAMP timestamp - 2 CARD16 left - 2 CARD16 top - 2 CARD16 width - 2 CARD16 height - 2 CARD16 track_left - 2 CARD16 track_top - 2 CARD16 track_width - 2 CARD16 track_height - 2 INT16 border_left - 2 INT16 border_top - 2 INT16 border_right - 2 INT16 border_bottom - ▶ - 1 1 Reply - 1 RRCONFIGSTATUS status - 2 CARD16 sequence number - 4 0 reply length - 4 TIMESTAMP new timestamp - 20 unused -└─── - -┌─── - RRSetOutputPrimary - 1 CARD8 major opcode - 1 30 RandR opcode - 2 3 length - 4 WINDOW window - 4 OUTPUT output -└─── - -┌─── - RRGetOutputPrimary - 1 CARD8 major opcode - 1 31 RandR opcode - 2 2 length - 4 WINDOW window - ▶ - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 CARD32 length - 4 OUTPUT output - 4 CARD32 pad1 - 4 CARD32 pad2 - 4 CARD32 pad3 - 4 CARD32 pad4 -└─── - -A.3 Protocol Events - -┌─── - 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 -└─── - -A.3.1 Protocol Events added with version 1.2 - -┌─── - RRCrtcChangeNotify - 1 Base + 1 code - 1 0 sub-code - 2 CARD16 sequence number - 4 TIMESTAMP timestamp - 4 WINDOW request window - 4 CRTC crtc affected - 4 MODE mode in use - 2 ROTATION new rotation and reflection - 2 unused - 2 INT16 x - 2 INT16 y - 2 CARD16 width - 2 CARD16 height -└─── -┌─── - RROutputChangeNotify - 1 Base + 1 code - 1 1 sub-code - 2 CARD16 sequence number - 4 TIMESTAMP timestamp - 4 TIMESTAMP configuration timestamp - 4 WINDOW request window - 4 OUTPUT output affected - 4 CRTC crtc in use - 4 MODE mode in use - 2 ROTATION rotation in use - 1 CONNECTION connection status - 1 SUBPIXELORDER subpixel order -└─── -┌─── - RROutputPropertyNotify - 1 Base + 1 code - 1 2 sub-code - 2 CARD16 sequence number - 4 WINDOW window - 4 OUTPUT output - 4 ATOM atom - 4 TIMESTAMP time - 1 state - 0 NewValue - 1 Deleted - 11 unused -└─── - -A.4 Protocol Errors - -┌─── - ERRORS - Base + 0 Output - Base + 1 Crtc - Base + 2 Mode -└─── - -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, - http://cgit.freedesktop.org/xorg/proto/renderproto/tree/renderproto.txt + The X Resize, Rotate and Reflect Extension + Version 1.4.0 + 2009-10-5 + + Jim Gettys + Jim.Gettys@hp.com + Cambridge Research Laboratory + HP Labs + Hewlett Packard Company + + Keith Packard + keith.packard@intel.com + Open Source Technology Center + Intel Corporation + +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 X 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 implementation has been removed from the +protocol described here, as it has been overtaken by events. + +These events include: + ► Modern toolkits (in this case, GTK+ 2.x) have progressed to the point + of implementing migration between screens of arbitrary depths + ► 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 + ► The continued decline of legacy toolkits whose design would have + required depth switching to support migration + ► The lack of depth switching 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 implemented 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 X.org server, and more fully in the hw/kdrive +implementation in the distribution, which fully implements resizing, +rotation and reflection. + +1.2 Introduction to version 1.2 of the extension + +One of the significant limitations found in version 1.1 of the RandR +protocol was the inability to deal with the Xinerama model where multiple +monitors display portions of a common underlying screen. In this environment, +zero or more video outputs are associated with each CRT controller which +defines both a set of video timings and a 'viewport' within the larger +screen. This viewport is independent of the overall size of the screen, and +may be located anywhere within the screen. + +The effect is to decouple the reported size of the screen from the size +presented by each video output, and to permit multiple outputs to present +information for a single screen. + +To extend RandR for this model, we separate out the output, CRTC and screen +configuration information and permit them to be configured separately. For +compatibility with the 1.1 version of the protocol, we make the 1.1 requests +simultaneously affect both the screen and the (presumably sole) CRTC and +output. The set of available outputs are presented with UTF-8 encoded names +and may be connected to CRTCs as permitted by the underlying hardware. CRTC +configuration is now done with full mode information instead of just size +and refresh rate, and these modes have names. These names also use UTF-8 +encoding. New modes may also be added by the user. + +Additional requests and events are provided for this new functionality. + + ┌────────────────────────────────┬──────────┐ + ┏━━━━━━━┳───────────────┐ ╔════════╗ ╔════════╗ + ┃ 1 ┃ │ ║ A ║ ║ B ║ + ┃ ┏━━━╋━━━━━━━━━━━━━━━┫ ║ ║ ║ ║ + ┣━━━╋━━━┛ ┃ ╚════════╝ ╚════════╝ + │ ┃ 2 ┃─────────────────┐ + │ ┃ ┃ ╔═══════════════════╗ + │ ┃ ┃ ║ ║ + │ ┗━━━━━━━━━━━━━━━━━━━┫ ║ C ║ + └───────────────────────┘ ║ ║ + ┌──────┐ ┏━━━━┓ ╔══════╗ ║ ║ + │screen│ ┃CRTC┃ ║output║ ╚═══════════════════╝ + └──────┘ ┗━━━━┛ ╚══════╝ + +In this picture, the screen is covered (incompletely) by two CRTCs. CRTC1 +is connected to two outputs, A and B. CRTC2 is connected to output C. +Outputs A and B will present exactly the same region of the screen using +the same mode line. Output C will present a different (larger) region of +the screen using a different mode line. + +RandR provides information about each available CRTC and output; the +connection between CRTC and output is under application control, although +the hardware will probably impose restrictions on the possible +configurations. The protocol doesn't try to describe these restrictions, +instead it provides a mechanism to find out what combinations are supported. + +1.3 Introduction to version 1.3 of the extension + +Version 1.3 builds on the changes made with version 1.2 and adds some new +capabilities without fundmentally changing the extension again. The +following features are added in this version: + + • Projective Transforms. The implementation work for general rotation + support made it trivial to add full projective transformations. These + can be used to scale the screen up/down as well as perform projector + keystone correct or other effects. + + • Panning. It was removed with RandR 1.2 because the old semantics didn't + fit any longer. With RandR 1.3 panning can be specified per crtc. + +1.4 Introduction to version 1.4 of the extension + +Version 1.4 adds a couple more capabilities to further expose the +underlying hardware to clients + + • Per-crtc pixmaps. This provides for multiple scan-out buffers + which applications can create and assign to arbitrary collections + of crtcs. + + • Sprite position and image transforms. These provide a projective + transform for both the hot spot location and the sprite image + itself for each CRTC. + + • RRSetCrtcConfigs request. This supplies a set of + crtc configurations to the server that must be applied together + or not at all. This can reduce screen flicker while also + providing the server a complete configuration for appropriate + resource management. + +The first two additions, per-crtc pixmaps and sprite transforms are +designed to solve two problems: + + 1) Screen transforms. The software transform code in the X server + uses a shadow frame buffer, adding another copy to every graphics + operation. Worse, the server has no idea about when clients are + done drawing a frame, so the user gets additional latency and + judder. + + The goal is to move this operation out to the compositing manager + which already deals with an extra copy of the frame buffer for + many operations. Have the compositing manager create and draw to a + separate pixmap for scanout. It can perform whatever transforms + are required to get the image in the right orientation for the + user. + + 2) Hardware scanout engine size limits. With a single scanout buffer + for the entire screen, it's possible for the user to ask for a + configuration which requires that scanout buffer to be larger than + the hardware is capable of scanning out from. Again, having the + compositing manager create a pixmap for each CRTC will allow for + any configuration where monitor position within the virtual space + isn't limited by the scanout limits. + +In both of these cases, the Sprite transforms are necessary to ensure +that the sprite appears at the desired spot on each CRTC and with the +right shape. + +1.99 Acknowledgements + +Our thanks to the contributors to the design found on the xpert mailing +list, in particular: + +Alan Hourihane for work on the early implementation +Andrew C. Aitchison for help with the XFree86 DDX implementation +Andy Ritger for early questions about how mergefb/Xinerama work with RandR +Carl Worth for editing the specification and Usenix paper +David Dawes for XFree86 DDX integration work +Thomas Winischhofer for the hardware-accelerated SiS rotation implementation +Matthew Tippett and Kevin Martin for splitting outputs and CRTCs to more +fully expose what video hardware can do + + ❧❧❧❧❧❧❧❧❧❧❧ + +2. Screen change model + +Screens may change dynamically, either under control of this extension, or +due to external events. Examples include: monitors being swapped, 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 or Express Card 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 enable 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 structure, 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 + +Errors are sent using core X error reports. + +Output + A value for an OUTPUT argument does not name a defined OUTPUT. +CRTC + A value for a CRTC argument does not name a defined CRTC. +Mode + A value for a MODE argument does not name a defined MODE. + + ❧❧❧❧❧❧❧❧❧❧❧ + +5. Protocol Types + +RRCONFIGSTATUS { Success + InvalidConfigTime + InvalidTime + Failed } + + A value of type RRCONFIGSTATUS returned when manipulating the output + configuration or querying information from the server that has some + time-dependency. + + InvalidConfigTime indicates that the supplied configuration + timestamp does not match the current X server configuration + timestamp. Usually this means that the output configuration has + changed since the timestamp was received by the application. + + InvalidTime indicates that the supplied output reconfiguration time + is earlier than the most recent output reconfiguration request. + Generally this indicates that another application has reconfigured + the output using a later timestamp. + + Failed is returned whenever the operation is unsuccessful for some + other reason. This generally indicates that the requested output + configuration is unsupported by the hardware. The goal is to make + these limitations expressed by the protocol, but when that isn't + possible it is correct to return this error value. If, as a + implentor, you find this error code required, please submit the + hardware constraints that exist so that a future version of the + extension can correctly capture the configuration constraints in + your system. + +ROTATION { Rotate_0 + Rotate_90 + Rotate_180 + Rotate_270 + Reflect_X + Reflect_Y } + + These values are used both to indicate a set of allowed rotations + and reflections as well as to indicate a specific rotation and + reflection combination. + +RRSELECTMASK { RRScreenChangeNotifyMask + RRCrtcChangeNotifyMask (New in version 1.2) + RROutputChangeNotifyMask (New in version 1.2) + RROutputPropertyNotifyMask (New in version 1.2) } + +SIZEID { CARD16 } + +MODE { XID or None } + +CRTC { XID } + +OUTPUT { XID } + +CONNECTION { Connected, Disconnected, UnknownConnection } + + This value provides an indication of whether an output is actually + connected to a monitor or other presentation device. + +SUBPIXELORDER { SubPixelUnknown The subpixel order uses the Render + SubPixelHorizontalRGB extensions definitions; they are here + SubPixelHorizontalBGR only for convenience. + SubPixelVerticalRGB + SubPixelVerticalBGR + SubPixelNone } + +SCREENSIZE { widthInPixels, heightInPixels: CARD16 + widthInMillimeters, heightInMillimeters: CARD16 } + +MODEFLAG { HSyncPositive + HSyncNegative + VSyncPositive + VSyncNegative + Interlace + DoubleScan + CSync + CSyncPositive + CSyncNegative + HSkewPresent + BCast + PixelMultiplex + DoubleClock + ClockDivideBy2 } + +MODEINFO { id: MODE + name: STRING + width, height: CARD16 + dotClock: CARD32 + hSyncStart, hSyncEnd, hTotal, hSkew: CARD16 + vSyncStart, vSyncEnd, vTotal: CARD16 + modeFlags: SETofMODEFLAG } + +REFRESH { rates: LISTofCARD16 } + + ❧❧❧❧❧❧❧❧❧❧❧ + +5.4. Protocol Types added in version 1.4 of the extension + +SCANOUTPIXMAPINFO { format: PICTFORMAT + maxWidth, maxHeight: CARD16 + rotations: SETofROTATION } + + 'format' is the format of the pixels within the scanout + pixmap. Only 'Direct' formats are supported, this will never + be an 'Indexed' format. + + 'maxWidth' and 'maxHeight' define the largest supported + scanout pixmap. There is no minimum size; scanout pixmaps down + to 1x1 may be created. + + 'rotations' lists the set of rotations which can be provided + without additional latency or memory usage within the + environment. This typically means that they are supported + directly by the hardware. It is expected that a compositing + manager will perform other transforms as a part of the + compositing process in conjunction with the sprite transforms + described in this extension. + +SCREENFLAG { SetScreenPixmapSize + SetScreenSize + SetScreenSizeInMillimeters + SetScreenCrtcs } + +CRTCFLAG { SetCrtcPosition + SetCrtcMode + SetCrtcRotation + SetCrtcOutputs + SetCrtcSpritePositionTransform + SetCrtcSpriteImageTransform + SetCrtcPixmap + SetCrtcPixmapPosition } + +CRTCCONFIG { crtc: CRTC + set: SETofCRTCFLAG + x, y: INT16 + mode: MODE + rotation: ROTATION + sprite-position-transform: TRANSFORM + sprite-image-transform: TRANSFORM + outputs: LISTofOUTPUT + pixmap: PIXMAP or None + pixmap-x, pixmap-y: INT16 } + + If 'set' includes SetCrtcSpritePositionTransform, then + sprite-position-transform is used as in the + RRSetCrtcSpriteTransform request position-transform parameter. + + If 'set' includes SetCrtcSpriteImageTransform, then + sprite-image-transform is used as in the + RRSetCrtcSpriteTransform request image-transform parameter. + + If 'set' includes SetCrtcPixmap, then 'pixmap' specifies the + origin of the pixel data to be presented on 'crtc'. If + 'pixmap' is None, then data will be presented from the screen + pixmap. + + If 'set' includes SetCrtcPixmapPosition, then 'pixmap-x' and + 'pixmap-y' specify the origin of the scanout data within the + pixmap, the area from that location to pixmap-x + + width-of(mode), pixmap-y + height-of(mode) is what will be + seen on the connected outputs. + + If 'set' includes SetCrtcPixmap, then 'pixmap' must specify a + scanout pixmap as created by RRCreateScanoutPixmap or + None. Otherwise a Match error results. Furthermore: + + * 'pixmap' must be at least as large as the area to be + scanned out, or a Match error results. + + * If 'pixmap' is destroyed while still being used as a + scanout pixmap, then the associated CRTC will have its + scanout pixmap set back to None, the CRTC origin set back + to 0,0 (to make sure it fits) and the screen pixmap width + and height increased to be at least as big as the current + CRTC mode. + + * Future crtc changes that do not change the scanout pixmap + will cause an existing scanout pixmap to be resized to be + large enough to hold the new mode at the then-current + pixmap-x/pixmap-y location. + + If 'set' includes SetCrtcRotation then: + + * Any new or existing scanout pixmap must have had the + specified 'rotation' included as a part of its creation + parameters, or a Match error results. + + * If no scanout pixmap is in use, then the crtc must support + 'rotation' else a Value error results. + + ❧❧❧❧❧❧❧❧❧❧❧ + +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: Window, Value + + If 'enable' is RRScreenChangeNotifyMask, RRScreenChangeNotify events + will be sent when the screen configuration changes, either from + this protocol extension, or due to detected external screen + configuration changes. RRScreenChangeNotify may also be sent when + this request executes if the screen configuration has changed since + the client connected, to avoid race conditions. + + New for version 1.2: + + If 'enable' contains RRCrtcChangeMask, RRCrtcChangeNotify events + will be sent when a the configuration for a CRTC associated with the + screen changes, either through this protocol extension or due to + detected external changes. RRCrtcChangeNotify may also be sent when + this request executes if the CRTC configuration has changed since + the client connected, to avoid race conditions. + + If 'enable' contains RROutputChangeMask, RROutputChangeNotify events + will be sent when a the configuration for an output associated with + the screen changes, either through this protocol extension or due to + detected external changes. RROutputChangeNotify may also be sent + when this request executes if the output configuration has changed + since the client connected, to avoid race conditions. + + If 'enable' contains RROutputPropertyNotifyMask, + RROutputPropertyNotify events will be sent when properties change on + this output. + +┌─── + RRSetScreenConfig + window: WINDOW + timestamp: TIMESTAMP + config-timestamp: TIMESTAMP + size-id: SIZEID + rotation: ROTATION + rate: CARD16 + ▶ + status: RRCONFIGSTATUS + new-timestamp: TIMESTAMP + config-timestamp: TIMESTAMP + root: WINDOW + subpixelOrder: SUBPIXELORDER +└─── + Errors: Value, Match + + If 'timestamp' is less than the time when the configuration was last + successfully set, the request is ignored and InvalidTime returned in + status. + + If 'config-timestamp' is not equal to when the server's screen + configurations last changed, the request is ignored and + InvalidConfigTime returned in status. 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. + + 'rate' contains the desired refresh rate. If it is zero, the server + selects an appropriate rate. + + This request may fail for other indeterminate reasons, in which case + 'status' will be set to Failed and no configuration change will be + made. + + This request sets the screen to the specified size, rate, rotation + and reflection. + + When this request succeeds, 'status' contains Success and the + requested changes to configuration will have been made. + + 'new-time-stamp' contains the time at which this request was + executed. + + 'config-timestamp' contains the time when the possible screen + configurations were last changed. + + 'root' contains the root window for the screen indicated by the + window. + + 'subpixelOrder' contains the resulting subpixel order of the screen + to allow correct subpixel rendering. + + Value errors are generated when 'rotation', 'rate' or 'size-id' + are invalid. + +┌─── + RRGetScreenInfo + window: WINDOW + ▶ + rotations: SETofROTATION + root: WINDOW + timestamp: TIMESTAMP + config-timestamp: TIMESTAMP + size-id: SIZEID + rotation: ROTATION + rate: CARD16 + sizes: LISTofSCREENSIZE + refresh: LISTofREFRESH +└─── + + Errors: Window + + RRGetScreenInfo returns information about the current and available + configurations for the screen associated with 'window'. + + 'rotations' contains the set of rotations and reflections supported + by the screen. + + 'root' is the root window of the screen. + + '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. + + 'timestamp' indicates when the configuration was last set. + + 'size-id' indicates which size is active. + + '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 size indicates 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 corresponding 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. + +7.1. Extension Requests added in version 1.2 of the extension + +As introduced above, version 1.2 of the extension splits the screen size +from the crtc and output configuration, permitting the subset of the screen +presented by multiple outputs to be configured. As a separate notion, the +size of the screen itself may be arbitrarily configured within a defined +range. As crtcs and outputs are added and removed from the system, the set +returned by the extension will change so that applications can detect +dynamic changes in the display environment. + +┌─── + RRGetScreenSizeRange + window: WINDOW + ▶ + CARD16 minWidth, minHeight + CARD16 maxWidth, maxHeight +└─── + Errors: Window + + Returns the range of possible screen sizes. The screen may be set to + any size within this range. + +┌─── + RRSetScreenSize + window: WINDOW + width: CARD16 + height: CARD16 + width-in-millimeters: CARD32 + height-in-millimeters: CARD32 +└─── + Errors: Window, Match, Value + + Sets the screen to the specified size. 'width' and 'height' must be + within the range allowed by GetScreenSizeRanges, otherwise a Value + error results. All active monitors must be configured to display a + subset of the specified size, else a Match error results. + + 'width-in-millimeters' and 'height-in-millimeters' can be set to + reflect the physical size of the screen reported both through this + extension and the core protocol. They must be non-zero, or Value + error results. + + If panning is enabled, the width and height of the panning and the + tracking areas are adapted to the new size and clamped afterwards. + Disabled panning axes remain disabled. + Panning borders are disabled if their requirements are no longer met + (see RRSetPanning). + +┌─── + RRGetScreenResources + window: WINDOW + ▶ + timestamp: TIMESTAMP + config-timestamp: TIMESTAMP + crtcs: LISTofCRTC + outputs: LISTofOUTPUT + modes: LISTofMODEINFO +└─── + Errors: Window + + RRGetScreenResources returns the list of outputs and crtcs connected + to the screen associated with 'window'. + + 'timestamp' indicates when the configuration was last set. + + 'config-timestamp' indicates when the configuration information last + changed. Requests to configure the output 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. + + 'crtcs' contains the list of CRTCs associated with the screen. + + 'outputs' contains the list of outputs associated with the screen. + + 'modes' contains the list of modes associated with the screen + + This request explicitly asks the server to ensure that the + configuration data is up-to-date wrt the hardware. If that requires + polling, this is when such polling would take place. If the + current configuration is all that's required, use + RRGetScreenResourcesCurrent instead. + +┌─── + RRGetOutputInfo + output: OUTPUT + config-timestamp: TIMESTAMP + ▶ + status: RRCONFIGSTATUS + timestamp: TIMESTAMP + crtc: CRTC + + name: STRING + connection: CONNECTION + subpixel-order: SUBPIXELORDER + widthInMillimeters, heightInMillimeters: CARD32 + crtcs: LISTofCRTC + clones: LISTofOUTPUT + modes: LISTofMODE + num-preferred: CARD16 +└─── + Errors: Output + + RRGetOutputInfo returns information about the current and available + configurations 'output'. + + If 'config-timestamp' does not match the current configuration + timestamp (as returned by RRGetScreenResources), 'status' is set to + InvalidConfigTime and the remaining reply data is empty. Otherwise, + 'status' is set to Success. + + 'timestamp' indicates when the configuration was last set. + + 'crtc' is the current source CRTC for video data, or Disabled if the + output is not connected to any CRTC. + + 'name' is a UTF-8 encoded string designed to be presented to the + user to indicate which output this is. E.g. "S-Video" or "DVI". + + 'connection' indicates whether the hardware was able to detect a + device connected to this output. If the hardware cannot determine + whether something is connected, it will set this to + UnknownConnection. + + 'subpixel-order' contains the resulting subpixel order of the + connected device to allow correct subpixel rendering. + + 'widthInMillimeters' and 'heightInMillimeters' report the physical + size of the displayed area. If unknown, or not really fixed (e.g., + for a projector), these values are both zero. + + 'crtcs' is the list of CRTCs that this output may be connected to. + Attempting to connect this output to a different CRTC results in a + Match error. + + 'clones' is the list of outputs which may be simultaneously + connected to the same CRTC along with this output. Attempting to + connect this output with an output not in the 'clones' list + results in a Match error. + + 'modes' is the list of modes supported by this output. Attempting to + connect this output to a CRTC not using one of these modes results + in a Match error. + + The first 'num-preferred' modes in 'modes' are preferred by the + monitor in some way; for fixed-pixel devices, this would generally + indicate which modes match the resolution of the output device. + +┌─── + RRListOutputProperties + output:OUTPUT + ▶ + atoms: LISTof ATOM +└─── + Errors: Output + + This request returns the atoms of properties currently defined on + the output. + +┌─── + RRQueryOutputProperty + output: OUTPUT + property: ATOM + ▶ + pending: BOOL + range: BOOL + immutable: BOOL + valid-values: LISTofINT32 +└─── + Errors: Name, Atom, Output + + If the specified property does not exist for the specified output, + then a Name error is returned. + + If 'pending' is TRUE, changes made to property values with + RRChangeOutputProperty will be saved in the pending property value + and be automatically copied to the current value on the next + RRSetCrtcConfig request involving the named output. If 'pending' is + FALSE, changes are copied immediately. + + If 'range' is TRUE, then the valid-values list will contain + precisely two values indicating the minimum and maximum allowed + values. If 'range' is FALSE, then the valid-values list will contain + the list of possible values; attempts to set other values will + result in a Value error. + + If 'immutable' is TRUE, then the property configuration cannot be + changed by clients. Immutable properties are interpreted by the X + server. + +┌─── + RRConfigureOutputProperty + output: OUTPUT + property: ATOM + pending: BOOL + range: BOOL + valid-values: LISTofINT32 +└─── + Errors: Access, Name, Atom, Output + + If the specified property is 'immutable', an Access error is + returned. + + Otherwise, the configuration of the specified property is changed to + the values provided in this request. + + If the specified property does not exist for the specified output, + it is created with an empty value and None type. + +┌─── + RRChangeOutputProperty + output: OUTPUT + property, type: ATOM + format: {8, 16, 32} + mode: { Replace, Prepend, Append } + data: LISTofINT8 or LISTofINT16 or LISTofINT32 +└─── + Errors: Alloc, Atom, Match, Value, Output + + This request alters the value of the property for the specified + output. If the property is marked as a 'pending' property, only the + pending value of the property is changed. Otherwise, changes are + reflected in both the pending and current values of the property. + The type is uninterpreted by the server. The format specifies + whether the data should be viewed as a list of 8-bit, 16-bit, or + 32-bit quantities so that the server can correctly byte-swap as + necessary. + + If the mode is Replace, the previous property value is discarded. + If the mode is Prepend or Append, then the type and format must + match the existing property value (or a Match error results). If + the property is undefined, it is treated as defined with the correct + type and format with zero-length data. + + For Prepend, the data is tacked on to the beginning of the existing + data, and for Append, it is tacked on to the end of the existing data. + + This request generates a OutputPropertyNotify + + The lifetime of a property is not tied to the storing client. + Properties remain until explicitly deleted, until the output is + destroyed, or until server reset (see section 10). + + The maximum size of a property is server-dependent and may vary + dynamically. + +┌─── + RRDeleteOutputProperty + output: OUTPUT + property: ATOM +└─── + Errors: Atom, Output + + This request deletes the property from the specified window if the + property exists and generates a OutputPropertyNotify event unless + the property does not exist. + +┌─── + RRGetOutputProperty + output: OUTPUT + property: ATOM + type: ATOM or AnyPropertyType + long-offset, long-length: CARD32 + delete: BOOL + pending: BOOL + ▶ + type: ATOM or None + format: {0, 8, 16, 32} + bytes-after: CARD32 + value: LISTofINT8 or LISTofINT16 or LISTofINT32 +└─── + Errors: Atom, Value, Output + + If the specified property does not exist for the specified output, + then the return type is None, the format and bytes-after are zero, + and the value is empty. The delete argument is ignored in this + case. + + If the specified property exists but its type does not match the + specified type, then the return type is the actual type of the + property, the format is the actual format of the property (never + zero), the bytes-after is the length of the property in bytes (even + if the format is 16 or 32), and the value is empty. The delete + argument is ignored in this case. + + If the specified property exists and either AnyPropertyType is + specified or the specified type matches the actual type of the + property, then the return type is the actual type of the property, + the format is the actual format of the property (never zero), and + the bytes-after and value are as follows, given: + + N = actual length of the stored property in bytes + (even if the format is 16 or 32) + I = 4 × offset + T = N - I + L = MINIMUM(T, 4 × long-length) + A = N - (I + L) + + If 'pending' is true, and if the property holds a pending value, + then the value returned will be the pending value of the property + rather than the current value. The returned value starts at byte + index I in the property (indexing from 0), and its length in bytes + is L. However, it is a Value error if long-offset is given such + that L is negative. The value of bytes-after is A, giving the + number of trailing unread bytes in the stored property. If delete + is True and the bytes-after is zero, the property is also deleted + from the output, and a RROutputPropertyNotify event is generated. + +┌─── + RRCreateMode + window: WINDOW + modeinfo: MODEINFO + ▶ + mode: MODE +└─── + Errors: Window, Name, Value + + 'modeinfo' provides a new mode for outputs on the screen + associated with 'window'. If the name of 'modeinfo' names an + existing mode, a Name error is returned. If some parameter of the + mode is not valid in some other way, a Value error is returned. + + The returned 'mode' provides the id for the mode. + +┌─── + RRDestroyMode + mode: MODE +└─── + Errors: Mode, Access + + The user-defined 'mode' is destroyed. 'mode' must name a mode + defined with RRCreateMode, else an Match error is returned. If + 'mode' is in use by some CRTC or Output, then an Access error is + returned. + +┌─── + RRAddOutputMode + output: OUTPUT + mode: MODE +└─── + Errors: Output, Mode, Match + + 'output' indicates which output is to be configured. + + 'mode' specifies which mode to add. If 'mode' is not valid for + 'output', then a Match error is generated. + + This request generates OutputChangeNotify events. + +┌─── + RRDeleteOutputMode + output: OUTPUT + mode: MODE +└─── + Errors: Output, Mode + + 'output' indicates which output is to be configured. + + 'mode' specifies which mode to delete. 'mode' must have been added + with RRAddOutputMode, else an Access error is returned. 'mode' must + not be active, else a Match error is returned. + + This request generates OutputChangeNotify events. + +┌─── + RRGetCrtcInfo + crtc: CRTC + config-timestamp: TIMESTAMP + ▶ + status: RRCONFIGSTATUS + timestamp: TIMESTAMP + x, y: INT16 + width, height: CARD16 + mode: MODE + rotation: ROTATION + outputs: LISTofOUTPUT + + rotations: SETofROTATION + possible-outputs: LISTofOUTPUT +└─── + + Errors: Window + + RRGetCrtcModes returns information about the current and available + configurations for the specified crtc connected to the screen + associated with 'window'. + + If 'config-timestamp' does not match the current configuration + timestamp (as returned by RRGetScreenResources), 'status' is set to + InvalidConfigTime and the remaining reply data is empty. Otherwise, + 'status' is set to Success. + + 'timestamp' indicates when the configuration was last set. + + 'x' and 'y' indicate the position of this CRTC within the screen + region. They will be set to 0 when the CRTC is disabled. + + 'width' and 'height' indicate the size of the area within the screen + presented by this CRTC. This may be different than the size of the + mode due to rotation. They will be set to 0 when the CRTC + is disabled. + + 'mode' indicates which mode is active, or None indicating that the + CRTC has been disabled and is not displaying the screen contents. + + 'rotation' indicates the active rotation. It is set to Rotate_0 + when the CRTC is disabled. + + 'outputs' is the list of outputs currently connected to this CRTC + and is empty when the CRTC is disabled. + + 'rotations' contains the set of rotations and reflections supported + by the CRTC. + + 'possible-outputs' lists all of the outputs which may be connected + to this CRTC. + +┌─── + RRSetCrtcConfig + crtc: CRTC + timestamp: TIMESTAMP + config-timestamp: TIMESTAMP + x, y: INT16 + mode: MODE + rotation: ROTATION + outputs: LISTofOUTPUT + ▶ + status: RRCONFIGSTATUS + new-timestamp: TIMESTAMP +└─── + Errors: Value, Match + + If 'timestamp' is less than the time when the configuration was last + successfully set, the request is ignored and InvalidTime returned in + status. + + If 'config-timestamp' is not equal to when the monitor's + configuration last changed, the request is ignored and + InvalidConfigTime returned in status. This could occur if the + monitor changed since you last made a RRGetScreenInfo request, + perhaps by a different monitor being connected to the machine. + Rather than allowing an incorrect call to be executed based on stale + data, the server will ignore the request. + + 'x' and 'y' contain the desired location within the screen for this + monitor's content. 'x' and 'y' must be within the screen size, else + a Value error results. + + 'mode' is either the desired mode or None indicating the CRTC should + be disabled. If 'mode' is not one of these values, a Value + error results. 'mode' must be valid for all of the configured outputs, + else a Match error. + + 'rotation' contains the desired rotation along with which + reflections should be enabled. The rotation and reflection values + must be among those allowed for this monitor, else a Value error + results. + + 'outputs' contains the set of outputs that this CRTC should be + connected to. The set must be among the list of acceptable output + sets for this CRTC or a Match error results. + + If 'mode' is None, then 'outputs' must be empty, else a Match error + results. Conversely, if 'mode' is not None, then 'outputs' must not be + empty, else a Match error results. + + This request may fail for other indeterminate reasons, in which case + 'status' will be set to Failed and no configuration change will be + made. + + This request sets the CRTC to the specified position, mode, rotation + and reflection. The entire area of the CRTC must fit within the + screen size, else a Match error results. As an example, rotating the + screen so that a single CRTC fills the entire screen before and + after may necessitate disabling the CRTC, resizing the screen, + then re-enabling the CRTC at the new configuration to avoid an + invalid intermediate configuration. + + If panning is enabled, the width and height of the panning and the + tracking areas are clamped to the new mode size. + Disabled panning axes remain disabled. + Panning borders are disabled if their requirements are no longer met + (see RRSetPanning). + + When this request succeeds, 'status' contains Success and the + requested changes to configuration will have been made. + + 'new-time-stamp' contains the time at which this request was + executed. + +┌─── + RRGetCrtcGammaSize + crtc: CRTC + ▶ + size: CARD16 +└─── + Errors: Crtc + + This request returns the size of the gamma ramps used by 'crtc'. + +┌─── + RRGetCrtcGamma + crtc: CRTC + ▶ + red: LISTofCARD16 + green: LISTofCARD16 + blue: LISTofCARD16 +└─── + Errors: Crtc + + This request returns the currently set gamma ramps for 'crtc'. All + three lists will be the size returned by the RRGetCrtcGammaSize + request. + +┌─── + RRSetCrtcGamma + crtc: CRTC + red: LISTofCARD16 + green: LISTofCARD16 + blue: LISTofCARD16 +└─── + Errors: Crtc, Match + + This request sets the gamma ramps for 'crtc'. All three lists + must be the size returned by RRGetCrtcGammaSize else a Value error + results. + +7.2. Extension Requests added in version 1.3 of the extension + +┌─── + RRGetScreenResourcesCurrent + window: WINDOW + ▶ + timestamp: TIMESTAMP + config-timestamp: TIMESTAMP + crtcs: LISTofCRTC + outputs: LISTofOUTPUT + modes: LISTofMODEINFO +└─── + Errors: Window + + RRGetScreenResourcesCurrent returns the list of outputs and crtcs + connected to the screen associated with 'window'. + + 'timestamp' indicates when the configuration was last set. + + 'config-timestamp' indicates when the configuration information last + changed. Requests to configure the output 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. + + 'crtcs' contains the list of CRTCs associated with the screen. + + 'outputs' contains the list of outputs associated with the screen. + + 'modes' contains the list of modes associated with the screen. + + Unlike RRGetScreenResources, this merely returns the current + configuration, and does not poll for hardware changes. + +┌─── + RRSetCrtcTransform + crtc: CRTC + transform: TRANSFORM + filter: STRING8 + values: LISTofFIXED +└─── + Errors: Crtc, Match + + This request provides a mechanism that is more general than the + existing rotation and reflection values for describing the + transformation from frame buffer image to crtc presentation. + 'transform' is a full 2D projective transformation from screen + coordinate space to crtc coordinate space. This transformation is + applied before the rotation and reflection values to compute the + complete transform. + + 'filter' and 'values' specify a Render filter that may be used by the + server when transforming data from frame buffer to crtc. + + This request sets the transform to be used at the next + RRSetCrtcConfig request execution; it does not cause any change to + occur in the current configuration. + + When a non-identity transformation is in use, the rectangle returned + by RRGetCrtcInfo defines the bounding rectangle of the screen that is + projected to the crtc. It is this projected rectangle which must be + within the area of the screen when the mode is set. + +┌─── + RRGetCrtcTransform + crtc: CRTC + ▶ + pending-transform: TRANSFORM + pending-filter: STRING8 + pending-values: LISTofFIXED + current-transform: TRANSFORM + current-filter: STRING8 + current-values: LISTofFIXED +└─── + + This request returns the pending and current transforms for the + specified CRTC. The pending transform will be the same as the current + transform if no new pending transform has been set since the last call + to RRSetCrtcConfig. + +┌─── + RRGetPanning + crtc: CRTC + ▶ + status: RRCONFIGSTATUS + timestamp: TIMESTAMP + left, top, width, height: CARD16 + track_left, track_top, track_width, track_height: CARD16 + border_left, border_top, border_right, border_bottom: INT16 +└─── + + Errors: Crtc + + Version 1.3 adds panning support again. If multiple crtcs are active + the panning behavior can be defined per crtc individually. + RRGetPanning returns information about the currently set panning + configuration for the specified crtc. If the CRTC does not support + panning, all fields (except timestamp) will be 0. + + 'timestamp' indicates when the configuration was last set. + + All other entries are explained for RRSetPanning. + +┌─── + RRSetPanning + crtc: CRTC + timestamp: TIMESTAMP + left, top, width, height: CARD16 + track_left, track_top, track_width, track_height: CARD16 + border_left, border_top, border_right, border_bottom: INT16 + ▶ + status: RRCONFIGSTATUS + new-timestamp: TIMESTAMP +└─── + Errors: Crtc, Match + + This request sets the panning parameters. As soon as panning is + enabled, the CRTC position can change with every pointer move. + RRCrtcChangeNotify events are sent to the clients requesting those. + + If 'timestamp' is less than the time when the configuration was last + successfully set, the request is ignored and InvalidTime returned in + status. + + ┌──┳━━━━━━━━━━━━━━┳─────┬ ─ ─ ─ ─ ─ ┐ + │ ┃ CRTC ┃ │ + │ ┃ ┃ │ │ + │ ┃ X┃→ │ + │ ┃ ┃ │ │ framebuffer + │ ┗━━━━━━━━━━━━━━┛ │ + │ │ │ + │panning area │ + └───────────────────────┴ ─ ─ ─ ─ ─ ┘ + + 'left', 'top', 'width', and 'height' contain the total panning area + for this CRTC. 'width' has to be larger than or equal to the CRTC's + width or 0, and 'left'+'width' must be within the screen size, else a + Match error results. Equivalent restrictions for the height exist. + 'width' or 'height' set to 0 indicate that panning should be disabled + on the according axis. Setting 'width'/'height' to the CRTC's + width/height will disable panning on the X/Y axis as well, but + RRSetScreenSize will silently enable panning if the screen size is + increased. This does not happen if set to 0. + + ┌────────┳━━━━━━━━━━━━━━┳ ─ ─ ─ ─ ─ ┐ + │ ┃ CRTC ┃ + │ ┃ ┃ │ + │ ┃ ┃ + │ ┃ ┃ │ tracking area + │ ┗━━━━━━━━━━━━━━┫ X + │ ↓ │ ↓ │ + │panning area │ + └───────────────────────┴ ─ ─ ─ ─ ─ ┘ + + 'track_left', 'track_top', 'track_width', and 'track_height' contain + the pointer area for which the panning region is updated. For normal + use cases it should enclose the panning area minus borders, and is + typically set to either the panning area minus borders, or to the + total screen size. If set to the total screen size, the CRTC will pan + in the remaining axis even if the pointer is outside the panning area + on a different CRTC, as shown in the figure above. If the pointer is + outside the tracking area, the CRTC will not pan. Zero can be used as + an alias for the total screen size. + + ┌──┳━━━━━━━━━━━━━━┳────────────┐ + │ ┃ CRTC ┃ │ + │ ┃ ┃ │ + │ ┃ ┃→ │ + │ ┃ X←→┃ │ + │ ┃ border_right │ + │ ┗━━━━━━━━━━━━━━┛ │ + │ │ + │panning area │ + └──────────────────────────────┘ + + 'border_left', 'border_top', 'border_right', and 'border_bottom' + define the distances from the CRTC borders that will activate panning + if the pointer hits them. If the borders are 0, the screen will pan + when the pointer hits the CRTC borders (behavior of pre-RandR Xserver + panning). If the borders are positive, the screen will pan when the + pointer gets close to the CRTC borders, if they are negative, the + screen will only pan when the pointer is already way past the CRTC + borders. Negative values might confuse users and disable panning to + the very edges of the screen. Thus they are discouraged. + border_left + border_right has to be lower or equal than the CRTC's + width, else a Match error results. An equivalent restriction for the + height exists. + + Screen size changes update the panning and the tracking areas to the + new size. Both screen size changes and mode changes clamp these areas + to the current CRTC size. In these cases panning borders are disabled + if their requirements are no longer met. + + When this request succeeds, 'status' contains Success and the + requested changes to configuration will have been made. + + 'new-time-stamp' contains the time at which this request was + executed. + +┌─── + RRSetOutputPrimary + window: WINDOW + output: OUTPUT +└─── + Errors: Match, Output, Window + + RRSetOutputPrimary marks 'output' as the primary output for the + screen with the same root window as 'window'. This output's CRTC + will be sorted to the front of the list in Xinerama and RANDR + geometry requests for the benefit of older applications. The + default primary output is None, and None is a legal value to pass + to RRSetOutputPrimary. This request is expected to be used by + desktop environments to mark the screen that should hold the primary + menu bar or panel. + + As this changes the logical layout of the screen, ConfigureNotify + and RRScreenChangeNotify will be generated on the appropriate root + window when the primary output is changed by this call. This request + also generates RROutputChangeNotify events on the outputs that gained + and lost primary status. + + If an output is disconnected asynchronously (eg. due to recabling), + the primary status does not change, but RROutputChangeNotify events + will be generated if the hardware is capable of detecting this; + clients are expected to reconfigure if appropriate. + + If an output is deleted (eg. due to device hotplug), the server will + act as though None was passed to RRSetOutputPrimary, including + generating the appropriate events. + +┌─── + RRGetOutputPrimary + window: WINDOW + ▶ + output: OUTPUT +└─── + Errors: Window + + RRGetOutputPrimary returns the primary output for the screen. + + ❧❧❧❧❧❧❧❧❧❧❧ + +7.3. Extension Requests added in version 1.4 of the extension. + +┌─── + RRQueryScanoutPixmaps + window: WINDOW + ▶ + infos: LISTofSCANOUTPIXMAPINFO +└─── + Errors: Window + + This request returns information about the server support for + alternate scanout pixmaps. For each pictformat, there is a set + of rotations and a maximum supported size. The rotations here + are those provided by the scanout hardware itself, not by + software emulation. + +┌─── + RRCreateScanoutPixmap + pixmap: PIXMAP + drawable: DRAWABLE + width, height: CARD16 + format: PICTFORMAT + rotations: SETofROTATION +└─── + Errors: Drawable, Match, Value + + Creates a pixmap which can subsequently be used as a scanout + buffer for the screen associated with 'drawable'. 'rotations' + is the set of rotation values which may be used with the + resulting scanout buffer when it is associated with a CRTC. + + 'format' must be one of the supported scanout formats, or a + Match error results. + + 'width' and 'height' must be within the supported range for + the specified format or a Value error results. + + 'rotations' must be a subset of those supported for the + specified format or a Match error results. + +┌─── + RRSetCrtcSpriteTransform + crtc: CRTC + position-transform: TRANSFORM + image-transform: TRANSFORM +└─── + Sets the sprite transforms for the specified crtc, any sprites + presented on this crtc will have their positions transformed + by the position-transform matrix. Sprite images displayed on the crtc + will be transformed by the image-transform matrix. + +┌─── + RRGetCrtcSpriteTransform + crtc: CRTC + ▶ + position-transform: TRANSFORM + image-transform: TRANSFORM +└─── + Gets the sprite transforms for the specified crtc. + +┌─── + RRSetCrtcConfigs + drawable: DRAWABLE + set: SETofSCREENFLAG + screen-pixmap-width: CARD16 + screen-pixmap-height: CARD16 + screen-width: CARD16 + screen-height: CARD16 + width-in-millimeters: CARD32 + height-in-millimeters: CARD32 + configs: LISTofCRTCCONFIG + ▶ + status: RRCONFIGSTATUS +└─── + Errors: Value, Match + + This works much like RRSetScreenSize followed by a sequence of + RRSetCrtcConfig, except that the entire configuration can be set + in a single operation, either succeeding or failing without + any partial execution. + + If 'set' includes 'SetScreenPixmapSize', then + 'screen-pixmap-width' and 'screen-pixmap-height' specify the + new screen pixmap size. + + If 'set' includes 'SetScreenSize', then 'screen-width' and + 'screen-height' specify the new screen size. + + If 'set' includes 'SetScreenSizeInMillimeters', then + 'width-in-millimeters' and 'height-in-millimeters' specify + the new screen physical size. + + If 'set' includes 'SetScreenCrtcs', then 'configs' includes + the list of new CRTC configurations. + + In addition to the pre-1.4 semantics, this request adds the + ability to specific a scanout pixmap for each crtc, and + integrates the 1.4 sprite transform request as well. + + ❧❧❧❧❧❧❧❧❧❧❧ + +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 +client needs 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 re-cabling a monitor, etc. + +┌─── + RRScreenChangeNotify + + rotation: ROTATION; new rotation + sequenceNumber: CARD16 low 16 bits of request 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 + size-id: SIZEID index of new SCREENSIZE + subpixelOrder: SUBPIXELORDER order of subpixels + widthInPixels: CARD16 width in pixels of the new SCREENSIZE + heightInPixels: CARD16 height in pixels of the new SCREENSIZE + widthInMillimeters: CARD16 width in mm of the new SCREENSIZE + heightInMillimeters: CARD16 height in mm of the new SCREENSIZE +└─── + This event is generated whenever the screen configuration is changed + and sent to requesting clients. 'timestamp' indicates when the + screen configuration was changed. 'configTimestamp' says when the + last time the configuration was changed. 'root' is the root of the + screen the change occurred on, 'window' is window selecting for this + event. 'size-id' contains the index of the current size. + + 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. + + 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. + + Note that the sizes in this event reflect the new SCREENSIZE and + thus will appear rotated by the 'rotation' parameter from the sizes + of the screen itself. In other words, when rotation is 90 or 270, + widthInPixels in this event will be the same as the height value + from a ConfigureNotify that reflects the same size change. This + will probably confuse developers. + +8.1 Events added in version 1.2 of the RandR extension + +┌─── + RROutputChangeNotify: + timestamp: TIMESTAMP time screen was reconfigured + config-timestamp: TIMESTAMP time available config data was changed + window: WINDOW window requesting notification + output: OUTPUT output affected by change + crtc: CRTC connected CRTC or None + mode: MODE mode in use on CRTC or None + connection: CONNECTION connection status +└─── + + This event is generated whenever the available output configurations + have changed and is sent to requesting clients. 'timestamp' + indicates when the crtc configuration was changed by a client. + 'config-timestamp' says when the last time the available + configurations changed. 'root' is the root of the screen the change + occurred on, 'window' is window selecting for this event. The + precise change can be detected by examining the new state of the + system. + +┌─── + RROutputPropertyNotify: + window: WINDOW window requesting notification + output: OUTPUT output affected by change + atom: ATOM affected property + time: TIMESTAMP time property was changed + subpixel-order: SUBPIXELORDER order of subpixels + state: { NewValue, Deleted } new property state +└─── + + This event is reported to clients selecting RROutputPropertyChange + on the window and is generated with state NewValue when a property + of the window is changed using RRChangeOutputProperty even when + adding zero-length data and when replacing all or part of a property + with identical data. It is generated with state Deleted when a + property of the window is deleted using either + RRDeleteOutputProperty or RRGetOutputProperty. The timestamp + indicates the server time when the property was changed. + +┌─── + RRCrtcChangeNotify + timestamp: TIMESTAMP time monitor was changed + window: WINDOW window requesting notification + crtc: CRTC CRTC which changed + mode: MODE new mode + rotation: ROTATION; new rotation + x: INT16 x position of CRTC within screen + y: INT16 y position of CRTC within screen + width: CARD16 width of new mode + height: CARD16 height of new mode +└─── + This event is generated whenever the CRTC configuration is changed + and sent to requesting clients. 'timestamp' indicates when the + CRTC configuration was changed. 'window' is window selecting for this + event. 'mode' is the new mode, or None if the crtc is disabled. + 'x' and 'y' mark the location in the screen where this CRTC + is reading data. 'width' and 'height' indicate the size of the + mode. 'x', 'y, 'width' and 'height' are all zero when 'mode' is None. + + This event is sent whenever the monitor's configuration changes + or if a new monitor configuration becomes available that was + not available in the past. In this case, the client MUST call + RRGetCrtcModes to update its view of possible monitor + configurations to have a correct view of possible monitor + organizations. + + Clients which select monitor change notification events may be + sent an event immediately if the monitor 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 monitor size or configuration. + + ❧❧❧❧❧❧❧❧❧❧❧ + +9. Properties + +Properties are used for output specific parameters, and for announcing +static or rarely changing data. Announced data is typically +immutable. Properties are also used for evaluating new parameters +before adding them to the RandR protocol. + +The following properties are hereby declared official, and drivers SHOULD +prefix driver specific properties with '_', unless they are planned to be +added to this specification. List values, that are not declared by the table +below, and will remain driver specific or are not planned to be added to this +specification, SHOULD be prefixed with "_" as well in order to avoid name +space or semantics clashes with future extensions of these values. + +Beginning with version 1.3 of the RandR extension, certain properties +are mandatory and MUST be provided by implementations. Earlier +versions of the RandR extension MAY provide these properties as well, +as long as the semantics are not altered. Clients SHOULD fall back +gracefully to lower version functionality, though, if the driver +doesn't handle a mandatory property correctly. + +9.1 Known properties + + "Backlight" aka RR_PROPERTY_BACKLIGHT + Type: INTEGER + Format: 32 + Num. items: 1 + Flags: - + Range/List: 0-x (driver specific) + + This property controls the brightness on laptop panels and equivalent + displays with a backlight controller. The driver specific maximum + value MUST turn the backlight to full brightness, 1 SHOULD turn the + backlight to minimum brightness, 0 SHOULD turn the backlight off. + + "CloneList" aka RR_PROPERTY_CLONE_LIST + Type: ATOM + Format: 32 + Num. items: 2*n + Flags: Immutable + Range/List: 0- + + Some combinations of outputs on some cards cannot be served + independently from each other, because they are wired up to the same + encoder outputs. + This property lists all output + signal format pairs that are + driven together with this output, and thus can only be programmed in + clone mode with the same CRTC. + This property MUST be symmetric, but may change with changing signal + format. I.e. if the property for DVI-1/VGA specifies VGA-1/VGA to be + cloned, VGA-1/VGA has to list DVI-1/VGA as well. + Outputs / format pairs listed in this property MUST be included in the + CompatibilityList. + + "CompatibilityList" aka RR_PROPERTY_COMPATIBILITY_LIST + Type: ATOM + Format: 32 + Num items: 2*n + Flags: Immutable + Range/List: 0- + + Some combinations of outputs on some cards cannot be served at all, + because the according encoder is only capable of driving one output at + a time. + This property lists all output + signal format pairs that can be + driven together with this output. NULL atoms specify any output / any + signal format, respectively. + This property MUST be symmetric, but may change with changing signal + format. I.e. if the property for DVI-1/TMDS specifies VGA-1/VGA to be + available, VGA-1/VGA has to list DVI-1/TMDS as well. + + "ConnectorNumber" aka RR_PROPERTY_CONNECTOR_NUMBER + Type: INTEGER + Format: 32 + Num items: 1 + Flags: Immutable, Static + Range/List: 0- + + Outputs that route their signal to the same connector MUST + have the same connector number. Outputs with the same + connector number MUST route their signal to the same + connector, except if it is 0, which indicates unknown + connectivity. 1 is called the primary connector, 2 the + secondary. 3 is typically a TV connector, but that is completely + driver / hardware dependent. + Outputs with the same connector number SHOULD have the same + connector type. Meaning and client behavior for mismatching + connector types is undefined at the moment. + + "ConnectorType" aka RR_PROPERTY_CONNECTOR_TYPE + Type: ATOM + Format: 32 + Num items: 1 + Flags: Immutable, Static + Range/List: unknown VGA DVI DVI‐I DVI‐A DVI‐D HDMI Panel + TV TV-Composite TV-SVideo TV-Component + TV-SCART TV-C4 DisplayPort + + Connector type, as far as known to the driver. + Values with dashes (TV‐Composite) describe more specific versions of + the base values (TV). The former SHOULD be used if the connector is + not capable of producing other signal formats. The later SHOULD be + used if the exact connector is unknown, or the connector is a + multi‐format connector that is not described otherwise. DVI, for + instance, SHOULD be handled like a DVI‐I connector, unless additional + information is available to the user agent. PANEL describes + laptop‐internal (normally LVDS) displays. TV, TV‐SCART, TV‐Component, + and TV‐C4 with signal format VGA are valid combinations and describe + RGB TV signals. + + "EDID" aka RR_PROPERTY_RANDR_EDID + Type: INTEGER + Format: 8 + Num items: n + Flags: Immutable + Range/List: - + + Raw EDID data from the device attached to the according + output. Should include main EDID data and all extension + blocks. Previously known as EdidData. + + "SignalFormat" aka RR_PROPERTY_SIGNAL_FORMAT + Type: ATOM + Format: 32 + Num items: 1 + Flags: - + Range/List: unknown VGA TMDS LVDS Composite Composite-PAL + Composite-NTSC Composite-SECAM SVideo + Component DisplayPort + + Signal format / physical protocol format that is used for the + specified output. valid-values lists all possible formats on this + output, which SHOULD be a subset of the list above and MUST be static. + Values with dashes (Composite-PAL) describe more specific versions of + the base values (Composite) and SHOULD be used if known to the driver. + A driver MAY change this property of an output if the underlying + hardware indicates a protocol change (e.g. TV formats). Clients are + allowed to change the signal format in order to select a different + signal format (e.g. Composite etc.) or physical protocol (e.g. VGA or + TMDS on DVI-I). + Laptop panels SHOULD not be detected with this property, but rather by + ConnectorType. + + "SignalProperties" aka RR_PROPERTY_SIGNAL_FORMAT + Type: ATOM + Format: 32 + Num items: n + Flags: - + Range/List: For Composite signals: + NTSC NTSC-M NTSC-J NTSC-N NTSC-4.43 NTSC-film + PAL PAL-B PAL-G PAL-H PAL-H PAL-I PAL-M PAL-D + PAL-N PAL-Nc PAL-L PAL-60 + SECAM SECAM-L SECAM-B SECAM-G SECAM-D SECAM-K + SECAM-H SECAM-K + For TMDS signals: + SingleLink DualLink + For DisplayPort signals: + Lane1 Lane2 Lane4 LowSpeed HiSpeed + + Properties of the signal format that is currently used for the + specified output. valid-values lists all possible properties on this + output, which SHOULD be a subset of the list above. It will change if + SignalFormat changes. Multiple properties are allowed. + Values with dashes (PAL-B) describe more specific versions of the base + values (PAL) and SHOULD be used if known to the driver. A driver MAY + change this property of an output if the underlying hardware indicates + a signal change (e.g. TV formats). Clients are allowed to change the + properties in order to select a different signal subformat. + + +9.2 Properties introduced with version 1.2 of the RandR extension + +Property Immutable Mandatory since +──────── ───────── ─────────────── +EDID yes n/a + +EDID is provided by the RandR frontend, thus not driver specific. + + +9.3 Properties introduced with version 1.3 of the RandR extension + +Property Immutable Mandatory since +──────── ───────── ─────────────── +CloneList yes not mandatory +CompatibilityList yes not mandatory +ConnectorNumber yes: static not mandatory +ConnectorType yes: static RandR 1.3 +SignalFormat no RandR 1.3 +SignalProperties no not mandatory + +9.4 Properties introduced with version 1.3.1 of the RandR extension + +Property Immutable Mandatory since +──────── ───────── ─────────────── +Backlight no not mandatory + + ❧❧❧❧❧❧❧❧❧❧❧ + +10. 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 provided. +This document describes the version 1.2 of the specification, the +partial implementations have version numbers less than that. Here's a +list of what each version provided: + + 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 + + 1.2: Separate screens from CRTCs and outputs, switch to full VESA + modes + + 1.3: Added cheap version of RRGetScreenResources. Added CRTC + transformations. Added panning. Added primary outputs. + Added standard properties. + +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. Version 1.2 offers an extended model of the +system with multiple output support. Version 1.3 adds a cheap version of +GetScreenResources to avoid expensive DDC operations, CRTC transformations, +panning, and the primary output concept. 1.2 and 1.3 are backward-compatible +with 1.1. + + ❧❧❧❧❧❧❧❧❧❧❧ + +11. Relationship with other extensions + +Two other extensions have a direct relationship with this extension. This +section attempts to explain how these three are supposed to work together. + +11.1 XFree86-VidModeExtension + +XFree86-VidModeExtension changes the configuration of a single monitor +attached to the screen without changing the configuration of the screen +itself. It provides the ability to specify new mode lines for the server to +use along with selecting among existing mode lines. As it uses screen +numbers instead of window identifiers, it can be used to affect multiple +monitors in a single-screen Xinerama configuration. However, the association +between screen numbers and root windows in a multi-Screen environment is not +defined by the extension. Version 2.0 of this extension added the ability to +adjust the DAC values in a TrueColor server to modify the brightness curves +of the display. + +All of the utility of this extension is subsumed by RandR version 1.2, RandR +should be used in preference to XFree86-VidModeExtension where both are +present. + +11.2 Xinerama + +Xinerama provides a mechanism for describing the relationship between the +overall screen display and monitors placed within that area. As such, it +provides the query functionality of RandR 1.2 without any of the +configuration functionality. Applications using Xinerama to discover +monitor geometry can continue to do so, with the caveat that they will not be +informed of changes when they occur. However, Xinerama configuration data +will be updated, so applications selecting for RandR notification and +re-querying the configuration with the Xinerama extension will get updated +information. It is probably better to view RandR as a superset of Xinerama +at this point and use it in preference to Xinerama where both are present. + + ❧❧❧❧❧❧❧❧❧❧❧ + +Appendix A. Protocol Encoding + +Syntactic Conventions + +This document uses the same syntactic conventions as the core X +protocol encoding document. + +A.1 Common Types + +┌─── + ROTATION + 0x0001 Rotate_0 + 0x0002 Rotate_90 + 0x0004 Rotate_180 + 0x0008 Rotate_270 + 0x0010 Reflect_X + 0x0020 Reflect_Y +└─── + Used to encode both sets of possible rotations and individual + selected rotations. + +┌─── + RRSELECTMASK + 0x0001 ScreenChangeNotifyMask + 0x0002 CrtcChangeNotifyMask Added in version 1.2 + 0x0004 OutputChangeNotifyMask Added in version 1.2 + 0x0008 OutputPropertyNotifyMask Added in version 1.2 +└─── + Event select mask for RRSelectInput + +┌─── + RRCONFIGSTATUS + 0x0 Success + 0x1 InvalidConfigTime + 0x2 InvalidTime + 0x3 Failed +└─── + Return status for requests which depend on time. + +┌─── + MODEINFO (32) Added in version 1.2 + 4 CARD32 id + 2 CARD16 width in pixels + 2 CARD16 height in pixels + 4 CARD32 dot clock + 2 CARD16 h sync start + 2 CARD16 h sync end + 2 CARD16 h total + 2 CARD16 h skew + 2 CARD16 v sync start + 2 CARD16 v sync end + 2 CARD16 v total + 2 CARD16 name length + 4 SETofMODEFLAG mode flags +└─── + + An output mode specifies the complete CRTC timings for + a specific mode. The vertical and horizontal synchronization rates + can be computed given the dot clock and the h total/v total + values. If the dot clock is zero, then all of the timing + parameters and flags are not used, and must be zero as this + indicates that the timings are unknown or otherwise unused. + The name itself will be encoded separately in each usage. + +┌─── + MODEFLAG + 0x00000001 HSyncPositive + 0x00000002 HSyncNegative + 0x00000004 VSyncPositive + 0x00000008 VSyncNegative + 0x00000010 Interlace + 0x00000020 DoubleScan + 0x00000040 CSync + 0x00000080 CSyncPositive + 0x00000100 CSyncNegative + 0x00000200 HSkewPresent + 0x00000400 BCast + 0x00000800 PixelMultiplex + 0x00001000 DoubleClock + 0x00002000 ClockDivideBy2 +└─── +┌─── + CONNECTION + 0 Connected + 1 Disconnected + 2 UnknownConnection +└─── + + +A.2 Protocol Requests + +Opcodes 1 and 3 were used in the 0.0 protocols, and will return +errors if used in version 1.0. + +┌─── + RRQueryVersion + + 1 CARD8 major opcode + 1 0 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 2 RandR opcode + 2 6 length + 4 WINDOW window on screen to be configured + 4 TIMESTAMP timestamp + 4 TIMESTAMP config timestamp + 2 SIZEID size index + 2 ROTATION rotation/reflection + 2 CARD16 refresh rate (1.1 only) + 2 CARD16 pad + ▶ + 1 1 Reply + 1 RRCONFIGSTATUS status + 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 4 RandR opcode + 2 3 length + 4 WINDOW window + 2 SETofRRSELECTMASK enable + 2 CARD16 pad +└─── +┌─── + RRGetScreenInfo + + 1 CARD8 major opcode + 1 5 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 SCREENSIZE following + 2 SIZEID current size index + 2 ROTATION current rotation and reflection + 2 CARD16 current rate (added in version 1.1) + 2 CARD16 length of rate info (number of CARD16s) + 2 CARD16 pad + + SCREENSIZE + 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.1 Protocol Requests added with version 1.2 + +┌─── + RRGetScreenSizeRange + 1 CARD8 major opcode + 1 6 RandR opcode + 2 2 length + 4 WINDOW window + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 0 reply length + 2 CARD16 minWidth + 2 CARD16 minHeight + 2 CARD16 maxWidth + 2 CARD16 maxHeight + 16 unused +└─── +┌─── + RRSetScreenSize + 1 CARD8 major opcode + 1 7 RandR opcode + 2 5 length + 4 WINDOW window + 2 CARD16 width + 2 CARD16 height + 4 CARD32 width in millimeters + 4 CARD32 height in millimeters +└─── +┌─── + RRGetScreenResources + 1 CARD8 major opcode + 1 8 RandR opcode + 2 2 length + 4 WINDOW window + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 c+o+8m+(b+p)/4 reply length + 4 TIMESTAMP timestamp + 4 TIMESTAMP config-timestamp + 2 c number of CRTCs + 2 o number of outputs + 2 m number of modeinfos + 2 b total bytes in mode names + 8 unused + 4c LISTofCRTC crtcs + 4o LISTofOUTPUT outputs + 32m LISTofMODEINFO modeinfos + b STRING8 mode names + p unused, p=pad(b) +└─── +┌─── + RRGetOutputInfo + 1 CARD8 major opcode + 1 9 RandR opcode + 2 3 length + 4 OUTPUT output + 4 TIMESTAMP config-timestamp + ▶ + 1 1 Reply + 1 RRCONFIGSTATUS status + 2 CARD16 sequence number + 4 1+c+m+(n+p)/4 reply length + 4 TIMESTAMP timestamp + 4 CRTC current connected crtc + 4 CARD32 width in millimeters + 4 CARD32 height in millimeters + 1 CONNECTION connection + 1 SUBPIXELORDER subpixel-order + 2 c number of CRTCs + 2 m number of modes + 2 p number of preferred modes + 2 o number of clones + 2 n length of name + 4c LISTofCRTC crtcs + 4m LISTofMODE modes + 4o LISTofOUTPUT clones + n STRING8 name + p unused, p=pad(n) +└─── +┌─── + RRListOutputProperties + 1 CARD8 major opcode + 1 10 RandR opcode + 2 2 length + 4 OUTPUT output + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 n reply length + 2 n number of ATOMs in atoms + 22 unused + 4n LISTofATOM atoms +└─── +┌─── + RRQueryOutputProperty + 1 CARD8 major opcode + 1 11 RandR opcode + 2 3 request length + 4 OUTPUT output + 4 ATOM property + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 n reply length + 1 BOOL pending + 1 BOOL range + 1 BOOL immutable + 21 unused + 4n LISTofINT32 valid values +└─── +┌─── + RRConfigureOutputProperty + 1 CARD8 major opcode + 1 12 RandR opcode + 2 4+n request length + 4 OUTPUT output + 4 ATOM property + 1 BOOL pending + 1 BOOL range + 2 unused + 4n LISTofINT32 valid values +└─── +┌─── + RRChangeOutputProperty + 1 CARD8 major opcode + 1 13 RandR opcode + 2 6+(n+p)/4 request length + 4 OUTPUT output + 4 ATOM property + 4 ATOM type + 1 CARD8 format + 1 mode + 0 Replace + 1 Prepend + 2 Append + 2 unused + 4 CARD32 length of data in format units + (= n for format = 8) + (= n/2 for format = 16) + (= n/4 for format = 32) + n LISTofBYTE data + (n is a multiple of 2 for format = 16) + (n is a multiple of 4 for format = 32) + p unused, p=pad(n) +└─── +┌─── + RRDeleteOutputProperty + 1 CARD8 major opcode + 1 14 RandR opcode + 2 3 request length + 4 OUTPUT output + 4 ATOM property +└─── +┌─── + RRGetOutputProperty + 1 CARD8 major opcode + 1 15 RandR opcode + 2 7 request length + 4 OUTPUT output + 4 ATOM property + 4 ATOM type + 0 AnyPropertyType + 4 CARD32 long-offset + 4 CARD32 long-length + 1 BOOL delete + 1 BOOL pending + 2 unused + ▶ + 1 1 Reply + 1 CARD8 format + 2 CARD16 sequence number + 4 (n+p)/4 reply length + 4 ATOM type + 0 None + 4 CARD32 bytes-after + 4 CARD32 length of value in format units + (= 0 for format = 0) + (= n for format = 8) + (= n/2 for format = 16) + (= n/4 for format = 32) + 12 unused + n LISTofBYTE value + (n is zero for format = 0) + (n is a multiple of 2 for format = 16) + (n is a multiple of 4 for format = 32) + p unused, p=pad(n) +└─── +┌─── + RRCreateMode + 1 CARD8 major opcode + 1 16 RandR opcode + 2 12+(n+p)/4 length + 4 WINDOW window + 32 MODEINFO mode + n STRING8 mode name + p unused, p=pad(n) + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 0 reply length + 4 MODE mode + 20 unused +└─── +┌─── + RRDestroyMode + 1 CARD8 major opcode + 1 17 RandR opcode + 2 2 length + 4 MODE mode +└─── +┌─── + RRAddOutputMode + 1 CARD8 major opcode + 1 18 RandR opcode + 2 3 length + 4 OUTPUT output + 4 MODE mode +└─── +┌─── + RRDeleteOutputMode + 1 CARD8 major opcode + 1 19 RandR opcode + 2 3 length + 4 OUTPUT output + 4 MODE mode +└─── +┌─── + RRGetCrtcInfo + 1 CARD8 major opcode + 1 20 RandR opcode + 2 3 length + 4 CRTC crtc + 4 TIMESTAMP config-timestamp + ▶ + 1 1 Reply + 1 RRCONFIGSTATUS status + 2 CARD16 sequence number + 4 o+p reply length + 4 TIMESTATMP timestamp + 2 INT16 x + 2 INT16 y + 2 CARD16 width + 2 CARD16 height + 4 MODE mode + 2 ROTATION current rotation and reflection + 2 ROTATION set of possible rotations + 2 o number of outputs + 2 p number of possible outputs + 4o LISTofOUTPUT outputs + 4p LISTofOUTPUT possible outputs +└─── +┌─── + RRSetCrtcConfig + 1 CARD8 major opcode + 1 21 RandR opcode + 2 7+2n length + 4 CRTC crtc + 4 TIMESTAMP timestamp + 4 TIMESTAMP config timestamp + 2 INT16 x + 2 INT16 y + 4 MODE mode + 2 ROTATION rotation/reflection + 2 unused + 8n LISTofOUTPUT outputs + ▶ + 1 1 Reply + 1 RRCONFIGSTATUS status + 2 CARD16 sequence number + 4 0 reply length + 4 TIMESTAMP new timestamp + 20 unused +└─── +┌─── + RRGetCrtcGammaSize + 1 CARD8 major opcode + 1 22 RandR opcode + 2 2 length + 4 CRTC crtc + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 0 reply length + 2 CARD16 size + 22 unused +└─── +┌─── + RRGetCrtcGamma + 1 CARD8 major opcode + 1 23 RandR opcode + 2 2 length + 4 CRTC crtc + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 (6n+2)/4 reply length + 2 n size + 20 unused + 2n LISTofCARD16 red + 2n LISTofCARD16 green + 2n LISTofCARD16 blue + p unused, p=pad(6n) +└─── +┌─── + RRSetCrtcGamma + 1 CARD8 major opcode + 1 24 RandR opcode + 2 3+(6n+2)/4 length + 4 CRTC crtc + 2 n size + 2 unused + 2n LISTofCARD16 red + 2n LISTofCARD16 green + 2n LISTofCARD16 blue + p unused, p=pad(6n) +└─── + +A.2.2 Protocol Requests added with version 1.3 + +┌─── + RRGetScreenResourcesCurrent + 1 CARD8 major opcode + 1 25 RandR opcode + 2 2 length + 4 WINDOW window + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 c+o+8m+(b+p)/4 reply length + 4 TIMESTAMP timestamp + 4 TIMESTAMP config-timestamp + 2 c number of CRTCs + 2 o number of outputs + 2 m number of modeinfos + 2 b total bytes in mode names + 8 unused + 4c LISTofCRTC crtcs + 4o LISTofOUTPUT outputs + 32m LISTofMODEINFO modeinfos + b STRING8 mode names + p unused, p=pad(b) +└─── + +┌─── + RRSetCrtcTransform + 1 CARD8 major opcode + 1 26 RandR opcode + 2 12+(n+p)/4+v length + 4 CRTC crtc + 36 TRANSFORM transform + 2 CARD16 filter length + 2 unused + n STRING8 filter name + p unused, p=pad(n) + 4v FIXED filter params +└─── + +┌─── + RRGetCrtcTransform + 1 CARD8 major opcode + 1 27 RandR opcode + 2 2 length + 4 CRTC crtc + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 16+(pn+pnp)/4+(cn+cnp)/4+pf+cf reply length + 36 TRANSFORM pending transform + 1 BOOL has transforms + 3 unused + 36 TRANSFORM current transform + 4 unused + 2 pn pending filter name length + 2 pf pending filter num params + 2 cn current filter name length + 2 cf current filter num params + pn STRING8 pending filter name + pnp unused, pnp=pad(pn) + 4*pf FIXED pending filter params + cn STRING8 current filter name + cnp unused, cnp=pad(cn) + 4*cf FIXED current filter params +└─── + +┌─── + RRGetPanning + 1 CARD8 major opcode + 1 28 RandR opcode + 2 2 length + 4 CRTC crtc + ▶ + 1 1 Reply + 1 RRCONFIGSTATUS status + 2 CARD16 sequence number + 4 1 reply length + 4 TIMESTAMP timestamp + 2 CARD16 left + 2 CARD16 top + 2 CARD16 width + 2 CARD16 height + 2 CARD16 track_left + 2 CARD16 track_top + 2 CARD16 track_width + 2 CARD16 track_height + 2 INT16 border_left + 2 INT16 border_top + 2 INT16 border_right + 2 INT16 border_bottom +└─── +┌─── + RRSetPanning + 1 CARD8 major opcode + 1 29 RandR opcode + 2 9 length + 4 CRTC crtc + 4 TIMESTAMP timestamp + 2 CARD16 left + 2 CARD16 top + 2 CARD16 width + 2 CARD16 height + 2 CARD16 track_left + 2 CARD16 track_top + 2 CARD16 track_width + 2 CARD16 track_height + 2 INT16 border_left + 2 INT16 border_top + 2 INT16 border_right + 2 INT16 border_bottom + ▶ + 1 1 Reply + 1 RRCONFIGSTATUS status + 2 CARD16 sequence number + 4 0 reply length + 4 TIMESTAMP new timestamp + 20 unused +└─── + +┌─── + RRSetOutputPrimary + 1 CARD8 major opcode + 1 30 RandR opcode + 2 3 length + 4 WINDOW window + 4 OUTPUT output +└─── + +┌─── + RRGetOutputPrimary + 1 CARD8 major opcode + 1 31 RandR opcode + 2 2 length + 4 WINDOW window + ▶ + 1 1 Reply + 1 unused + 2 CARD16 sequence number + 4 CARD32 length + 4 OUTPUT output + 4 CARD32 pad1 + 4 CARD32 pad2 + 4 CARD32 pad3 + 4 CARD32 pad4 +└─── + +A.3 Protocol Events + +┌─── + 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 +└─── + +A.3.1 Protocol Events added with version 1.2 + +┌─── + RRCrtcChangeNotify + 1 Base + 1 code + 1 0 sub-code + 2 CARD16 sequence number + 4 TIMESTAMP timestamp + 4 WINDOW request window + 4 CRTC crtc affected + 4 MODE mode in use + 2 ROTATION new rotation and reflection + 2 unused + 2 INT16 x + 2 INT16 y + 2 CARD16 width + 2 CARD16 height +└─── +┌─── + RROutputChangeNotify + 1 Base + 1 code + 1 1 sub-code + 2 CARD16 sequence number + 4 TIMESTAMP timestamp + 4 TIMESTAMP configuration timestamp + 4 WINDOW request window + 4 OUTPUT output affected + 4 CRTC crtc in use + 4 MODE mode in use + 2 ROTATION rotation in use + 1 CONNECTION connection status + 1 SUBPIXELORDER subpixel order +└─── +┌─── + RROutputPropertyNotify + 1 Base + 1 code + 1 2 sub-code + 2 CARD16 sequence number + 4 WINDOW window + 4 OUTPUT output + 4 ATOM atom + 4 TIMESTAMP time + 1 state + 0 NewValue + 1 Deleted + 11 unused +└─── + +A.4 Protocol Errors + +┌─── + ERRORS + Base + 0 Output + Base + 1 Crtc + Base + 2 Mode +└─── + +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, + http://cgit.freedesktop.org/xorg/proto/renderproto/tree/renderproto.txt diff --git a/mesalib/src/gallium/auxiliary/util/u_format.c b/mesalib/src/gallium/auxiliary/util/u_format.c index 91485b05c..34922ab18 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.c +++ b/mesalib/src/gallium/auxiliary/util/u_format.c @@ -1,392 +1,442 @@ -/************************************************************************** - * - * Copyright 2010 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * @file - * Pixel format accessor functions. - * - * @author Jose Fonseca - */ - -#include "u_math.h" -#include "u_memory.h" -#include "u_rect.h" -#include "u_format.h" -#include "u_format_s3tc.h" - -#include "pipe/p_defines.h" - - -boolean -util_format_is_float(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - unsigned i; - - assert(desc); - if (!desc) { - return FALSE; - } - - /* Find the first non-void channel. */ - for (i = 0; i < 4; i++) { - if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { - break; - } - } - - if (i == 4) { - return FALSE; - } - - return desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT ? TRUE : FALSE; -} - - -boolean -util_format_is_supported(enum pipe_format format, unsigned bind) -{ - if (util_format_is_s3tc(format) && !util_format_s3tc_enabled) { - return FALSE; - } - -#ifndef TEXTURE_FLOAT_ENABLED - if ((bind & PIPE_BIND_RENDER_TARGET) && - format != PIPE_FORMAT_R9G9B9E5_FLOAT && - format != PIPE_FORMAT_R11G11B10_FLOAT && - util_format_is_float(format)) { - return FALSE; - } -#endif - - return TRUE; -} - - -void -util_format_read_4f(enum pipe_format format, - float *dst, unsigned dst_stride, - const void *src, unsigned src_stride, - unsigned x, unsigned y, unsigned w, unsigned h) -{ - const struct util_format_description *format_desc; - const uint8_t *src_row; - float *dst_row; - - format_desc = util_format_description(format); - - assert(x % format_desc->block.width == 0); - assert(y % format_desc->block.height == 0); - - src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8); - dst_row = dst; - - format_desc->unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h); -} - - -void -util_format_write_4f(enum pipe_format format, - const float *src, unsigned src_stride, - void *dst, unsigned dst_stride, - unsigned x, unsigned y, unsigned w, unsigned h) -{ - const struct util_format_description *format_desc; - uint8_t *dst_row; - const float *src_row; - - format_desc = util_format_description(format); - - assert(x % format_desc->block.width == 0); - assert(y % format_desc->block.height == 0); - - dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8); - src_row = src; - - format_desc->pack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h); -} - - -void -util_format_read_4ub(enum pipe_format format, uint8_t *dst, unsigned dst_stride, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h) -{ - const struct util_format_description *format_desc; - const uint8_t *src_row; - uint8_t *dst_row; - - format_desc = util_format_description(format); - - assert(x % format_desc->block.width == 0); - assert(y % format_desc->block.height == 0); - - src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8); - dst_row = dst; - - format_desc->unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h); -} - - -void -util_format_write_4ub(enum pipe_format format, const uint8_t *src, unsigned src_stride, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h) -{ - const struct util_format_description *format_desc; - uint8_t *dst_row; - const uint8_t *src_row; - - format_desc = util_format_description(format); - - assert(x % format_desc->block.width == 0); - assert(y % format_desc->block.height == 0); - - dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8); - src_row = src; - - format_desc->pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h); -} - - -boolean -util_is_format_compatible(const struct util_format_description *src_desc, - const struct util_format_description *dst_desc) -{ - unsigned chan; - - if (src_desc->format == dst_desc->format) { - return TRUE; - } - - if (src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN || - dst_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { - return FALSE; - } - - if (src_desc->block.bits != dst_desc->block.bits || - src_desc->nr_channels != dst_desc->nr_channels || - src_desc->colorspace != dst_desc->colorspace) { - return FALSE; - } - - for (chan = 0; chan < 4; ++chan) { - if (src_desc->channel[chan].size != - dst_desc->channel[chan].size) { - return FALSE; - } - } - - for (chan = 0; chan < 4; ++chan) { - enum util_format_swizzle swizzle = dst_desc->swizzle[chan]; - - if (swizzle < 4) { - if (src_desc->swizzle[chan] != swizzle) { - return FALSE; - } - if ((src_desc->channel[swizzle].type != - dst_desc->channel[swizzle].type) || - (src_desc->channel[swizzle].normalized != - dst_desc->channel[swizzle].normalized)) { - return FALSE; - } - } - } - - return TRUE; -} - - -boolean -util_format_fits_8unorm(const struct util_format_description *format_desc) -{ - unsigned chan; - - /* - * After linearized sRGB values require more than 8bits. - */ - - if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { - return FALSE; - } - - switch (format_desc->layout) { - - case UTIL_FORMAT_LAYOUT_S3TC: - case UTIL_FORMAT_LAYOUT_RGTC: - /* - * These are straight forward. - */ - - return TRUE; - - case UTIL_FORMAT_LAYOUT_PLAIN: - /* - * For these we can find a generic rule. - */ - - for (chan = 0; chan < format_desc->nr_channels; ++chan) { - switch (format_desc->channel[chan].type) { - case UTIL_FORMAT_TYPE_VOID: - break; - case UTIL_FORMAT_TYPE_UNSIGNED: - if (!format_desc->channel[chan].normalized || - format_desc->channel[chan].size > 8) { - return FALSE; - } - break; - default: - return FALSE; - } - } - return TRUE; - - default: - /* - * Handle all others on a case by case basis. - */ - - switch (format_desc->format) { - case PIPE_FORMAT_R1_UNORM: - case PIPE_FORMAT_UYVY: - case PIPE_FORMAT_YUYV: - case PIPE_FORMAT_R8G8_B8G8_UNORM: - case PIPE_FORMAT_G8R8_G8B8_UNORM: - return TRUE; - - default: - return FALSE; - } - } -} - - -void -util_format_translate(enum pipe_format dst_format, - void *dst, unsigned dst_stride, - unsigned dst_x, unsigned dst_y, - enum pipe_format src_format, - const void *src, unsigned src_stride, - unsigned src_x, unsigned src_y, - unsigned width, unsigned height) -{ - const struct util_format_description *dst_format_desc; - const struct util_format_description *src_format_desc; - uint8_t *dst_row; - const uint8_t *src_row; - unsigned x_step, y_step; - unsigned dst_step; - unsigned src_step; - - dst_format_desc = util_format_description(dst_format); - src_format_desc = util_format_description(src_format); - - if (util_is_format_compatible(src_format_desc, dst_format_desc)) { - /* - * Trivial case. - */ - - util_copy_rect(dst, dst_format, dst_stride, dst_x, dst_y, - width, height, src, (int)src_stride, - src_x, src_y); - return; - } - - assert(dst_x % dst_format_desc->block.width == 0); - assert(dst_y % dst_format_desc->block.height == 0); - assert(src_x % src_format_desc->block.width == 0); - assert(src_y % src_format_desc->block.height == 0); - - dst_row = (uint8_t *)dst + dst_y*dst_stride + dst_x*(dst_format_desc->block.bits/8); - src_row = (const uint8_t *)src + src_y*src_stride + src_x*(src_format_desc->block.bits/8); - - /* - * This works because all pixel formats have pixel blocks with power of two - * sizes. - */ - - y_step = MAX2(dst_format_desc->block.height, src_format_desc->block.height); - x_step = MAX2(dst_format_desc->block.width, src_format_desc->block.width); - assert(y_step % dst_format_desc->block.height == 0); - assert(y_step % src_format_desc->block.height == 0); - - dst_step = y_step / dst_format_desc->block.height * dst_stride; - src_step = y_step / src_format_desc->block.height * src_stride; - - /* - * TODO: double formats will loose precision - * TODO: Add a special case for formats that are mere swizzles of each other - */ - - if (util_format_fits_8unorm(src_format_desc) || - util_format_fits_8unorm(dst_format_desc)) { - unsigned tmp_stride; - uint8_t *tmp_row; - - tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row; - tmp_row = MALLOC(y_step * tmp_stride); - if (!tmp_row) - return; - - while (height >= y_step) { - src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, y_step); - dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step); - - dst_row += dst_step; - src_row += src_step; - height -= y_step; - } - - if (height) { - src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, height); - dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, height); - } - - FREE(tmp_row); - } - else { - unsigned tmp_stride; - float *tmp_row; - - tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row; - tmp_row = MALLOC(y_step * tmp_stride); - if (!tmp_row) - return; - - while (height >= y_step) { - src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, y_step); - dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step); - - dst_row += dst_step; - src_row += src_step; - height -= y_step; - } - - if (height) { - src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, height); - dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, height); - } - - FREE(tmp_row); - } -} +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Pixel format accessor functions. + * + * @author Jose Fonseca + */ + +#include "u_math.h" +#include "u_memory.h" +#include "u_rect.h" +#include "u_format.h" +#include "u_format_s3tc.h" + +#include "pipe/p_defines.h" + + +boolean +util_format_is_float(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + unsigned i; + + assert(desc); + if (!desc) { + return FALSE; + } + + /* Find the first non-void channel. */ + for (i = 0; i < 4; i++) { + if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { + break; + } + } + + if (i == 4) { + return FALSE; + } + + return desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT ? TRUE : FALSE; +} + + +boolean +util_format_is_supported(enum pipe_format format, unsigned bind) +{ + if (util_format_is_s3tc(format) && !util_format_s3tc_enabled) { + return FALSE; + } + +#ifndef TEXTURE_FLOAT_ENABLED + if ((bind & PIPE_BIND_RENDER_TARGET) && + format != PIPE_FORMAT_R9G9B9E5_FLOAT && + format != PIPE_FORMAT_R11G11B10_FLOAT && + util_format_is_float(format)) { + return FALSE; + } +#endif + + return TRUE; +} + + +void +util_format_read_4f(enum pipe_format format, + float *dst, unsigned dst_stride, + const void *src, unsigned src_stride, + unsigned x, unsigned y, unsigned w, unsigned h) +{ + const struct util_format_description *format_desc; + const uint8_t *src_row; + float *dst_row; + + format_desc = util_format_description(format); + + assert(x % format_desc->block.width == 0); + assert(y % format_desc->block.height == 0); + + src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8); + dst_row = dst; + + format_desc->unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h); +} + + +void +util_format_write_4f(enum pipe_format format, + const float *src, unsigned src_stride, + void *dst, unsigned dst_stride, + unsigned x, unsigned y, unsigned w, unsigned h) +{ + const struct util_format_description *format_desc; + uint8_t *dst_row; + const float *src_row; + + format_desc = util_format_description(format); + + assert(x % format_desc->block.width == 0); + assert(y % format_desc->block.height == 0); + + dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8); + src_row = src; + + format_desc->pack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h); +} + + +void +util_format_read_4ub(enum pipe_format format, uint8_t *dst, unsigned dst_stride, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h) +{ + const struct util_format_description *format_desc; + const uint8_t *src_row; + uint8_t *dst_row; + + format_desc = util_format_description(format); + + assert(x % format_desc->block.width == 0); + assert(y % format_desc->block.height == 0); + + src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8); + dst_row = dst; + + format_desc->unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h); +} + + +void +util_format_write_4ub(enum pipe_format format, const uint8_t *src, unsigned src_stride, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h) +{ + const struct util_format_description *format_desc; + uint8_t *dst_row; + const uint8_t *src_row; + + format_desc = util_format_description(format); + + assert(x % format_desc->block.width == 0); + assert(y % format_desc->block.height == 0); + + dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8); + src_row = src; + + format_desc->pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h); +} + + +boolean +util_is_format_compatible(const struct util_format_description *src_desc, + const struct util_format_description *dst_desc) +{ + unsigned chan; + + if (src_desc->format == dst_desc->format) { + return TRUE; + } + + if (src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN || + dst_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { + return FALSE; + } + + if (src_desc->block.bits != dst_desc->block.bits || + src_desc->nr_channels != dst_desc->nr_channels || + src_desc->colorspace != dst_desc->colorspace) { + return FALSE; + } + + for (chan = 0; chan < 4; ++chan) { + if (src_desc->channel[chan].size != + dst_desc->channel[chan].size) { + return FALSE; + } + } + + for (chan = 0; chan < 4; ++chan) { + enum util_format_swizzle swizzle = dst_desc->swizzle[chan]; + + if (swizzle < 4) { + if (src_desc->swizzle[chan] != swizzle) { + return FALSE; + } + if ((src_desc->channel[swizzle].type != + dst_desc->channel[swizzle].type) || + (src_desc->channel[swizzle].normalized != + dst_desc->channel[swizzle].normalized)) { + return FALSE; + } + } + } + + return TRUE; +} + + +boolean +util_format_fits_8unorm(const struct util_format_description *format_desc) +{ + unsigned chan; + + /* + * After linearized sRGB values require more than 8bits. + */ + + if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { + return FALSE; + } + + switch (format_desc->layout) { + + case UTIL_FORMAT_LAYOUT_S3TC: + case UTIL_FORMAT_LAYOUT_RGTC: + /* + * These are straight forward. + */ + + return TRUE; + + case UTIL_FORMAT_LAYOUT_PLAIN: + /* + * For these we can find a generic rule. + */ + + for (chan = 0; chan < format_desc->nr_channels; ++chan) { + switch (format_desc->channel[chan].type) { + case UTIL_FORMAT_TYPE_VOID: + break; + case UTIL_FORMAT_TYPE_UNSIGNED: + if (!format_desc->channel[chan].normalized || + format_desc->channel[chan].size > 8) { + return FALSE; + } + break; + default: + return FALSE; + } + } + return TRUE; + + default: + /* + * Handle all others on a case by case basis. + */ + + switch (format_desc->format) { + case PIPE_FORMAT_R1_UNORM: + case PIPE_FORMAT_UYVY: + case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_R8G8_B8G8_UNORM: + case PIPE_FORMAT_G8R8_G8B8_UNORM: + return TRUE; + + default: + return FALSE; + } + } +} + + +void +util_format_translate(enum pipe_format dst_format, + void *dst, unsigned dst_stride, + unsigned dst_x, unsigned dst_y, + enum pipe_format src_format, + const void *src, unsigned src_stride, + unsigned src_x, unsigned src_y, + unsigned width, unsigned height) +{ + const struct util_format_description *dst_format_desc; + const struct util_format_description *src_format_desc; + uint8_t *dst_row; + const uint8_t *src_row; + unsigned x_step, y_step; + unsigned dst_step; + unsigned src_step; + + dst_format_desc = util_format_description(dst_format); + src_format_desc = util_format_description(src_format); + + if (util_is_format_compatible(src_format_desc, dst_format_desc)) { + /* + * Trivial case. + */ + + util_copy_rect(dst, dst_format, dst_stride, dst_x, dst_y, + width, height, src, (int)src_stride, + src_x, src_y); + return; + } + + assert(dst_x % dst_format_desc->block.width == 0); + assert(dst_y % dst_format_desc->block.height == 0); + assert(src_x % src_format_desc->block.width == 0); + assert(src_y % src_format_desc->block.height == 0); + + dst_row = (uint8_t *)dst + dst_y*dst_stride + dst_x*(dst_format_desc->block.bits/8); + src_row = (const uint8_t *)src + src_y*src_stride + src_x*(src_format_desc->block.bits/8); + + /* + * This works because all pixel formats have pixel blocks with power of two + * sizes. + */ + + y_step = MAX2(dst_format_desc->block.height, src_format_desc->block.height); + x_step = MAX2(dst_format_desc->block.width, src_format_desc->block.width); + assert(y_step % dst_format_desc->block.height == 0); + assert(y_step % src_format_desc->block.height == 0); + + dst_step = y_step / dst_format_desc->block.height * dst_stride; + src_step = y_step / src_format_desc->block.height * src_stride; + + /* + * TODO: double formats will loose precision + * TODO: Add a special case for formats that are mere swizzles of each other + */ + + if (util_format_fits_8unorm(src_format_desc) || + util_format_fits_8unorm(dst_format_desc)) { + unsigned tmp_stride; + uint8_t *tmp_row; + + tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row; + tmp_row = MALLOC(y_step * tmp_stride); + if (!tmp_row) + return; + + while (height >= y_step) { + src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, y_step); + dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step); + + dst_row += dst_step; + src_row += src_step; + height -= y_step; + } + + if (height) { + src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, height); + dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, height); + } + + FREE(tmp_row); + } + else { + unsigned tmp_stride; + float *tmp_row; + + tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row; + tmp_row = MALLOC(y_step * tmp_stride); + if (!tmp_row) + return; + + while (height >= y_step) { + src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, y_step); + dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step); + + dst_row += dst_step; + src_row += src_step; + height -= y_step; + } + + if (height) { + src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, height); + dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, height); + } + + FREE(tmp_row); + } +} + +void util_format_compose_swizzles(const unsigned char swz1[4], + const unsigned char swz2[4], + unsigned char dst[4]) +{ + unsigned i; + + for (i = 0; i < 4; i++) { + dst[i] = swz2[i] <= UTIL_FORMAT_SWIZZLE_W ? + swz1[swz2[i]] : swz2[i]; + } +} + +void util_format_swizzle_4f(float *dst, const float *src, + const unsigned char swz[4]) +{ + unsigned i; + + for (i = 0; i < 4; i++) { + if (swz[i] <= UTIL_FORMAT_SWIZZLE_W) + dst[i] = src[swz[i]]; + else if (swz[i] == UTIL_FORMAT_SWIZZLE_0) + dst[i] = 0; + else if (swz[i] == UTIL_FORMAT_SWIZZLE_1) + dst[i] = 1; + } +} + +void util_format_unswizzle_4f(float *dst, const float *src, + const unsigned char swz[4]) +{ + unsigned i; + + for (i = 0; i < 4; i++) { + switch (swz[i]) { + case UTIL_FORMAT_SWIZZLE_X: + dst[0] = src[i]; + break; + case UTIL_FORMAT_SWIZZLE_Y: + dst[1] = src[i]; + break; + case UTIL_FORMAT_SWIZZLE_Z: + dst[2] = src[i]; + break; + case UTIL_FORMAT_SWIZZLE_W: + dst[3] = src[i]; + break; + } + } +} diff --git a/mesalib/src/gallium/auxiliary/util/u_format.h b/mesalib/src/gallium/auxiliary/util/u_format.h index 6e9b6902e..566fa79e7 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.h +++ b/mesalib/src/gallium/auxiliary/util/u_format.h @@ -1,822 +1,841 @@ -/************************************************************************** - * - * Copyright 2009-2010 Vmware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef U_FORMAT_H -#define U_FORMAT_H - - -#include "pipe/p_format.h" -#include "util/u_debug.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * Describe how to pack/unpack pixels into/from the prescribed format. - * - * XXX: This could be renamed to something like util_format_pack, or broke down - * in flags inside util_format_block that said exactly what we want. - */ -enum util_format_layout { - /** - * Formats with util_format_block::width == util_format_block::height == 1 - * that can be described as an ordinary data structure. - */ - UTIL_FORMAT_LAYOUT_PLAIN = 0, - - /** - * Formats with sub-sampled channels. - * - * This is for formats like YV12 where there is less than one sample per - * pixel. - */ - UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3, - - /** - * S3 Texture Compression formats. - */ - UTIL_FORMAT_LAYOUT_S3TC = 4, - - /** - * Red-Green Texture Compression formats. - */ - UTIL_FORMAT_LAYOUT_RGTC = 5, - - /** - * Everything else that doesn't fit in any of the above layouts. - */ - UTIL_FORMAT_LAYOUT_OTHER = 6 -}; - - -struct util_format_block -{ - /** Block width in pixels */ - unsigned width; - - /** Block height in pixels */ - unsigned height; - - /** Block size in bits */ - unsigned bits; -}; - - -enum util_format_type { - UTIL_FORMAT_TYPE_VOID = 0, - UTIL_FORMAT_TYPE_UNSIGNED = 1, - UTIL_FORMAT_TYPE_SIGNED = 2, - UTIL_FORMAT_TYPE_FIXED = 3, - UTIL_FORMAT_TYPE_FLOAT = 4 -}; - - -enum util_format_swizzle { - UTIL_FORMAT_SWIZZLE_X = 0, - UTIL_FORMAT_SWIZZLE_Y = 1, - UTIL_FORMAT_SWIZZLE_Z = 2, - UTIL_FORMAT_SWIZZLE_W = 3, - UTIL_FORMAT_SWIZZLE_0 = 4, - UTIL_FORMAT_SWIZZLE_1 = 5, - UTIL_FORMAT_SWIZZLE_NONE = 6 -}; - - -enum util_format_colorspace { - UTIL_FORMAT_COLORSPACE_RGB = 0, - UTIL_FORMAT_COLORSPACE_SRGB = 1, - UTIL_FORMAT_COLORSPACE_YUV = 2, - UTIL_FORMAT_COLORSPACE_ZS = 3 -}; - - -struct util_format_channel_description -{ - unsigned type:6; - unsigned normalized:1; - unsigned size:9; -}; - - -struct util_format_description -{ - enum pipe_format format; - - const char *name; - - /** - * Short name, striped of the prefix, lower case. - */ - const char *short_name; - - /** - * Pixel block dimensions. - */ - struct util_format_block block; - - enum util_format_layout layout; - - /** - * The number of channels. - */ - unsigned nr_channels:3; - - /** - * Whether all channels have the same number of (whole) bytes. - */ - unsigned is_array:1; - - /** - * Whether the pixel format can be described as a bitfield structure. - * - * In particular: - * - pixel depth must be 8, 16, or 32 bits; - * - all channels must be unsigned, signed, or void - */ - unsigned is_bitmask:1; - - /** - * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID). - */ - unsigned is_mixed:1; - - /** - * Input channel description. - * - * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats. - */ - struct util_format_channel_description channel[4]; - - /** - * Output channel swizzle. - * - * The order is either: - * - RGBA - * - YUV(A) - * - ZS - * depending on the colorspace. - */ - unsigned char swizzle[4]; - - /** - * Colorspace transformation. - */ - enum util_format_colorspace colorspace; - - /** - * Unpack pixel blocks to R8G8B8A8_UNORM. - * Note: strides are in bytes. - * - * Only defined for non-depth-stencil formats. - */ - void - (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, - const uint8_t *src, unsigned src_stride, - unsigned width, unsigned height); - - /** - * Pack pixel blocks from R8G8B8A8_UNORM. - * Note: strides are in bytes. - * - * Only defined for non-depth-stencil formats. - */ - void - (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, - const uint8_t *src, unsigned src_stride, - unsigned width, unsigned height); - - /** - * Fetch a single pixel (i, j) from a block. - * - * XXX: Only defined for a very few select formats. - */ - void - (*fetch_rgba_8unorm)(uint8_t *dst, - const uint8_t *src, - unsigned i, unsigned j); - - /** - * Unpack pixel blocks to R32G32B32A32_FLOAT. - * Note: strides are in bytes. - * - * Only defined for non-depth-stencil formats. - */ - void - (*unpack_rgba_float)(float *dst, unsigned dst_stride, - const uint8_t *src, unsigned src_stride, - unsigned width, unsigned height); - - /** - * Pack pixel blocks from R32G32B32A32_FLOAT. - * Note: strides are in bytes. - * - * Only defined for non-depth-stencil formats. - */ - void - (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride, - const float *src, unsigned src_stride, - unsigned width, unsigned height); - - /** - * Fetch a single pixel (i, j) from a block. - * - * Only defined for non-depth-stencil formats. - */ - void - (*fetch_rgba_float)(float *dst, - const uint8_t *src, - unsigned i, unsigned j); - - /** - * Unpack pixels to Z32_UNORM. - * Note: strides are in bytes. - * - * Only defined for depth formats. - */ - void - (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride, - const uint8_t *src, unsigned src_stride, - unsigned width, unsigned height); - - /** - * Pack pixels from Z32_FLOAT. - * Note: strides are in bytes. - * - * Only defined for depth formats. - */ - void - (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride, - const uint32_t *src, unsigned src_stride, - unsigned width, unsigned height); - - /** - * Unpack pixels to Z32_FLOAT. - * Note: strides are in bytes. - * - * Only defined for depth formats. - */ - void - (*unpack_z_float)(float *dst, unsigned dst_stride, - const uint8_t *src, unsigned src_stride, - unsigned width, unsigned height); - - /** - * Pack pixels from Z32_FLOAT. - * Note: strides are in bytes. - * - * Only defined for depth formats. - */ - void - (*pack_z_float)(uint8_t *dst, unsigned dst_stride, - const float *src, unsigned src_stride, - unsigned width, unsigned height); - - /** - * Unpack pixels to S8_USCALED. - * Note: strides are in bytes. - * - * Only defined for stencil formats. - */ - void - (*unpack_s_8uscaled)(uint8_t *dst, unsigned dst_stride, - const uint8_t *src, unsigned src_stride, - unsigned width, unsigned height); - - /** - * Pack pixels from S8_USCALED. - * Note: strides are in bytes. - * - * Only defined for stencil formats. - */ - void - (*pack_s_8uscaled)(uint8_t *dst, unsigned dst_stride, - const uint8_t *src, unsigned src_stride, - unsigned width, unsigned height); - -}; - - -extern const struct util_format_description -util_format_description_table[]; - - -const struct util_format_description * -util_format_description(enum pipe_format format); - - -/* - * Format query functions. - */ - -static INLINE const char * -util_format_name(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - if (!desc) { - return "PIPE_FORMAT_???"; - } - - return desc->name; -} - -static INLINE const char * -util_format_short_name(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - if (!desc) { - return "???"; - } - - return desc->short_name; -} - -/** - * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info. - */ -static INLINE boolean -util_format_is_plain(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - if (!format) { - return FALSE; - } - - return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE; -} - -static INLINE boolean -util_format_is_compressed(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - if (!desc) { - return FALSE; - } - - switch (desc->layout) { - case UTIL_FORMAT_LAYOUT_S3TC: - case UTIL_FORMAT_LAYOUT_RGTC: - /* XXX add other formats in the future */ - return TRUE; - default: - return FALSE; - } -} - -static INLINE boolean -util_format_is_s3tc(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - if (!desc) { - return FALSE; - } - - return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE; -} - -static INLINE boolean -util_format_is_depth_or_stencil(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - if (!desc) { - return FALSE; - } - - return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE; -} - -static INLINE boolean -util_format_is_depth_and_stencil(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - if (!desc) { - return FALSE; - } - - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { - return FALSE; - } - - return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE && - desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE; -} - - -/** - * Give the RGBA colormask of the channels that can be represented in this - * format. - * - * That is, the channels whose values are preserved. - */ -static INLINE unsigned -util_format_colormask(const struct util_format_description *desc) -{ - unsigned colormask; - unsigned chan; - - switch (desc->colorspace) { - case UTIL_FORMAT_COLORSPACE_RGB: - case UTIL_FORMAT_COLORSPACE_SRGB: - case UTIL_FORMAT_COLORSPACE_YUV: - colormask = 0; - for (chan = 0; chan < 4; ++chan) { - if (desc->swizzle[chan] < 4) { - colormask |= (1 << chan); - } - } - return colormask; - case UTIL_FORMAT_COLORSPACE_ZS: - return 0; - default: - assert(0); - return 0; - } -} - - -boolean -util_format_is_float(enum pipe_format format); - - -/** - * Whether the src format can be blitted to destation format with a simple - * memcpy. - */ -boolean -util_is_format_compatible(const struct util_format_description *src_desc, - const struct util_format_description *dst_desc); - -/** - * Whether the format is supported by Gallium for the given bindings. - * This covers S3TC textures and floating-point render targets. - */ -boolean -util_format_is_supported(enum pipe_format format, unsigned bind); - -/** - * Whether this format is a rgab8 variant. - * - * That is, any format that matches the - * - * PIPE_FORMAT_?8?8?8?8_UNORM - */ -static INLINE boolean -util_format_is_rgba8_variant(const struct util_format_description *desc) -{ - unsigned chan; - - if(desc->block.width != 1 || - desc->block.height != 1 || - desc->block.bits != 32) - return FALSE; - - for(chan = 0; chan < 4; ++chan) { - if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED && - desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID) - return FALSE; - if(desc->channel[chan].size != 8) - return FALSE; - } - - return TRUE; -} - - -/** - * Return total bits needed for the pixel format per block. - */ -static INLINE uint -util_format_get_blocksizebits(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - if (!desc) { - return 0; - } - - return desc->block.bits; -} - -/** - * Return bytes per block (not pixel) for the given format. - */ -static INLINE uint -util_format_get_blocksize(enum pipe_format format) -{ - uint bits = util_format_get_blocksizebits(format); - - assert(bits % 8 == 0); - - return bits / 8; -} - -static INLINE uint -util_format_get_blockwidth(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - if (!desc) { - return 1; - } - - return desc->block.width; -} - -static INLINE uint -util_format_get_blockheight(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - if (!desc) { - return 1; - } - - return desc->block.height; -} - -static INLINE unsigned -util_format_get_nblocksx(enum pipe_format format, - unsigned x) -{ - unsigned blockwidth = util_format_get_blockwidth(format); - return (x + blockwidth - 1) / blockwidth; -} - -static INLINE unsigned -util_format_get_nblocksy(enum pipe_format format, - unsigned y) -{ - unsigned blockheight = util_format_get_blockheight(format); - return (y + blockheight - 1) / blockheight; -} - -static INLINE unsigned -util_format_get_nblocks(enum pipe_format format, - unsigned width, - unsigned height) -{ - return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height); -} - -static INLINE size_t -util_format_get_stride(enum pipe_format format, - unsigned width) -{ - return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format); -} - -static INLINE size_t -util_format_get_2d_size(enum pipe_format format, - size_t stride, - unsigned height) -{ - return util_format_get_nblocksy(format, height) * stride; -} - -static INLINE uint -util_format_get_component_bits(enum pipe_format format, - enum util_format_colorspace colorspace, - uint component) -{ - const struct util_format_description *desc = util_format_description(format); - enum util_format_colorspace desc_colorspace; - - assert(format); - if (!format) { - return 0; - } - - assert(component < 4); - - /* Treat RGB and SRGB as equivalent. */ - if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { - colorspace = UTIL_FORMAT_COLORSPACE_RGB; - } - if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { - desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB; - } else { - desc_colorspace = desc->colorspace; - } - - if (desc_colorspace != colorspace) { - return 0; - } - - switch (desc->swizzle[component]) { - case UTIL_FORMAT_SWIZZLE_X: - return desc->channel[0].size; - case UTIL_FORMAT_SWIZZLE_Y: - return desc->channel[1].size; - case UTIL_FORMAT_SWIZZLE_Z: - return desc->channel[2].size; - case UTIL_FORMAT_SWIZZLE_W: - return desc->channel[3].size; - default: - return 0; - } -} - -static INLINE boolean -util_format_has_alpha(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(format); - if (!format) { - return FALSE; - } - - switch (desc->colorspace) { - case UTIL_FORMAT_COLORSPACE_RGB: - case UTIL_FORMAT_COLORSPACE_SRGB: - return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1; - case UTIL_FORMAT_COLORSPACE_YUV: - return FALSE; - case UTIL_FORMAT_COLORSPACE_ZS: - return FALSE; - default: - assert(0); - return FALSE; - } -} - -/** - * Given a linear RGB colorspace format, return the corresponding SRGB - * format, or PIPE_FORMAT_NONE if none. - */ -static INLINE enum pipe_format -util_format_srgb(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_L8_UNORM: - return PIPE_FORMAT_L8_SRGB; - case PIPE_FORMAT_L8A8_UNORM: - return PIPE_FORMAT_L8A8_SRGB; - case PIPE_FORMAT_R8G8B8_UNORM: - return PIPE_FORMAT_R8G8B8_SRGB; - case PIPE_FORMAT_A8B8G8R8_UNORM: - return PIPE_FORMAT_A8B8G8R8_SRGB; - case PIPE_FORMAT_X8B8G8R8_UNORM: - return PIPE_FORMAT_X8B8G8R8_SRGB; - case PIPE_FORMAT_B8G8R8A8_UNORM: - return PIPE_FORMAT_B8G8R8A8_SRGB; - case PIPE_FORMAT_B8G8R8X8_UNORM: - return PIPE_FORMAT_B8G8R8X8_SRGB; - case PIPE_FORMAT_A8R8G8B8_UNORM: - return PIPE_FORMAT_A8R8G8B8_SRGB; - case PIPE_FORMAT_X8R8G8B8_UNORM: - return PIPE_FORMAT_X8R8G8B8_SRGB; - case PIPE_FORMAT_DXT1_RGB: - return PIPE_FORMAT_DXT1_SRGB; - case PIPE_FORMAT_DXT1_RGBA: - return PIPE_FORMAT_DXT1_SRGBA; - case PIPE_FORMAT_DXT3_RGBA: - return PIPE_FORMAT_DXT3_SRGBA; - case PIPE_FORMAT_DXT5_RGBA: - return PIPE_FORMAT_DXT5_SRGBA; - default: - return PIPE_FORMAT_NONE; - } -} - -/** - * Given an sRGB format, return the corresponding linear colorspace format. - * For non sRGB formats, return the format unchanged. - */ -static INLINE enum pipe_format -util_format_linear(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_L8_SRGB: - return PIPE_FORMAT_L8_UNORM; - case PIPE_FORMAT_L8A8_SRGB: - return PIPE_FORMAT_L8A8_UNORM; - case PIPE_FORMAT_R8G8B8_SRGB: - return PIPE_FORMAT_R8G8B8_UNORM; - case PIPE_FORMAT_A8B8G8R8_SRGB: - return PIPE_FORMAT_A8B8G8R8_UNORM; - case PIPE_FORMAT_X8B8G8R8_SRGB: - return PIPE_FORMAT_X8B8G8R8_UNORM; - case PIPE_FORMAT_B8G8R8A8_SRGB: - return PIPE_FORMAT_B8G8R8A8_UNORM; - case PIPE_FORMAT_B8G8R8X8_SRGB: - return PIPE_FORMAT_B8G8R8X8_UNORM; - case PIPE_FORMAT_A8R8G8B8_SRGB: - return PIPE_FORMAT_A8R8G8B8_UNORM; - case PIPE_FORMAT_X8R8G8B8_SRGB: - return PIPE_FORMAT_X8R8G8B8_UNORM; - case PIPE_FORMAT_DXT1_SRGB: - return PIPE_FORMAT_DXT1_RGB; - case PIPE_FORMAT_DXT1_SRGBA: - return PIPE_FORMAT_DXT1_RGBA; - case PIPE_FORMAT_DXT3_SRGBA: - return PIPE_FORMAT_DXT3_RGBA; - case PIPE_FORMAT_DXT5_SRGBA: - return PIPE_FORMAT_DXT5_RGBA; - default: - return format; - } -} - -/** - * Return the number of components stored. - * Formats with block size != 1x1 will always have 1 component (the block). - */ -static INLINE unsigned -util_format_get_nr_components(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - return desc->nr_channels; -} - -/* - * Format access functions. - */ - -void -util_format_read_4f(enum pipe_format format, - float *dst, unsigned dst_stride, - const void *src, unsigned src_stride, - unsigned x, unsigned y, unsigned w, unsigned h); - -void -util_format_write_4f(enum pipe_format format, - const float *src, unsigned src_stride, - void *dst, unsigned dst_stride, - unsigned x, unsigned y, unsigned w, unsigned h); - -void -util_format_read_4ub(enum pipe_format format, - uint8_t *dst, unsigned dst_stride, - const void *src, unsigned src_stride, - unsigned x, unsigned y, unsigned w, unsigned h); - -void -util_format_write_4ub(enum pipe_format format, - const uint8_t *src, unsigned src_stride, - void *dst, unsigned dst_stride, - unsigned x, unsigned y, unsigned w, unsigned h); - -/* - * Generic format conversion; - */ - -boolean -util_format_fits_8unorm(const struct util_format_description *format_desc); - -void -util_format_translate(enum pipe_format dst_format, - void *dst, unsigned dst_stride, - unsigned dst_x, unsigned dst_y, - enum pipe_format src_format, - const void *src, unsigned src_stride, - unsigned src_x, unsigned src_y, - unsigned width, unsigned height); - -#ifdef __cplusplus -} // extern "C" { -#endif - -#endif /* ! U_FORMAT_H */ +/************************************************************************** + * + * Copyright 2009-2010 Vmware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef U_FORMAT_H +#define U_FORMAT_H + + +#include "pipe/p_format.h" +#include "util/u_debug.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Describe how to pack/unpack pixels into/from the prescribed format. + * + * XXX: This could be renamed to something like util_format_pack, or broke down + * in flags inside util_format_block that said exactly what we want. + */ +enum util_format_layout { + /** + * Formats with util_format_block::width == util_format_block::height == 1 + * that can be described as an ordinary data structure. + */ + UTIL_FORMAT_LAYOUT_PLAIN = 0, + + /** + * Formats with sub-sampled channels. + * + * This is for formats like YV12 where there is less than one sample per + * pixel. + */ + UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3, + + /** + * S3 Texture Compression formats. + */ + UTIL_FORMAT_LAYOUT_S3TC = 4, + + /** + * Red-Green Texture Compression formats. + */ + UTIL_FORMAT_LAYOUT_RGTC = 5, + + /** + * Everything else that doesn't fit in any of the above layouts. + */ + UTIL_FORMAT_LAYOUT_OTHER = 6 +}; + + +struct util_format_block +{ + /** Block width in pixels */ + unsigned width; + + /** Block height in pixels */ + unsigned height; + + /** Block size in bits */ + unsigned bits; +}; + + +enum util_format_type { + UTIL_FORMAT_TYPE_VOID = 0, + UTIL_FORMAT_TYPE_UNSIGNED = 1, + UTIL_FORMAT_TYPE_SIGNED = 2, + UTIL_FORMAT_TYPE_FIXED = 3, + UTIL_FORMAT_TYPE_FLOAT = 4 +}; + + +enum util_format_swizzle { + UTIL_FORMAT_SWIZZLE_X = 0, + UTIL_FORMAT_SWIZZLE_Y = 1, + UTIL_FORMAT_SWIZZLE_Z = 2, + UTIL_FORMAT_SWIZZLE_W = 3, + UTIL_FORMAT_SWIZZLE_0 = 4, + UTIL_FORMAT_SWIZZLE_1 = 5, + UTIL_FORMAT_SWIZZLE_NONE = 6 +}; + + +enum util_format_colorspace { + UTIL_FORMAT_COLORSPACE_RGB = 0, + UTIL_FORMAT_COLORSPACE_SRGB = 1, + UTIL_FORMAT_COLORSPACE_YUV = 2, + UTIL_FORMAT_COLORSPACE_ZS = 3 +}; + + +struct util_format_channel_description +{ + unsigned type:6; + unsigned normalized:1; + unsigned size:9; +}; + + +struct util_format_description +{ + enum pipe_format format; + + const char *name; + + /** + * Short name, striped of the prefix, lower case. + */ + const char *short_name; + + /** + * Pixel block dimensions. + */ + struct util_format_block block; + + enum util_format_layout layout; + + /** + * The number of channels. + */ + unsigned nr_channels:3; + + /** + * Whether all channels have the same number of (whole) bytes. + */ + unsigned is_array:1; + + /** + * Whether the pixel format can be described as a bitfield structure. + * + * In particular: + * - pixel depth must be 8, 16, or 32 bits; + * - all channels must be unsigned, signed, or void + */ + unsigned is_bitmask:1; + + /** + * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID). + */ + unsigned is_mixed:1; + + /** + * Input channel description. + * + * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats. + */ + struct util_format_channel_description channel[4]; + + /** + * Output channel swizzle. + * + * The order is either: + * - RGBA + * - YUV(A) + * - ZS + * depending on the colorspace. + */ + unsigned char swizzle[4]; + + /** + * Colorspace transformation. + */ + enum util_format_colorspace colorspace; + + /** + * Unpack pixel blocks to R8G8B8A8_UNORM. + * Note: strides are in bytes. + * + * Only defined for non-depth-stencil formats. + */ + void + (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Pack pixel blocks from R8G8B8A8_UNORM. + * Note: strides are in bytes. + * + * Only defined for non-depth-stencil formats. + */ + void + (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Fetch a single pixel (i, j) from a block. + * + * XXX: Only defined for a very few select formats. + */ + void + (*fetch_rgba_8unorm)(uint8_t *dst, + const uint8_t *src, + unsigned i, unsigned j); + + /** + * Unpack pixel blocks to R32G32B32A32_FLOAT. + * Note: strides are in bytes. + * + * Only defined for non-depth-stencil formats. + */ + void + (*unpack_rgba_float)(float *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Pack pixel blocks from R32G32B32A32_FLOAT. + * Note: strides are in bytes. + * + * Only defined for non-depth-stencil formats. + */ + void + (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride, + const float *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Fetch a single pixel (i, j) from a block. + * + * Only defined for non-depth-stencil formats. + */ + void + (*fetch_rgba_float)(float *dst, + const uint8_t *src, + unsigned i, unsigned j); + + /** + * Unpack pixels to Z32_UNORM. + * Note: strides are in bytes. + * + * Only defined for depth formats. + */ + void + (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Pack pixels from Z32_FLOAT. + * Note: strides are in bytes. + * + * Only defined for depth formats. + */ + void + (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride, + const uint32_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Unpack pixels to Z32_FLOAT. + * Note: strides are in bytes. + * + * Only defined for depth formats. + */ + void + (*unpack_z_float)(float *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Pack pixels from Z32_FLOAT. + * Note: strides are in bytes. + * + * Only defined for depth formats. + */ + void + (*pack_z_float)(uint8_t *dst, unsigned dst_stride, + const float *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Unpack pixels to S8_USCALED. + * Note: strides are in bytes. + * + * Only defined for stencil formats. + */ + void + (*unpack_s_8uscaled)(uint8_t *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + + /** + * Pack pixels from S8_USCALED. + * Note: strides are in bytes. + * + * Only defined for stencil formats. + */ + void + (*pack_s_8uscaled)(uint8_t *dst, unsigned dst_stride, + const uint8_t *src, unsigned src_stride, + unsigned width, unsigned height); + +}; + + +extern const struct util_format_description +util_format_description_table[]; + + +const struct util_format_description * +util_format_description(enum pipe_format format); + + +/* + * Format query functions. + */ + +static INLINE const char * +util_format_name(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return "PIPE_FORMAT_???"; + } + + return desc->name; +} + +static INLINE const char * +util_format_short_name(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return "???"; + } + + return desc->short_name; +} + +/** + * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info. + */ +static INLINE boolean +util_format_is_plain(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + if (!format) { + return FALSE; + } + + return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE; +} + +static INLINE boolean +util_format_is_compressed(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return FALSE; + } + + switch (desc->layout) { + case UTIL_FORMAT_LAYOUT_S3TC: + case UTIL_FORMAT_LAYOUT_RGTC: + /* XXX add other formats in the future */ + return TRUE; + default: + return FALSE; + } +} + +static INLINE boolean +util_format_is_s3tc(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return FALSE; + } + + return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE; +} + +static INLINE boolean +util_format_is_depth_or_stencil(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return FALSE; + } + + return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE; +} + +static INLINE boolean +util_format_is_depth_and_stencil(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return FALSE; + } + + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { + return FALSE; + } + + return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE && + desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE; +} + + +/** + * Give the RGBA colormask of the channels that can be represented in this + * format. + * + * That is, the channels whose values are preserved. + */ +static INLINE unsigned +util_format_colormask(const struct util_format_description *desc) +{ + unsigned colormask; + unsigned chan; + + switch (desc->colorspace) { + case UTIL_FORMAT_COLORSPACE_RGB: + case UTIL_FORMAT_COLORSPACE_SRGB: + case UTIL_FORMAT_COLORSPACE_YUV: + colormask = 0; + for (chan = 0; chan < 4; ++chan) { + if (desc->swizzle[chan] < 4) { + colormask |= (1 << chan); + } + } + return colormask; + case UTIL_FORMAT_COLORSPACE_ZS: + return 0; + default: + assert(0); + return 0; + } +} + + +boolean +util_format_is_float(enum pipe_format format); + + +/** + * Whether the src format can be blitted to destation format with a simple + * memcpy. + */ +boolean +util_is_format_compatible(const struct util_format_description *src_desc, + const struct util_format_description *dst_desc); + +/** + * Whether the format is supported by Gallium for the given bindings. + * This covers S3TC textures and floating-point render targets. + */ +boolean +util_format_is_supported(enum pipe_format format, unsigned bind); + +/** + * Whether this format is a rgab8 variant. + * + * That is, any format that matches the + * + * PIPE_FORMAT_?8?8?8?8_UNORM + */ +static INLINE boolean +util_format_is_rgba8_variant(const struct util_format_description *desc) +{ + unsigned chan; + + if(desc->block.width != 1 || + desc->block.height != 1 || + desc->block.bits != 32) + return FALSE; + + for(chan = 0; chan < 4; ++chan) { + if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED && + desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID) + return FALSE; + if(desc->channel[chan].size != 8) + return FALSE; + } + + return TRUE; +} + + +/** + * Return total bits needed for the pixel format per block. + */ +static INLINE uint +util_format_get_blocksizebits(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return 0; + } + + return desc->block.bits; +} + +/** + * Return bytes per block (not pixel) for the given format. + */ +static INLINE uint +util_format_get_blocksize(enum pipe_format format) +{ + uint bits = util_format_get_blocksizebits(format); + + assert(bits % 8 == 0); + + return bits / 8; +} + +static INLINE uint +util_format_get_blockwidth(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return 1; + } + + return desc->block.width; +} + +static INLINE uint +util_format_get_blockheight(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (!desc) { + return 1; + } + + return desc->block.height; +} + +static INLINE unsigned +util_format_get_nblocksx(enum pipe_format format, + unsigned x) +{ + unsigned blockwidth = util_format_get_blockwidth(format); + return (x + blockwidth - 1) / blockwidth; +} + +static INLINE unsigned +util_format_get_nblocksy(enum pipe_format format, + unsigned y) +{ + unsigned blockheight = util_format_get_blockheight(format); + return (y + blockheight - 1) / blockheight; +} + +static INLINE unsigned +util_format_get_nblocks(enum pipe_format format, + unsigned width, + unsigned height) +{ + return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height); +} + +static INLINE size_t +util_format_get_stride(enum pipe_format format, + unsigned width) +{ + return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format); +} + +static INLINE size_t +util_format_get_2d_size(enum pipe_format format, + size_t stride, + unsigned height) +{ + return util_format_get_nblocksy(format, height) * stride; +} + +static INLINE uint +util_format_get_component_bits(enum pipe_format format, + enum util_format_colorspace colorspace, + uint component) +{ + const struct util_format_description *desc = util_format_description(format); + enum util_format_colorspace desc_colorspace; + + assert(format); + if (!format) { + return 0; + } + + assert(component < 4); + + /* Treat RGB and SRGB as equivalent. */ + if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { + colorspace = UTIL_FORMAT_COLORSPACE_RGB; + } + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { + desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB; + } else { + desc_colorspace = desc->colorspace; + } + + if (desc_colorspace != colorspace) { + return 0; + } + + switch (desc->swizzle[component]) { + case UTIL_FORMAT_SWIZZLE_X: + return desc->channel[0].size; + case UTIL_FORMAT_SWIZZLE_Y: + return desc->channel[1].size; + case UTIL_FORMAT_SWIZZLE_Z: + return desc->channel[2].size; + case UTIL_FORMAT_SWIZZLE_W: + return desc->channel[3].size; + default: + return 0; + } +} + +static INLINE boolean +util_format_has_alpha(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(format); + if (!format) { + return FALSE; + } + + switch (desc->colorspace) { + case UTIL_FORMAT_COLORSPACE_RGB: + case UTIL_FORMAT_COLORSPACE_SRGB: + return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1; + case UTIL_FORMAT_COLORSPACE_YUV: + return FALSE; + case UTIL_FORMAT_COLORSPACE_ZS: + return FALSE; + default: + assert(0); + return FALSE; + } +} + +/** + * Given a linear RGB colorspace format, return the corresponding SRGB + * format, or PIPE_FORMAT_NONE if none. + */ +static INLINE enum pipe_format +util_format_srgb(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_L8_UNORM: + return PIPE_FORMAT_L8_SRGB; + case PIPE_FORMAT_L8A8_UNORM: + return PIPE_FORMAT_L8A8_SRGB; + case PIPE_FORMAT_R8G8B8_UNORM: + return PIPE_FORMAT_R8G8B8_SRGB; + case PIPE_FORMAT_A8B8G8R8_UNORM: + return PIPE_FORMAT_A8B8G8R8_SRGB; + case PIPE_FORMAT_X8B8G8R8_UNORM: + return PIPE_FORMAT_X8B8G8R8_SRGB; + case PIPE_FORMAT_B8G8R8A8_UNORM: + return PIPE_FORMAT_B8G8R8A8_SRGB; + case PIPE_FORMAT_B8G8R8X8_UNORM: + return PIPE_FORMAT_B8G8R8X8_SRGB; + case PIPE_FORMAT_A8R8G8B8_UNORM: + return PIPE_FORMAT_A8R8G8B8_SRGB; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return PIPE_FORMAT_X8R8G8B8_SRGB; + case PIPE_FORMAT_DXT1_RGB: + return PIPE_FORMAT_DXT1_SRGB; + case PIPE_FORMAT_DXT1_RGBA: + return PIPE_FORMAT_DXT1_SRGBA; + case PIPE_FORMAT_DXT3_RGBA: + return PIPE_FORMAT_DXT3_SRGBA; + case PIPE_FORMAT_DXT5_RGBA: + return PIPE_FORMAT_DXT5_SRGBA; + default: + return PIPE_FORMAT_NONE; + } +} + +/** + * Given an sRGB format, return the corresponding linear colorspace format. + * For non sRGB formats, return the format unchanged. + */ +static INLINE enum pipe_format +util_format_linear(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_L8_SRGB: + return PIPE_FORMAT_L8_UNORM; + case PIPE_FORMAT_L8A8_SRGB: + return PIPE_FORMAT_L8A8_UNORM; + case PIPE_FORMAT_R8G8B8_SRGB: + return PIPE_FORMAT_R8G8B8_UNORM; + case PIPE_FORMAT_A8B8G8R8_SRGB: + return PIPE_FORMAT_A8B8G8R8_UNORM; + case PIPE_FORMAT_X8B8G8R8_SRGB: + return PIPE_FORMAT_X8B8G8R8_UNORM; + case PIPE_FORMAT_B8G8R8A8_SRGB: + return PIPE_FORMAT_B8G8R8A8_UNORM; + case PIPE_FORMAT_B8G8R8X8_SRGB: + return PIPE_FORMAT_B8G8R8X8_UNORM; + case PIPE_FORMAT_A8R8G8B8_SRGB: + return PIPE_FORMAT_A8R8G8B8_UNORM; + case PIPE_FORMAT_X8R8G8B8_SRGB: + return PIPE_FORMAT_X8R8G8B8_UNORM; + case PIPE_FORMAT_DXT1_SRGB: + return PIPE_FORMAT_DXT1_RGB; + case PIPE_FORMAT_DXT1_SRGBA: + return PIPE_FORMAT_DXT1_RGBA; + case PIPE_FORMAT_DXT3_SRGBA: + return PIPE_FORMAT_DXT3_RGBA; + case PIPE_FORMAT_DXT5_SRGBA: + return PIPE_FORMAT_DXT5_RGBA; + default: + return format; + } +} + +/** + * Return the number of components stored. + * Formats with block size != 1x1 will always have 1 component (the block). + */ +static INLINE unsigned +util_format_get_nr_components(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + return desc->nr_channels; +} + +/* + * Format access functions. + */ + +void +util_format_read_4f(enum pipe_format format, + float *dst, unsigned dst_stride, + const void *src, unsigned src_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +void +util_format_write_4f(enum pipe_format format, + const float *src, unsigned src_stride, + void *dst, unsigned dst_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +void +util_format_read_4ub(enum pipe_format format, + uint8_t *dst, unsigned dst_stride, + const void *src, unsigned src_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +void +util_format_write_4ub(enum pipe_format format, + const uint8_t *src, unsigned src_stride, + void *dst, unsigned dst_stride, + unsigned x, unsigned y, unsigned w, unsigned h); + +/* + * Generic format conversion; + */ + +boolean +util_format_fits_8unorm(const struct util_format_description *format_desc); + +void +util_format_translate(enum pipe_format dst_format, + void *dst, unsigned dst_stride, + unsigned dst_x, unsigned dst_y, + enum pipe_format src_format, + const void *src, unsigned src_stride, + unsigned src_x, unsigned src_y, + unsigned width, unsigned height); + +/* + * Swizzle operations. + */ + +/* Compose two sets of swizzles. + * If V is a 4D vector and the function parameters represent functions that + * swizzle vector components, this holds: + * swz2(swz1(V)) = dst(V) + */ +void util_format_compose_swizzles(const unsigned char swz1[4], + const unsigned char swz2[4], + unsigned char dst[4]); + +void util_format_swizzle_4f(float *dst, const float *src, + const unsigned char swz[4]); + +void util_format_unswizzle_4f(float *dst, const float *src, + const unsigned char swz[4]); + +#ifdef __cplusplus +} // extern "C" { +#endif + +#endif /* ! U_FORMAT_H */ diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp index 6cfc32cc2..2a4de5b0d 100644 --- a/mesalib/src/glsl/ir_function.cpp +++ b/mesalib/src/glsl/ir_function.cpp @@ -30,14 +30,6 @@ typedef enum { PARAMETER_LIST_INEXACT_MATCH, /*< Match requires implicit conversion. */ } parameter_list_match_t; -/** - * \brief Check if two parameter lists match. - * - * \param list_a Parameters of the function definition. - * \param list_b Actual parameters passed to the function. - * \see matching_signature() - */ - /** * \brief Check if two parameter lists match. * diff --git a/mesalib/src/glsl/ir_function_detect_recursion.cpp b/mesalib/src/glsl/ir_function_detect_recursion.cpp index 44a1cd0b9..8f805bf1b 100644 --- a/mesalib/src/glsl/ir_function_detect_recursion.cpp +++ b/mesalib/src/glsl/ir_function_detect_recursion.cpp @@ -125,6 +125,7 @@ #include "glsl_parser_extras.h" #include "linker.h" #include "program/hash_table.h" +#include "program.h" struct call_node : public exec_node { class function *func; @@ -311,9 +312,7 @@ emit_errors_linked(const void *key, void *data, void *closure) f->sig->function_name(), &f->sig->parameters); - linker_error_printf(prog, - "function `%s' has static recursion.\n", - proto); + linker_error(prog, "function `%s' has static recursion.\n", proto); ralloc_free(proto); prog->LinkStatus = false; } diff --git a/mesalib/src/glsl/link_functions.cpp b/mesalib/src/glsl/link_functions.cpp index 7ba760daa..d40f771e3 100644 --- a/mesalib/src/glsl/link_functions.cpp +++ b/mesalib/src/glsl/link_functions.cpp @@ -91,8 +91,8 @@ public: if (sig == NULL) { /* FINISHME: Log the full signature of unresolved function. */ - linker_error_printf(this->prog, "unresolved reference to function " - "`%s'\n", name); + linker_error(this->prog, "unresolved reference to function `%s'\n", + name); this->success = false; return visit_stop; } diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index fe570b6cc..19eb9b5ff 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -164,7 +164,7 @@ private: void -linker_error_printf(gl_shader_program *prog, const char *fmt, ...) +linker_error(gl_shader_program *prog, const char *fmt, ...) { va_list ap; @@ -172,6 +172,21 @@ linker_error_printf(gl_shader_program *prog, const char *fmt, ...) va_start(ap, fmt); ralloc_vasprintf_append(&prog->InfoLog, fmt, ap); va_end(ap); + + prog->LinkStatus = false; +} + + +void +linker_warning(gl_shader_program *prog, const char *fmt, ...) +{ + va_list ap; + + ralloc_strcat(&prog->InfoLog, "error: "); + va_start(ap, fmt); + ralloc_vasprintf_append(&prog->InfoLog, fmt, ap); + va_end(ap); + } @@ -243,8 +258,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, find_assignment_visitor find("gl_Position"); find.run(shader->ir); if (!find.variable_found()) { - linker_error_printf(prog, - "vertex shader does not write to `gl_Position'\n"); + linker_error(prog, "vertex shader does not write to `gl_Position'\n"); return false; } @@ -271,8 +285,8 @@ validate_fragment_shader_executable(struct gl_shader_program *prog, frag_data.run(shader->ir); if (frag_color.variable_found() && frag_data.variable_found()) { - linker_error_printf(prog, "fragment shader writes to both " - "`gl_FragColor' and `gl_FragData'\n"); + linker_error(prog, "fragment shader writes to both " + "`gl_FragColor' and `gl_FragData'\n"); return false; } @@ -357,11 +371,11 @@ cross_validate_globals(struct gl_shader_program *prog, existing->type = var->type; } } else { - linker_error_printf(prog, "%s `%s' declared as type " - "`%s' and type `%s'\n", - mode_string(var), - var->name, var->type->name, - existing->type->name); + linker_error(prog, "%s `%s' declared as type " + "`%s' and type `%s'\n", + mode_string(var), + var->name, var->type->name, + existing->type->name); return false; } } @@ -369,9 +383,9 @@ cross_validate_globals(struct gl_shader_program *prog, if (var->explicit_location) { if (existing->explicit_location && (var->location != existing->location)) { - linker_error_printf(prog, "explicit locations for %s " - "`%s' have differing values\n", - mode_string(var), var->name); + linker_error(prog, "explicit locations for %s " + "`%s' have differing values\n", + mode_string(var), var->name); return false; } @@ -392,12 +406,12 @@ cross_validate_globals(struct gl_shader_program *prog, bool layout_declared = var->depth_layout != ir_depth_layout_none; bool layout_differs = var->depth_layout != existing->depth_layout; if (layout_declared && layout_differs) { - linker_error_printf(prog, + linker_error(prog, "All redeclarations of gl_FragDepth in all fragment shaders " "in a single program must have the same set of qualifiers."); } if (var->used && layout_differs) { - linker_error_printf(prog, + linker_error(prog, "If gl_FragDepth is redeclared with a layout qualifier in" "any fragment shader, it must be redeclared with the same" "layout qualifier in all fragment shaders that have" @@ -410,9 +424,9 @@ cross_validate_globals(struct gl_shader_program *prog, if (var->constant_value != NULL) { if (existing->constant_value != NULL) { if (!var->constant_value->has_value(existing->constant_value)) { - linker_error_printf(prog, "initializers for %s " - "`%s' have differing values\n", - mode_string(var), var->name); + linker_error(prog, "initializers for %s " + "`%s' have differing values\n", + mode_string(var), var->name); return false; } } else @@ -433,15 +447,15 @@ cross_validate_globals(struct gl_shader_program *prog, } if (existing->invariant != var->invariant) { - linker_error_printf(prog, "declarations for %s `%s' have " - "mismatching invariant qualifiers\n", - mode_string(var), var->name); + linker_error(prog, "declarations for %s `%s' have " + "mismatching invariant qualifiers\n", + mode_string(var), var->name); return false; } if (existing->centroid != var->centroid) { - linker_error_printf(prog, "declarations for %s `%s' have " - "mismatching centroid qualifiers\n", - mode_string(var), var->name); + linker_error(prog, "declarations for %s `%s' have " + "mismatching centroid qualifiers\n", + mode_string(var), var->name); return false; } } else @@ -529,13 +543,12 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog, */ if (!output->type->is_array() || (strncmp("gl_", output->name, 3) != 0)) { - linker_error_printf(prog, - "%s shader output `%s' declared as " - "type `%s', but %s shader input declared " - "as type `%s'\n", - producer_stage, output->name, - output->type->name, - consumer_stage, input->type->name); + linker_error(prog, + "%s shader output `%s' declared as type `%s', " + "but %s shader input declared as type `%s'\n", + producer_stage, output->name, + output->type->name, + consumer_stage, input->type->name); return false; } } @@ -543,40 +556,40 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog, /* Check that all of the qualifiers match between stages. */ if (input->centroid != output->centroid) { - linker_error_printf(prog, - "%s shader output `%s' %s centroid qualifier, " - "but %s shader input %s centroid qualifier\n", - producer_stage, - output->name, - (output->centroid) ? "has" : "lacks", - consumer_stage, - (input->centroid) ? "has" : "lacks"); + linker_error(prog, + "%s shader output `%s' %s centroid qualifier, " + "but %s shader input %s centroid qualifier\n", + producer_stage, + output->name, + (output->centroid) ? "has" : "lacks", + consumer_stage, + (input->centroid) ? "has" : "lacks"); return false; } if (input->invariant != output->invariant) { - linker_error_printf(prog, - "%s shader output `%s' %s invariant qualifier, " - "but %s shader input %s invariant qualifier\n", - producer_stage, - output->name, - (output->invariant) ? "has" : "lacks", - consumer_stage, - (input->invariant) ? "has" : "lacks"); + linker_error(prog, + "%s shader output `%s' %s invariant qualifier, " + "but %s shader input %s invariant qualifier\n", + producer_stage, + output->name, + (output->invariant) ? "has" : "lacks", + consumer_stage, + (input->invariant) ? "has" : "lacks"); return false; } if (input->interpolation != output->interpolation) { - linker_error_printf(prog, - "%s shader output `%s' specifies %s " - "interpolation qualifier, " - "but %s shader input specifies %s " - "interpolation qualifier\n", - producer_stage, - output->name, - output->interpolation_string(), - consumer_stage, - input->interpolation_string()); + linker_error(prog, + "%s shader output `%s' specifies %s " + "interpolation qualifier, " + "but %s shader input specifies %s " + "interpolation qualifier\n", + producer_stage, + output->name, + output->interpolation_string(), + consumer_stage, + input->interpolation_string()); return false; } } @@ -823,9 +836,8 @@ link_intrastage_shaders(void *mem_ctx, if ((other_sig != NULL) && other_sig->is_defined && !other_sig->is_builtin) { - linker_error_printf(prog, - "function `%s' is multiply defined", - f->name); + linker_error(prog, "function `%s' is multiply defined", + f->name); return NULL; } } @@ -849,9 +861,9 @@ link_intrastage_shaders(void *mem_ctx, } if (main == NULL) { - linker_error_printf(prog, "%s shader lacks `main'\n", - (shader_list[0]->Type == GL_VERTEX_SHADER) - ? "vertex" : "fragment"); + linker_error(prog, "%s shader lacks `main'\n", + (shader_list[0]->Type == GL_VERTEX_SHADER) + ? "vertex" : "fragment"); return NULL; } @@ -1309,10 +1321,10 @@ assign_attribute_or_color_locations(gl_shader_program *prog, * attribute overlaps any previously allocated bits. */ if ((~(use_mask << attr) & used_locations) != used_locations) { - linker_error_printf(prog, - "insufficient contiguous attribute locations " - "available for vertex shader input `%s'", - var->name); + linker_error(prog, + "insufficient contiguous attribute locations " + "available for vertex shader input `%s'", + var->name); return false; } @@ -1353,11 +1365,10 @@ assign_attribute_or_color_locations(gl_shader_program *prog, if ((var->location >= (int)(max_index + generic_base)) || (var->location < 0)) { - linker_error_printf(prog, - "invalid explicit location %d specified for " - "`%s'\n", - (var->location < 0) ? var->location : attr, - var->name); + linker_error(prog, + "invalid explicit location %d specified for `%s'\n", + (var->location < 0) ? var->location : attr, + var->name); return false; } else if (var->location >= generic_base) { used_locations |= (use_mask << attr); @@ -1406,10 +1417,10 @@ assign_attribute_or_color_locations(gl_shader_program *prog, const char *const string = (target_index == MESA_SHADER_VERTEX) ? "vertex shader input" : "fragment shader output"; - linker_error_printf(prog, - "insufficient contiguous attribute locations " - "available for %s `%s'", - string, to_assign[i].var->name); + linker_error(prog, + "insufficient contiguous attribute locations " + "available for %s `%s'", + string, to_assign[i].var->name); return false; } @@ -1525,9 +1536,8 @@ assign_varying_locations(struct gl_context *ctx, * "glsl1-varying read but not written" in piglit. */ - linker_error_printf(prog, "fragment shader varying %s not written " - "by vertex shader\n.", var->name); - prog->LinkStatus = false; + linker_error(prog, "fragment shader varying %s not written " + "by vertex shader\n.", var->name); } /* An 'in' variable is only really a shader input if its @@ -1544,17 +1554,17 @@ assign_varying_locations(struct gl_context *ctx, if (ctx->API == API_OPENGLES2 || prog->Version == 100) { if (varying_vectors > ctx->Const.MaxVarying) { - linker_error_printf(prog, "shader uses too many varying vectors " - "(%u > %u)\n", - varying_vectors, ctx->Const.MaxVarying); + linker_error(prog, "shader uses too many varying vectors " + "(%u > %u)\n", + varying_vectors, ctx->Const.MaxVarying); return false; } } else { const unsigned float_components = varying_vectors * 4; if (float_components > ctx->Const.MaxVarying * 4) { - linker_error_printf(prog, "shader uses too many varying components " - "(%u > %u)\n", - float_components, ctx->Const.MaxVarying * 4); + linker_error(prog, "shader uses too many varying components " + "(%u > %u)\n", + float_components, ctx->Const.MaxVarying * 4); return false; } } @@ -1618,8 +1628,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) assert(max_version <= 130); if ((max_version >= 130 || min_version == 100) && min_version != max_version) { - linker_error_printf(prog, "all shaders must use same shading " - "language version\n"); + linker_error(prog, "all shaders must use same shading " + "language version\n"); goto done; } @@ -1720,12 +1730,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) * FINISHME: at least 16, so hardcode 16 for now. */ if (!assign_attribute_or_color_locations(prog, MESA_SHADER_VERTEX, 16)) { - prog->LinkStatus = false; goto done; } if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) { - prog->LinkStatus = false; goto done; } @@ -1742,7 +1750,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) if (!assign_varying_locations(ctx, prog, prog->_LinkedShaders[prev], prog->_LinkedShaders[i])) { - prog->LinkStatus = false; goto done; } @@ -1774,11 +1781,9 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) */ if (ctx->API == API_OPENGLES2 || prog->Version == 100) { if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { - linker_error_printf(prog, "program lacks a vertex shader\n"); - prog->LinkStatus = false; + linker_error(prog, "program lacks a vertex shader\n"); } else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) { - linker_error_printf(prog, "program lacks a fragment shader\n"); - prog->LinkStatus = false; + linker_error(prog, "program lacks a fragment shader\n"); } } diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h index a8ce16a7e..769cf68b6 100644 --- a/mesalib/src/glsl/linker.h +++ b/mesalib/src/glsl/linker.h @@ -25,9 +25,6 @@ #ifndef GLSL_LINKER_H #define GLSL_LINKER_H -extern void -linker_error_printf(gl_shader_program *prog, const char *fmt, ...); - extern bool link_function_calls(gl_shader_program *prog, gl_shader *main, gl_shader **shader_list, unsigned num_shaders); diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index 9f85096e1..9b8a50738 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -221,6 +221,7 @@ main(int argc, char **argv) whole_program = rzalloc (NULL, struct gl_shader_program); assert(whole_program != NULL); + whole_program->InfoLog = ralloc_strdup(whole_program, ""); for (/* empty */; argc > optind; optind++) { whole_program->Shaders = diff --git a/mesalib/src/glsl/program.h b/mesalib/src/glsl/program.h index 6834b42f4..437ca1462 100644 --- a/mesalib/src/glsl/program.h +++ b/mesalib/src/glsl/program.h @@ -1,27 +1,35 @@ -/* - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "main/core.h" - -extern void -link_shaders(struct gl_context *ctx, struct gl_shader_program *prog); +/* + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "main/core.h" + +extern void +link_shaders(struct gl_context *ctx, struct gl_shader_program *prog); + +extern void +linker_error(gl_shader_program *prog, const char *fmt, ...) + PRINTFLIKE(2, 3); + +extern void +linker_warning(gl_shader_program *prog, const char *fmt, ...) + PRINTFLIKE(2, 3); diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index 67dd5c9aa..f128648f4 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -1,414 +1,415 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file shaderobj.c - * \author Brian Paul - * - */ - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/hash.h" -#include "main/mfeatures.h" -#include "main/mtypes.h" -#include "main/shaderobj.h" -#include "program/program.h" -#include "program/prog_parameter.h" -#include "program/prog_uniform.h" -#include "ralloc.h" - -/**********************************************************************/ -/*** Shader object functions ***/ -/**********************************************************************/ - - -/** - * Set ptr to point to sh. - * If ptr is pointing to another shader, decrement its refcount (and delete - * if refcount hits zero). - * Then set ptr to point to sh, incrementing its refcount. - */ -void -_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, - struct gl_shader *sh) -{ - assert(ptr); - if (*ptr == sh) { - /* no-op */ - return; - } - if (*ptr) { - /* Unreference the old shader */ - GLboolean deleteFlag = GL_FALSE; - struct gl_shader *old = *ptr; - - ASSERT(old->RefCount > 0); - old->RefCount--; - /*printf("SHADER DECR %p (%d) to %d\n", - (void*) old, old->Name, old->RefCount);*/ - deleteFlag = (old->RefCount == 0); - - if (deleteFlag) { - if (old->Name != 0) - _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); - ctx->Driver.DeleteShader(ctx, old); - } - - *ptr = NULL; - } - assert(!*ptr); - - if (sh) { - /* reference new */ - sh->RefCount++; - /*printf("SHADER INCR %p (%d) to %d\n", - (void*) sh, sh->Name, sh->RefCount);*/ - *ptr = sh; - } -} - -void -_mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader) -{ - shader->RefCount = 1; -} - -/** - * Allocate a new gl_shader object, initialize it. - * Called via ctx->Driver.NewShader() - */ -struct gl_shader * -_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type) -{ - struct gl_shader *shader; - assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER || - type == GL_GEOMETRY_SHADER_ARB); - shader = rzalloc(NULL, struct gl_shader); - if (shader) { - shader->Type = type; - shader->Name = name; - _mesa_init_shader(ctx, shader); - } - return shader; -} - - -/** - * Delete a shader object. - * Called via ctx->Driver.DeleteShader(). - */ -static void -_mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh) -{ - if (sh->Source) - free((void *) sh->Source); - _mesa_reference_program(ctx, &sh->Program, NULL); - ralloc_free(sh); -} - - -/** - * Lookup a GLSL shader object. - */ -struct gl_shader * -_mesa_lookup_shader(struct gl_context *ctx, GLuint name) -{ - if (name) { - struct gl_shader *sh = (struct gl_shader *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - /* Note that both gl_shader and gl_shader_program objects are kept - * in the same hash table. Check the object's type to be sure it's - * what we're expecting. - */ - if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) { - return NULL; - } - return sh; - } - return NULL; -} - - -/** - * As above, but record an error if shader is not found. - */ -struct gl_shader * -_mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller) -{ - if (!name) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); - return NULL; - } - else { - struct gl_shader *sh = (struct gl_shader *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - if (!sh) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); - return NULL; - } - if (sh->Type == GL_SHADER_PROGRAM_MESA) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); - return NULL; - } - return sh; - } -} - - - -/**********************************************************************/ -/*** Shader Program object functions ***/ -/**********************************************************************/ - - -/** - * Set ptr to point to shProg. - * If ptr is pointing to another object, decrement its refcount (and delete - * if refcount hits zero). - * Then set ptr to point to shProg, incrementing its refcount. - */ -void -_mesa_reference_shader_program(struct gl_context *ctx, - struct gl_shader_program **ptr, - struct gl_shader_program *shProg) -{ - assert(ptr); - if (*ptr == shProg) { - /* no-op */ - return; - } - if (*ptr) { - /* Unreference the old shader program */ - GLboolean deleteFlag = GL_FALSE; - struct gl_shader_program *old = *ptr; - - ASSERT(old->RefCount > 0); - old->RefCount--; -#if 0 - printf("ShaderProgram %p ID=%u RefCount-- to %d\n", - (void *) old, old->Name, old->RefCount); -#endif - deleteFlag = (old->RefCount == 0); - - if (deleteFlag) { - if (old->Name != 0) - _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); - ctx->Driver.DeleteShaderProgram(ctx, old); - } - - *ptr = NULL; - } - assert(!*ptr); - - if (shProg) { - shProg->RefCount++; -#if 0 - printf("ShaderProgram %p ID=%u RefCount++ to %d\n", - (void *) shProg, shProg->Name, shProg->RefCount); -#endif - *ptr = shProg; - } -} - -void -_mesa_init_shader_program(struct gl_context *ctx, struct gl_shader_program *prog) -{ - prog->Type = GL_SHADER_PROGRAM_MESA; - prog->RefCount = 1; - prog->Attributes = _mesa_new_parameter_list(); -#if FEATURE_ARB_geometry_shader4 - prog->Geom.VerticesOut = 0; - prog->Geom.InputType = GL_TRIANGLES; - prog->Geom.OutputType = GL_TRIANGLE_STRIP; -#endif -} - -/** - * Allocate a new gl_shader_program object, initialize it. - * Called via ctx->Driver.NewShaderProgram() - */ -static struct gl_shader_program * -_mesa_new_shader_program(struct gl_context *ctx, GLuint name) -{ - struct gl_shader_program *shProg; - shProg = rzalloc(NULL, struct gl_shader_program); - if (shProg) { - shProg->Name = name; - _mesa_init_shader_program(ctx, shProg); - } - return shProg; -} - - -/** - * Clear (free) the shader program state that gets produced by linking. - */ -void -_mesa_clear_shader_program_data(struct gl_context *ctx, - struct gl_shader_program *shProg) -{ - _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); - _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); - _mesa_reference_geomprog(ctx, &shProg->GeometryProgram, NULL); - - if (shProg->Uniforms) { - _mesa_free_uniform_list(shProg->Uniforms); - shProg->Uniforms = NULL; - } - - if (shProg->Varying) { - _mesa_free_parameter_list(shProg->Varying); - shProg->Varying = NULL; - } -} - - -/** - * Free all the data that hangs off a shader program object, but not the - * object itself. - */ -void -_mesa_free_shader_program_data(struct gl_context *ctx, - struct gl_shader_program *shProg) -{ - GLuint i; - gl_shader_type sh; - - assert(shProg->Type == GL_SHADER_PROGRAM_MESA); - - _mesa_clear_shader_program_data(ctx, shProg); - - if (shProg->Attributes) { - _mesa_free_parameter_list(shProg->Attributes); - shProg->Attributes = NULL; - } - - /* detach shaders */ - for (i = 0; i < shProg->NumShaders; i++) { - _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); - } - shProg->NumShaders = 0; - - if (shProg->Shaders) { - free(shProg->Shaders); - shProg->Shaders = NULL; - } - - if (shProg->InfoLog) { - ralloc_free(shProg->InfoLog); - shProg->InfoLog = NULL; - } - - /* Transform feedback varying vars */ - for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { - free(shProg->TransformFeedback.VaryingNames[i]); - } - free(shProg->TransformFeedback.VaryingNames); - shProg->TransformFeedback.VaryingNames = NULL; - shProg->TransformFeedback.NumVarying = 0; - - - for (sh = 0; sh < MESA_SHADER_TYPES; sh++) { - if (shProg->_LinkedShaders[sh] != NULL) { - ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[sh]); - shProg->_LinkedShaders[sh] = NULL; - } - } -} - - -/** - * Free/delete a shader program object. - * Called via ctx->Driver.DeleteShaderProgram(). - */ -static void -_mesa_delete_shader_program(struct gl_context *ctx, struct gl_shader_program *shProg) -{ - _mesa_free_shader_program_data(ctx, shProg); - - ralloc_free(shProg); -} - - -/** - * Lookup a GLSL program object. - */ -struct gl_shader_program * -_mesa_lookup_shader_program(struct gl_context *ctx, GLuint name) -{ - struct gl_shader_program *shProg; - if (name) { - shProg = (struct gl_shader_program *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - /* Note that both gl_shader and gl_shader_program objects are kept - * in the same hash table. Check the object's type to be sure it's - * what we're expecting. - */ - if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) { - return NULL; - } - return shProg; - } - return NULL; -} - - -/** - * As above, but record an error if program is not found. - */ -struct gl_shader_program * -_mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name, - const char *caller) -{ - if (!name) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); - return NULL; - } - else { - struct gl_shader_program *shProg = (struct gl_shader_program *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - if (!shProg) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); - return NULL; - } - if (shProg->Type != GL_SHADER_PROGRAM_MESA) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); - return NULL; - } - return shProg; - } -} - - -void -_mesa_init_shader_object_functions(struct dd_function_table *driver) -{ - driver->NewShader = _mesa_new_shader; - driver->DeleteShader = _mesa_delete_shader; - driver->NewShaderProgram = _mesa_new_shader_program; - driver->DeleteShaderProgram = _mesa_delete_shader_program; - driver->LinkShader = _mesa_ir_link_shader; -} +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file shaderobj.c + * \author Brian Paul + * + */ + + +#include "main/glheader.h" +#include "main/context.h" +#include "main/hash.h" +#include "main/mfeatures.h" +#include "main/mtypes.h" +#include "main/shaderobj.h" +#include "program/program.h" +#include "program/prog_parameter.h" +#include "program/prog_uniform.h" +#include "ralloc.h" + +/**********************************************************************/ +/*** Shader object functions ***/ +/**********************************************************************/ + + +/** + * Set ptr to point to sh. + * If ptr is pointing to another shader, decrement its refcount (and delete + * if refcount hits zero). + * Then set ptr to point to sh, incrementing its refcount. + */ +void +_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, + struct gl_shader *sh) +{ + assert(ptr); + if (*ptr == sh) { + /* no-op */ + return; + } + if (*ptr) { + /* Unreference the old shader */ + GLboolean deleteFlag = GL_FALSE; + struct gl_shader *old = *ptr; + + ASSERT(old->RefCount > 0); + old->RefCount--; + /*printf("SHADER DECR %p (%d) to %d\n", + (void*) old, old->Name, old->RefCount);*/ + deleteFlag = (old->RefCount == 0); + + if (deleteFlag) { + if (old->Name != 0) + _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); + ctx->Driver.DeleteShader(ctx, old); + } + + *ptr = NULL; + } + assert(!*ptr); + + if (sh) { + /* reference new */ + sh->RefCount++; + /*printf("SHADER INCR %p (%d) to %d\n", + (void*) sh, sh->Name, sh->RefCount);*/ + *ptr = sh; + } +} + +void +_mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader) +{ + shader->RefCount = 1; +} + +/** + * Allocate a new gl_shader object, initialize it. + * Called via ctx->Driver.NewShader() + */ +struct gl_shader * +_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type) +{ + struct gl_shader *shader; + assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER || + type == GL_GEOMETRY_SHADER_ARB); + shader = rzalloc(NULL, struct gl_shader); + if (shader) { + shader->Type = type; + shader->Name = name; + _mesa_init_shader(ctx, shader); + } + return shader; +} + + +/** + * Delete a shader object. + * Called via ctx->Driver.DeleteShader(). + */ +static void +_mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh) +{ + if (sh->Source) + free((void *) sh->Source); + _mesa_reference_program(ctx, &sh->Program, NULL); + ralloc_free(sh); +} + + +/** + * Lookup a GLSL shader object. + */ +struct gl_shader * +_mesa_lookup_shader(struct gl_context *ctx, GLuint name) +{ + if (name) { + struct gl_shader *sh = (struct gl_shader *) + _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + /* Note that both gl_shader and gl_shader_program objects are kept + * in the same hash table. Check the object's type to be sure it's + * what we're expecting. + */ + if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) { + return NULL; + } + return sh; + } + return NULL; +} + + +/** + * As above, but record an error if shader is not found. + */ +struct gl_shader * +_mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller) +{ + if (!name) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); + return NULL; + } + else { + struct gl_shader *sh = (struct gl_shader *) + _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + if (!sh) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); + return NULL; + } + if (sh->Type == GL_SHADER_PROGRAM_MESA) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); + return NULL; + } + return sh; + } +} + + + +/**********************************************************************/ +/*** Shader Program object functions ***/ +/**********************************************************************/ + + +/** + * Set ptr to point to shProg. + * If ptr is pointing to another object, decrement its refcount (and delete + * if refcount hits zero). + * Then set ptr to point to shProg, incrementing its refcount. + */ +void +_mesa_reference_shader_program(struct gl_context *ctx, + struct gl_shader_program **ptr, + struct gl_shader_program *shProg) +{ + assert(ptr); + if (*ptr == shProg) { + /* no-op */ + return; + } + if (*ptr) { + /* Unreference the old shader program */ + GLboolean deleteFlag = GL_FALSE; + struct gl_shader_program *old = *ptr; + + ASSERT(old->RefCount > 0); + old->RefCount--; +#if 0 + printf("ShaderProgram %p ID=%u RefCount-- to %d\n", + (void *) old, old->Name, old->RefCount); +#endif + deleteFlag = (old->RefCount == 0); + + if (deleteFlag) { + if (old->Name != 0) + _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); + ctx->Driver.DeleteShaderProgram(ctx, old); + } + + *ptr = NULL; + } + assert(!*ptr); + + if (shProg) { + shProg->RefCount++; +#if 0 + printf("ShaderProgram %p ID=%u RefCount++ to %d\n", + (void *) shProg, shProg->Name, shProg->RefCount); +#endif + *ptr = shProg; + } +} + +void +_mesa_init_shader_program(struct gl_context *ctx, struct gl_shader_program *prog) +{ + prog->Type = GL_SHADER_PROGRAM_MESA; + prog->RefCount = 1; + prog->Attributes = _mesa_new_parameter_list(); +#if FEATURE_ARB_geometry_shader4 + prog->Geom.VerticesOut = 0; + prog->Geom.InputType = GL_TRIANGLES; + prog->Geom.OutputType = GL_TRIANGLE_STRIP; +#endif + + prog->InfoLog = ralloc_strdup(prog, ""); +} + +/** + * Allocate a new gl_shader_program object, initialize it. + * Called via ctx->Driver.NewShaderProgram() + */ +static struct gl_shader_program * +_mesa_new_shader_program(struct gl_context *ctx, GLuint name) +{ + struct gl_shader_program *shProg; + shProg = rzalloc(NULL, struct gl_shader_program); + if (shProg) { + shProg->Name = name; + _mesa_init_shader_program(ctx, shProg); + } + return shProg; +} + + +/** + * Clear (free) the shader program state that gets produced by linking. + */ +void +_mesa_clear_shader_program_data(struct gl_context *ctx, + struct gl_shader_program *shProg) +{ + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); + _mesa_reference_geomprog(ctx, &shProg->GeometryProgram, NULL); + + if (shProg->Uniforms) { + _mesa_free_uniform_list(shProg->Uniforms); + shProg->Uniforms = NULL; + } + + if (shProg->Varying) { + _mesa_free_parameter_list(shProg->Varying); + shProg->Varying = NULL; + } + + assert(shProg->InfoLog != NULL); + ralloc_free(shProg->InfoLog); + shProg->InfoLog = ralloc_strdup(shProg, ""); +} + + +/** + * Free all the data that hangs off a shader program object, but not the + * object itself. + */ +void +_mesa_free_shader_program_data(struct gl_context *ctx, + struct gl_shader_program *shProg) +{ + GLuint i; + gl_shader_type sh; + + assert(shProg->Type == GL_SHADER_PROGRAM_MESA); + + _mesa_clear_shader_program_data(ctx, shProg); + + if (shProg->Attributes) { + _mesa_free_parameter_list(shProg->Attributes); + shProg->Attributes = NULL; + } + + /* detach shaders */ + for (i = 0; i < shProg->NumShaders; i++) { + _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); + } + shProg->NumShaders = 0; + + if (shProg->Shaders) { + free(shProg->Shaders); + shProg->Shaders = NULL; + } + + /* Transform feedback varying vars */ + for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { + free(shProg->TransformFeedback.VaryingNames[i]); + } + free(shProg->TransformFeedback.VaryingNames); + shProg->TransformFeedback.VaryingNames = NULL; + shProg->TransformFeedback.NumVarying = 0; + + + for (sh = 0; sh < MESA_SHADER_TYPES; sh++) { + if (shProg->_LinkedShaders[sh] != NULL) { + ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[sh]); + shProg->_LinkedShaders[sh] = NULL; + } + } +} + + +/** + * Free/delete a shader program object. + * Called via ctx->Driver.DeleteShaderProgram(). + */ +static void +_mesa_delete_shader_program(struct gl_context *ctx, struct gl_shader_program *shProg) +{ + _mesa_free_shader_program_data(ctx, shProg); + + ralloc_free(shProg); +} + + +/** + * Lookup a GLSL program object. + */ +struct gl_shader_program * +_mesa_lookup_shader_program(struct gl_context *ctx, GLuint name) +{ + struct gl_shader_program *shProg; + if (name) { + shProg = (struct gl_shader_program *) + _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + /* Note that both gl_shader and gl_shader_program objects are kept + * in the same hash table. Check the object's type to be sure it's + * what we're expecting. + */ + if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) { + return NULL; + } + return shProg; + } + return NULL; +} + + +/** + * As above, but record an error if program is not found. + */ +struct gl_shader_program * +_mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name, + const char *caller) +{ + if (!name) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); + return NULL; + } + else { + struct gl_shader_program *shProg = (struct gl_shader_program *) + _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); + return NULL; + } + if (shProg->Type != GL_SHADER_PROGRAM_MESA) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); + return NULL; + } + return shProg; + } +} + + +void +_mesa_init_shader_object_functions(struct dd_function_table *driver) +{ + driver->NewShader = _mesa_new_shader; + driver->DeleteShader = _mesa_delete_shader; + driver->NewShaderProgram = _mesa_new_shader_program; + driver->DeleteShaderProgram = _mesa_delete_shader_program; + driver->LinkShader = _mesa_ir_link_shader; +} diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 8b4a535b7..382cda0c7 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -331,20 +331,6 @@ dst_reg undef_dst = dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP); dst_reg address_reg = dst_reg(PROGRAM_ADDRESS, WRITEMASK_X); -static void -fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); - -static void -fail_link(struct gl_shader_program *prog, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - ralloc_vasprintf_append(&prog->InfoLog, fmt, args); - va_end(args); - - prog->LinkStatus = GL_FALSE; -} - static int swizzle_for_size(int size) { @@ -789,10 +775,11 @@ ir_to_mesa_visitor::visit(ir_variable *ir) if (storage->file == PROGRAM_TEMPORARY && dst.index != storage->index + (int) ir->num_state_slots) { - fail_link(this->shader_program, - "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", - ir->name, dst.index - storage->index, - type_size(ir->type)); + linker_error(this->shader_program, + "failed to load builtin uniform `%s' " + "(%d/%d regs loaded)\n", + ir->name, dst.index - storage->index, + type_size(ir->type)); } } } @@ -2413,29 +2400,32 @@ check_resources(const struct gl_context *ctx, case GL_VERTEX_PROGRAM_ARB: if (_mesa_bitcount(prog->SamplersUsed) > ctx->Const.MaxVertexTextureImageUnits) { - fail_link(shader_program, "Too many vertex shader texture samplers"); + linker_error(shader_program, + "Too many vertex shader texture samplers"); } if (prog->Parameters->NumParameters > MAX_UNIFORMS) { - fail_link(shader_program, "Too many vertex shader constants"); + linker_error(shader_program, "Too many vertex shader constants"); } break; case MESA_GEOMETRY_PROGRAM: if (_mesa_bitcount(prog->SamplersUsed) > ctx->Const.MaxGeometryTextureImageUnits) { - fail_link(shader_program, "Too many geometry shader texture samplers"); + linker_error(shader_program, + "Too many geometry shader texture samplers"); } if (prog->Parameters->NumParameters > MAX_GEOMETRY_UNIFORM_COMPONENTS / 4) { - fail_link(shader_program, "Too many geometry shader constants"); + linker_error(shader_program, "Too many geometry shader constants"); } break; case GL_FRAGMENT_PROGRAM_ARB: if (_mesa_bitcount(prog->SamplersUsed) > ctx->Const.MaxTextureImageUnits) { - fail_link(shader_program, "Too many fragment shader texture samplers"); + linker_error(shader_program, + "Too many fragment shader texture samplers"); } if (prog->Parameters->NumParameters > MAX_UNIFORMS) { - fail_link(shader_program, "Too many fragment shader constants"); + linker_error(shader_program, "Too many fragment shader constants"); } break; default: @@ -2550,9 +2540,10 @@ add_uniforms_to_parameters_list(struct gl_shader_program *shader_program, * from _mesa_add_uniform) has to match what the linker chose. */ if (index != parameter_index) { - fail_link(shader_program, "Allocation of uniform `%s' to target " - "failed (%d vs %d)\n", - uniform->Name, index, parameter_index); + linker_error(shader_program, + "Allocation of uniform `%s' to target failed " + "(%d vs %d)\n", + uniform->Name, index, parameter_index); } } } @@ -2585,8 +2576,8 @@ set_uniform_initializer(struct gl_context *ctx, void *mem_ctx, int loc = _mesa_get_uniform_location(ctx, shader_program, name); if (loc == -1) { - fail_link(shader_program, - "Couldn't find uniform for initializer %s\n", name); + linker_error(shader_program, + "Couldn't find uniform for initializer %s\n", name); return; } @@ -2986,11 +2977,31 @@ get_mesa_program(struct gl_context *ctx, if (mesa_inst->SrcReg[src].RelAddr) prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; - if (options->EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) { - fail_link(shader_program, "Couldn't flatten if statement\n"); - } - switch (mesa_inst->Opcode) { + case OPCODE_IF: + if (options->EmitNoIfs) { + linker_warning(shader_program, + "Couldn't flatten if-statement. " + "This will likely result in software " + "rasterization.\n"); + } + break; + case OPCODE_BGNLOOP: + if (options->EmitNoLoops) { + linker_warning(shader_program, + "Couldn't unroll loop. " + "This will likely result in software " + "rasterization.\n"); + } + break; + case OPCODE_CONT: + if (options->EmitNoCont) { + linker_warning(shader_program, + "Couldn't lower continue-statement. " + "This will likely result in software " + "rasterization.\n"); + } + break; case OPCODE_BGNSUB: inst->function->inst = i; mesa_inst->Comment = strdup(inst->function->sig->function_name()); @@ -3258,7 +3269,7 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) for (i = 0; i < prog->NumShaders; i++) { if (!prog->Shaders[i]->CompileStatus) { - fail_link(prog, "linking with uncompiled shader"); + linker_error(prog, "linking with uncompiled shader"); prog->LinkStatus = GL_FALSE; } } diff --git a/xorg-server/composite/compalloc.c b/xorg-server/composite/compalloc.c index 5c27631e1..f00bf4eb0 100644 --- a/xorg-server/composite/compalloc.c +++ b/xorg-server/composite/compalloc.c @@ -434,6 +434,7 @@ compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update) * critical output */ DamageExtSetCritical (pClient, TRUE); + pWin->inhibitBGPaint = TRUE; } return Success; } @@ -466,6 +467,7 @@ compFreeClientSubwindows (WindowPtr pWin, XID id) */ DamageExtSetCritical (pClient, FALSE); csw->update = CompositeRedirectAutomatic; + pWin->inhibitBGPaint = FALSE; if (pWin->mapped) (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE); } @@ -557,7 +559,7 @@ compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin) } static PixmapPtr -compNewPixmap (WindowPtr pWin, int x, int y, int w, int h, Bool map) +compNewPixmap (WindowPtr pWin, int x, int y, int w, int h) { ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pParent = pWin->parent; @@ -572,10 +574,6 @@ compNewPixmap (WindowPtr pWin, int x, int y, int w, int h, Bool map) pPixmap->screen_x = x; pPixmap->screen_y = y; - /* resize allocations will update later in compCopyWindow, not here */ - if (!map) - return pPixmap; - if (pParent->drawable.depth == pWin->drawable.depth) { GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen); @@ -641,7 +639,7 @@ compAllocPixmap (WindowPtr pWin) int y = pWin->drawable.y - bw; int w = pWin->drawable.width + (bw << 1); int h = pWin->drawable.height + (bw << 1); - PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h, TRUE); + PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h); CompWindowPtr cw = GetCompWindow (pWin); if (!pPixmap) @@ -713,7 +711,7 @@ compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y, pix_h = h + (bw << 1); if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height) { - pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h, FALSE); + pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h); if (!pNew) return FALSE; cw->pOldPixmap = pOld; diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 24388259c..4f4bcf218 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -26,8 +26,8 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([xorg-server], 1.10.99.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2011-06-01" +AC_INIT([xorg-server], 1.10.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2011-08-03" AC_CONFIG_SRCDIR([Makefile.am]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE diff --git a/xorg-server/hw/xquartz/X11Application.m b/xorg-server/hw/xquartz/X11Application.m index 8a03fbe29..7fd7dab3c 100644 --- a/xorg-server/hw/xquartz/X11Application.m +++ b/xorg-server/hw/xquartz/X11Application.m @@ -1014,7 +1014,7 @@ void X11ApplicationMain (int argc, char **argv, char **envp) { if (app_prefs_domain_cfstr == NULL) { ErrorF("X11ApplicationMain: Unable to determine bundle identifier. Your installation of XQuartz may be broken.\n"); - app_prefs_domain_cfstr = @BUNDLE_ID_PREFIX".X11"; + app_prefs_domain_cfstr = CFSTR(BUNDLE_ID_PREFIX".X11"); } [NSApp read_defaults]; diff --git a/xorg-server/hw/xquartz/bundle/Makefile.am b/xorg-server/hw/xquartz/bundle/Makefile.am index 6deecae55..6e83a42d6 100644 --- a/xorg-server/hw/xquartz/bundle/Makefile.am +++ b/xorg-server/hw/xquartz/bundle/Makefile.am @@ -40,6 +40,9 @@ EXTRA_DIST = \ Resources/Dutch.lproj/InfoPlist.strings \ Resources/Dutch.lproj/Localizable.strings \ Resources/Dutch.lproj/main.nib/keyedobjects.nib \ + Resources/el.lproj/InfoPlist.strings \ + Resources/el.lproj/Localizable.strings \ + Resources/el.lproj/main.nib/keyedobjects.nib \ Resources/English.lproj/InfoPlist.strings \ Resources/English.lproj/Localizable.strings \ Resources/English.lproj/main.nib/designable.nib \ @@ -53,6 +56,9 @@ EXTRA_DIST = \ Resources/German.lproj/InfoPlist.strings \ Resources/German.lproj/Localizable.strings \ Resources/German.lproj/main.nib/keyedobjects.nib \ + Resources/he.lproj/InfoPlist.strings \ + Resources/he.lproj/Localizable.strings \ + Resources/he.lproj/main.nib/keyedobjects.nib \ Resources/Italian.lproj/InfoPlist.strings \ Resources/Italian.lproj/Localizable.strings \ Resources/Italian.lproj/main.nib/keyedobjects.nib \ @@ -77,6 +83,9 @@ EXTRA_DIST = \ Resources/ru.lproj/InfoPlist.strings \ Resources/ru.lproj/Localizable.strings \ Resources/ru.lproj/main.nib/keyedobjects.nib \ + Resources/sk.lproj/InfoPlist.strings \ + Resources/sk.lproj/Localizable.strings \ + Resources/sk.lproj/main.nib/keyedobjects.nib \ Resources/Spanish.lproj/InfoPlist.strings \ Resources/Spanish.lproj/Localizable.strings \ Resources/Spanish.lproj/main.nib/keyedobjects.nib \ diff --git a/xorg-server/hw/xquartz/xpr/xprFrame.c b/xorg-server/hw/xquartz/xpr/xprFrame.c index 4818653f6..98f1cc3ed 100644 --- a/xorg-server/hw/xquartz/xpr/xprFrame.c +++ b/xorg-server/hw/xquartz/xpr/xprFrame.c @@ -223,7 +223,7 @@ xprDestroyFrame(RootlessFrameID wid) err = xp_destroy_window(x_cvt_vptr_to_uint(wid)); if (err != Success) - FatalError("Could not destroy window %i.", (int)x_cvt_vptr_to_uint(wid)); + FatalError("Could not destroy window %d (%d).", (int)x_cvt_vptr_to_uint(wid), (int)err); } @@ -364,7 +364,7 @@ xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow) err = xp_lock_window(x_cvt_vptr_to_uint(wid), NULL, NULL, data, rowbytes, NULL); if (err != Success) - FatalError("Could not lock window %i for drawing.", (int)x_cvt_vptr_to_uint(wid)); + FatalError("Could not lock window %d for drawing (%d).", (int)x_cvt_vptr_to_uint(wid), (int)err); *pixelData = data[0]; *bytesPerRow = rowbytes[0]; @@ -380,8 +380,11 @@ xprStopDrawing(RootlessFrameID wid, Bool flush) xp_error err; err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush); + /* This should be a FatalError, but we started tripping over it. Make it a + * FatalError after http://xquartz.macosforge.org/trac/ticket/482 is fixed. + */ if(err != Success) - FatalError("Could not unlock window %i after drawing.", (int)x_cvt_vptr_to_uint(wid)); + ErrorF("Could not unlock window %d after drawing (%d).", (int)x_cvt_vptr_to_uint(wid), (int)err); } diff --git a/xorg-server/include/windowstr.h b/xorg-server/include/windowstr.h index e967223b4..222de31dc 100644 --- a/xorg-server/include/windowstr.h +++ b/xorg-server/include/windowstr.h @@ -1,221 +1,222 @@ -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -#ifndef WINDOWSTRUCT_H -#define WINDOWSTRUCT_H - -#include "window.h" -#include "pixmapstr.h" -#include "regionstr.h" -#include "cursor.h" -#include "property.h" -#include "resource.h" /* for ROOT_WINDOW_ID_BASE */ -#include "dix.h" -#include "privates.h" -#include "miscstruct.h" -#include -#include "opaque.h" - -#define GuaranteeNothing 0 -#define GuaranteeVisBack 1 - -#define SameBackground(as, a, bs, b) \ - ((as) == (bs) && ((as) == None || \ - (as) == ParentRelative || \ - SamePixUnion(a,b,as == BackgroundPixel))) - -#define SameBorder(as, a, bs, b) \ - EqualPixUnion(as, a, bs, b) - -/* used as NULL-terminated list */ -typedef struct _DevCursorNode { - CursorPtr cursor; - DeviceIntPtr dev; - struct _DevCursorNode* next; -} DevCursNodeRec, *DevCursNodePtr, *DevCursorList; - -typedef struct _WindowOpt { - CursorPtr cursor; /* default: window.cursorNone */ - VisualID visual; /* default: same as parent */ - Colormap colormap; /* default: same as parent */ - Mask dontPropagateMask; /* default: window.dontPropagate */ - Mask otherEventMasks; /* default: 0 */ - struct _OtherClients *otherClients; /* default: NULL */ - struct _GrabRec *passiveGrabs; /* default: NULL */ - PropertyPtr userProps; /* default: NULL */ - unsigned long backingBitPlanes; /* default: ~0L */ - unsigned long backingPixel; /* default: 0 */ - RegionPtr boundingShape; /* default: NULL */ - RegionPtr clipShape; /* default: NULL */ - RegionPtr inputShape; /* default: NULL */ - struct _OtherInputMasks *inputMasks; /* default: NULL */ - DevCursorList deviceCursors; /* default: NULL */ -} WindowOptRec, *WindowOptPtr; - -#define BackgroundPixel 2L -#define BackgroundPixmap 3L - -/* - * The redirectDraw field can have one of three values: - * - * RedirectDrawNone - * A normal window; painted into the same pixmap as the parent - * and clipping parent and siblings to its geometry. These - * windows get a clip list equal to the intersection of their - * geometry with the parent geometry, minus the geometry - * of overlapping None and Clipped siblings. - * RedirectDrawAutomatic - * A redirected window which clips parent and sibling drawing. - * Contents for these windows are manage inside the server. - * These windows get an internal clip list equal to their - * geometry. - * RedirectDrawManual - * A redirected window which does not clip parent and sibling - * drawing; the window must be represented within the parent - * geometry by the client performing the redirection management. - * Contents for these windows are managed outside the server. - * These windows get an internal clip list equal to their - * geometry. - */ - -#define RedirectDrawNone 0 -#define RedirectDrawAutomatic 1 -#define RedirectDrawManual 2 - -typedef struct _Window { - DrawableRec drawable; - PrivateRec *devPrivates; - WindowPtr parent; /* ancestor chain */ - WindowPtr nextSib; /* next lower sibling */ - WindowPtr prevSib; /* next higher sibling */ - WindowPtr firstChild; /* top-most child */ - WindowPtr lastChild; /* bottom-most child */ - RegionRec clipList; /* clipping rectangle for output */ - RegionRec borderClip; /* NotClippedByChildren + border */ - union _Validate *valdata; - RegionRec winSize; - RegionRec borderSize; - DDXPointRec origin; /* position relative to parent */ - unsigned short borderWidth; - unsigned short deliverableEvents; /* all masks from all clients */ - Mask eventMask; /* mask from the creating client */ - PixUnion background; - PixUnion border; - pointer backStorage; /* null when BS disabled */ - WindowOptPtr optional; - unsigned backgroundState:2; /* None, Relative, Pixel, Pixmap */ - unsigned borderIsPixel:1; - unsigned cursorIsNone:1; /* else real cursor (might inherit) */ - unsigned backingStore:2; - unsigned saveUnder:1; - unsigned DIXsaveUnder:1; - unsigned bitGravity:4; - unsigned winGravity:4; - unsigned overrideRedirect:1; - unsigned visibility:2; - unsigned mapped:1; - unsigned realized:1; /* ancestors are all mapped */ - unsigned viewable:1; /* realized && InputOutput */ - unsigned dontPropagate:3;/* index into DontPropagateMasks */ - unsigned forcedBS:1; /* system-supplied backingStore */ - unsigned redirectDraw:2; /* COMPOSITE rendering redirect */ - unsigned forcedBG:1; /* must have an opaque background */ -#ifdef ROOTLESS - unsigned rootlessUnhittable:1; /* doesn't hit-test */ -#endif -#ifdef COMPOSITE - unsigned damagedDescendants:1; /* some descendants are damaged */ -#endif -} WindowRec; - -/* - * Ok, a bunch of macros for accessing the optional record - * fields (or filling the appropriate default value) - */ - -extern _X_EXPORT Mask DontPropagateMasks[]; - -#define wTrackParent(w,field) ((w)->optional ? \ - (w)->optional->field \ - : FindWindowWithOptional(w)->optional->field) -#define wUseDefault(w,field,def) ((w)->optional ? \ - (w)->optional->field \ - : def) - -#define wVisual(w) wTrackParent(w, visual) -#define wCursor(w) ((w)->cursorIsNone ? None : wTrackParent(w, cursor)) -#define wColormap(w) ((w)->drawable.class == InputOnly ? None : wTrackParent(w, colormap)) -#define wDontPropagateMask(w) wUseDefault(w, dontPropagateMask, DontPropagateMasks[(w)->dontPropagate]) -#define wOtherEventMasks(w) wUseDefault(w, otherEventMasks, 0) -#define wOtherClients(w) wUseDefault(w, otherClients, NULL) -#define wOtherInputMasks(w) wUseDefault(w, inputMasks, NULL) -#define wPassiveGrabs(w) wUseDefault(w, passiveGrabs, NULL) -#define wUserProps(w) wUseDefault(w, userProps, NULL) -#define wBackingBitPlanes(w) wUseDefault(w, backingBitPlanes, ~0L) -#define wBackingPixel(w) wUseDefault(w, backingPixel, 0) -#define wBoundingShape(w) wUseDefault(w, boundingShape, NULL) -#define wClipShape(w) wUseDefault(w, clipShape, NULL) -#define wInputShape(w) wUseDefault(w, inputShape, NULL) -#define wClient(w) (clients[CLIENT_ID((w)->drawable.id)]) -#define wBorderWidth(w) ((int) (w)->borderWidth) - -/* true when w needs a border drawn. */ - -#define HasBorder(w) ((w)->borderWidth || wClipShape(w)) - -typedef struct _ScreenSaverStuff *ScreenSaverStuffPtr; - -#define SCREEN_IS_BLANKED 0 -#define SCREEN_ISNT_SAVED 1 -#define SCREEN_IS_TILED 2 -#define SCREEN_IS_BLACK 3 - -#define HasSaverWindow(pScreen) (pScreen->screensaver.pWindow != NullWindow) - -extern _X_EXPORT int screenIsSaved; - -#endif /* WINDOWSTRUCT_H */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef WINDOWSTRUCT_H +#define WINDOWSTRUCT_H + +#include "window.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "cursor.h" +#include "property.h" +#include "resource.h" /* for ROOT_WINDOW_ID_BASE */ +#include "dix.h" +#include "privates.h" +#include "miscstruct.h" +#include +#include "opaque.h" + +#define GuaranteeNothing 0 +#define GuaranteeVisBack 1 + +#define SameBackground(as, a, bs, b) \ + ((as) == (bs) && ((as) == None || \ + (as) == ParentRelative || \ + SamePixUnion(a,b,as == BackgroundPixel))) + +#define SameBorder(as, a, bs, b) \ + EqualPixUnion(as, a, bs, b) + +/* used as NULL-terminated list */ +typedef struct _DevCursorNode { + CursorPtr cursor; + DeviceIntPtr dev; + struct _DevCursorNode* next; +} DevCursNodeRec, *DevCursNodePtr, *DevCursorList; + +typedef struct _WindowOpt { + CursorPtr cursor; /* default: window.cursorNone */ + VisualID visual; /* default: same as parent */ + Colormap colormap; /* default: same as parent */ + Mask dontPropagateMask; /* default: window.dontPropagate */ + Mask otherEventMasks; /* default: 0 */ + struct _OtherClients *otherClients; /* default: NULL */ + struct _GrabRec *passiveGrabs; /* default: NULL */ + PropertyPtr userProps; /* default: NULL */ + unsigned long backingBitPlanes; /* default: ~0L */ + unsigned long backingPixel; /* default: 0 */ + RegionPtr boundingShape; /* default: NULL */ + RegionPtr clipShape; /* default: NULL */ + RegionPtr inputShape; /* default: NULL */ + struct _OtherInputMasks *inputMasks; /* default: NULL */ + DevCursorList deviceCursors; /* default: NULL */ +} WindowOptRec, *WindowOptPtr; + +#define BackgroundPixel 2L +#define BackgroundPixmap 3L + +/* + * The redirectDraw field can have one of three values: + * + * RedirectDrawNone + * A normal window; painted into the same pixmap as the parent + * and clipping parent and siblings to its geometry. These + * windows get a clip list equal to the intersection of their + * geometry with the parent geometry, minus the geometry + * of overlapping None and Clipped siblings. + * RedirectDrawAutomatic + * A redirected window which clips parent and sibling drawing. + * Contents for these windows are manage inside the server. + * These windows get an internal clip list equal to their + * geometry. + * RedirectDrawManual + * A redirected window which does not clip parent and sibling + * drawing; the window must be represented within the parent + * geometry by the client performing the redirection management. + * Contents for these windows are managed outside the server. + * These windows get an internal clip list equal to their + * geometry. + */ + +#define RedirectDrawNone 0 +#define RedirectDrawAutomatic 1 +#define RedirectDrawManual 2 + +typedef struct _Window { + DrawableRec drawable; + PrivateRec *devPrivates; + WindowPtr parent; /* ancestor chain */ + WindowPtr nextSib; /* next lower sibling */ + WindowPtr prevSib; /* next higher sibling */ + WindowPtr firstChild; /* top-most child */ + WindowPtr lastChild; /* bottom-most child */ + RegionRec clipList; /* clipping rectangle for output */ + RegionRec borderClip; /* NotClippedByChildren + border */ + union _Validate *valdata; + RegionRec winSize; + RegionRec borderSize; + DDXPointRec origin; /* position relative to parent */ + unsigned short borderWidth; + unsigned short deliverableEvents; /* all masks from all clients */ + Mask eventMask; /* mask from the creating client */ + PixUnion background; + PixUnion border; + pointer backStorage; /* null when BS disabled */ + WindowOptPtr optional; + unsigned backgroundState:2; /* None, Relative, Pixel, Pixmap */ + unsigned borderIsPixel:1; + unsigned cursorIsNone:1; /* else real cursor (might inherit) */ + unsigned backingStore:2; + unsigned saveUnder:1; + unsigned DIXsaveUnder:1; + unsigned bitGravity:4; + unsigned winGravity:4; + unsigned overrideRedirect:1; + unsigned visibility:2; + unsigned mapped:1; + unsigned realized:1; /* ancestors are all mapped */ + unsigned viewable:1; /* realized && InputOutput */ + unsigned dontPropagate:3;/* index into DontPropagateMasks */ + unsigned forcedBS:1; /* system-supplied backingStore */ + unsigned redirectDraw:2; /* COMPOSITE rendering redirect */ + unsigned forcedBG:1; /* must have an opaque background */ +#ifdef ROOTLESS + unsigned rootlessUnhittable:1; /* doesn't hit-test */ +#endif +#ifdef COMPOSITE + unsigned damagedDescendants:1; /* some descendants are damaged */ + unsigned inhibitBGPaint:1; /* paint the background? */ +#endif +} WindowRec; + +/* + * Ok, a bunch of macros for accessing the optional record + * fields (or filling the appropriate default value) + */ + +extern _X_EXPORT Mask DontPropagateMasks[]; + +#define wTrackParent(w,field) ((w)->optional ? \ + (w)->optional->field \ + : FindWindowWithOptional(w)->optional->field) +#define wUseDefault(w,field,def) ((w)->optional ? \ + (w)->optional->field \ + : def) + +#define wVisual(w) wTrackParent(w, visual) +#define wCursor(w) ((w)->cursorIsNone ? None : wTrackParent(w, cursor)) +#define wColormap(w) ((w)->drawable.class == InputOnly ? None : wTrackParent(w, colormap)) +#define wDontPropagateMask(w) wUseDefault(w, dontPropagateMask, DontPropagateMasks[(w)->dontPropagate]) +#define wOtherEventMasks(w) wUseDefault(w, otherEventMasks, 0) +#define wOtherClients(w) wUseDefault(w, otherClients, NULL) +#define wOtherInputMasks(w) wUseDefault(w, inputMasks, NULL) +#define wPassiveGrabs(w) wUseDefault(w, passiveGrabs, NULL) +#define wUserProps(w) wUseDefault(w, userProps, NULL) +#define wBackingBitPlanes(w) wUseDefault(w, backingBitPlanes, ~0L) +#define wBackingPixel(w) wUseDefault(w, backingPixel, 0) +#define wBoundingShape(w) wUseDefault(w, boundingShape, NULL) +#define wClipShape(w) wUseDefault(w, clipShape, NULL) +#define wInputShape(w) wUseDefault(w, inputShape, NULL) +#define wClient(w) (clients[CLIENT_ID((w)->drawable.id)]) +#define wBorderWidth(w) ((int) (w)->borderWidth) + +/* true when w needs a border drawn. */ + +#define HasBorder(w) ((w)->borderWidth || wClipShape(w)) + +typedef struct _ScreenSaverStuff *ScreenSaverStuffPtr; + +#define SCREEN_IS_BLANKED 0 +#define SCREEN_ISNT_SAVED 1 +#define SCREEN_IS_TILED 2 +#define SCREEN_IS_BLACK 3 + +#define HasSaverWindow(pScreen) (pScreen->screensaver.pWindow != NullWindow) + +extern _X_EXPORT int screenIsSaved; + +#endif /* WINDOWSTRUCT_H */ diff --git a/xorg-server/mi/miexpose.c b/xorg-server/mi/miexpose.c index 89f45016d..0f1ebe59c 100644 --- a/xorg-server/mi/miexpose.c +++ b/xorg-server/mi/miexpose.c @@ -1,697 +1,701 @@ -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ -/***************************************************************** - -Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, -BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of Digital Equipment Corporation -shall not be used in advertising or otherwise to promote the sale, use or other -dealings in this Software without prior written authorization from Digital -Equipment Corporation. - -******************************************************************/ - - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include -#include - -#include "misc.h" -#include "regionstr.h" -#include "scrnintstr.h" -#include "gcstruct.h" -#include "windowstr.h" -#include "pixmap.h" -#include "input.h" - -#include "dixstruct.h" -#include "mi.h" -#include - -#include "globals.h" - -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif - -/* - machine-independent graphics exposure code. any device that uses -the region package can call this. -*/ - -#ifndef RECTLIMIT -#define RECTLIMIT 25 /* pick a number, any number > 8 */ -#endif - -/* miHandleExposures - generate a region for exposures for areas that were copied from obscured or -non-existent areas to non-obscured areas of the destination. Paint the -background for the region, if the destination is a window. - -NOTE: - this should generally be called, even if graphicsExposures is false, -because this is where bits get recovered from backing store. - -NOTE: - added argument 'plane' is used to indicate how exposures from backing -store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea -should be used, else a CopyPlane of the indicated plane will be used. The -exposing is done by the backing store's GraphicsExpose function, of course. - -*/ - -RegionPtr -miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, - GCPtr pGC, int srcx, int srcy, int width, int height, - int dstx, int dsty, unsigned long plane) -{ - RegionPtr prgnSrcClip; /* drawable-relative source clip */ - RegionRec rgnSrcRec; - RegionPtr prgnDstClip; /* drawable-relative dest clip */ - RegionRec rgnDstRec; - BoxRec srcBox; /* unclipped source */ - RegionRec rgnExposed; /* exposed region, calculated source- - relative, made dst relative to - intersect with visible parts of - dest and send events to client, - and then screen relative to paint - the window background - */ - WindowPtr pSrcWin; - BoxRec expBox; - Bool extents; - - /* avoid work if we can */ - if (!pGC->graphicsExposures && - (pDstDrawable->type == DRAWABLE_PIXMAP) && - ((pSrcDrawable->type == DRAWABLE_PIXMAP) || - (((WindowPtr)pSrcDrawable)->backStorage == NULL))) - return NULL; - - srcBox.x1 = srcx; - srcBox.y1 = srcy; - srcBox.x2 = srcx+width; - srcBox.y2 = srcy+height; - - if (pSrcDrawable->type != DRAWABLE_PIXMAP) - { - BoxRec TsrcBox; - - TsrcBox.x1 = srcx + pSrcDrawable->x; - TsrcBox.y1 = srcy + pSrcDrawable->y; - TsrcBox.x2 = TsrcBox.x1 + width; - TsrcBox.y2 = TsrcBox.y1 + height; - pSrcWin = (WindowPtr) pSrcDrawable; - if (pGC->subWindowMode == IncludeInferiors) - { - prgnSrcClip = NotClippedByChildren (pSrcWin); - if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) - { - RegionDestroy(prgnSrcClip); - return NULL; - } - } - else - { - if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN) - return NULL; - prgnSrcClip = &rgnSrcRec; - RegionNull(prgnSrcClip); - RegionCopy(prgnSrcClip, &pSrcWin->clipList); - } - RegionTranslate(prgnSrcClip, - -pSrcDrawable->x, -pSrcDrawable->y); - } - else - { - BoxRec box; - - if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && - (srcBox.x2 <= pSrcDrawable->width) && - (srcBox.y2 <= pSrcDrawable->height)) - return NULL; - - box.x1 = 0; - box.y1 = 0; - box.x2 = pSrcDrawable->width; - box.y2 = pSrcDrawable->height; - prgnSrcClip = &rgnSrcRec; - RegionInit(prgnSrcClip, &box, 1); - pSrcWin = NULL; - } - - if (pDstDrawable == pSrcDrawable) - { - prgnDstClip = prgnSrcClip; - } - else if (pDstDrawable->type != DRAWABLE_PIXMAP) - { - if (pGC->subWindowMode == IncludeInferiors) - { - prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable); - } - else - { - prgnDstClip = &rgnDstRec; - RegionNull(prgnDstClip); - RegionCopy(prgnDstClip, - &((WindowPtr)pDstDrawable)->clipList); - } - RegionTranslate(prgnDstClip, - -pDstDrawable->x, -pDstDrawable->y); - } - else - { - BoxRec box; - - box.x1 = 0; - box.y1 = 0; - box.x2 = pDstDrawable->width; - box.y2 = pDstDrawable->height; - prgnDstClip = &rgnDstRec; - RegionInit(prgnDstClip, &box, 1); - } - - /* drawable-relative source region */ - RegionInit(&rgnExposed, &srcBox, 1); - - /* now get the hidden parts of the source box*/ - RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip); - - /* move them over the destination */ - RegionTranslate(&rgnExposed, dstx-srcx, dsty-srcy); - - /* intersect with visible areas of dest */ - RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip); - - /* intersect with client clip region. */ - if (pGC->clientClipType == CT_REGION) - RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); - - /* - * If we have LOTS of rectangles, we decide to take the extents - * and force an exposure on that. This should require much less - * work overall, on both client and server. This is cheating, but - * isn't prohibited by the protocol ("spontaneous combustion" :-) - * for windows. - */ - extents = pGC->graphicsExposures && - (RegionNumRects(&rgnExposed) > RECTLIMIT) && - (pDstDrawable->type != DRAWABLE_PIXMAP); - if (pSrcWin) - { - RegionPtr region; - if (!(region = wClipShape (pSrcWin))) - region = wBoundingShape (pSrcWin); - /* - * If you try to CopyArea the extents of a shaped window, compacting the - * exposed region will undo all our work! - */ - if (extents && pSrcWin && region && - (RegionContainsRect(region, &srcBox) != rgnIN)) - extents = FALSE; - } - if (extents) - { - expBox = *RegionExtents(&rgnExposed); - RegionReset(&rgnExposed, &expBox); - } - if ((pDstDrawable->type != DRAWABLE_PIXMAP) && - (((WindowPtr)pDstDrawable)->backgroundState != None)) - { - WindowPtr pWin = (WindowPtr)pDstDrawable; - - /* make the exposed area screen-relative */ - RegionTranslate(&rgnExposed, - pDstDrawable->x, pDstDrawable->y); - - if (extents) - { - /* miPaintWindow doesn't clip, so we have to */ - RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); - } - miPaintWindow((WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND); - - if (extents) - { - RegionReset(&rgnExposed, &expBox); - } - else - RegionTranslate(&rgnExposed, - -pDstDrawable->x, -pDstDrawable->y); - } - if (prgnDstClip == &rgnDstRec) - { - RegionUninit(prgnDstClip); - } - else if (prgnDstClip != prgnSrcClip) - { - RegionDestroy(prgnDstClip); - } - - if (prgnSrcClip == &rgnSrcRec) - { - RegionUninit(prgnSrcClip); - } - else - { - RegionDestroy(prgnSrcClip); - } - - if (pGC->graphicsExposures) - { - /* don't look */ - RegionPtr exposed = RegionCreate(NullBox, 0); - *exposed = rgnExposed; - return exposed; - } - else - { - RegionUninit(&rgnExposed); - return NULL; - } -} - -/* send GraphicsExpose events, or a NoExpose event, based on the region */ - -void -miSendGraphicsExpose (ClientPtr client, RegionPtr pRgn, XID drawable, - int major, int minor) -{ - if (pRgn && !RegionNil(pRgn)) - { - xEvent *pEvent; - xEvent *pe; - BoxPtr pBox; - int i; - int numRects; - - numRects = RegionNumRects(pRgn); - pBox = RegionRects(pRgn); - if(!(pEvent = malloc(numRects * sizeof(xEvent)))) - return; - pe = pEvent; - - for (i=1; i<=numRects; i++, pe++, pBox++) - { - pe->u.u.type = GraphicsExpose; - pe->u.graphicsExposure.drawable = drawable; - pe->u.graphicsExposure.x = pBox->x1; - pe->u.graphicsExposure.y = pBox->y1; - pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; - pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; - pe->u.graphicsExposure.count = numRects - i; - pe->u.graphicsExposure.majorEvent = major; - pe->u.graphicsExposure.minorEvent = minor; - } - /* GraphicsExpose is a "critical event", which TryClientEvents - * handles specially. */ - TryClientEvents(client, NULL, pEvent, numRects, - (Mask)0, NoEventMask, NullGrab); - free(pEvent); - } - else - { - xEvent event; - memset(&event, 0, sizeof(xEvent)); - event.u.u.type = NoExpose; - event.u.noExposure.drawable = drawable; - event.u.noExposure.majorEvent = major; - event.u.noExposure.minorEvent = minor; - WriteEventsToClient(client, 1, &event); - } -} - - -void -miSendExposures( WindowPtr pWin, RegionPtr pRgn, int dx, int dy) -{ - BoxPtr pBox; - int numRects; - xEvent *pEvent, *pe; - int i; - - pBox = RegionRects(pRgn); - numRects = RegionNumRects(pRgn); - if(!(pEvent = calloc(1, numRects * sizeof(xEvent)))) - return; - - for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++) - { - pe->u.u.type = Expose; - pe->u.expose.window = pWin->drawable.id; - pe->u.expose.x = pBox->x1 - dx; - pe->u.expose.y = pBox->y1 - dy; - pe->u.expose.width = pBox->x2 - pBox->x1; - pe->u.expose.height = pBox->y2 - pBox->y1; - pe->u.expose.count = i; - } - -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - int scrnum = pWin->drawable.pScreen->myNum; - int x = 0, y = 0; - XID realWin = 0; - - if(!pWin->parent) { - x = screenInfo.screens[scrnum]->x; - y = screenInfo.screens[scrnum]->y; - pWin = screenInfo.screens[0]->root; - realWin = pWin->drawable.id; - } else if (scrnum) { - PanoramiXRes *win; - win = PanoramiXFindIDByScrnum(XRT_WINDOW, - pWin->drawable.id, scrnum); - if(!win) { - free(pEvent); - return; - } - realWin = win->info[0].id; - dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess); - } - if(x || y || scrnum) - for (i = 0; i < numRects; i++) { - pEvent[i].u.expose.window = realWin; - pEvent[i].u.expose.x += x; - pEvent[i].u.expose.y += y; - } - } -#endif - - DeliverEvents(pWin, pEvent, numRects, NullWindow); - - free(pEvent); -} - -void -miWindowExposures( WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed) -{ - RegionPtr exposures = prgn; - if ((prgn && !RegionNil(prgn)) || - (exposures && !RegionNil(exposures)) || other_exposed) - { - RegionRec expRec; - int clientInterested; - - /* - * Restore from backing-store FIRST. - */ - clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask; - if (other_exposed) - { - if (exposures) - { - RegionUnion(other_exposed, - exposures, - other_exposed); - if (exposures != prgn) - RegionDestroy(exposures); - } - exposures = other_exposed; - } - if (clientInterested && exposures && (RegionNumRects(exposures) > RECTLIMIT)) - { - /* - * If we have LOTS of rectangles, we decide to take the extents - * and force an exposure on that. This should require much less - * work overall, on both client and server. This is cheating, but - * isn't prohibited by the protocol ("spontaneous combustion" :-). - */ - BoxRec box; - - box = *RegionExtents(exposures); - if (exposures == prgn) { - exposures = &expRec; - RegionInit(exposures, &box, 1); - RegionReset(prgn, &box); - } else { - RegionReset(exposures, &box); - RegionUnion(prgn, prgn, exposures); - } - /* miPaintWindow doesn't clip, so we have to */ - RegionIntersect(prgn, prgn, &pWin->clipList); - } - if (prgn && !RegionNil(prgn)) - miPaintWindow(pWin, prgn, PW_BACKGROUND); - if (clientInterested && exposures && !RegionNil(exposures)) - miSendExposures(pWin, exposures, - pWin->drawable.x, pWin->drawable.y); - if (exposures == &expRec) - { - RegionUninit(exposures); - } - else if (exposures && exposures != prgn && exposures != other_exposed) - RegionDestroy(exposures); - if (prgn) - RegionEmpty(prgn); - } - else if (exposures && exposures != prgn) - RegionDestroy(exposures); -} - -#ifdef ROOTLESS -/* Ugly, ugly, but we lost our hooks into miPaintWindow... =/ */ -void RootlessSetPixmapOfAncestors(WindowPtr pWin); -void RootlessStartDrawing(WindowPtr pWin); -void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn); -Bool IsFramedWindow(WindowPtr pWin); -#endif - -void -miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - ChangeGCVal gcval[6]; - BITS32 gcmask; - GCPtr pGC; - int i; - BoxPtr pbox; - xRectangle *prect; - int numRects; - /* - * Distance from screen to destination drawable, use this - * to adjust rendering coordinates which come in in screen space - */ - int draw_x_off, draw_y_off; - /* - * Tile offset for drawing; these need to align the tile - * to the appropriate window origin - */ - int tile_x_off, tile_y_off; - PixUnion fill; - Bool solid = TRUE; - DrawablePtr drawable = &pWin->drawable; - -#ifdef ROOTLESS - if(!drawable || drawable->type == UNDRAWABLE_WINDOW) - return; - - if(IsFramedWindow(pWin)) { - RootlessStartDrawing(pWin); - RootlessDamageRegion(pWin, prgn); - - if(pWin->backgroundState == ParentRelative) { - if((what == PW_BACKGROUND) || - (what == PW_BORDER && !pWin->borderIsPixel)) - RootlessSetPixmapOfAncestors(pWin); - } - } -#endif - - if (what == PW_BACKGROUND) - { - while (pWin->backgroundState == ParentRelative) - pWin = pWin->parent; - - draw_x_off = drawable->x; - draw_y_off = drawable->y; - - tile_x_off = pWin->drawable.x - draw_x_off; - tile_y_off = pWin->drawable.y - draw_y_off; - fill = pWin->background; - switch (pWin->backgroundState) { - case None: - return; - case BackgroundPixmap: - solid = FALSE; - break; - } - } - else - { - PixmapPtr pixmap; - - tile_x_off = drawable->x; - tile_y_off = drawable->y; - - /* servers without pixmaps draw their own borders */ - if (!pScreen->GetWindowPixmap) - return; - pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); - drawable = &pixmap->drawable; -#ifdef COMPOSITE - draw_x_off = pixmap->screen_x; - draw_y_off = pixmap->screen_y; - tile_x_off -= draw_x_off; - tile_y_off -= draw_y_off; -#else - draw_x_off = 0; - draw_y_off = 0; -#endif - fill = pWin->border; - solid = pWin->borderIsPixel; - } - - gcval[0].val = GXcopy; - gcmask = GCFunction; - -#ifdef ROOTLESS_SAFEALPHA -/* Bit mask for alpha channel with a particular number of bits per - * pixel. Note that we only care for 32bpp data. Mac OS X uses planar - * alpha for 16bpp. - */ -#define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0) -#endif - - if (solid) - { -#ifdef ROOTLESS_SAFEALPHA - gcval[1].val = fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); -#else - gcval[1].val = fill.pixel; -#endif - gcval[2].val = FillSolid; - gcmask |= GCForeground | GCFillStyle; - } - else - { - int c=1; -#ifdef ROOTLESS_SAFEALPHA - gcval[c++].val = ((CARD32)-1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel); - gcmask |= GCPlaneMask; -#endif - gcval[c++].val = FillTiled; - gcval[c++].ptr = (pointer)fill.pixmap; - gcval[c++].val = tile_x_off; - gcval[c++].val = tile_y_off; - gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; - } - - prect = malloc(RegionNumRects(prgn) * sizeof(xRectangle)); - if (!prect) - return; - - pGC = GetScratchGC(drawable->depth, drawable->pScreen); - if (!pGC) - { - free(prect); - return; - } - - ChangeGC (NullClient, pGC, gcmask, gcval); - ValidateGC (drawable, pGC); - - numRects = RegionNumRects(prgn); - pbox = RegionRects(prgn); - for (i= numRects; --i >= 0; pbox++, prect++) - { - prect->x = pbox->x1 - draw_x_off; - prect->y = pbox->y1 - draw_y_off; - prect->width = pbox->x2 - pbox->x1; - prect->height = pbox->y2 - pbox->y1; - } - prect -= numRects; - (*pGC->ops->PolyFillRect)(drawable, pGC, numRects, prect); - free(prect); - - FreeScratchGC(pGC); -} - - -/* MICLEARDRAWABLE -- sets the entire drawable to the background color of - * the GC. Useful when we have a scratch drawable and need to initialize - * it. */ -void -miClearDrawable(DrawablePtr pDraw, GCPtr pGC) -{ - ChangeGCVal fg, bg; - xRectangle rect; - - fg.val = pGC->fgPixel; - bg.val = pGC->bgPixel; - rect.x = 0; - rect.y = 0; - rect.width = pDraw->width; - rect.height = pDraw->height; - ChangeGC(NullClient, pGC, GCForeground, &bg); - ValidateGC(pDraw, pGC); - (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect); - ChangeGC(NullClient, pGC, GCForeground, &fg); - ValidateGC(pDraw, pGC); -} +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/***************************************************************** + +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. + +******************************************************************/ + + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "misc.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmap.h" +#include "input.h" + +#include "dixstruct.h" +#include "mi.h" +#include + +#include "globals.h" + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif + +/* + machine-independent graphics exposure code. any device that uses +the region package can call this. +*/ + +#ifndef RECTLIMIT +#define RECTLIMIT 25 /* pick a number, any number > 8 */ +#endif + +/* miHandleExposures + generate a region for exposures for areas that were copied from obscured or +non-existent areas to non-obscured areas of the destination. Paint the +background for the region, if the destination is a window. + +NOTE: + this should generally be called, even if graphicsExposures is false, +because this is where bits get recovered from backing store. + +NOTE: + added argument 'plane' is used to indicate how exposures from backing +store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea +should be used, else a CopyPlane of the indicated plane will be used. The +exposing is done by the backing store's GraphicsExpose function, of course. + +*/ + +RegionPtr +miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, + GCPtr pGC, int srcx, int srcy, int width, int height, + int dstx, int dsty, unsigned long plane) +{ + RegionPtr prgnSrcClip; /* drawable-relative source clip */ + RegionRec rgnSrcRec; + RegionPtr prgnDstClip; /* drawable-relative dest clip */ + RegionRec rgnDstRec; + BoxRec srcBox; /* unclipped source */ + RegionRec rgnExposed; /* exposed region, calculated source- + relative, made dst relative to + intersect with visible parts of + dest and send events to client, + and then screen relative to paint + the window background + */ + WindowPtr pSrcWin; + BoxRec expBox; + Bool extents; + + /* avoid work if we can */ + if (!pGC->graphicsExposures && + (pDstDrawable->type == DRAWABLE_PIXMAP) && + ((pSrcDrawable->type == DRAWABLE_PIXMAP) || + (((WindowPtr)pSrcDrawable)->backStorage == NULL))) + return NULL; + + srcBox.x1 = srcx; + srcBox.y1 = srcy; + srcBox.x2 = srcx+width; + srcBox.y2 = srcy+height; + + if (pSrcDrawable->type != DRAWABLE_PIXMAP) + { + BoxRec TsrcBox; + + TsrcBox.x1 = srcx + pSrcDrawable->x; + TsrcBox.y1 = srcy + pSrcDrawable->y; + TsrcBox.x2 = TsrcBox.x1 + width; + TsrcBox.y2 = TsrcBox.y1 + height; + pSrcWin = (WindowPtr) pSrcDrawable; + if (pGC->subWindowMode == IncludeInferiors) + { + prgnSrcClip = NotClippedByChildren (pSrcWin); + if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) + { + RegionDestroy(prgnSrcClip); + return NULL; + } + } + else + { + if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN) + return NULL; + prgnSrcClip = &rgnSrcRec; + RegionNull(prgnSrcClip); + RegionCopy(prgnSrcClip, &pSrcWin->clipList); + } + RegionTranslate(prgnSrcClip, + -pSrcDrawable->x, -pSrcDrawable->y); + } + else + { + BoxRec box; + + if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && + (srcBox.x2 <= pSrcDrawable->width) && + (srcBox.y2 <= pSrcDrawable->height)) + return NULL; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pSrcDrawable->width; + box.y2 = pSrcDrawable->height; + prgnSrcClip = &rgnSrcRec; + RegionInit(prgnSrcClip, &box, 1); + pSrcWin = NULL; + } + + if (pDstDrawable == pSrcDrawable) + { + prgnDstClip = prgnSrcClip; + } + else if (pDstDrawable->type != DRAWABLE_PIXMAP) + { + if (pGC->subWindowMode == IncludeInferiors) + { + prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable); + } + else + { + prgnDstClip = &rgnDstRec; + RegionNull(prgnDstClip); + RegionCopy(prgnDstClip, + &((WindowPtr)pDstDrawable)->clipList); + } + RegionTranslate(prgnDstClip, + -pDstDrawable->x, -pDstDrawable->y); + } + else + { + BoxRec box; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pDstDrawable->width; + box.y2 = pDstDrawable->height; + prgnDstClip = &rgnDstRec; + RegionInit(prgnDstClip, &box, 1); + } + + /* drawable-relative source region */ + RegionInit(&rgnExposed, &srcBox, 1); + + /* now get the hidden parts of the source box*/ + RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip); + + /* move them over the destination */ + RegionTranslate(&rgnExposed, dstx-srcx, dsty-srcy); + + /* intersect with visible areas of dest */ + RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip); + + /* intersect with client clip region. */ + if (pGC->clientClipType == CT_REGION) + RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); + + /* + * If we have LOTS of rectangles, we decide to take the extents + * and force an exposure on that. This should require much less + * work overall, on both client and server. This is cheating, but + * isn't prohibited by the protocol ("spontaneous combustion" :-) + * for windows. + */ + extents = pGC->graphicsExposures && + (RegionNumRects(&rgnExposed) > RECTLIMIT) && + (pDstDrawable->type != DRAWABLE_PIXMAP); + if (pSrcWin) + { + RegionPtr region; + if (!(region = wClipShape (pSrcWin))) + region = wBoundingShape (pSrcWin); + /* + * If you try to CopyArea the extents of a shaped window, compacting the + * exposed region will undo all our work! + */ + if (extents && pSrcWin && region && + (RegionContainsRect(region, &srcBox) != rgnIN)) + extents = FALSE; + } + if (extents) + { + expBox = *RegionExtents(&rgnExposed); + RegionReset(&rgnExposed, &expBox); + } + if ((pDstDrawable->type != DRAWABLE_PIXMAP) && + (((WindowPtr)pDstDrawable)->backgroundState != None)) + { + WindowPtr pWin = (WindowPtr)pDstDrawable; + + /* make the exposed area screen-relative */ + RegionTranslate(&rgnExposed, + pDstDrawable->x, pDstDrawable->y); + + if (extents) + { + /* miPaintWindow doesn't clip, so we have to */ + RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); + } + miPaintWindow((WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND); + + if (extents) + { + RegionReset(&rgnExposed, &expBox); + } + else + RegionTranslate(&rgnExposed, + -pDstDrawable->x, -pDstDrawable->y); + } + if (prgnDstClip == &rgnDstRec) + { + RegionUninit(prgnDstClip); + } + else if (prgnDstClip != prgnSrcClip) + { + RegionDestroy(prgnDstClip); + } + + if (prgnSrcClip == &rgnSrcRec) + { + RegionUninit(prgnSrcClip); + } + else + { + RegionDestroy(prgnSrcClip); + } + + if (pGC->graphicsExposures) + { + /* don't look */ + RegionPtr exposed = RegionCreate(NullBox, 0); + *exposed = rgnExposed; + return exposed; + } + else + { + RegionUninit(&rgnExposed); + return NULL; + } +} + +/* send GraphicsExpose events, or a NoExpose event, based on the region */ + +void +miSendGraphicsExpose (ClientPtr client, RegionPtr pRgn, XID drawable, + int major, int minor) +{ + if (pRgn && !RegionNil(pRgn)) + { + xEvent *pEvent; + xEvent *pe; + BoxPtr pBox; + int i; + int numRects; + + numRects = RegionNumRects(pRgn); + pBox = RegionRects(pRgn); + if(!(pEvent = malloc(numRects * sizeof(xEvent)))) + return; + pe = pEvent; + + for (i=1; i<=numRects; i++, pe++, pBox++) + { + pe->u.u.type = GraphicsExpose; + pe->u.graphicsExposure.drawable = drawable; + pe->u.graphicsExposure.x = pBox->x1; + pe->u.graphicsExposure.y = pBox->y1; + pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; + pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; + pe->u.graphicsExposure.count = numRects - i; + pe->u.graphicsExposure.majorEvent = major; + pe->u.graphicsExposure.minorEvent = minor; + } + /* GraphicsExpose is a "critical event", which TryClientEvents + * handles specially. */ + TryClientEvents(client, NULL, pEvent, numRects, + (Mask)0, NoEventMask, NullGrab); + free(pEvent); + } + else + { + xEvent event; + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = NoExpose; + event.u.noExposure.drawable = drawable; + event.u.noExposure.majorEvent = major; + event.u.noExposure.minorEvent = minor; + WriteEventsToClient(client, 1, &event); + } +} + + +void +miSendExposures( WindowPtr pWin, RegionPtr pRgn, int dx, int dy) +{ + BoxPtr pBox; + int numRects; + xEvent *pEvent, *pe; + int i; + + pBox = RegionRects(pRgn); + numRects = RegionNumRects(pRgn); + if(!(pEvent = calloc(1, numRects * sizeof(xEvent)))) + return; + + for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++) + { + pe->u.u.type = Expose; + pe->u.expose.window = pWin->drawable.id; + pe->u.expose.x = pBox->x1 - dx; + pe->u.expose.y = pBox->y1 - dy; + pe->u.expose.width = pBox->x2 - pBox->x1; + pe->u.expose.height = pBox->y2 - pBox->y1; + pe->u.expose.count = i; + } + +#ifdef PANORAMIX + if(!noPanoramiXExtension) { + int scrnum = pWin->drawable.pScreen->myNum; + int x = 0, y = 0; + XID realWin = 0; + + if(!pWin->parent) { + x = screenInfo.screens[scrnum]->x; + y = screenInfo.screens[scrnum]->y; + pWin = screenInfo.screens[0]->root; + realWin = pWin->drawable.id; + } else if (scrnum) { + PanoramiXRes *win; + win = PanoramiXFindIDByScrnum(XRT_WINDOW, + pWin->drawable.id, scrnum); + if(!win) { + free(pEvent); + return; + } + realWin = win->info[0].id; + dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess); + } + if(x || y || scrnum) + for (i = 0; i < numRects; i++) { + pEvent[i].u.expose.window = realWin; + pEvent[i].u.expose.x += x; + pEvent[i].u.expose.y += y; + } + } +#endif + + DeliverEvents(pWin, pEvent, numRects, NullWindow); + + free(pEvent); +} + +void +miWindowExposures( WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed) +{ + RegionPtr exposures = prgn; + if ((prgn && !RegionNil(prgn)) || + (exposures && !RegionNil(exposures)) || other_exposed) + { + RegionRec expRec; + int clientInterested; + + /* + * Restore from backing-store FIRST. + */ + clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask; + if (other_exposed) + { + if (exposures) + { + RegionUnion(other_exposed, + exposures, + other_exposed); + if (exposures != prgn) + RegionDestroy(exposures); + } + exposures = other_exposed; + } + if (clientInterested && exposures && (RegionNumRects(exposures) > RECTLIMIT)) + { + /* + * If we have LOTS of rectangles, we decide to take the extents + * and force an exposure on that. This should require much less + * work overall, on both client and server. This is cheating, but + * isn't prohibited by the protocol ("spontaneous combustion" :-). + */ + BoxRec box; + + box = *RegionExtents(exposures); + if (exposures == prgn) { + exposures = &expRec; + RegionInit(exposures, &box, 1); + RegionReset(prgn, &box); + } else { + RegionReset(exposures, &box); + RegionUnion(prgn, prgn, exposures); + } + /* miPaintWindow doesn't clip, so we have to */ + RegionIntersect(prgn, prgn, &pWin->clipList); + } + if (prgn && !RegionNil(prgn)) + miPaintWindow(pWin, prgn, PW_BACKGROUND); + if (clientInterested && exposures && !RegionNil(exposures)) + miSendExposures(pWin, exposures, + pWin->drawable.x, pWin->drawable.y); + if (exposures == &expRec) + { + RegionUninit(exposures); + } + else if (exposures && exposures != prgn && exposures != other_exposed) + RegionDestroy(exposures); + if (prgn) + RegionEmpty(prgn); + } + else if (exposures && exposures != prgn) + RegionDestroy(exposures); +} + +#ifdef ROOTLESS +/* Ugly, ugly, but we lost our hooks into miPaintWindow... =/ */ +void RootlessSetPixmapOfAncestors(WindowPtr pWin); +void RootlessStartDrawing(WindowPtr pWin); +void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn); +Bool IsFramedWindow(WindowPtr pWin); +#endif + +void +miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + ChangeGCVal gcval[6]; + BITS32 gcmask; + GCPtr pGC; + int i; + BoxPtr pbox; + xRectangle *prect; + int numRects; + /* + * Distance from screen to destination drawable, use this + * to adjust rendering coordinates which come in in screen space + */ + int draw_x_off, draw_y_off; + /* + * Tile offset for drawing; these need to align the tile + * to the appropriate window origin + */ + int tile_x_off, tile_y_off; + PixUnion fill; + Bool solid = TRUE; + DrawablePtr drawable = &pWin->drawable; + +#ifdef ROOTLESS + if(!drawable || drawable->type == UNDRAWABLE_WINDOW) + return; + + if(IsFramedWindow(pWin)) { + RootlessStartDrawing(pWin); + RootlessDamageRegion(pWin, prgn); + + if(pWin->backgroundState == ParentRelative) { + if((what == PW_BACKGROUND) || + (what == PW_BORDER && !pWin->borderIsPixel)) + RootlessSetPixmapOfAncestors(pWin); + } + } +#endif + + if (what == PW_BACKGROUND) + { + while (pWin->backgroundState == ParentRelative) + pWin = pWin->parent; + + draw_x_off = drawable->x; + draw_y_off = drawable->y; + + tile_x_off = pWin->drawable.x - draw_x_off; + tile_y_off = pWin->drawable.y - draw_y_off; + fill = pWin->background; +#ifdef COMPOSITE + if (pWin->inhibitBGPaint) + return; +#endif + switch (pWin->backgroundState) { + case None: + return; + case BackgroundPixmap: + solid = FALSE; + break; + } + } + else + { + PixmapPtr pixmap; + + tile_x_off = drawable->x; + tile_y_off = drawable->y; + + /* servers without pixmaps draw their own borders */ + if (!pScreen->GetWindowPixmap) + return; + pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); + drawable = &pixmap->drawable; +#ifdef COMPOSITE + draw_x_off = pixmap->screen_x; + draw_y_off = pixmap->screen_y; + tile_x_off -= draw_x_off; + tile_y_off -= draw_y_off; +#else + draw_x_off = 0; + draw_y_off = 0; +#endif + fill = pWin->border; + solid = pWin->borderIsPixel; + } + + gcval[0].val = GXcopy; + gcmask = GCFunction; + +#ifdef ROOTLESS_SAFEALPHA +/* Bit mask for alpha channel with a particular number of bits per + * pixel. Note that we only care for 32bpp data. Mac OS X uses planar + * alpha for 16bpp. + */ +#define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0) +#endif + + if (solid) + { +#ifdef ROOTLESS_SAFEALPHA + gcval[1].val = fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); +#else + gcval[1].val = fill.pixel; +#endif + gcval[2].val = FillSolid; + gcmask |= GCForeground | GCFillStyle; + } + else + { + int c=1; +#ifdef ROOTLESS_SAFEALPHA + gcval[c++].val = ((CARD32)-1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel); + gcmask |= GCPlaneMask; +#endif + gcval[c++].val = FillTiled; + gcval[c++].ptr = (pointer)fill.pixmap; + gcval[c++].val = tile_x_off; + gcval[c++].val = tile_y_off; + gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; + } + + prect = malloc(RegionNumRects(prgn) * sizeof(xRectangle)); + if (!prect) + return; + + pGC = GetScratchGC(drawable->depth, drawable->pScreen); + if (!pGC) + { + free(prect); + return; + } + + ChangeGC (NullClient, pGC, gcmask, gcval); + ValidateGC (drawable, pGC); + + numRects = RegionNumRects(prgn); + pbox = RegionRects(prgn); + for (i= numRects; --i >= 0; pbox++, prect++) + { + prect->x = pbox->x1 - draw_x_off; + prect->y = pbox->y1 - draw_y_off; + prect->width = pbox->x2 - pbox->x1; + prect->height = pbox->y2 - pbox->y1; + } + prect -= numRects; + (*pGC->ops->PolyFillRect)(drawable, pGC, numRects, prect); + free(prect); + + FreeScratchGC(pGC); +} + + +/* MICLEARDRAWABLE -- sets the entire drawable to the background color of + * the GC. Useful when we have a scratch drawable and need to initialize + * it. */ +void +miClearDrawable(DrawablePtr pDraw, GCPtr pGC) +{ + ChangeGCVal fg, bg; + xRectangle rect; + + fg.val = pGC->fgPixel; + bg.val = pGC->bgPixel; + rect.x = 0; + rect.y = 0; + rect.width = pDraw->width; + rect.height = pDraw->height; + ChangeGC(NullClient, pGC, GCForeground, &bg); + ValidateGC(pDraw, pGC); + (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect); + ChangeGC(NullClient, pGC, GCForeground, &fg); + ValidateGC(pDraw, pGC); +} -- cgit v1.2.3