diff options
author | Peter Åstrand (astrand) <astrand@cendio.se> | 2018-03-27 09:14:38 +0200 |
---|---|---|
committer | Peter Åstrand (astrand) <astrand@cendio.se> | 2018-04-09 20:31:25 +0200 |
commit | 54f49fded05ba29a93f6b77f8b70316e18342580 (patch) | |
tree | 46d41db5da3595bf6966631174a7752103cebe16 /unix/xserver | |
parent | 651faf8127276d6704f5ee5304586b66c89cc9b4 (diff) | |
download | tigervnc-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.c | 64 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/XorgGlue.h | 4 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncModule.c | 33 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/xvnc.c | 63 |
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; |