summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-03-30 12:29:27 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-03-30 12:31:32 +0200
commitb35988fe3299b2f76fb29507ca46298c2bef47df (patch)
treeac67a338bef6a08a7fa46040f21472d791b57e39 /src/plugins/platforms/xcb
parentc25609217e99f890431c0170fea585b3e86822ad (diff)
Added X error tracking to XCB platform.
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp37
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h32
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp106
-rw-r--r--src/plugins/platforms/xcb/qxcbwindowsurface.cpp14
4 files changed, 122 insertions, 67 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 1ac73c9227..9924b1e205 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -207,9 +207,9 @@ break;
void printXcbEvent(const char *message, xcb_generic_event_t *event)
{
#ifdef XCB_EVENT_DEBUG
-#define PRINT_XCB_EVENT(event) \
- case event: \
- printf("%s: %d - %s\n", message, int(event), #event); \
+#define PRINT_XCB_EVENT(ev) \
+ case ev: \
+ printf("%s: %d - %s - sequence: %d\n", message, int(ev), #ev, event->sequence); \
break;
switch (event->response_type & ~0x80) {
@@ -402,6 +402,16 @@ const char *xcb_protocol_request_codes[] =
"Unknown"
};
+void QXcbConnection::log(const char *file, int line, int sequence)
+{
+ CallInfo info;
+ info.sequence = sequence;
+ info.file = file;
+ info.line = line;
+
+ m_callLog << info;
+}
+
void QXcbConnection::run()
{
while (xcb_generic_event_t *event = xcb_wait_for_event(xcb_connection())) {
@@ -415,13 +425,30 @@ void QXcbConnection::run()
uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
- printf("XCB error: %d (%s), resource id: %d, major code: %d (%s), minor code: %d\n",
- int(error->error_code), xcb_errors[clamped_error_code], int(error->resource_id),
+ printf("XCB error: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d\n",
+ int(error->error_code), xcb_errors[clamped_error_code],
+ int(error->sequence), int(error->resource_id),
int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
int(error->minor_code));
+#ifdef Q_XCB_DEBUG
+ for (int i = 0; i < m_callLog.size(); ++i) {
+ if (m_callLog.at(i).sequence == error->sequence) {
+ printf("Caused by: %s:%d\n", qPrintable(m_callLog.at(i).file), m_callLog.at(i).line);
+ break;
+ }
+ }
+#endif
continue;
}
+#ifdef Q_XCB_DEBUG
+ int i = 0;
+ for (; i < m_callLog.size(); ++i)
+ if (m_callLog.at(i).sequence >= event->sequence)
+ break;
+ m_callLog.remove(0, i);
+#endif
+
if (response_type == XCB_CLIENT_MESSAGE
&& ((xcb_client_message_event_t *)event)->type == QXcbAtom::_QT_CLOSE_CONNECTION)
return;
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index a36694daff..0a7efd54f3 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -1,5 +1,4 @@
-/****************************************************************************
-**
+/**************************************************************************** **
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -46,8 +45,11 @@
#include <QList>
#include <QMutex>
+#include <QVector>
#include <QThread>
+#define Q_XCB_DEBUG
+
class QXcbScreen;
namespace QXcbAtom {
@@ -295,10 +297,36 @@ private:
void *m_egl_display;
bool m_has_egl;
#endif
+#ifdef Q_XCB_DEBUG
+ struct CallInfo {
+ int sequence;
+ QByteArray file;
+ int line;
+ };
+ QVector<CallInfo> m_callLog;
+ void log(const char *file, int line, int sequence);
+ template <typename cookie_t>
+ friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line);
+#endif
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
+#ifdef Q_XCB_DEBUG
+template <typename cookie_t>
+cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line)
+{
+ connection->log(file, line, cookie.sequence);
+ return cookie;
+}
+#define Q_XCB_CALL(x) q_xcb_call_template(x, connection(), __FILE__, __LINE__)
+#define Q_XCB_CALL2(x, connection) q_xcb_call_template(x, connection, __FILE__, __LINE__)
+#else
+#define Q_XCB_CALL(x) x
+#define Q_XCB_CALL2(x, connection) x
+#endif
+
+
#if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
#define EGL_DISPLAY_FROM_XCB(object) ((EGLDisplay)(object->connection()->egl_display()))
#endif //endifXCB_USE_DRI2
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 54a4d7ff1b..710d5317e3 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -148,24 +148,24 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
{
m_window = xcb_generate_id(xcb_connection());
- xcb_create_window(xcb_connection(),
- XCB_COPY_FROM_PARENT, // depth -- same as root
- m_window, // window id
- m_screen->root(), // parent window id
- tlw->x(),
- tlw->y(),
- tlw->width(),
- tlw->height(),
- 0, // border width
- XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
- m_screen->screen()->root_visual, // visual
- 0, // value mask
- 0); // value list
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT, // depth -- same as root
+ m_window, // window id
+ m_screen->root(), // parent window id
+ tlw->x(),
+ tlw->y(),
+ tlw->width(),
+ tlw->height(),
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ m_screen->screen()->root_visual, // visual
+ 0, // value mask
+ 0)); // value list
printf("created regular window: %d\n", m_window);
}
- xcb_change_window_attributes(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
xcb_atom_t properties[4];
int propertyCount = 0;
@@ -176,22 +176,22 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
if (tlw->windowFlags() & Qt::WindowContextHelpButtonHint)
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP);
- xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_window,
- atom(QXcbAtom::WM_PROTOCOLS),
- 4,
- 32,
- propertyCount,
- properties);
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::WM_PROTOCOLS),
+ 4,
+ 32,
+ propertyCount,
+ properties));
if (isTransient(tlw) && tlw->parentWidget()) {
// ICCCM 4.1.2.6
QWidget *p = tlw->parentWidget()->window();
xcb_window_t parentWindow = p->winId();
- xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
- XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
- 1, &parentWindow);
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
+ 1, &parentWindow));
}
}
@@ -199,7 +199,7 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
QXcbWindow::~QXcbWindow()
{
delete m_context;
- xcb_destroy_window(xcb_connection(), m_window);
+ Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
}
void QXcbWindow::setGeometry(const QRect &rect)
@@ -209,7 +209,7 @@ void QXcbWindow::setGeometry(const QRect &rect)
const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
const quint32 values[] = { rect.x(), rect.y(), rect.width(), rect.height() };
- xcb_configure_window(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
void QXcbWindow::setVisible(bool visible)
@@ -221,12 +221,12 @@ void QXcbWindow::setVisible(bool visible)
else
xcb_wm_hints_set_normal(&hints);
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
- xcb_map_window(xcb_connection(), m_window);
+ Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
#if defined(XCB_USE_GLX)
glXWaitX();
#endif
} else {
- xcb_unmap_window(xcb_connection(), m_window);
+ Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
// send synthetic UnmapNotify event according to icccm 4.1.4
xcb_unmap_notify_event_t event;
@@ -235,8 +235,8 @@ void QXcbWindow::setVisible(bool visible)
event.event = m_screen->root();
event.window = m_window;
event.from_configure = false;
- xcb_send_event(xcb_connection(), false, m_screen->root(),
- XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event);
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
xcb_flush(xcb_connection());
}
@@ -360,23 +360,23 @@ Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
}
if (mwmhints.flags != 0l) {
- xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_window,
- atom(QXcbAtom::_MOTIF_WM_HINTS),
- atom(QXcbAtom::_MOTIF_WM_HINTS),
- 32,
- 5,
- &mwmhints);
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::_MOTIF_WM_HINTS),
+ atom(QXcbAtom::_MOTIF_WM_HINTS),
+ 32,
+ 5,
+ &mwmhints));
} else {
- xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_MOTIF_WM_HINTS));
+ Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_MOTIF_WM_HINTS)));
}
if (popup || tooltip) {
const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER;
const quint32 values[] = { true, true };
- xcb_change_window_attributes(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
}
return QPlatformWindow::setWindowFlags(flags);
@@ -390,39 +390,39 @@ WId QXcbWindow::winId() const
void QXcbWindow::setParent(const QPlatformWindow *parent)
{
QPoint topLeft = geometry().topLeft();
- xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y());
+ Q_XCB_CALL(xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y()));
}
void QXcbWindow::setWindowTitle(const QString &title)
{
QByteArray ba = title.toUtf8();
- xcb_change_property (xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_window,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData());
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::_NET_WM_NAME),
+ atom(QXcbAtom::UTF8_STRING),
+ 8,
+ ba.length(),
+ ba.constData()));
}
void QXcbWindow::raise()
{
const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
const quint32 values[] = { XCB_STACK_MODE_ABOVE };
- xcb_configure_window(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
void QXcbWindow::lower()
{
const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
const quint32 values[] = { XCB_STACK_MODE_BELOW };
- xcb_configure_window(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
void QXcbWindow::requestActivateWindow()
{
- xcb_set_input_focus(xcb_connection(), m_window, XCB_INPUT_FOCUS_PARENT, XCB_TIME_CURRENT_TIME);
+ Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), m_window, XCB_INPUT_FOCUS_PARENT, XCB_TIME_CURRENT_TIME));
}
QPlatformGLContext *QXcbWindow::glContext() const
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
index e1ebce2fe3..61239af3e7 100644
--- a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
@@ -103,28 +103,27 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
m_shm_info.shmseg = xcb_generate_id(xcb_connection());
- xcb_shm_attach(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false);
+ Q_XCB_CALL(xcb_shm_attach(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, screen->format());
}
void QXcbShmImage::destroy()
{
- xcb_shm_detach(xcb_connection(), m_shm_info.shmseg);
+ Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg));
xcb_image_destroy(m_xcb_image);
shmdt(m_shm_info.shmaddr);
shmctl(m_shm_info.shmid, IPC_RMID, 0);
-
- xcb_free_gc(xcb_connection(), m_gc);
+ Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
}
void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source)
{
if (m_gc_window != window) {
- xcb_free_gc(xcb_connection(), m_gc);
+ Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
m_gc = xcb_generate_id(xcb_connection());
- xcb_create_gc(xcb_connection(), m_gc, window, 0, 0);
+ Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0));
m_gc_window = window;
}
@@ -152,7 +151,8 @@ void QXcbShmImage::preparePaint(const QRegion &region)
// to prevent X from reading from the image region while we're writing to it
if (m_dirty.intersects(region)) {
// from xcb_aux_sync
- free(xcb_get_input_focus_reply(xcb_connection(), xcb_get_input_focus(xcb_connection()), 0));
+ xcb_get_input_focus_cookie_t cookie = Q_XCB_CALL(xcb_get_input_focus(xcb_connection()));
+ free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
m_dirty = QRegion();
}
}