summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qscreen.cpp14
-rw-r--r--src/gui/kernel/qscreen.h8
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp91
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp184
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h31
6 files changed, 263 insertions, 67 deletions
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 7a3854be81..13740e5c5f 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -286,6 +286,9 @@ QList<QScreen *> QScreen::virtualSiblings() const
}
/*!
+ \property QScreen::virtualSize
+ \brief the pixel size of the virtual desktop to which this screen belongs
+
Returns the pixel size of the virtual desktop corresponding to this screen.
This is the combined size of the virtual siblings' individual geometries.
@@ -298,6 +301,9 @@ QSize QScreen::virtualSize() const
}
/*!
+ \property QScreen::virtualGeometry
+ \brief the pixel geometry of the virtual desktop to which this screen belongs
+
Returns the pixel geometry of the virtual desktop corresponding to this screen.
This is the union of the virtual siblings' individual geometries.
@@ -313,6 +319,9 @@ QRect QScreen::virtualGeometry() const
}
/*!
+ \property QScreen::availableVirtualSize
+ \brief the available size of the virtual desktop to which this screen belongs
+
Returns the available pixel size of the virtual desktop corresponding to this screen.
This is the combined size of the virtual siblings' individual available geometries.
@@ -325,7 +334,10 @@ QSize QScreen::availableVirtualSize() const
}
/*!
- Returns the available size of the virtual desktop corresponding to this screen.
+ \property QScreen::availableVirtualGeometry
+ \brief the available geometry of the virtual desktop to which this screen belongs
+
+ Returns the available geometry of the virtual desktop corresponding to this screen.
This is the union of the virtual siblings' individual available geometries.
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index 5902d8c757..588a2cb445 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -71,7 +71,13 @@ class Q_GUI_EXPORT QScreen : public QObject
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(int depth READ depth CONSTANT)
Q_PROPERTY(QSize size READ size NOTIFY sizeChanged)
+ Q_PROPERTY(QSize availableSize READ availableSize NOTIFY availableSizeChanged)
+ Q_PROPERTY(QSize virtualSize READ virtualSize NOTIFY sizeChanged)
+ Q_PROPERTY(QSize availableVirtualSize READ availableVirtualSize NOTIFY availableSizeChanged)
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
+ Q_PROPERTY(QRect availableGeometry READ availableGeometry NOTIFY availableGeometryChanged)
+ Q_PROPERTY(QRect virtualGeometry READ virtualGeometry NOTIFY sizeChanged)
+ Q_PROPERTY(QRect availableVirtualGeometry READ availableVirtualGeometry NOTIFY availableGeometryChanged)
Q_PROPERTY(QSizeF physicalSize READ physicalSize CONSTANT)
Q_PROPERTY(qreal physicalDotsPerInchX READ physicalDotsPerInchX NOTIFY physicalDotsPerInchXChanged)
Q_PROPERTY(qreal physicalDotsPerInchY READ physicalDotsPerInchY NOTIFY physicalDotsPerInchYChanged)
@@ -79,8 +85,6 @@ class Q_GUI_EXPORT QScreen : public QObject
Q_PROPERTY(qreal logicalDotsPerInchX READ logicalDotsPerInchX NOTIFY logicalDotsPerInchXChanged)
Q_PROPERTY(qreal logicalDotsPerInchY READ logicalDotsPerInchY NOTIFY logicalDotsPerInchYChanged)
Q_PROPERTY(qreal logicalDotsPerInch READ logicalDotsPerInch NOTIFY logicalDotsPerInchChanged)
- Q_PROPERTY(QSize availableSize READ availableSize NOTIFY availableSizeChanged)
- Q_PROPERTY(QRect availableGeometry READ availableGeometry NOTIFY availableGeometryChanged)
Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY primaryOrientationChanged)
Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged)
Q_PROPERTY(qreal refreshRate READ refreshRate NOTIFY refreshRateChanged)
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 11e1cc0c17..2d64a30a51 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -60,7 +60,6 @@
#include <stdio.h>
#include <errno.h>
#include <xcb/xfixes.h>
-#include <xcb/randr.h>
#ifdef XCB_USE_XLIB
#include <X11/Xlib.h>
@@ -101,9 +100,27 @@ static int nullErrorHandler(Display *, XErrorEvent *)
}
#endif
+QXcbScreen* QXcbConnection::createScreenWithFabricatedName(int screenNumber, xcb_screen_t* xcbScreen)
+{
+ QByteArray displayName = m_displayName;
+ int dotPos = displayName.lastIndexOf('.');
+ if (dotPos != -1)
+ displayName.truncate(dotPos);
+ QString name = displayName + QLatin1Char('.') + QString::number(screenNumber);
+ QXcbScreen *screen = new QXcbScreen(this, xcbScreen, NULL, name, screenNumber);
+ // make sure the primary screen appears first since it is used by QGuiApplication::primaryScreen()
+ if (m_primaryScreen == screenNumber) {
+ m_screens.prepend(screen);
+ } else {
+ m_screens.append(screen);
+ }
+ return screen;
+}
+
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName)
: m_connection(0)
, m_primaryScreen(0)
+ , m_primaryOutput(-1)
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
, m_nativeInterface(nativeInterface)
#ifdef XCB_USE_XINPUT2_MAEMO
@@ -171,14 +188,72 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char
int screenNumber = 0;
while (it.rem) {
- QXcbScreen *screen = new QXcbScreen(this, it.data, screenNumber);
- // make sure the primary screen appears first since it is used by QGuiApplication::primaryScreen()
- if (m_primaryScreen == screenNumber) {
- m_screens.prepend(screen);
+ // Each "screen" in xcb terminology is a virtual desktop,
+ // potentially a collection of separate juxtaposed monitors.
+ // Now iterate the individual outputs (e.g. DVI-I-1, VGA-1, etc.)
+ // and make a QScreen instance for each.
+ xcb_screen_t *xcbScreen = it.data;
+ QList<QPlatformScreen *> siblings;
+ if (has_randr_extension) {
+ xcb_randr_get_output_primary_cookie_t primaryCookie =
+ xcb_randr_get_output_primary_unchecked(xcb_connection(), xcbScreen->root);
+ xcb_randr_get_screen_resources_current_cookie_t resourcesCookie =
+ xcb_randr_get_screen_resources_current_unchecked(xcb_connection(), xcbScreen->root);
+ xcb_randr_get_output_primary_reply_t *primary =
+ xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, NULL);
+ xcb_randr_get_screen_resources_current_reply_t *resources =
+ xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, NULL);
+ xcb_timestamp_t timestamp = resources->config_timestamp;
+ int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources);
+ xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(resources);
+
+ if (outputCount == 0) {
+ // This happens on VNC for example. But there is actually a screen anyway.
+#ifdef Q_XCB_DEBUG
+ qDebug("Found a screen with zero outputs");
+#endif
+ QXcbScreen *screen = createScreenWithFabricatedName(screenNumber, it.data);
+ siblings << screen;
+ ++screenNumber;
+ }
+ for (int i = 0; i < outputCount; i++) {
+ xcb_randr_get_output_info_reply_t *output =
+ xcb_randr_get_output_info_reply(xcb_connection(),
+ xcb_randr_get_output_info_unchecked(xcb_connection(), outputs[i], timestamp), NULL);
+ if (output == NULL)
+ continue;
+ QString outputName = QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output),
+ xcb_randr_get_output_info_name_length(output));
+
+ if (output->crtc == XCB_NONE) {
+#ifdef Q_XCB_DEBUG
+ qDebug("Screen output %s is not connected", qPrintable(outputName));
+#endif
+ continue;
+ }
+
+ QXcbScreen *screen = new QXcbScreen(this, xcbScreen, output, outputName, screenNumber);
+ siblings << screen;
+ // make sure the primary screen appears first since it is used by QGuiApplication::primaryScreen()
+ if (outputs[i] == primary->output && m_primaryOutput < 0) {
+ m_primaryOutput = screenNumber;
+ m_screens.prepend(screen);
+ } else {
+ m_screens.append(screen);
+ }
+ ++screenNumber;
+ free(output);
+ }
+
+ free(primary);
+ free(resources);
} else {
- m_screens.append(screen);
+ QXcbScreen *screen = createScreenWithFabricatedName(screenNumber, it.data);
+ siblings << screen;
+ ++screenNumber;
}
- ++screenNumber;
+ foreach (QPlatformScreen* s, siblings)
+ ((QXcbScreen*)s)->setVirtualSiblings(siblings);
xcb_screen_next(&it);
}
@@ -637,8 +712,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
xcb_randr_screen_change_notify_event_t *change_event = (xcb_randr_screen_change_notify_event_t *)event;
foreach (QXcbScreen *s, m_screens) {
if (s->root() == change_event->root ) {
+ s->handleScreenChange(change_event);
s->updateRefreshRate();
- break;
}
}
handled = true;
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index d97db9a74d..8feca95ecc 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -398,6 +398,7 @@ private:
void handleGenericEventMaemo(xcb_ge_event_t *event);
#endif
void handleClientMessageEvent(const xcb_client_message_event_t *event);
+ QXcbScreen* createScreenWithFabricatedName(int screenNumber, xcb_screen_t* xcbScreen);
bool m_xi2Enabled;
int m_xi2Minor;
@@ -442,6 +443,7 @@ private:
QList<QXcbScreen *> m_screens;
int m_primaryScreen;
+ int m_primaryOutput;
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index d92004b1ac..315c94bb56 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -43,38 +43,59 @@
#include "qxcbwindow.h"
#include "qxcbcursor.h"
#include "qxcbimage.h"
+#include "qnamespace.h"
#include <stdio.h>
#include <QDebug>
-#include <xcb/randr.h>
-
#include <qpa/qwindowsysteminterface.h>
QT_BEGIN_NAMESPACE
-QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int number)
+QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
+ xcb_randr_get_output_info_reply_t *output, QString outputName, int number)
: QXcbObject(connection)
- , m_screen(screen)
+ , m_screen(scr)
+ , m_crtc(output ? output->crtc : 0)
+ , m_outputName(outputName)
+ , m_sizeMillimeters(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)
, m_number(number)
, m_refreshRate(60)
{
if (connection->hasXRandr())
- xcb_randr_select_input(xcb_connection(), screen->root, true);
+ xcb_randr_select_input(xcb_connection(), screen()->root, true);
+ updateGeometry(output ? output->timestamp : 0);
updateRefreshRate();
+ // On VNC, it can be that physical size is unknown while
+ // virtual size is known (probably back-calculated from DPI and resolution)
+ if (m_sizeMillimeters.isEmpty())
+ m_sizeMillimeters = m_virtualSizeMillimeters;
+ if (m_geometry.isEmpty())
+ m_geometry = QRect(QPoint(), m_virtualSize);
+ if (m_availableGeometry.isEmpty())
+ m_availableGeometry = QRect(QPoint(), m_virtualSize);
+
#ifdef Q_XCB_DEBUG
qDebug();
- qDebug("Information of screen %d:", screen->root);
- qDebug(" width.........: %d", screen->width_in_pixels);
- qDebug(" height........: %d", screen->height_in_pixels);
- qDebug(" depth.........: %d", screen->root_depth);
- qDebug(" white pixel...: %x", screen->white_pixel);
- qDebug(" black pixel...: %x", screen->black_pixel);
+ qDebug("Screen %s:", m_outputName.toUtf8().constData());
+ qDebug(" width..........: %lf", m_sizeMillimeters.width());
+ qDebug(" height.........: %lf", m_sizeMillimeters.height());
+ qDebug(" geometry.......: %d x %d +%d +%d", m_geometry.width(), m_geometry.height(), m_geometry.x(), m_geometry.y());
+ qDebug(" virtual width..: %lf", m_virtualSizeMillimeters.width());
+ 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(" depth..........: %d", screen()->root_depth);
+ qDebug(" white pixel....: %x", screen()->white_pixel);
+ qDebug(" black pixel....: %x", screen()->black_pixel);
qDebug(" refresh rate...: %d", m_refreshRate);
- qDebug();
+ qDebug(" root ID........: %x", screen()->root);
#endif
const quint32 mask = XCB_CW_EVENT_MASK;
@@ -85,11 +106,11 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
| XCB_EVENT_MASK_PROPERTY_CHANGE
};
- xcb_change_window_attributes(xcb_connection(), screen->root, mask, values);
+ xcb_change_window_attributes(xcb_connection(), screen()->root, mask, values);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xcb_connection(),
- xcb_get_property_unchecked(xcb_connection(), false, screen->root,
+ xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK),
XCB_ATOM_WINDOW, 0, 1024), NULL);
@@ -105,14 +126,14 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) {
m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply), xcb_get_property_value_length(windowManagerReply));
#ifdef Q_XCB_DEBUG
- qDebug("Running window manager: %s", qPrintable(m_windowManagerName));
+ qDebug(" window manager.: %s", qPrintable(m_windowManagerName));
+ qDebug();
#endif
}
free(windowManagerReply);
}
}
-
free(reply);
const xcb_query_extension_reply_t *sync_reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id);
@@ -125,11 +146,11 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
Q_XCB_CALL2(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT,
m_clientLeader,
- m_screen->root,
+ screen()->root,
0, 0, 1, 1,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
- m_screen->root_visual,
+ screen()->root_visual,
0, 0), connection);
Q_XCB_CALL2(xcb_change_property(xcb_connection(),
@@ -142,7 +163,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
&m_clientLeader), connection);
xcb_depth_iterator_t depth_iterator =
- xcb_screen_allowed_depths_iterator(screen);
+ xcb_screen_allowed_depths_iterator(screen());
while (depth_iterator.rem) {
xcb_depth_t *depth = depth_iterator.data;
@@ -214,34 +235,113 @@ const xcb_visualtype_t *QXcbScreen::visualForId(xcb_visualid_t visualid) const
return &*it;
}
-QRect QXcbScreen::geometry() const
-{
- return QRect(0, 0, m_screen->width_in_pixels, m_screen->height_in_pixels);
-}
-
-int QXcbScreen::depth() const
-{
- return m_screen->root_depth;
-}
-
QImage::Format QXcbScreen::format() const
{
return QImage::Format_RGB32;
}
-QSizeF QXcbScreen::physicalSize() const
+QPlatformCursor *QXcbScreen::cursor() const
{
- return QSizeF(m_screen->width_in_millimeters, m_screen->height_in_millimeters);
+ return m_cursor;
}
-QPlatformCursor *QXcbScreen::cursor() const
+/*!
+ \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)
{
- return m_cursor;
+ 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::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
+ QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);
}
-qreal QXcbScreen::refreshRate() const
+void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
{
- return m_refreshRate;
+ if (connection()->hasXRandr()) {
+ xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(xcb_connection(),
+ xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, timestamp), NULL);
+ if (crtc) {
+ m_geometry = QRect(crtc->x, crtc->y, crtc->width, crtc->height);
+ m_availableGeometry = m_geometry;
+ free(crtc);
+ }
+ }
+
+ xcb_get_property_reply_t * workArea =
+ xcb_get_property_reply(xcb_connection(),
+ xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
+ atom(QXcbAtom::_NET_WORKAREA),
+ XCB_ATOM_CARDINAL, 0, 1024), NULL);
+
+ if (workArea && workArea->type == XCB_ATOM_CARDINAL && workArea->format == 32 && workArea->value_len >= 4) {
+ // If workArea->value_len > 4, the remaining ones seem to be for virtual desktops.
+ // But QScreen doesn't know about that concept. In reality there could be a
+ // "docked" panel (with _NET_WM_STRUT_PARTIAL atom set) on just one desktop.
+ // But for now just assume the first 4 values give us the geometry of the
+ // "work area", AKA "available geometry"
+ uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea);
+ QRect virtualAvailableGeometry(geom[0], geom[1], geom[2], geom[3]);
+ // Take the intersection of the desktop's available geometry with this screen's geometry
+ // to get the part of the available geometry which belongs to this screen.
+ m_availableGeometry = m_geometry & virtualAvailableGeometry;
+ }
+ free(workArea);
}
void QXcbScreen::updateRefreshRate()
@@ -267,11 +367,6 @@ void QXcbScreen::updateRefreshRate()
QWindowSystemInterface::handleScreenRefreshRateChange(QPlatformScreen::screen(), rate);
}
-int QXcbScreen::screenNumber() const
-{
- return m_number;
-}
-
QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
if (width == 0 || height == 0)
@@ -369,13 +464,4 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height)
return result;
}
-QString QXcbScreen::name() const
-{
- QByteArray displayName = connection()->displayName();
- int dotPos = displayName.lastIndexOf('.');
- if (dotPos != -1)
- displayName.truncate(dotPos);
- return displayName + QLatin1Char('.') + QString::number(screenNumber());
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index 7a81d8b43a..dfec3609a5 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -46,6 +46,7 @@
#include <QtCore/QString>
#include <xcb/xcb.h>
+#include <xcb/randr.h>
#include "qxcbobject.h"
@@ -57,21 +58,26 @@ class QXcbCursor;
class QXcbScreen : public QXcbObject, public QPlatformScreen
{
public:
- QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int number);
+ QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen,
+ xcb_randr_get_output_info_reply_t *output, QString outputName, int number);
~QXcbScreen();
QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
QWindow *topLevelAt(const QPoint &point) const;
- QRect geometry() const;
- int depth() const;
+ QRect geometry() const { return m_geometry; }
+ QRect availableGeometry() const {return m_availableGeometry;}
+ int depth() const { return m_screen->root_depth; }
QImage::Format format() const;
- QSizeF physicalSize() const;
+ QSizeF physicalSize() const { return m_sizeMillimeters; }
QPlatformCursor *cursor() const;
- qreal refreshRate() const;
+ qreal refreshRate() const { return m_refreshRate; }
+ Qt::ScreenOrientation orientation() const { return m_orientation; }
+ QList<QPlatformScreen *> virtualSiblings() const { return m_siblings; }
+ void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; }
- int screenNumber() const;
+ int screenNumber() const { return m_number; }
xcb_screen_t *screen() const { return m_screen; }
xcb_window_t root() const { return m_screen->root; }
@@ -83,12 +89,23 @@ public:
const xcb_visualtype_t *visualForId(xcb_visualid_t) const;
- QString name() const;
+ QString name() const { return m_outputName; }
+ void handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event);
+ void updateGeometry(xcb_timestamp_t timestamp);
void updateRefreshRate();
private:
xcb_screen_t *m_screen;
+ xcb_randr_crtc_t m_crtc;
+ QString m_outputName;
+ QSizeF m_sizeMillimeters;
+ QRect m_geometry;
+ QRect m_availableGeometry;
+ QSize m_virtualSize;
+ QSizeF m_virtualSizeMillimeters;
+ QList<QPlatformScreen *> m_siblings;
+ Qt::ScreenOrientation m_orientation;
int m_number;
QString m_windowManagerName;
bool m_syncRequestSupported;