hw/xfree86: Propagate physical dimensions from DRM connector

Physical dimmension of display can be obtained not just by configuration or
DDC, but also directly from kernel via drmModeGetConnector(). Until now
xserver silently discarded these values even when no configuration nor EDID
were present and fallbacked to default DPI.
This commit is contained in:
Daniel Strnad 2020-05-19 15:52:35 +02:00 committed by Povilas Kanapickas
parent f8a6be04d0
commit 05b3c681ea
3 changed files with 28 additions and 14 deletions

View File

@ -55,6 +55,7 @@
#include "xf86Xinput.h" #include "xf86Xinput.h"
#include "xf86InPriv.h" #include "xf86InPriv.h"
#include "mivalidate.h" #include "mivalidate.h"
#include "xf86Crtc.h"
/* For xf86GetClocks */ /* For xf86GetClocks */
#if defined(CSRG_BASED) || defined(__GNU__) #if defined(CSRG_BASED) || defined(__GNU__)
@ -851,8 +852,9 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
{ {
MessageType from = X_DEFAULT; MessageType from = X_DEFAULT;
xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC); xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC);
int ddcWidthmm, ddcHeightmm; int probedWidthmm, probedHeightmm;
int widthErr, heightErr; int widthErr, heightErr;
xf86OutputPtr compat = xf86CompatOutput(pScrn);
/* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */ /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
pScrn->widthmm = pScrn->monitor->widthmm; pScrn->widthmm = pScrn->monitor->widthmm;
@ -862,11 +864,15 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
/* DDC gives display size in mm for individual modes, /* DDC gives display size in mm for individual modes,
* but cm for monitor * but cm for monitor
*/ */
ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */ probedWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */ probedHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
}
else if (compat && compat->mm_width > 0 && compat->mm_height > 0) {
probedWidthmm = compat->mm_width;
probedHeightmm = compat->mm_height;
} }
else { else {
ddcWidthmm = ddcHeightmm = 0; probedWidthmm = probedHeightmm = 0;
} }
if (monitorResolution > 0) { if (monitorResolution > 0) {
@ -892,15 +898,15 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
pScrn->widthmm, pScrn->heightmm); pScrn->widthmm, pScrn->heightmm);
/* Warn if config and probe disagree about display size */ /* Warn if config and probe disagree about display size */
if (ddcWidthmm && ddcHeightmm) { if (probedWidthmm && probedHeightmm) {
if (pScrn->widthmm > 0) { if (pScrn->widthmm > 0) {
widthErr = abs(ddcWidthmm - pScrn->widthmm); widthErr = abs(probedWidthmm - pScrn->widthmm);
} }
else { else {
widthErr = 0; widthErr = 0;
} }
if (pScrn->heightmm > 0) { if (pScrn->heightmm > 0) {
heightErr = abs(ddcHeightmm - pScrn->heightmm); heightErr = abs(probedHeightmm - pScrn->heightmm);
} }
else { else {
heightErr = 0; heightErr = 0;
@ -909,17 +915,17 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
/* Should include config file name for monitor here */ /* Should include config file name for monitor here */
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n", "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
ddcWidthmm, ddcHeightmm, pScrn->widthmm, probedWidthmm, probedHeightmm, pScrn->widthmm,
pScrn->heightmm); pScrn->heightmm);
} }
} }
} }
else if (ddcWidthmm && ddcHeightmm) { else if (probedWidthmm && probedHeightmm) {
from = X_PROBED; from = X_PROBED;
xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
ddcWidthmm, ddcHeightmm); probedWidthmm, probedHeightmm);
pScrn->widthmm = ddcWidthmm; pScrn->widthmm = probedWidthmm;
pScrn->heightmm = ddcHeightmm; pScrn->heightmm = probedHeightmm;
if (pScrn->widthmm > 0) { if (pScrn->widthmm > 0) {
pScrn->xDpi = pScrn->xDpi =
(int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm); (int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);

View File

@ -3256,8 +3256,10 @@ xf86OutputSetEDID(xf86OutputPtr output, xf86MonPtr edid_mon)
free(output->MonInfo); free(output->MonInfo);
output->MonInfo = edid_mon; output->MonInfo = edid_mon;
output->mm_width = 0; if (edid_mon) {
output->mm_height = 0; output->mm_width = 0;
output->mm_height = 0;
}
if (debug_modes) { if (debug_modes) {
xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n",

View File

@ -806,6 +806,12 @@ xf86RandR12CreateScreenResources(ScreenPtr pScreen)
mmWidth = output->conf_monitor->mon_width; mmWidth = output->conf_monitor->mon_width;
mmHeight = output->conf_monitor->mon_height; mmHeight = output->conf_monitor->mon_height;
} }
else if (output &&
(output->mm_width > 0 &&
output->mm_height > 0)) {
mmWidth = output->mm_width;
mmHeight = output->mm_height;
}
else { else {
/* /*
* Otherwise, just set the screen to DEFAULT_DPI * Otherwise, just set the screen to DEFAULT_DPI