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/mirrcrtc.c | 174 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 xorg-server/randr/mirrcrtc.c (limited to 'xorg-server/randr/mirrcrtc.c') 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; +} -- cgit v1.2.3