diff options
Diffstat (limited to 'src/platformsupport')
52 files changed, 5288 insertions, 0 deletions
diff --git a/src/platformsupport/cglconvenience/cglconvenience.mm b/src/platformsupport/cglconvenience/cglconvenience.mm new file mode 100644 index 0000000000..43d955e2b2 --- /dev/null +++ b/src/platformsupport/cglconvenience/cglconvenience.mm @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "cglconvenience_p.h" +#include <QtCore/private/qcore_mac_p.h> +#include <Cocoa/Cocoa.h> + +void (*qcgl_getProcAddress(const QByteArray &procName))() +{ + CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, + CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, false); + CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault, url); + CFStringRef procNameCF = QCFString::toCFStringRef(QString::fromAscii(procName.constData())); + void *proc = CFBundleGetFunctionPointerForName(bundle, procNameCF); + CFRelease(url); + CFRelease(bundle); + CFRelease(procNameCF); + return (void (*) ())proc; +} + +// Match up with createNSOpenGLPixelFormat below! +QSurfaceFormat qcgl_surfaceFormat() +{ + QSurfaceFormat format; + format.setRedBufferSize(8); + format.setGreenBufferSize(8); + format.setBlueBufferSize(8); + format.setAlphaBufferSize(8); +/* + format.setDepthBufferSize(24); + format.setAccumBufferSize(0); + format.setStencilBufferSize(8); + format.setSampleBuffers(false); + format.setSamples(1); + format.setDepth(true); + format.setRgba(true); + format.setAlpha(true); + format.setAccum(false); + format.setStencil(true); + format.setStereo(false); + format.setDirectRendering(false); +*/ + return format; +} + +void *qcgl_createNSOpenGLPixelFormat() +{ + NSOpenGLPixelFormatAttribute attrs[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, 32, + 0 + }; + + NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + return pixelFormat; +} + +CGLContextObj qcgl_createGlContext() +{ + CGLContextObj context; + NSOpenGLPixelFormat *format = reinterpret_cast<NSOpenGLPixelFormat *>(qcgl_createNSOpenGLPixelFormat()); + CGLPixelFormatObj cglFormat = static_cast<CGLPixelFormatObj>([format CGLPixelFormatObj]); + CGLCreateContext(cglFormat ,NULL, &context); + return context; +} + diff --git a/src/platformsupport/cglconvenience/cglconvenience.pri b/src/platformsupport/cglconvenience/cglconvenience.pri new file mode 100644 index 0000000000..fef3b50ea3 --- /dev/null +++ b/src/platformsupport/cglconvenience/cglconvenience.pri @@ -0,0 +1,11 @@ +mac { + INCLUDEPATH += $$PWD + + HEADERS += \ + $$PWD/cglconvenience_p.h + + OBJECTIVE_SOURCES += \ + $$PWD/cglconvenience.mm + + LIBS += -framework Cocoa -framework OpenGl +} diff --git a/src/platformsupport/cglconvenience/cglconvenience_p.h b/src/platformsupport/cglconvenience/cglconvenience_p.h new file mode 100644 index 0000000000..f7426b4cc1 --- /dev/null +++ b/src/platformsupport/cglconvenience/cglconvenience_p.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMACGLCONVENIENCE_H +#define QMACGLCONVENIENCE_H + +#include <QSurfaceFormat> +#include <QString> +#include <OpenGL/OpenGL.h> + +Q_GUI_EXPORT void (*qcgl_getProcAddress(const QByteArray &procName))(); +Q_GUI_EXPORT QSurfaceFormat qcgl_surfaceFormat(); +Q_GUI_EXPORT void *qcgl_createNSOpenGLPixelFormat(); +Q_GUI_EXPORT CGLContextObj qcgl_createGlContext(); + +#endif // QMACGLCONVENIENCE_H diff --git a/src/platformsupport/dnd/dnd.pri b/src/platformsupport/dnd/dnd.pri new file mode 100644 index 0000000000..e100dd10cb --- /dev/null +++ b/src/platformsupport/dnd/dnd.pri @@ -0,0 +1,4 @@ +HEADERS += \ + $$PWD/qsimpledrag_p.h +SOURCES += \ + $$PWD/qsimpledrag.cpp diff --git a/src/platformsupport/dnd/qsimpledrag.cpp b/src/platformsupport/dnd/qsimpledrag.cpp new file mode 100644 index 0000000000..72da29c063 --- /dev/null +++ b/src/platformsupport/dnd/qsimpledrag.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsimpledrag_p.h" + +#include "qbitmap.h" +#include "qdrag.h" +#include "qpixmap.h" +#include "qevent.h" +#include "qfile.h" +#include "qtextcodec.h" +#include "qguiapplication.h" +#include "qpoint.h" +#include "qbuffer.h" +#include "qimage.h" +#include "qregexp.h" +#include "qdir.h" +#include "qimagereader.h" +#include "qimagewriter.h" + +#include <private/qguiapplication_p.h> +#include <private/qdnd_p.h> + +QT_BEGIN_NAMESPACE + +class QDropData : public QInternalMimeData +{ +public: + QDropData(); + ~QDropData(); + +protected: + bool hasFormat_sys(const QString &mimeType) const; + QStringList formats_sys() const; + QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const; +}; + +QSimpleDrag::QSimpleDrag() +{ + m_dropData = new QDropData(); + currentWindow = 0; +} + +QSimpleDrag::~QSimpleDrag() +{ + delete m_dropData; +} + +QMimeData *QSimpleDrag::platformDropData() +{ + return m_dropData; +} + +void QSimpleDrag::cancel() +{ + QDragManager *m = QDragManager::self(); +// qDebug("QDragManager::cancel"); + if (m->object->target()) { + QDragLeaveEvent dle; + QCoreApplication::sendEvent(m->object->target(), &dle); + } + +} + +void QSimpleDrag::move(const QMouseEvent *me) +{ + QWindow *window = QGuiApplication::topLevelAt(me->globalPos()); + QPoint pos; + if (window) + pos = me->globalPos() - window->geometry().topLeft(); + + QDragManager *m = QDragManager::self(); + + if (me->buttons()) { + Qt::DropAction prevAction = m->global_accepted_action; + + if (currentWindow != window) { + if (currentWindow) { + QDragLeaveEvent dle; + QCoreApplication::sendEvent(currentWindow, &dle); + m->willDrop = false; + m->global_accepted_action = Qt::IgnoreAction; + } + currentWindow = window; + if (currentWindow) { + QDragEnterEvent dee(pos, m->possible_actions, m->dropData(), me->buttons(), me->modifiers()); + QCoreApplication::sendEvent(currentWindow, &dee); + m->willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction; + m->global_accepted_action = m->willDrop ? dee.dropAction() : Qt::IgnoreAction; + } + m->updateCursor(); + } else if (window) { + Q_ASSERT(currentWindow); + QDragMoveEvent dme(pos, m->possible_actions, m->dropData(), me->buttons(), me->modifiers()); + if (m->global_accepted_action != Qt::IgnoreAction) { + dme.setDropAction(m->global_accepted_action); + dme.accept(); + } + QCoreApplication::sendEvent(currentWindow, &dme); + m->willDrop = dme.isAccepted(); + m->global_accepted_action = m->willDrop ? dme.dropAction() : Qt::IgnoreAction; + m->updatePixmap(); + m->updateCursor(); + } + if (m->global_accepted_action != prevAction) + m->emitActionChanged(m->global_accepted_action); + } +} + +void QSimpleDrag::drop(const QMouseEvent *me) +{ + QDragManager *m = QDragManager::self(); + + QWindow *window = QGuiApplication::topLevelAt(me->globalPos()); + + if (window) { + QPoint pos = me->globalPos() - window->geometry().topLeft(); + + QDropEvent de(pos, m->possible_actions, m->dropData(), me->buttons(), me->modifiers()); + QCoreApplication::sendEvent(window, &de); + if (de.isAccepted()) + m->global_accepted_action = de.dropAction(); + else + m->global_accepted_action = Qt::IgnoreAction; + } + currentWindow = 0; +} + + + +QDropData::QDropData() + : QInternalMimeData() +{ +} + +QDropData::~QDropData() +{ +} + +QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const +{ + QDrag *object = QDragManager::self()->object; + if (!object) + return QVariant(); + QByteArray data = object->mimeData()->data(mimetype); + if (type == QVariant::String) + return QString::fromUtf8(data); + return data; +} + +bool QDropData::hasFormat_sys(const QString &format) const +{ + return formats().contains(format); +} + +QStringList QDropData::formats_sys() const +{ + QDrag *object = QDragManager::self()->object; + if (object) + return object->mimeData()->formats(); + return QStringList(); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/dnd/qsimpledrag_p.h b/src/platformsupport/dnd/qsimpledrag_p.h new file mode 100644 index 0000000000..82668a68c9 --- /dev/null +++ b/src/platformsupport/dnd/qsimpledrag_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSIMPLEDRAG_H +#define QSIMPLEDRAG_H + +#include <qplatformdrag_qpa.h> + +QT_BEGIN_NAMESPACE + +class QMouseEvent; +class QWindow; + +class QDropData; + +class QSimpleDrag : public QPlatformDrag +{ +public: + QSimpleDrag(); + ~QSimpleDrag(); + + virtual QMimeData *platformDropData(); + +// virtual Qt::DropAction drag(QDrag *); + + virtual void cancel(); + virtual void move(const QMouseEvent *me); + virtual void drop(const QMouseEvent *me); +private: + QDropData *m_dropData; + + QWindow *currentWindow; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri new file mode 100644 index 0000000000..f8500e2de0 --- /dev/null +++ b/src/platformsupport/eglconvenience/eglconvenience.pri @@ -0,0 +1,15 @@ +contains(QT_CONFIG,opengles2) { + HEADERS += \ + $$PWD/qeglconvenience_p.h \ + $$PWD/qeglplatformcontext_p.h + SOURCES += \ + $$PWD/qeglconvenience.cpp \ + $$PWD/qeglplatformcontext.cpp + + contains(QT_CONFIG,xlib) { + HEADERS += \ + $$PWD/qxlibeglintegration_p.h + SOURCES += \ + $$PWD/qxlibeglintegration.cpp + } +} diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp new file mode 100644 index 0000000000..63f564c2d5 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -0,0 +1,306 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QByteArray> + +#include "qeglconvenience_p.h" + +QT_BEGIN_NAMESPACE + +QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format) +{ + int redSize = format.redBufferSize(); + int greenSize = format.greenBufferSize(); + int blueSize = format.blueBufferSize(); + int alphaSize = format.alphaBufferSize(); + int depthSize = format.depthBufferSize(); + int stencilSize = format.stencilBufferSize(); + int sampleCount = format.samples(); + + // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide + // the best performance. The EGL config selection algorithm is a bit stange in this regard: + // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard + // 32-bit configs completely from the selection. So it then comes to the sorting algorithm. + // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort + // order is special and described as "by larger _total_ number of color bits.". So EGL will + // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on + // to say "If the requested number of bits in attrib_list for a particular component is 0, + // then the number of bits for that component is not considered". This part of the spec also + // seems to imply that setting the red/green/blue bits to zero means none of the components + // are considered and EGL disregards the entire sorting rule. It then looks to the next + // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being + // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are + // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit, + // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that + // if the application sets the red/green/blue size to 5/6/5 on the QSurfaceFormat, + // they will probably get a 32-bit config, even when there's an RGB565 config available. + +// // Now normalize the values so -1 becomes 0 +// redSize = redSize > 0 ? redSize : 0; +// greenSize = greenSize > 0 ? greenSize : 0; +// blueSize = blueSize > 0 ? blueSize : 0; +// alphaSize = alphaSize > 0 ? alphaSize : 0; +// depthSize = depthSize > 0 ? depthSize : 0; +// stencilSize = stencilSize > 0 ? stencilSize : 0; +// sampleCount = sampleCount > 0 ? sampleCount : 0; + + QVector<EGLint> configAttributes; + + configAttributes.append(EGL_RED_SIZE); + configAttributes.append(redSize); + + configAttributes.append(EGL_GREEN_SIZE); + configAttributes.append(greenSize); + + configAttributes.append(EGL_BLUE_SIZE); + configAttributes.append(blueSize); + + configAttributes.append(EGL_ALPHA_SIZE); + configAttributes.append(alphaSize); + + configAttributes.append(EGL_DEPTH_SIZE); + configAttributes.append(depthSize); + + configAttributes.append(EGL_STENCIL_SIZE); + configAttributes.append(stencilSize); + + configAttributes.append(EGL_SAMPLES); + configAttributes.append(sampleCount); + + configAttributes.append(EGL_SAMPLE_BUFFERS); + configAttributes.append(sampleCount? 1:0); + + return configAttributes; +} + +bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes) +{ + int i = -1; + // Reduce the complexity of a configuration request to ask for less + // because the previous request did not result in success. Returns + // true if the complexity was reduced, or false if no further + // reductions in complexity are possible. + + i = configAttributes->indexOf(EGL_SWAP_BEHAVIOR); + if (i >= 0) { + configAttributes->remove(i,2); + } + +#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT + // For OpenVG, we sometimes try to create a surface using a pre-multiplied format. If we can't + // find a config which supports pre-multiplied formats, remove the flag on the surface type: + + i = configAttributes->indexOf(EGL_SURFACE_TYPE); + if (i >= 0) { + EGLint surfaceType = configAttributes->at(i +1); + if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) { + surfaceType ^= EGL_VG_ALPHA_FORMAT_PRE_BIT; + configAttributes->replace(i+1,surfaceType); + return true; + } + } +#endif + + // EGL chooses configs with the highest color depth over + // those with smaller (but faster) lower color depths. One + // way around this is to set EGL_BUFFER_SIZE to 16, which + // trumps the others. Of course, there may not be a 16-bit + // config available, so it's the first restraint we remove. + i = configAttributes->indexOf(EGL_BUFFER_SIZE); + if (i >= 0) { + if (configAttributes->at(i+1) == 16) { + configAttributes->remove(i,2); + return true; + } + } + + i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS); + if (i >= 0) { + configAttributes->remove(i,2); + i = configAttributes->indexOf(EGL_SAMPLES); + if (i >= 0) { + configAttributes->remove(i,2); + } + return true; + } + + i = configAttributes->indexOf(EGL_ALPHA_SIZE); + if (i >= 0) { + configAttributes->remove(i,2); +#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB) + i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGBA); + if (i >= 0) { + configAttributes->replace(i,EGL_BIND_TO_TEXTURE_RGB); + configAttributes->replace(i+1,TRUE); + + } +#endif + return true; + } + + i = configAttributes->indexOf(EGL_STENCIL_SIZE); + if (i >= 0) { + configAttributes->remove(i,2); + return true; + } + i = configAttributes->indexOf(EGL_DEPTH_SIZE); + if (i >= 0) { + configAttributes->remove(i,2); + return true; + } +#ifdef EGL_BIND_TO_TEXTURE_RGB + i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGB); + if (i >= 0) { + configAttributes->remove(i,2); + return true; + } +#endif + + return false; +} + +EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format, bool highestPixelFormat, int surfaceType) +{ + EGLConfig cfg = 0; + QVector<EGLint> configureAttributes = q_createConfigAttributesFromFormat(format); + configureAttributes.append(EGL_SURFACE_TYPE); //we only support eglconfigs for windows for now + configureAttributes.append(surfaceType); + + configureAttributes.append(EGL_RENDERABLE_TYPE); + configureAttributes.append(EGL_OPENGL_ES2_BIT); + configureAttributes.append(EGL_NONE); + + do { + // Get the number of matching configurations for this set of properties. + EGLint matching = 0; + if (!eglChooseConfig(display, configureAttributes.constData(), 0, 0, &matching) || !matching) + continue; + + // If we want the best pixel format, then return the first + // matching configuration. + if (highestPixelFormat) { + eglChooseConfig(display, configureAttributes.constData(), &cfg, 1, &matching); + if (matching < 1) + continue; + return cfg; + } + + // Fetch all of the matching configurations and find the + // first that matches the pixel format we wanted. + int i = configureAttributes.indexOf(EGL_RED_SIZE); + int confAttrRed = configureAttributes.at(i+1); + i = configureAttributes.indexOf(EGL_GREEN_SIZE); + int confAttrGreen = configureAttributes.at(i+1); + i = configureAttributes.indexOf(EGL_BLUE_SIZE); + int confAttrBlue = configureAttributes.at(i+1); + i = configureAttributes.indexOf(EGL_ALPHA_SIZE); + int confAttrAlpha = configureAttributes.at(i+1); + + EGLint size = matching; + EGLConfig *configs = new EGLConfig [size]; + eglChooseConfig(display, configureAttributes.constData(), configs, size, &matching); + for (EGLint index = 0; index < size; ++index) { + EGLint red, green, blue, alpha; + eglGetConfigAttrib(display, configs[index], EGL_RED_SIZE, &red); + eglGetConfigAttrib(display, configs[index], EGL_GREEN_SIZE, &green); + eglGetConfigAttrib(display, configs[index], EGL_BLUE_SIZE, &blue); + eglGetConfigAttrib(display, configs[index], EGL_ALPHA_SIZE, &alpha); + if (red == confAttrRed && + green == confAttrGreen && + blue == confAttrBlue && + (confAttrAlpha == 0 || + alpha == confAttrAlpha)) { + cfg = configs[index]; + delete [] configs; + return cfg; + } + } + delete [] configs; + } while (q_reduceConfigAttributes(&configureAttributes)); + qWarning("Cant find EGLConfig, returning null config"); + return 0; +} + +QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config) +{ + QSurfaceFormat format; + EGLint redSize = 0; + EGLint greenSize = 0; + EGLint blueSize = 0; + EGLint alphaSize = 0; + EGLint depthSize = 0; + EGLint stencilSize = 0; + EGLint sampleCount = 0; + + eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize); + eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize); + eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize); + eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize); + eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize); + eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize); + eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount); + + format.setRedBufferSize(redSize); + format.setGreenBufferSize(greenSize); + format.setBlueBufferSize(blueSize); + format.setAlphaBufferSize(alphaSize); + format.setDepthBufferSize(depthSize); + format.setStencilBufferSize(stencilSize); + format.setSamples(sampleCount); + format.setStereo(false); // EGL doesn't support stereo buffers + + // Clear the EGL error state because some of the above may + // have errored out because the attribute is not applicable + // to the surface type. Such errors don't matter. + eglGetError(); + + return format; +} + +bool q_hasEglExtension(EGLDisplay display, const char* extensionName) +{ + QList<QByteArray> extensions = + QByteArray(reinterpret_cast<const char *> + (eglQueryString(display, EGL_EXTENSIONS))).split(' '); + return extensions.contains(extensionName); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h new file mode 100644 index 0000000000..7b5b970415 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLCONVENIENCE_H +#define QEGLCONVENIENCE_H + + +#include <QtGui/QSurfaceFormat> +#include <QtCore/QVector> + +#include <EGL/egl.h> +QT_BEGIN_NAMESPACE + +QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format); +bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes); +EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format, bool highestPixelFormat = false, int surfaceType = EGL_WINDOW_BIT); +QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config); +bool q_hasEglExtension(EGLDisplay display,const char* extensionName); + +QT_END_NAMESPACE + +#endif //QEGLCONVENIENCE_H diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp new file mode 100644 index 0000000000..0e61dd3486 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglplatformcontext_p.h" + +#include "qeglconvenience_p.h" + +#include <QtGui/QPlatformWindow> + +#include <EGL/egl.h> + +QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformGLContext *share, EGLDisplay display, + EGLint eglClientVersion, EGLenum eglApi) + : m_eglDisplay(display) + , m_eglApi(eglApi) + , m_format(format) +{ + EGLConfig config = q_configFromGLFormat(display, format, true); + m_format = q_glFormatFromConfig(display, config); + + EGLContext shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0; + + QVector<EGLint> contextAttrs; + contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); + contextAttrs.append(eglClientVersion); + contextAttrs.append(EGL_NONE); + + eglBindAPI(m_eglApi); + m_eglContext = eglCreateContext(m_eglDisplay, config, shareContext, contextAttrs.constData()); + if (m_eglContext == EGL_NO_CONTEXT) { + qWarning("Could not create the egl context\n"); + eglTerminate(m_eglDisplay); + qFatal("EGL error"); + } +} + +bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface) +{ +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglContext::makeCurrent: %p\n",this); +#endif + eglBindAPI(m_eglApi); + + EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface); + + bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext); + if (!ok) + qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this); +#ifdef QEGL_EXTRA_DEBUG + static bool showDebug = true; + if (showDebug) { + showDebug = false; + const char *str = (const char*)glGetString(GL_VENDOR); + qWarning("Vendor %s\n", str); + str = (const char*)glGetString(GL_RENDERER); + qWarning("Renderer %s\n", str); + str = (const char*)glGetString(GL_VERSION); + qWarning("Version %s\n", str); + + str = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); + qWarning("Extensions %s\n",str); + + str = (const char*)glGetString(GL_EXTENSIONS); + qWarning("Extensions %s\n", str); + + } +#endif + return ok; +} + +QEGLPlatformContext::~QEGLPlatformContext() +{ +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglContext::~QEglContext(): %p\n",this); +#endif + if (m_eglContext != EGL_NO_CONTEXT) { + eglDestroyContext(m_eglDisplay, m_eglContext); + m_eglContext = EGL_NO_CONTEXT; + } +} + +void QEGLPlatformContext::doneCurrent() +{ +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglContext::doneCurrent:%p\n",this); +#endif + eglBindAPI(m_eglApi); + bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (!ok) + qWarning("QEGLPlatformContext::doneCurrent(): eglError: %d, this: %p \n", eglGetError(), this); +} + +void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface) +{ +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglContext::swapBuffers:%p\n",this); +#endif + eglBindAPI(m_eglApi); + EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface); + bool ok = eglSwapBuffers(m_eglDisplay, eglSurface); + if (!ok) + qWarning("QEGLPlatformContext::swapBuffers(): eglError: %d, this: %p \n", eglGetError(), this); +} + +void (*QEGLPlatformContext::getProcAddress(const QByteArray &procName)) () +{ +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglContext::getProcAddress%p\n",this); +#endif + eglBindAPI(m_eglApi); + return eglGetProcAddress(procName.constData()); +} + +QSurfaceFormat QEGLPlatformContext::format() const +{ + return m_format; +} + +EGLContext QEGLPlatformContext::eglContext() const +{ + return m_eglContext; +} diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h new file mode 100644 index 0000000000..56a873afcb --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLPLATFORMCONTEXT_H +#define QEGLPLATFORMCONTEXT_H + +#include <QtGui/QPlatformWindow> +#include <QtGui/QPlatformGLContext> +#include <EGL/egl.h> + +class QEGLPlatformContext : public QPlatformGLContext +{ +public: + QEGLPlatformContext(const QSurfaceFormat &format, QPlatformGLContext *share, EGLDisplay display, + EGLint eglClientVersion = 2, EGLenum eglApi = EGL_OPENGL_ES_API); + ~QEGLPlatformContext(); + + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + void swapBuffers(QPlatformSurface *surface); + void (*getProcAddress(const QByteArray &procName)) (); + + QSurfaceFormat format() const; + + EGLContext eglContext() const; + +protected: + virtual EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) = 0; + +private: + EGLContext m_eglContext; + EGLDisplay m_eglDisplay; + EGLenum m_eglApi; + + QSurfaceFormat m_format; +}; + +#endif //QEGLPLATFORMCONTEXT_H diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp new file mode 100644 index 0000000000..aeebd35d21 --- /dev/null +++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qxlibeglintegration_p.h" + +static int countBits(unsigned long mask) +{ + int count = 0; + while (mask != 0) { + if (mask & 1) + ++count; + mask >>= 1; + } + return count; +} + +VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config) +{ + VisualID visualId = 0; + EGLint eglValue = 0; + + EGLint configRedSize = 0; + eglGetConfigAttrib(eglDisplay, config, EGL_RED_SIZE, &configRedSize); + + EGLint configGreenSize = 0; + eglGetConfigAttrib(eglDisplay, config, EGL_GREEN_SIZE, &configGreenSize); + + EGLint configBlueSize = 0; + eglGetConfigAttrib(eglDisplay, config, EGL_BLUE_SIZE, &configBlueSize); + + EGLint configAlphaSize = 0; + eglGetConfigAttrib(eglDisplay, config, EGL_ALPHA_SIZE, &configAlphaSize); + + eglGetConfigAttrib(eglDisplay, config, EGL_CONFIG_ID, &eglValue); + int configId = eglValue; + + // See if EGL provided a valid VisualID: + eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &eglValue); + visualId = (VisualID)eglValue; + if (visualId) { + // EGL has suggested a visual id, so get the rest of the visual info for that id: + XVisualInfo visualInfoTemplate; + memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); + visualInfoTemplate.visualid = visualId; + + XVisualInfo *chosenVisualInfo; + int matchingCount = 0; + chosenVisualInfo = XGetVisualInfo(display, VisualIDMask, &visualInfoTemplate, &matchingCount); + if (chosenVisualInfo) { + // Skip size checks if implementation supports non-matching visual + // and config (http://bugreports.qt.nokia.com/browse/QTBUG-9444). + if (q_hasEglExtension(eglDisplay,"EGL_NV_post_convert_rounding")) { + XFree(chosenVisualInfo); + return visualId; + } + + int visualRedSize = countBits(chosenVisualInfo->red_mask); + int visualGreenSize = countBits(chosenVisualInfo->green_mask); + int visualBlueSize = countBits(chosenVisualInfo->blue_mask); + int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size + + bool visualMatchesConfig = false; + if ( visualRedSize == configRedSize && + visualGreenSize == configGreenSize && + visualBlueSize == configBlueSize ) + { + // We need XRender to check the alpha channel size of the visual. If we don't have + // the alpha size, we don't check it against the EGL config's alpha size. + if (visualAlphaSize >= 0) + visualMatchesConfig = visualAlphaSize == configAlphaSize; + else + visualMatchesConfig = true; + } + + if (!visualMatchesConfig) { + if (visualAlphaSize >= 0) { + qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable", + (int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize, + configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize); + } else { + qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable", + (int)visualId, visualRedSize, visualGreenSize, visualBlueSize, + configId, configRedSize, configGreenSize, configBlueSize); + } + visualId = 0; + } + } else { + qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID", + (int)visualId, configId); + visualId = 0; + } + XFree(chosenVisualInfo); + } +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + else + qDebug("EGL did not suggest a VisualID (EGL_NATIVE_VISUAL_ID was zero) for EGLConfig %d", configId); +#endif + + if (visualId) { +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + if (configAlphaSize > 0) + qDebug("Using ARGB Visual ID %d provided by EGL for config %d", (int)visualId, configId); + else + qDebug("Using Opaque Visual ID %d provided by EGL for config %d", (int)visualId, configId); +#endif + return visualId; + } + + // Finally, try to + // use XGetVisualInfo and only use the bit depths to match on: + if (!visualId) { + XVisualInfo visualInfoTemplate; + memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); + XVisualInfo *matchingVisuals; + int matchingCount = 0; + + visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize + configAlphaSize; + matchingVisuals = XGetVisualInfo(display, + VisualDepthMask, + &visualInfoTemplate, + &matchingCount); + if (!matchingVisuals) { + // Try again without taking the alpha channel into account: + visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize; + matchingVisuals = XGetVisualInfo(display, + VisualDepthMask, + &visualInfoTemplate, + &matchingCount); + } + + if (matchingVisuals) { + visualId = matchingVisuals[0].visualid; + XFree(matchingVisuals); + } + } + + if (visualId) { +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + qDebug("Using Visual ID %d provided by XGetVisualInfo for EGL config %d", (int)visualId, configId); +#endif + return visualId; + } + + qWarning("Unable to find an X11 visual which matches EGL config %d", configId); + return (VisualID)0; +} diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration_p.h b/src/platformsupport/eglconvenience/qxlibeglintegration_p.h new file mode 100644 index 0000000000..cce394758d --- /dev/null +++ b/src/platformsupport/eglconvenience/qxlibeglintegration_p.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTESTLITEEGLINTEGRATION_H +#define QTESTLITEEGLINTEGRATION_H + +#include "qeglconvenience_p.h" + +class QXlibEglIntegration +{ +public: + static VisualID getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config); +}; + +#endif // QTESTLITEEGLINTEGRATION_H diff --git a/src/platformsupport/eventdispatchers/eventdispatchers.pri b/src/platformsupport/eventdispatchers/eventdispatchers.pri new file mode 100644 index 0000000000..38aca26b42 --- /dev/null +++ b/src/platformsupport/eventdispatchers/eventdispatchers.pri @@ -0,0 +1,16 @@ +unix { +SOURCES +=\ + $$PWD/qeventdispatcher_qpa.cpp\ + $$PWD/qgenericunixeventdispatcher.cpp\ + +HEADERS +=\ + $$PWD/qeventdispatcher_qpa_p.h\ + $$PWD/qgenericunixeventdispatcher_p.h\ +} + +contains(QT_CONFIG, glib) { + SOURCES +=$$PWD/qeventdispatcher_glib.cpp + HEADERS +=$$PWD/qeventdispatcher_glib_p.h + QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB + LIBS_PRIVATE += $$QT_LIBS_GLIB +} diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp b/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp new file mode 100644 index 0000000000..005c44a034 --- /dev/null +++ b/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeventdispatcher_glib_p.h" + +#include "qguiapplication.h" + +#include "qplatformdefs.h" + +#include <glib.h> +#include "private/qguiapplication_p.h" + +#include <qdebug.h> + +QT_BEGIN_NAMESPACE + +struct GUserEventSource +{ + GSource source; + QPAEventDispatcherGlib *q; +}; + +static gboolean userEventSourcePrepare(GSource *s, gint *timeout) +{ + Q_UNUSED(s) + Q_UNUSED(timeout) + + return QWindowSystemInterface::windowSystemEventsQueued() > 0; +} + +static gboolean userEventSourceCheck(GSource *source) +{ + return userEventSourcePrepare(source, 0); +} + +static gboolean userEventSourceDispatch(GSource *s, GSourceFunc, gpointer) +{ + GUserEventSource * source = reinterpret_cast<GUserEventSource *>(s); + QWindowSystemInterface::sendWindowSystemEvents(source->q, QEventLoop::AllEvents); + return true; +} + +static GSourceFuncs userEventSourceFuncs = { + userEventSourcePrepare, + userEventSourceCheck, + userEventSourceDispatch, + NULL, + NULL, + NULL +}; + +QPAEventDispatcherGlibPrivate::QPAEventDispatcherGlibPrivate(GMainContext *context) + : QEventDispatcherGlibPrivate(context) +{ + userEventSource = reinterpret_cast<GUserEventSource *>(g_source_new(&userEventSourceFuncs, + sizeof(GUserEventSource))); + userEventSource->q = 0; + g_source_set_can_recurse(&userEventSource->source, true); + g_source_attach(&userEventSource->source, mainContext); +} + + +QPAEventDispatcherGlib::QPAEventDispatcherGlib(QObject *parent) + : QEventDispatcherGlib(*new QPAEventDispatcherGlibPrivate, parent) +{ + Q_D(QPAEventDispatcherGlib); + d->userEventSource->q = this; +} + +QPAEventDispatcherGlib::~QPAEventDispatcherGlib() +{ + Q_D(QPAEventDispatcherGlib); + + g_source_destroy(&d->userEventSource->source); + g_source_unref(&d->userEventSource->source); + d->userEventSource = 0; +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h b/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h new file mode 100644 index 0000000000..8a34e78357 --- /dev/null +++ b/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVENTDISPATCHER_GLIB_QPA_P_H +#define QEVENTDISPATCHER_GLIB_QPA_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the QLibrary class. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/private/qeventdispatcher_glib_p.h> + +typedef struct _GMainContext GMainContext; + +QT_BEGIN_NAMESPACE +class QPAEventDispatcherGlibPrivate; + +class QPAEventDispatcherGlib : public QEventDispatcherGlib +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QPAEventDispatcherGlib) + +public: + explicit QPAEventDispatcherGlib(QObject *parent = 0); + ~QPAEventDispatcherGlib(); +}; + +struct GUserEventSource; + +class QPAEventDispatcherGlibPrivate : public QEventDispatcherGlibPrivate +{ + Q_DECLARE_PUBLIC(QPAEventDispatcherGlib) +public: + QPAEventDispatcherGlibPrivate(GMainContext *context = 0); + GUserEventSource *userEventSource; +}; + + +QT_END_NAMESPACE + +#endif // QEVENTDISPATCHER_GLIB_QPA_P_H diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_qpa.cpp b/src/platformsupport/eventdispatchers/qeventdispatcher_qpa.cpp new file mode 100644 index 0000000000..bfadd8b654 --- /dev/null +++ b/src/platformsupport/eventdispatchers/qeventdispatcher_qpa.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformdefs.h" +#include "qcoreapplication.h" +#include "qeventdispatcher_qpa_p.h" +#include "private/qguiapplication_p.h" + +#include <QWindowSystemInterface> +#include <QtCore/QElapsedTimer> +#include <QtCore/QAtomicInt> +#include <QtCore/QSemaphore> + +#include <QtCore/QDebug> + +#include <errno.h> + +QT_BEGIN_NAMESPACE + +QT_USE_NAMESPACE + + +QEventDispatcherQPA::QEventDispatcherQPA(QObject *parent) + : QEventDispatcherUNIX(parent) +{ } + +QEventDispatcherQPA::~QEventDispatcherQPA() +{ } + +bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags) +{ + Q_D(QEventDispatcherQPA); + + bool didSendEvents = QWindowSystemInterface::sendWindowSystemEvents(this, flags); + + if (QEventDispatcherUNIX::processEvents(flags)) { + QEventDispatcherUNIX::processEvents(flags); + return true; + } + + return didSendEvents; +} + +bool QEventDispatcherQPA::hasPendingEvents() +{ + extern uint qGlobalPostedEventsCount(); // from qapplication.cpp + return qGlobalPostedEventsCount() || QWindowSystemInterface::windowSystemEventsQueued(); +} + +void QEventDispatcherQPA::flush() +{ + if(qApp) + qApp->sendPostedEvents(); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_qpa_p.h b/src/platformsupport/eventdispatchers/qeventdispatcher_qpa_p.h new file mode 100644 index 0000000000..cb67701750 --- /dev/null +++ b/src/platformsupport/eventdispatchers/qeventdispatcher_qpa_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVENTDISPATCHER_QPA_H +#define QEVENTDISPATCHER_QPA_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtCore/private/qeventdispatcher_unix_p.h> + +QT_BEGIN_NAMESPACE + +class QEventDispatcherQPAPrivate; + +class Q_GUI_EXPORT QEventDispatcherQPA : public QEventDispatcherUNIX +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QEventDispatcherQPA) + +public: + explicit QEventDispatcherQPA(QObject *parent = 0); + ~QEventDispatcherQPA(); + + bool processEvents(QEventLoop::ProcessEventsFlags flags); + bool hasPendingEvents(); + + void flush(); +}; + +QT_END_NAMESPACE + +#endif // QEVENTDISPATCHER_QPA_H diff --git a/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp new file mode 100644 index 0000000000..12981c5721 --- /dev/null +++ b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgenericunixeventdispatcher_p.h" +#include "qeventdispatcher_qpa_p.h" +#include "qeventdispatcher_glib_p.h" +#include <qglobal.h> + +class QAbstractEventDispatcher *createUnixEventDispatcher() +{ +#if !defined(QT_NO_GLIB) && !defined(Q_OS_WIN) + if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported()) + return new QPAEventDispatcherGlib(); + else +#endif + return new QEventDispatcherQPA(); +} diff --git a/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h new file mode 100644 index 0000000000..06221ee075 --- /dev/null +++ b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +class QAbstractEventDispatcher; +#ifdef Q_OS_MAC +Q_GUI_EXPORT QAbstractEventDispatcher* createUnixEventDispatcher(); +#else +QAbstractEventDispatcher* createUnixEventDispatcher(); +#endif
\ No newline at end of file diff --git a/src/platformsupport/fb_base/fb_base.cpp b/src/platformsupport/fb_base/fb_base.cpp new file mode 100644 index 0000000000..aa395fec29 --- /dev/null +++ b/src/platformsupport/fb_base/fb_base.cpp @@ -0,0 +1,507 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "fb_base_p.h" +#include <qpainter.h> +#include <qdebug.h> +#include <qbitmap.h> +#include <QPlatformCursor> +#include <QWindowSystemInterface> + +QPlatformSoftwareCursor::QPlatformSoftwareCursor(QPlatformScreen *scr) + : QPlatformCursor(scr), currentRect(QRect()), prevRect(QRect()) +{ + graphic = new QPlatformCursorImage(0, 0, 0, 0, 0, 0); + setCursor(Qt::ArrowCursor); +} + +QRect QPlatformSoftwareCursor::getCurrentRect() +{ + QRect rect = graphic->image()->rect().translated(-graphic->hotspot().x(), + -graphic->hotspot().y()); + rect.translate(QCursor::pos()); + QPoint screenOffset = screen->geometry().topLeft(); + rect.translate(-screenOffset); // global to local translation + return rect; +} + + +void QPlatformSoftwareCursor::pointerEvent(const QMouseEvent & e) +{ + Q_UNUSED(e); + QPoint screenOffset = screen->geometry().topLeft(); + currentRect = getCurrentRect(); + // global to local translation + if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset))) { + setDirty(); + } +} + +QRect QPlatformSoftwareCursor::drawCursor(QPainter & painter) +{ + dirty = false; + if (currentRect.isNull()) + return QRect(); + + // We need this because the cursor might be dirty due to moving off screen + QPoint screenOffset = screen->geometry().topLeft(); + // global to local translation + if (!currentRect.translated(screenOffset).intersects(screen->geometry())) + return QRect(); + + prevRect = currentRect; + painter.drawImage(prevRect, *graphic->image()); + onScreen = true; + return prevRect; +} + +QRect QPlatformSoftwareCursor::dirtyRect() +{ + if (onScreen) { + onScreen = false; + return prevRect; + } + return QRect(); +} + +void QPlatformSoftwareCursor::setCursor(Qt::CursorShape shape) +{ + graphic->set(shape); +} + +void QPlatformSoftwareCursor::setCursor(const QImage &image, int hotx, int hoty) +{ + graphic->set(image, hotx, hoty); +} + +void QPlatformSoftwareCursor::setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY) +{ + graphic->set(data, mask, width, height, hotX, hotY); +} + +void QPlatformSoftwareCursor::changeCursor(QCursor * widgetCursor, QWidget * widget) +{ + Q_UNUSED(widget); + Qt::CursorShape shape = widgetCursor->shape(); + + if (shape == Qt::BitmapCursor) { + // application supplied cursor + QPoint spot = widgetCursor->hotSpot(); + setCursor(widgetCursor->pixmap().toImage(), spot.x(), spot.y()); + } else { + // system cursor + setCursor(shape); + } + currentRect = getCurrentRect(); + QPoint screenOffset = screen->geometry().topLeft(); // global to local translation + if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset))) + setDirty(); +} + +QFbScreen::QFbScreen() : cursor(0), mGeometry(), mDepth(16), mFormat(QImage::Format_RGB16), mScreenImage(0), compositePainter(0), isUpToDate(false) +{ + mScreenImage = new QImage(mGeometry.size(), mFormat); + redrawTimer.setSingleShot(true); + redrawTimer.setInterval(0); + QObject::connect(&redrawTimer, SIGNAL(timeout()), this, SLOT(doRedraw())); +} + +void QFbScreen::setGeometry(QRect rect) +{ + delete mScreenImage; + mGeometry = rect; + mScreenImage = new QImage(mGeometry.size(), mFormat); + delete compositePainter; + compositePainter = 0; + invalidateRectCache(); +} + +void QFbScreen::setDepth(int depth) +{ + mDepth = depth; +} + +void QFbScreen::setPhysicalSize(QSize size) +{ + mPhysicalSize = size; +} + +void QFbScreen::setFormat(QImage::Format format) +{ + mFormat = format; + delete mScreenImage; + mScreenImage = new QImage(mGeometry.size(), mFormat); + delete compositePainter; + compositePainter = 0; +} + +QFbScreen::~QFbScreen() +{ + delete compositePainter; + delete mScreenImage; +} + +void QFbScreen::setDirty(const QRect &rect) +{ + QRect intersection = rect.intersected(mGeometry); + QPoint screenOffset = mGeometry.topLeft(); + repaintRegion += intersection.translated(-screenOffset); // global to local translation + if (!redrawTimer.isActive()) { + redrawTimer.start(); + } +} + +void QFbScreen::generateRects() +{ + cachedRects.clear(); + QPoint screenOffset = mGeometry.topLeft(); + QRegion remainingScreen(mGeometry.translated(-screenOffset)); // global to local translation + + for (int i = 0; i < windowStack.length(); i++) { + if (remainingScreen.isEmpty()) + break; + if (!windowStack[i]->visible()) + continue; + if (windowStack[i]->widget()->isMinimized()) + continue; + + if (!windowStack[i]->widget()->testAttribute(Qt::WA_TranslucentBackground)) { + QRect localGeometry = windowStack.at(i)->geometry().translated(-screenOffset); // global to local translation + remainingScreen -= localGeometry; + QRegion windowRegion(localGeometry); + windowRegion -= remainingScreen; + foreach(QRect rect, windowRegion.rects()) { + cachedRects += QPair<QRect, int>(rect, i); + } + } + } + foreach (QRect rect, remainingScreen.rects()) + cachedRects += QPair<QRect, int>(rect, -1); + isUpToDate = true; + return; +} + + + +QRegion QFbScreen::doRedraw() +{ + QPoint screenOffset = mGeometry.topLeft(); + + QRegion touchedRegion; + if (cursor && cursor->isDirty() && cursor->isOnScreen()) { + QRect lastCursor = cursor->dirtyRect(); + repaintRegion += lastCursor; + } + if (repaintRegion.isEmpty() && (!cursor || !cursor->isDirty())) { + return touchedRegion; + } + + QVector<QRect> rects = repaintRegion.rects(); + + if (!isUpToDate) + generateRects(); + + if (!compositePainter) + compositePainter = new QPainter(mScreenImage); + for (int rectIndex = 0; rectIndex < repaintRegion.numRects(); rectIndex++) { + QRegion rectRegion = rects[rectIndex]; + + for(int i = 0; i < cachedRects.length(); i++) { + QRect screenSubRect = cachedRects[i].first; + int layer = cachedRects[i].second; + QRegion intersect = rectRegion.intersected(screenSubRect); + + if (intersect.isEmpty()) + continue; + + rectRegion -= intersect; + + // we only expect one rectangle, but defensive coding... + foreach (QRect rect, intersect.rects()) { + bool firstLayer = true; + if (layer == -1) { + compositePainter->fillRect(rect, Qt::black); + firstLayer = false; + layer = windowStack.size() - 1; + } + + for (int layerIndex = layer; layerIndex != -1; layerIndex--) { + if (!windowStack[layerIndex]->visible()) + continue; + if (windowStack[layerIndex]->widget()->isMinimized()) + continue; + QRect windowRect = windowStack[layerIndex]->geometry().translated(-screenOffset); + QRect windowIntersect = rect.translated(-windowRect.left(), + -windowRect.top()); + compositePainter->drawImage(rect, windowStack[layerIndex]->surface->image(), + windowIntersect); + if (firstLayer) { + firstLayer = false; + } + } + } + } + } + + QRect cursorRect; + if (cursor && (cursor->isDirty() || repaintRegion.intersects(cursor->lastPainted()))) { + cursorRect = cursor->drawCursor(*compositePainter); + touchedRegion += cursorRect; + } + touchedRegion += repaintRegion; + repaintRegion = QRegion(); + + + +// qDebug() << "QFbScreen::doRedraw" << windowStack.size() << mScreenImage->size() << touchedRegion; + + + return touchedRegion; +} + +void QFbScreen::addWindow(QFbWindow *surface) +{ + windowStack.prepend(surface); + surface->mScreens.append(this); + invalidateRectCache(); + setDirty(surface->geometry()); +} + +void QFbScreen::removeWindow(QFbWindow * surface) +{ + windowStack.removeOne(surface); + surface->mScreens.removeOne(this); + invalidateRectCache(); + setDirty(surface->geometry()); +} + +void QFbWindow::raise() +{ + QList<QFbScreen *>::const_iterator i = mScreens.constBegin(); + QList<QFbScreen *>::const_iterator end = mScreens.constEnd(); + while (i != end) { + (*i)->raise(this); + ++i; + } +} + +void QFbScreen::raise(QPlatformWindow * surface) +{ + QFbWindow *s = static_cast<QFbWindow *>(surface); + int index = windowStack.indexOf(s); + if (index <= 0) + return; + windowStack.move(index, 0); + invalidateRectCache(); + setDirty(s->geometry()); +} + +void QFbWindow::lower() +{ + QList<QFbScreen *>::const_iterator i = mScreens.constBegin(); + QList<QFbScreen *>::const_iterator end = mScreens.constEnd(); + while (i != end) { + (*i)->lower(this); + ++i; + } +} + +void QFbScreen::lower(QPlatformWindow * surface) +{ + QFbWindow *s = static_cast<QFbWindow *>(surface); + int index = windowStack.indexOf(s); + if (index == -1 || index == (windowStack.size() - 1)) + return; + windowStack.move(index, windowStack.size() - 1); + invalidateRectCache(); + setDirty(s->geometry()); +} + +QWidget * QFbScreen::topLevelAt(const QPoint & p) const +{ + for(int i = 0; i < windowStack.size(); i++) { + if (windowStack[i]->geometry().contains(p, false) && + windowStack[i]->visible() && + !windowStack[i]->widget()->isMinimized()) { + return windowStack[i]->widget(); + } + } + return 0; +} + +QFbWindow::QFbWindow(QWidget *window) + :QPlatformWindow(window), + visibleFlag(false) +{ + static QAtomicInt winIdGenerator(1); + windowId = winIdGenerator.fetchAndAddRelaxed(1); +} + + +QFbWindow::~QFbWindow() +{ + QList<QFbScreen *>::const_iterator i = mScreens.constBegin(); + QList<QFbScreen *>::const_iterator end = mScreens.constEnd(); + while (i != end) { + (*i)->removeWindow(this); + ++i; + } +} + + +QFbWindowSurface::QFbWindowSurface(QFbScreen *screen, QWidget *window) + : QWindowSurface(window), + mScreen(screen) +{ + mImage = QImage(window->size(), mScreen->format()); + + platformWindow = static_cast<QFbWindow*>(window->platformWindow()); + platformWindow->surface = this; +} + +QFbWindowSurface::~QFbWindowSurface() +{ +} + +void QFbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(widget); + Q_UNUSED(offset); + + +// qDebug() << "QFbWindowSurface::flush" << region; + + + platformWindow->repaint(region); +} + + +void QFbWindow::repaint(const QRegion ®ion) +{ + QRect currentGeometry = geometry(); + + QRect dirtyClient = region.boundingRect(); + QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(), + currentGeometry.top() + dirtyClient.top(), + dirtyClient.width(), + dirtyClient.height()); + QList<QFbScreen *>::const_iterator i = mScreens.constBegin(); + QList<QFbScreen *>::const_iterator end = mScreens.constEnd(); + QRect oldGeometryLocal = oldGeometry; + oldGeometry = currentGeometry; + while (i != end) { + // If this is a move, redraw the previous location + if (oldGeometryLocal != currentGeometry) { + (*i)->setDirty(oldGeometryLocal); + } + (*i)->setDirty(dirtyRegion); + ++i; + } +} + +void QFbWindowSurface::resize(const QSize &size) +{ + // change the widget's QImage if this is a resize + if (mImage.size() != size) + mImage = QImage(size, mScreen->format()); + QWindowSurface::resize(size); +} + +void QFbWindow::setGeometry(const QRect &rect) +{ +// store previous geometry for screen update + oldGeometry = geometry(); + + + QList<QFbScreen *>::const_iterator i = mScreens.constBegin(); + QList<QFbScreen *>::const_iterator end = mScreens.constEnd(); + while (i != end) { + (*i)->invalidateRectCache(); + ++i; + } +//### QWindowSystemInterface::handleGeometryChange(window(), rect); + + QPlatformWindow::setGeometry(rect); +} + +bool QFbWindowSurface::scroll(const QRegion &area, int dx, int dy) +{ + return QWindowSurface::scroll(area, dx, dy); +} + +void QFbWindowSurface::beginPaint(const QRegion ®ion) +{ + Q_UNUSED(region); +} + +void QFbWindowSurface::endPaint(const QRegion ®ion) +{ + Q_UNUSED(region); +} + +void QFbWindow::setVisible(bool visible) +{ + visibleFlag = visible; + QList<QFbScreen *>::const_iterator i = mScreens.constBegin(); + QList<QFbScreen *>::const_iterator end = mScreens.constEnd(); + while (i != end) { + (*i)->invalidateRectCache(); + (*i)->setDirty(geometry()); + ++i; + } +} + +Qt::WindowFlags QFbWindow::setWindowFlags(Qt::WindowFlags type) +{ + flags = type; + QList<QFbScreen *>::const_iterator i = mScreens.constBegin(); + QList<QFbScreen *>::const_iterator end = mScreens.constEnd(); + while (i != end) { + (*i)->invalidateRectCache(); + ++i; + } + return flags; +} + +Qt::WindowFlags QFbWindow::windowFlags() const +{ + return flags; +} diff --git a/src/platformsupport/fb_base/fb_base.pri b/src/platformsupport/fb_base/fb_base.pri new file mode 100644 index 0000000000..e80125d54e --- /dev/null +++ b/src/platformsupport/fb_base/fb_base.pri @@ -0,0 +1,4 @@ +do_not_compile_untill_ported_to_qt5 { + SOURCES += $$PWD/fb_base.cpp + HEADERS += $$PWD/fb_base_p.h +} diff --git a/src/platformsupport/fb_base/fb_base_p.h b/src/platformsupport/fb_base/fb_base_p.h new file mode 100644 index 0000000000..6b0b152482 --- /dev/null +++ b/src/platformsupport/fb_base/fb_base_p.h @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QLIGHTHOUSEGRAPHICSSCREEN_H +#define QLIGHTHOUSEGRAPHICSSCREEN_H + +#include <qrect.h> +#include <qimage.h> +#include <qtimer.h> +#include <qpainter.h> +#include <QPlatformCursor> +#include <QPlatformScreen> +#include <QPlatformWindow> +#include <QtGui/private/qwindowsurface_p.h> + +class QMouseEvent; +class QSize; +class QPainter; + +class QFbScreen; + +class QPlatformSoftwareCursor : public QPlatformCursor +{ +public: + QPlatformSoftwareCursor(QPlatformScreen * scr); + + // output methods + QRect dirtyRect(); + virtual QRect drawCursor(QPainter & painter); + + // input methods + virtual void pointerEvent(const QMouseEvent & event); + virtual void changeCursor(QCursor * widgetCursor, QWidget * widget); + + virtual void setDirty() { dirty = true; screen->setDirty(QRect()); } + virtual bool isDirty() { return dirty; } + virtual bool isOnScreen() { return onScreen; } + virtual QRect lastPainted() { return prevRect; } + +protected: + QPlatformCursorImage * graphic; + +private: + void setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY); + void setCursor(Qt::CursorShape shape); + void setCursor(const QImage &image, int hotx, int hoty); + QRect currentRect; // next place to draw the cursor + QRect prevRect; // last place the cursor was drawn + QRect getCurrentRect(); + bool dirty; + bool onScreen; +}; + +class QFbWindow; + +class QFbWindowSurface : public QWindowSurface +{ +public: + QFbWindowSurface(QFbScreen *screen, QWidget *window); + ~QFbWindowSurface(); + + virtual QPaintDevice *paintDevice() { return &mImage; } + virtual void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + virtual bool scroll(const QRegion &area, int dx, int dy); + + virtual void beginPaint(const QRegion ®ion); + virtual void endPaint(const QRegion ®ion); + + + const QImage image() { return mImage; } + void resize(const QSize &size); + +protected: + friend class QFbWindow; + QFbWindow *platformWindow; + + QFbScreen *mScreen; + QImage mImage; +}; + + +class QFbWindow : public QPlatformWindow +{ +public: + + QFbWindow(QWidget *window); + ~QFbWindow(); + + + virtual void setVisible(bool visible); + virtual bool visible() { return visibleFlag; } + + virtual void raise(); + virtual void lower(); + + void setGeometry(const QRect &rect); + + virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags type); + virtual Qt::WindowFlags windowFlags() const; + + WId winId() const { return windowId; } + + virtual void repaint(const QRegion&); + +protected: + friend class QFbWindowSurface; + friend class QFbScreen; + QFbWindowSurface *surface; + QList<QFbScreen *> mScreens; + QRect oldGeometry; + bool visibleFlag; + Qt::WindowFlags flags; + + WId windowId; +}; + +class QFbScreen : public QPlatformScreen +{ + Q_OBJECT +public: + QFbScreen(); + ~QFbScreen(); + + virtual QRect geometry() const { return mGeometry; } + virtual int depth() const { return mDepth; } + virtual QImage::Format format() const { return mFormat; } + virtual QSize physicalSize() const { return mPhysicalSize; } + + virtual void setGeometry(QRect rect); + virtual void setDepth(int depth); + virtual void setFormat(QImage::Format format); + virtual void setPhysicalSize(QSize size); + + virtual void setDirty(const QRect &rect); + + virtual void removeWindow(QFbWindow * surface); + virtual void addWindow(QFbWindow * surface); + virtual void raise(QPlatformWindow * surface); + virtual void lower(QPlatformWindow * surface); + virtual QWidget * topLevelAt(const QPoint & p) const; + + QImage * image() const { return mScreenImage; } + QPaintDevice * paintDevice() const { return mScreenImage; } + +protected: + QList<QFbWindow *> windowStack; + QRegion repaintRegion; + QPlatformSoftwareCursor * cursor; + QTimer redrawTimer; + +protected slots: + virtual QRegion doRedraw(); + +protected: + QRect mGeometry; + int mDepth; + QImage::Format mFormat; + QSize mPhysicalSize; + QImage *mScreenImage; + +private: + QPainter * compositePainter; + void generateRects(); + QList<QPair<QRect, int> > cachedRects; + + void invalidateRectCache() { isUpToDate = false; } + friend class QFbWindowSurface; + friend class QFbWindow; + bool isUpToDate; +}; + +#endif // QLIGHTHOUSEGRAPHICSSCREEN_H diff --git a/src/platformsupport/fontdatabases/basicunix/basicunix.pri b/src/platformsupport/fontdatabases/basicunix/basicunix.pri new file mode 100644 index 0000000000..f83b89063b --- /dev/null +++ b/src/platformsupport/fontdatabases/basicunix/basicunix.pri @@ -0,0 +1,84 @@ +DEFINES += QT_NO_FONTCONFIG +QT += gui-private core-private + +HEADERS += \ + $$PWD/qbasicunixfontdatabase_p.h \ + $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h + +SOURCES += \ + $$PWD/qbasicunixfontdatabase.cpp \ + $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp + +CONFIG += opentype + +contains(QT_CONFIG, freetype) { + QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype + SOURCES += \ + $$QT_FREETYPE_DIR/src/base/ftbase.c \ + $$QT_FREETYPE_DIR/src/base/ftbbox.c \ + $$QT_FREETYPE_DIR/src/base/ftdebug.c \ + $$QT_FREETYPE_DIR/src/base/ftglyph.c \ + $$QT_FREETYPE_DIR/src/base/ftinit.c \ + $$QT_FREETYPE_DIR/src/base/ftmm.c \ + $$QT_FREETYPE_DIR/src/base/fttype1.c \ + $$QT_FREETYPE_DIR/src/base/ftsynth.c \ + $$QT_FREETYPE_DIR/src/base/ftbitmap.c \ + $$QT_FREETYPE_DIR/src/bdf/bdf.c \ + $$QT_FREETYPE_DIR/src/cache/ftcache.c \ + $$QT_FREETYPE_DIR/src/cff/cff.c \ + $$QT_FREETYPE_DIR/src/cid/type1cid.c \ + $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \ + $$QT_FREETYPE_DIR/src/pcf/pcf.c \ + $$QT_FREETYPE_DIR/src/pfr/pfr.c \ + $$QT_FREETYPE_DIR/src/psaux/psaux.c \ + $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \ + $$QT_FREETYPE_DIR/src/psnames/psmodule.c \ + $$QT_FREETYPE_DIR/src/raster/raster.c \ + $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \ + $$QT_FREETYPE_DIR/src/smooth/smooth.c \ + $$QT_FREETYPE_DIR/src/truetype/truetype.c \ + $$QT_FREETYPE_DIR/src/type1/type1.c \ + $$QT_FREETYPE_DIR/src/type42/type42.c \ + $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \ + $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\ + $$QT_FREETYPE_DIR/src/autofit/afangles.c\ + $$QT_FREETYPE_DIR/src/autofit/afglobal.c\ + $$QT_FREETYPE_DIR/src/autofit/aflatin.c\ + $$QT_FREETYPE_DIR/src/autofit/afmodule.c\ + $$QT_FREETYPE_DIR/src/autofit/afdummy.c\ + $$QT_FREETYPE_DIR/src/autofit/afhints.c\ + $$QT_FREETYPE_DIR/src/autofit/afloader.c\ + $$QT_FREETYPE_DIR/src/autofit/autofit.c + + symbian { + SOURCES += \ + $$QT_FREETYPE_DIR/src/base/ftsystem.c + } else { + SOURCES += \ + $$QT_FREETYPE_DIR/builds/unix/ftsystem.c + INCLUDEPATH += \ + $$QT_FREETYPE_DIR/builds/unix + } + + INCLUDEPATH += \ + $$QT_FREETYPE_DIR/src \ + $$QT_FREETYPE_DIR/include + + DEFINES += FT2_BUILD_LIBRARY + contains(QT_CONFIG, system-zlib) { + DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB + } + +} else:contains(QT_CONFIG, system-freetype) { + # pull in the proper freetype2 include directory + include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri) +} + diff --git a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp new file mode 100644 index 0000000000..1b0966d4b8 --- /dev/null +++ b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp @@ -0,0 +1,328 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbasicunixfontdatabase_p.h" + +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/QPlatformScreen> + +#include <QtCore/QFile> +#include <QtCore/QLibraryInfo> +#include <QtCore/QDir> + +#undef QT_NO_FREETYPE +#include <QtGui/private/qfontengine_ft_p.h> +#include <QtGui/private/qfontengine_p.h> + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H + +#define SimplifiedChineseCsbBit 18 +#define TraditionalChineseCsbBit 20 +#define JapaneseCsbBit 17 +#define KoreanCsbBit 21 + +static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { + // Any, + { 127, 127 }, + // Latin, + { 0, 127 }, + // Greek, + { 7, 127 }, + // Cyrillic, + { 9, 127 }, + // Armenian, + { 10, 127 }, + // Hebrew, + { 11, 127 }, + // Arabic, + { 13, 127 }, + // Syriac, + { 71, 127 }, + //Thaana, + { 72, 127 }, + //Devanagari, + { 15, 127 }, + //Bengali, + { 16, 127 }, + //Gurmukhi, + { 17, 127 }, + //Gujarati, + { 18, 127 }, + //Oriya, + { 19, 127 }, + //Tamil, + { 20, 127 }, + //Telugu, + { 21, 127 }, + //Kannada, + { 22, 127 }, + //Malayalam, + { 23, 127 }, + //Sinhala, + { 73, 127 }, + //Thai, + { 24, 127 }, + //Lao, + { 25, 127 }, + //Tibetan, + { 70, 127 }, + //Myanmar, + { 74, 127 }, + // Georgian, + { 26, 127 }, + // Khmer, + { 80, 127 }, + // SimplifiedChinese, + { 126, 127 }, + // TraditionalChinese, + { 126, 127 }, + // Japanese, + { 126, 127 }, + // Korean, + { 56, 127 }, + // Vietnamese, + { 0, 127 }, // same as latin1 + // Other, + { 126, 127 }, + // Ogham, + { 78, 127 }, + // Runic, + { 79, 127 }, + // Nko, + { 14, 127 }, +}; + +static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2]) +{ + QSupportedWritingSystems writingSystems; + bool hasScript = false; + + int i; + for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) { + int bit = requiredUnicodeBits[i][0]; + int index = bit/32; + int flag = 1 << (bit&31); + if (bit != 126 && unicodeRange[index] & flag) { + bit = requiredUnicodeBits[i][1]; + index = bit/32; + + flag = 1 << (bit&31); + if (bit == 127 || unicodeRange[index] & flag) { + writingSystems.setSupported(QFontDatabase::WritingSystem(i)); + hasScript = true; + // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i); + } + } + } + if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) { + writingSystems.setSupported(QFontDatabase::SimplifiedChinese); + hasScript = true; + //qDebug("font %s supports Simplified Chinese", familyName.latin1()); + } + if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) { + writingSystems.setSupported(QFontDatabase::TraditionalChinese); + hasScript = true; + //qDebug("font %s supports Traditional Chinese", familyName.latin1()); + } + if(codePageRange[0] & (1 << JapaneseCsbBit)) { + writingSystems.setSupported(QFontDatabase::Japanese); + hasScript = true; + //qDebug("font %s supports Japanese", familyName.latin1()); + } + if(codePageRange[0] & (1 << KoreanCsbBit)) { + writingSystems.setSupported(QFontDatabase::Korean); + hasScript = true; + //qDebug("font %s supports Korean", familyName.latin1()); + } + if (!hasScript) + writingSystems.setSupported(QFontDatabase::Symbol); + + return writingSystems; +} + +static inline bool scriptRequiresOpenType(int script) +{ + return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala) + || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko); +} + +void QBasicUnixFontDatabase::populateFontDatabase() +{ + QPlatformFontDatabase::populateFontDatabase(); + QString fontpath = fontDir(); + + if(!QFile::exists(fontpath)) { + qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?", + qPrintable(fontpath)); + } + + QDir dir(fontpath); + dir.setNameFilters(QStringList() << QLatin1String("*.ttf") + << QLatin1String("*.ttc") << QLatin1String("*.pfa") + << QLatin1String("*.pfb")); + dir.refresh(); + for (int i = 0; i < int(dir.count()); ++i) { + const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i])); +// qDebug() << "looking at" << file; + addTTFile(QByteArray(), file); + } +} + +QFontEngine *QBasicUnixFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *usrPtr) +{ + QFontEngineFT *engine; + FontFile *fontfile = static_cast<FontFile *> (usrPtr); + QFontEngine::FaceId fid; + fid.filename = fontfile->fileName.toLocal8Bit(); + fid.index = fontfile->indexValue; + engine = new QFontEngineFT(fontDef); + + bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); + QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono; + if (!engine->init(fid,antialias,format)) { + delete engine; + engine = 0; + return engine; + } + if (engine->invalid()) { + delete engine; + engine = 0; + } else if (scriptRequiresOpenType(script)) { + HB_Face hbFace = engine->harfbuzzFace(); + if (!hbFace || !hbFace->supported_scripts[script]) { + delete engine; + engine = 0; + } + } + + return engine; +} + +QStringList QBasicUnixFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const +{ + Q_UNUSED(family); + Q_UNUSED(style); + Q_UNUSED(script); + return QStringList(); +} + +QStringList QBasicUnixFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) +{ + return addTTFile(fontData,fileName.toLocal8Bit()); +} + +void QBasicUnixFontDatabase::releaseHandle(void *handle) +{ + FontFile *file = static_cast<FontFile *>(handle); + delete file; +} + +QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file) +{ + extern FT_Library qt_getFreetype(); + FT_Library library = qt_getFreetype(); + + int index = 0; + int numFaces = 0; + QStringList families; + do { + FT_Face face; + FT_Error error; + if (!fontData.isEmpty()) { + error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face); + } else { + error = FT_New_Face(library, file.constData(), index, &face); + } + if (error != FT_Err_Ok) { + qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error; + break; + } + numFaces = face->num_faces; + + QFont::Weight weight = QFont::Normal; + + QFont::Style style = QFont::StyleNormal; + if (face->style_flags & FT_STYLE_FLAG_ITALIC) + style = QFont::StyleItalic; + + if (face->style_flags & FT_STYLE_FLAG_BOLD) + weight = QFont::Bold; + + QSupportedWritingSystems writingSystems; + // detect symbol fonts + for (int i = 0; i < face->num_charmaps; ++i) { + FT_CharMap cm = face->charmaps[i]; + if (cm->encoding == ft_encoding_adobe_custom + || cm->encoding == ft_encoding_symbol) { + writingSystems.setSupported(QFontDatabase::Symbol); + break; + } + } + + TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2); + if (os2) { + quint32 unicodeRange[4] = { + os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4 + }; + quint32 codePageRange[2] = { + os2->ulCodePageRange1, os2->ulCodePageRange2 + }; + + writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + } + + QString family = QString::fromAscii(face->family_name); + FontFile *fontFile = new FontFile; + fontFile->fileName = QString::fromAscii(file); + fontFile->indexValue = index; + + QFont::Stretch stretch = QFont::Unstretched; + + registerFont(family,QString(),weight,style,stretch,true,true,0,writingSystems,fontFile); + + families.append(family); + + FT_Done_Face(face); + ++index; + } while (index < numFaces); + return families; +} diff --git a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h new file mode 100644 index 0000000000..85b5cee733 --- /dev/null +++ b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBASICUNIXFONTDATABASE_H +#define QBASICUNIXFONTDATABASE_H + +#include <QPlatformFontDatabase> +#include <QtCore/QByteArray> +#include <QtCore/QString> + +struct FontFile +{ + QString fileName; + int indexValue; +}; + +#ifdef Q_OS_MAC +class Q_GUI_EXPORT QBasicUnixFontDatabase : public QPlatformFontDatabase +#else +class QBasicUnixFontDatabase : public QPlatformFontDatabase +#endif +{ +public: + void populateFontDatabase(); + QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle); + QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const; + QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); + void releaseHandle(void *handle); + + static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file); +}; + +#endif // QBASICUNIXFONTDATABASE_H diff --git a/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri new file mode 100644 index 0000000000..2efcb4d4dc --- /dev/null +++ b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri @@ -0,0 +1,2 @@ +HEADERS += $$PWD/qfontconfigdatabase_p.h +SOURCES += $$PWD/qfontconfigdatabase.cpp diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp new file mode 100644 index 0000000000..d506d7c0f8 --- /dev/null +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -0,0 +1,601 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfontconfigdatabase_p.h" + +#include <QtCore/QList> +#include <QtGui/private/qfont_p.h> + +#include <QtCore/QElapsedTimer> + +#include <QtGui/QPlatformScreen> + +#include <QtGui/private/qfontengine_ft_p.h> +#include <QtGui/private/qfontengine_p.h> + + + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H + +#include <fontconfig/fontconfig.h> + +#define SimplifiedChineseCsbBit 18 +#define TraditionalChineseCsbBit 20 +#define JapaneseCsbBit 17 +#define KoreanCsbBit 21 + +static inline bool requiresOpenType(int writingSystem) +{ + return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala) + || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko); +} +static inline bool scriptRequiresOpenType(int script) +{ + return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala) + || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko); +} + +static int getFCWeight(int fc_weight) +{ + int qtweight = QFont::Black; + if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2) + qtweight = QFont::Light; + else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2) + qtweight = QFont::Normal; + else if (fc_weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2) + qtweight = QFont::DemiBold; + else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2) + qtweight = QFont::Bold; + + return qtweight; +} + +static const char *specialLanguages[] = { + "en", // Common + "el", // Greek + "ru", // Cyrillic + "hy", // Armenian + "he", // Hebrew + "ar", // Arabic + "syr", // Syriac + "div", // Thaana + "hi", // Devanagari + "bn", // Bengali + "pa", // Gurmukhi + "gu", // Gujarati + "or", // Oriya + "ta", // Tamil + "te", // Telugu + "kn", // Kannada + "ml", // Malayalam + "si", // Sinhala + "th", // Thai + "lo", // Lao + "bo", // Tibetan + "my", // Myanmar + "ka", // Georgian + "ko", // Hangul + "", // Ogham + "", // Runic + "km", // Khmer + "" // N'Ko +}; +enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) }; + +static const ushort specialChars[] = { + 0, // English + 0, // Greek + 0, // Cyrillic + 0, // Armenian + 0, // Hebrew + 0, // Arabic + 0, // Syriac + 0, // Thaana + 0, // Devanagari + 0, // Bengali + 0, // Gurmukhi + 0, // Gujarati + 0, // Oriya + 0, // Tamil + 0xc15, // Telugu + 0xc95, // Kannada + 0xd15, // Malayalam + 0xd9a, // Sinhala + 0, // Thai + 0, // Lao + 0, // Tibetan + 0x1000, // Myanmar + 0, // Georgian + 0, // Hangul + 0x1681, // Ogham + 0x16a0, // Runic + 0, // Khmer + 0x7ca // N'Ko +}; +enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) }; + +// this could become a list of all languages used for each writing +// system, instead of using the single most common language. +static const char *languageForWritingSystem[] = { + 0, // Any + "en", // Latin + "el", // Greek + "ru", // Cyrillic + "hy", // Armenian + "he", // Hebrew + "ar", // Arabic + "syr", // Syriac + "div", // Thaana + "hi", // Devanagari + "bn", // Bengali + "pa", // Gurmukhi + "gu", // Gujarati + "or", // Oriya + "ta", // Tamil + "te", // Telugu + "kn", // Kannada + "ml", // Malayalam + "si", // Sinhala + "th", // Thai + "lo", // Lao + "bo", // Tibetan + "my", // Myanmar + "ka", // Georgian + "km", // Khmer + "zh-cn", // SimplifiedChinese + "zh-tw", // TraditionalChinese + "ja", // Japanese + "ko", // Korean + "vi", // Vietnamese + 0, // Symbol + 0, // Ogham + 0, // Runic + 0 // N'Ko +}; +enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) }; + +// Unfortunately FontConfig doesn't know about some languages. We have to test these through the +// charset. The lists below contain the systems where we need to do this. +static const ushort sampleCharForWritingSystem[] = { + 0, // Any + 0, // Latin + 0, // Greek + 0, // Cyrillic + 0, // Armenian + 0, // Hebrew + 0, // Arabic + 0, // Syriac + 0, // Thaana + 0, // Devanagari + 0, // Bengali + 0, // Gurmukhi + 0, // Gujarati + 0, // Oriya + 0, // Tamil + 0xc15, // Telugu + 0xc95, // Kannada + 0xd15, // Malayalam + 0xd9a, // Sinhala + 0, // Thai + 0, // Lao + 0, // Tibetan + 0x1000, // Myanmar + 0, // Georgian + 0, // Khmer + 0, // SimplifiedChinese + 0, // TraditionalChinese + 0, // Japanese + 0, // Korean + 0, // Vietnamese + 0, // Symbol + 0x1681, // Ogham + 0x16a0, // Runic + 0x7ca // N'Ko +}; +enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) }; + +// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no +// open type tables for is directly. Do this so we don't pick some strange +// pseudo unicode font +static const char *openType[] = { + 0, // Any + 0, // Latin + 0, // Greek + 0, // Cyrillic + 0, // Armenian + 0, // Hebrew + 0, // Arabic + "syrc", // Syriac + "thaa", // Thaana + "deva", // Devanagari + "beng", // Bengali + "guru", // Gurmukhi + "gurj", // Gujarati + "orya", // Oriya + "taml", // Tamil + "telu", // Telugu + "knda", // Kannada + "mlym", // Malayalam + "sinh", // Sinhala + 0, // Thai + 0, // Lao + "tibt", // Tibetan + "mymr", // Myanmar + 0, // Georgian + "khmr", // Khmer + 0, // SimplifiedChinese + 0, // TraditionalChinese + 0, // Japanese + 0, // Korean + 0, // Vietnamese + 0, // Symbol + 0, // Ogham + 0, // Runic + "nko " // N'Ko +}; + +static const char *getFcFamilyForStyleHint(const QFont::StyleHint style) +{ + const char *stylehint = 0; + switch (style) { + case QFont::SansSerif: + stylehint = "sans-serif"; + break; + case QFont::Serif: + stylehint = "serif"; + break; + case QFont::TypeWriter: + stylehint = "monospace"; + break; + default: + break; + } + return stylehint; +} + +void QFontconfigDatabase::populateFontDatabase() +{ + FcFontSet *fonts; + + QString familyName; + FcChar8 *value = 0; + int weight_value; + int slant_value; + int spacing_value; + FcChar8 *file_value; + int indexValue; + FcChar8 *foundry_value; + FcBool scalable; + FcBool antialias; + + { + FcObjectSet *os = FcObjectSetCreate(); + FcPattern *pattern = FcPatternCreate(); + const char *properties [] = { + FC_FAMILY, FC_WEIGHT, FC_SLANT, + FC_SPACING, FC_FILE, FC_INDEX, + FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT, + FC_WIDTH, +#if FC_VERSION >= 20297 + FC_CAPABILITY, +#endif + (const char *)0 + }; + const char **p = properties; + while (*p) { + FcObjectSetAdd(os, *p); + ++p; + } + fonts = FcFontList(0, pattern, os); + FcObjectSetDestroy(os); + FcPatternDestroy(pattern); + } + + for (int i = 0; i < fonts->nfont; i++) { + if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch) + continue; + // capitalize(value); + familyName = QString::fromUtf8((const char *)value); + slant_value = FC_SLANT_ROMAN; + weight_value = FC_WEIGHT_MEDIUM; + spacing_value = FC_PROPORTIONAL; + file_value = 0; + indexValue = 0; + scalable = FcTrue; + + + if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch) + slant_value = FC_SLANT_ROMAN; + if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch) + weight_value = FC_WEIGHT_MEDIUM; + if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch) + spacing_value = FC_PROPORTIONAL; + if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch) + file_value = 0; + if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch) + indexValue = 0; + if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch) + scalable = FcTrue; + if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch) + foundry_value = 0; + if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch) + antialias = true; + + QSupportedWritingSystems writingSystems; + FcLangSet *langset = 0; + FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset); + if (res == FcResultMatch) { + for (int i = 1; i < LanguageCount; ++i) { + const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[i]; + if (lang) { + FcLangResult langRes = FcLangSetHasLang(langset, lang); + if (langRes != FcLangDifferentLang) + writingSystems.setSupported(QFontDatabase::WritingSystem(i)); + } + } + } else { + // we set Other to supported for symbol fonts. It makes no + // sense to merge these with other ones, as they are + // special in a way. + writingSystems.setSupported(QFontDatabase::Other); + } + + FcCharSet *cs = 0; + res = FcPatternGetCharSet(fonts->fonts[i], FC_CHARSET, 0, &cs); + if (res == FcResultMatch) { + // some languages are not supported by FontConfig, we rather check the + // charset to detect these + for (int i = 1; i < SampleCharCount; ++i) { + if (!sampleCharForWritingSystem[i]) + continue; + if (FcCharSetHasChar(cs, sampleCharForWritingSystem[i])) + writingSystems.setSupported(QFontDatabase::WritingSystem(i)); + } + } + +#if FC_VERSION >= 20297 + for (int j = 1; j < LanguageCount; ++j) { + if (writingSystems.supported(QFontDatabase::WritingSystem(j)) + && requiresOpenType(j) && openType[j]) { + FcChar8 *cap; + res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap); + if (res != FcResultMatch || !strstr((const char *)cap, openType[j])) + writingSystems.setSupported(QFontDatabase::WritingSystem(j),false); + } + } +#endif + + FontFile *fontFile = new FontFile; + fontFile->fileName = QLatin1String((const char *)file_value); + fontFile->indexValue = indexValue; + + QFont::Style style = (slant_value == FC_SLANT_ITALIC) + ? QFont::StyleItalic + : ((slant_value == FC_SLANT_OBLIQUE) + ? QFont::StyleOblique + : QFont::StyleNormal); + QFont::Weight weight = QFont::Weight(getFCWeight(weight_value)); + + double pixel_size = 0; + if (!scalable) { + int width = 100; + FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width); + FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size); + } + + QFont::Stretch stretch = QFont::Unstretched; + QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,writingSystems,fontFile); +// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size; + } + + FcFontSetDestroy (fonts); + + struct FcDefaultFont { + const char *qtname; + const char *rawname; + bool fixed; + }; + const FcDefaultFont defaults[] = { + { "Serif", "serif", false }, + { "Sans Serif", "sans-serif", false }, + { "Monospace", "monospace", true }, + { 0, 0, false } + }; + const FcDefaultFont *f = defaults; + // aliases only make sense for 'common', not for any of the specials + QSupportedWritingSystems ws; + ws.setSupported(QFontDatabase::Latin); + + + QString familyQtName = QString::fromLatin1(f->qtname); + while (f->qtname) { + registerFont(familyQtName,QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,ws,0); + registerFont(familyQtName,QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,ws,0); + registerFont(familyQtName,QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,ws,0); + ++f; + } + + //Lighthouse has very lazy population of the font db. We want it to be initialized when + //QApplication is constructed, so that the population procedure can do something like this to + //set the default font +// const FcDefaultFont *s = defaults; +// QFont font("Sans Serif"); +// font.setPointSize(9); +// QApplication::setFont(font); +} + +QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr) +{ + if (!usrPtr) + return 0; + QFontDef fontDef = f; + + QFontEngineFT *engine; + FontFile *fontfile = static_cast<FontFile *> (usrPtr); + QFontEngine::FaceId fid; + fid.filename = fontfile->fileName.toLocal8Bit(); + fid.index = fontfile->indexValue; + + //try and get the pattern + FcPattern *pattern = FcPatternCreate(); + + bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); + QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono; + + engine = new QFontEngineFT(fontDef); + + FcValue value; + value.type = FcTypeString; + QByteArray cs = fontDef.family.toUtf8(); + value.u.s = (const FcChar8 *)cs.data(); + FcPatternAdd(pattern,FC_FAMILY,value,true); + + + value.u.s = (const FcChar8 *)fid.filename.data(); + FcPatternAdd(pattern,FC_FILE,value,true); + + value.type = FcTypeInteger; + value.u.i = fid.index; + FcPatternAdd(pattern,FC_INDEX,value,true); + + QFontEngineFT::HintStyle default_hint_style; + + if (FcConfigSubstitute(0,pattern,FcMatchPattern)) { + + //hinting + int hint_style = 0; + if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch) + hint_style = QFontEngineFT::HintFull; + switch (hint_style) { + case FC_HINT_NONE: + default_hint_style = QFontEngineFT::HintNone; + break; + case FC_HINT_SLIGHT: + default_hint_style = QFontEngineFT::HintLight; + break; + case FC_HINT_MEDIUM: + default_hint_style = QFontEngineFT::HintMedium; + break; + default: + default_hint_style = QFontEngineFT::HintFull; + break; + } + } + + engine->setDefaultHintStyle(default_hint_style); + if (!engine->init(fid,antialias,format)) { + delete engine; + engine = 0; + return engine; + } + if (engine->invalid()) { + delete engine; + engine = 0; + } else if (scriptRequiresOpenType(script)) { + HB_Face hbFace = engine->harfbuzzFace(); + if (!hbFace || !hbFace->supported_scripts[script]) { + delete engine; + engine = 0; + } + } + + return engine; +} + +QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const +{ + QStringList fallbackFamilies; + FcPattern *pattern = FcPatternCreate(); + if (!pattern) + return fallbackFamilies; + + FcValue value; + value.type = FcTypeString; + QByteArray cs = family.toUtf8(); + value.u.s = (const FcChar8 *)cs.data(); + FcPatternAdd(pattern,FC_FAMILY,value,true); + + int slant_value = FC_SLANT_ROMAN; + if (style == QFont::StyleItalic) + slant_value = FC_SLANT_ITALIC; + else if (style == QFont::StyleOblique) + slant_value = FC_SLANT_OBLIQUE; + FcPatternAddInteger(pattern, FC_SLANT, slant_value); + + if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') { + Q_ASSERT(script < QUnicodeTables::ScriptCount); + FcLangSet *ls = FcLangSetCreate(); + FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]); + FcPatternAddLangSet(pattern, FC_LANG, ls); + FcLangSetDestroy(ls); + } + + const char *stylehint = getFcFamilyForStyleHint(styleHint); + if (stylehint) { + value.u.s = (const FcChar8 *)stylehint; + FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue); + } + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcConfigSubstitute(0, pattern, FcMatchFont); + + FcResult result = FcResultMatch; + FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result); + + if (fontSet && result == FcResultMatch) + { + for (int i = 0; i < fontSet->nfont; i++) { + FcChar8 *value = 0; + if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch) + continue; + // capitalize(value); + QString familyName = QString::fromUtf8((const char *)value); + if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive)) { + fallbackFamilies << familyName; + } + + } + } +// qDebug() << "fallbackFamilies for:" << family << fallbackFamilies; + + return fallbackFamilies; +} diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h new file mode 100644 index 0000000000..5a5e4b670f --- /dev/null +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFONTCONFIGDATABASE_H +#define QFONTCONFIGDATABASE_H + +#include <QPlatformFontDatabase> +#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h> + +class QFontconfigDatabase : public QBasicUnixFontDatabase +{ +public: + void populateFontDatabase(); + QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle); + QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const; +}; + +#endif // QFONTCONFIGDATABASE_H diff --git a/src/platformsupport/fontdatabases/fontdatabases.pri b/src/platformsupport/fontdatabases/fontdatabases.pri new file mode 100644 index 0000000000..0e282d97dd --- /dev/null +++ b/src/platformsupport/fontdatabases/fontdatabases.pri @@ -0,0 +1,10 @@ +DEFINES += QT_COMPILES_IN_HARFBUZZ +INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src + +unix { + include($$PWD/basicunix/basicunix.pri) + include($$PWD/genericunix/genericunix.pri) + contains(QT_CONFIG,fontconfig) { + include($$PWD/fontconfig/fontconfig.pri) + } +} diff --git a/src/platformsupport/fontdatabases/genericunix/genericunix.pri b/src/platformsupport/fontdatabases/genericunix/genericunix.pri new file mode 100644 index 0000000000..e9db6c07e2 --- /dev/null +++ b/src/platformsupport/fontdatabases/genericunix/genericunix.pri @@ -0,0 +1 @@ +HEADERS += $$PWD/qgenericunixfontdatabase_p.h diff --git a/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h b/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h new file mode 100644 index 0000000000..721bccd585 --- /dev/null +++ b/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGENERICUNIXFONTDATABASE_H +#define QGENERICUNIXFONTDATABASE_H + +#ifdef Q_FONTCONFIGDATABASE +#include "QtPlatformSupport/private/qfontconfigdatabase_p.h" +typedef QFontconfigDatabase QGenericUnixFontDatabase; +#else +#include "QtPlatformSupport/private/qbasicunixfontdatabase_p.h" +typedef QBasicUnixFontDatabase QGenericUnixFontDatabase; +#endif //Q_FONTCONFIGDATABASE + +#endif // QGENERICUNIXFONTDATABASE_H diff --git a/src/platformsupport/glxconvenience/glxconvenience.pri b/src/platformsupport/glxconvenience/glxconvenience.pri new file mode 100644 index 0000000000..5b65e13306 --- /dev/null +++ b/src/platformsupport/glxconvenience/glxconvenience.pri @@ -0,0 +1,6 @@ +contains(QT_CONFIG,xlib) { + contains(QT_CONFIG,opengl):!contains(QT_CONFIG,opengles2) { + HEADERS += $$PWD/qglxconvenience_p.h + SOURCES += $$PWD/qglxconvenience.cpp + } +} diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp new file mode 100644 index 0000000000..ce0c49d93f --- /dev/null +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qglxconvenience_p.h" + +#include <QtCore/QVector> + +#ifndef QT_NO_XRENDER +#include <X11/extensions/Xrender.h> +#endif + +enum { + XFocusOut = FocusOut, + XFocusIn = FocusIn, + XKeyPress = KeyPress, + XKeyRelease = KeyRelease, + XNone = None, + XRevertToParent = RevertToParent, + XGrayScale = GrayScale, + XCursorShape = CursorShape +}; +#undef FocusOut +#undef FocusIn +#undef KeyPress +#undef KeyRelease +#undef None +#undef RevertToParent +#undef GrayScale +#undef CursorShape + +#ifdef FontChange +#undef FontChange +#endif + +QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit) +{ + QVector<int> spec(48); + int i = 0; + + spec[i++] = GLX_LEVEL; + spec[i++] = 0; + spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = drawableBit; + + spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT; + + spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize(); + spec[i++] = GLX_GREEN_SIZE; spec[i++] = (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize(); + spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize(); + if (format.hasAlpha()) { + spec[i++] = GLX_ALPHA_SIZE; spec[i++] = format.alphaBufferSize(); + } + + spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.swapBehavior() != QSurfaceFormat::SingleBuffer ? True : False; + + spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False; + + if (format.depthBufferSize() > 0) { + spec[i++] = GLX_DEPTH_SIZE; spec[i++] = format.depthBufferSize(); + } + + if (format.stencilBufferSize() > 0) { + spec[i++] = GLX_STENCIL_SIZE; spec[i++] = (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize(); + } + + if (format.samples() > 1) { + spec[i++] = GLX_SAMPLE_BUFFERS_ARB; + spec[i++] = 1; + spec[i++] = GLX_SAMPLES_ARB; + spec[i++] = format.samples(); + } + + spec[i++] = XNone; + return spec; +} + +GLXFBConfig qglx_findConfig(Display *display, int screen , const QSurfaceFormat &format, int drawableBit) +{ + bool reduced = true; + GLXFBConfig chosenConfig = 0; + QSurfaceFormat reducedFormat = format; + while (!chosenConfig && reduced) { + QVector<int> spec = qglx_buildSpec(reducedFormat, drawableBit); + int confcount = 0; + GLXFBConfig *configs; + configs = glXChooseFBConfig(display, screen,spec.constData(),&confcount); + if (confcount) + { + for (int i = 0; i < confcount; i++) { + chosenConfig = configs[i]; + // Make sure we try to get an ARGB visual if the format asked for an alpha: + if (reducedFormat.hasAlpha()) { + int alphaSize; + glXGetFBConfigAttrib(display,configs[i],GLX_ALPHA_SIZE,&alphaSize); + if (alphaSize > 0) { + XVisualInfo *visual = glXGetVisualFromFBConfig(display, chosenConfig); +#if !defined(QT_NO_XRENDER) + XRenderPictFormat *pictFormat = XRenderFindVisualFormat(display, visual->visual); + if (pictFormat->direct.alphaMask > 0) + break; +#else + if (visual->depth == 32) + break; +#endif + } + } else { + break; // Just choose the first in the list if there's no alpha requested + } + } + + XFree(configs); + } + reducedFormat = qglx_reduceSurfaceFormat(reducedFormat,&reduced); + } + + if (!chosenConfig) + qWarning("Warning: no suitable glx confiuration found"); + + return chosenConfig; +} + +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QSurfaceFormat &format) +{ + GLXFBConfig config = qglx_findConfig(display,screen,format); + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display,config); + return visualInfo; +} + +QSurfaceFormat qglx_surfaceFormatFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext) +{ + QSurfaceFormat format; + int redSize = 0; + int greenSize = 0; + int blueSize = 0; + int alphaSize = 0; + int depthSize = 0; + int stencilSize = 0; + int sampleBuffers = 0; + int sampleCount = 0; + int stereo = 0; + + XVisualInfo *vi = glXGetVisualFromFBConfig(display,config); + XFree(vi); + glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize); + glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize); + glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE, &blueSize); + glXGetFBConfigAttrib(display, config, GLX_ALPHA_SIZE, &alphaSize); + glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE, &depthSize); + glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize); + glXGetFBConfigAttrib(display, config, GLX_SAMPLES, &sampleBuffers); + glXGetFBConfigAttrib(display, config, GLX_STEREO, &stereo); + + format.setRedBufferSize(redSize); + format.setGreenBufferSize(greenSize); + format.setBlueBufferSize(blueSize); + format.setAlphaBufferSize(alphaSize); + format.setDepthBufferSize(depthSize); + format.setStencilBufferSize(stencilSize); + if (sampleBuffers) { + glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount); + format.setSamples(sampleCount); + } + + format.setStereo(stereo); + + return format; +} + +QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced) +{ + QSurfaceFormat retFormat = format; + *reduced = true; + + if (retFormat.samples() > 1) { + retFormat.setSamples(0); + } else if (retFormat.stereo()) { + retFormat.setStereo(false); + }else if (retFormat.stencilBufferSize() > 0) { + retFormat.setStencilBufferSize(0); + }else if (retFormat.hasAlpha()) { + retFormat.setAlphaBufferSize(0); + }else if (retFormat.depthBufferSize() > 0) { + retFormat.setDepthBufferSize(0); + }else{ + *reduced = false; + } + return retFormat; +} diff --git a/src/platformsupport/glxconvenience/qglxconvenience_p.h b/src/platformsupport/glxconvenience/qglxconvenience_p.h new file mode 100644 index 0000000000..4892b07729 --- /dev/null +++ b/src/platformsupport/glxconvenience/qglxconvenience_p.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGLXCONVENIENCE_H +#define QGLXCONVENIENCE_H + +#include <QSurfaceFormat> +#include <QVector> + +#include <X11/Xlib.h> +#include <GL/glx.h> + +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QSurfaceFormat &format); +GLXFBConfig qglx_findConfig(Display *display, int screen, const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT); +QSurfaceFormat qglx_surfaceFormatFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context); +QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT); +QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced); + +#endif // QGLXCONVENIENCE_H diff --git a/src/platformsupport/inputmethods/ibus/ibus.pri b/src/platformsupport/inputmethods/ibus/ibus.pri new file mode 100644 index 0000000000..c6e59aa484 --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/ibus.pri @@ -0,0 +1,11 @@ +QT += dbus + +SOURCES += $$PWD/qibusplatforminputcontext.cpp \ + $$PWD/qibusproxy.cpp \ + $$PWD/qibusinputcontextproxy.cpp \ + $$PWD/qibustypes.cpp + +HEADERS += $$PWD/qibusplatforminputcontext.h \ + $$PWD/qibusproxy.h \ + $$PWD/qibusinputcontextproxy.h \ + $$PWD/qibustypes.h diff --git a/src/platformsupport/inputmethods/ibus/interfaces/org.freedesktop.IBus.InputContext.xml b/src/platformsupport/inputmethods/ibus/interfaces/org.freedesktop.IBus.InputContext.xml new file mode 100644 index 0000000000..dbc79c178b --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/interfaces/org.freedesktop.IBus.InputContext.xml @@ -0,0 +1,80 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.freedesktop.IBus.InputContext"> + <method name="ProcessKeyEvent"> + <arg name="keyval" direction="in" type="u"/> + <arg name="keycode" direction="in" type="u"/> + <arg name="state" direction="in" type="u"/> + <arg name="handled" direction="out" type="b"/> + </method> + <method name="SetCursorLocation"> + <arg name="x" direction="in" type="i"/> + <arg name="y" direction="in" type="i"/> + <arg name="w" direction="in" type="i"/> + <arg name="h" direction="in" type="i"/> + </method> + <method name="FocusIn"/> + <method name="FocusOut"/> + <method name="Reset"/> + <method name="Enable"/> + <method name="Disable"/> + <method name="IsEnabled"> + <arg name="enable" direction="out" type="b"/> + </method> + <method name="SetCapabilities"> + <arg name="caps" direction="in" type="u"/> + </method> + <method name="PropertyActivate"> + <arg name="name" direction="in" type="s"/> + <arg name="state" direction="in" type="i"/> + </method> + <method name="SetEngine"> + <arg name="name" direction="in" type="s"/> + </method> + <method name="GetEngine"> + <arg name="desc" direction="out" type="v"/> + </method> + <method name="Destroy"/> + <signal name="CommitText"> + <arg name="text" type="v"/> + </signal> + <signal name="Enabled"/> + <signal name="Disabled"/> + <signal name="ForwardKeyEvent"> + <arg name="keyval" type="u"/> + <arg name="keycode" type="u"/> + <arg name="state" type="u"/> + </signal> + <signal name="UpdatePreeditText"> + <arg name="text" type="v"/> + <arg name="cursor_pos" type="u"/> + <arg name="visible" type="b"/> + </signal> + <signal name="ShowPreeditText"/> + <signal name="HidePreeditText"/> + <signal name="UpdateAuxiliaryText"> + <arg name="text" type="v"/> + <arg name="visible" type="b"/> + </signal> + <signal name="ShowAuxiliaryText"/> + <signal name="HideAuxiliaryText"/> + <signal name="UpdateLookupTable"> + <arg name="table" type="v"/> + <arg name="visible" type="b"/> + </signal> + <signal name="ShowLookupTable"/> + <signal name="HideLookupTable"/> + <signal name="PageUpLookupTable"/> + <signal name="PageDownLookupTable"/> + <signal name="CursorUpLookupTable"/> + <signal name="CursorDownLookupTable"/> + <signal name="RegisterProperties"> + <arg name="props" type="v"/> + </signal> + <signal name="UpdateProperty"> + <arg name="prop" type="v"/> + </signal> + </interface> +</node> + diff --git a/src/platformsupport/inputmethods/ibus/interfaces/org.freedesktop.IBus.xml b/src/platformsupport/inputmethods/ibus/interfaces/org.freedesktop.IBus.xml new file mode 100644 index 0000000000..6ac4891771 --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/interfaces/org.freedesktop.IBus.xml @@ -0,0 +1,30 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.freedesktop.IBus"> + <method name="GetAddress"> + <arg name="address" direction="out" type="s"/> + </method> + <method name="CreateInputContext"> + <arg name="name" direction="in" type="s"/> + <arg name="context" direction="out" type="o"/> + </method> + <method name="RegisterComponent"> + <arg name="components" direction="in" type="v"/> + </method> + <method name="ListEngines"> + <arg name="engines" direction="out" type="av"/> + </method> + <method name="ListActiveEngines"> + <arg name="engines" direction="out" type="av"/> + </method> + <method name="Exit"> + <arg name="restart" direction="in" type="b"/> + </method> + <method name="Ping"> + <arg name="data" direction="in" type="v"/> + <arg name="data" direction="out" type="v"/> + </method> + </interface> +</node> + diff --git a/src/platformsupport/inputmethods/ibus/qibusinputcontextproxy.cpp b/src/platformsupport/inputmethods/ibus/qibusinputcontextproxy.cpp new file mode 100644 index 0000000000..7adffbc2e2 --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/qibusinputcontextproxy.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -N -p qibusinputcontextproxy -c QIBusInputContextProxy interfaces/org.freedesktop.IBus.InputContext.xml + * + * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "qibusinputcontextproxy.h" + +/* + * Implementation of interface class QIBusInputContextProxy + */ + +QIBusInputContextProxy::QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +QIBusInputContextProxy::~QIBusInputContextProxy() +{ +} + diff --git a/src/platformsupport/inputmethods/ibus/qibusinputcontextproxy.h b/src/platformsupport/inputmethods/ibus/qibusinputcontextproxy.h new file mode 100644 index 0000000000..9a91c4e484 --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/qibusinputcontextproxy.h @@ -0,0 +1,144 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -N -p qibusinputcontextproxy -c QIBusInputContextProxy interfaces/org.freedesktop.IBus.InputContext.xml + * + * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef QIBUSINPUTCONTEXTPROXY_H_1308831153 +#define QIBUSINPUTCONTEXTPROXY_H_1308831153 + +#include <QtCore/QObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> +#include <QtDBus/QtDBus> + +/* + * Proxy class for interface org.freedesktop.IBus.InputContext + */ +class QIBusInputContextProxy: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.freedesktop.IBus.InputContext"; } + +public: + QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~QIBusInputContextProxy(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Destroy() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("Destroy"), argumentList); + } + + inline QDBusPendingReply<> Disable() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("Disable"), argumentList); + } + + inline QDBusPendingReply<> Enable() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("Enable"), argumentList); + } + + inline QDBusPendingReply<> FocusIn() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("FocusIn"), argumentList); + } + + inline QDBusPendingReply<> FocusOut() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("FocusOut"), argumentList); + } + + inline QDBusPendingReply<QDBusVariant> GetEngine() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("GetEngine"), argumentList); + } + + inline QDBusPendingReply<bool> IsEnabled() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("IsEnabled"), argumentList); + } + + inline QDBusPendingReply<bool> ProcessKeyEvent(uint keyval, uint keycode, uint state) + { + QList<QVariant> argumentList; + argumentList << QVariant::fromValue(keyval) << QVariant::fromValue(keycode) << QVariant::fromValue(state); + return asyncCallWithArgumentList(QLatin1String("ProcessKeyEvent"), argumentList); + } + + inline QDBusPendingReply<> PropertyActivate(const QString &name, int state) + { + QList<QVariant> argumentList; + argumentList << QVariant::fromValue(name) << QVariant::fromValue(state); + return asyncCallWithArgumentList(QLatin1String("PropertyActivate"), argumentList); + } + + inline QDBusPendingReply<> Reset() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("Reset"), argumentList); + } + + inline QDBusPendingReply<> SetCapabilities(uint caps) + { + QList<QVariant> argumentList; + argumentList << QVariant::fromValue(caps); + return asyncCallWithArgumentList(QLatin1String("SetCapabilities"), argumentList); + } + + inline QDBusPendingReply<> SetCursorLocation(int x, int y, int w, int h) + { + QList<QVariant> argumentList; + argumentList << QVariant::fromValue(x) << QVariant::fromValue(y) << QVariant::fromValue(w) << QVariant::fromValue(h); + return asyncCallWithArgumentList(QLatin1String("SetCursorLocation"), argumentList); + } + + inline QDBusPendingReply<> SetEngine(const QString &name) + { + QList<QVariant> argumentList; + argumentList << QVariant::fromValue(name); + return asyncCallWithArgumentList(QLatin1String("SetEngine"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void CommitText(const QDBusVariant &text); + void CursorDownLookupTable(); + void CursorUpLookupTable(); + void Disabled(); + void Enabled(); + void ForwardKeyEvent(uint keyval, uint keycode, uint state); + void HideAuxiliaryText(); + void HideLookupTable(); + void HidePreeditText(); + void PageDownLookupTable(); + void PageUpLookupTable(); + void RegisterProperties(const QDBusVariant &props); + void ShowAuxiliaryText(); + void ShowLookupTable(); + void ShowPreeditText(); + void UpdateAuxiliaryText(const QDBusVariant &text, bool visible); + void UpdateLookupTable(const QDBusVariant &table, bool visible); + void UpdatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible); + void UpdateProperty(const QDBusVariant &prop); +}; + +#endif diff --git a/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.cpp b/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.cpp new file mode 100644 index 0000000000..55c0c4b249 --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.cpp @@ -0,0 +1,303 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qibusplatforminputcontext.h" + +#include <QtDebug> +#include <QTextCharFormat> +#include <QGuiApplication> +#include <qevent.h> + +#include "qibusproxy.h" +#include "qibusinputcontextproxy.h" +#include "qibustypes.h" + +#include <sys/types.h> +#include <signal.h> + +#include <QtDBus> + +class QIBusPlatformInputContextPrivate +{ +public: + QIBusPlatformInputContextPrivate(); + ~QIBusPlatformInputContextPrivate() + { + delete context; + delete bus; + delete connection; + } + + static QDBusConnection *createConnection(); + + QDBusConnection *connection; + QIBusProxy *bus; + QIBusInputContextProxy *context; + + bool valid; +}; + + +QIBusPlatformInputContext::QIBusPlatformInputContext () + : d(new QIBusPlatformInputContextPrivate()) +{ + if (d->context) { + connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant))); + connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool))); + } +} + +QIBusPlatformInputContext::~QIBusPlatformInputContext (void) +{ + delete d; +} + +void QIBusPlatformInputContext::mouseHandler (int x, QMouseEvent *event) +{ + QPlatformInputContext::mouseHandler (x, event); + + if (!d->valid) + return; +} + +void QIBusPlatformInputContext::reset() +{ + QPlatformInputContext::reset(); + + if (!d->valid) + return; + + d->context->Reset(); +} + +void QIBusPlatformInputContext::update() +{ + QPlatformInputContext::update(); + + if (!d->valid) + return; + + QObject *o = focusObject(); + if (!o) + return; + + QInputMethodQueryEvent query(Qt::ImMicroFocus); + QGuiApplication::sendEvent(o, &query); + QRect r = query.value().toRect(); + if(r.isValid()) { + qDebug() << "mocroFocus" << r; + d->context->SetCursorLocation(r.x(), r.y(), r.width(), r.height()); + } +} + +void QIBusPlatformInputContext::setFocusObject(QObject *object) +{ + QPlatformInputContext::setFocusObject(object); + + if (!d->valid) + return; + + qDebug() << "setFocusObject" << object; + if (object) + d->context->FocusIn(); + else + d->context->FocusOut(); +} + + +void QIBusPlatformInputContext::commitText(const QDBusVariant &text) +{ + const QDBusArgument arg = text.variant().value<QDBusArgument>(); + + QIBusText t; + qDebug() << arg.currentSignature(); + t.fromDBusArgument(arg); + qDebug() << "commit text:" << t.text; + + QInputMethodEvent event; + event.setCommitString(t.text); + QCoreApplication::sendEvent(focusObject(), &event); +} + +void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint cursorPos, bool visible) +{ + const QDBusArgument arg = text.variant().value<QDBusArgument>(); + + QIBusText t; + t.fromDBusArgument(arg); + qDebug() << "preedit text:" << t.text; + + QList<QInputMethodEvent::Attribute> attributes = t.attributes.imAttributes(); + attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, visible ? 1 : 0, QVariant()); + + QInputMethodEvent event(t.text, attributes); + QCoreApplication::sendEvent(focusObject(), &event); +} + + +/* Kernel keycode -> X keycode table */ +static const unsigned int keycode_table[256] = { + 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 76, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 111, 221, 94, 95, 96, 211, 128, 127, 129, 208, 131, 126, + 108, 109, 112, 111, 113, 181, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, + 239, 160, 174, 176, 222, 157, 123, 110, 139, 134, 209, 210, 133, 115, 116, 117, + 232, 133, 134, 135, 140, 248, 191, 192, 122, 188, 245, 158, 161, 193, 223, 227, + 198, 199, 200, 147, 159, 151, 178, 201, 146, 203, 166, 236, 230, 235, 234, 233, + 163, 204, 253, 153, 162, 144, 164, 177, 152, 190, 208, 129, 130, 231, 209, 210, + 136, 220, 143, 246, 251, 137, 138, 182, 183, 184, 93, 184, 247, 132, 170, 219, + 249, 205, 207, 149, 150, 154, 155, 167, 168, 169, 171, 172, 173, 165, 175, 179, + 180, 0, 185, 186, 187, 118, 119, 120, 121, 229, 194, 195, 196, 197, 148, 202, + 101, 212, 237, 214, 215, 216, 217, 218, 228, 142, 213, 240, 241, 242, 243, 244, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +bool +QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state, bool press) +{ + if (!d->valid) + return false; + + if (!press) + return false; + + keycode -= 8; // ### + QDBusReply<bool> reply = d->context->ProcessKeyEvent(keyval, keycode, state); + +// qDebug() << "x11FilterEvent return" << reply.value(); + + return reply.value(); +} + +QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate() + : connection(createConnection()), + bus(0), + context(0), + valid(false) +{ + if (!connection || !connection->isConnected()) { + qDebug() << "not connected"; + return; + } + + bus = new QIBusProxy(QLatin1String("org.freedesktop.IBus"), + QLatin1String("/org/freedesktop/IBus"), + *connection); + if (!bus->isValid()) { + qDebug() << "invalid bus"; + return; + } + + QDBusReply<QDBusObjectPath> ic = bus->CreateInputContext(QLatin1String("QIBusInputContext")); + if (!ic.isValid()) { + qDebug() << "CreateInputContext failed"; + return; + } + + context = new QIBusInputContextProxy(QLatin1String("org.freedesktop.IBus"), ic.value().path(), *connection); + + if (!context->isValid()) { + qDebug() << "invalid input context"; + return; + } + + enum Capabilities { + IBUS_CAP_PREEDIT_TEXT = 1 << 0, + IBUS_CAP_AUXILIARY_TEXT = 1 << 1, + IBUS_CAP_LOOKUP_TABLE = 1 << 2, + IBUS_CAP_FOCUS = 1 << 3, + IBUS_CAP_PROPERTY = 1 << 4, + IBUS_CAP_SURROUNDING_TEXT = 1 << 5, + }; + context->SetCapabilities(IBUS_CAP_PREEDIT_TEXT|IBUS_CAP_FOCUS); + + qDebug() << ">>>> valid!"; + valid = true; +} + +QDBusConnection *QIBusPlatformInputContextPrivate::createConnection() +{ + QByteArray display(getenv("DISPLAY")); + QByteArray host = "unix"; + QByteArray displayNumber = "0"; + + int pos = display.indexOf(':'); + if (pos > 0) + host = display.left(pos); + ++pos; + int pos2 = display.indexOf('.', pos); + if (pos2 > 0) + displayNumber = display.mid(pos, pos2 - pos); + qDebug() << "host=" << host << "displayNumber" << displayNumber; + + QFile file(QDir::homePath() + QLatin1String("/.config/ibus/bus/") + + QLatin1String(QDBusConnection::localMachineId()) + + QLatin1Char('-') + QString::fromLocal8Bit(host) + QLatin1Char('-') + QString::fromLocal8Bit(displayNumber)); + + if (!file.exists()) { + qDebug() << "ibus config file does not exist"; + return 0; + } + + file.open(QFile::ReadOnly); + + QByteArray address; + int pid = -1; + + while (!file.atEnd()) { + QByteArray line = file.readLine().trimmed(); + if (line.startsWith('#')) + continue; + + if (line.startsWith("IBUS_ADDRESS=")) + address = line.mid(sizeof("IBUS_ADDRESS=") - 1); + if (line.startsWith("IBUS_DAEMON_PID=")) + pid = line.mid(sizeof("IBUS_DAEMON_PID=") - 1).toInt(); + } + + qDebug() << "IBUS_ADDRESS=" << address << "PID=" << pid; + if (address.isEmpty() || pid < 0 || kill(pid, 0) != 0) + return 0; + + return new QDBusConnection(QDBusConnection::connectToBus(QString::fromLatin1(address), QLatin1String("QIBusProxy"))); +} diff --git a/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.h b/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.h new file mode 100644 index 0000000000..6912fe4c20 --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QIBUSPLATFORMINPUTCONTEXT_H +#define QIBUSPLATFORMINPUTCONTEXT_H + +#include <QPlatformInputContext> + +class QIBusPlatformInputContextPrivate; +class QDBusVariant; + +class QIBusPlatformInputContext : public QObject, public QPlatformInputContext +{ + Q_OBJECT +public: + QIBusPlatformInputContext(); + ~QIBusPlatformInputContext(); + + void mouseHandler(int x, QMouseEvent *event); + void reset(void); + void update(void); + void setFocusObject(QObject *object); + + bool x11FilterEvent(uint keyval, uint keycode, uint state, bool press); + +public Q_SLOTS: + void commitText(const QDBusVariant &text); + void updatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible); + +private: + QIBusPlatformInputContextPrivate *d; +}; + +#endif diff --git a/src/platformsupport/inputmethods/ibus/qibusproxy.cpp b/src/platformsupport/inputmethods/ibus/qibusproxy.cpp new file mode 100644 index 0000000000..9d64b603f3 --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/qibusproxy.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -N -p qibusproxy -c QIBusProxy interfaces/org.freedesktop.IBus.xml + * + * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "qibusproxy.h" + +/* + * Implementation of interface class QIBusProxy + */ + +QIBusProxy::QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +QIBusProxy::~QIBusProxy() +{ +} + diff --git a/src/platformsupport/inputmethods/ibus/qibusproxy.h b/src/platformsupport/inputmethods/ibus/qibusproxy.h new file mode 100644 index 0000000000..389eec3175 --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/qibusproxy.h @@ -0,0 +1,88 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -N -p qibusproxy -c QIBusProxy interfaces/org.freedesktop.IBus.xml + * + * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef QIBUSPROXY_H_1308831142 +#define QIBUSPROXY_H_1308831142 + +#include <QtCore/QObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> +#include <QtDBus/QtDBus> + +/* + * Proxy class for interface org.freedesktop.IBus + */ +class QIBusProxy: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.freedesktop.IBus"; } + +public: + QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~QIBusProxy(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<QDBusObjectPath> CreateInputContext(const QString &name) + { + QList<QVariant> argumentList; + argumentList << QVariant::fromValue(name); + return asyncCallWithArgumentList(QLatin1String("CreateInputContext"), argumentList); + } + + inline QDBusPendingReply<> Exit(bool restart) + { + QList<QVariant> argumentList; + argumentList << QVariant::fromValue(restart); + return asyncCallWithArgumentList(QLatin1String("Exit"), argumentList); + } + + inline QDBusPendingReply<QString> GetAddress() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("GetAddress"), argumentList); + } + + inline QDBusPendingReply<QVariantList> ListActiveEngines() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("ListActiveEngines"), argumentList); + } + + inline QDBusPendingReply<QVariantList> ListEngines() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("ListEngines"), argumentList); + } + + inline QDBusPendingReply<QDBusVariant> Ping(const QDBusVariant &data) + { + QList<QVariant> argumentList; + argumentList << QVariant::fromValue(data); + return asyncCallWithArgumentList(QLatin1String("Ping"), argumentList); + } + + inline QDBusPendingReply<> RegisterComponent(const QDBusVariant &components) + { + QList<QVariant> argumentList; + argumentList << QVariant::fromValue(components); + return asyncCallWithArgumentList(QLatin1String("RegisterComponent"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/src/platformsupport/inputmethods/ibus/qibustypes.cpp b/src/platformsupport/inputmethods/ibus/qibustypes.cpp new file mode 100644 index 0000000000..8d8c61afb7 --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/qibustypes.cpp @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qibustypes.h" +#include <qtextformat.h> +#include <QtDBus> + +QIBusSerializable::QIBusSerializable() +{ +} + +QIBusSerializable::~QIBusSerializable() +{ +} + +void QIBusSerializable::fromDBusArgument(const QDBusArgument &arg) +{ + arg >> name; + arg.beginMap(); + while (!arg.atEnd()) { + arg.beginMapEntry(); + QString key; + QDBusVariant value; + arg >> key; + arg >> value; + arg.endMapEntry(); + attachments[key] = value.variant().value<QDBusArgument>(); + } + arg.endMap(); +} + + + +QIBusAttribute::QIBusAttribute() + : type(Invalid), + value(0), + start(0), + end(0) +{ +} + +QIBusAttribute::~QIBusAttribute() +{ + +} + +void QIBusAttribute::fromDBusArgument(const QDBusArgument &arg) +{ +// qDebug() << "QIBusAttribute::fromDBusArgument()" << arg.currentSignature(); + arg.beginStructure(); + + QIBusSerializable::fromDBusArgument(arg); + + quint32 t; + arg >> t; + type = (Type)t; + arg >> value; + arg >> start; + arg >> end; + + arg.endStructure(); +} + +QTextFormat QIBusAttribute::format() const +{ + QTextCharFormat fmt; + switch (type) { + case Invalid: + break; + case Underline: { + QTextCharFormat::UnderlineStyle style = QTextCharFormat::NoUnderline; + + switch (value) { + case UnderlineNone: + break; + case UnderlineSingle: + style = QTextCharFormat::SingleUnderline; + break; + case UnderlineDouble: + style = QTextCharFormat::DashUnderline; + break; + case UnderlineLow: + style = QTextCharFormat::DashDotLine; + break; + case UnderlineError: + style = QTextCharFormat::WaveUnderline; + fmt.setUnderlineColor(Qt::red); + break; + } + + fmt.setUnderlineStyle(style); + break; + } + case Foreground: + fmt.setForeground(QColor(value)); + break; + case Background: + fmt.setBackground(QColor(value)); + break; + } + return fmt; +} + + +QIBusAttributeList::QIBusAttributeList() +{ + +} + +QIBusAttributeList::~QIBusAttributeList() +{ + +} + +void QIBusAttributeList::fromDBusArgument(const QDBusArgument &arg) +{ +// qDebug() << "QIBusAttributeList::fromDBusArgument()" << arg.currentSignature(); + arg.beginStructure(); + + QIBusSerializable::fromDBusArgument(arg); + + arg.beginArray(); + while(!arg.atEnd()) { + QDBusVariant var; + arg >> var; + + QIBusAttribute attr; + attr.fromDBusArgument(var.variant().value<QDBusArgument>()); + attributes.append(attr); + } + arg.endArray(); + + arg.endStructure(); +} + +QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const +{ + QList<QInputMethodEvent::Attribute> imAttrs; + for (int i = 0; i < attributes.size(); ++i) { + const QIBusAttribute &attr = attributes.at(i); + imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, attr.start, attr.end - attr.start, attr.format()); + } + return imAttrs; +} + + +QIBusText::QIBusText() +{ + +} + +QIBusText::~QIBusText() +{ + +} + +void QIBusText::fromDBusArgument(const QDBusArgument &arg) +{ +// qDebug() << "QIBusText::fromDBusArgument()" << arg.currentSignature(); + arg.beginStructure(); + + QIBusSerializable::fromDBusArgument(arg); + + arg >> text; + QDBusVariant variant; + arg >> variant; + attributes.fromDBusArgument(variant.variant().value<QDBusArgument>()); + + arg.endStructure(); +} + diff --git a/src/platformsupport/inputmethods/ibus/qibustypes.h b/src/platformsupport/inputmethods/ibus/qibustypes.h new file mode 100644 index 0000000000..c426ff7eda --- /dev/null +++ b/src/platformsupport/inputmethods/ibus/qibustypes.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QIBUSTYPES_H +#define QIBUSTYPES_H + +#include <qvector.h> +#include <qevent.h> + +class QDBusArgument; + +class QIBusSerializable +{ +public: + QIBusSerializable(); + virtual ~QIBusSerializable(); + + virtual void fromDBusArgument(const QDBusArgument &arg); + + QString name; + QHash<QString, QDBusArgument> attachments; +}; + +class QIBusAttribute : public QIBusSerializable +{ +public: + enum Type { + Invalid = 0, + Underline = 1, + Foreground = 2, + Background = 3, + }; + + enum Underline { + UnderlineNone = 0, + UnderlineSingle = 1, + UnderlineDouble = 2, + UnderlineLow = 3, + UnderlineError = 4, + }; + + QIBusAttribute(); + ~QIBusAttribute(); + + void fromDBusArgument(const QDBusArgument &arg); + QTextFormat format() const; + + Type type; + quint32 value; + quint32 start; + quint32 end; +}; + +class QIBusAttributeList : public QIBusSerializable +{ +public: + QIBusAttributeList(); + ~QIBusAttributeList(); + + void fromDBusArgument(const QDBusArgument &arg); + + QList<QInputMethodEvent::Attribute> imAttributes() const; + + QVector<QIBusAttribute> attributes; +}; + +class QIBusText : public QIBusSerializable +{ +public: + QIBusText(); + ~QIBusText(); + + void fromDBusArgument(const QDBusArgument &arg); + + QString text; + QIBusAttributeList attributes; +}; + +#endif diff --git a/src/platformsupport/inputmethods/inputmethods.pri b/src/platformsupport/inputmethods/inputmethods.pri new file mode 100644 index 0000000000..124008df60 --- /dev/null +++ b/src/platformsupport/inputmethods/inputmethods.pri @@ -0,0 +1,3 @@ +!mac:unix { + include($$PWD/ibus/ibus.pri) +} diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro new file mode 100644 index 0000000000..5609996d8d --- /dev/null +++ b/src/platformsupport/platformsupport.pro @@ -0,0 +1,31 @@ +load(qt_module) +TARGET = $$qtLibraryTarget(QtPlatformSupport) +QPRO_PWD = $$PWD +QT += core-private gui-private +TEMPLATE = lib +DESTDIR = $$QMAKE_LIBDIR_QT + +CONFIG += module +!mac:CONFIG += staticlib +mac:LIBS += -lz -framework CoreFoundation -framework Carbon + +MODULE_PRI = ../modules/qt_platformssupport.pri + +unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui + +include(../qbase.pri) + +HEADERS += $$PWD/qtplatformsupportversion.h + +DEFINES += QT_NO_CAST_FROM_ASCII +PRECOMPILED_HEADER = ../corelib/global/qt_pch.h + +include(cglconvenience/cglconvenience.pri) +include(dnd/dnd.pri) +include(eglconvenience/eglconvenience.pri) +include(eventdispatchers/eventdispatchers.pri) +include(fb_base/fb_base.pri) +include(fontdatabases/fontdatabases.pri) +include(glxconvenience/glxconvenience.pri) +include(printersupport/printersupport.pri) +include(inputmethods/inputmethods.pri) diff --git a/src/platformsupport/printersupport/genericunix/genericunix.pri b/src/platformsupport/printersupport/genericunix/genericunix.pri new file mode 100644 index 0000000000..06bd1b6d21 --- /dev/null +++ b/src/platformsupport/printersupport/genericunix/genericunix.pri @@ -0,0 +1,2 @@ +HEADERS += $$PWD/qgenericunixprintersupport_p.h +SOURCES += $$PWD/qgenericunixprintersupport.cpp diff --git a/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp new file mode 100644 index 0000000000..ae66ce859f --- /dev/null +++ b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgenericunixprintersupport_p.h" + +#include <QtGui/QPrinterInfo> +#include <private/qcups_p.h> + +QT_BEGIN_NAMESPACE + +QList<QPrinter::PaperSize> QGenericUnixPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const +{ +#ifndef QT_NO_CUPS + return QCUPSSupport::getCupsPrinterPaperSizes(QPlatformPrinterSupport::printerInfoCupsPrinterIndex(printerInfo)); +#else + return QList<QPrinter::PaperSize>(); +#endif +} + +QList<QPrinterInfo> QGenericUnixPrinterSupport::availablePrinters() +{ + QList<QPrinterInfo> printers; +#ifndef QT_NO_CUPS + foreach (const QCUPSSupport::Printer &p, QCUPSSupport::availableUnixPrinters()) { + QPrinterInfo printer(QPlatformPrinterSupport::printerInfo(p.name, p.isDefault)); + QPlatformPrinterSupport::setPrinterInfoCupsPrinterIndex(&printer, p.cupsPrinterIndex); + printers.append(printer); + } +#endif + return printers; +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h new file mode 100644 index 0000000000..5d7b3b43fb --- /dev/null +++ b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGENERICUNIXPRINTINGSUPPORT_H +#define QGENERICUNIXPRINTINGSUPPORT_H + +#include <QtGui/QPlatformPrinterSupport> + +QT_BEGIN_NAMESPACE + +class QGenericUnixPrinterSupport : public QPlatformPrinterSupport +{ +public: + virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const; + + virtual QList<QPrinterInfo> availablePrinters(); +}; + +QT_END_NAMESPACE + +#endif // QGENERICUNIXPRINTINGSUPPORT_H diff --git a/src/platformsupport/printersupport/printersupport.pri b/src/platformsupport/printersupport/printersupport.pri new file mode 100644 index 0000000000..797ac771e7 --- /dev/null +++ b/src/platformsupport/printersupport/printersupport.pri @@ -0,0 +1,3 @@ +unix { + include($$PWD/genericunix/genericunix.pri) +} |