Eliminate RRModeRec devPrivate field.
The xf86 mode setting code was mis-using this field to try and store a
pointer to a DisplayModeRec, however, each output has its own copy of every
DisplayModeRec leaving the one in in the RRModeRec devPrivate field pointing
at a random DisplayModeRec.
Instead of attempting to rectify this, eliminating the devPrivate entirely
turned out to be very easy; the DDX code now accepts an arbitrary RRModeRec
structure and set that to the hardware, converting it on the fly to a
DisplayModeRec as needed.
(cherry picked from commit 3506b9376c
)
This commit is contained in:
parent
2c93083edd
commit
9d0c3b52f2
|
@ -556,6 +556,56 @@ xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
|
|||
}
|
||||
|
||||
#if RANDR_12_INTERFACE
|
||||
|
||||
#define FLAG_BITS (RR_HSyncPositive | \
|
||||
RR_HSyncNegative | \
|
||||
RR_VSyncPositive | \
|
||||
RR_VSyncNegative | \
|
||||
RR_Interlace | \
|
||||
RR_DoubleScan | \
|
||||
RR_CSync | \
|
||||
RR_CSyncPositive | \
|
||||
RR_CSyncNegative | \
|
||||
RR_HSkewPresent | \
|
||||
RR_BCast | \
|
||||
RR_PixelMultiplex | \
|
||||
RR_DoubleClock | \
|
||||
RR_ClockDivideBy2)
|
||||
|
||||
static Bool
|
||||
xf86RandRModeMatches (RRModePtr randr_mode,
|
||||
DisplayModePtr mode)
|
||||
{
|
||||
#if 0
|
||||
if (match_name)
|
||||
{
|
||||
/* check for same name */
|
||||
int len = strlen (mode->name);
|
||||
if (randr_mode->mode.nameLength != len) return FALSE;
|
||||
if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check for same timings */
|
||||
if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE;
|
||||
if (randr_mode->mode.width != mode->HDisplay) return FALSE;
|
||||
if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE;
|
||||
if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE;
|
||||
if (randr_mode->mode.hTotal != mode->HTotal) return FALSE;
|
||||
if (randr_mode->mode.hSkew != mode->HSkew) return FALSE;
|
||||
if (randr_mode->mode.height != mode->VDisplay) return FALSE;
|
||||
if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE;
|
||||
if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE;
|
||||
if (randr_mode->mode.vTotal != mode->VTotal) return FALSE;
|
||||
|
||||
/* check for same flags (using only the XF86 valid flag bits) */
|
||||
if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS))
|
||||
return FALSE;
|
||||
|
||||
/* everything matches */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
|
||||
{
|
||||
|
@ -594,12 +644,15 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
|
|||
* We make copies of modes, so pointer equality
|
||||
* isn't sufficient
|
||||
*/
|
||||
for (j = 0; j < randr_output->numModes; j++)
|
||||
for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
|
||||
{
|
||||
DisplayModePtr outMode = randr_output->modes[j]->devPrivate;
|
||||
if (xf86ModesEqual(mode, outMode))
|
||||
RRModePtr m = (j < randr_output->numModes ?
|
||||
randr_output->modes[j] :
|
||||
randr_output->userModes[j-randr_output->numModes]);
|
||||
|
||||
if (xf86RandRModeMatches (m, mode))
|
||||
{
|
||||
randr_mode = randr_output->modes[j];
|
||||
randr_mode = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -611,6 +664,39 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a RandR mode to a DisplayMode
|
||||
*/
|
||||
static void
|
||||
xf86RandRModeConvert (ScrnInfoPtr scrn,
|
||||
RRModePtr randr_mode,
|
||||
DisplayModePtr mode)
|
||||
{
|
||||
mode->prev = NULL;
|
||||
mode->next = NULL;
|
||||
mode->name = NULL;
|
||||
mode->status = MODE_OK;
|
||||
mode->type = 0;
|
||||
|
||||
mode->Clock = randr_mode->mode.dotClock / 1000;
|
||||
|
||||
mode->HDisplay = randr_mode->mode.width;
|
||||
mode->HSyncStart = randr_mode->mode.hSyncStart;
|
||||
mode->HSyncEnd = randr_mode->mode.hSyncEnd;
|
||||
mode->HTotal = randr_mode->mode.hTotal;
|
||||
mode->HSkew = randr_mode->mode.hSkew;
|
||||
|
||||
mode->VDisplay = randr_mode->mode.height;
|
||||
mode->VSyncStart = randr_mode->mode.vSyncStart;
|
||||
mode->VSyncEnd = randr_mode->mode.vSyncEnd;
|
||||
mode->VTotal = randr_mode->mode.vTotal;
|
||||
mode->VScan = 0;
|
||||
|
||||
mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS;
|
||||
|
||||
xf86SetModeCrtc (mode, scrn->adjustFlags);
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86RandR12CrtcSet (ScreenPtr pScreen,
|
||||
RRCrtcPtr randr_crtc,
|
||||
|
@ -624,16 +710,15 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
|
||||
Bool changed = FALSE;
|
||||
int o, ro;
|
||||
xf86CrtcPtr *save_crtcs;
|
||||
Bool save_enabled = crtc->enabled;
|
||||
|
||||
save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
|
||||
if ((mode != NULL) != crtc->enabled)
|
||||
if ((randr_mode != NULL) != crtc->enabled)
|
||||
changed = TRUE;
|
||||
else if (mode && !xf86ModesEqual (&crtc->mode, mode))
|
||||
else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
|
||||
changed = TRUE;
|
||||
|
||||
if (rotation != crtc->rotation)
|
||||
|
@ -667,11 +752,14 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
/* XXX need device-independent mode setting code through an API */
|
||||
if (changed)
|
||||
{
|
||||
crtc->enabled = mode != NULL;
|
||||
crtc->enabled = randr_mode != NULL;
|
||||
|
||||
if (mode)
|
||||
if (randr_mode)
|
||||
{
|
||||
if (!xf86CrtcSetMode (crtc, mode, rotation, x, y))
|
||||
DisplayModeRec mode;
|
||||
|
||||
xf86RandRModeConvert (pScrn, randr_mode, &mode);
|
||||
if (!xf86CrtcSetMode (crtc, &mode, rotation, x, y))
|
||||
{
|
||||
crtc->enabled = save_enabled;
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
|
@ -685,7 +773,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
/*
|
||||
* Save the last successful setting for EnterVT
|
||||
*/
|
||||
crtc->desiredMode = *mode;
|
||||
crtc->desiredMode = mode;
|
||||
crtc->desiredRotation = rotation;
|
||||
crtc->desiredX = x;
|
||||
crtc->desiredY = y;
|
||||
|
@ -733,33 +821,12 @@ xf86RandR12OutputValidateMode (ScreenPtr pScreen,
|
|||
RROutputPtr randr_output,
|
||||
RRModePtr randr_mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
xf86OutputPtr output = randr_output->devPrivate;
|
||||
DisplayModePtr mode = randr_mode->devPrivate;
|
||||
DisplayModeRec mode;
|
||||
|
||||
if (!mode)
|
||||
{
|
||||
mode = xalloc (sizeof (DisplayModeRec) + randr_mode->mode.nameLength + 1);
|
||||
if (!mode)
|
||||
return FALSE;
|
||||
mode->name = (char *) mode + 1;
|
||||
memcpy (mode->name, randr_mode->name, randr_mode->mode.nameLength);
|
||||
mode->name[randr_mode->mode.nameLength] = '\0';
|
||||
mode->Clock = randr_mode->mode.dotClock / 1000;
|
||||
mode->HDisplay = randr_mode->mode.width;
|
||||
mode->HSyncStart = randr_mode->mode.hSyncStart;
|
||||
mode->HSyncEnd = randr_mode->mode.hSyncEnd;
|
||||
mode->HTotal = randr_mode->mode.hTotal;
|
||||
mode->HSkew = randr_mode->mode.hSkew;
|
||||
|
||||
mode->VDisplay = randr_mode->mode.height;
|
||||
mode->VSyncStart = randr_mode->mode.vSyncStart;
|
||||
mode->VSyncEnd = randr_mode->mode.vSyncEnd;
|
||||
mode->VTotal = randr_mode->mode.vTotal;
|
||||
|
||||
mode->Flags = randr_mode->mode.modeFlags;
|
||||
randr_mode->devPrivate = mode;
|
||||
}
|
||||
if (!output->funcs->mode_valid (output, mode))
|
||||
xf86RandRModeConvert (pScrn, randr_mode, &mode);
|
||||
if (output->funcs->mode_valid (output, &mode) != MODE_OK)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -767,13 +834,6 @@ xf86RandR12OutputValidateMode (ScreenPtr pScreen,
|
|||
static void
|
||||
xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode)
|
||||
{
|
||||
DisplayModePtr mode = randr_mode->devPrivate;
|
||||
|
||||
if (mode)
|
||||
{
|
||||
xfree (mode);
|
||||
randr_mode->devPrivate = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -822,7 +882,6 @@ xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
|
|||
|
||||
rrmode = RRModeGet (&modeInfo, mode->name);
|
||||
if (rrmode) {
|
||||
rrmode->devPrivate = mode;
|
||||
rrmodes[nmode++] = rrmode;
|
||||
npreferred += pref;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,6 @@ struct _rrMode {
|
|||
int refcnt;
|
||||
xRRModeInfo mode;
|
||||
char *name;
|
||||
void *devPrivate;
|
||||
ScreenPtr userScreen;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user