summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorKeith Packard <keithp@guitar.keithp.com>2007-02-20 23:04:26 -0800
committerKeith Packard <keithp@neko.keithp.com>2007-03-17 23:34:58 -0700
commit9d0c3b52f25df89738fb1a62ccffda8c8cbb4689 (patch)
treebfd47fa3ccdf491f168644d6669f9f0c75d998f1 /hw
parent2c93083edd29a65e73bb2e8eff9d353e92845c9b (diff)
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 3506b9376c2b0db09bfff58d64e07af88a6e8195)
Diffstat (limited to 'hw')
-rw-r--r--hw/xfree86/modes/xf86RandR12.c147
1 files changed, 103 insertions, 44 deletions
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 73647a68b..4213fea52 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -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;
}