This permits clients to perform incremental configuration changes instead of requiring a complete new configuration to be written.
Signed-off-by: Keith Packard <kei...@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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel