Beispiel #1
0
/*!
    \brief handle the XCB screen change event and update properties

    On a mobile device, the ideal use case is that the accelerometer would
    drive the orientation. This could be achieved by using QSensors to read the
    accelerometer and adjusting the rotation in QML, or by reading the
    orientation from the QScreen object and doing the same, or in many other
    ways. However, on X we have the XRandR extension, which makes it possible
    to have the whole screen rotated, so that individual apps DO NOT have to
    rotate themselves. Apps could optionally use the
    QScreen::primaryOrientation property to optimize layout though.
    Furthermore, there is no support in X for accelerometer events anyway. So
    it makes more sense on a Linux system running X to just run a daemon which
    monitors the accelerometer and runs xrandr automatically to do the rotation,
    then apps do not have to be aware of it (but probably the window manager
    would resize them accordingly). updateGeometry() is written with this
    design in mind. Therefore the physical geometry, available geometry,
    virtual geometry, orientation and primaryOrientation should all change at
    the same time.  On a system which cannot rotate the whole screen, it would
    be correct for only the orientation (not the primary orientation) to
    change.
*/
void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event)
{
    updateGeometry(change_event->config_timestamp);

    switch (change_event->rotation) {
    case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
        m_orientation = Qt::LandscapeOrientation;
        m_virtualSize.setWidth(change_event->width);
        m_virtualSize.setHeight(change_event->height);
        m_virtualSizeMillimeters.setWidth(change_event->mwidth);
        m_virtualSizeMillimeters.setHeight(change_event->mheight);
        break;
    case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left
        m_orientation = Qt::PortraitOrientation;
        m_virtualSize.setWidth(change_event->height);
        m_virtualSize.setHeight(change_event->width);
        m_virtualSizeMillimeters.setWidth(change_event->mheight);
        m_virtualSizeMillimeters.setHeight(change_event->mwidth);
        break;
    case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted
        m_orientation = Qt::InvertedLandscapeOrientation;
        m_virtualSize.setWidth(change_event->width);
        m_virtualSize.setHeight(change_event->height);
        m_virtualSizeMillimeters.setWidth(change_event->mwidth);
        m_virtualSizeMillimeters.setHeight(change_event->mheight);
        break;
    case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right
        m_orientation = Qt::InvertedPortraitOrientation;
        m_virtualSize.setWidth(change_event->height);
        m_virtualSize.setHeight(change_event->width);
        m_virtualSizeMillimeters.setWidth(change_event->mheight);
        m_virtualSizeMillimeters.setHeight(change_event->mwidth);
        break;
    // We don't need to do anything with these, since QScreen doesn't store reflection state,
    // and Qt-based applications probably don't need to care about it anyway.
    case XCB_RANDR_ROTATION_REFLECT_X: break;
    case XCB_RANDR_ROTATION_REFLECT_Y: break;
    }

    QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
    QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);

    QDpi ldpi = logicalDpi();
    QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), ldpi.first, ldpi.second);
}
qreal QEGLDeviceIntegration::pixelDensity() const
{
    return qRound(logicalDpi().first / qreal(100));
}