From 25b9dbb15f0dc98cfc6b5585e7efebf3250f64d3 Mon Sep 17 00:00:00 2001 From: marha Date: Tue, 7 Dec 2010 15:49:06 +0000 Subject: xserver pixman git update 7-12-2010 --- xorg-server/randr/Makefile.am | 6 +- xorg-server/randr/mirrcrtc.c | 174 ++++++ xorg-server/randr/randr.c | 15 + xorg-server/randr/randrstr.h | 207 ++++++- xorg-server/randr/rrcrtc.c | 562 +++++++++++++++++-- xorg-server/randr/rrdispatch.c | 6 + xorg-server/randr/rrinfo.c | 2 +- xorg-server/randr/rrpixmap.c | 154 ++++++ xorg-server/randr/rrscreen.c | 32 +- xorg-server/randr/rrsdispatch.c | 1138 ++++++++++++++++++++++----------------- xorg-server/randr/rrsprite.c | 104 ++++ xorg-server/randr/rrtransform.c | 64 ++- xorg-server/randr/rrtransform.h | 161 +++--- 13 files changed, 1955 insertions(+), 670 deletions(-) create mode 100644 xorg-server/randr/mirrcrtc.c create mode 100644 xorg-server/randr/rrpixmap.c create mode 100644 xorg-server/randr/rrsprite.c (limited to 'xorg-server/randr') diff --git a/xorg-server/randr/Makefile.am b/xorg-server/randr/Makefile.am index 4842df89c..2b0b3a984 100644 --- a/xorg-server/randr/Makefile.am +++ b/xorg-server/randr/Makefile.am @@ -16,12 +16,16 @@ librandr_la_SOURCES = \ rrinfo.c \ rrmode.c \ rroutput.c \ + rrpixmap.c \ rrpointer.c \ rrproperty.c \ rrscreen.c \ rrsdispatch.c \ + rrsprite.c \ rrtransform.h \ - rrtransform.c + rrtransform.c \ + mirrcrtc.c + if XINERAMA librandr_la_SOURCES += ${XINERAMA_SRCS} diff --git a/xorg-server/randr/mirrcrtc.c b/xorg-server/randr/mirrcrtc.c new file mode 100644 index 000000000..812b2b68b --- /dev/null +++ b/xorg-server/randr/mirrcrtc.c @@ -0,0 +1,174 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "randrstr.h" + +Bool +miRRSetScreenConfig(ScreenPtr screen, + RRScreenConfigPtr screen_config) +{ + RRScreenConfigRec old_screen_config; + + RRScreenCurrentConfig(screen, &old_screen_config); + + /* Check and see if nothing has changed */ + if (old_screen_config.screen_width == screen_config->screen_width && + old_screen_config.screen_height == screen_config->screen_height && + old_screen_config.screen_pixmap_width == screen_config->screen_pixmap_width && + old_screen_config.screen_pixmap_height == screen_config->screen_pixmap_height && + old_screen_config.mm_width == screen_config->mm_width && + old_screen_config.mm_height == screen_config->mm_height) + return TRUE; + + return RRScreenSizeSet(screen, + screen_config->screen_width, + screen_config->screen_height, + screen_config->screen_pixmap_width, + screen_config->screen_pixmap_height, + screen_config->mm_width, + screen_config->mm_height); +} + +Bool +miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config) +{ + int x = crtc_config->x, y = crtc_config->y; + + if (crtc_config->pixmap) { + x = crtc_config->pixmap_x; + y = crtc_config->pixmap_y; + } + if (!RRCrtcSet(crtc_config->crtc, + crtc_config->mode, + x, + y, + crtc_config->rotation, + crtc_config->numOutputs, + crtc_config->outputs, + crtc_config->pixmap)) + return FALSE; + RRCrtcSpriteTransformSet(crtc_config->crtc, + &crtc_config->sprite_position_transform, + &crtc_config->sprite_image_transform, + &crtc_config->sprite_position_f_transform, + &crtc_config->sprite_image_f_transform); + return TRUE; +} + +Bool +miRRDisableCrtc(RRCrtcPtr crtc) +{ + RRCrtcConfigRec off_config; + + memset(&off_config, '\0', sizeof (RRCrtcConfigRec)); + off_config.crtc = crtc; + return miRRSetCrtcConfig(&off_config); +} + +/* + * If the current crtc configuration doesn't fit + * with the new screen config, disable it + */ +Bool +miRRCheckDisableCrtc(RRScreenConfigPtr new_screen_config, + RRCrtcConfigPtr old_crtc_config) +{ + RRCrtcPtr crtc = old_crtc_config->crtc; + + /* If it's already disabled, we're done */ + if (!old_crtc_config->mode) + return TRUE; + + /* If the crtc isn't scanning from the screen pixmap, + * we're done + */ + if (old_crtc_config->pixmap) + return TRUE; + + /* If the new screen configuration covers the existing CRTC space, + * we're done + */ + if (RRScreenCoversCrtc(new_screen_config, old_crtc_config, + &crtc->client_current_transform, NULL)) + return TRUE; + + /* Disable the crtc and let it get re-enabled */ + return miRRDisableCrtc(crtc); +} + +Bool +miRRSetCrtcConfigs(ScreenPtr screen, + RRScreenConfigPtr screen_config, + RRCrtcConfigPtr crtc_configs, + int num_configs) +{ + RRScreenConfigRec old_screen_config; + RRCrtcConfigPtr old_crtc_configs; + int i; + + /* + * Save existing state + */ + + RRScreenCurrentConfig(screen, &old_screen_config); + old_crtc_configs = calloc(num_configs, sizeof (RRCrtcConfigRec)); + if (!old_crtc_configs) + return FALSE; + + for (i = 0; i < num_configs; i++) + if (!RRCrtcCurrentConfig(crtc_configs[i].crtc, &old_crtc_configs[i])) + goto fail_save; + /* + * Set the new configuration. If anything goes wrong, + * bail and restore the old configuration + */ + for (i = 0; i < num_configs; i++) + if (!miRRCheckDisableCrtc(screen_config, &old_crtc_configs[i])) + goto fail_disable; + + if (!miRRSetScreenConfig(screen, screen_config)) + goto fail_set_screen; + + for (i = 0; i < num_configs; i++) + if (!miRRSetCrtcConfig(&crtc_configs[i])) + goto fail_set_crtc; + + RRFreeCrtcConfigs(old_crtc_configs, num_configs); + return TRUE; + +fail_set_crtc: + /* + * Restore the previous configuration. Ignore any errors + * as we just need to hope that the driver can manage to + * get back to the previous state without trouble. + */ + for (i = 0; i < num_configs; i++) + (void) miRRDisableCrtc(old_crtc_configs[i].crtc); + (void) miRRSetScreenConfig(screen, &old_screen_config); +fail_set_screen: +fail_disable: + for (i = 0; i < num_configs; i++) + (void) miRRSetCrtcConfig(&old_crtc_configs[i]); +fail_save: + RRFreeCrtcConfigs(old_crtc_configs, num_configs); + return FALSE; +} diff --git a/xorg-server/randr/randr.c b/xorg-server/randr/randr.c index aa1e71dcf..1346d1e9c 100644 --- a/xorg-server/randr/randr.c +++ b/xorg-server/randr/randr.c @@ -98,6 +98,7 @@ RRCloseScreen (int i, ScreenPtr pScreen) free(pScrPriv->crtcs); free(pScrPriv->outputs); + free(pScrPriv->scanout_info); free(pScrPriv); RRNScreens -= 1; /* ok, one fewer screen with RandR running */ return (*pScreen->CloseScreen) (i, pScreen); @@ -248,6 +249,8 @@ Bool RRScreenInit(ScreenPtr pScreen) pScrPriv->rrCrtcSet = NULL; pScrPriv->rrCrtcSetGamma = NULL; #endif + pScrPriv->scanout_info = NULL; + pScrPriv->n_scanout_info = 0; #if RANDR_10_INTERFACE pScrPriv->rrSetConfig = 0; pScrPriv->rotations = RR_Rotate_0; @@ -482,6 +485,18 @@ RRVerticalRefresh (xRRModeInfo *mode) return (CARD16) refresh; } +RRScanoutPixmapInfo * +RRQueryScanoutPixmapInfo(ScreenPtr screen, int *n_info) +{ + rrScrPriv(screen); + + if (!pScrPriv->scanout_info && pScrPriv->rrQueryScanoutPixmaps) + pScrPriv->scanout_info = pScrPriv->rrQueryScanoutPixmaps(screen, + &pScrPriv->n_scanout_info); + *n_info = pScrPriv->n_scanout_info; + return pScrPriv->scanout_info; +} + static int ProcRRDispatch (ClientPtr client) { diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h index b4acfe12a..ee208f569 100644 --- a/xorg-server/randr/randrstr.h +++ b/xorg-server/randr/randrstr.h @@ -55,9 +55,10 @@ #define RANDR_10_INTERFACE 1 #define RANDR_12_INTERFACE 1 #define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */ +#define RANDR_14_INTERFACE 1 /* requires RANDR_13_INTERFACE */ #define RANDR_GET_CRTC_INTERFACE 1 -#define RANDR_INTERFACE_VERSION 0x0103 +#define RANDR_INTERFACE_VERSION 0x0104 typedef XID RRMode; typedef XID RROutput; @@ -77,6 +78,8 @@ typedef struct _rrMode RRModeRec, *RRModePtr; typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr; typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr; typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; +typedef struct _rrScreenConfig RRScreenConfigRec, *RRScreenConfigPtr; +typedef struct _rrCrtcConfig RRCrtcConfigRec, *RRCrtcConfigPtr; typedef struct _rrOutput RROutputRec, *RROutputPtr; struct _rrMode { @@ -120,11 +123,43 @@ struct _rrCrtc { CARD16 *gammaGreen; void *devPrivate; Bool transforms; + PixmapPtr scanoutPixmap; RRTransformRec client_pending_transform; RRTransformRec client_current_transform; + PictTransform client_sprite_position_transform; + PictTransform client_sprite_image_transform; + struct pict_f_transform client_sprite_f_position_transform; + struct pict_f_transform client_sprite_f_image_transform; + PictTransform transform; struct pict_f_transform f_transform; struct pict_f_transform f_inverse; + struct pict_f_transform f_sprite_position; /* crtc from screen */ + struct pict_f_transform f_sprite_image_inverse; /* image from crtc */ +}; + +struct _rrScreenConfig { + CARD16 screen_pixmap_width; + CARD16 screen_pixmap_height; + CARD16 screen_width; + CARD16 screen_height; + CARD32 mm_width; + CARD32 mm_height; +}; + +struct _rrCrtcConfig { + RRCrtcPtr crtc; + int x, y; + RRModePtr mode; + Rotation rotation; + int numOutputs; + RROutputPtr *outputs; + PictTransform sprite_position_transform; + PictTransform sprite_image_transform; + struct pict_f_transform sprite_position_f_transform; + struct pict_f_transform sprite_image_f_transform; + PixmapPtr pixmap; + int pixmap_x, pixmap_y; }; struct _rrOutput { @@ -156,6 +191,8 @@ struct _rrOutput { typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, CARD16 width, CARD16 height, + CARD16 pixWidth, + CARD16 pixHeight, CARD32 mmWidth, CARD32 mmHeight); @@ -166,7 +203,8 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, int y, Rotation rotation, int numOutputs, - RROutputPtr *outputs); + RROutputPtr *outputs, + PixmapPtr scanout_pixmap); typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc); @@ -232,6 +270,35 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, #endif +typedef struct { + PictFormatPtr format; + int maxWidth, maxHeight; + int depth; + Rotation rotations; +} RRScanoutPixmapInfo; + +typedef RRScanoutPixmapInfo *(*RRQueryScanoutPixmapsPtr) (ScreenPtr pScreen, + int *num_info); + +typedef PixmapPtr (*RRCreateScanoutPixmapPtr) (ScreenPtr pScreen, + int width, int height, int depth, + Rotation rotations, + PictFormatPtr format); + +typedef void (*RRSetCrtcSpriteTransformPtr) (ScreenPtr pScreen, + RRCrtcPtr randr_crtc, + struct pict_f_transform *position_transform, + struct pict_f_transform *image_transform); + +typedef void (*RRGetCrtcSpriteTransformPtr) (ScreenPtr pScreen, + RRCrtcPtr randr_crtc, + struct pict_f_transform *position_transform, + struct pict_f_transform *image_transform); + +typedef Bool (*RRSetCrtcConfigsPtr) (ScreenPtr screen, + RRScreenConfigPtr screen_config, + RRCrtcConfigPtr crtc_configs, + int num_configs); typedef struct _rrScrPriv { /* @@ -256,7 +323,12 @@ typedef struct _rrScrPriv { RRGetPanningProcPtr rrGetPanning; RRSetPanningProcPtr rrSetPanning; #endif - + RRQueryScanoutPixmapsPtr rrQueryScanoutPixmaps; + RRCreateScanoutPixmapPtr rrCreateScanoutPixmap; + RRSetCrtcSpriteTransformPtr rrSetCrtcSpriteTransform; + RRGetCrtcSpriteTransformPtr rrGetCrtcSpriteTransform; + RRSetCrtcConfigsPtr rrSetCrtcConfigs; + /* * Private part of the structure; not considered part of the ABI */ @@ -283,6 +355,8 @@ typedef struct _rrScrPriv { /* Last known pointer position */ RRCrtcPtr pointerCrtc; + RRScanoutPixmapInfo *scanout_info; + int n_scanout_info; #ifdef RANDR_10_INTERFACE /* * Configuration information @@ -297,6 +371,7 @@ typedef struct _rrScrPriv { int rate; int size; #endif + } rrScrPrivRec, *rrScrPrivPtr; extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec; @@ -405,9 +480,15 @@ extern _X_EXPORT Bool RRScreenSizeSet (ScreenPtr pScreen, CARD16 width, CARD16 height, + CARD16 pixWidth, + CARD16 pixHeight, CARD32 mmWidth, CARD32 mmHeight); +extern _X_EXPORT void +RRScreenCurrentConfig(ScreenPtr screen, + RRScreenConfigPtr screen_config); + /* * Send ConfigureNotify event to root window when 'something' happens */ @@ -467,6 +548,9 @@ RRGetRotation (ScreenPtr pScreen); extern _X_EXPORT CARD16 RRVerticalRefresh (xRRModeInfo *mode); +extern _X_EXPORT RRScanoutPixmapInfo * +RRQueryScanoutPixmapInfo(ScreenPtr screen, int *n_info); + #ifdef RANDR_10_INTERFACE /* * This is the old interface, deprecated but left @@ -545,7 +629,8 @@ RRCrtcNotify (RRCrtcPtr crtc, Rotation rotation, RRTransformPtr transform, int numOutputs, - RROutputPtr *outputs); + RROutputPtr *outputs, + PixmapPtr scanoutPixmap); extern _X_EXPORT void RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc); @@ -560,7 +645,8 @@ RRCrtcSet (RRCrtcPtr crtc, int y, Rotation rotation, int numOutput, - RROutputPtr *outputs); + RROutputPtr *outputs, + PixmapPtr scanout_pixmap); /* * Request that the Crtc gamma be changed @@ -589,6 +675,10 @@ RRCrtcGammaGet(RRCrtcPtr crtc); extern _X_EXPORT Bool RRCrtcGammaNotify (RRCrtcPtr crtc); +void +RRModeGetScanoutSize (RRModePtr mode, struct pixman_f_transform *transform, + int *width, int *height); + /* * Set the size of the gamma table at server startup time */ @@ -605,25 +695,6 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc, extern _X_EXPORT void RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height); -/* - * Compute the complete transformation matrix including - * client-specified transform, rotation/reflection values and the crtc - * offset. - * - * Return TRUE if the resulting transform is not a simple translation. - */ -extern _X_EXPORT Bool -RRTransformCompute (int x, - int y, - int width, - int height, - Rotation rotation, - RRTransformPtr rr_transform, - - PictTransformPtr transform, - struct pict_f_transform *f_transform, - struct pict_f_transform *f_inverse); - /* * Return crtc transform */ @@ -669,6 +740,38 @@ RRCrtcInit (void); extern _X_EXPORT void RRCrtcInitErrorValue (void); +/* + * Free a set of crtc configs and their attached output arrays + */ +void +RRFreeCrtcConfigs(RRCrtcConfigPtr configs, int num_configs); + +/* + * Convert the current crtc configuration into an RRCrtcConfig + */ +extern _X_EXPORT Bool +RRCrtcCurrentConfig(RRCrtcPtr crtc, + RRCrtcConfigPtr crtc_config); + +/* + * Figure out whether the specific crtc_config can fit + * within the screen_config + */ +Bool +RRScreenCoversCrtc(RRScreenConfigPtr screen_config, + RRCrtcConfigPtr crtc_config, + RRTransformPtr client_transform, + XID *errorValue); + +/* + * Set a screen and set of crtc configurations in one operation + */ +Bool +RRSetCrtcConfigs(ScreenPtr screen, + RRScreenConfigPtr screen_config, + RRCrtcConfigPtr crtc_configs, + int num_configs); + /* * Crtc dispatch */ @@ -694,12 +797,40 @@ ProcRRSetCrtcTransform (ClientPtr client); extern _X_EXPORT int ProcRRGetCrtcTransform (ClientPtr client); +extern _X_EXPORT int +ProcRRSetCrtcConfigs (ClientPtr client); + int ProcRRGetPanning (ClientPtr client); int ProcRRSetPanning (ClientPtr client); +void +RRCrtcSpriteTransformSet(RRCrtcPtr crtc, + PictTransform *position_transform, + PictTransform *image_transform, + struct pict_f_transform *f_position_transform, + struct pict_f_transform *f_image_transform); + +int +ProcRRQueryScanoutPixmaps (ClientPtr client); + +int +ProcRRCreateScanoutPixmap (ClientPtr client); + +int +ProcRRSetCrtcPixmapConfig (ClientPtr client); + +int +ProcRRSetCrtcSpriteTransform (ClientPtr client); + +int +ProcRRGetCrtcSpriteTransform (ClientPtr client); + +int +ProcRRSetCrtcConfigs (ClientPtr client); + /* rrdispatch.c */ extern _X_EXPORT Bool RRClientKnowsRates (ClientPtr pClient); @@ -889,12 +1020,40 @@ ProcRRConfigureOutputProperty (ClientPtr client); extern _X_EXPORT int ProcRRDeleteOutputProperty (ClientPtr client); +/* rrsprite.c */ +extern _X_EXPORT int +ProcRRSetCrtcSpriteTransform (ClientPtr client); + +extern _X_EXPORT int +ProcRRGetCrtcSpriteTransform (ClientPtr client); + /* rrxinerama.c */ #ifdef XINERAMA extern _X_EXPORT void RRXineramaExtensionInit(void); #endif +/* mirrcrtc.c */ +Bool +miRRSetScreenConfig(ScreenPtr screen, + RRScreenConfigPtr screen_config); + +Bool +miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config); + +Bool +miRRDisableCrtc(RRCrtcPtr crtc); + +Bool +miRRCheckDisableCrtc(RRScreenConfigPtr new_screen_config, + RRCrtcConfigPtr old_crtc_config); + +Bool +miRRSetCrtcConfigs(ScreenPtr screen, + RRScreenConfigPtr screen_config, + RRCrtcConfigPtr crtc_configs, + int num_configs); + #endif /* _RANDRSTR_H_ */ /* diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c index fba9f4805..524fcd266 100644 --- a/xorg-server/randr/rrcrtc.c +++ b/xorg-server/randr/rrcrtc.c @@ -37,7 +37,7 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged) if (pScreen) { rrScrPriv(pScreen); - + pScrPriv->changed = TRUE; /* * Send ConfigureNotify on any layout change @@ -59,19 +59,19 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate) if (!RRInit()) return NULL; - + pScrPriv = rrGetScrPriv(pScreen); /* make space for the crtc pointer */ if (pScrPriv->numCrtcs) - crtcs = realloc(pScrPriv->crtcs, + crtcs = realloc(pScrPriv->crtcs, (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); else crtcs = malloc(sizeof (RRCrtcPtr)); if (!crtcs) return FALSE; pScrPriv->crtcs = crtcs; - + crtc = calloc(1, sizeof (RRCrtcRec)); if (!crtc) return NULL; @@ -90,9 +90,13 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate) crtc->devPrivate = devPrivate; RRTransformInit (&crtc->client_pending_transform); RRTransformInit (&crtc->client_current_transform); + pixman_transform_init_identity (&crtc->client_sprite_position_transform); + pixman_transform_init_identity (&crtc->client_sprite_image_transform); pixman_transform_init_identity (&crtc->transform); pixman_f_transform_init_identity (&crtc->f_transform); pixman_f_transform_init_identity (&crtc->f_inverse); + pixman_f_transform_init_identity (&crtc->f_sprite_position); + pixman_f_transform_init_identity (&crtc->f_sprite_image_inverse); if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) return NULL; @@ -100,7 +104,7 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate) /* attach the screen and crtc together */ crtc->pScreen = pScreen; pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; - + return crtc; } @@ -134,10 +138,11 @@ RRCrtcNotify (RRCrtcPtr crtc, Rotation rotation, RRTransformPtr transform, int numOutputs, - RROutputPtr *outputs) + RROutputPtr *outputs, + PixmapPtr scanoutPixmap) { int i, j; - + /* * Check to see if any of the new outputs were * not in the old list and mark them as changed @@ -177,7 +182,7 @@ RRCrtcNotify (RRCrtcPtr crtc, if (numOutputs != crtc->numOutputs) { RROutputPtr *newoutputs; - + if (numOutputs) { if (crtc->numOutputs) @@ -231,15 +236,30 @@ RRCrtcNotify (RRCrtcPtr crtc, RRTransformCopy (&crtc->client_current_transform, transform); RRCrtcChanged (crtc, TRUE); } + + if (scanoutPixmap != crtc->scanoutPixmap) + { + if (scanoutPixmap) + ++scanoutPixmap->refcnt; + if (crtc->scanoutPixmap) + (*crtc->scanoutPixmap->drawable.pScreen->DestroyPixmap) (crtc->scanoutPixmap); + crtc->scanoutPixmap = scanoutPixmap; + } + if (crtc->changed && mode) { RRTransformCompute (x, y, mode->mode.width, mode->mode.height, rotation, &crtc->client_current_transform, + &crtc->client_sprite_f_position_transform, + &crtc->client_sprite_f_image_transform, &crtc->transform, &crtc->f_transform, - &crtc->f_inverse); + &crtc->f_inverse, &crtc->f_sprite_position, + &crtc->f_sprite_image_inverse, + NULL); } + return TRUE; } @@ -250,7 +270,7 @@ RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) rrScrPriv (pScreen); xRRCrtcChangeNotifyEvent ce; RRModePtr mode = crtc->mode; - + ce.type = RRNotify + RREventBase; ce.subCode = RRNotify_CrtcChange; ce.timestamp = pScrPriv->lastSetTime.milliseconds; @@ -302,7 +322,8 @@ RRCrtcSet (RRCrtcPtr crtc, int y, Rotation rotation, int numOutputs, - RROutputPtr *outputs) + RROutputPtr *outputs, + PixmapPtr scanout_pixmap) { ScreenPtr pScreen = crtc->pScreen; Bool ret = FALSE; @@ -316,7 +337,8 @@ RRCrtcSet (RRCrtcPtr crtc, crtc->numOutputs == numOutputs && !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) && !RRCrtcPendingProperties (crtc) && - !RRCrtcPendingTransform (crtc)) + !RRCrtcPendingTransform (crtc) && + crtc->scanoutPixmap == scanout_pixmap) { ret = TRUE; } @@ -325,8 +347,8 @@ RRCrtcSet (RRCrtcPtr crtc, #if RANDR_12_INTERFACE if (pScrPriv->rrCrtcSet) { - ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, - rotation, numOutputs, outputs); + ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, + rotation, numOutputs, outputs, scanout_pixmap); } else #endif @@ -339,7 +361,7 @@ RRCrtcSet (RRCrtcPtr crtc, if (!mode) { - RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL); + RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL, scanout_pixmap); ret = TRUE; } else @@ -365,7 +387,7 @@ RRCrtcSet (RRCrtcPtr crtc, */ if (ret) { - RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs); + RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs, scanout_pixmap); RRScreenSizeNotify (pScreen); } } @@ -384,6 +406,60 @@ RRCrtcSet (RRCrtcPtr crtc, return ret; } +void +RRFreeCrtcConfigs(RRCrtcConfigPtr configs, int num_configs) +{ + int i; + + for (i = 0; i < num_configs; i++) + free(configs[i].outputs); + free(configs); +} + +Bool +RRCrtcCurrentConfig(RRCrtcPtr crtc, + RRCrtcConfigPtr crtc_config) +{ + crtc_config->crtc = crtc; + crtc_config->x = crtc->x; + crtc_config->y = crtc->y; + crtc_config->mode = crtc->mode; + crtc_config->rotation = crtc->rotation; + crtc_config->numOutputs = crtc->numOutputs; + crtc_config->outputs = calloc(crtc->numOutputs, sizeof (RROutputPtr)); + if (!crtc_config->outputs) + return FALSE; + memcpy(crtc_config->outputs, crtc->outputs, crtc->numOutputs * sizeof (RROutputPtr)); + crtc_config->sprite_position_transform = crtc->client_sprite_position_transform; + crtc_config->sprite_image_transform = crtc->client_sprite_image_transform; + crtc_config->sprite_position_f_transform = crtc->client_sprite_f_position_transform; + crtc_config->sprite_image_f_transform = crtc->client_sprite_f_image_transform; + + crtc_config->pixmap = crtc->scanoutPixmap; + crtc_config->pixmap_x = crtc->x; + crtc_config->pixmap_y = crtc->y; + return TRUE; +} + + +/* + * Request that a set of crtcs be configured at the same + * time on a single screen + */ + +Bool +RRSetCrtcConfigs(ScreenPtr screen, + RRScreenConfigPtr screen_config, + RRCrtcConfigPtr crtc_configs, + int num_configs) +{ + rrScrPrivPtr scr_priv = rrGetScrPriv(screen); + + if (!scr_priv) + return FALSE; + return (*scr_priv->rrSetCrtcConfigs)(screen, screen_config, crtc_configs, num_configs); +} + /* * Return crtc transform */ @@ -427,7 +503,7 @@ RRCrtcDestroyResource (pointer value, XID pid) { rrScrPriv(pScreen); int i; - + for (i = 0; i < pScrPriv->numCrtcs; i++) { if (pScrPriv->crtcs[i] == crtc) @@ -460,7 +536,7 @@ RRCrtcGammaSet (RRCrtcPtr crtc, #if RANDR_12_INTERFACE ScreenPtr pScreen = crtc->pScreen; #endif - + memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16)); memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16)); memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16)); @@ -510,8 +586,11 @@ RRCrtcGammaNotify (RRCrtcPtr crtc) return TRUE; /* not much going on here */ } -static void -RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform, +/* + * Compute overall scanout buffer requirements for the specified mode + */ +void +RRModeGetScanoutSize (RRModePtr mode, struct pixman_f_transform *transform, int *width, int *height) { BoxRec box; @@ -527,7 +606,7 @@ RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform, box.x2 = mode->mode.width; box.y2 = mode->mode.height; - pixman_transform_bounds (transform, &box); + pixman_f_transform_bounds (transform, &box); *width = box.x2 - box.x1; *height = box.y2 - box.y1; } @@ -538,7 +617,7 @@ RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform, void RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height) { - return RRModeGetScanoutSize (crtc->mode, &crtc->transform, width, height); + RRModeGetScanoutSize (crtc->mode, &crtc->f_transform, width, height); } /* @@ -622,6 +701,44 @@ RRCrtcTransformSet (RRCrtcPtr crtc, return Success; } +/* + * Figure out whether the specific crtc_config can fit + * within the screen_config + */ +Bool +RRScreenCoversCrtc(RRScreenConfigPtr screen_config, + RRCrtcConfigPtr crtc_config, + RRTransformPtr client_transform, + XID *errorValue) +{ + int source_width; + int source_height; + struct pixman_f_transform f_transform; + + RRTransformCompute (crtc_config->x, crtc_config->y, + crtc_config->mode->mode.width, crtc_config->mode->mode.height, + crtc_config->rotation, + client_transform, + &crtc_config->sprite_position_f_transform, + &crtc_config->sprite_image_f_transform, + NULL, &f_transform, NULL, NULL, NULL, NULL); + + RRModeGetScanoutSize (crtc_config->mode, &f_transform, + &source_width, &source_height); + if (crtc_config->x + source_width > screen_config->screen_pixmap_width) { + if (errorValue) + *errorValue = crtc_config->x; + return FALSE; + } + + if (crtc_config->y + source_height > screen_config->screen_pixmap_height) { + if (errorValue) + *errorValue = crtc_config->y; + return FALSE; + } + return TRUE; +} + /* * Initialize crtc type */ @@ -631,7 +748,7 @@ RRCrtcInit (void) RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource, "CRTC"); if (!RRCrtcType) return FALSE; - + return TRUE; } @@ -660,7 +777,7 @@ ProcRRGetCrtcInfo (ClientPtr client) int i, j, k, n; int width, height; BoxRec panned_area; - + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); @@ -671,7 +788,7 @@ ProcRRGetCrtcInfo (ClientPtr client) pScrPriv = rrGetScrPriv(pScreen); mode = crtc->mode; - + rep.type = X_Reply; rep.status = RRSetConfigSuccess; rep.sequenceNumber = client->sequence; @@ -704,7 +821,7 @@ ProcRRGetCrtcInfo (ClientPtr client) if (pScrPriv->outputs[i]->crtcs[j] == crtc) k++; rep.nPossibleOutput = k; - + rep.length = rep.nOutput + rep.nPossibleOutput; extraLen = rep.length << 2; @@ -719,7 +836,7 @@ ProcRRGetCrtcInfo (ClientPtr client) outputs = (RROutput *) extra; possible = (RROutput *) (outputs + rep.nOutput); - + for (i = 0; i < crtc->numOutputs; i++) { outputs[i] = crtc->outputs[i]->id; @@ -736,7 +853,7 @@ ProcRRGetCrtcInfo (ClientPtr client) swapl (&possible[k], n); k++; } - + if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); @@ -757,7 +874,7 @@ ProcRRGetCrtcInfo (ClientPtr client) WriteToClient (client, extraLen, (char *) extra); free(extra); } - + return Success; } @@ -777,10 +894,10 @@ ProcRRSetCrtcConfig (ClientPtr client) TimeStamp time; Rotation rotation; int rc, i, j; - + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); numOutputs = (stuff->length - bytes_to_int32(SIZEOF (xRRSetCrtcConfigReq))); - + VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess); if (stuff->mode == None) @@ -803,7 +920,7 @@ ProcRRSetCrtcConfig (ClientPtr client) } else outputs = NULL; - + outputIds = (RROutput *) (stuff + 1); for (i = 0; i < numOutputs; i++) { @@ -826,7 +943,7 @@ ProcRRSetCrtcConfig (ClientPtr client) /* validate mode for this output */ for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) { - RRModePtr m = (j < outputs[i]->numModes ? + RRModePtr m = (j < outputs[i]->numModes ? outputs[i]->modes[j] : outputs[i]->userModes[j - outputs[i]->numModes]); if (m == mode) @@ -861,17 +978,17 @@ ProcRRSetCrtcConfig (ClientPtr client) pScreen = crtc->pScreen; pScrPriv = rrGetScrPriv(pScreen); - + time = ClientTimeToServerTime(stuff->timestamp); configTime = ClientTimeToServerTime(stuff->configTimestamp); - + if (!pScrPriv) { time = currentTime; rep.status = RRSetConfigFailed; goto sendReply; } - + /* * Validate requested rotation */ @@ -904,7 +1021,7 @@ ProcRRSetCrtcConfig (ClientPtr client) free(outputs); return BadMatch; } - + #ifdef RANDR_12_INTERFACE /* * Check screen size bounds if the DDX provides a 1.2 interface @@ -924,16 +1041,19 @@ ProcRRSetCrtcConfig (ClientPtr client) mode->mode.width, mode->mode.height, rotation, &crtc->client_pending_transform, - &transform, &f_transform, &f_inverse); + &crtc->client_sprite_f_position_transform, + &crtc->client_sprite_f_image_transform, + &transform, &f_transform, &f_inverse, NULL, NULL, NULL); - RRModeGetScanoutSize (mode, &transform, &source_width, &source_height); + RRModeGetScanoutSize (mode, &f_transform, + &source_width, &source_height); if (stuff->x + source_width > pScreen->width) { client->errorValue = stuff->x; free(outputs); return BadValue; } - + if (stuff->y + source_height > pScreen->height) { client->errorValue = stuff->y; @@ -943,26 +1063,26 @@ ProcRRSetCrtcConfig (ClientPtr client) } #endif } - + if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y, - rotation, numOutputs, outputs)) + rotation, numOutputs, outputs, NULL)) { rep.status = RRSetConfigFailed; goto sendReply; } rep.status = RRSetConfigSuccess; pScrPriv->lastSetTime = time; - + sendReply: free(outputs); - + rep.type = X_Reply; /* rep.status has already been filled in */ rep.length = 0; rep.sequenceNumber = client->sequence; rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - if (client->swapped) + if (client->swapped) { int n; swaps(&rep.sequenceNumber, n); @@ -970,7 +1090,7 @@ sendReply: swapl(&rep.newTimestamp, n); } WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep); - + return Success; } @@ -986,7 +1106,7 @@ ProcRRGetPanning (ClientPtr client) BoxRec tracking; INT16 border[4]; int n; - + REQUEST_SIZE_MATCH(xRRGetPanningReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); @@ -1056,7 +1176,7 @@ ProcRRSetPanning (ClientPtr client) BoxRec tracking; INT16 border[4]; int n; - + REQUEST_SIZE_MATCH(xRRSetPanningReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); @@ -1071,9 +1191,9 @@ ProcRRSetPanning (ClientPtr client) rep.status = RRSetConfigFailed; goto sendReply; } - + time = ClientTimeToServerTime(stuff->timestamp); - + if (!pScrPriv->rrGetPanning) return RRErrorBase + BadRRCrtc; @@ -1149,7 +1269,7 @@ ProcRRGetCrtcGamma (ClientPtr client) int n; unsigned long len; char *extra = NULL; - + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); @@ -1158,7 +1278,7 @@ ProcRRGetCrtcGamma (ClientPtr client) return RRErrorBase + BadRRCrtc; len = crtc->gammaSize * 3 * 2; - + if (crtc->gammaSize) { extra = malloc(len); if (!extra) @@ -1192,21 +1312,21 @@ ProcRRSetCrtcGamma (ClientPtr client) RRCrtcPtr crtc; unsigned long len; CARD16 *red, *green, *blue; - + REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - + len = client->req_len - bytes_to_int32(sizeof (xRRSetCrtcGammaReq)); if (len < (stuff->size * 3 + 1) >> 1) return BadLength; if (stuff->size != crtc->gammaSize) return BadMatch; - + red = (CARD16 *) (stuff + 1); green = red + crtc->gammaSize; blue = green + crtc->gammaSize; - + RRCrtcGammaSet (crtc, red, green, blue); return Success; @@ -1247,7 +1367,7 @@ ProcRRSetCrtcTransform (ClientPtr client) #define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32) - + static int transform_filter_length (RRTransformPtr transform) { @@ -1349,3 +1469,331 @@ ProcRRGetCrtcTransform (ClientPtr client) free(reply); return Success; } + +static int +RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen, + RRScreenConfigPtr screen_config, + RRCrtcConfigPtr config, xRRCrtcConfig *x, + RROutput *outputIds) +{ + RRCrtcPtr crtc; + RROutputPtr *outputs; + rrScrPrivPtr scr_priv; + RRModePtr mode; + PixmapPtr pixmap; + int rc, i, j; + Rotation rotation; + + VERIFY_RR_CRTC(x->crtc, crtc, DixSetAttrAccess); + + if (x->mode == None) + { + mode = NULL; + if (x->nOutput > 0) + return BadMatch; + } + else + { + VERIFY_RR_MODE(x->mode, mode, DixSetAttrAccess); + if (x->nOutput == 0) + return BadMatch; + } + if (x->nOutput) + { + outputs = malloc(x->nOutput * sizeof (RROutputPtr)); + if (!outputs) + return BadAlloc; + } + else + outputs = NULL; + + if (x->pixmap == None) + pixmap = NULL; + else if (x->pixmap == RR_CurrentScanoutPixmap) + pixmap = crtc->scanoutPixmap; + else + { + rc = dixLookupResourceByType((pointer *) &pixmap, x->pixmap, + RT_PIXMAP, client, DixWriteAccess); + if (rc != Success) { + free(outputs); + return rc; + } + /* XXX check to make sure this is a scanout pixmap */ + } + + for (i = 0; i < x->nOutput; i++) + { + rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i], + RROutputType, client, DixSetAttrAccess); + if (rc != Success) + { + free(outputs); + return rc; + } + /* validate crtc for this output */ + for (j = 0; j < outputs[i]->numCrtcs; j++) + if (outputs[i]->crtcs[j] == crtc) + break; + if (j == outputs[i]->numCrtcs) + { + free(outputs); + return BadMatch; + } + /* validate mode for this output */ + for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) + { + RRModePtr m = (j < outputs[i]->numModes ? + outputs[i]->modes[j] : + outputs[i]->userModes[j - outputs[i]->numModes]); + if (m == mode) + break; + } + if (j == outputs[i]->numModes + outputs[i]->numUserModes) + { + free(outputs); + return BadMatch; + } + } + /* validate clones */ + for (i = 0; i < x->nOutput; i++) + { + for (j = 0; j < x->nOutput; j++) + { + int k; + if (i == j) + continue; + for (k = 0; k < outputs[i]->numClones; k++) + { + if (outputs[i]->clones[k] == outputs[j]) + break; + } + if (k == outputs[i]->numClones) + { + free(outputs); + return BadMatch; + } + } + } + + if (crtc->pScreen != screen) + return BadMatch; + + scr_priv = rrGetScrPriv(screen); + + config->crtc = crtc; + config->x = x->x; + config->y = x->y; + config->mode = mode; + config->rotation = x->rotation; + config->numOutputs = x->nOutput; + config->outputs = outputs; + PictTransform_from_xRenderTransform(&config->sprite_position_transform, + &x->spritePositionTransform); + PictTransform_from_xRenderTransform(&config->sprite_image_transform, + &x->spriteImageTransform); + pixman_f_transform_from_pixman_transform(&config->sprite_position_f_transform, + &config->sprite_position_transform); + pixman_f_transform_from_pixman_transform(&config->sprite_image_f_transform, + &config->sprite_image_transform); + config->pixmap = pixmap; + config->pixmap_x = x->xPixmap; + config->pixmap_y = x->yPixmap; + + /* + * Validate requested rotation + */ + rotation = (Rotation) x->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = x->rotation; + free(outputs); + return BadValue; + } + + if (mode) + { + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = x->rotation; + free(outputs); + return BadMatch; + } + + /* + * If scanning out from another pixmap, make sure the mode + * fits + */ + if (pixmap) + { + if (x->xPixmap + mode->mode.width > pixmap->drawable.width) { + client->errorValue = x->xPixmap; + free(outputs); + return BadValue; + } + if (x->yPixmap + mode->mode.height > pixmap->drawable.height) { + client->errorValue = x->yPixmap; + free(outputs); + return BadValue; + } + } + /* + * Check screen size bounds if the DDX provides a 1.2 interface + * for setting screen size. Else, assume the CrtcSet sets + * the size along with the mode. If the driver supports transforms, + * then it must allow crtcs to display a subset of the screen, so + * only do this check for drivers without transform support. + */ + else if (scr_priv->rrScreenSetSize && !crtc->transforms) + { + if (!RRScreenCoversCrtc(screen_config, config, + &crtc->client_pending_transform, + &client->errorValue)) + { + free(outputs); + return BadValue; + } + } + } + + return Success; +} + +int +ProcRRSetCrtcConfigs (ClientPtr client) +{ + REQUEST(xRRSetCrtcConfigsReq); + xRRSetCrtcConfigsReply rep; + DrawablePtr drawable; + ScreenPtr screen; + rrScrPrivPtr scr_priv; + xRRCrtcConfig *x_configs; + RRScreenConfigRec screen_config; + RRCrtcConfigPtr configs = NULL; + RROutput *output_ids; + int num_configs = 0; + int rc, i; + int extra_len; + int num_output_ids; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq); + + extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq)); + + num_configs = stuff->nConfigs; + + /* Check request length against number of configs specified */ + if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len) + return BadLength; + + extra_len -= num_configs * (sizeof (xRRCrtcConfig) >> 2); + x_configs = (xRRCrtcConfig *) (stuff + 1); + + /* Check remaining request length against number of outputs */ + num_output_ids = 0; + for (i = 0; i < num_configs; i++) + num_output_ids += x_configs[i].nOutput; + + if (extra_len != num_output_ids) + return BadLength; + + rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess); + if (rc != Success) + return rc; + + screen = drawable->pScreen; + + scr_priv = rrGetScrPriv(screen); + + if (!scr_priv) + { + rep.status = RRSetConfigFailed; + goto sendReply; + } + + if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) + { + client->errorValue = 0; + return BadValue; + } + + if (stuff->screenPixmapWidth < scr_priv->minWidth || + scr_priv->maxWidth < stuff->screenPixmapWidth) + { + client->errorValue = stuff->screenPixmapWidth; + return BadValue; + } + if (stuff->screenPixmapHeight < scr_priv->minHeight || + scr_priv->maxHeight < stuff->screenPixmapHeight) + { + client->errorValue = stuff->screenPixmapHeight; + return BadValue; + } + + screen_config.screen_pixmap_width = stuff->screenPixmapWidth; + screen_config.screen_pixmap_height = stuff->screenPixmapHeight; + screen_config.screen_width = stuff->screenWidth; + screen_config.screen_height = stuff->screenHeight; + screen_config.mm_width = stuff->widthInMillimeters; + screen_config.mm_height = stuff->heightInMillimeters; + + output_ids = (RROutput *) (x_configs + num_configs); + + /* + * Convert protocol crtc configurations into + * server crtc configurations + */ + configs = calloc(num_configs, sizeof (RRCrtcConfigRec)); + if (num_configs > 0 && configs == NULL) + return BadAlloc; + for (i = 0; i < num_configs; i++) { + rc = RRConvertCrtcConfig(client, screen, &screen_config, + &configs[i], + &x_configs[i], output_ids); + if (rc != Success) { + rep.status = RRSetConfigFailed; + goto sendReply; + } + output_ids += x_configs[i].nOutput; + } + + if (num_configs && + !RRSetCrtcConfigs (screen, &screen_config, configs, num_configs)) + { + rep.status = RRSetConfigFailed; + goto sendReply; + } + rep.status = RRSetConfigSuccess; + scr_priv->lastSetTime = currentTime; + +sendReply: + RRFreeCrtcConfigs(configs, num_configs); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + WriteToClient(client, sizeof(xRRSetCrtcConfigsReply), (char *)&rep); + + return Success; +} diff --git a/xorg-server/randr/rrdispatch.c b/xorg-server/randr/rrdispatch.c index b54086bcb..7540b4d35 100644 --- a/xorg-server/randr/rrdispatch.c +++ b/xorg-server/randr/rrdispatch.c @@ -224,5 +224,11 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { ProcRRSetPanning, /* 29 */ ProcRRSetOutputPrimary, /* 30 */ ProcRRGetOutputPrimary, /* 31 */ +/* V1.4 additions */ + ProcRRQueryScanoutPixmaps, /* 32 */ + ProcRRCreateScanoutPixmap, /* 33 */ + ProcRRSetCrtcSpriteTransform,/* 34 */ + ProcRRGetCrtcSpriteTransform,/* 35 */ + ProcRRSetCrtcConfigs, /* 36 */ }; diff --git a/xorg-server/randr/rrinfo.c b/xorg-server/randr/rrinfo.c index 04c1a6c98..faac15afb 100644 --- a/xorg-server/randr/rrinfo.c +++ b/xorg-server/randr/rrinfo.c @@ -168,7 +168,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) /* notice current mode */ if (newMode) RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation, - NULL, 1, &output); + NULL, 1, &output, NULL); } #endif diff --git a/xorg-server/randr/rrpixmap.c b/xorg-server/randr/rrpixmap.c new file mode 100644 index 000000000..5949309c9 --- /dev/null +++ b/xorg-server/randr/rrpixmap.c @@ -0,0 +1,154 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "randrstr.h" +#include "xace.h" + +int +ProcRRQueryScanoutPixmaps (ClientPtr client) +{ + REQUEST(xRRQueryScanoutPixmapsReq); + xRRQueryScanoutPixmapsReply rep; + RRScanoutPixmapInfo *info; + xRRScanoutPixmapInfo *x_info; + int n_info; + int rc; + DrawablePtr drawable; + ScreenPtr screen; + rrScrPrivPtr screen_priv; + int n, s; + + REQUEST_SIZE_MATCH(xRRQueryScanoutPixmapsReq); + rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess); + if (rc != Success) { + client->errorValue = stuff->drawable; + return rc; + } + + screen = drawable->pScreen; + screen_priv = rrGetScrPriv(screen); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + + info = RRQueryScanoutPixmapInfo(screen, &n_info); + x_info = calloc(n_info, sizeof (xRRScanoutPixmapInfo)); + if (n_info && !x_info) + return BadAlloc; + rep.length += (n_info * sizeof (xRRScanoutPixmapInfo)) >> 2; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + + for (s = 0; s < n_info; s++) { + x_info[s].format = info[s].format->id; + x_info[s].maxWidth = info[s].maxWidth; + x_info[s].maxHeight = info[s].maxHeight; + x_info[s].rotations = info[s].rotations; + if (client->swapped) { + swapl(&x_info[s].format, n); + swaps(&x_info[s].maxWidth, n); + swaps(&x_info[s].maxHeight, n); + swaps(&x_info[s].rotations, n); + } + } + + WriteToClient(client, sizeof(rep), (char *)&rep); + if (n_info) + WriteToClient(client, n_info * sizeof (xRRScanoutPixmapInfo), + (char *) x_info); + return Success; +} + +int +ProcRRCreateScanoutPixmap (ClientPtr client) +{ + REQUEST(xRRCreateScanoutPixmapReq); + int rc; + DrawablePtr drawable; + ScreenPtr screen; + rrScrPrivPtr screen_priv; + PixmapPtr pixmap; + int n_info; + RRScanoutPixmapInfo *info; + int s; + + REQUEST_SIZE_MATCH(xRRCreateScanoutPixmapReq); + client->errorValue = stuff->pid; + LEGAL_NEW_RESOURCE(stuff->pid, client); + + rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess); + if (rc != Success) { + client->errorValue = stuff->drawable; + return rc; + } + screen = drawable->pScreen; + screen_priv = rrGetScrPriv(screen); + if (!screen_priv) + return BadValue; + + info = RRQueryScanoutPixmapInfo(screen, &n_info); + for (s = 0; s < n_info; s++) { + if (info[s].format->id == stuff->format) + break; + } + if (s == n_info || !screen_priv->rrCreateScanoutPixmap) { + client->errorValue = stuff->format; + return BadValue; + } + info = &info[s]; + if (!stuff->width || stuff->width > info->maxWidth) { + client->errorValue = stuff->width; + return BadValue; + } + if (!stuff->height || stuff->height > info->maxHeight) { + client->errorValue = stuff->height; + return BadValue; + } + if ((stuff->rotations & info->rotations) != stuff->rotations) { + client->errorValue = stuff->rotations; + return BadValue; + } + + pixmap = screen_priv->rrCreateScanoutPixmap (screen, + stuff->width, stuff->height, + info->depth, + stuff->rotations, + info->format); + if (!pixmap) + return BadAlloc; + + pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pixmap->drawable.id = stuff->pid; + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, + pixmap, RT_NONE, NULL, DixCreateAccess); + if (rc != Success) { + screen->DestroyPixmap(pixmap); + return rc; + } + if (!AddResource(stuff->pid, RT_PIXMAP, pixmap)) + return BadAlloc; + return Success; +} diff --git a/xorg-server/randr/rrscreen.c b/xorg-server/randr/rrscreen.c index 6f842fe62..318dfaa91 100644 --- a/xorg-server/randr/rrscreen.c +++ b/xorg-server/randr/rrscreen.c @@ -168,6 +168,8 @@ Bool RRScreenSizeSet (ScreenPtr pScreen, CARD16 width, CARD16 height, + CARD16 pixWidth, + CARD16 pixHeight, CARD32 mmWidth, CARD32 mmHeight) { @@ -178,6 +180,7 @@ RRScreenSizeSet (ScreenPtr pScreen, { return (*pScrPriv->rrScreenSetSize) (pScreen, width, height, + pixWidth, pixHeight, mmWidth, mmHeight); } #endif @@ -190,6 +193,24 @@ RRScreenSizeSet (ScreenPtr pScreen, return FALSE; } +/* + * Compute an RRScreenConfig from the current screen information + */ +void +RRScreenCurrentConfig(ScreenPtr screen, + RRScreenConfigPtr screen_config) +{ + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + WindowPtr root = screen->root; + + screen_config->screen_pixmap_width = screen_pixmap->drawable.width; + screen_config->screen_pixmap_height = screen_pixmap->drawable.height; + screen_config->screen_width = root->drawable.width; + screen_config->screen_height = root->drawable.height; + screen_config->mm_width = screen->mmWidth; + screen_config->mm_height = screen->mmHeight; +} + /* * Retrieve valid screen size range */ @@ -299,6 +320,7 @@ ProcRRSetScreenSize (ClientPtr client) return BadValue; } if (!RRScreenSizeSet (pScreen, + stuff->width, stuff->height, stuff->width, stuff->height, stuff->widthInMillimeters, stuff->heightInMillimeters)) @@ -776,8 +798,10 @@ ProcRRSetScreenConfig (ClientPtr client) } rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); - if (rc != Success) + if (rc != Success) { + client->errorValue = stuff->drawable; return rc; + } pScreen = pDraw->pScreen; @@ -922,14 +946,14 @@ ProcRRSetScreenConfig (ClientPtr client) for (c = 0; c < pScrPriv->numCrtcs; c++) { if (!RRCrtcSet (pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0, - 0, NULL)) + 0, NULL, NULL)) { rep.status = RRSetConfigFailed; /* XXX recover from failure */ goto sendReply; } } - if (!RRScreenSizeSet (pScreen, width, height, + if (!RRScreenSizeSet (pScreen, width, height, width, height, pScreen->mmWidth, pScreen->mmHeight)) { rep.status = RRSetConfigFailed; @@ -938,7 +962,7 @@ ProcRRSetScreenConfig (ClientPtr client) } } - if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output)) + if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output, NULL)) rep.status = RRSetConfigFailed; else { pScrPriv->lastSetTime = time; diff --git a/xorg-server/randr/rrsdispatch.c b/xorg-server/randr/rrsdispatch.c index e16090a41..5c6978aa1 100644 --- a/xorg-server/randr/rrsdispatch.c +++ b/xorg-server/randr/rrsdispatch.c @@ -1,503 +1,635 @@ -/* - * Copyright © 2006 Keith Packard - * - * 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, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#include "randrstr.h" - -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetScreenConfig (ClientPtr client) -{ - register int n; - REQUEST(xRRSetScreenConfigReq); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - swaps (&stuff->rate, n); - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - } - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->sizeID, n); - swaps(&stuff->rotation, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - swaps(&stuff->enable, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetScreenSizeRange (ClientPtr client) -{ - int n; - REQUEST(xRRGetScreenSizeRangeReq); - - REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetScreenSize (ClientPtr client) -{ - int n; - REQUEST(xRRSetScreenSizeReq); - - REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - swaps(&stuff->width, n); - swaps(&stuff->height, n); - swapl(&stuff->widthInMillimeters, n); - swapl(&stuff->heightInMillimeters, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetScreenResources (ClientPtr client) -{ - int n; - REQUEST(xRRGetScreenResourcesReq); - - REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetOutputInfo (ClientPtr client) -{ - int n; - REQUEST(xRRGetOutputInfoReq); - - REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->configTimestamp, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRListOutputProperties (ClientPtr client) -{ - int n; - REQUEST(xRRListOutputPropertiesReq); - - REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRQueryOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRQueryOutputPropertyReq); - - REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRConfigureOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRConfigureOutputPropertyReq); - - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - SwapRestL(stuff); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRChangeOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRChangeOutputPropertyReq); - - REQUEST_AT_LEAST_SIZE (xRRChangeOutputPropertyReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - swapl(&stuff->type, n); - swapl(&stuff->nUnits, n); - switch(stuff->format) { - case 8: - break; - case 16: - SwapRestS(stuff); - break; - case 32: - SwapRestL(stuff); - break; - default: - client->errorValue = stuff->format; - return BadValue; - } - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRDeleteOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRDeleteOutputPropertyReq); - - REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRGetOutputPropertyReq); - - REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - swapl(&stuff->type, n); - swapl(&stuff->longOffset, n); - swapl(&stuff->longLength, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRCreateMode (ClientPtr client) -{ - int n; - xRRModeInfo *modeinfo; - REQUEST(xRRCreateModeReq); - - REQUEST_AT_LEAST_SIZE(xRRCreateModeReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - - modeinfo = &stuff->modeInfo; - swapl(&modeinfo->id, n); - swaps(&modeinfo->width, n); - swaps(&modeinfo->height, n); - swapl(&modeinfo->dotClock, n); - swaps(&modeinfo->hSyncStart, n); - swaps(&modeinfo->hSyncEnd, n); - swaps(&modeinfo->hTotal, n); - swaps(&modeinfo->vSyncStart, n); - swaps(&modeinfo->vSyncEnd, n); - swaps(&modeinfo->vTotal, n); - swaps(&modeinfo->nameLength, n); - swapl(&modeinfo->modeFlags, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRDestroyMode (ClientPtr client) -{ - int n; - REQUEST(xRRDestroyModeReq); - - REQUEST_SIZE_MATCH(xRRDestroyModeReq); - swaps(&stuff->length, n); - swapl(&stuff->mode, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRAddOutputMode (ClientPtr client) -{ - int n; - REQUEST(xRRAddOutputModeReq); - - REQUEST_SIZE_MATCH(xRRAddOutputModeReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->mode, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRDeleteOutputMode (ClientPtr client) -{ - int n; - REQUEST(xRRDeleteOutputModeReq); - - REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->mode, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetCrtcInfo (ClientPtr client) -{ - int n; - REQUEST(xRRGetCrtcInfoReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - swapl(&stuff->configTimestamp, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetCrtcConfig (ClientPtr client) -{ - int n; - REQUEST(xRRSetCrtcConfigReq); - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - swapl(&stuff->timestamp, n); - swapl(&stuff->configTimestamp, n); - swaps(&stuff->x, n); - swaps(&stuff->y, n); - swapl(&stuff->mode, n); - swaps(&stuff->rotation, n); - SwapRestL(stuff); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetCrtcGammaSize (ClientPtr client) -{ - int n; - REQUEST(xRRGetCrtcGammaSizeReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetCrtcGamma (ClientPtr client) -{ - int n; - REQUEST(xRRGetCrtcGammaReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetCrtcGamma (ClientPtr client) -{ - int n; - REQUEST(xRRSetCrtcGammaReq); - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - swaps(&stuff->size, n); - SwapRestS(stuff); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetCrtcTransform (ClientPtr client) -{ - int n, nparams; - char *filter; - CARD32 *params; - REQUEST(xRRSetCrtcTransformReq); - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - SwapLongs((CARD32 *)&stuff->transform, bytes_to_int32(sizeof(xRenderTransform))); - swaps(&stuff->nbytesFilter, n); - filter = (char *)(stuff + 1); - params = (CARD32 *) (filter + pad_to_int32(stuff->nbytesFilter)); - nparams = ((CARD32 *) stuff + client->req_len) - params; - if (nparams < 0) - return BadLength; - - SwapLongs(params, nparams); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetCrtcTransform (ClientPtr client) -{ - int n; - REQUEST(xRRGetCrtcTransformReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetPanning (ClientPtr client) -{ - int n; - REQUEST(xRRGetPanningReq); - - REQUEST_SIZE_MATCH(xRRGetPanningReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetPanning (ClientPtr client) -{ - int n; - REQUEST(xRRSetPanningReq); - - REQUEST_SIZE_MATCH(xRRSetPanningReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->left, n); - swaps(&stuff->top, n); - swaps(&stuff->width, n); - swaps(&stuff->height, n); - swaps(&stuff->track_left, n); - swaps(&stuff->track_top, n); - swaps(&stuff->track_width, n); - swaps(&stuff->track_height, n); - swaps(&stuff->border_left, n); - swaps(&stuff->border_top, n); - swaps(&stuff->border_right, n); - swaps(&stuff->border_bottom, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetOutputPrimary (ClientPtr client) -{ - int n; - REQUEST(xRRSetOutputPrimaryReq); - - REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - swapl(&stuff->output, n); - return ProcRandrVector[stuff->randrReqType](client); -} - -static int -SProcRRGetOutputPrimary (ClientPtr client) -{ - int n; - REQUEST(xRRGetOutputPrimaryReq); - - REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRandrVector[stuff->randrReqType](client); -} - -int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { - SProcRRQueryVersion, /* 0 */ -/* we skip 1 to make old clients fail pretty immediately */ - NULL, /* 1 SProcRandrOldGetScreenInfo */ -/* V1.0 apps share the same set screen config request id */ - SProcRRSetScreenConfig, /* 2 */ - NULL, /* 3 SProcRandrOldScreenChangeSelectInput */ -/* 3 used to be ScreenChangeSelectInput; deprecated */ - SProcRRSelectInput, /* 4 */ - SProcRRGetScreenInfo, /* 5 */ -/* V1.2 additions */ - SProcRRGetScreenSizeRange, /* 6 */ - SProcRRSetScreenSize, /* 7 */ - SProcRRGetScreenResources, /* 8 */ - SProcRRGetOutputInfo, /* 9 */ - SProcRRListOutputProperties,/* 10 */ - SProcRRQueryOutputProperty, /* 11 */ - SProcRRConfigureOutputProperty, /* 12 */ - SProcRRChangeOutputProperty,/* 13 */ - SProcRRDeleteOutputProperty,/* 14 */ - SProcRRGetOutputProperty, /* 15 */ - SProcRRCreateMode, /* 16 */ - SProcRRDestroyMode, /* 17 */ - SProcRRAddOutputMode, /* 18 */ - SProcRRDeleteOutputMode, /* 19 */ - SProcRRGetCrtcInfo, /* 20 */ - SProcRRSetCrtcConfig, /* 21 */ - SProcRRGetCrtcGammaSize, /* 22 */ - SProcRRGetCrtcGamma, /* 23 */ - SProcRRSetCrtcGamma, /* 24 */ -/* V1.3 additions */ - SProcRRGetScreenResources, /* 25 GetScreenResourcesCurrent */ - SProcRRSetCrtcTransform, /* 26 */ - SProcRRGetCrtcTransform, /* 27 */ - SProcRRGetPanning, /* 28 */ - SProcRRSetPanning, /* 29 */ - SProcRRSetOutputPrimary, /* 30 */ - SProcRRGetOutputPrimary, /* 31 */ -}; - +/* + * Copyright © 2006 Keith Packard + * + * 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, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "randrstr.h" + +static int +SProcRRQueryVersion (ClientPtr client) +{ + register int n; + REQUEST(xRRQueryVersionReq); + + swaps(&stuff->length, n); + swapl(&stuff->majorVersion, n); + swapl(&stuff->minorVersion, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenInfo (ClientPtr client) +{ + register int n; + REQUEST(xRRGetScreenInfoReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetScreenConfig (ClientPtr client) +{ + register int n; + REQUEST(xRRSetScreenConfigReq); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + swaps (&stuff->rate, n); + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + } + + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + swapl(&stuff->timestamp, n); + swaps(&stuff->sizeID, n); + swaps(&stuff->rotation, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSelectInput (ClientPtr client) +{ + register int n; + REQUEST(xRRSelectInputReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swaps(&stuff->enable, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenSizeRange (ClientPtr client) +{ + int n; + REQUEST(xRRGetScreenSizeRangeReq); + + REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetScreenSize (ClientPtr client) +{ + int n; + REQUEST(xRRSetScreenSizeReq); + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swapl(&stuff->widthInMillimeters, n); + swapl(&stuff->heightInMillimeters, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenResources (ClientPtr client) +{ + int n; + REQUEST(xRRGetScreenResourcesReq); + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetOutputInfo (ClientPtr client) +{ + int n; + REQUEST(xRRGetOutputInfoReq); + + REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->configTimestamp, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRListOutputProperties (ClientPtr client) +{ + int n; + REQUEST(xRRListOutputPropertiesReq); + + REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRQueryOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRQueryOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRConfigureOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRConfigureOutputPropertyReq); + + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + SwapRestL(stuff); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRChangeOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRChangeOutputPropertyReq); + + REQUEST_AT_LEAST_SIZE (xRRChangeOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + swapl(&stuff->type, n); + swapl(&stuff->nUnits, n); + switch(stuff->format) { + case 8: + break; + case 16: + SwapRestS(stuff); + break; + case 32: + SwapRestL(stuff); + break; + default: + client->errorValue = stuff->format; + return BadValue; + } + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRDeleteOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRDeleteOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRGetOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + swapl(&stuff->type, n); + swapl(&stuff->longOffset, n); + swapl(&stuff->longLength, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRCreateMode (ClientPtr client) +{ + int n; + xRRModeInfo *modeinfo; + REQUEST(xRRCreateModeReq); + + REQUEST_AT_LEAST_SIZE(xRRCreateModeReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + + modeinfo = &stuff->modeInfo; + swapl(&modeinfo->id, n); + swaps(&modeinfo->width, n); + swaps(&modeinfo->height, n); + swapl(&modeinfo->dotClock, n); + swaps(&modeinfo->hSyncStart, n); + swaps(&modeinfo->hSyncEnd, n); + swaps(&modeinfo->hTotal, n); + swaps(&modeinfo->vSyncStart, n); + swaps(&modeinfo->vSyncEnd, n); + swaps(&modeinfo->vTotal, n); + swaps(&modeinfo->nameLength, n); + swapl(&modeinfo->modeFlags, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRDestroyMode (ClientPtr client) +{ + int n; + REQUEST(xRRDestroyModeReq); + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + swaps(&stuff->length, n); + swapl(&stuff->mode, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRAddOutputMode (ClientPtr client) +{ + int n; + REQUEST(xRRAddOutputModeReq); + + REQUEST_SIZE_MATCH(xRRAddOutputModeReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->mode, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRDeleteOutputMode (ClientPtr client) +{ + int n; + REQUEST(xRRDeleteOutputModeReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->mode, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcInfo (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcInfoReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swapl(&stuff->configTimestamp, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetCrtcConfig (ClientPtr client) +{ + int n; + REQUEST(xRRSetCrtcConfigReq); + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swapl(&stuff->timestamp, n); + swapl(&stuff->configTimestamp, n); + swaps(&stuff->x, n); + swaps(&stuff->y, n); + swapl(&stuff->mode, n); + swaps(&stuff->rotation, n); + SwapRestL(stuff); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcGammaSize (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcGammaSizeReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcGamma (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetCrtcGamma (ClientPtr client) +{ + int n; + REQUEST(xRRSetCrtcGammaReq); + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swaps(&stuff->size, n); + SwapRestS(stuff); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetCrtcTransform (ClientPtr client) +{ + int n, nparams; + char *filter; + CARD32 *params; + REQUEST(xRRSetCrtcTransformReq); + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + SwapLongs((CARD32 *)&stuff->transform, bytes_to_int32(sizeof(xRenderTransform))); + swaps(&stuff->nbytesFilter, n); + filter = (char *)(stuff + 1); + params = (CARD32 *) (filter + pad_to_int32(stuff->nbytesFilter)); + nparams = ((CARD32 *) stuff + client->req_len) - params; + if (nparams < 0) + return BadLength; + + SwapLongs(params, nparams); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcTransform (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcTransformReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetPanning (ClientPtr client) +{ + int n; + REQUEST(xRRGetPanningReq); + + REQUEST_SIZE_MATCH(xRRGetPanningReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetPanning (ClientPtr client) +{ + int n; + REQUEST(xRRSetPanningReq); + + REQUEST_SIZE_MATCH(xRRSetPanningReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swapl(&stuff->timestamp, n); + swaps(&stuff->left, n); + swaps(&stuff->top, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swaps(&stuff->track_left, n); + swaps(&stuff->track_top, n); + swaps(&stuff->track_width, n); + swaps(&stuff->track_height, n); + swaps(&stuff->border_left, n); + swaps(&stuff->border_top, n); + swaps(&stuff->border_right, n); + swaps(&stuff->border_bottom, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetOutputPrimary (ClientPtr client) +{ + int n; + REQUEST(xRRSetOutputPrimaryReq); + + REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swapl(&stuff->output, n); + return ProcRandrVector[stuff->randrReqType](client); +} + +static int +SProcRRGetOutputPrimary (ClientPtr client) +{ + int n; + REQUEST(xRRGetOutputPrimaryReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return ProcRandrVector[stuff->randrReqType](client); +} + +static int +SProcRRQueryScanoutPixmaps (ClientPtr client) +{ + int n; + REQUEST(xRRQueryScanoutPixmapsReq); + + REQUEST_SIZE_MATCH(xRRQueryScanoutPixmapsReq); + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + return ProcRandrVector[stuff->randrReqType](client); +} + +static int +SProcRRCreateScanoutPixmap (ClientPtr client) +{ + int n; + REQUEST(xRRCreateScanoutPixmapReq); + + REQUEST_SIZE_MATCH(xRRCreateScanoutPixmapReq); + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->drawable, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swapl(&stuff->format, n); + swaps(&stuff->rotations, n); + return ProcRandrVector[stuff->randrReqType](client); +} + +static void +swap_transform(xRenderTransform *t) +{ + int n; + swapl(&t->matrix11, n); + swapl(&t->matrix12, n); + swapl(&t->matrix13, n); + swapl(&t->matrix21, n); + swapl(&t->matrix22, n); + swapl(&t->matrix23, n); + swapl(&t->matrix31, n); + swapl(&t->matrix32, n); + swapl(&t->matrix33, n); +} + +static int +SProcRRSetCrtcSpriteTransform (ClientPtr client) +{ + int n; + REQUEST(xRRSetCrtcSpriteTransformReq); + + REQUEST_SIZE_MATCH(xRRSetCrtcSpriteTransformReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swap_transform(&stuff->positionTransform); + swap_transform(&stuff->imageTransform); + return ProcRandrVector[stuff->randrReqType](client); +} + +static int +SProcRRGetCrtcSpriteTransform (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcSpriteTransformReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcSpriteTransformReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return ProcRandrVector[stuff->randrReqType](client); +} + +static int +SProcRRSetCrtcConfigs (ClientPtr client) +{ + int n; + REQUEST(xRRSetCrtcConfigsReq); + int c; + int extra_len; + int num_configs; + int num_output_ids; + xRRCrtcConfig *x_configs; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq); + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + swaps(&stuff->screenPixmapWidth, n); + swaps(&stuff->screenPixmapHeight, n); + swaps(&stuff->screenWidth, n); + swaps(&stuff->screenHeight, n); + swapl(&stuff->widthInMillimeters, n); + swapl(&stuff->heightInMillimeters, n); + swaps(&stuff->nConfigs, n); + + extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq)); + + num_configs = stuff->nConfigs; + + /* Check request length against number of configs specified */ + if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len) + return BadLength; + + x_configs = (xRRCrtcConfig *) (stuff + 1); + for (c = 0; c < num_configs; c++) { + swapl(&x_configs->crtc, n); + swaps(&x_configs->x, n); + swaps(&x_configs->y, n); + swapl(&x_configs->mode, n); + swaps(&x_configs->rotation, n); + swaps(&x_configs->nOutput, n); + swap_transform(&x_configs->spritePositionTransform); + swap_transform(&x_configs->spriteImageTransform); + swapl(&x_configs->pixmap, n); + swaps(&x_configs->xPixmap, n); + swaps(&x_configs->yPixmap, n); + x_configs++; + } + + /* Let the other dispatch function deal with verifying that + * the right number of output ids are present, just + * swap whatever is here + */ + num_output_ids = extra_len - (num_configs * (sizeof (xRRCrtcConfig)) >> 2); + SwapLongs((CARD32 *) x_configs, num_output_ids); + + return ProcRandrVector[stuff->randrReqType](client); +} + +int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { + SProcRRQueryVersion, /* 0 */ +/* we skip 1 to make old clients fail pretty immediately */ + NULL, /* 1 SProcRandrOldGetScreenInfo */ +/* V1.0 apps share the same set screen config request id */ + SProcRRSetScreenConfig, /* 2 */ + NULL, /* 3 SProcRandrOldScreenChangeSelectInput */ +/* 3 used to be ScreenChangeSelectInput; deprecated */ + SProcRRSelectInput, /* 4 */ + SProcRRGetScreenInfo, /* 5 */ +/* V1.2 additions */ + SProcRRGetScreenSizeRange, /* 6 */ + SProcRRSetScreenSize, /* 7 */ + SProcRRGetScreenResources, /* 8 */ + SProcRRGetOutputInfo, /* 9 */ + SProcRRListOutputProperties,/* 10 */ + SProcRRQueryOutputProperty, /* 11 */ + SProcRRConfigureOutputProperty, /* 12 */ + SProcRRChangeOutputProperty,/* 13 */ + SProcRRDeleteOutputProperty,/* 14 */ + SProcRRGetOutputProperty, /* 15 */ + SProcRRCreateMode, /* 16 */ + SProcRRDestroyMode, /* 17 */ + SProcRRAddOutputMode, /* 18 */ + SProcRRDeleteOutputMode, /* 19 */ + SProcRRGetCrtcInfo, /* 20 */ + SProcRRSetCrtcConfig, /* 21 */ + SProcRRGetCrtcGammaSize, /* 22 */ + SProcRRGetCrtcGamma, /* 23 */ + SProcRRSetCrtcGamma, /* 24 */ +/* V1.3 additions */ + SProcRRGetScreenResources, /* 25 GetScreenResourcesCurrent */ + SProcRRSetCrtcTransform, /* 26 */ + SProcRRGetCrtcTransform, /* 27 */ + SProcRRGetPanning, /* 28 */ + SProcRRSetPanning, /* 29 */ + SProcRRSetOutputPrimary, /* 30 */ + SProcRRGetOutputPrimary, /* 31 */ +/* V1.4 additions */ + SProcRRQueryScanoutPixmaps, /* 32 */ + SProcRRCreateScanoutPixmap, /* 33 */ + SProcRRSetCrtcSpriteTransform,/* 34 */ + SProcRRGetCrtcSpriteTransform,/* 35 */ + SProcRRSetCrtcConfigs, /* 36 */ +}; + diff --git a/xorg-server/randr/rrsprite.c b/xorg-server/randr/rrsprite.c new file mode 100644 index 000000000..c441e0396 --- /dev/null +++ b/xorg-server/randr/rrsprite.c @@ -0,0 +1,104 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "randrstr.h" +#include "swaprep.h" + +void +RRCrtcSpriteTransformSet(RRCrtcPtr crtc, + PictTransform *position_transform, + PictTransform *image_transform, + struct pict_f_transform *f_position_transform, + struct pict_f_transform *f_image_transform) +{ + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + crtc->client_sprite_position_transform = *position_transform; + crtc->client_sprite_image_transform = *image_transform; + crtc->client_sprite_f_position_transform = *f_position_transform; + crtc->client_sprite_f_image_transform = *f_image_transform; + if (pScrPriv->rrSetCrtcSpriteTransform) + (*pScrPriv->rrSetCrtcSpriteTransform) (pScreen, crtc, + &crtc->client_sprite_f_position_transform, + &crtc->client_sprite_f_image_transform); +} + +int +ProcRRSetCrtcSpriteTransform (ClientPtr client) +{ + REQUEST(xRRSetCrtcSpriteTransformReq); + RRCrtcPtr crtc; + PictTransform position_transform, image_transform; + struct pixman_f_transform f_position_transform, f_image_transform; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcSpriteTransformReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + PictTransform_from_xRenderTransform (&position_transform, &stuff->positionTransform); + PictTransform_from_xRenderTransform (&image_transform, &stuff->imageTransform); + pixman_f_transform_from_pixman_transform (&f_position_transform, &position_transform); + pixman_f_transform_from_pixman_transform (&f_image_transform, &image_transform); + + RRCrtcSpriteTransformSet (crtc, &position_transform, &image_transform, + &f_position_transform, &f_image_transform); + return Success; +} + +#define CrtcSpriteTransformExtra (SIZEOF(xRRGetCrtcSpriteTransformReply) - 32) + +int +ProcRRGetCrtcSpriteTransform (ClientPtr client) +{ + REQUEST(xRRGetCrtcSpriteTransformReq); + xRRGetCrtcSpriteTransformReply *reply; + RRCrtcPtr crtc; + int n; + char *extra; + + REQUEST_SIZE_MATCH (xRRGetCrtcSpriteTransformReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + reply = malloc(sizeof (xRRGetCrtcSpriteTransformReply)); + if (!reply) + return BadAlloc; + + extra = (char *) (reply + 1); + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = bytes_to_int32(CrtcSpriteTransformExtra); + + xRenderTransform_from_PictTransform(&reply->positionTransform, &crtc->client_sprite_position_transform); + xRenderTransform_from_PictTransform(&reply->imageTransform, &crtc->client_sprite_image_transform); + + if (client->swapped) { + swaps (&reply->sequenceNumber, n); + swapl (&reply->length, n); + SwapLongs((CARD32 *) &reply->positionTransform, bytes_to_int32(sizeof(xRenderTransform))); + SwapLongs((CARD32 *) &reply->imageTransform, bytes_to_int32(sizeof(xRenderTransform))); + } + WriteToClient (client, sizeof (xRRGetCrtcSpriteTransformReply), (char *) reply); + free(reply); + return Success; +} diff --git a/xorg-server/randr/rrtransform.c b/xorg-server/randr/rrtransform.c index 102a0f48e..f78d5f913 100644 --- a/xorg-server/randr/rrtransform.c +++ b/xorg-server/randr/rrtransform.c @@ -134,6 +134,24 @@ RRTransformRescale(struct pixman_f_transform *f_transform, double limit) f_transform->m[j][i] *= scale; } +#define EPSILON (1e-20) +#define IS_F_SAME(a,b) (fabs((a)-(b)) < EPSILON) +#define IS_F_ZERO(a) (fabs(a) < EPSILON) + +static Bool +pict_f_transform_is_identity (const struct pixman_f_transform *t) +{ + return (IS_F_SAME (t->m[0][0], t->m[1][1]) && + IS_F_SAME (t->m[0][0], t->m[2][2]) && + !IS_F_ZERO (t->m[0][0]) && + IS_F_ZERO (t->m[0][1]) && + IS_F_ZERO (t->m[0][2]) && + IS_F_ZERO (t->m[1][0]) && + IS_F_ZERO (t->m[1][2]) && + IS_F_ZERO (t->m[2][0]) && + IS_F_ZERO (t->m[2][1])); +} + /* * Compute the complete transformation matrix including * client-specified transform, rotation/reflection values and the crtc @@ -148,23 +166,39 @@ RRTransformCompute (int x, int height, Rotation rotation, RRTransformPtr rr_transform, + struct pixman_f_transform *sprite_position_transform, + struct pixman_f_transform *sprite_image_transform, PictTransformPtr transform, struct pixman_f_transform *f_transform, - struct pixman_f_transform *f_inverse) + struct pixman_f_transform *f_inverse, + struct pixman_f_transform *f_fb_to_sprite, + struct pixman_f_transform *f_sprite_to_image, + Bool *sprite_transform_in_use) { PictTransform t_transform, inverse; struct pixman_f_transform tf_transform, tf_inverse; + struct pixman_f_transform sf_position_transform, sf_image_transform; + struct pixman_f_transform f_image_to_sprite; Bool overflow = FALSE; + Bool ret = TRUE; if (!transform) transform = &t_transform; if (!f_transform) f_transform = &tf_transform; if (!f_inverse) f_inverse = &tf_inverse; + if (!f_fb_to_sprite) f_fb_to_sprite = &sf_position_transform; + if (!f_sprite_to_image) f_sprite_to_image = &sf_image_transform; + + /* invert the sprite image transform to have it go from dest to source */ + if (!pixman_f_transform_invert (&f_image_to_sprite, f_sprite_to_image)) + pixman_f_transform_init_identity(&f_image_to_sprite); pixman_transform_init_identity (transform); pixman_transform_init_identity (&inverse); pixman_f_transform_init_identity (f_transform); pixman_f_transform_init_identity (f_inverse); + pixman_f_transform_init_identity (f_fb_to_sprite); + pixman_f_transform_init_identity (f_sprite_to_image); if (rotation != RR_Rotate_0) { double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy; @@ -246,7 +280,14 @@ RRTransformCompute (int x, pixman_f_transform_translate (f_transform, f_inverse, f_scale_dx, f_scale_dy); } -#ifdef RANDR_12_INTERFACE + /* + * Sprite position is affected by the transform matrix, + * but the image is not + */ + pixman_f_transform_multiply(f_sprite_to_image, + f_transform, + &f_image_to_sprite); + if (rr_transform) { if (!pixman_transform_multiply (transform, &rr_transform->transform, transform)) @@ -254,7 +295,7 @@ RRTransformCompute (int x, pixman_f_transform_multiply (f_transform, &rr_transform->f_transform, f_transform); pixman_f_transform_multiply (f_inverse, f_inverse, &rr_transform->f_inverse); } -#endif + /* * Compute the class of the resulting transform */ @@ -264,7 +305,7 @@ RRTransformCompute (int x, pixman_f_transform_init_translate (f_transform, x, y); pixman_f_transform_init_translate (f_inverse, -x, -y); - return FALSE; + ret = FALSE; } else { @@ -278,6 +319,19 @@ RRTransformCompute (int x, RRTransformRescale(&f_scaled, 16384.0); pixman_transform_from_pixman_f_transform(transform, &f_scaled); } - return TRUE; + ret = TRUE; } + + /* + * Sprite position is affected by the transform matrix, + * but the image is not + */ + pixman_f_transform_multiply(f_fb_to_sprite, + f_inverse, + sprite_position_transform); + if (sprite_transform_in_use) + *sprite_transform_in_use = ret || !pict_f_transform_is_identity(f_fb_to_sprite); + return ret; } + + diff --git a/xorg-server/randr/rrtransform.h b/xorg-server/randr/rrtransform.h index 561762dfe..eaced0d3e 100644 --- a/xorg-server/randr/rrtransform.h +++ b/xorg-server/randr/rrtransform.h @@ -1,75 +1,86 @@ -/* - * Copyright © 2007 Keith Packard - * - * 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, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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 _RRTRANSFORM_H_ -#define _RRTRANSFORM_H_ - -#include -#include "picturestr.h" - -typedef struct _rrTransform RRTransformRec, *RRTransformPtr; - -struct _rrTransform { - PictTransform transform; - struct pict_f_transform f_transform; - struct pict_f_transform f_inverse; - PictFilterPtr filter; - xFixed *params; - int nparams; - int width; - int height; -}; - -extern _X_EXPORT void -RRTransformInit (RRTransformPtr transform); - -extern _X_EXPORT void -RRTransformFini (RRTransformPtr transform); - -extern _X_EXPORT Bool -RRTransformEqual (RRTransformPtr a, RRTransformPtr b); - -extern _X_EXPORT Bool -RRTransformSetFilter (RRTransformPtr dst, - PictFilterPtr filter, - xFixed *params, - int nparams, - int width, - int height); - -extern _X_EXPORT Bool -RRTransformCopy (RRTransformPtr dst, RRTransformPtr src); - -extern _X_EXPORT Bool -RRTransformCompute (int x, - int y, - int width, - int height, - Rotation rotation, - RRTransformPtr rr_transform, - - PictTransformPtr transform, - struct pict_f_transform *f_transform, - struct pict_f_transform *f_inverse); - - -#endif /* _RRTRANSFORM_H_ */ +/* + * Copyright © 2007 Keith Packard + * + * 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, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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 _RRTRANSFORM_H_ +#define _RRTRANSFORM_H_ + +#include +#include "picturestr.h" + +typedef struct _rrTransform RRTransformRec, *RRTransformPtr; + +struct _rrTransform { + PictTransform transform; + struct pict_f_transform f_transform; + struct pict_f_transform f_inverse; + PictFilterPtr filter; + xFixed *params; + int nparams; + int width; + int height; +}; + +extern _X_EXPORT void +RRTransformInit (RRTransformPtr transform); + +extern _X_EXPORT void +RRTransformFini (RRTransformPtr transform); + +extern _X_EXPORT Bool +RRTransformEqual (RRTransformPtr a, RRTransformPtr b); + +extern _X_EXPORT Bool +RRTransformSetFilter (RRTransformPtr dst, + PictFilterPtr filter, + xFixed *params, + int nparams, + int width, + int height); + +extern _X_EXPORT Bool +RRTransformCopy (RRTransformPtr dst, RRTransformPtr src); + +/* + * Compute the complete transformation matrix including + * client-specified transform, rotation/reflection values and the crtc + * offset. + * + * Return TRUE if the resulting transform is not a simple translation. + */ +extern _X_EXPORT Bool +RRTransformCompute (int x, + int y, + int width, + int height, + Rotation rotation, + RRTransformPtr rr_transform, + struct pict_f_transform *sprite_position_transform, + struct pict_f_transform *sprite_image_transform, + + PictTransformPtr transform, + struct pict_f_transform *f_transform, + struct pict_f_transform *f_inverse, + struct pict_f_transform *f_fb_to_sprite, + struct pict_f_transform *f_sprite_to_image, + Bool *sprite_transform_in_use); + +#endif /* _RRTRANSFORM_H_ */ -- cgit v1.2.3