summaryrefslogtreecommitdiff
path: root/src/radeon_mergedfb.c
diff options
context:
space:
mode:
authorAlex Deucher <agd5f@yahoo.com>2006-04-01 23:02:40 +0000
committerAlex Deucher <agd5f@yahoo.com>2006-04-01 23:02:40 +0000
commitf1ce6170ef21e1f9769337c3138cd8d65c33e40a (patch)
treebd8be17defe5bb11646db46b5f3eb4b43ca3832e /src/radeon_mergedfb.c
parent607f18cfbfc2a7b5509f8b567bf510fce31b361e (diff)
- Fix dpi when switching from clone to dualhead with MergedFB.
- Add ConstantDPI option to force a particlar dpi across mode changes Both based on Thomas Winischhofer's sis code.
Diffstat (limited to 'src/radeon_mergedfb.c')
-rw-r--r--src/radeon_mergedfb.c262
1 files changed, 160 insertions, 102 deletions
diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 0510bb6..70846d9 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -1741,119 +1741,125 @@ RADEONAdjustFrameMerged(int scrnIndex, int x, int y, int flags)
RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);
}
-void
-RADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel)
+static void
+RADEONMergedFBCalcDPI(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel, Bool quiet)
{
- RADEONInfoPtr info = RADEONPTR(pScrn1);
- MessageType from = X_DEFAULT;
- xf86MonPtr DDC1 = (xf86MonPtr)(pScrn1->monitor->DDC);
- xf86MonPtr DDC2 = (xf86MonPtr)(pScrn2->monitor->DDC);
- int ddcWidthmm = 0, ddcHeightmm = 0;
- const char *dsstr = "MergedFB: Display dimensions: (%d, %d) mm\n";
-
- /* This sets the DPI for MergedFB mode. The problem is that
- * this can never be exact, because the output devices may
- * have different dimensions. This function tries to compromise
- * through a few assumptions, and it just calculates an average DPI
- * value for both monitors.
- */
-
- /* Given DisplaySize should regard BOTH monitors */
- pScrn1->widthmm = pScrn1->monitor->widthmm;
- pScrn1->heightmm = pScrn1->monitor->heightmm;
-
- /* Get DDC display size; if only either CRT1 or CRT2 provided these,
- * assume equal dimensions for both, otherwise add dimensions
- */
- if( (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
- (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) ) {
- ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
- ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf:
- ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
- break;
- case radeonAbove:
- case radeonBelow:
- ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
- default:
- break;
- }
-
- } else if(DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
- ddcWidthmm = DDC1->features.hsize * 10;
- ddcHeightmm = DDC1->features.vsize * 10;
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf:
- ddcWidthmm *= 2;
- break;
- case radeonAbove:
- case radeonBelow:
- ddcHeightmm *= 2;
- default:
- break;
- }
- } else if(DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0) ) {
- ddcWidthmm = DDC2->features.hsize * 10;
- ddcHeightmm = DDC2->features.vsize * 10;
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf:
- ddcWidthmm *= 2;
- break;
- case radeonAbove:
- case radeonBelow:
- ddcHeightmm *= 2;
- default:
- break;
- }
- }
+ RADEONInfoPtr info = RADEONPTR(pScrn1);
+ MessageType from = X_DEFAULT;
+ xf86MonPtr DDC1 = (xf86MonPtr)(pScrn1->monitor->DDC);
+ xf86MonPtr DDC2 = (xf86MonPtr)(pScrn2->monitor->DDC);
+ int ddcWidthmm = 0, ddcHeightmm = 0;
+ const char *dsstr = "MergedFB: Display dimensions: %dx%d mm\n";
+
+ /* This sets the DPI for MergedFB mode. The problem is that
+ * this can never be exact, because the output devices may
+ * have different dimensions. This function tries to compromise
+ * through a few assumptions, and it just calculates an average
+ * DPI value for both monitors.
+ */
- if(monitorResolution > 0) {
+ /* Copy user-given DisplaySize (which should regard BOTH monitors!) */
+ pScrn1->widthmm = pScrn1->monitor->widthmm;
+ pScrn1->heightmm = pScrn1->monitor->heightmm;
- /* Set command line given values (overrules given options) */
- pScrn1->xDpi = monitorResolution;
- pScrn1->yDpi = monitorResolution;
- from = X_CMDLINE;
+ if(monitorResolution > 0) {
- } else if(info->MergedFBXDPI) {
+ /* Set command line given values (overrules given options) */
+ pScrn1->xDpi = monitorResolution;
+ pScrn1->yDpi = monitorResolution;
+ from = X_CMDLINE;
- /* Set option-wise given values (overrule DisplaySize) */
- pScrn1->xDpi = info->MergedFBXDPI;
- pScrn1->yDpi = info->MergedFBYDPI;
- from = X_CONFIG;
+ } else if(info->MergedFBXDPI) {
- } else if(pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
+ /* Set option-wise given values (overrules DisplaySize config option) */
+ pScrn1->xDpi = info->MergedFBXDPI;
+ pScrn1->yDpi = info->MergedFBYDPI;
+ from = X_CONFIG;
- /* Set values calculated from given DisplaySize */
- from = X_CONFIG;
- if(pScrn1->widthmm > 0) {
- pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
- }
- if(pScrn1->heightmm > 0) {
- pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
- }
- xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm, pScrn1->heightmm);
+ } else if(pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
+
+ /* Set values calculated from given DisplaySize */
+ from = X_CONFIG;
+ if(pScrn1->widthmm > 0) {
+ pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
+ }
+ if(pScrn1->heightmm > 0) {
+ pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
+ }
+ if(!quiet) {
+ xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm, pScrn1->heightmm);
+ }
} else if(ddcWidthmm && ddcHeightmm) {
- /* Set values from DDC-provided display size */
- from = X_PROBED;
- xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm );
- pScrn1->widthmm = ddcWidthmm;
- pScrn1->heightmm = ddcHeightmm;
- if(pScrn1->widthmm > 0) {
- pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
- }
- if(pScrn1->heightmm > 0) {
- pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
- }
+ /* Set values from DDC-provided display size */
+
+ /* Get DDC display size; if only either CRT1 or CRT2 provided these,
+ * assume equal dimensions for both, otherwise add dimensions
+ */
+ if( (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
+ (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) ) {
+ ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
+ ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
+ switch(srel) {
+ case radeonLeftOf:
+ case radeonRightOf:
+ ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
+ break;
+ case radeonAbove:
+ case radeonBelow:
+ ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
+ default:
+ break;
+ }
+ } else if(DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
+ ddcWidthmm = DDC1->features.hsize * 10;
+ ddcHeightmm = DDC1->features.vsize * 10;
+ switch(srel) {
+ case radeonLeftOf:
+ case radeonRightOf:
+ ddcWidthmm *= 2;
+ break;
+ case radeonAbove:
+ case radeonBelow:
+ ddcHeightmm *= 2;
+ default:
+ break;
+ }
+ } else if(DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0) ) {
+ ddcWidthmm = DDC2->features.hsize * 10;
+ ddcHeightmm = DDC2->features.vsize * 10;
+ switch(srel) {
+ case radeonLeftOf:
+ case radeonRightOf:
+ ddcWidthmm *= 2;
+ break;
+ case radeonAbove:
+ case radeonBelow:
+ ddcHeightmm *= 2;
+ default:
+ break;
+ }
+ }
+
+ from = X_PROBED;
+
+ if(!quiet) {
+ xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm);
+ }
+
+ pScrn1->widthmm = ddcWidthmm;
+ pScrn1->heightmm = ddcHeightmm;
+ if(pScrn1->widthmm > 0) {
+ pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
+ }
+ if(pScrn1->heightmm > 0) {
+ pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
+ }
} else {
- pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
+ pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
}
@@ -1866,8 +1872,60 @@ RADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel
pScrn2->xDpi = pScrn1->xDpi;
pScrn2->yDpi = pScrn1->yDpi;
- xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
- pScrn1->xDpi, pScrn1->yDpi);
+ if(!quiet) {
+ xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
+ pScrn1->xDpi, pScrn1->yDpi);
+ }
+}
+
+
+void
+RADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn1);
+
+ RADEONMergedFBCalcDPI(pScrn1, pScrn2, srel, FALSE);
+
+ info->MergedDPISRel = srel;
+ info->RADEONMergedDPIVX = pScrn1->virtualX;
+ info->RADEONMergedDPIVY = pScrn1->virtualY;
+
+}
+
+void
+RADEONMergedFBResetDpi(ScrnInfoPtr pScrn, Bool force)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+ RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
+
+ /* This does the same calculation for the DPI as
+ * the initial run. This means that an eventually
+ * given -dpi command line switch will lead to
+ * constant dpi values, regardless of the virtual
+ * screen size.
+ * I consider this consequent. If this is undesired,
+ * one should use the DisplaySize parameter in the
+ * config file instead of the command line switch.
+ * The DPI will be calculated then.
+ */
+
+ if(force ||
+ (info->MergedDPISRel != srel) ||
+ (info->RADEONMergedDPIVX != pScrn->virtualX) ||
+ (info->RADEONMergedDPIVY != pScrn->virtualY)
+ ) {
+
+ RADEONMergedFBCalcDPI(pScrn, info->CRT2pScrn, srel, TRUE);
+
+ pScreen->mmWidth = (pScrn->virtualX * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10);
+ pScreen->mmHeight = (pScrn->virtualY * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10);
+
+ info->MergedDPISRel = srel;
+ info->RADEONMergedDPIVX = pScrn->virtualX;
+ info->RADEONMergedDPIVY = pScrn->virtualY;
+
+ }
}
/* radeon cursor helpers */