randr: Rework panning area verification
This commit is contained in:
parent
219c26ce0c
commit
bad118ace6
|
@ -88,40 +88,88 @@ xf86RandR12ModeRefresh (DisplayModePtr mode)
|
||||||
return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
|
return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Adapt panning area; return TRUE if panning area was valid without adaption */
|
||||||
static int
|
static int
|
||||||
xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
|
xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
|
||||||
{
|
{
|
||||||
|
int ret = TRUE;
|
||||||
|
|
||||||
if (crtc->version < 2)
|
if (crtc->version < 2)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 ||
|
if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) {
|
||||||
crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
|
/* Panning in X is disabled */
|
||||||
memset (&crtc->panningTotalArea, 0, sizeof(BoxRec));
|
if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2)
|
||||||
memset (&crtc->panningTrackingArea, 0, sizeof(BoxRec));
|
/* Illegal configuration -> fail/disable */
|
||||||
memset (&crtc->panningBorder, 0, 4*sizeof(INT16));
|
ret = FALSE;
|
||||||
return TRUE;
|
crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0;
|
||||||
|
crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0;
|
||||||
|
crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
|
||||||
|
} else {
|
||||||
|
/* Panning in X is enabled */
|
||||||
|
if (crtc->panningTotalArea.x1 < 0) {
|
||||||
|
/* Panning region outside screen -> move inside */
|
||||||
|
crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1;
|
||||||
|
crtc->panningTotalArea.x1 = 0;
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) {
|
||||||
|
/* Panning region smaller than displayed area -> crop to displayed area */
|
||||||
|
crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay;
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
if (crtc->panningTotalArea.x2 > screenWidth) {
|
||||||
|
/* Panning region larger than screen -> move inside, then crop to screen */
|
||||||
|
crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth;
|
||||||
|
crtc->panningTotalArea.x2 = screenWidth;
|
||||||
|
ret = FALSE;
|
||||||
|
if (crtc->panningTotalArea.x1 < 0)
|
||||||
|
crtc->panningTotalArea.x1 = 0;
|
||||||
|
}
|
||||||
|
if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) {
|
||||||
|
/* Borders too large -> set to 0 */
|
||||||
|
crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 ||
|
if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
|
||||||
crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1 ||
|
/* Panning in Y is disabled */
|
||||||
crtc->panningTotalArea.x1 < 0 ||
|
if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2)
|
||||||
crtc->panningTotalArea.y1 < 0 ||
|
/* Illegal configuration -> fail/disable */
|
||||||
crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay ||
|
ret = FALSE;
|
||||||
crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay ||
|
crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0;
|
||||||
crtc->panningTotalArea.x2 > screenWidth ||
|
crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0;
|
||||||
crtc->panningTotalArea.y2 > screenHeight)
|
crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
|
||||||
{
|
} else {
|
||||||
memset (&crtc->panningTotalArea, 0, sizeof(BoxRec));
|
/* Panning in Y is enabled */
|
||||||
memset (&crtc->panningTrackingArea, 0, sizeof(BoxRec));
|
if (crtc->panningTotalArea.y1 < 0) {
|
||||||
memset (&crtc->panningBorder, 0, 4*sizeof(INT16));
|
/* Panning region outside screen -> move inside */
|
||||||
return FALSE;
|
crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1;
|
||||||
|
crtc->panningTotalArea.y1 = 0;
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) {
|
||||||
|
/* Panning region smaller than displayed area -> crop to displayed area */
|
||||||
|
crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay;
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
if (crtc->panningTotalArea.y2 > screenHeight) {
|
||||||
|
/* Panning region larger than screen -> move inside, then crop to screen */
|
||||||
|
crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight;
|
||||||
|
crtc->panningTotalArea.y2 = screenHeight;
|
||||||
|
ret = FALSE;
|
||||||
|
if (crtc->panningTotalArea.y1 < 0)
|
||||||
|
crtc->panningTotalArea.y1 = 0;
|
||||||
|
}
|
||||||
|
if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
|
||||||
|
/* Borders too large -> set to 0 */
|
||||||
|
crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay ||
|
|
||||||
crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
|
return ret;
|
||||||
memset (&crtc->panningBorder, 0, 4*sizeof(INT16));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue