diff options
Diffstat (limited to 'src/gui/kernel')
36 files changed, 1994 insertions, 515 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index e9e4a1d818..2aeea6288b 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -68,11 +68,10 @@ HEADERS += \ kernel/qplatformservices.h \ kernel/qplatformscreenpageflipper.h \ kernel/qplatformsystemtrayicon.h \ - kernel/qplatformsessionmanager.h + kernel/qplatformsessionmanager.h \ + kernel/qpixelformat.h SOURCES += \ - kernel/qclipboard_qpa.cpp \ - kernel/qcursor_qpa.cpp \ kernel/qgenericpluginfactory.cpp \ kernel/qgenericplugin.cpp \ kernel/qwindowsysteminterface.cpp \ @@ -109,7 +108,6 @@ SOURCES += \ kernel/qinputmethod.cpp \ kernel/qkeysequence.cpp \ kernel/qkeymapper.cpp \ - kernel/qkeymapper_qpa.cpp \ kernel/qpalette.cpp \ kernel/qguivariant.cpp \ kernel/qscreen.cpp \ @@ -120,9 +118,10 @@ SOURCES += \ kernel/qplatformdialoghelper.cpp \ kernel/qplatformservices.cpp \ kernel/qplatformscreenpageflipper.cpp \ - kernel/qplatformsystemtrayicon_qpa.cpp \ + kernel/qplatformsystemtrayicon.cpp \ kernel/qplatformsessionmanager.cpp \ - kernel/qplatformmenu.cpp + kernel/qplatformmenu.cpp \ + kernel/qpixelformat.cpp contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) { HEADERS += \ diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index 3c2d36ce86..672eb9eb65 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -50,6 +50,10 @@ #include "qimage.h" #include "qtextcodec.h" +#include "private/qguiapplication_p.h" +#include <qpa/qplatformintegration.h> +#include <qpa/qplatformclipboard.h> + QT_BEGIN_NAMESPACE /*! @@ -438,6 +442,12 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode) \sa setMimeData() */ +const QMimeData* QClipboard::mimeData(Mode mode) const +{ + QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); + if (!clipboard->supportsMode(mode)) return 0; + return clipboard->mimeData(mode); +} /*! \fn void QClipboard::setMimeData(QMimeData *src, Mode mode) @@ -458,6 +468,13 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode) \sa mimeData() */ +void QClipboard::setMimeData(QMimeData* src, Mode mode) +{ + QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); + if (!clipboard->supportsMode(mode)) return; + + clipboard->setMimeData(src,mode); +} /*! \fn void QClipboard::clear(Mode mode) @@ -472,7 +489,10 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode) \sa QClipboard::Mode, supportsSelection() */ - +void QClipboard::clear(Mode mode) +{ + setMimeData(0, mode); +} /*! Returns \c true if the clipboard supports mouse selection; otherwise @@ -527,6 +547,11 @@ bool QClipboard::ownsFindBuffer() const Returns \c true if the clipboard supports the clipboard mode speacified by \a mode; otherwise returns \c false. */ +bool QClipboard::supportsMode(Mode mode) const +{ + QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); + return clipboard->supportsMode(mode); +} /*! \internal @@ -534,6 +559,11 @@ bool QClipboard::ownsFindBuffer() const Returns \c true if the clipboard supports the clipboard data speacified by \a mode; otherwise returns \c false. */ +bool QClipboard::ownsMode(Mode mode) const +{ + QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); + return clipboard->ownsMode(mode); +} /*! \internal diff --git a/src/gui/kernel/qclipboard_qpa.cpp b/src/gui/kernel/qclipboard_qpa.cpp deleted file mode 100644 index ff8a210cba..0000000000 --- a/src/gui/kernel/qclipboard_qpa.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qclipboard.h" - -#ifndef QT_NO_CLIPBOARD - -#include "qmimedata.h" -#include "private/qguiapplication_p.h" -#include <qpa/qplatformclipboard.h> -#include <qpa/qplatformintegration.h> - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -void QClipboard::clear(Mode mode) -{ - setMimeData(0, mode); -} - -const QMimeData* QClipboard::mimeData(Mode mode) const -{ - QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); - if (!clipboard->supportsMode(mode)) return 0; - return clipboard->mimeData(mode); -} - -void QClipboard::setMimeData(QMimeData* src, Mode mode) -{ - QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); - if (!clipboard->supportsMode(mode)) return; - - clipboard->setMimeData(src,mode); -} - -bool QClipboard::supportsMode(Mode mode) const -{ - QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); - return clipboard->supportsMode(mode); -} - -bool QClipboard::ownsMode(Mode mode) const -{ - QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); - return clipboard->ownsMode(mode); -} - -#endif // QT_NO_CLIPBOARD - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index a33b264704..87774b2056 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -51,6 +51,9 @@ #include <private/qcursor_p.h> #include <qdebug.h> +#include <qpa/qplatformcursor.h> +#include <private/qguiapplication_p.h> + QT_BEGIN_NAMESPACE /*! @@ -172,6 +175,13 @@ QT_BEGIN_NAMESPACE \sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal() */ +QPoint QCursor::pos(const QScreen *screen) +{ + if (screen) + if (const QPlatformCursor *cursor = screen->handle()->cursor()) + return cursor->pos(); + return QGuiApplicationPrivate::lastCursorPosition.toPoint(); +} /*! \fn QPoint QCursor::pos() @@ -191,7 +201,10 @@ QT_BEGIN_NAMESPACE \sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen() */ - +QPoint QCursor::pos() +{ + return QCursor::pos(QGuiApplication::primaryScreen()); +} /*! \fn void QCursor::setPos(QScreen *screen, int x, int y) @@ -214,6 +227,19 @@ QT_BEGIN_NAMESPACE \sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal() */ +void QCursor::setPos(QScreen *screen, int x, int y) +{ + if (screen) { + if (QPlatformCursor *cursor = screen->handle()->cursor()) { + const QPoint pos = QPoint(x, y); + // Need to check, since some X servers generate null mouse move + // events, causing looping in applications which call setPos() on + // every mouse move event. + if (pos != cursor->pos()) + cursor->setPos(pos); + } + } +} /*! \fn void QCursor::setPos(int x, int y) @@ -226,6 +252,10 @@ QT_BEGIN_NAMESPACE \sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen() */ +void QCursor::setPos(int x, int y) +{ + QCursor::setPos(QGuiApplication::primaryScreen(), x, y); +} /*! \fn void QCursor::setPos (const QPoint &p) @@ -401,34 +431,6 @@ QCursor::QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) d = QCursorData::setBitmap(bitmap, mask, hotX, hotY); } -QCursorData *qt_cursorTable[Qt::LastCursor + 1]; -bool QCursorData::initialized = false; - -/*! \internal */ -void QCursorData::cleanup() -{ - if(!QCursorData::initialized) - return; - - for (int shape = 0; shape <= Qt::LastCursor; ++shape) { - // In case someone has a static QCursor defined with this shape - if (!qt_cursorTable[shape]->ref.deref()) - delete qt_cursorTable[shape]; - qt_cursorTable[shape] = 0; - } - QCursorData::initialized = false; -} - -/*! \internal */ -void QCursorData::initialize() -{ - if (QCursorData::initialized) - return; - for (int shape = 0; shape <= Qt::LastCursor; ++shape) - qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape); - QCursorData::initialized = true; -} - /*! Constructs a cursor with the default arrow shape. */ @@ -602,6 +604,73 @@ QDebug operator<<(QDebug dbg, const QCursor &c) } #endif +/***************************************************************************** + Internal QCursorData class + *****************************************************************************/ + +QCursorData *qt_cursorTable[Qt::LastCursor + 1]; +bool QCursorData::initialized = false; + +QCursorData::QCursorData(Qt::CursorShape s) + : ref(1), cshape(s), bm(0), bmm(0), hx(0), hy(0) +{ +} + +QCursorData::~QCursorData() +{ + delete bm; + delete bmm; +} + +/*! \internal */ +void QCursorData::cleanup() +{ + if(!QCursorData::initialized) + return; + + for (int shape = 0; shape <= Qt::LastCursor; ++shape) { + // In case someone has a static QCursor defined with this shape + if (!qt_cursorTable[shape]->ref.deref()) + delete qt_cursorTable[shape]; + qt_cursorTable[shape] = 0; + } + QCursorData::initialized = false; +} + +/*! \internal */ +void QCursorData::initialize() +{ + if (QCursorData::initialized) + return; + for (int shape = 0; shape <= Qt::LastCursor; ++shape) + qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape); + QCursorData::initialized = true; +} + +QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) +{ + if (!QCursorData::initialized) + QCursorData::initialize(); + if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) { + qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)"); + QCursorData *c = qt_cursorTable[0]; + c->ref.ref(); + return c; + } + QCursorData *d = new QCursorData; + d->bm = new QBitmap(bitmap); + d->bmm = new QBitmap(mask); + d->cshape = Qt::BitmapCursor; + d->hx = hotX >= 0 ? hotX : bitmap.width() / 2; + d->hy = hotY >= 0 ? hotY : bitmap.height() / 2; + + return d; +} + +void QCursorData::update() +{ +} + QT_END_NAMESPACE #endif // QT_NO_CURSOR diff --git a/src/gui/kernel/qcursor_qpa.cpp b/src/gui/kernel/qcursor_qpa.cpp deleted file mode 100644 index 0b19a47c69..0000000000 --- a/src/gui/kernel/qcursor_qpa.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qcursor.h> -#include <qscreen.h> -#include <private/qcursor_p.h> -#include <qpa/qplatformcursor.h> -#include <private/qguiapplication_p.h> -#include <qbitmap.h> - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -#ifndef QT_NO_CURSOR - -/***************************************************************************** - Internal QCursorData class - *****************************************************************************/ - -QCursorData::QCursorData(Qt::CursorShape s) - : ref(1), cshape(s), bm(0), bmm(0), hx(0), hy(0) -{ -} - -QCursorData::~QCursorData() -{ - delete bm; - delete bmm; -} - - -/***************************************************************************** - Global cursors - *****************************************************************************/ - -extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp - -QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) -{ - if (!QCursorData::initialized) - QCursorData::initialize(); - if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) { - qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)"); - QCursorData *c = qt_cursorTable[0]; - c->ref.ref(); - return c; - } - QCursorData *d = new QCursorData; - d->bm = new QBitmap(bitmap); - d->bmm = new QBitmap(mask); - d->cshape = Qt::BitmapCursor; - d->hx = hotX >= 0 ? hotX : bitmap.width() / 2; - d->hy = hotY >= 0 ? hotY : bitmap.height() / 2; - - return d; -} - -void QCursorData::update() -{ -} - -#endif //QT_NO_CURSOR - -QPoint QCursor::pos() -{ - return QCursor::pos(QGuiApplication::primaryScreen()); -} - -QPoint QCursor::pos(const QScreen *screen) -{ - if (screen) - if (const QPlatformCursor *cursor = screen->handle()->cursor()) - return cursor->pos(); - return QGuiApplicationPrivate::lastCursorPosition.toPoint(); -} - -void QCursor::setPos(QScreen *screen, int x, int y) -{ - if (screen) { - if (QPlatformCursor *cursor = screen->handle()->cursor()) { - const QPoint pos = QPoint(x, y); - // Need to check, since some X servers generate null mouse move - // events, causing looping in applications which call setPos() on - // every mouse move event. - if (pos != cursor->pos()) - cursor->setPos(pos); - } - } -} - -void QCursor::setPos(int x, int y) -{ - QCursor::setPos(QGuiApplication::primaryScreen(), x, y); -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp index d34a135eb7..328ca389ed 100644 --- a/src/gui/kernel/qdnd.cpp +++ b/src/gui/kernel/qdnd.cpp @@ -142,6 +142,7 @@ Qt::DropAction QDragManager::drag(QDrag *o) QGuiApplicationPrivate::instance()->notifyDragStarted(o); const Qt::DropAction result = m_platformDrag->drag(m_object); m_object = 0; + o->deleteLater(); return result; } diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index d6741af152..492f2a11c9 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -287,6 +287,8 @@ QMouseEvent::~QMouseEvent() \l Qt::MouseEventNotSynthesized is returned always. \sa Qt::MouseEventSource + \sa QGraphicsSceneMouseEvent::source() + \sa QGraphicsSceneMouseEvent::setSource() */ Qt::MouseEventSource QMouseEvent::source() const { @@ -301,6 +303,8 @@ Qt::MouseEventSource QMouseEvent::source() const The mouse event flags provide additional information about a mouse event. \sa Qt::MouseEventFlag + \sa QGraphicsSceneMouseEvent::flags() + \sa QGraphicsSceneMouseEvent::setFlags() */ Qt::MouseEventFlags QMouseEvent::flags() const { @@ -1185,7 +1189,7 @@ Qt::FocusReason QFocusEvent::reason() const The event contains a region() that needs to be updated, and a rect() that is the bounding rectangle of that region. Both are - provided because many widgets can't make much use of region(), + provided because many widgets cannot make much use of region(), and rect() can be much faster than region().boundingRect(). \section1 Automatic Clipping @@ -1977,40 +1981,63 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const \ingroup events - Tablet Events are generated from a Wacom tablet. Most of the time you will - want to deal with events from the tablet as if they were events from a - mouse; for example, you would retrieve the cursor position with x(), y(), - pos(), globalX(), globalY(), and globalPos(). In some situations you may - wish to retrieve the extra information provided by the tablet device - driver; for example, you might want to do subpixeling with higher - resolution coordinates or you may want to adjust color brightness based on - pressure. QTabletEvent allows you to read the pressure(), the xTilt(), and - yTilt(), as well as the type of device being used with device() (see - \l{TabletDevice}). It can also give you the minimum and maximum values for - each device's pressure and high resolution coordinates. - - A tablet event contains a special accept flag that indicates whether the - receiver wants the event. You should call QTabletEvent::accept() if you - handle the tablet event; otherwise it will be sent to the parent widget. - The exception are TabletEnterProximity and TabletLeaveProximity events, - these are only sent to QApplication and don't check whether or not they are - accepted. - - The QWidget::setEnabled() function can be used to enable or - disable mouse and keyboard events for a widget. - - The event handler QWidget::tabletEvent() receives all three types of - tablet events. Qt will first send a tabletEvent then, if it is not - accepted, it will send a mouse event. This allows applications that - don't utilize tablets to use a tablet like a mouse, while also - enabling those who want to use both tablets and mouses differently. + \e{Tablet events} are generated from tablet peripherals such as Wacom + tablets and various other brands, and electromagnetic stylus devices + included with some types of tablet computers. (It is not the same as + \l QTouchEvent which a touchscreen generates, even when a passive stylus is + used on a touchscreen.) + + Tablet events are similar to mouse events; for example, the \l x(), \l y(), + \l pos(), \l globalX(), \l globalY(), and \l globalPos() accessors provide + the cursor position, and you can see which \l buttons() are pressed + (pressing the stylus tip against the tablet surface is equivalent to a left + mouse button). But tablet events also pass through some extra information + that the tablet device driver provides; for example, you might want to do + subpixel rendering with higher resolution coordinates (\l hiResGlobalX() + and \l hiResGlobalY()), adjust color brightness based on the \l pressure() + of the tool against the tablet surface, use different brushes depending on + the type of tool in use (\l device()), modulate the brush shape in some way + according to the X-axis and Y-axis tilt of the tool with respect to the + tablet surface (\l xTilt() and \l yTilt()), and use a virtual eraser + instead of a brush if the user switches to the other end of a double-ended + stylus (\l pointerType()). + + Every event contains an accept flag that indicates whether the receiver + wants the event. You should call QTabletEvent::accept() if you handle the + tablet event; otherwise it will be sent to the parent widget. The exception + are TabletEnterProximity and TabletLeaveProximity events: these are only + sent to QApplication and do not check whether or not they are accepted. + + The QWidget::setEnabled() function can be used to enable or disable + mouse, tablet and keyboard events for a widget. + + The event handler QWidget::tabletEvent() receives TabletPress, + TabletRelease and TabletMove events. Qt will first send a + tablet event, then if it is not accepted by any widget, it will send a + mouse event. This allows users of applications that are not designed for + tablets to use a tablet like a mouse. However high-resolution drawing + applications should handle the tablet events, because they can occur at a + higher frequency, which is a benefit for smooth and accurate drawing. + If the tablet events are rejected, the synthetic mouse events may be + compressed for efficiency. + + New in Qt 5.4: QTabletEvent includes all information available from the + device, including \l QTabletEvent::buttons(). Previously it was not + possible to accept all tablet events and also know which stylus buttons + were pressed. + + Note that pressing the stylus button while the stylus hovers over the + tablet will generate a button press on some types of tablets, while on + other types it will be necessary to press the stylus against the tablet + surface in order to register the simultaneous stylus button press. \section1 Notes for X11 Users - Qt uses the following hard-coded names to identify tablet - devices from the xorg.conf file on X11 (apart from IRIX): - 'stylus', 'pen', and 'eraser'. If the devices have other names, - they will not be picked up Qt. + If the tablet is configured in xorg.conf to use the Wacom driver, there + will be separate XInput "devices" for the stylus, eraser, and (optionally) + cursor and touchpad. Qt recognizes these by their names. Otherwise, if the + tablet is configured to use the evdev driver, there will be only one device + and applications may not be able to distinguish the stylus from the eraser. */ /*! @@ -2068,11 +2095,73 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const The \a tangentialPressure parameter contins the tangential pressure of an air brush. If the device does not support tangential pressure, pass 0 here. + \a rotation contains the device's rotation in degrees. 4D mice and the Wacom + Art Pen support rotation. If the device does not support rotation, pass 0 here. + + The \a button that caused the event is given as a value from the + \l Qt::MouseButton enum. If the event \a type is not \l TabletPress or + \l TabletRelease, the appropriate button for this event is \l Qt::NoButton. + + \a buttons is the state of all buttons at the time of the event. + + \sa pos(), globalPos(), device(), pressure(), xTilt(), yTilt(), uniqueId(), rotation(), + tangentialPressure(), z() +*/ + +QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalPos, + int device, int pointerType, + qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, + qreal rotation, int z, Qt::KeyboardModifiers keyState, qint64 uniqueID, + Qt::MouseButton button, Qt::MouseButtons buttons) + : QInputEvent(type, keyState), + mPos(pos), + mGPos(globalPos), + mDev(device), + mPointerType(pointerType), + mXT(xTilt), + mYT(yTilt), + mZ(z), + mPress(pressure), + mTangential(tangentialPressure), + mRot(rotation), + mUnique(uniqueID), + mExtra(new QTabletEventPrivate(button, buttons)) +{ +} + +/*! + Construct a tablet event of the given \a type. + + The \a pos parameter indicates where the event occurred in the + widget; \a globalPos is the corresponding position in absolute + coordinates. + + \a pressure contains the pressure exerted on the \a device. + + \a pointerType describes the type of pen that is being used. + + \a xTilt and \a yTilt contain the device's degree of tilt from the + x and y axes respectively. + + \a keyState specifies which keyboard modifiers are pressed (e.g., + \uicontrol{Ctrl}). + + The \a uniqueID parameter contains the unique ID for the current device. + + The \a z parameter contains the coordinate of the device on the tablet, this + is usually given by a wheel on 4D mouse. If the device does not support a + Z-axis, pass zero here. + + The \a tangentialPressure parameter contins the tangential pressure of an air + brush. If the device does not support tangential pressure, pass 0 here. + \a rotation contains the device's rotation in degrees. 4D mice support rotation. If the device does not support rotation, pass 0 here. \sa pos(), globalPos(), device(), pressure(), xTilt(), yTilt(), uniqueId(), rotation(), tangentialPressure(), z() + + \deprecated in 5.4: use the constructor with MouseButton status */ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalPos, @@ -2091,7 +2180,7 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP mTangential(tangentialPressure), mRot(rotation), mUnique(uniqueID), - mExtra(0) + mExtra(new QTabletEventPrivate(Qt::NoButton, Qt::NoButton)) { } @@ -2103,6 +2192,34 @@ QTabletEvent::~QTabletEvent() } /*! + Returns the button that caused the event. + + Note that the returned value is always Qt::NoButton for \l TabletMove, + \l TabletEnterProximity and \l TabletLeaveProximity events. + + \sa buttons(), Qt::MouseButton +*/ +Qt::MouseButton QTabletEvent::button() const +{ + return static_cast<QTabletEventPrivate *>(mExtra)->b; +} + +/*! + Returns the button state when the event was generated. The button state is + a combination of buttons from the \l Qt::MouseButton enum using the OR + operator. For \l TabletMove events, this is all buttons that are pressed + down. For \l TabletPress events this includes the button that caused the + event. For \l TabletRelease events this excludes the button that caused the + event. + + \sa button(), Qt::MouseButton +*/ +Qt::MouseButtons QTabletEvent::buttons() const +{ + return static_cast<QTabletEventPrivate *>(mExtra)->buttonState; +} + +/*! \fn TabletDevices QTabletEvent::device() const Returns the type of device that generated the event. @@ -2132,7 +2249,7 @@ QTabletEvent::~QTabletEvent() \fn qreal QTabletEvent::rotation() const Returns the rotation of the current device in degress. This is usually - given by a 4D Mouse. If the device doesn't support rotation this value is + given by a 4D Mouse. If the device does not support rotation this value is always 0.0. */ @@ -3036,7 +3153,7 @@ QActionEvent::~QActionEvent() If spontaneous() is true, the event originated outside the application. In this case, the user hid the window using the window manager controls, either by iconifying the window or by - switching to another virtual desktop where the window isn't + switching to another virtual desktop where the window is not visible. The window will become hidden but not withdrawn. If the window was iconified, QWidget::isMinimized() returns \c true. @@ -3265,6 +3382,61 @@ static inline void formatTouchEvent(QDebug d, const char *name, const QTouchEven d << ')'; } +static void formatUnicodeString(QDebug d, const QString &s) +{ + d << '"' << hex; + for (int i = 0; i < s.size(); ++i) { + if (i) + d << ','; + d << "U+" << s.at(i).unicode(); + } + d << dec << '"'; +} + +static inline void formatInputMethodEvent(QDebug d, const QInputMethodEvent *e) +{ + d << "QInputMethodEvent("; + if (!e->preeditString().isEmpty()) { + d << "preedit="; + formatUnicodeString(d, e->preeditString()); + } + if (!e->commitString().isEmpty()) { + d << ", commit="; + formatUnicodeString(d, e->commitString()); + } + if (e->replacementLength()) { + d << ", replacementStart=" << e->replacementStart() << ", replacementLength=" + << e->replacementLength(); + } + if (const int attributeCount = e->attributes().size()) { + d << ", attributes= {"; + for (int a = 0; a < attributeCount; ++a) { + const QInputMethodEvent::Attribute &at = e->attributes().at(a); + if (a) + d << ','; + d << "[type= " << at.type << ", start=" << at.start << ", length=" << at.length + << ", value=" << at.value << ']'; + } + d << '}'; + } + d << ')'; +} + +static inline void formatInputMethodQueryEvent(QDebug d, const QInputMethodQueryEvent *e) +{ + const Qt::InputMethodQueries queries = e->queries(); + d << "QInputMethodQueryEvent(queries=" << showbase << hex << int(queries) + << noshowbase << dec << ", {"; + for (unsigned mask = 1; mask <= Qt::ImTextAfterCursor; mask<<=1) { + if (queries & mask) { + const QVariant value = e->value(static_cast<Qt::InputMethodQuery>(mask)); + if (value.isValid()) + d << '[' << showbase << hex << mask << noshowbase << dec << '=' << value << "],"; + } + } + d << "})"; +} + QDebug operator<<(QDebug dbg, const QEvent *e) { // More useful event output could be added here if (!e) @@ -3302,6 +3474,8 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { << ", " << hex << (int)me->modifiers() << dec; if (const Qt::MouseEventSource source = me->source()) nsp << ", source = " << source; + if (const Qt::MouseEventFlags flags = me->flags()) + nsp << ", flags = " << hex << int(flags) << dec; nsp << ')'; } return dbg.space(); @@ -3355,11 +3529,13 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { } return dbg.space(); case QEvent::FocusIn: - n = "FocusIn"; - break; + dbg.nospace() << "QFocusEvent(FocusIn, reason=" + << static_cast<const QFocusEvent *>(e)->reason() << ')'; + return dbg.space(); case QEvent::FocusOut: - n = "FocusOut"; - break; + dbg.nospace() << "QFocusEvent(FocusOut, reason=" + << static_cast<const QFocusEvent *>(e)->reason() << ')'; + return dbg.space(); case QEvent::Enter: n = "Enter"; break; @@ -3381,12 +3557,24 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::Paint: n = "Paint"; break; - case QEvent::Move: - n = "Move"; - break; - case QEvent::Resize: - n = "Resize"; - break; + case QEvent::Move: { + const QMoveEvent *me = static_cast<const QMoveEvent *>(e); + QDebug nospace = dbg.nospace(); + nospace << "QMoveEvent(" << me->pos(); + if (!me->spontaneous()) + nospace << ", non-spontaneous"; + nospace << ')'; + } + return dbg.space(); + case QEvent::Resize: { + const QResizeEvent *re = static_cast<const QResizeEvent *>(e); + QDebug nospace = dbg.nospace(); + nospace << "QResizeEvent(" << re->size(); + if (!re->spontaneous()) + nospace << ", non-spontaneous"; + nospace << ')'; + } + return dbg.space(); case QEvent::Create: n = "Create"; break; @@ -3498,6 +3686,18 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::GraphicsSceneMove: n = "GraphicsSceneMove"; break; + case QEvent::InputMethod: { + QDebugStateSaver saver(dbg); + dbg.nospace(); + formatInputMethodEvent(dbg, static_cast<const QInputMethodEvent *>(e)); + } + return dbg; + case QEvent::InputMethodQuery: { + QDebugStateSaver saver(dbg); + dbg.nospace(); + formatInputMethodQueryEvent(dbg, static_cast<const QInputMethodQueryEvent *>(e)); + } + return dbg; case QEvent::CursorChange: n = "CursorChange"; break; @@ -3551,7 +3751,23 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::Gesture: n = "Gesture"; break; + case QEvent::GestureOverride: + n = "GestureOverride"; + break; #endif + case QEvent::MetaCall: + n = "MetaCall"; + break; + case QEvent::ApplicationStateChange: + dbg.nospace() << "QApplicationStateChangeEvent(" + << static_cast<const QApplicationStateChangeEvent *>(e)->applicationState() << ')'; + return dbg.space(); + case QEvent::WindowTitleChange: + n = "WindowTitleChange"; + break; + case QEvent::Expose: + n = "Expose"; + break; default: dbg.nospace() << "QEvent(" << (const void *)e << ", type = " << e->type() << ')'; return dbg.space(); @@ -3570,7 +3786,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { \ingroup events \inmodule QtGui - Normally you don't need to use this class directly; QShortcut + Normally you do not need to use this class directly; QShortcut provides a higher-level interface to handle shortcut keys. \sa QShortcut diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 0a826284c9..346c0a4ba0 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -230,7 +230,12 @@ public: QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos, int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, - Qt::KeyboardModifiers keyState, qint64 uniqueID); + Qt::KeyboardModifiers keyState, qint64 uniqueID); // ### remove in Qt 6 + QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos, + int device, int pointerType, qreal pressure, int xTilt, int yTilt, + qreal tangentialPressure, qreal rotation, int z, + Qt::KeyboardModifiers keyState, qint64 uniqueID, + Qt::MouseButton button, Qt::MouseButtons buttons); ~QTabletEvent(); inline QPoint pos() const { return mPos.toPoint(); } @@ -257,6 +262,8 @@ public: inline qreal rotation() const { return mRot; } inline int xTilt() const { return mXT; } inline int yTilt() const { return mYT; } + Qt::MouseButton button() const; + Qt::MouseButtons buttons() const; protected: QPointF mPos, mGPos; @@ -264,9 +271,8 @@ protected: qreal mPress, mTangential, mRot; qint64 mUnique; - // I don't know what the future holds for tablets but there could be some - // new devices coming along, and there seem to be "holes" in the - // OS-specific events for this. + // QTabletEventPrivate for extra storage. + // ### Qt 6: QPointingEvent will have Buttons, QTabletEvent will inherit void *mExtra; }; #endif // QT_NO_TABLETEVENT @@ -377,8 +383,6 @@ public: inline const QRegion ®ion() const { return m_region; } protected: - friend class QApplication; - friend class QCoreApplication; QRect m_rect; QRegion m_region; bool m_erased; @@ -395,7 +399,6 @@ public: protected: QPoint p, oldp; friend class QApplication; - friend class QCoreApplication; }; class Q_GUI_EXPORT QExposeEvent : public QEvent @@ -421,7 +424,6 @@ public: protected: QSize s, olds; friend class QApplication; - friend class QCoreApplication; }; @@ -601,7 +603,6 @@ public: inline void ignore(const QRect & r) { ignore(); rect = r; } protected: - friend class QApplication; QRect rect; }; diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index e01216e9f1..d24f3768a8 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -92,6 +92,20 @@ public: QVector<QPointF> rawScreenPositions; }; +#ifndef QT_NO_TABLETEVENT +class QTabletEventPrivate +{ +public: + inline QTabletEventPrivate(Qt::MouseButton button, Qt::MouseButtons buttons) + : b(button), + buttonState(buttons) + { } + + Qt::MouseButton b; + Qt::MouseButtons buttonState; +}; +#endif // QT_NO_TABLETEVENT + QT_END_NAMESPACE #endif // QEVENT_P_H diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index e5cf48dd6b..831ebd19c0 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -118,7 +118,7 @@ Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier; QPointF QGuiApplicationPrivate::lastCursorPosition(qInf(), qInf()); -bool QGuiApplicationPrivate::tabletState = false; +Qt::MouseButtons QGuiApplicationPrivate::tabletState = Qt::NoButton; QWindow *QGuiApplicationPrivate::tabletPressTarget = 0; QWindow *QGuiApplicationPrivate::currentMouseWindow = 0; @@ -507,6 +507,7 @@ static QWindowGeometrySpecification windowGeometrySpecification; \li \c {-qwindowgeometry} \e geometry, specifies window geometry for the main window using the X11-syntax. For example: \c {-qwindowgeometry 100x100+50+50} + \li \c {-qwindowicon}, sets the default window icon \li \c {-qwindowtitle}, sets the title of the first window \li \c{-reverse}, sets the application's layout direction to Qt::RightToLeft. This option is intended to aid debugging and should @@ -900,7 +901,19 @@ QList<QScreen *> QGuiApplication::screens() This signal is emitted whenever a new screen \a screen has been added to the system. - \sa screens(), primaryScreen() + \sa screens(), primaryScreen(), screenRemoved() +*/ + +/*! + \fn void QGuiApplication::screenRemoved(QScreen *screen) + + This signal is emitted whenever a \a screen is removed from the system. It + provides an opportunity to manage the windows on the screen before Qt falls back + to moving them to the primary screen. + + \sa screens(), screenAdded(), QObject::destroyed(), QWindow::setScreen() + + \since 5.4 */ @@ -1112,12 +1125,15 @@ void QGuiApplicationPrivate::createPlatformIntegration() // Get command line params + QString icon; + int j = argc ? 1 : 0; for (int i=1; i<argc; i++) { if (argv[i] && *argv[i] != '-') { argv[j++] = argv[i]; continue; } + const bool isXcb = platformName == "xcb"; QByteArray arg = argv[i]; if (arg.startsWith("--")) arg.remove(0, 1); @@ -1130,12 +1146,16 @@ void QGuiApplicationPrivate::createPlatformIntegration() } else if (arg == "-platformtheme") { if (++i < argc) platformThemeName = QString::fromLocal8Bit(argv[i]); - } else if (arg == "-qwindowgeometry" || (platformName == "xcb" && arg == "-geometry")) { + } else if (arg == "-qwindowgeometry" || (isXcb && arg == "-geometry")) { if (++i < argc) windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]); - } else if (arg == "-qwindowtitle" || (platformName == "xcb" && arg == "-title")) { + } else if (arg == "-qwindowtitle" || (isXcb && arg == "-title")) { if (++i < argc) firstWindowTitle = QString::fromLocal8Bit(argv[i]); + } else if (arg == "-qwindowicon" || (isXcb && arg == "-icon")) { + if (++i < argc) { + icon = QString::fromLocal8Bit(argv[i]); + } } else { argv[j++] = argv[i]; } @@ -1148,6 +1168,8 @@ void QGuiApplicationPrivate::createPlatformIntegration() init_platform(QLatin1String(platformName), platformPluginPath, platformThemeName, argc, argv); + if (!icon.isEmpty()) + forcedWindowIcon = QDir::isAbsolutePath(icon) ? QIcon(icon) : QIcon::fromTheme(icon); } /*! @@ -1449,6 +1471,20 @@ QPlatformNativeInterface *QGuiApplication::platformNativeInterface() } /*! + Returns a function pointer from the platformplugin matching \a function +*/ +QFunctionPointer QGuiApplication::platformFunction(const QByteArray &function) +{ + QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); + if (!pi) { + qWarning() << "QGuiApplication::platformFunction(): Must construct a QGuiApplication before accessing a platform function"; + return Q_NULLPTR; + } + + return pi->nativeInterface() ? pi->nativeInterface()->platformFunction(function) : Q_NULLPTR; +} + +/*! Enters the main event loop and waits until exit() is called, and then returns the value that was set to exit() (which is 0 if exit() is called via quit()). @@ -1571,8 +1607,9 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv case QWindowSystemInterfacePrivate::WindowScreenChanged: QGuiApplicationPrivate::processWindowScreenChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowScreenChangedEvent *>(e)); break; - case QWindowSystemInterfacePrivate::ApplicationStateChanged: - QGuiApplicationPrivate::setApplicationState(static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e)->newState); + case QWindowSystemInterfacePrivate::ApplicationStateChanged: { + QWindowSystemInterfacePrivate::ApplicationStateChangedEvent * changeEvent = static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e); + QGuiApplicationPrivate::setApplicationState(changeEvent->newState, changeEvent->forcePropagate); } break; case QWindowSystemInterfacePrivate::FlushEvents: QWindowSystemInterface::deferredFlushWindowSystemEvents(); @@ -1967,7 +2004,7 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf { if (QWindow *window = wse->window.data()) { if (QScreen *screen = wse->screen.data()) - window->d_func()->setScreen(screen, false /* recreate */); + window->d_func()->setTopLevelScreen(screen, false /* recreate */); else // Fall back to default behavior, and try to find some appropriate screen window->setScreen(0); } @@ -2053,10 +2090,8 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T { #ifndef QT_NO_TABLETEVENT QEvent::Type type = QEvent::TabletMove; - if (e->down != tabletState) { - type = e->down ? QEvent::TabletPress : QEvent::TabletRelease; - tabletState = e->down; - } + if (e->buttons != tabletState) + type = (e->buttons > tabletState) ? QEvent::TabletPress : QEvent::TabletRelease; QWindow *window = e->window.data(); modifier_buttons = e->modifiers; @@ -2088,12 +2123,21 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T QPointF delta = e->global - e->global.toPoint(); local = window->mapFromGlobal(e->global.toPoint()) + delta; } + Qt::MouseButtons stateChange = e->buttons ^ tabletState; + Qt::MouseButton button = Qt::NoButton; + for (int check = Qt::LeftButton; check <= int(Qt::MaxMouseButton); check = check << 1) { + if (check & stateChange) { + button = Qt::MouseButton(check); + break; + } + } QTabletEvent ev(type, local, e->global, e->device, e->pointerType, e->pressure, e->xTilt, e->yTilt, e->tangentialPressure, e->rotation, e->z, - e->modifiers, e->uid); + e->modifiers, e->uid, button, e->buttons); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(window, &ev); + tabletState = e->buttons; #else Q_UNUSED(e) #endif @@ -2105,7 +2149,7 @@ void QGuiApplicationPrivate::processTabletEnterProximityEvent(QWindowSystemInter QTabletEvent ev(QEvent::TabletEnterProximity, QPointF(), QPointF(), e->device, e->pointerType, 0, 0, 0, 0, 0, 0, - Qt::NoModifier, e->uid); + Qt::NoModifier, e->uid, Qt::NoButton, tabletState); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev); #else @@ -2119,7 +2163,7 @@ void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInter QTabletEvent ev(QEvent::TabletLeaveProximity, QPointF(), QPointF(), e->device, e->pointerType, 0, 0, 0, 0, 0, 0, - Qt::NoModifier, e->uid); + Qt::NoModifier, e->uid, Qt::NoButton, tabletState); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev); #else @@ -2651,6 +2695,15 @@ QClipboard * QGuiApplication::clipboard() #endif /*! + \since 5.4 + \fn void QGuiApplication::paletteChanged(const QPalette &palette) + + This signal is emitted when the \a palette of the application changes. + + \sa palette() +*/ + +/*! Returns the default application palette. \sa setPalette() @@ -2676,6 +2729,7 @@ void QGuiApplication::setPalette(const QPalette &pal) else *QGuiApplicationPrivate::app_pal = pal; applicationResourceFlags |= ApplicationPaletteExplicitlySet; + emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal); } QRect QGuiApplicationPrivate::applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window) @@ -2885,9 +2939,9 @@ Qt::ApplicationState QGuiApplication::applicationState() \sa applicationState() */ -void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state) +void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state, bool forcePropagate) { - if (applicationState == state) + if ((applicationState == state) && !forcePropagate) return; applicationState = state; @@ -3088,6 +3142,8 @@ void QGuiApplicationPrivate::saveState() On system start-up, the default layout direction depends on the application's language. + The notifier signal was introduced in Qt 5.4. + \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft() */ @@ -3098,7 +3154,10 @@ void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction) layout_direction = direction; - QGuiApplicationPrivate::self->notifyLayoutDirectionChange(); + if (qGuiApp) { + emit qGuiApp->layoutDirectionChanged(direction); + QGuiApplicationPrivate::self->notifyLayoutDirectionChange(); + } } Qt::LayoutDirection QGuiApplication::layoutDirection() diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 6d9a4b2376..6e751e1275 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -75,7 +75,7 @@ class Q_GUI_EXPORT QGuiApplication : public QCoreApplication Q_OBJECT Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon) Q_PROPERTY(QString applicationDisplayName READ applicationDisplayName WRITE setApplicationDisplayName) - Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection) + Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) Q_PROPERTY(QString platformName READ platformName STORED false) Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE setQuitOnLastWindowClosed) @@ -143,6 +143,8 @@ public: static QPlatformNativeInterface *platformNativeInterface(); + static QFunctionPointer platformFunction(const QByteArray &function); + static void setQuitOnLastWindowClosed(bool quit); static bool quitOnLastWindowClosed(); @@ -163,14 +165,17 @@ public: Q_SIGNALS: void fontDatabaseChanged(); void screenAdded(QScreen *screen); + void screenRemoved(QScreen *screen); void lastWindowClosed(); void focusObjectChanged(QObject *focusObject); void focusWindowChanged(QWindow *focusWindow); void applicationStateChanged(Qt::ApplicationState state); + void layoutDirectionChanged(Qt::LayoutDirection direction); #ifndef QT_NO_SESSIONMANAGER void commitDataRequest(QSessionManager &sessionManager); void saveStateRequest(QSessionManager &sessionManager); #endif + void paletteChanged(const QPalette &pal); protected: bool event(QEvent *); diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 1ec808ec27..5f9f6ad9f2 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -207,7 +207,7 @@ public: static int mousePressY; static int mouse_double_click_distance; static QPointF lastCursorPosition; - static bool tabletState; + static Qt::MouseButtons tabletState; static QWindow *tabletPressTarget; static QWindow *currentMouseWindow; static Qt::ApplicationState applicationState; @@ -234,6 +234,7 @@ public: QInputMethod *inputMethod; QString firstWindowTitle; + QIcon forcedWindowIcon; static QList<QObject *> generic_plugin_list; #ifndef QT_NO_SHORTCUT @@ -288,7 +289,7 @@ public: static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window); - static void setApplicationState(Qt::ApplicationState state); + static void setApplicationState(Qt::ApplicationState state, bool forcePropagate = false); protected: virtual void notifyThemeChanged(); diff --git a/src/gui/kernel/qkeymapper.cpp b/src/gui/kernel/qkeymapper.cpp index 0e150a9c1e..2ec72fd2d0 100644 --- a/src/gui/kernel/qkeymapper.cpp +++ b/src/gui/kernel/qkeymapper.cpp @@ -45,6 +45,9 @@ #include <private/qobject_p.h> #include "qkeymapper_p.h" +#include <private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> + QT_BEGIN_NAMESPACE /*! @@ -117,4 +120,32 @@ QKeyMapperPrivate *qt_keymapper_private() return QKeyMapper::instance()->d_func(); } +QKeyMapperPrivate::QKeyMapperPrivate() +{ + keyboardInputLocale = QLocale::system(); + keyboardInputDirection = keyboardInputLocale.textDirection(); +} + +QKeyMapperPrivate::~QKeyMapperPrivate() +{ + // clearMappings(); +} + +void QKeyMapperPrivate::clearMappings() +{ +} + +QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e) +{ + QList<int> result = QGuiApplicationPrivate::platformIntegration()->possibleKeys(e); + if (!result.isEmpty()) + return result; + + if (e->key() && (e->key() != Qt::Key_unknown)) + result << int(e->key() + e->modifiers()); + else if (!e->text().isEmpty()) + result << int(e->text().at(0).unicode() + e->modifiers()); + return result; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qkeymapper_qpa.cpp b/src/gui/kernel/qkeymapper_qpa.cpp deleted file mode 100644 index 3966909db1..0000000000 --- a/src/gui/kernel/qkeymapper_qpa.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qkeymapper_p.h" -#include <qdebug.h> -#include <private/qevent_p.h> -#include <private/qlocale_p.h> -#include <private/qguiapplication_p.h> -#include <qpa/qplatformintegration.h> - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - - -QKeyMapperPrivate::QKeyMapperPrivate() -{ - keyboardInputLocale = QLocale::system(); - keyboardInputDirection = keyboardInputLocale.textDirection(); -} - -QKeyMapperPrivate::~QKeyMapperPrivate() -{ - // clearMappings(); -} - -void QKeyMapperPrivate::clearMappings() -{ -} - -QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e) -{ - QList<int> result = QGuiApplicationPrivate::platformIntegration()->possibleKeys(e); - if (!result.isEmpty()) - return result; - - if (e->key() && (e->key() != Qt::Key_unknown)) - result << int(e->key() + e->modifiers()); - else if (!e->text().isEmpty()) - result << int(e->text().at(0).unicode() + e->modifiers()); - return result; -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 59cdabbc0f..8261ac7208 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -490,7 +490,7 @@ static const struct { { Qt::Key_BrightnessAdjust, QT_TRANSLATE_NOOP("QShortcut", "Adjust Brightness") }, { Qt::Key_Finance, QT_TRANSLATE_NOOP("QShortcut", "Finance") }, { Qt::Key_Community, QT_TRANSLATE_NOOP("QShortcut", "Community") }, - { Qt::Key_AudioRewind, QT_TRANSLATE_NOOP("QShortcut", "Audio Rewind") }, + { Qt::Key_AudioRewind, QT_TRANSLATE_NOOP("QShortcut", "Media Rewind") }, { Qt::Key_BackForward, QT_TRANSLATE_NOOP("QShortcut", "Back Forward") }, { Qt::Key_ApplicationLeft, QT_TRANSLATE_NOOP("QShortcut", "Application Left") }, { Qt::Key_ApplicationRight, QT_TRANSLATE_NOOP("QShortcut", "Application Right") }, @@ -550,17 +550,40 @@ static const struct { { Qt::Key_Bluetooth, QT_TRANSLATE_NOOP("QShortcut", "Bluetooth") }, { Qt::Key_WLAN, QT_TRANSLATE_NOOP("QShortcut", "Wireless") }, { Qt::Key_UWB, QT_TRANSLATE_NOOP("QShortcut", "Ultra Wide Band") }, - { Qt::Key_AudioForward, QT_TRANSLATE_NOOP("QShortcut", "Audio Forward") }, + { Qt::Key_AudioForward, QT_TRANSLATE_NOOP("QShortcut", "Media Fast Forward") }, { Qt::Key_AudioRepeat, QT_TRANSLATE_NOOP("QShortcut", "Audio Repeat") }, { Qt::Key_AudioRandomPlay, QT_TRANSLATE_NOOP("QShortcut", "Audio Random Play") }, { Qt::Key_Subtitle, QT_TRANSLATE_NOOP("QShortcut", "Subtitle") }, { Qt::Key_AudioCycleTrack, QT_TRANSLATE_NOOP("QShortcut", "Audio Cycle Track") }, { Qt::Key_Time, QT_TRANSLATE_NOOP("QShortcut", "Time") }, - { Qt::Key_Select, QT_TRANSLATE_NOOP("QShortcut", "Select") }, + { Qt::Key_Hibernate, QT_TRANSLATE_NOOP("QShortcut", "Hibernate") }, { Qt::Key_View, QT_TRANSLATE_NOOP("QShortcut", "View") }, { Qt::Key_TopMenu, QT_TRANSLATE_NOOP("QShortcut", "Top Menu") }, + { Qt::Key_PowerDown, QT_TRANSLATE_NOOP("QShortcut", "Power Down") }, { Qt::Key_Suspend, QT_TRANSLATE_NOOP("QShortcut", "Suspend") }, - { Qt::Key_Hibernate, QT_TRANSLATE_NOOP("QShortcut", "Hibernate") }, + + { Qt::Key_MicMute, QT_TRANSLATE_NOOP("QShortcut", "Microphone Mute") }, + + { Qt::Key_Red, QT_TRANSLATE_NOOP("QShortcut", "Red") }, + { Qt::Key_Green, QT_TRANSLATE_NOOP("QShortcut", "Green") }, + { Qt::Key_Yellow, QT_TRANSLATE_NOOP("QShortcut", "Yellow") }, + { Qt::Key_Blue, QT_TRANSLATE_NOOP("QShortcut", "Blue") }, + + { Qt::Key_ChannelUp, QT_TRANSLATE_NOOP("QShortcut", "Channel Up") }, + { Qt::Key_ChannelDown, QT_TRANSLATE_NOOP("QShortcut", "Channel Down") }, + + { Qt::Key_Guide, QT_TRANSLATE_NOOP("QShortcut", "Guide") }, + { Qt::Key_Info, QT_TRANSLATE_NOOP("QShortcut", "Info") }, + { Qt::Key_Settings, QT_TRANSLATE_NOOP("QShortcut", "Settings") }, + + { Qt::Key_MicVolumeUp, QT_TRANSLATE_NOOP("QShortcut", "Microphone Volume Up") }, + { Qt::Key_MicVolumeDown, QT_TRANSLATE_NOOP("QShortcut", "Microphone Volume Down") }, + + { Qt::Key_New, QT_TRANSLATE_NOOP("QShortcut", "New") }, + { Qt::Key_Open, QT_TRANSLATE_NOOP("QShortcut", "Open") }, + { Qt::Key_Find, QT_TRANSLATE_NOOP("QShortcut", "Find") }, + { Qt::Key_Undo, QT_TRANSLATE_NOOP("QShortcut", "Undo") }, + { Qt::Key_Redo, QT_TRANSLATE_NOOP("QShortcut", "Redo") }, // -------------------------------------------------------------- // More consistent namings @@ -647,6 +670,7 @@ static const struct { { Qt::Key_Execute, QT_TRANSLATE_NOOP("QShortcut", "Execute") }, { Qt::Key_Play, QT_TRANSLATE_NOOP("QShortcut", "Play") }, { Qt::Key_Zoom, QT_TRANSLATE_NOOP("QShortcut", "Zoom") }, + { Qt::Key_Exit, QT_TRANSLATE_NOOP("QShortcut", "Exit") }, { 0, 0 } }; diff --git a/src/gui/kernel/qoffscreensurface.cpp b/src/gui/kernel/qoffscreensurface.cpp index 1625909843..003e3a0cc9 100644 --- a/src/gui/kernel/qoffscreensurface.cpp +++ b/src/gui/kernel/qoffscreensurface.cpp @@ -171,6 +171,9 @@ void QOffscreenSurface::create() if (QThread::currentThread() != qGuiApp->thread()) qWarning("Attempting to create QWindow-based QOffscreenSurface outside the gui thread. Expect failures."); d->offscreenWindow = new QWindow(d->screen); + // Remove this window from the global list since we do not want it to be destroyed when closing the app. + // The QOffscreenSurface has to be usable even after exiting the event loop. + QGuiApplicationPrivate::window_list.removeOne(d->offscreenWindow); d->offscreenWindow->setSurfaceType(QWindow::OpenGLSurface); d->offscreenWindow->setFormat(d->requestedFormat); d->offscreenWindow->setGeometry(0, 0, d->size.width(), d->size.height()); diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index be592153d2..c7f4e6455c 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -63,6 +63,7 @@ #ifndef QT_OPENGL_ES_2 #include <QOpenGLFunctions_1_0> +#include <QOpenGLFunctions_3_2_Core> #endif QT_BEGIN_NAMESPACE @@ -370,9 +371,25 @@ int QOpenGLContextPrivate::maxTextureSize() GLint size; GLint next = 64; funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - QOpenGLFunctions_1_0 *gl1funcs = q->versionFunctions<QOpenGLFunctions_1_0>(); - gl1funcs->initializeOpenGLFunctions(); - gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + + QOpenGLFunctions_1_0 *gl1funcs = 0; + QOpenGLFunctions_3_2_Core *gl3funcs = 0; + + if (q->format().profile() == QSurfaceFormat::CoreProfile) { + gl3funcs = q->versionFunctions<QOpenGLFunctions_3_2_Core>(); + gl3funcs->initializeOpenGLFunctions(); + } else { + gl1funcs = q->versionFunctions<QOpenGLFunctions_1_0>(); + gl1funcs->initializeOpenGLFunctions(); + } + + Q_ASSERT(gl1funcs || gl3funcs); + + if (gl1funcs) + gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + else + gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + if (size == 0) { return max_texture_size; } @@ -383,7 +400,11 @@ int QOpenGLContextPrivate::maxTextureSize() if (next > max_texture_size) break; funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); + if (gl1funcs) + gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); + else + gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); + } while (next > size); max_texture_size = size; @@ -486,6 +507,64 @@ void QOpenGLContext::setScreen(QScreen *screen) } /*! + Set the native handles for this context. When create() is called and a + native handle is set, configuration settings, like format(), are ignored + since this QOpenGLContext will wrap an already created native context + instead of creating a new one from scratch. + + On some platforms the native context handle is not sufficient and other + related handles (for example, for a window or display) have to be provided + in addition. Therefore \a handle is variant containing a platform-specific + value type. These classes can be found in the QtPlatformHeaders module. + + When create() is called with native handles set, the handles' ownership are + not taken, meaning that destroy() will not destroy the native context. + + \note Some frameworks track the current context and surfaces internally. + Making the adopted QOpenGLContext current via Qt will have no effect on such + other frameworks' internal state. Therefore a subsequent makeCurrent done + via the other framework may have no effect. It is therefore advisable to + make explicit calls to make no context and surface current to reset the + other frameworks' internal state after performing OpenGL operations via Qt. + + \note Using foreign contexts with Qt windows and Qt contexts with windows + and surfaces created by other frameworks may give unexpected results, + depending on the platform, due to potential mismatches in context and window + pixel formats. To make sure this does not happen, avoid making contexts and + surfaces from different frameworks current together. Instead, prefer + approaches based on context sharing where OpenGL resources like textures are + accessible both from Qt's and the foreign framework's contexts. + + \since 5.4 + \sa nativeHandle() +*/ +void QOpenGLContext::setNativeHandle(const QVariant &handle) +{ + Q_D(QOpenGLContext); + d->nativeHandle = handle; +} + +/*! + Returns the native handle for the context. + + This function provides access to the QOpenGLContext's underlying native + context. The returned variant contains a platform-specific value type. These + classes can be found in the module QtPlatformHeaders. + + On platforms where retrieving the native handle is not supported, or if + neither create() nor setNativeHandle() was called, a null variant is + returned. + + \since 5.4 + \sa setNativeHandle() + */ +QVariant QOpenGLContext::nativeHandle() const +{ + Q_D(const QOpenGLContext); + return d->nativeHandle; +} + +/*! Attempts to create the OpenGL context with the current configuration. The current configuration includes the format, the share context, and the @@ -506,7 +585,8 @@ void QOpenGLContext::setScreen(QScreen *screen) */ bool QOpenGLContext::create() { - destroy(); + if (isValid()) + destroy(); Q_D(QOpenGLContext); d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this); @@ -556,6 +636,7 @@ void QOpenGLContext::destroy() d->versionFunctionsBackend.clear(); delete d->textureFunctions; d->textureFunctions = 0; + d->nativeHandle = QVariant(); } /*! diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index 19aecee75a..99f2fece51 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -64,6 +64,7 @@ #include <QtCore/qhash.h> #include <QtCore/qpair.h> +#include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -153,6 +154,7 @@ public: void setFormat(const QSurfaceFormat &format); void setShareContext(QOpenGLContext *shareContext); void setScreen(QScreen *screen); + void setNativeHandle(const QVariant &handle); bool create(); bool isValid() const; @@ -161,6 +163,7 @@ public: QOpenGLContext *shareContext() const; QOpenGLContextGroup *shareGroup() const; QScreen *screen() const; + QVariant nativeHandle() const; GLuint defaultFramebufferObject() const; @@ -242,4 +245,4 @@ QT_END_NAMESPACE #endif // QT_NO_OPENGL -#endif // QGUIGLCONTEXT_H +#endif // QOPENGLCONTEXT_H diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h index 711a3b1b2f..77e3605a4b 100644 --- a/src/gui/kernel/qopenglcontext_p.h +++ b/src/gui/kernel/qopenglcontext_p.h @@ -205,7 +205,6 @@ public: , surface(0) , functions(0) , textureFunctions(0) - , current_fbo(0) , max_texture_size(-1) , workaround_brokenFBOReadBack(false) , workaround_brokenTexSubImage(false) @@ -236,7 +235,6 @@ public: mutable QSet<QByteArray> extensionNames; QOpenGLTextureHelper* textureFunctions; - GLuint current_fbo; GLint max_texture_size; bool workaround_brokenFBOReadBack; @@ -245,6 +243,8 @@ public: QPaintEngineEx *active_engine; + QVariant nativeHandle; + static QOpenGLContext *setCurrentContext(QOpenGLContext *context); static void setGlobalShareContext(QOpenGLContext *context); diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index f284c20af5..62e555b821 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -1141,9 +1141,33 @@ Q_GUI_EXPORT QPalette qt_fusionPalette() } #ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug dbg, const QPalette &) +QDebug operator<<(QDebug dbg, const QPalette &p) { - dbg.nospace() << "QPalette()"; + const char *colorGroupNames[] = {"Active", "Disabled", "Inactive"}; + const char *colorRoleNames[] = + {"WindowText", "Button", "Light", "Midlight", "Dark", "Mid", "Text", + "BrightText", "ButtonText", "Base", "Window", "Shadow", "Highlight", + "HighlightedText", "Link", "LinkVisited", "AlternateBase", "NoRole", + "ToolTipBase","ToolTipText" }; + QDebug nospace = dbg.nospace(); + const uint mask = p.resolve(); + nospace << "QPalette(resolve=" << hex << showbase << mask << ','; + for (int role = 0; role < (int)QPalette::NColorRoles; ++role) { + if (mask & (1<<role)) { + if (role) + nospace << ','; + nospace << colorRoleNames[role] << ":["; + for (int group = 0; group < (int)QPalette::NColorGroups; ++group) { + if (group) + nospace << ','; + const QRgb color = p.color(static_cast<QPalette::ColorGroup>(group), + static_cast<QPalette::ColorRole>(role)).rgba(); + nospace << colorGroupNames[group] << ':' << color; + } + nospace << ']'; + } + } + nospace << ')' << noshowbase << dec; return dbg.space(); } #endif diff --git a/src/gui/kernel/qpixelformat.cpp b/src/gui/kernel/qpixelformat.cpp new file mode 100644 index 0000000000..1e3345ee7a --- /dev/null +++ b/src/gui/kernel/qpixelformat.cpp @@ -0,0 +1,630 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpixelformat.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QPixelFormat + \inmodule QtGui + \since 5.4 + \brief QPixelFormat is a class for describing different pixel + layouts in graphics buffers + + In Qt there is a often a need to represent the layout of the pixels in a + graphics buffer. Internally QPixelFormat stores everything in a 64 bit + datastructure. This gives performance but also some limitations. + + QPixelFormat can describe 5 color channels and 1 alpha channel, each can use + 6 bits to describe the size of the color channel. + + The position of the alpha channel is described with a separate enum. This is + to make it possible to describe QImage formats like ARGB32, and also + describe typical OpenGL formats like RBGA8888. + + How pixels are suppose to be read is determined by the TypeInterpretation + enum. It describes if color values are suppose to be read byte per byte, + or if a pixel is suppose to be read as a complete int and then masked. + \sa TypeInterpretation + + There is no support for describing YUV's macro pixels. Instead a list of YUV + formats has been made. When a QPixelFormat is describing a YUV format, the + bitsPerPixel value has been deduced by the YUV Layout enum. Also, the color + channels should all be set to zero except the fifth color channel that + should store the bitsPerPixel value. +*/ + +/*! + \enum QPixelFormat::ColorModel + + This enum type is used to describe the color model of the pixelformat. + + \value RGB The color model is RGB. + + \value BGR This is logically the opposite endian version of RGB. However, + for ease of use it has its own model. + + \value Indexed The color model uses a color palette. + + \value Grayscale The color model is Grayscale. + + \value CMYK The color model is CMYK. + + \value HSL The color model is HSL. + + \value HSV The color model is HSV. + + \value YUV The color model is YUV. +*/ + +/*! + \enum QPixelFormat::AlphaUsage + + This enum describes if the alpha channel is used or not. Sometimes the + pixelformat will have a size for the alpha channel, but the pixel format + does actually not use the alpha channel. For example RGB32 is such a + format. The RGB channels are 8 bits each, and there is no alpha channel. + But the complete size for each pixel is 32. Therefore the alpha channel size + is 8, but the alpha channel is ignored. Its important to note that in such + situations the position of the alpha channel is significant. + + \value IgnoresAlpha The alpha channel is not used. + + \value UsesAlpha The alpha channel is used. +*/ + +/*! + \enum QPixelFormat::AlphaPosition + + This enum type is used to describe the alpha channels position relative to the + color channels. + + \value AtBeginning The alpha channel will be put in front of the color + channels . E.g. ARGB. + + \value AtEnd The alpha channel will be put in the back of the color + channels. E.g. RGBA. +*/ + +/*! + \enum QPixelFormat::AlphaPremultiplied + + This enum type describes the boolean state if the alpha channel is multiplied + into the color channels or not. + + \value NotPremultiplied The alpha channel is not multiplied into the color channels. + + \value Premultiplied The alpha channel is multiplied into the color channels. +*/ + +/*! + \enum QPixelFormat::TypeInterpretation + + This enum describes how each pixel is interpreted. If a pixel is read as a + full 32 bit unsigned integer and then each channel is masked out, or if + each byte is read as unsigned char values. Typically QImage formats + interpret one pixel as an unsigned integer and then the color channels are + masked out. OpenGL on the other hand typically interpreted pixels "one byte + after the other", Ie. unsigned byte. + + QImage also have the format Format_RGBA8888 (and its derivatives), where + the pixels are interpreted as unsigned bytes. OpenGL has extensions that makes it + possible to upload pixel buffers in an unsigned integer format. + + \image qpixelformat-argb32buffer.png An unsigned integer ARGB32 pixel. + + The image above shows a ARGB pixel in memory read as an unsigned integer. + However, if this pixel was read byte for byte on a little endian system the + first byte would be the byte containing the B-channel. The next byte would + be the G-channel, then the R-channel and finally the A-channel. This shows + that on little endian systems, how each pixel is interpreted is significant + for integer formats. This is not the case on big endian systems. + + \value UnsignedInteger + \value UnsignedShort + \value UnsignedByte + \value FloatingPoint +*/ + +/*! + \enum QPixelFormat::ByteOrder + + This enum describes the ByteOrder of the pixel format. This enum is mostly + ignored but have some use cases for YUV formats. BGR formats have their own + color model, and should not be described by using the opposite endianness + on an RGB format. + + \value LittleEndian The byte order is little endian. + \value BigEndian The byte order is big endian. + \value CurrentSystemEndian This enum will not be stored, but is converted in + the constructor to the endian enum that matches + the enum of the current system. + +*/ + +/*! + \enum QPixelFormat::YUVLayout + + YUV is not represented by describing the size of the color channels. This is + because YUV often use macro pixels, making the concept of sperate color channels + invalid. Instead the different YUV layouts are described with this enum. + + \value YUV444 + \value YUV422 + \value YUV411 + \value YUV420P + \value YUV420SP + \value YV12 + \value UYVY + \value YUYV + \value NV12 + \value NV21 + \value IMC1 + \value IMC2 + \value IMC3 + \value IMC4 + \value Y8 + \value Y16 +*/ + +/*! + \fn QPixelFormat::QPixelFormat() + + Creates a null pixelformat. This format maps to QImage::Format_Invalid. +*/ + +/*! + \fn QPixelFormat::QPixelFormat(ColorModel colorModel, + uchar firstSize, + uchar secondSize, + uchar thirdSize, + uchar fourthSize, + uchar fifthSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied, + TypeInterpretation typeInterpretation, + ByteOrder byteOrder = CurrentSystemEndian, + uchar subEnum = 0) + + Creates a QPixelFormat which assigns its data to the attributes. + \a colorModel will be put into a buffer which is 4 bits long. + + \a firstSize \a secondSize \a thirdSize \a fourthSize \a fifthSize \a + alphaSize are all meant to represent the size of a channel. The channels will + be used for different uses dependent on the \a colorModel. For RGB the + firstSize will represent the Red channel. On CMYK it will represent the + value of the Cyan channel. + + \a alphaUsage represents if the alpha channel is used or not. + + \a alphaPosition is the position of the alpha channel. + + \a premultiplied represents if the alpha channel is already multiplied with + the color channels. + + \a typeInterpretation is how the pixel is interpreted. + + \a byteOrder represents the endianness of the pixelformat. This defaults to + CurrentSystemEndian. + + \a subEnum is used for colorModels that have to store some extra + information with supplying an extra enum. This is used by YUV to store the + YUV type The default value is 0. +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatRgb) == sizeof(QPixelFormat)); + +/*! + \class QPixelFormatRgb + \inmodule QtGui + \since 5.4 + \brief QPixelFormatRgb is a helper class for creating pixel formats with + the rgb color model + + The size of QPixelFormatRgb is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatRgb::QPixelFormatRgb(uchar redSize, + uchar greenSize, + uchar blueSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedInteger) + + Constructor making an RGB pixelformat. \a redSize \a greenSize \a + blueSize represent the size of each color channel. \a alphaSize describes + the alpha channel size and its position is described with \a alphaPosition. + \a alphaUsage is used to determine if the alpha channel is used or not. + Setting the alpha channel size to 8 and alphaUsage to IgnoresAlpha is how + it is possible to create a 32 bit format where the rgb channels only use 24 + bits combined. \a premultiplied \a typeInterpretation are + accessible with accessors with the same name. + + \sa TypeInterpretation +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatGrayScale) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatGrayScale + \inmodule QtGui + \since 5.4 + \brief QPixelFormatGrayScale is a helper class for creating pixel formats with + the gray scale color model. + + The size of QPixelFormatGrayScale is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatGrayScale::QPixelFormatGrayScale(uchar channelSize, + TypeInterpretation typeInterpretation = UnsignedInteger) + + Constructor for creating a Grayscale format. Monochrome formats can be + described by passing 1 to \a channelSize. Its also possible to define very + accurate greyscale formats using doubles to describe each pixel by passing 8 + as \a channelSize and FloatingPoint as \a typeInterpretation. + + \sa TypeInterpretation +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatCmyk) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatCmyk + \inmodule QtGui + \since 5.4 + \brief QPixelFormatCmyk is a helper class for creating pixel formats with + the CMYK color model + + The size of QPixelFormatCmyk is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatCmyk::QPixelFormatCmyk(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = UnsignedInteger) + + Constructor for creating CMYK formats. The channel count will be 4 or + 5 depending on if \a alphaSize is bigger than zero or not. The CMYK color + channels will all be set to the value of \a channelSize. + + \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with + the accessors with the same name. + + \sa TypeInterpretation +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatHsl) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatHsl + \inmodule QtGui + \since 5.4 + \brief QPixelFormatHsl is a helper class for creating pixel formats with + the HSL color model. + + The size of QPixelFormatHsl is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatHsl::QPixelFormatHsl(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) + + Constructor for creating HSL formats. The channel count will be 3 or 4 + depending on if \a alphaSize is bigger than 0. + + \a channelSize will set the hueSize saturationSize and lightnessSize to the same value. + + \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with + the accessors with the same name. +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatHsv) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatHsv + \inmodule QtGui + \since 5.4 + \brief QPixelFormatHsv is a helper class for creating pixel formats with + the HSV color model. + + The size of QPixelFormatHsv is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatHsv::QPixelFormatHsv(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) + + Constructor for creating HSV formats. The channel count will be 3 or 4 + depending on if \a alphaSize is bigger than 0. + + \a channelSize will set the hueSize saturationSize and brightnessSize to the same value. + + \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with + the accessors with the same name. +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatYuv) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatYuv + \inmodule QtGui + \since 5.4 + \brief QPixelFormatYuv is a helper class for creating pixel formats with + the YUV color model. + + The size of QPixelFormatYuv is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatYuv::QPixelFormatYuv(YUVLayout yuvLayout, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedByte, + ByteOrder byteOrder = LittleEndian) + + Constructor for creating a QPixelFormat describing a YUV format with + \a yuvLayout. \a alphaSize describes the size of a potential alpha channel + and is position is described with \a alphaPosition. The "first" "second" .. + "fifth" channels are all set to 0. \a alphaUsage \a premultiplied \a + typeInterpretation and \a byteOrder will work as with other formats. +*/ + +/*! + \fn ColorModel QPixelFormat::colorModel() const + + Accessor function for getting the colorModel. +*/ + +/*! + \fn uchar QPixelFormat::channelCount() const + + Accessor function for getting the channelCount. Channel Count is deduced + by color channels with a size > 0 and if the size of the alpha channel is > 0. +*/ + +/*! + \fn uchar QPixelFormat::redSize() const + + Accessor function for the size of the red color channel. +*/ + +/*! + \fn uchar QPixelFormat::greenSize() const + + Accessor function for the size of the green color channel. +*/ + +/*! + \fn uchar QPixelFormat::blueSize() const + + Accessor function for the size of the blue color channel. +*/ + +/*! + \fn uchar QPixelFormat::cyanSize() const + + Accessor function for the cyan color channel. +*/ + +/*! + \fn uchar QPixelFormat::magentaSize() const + + Accessor function for the megenta color channel. +*/ + +/*! + \fn uchar QPixelFormat::yellowSize() const + + Accessor function for the yellow color channel. +*/ + +/*! + \fn uchar QPixelFormat::blackSize() const + + Accessor function for the black/key color channel. +*/ + +/*! + \fn uchar QPixelFormat::hueSize() const + + Accessor function for the hue channel size. +*/ + +/*! + \fn uchar QPixelFormat::saturationSize() const + + Accessor function for the saturation channel size. +*/ + +/*! + \fn uchar QPixelFormat::lightnessSize() const + + Accessor function for the lightness channel size. +*/ + +/*! + \fn uchar QPixelFormat::brightnessSize() const + + Accessor function for the brightness channel size. +*/ + +/*! + \fn uchar QPixelFormat::alphaSize() const + + Accessor function for the alpha channel size. +*/ + +/*! + \fn uchar QPixelFormat::bitsPerPixel() const + + Accessor function for the bits used per pixel. This function returns the + sum of the color channels + the size of the alpha channel. +*/ + +/*! + \fn AlphaPremultiplied QPixelFormat::premultiplied() const + + Accessor function for the AlphaPremultiplied enum. This indicates if the + alpha channel is multiplied in to the color channels. + +*/ + +/*! + \fn TypeInterpretation QPixelFormat::typeInterpretation() const + + Accessor function for the type representation of a color channel or a pixel. + + \sa TypeInterpretation +*/ + +/*! + \fn ByteOrder QPixelFormat::byteOrder() const + + The byte order is almost always set the the byte order of the current + system. However, it can be useful to describe some YUV formats. This + function should never return QPixelFormat::CurrentSystemEndian as this + value is translated to a endian value in the constructor. +*/ + +/*! + \fn AlphaUsage QPixelFormat::alphaUsage() const + + Accessor function for alphaUsage. +*/ + +/*! + \fn AlphaPosition QPixelFormat::alphaPosition() const + + Accessor function for alphaPosition. +*/ + +/*! + \fn YUVLayout QPixelFormat::yuvLayout() const + + Accessor function for the YUVLayout. It is difficult to describe the color + channels of a YUV pixel format since YUV color model uses macro pixels. + Instead the layout of the pixels are stored as an enum. +*/ + +/*! + \fn uchar QPixelFormat::subEnum() const + + Accessor for the datapart which contains subEnums + This is the same as the yuvLayout() function. + + \sa yuvLayout() + \internal +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormat) == sizeof(quint64)); + + +namespace QtPrivate { + QPixelFormat QPixelFormat_createYUV(QPixelFormat::YUVLayout yuvLayout, + uchar alphaSize, + QPixelFormat::AlphaUsage alphaUsage, + QPixelFormat::AlphaPosition alphaPosition, + QPixelFormat::AlphaPremultiplied premultiplied, + QPixelFormat::TypeInterpretation typeInterpretation, + QPixelFormat::ByteOrder byteOrder) + { + uchar bits_per_pixel = 0; + switch (yuvLayout) { + case QPixelFormat::YUV444: + bits_per_pixel = 24; + break; + case QPixelFormat::YUV422: + bits_per_pixel = 16; + break; + case QPixelFormat::YUV411: + case QPixelFormat::YUV420P: + case QPixelFormat::YUV420SP: + case QPixelFormat::YV12: + bits_per_pixel = 12; + break; + case QPixelFormat::UYVY: + case QPixelFormat::YUYV: + bits_per_pixel = 16; + break; + case QPixelFormat::NV12: + case QPixelFormat::NV21: + bits_per_pixel = 12; + break; + case QPixelFormat::IMC1: + case QPixelFormat::IMC2: + case QPixelFormat::IMC3: + case QPixelFormat::IMC4: + bits_per_pixel = 12; + break; + case QPixelFormat::Y8: + bits_per_pixel = 8; + break; + case QPixelFormat::Y16: + bits_per_pixel = 16; + break; + } + + return QPixelFormat(QPixelFormat::YUV, + 0, 0, 0, 0, + bits_per_pixel, + alphaSize, + alphaUsage, + alphaPosition, + premultiplied, + typeInterpretation, + byteOrder, + yuvLayout); + } +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qpixelformat.h b/src/gui/kernel/qpixelformat.h new file mode 100644 index 0000000000..0e5df679f8 --- /dev/null +++ b/src/gui/kernel/qpixelformat.h @@ -0,0 +1,452 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPIXELFORMAT_H +#define QPIXELFORMAT_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +class QPixelFormat +{ +public: + enum ColorModel { + RGB, + BGR, + Indexed, + Grayscale, + CMYK, + HSL, + HSV, + YUV + }; + + enum AlphaUsage { + UsesAlpha, + IgnoresAlpha + }; + + enum AlphaPosition { + AtBeginning, + AtEnd + }; + + enum AlphaPremultiplied { + NotPremultiplied, + Premultiplied + }; + + enum TypeInterpretation { + UnsignedInteger, + UnsignedShort, + UnsignedByte, + FloatingPoint + }; + + enum YUVLayout { + YUV444, + YUV422, + YUV411, + YUV420P, + YUV420SP, + YV12, + UYVY, + YUYV, + NV12, + NV21, + IMC1, + IMC2, + IMC3, + IMC4, + Y8, + Y16 + }; + + enum ByteOrder { + LittleEndian, + BigEndian, + CurrentSystemEndian + }; + + Q_DECL_CONSTEXPR inline QPixelFormat() Q_DECL_NOTHROW; + Q_DECL_CONSTEXPR inline QPixelFormat(ColorModel colorModel, + uchar firstSize, + uchar secondSize, + uchar thirdSize, + uchar fourthSize, + uchar fifthSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied, + TypeInterpretation typeInterpretation, + ByteOrder byteOrder = CurrentSystemEndian, + uchar subEnum = 0) Q_DECL_NOTHROW; + + Q_DECL_CONSTEXPR inline ColorModel colorModel() const Q_DECL_NOTHROW { return ColorModel(model); } + Q_DECL_CONSTEXPR inline uchar channelCount() const Q_DECL_NOTHROW { return (first > 0) + + (second > 0) + + (third > 0) + + (fourth > 0) + + (fifth > 0) + + (alpha > 0); } + + Q_DECL_CONSTEXPR inline uchar redSize() const Q_DECL_NOTHROW { return first; } + Q_DECL_CONSTEXPR inline uchar greenSize() const Q_DECL_NOTHROW { return second; } + Q_DECL_CONSTEXPR inline uchar blueSize() const Q_DECL_NOTHROW { return third; } + + Q_DECL_CONSTEXPR inline uchar cyanSize() const Q_DECL_NOTHROW { return first; } + Q_DECL_CONSTEXPR inline uchar magentaSize() const Q_DECL_NOTHROW { return second; } + Q_DECL_CONSTEXPR inline uchar yellowSize() const Q_DECL_NOTHROW { return third; } + Q_DECL_CONSTEXPR inline uchar blackSize() const Q_DECL_NOTHROW { return fourth; } + + Q_DECL_CONSTEXPR inline uchar hueSize() const Q_DECL_NOTHROW { return first; } + Q_DECL_CONSTEXPR inline uchar saturationSize() const Q_DECL_NOTHROW { return second; } + Q_DECL_CONSTEXPR inline uchar lightnessSize() const Q_DECL_NOTHROW { return third; } + Q_DECL_CONSTEXPR inline uchar brightnessSize() const Q_DECL_NOTHROW { return third; } + + Q_DECL_CONSTEXPR inline uchar alphaSize() const Q_DECL_NOTHROW { return alpha; } + + Q_DECL_CONSTEXPR inline uchar bitsPerPixel() const Q_DECL_NOTHROW { return first + + second + + third + + fourth + + fifth + + alpha; } + + Q_DECL_CONSTEXPR inline AlphaUsage alphaUsage() const Q_DECL_NOTHROW { return AlphaUsage(alpha_usage); } + Q_DECL_CONSTEXPR inline AlphaPosition alphaPosition() const Q_DECL_NOTHROW { return AlphaPosition(alpha_position); } + Q_DECL_CONSTEXPR inline AlphaPremultiplied premultiplied() const Q_DECL_NOTHROW { return AlphaPremultiplied(premul); } + Q_DECL_CONSTEXPR inline TypeInterpretation typeInterpretation() const Q_DECL_NOTHROW { return TypeInterpretation(type_interpretation); } + Q_DECL_CONSTEXPR inline ByteOrder byteOrder() const Q_DECL_NOTHROW { return ByteOrder(byte_order); } + + Q_DECL_CONSTEXPR inline YUVLayout yuvLayout() const Q_DECL_NOTHROW { return YUVLayout(sub_enum); } + Q_DECL_CONSTEXPR inline uchar subEnum() const Q_DECL_NOTHROW { return sub_enum; } + +protected: + quint64 model : 4; + quint64 first : 6; + quint64 second : 6; + quint64 third : 6; + quint64 fourth : 6; + quint64 fifth : 6; + quint64 alpha : 6; + quint64 alpha_usage : 1; + quint64 alpha_position : 1; + quint64 premul: 1; + quint64 type_interpretation : 4; + quint64 byte_order : 2; + quint64 sub_enum : 6; + quint64 unused : 8; + + friend Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator==(const QPixelFormat &fmt1, const QPixelFormat &fmt2); + friend Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator!=(const QPixelFormat &fmt1, const QPixelFormat &fmt2); +}; +Q_DECLARE_TYPEINFO(QPixelFormat, Q_PRIMITIVE_TYPE); + +class QPixelFormatRgb : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatRgb(uchar redSize, + uchar greenSize, + uchar blueSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedInteger) Q_DECL_NOTHROW; +}; + +class QPixelFormatGrayScale : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatGrayScale(uchar bufferSize, + TypeInterpretation typeInterpretation = UnsignedInteger) Q_DECL_NOTHROW; +}; + +class QPixelFormatCmyk : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatCmyk(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = UnsignedInteger) Q_DECL_NOTHROW; +}; + +class QPixelFormatHsl : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatHsl(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) Q_DECL_NOTHROW; +}; + +class QPixelFormatHsv : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatHsv(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) Q_DECL_NOTHROW; +}; + +namespace QtPrivate { + QPixelFormat Q_GUI_EXPORT QPixelFormat_createYUV(QPixelFormat::YUVLayout yuvLayout, + uchar alphaSize, + QPixelFormat::AlphaUsage alphaUsage, + QPixelFormat::AlphaPosition alphaPosition, + QPixelFormat::AlphaPremultiplied premultiplied, + QPixelFormat::TypeInterpretation typeInterpretation, + QPixelFormat::ByteOrder byteOrder); +} + +class QPixelFormatYuv : public QPixelFormat +{ +public: + inline QPixelFormatYuv(YUVLayout yuvLayout, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedByte, + ByteOrder byteOrder = LittleEndian); +}; + +Q_DECL_CONSTEXPR +QPixelFormat::QPixelFormat() Q_DECL_NOTHROW + : model(0) + , first(0) + , second(0) + , third(0) + , fourth(0) + , fifth(0) + , alpha(0) + , alpha_usage(0) + , alpha_position(0) + , premul(0) + , type_interpretation(0) + , byte_order(0) + , sub_enum(0) + , unused(0) +{ +} + +Q_DECL_CONSTEXPR +QPixelFormat::QPixelFormat(ColorModel mdl, + uchar firstSize, + uchar secondSize, + uchar thirdSize, + uchar fourthSize, + uchar fifthSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + AlphaPremultiplied premult, + TypeInterpretation typeInterp, + ByteOrder b_order, + uchar s_enum) Q_DECL_NOTHROW + : model(mdl) + , first(firstSize) + , second(secondSize) + , third(thirdSize) + , fourth(fourthSize) + , fifth(fifthSize) + , alpha(alfa) + , alpha_usage(usage) + , alpha_position(position) + , premul(premult) + , type_interpretation(typeInterp) +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + , byte_order(b_order == CurrentSystemEndian ? LittleEndian : b_order) +#else + , byte_order(b_order == CurrentSystemEndian ? BigEndian : b_order) +#endif + , sub_enum(s_enum) + , unused(0) +{ +} + +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator==(const QPixelFormat &fmt1, const QPixelFormat &fmt2) +{ + return fmt1.model == fmt2.model + && fmt1.first == fmt2.first + && fmt1.second == fmt2.second + && fmt1.third == fmt2.third + && fmt1.fourth == fmt2.fourth + && fmt1.fifth == fmt2.fifth + && fmt1.alpha == fmt2.alpha + && fmt1.alpha_usage == fmt2.alpha_usage + && fmt1.alpha_position == fmt2.alpha_position + && fmt1.premul == fmt2.premul + && fmt1.type_interpretation == fmt2.type_interpretation + && fmt1.byte_order == fmt2.byte_order + && fmt1.sub_enum == fmt2.sub_enum + && fmt1.unused == fmt2.unused; +} + +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator!=(const QPixelFormat &fmt1, const QPixelFormat &fmt2) +{ return !(fmt1 == fmt2); } + +Q_DECL_CONSTEXPR +QPixelFormatRgb::QPixelFormatRgb(uchar red, + uchar green, + uchar blue, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + AlphaPremultiplied pmul, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(RGB, + red, + green, + blue, + 0, + 0, + alfa, + usage, + position, + pmul, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatGrayScale::QPixelFormatGrayScale(uchar channelSize, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(Grayscale, + channelSize, + 0, + 0, + 0, + 0, + 0, + IgnoresAlpha, + AtBeginning, + NotPremultiplied, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatCmyk::QPixelFormatCmyk(uchar channelSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(CMYK, + channelSize, + channelSize, + channelSize, + channelSize, + 0, + alfa, + usage, + position, + NotPremultiplied, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatHsl::QPixelFormatHsl(uchar channelSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(HSL, + channelSize, + channelSize, + channelSize, + 0, + 0, + alfa, + usage, + position, + NotPremultiplied, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatHsv::QPixelFormatHsv(uchar channelSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(HSV, + channelSize, + channelSize, + channelSize, + 0, + 0, + alfa, + usage, + position, + NotPremultiplied, + typeInt) +{ } + +QPixelFormatYuv::QPixelFormatYuv(YUVLayout layout, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + AlphaPremultiplied p_mul, + TypeInterpretation typeInt, + ByteOrder b_order) + : QPixelFormat(QtPrivate::QPixelFormat_createYUV(layout, + alfa, + usage, + position, + p_mul, + typeInt, + b_order)) + +{ } + +QT_END_NAMESPACE + +#endif //QPIXELFORMAT_H diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index da192a8e25..f20482a859 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -271,13 +271,32 @@ QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::Pix } #ifndef QT_NO_OPENGL +/*! + Factory function for QPlatformOpenGLContext. The \a context parameter is a pointer to + the context for which a platform-specific context backend needs to be + created. Configuration settings like the format, share context and screen have to be + taken from this QOpenGLContext and the resulting platform context is expected to be + backed by a native context that fulfills these criteria. + + If the context has native handles set, no new native context is expected to be created. + Instead, the provided handles have to be used. In this case the ownership of the handle + must not be taken and the platform implementation is not allowed to destroy the native + context. Configuration parameters like the format are also to be ignored. Instead, the + platform implementation is responsible for querying the configuriation from the provided + native context. + + Returns a pointer to a QPlatformOpenGLContext instance or \c NULL if the context could + not be created. + + \sa QOpenGLContext +*/ QPlatformOpenGLContext *QPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { Q_UNUSED(context); qWarning("This plugin does not support createPlatformOpenGLContext!"); return 0; } -#endif +#endif // QT_NO_OPENGL /*! Factory function for QPlatformSharedGraphicsCache. This function will return 0 if the platform diff --git a/src/gui/kernel/qplatformnativeinterface.cpp b/src/gui/kernel/qplatformnativeinterface.cpp index 6571a47849..2e5485f1c2 100644 --- a/src/gui/kernel/qplatformnativeinterface.cpp +++ b/src/gui/kernel/qplatformnativeinterface.cpp @@ -118,6 +118,12 @@ QPlatformNativeInterface::NativeResourceForBackingStoreFunction QPlatformNativeI return 0; } +QFunctionPointer QPlatformNativeInterface::platformFunction(const QByteArray &function) const +{ + Q_UNUSED(function); + return Q_NULLPTR; +} + /*! Contains generic window properties that the platform may utilize. */ diff --git a/src/gui/kernel/qplatformnativeinterface.h b/src/gui/kernel/qplatformnativeinterface.h index eaa24a9e55..58d13c4320 100644 --- a/src/gui/kernel/qplatformnativeinterface.h +++ b/src/gui/kernel/qplatformnativeinterface.h @@ -85,6 +85,8 @@ public: virtual NativeResourceForWindowFunction nativeResourceFunctionForWindow(const QByteArray &resource); virtual NativeResourceForBackingStoreFunction nativeResourceFunctionForBackingStore(const QByteArray &resource); + virtual QFunctionPointer platformFunction(const QByteArray &function) const; + virtual QVariantMap windowProperties(QPlatformWindow *window) const; virtual QVariant windowProperty(QPlatformWindow *window, const QString &name) const; virtual QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const; diff --git a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp b/src/gui/kernel/qplatformsystemtrayicon.cpp index bc37f99210..bc37f99210 100644 --- a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp +++ b/src/gui/kernel/qplatformsystemtrayicon.cpp diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index faaf418522..bb7b690992 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -474,6 +474,29 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString & } /*! + Helper function for finding the new screen for \a newGeometry in response to + a geometry changed event. Returns the new screen if the window was moved to + another virtual sibling. If the screen changes, the platform plugin should call + QWindowSystemInterface::handleWindowScreenChanged(). + \note: The current screen will always be returned for child windows since + they should never signal screen changes. + + \since 5.4 + \sa QWindowSystemInterface::handleWindowScreenChanged() +*/ +QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const +{ + QPlatformScreen *currentScreen = screen(); + if (!parent() && !currentScreen->geometry().intersects(newGeometry)) { + Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) { + if (screen->geometry().intersects(newGeometry)) + return screen; + } + } + return currentScreen; +} + +/*! Reimplement this method to set whether the window demands attention (for example, by flashing the taskbar icon) depending on \a enabled. diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 39bd8324a0..8f0e5ff352 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -139,6 +139,7 @@ public: protected: static QString formatWindowTitle(const QString &title, const QString &separator); + QPlatformScreen *screenForGeometry(const QRect &newGeometry) const; QScopedPointer<QPlatformWindowPrivate> d_ptr; private: diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 70ee631fc8..90f48d4593 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -74,6 +74,16 @@ QScreen::QScreen(QPlatformScreen *screen) { } + +/*! + Destroys the screen. + */ +QScreen::~QScreen() +{ + if (qApp) + Q_EMIT qApp->screenRemoved(this); +} + /*! Get the platform screen handle. */ diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h index bdd5939657..9e439f5a20 100644 --- a/src/gui/kernel/qscreen.h +++ b/src/gui/kernel/qscreen.h @@ -89,6 +89,7 @@ class Q_GUI_EXPORT QScreen : public QObject Q_PROPERTY(qreal refreshRate READ refreshRate NOTIFY refreshRateChanged) public: + ~QScreen(); QPlatformScreen *handle() const; QString name() const; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index d6f9fad070..8159b7746e 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -156,9 +156,7 @@ QWindow::QWindow(QScreen *targetScreen) , QSurface(QSurface::Window) { Q_D(QWindow); - d->screen = targetScreen; - if (!d->screen) - d->screen = QGuiApplication::primaryScreen(); + d->connectToScreen(targetScreen ? targetScreen : QGuiApplication::primaryScreen()); d->init(); } @@ -178,10 +176,8 @@ QWindow::QWindow(QWindow *parent) { Q_D(QWindow); d->parentWindow = parent; - if (parent) - d->screen = parent->screen(); - if (!d->screen) - d->screen = QGuiApplication::primaryScreen(); + if (!parent) + d->connectToScreen(QGuiApplication::primaryScreen()); d->init(); } @@ -203,10 +199,8 @@ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent) { Q_D(QWindow); d->parentWindow = parent; - if (parent) - d->screen = parent->screen(); - if (!d->screen) - d->screen = QGuiApplication::primaryScreen(); + if (!parent) + d->connectToScreen(QGuiApplication::primaryScreen()); d->init(); } @@ -215,14 +209,8 @@ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent) */ QWindow::~QWindow() { - if (QGuiApplicationPrivate::focus_window == this) - QGuiApplicationPrivate::focus_window = 0; - if (QGuiApplicationPrivate::currentMouseWindow == this) - QGuiApplicationPrivate::currentMouseWindow = 0; - if (QGuiApplicationPrivate::tabletPressTarget == this) - QGuiApplicationPrivate::tabletPressTarget = 0; - QGuiApplicationPrivate::window_list.removeAll(this); destroy(); + QGuiApplicationPrivate::window_list.removeAll(this); } void QWindowPrivate::init() @@ -231,11 +219,10 @@ void QWindowPrivate::init() // If your application aborts here, you are probably creating a QWindow // before the screen list is populated. - if (!screen) { + if (!parentWindow && !topLevelScreen) { qFatal("Cannot create window: no screens available"); exit(1); } - QObject::connect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*))); QGuiApplicationPrivate::window_list.prepend(q); } @@ -353,23 +340,57 @@ void QWindowPrivate::updateVisibility() emit q->visibilityChanged(visibility); } -void QWindowPrivate::setScreen(QScreen *newScreen, bool recreate) +inline bool QWindowPrivate::windowRecreationRequired(QScreen *newScreen) const +{ + Q_Q(const QWindow); + const QScreen *oldScreen = q->screen(); + return oldScreen != newScreen && platformWindow + && !(oldScreen && oldScreen->virtualSiblings().contains(newScreen)); +} + +inline void QWindowPrivate::disconnectFromScreen() +{ + if (topLevelScreen) { + Q_Q(QWindow); + QObject::disconnect(topLevelScreen, &QObject::destroyed, q, &QWindow::screenDestroyed); + topLevelScreen = 0; + } +} + +void QWindowPrivate::connectToScreen(QScreen *screen) { Q_Q(QWindow); - if (newScreen != screen) { - const bool shouldRecreate = recreate && platformWindow != 0 - && !(screen && screen->virtualSiblings().contains(newScreen)); + disconnectFromScreen(); + topLevelScreen = screen; + if (topLevelScreen) + QObject::connect(topLevelScreen, &QObject::destroyed, q, &QWindow::screenDestroyed); +} + +void QWindowPrivate::emitScreenChangedRecursion(QScreen *newScreen) +{ + Q_Q(QWindow); + emit q->screenChanged(newScreen); + foreach (QObject *child, q->children()) { + if (child->isWindowType()) + static_cast<QWindow *>(child)->d_func()->emitScreenChangedRecursion(newScreen); + } +} + +void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate) +{ + Q_Q(QWindow); + if (parentWindow) { + qWarning() << this << Q_FUNC_INFO << '(' << newScreen << "): Attempt to set a screen on a child window."; + return; + } + if (newScreen != topLevelScreen) { + const bool shouldRecreate = recreate && windowRecreationRequired(newScreen); if (shouldRecreate) q->destroy(); - if (screen) - q->disconnect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*))); - screen = newScreen; - if (newScreen) { - q->connect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*))); - if (shouldRecreate) - q->create(); - } - emit q->screenChanged(newScreen); + connectToScreen(newScreen); + if (newScreen && shouldRecreate) + q->create(); + emitScreenChangedRecursion(newScreen); } } @@ -436,11 +457,14 @@ void QWindow::setVisible(bool visible) QCoreApplication::removePostedEvents(qApp, QEvent::Quit); if (type() == Qt::Window) { - QString &firstWindowTitle = QGuiApplicationPrivate::instance()->firstWindowTitle; + QGuiApplicationPrivate *app_priv = QGuiApplicationPrivate::instance(); + QString &firstWindowTitle = app_priv->firstWindowTitle; if (!firstWindowTitle.isEmpty()) { setTitle(firstWindowTitle); firstWindowTitle = QString(); } + if (!app_priv->forcedWindowIcon.isNull()) + setIcon(app_priv->forcedWindowIcon); } QShowEvent showEvent; @@ -549,8 +573,20 @@ QWindow *QWindow::parent() const void QWindow::setParent(QWindow *parent) { Q_D(QWindow); + if (d->parentWindow == parent) + return; + + QScreen *newScreen = parent ? parent->screen() : screen(); + if (d->windowRecreationRequired(newScreen)) { + qWarning() << this << Q_FUNC_INFO << '(' << parent << "): Cannot change screens (" << screen() << newScreen << ')'; + return; + } QObject::setParent(parent); + if (parent) + d->disconnectFromScreen(); + else + d->connectToScreen(newScreen); if (d->platformWindow) { if (parent && parent->d_func()->platformWindow) { @@ -1524,21 +1560,36 @@ void QWindow::resize(const QSize &newSize) void QWindow::destroy() { Q_D(QWindow); + if (!d->platformWindow) + return; + QObjectList childrenWindows = children(); for (int i = 0; i < childrenWindows.size(); i++) { QObject *object = childrenWindows.at(i); if (object->isWindowType()) { QWindow *w = static_cast<QWindow*>(object); - QGuiApplicationPrivate::window_list.removeAll(w); w->destroy(); } } + + if (QGuiApplicationPrivate::focus_window == this) + QGuiApplicationPrivate::focus_window = parent(); + if (QGuiApplicationPrivate::currentMouseWindow == this) + QGuiApplicationPrivate::currentMouseWindow = parent(); + if (QGuiApplicationPrivate::tabletPressTarget == this) + QGuiApplicationPrivate::tabletPressTarget = parent(); + + bool wasVisible = isVisible(); + setVisible(false); delete d->platformWindow; d->resizeEventPending = true; d->receivedExpose = false; d->exposed = false; d->platformWindow = 0; + + if (wasVisible) + d->maybeQuitOnLastWindowClosed(); } /*! @@ -1605,15 +1656,14 @@ bool QWindow::setMouseGrabEnabled(bool grab) /*! Returns the screen on which the window is shown. - The value returned will not change when the window is moved - between virtual screens (as returned by QScreen::virtualSiblings()). + For child windows, this returns the screen of the corresponding top level window. \sa setScreen(), QScreen::virtualSiblings() */ QScreen *QWindow::screen() const { Q_D(const QWindow); - return d->screen; + return d->parentWindow ? d->parentWindow->screen() : d->topLevelScreen; } /*! @@ -1624,6 +1674,8 @@ QScreen *QWindow::screen() const Note that if the screen is part of a virtual desktop of multiple screens, the window can appear on any of the screens returned by QScreen::virtualSiblings(). + This function only works for top level windows. + \sa screen(), QScreen::virtualSiblings() */ void QWindow::setScreen(QScreen *newScreen) @@ -1631,13 +1683,15 @@ void QWindow::setScreen(QScreen *newScreen) Q_D(QWindow); if (!newScreen) newScreen = QGuiApplication::primaryScreen(); - d->setScreen(newScreen, true /* recreate */); + d->setTopLevelScreen(newScreen, true /* recreate */); } void QWindow::screenDestroyed(QObject *object) { Q_D(QWindow); - if (object == static_cast<QObject *>(d->screen)) { + if (d->parentWindow) + return; + if (object == static_cast<QObject *>(d->topLevelScreen)) { const bool wasVisible = isVisible(); setScreen(0); // destroy() might have hidden our window, show it again. @@ -1793,15 +1847,13 @@ bool QWindow::close() if (parent()) return false; - if (QGuiApplicationPrivate::focus_window == this) - QGuiApplicationPrivate::focus_window = 0; - if (QGuiApplicationPrivate::currentMouseWindow == this) - QGuiApplicationPrivate::currentMouseWindow = 0; + if (!d->platformWindow) + return true; - QGuiApplicationPrivate::window_list.removeAll(this); - destroy(); - d->maybeQuitOnLastWindowClosed(); - return true; + bool accepted = false; + QWindowSystemInterface::handleCloseEvent(this, &accepted); + QWindowSystemInterface::flushWindowSystemEvents(); + return accepted; } /*! @@ -1947,15 +1999,10 @@ bool QWindow::event(QEvent *ev) break; #endif - case QEvent::Close: { - Q_D(QWindow); - bool wasVisible = isVisible(); - if (ev->isAccepted()) { + case QEvent::Close: + if (ev->isAccepted()) destroy(); - if (wasVisible) - d->maybeQuitOnLastWindowClosed(); - } - break; } + break; case QEvent::Expose: exposeEvent(static_cast<QExposeEvent *>(ev)); @@ -2167,8 +2214,10 @@ Q_GUI_EXPORT QWindowPrivate *qt_window_private(QWindow *window) void QWindowPrivate::maybeQuitOnLastWindowClosed() { - Q_Q(QWindow); + if (!QCoreApplication::instance()) + return; + Q_Q(QWindow); // Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent bool quitOnClose = QGuiApplication::quitOnLastWindowClosed() && !q->parent(); @@ -2327,7 +2376,7 @@ void QWindowPrivate::setCursor(const QCursor *newCursor) hasCursor = false; } // Only attempt to set cursor and emit signal if there is an actual platform cursor - if (screen->handle()->cursor()) { + if (q->screen()->handle()->cursor()) { applyCursor(); QEvent event(QEvent::CursorChange); QGuiApplication::sendEvent(q, &event); @@ -2338,7 +2387,7 @@ void QWindowPrivate::applyCursor() { Q_Q(QWindow); if (platformWindow) { - if (QPlatformCursor *platformCursor = screen->handle()->cursor()) { + if (QPlatformCursor *platformCursor = q->screen()->handle()->cursor()) { QCursor *c = QGuiApplication::overrideCursor(); if (!c && hasCursor) c = &cursor; diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 4305edea51..0c58745735 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -95,7 +95,7 @@ public: , modality(Qt::NonModal) , blockedByModalWindow(false) , transientParent(0) - , screen(0) + , topLevelScreen(0) #ifndef QT_NO_CURSOR , cursor(Qt::ArrowCursor) , hasCursor(false) @@ -131,7 +131,11 @@ public: void updateVisibility(); void _q_clearAlert(); - void setScreen(QScreen *newScreen, bool recreate); + bool windowRecreationRequired(QScreen *newScreen) const; + void setTopLevelScreen(QScreen *newScreen, bool recreate); + void connectToScreen(QScreen *topLevelScreen); + void disconnectFromScreen(); + void emitScreenChangedRecursion(QScreen *newScreen); virtual void clearFocusObject(); @@ -165,7 +169,7 @@ public: bool blockedByModalWindow; QPointer<QWindow> transientParent; - QScreen *screen; + QScreen *topLevelScreen; #ifndef QT_NO_CURSOR QCursor cursor; diff --git a/src/gui/kernel/qwindowdefs_win.h b/src/gui/kernel/qwindowdefs_win.h index fea995a0f5..0dd027e585 100644 --- a/src/gui/kernel/qwindowdefs_win.h +++ b/src/gui/kernel/qwindowdefs_win.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -107,7 +107,7 @@ Q_DECLARE_HANDLE(HRGN); #ifndef HMONITOR Q_DECLARE_HANDLE(HMONITOR); #endif -#ifndef HRESULT +#ifndef _HRESULT_DEFINED typedef long HRESULT; #endif diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 49ff8bcb0d..b716e84a42 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -133,11 +133,11 @@ void QWindowSystemInterface::handleWindowScreenChanged(QWindow *tlw, QScreen *sc QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } -void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState newState) +void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate) { Q_ASSERT(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)); QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *e = - new QWindowSystemInterfacePrivate::ApplicationStateChangedEvent(newState); + new QWindowSystemInterfacePrivate::ApplicationStateChangedEvent(newState, forcePropagate); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -629,24 +629,42 @@ void QWindowSystemInterface::handleFileOpenEvent(const QUrl &url) QGuiApplicationPrivate::processWindowSystemEvent(&e); } -void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, bool down, const QPointF &local, const QPointF &global, - int device, int pointerType, qreal pressure, int xTilt, int yTilt, +void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, const QPointF &local, const QPointF &global, + int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, qint64 uid, Qt::KeyboardModifiers modifiers) { QWindowSystemInterfacePrivate::TabletEvent *e = - new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, down, local, global, device, pointerType, pressure, + new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, local, global, device, pointerType, buttons, pressure, xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } +void QWindowSystemInterface::handleTabletEvent(QWindow *w, const QPointF &local, const QPointF &global, + int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt, + qreal tangentialPressure, qreal rotation, int z, qint64 uid, + Qt::KeyboardModifiers modifiers) +{ + ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed(); + handleTabletEvent(w, time, local, global, device, pointerType, buttons, pressure, + xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); +} + +void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, bool down, const QPointF &local, const QPointF &global, + int device, int pointerType, qreal pressure, int xTilt, int yTilt, + qreal tangentialPressure, qreal rotation, int z, qint64 uid, + Qt::KeyboardModifiers modifiers) +{ + handleTabletEvent(w, timestamp, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure, + xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); +} + void QWindowSystemInterface::handleTabletEvent(QWindow *w, bool down, const QPointF &local, const QPointF &global, int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, qint64 uid, Qt::KeyboardModifiers modifiers) { - ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - handleTabletEvent(w, time, down, local, global, device, pointerType, pressure, + handleTabletEvent(w, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure, xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 71feb1bcb7..1462c62e2b 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -148,7 +148,7 @@ public: static void handleWindowStateChanged(QWindow *w, Qt::WindowState newState); static void handleWindowScreenChanged(QWindow *w, QScreen *newScreen); - static void handleApplicationStateChanged(Qt::ApplicationState newState); + static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false); static void handleExposeEvent(QWindow *tlw, const QRegion ®ion); @@ -172,14 +172,22 @@ public: static void handleFileOpenEvent(const QString& fileName); static void handleFileOpenEvent(const QUrl &url); + static void handleTabletEvent(QWindow *w, ulong timestamp, const QPointF &local, const QPointF &global, + int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt, + qreal tangentialPressure, qreal rotation, int z, qint64 uid, + Qt::KeyboardModifiers modifiers = Qt::NoModifier); + static void handleTabletEvent(QWindow *w, const QPointF &local, const QPointF &global, + int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt, + qreal tangentialPressure, qreal rotation, int z, qint64 uid, + Qt::KeyboardModifiers modifiers = Qt::NoModifier); static void handleTabletEvent(QWindow *w, ulong timestamp, bool down, const QPointF &local, const QPointF &global, int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, qint64 uid, - Qt::KeyboardModifiers modifiers = Qt::NoModifier); + Qt::KeyboardModifiers modifiers = Qt::NoModifier); // ### remove in Qt 6 static void handleTabletEvent(QWindow *w, bool down, const QPointF &local, const QPointF &global, int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, qint64 uid, - Qt::KeyboardModifiers modifiers = Qt::NoModifier); + Qt::KeyboardModifiers modifiers = Qt::NoModifier); // ### remove in Qt 6 static void handleTabletEnterProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid); static void handleTabletEnterProximityEvent(int device, int pointerType, qint64 uid); static void handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 8e503bbf3d..89ca4064b2 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -176,11 +176,12 @@ public: class ApplicationStateChangedEvent : public WindowSystemEvent { public: - ApplicationStateChangedEvent(Qt::ApplicationState newState) - : WindowSystemEvent(ApplicationStateChanged), newState(newState) + ApplicationStateChangedEvent(Qt::ApplicationState newState, bool forcePropagate = false) + : WindowSystemEvent(ApplicationStateChanged), newState(newState), forcePropagate(forcePropagate) { } Qt::ApplicationState newState; + bool forcePropagate; }; class FlushEventsEvent : public WindowSystemEvent { @@ -337,19 +338,19 @@ public: class TabletEvent : public InputEvent { public: - static void handleTabletEvent(QWindow *w, bool down, const QPointF &local, const QPointF &global, - int device, int pointerType, qreal pressure, int xTilt, int yTilt, + static void handleTabletEvent(QWindow *w, const QPointF &local, const QPointF &global, + int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, qint64 uid, Qt::KeyboardModifiers modifiers = Qt::NoModifier); - TabletEvent(QWindow *w, ulong time, bool down, const QPointF &local, const QPointF &global, - int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tpressure, + TabletEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global, + int device, int pointerType, Qt::MouseButtons b, qreal pressure, int xTilt, int yTilt, qreal tpressure, qreal rotation, int z, qint64 uid, Qt::KeyboardModifiers mods) : InputEvent(w, time, Tablet, mods), - down(down), local(local), global(global), device(device), pointerType(pointerType), + buttons(b), local(local), global(global), device(device), pointerType(pointerType), pressure(pressure), xTilt(xTilt), yTilt(yTilt), tangentialPressure(tpressure), rotation(rotation), z(z), uid(uid) { } - bool down; + Qt::MouseButtons buttons; QPointF local; QPointF global; int device; |