diff options
Diffstat (limited to 'src/plugins/platforms/xcb')
34 files changed, 218 insertions, 82 deletions
diff --git a/src/plugins/platforms/xcb/main.cpp b/src/plugins/platforms/xcb/main.cpp index c544f7073d..16ef7628a7 100644 --- a/src/plugins/platforms/xcb/main.cpp +++ b/src/plugins/platforms/xcb/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qdri2context.cpp b/src/plugins/platforms/xcb/qdri2context.cpp index 31e613d4ba..c16052f021 100644 --- a/src/plugins/platforms/xcb/qdri2context.cpp +++ b/src/plugins/platforms/xcb/qdri2context.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qdri2context.h b/src/plugins/platforms/xcb/qdri2context.h index 6b93a0a93f..7c4dbb35c2 100644 --- a/src/plugins/platforms/xcb/qdri2context.h +++ b/src/plugins/platforms/xcb/qdri2context.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index de41f862bd..86b7f09166 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h index 211a654c03..93c4805ec8 100644 --- a/src/plugins/platforms/xcb/qglxintegration.h +++ b/src/plugins/platforms/xcb/qglxintegration.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index fb8384212d..ad8b47c25a 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -124,7 +124,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI m_shm_info.shmaddr = 0; - m_xcb_image->data = (uint8_t *)qMalloc(segmentSize); + m_xcb_image->data = (uint8_t *)malloc(segmentSize); } else { if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1) qWarning() << "QXcbBackingStore: Error while marking the shared memory segment to be destroyed"; @@ -146,7 +146,7 @@ void QXcbShmImage::destroy() shmdt(m_shm_info.shmaddr); shmctl(m_shm_info.shmid, IPC_RMID, 0); } else { - qFree(m_xcb_image->data); + free(m_xcb_image->data); } } @@ -182,17 +182,47 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s source.height(), false); } else { - xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, source.x(), source.y(), source.width(), source.height(), - 0, 0, 0); - xcb_image_put(xcb_connection(), - window, - m_gc, - subimage, - target.x(), - target.y(), - 0); - - xcb_image_destroy(subimage); + // If we upload the whole image in a single chunk, the result might be + // larger than the server's maximum request size and stuff breaks. + // To work around that, we upload the image in chunks where each chunk + // is small enough for a single request. + int src_x = source.x(); + int src_y = source.y(); + int target_x = target.x(); + int target_y = target.y(); + int width = source.width(); + int height = source.height(); + + // We must make sure that each request is not larger than max_req_size. + // Each request takes req_size + m_xcb_image->stride * height bytes. + uint32_t max_req_size = xcb_get_maximum_request_length(xcb_connection()); + uint32_t req_size = sizeof(xcb_put_image_request_t); + int rows_per_put = (max_req_size - req_size) / m_xcb_image->stride; + + // This assert could trigger if a single row has more pixels than fit in + // a single PutImage request. However, max_req_size is guaranteed to be + // at least 16384 bytes. That should be enough for quite large images. + Q_ASSERT(rows_per_put > 0); + + while (height > 0) { + int rows = std::min(height, rows_per_put); + + xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, src_x, src_y, width, rows, + 0, 0, 0); + xcb_image_put(xcb_connection(), + window, + m_gc, + subimage, + target_x, + target_y, + 0); + + xcb_image_destroy(subimage); + + src_y += rows; + target_y += rows; + height -= rows; + } } Q_XCB_NOOP(connection()); diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h index a389f97ac3..70fed46563 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.h +++ b/src/plugins/platforms/xcb/qxcbbackingstore.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 03ee054f59..14d802a8bd 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -208,11 +208,12 @@ QXcbClipboard::~QXcbClipboard() connection()->sync(); // waiting until the clipboard manager fetches the content. - if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, 5000)) { + if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, clipboard_timeout, true)) { qWarning("QClipboard: Unable to receive an event from the " "clipboard manager in a reasonable time"); } } + free(reply); } } @@ -595,6 +596,7 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0); if (!reply || reply->type == XCB_NONE) { + free(reply); buffer->resize(0); return false; } @@ -687,7 +689,7 @@ namespace : window(win), type(t) {} xcb_window_t window; int type; - bool check(xcb_generic_event_t *event) const { + bool checkEvent(xcb_generic_event_t *event) const { if (!event) return false; int t = event->response_type & 0x7f; @@ -710,7 +712,7 @@ namespace ClipboardEvent(QXcbConnection *c) { clipboard = c->internAtom("CLIPBOARD"); } xcb_atom_t clipboard; - bool check(xcb_generic_event_t *e) const { + bool checkEvent(xcb_generic_event_t *e) const { if (!e) return false; int type = e->response_type & 0x7f; @@ -726,7 +728,7 @@ namespace }; } -xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int type, int timeout) +xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int type, int timeout, bool checkManager) { QElapsedTimer timer; timer.start(); @@ -736,6 +738,16 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int if (e) return e; + if (checkManager) { + xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER)); + xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0); + if (!reply || reply->owner == XCB_NONE) { + free(reply); + return 0; + } + free(reply); + } + // process other clipboard events, since someone is probably requesting data from us ClipboardEvent clipboard(connection()); e = connection()->checkEvent(clipboard); diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h index 3fd59964c1..c3b072984e 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.h +++ b/src/plugins/platforms/xcb/qxcbclipboard.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -85,7 +85,7 @@ public: QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property); private: - xcb_generic_event_t *waitForClipboardEvent(xcb_window_t win, int type, int timeout); + xcb_generic_event_t *waitForClipboardEvent(xcb_window_t win, int type, int timeout, bool checkManager = false); xcb_atom_t sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property); xcb_atom_t sendSelection(QMimeData *d, xcb_atom_t target, xcb_window_t window, xcb_atom_t property); diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 6969124b2a..ca21b1eb9d 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -86,13 +86,16 @@ extern "C" { QT_BEGIN_NAMESPACE +#ifdef XCB_USE_XLIB static int nullErrorHandler(Display *, XErrorEvent *) { return 0; } +#endif QXcbConnection::QXcbConnection(const char *displayName) - : m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) + : m_connection(0) + , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) #ifdef XCB_USE_XINPUT2_MAEMO , m_xinputData(0) #endif @@ -108,24 +111,26 @@ QXcbConnection::QXcbConnection(const char *displayName) #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); - m_primaryScreen = DefaultScreen(dpy); - m_connection = XGetXCBConnection(dpy); - XSetEventQueueOwner(dpy, XCBOwnsEventQueue); - XSetErrorHandler(nullErrorHandler); - m_xlib_display = dpy; + if (dpy) { + m_primaryScreen = DefaultScreen(dpy); + m_connection = XGetXCBConnection(dpy); + XSetEventQueueOwner(dpy, XCBOwnsEventQueue); + XSetErrorHandler(nullErrorHandler); + m_xlib_display = dpy; #ifdef XCB_USE_EGL - EGLDisplay eglDisplay = eglGetDisplay(dpy); - m_egl_display = eglDisplay; - EGLint major, minor; - eglBindAPI(EGL_OPENGL_ES_API); - m_has_egl = eglInitialize(eglDisplay,&major,&minor); + EGLDisplay eglDisplay = eglGetDisplay(dpy); + m_egl_display = eglDisplay; + EGLint major, minor; + eglBindAPI(EGL_OPENGL_ES_API); + m_has_egl = eglInitialize(eglDisplay,&major,&minor); #endif //XCB_USE_EGL + } #else m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreen); #endif //XCB_USE_XLIB - if (m_connection) - qDebug("Successfully connected to display %s", m_displayName.constData()); + if (!m_connection) + qFatal("Could not connect to display %s", m_displayName.constData()); m_reader = new QXcbEventReader(this); #ifdef XCB_POLL_FOR_QUEUED_EVENT @@ -568,13 +573,17 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) if (!handled) { // Check if a custom XEvent constructor was registered in xlib for this event type, and call it discarding the constructed XEvent if any. // XESetWireToEvent might be used by libraries to intercept messages from the X server e.g. the OpenGL lib waiting for DRI2 events. - Bool (*proc)(Display*, XEvent*, xEvent*) = XESetWireToEvent((Display*)m_xlib_display, response_type, 0); + + Display *xdisplay = (Display *)m_xlib_display; + XLockDisplay(xdisplay); + Bool (*proc)(Display*, XEvent*, xEvent*) = XESetWireToEvent(xdisplay, response_type, 0); if (proc) { - XESetWireToEvent((Display*)m_xlib_display, response_type, proc); + XESetWireToEvent(xdisplay, response_type, proc); XEvent dummy; event->sequence = LastKnownRequestProcessed(m_xlib_display); - proc((Display*)m_xlib_display, &dummy, (xEvent*)event); + proc(xdisplay, &dummy, (xEvent*)event); } + XUnlockDisplay(xdisplay); } #endif @@ -615,7 +624,7 @@ void QXcbEventReader::addEvent(xcb_generic_event_t *event) m_events << event; } -QList<xcb_generic_event_t *> *QXcbEventReader::lock() +QXcbEventArray *QXcbEventReader::lock() { m_mutex.lock(); #ifndef XCB_POLL_FOR_QUEUED_EVENT @@ -648,7 +657,7 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id) void QXcbConnection::processXcbEvents() { - QList<xcb_generic_event_t *> *eventqueue = m_reader->lock(); + QXcbEventArray *eventqueue = m_reader->lock(); for(int i = 0; i < eventqueue->size(); ++i) { xcb_generic_event_t *event = eventqueue->at(i); @@ -711,7 +720,7 @@ void QXcbConnection::handleClientMessageEvent(const xcb_client_message_event_t * xcb_generic_event_t *QXcbConnection::checkEvent(int type) { - QList<xcb_generic_event_t *> *eventqueue = m_reader->lock(); + QXcbEventArray *eventqueue = m_reader->lock(); for (int i = 0; i < eventqueue->size(); ++i) { xcb_generic_event_t *event = eventqueue->at(i); @@ -960,6 +969,7 @@ QByteArray QXcbConnection::atomName(xcb_atom_t atom) xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(xcb_connection(), cookie, &error); if (error) { qWarning() << "QXcbConnection::atomName: bad Atom" << atom; + free(error); } if (reply) { QByteArray result(xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply)); diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index ebe95c0013..c227b4c863 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -50,12 +50,13 @@ #include <QObject> #include <QThread> #include <QVector> +#include <QVarLengthArray> #ifdef XCB_USE_XINPUT2_MAEMO struct XInput2Data; #endif -#define Q_XCB_DEBUG +//#define Q_XCB_DEBUG QT_BEGIN_NAMESPACE @@ -249,6 +250,8 @@ namespace QXcbAtom { }; } +typedef QVarLengthArray<xcb_generic_event_t *, 64> QXcbEventArray; + class QXcbConnection; class QXcbEventReader : public QThread { @@ -263,7 +266,7 @@ public: void run(); #endif - QList<xcb_generic_event_t *> *lock(); + QXcbEventArray *lock(); void unlock(); signals: @@ -273,7 +276,7 @@ private: void addEvent(xcb_generic_event_t *event); QMutex m_mutex; - QList<xcb_generic_event_t *> m_events; + QXcbEventArray m_events; QXcbConnection *m_connection; }; @@ -337,7 +340,7 @@ public: xcb_generic_event_t *checkEvent(int type); template<typename T> - inline xcb_generic_event_t *checkEvent(const T &checker); + inline xcb_generic_event_t *checkEvent(T &checker); typedef bool (*PeekFunc)(xcb_generic_event_t *); void addPeekFunc(PeekFunc f); @@ -425,13 +428,13 @@ private: #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display())) template<typename T> -xcb_generic_event_t *QXcbConnection::checkEvent(const T &checker) +xcb_generic_event_t *QXcbConnection::checkEvent(T &checker) { - QList<xcb_generic_event_t *> *eventqueue = m_reader->lock(); + QXcbEventArray *eventqueue = m_reader->lock(); for (int i = 0; i < eventqueue->size(); ++i) { xcb_generic_event_t *event = eventqueue->at(i); - if (checker.check(event)) { + if (checker.checkEvent(event)) { (*eventqueue)[i] = 0; m_reader->unlock(); return event; diff --git a/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp b/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp index 719fc85ae2..12b3d67b9f 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -222,7 +222,6 @@ void QXcbConnection::handleGenericEvent(xcb_ge_event_t *event) for (int i = 0; i < m_xinputData->xiMaxContacts; ++i) { QWindowSystemInterface::TouchPoint tp; tp.id = i; - tp.isPrimary = (i == 0); tp.state = Qt::TouchPointReleased; touchPoints << tp; } @@ -288,7 +287,7 @@ void QXcbConnection::handleGenericEvent(xcb_ge_event_t *event) QWindowSystemInterface::registerTouchDevice(dev); m_xinputData->qtTouchDevice = dev; } - QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xideviceevent->time, (QEvent::Type)0 /*None*/, dev, touchPoints); + QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xideviceevent->time, dev, touchPoints); } if (xideviceevent->evtype == XI_ButtonRelease) { diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index f6856d5694..a00fdd4824 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index 4bbb9a928b..f766d7c74e 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index c15bbeed83..89b1fa7445 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -818,7 +818,7 @@ namespace public: ClientMessageScanner(xcb_atom_t a) : atom(a) {} xcb_atom_t atom; - bool check(xcb_generic_event_t *event) const { + bool checkEvent(xcb_generic_event_t *event) const { if (!event) return false; if ((event->response_type & 0x7f) != XCB_CLIENT_MESSAGE) diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h index 8142a77875..0233cc32b2 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.h +++ b/src/plugins/platforms/xcb/qxcbdrag.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbeglsurface.h b/src/plugins/platforms/xcb/qxcbeglsurface.h index a372cd9830..c4367cf572 100644 --- a/src/plugins/platforms/xcb/qxcbeglsurface.h +++ b/src/plugins/platforms/xcb/qxcbeglsurface.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp index 569e4fc4e4..824805a983 100644 --- a/src/plugins/platforms/xcb/qxcbimage.cpp +++ b/src/plugins/platforms/xcb/qxcbimage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbimage.h b/src/plugins/platforms/xcb/qxcbimage.h index 1e7f104084..6a06610937 100644 --- a/src/plugins/platforms/xcb/qxcbimage.h +++ b/src/plugins/platforms/xcb/qxcbimage.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 2190722f98..3cf50cbbd9 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 91fcc0b6cb..8a3926dbfb 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 581693ccb7..ef71b78339 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -907,6 +907,7 @@ QString QXcbKeyboard::translateKeySym(xcb_keysym_t keysym, uint xmodifiers, QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection) : QXcbObject(connection) + , m_autorepeat_code(0) { m_key_symbols = xcb_key_symbols_alloc(xcb_connection()); setupModifiers(); @@ -1020,6 +1021,62 @@ void QXcbKeyboard::setMask(uint sym, uint mask) // #define XCB_KEYBOARD_DEBUG +class KeyChecker +{ +public: + KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time) + : m_window(window) + , m_code(code) + , m_time(time) + , m_error(false) + , m_release(true) + { + } + + bool checkEvent(xcb_generic_event_t *ev) + { + if (m_error || !ev) + return false; + + int type = ev->response_type & ~0x80; + if (type != XCB_KEY_PRESS && type != XCB_KEY_RELEASE) + return false; + + xcb_key_press_event_t *event = (xcb_key_press_event_t *)ev; + + if (event->event != m_window || event->detail != m_code) { + m_error = true; + return false; + } + + if (type == XCB_KEY_PRESS) { + m_error = !m_release || event->time - m_time > 10; + return !m_error; + } + + if (m_release) { + m_error = true; + return false; + } + + m_release = true; + m_time = event->time; + + return false; + } + + bool release() const { return m_release; } + xcb_timestamp_t time() const { return m_time; } + +private: + xcb_window_t m_window; + xcb_keycode_t m_code; + xcb_timestamp_t m_time; + + bool m_error; + bool m_release; +}; + void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time) { @@ -1062,8 +1119,32 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod return; } + bool isAutoRepeat = false; + + if (type == QEvent::KeyPress) { + if (m_autorepeat_code == code) { + isAutoRepeat = true; + m_autorepeat_code = 0; + } + } else { + // look ahead for auto-repeat + KeyChecker checker(((QXcbWindow *)window->handle())->xcb_window(), code, time); + xcb_generic_event_t *event = connection()->checkEvent(checker); + if (event) { + isAutoRepeat = true; + free(event); + } + m_autorepeat_code = isAutoRepeat ? code : 0; + } + QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers, - code, 0, state, string.left(count)); + code, 0, state, string.left(count), isAutoRepeat); + + if (isAutoRepeat && type == QEvent::KeyRelease) { + // since we removed it from the event queue using checkEvent we need to send the key press here + QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers, + code, 0, state, string.left(count), isAutoRepeat); + } } #ifdef XCB_USE_XLIB diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index a4b6a28886..4a62dde11a 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -86,6 +86,7 @@ private: uint m_caps_lock_mask; xcb_key_symbols_t *m_key_symbols; + xcb_keycode_t m_autorepeat_code; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp index 271d41ae75..5d86a118c7 100644 --- a/src/plugins/platforms/xcb/qxcbmime.cpp +++ b/src/plugins/platforms/xcb/qxcbmime.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbmime.h b/src/plugins/platforms/xcb/qxcbmime.h index ac032db442..02be4c9c5b 100644 --- a/src/plugins/platforms/xcb/qxcbmime.h +++ b/src/plugins/platforms/xcb/qxcbmime.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 5e0af8d24d..52ff30991e 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index 0902af03eb..517e92bc64 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbobject.h b/src/plugins/platforms/xcb/qxcbobject.h index a594066545..b164f63f76 100644 --- a/src/plugins/platforms/xcb/qxcbobject.h +++ b/src/plugins/platforms/xcb/qxcbobject.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 1336ddb32a..8b01b4389f 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 76cc0fa1b4..1975d56189 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 8e01c8ec40..2cd2a15fb7 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 6ff1627f98..f0b6437699 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp index 15e423e95b..f06c9c503c 100644 --- a/src/plugins/platforms/xcb/qxcbwmsupport.cpp +++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.h b/src/plugins/platforms/xcb/qxcbwmsupport.h index 7b0a21f035..faa0934a3d 100644 --- a/src/plugins/platforms/xcb/qxcbwmsupport.h +++ b/src/plugins/platforms/xcb/qxcbwmsupport.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** |