summaryrefslogtreecommitdiff
path: root/hw/xfree86/modes/xf86RandR12.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/modes/xf86RandR12.c')
-rw-r--r--hw/xfree86/modes/xf86RandR12.c140
1 files changed, 124 insertions, 16 deletions
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 5e8225e54..13437a5a5 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -557,6 +557,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)
{
@@ -595,12 +645,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;
}
}
@@ -612,6 +665,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,
@@ -625,16 +711,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)
@@ -668,11 +753,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++)
@@ -686,7 +774,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;
@@ -729,6 +817,26 @@ xf86RandR12OutputSetProperty (ScreenPtr pScreen,
return output->funcs->set_property(output, property, value);
}
+static Bool
+xf86RandR12OutputValidateMode (ScreenPtr pScreen,
+ RROutputPtr randr_output,
+ RRModePtr randr_mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86OutputPtr output = randr_output->devPrivate;
+ DisplayModeRec mode;
+
+ xf86RandRModeConvert (pScrn, randr_mode, &mode);
+ if (output->funcs->mode_valid (output, &mode) != MODE_OK)
+ return FALSE;
+ return TRUE;
+}
+
+static void
+xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode)
+{
+}
+
/**
* Given a list of xf86 modes and a RandR Output object, construct
* RandR modes and assign them to the output
@@ -775,7 +883,6 @@ xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
rrmode = RRModeGet (&modeInfo, mode->name);
if (rrmode) {
- rrmode->devPrivate = mode;
rrmodes[nmode++] = rrmode;
npreferred += pref;
}
@@ -905,8 +1012,7 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
{
xf86CrtcPtr crtc = config->crtc[c];
- crtc->randr_crtc = RRCrtcCreate (crtc);
- RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
+ crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
RRCrtcGammaSetSize (crtc->randr_crtc, 256);
}
/*
@@ -916,13 +1022,13 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
{
xf86OutputPtr output = config->output[o];
- output->randr_output = RROutputCreate (output->name,
+ output->randr_output = RROutputCreate (pScreen, output->name,
strlen (output->name),
output);
- RROutputAttachScreen (output->randr_output, pScreen);
if (output->funcs->create_resources != NULL)
output->funcs->create_resources(output);
+ RRPostPendingProperties (output->randr_output);
}
return TRUE;
}
@@ -959,6 +1065,8 @@ xf86RandR12Init12 (ScreenPtr pScreen)
rp->rrCrtcSet = xf86RandR12CrtcSet;
rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
+ rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
+ rp->rrModeDestroy = xf86RandR12ModeDestroy;
rp->rrSetConfig = NULL;
pScrn->PointerMoved = xf86RandR12PointerMoved;
if (!xf86RandR12CreateObjects12 (pScreen))