summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2012-09-26 16:25:57 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-02 13:22:49 +0200
commit341dcae472553f20d4ed91897f05637523922c1b (patch)
tree18ca3e8927eb2203945a39934c8ea05cbac474b6 /src
parente840b8b2e3d62dfc222b672a0ba32e7da8dc159e (diff)
Fix a crash with xcb on 64bit systems when hitting any key.
xcb uses 32bits for xcb_keysym_t, but Xlib uses 64bit longs on 64bits systems for KeySym and all other XIDs on the client side. Passing an xcb_keysym_t* to XLookupString, expecting a KeySym*, would overwrite the next 32bits in memory and possibly cause a crash. This patch makes sure that a KeySym* is passed to XLookupString, and use the signature declared in Xutil.h to make sure the types are right. Encapsulate it in qxlibconvenience.cpp since including Xutil.h inside qxcbkeyboard.cpp causes macro expansion problems. Change-Id: I68451a24cb44a43dfa4382b5dce1ea7845f14e26 Reviewed-by: Samuel Rødal <samuel.rodal@digia.com> Reviewed-by: Laszlo Papp <lpapp@kde.org>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp42
-rw-r--r--src/plugins/platforms/xcb/qxlibconvenience.cpp71
-rw-r--r--src/plugins/platforms/xcb/qxlibconvenience.h57
-rw-r--r--src/plugins/platforms/xcb/xcb.pro6
4 files changed, 138 insertions, 38 deletions
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 3d0b8eebe5..be04bf11ff 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -42,6 +42,7 @@
#include "qxcbkeyboard.h"
#include "qxcbwindow.h"
#include "qxcbscreen.h"
+#include "qxlibconvenience.h"
#include <xcb/xcb_keysyms.h>
#include <X11/keysym.h>
#include <qpa/qwindowsysteminterface.h>
@@ -1132,46 +1133,15 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
}
}
-#ifdef XCB_USE_XLIB
-extern "C" {
- int XLookupString(void *event, char *buf, int count, void *keysym, void *comp);
-}
-typedef struct { // must match XKeyEvent in Xlib.h
- int type;
- unsigned long serial;
- int send_event;
- void *display;
- unsigned long window;
- unsigned long root;
- unsigned long subwindow;
- unsigned long time;
- int x, y;
- int x_root, y_root;
- unsigned int state;
- unsigned int keycode;
- int same_screen;
-} FakeXKeyEvent;
-#endif
-
xcb_keysym_t QXcbKeyboard::lookupString(QWindow *window, uint state, xcb_keycode_t code,
QEvent::Type type, QByteArray *chars)
{
#ifdef XCB_USE_XLIB
-
- xcb_keysym_t sym = XCB_NO_SYMBOL;
- chars->resize(512);
- FakeXKeyEvent event;
- memset(&event, 0, sizeof(event));
- event.type = (type == QEvent::KeyRelease ? 3 : 2);
- event.display = connection()->xlib_display();
- event.window = static_cast<QXcbWindow *>(window->handle())->xcb_window();
- event.root = connection()->screens().at(0)->root();
- event.state = state;
- event.keycode = code;
- int count = XLookupString(&event, chars->data(), chars->size(), &sym, 0);
- chars->resize(count);
- return sym;
-
+ xcb_window_t xWindow = static_cast<QXcbWindow *>(window->handle())->xcb_window();
+ xcb_window_t root = connection()->screens().at(0)->root();
+ void *xDisplay = connection()->xlib_display();
+ int xType = (type == QEvent::KeyRelease ? 3 : 2);
+ return q_XLookupString(xDisplay, xWindow, root, state, code, xType, chars);
#else
// No XLookupString available. The following is really incomplete...
diff --git a/src/plugins/platforms/xcb/qxlibconvenience.cpp b/src/plugins/platforms/xcb/qxlibconvenience.cpp
new file mode 100644
index 0000000000..06bfbaa928
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxlibconvenience.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifdef XCB_USE_XLIB
+
+#include "qxlibconvenience.h"
+
+// Some Xlib headers are heavy macro namespace polluters and conflict with Qt types.
+// This unit makes it easier to deal with them by encapsulating these includes in this .cpp.
+#include <X11/Xutil.h>
+
+QT_BEGIN_NAMESPACE
+
+xcb_keysym_t q_XLookupString(void *display, xcb_window_t window, xcb_window_t root, uint state, xcb_keycode_t code, int type, QByteArray *chars)
+{
+ KeySym sym = 0;
+ chars->resize(512);
+ XKeyEvent event;
+ memset(&event, 0, sizeof(event));
+ event.type = type;
+ event.display = static_cast<Display*>(display);
+ event.window = window;
+ event.root = root;
+ event.state = state;
+ event.keycode = code;
+ int count = XLookupString(&event, chars->data(), chars->size(), &sym, 0);
+ chars->resize(count);
+ return sym;
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxlibconvenience.h b/src/plugins/platforms/xcb/qxlibconvenience.h
new file mode 100644
index 0000000000..922c841c15
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxlibconvenience.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XLIBUTILS_H
+#define XLIBUTILS_H
+
+#ifdef XCB_USE_XLIB
+
+#include <xcb/xcb_keysyms.h>
+#include <QByteArray>
+
+QT_BEGIN_NAMESPACE
+
+xcb_keysym_t q_XLookupString(void *display, xcb_window_t window, xcb_window_t root, uint state, xcb_keycode_t code, int type, QByteArray *chars);
+
+QT_END_NAMESPACE
+
+#endif // XCB_USE_XLIB
+#endif
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
index df37e59365..116951d36d 100644
--- a/src/plugins/platforms/xcb/xcb.pro
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -20,7 +20,8 @@ SOURCES = \
main.cpp \
qxcbnativeinterface.cpp \
qxcbcursor.cpp \
- qxcbimage.cpp
+ qxcbimage.cpp \
+ qxlibconvenience.cpp
HEADERS = \
qxcbclipboard.h \
@@ -36,7 +37,8 @@ HEADERS = \
qxcbwmsupport.h \
qxcbnativeinterface.h \
qxcbcursor.h \
- qxcbimage.h
+ qxcbimage.h \
+ qxlibconvenience.h
contains(QT_CONFIG, xcb-poll-for-queued-event) {
DEFINES += XCB_POLL_FOR_QUEUED_EVENT