[PATCH] randr: Add 'set' fields to SetCrtcConfigs request
Keith Packard
keithp at keithp.com
Wed Feb 16 22:59:22 PST 2011
This permits clients to perform incremental configuration changes
instead of requiring a complete new configuration to be written.
Signed-off-by: Keith Packard <keithp at keithp.com>
---
randr/rrcrtc.c | 332 ++++++++++++++++++++++++++++++++++----------------------
1 files changed, 202 insertions(+), 130 deletions(-)
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 5fe6900..07e9019 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -1483,63 +1483,82 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
PixmapPtr pixmap;
int rc, i, j;
Rotation rotation;
+ int numOutputs;
VERIFY_RR_CRTC(x->crtc, crtc, DixSetAttrAccess);
- if (x->mode == None)
- {
- mode = NULL;
- if (x->nOutput > 0)
- return BadMatch;
+ mode = crtc->mode;
+ numOutputs = crtc->numOutputs;
+
+ if (x->set & RR_SetCrtcOutputs)
+ numOutputs = x->nOutput;
+
+ if (x->set & RR_SetCrtcMode) {
+ if (x->mode == None)
+ mode = NULL;
+ else
+ {
+ VERIFY_RR_MODE(x->mode, mode, DixSetAttrAccess);
+ if (x->nOutput == 0)
+ return BadMatch;
+ }
}
- else
+
+ if (numOutputs)
{
- VERIFY_RR_MODE(x->mode, mode, DixSetAttrAccess);
- if (x->nOutput == 0)
+ if (mode == NULL)
return BadMatch;
- }
- if (x->nOutput)
- {
- outputs = malloc(x->nOutput * sizeof (RROutputPtr));
+ outputs = malloc(numOutputs * sizeof (RROutputPtr));
if (!outputs)
return BadAlloc;
}
- else
+ else {
+ if (mode != NULL)
+ return BadMatch;
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)
+ if (x->set & RR_SetCrtcPixmap) {
+ if (x->pixmap == None)
+ pixmap = NULL;
+ else
{
- free(outputs);
- return rc;
+ 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 */
}
- /* 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)
+ } else
+ pixmap = crtc->scanoutPixmap;
+
+ if (x->set & RR_SetCrtcOutputs) {
+ for (i = 0; i < numOutputs; i++)
{
- free(outputs);
- return BadMatch;
+ 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;
+ }
}
+ } else
+ memcpy(outputs, crtc->outputs, numOutputs * sizeof (RROutputPtr));
+
+ for (i = 0; i < numOutputs; i++)
+ {
/* validate mode for this output */
for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
{
@@ -1555,10 +1574,11 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
return BadMatch;
}
}
+
/* validate clones */
- for (i = 0; i < x->nOutput; i++)
+ for (i = 0; i < numOutputs; i++)
{
- for (j = 0; j < x->nOutput; j++)
+ for (j = 0; j < numOutputs; j++)
{
int k;
if (i == j)
@@ -1579,46 +1599,68 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
if (crtc->pScreen != screen)
return BadMatch;
+ rotation = crtc->rotation;
+ if (x->set & RR_SetCrtcRotation) {
+ /*
+ * 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;
+ }
+ }
+
scr_priv = rrGetScrPriv(screen);
config->crtc = crtc;
- config->x = x->x;
- config->y = x->y;
+ config->x = crtc->x;
+ config->y = crtc->y;
+ if (x->set & RR_SetCrtcPosition) {
+ config->x = x->x;
+ config->y = x->y;
+ }
config->mode = mode;
- config->rotation = x->rotation;
- config->numOutputs = x->nOutput;
+ config->rotation = rotation;
+ config->numOutputs = numOutputs;
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 (x->set & RR_SetCrtcSpritePositionTransform) {
+ PictTransform_from_xRenderTransform(&config->sprite_position_transform,
+ &x->spritePositionTransform);
+ pixman_f_transform_from_pixman_transform(&config->sprite_position_f_transform,
+ &config->sprite_position_transform);
+ } else {
+ config->sprite_position_transform = crtc->client_sprite_position_transform;
+ config->sprite_position_f_transform = crtc->client_sprite_f_position_transform;
+ }
+ if (x->set & RR_SetCrtcSpriteImageTransform) {
+ PictTransform_from_xRenderTransform(&config->sprite_image_transform,
+ &x->spriteImageTransform);
+ pixman_f_transform_from_pixman_transform(&config->sprite_image_f_transform,
+ &config->sprite_image_transform);
+ } else {
+ config->sprite_image_transform = crtc->client_sprite_image_transform;
+ config->sprite_image_f_transform = crtc->client_sprite_f_image_transform;
+ }
+ config->pixmap = pixmap;
+ config->pixmap_x = crtc->x;
+ config->pixmap_y = crtc->y;
+ if (x->set & RR_SetCrtcPixmapPosition) {
+ config->pixmap_x = x->xPixmap;
+ config->pixmap_y = x->yPixmap;
}
if (mode)
@@ -1628,7 +1670,7 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
/*
* requested rotation or reflection not supported by screen
*/
- client->errorValue = x->rotation;
+ client->errorValue = rotation;
free(outputs);
return BadMatch;
}
@@ -1639,13 +1681,13 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
*/
if (pixmap)
{
- if (x->xPixmap + mode->mode.width > pixmap->drawable.width) {
- client->errorValue = x->xPixmap;
+ if (config->pixmap_x + mode->mode.width > pixmap->drawable.width) {
+ client->errorValue = config->pixmap_x;
free(outputs);
return BadValue;
}
- if (x->yPixmap + mode->mode.height > pixmap->drawable.height) {
- client->errorValue = x->yPixmap;
+ if (config->pixmap_y + mode->mode.height > pixmap->drawable.height) {
+ client->errorValue = config->pixmap_y;
free(outputs);
return BadValue;
}
@@ -1687,13 +1729,15 @@ ProcRRSetCrtcConfigs (ClientPtr client)
int num_configs = 0;
int rc, i;
int extra_len;
- int num_output_ids;
+ int num_output_ids = 0;
REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq);
extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq));
- num_configs = stuff->nConfigs;
+ num_configs = 0;
+ if (stuff->set & RR_SetScreenCrtcs)
+ num_configs = stuff->nConfigs;
/* Check request length against number of configs specified */
if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len)
@@ -1702,10 +1746,11 @@ ProcRRSetCrtcConfigs (ClientPtr client)
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 (stuff->set & RR_SetScreenCrtcs) {
+ /* Check remaining request length against number of outputs */
+ for (i = 0; i < num_configs; i++)
+ num_output_ids += x_configs[i].nOutput;
+ }
if (extra_len != num_output_ids)
return BadLength;
@@ -1724,57 +1769,84 @@ ProcRRSetCrtcConfigs (ClientPtr client)
goto sendReply;
}
- if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0)
- {
- client->errorValue = 0;
- return BadValue;
+ if (stuff->set & RR_SetScreenSizeInMillimeters) {
+ if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ screen_config.mm_width = stuff->widthInMillimeters;
+ screen_config.mm_height = stuff->heightInMillimeters;
+ } else {
+ screen_config.mm_width = screen->mmWidth;
+ screen_config.mm_height = screen->mmHeight;
}
- 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;
+ if (stuff->set & RR_SetScreenPixmapSize) {
+ 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;
+ } else {
+ PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+ screen_config.screen_pixmap_width = screen_pixmap->drawable.width;
+ screen_config.screen_pixmap_height = screen_pixmap->drawable.height;
+ }
+
+ if (stuff->set & RR_SetScreenSize) {
+ if (stuff->screenWidth <= 0 || stuff->screenWidth > 32767) {
+ client->errorValue = stuff->screenWidth;
+ return BadValue;
+ }
+ screen_config.screen_width = stuff->screenWidth;
+
+ if (stuff->screenHeight <= 0 || stuff->screenHeight > 32767) {
+ client->errorValue = stuff->screenHeight;
+ return BadValue;
+ }
+ screen_config.screen_height = stuff->screenHeight;
+ } else {
+ WindowPtr root = screen->root;
+ screen_config.screen_width = root->drawable.width;
+ screen_config.screen_height = root->drawable.height;
}
- 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;
+ if (num_configs > 0) {
- output_ids = (RROutput *) (x_configs + num_configs);
+ output_ids = (RROutput *) (x_configs + num_configs);
+ /*
+ * Convert protocol crtc configurations into
+ * server crtc configurations
+ */
+ configs = calloc(num_configs, sizeof (RRCrtcConfigRec));
+ if (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;
+ }
- /*
- * 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) {
+ if (!RRSetCrtcConfigs (screen, &screen_config, configs, num_configs))
+ {
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;
--
1.7.2.3
More information about the xorg-devel
mailing list