diff options
author | marha <marha@users.sourceforge.net> | 2010-12-08 16:07:08 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-12-08 16:07:08 +0000 |
commit | 8308417ba79394ca96a326c8cb5c36024b36c1e2 (patch) | |
tree | c6e087e837c83457b68a7a10363af47778a9b1b7 /xorg-server/randr/mirrcrtc.c | |
parent | fea28ce54ffbea6eda28791518ccca0e0df2df0d (diff) | |
parent | 531a0d974b98074978535f086a73b6b662fa0cea (diff) | |
download | vcxsrv-8308417ba79394ca96a326c8cb5c36024b36c1e2.tar.gz vcxsrv-8308417ba79394ca96a326c8cb5c36024b36c1e2.tar.bz2 vcxsrv-8308417ba79394ca96a326c8cb5c36024b36c1e2.zip |
svn merge ^/branches/released .
Diffstat (limited to 'xorg-server/randr/mirrcrtc.c')
-rw-r--r-- | xorg-server/randr/mirrcrtc.c | 174 |
1 files changed, 174 insertions, 0 deletions
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;
+}
|