RandR 1.0 refresh rates unscrambled. SetScreenConfig uses RRCrtcSet right.
RandR 1.0 refresh rates were scrambled when working with a 1.2 driver that returned sizes in a mixed order. SetScreenConfig was treating RRCrtcSet as returning an RandR status instead of a Bool.
This commit is contained in:
parent
98d18a6578
commit
6dc711833d
113
randr/rrscreen.c
113
randr/rrscreen.c
|
@ -481,62 +481,81 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
|
||||||
RR10DataPtr data;
|
RR10DataPtr data;
|
||||||
RRScreenSizePtr size;
|
RRScreenSizePtr size;
|
||||||
int nmode = output->numModes;
|
int nmode = output->numModes;
|
||||||
int i, j, k;
|
int o, os, l, r;
|
||||||
RRScreenRatePtr refresh;
|
RRScreenRatePtr refresh;
|
||||||
CARD16 vRefresh;
|
CARD16 vRefresh;
|
||||||
RRModePtr mode;
|
RRModePtr mode;
|
||||||
|
Bool *used;
|
||||||
|
|
||||||
/* Make sure there is plenty of space for any combination */
|
/* Make sure there is plenty of space for any combination */
|
||||||
data = malloc (sizeof (RR10DataRec) +
|
data = malloc (sizeof (RR10DataRec) +
|
||||||
sizeof (RRScreenSize) * nmode +
|
sizeof (RRScreenSize) * nmode +
|
||||||
sizeof (RRScreenRate) * nmode);
|
sizeof (RRScreenRate) * nmode +
|
||||||
|
sizeof (Bool) * nmode);
|
||||||
if (!data)
|
if (!data)
|
||||||
return NULL;
|
return NULL;
|
||||||
size = (RRScreenSizePtr) (data + 1);
|
size = (RRScreenSizePtr) (data + 1);
|
||||||
refresh = (RRScreenRatePtr) (size + nmode);
|
refresh = (RRScreenRatePtr) (size + nmode);
|
||||||
|
used = (Bool *) (refresh + nmode);
|
||||||
|
memset (used, '\0', sizeof (Bool) * nmode);
|
||||||
data->sizes = size;
|
data->sizes = size;
|
||||||
data->nsize = 0;
|
data->nsize = 0;
|
||||||
data->nrefresh = 0;
|
data->nrefresh = 0;
|
||||||
data->size = 0;
|
data->size = 0;
|
||||||
data->refresh = 0;
|
data->refresh = 0;
|
||||||
for (i = 0; i < output->numModes; i++)
|
|
||||||
|
/*
|
||||||
|
* find modes not yet listed
|
||||||
|
*/
|
||||||
|
for (o = 0; o < output->numModes; o++)
|
||||||
{
|
{
|
||||||
mode = output->modes[i];
|
if (used[o]) continue;
|
||||||
for (j = 0; j < data->nsize; j++)
|
|
||||||
if (mode->mode.width == size[j].width &&
|
mode = output->modes[o];
|
||||||
mode->mode.height == size[j].height)
|
|
||||||
break;
|
l = data->nsize;
|
||||||
if (j == data->nsize)
|
size[l].id = data->nsize;
|
||||||
|
size[l].width = mode->mode.width;
|
||||||
|
size[l].height = mode->mode.height;
|
||||||
|
if (output->mmWidth && output->mmHeight) {
|
||||||
|
size[l].mmWidth = output->mmWidth;
|
||||||
|
size[l].mmHeight = output->mmHeight;
|
||||||
|
} else {
|
||||||
|
size[l].mmWidth = pScreen->mmWidth;
|
||||||
|
size[l].mmHeight = pScreen->mmHeight;
|
||||||
|
}
|
||||||
|
size[l].nRates = 0;
|
||||||
|
size[l].pRates = &refresh[data->nrefresh];
|
||||||
|
data->nsize++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find all modes with matching size
|
||||||
|
*/
|
||||||
|
for (os = o; os < output->numModes; os++)
|
||||||
{
|
{
|
||||||
size[j].id = j;
|
mode = output->modes[os];
|
||||||
size[j].width = mode->mode.width;
|
if (mode->mode.width == size[l].width &&
|
||||||
size[j].height = mode->mode.height;
|
mode->mode.height == size[l].height)
|
||||||
if (output->mmWidth && output->mmHeight) {
|
{
|
||||||
size[j].mmWidth = output->mmWidth;
|
vRefresh = RRVerticalRefresh (&mode->mode);
|
||||||
size[j].mmHeight = output->mmHeight;
|
used[os] = TRUE;
|
||||||
} else {
|
|
||||||
size[j].mmWidth = pScreen->mmWidth;
|
for (r = 0; r < size[l].nRates; r++)
|
||||||
size[j].mmHeight = pScreen->mmHeight;
|
if (vRefresh == size[l].pRates[r].rate)
|
||||||
|
break;
|
||||||
|
if (r == size[l].nRates)
|
||||||
|
{
|
||||||
|
size[l].pRates[r].rate = vRefresh;
|
||||||
|
size[l].pRates[r].mode = mode;
|
||||||
|
size[l].nRates++;
|
||||||
|
data->nrefresh++;
|
||||||
|
}
|
||||||
|
if (mode == output->crtc->mode)
|
||||||
|
{
|
||||||
|
data->size = l;
|
||||||
|
data->refresh = vRefresh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
size[j].nRates = 0;
|
|
||||||
size[j].pRates = &refresh[data->nrefresh];
|
|
||||||
data->nsize++;
|
|
||||||
}
|
|
||||||
vRefresh = RRVerticalRefresh (&mode->mode);
|
|
||||||
for (k = 0; k < size[j].nRates; k++)
|
|
||||||
if (vRefresh == size[j].pRates[k].rate)
|
|
||||||
break;
|
|
||||||
if (k == size[j].nRates)
|
|
||||||
{
|
|
||||||
size[j].pRates[k].rate = vRefresh;
|
|
||||||
size[j].pRates[k].mode = mode;
|
|
||||||
size[j].nRates++;
|
|
||||||
data->nrefresh++;
|
|
||||||
}
|
|
||||||
if (mode == output->crtc->mode)
|
|
||||||
{
|
|
||||||
data->size = j;
|
|
||||||
data->refresh = vRefresh;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
|
@ -864,22 +883,28 @@ ProcRRSetScreenConfig (ClientPtr client)
|
||||||
|
|
||||||
for (c = 0; c < pScrPriv->numCrtcs; c++)
|
for (c = 0; c < pScrPriv->numCrtcs; c++)
|
||||||
{
|
{
|
||||||
rep.status = RRCrtcSet (pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0,
|
if (!RRCrtcSet (pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0,
|
||||||
0, NULL);
|
0, NULL))
|
||||||
if (rep.status != Success)
|
{
|
||||||
|
rep.status = RRSetConfigFailed;
|
||||||
|
/* XXX recover from failure */
|
||||||
goto sendReply;
|
goto sendReply;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!RRScreenSizeSet (pScreen, mode->mode.width, mode->mode.height,
|
if (!RRScreenSizeSet (pScreen, mode->mode.width, mode->mode.height,
|
||||||
pScreen->mmWidth, pScreen->mmHeight))
|
pScreen->mmWidth, pScreen->mmHeight))
|
||||||
{
|
{
|
||||||
rep.status = RRSetConfigFailed;
|
rep.status = RRSetConfigFailed;
|
||||||
|
/* XXX recover from failure */
|
||||||
goto sendReply;
|
goto sendReply;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation,
|
if (!RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, 1, &output))
|
||||||
1, &output);
|
rep.status = RRSetConfigFailed;
|
||||||
|
else
|
||||||
|
rep.status = RRSetConfigSuccess;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX Configure other crtcs to mirror as much as possible
|
* XXX Configure other crtcs to mirror as much as possible
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user