Fix physical DPI and size for rotated screens on X11

Rotated screens would use the unrotated physical geometry, causing the
calculated physical DPI to be completely wrong.

In RandR, the output does not rotate, so the physical size is always for the
unrotated display. The transformation is done on the crtc.
http://www.x.org/releases/X11R7.6/doc/randrproto/randrproto.txt

Task-number: QTBUG-43688
Change-Id: Ifde192fcc99a37d0bfd6d57b4cdeac124a054ca3
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Reviewed-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Paul Olav Tvete 2015-01-07 15:19:07 +01:00
parent 7ab513d539
commit e6699afbee
2 changed files with 22 additions and 1 deletions

View File

@ -53,7 +53,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
, m_screen(scr)
, m_crtc(output ? output->crtc : 0)
, m_outputName(outputName)
, m_sizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
, m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
, m_virtualSize(scr->width_in_pixels, scr->height_in_pixels)
, m_virtualSizeMillimeters(scr->width_in_millimeters, scr->height_in_millimeters)
, m_orientation(Qt::PrimaryOrientation)
@ -71,6 +71,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
updateGeometry(output ? output->timestamp : 0);
updateRefreshRate();
const int dpr = int(devicePixelRatio());
// On VNC, it can be that physical size is unknown while
// virtual size is known (probably back-calculated from DPI and resolution)
@ -93,6 +94,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
qDebug(" virtual height.: %lf", m_virtualSizeMillimeters.height());
qDebug(" virtual geom...: %d x %d", m_virtualSize.width(), m_virtualSize.height());
qDebug(" avail virt geom: %d x %d +%d +%d", m_availableGeometry.width(), m_availableGeometry.height(), m_availableGeometry.x(), m_availableGeometry.y());
qDebug(" orientation....: %d", m_orientation);
qDebug(" pixel ratio....: %d", m_devicePixelRatio);
qDebug(" depth..........: %d", screen()->root_depth);
qDebug(" white pixel....: %x", screen()->white_pixel);
@ -413,6 +415,24 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
if (crtc) {
xGeometry = QRect(crtc->x, crtc->y, crtc->width, crtc->height);
xAvailableGeometry = xGeometry;
switch (crtc->rotation) {
case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
m_orientation = Qt::LandscapeOrientation;
m_sizeMillimeters = m_outputSizeMillimeters;
break;
case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left
m_orientation = Qt::PortraitOrientation;
m_sizeMillimeters = m_outputSizeMillimeters.transposed();
break;
case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted
m_orientation = Qt::InvertedLandscapeOrientation;
m_sizeMillimeters = m_outputSizeMillimeters;
break;
case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right
m_orientation = Qt::InvertedPortraitOrientation;
m_sizeMillimeters = m_outputSizeMillimeters.transposed();
break;
}
free(crtc);
}
}

View File

@ -111,6 +111,7 @@ private:
xcb_screen_t *m_screen;
xcb_randr_crtc_t m_crtc;
QString m_outputName;
QSizeF m_outputSizeMillimeters;
QSizeF m_sizeMillimeters;
QRect m_geometry;
QRect m_availableGeometry;