summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@digia.com>2012-09-21 13:47:16 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-09-26 04:03:41 +0200
commit9cec2def90c9644cc75b26d3c9bd38739b9307da (patch)
tree47f039d85d60ee288be447637b6f3f72822f0016 /src
parent1e39e8f53b2edd6c2f1e313e708d78ebb0088ea5 (diff)
xcb: better error handling if no randr or screen resources query fails
Marc Mutz already reported problems with ssh -X fowarding. Now all such errors are treated the same: if we can't get screen output attributes, just assume there is only one. Change-Id: I96802fc90072c623de3370ed2898893daf58198a Reviewed-by: Marc Mutz <marc.mutz@kdab.com> Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp100
1 files changed, 53 insertions, 47 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 9e394d674f..b82a17dc05 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -141,68 +141,74 @@ void QXcbConnection::updateScreens()
// which will become virtual siblings.
xcb_screen_t *xcbScreen = it.data;
QList<QPlatformScreen *> siblings;
+ int outputCount = 0;
if (has_randr_extension) {
+ xcb_generic_error_t *error = NULL;
xcb_randr_get_output_primary_cookie_t primaryCookie =
- xcb_randr_get_output_primary_unchecked(xcb_connection(), xcbScreen->root);
+ xcb_randr_get_output_primary(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_screen_resources_current(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 = findOrCreateScreen(newScreens, xcbScreenNumber, xcbScreen);
- siblings << screen;
- activeScreens << screen;
- if (!primaryScreen)
- primaryScreen = 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;
+ xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error);
+ if (!primary || error) {
+ qWarning("QXcbConnection: Failed to get the primary output of the screen");
+ free(error);
+ } else {
+ xcb_randr_get_screen_resources_current_reply_t *resources =
+ xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, &error);
+ if (!resources || error) {
+ qWarning("QXcbConnection: Failed to get the screen resources");
+ free(error);
+ } else {
+ xcb_timestamp_t timestamp = resources->config_timestamp;
+ outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources);
+ xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(resources);
+
+ 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;
#ifdef Q_XCB_DEBUG
- QString outputName = QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output),
- xcb_randr_get_output_info_name_length(output));
+ QString outputName = QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output),
+ xcb_randr_get_output_info_name_length(output));
#endif
- if (output->crtc == XCB_NONE) {
+ if (output->crtc == XCB_NONE) {
#ifdef Q_XCB_DEBUG
- qDebug("Screen output %s is not connected", qPrintable(outputName));
+ qDebug("Screen output %s is not connected", qPrintable(outputName));
#endif
- continue;
- }
-
- QXcbScreen *screen = findOrCreateScreen(newScreens, xcbScreenNumber, xcbScreen, output);
- siblings << screen;
- activeScreens << screen;
- ++screenNumber;
- if (!primaryScreen && primary) {
- if (primary->output == XCB_NONE || outputs[i] == primary->output) {
- primaryScreen = screen;
- siblings.prepend(siblings.takeLast());
+ continue;
+ }
+
+ QXcbScreen *screen = findOrCreateScreen(newScreens, xcbScreenNumber, xcbScreen, output);
+ siblings << screen;
+ activeScreens << screen;
+ ++screenNumber;
+ if (!primaryScreen && primary) {
+ if (primary->output == XCB_NONE || outputs[i] == primary->output) {
+ primaryScreen = screen;
+ siblings.prepend(siblings.takeLast());
#ifdef Q_XCB_DEBUG
- qDebug("Primary output is %d: %s", primary->output, qPrintable(outputName));
+ qDebug("Primary output is %d: %s", primary->output, qPrintable(outputName));
#endif
+ }
+ }
+ free(output);
}
}
- free(output);
+ free(resources);
}
free(primary);
- free(resources);
- } else {
+ }
+ // If there's no randr extension, or there was some error above, or the screen
+ // doesn't have outputs for some other reason (e.g. on VNC or ssh -X), just assume there is one screen.
+ if (outputCount == 0) {
+#ifdef Q_XCB_DEBUG
+ qDebug("Found a screen with zero outputs");
+#endif
QXcbScreen *screen = findOrCreateScreen(newScreens, xcbScreenNumber, xcbScreen);
siblings << screen;
activeScreens << screen;
@@ -214,7 +220,7 @@ void QXcbConnection::updateScreens()
((QXcbScreen*)s)->setVirtualSiblings(siblings);
xcb_screen_next(&it);
++xcbScreenNumber;
- }
+ } // for each xcb screen
// Now activeScreens is the complete set of screens which are active at this time.
// Delete any existing screens which are not in activeScreens