summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbconnection.cpp
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-04-22 09:04:29 +0200
committerLiang Qi <liang.qi@theqtcompany.com>2015-04-22 09:25:54 +0200
commitaed5a7168354c6ae47687d20b4bd3f0adcc14f8e (patch)
treed2060479a7c12fdba8c1955e5d363754feffabb8 /src/plugins/platforms/xcb/qxcbconnection.cpp
parentd3d10cf23d61f4a011f1a7e9abdee1a92717e80f (diff)
parent628fa13ea4d6ff0e2e2ee76c9adfc78676de3c59 (diff)
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts: src/corelib/statemachine/qstatemachine.cpp src/corelib/statemachine/qstatemachine_p.h src/gui/painting/qdrawhelper.cpp src/plugins/platforms/xcb/qxcbnativeinterface.cpp src/plugins/platforms/xcb/qxcbwindow.cpp src/plugins/platforms/xcb/qxcbwindow.h src/testlib/qtestblacklist.cpp src/tools/qdoc/node.cpp src/tools/qdoc/node.h tests/auto/gui/painting/qcolor/tst_qcolor.cpp Change-Id: I6c78b7b162001712d5774293f501b06b4ff32684
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp74
1 files changed, 50 insertions, 24 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 706b9c8e48..8500aa1ffa 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -66,6 +66,7 @@
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
#endif
#if defined(XCB_USE_XINPUT2)
@@ -83,6 +84,12 @@ Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input")
Q_LOGGING_CATEGORY(lcQpaXInputDevices, "qt.qpa.input.devices")
Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen")
+// this event type was added in libxcb 1.10,
+// but we support also older version
+#ifndef XCB_GE_GENERIC
+#define XCB_GE_GENERIC 35
+#endif
+
#ifdef XCB_USE_XLIB
static const char * const xcbConnectionErrors[] = {
"No error", /* Error 0 */
@@ -137,7 +144,7 @@ QXcbScreen* QXcbConnection::findScreenForOutput(xcb_window_t rootWindow, xcb_ran
return 0;
}
-QXcbScreen* QXcbConnection::createScreen(int screenNumber, xcb_screen_t* xcbScreen,
+QXcbScreen* QXcbConnection::createScreen(QXcbVirtualDesktop* virtualDesktop,
xcb_randr_output_t outputId,
xcb_randr_get_output_info_reply_t *output)
{
@@ -150,10 +157,10 @@ QXcbScreen* QXcbConnection::createScreen(int screenNumber, xcb_screen_t* xcbScre
int dotPos = displayName.lastIndexOf('.');
if (dotPos != -1)
displayName.truncate(dotPos);
- name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') + QString::number(screenNumber);
+ name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') + QString::number(virtualDesktop->number());
}
- return new QXcbScreen(this, xcbScreen, outputId, output, name, screenNumber);
+ return new QXcbScreen(this, virtualDesktop, outputId, output, name);
}
bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output)
@@ -173,15 +180,11 @@ bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_out
return isPrimary;
}
-xcb_screen_t* QXcbConnection::xcbScreenForRootWindow(xcb_window_t rootWindow, int *xcbScreenNumber)
+QXcbVirtualDesktop* QXcbConnection::virtualDesktopForRootWindow(xcb_window_t rootWindow)
{
- xcb_screen_iterator_t xcbScreenIter = xcb_setup_roots_iterator(m_setup);
- for (; xcbScreenIter.rem; xcb_screen_next(&xcbScreenIter)) {
- if (xcbScreenIter.data->root == rootWindow) {
- if (xcbScreenNumber)
- *xcbScreenNumber = xcb_setup_roots_length(m_setup) - xcbScreenIter.rem;
- return xcbScreenIter.data;
- }
+ foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops) {
+ if (virtualDesktop->screen()->root == rootWindow)
+ return virtualDesktop;
}
return 0;
@@ -194,8 +197,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
{
if (event->subCode == XCB_RANDR_NOTIFY_CRTC_CHANGE) {
xcb_randr_crtc_change_t crtc = event->u.cc;
- xcb_screen_t *xcbScreen = xcbScreenForRootWindow(crtc.window);
- if (!xcbScreen)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(crtc.window);
+ if (!virtualDesktop)
// Not for us
return;
@@ -212,9 +215,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
} else if (event->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) {
xcb_randr_output_change_t output = event->u.oc;
- int xcbScreenNumber = 0;
- xcb_screen_t *xcbScreen = xcbScreenForRootWindow(output.window, &xcbScreenNumber);
- if (!xcbScreen)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(output.window);
+ if (!virtualDesktop)
// Not for us
return;
@@ -242,7 +244,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo(
xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL));
- screen = createScreen(xcbScreenNumber, xcbScreen, output.output, outputInfo.data());
+ screen = createScreen(virtualDesktop, output.output, outputInfo.data());
qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled";
screen->setPrimary(checkOutputIsPrimary(output.window, output.output));
@@ -293,14 +295,15 @@ void QXcbConnection::initializeScreens()
xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
int xcbScreenNumber = 0; // screen number in the xcb sense
QXcbScreen* primaryScreen = Q_NULLPTR;
- xcb_screen_t *xcbScreen = Q_NULLPTR;
bool hasOutputs = false;
while (it.rem) {
// Each "screen" in xcb terminology is a virtual desktop,
// potentially a collection of separate juxtaposed monitors.
// But we want a separate QScreen for each output (e.g. DVI-I-1, VGA-1, etc.)
// which will become virtual siblings.
- xcbScreen = it.data;
+ xcb_screen_t *xcbScreen = it.data;
+ QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber);
+ m_virtualDesktops.append(virtualDesktop);
QList<QPlatformScreen *> siblings;
int outputCount = 0;
int connectedOutputCount = 0;
@@ -370,7 +373,7 @@ void QXcbConnection::initializeScreens()
continue;
}
- QXcbScreen *screen = createScreen(xcbScreenNumber, xcbScreen, outputs[i], output.data());
+ QXcbScreen *screen = createScreen(virtualDesktop, outputs[i], output.data());
siblings << screen;
++connectedOutputCount;
hasOutputs = true;
@@ -405,8 +408,9 @@ void QXcbConnection::initializeScreens()
// but the dimensions are known anyway, and we don't already have any lingering
// (possibly disconnected) screens, then showing windows should be possible,
// so create one screen. (QTBUG-31389)
- if (xcbScreen && !hasOutputs && xcbScreen->width_in_pixels > 0 && xcbScreen->height_in_pixels > 0 && m_screens.isEmpty()) {
- QXcbScreen *screen = createScreen(0, xcbScreen, 0, Q_NULLPTR);
+ QXcbVirtualDesktop *virtualDesktop = m_virtualDesktops.value(0);
+ if (virtualDesktop && !hasOutputs && !virtualDesktop->size().isEmpty() && m_screens.isEmpty()) {
+ QXcbScreen *screen = createScreen(virtualDesktop, 0, Q_NULLPTR);
screen->setVirtualSiblings(QList<QPlatformScreen *>() << screen);
m_screens << screen;
primaryScreen = screen;
@@ -434,9 +438,10 @@ void QXcbConnection::initializeScreens()
qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name();
}
-QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName)
+QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
: m_connection(0)
, m_canGrabServer(canGrabServer)
+ , m_defaultVisualId(defaultVisualId)
, m_primaryScreenNumber(0)
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
, m_nativeInterface(nativeInterface)
@@ -577,6 +582,9 @@ QXcbConnection::~QXcbConnection()
while (!m_screens.isEmpty())
integration->destroyScreen(m_screens.takeLast());
+ while (!m_virtualDesktops.isEmpty())
+ delete m_virtualDesktops.takeLast();
+
delete m_glIntegration;
#ifdef XCB_USE_XLIB
@@ -666,6 +674,7 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event)
PRINT_XCB_EVENT(XCB_KEYMAP_NOTIFY);
PRINT_XCB_EVENT(XCB_EXPOSE);
PRINT_XCB_EVENT(XCB_GRAPHICS_EXPOSURE);
+ PRINT_XCB_EVENT(XCB_NO_EXPOSURE);
PRINT_XCB_EVENT(XCB_VISIBILITY_NOTIFY);
PRINT_XCB_EVENT(XCB_CREATE_NOTIFY);
PRINT_XCB_EVENT(XCB_DESTROY_NOTIFY);
@@ -685,6 +694,8 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event)
PRINT_XCB_EVENT(XCB_SELECTION_NOTIFY);
PRINT_XCB_EVENT(XCB_COLORMAP_NOTIFY);
PRINT_XCB_EVENT(XCB_CLIENT_MESSAGE);
+ PRINT_XCB_EVENT(XCB_MAPPING_NOTIFY);
+ PRINT_XCB_EVENT(XCB_GE_GENERIC);
default:
qDebug("QXcbConnection: %s: unknown event - response_type: %d - sequence: %d", message, int(event->response_type & ~0x80), int(event->sequence));
}
@@ -1080,7 +1091,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
break;
#if defined(XCB_USE_XINPUT2)
- case GenericEvent:
+ case XCB_GE_GENERIC:
if (m_xi2Enabled)
xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
break;
@@ -1342,6 +1353,21 @@ void *QXcbConnection::xlib_display() const
{
return m_xlib_display;
}
+
+void *QXcbConnection::createVisualInfoForDefaultVisualId() const
+{
+ if (m_defaultVisualId == UINT_MAX)
+ return 0;
+ XVisualInfo info;
+ memset(&info, 0, sizeof info);
+ info.visualid = m_defaultVisualId;
+
+ int count = 0;
+ XVisualInfo *retVisual = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &info, &count);
+ Q_ASSERT(count < 2);
+ return retVisual;
+}
+
#endif
void QXcbConnection::processXcbEvents()