summaryrefslogtreecommitdiffstats
path: root/unix/xserver
diff options
context:
space:
mode:
authorPeter Åstrand (astrand) <astrand@cendio.se>2018-03-27 09:14:38 +0200
committerPeter Åstrand (astrand) <astrand@cendio.se>2018-04-09 20:31:25 +0200
commit54f49fded05ba29a93f6b77f8b70316e18342580 (patch)
tree46d41db5da3595bf6966631174a7752103cebe16 /unix/xserver
parent651faf8127276d6704f5ee5304586b66c89cc9b4 (diff)
downloadtigervnc-54f49fded05ba29a93f6b77f8b70316e18342580.tar.gz
tigervnc-54f49fded05ba29a93f6b77f8b70316e18342580.zip
Add a tryScreenLayout function
This can be used to test if a layout if possible.
Diffstat (limited to 'unix/xserver')
-rw-r--r--unix/xserver/hw/vnc/RandrGlue.c64
-rw-r--r--unix/xserver/hw/vnc/XorgGlue.h4
-rw-r--r--unix/xserver/hw/vnc/vncModule.c33
-rw-r--r--unix/xserver/hw/vnc/xvnc.c63
4 files changed, 141 insertions, 23 deletions
diff --git a/unix/xserver/hw/vnc/RandrGlue.c b/unix/xserver/hw/vnc/RandrGlue.c
index dc8512bd..82e85524 100644
--- a/unix/xserver/hw/vnc/RandrGlue.c
+++ b/unix/xserver/hw/vnc/RandrGlue.c
@@ -49,9 +49,22 @@ int vncGetScreenHeight(void)
return screenInfo.screens[scrIdx]->height;
}
+int vncRandRIsValidScreenSize(int width, int height)
+{
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+
+ if (width < rp->minWidth || rp->maxWidth < width)
+ return 0;
+ if (height < rp->minHeight || rp->maxHeight < height)
+ return 0;
+
+ return 1;
+}
+
int vncRandRResizeScreen(int width, int height)
{
ScreenPtr pScreen = screenInfo.screens[scrIdx];
+
/* Try to retain DPI when we resize */
return RRScreenSizeSet(pScreen, width, height,
pScreen->mmWidth * width / pScreen->width,
@@ -183,6 +196,44 @@ int vncRandRIsOutputConnected(int outputIdx)
return (output->connection == RR_Connected);
}
+static RRModePtr vncRandRGetMatchingMode(int outputIdx, int width, int height)
+{
+ rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
+
+ RROutputPtr output;
+
+ output = rp->outputs[outputIdx];
+
+ if (output->crtc != NULL) {
+ unsigned int swap;
+ switch (output->crtc->rotation) {
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ swap = width;
+ width = height;
+ height = swap;
+ break;
+ }
+ }
+
+ for (int i = 0; i < output->numModes; i++) {
+ if ((output->modes[i]->mode.width == width) &&
+ (output->modes[i]->mode.height == height))
+ return output->modes[i];
+ }
+
+ return NULL;
+}
+
+int vncRandRCheckOutputMode(int outputIdx, int width, int height)
+{
+ if (vncRandRGetMatchingMode(outputIdx, width, height) != NULL)
+ return 1;
+ if (vncRandRCanCreateModes())
+ return 1;
+ return 0;
+}
+
int vncRandRDisableOutput(int outputIdx)
{
rrScrPrivPtr rp = rrGetScrPriv(screenInfo.screens[scrIdx]);
@@ -284,7 +335,13 @@ int vncRandRReconfigureOutput(int outputIdx, int x, int y,
}
/* Make sure we have the mode we want */
- mode = vncRandRCreatePreferredMode(output, width, height);
+ mode = vncRandRGetMatchingMode(outputIdx, width, height);
+ if (mode == NULL) {
+ mode = vncRandRCreateMode(output, width, height);
+ if (mode == NULL)
+ return 0;
+ }
+ mode = vncRandRSetPreferredMode(output, mode);
if (mode == NULL)
return 0;
@@ -292,6 +349,11 @@ int vncRandRReconfigureOutput(int outputIdx, int x, int y,
return RRCrtcSet(crtc, mode, x, y, crtc->rotation, 1, &output);
}
+int vncRandRCanCreateOutputs(int extraOutputs)
+{
+ return vncRandRCanCreateScreenOutputs(scrIdx, extraOutputs);
+}
+
int vncRandRCreateOutputs(int extraOutputs)
{
return vncRandRCreateScreenOutputs(scrIdx, extraOutputs);
diff --git a/unix/xserver/hw/vnc/XorgGlue.h b/unix/xserver/hw/vnc/XorgGlue.h
index 68d66686..5d019493 100644
--- a/unix/xserver/hw/vnc/XorgGlue.h
+++ b/unix/xserver/hw/vnc/XorgGlue.h
@@ -48,7 +48,11 @@ int vncGetScreenY(int scrIdx);
// These hide in xvnc.c or vncModule.c
void vncClientGone(int fd);
+int vncRandRCanCreateScreenOutputs(int scrIdx, int extraOutputs);
int vncRandRCreateScreenOutputs(int scrIdx, int extraOutputs);
+int vncRandRCanCreateModes(void);
+void* vncRandRCreateMode(void* output, int width, int height);
+void* vncRandRSetPreferredMode(void* output, void* mode);
#ifdef __cplusplus
}
diff --git a/unix/xserver/hw/vnc/vncModule.c b/unix/xserver/hw/vnc/vncModule.c
index 2a6e73c9..451f527a 100644
--- a/unix/xserver/hw/vnc/vncModule.c
+++ b/unix/xserver/hw/vnc/vncModule.c
@@ -110,28 +110,31 @@ void vncClientGone(int fd)
{
}
+int vncRandRCanCreateScreenOutputs(int scrIdx, int extraOutputs)
+{
+ return 0;
+}
+
int vncRandRCreateScreenOutputs(int scrIdx, int extraOutputs)
{
return 0;
}
-void *vncRandRCreatePreferredMode(void *out, int width, int height)
+int vncRandRCanCreateModes(void)
+{
+ return 0;
+}
+
+void* vncRandRCreateMode(void* output, int width, int height)
{
- RROutputPtr output;
+ return 0;
+}
+void* vncRandRSetPreferredMode(void* output, void* mode)
+{
/*
- * We're not going to change which modes are preferred, but let's
- * see if we can at least find a mode with matching dimensions.
+ * We're not going to change which modes are preferred,
+ * so just return the incoming mode.
*/
-
- output = out;
-
- for (int i = 0;i < output->numModes;i++) {
- if ((output->modes[i]->mode.width == width) &&
- (output->modes[i]->mode.height == height))
- return output->modes[i];
- }
-
- return NULL;
+ return mode;
}
-
diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c
index f06e0b15..57152cd5 100644
--- a/unix/xserver/hw/vnc/xvnc.c
+++ b/unix/xserver/hw/vnc/xvnc.c
@@ -1377,6 +1377,12 @@ static RRCrtcPtr vncRandRCrtcCreate(ScreenPtr pScreen)
}
/* Used from XserverDesktop when it needs more outputs... */
+
+int vncRandRCanCreateScreenOutputs(int scrIdx, int extraOutputs)
+{
+ return 1;
+}
+
int vncRandRCreateScreenOutputs(int scrIdx, int extraOutputs)
{
RRCrtcPtr crtc;
@@ -1391,27 +1397,67 @@ int vncRandRCreateScreenOutputs(int scrIdx, int extraOutputs)
return 1;
}
-/* Used to create a preferred mode from various places */
-void *vncRandRCreatePreferredMode(void *out, int width, int height)
+/* Creating and modifying modes, used by XserverDesktop and init here */
+
+int vncRandRCanCreateModes()
+{
+ return 1;
+}
+
+void* vncRandRCreateMode(void* out, int width, int height)
{
RROutputPtr output;
output = out;
+ /* Do we already have the mode? */
+ for (int i = 0; i < output->numModes; i++) {
+ if ((output->modes[i]->mode.width == width) &&
+ (output->modes[i]->mode.height == height))
+ return output->modes[i];
+ }
+
+ /* Just recreate the entire list */
+ vncRandRSetModes(output, width, height);
+
+ /* Find the new mode */
+ for (int i = 0; i < output->numModes; i++) {
+ if ((output->modes[i]->mode.width == width) &&
+ (output->modes[i]->mode.height == height))
+ return output->modes[i];
+ }
+
+ /* Something went horribly wrong */
+ return NULL;
+}
+
+void* vncRandRSetPreferredMode(void* out, void* m)
+{
+ RRModePtr mode;
+ RROutputPtr output;
+ int width, height;
+
+ mode = m;
+ output = out;
+
+ width = mode->mode.width;
+ height = mode->mode.height;
+
/* Already the preferred mode? */
if ((output->numModes >= 1) && (output->numPreferred == 1) &&
- (output->modes[0]->mode.width == width) &&
- (output->modes[0]->mode.height == height))
- return output->modes[0];
+ (output->modes[0] == mode))
+ return mode;
/* Recreate the list, with the mode we want as preferred */
vncRandRSetModes(output, width, height);
+ /* Sanity check */
if ((output->numModes >= 1) && (output->numPreferred == 1) &&
(output->modes[0]->mode.width == width) &&
(output->modes[0]->mode.height == height))
return output->modes[0];
+ /* Something went horribly wrong */
return NULL;
}
@@ -1434,8 +1480,11 @@ static Bool vncRandRInit(ScreenPtr pScreen)
crtc = vncRandRCrtcCreate(pScreen);
/* Make sure the current screen size is the active mode */
- mode = vncRandRCreatePreferredMode(crtc->outputs[0],
- pScreen->width, pScreen->height);
+ mode = vncRandRCreateMode(crtc->outputs[0],
+ pScreen->width, pScreen->height);
+ if (mode == NULL)
+ return FALSE;
+ mode = vncRandRSetPreferredMode(crtc->outputs[0], mode);
if (mode == NULL)
return FALSE;