summaryrefslogtreecommitdiffstats
path: root/unix/xserver/hw/vnc/RandrGlue.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/xserver/hw/vnc/RandrGlue.c')
-rw-r--r--unix/xserver/hw/vnc/RandrGlue.c283
1 files changed, 283 insertions, 0 deletions
diff --git a/unix/xserver/hw/vnc/RandrGlue.c b/unix/xserver/hw/vnc/RandrGlue.c
new file mode 100644
index 00000000..9f770fa9
--- /dev/null
+++ b/unix/xserver/hw/vnc/RandrGlue.c
@@ -0,0 +1,283 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2011-2015 Pierre Ossman for Cendio AB
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "scrnintstr.h"
+#ifdef RANDR
+#include "randrstr.h"
+#endif
+
+#include "RandrGlue.h"
+
+int vncGetScreenWidth(int scrIdx)
+{
+ return screenInfo.screens[scrIdx]->width;
+}
+
+int vncGetScreenHeight(int scrIdx)
+{
+ return screenInfo.screens[scrIdx]->height;
+}
+
+int vncRandRResizeScreen(int scrIdx, int width, int height)
+{
+#ifdef RANDR
+ ScreenPtr pScreen = screenInfo.screens[scrIdx];
+ /* Try to retain DPI when we resize */
+ return RRScreenSizeSet(pScreen, width, height,
+ pScreen->mmWidth * width / pScreen->width,
+ pScreen->mmHeight * height / pScreen->height);
+#else
+ return -1;
+#endif
+}
+
+void vncRandRUpdateSetTime(int scrIdx)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+ rp->lastSetTime = currentTime;
+#endif
+}
+
+int vncRandRHasOutputClones(int scrIdx)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+ for (int i = 0;i < rp->numCrtcs;i++) {
+ if (rp->crtcs[i]->numOutputs > 1)
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+int vncRandRGetOutputCount(int scrIdx)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+ return rp->numOutputs;
+#else
+ return 0;
+#endif
+}
+
+int vncRandRGetAvailableOutputs(int scrIdx)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+
+ int availableOutputs;
+ RRCrtcPtr *usedCrtcs;
+ int numUsed;
+
+ int i, j, k;
+
+ usedCrtcs = malloc(sizeof(RRCrtcPtr) * rp->numCrtcs);
+ if (usedCrtcs == NULL)
+ return 0;
+
+ /*
+ * This gets slightly complicated because we might need to hook a CRTC
+ * up to the output, but also check that we don't try to use the same
+ * CRTC for multiple outputs.
+ */
+ availableOutputs = 0;
+ numUsed = 0;
+ for (i = 0;i < rp->numOutputs;i++) {
+ RROutputPtr output;
+
+ output = rp->outputs[i];
+
+ if (output->crtc != NULL)
+ availableOutputs++;
+ else {
+ for (j = 0;j < output->numCrtcs;j++) {
+ if (output->crtcs[j]->numOutputs != 0)
+ continue;
+
+ for (k = 0;k < numUsed;k++) {
+ if (usedCrtcs[k] == output->crtcs[j])
+ break;
+ }
+ if (k != numUsed)
+ continue;
+
+ availableOutputs++;
+
+ usedCrtcs[numUsed] = output->crtcs[j];
+ numUsed++;
+
+ break;
+ }
+ }
+ }
+
+ free(usedCrtcs);
+
+ return availableOutputs;
+#else
+ return 0;
+#endif
+}
+
+char *vncRandRGetOutputName(int scrIdx, int outputIdx)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+ return strdup(rp->outputs[outputIdx]->name);
+#else
+ return strdup("");
+#endif
+}
+
+int vncRandRIsOutputEnabled(int scrIdx, int outputIdx)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+
+ if (rp->outputs[outputIdx]->crtc == NULL)
+ return 0;
+ if (rp->outputs[outputIdx]->crtc->mode == NULL)
+ return 0;
+
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+int vncRandRIsOutputUsable(int scrIdx, int outputIdx)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+
+ RROutputPtr output;
+ int i;
+
+ output = rp->outputs[outputIdx];
+ if (output->crtc != NULL)
+ return 1;
+
+ /* Any unused CRTCs? */
+ for (i = 0;i < output->numCrtcs;i++) {
+ if (output->crtcs[i]->numOutputs == 0)
+ return 1;
+ }
+#endif
+
+ return 0;
+}
+
+int vncRandRDisableOutput(int scrIdx, int outputIdx)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+ RRCrtcPtr crtc;
+
+ crtc = rp->outputs[outputIdx]->crtc;
+ if (crtc == NULL)
+ return 0;
+
+ return RRCrtcSet(crtc, NULL, crtc->x, crtc->y, crtc->rotation, 0, NULL);
+#else
+ return -1;
+#endif
+}
+
+unsigned int vncRandRGetOutputId(int scrIdx, int outputIdx)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+ return rp->outputs[outputIdx]->id;
+#else
+ return 0;
+#endif
+}
+
+void vncRandRGetOutputDimensions(int scrIdx, int outputIdx,
+ int *x, int *y, int *width, int *height)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+ int swap;
+
+ *x = rp->outputs[outputIdx]->crtc->x;
+ *y = rp->outputs[outputIdx]->crtc->y;
+ *width = rp->outputs[outputIdx]->crtc->mode->mode.width;
+ *height = rp->outputs[outputIdx]->crtc->mode->mode.height;
+
+ switch (rp->outputs[outputIdx]->crtc->rotation & 0xf) {
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ swap = *width;
+ *width = *height;
+ *height = swap;
+ break;
+ }
+#endif
+}
+
+int vncRandRReconfigureOutput(int scrIdx, int outputIdx, int x, int y,
+ int width, int height)
+{
+#ifdef RANDR
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+
+ RROutputPtr output;
+ RRCrtcPtr crtc;
+ RRModePtr mode;
+
+ int i;
+
+ output = rp->outputs[outputIdx];
+ crtc = output->crtc;
+
+ /* Need a CRTC? */
+ if (crtc == NULL) {
+ for (i = 0;i < output->numCrtcs;i++) {
+ if (output->crtcs[i]->numOutputs != 0)
+ continue;
+
+ crtc = output->crtcs[i];
+ break;
+ }
+
+ /* Couldn't find one... */
+ if (crtc == NULL)
+ return -1;
+ }
+
+ /* Make sure we have the mode we want */
+ mode = vncRandRCreatePreferredMode(output, width, height);
+ if (mode == NULL)
+ return -1;
+
+ /* Reconfigure new mode and position */
+ return RRCrtcSet(crtc, mode, x, y, crtc->rotation, 1, &output);
+#else
+ return -1;
+#endif
+}