Merge "Merge remote-tracking branch 'origin/5.6' into 5.7" into refs/staging/5.7

This commit is contained in:
Liang Qi 2016-02-19 21:18:19 +00:00 committed by The Qt Project
commit 611942f2d7
130 changed files with 1166 additions and 361 deletions

View File

@ -1,6 +1,10 @@
SOURCES = journald.c
CONFIG += link_pkgconfig
PKGCONFIG_PRIVATE += libsystemd-journal
packagesExist(libsystemd): \
PKGCONFIG_PRIVATE += libsystemd
else: \
PKGCONFIG_PRIVATE += libsystemd-journal
CONFIG -= qt

2
configure vendored
View File

@ -2872,7 +2872,7 @@ if [ -z "$PLATFORM" ]; then
PLATFORM=ultrix-g++
;;
FreeBSD:*)
PLATFORM=freebsd-g++
PLATFORM=freebsd-clang
PLATFORM_NOTES="
- Also available for FreeBSD: freebsd-icc
"

View File

@ -194,7 +194,7 @@ equals(QT_ARCH, i386):contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):compiler_support
android: CONFIG += qt_android_deps no_linker_version_script
!header_module:unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static {
verscript = $$OUT_PWD/$${TARGET}.version
verscript = $${TARGET}.version
QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript
internal_module {
@ -219,16 +219,20 @@ android: CONFIG += qt_android_deps no_linker_version_script
}
# Add a post-processing step to replace the @FILE:filename@
verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < $${verscript}.in > $@
verscriptprocess.target = $$verscript
verscript_in = $${verscript}.in
verscriptprocess.name = linker version script ${QMAKE_FILE_BASE}
verscriptprocess.input = verscript_in
verscriptprocess.CONFIG += no_link target_predeps
for(header, SYNCQT.PRIVATE_HEADER_FILES): \
verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header
verscriptprocess.depends += $${verscript}.in
QMAKE_EXTRA_TARGETS += verscriptprocess
PRE_TARGETDEPS += $$verscript
verscript = $${verscript}.in
verscriptprocess.output = $$verscript
verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < ${QMAKE_FILE_IN} > $@
silent:verscriptprocess.commands = @echo creating linker version script ${QMAKE_FILE_BASE} && $$verscriptprocess.commands
QMAKE_EXTRA_COMPILERS += verscriptprocess
verscript = $$verscript_in
}
write_file($$verscript, verscript_content)|error("Aborting.")
write_file($$OUT_PWD/$$verscript, verscript_content)|error("Aborting.")
unset(current)
unset(previous)
unset(verscript)

View File

@ -30,7 +30,7 @@ QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P
QMAKE_RANLIB =
include(../../common/gcc-base-unix.conf)
include(../../common/clang.conf)
include(../common/gcc-base-unix.conf)
include(../common/clang.conf)
load(qt_config)

View File

@ -5,7 +5,7 @@
MAKEFILE_GENERATOR = UNIX
QMAKE_PLATFORM = freebsd bsd
include(../common/unix.conf)
include(../../common/unix.conf)
QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE
@ -29,6 +29,6 @@ QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P
QMAKE_RANLIB =
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)
load(qt_config)

View File

@ -37,4 +37,4 @@
**
****************************************************************************/
#include "../../freebsd-g++/qplatformdefs.h"
#include "../../freebsd-clang/qplatformdefs.h"

View File

@ -5,7 +5,7 @@
MAKEFILE_GENERATOR = UNIX
QMAKE_PLATFORM = freebsd bsd
include(../common/unix.conf)
include(../../common/unix.conf)
QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE
@ -29,8 +29,8 @@ QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P
QMAKE_RANLIB =
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)
# Redefined here because g++-base.conf sets QMAKE_CC and QMAKE_CXX
# to gcc and g++, respectively.

View File

@ -37,4 +37,4 @@
**
****************************************************************************/
#include "../freebsd-g++/qplatformdefs.h"
#include "../../freebsd-clang/qplatformdefs.h"

View File

@ -25,6 +25,10 @@ ANDROID_PERMISSIONS = \
android.permission.INTERNET \
android.permission.WRITE_EXTERNAL_STORAGE
# QtCore can't be compiled with -Wl,-no-undefined because it uses the "environ"
# variable and on FreeBSD, this variable is in the final executable itself
freebsd: QMAKE_LFLAGS_NOUNDEF =
load(qt_module)
load(qfeatures)

View File

@ -53,7 +53,10 @@ slog2 {
journald {
CONFIG += link_pkgconfig
PKGCONFIG_PRIVATE += libsystemd-journal
packagesExist(libsystemd): \
PKGCONFIG_PRIVATE += libsystemd
else: \
PKGCONFIG_PRIVATE += libsystemd-journal
DEFINES += QT_USE_JOURNALD
}

View File

@ -65,11 +65,7 @@ QT_BEGIN_NAMESPACE
#elif defined(Q_CC_GNU) && !defined(Q_OS_ANDROID)
# if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL))
# if defined(Q_PROCESSOR_X86_64) // x86-64 or x32
# if defined(__code_model_large__)
# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
# else
# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOTPCREL\n"
# endif
# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
# else // x86
# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
# endif

View File

@ -49,13 +49,8 @@ QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipe, QObject * parent)
quitNow(false),
hasWritten(false)
{
#if !defined(Q_OS_WINCE) || (_WIN32_WCE >= 0x600)
DuplicateHandle(GetCurrentProcess(), pipe, GetCurrentProcess(),
&writePipe, 0, FALSE, DUPLICATE_SAME_ACCESS);
#else
Q_UNUSED(pipe);
writePipe = GetCurrentProcess();
#endif
}
QWindowsPipeWriter::~QWindowsPipeWriter()
@ -66,9 +61,7 @@ QWindowsPipeWriter::~QWindowsPipeWriter()
lock.unlock();
if (!wait(30000))
terminate();
#if !defined(Q_OS_WINCE) || (_WIN32_WCE >= 0x600)
CloseHandle(writePipe);
#endif
}
bool QWindowsPipeWriter::waitForWrite(int msecs)
@ -159,7 +152,6 @@ void QWindowsPipeWriter::run()
msleep(100);
continue;
}
#ifndef Q_OS_WINCE
if (writeError != ERROR_IO_PENDING) {
qErrnoWarning(writeError, "QWindowsPipeWriter: async WriteFile failed.");
return;
@ -168,9 +160,6 @@ void QWindowsPipeWriter::run()
qErrnoWarning(GetLastError(), "QWindowsPipeWriter: GetOverlappedResult failed.");
return;
}
#else
return;
#endif
}
totalWritten += written;
#if defined QPIPEWRITER_DEBUG

View File

@ -81,6 +81,22 @@ QT_BEGIN_NAMESPACE
or WriteFile() is ignored and can be used for other purposes.
\warning This class is only available on Windows.
Due to peculiarities of the Windows I/O completion port API, users of
QWinOverlappedIoNotifier must pay attention to the following restrictions:
\list
\li File handles with a QWinOverlappedIoNotifer are assigned to an I/O
completion port until the handle is closed. It is impossible to
disassociate the file handle from the I/O completion port.
\li There can be only one QWinOverlappedIoNotifer per file handle. Creating
another QWinOverlappedIoNotifier for that file, even with a duplicated
handle, will fail.
\li Certain Windows API functions are unavailable for file handles that are
assigned to an I/O completion port. This includes the functions
\c{ReadFileEx} and \c{WriteFileEx}.
\endlist
See also the remarks in the MSDN documentation for the
\c{CreateIoCompletionPort} function.
*/
struct IOResult

View File

@ -795,7 +795,11 @@ public:
if (reserve) {
if (reserve < 128)
reserve = 128;
size = qMax(size + reserve, size *2);
size = qMax(size + reserve, qMin(size *2, (int)Value::MaxSize));
if (size > Value::MaxSize) {
qWarning("QJson: Document too large to store in data structure");
return 0;
}
}
char *raw = (char *)malloc(size);
Q_CHECK_PTR(raw);

View File

@ -262,8 +262,45 @@ QJsonArray QJsonArray::fromStringList(const QStringList &list)
QJsonArray QJsonArray::fromVariantList(const QVariantList &list)
{
QJsonArray array;
for (QVariantList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it)
array.append(QJsonValue::fromVariant(*it));
if (list.isEmpty())
return array;
array.detach2(1024);
QVector<QJsonPrivate::Value> values;
values.resize(list.size());
QJsonPrivate::Value *valueData = values.data();
uint currentOffset = sizeof(QJsonPrivate::Base);
for (int i = 0; i < list.size(); ++i) {
QJsonValue val = QJsonValue::fromVariant(list.at(i));
bool latinOrIntValue;
int valueSize = QJsonPrivate::Value::requiredStorage(val, &latinOrIntValue);
if (!array.detach2(valueSize))
return QJsonArray();
QJsonPrivate::Value *v = valueData + i;
v->type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t);
v->latinOrIntValue = latinOrIntValue;
v->latinKey = false;
v->value = QJsonPrivate::Value::valueToStore(val, currentOffset);
if (valueSize)
QJsonPrivate::Value::copyData(val, (char *)array.a + currentOffset, latinOrIntValue);
currentOffset += valueSize;
array.a->size = currentOffset;
}
// write table
array.a->tableOffset = currentOffset;
if (!array.detach2(sizeof(QJsonPrivate::offset)*values.size()))
return QJsonArray();
memcpy(array.a->table(), values.constData(), values.size()*sizeof(uint));
array.a->length = values.size();
array.a->size = currentOffset + sizeof(QJsonPrivate::offset)*values.size();
return array;
}
@ -388,7 +425,7 @@ void QJsonArray::removeAt(int i)
if (!a || i < 0 || i >= (int)a->length)
return;
detach();
detach2();
a->removeItems(i, 1);
++d->compactionCounter;
if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u)
@ -448,7 +485,8 @@ void QJsonArray::insert(int i, const QJsonValue &value)
bool compressed;
int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed);
detach(valueSize + sizeof(QJsonPrivate::Value));
if (!detach2(valueSize + sizeof(QJsonPrivate::Value)))
return;
if (!a->length)
a->tableOffset = sizeof(QJsonPrivate::Array);
@ -498,7 +536,8 @@ void QJsonArray::replace(int i, const QJsonValue &value)
bool compressed;
int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed);
detach(valueSize);
if (!detach2(valueSize))
return;
if (!a->length)
a->tableOffset = sizeof(QJsonPrivate::Array);
@ -1128,22 +1167,39 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
\internal
*/
void QJsonArray::detach(uint reserve)
{
Q_UNUSED(reserve)
Q_ASSERT(!reserve);
detach2(0);
}
/*!
\internal
*/
bool QJsonArray::detach2(uint reserve)
{
if (!d) {
if (reserve >= QJsonPrivate::Value::MaxSize) {
qWarning("QJson: Document too large to store in data structure");
return false;
}
d = new QJsonPrivate::Data(reserve, QJsonValue::Array);
a = static_cast<QJsonPrivate::Array *>(d->header->root());
d->ref.ref();
return;
return true;
}
if (reserve == 0 && d->ref.load() == 1)
return;
return true;
QJsonPrivate::Data *x = d->clone(a, reserve);
if (!x)
return false;
x->ref.ref();
if (!d->ref.deref())
delete d;
d = x;
a = static_cast<QJsonPrivate::Array *>(d->header->root());
return true;
}
/*!
@ -1154,7 +1210,7 @@ void QJsonArray::compact()
if (!d || !d->compactionCounter)
return;
detach();
detach2();
d->compact();
a = static_cast<QJsonPrivate::Array *>(d->header->root());
}

View File

@ -191,10 +191,10 @@ public:
friend class const_iterator;
// stl style
inline iterator begin() { detach(); return iterator(this, 0); }
inline iterator begin() { detach2(); return iterator(this, 0); }
inline const_iterator begin() const { return const_iterator(this, 0); }
inline const_iterator constBegin() const { return const_iterator(this, 0); }
inline iterator end() { detach(); return iterator(this, size()); }
inline iterator end() { detach2(); return iterator(this, size()); }
inline const_iterator end() const { return const_iterator(this, size()); }
inline const_iterator constEnd() const { return const_iterator(this, size()); }
iterator insert(iterator before, const QJsonValue &value) { insert(before.i, value); return before; }
@ -235,7 +235,9 @@ private:
QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array);
void initialize();
void compact();
// ### Qt 6: remove me and merge with detach2
void detach(uint reserve = 0);
bool detach2(uint reserve = 0);
QJsonPrivate::Data *d;
QJsonPrivate::Array *a;

View File

@ -488,7 +488,7 @@ void QJsonDocument::setObject(const QJsonObject &object)
if (d->compactionCounter)
o.compact();
else
o.detach();
o.detach2();
d = o.d;
d->ref.ref();
return;
@ -515,7 +515,7 @@ void QJsonDocument::setArray(const QJsonArray &array)
if (d->compactionCounter)
a.compact();
else
a.detach();
a.detach2();
d = a.d;
d->ref.ref();
return;

View File

@ -203,11 +203,54 @@ QJsonObject &QJsonObject::operator =(const QJsonObject &other)
*/
QJsonObject QJsonObject::fromVariantMap(const QVariantMap &map)
{
// ### this is implemented the trivial way, not the most efficient way
QJsonObject object;
for (QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it)
object.insert(it.key(), QJsonValue::fromVariant(it.value()));
if (map.isEmpty())
return object;
object.detach2(1024);
QVector<QJsonPrivate::offset> offsets;
QJsonPrivate::offset currentOffset;
currentOffset = sizeof(QJsonPrivate::Base);
// the map is already sorted, so we can simply append one entry after the other and
// write the offset table at the end
for (QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) {
QString key = it.key();
QJsonValue val = QJsonValue::fromVariant(it.value());
bool latinOrIntValue;
int valueSize = QJsonPrivate::Value::requiredStorage(val, &latinOrIntValue);
bool latinKey = QJsonPrivate::useCompressed(key);
int valueOffset = sizeof(QJsonPrivate::Entry) + QJsonPrivate::qStringSize(key, latinKey);
int requiredSize = valueOffset + valueSize;
if (!object.detach2(requiredSize + sizeof(QJsonPrivate::offset))) // offset for the new index entry
return QJsonObject();
QJsonPrivate::Entry *e = reinterpret_cast<QJsonPrivate::Entry *>(reinterpret_cast<char *>(object.o) + currentOffset);
e->value.type = val.t;
e->value.latinKey = latinKey;
e->value.latinOrIntValue = latinOrIntValue;
e->value.value = QJsonPrivate::Value::valueToStore(val, (char *)e - (char *)object.o + valueOffset);
QJsonPrivate::copyString((char *)(e + 1), key, latinKey);
if (valueSize)
QJsonPrivate::Value::copyData(val, (char *)e + valueOffset, latinOrIntValue);
offsets << currentOffset;
currentOffset += requiredSize;
object.o->size = currentOffset;
}
// write table
object.o->tableOffset = currentOffset;
if (!object.detach2(sizeof(QJsonPrivate::offset)*offsets.size()))
return QJsonObject();
memcpy(object.o->table(), offsets.constData(), offsets.size()*sizeof(uint));
object.o->length = offsets.size();
object.o->size = currentOffset + sizeof(QJsonPrivate::offset)*offsets.size();
return object;
}
@ -276,16 +319,14 @@ QVariantHash QJsonObject::toVariantHash() const
*/
QStringList QJsonObject::keys() const
{
if (!d)
return QStringList();
QStringList keys;
keys.reserve(o->length);
for (uint i = 0; i < o->length; ++i) {
QJsonPrivate::Entry *e = o->entryAt(i);
keys.append(e->key());
if (o) {
keys.reserve(o->length);
for (uint i = 0; i < o->length; ++i) {
QJsonPrivate::Entry *e = o->entryAt(i);
keys.append(e->key());
}
}
return keys;
}
@ -397,7 +438,8 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &
int valueOffset = sizeof(QJsonPrivate::Entry) + QJsonPrivate::qStringSize(key, latinKey);
int requiredSize = valueOffset + valueSize;
detach(requiredSize + sizeof(QJsonPrivate::offset)); // offset for the new index entry
if (!detach2(requiredSize + sizeof(QJsonPrivate::offset))) // offset for the new index entry
return iterator();
if (!o->length)
o->tableOffset = sizeof(QJsonPrivate::Object);
@ -441,7 +483,7 @@ void QJsonObject::remove(const QString &key)
if (!keyExists)
return;
detach();
detach2();
o->removeItems(index, 1);
++d->compactionCounter;
if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u)
@ -468,7 +510,7 @@ QJsonValue QJsonObject::take(const QString &key)
return QJsonValue(QJsonValue::Undefined);
QJsonValue v(d, o, o->entryAt(index)->value);
detach();
detach2();
o->removeItems(index, 1);
++d->compactionCounter;
if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u)
@ -562,7 +604,7 @@ QJsonObject::iterator QJsonObject::find(const QString &key)
int index = o ? o->indexOf(key, &keyExists) : 0;
if (!keyExists)
return end();
detach();
detach2();
return iterator(this, index);
}
@ -1068,22 +1110,36 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
\internal
*/
void QJsonObject::detach(uint reserve)
{
Q_UNUSED(reserve)
Q_ASSERT(!reserve);
detach2(reserve);
}
bool QJsonObject::detach2(uint reserve)
{
if (!d) {
if (reserve >= QJsonPrivate::Value::MaxSize) {
qWarning("QJson: Document too large to store in data structure");
return false;
}
d = new QJsonPrivate::Data(reserve, QJsonValue::Object);
o = static_cast<QJsonPrivate::Object *>(d->header->root());
d->ref.ref();
return;
return true;
}
if (reserve == 0 && d->ref.load() == 1)
return;
return true;
QJsonPrivate::Data *x = d->clone(o, reserve);
if (!x)
return false;
x->ref.ref();
if (!d->ref.deref())
delete d;
d = x;
o = static_cast<QJsonPrivate::Object *>(d->header->root());
return true;
}
/*!
@ -1094,7 +1150,7 @@ void QJsonObject::compact()
if (!d || !d->compactionCounter)
return;
detach();
detach2();
d->compact();
o = static_cast<QJsonPrivate::Object *>(d->header->root());
}

View File

@ -188,10 +188,10 @@ public:
friend class const_iterator;
// STL style
inline iterator begin() { detach(); return iterator(this, 0); }
inline iterator begin() { detach2(); return iterator(this, 0); }
inline const_iterator begin() const { return const_iterator(this, 0); }
inline const_iterator constBegin() const { return const_iterator(this, 0); }
inline iterator end() { detach(); return iterator(this, size()); }
inline iterator end() { detach2(); return iterator(this, size()); }
inline const_iterator end() const { return const_iterator(this, size()); }
inline const_iterator constEnd() const { return const_iterator(this, size()); }
iterator erase(iterator it);
@ -221,7 +221,9 @@ private:
QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object);
void initialize();
// ### Qt 6: remove me and merge with detach2
void detach(uint reserve = 0);
bool detach2(uint reserve = 0);
void compact();
QString keyAt(int i) const;

View File

@ -113,6 +113,7 @@ QAppleOperatingSystemVersion qt_apple_os_version()
// Use temporary variables so we can return 0.0.0 (unknown version)
// in case of an error partway through determining the OS version
qint32 major = 0, minor = 0, patch = 0;
#if QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_10_10, __IPHONE_8_0)
#if defined(Q_OS_IOS)
@autoreleasepool {
NSArray *parts = [UIDevice.currentDevice.systemVersion componentsSeparatedByString:@"."];
@ -135,6 +136,7 @@ QAppleOperatingSystemVersion qt_apple_os_version()
return v;
if (pGestalt('sys3', &patch) != 0)
return v;
#endif
#endif
v.major = major;
v.minor = minor;

View File

@ -942,9 +942,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
{
Q_ASSERT(notifier);
int sockfd = notifier->socket();
int type = notifier->type();
#ifndef QT_NO_DEBUG
int sockfd = notifier->socket();
if (sockfd < 0) {
qWarning("QSocketNotifier: Internal error");
return;
@ -953,8 +952,16 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
return;
}
#endif
doUnregisterSocketNotifier(notifier);
}
void QEventDispatcherWin32::doUnregisterSocketNotifier(QSocketNotifier *notifier)
{
Q_D(QEventDispatcherWin32);
int type = notifier->type();
int sockfd = notifier->socket();
Q_ASSERT(sockfd >= 0);
QSFDict::iterator it = d->active_fd.find(sockfd);
if (it != d->active_fd.end()) {
QSockFd &sd = it.value();
@ -1210,11 +1217,11 @@ void QEventDispatcherWin32::closingDown()
// clean up any socketnotifiers
while (!d->sn_read.isEmpty())
unregisterSocketNotifier((*(d->sn_read.begin()))->obj);
doUnregisterSocketNotifier((*(d->sn_read.begin()))->obj);
while (!d->sn_write.isEmpty())
unregisterSocketNotifier((*(d->sn_write.begin()))->obj);
doUnregisterSocketNotifier((*(d->sn_write.begin()))->obj);
while (!d->sn_except.isEmpty())
unregisterSocketNotifier((*(d->sn_except.begin()))->obj);
doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj);
Q_ASSERT(d->active_fd.isEmpty());
// clean up any timers

View File

@ -109,6 +109,7 @@ public:
protected:
QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0);
virtual void sendPostedEvents();
void doUnregisterSocketNotifier(QSocketNotifier *notifier);
private:
friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);

View File

@ -1181,7 +1181,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
/*!
\fn QPair<iterator, iterator> QMap::equal_range(const Key &key)
Returns a pair of iterators delimiting the range of values that
Returns a pair of iterators delimiting the range of values \c{[first, second)}, that
are stored under \a key.
*/

View File

@ -42,7 +42,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qatomic.h>
#if QT_DEPRECATED_SINCE(5, 5)
#if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h>
#endif
#include <QtCore/qhashfunctions.h>

View File

@ -63,7 +63,7 @@ QT_END_NAMESPACE
#include <QtCore/qatomic.h>
#include <QtCore/qobject.h> // for qobject_cast
#include <QtCore/qdebug.h>
#if QT_DEPRECATED_SINCE(5, 5)
#if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h>
#endif
#include <QtCore/qhashfunctions.h>

View File

@ -49,6 +49,10 @@
#include <QtDBus/qdbusextratypes.h>
#include <QtDBus/qdbusconnection.h>
#ifdef interface
#undef interface
#endif
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE

View File

@ -60,6 +60,10 @@
#include <algorithm>
#ifdef interface
#undef interface
#endif
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE

View File

@ -45,7 +45,7 @@
#include <QtCore/qvariant.h>
#include <QtCore/qstring.h>
#include <QtDBus/qdbusmacros.h>
#if QT_DEPRECATED_SINCE(5, 5)
#if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h>
#endif
#include <QtCore/qhashfunctions.h>

View File

@ -69,6 +69,9 @@
#include "qdbusthreaddebug_p.h"
#include <algorithm>
#ifdef interface
#undef interface
#endif
#ifndef QT_NO_DBUS

View File

@ -300,7 +300,7 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
if (depth != 32) {
ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
if (ncols > 256) // sanity check - don't run out of mem if color table is broken
if (ncols < 1 || ncols > 256) // sanity check - don't run out of mem if color table is broken
return false;
image.setColorCount(ncols);
}

View File

@ -205,7 +205,7 @@ void QGIFFormat::disposePrevious(QImage *image)
fillRect(image, l, t, r-l+1, b-t+1, color(bgcol));
} else {
// Impossible: We don't know of a bgcol - use pixel 0
QRgb *bits = (QRgb*)image->bits();
const QRgb *bits = reinterpret_cast<const QRgb *>(image->constBits());
fillRect(image, l, t, r-l+1, b-t+1, bits[0]);
}
// ### Changed: QRect(l, t, r-l+1, b-t+1)
@ -214,7 +214,7 @@ void QGIFFormat::disposePrevious(QImage *image)
if (frame >= 0) {
for (int ln=t; ln<=b; ln++) {
memcpy(image->scanLine(ln)+l,
backingstore.scanLine(ln-t),
backingstore.constScanLine(ln-t),
(r-l+1)*sizeof(QRgb));
}
// ### Changed: QRect(l, t, r-l+1, b-t+1)

View File

@ -195,6 +195,12 @@ inline QImage::Format qt_alphaVersion(QImage::Format format)
return QImage::Format_ARGB32_Premultiplied;
}
inline QImage::Format qt_maybeAlphaVersionWithSameDepth(QImage::Format format)
{
const QImage::Format toFormat = qt_alphaVersion(format);
return qt_depthForFormat(format) == qt_depthForFormat(toFormat) ? toFormat : format;
}
inline QImage::Format qt_alphaVersionForPainting(QImage::Format format)
{
QImage::Format toFormat = qt_alphaVersion(format);

View File

@ -189,7 +189,7 @@ void QBlittablePlatformPixmap::fromImage(const QImage &image,
correctFormatPic = correctFormatPic.convertToFormat(thisImg->format(), flags);
uchar *mem = thisImg->bits();
const uchar *bits = correctFormatPic.bits();
const uchar *bits = correctFormatPic.constBits();
int bytesCopied = 0;
while (bytesCopied < correctFormatPic.byteCount()) {
memcpy(mem,bits,correctFormatPic.bytesPerLine());

View File

@ -204,7 +204,7 @@ Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap)
QScopedArrayPointer<uchar> bits(new uchar[bpl * h]);
bm.invertPixels();
for (int y = 0; y < h; ++y)
memcpy(bits.data() + y * bpl, bm.scanLine(y), bpl);
memcpy(bits.data() + y * bpl, bm.constScanLine(y), bpl);
HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits.data());
return hbm;
}

View File

@ -335,7 +335,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
if (image.format() == QImage::Format_Indexed8) {
QVector<QRgb> color = image.colorTable();
for (uint y=0; y<h; y++) {
uchar *b = image.scanLine(y);
const uchar *b = image.constScanLine(y);
uchar *p = buf;
uchar *end = buf+bpl;
if (gray) {
@ -356,7 +356,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
}
} else {
for (uint y=0; y<h; y++) {
uchar *b = image.scanLine(y);
const uchar *b = image.constScanLine(y);
uchar *p = buf;
uchar *end = buf + bpl;
if (gray) {
@ -386,7 +386,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
uint bpl = w * 3;
uchar *buf = new uchar[bpl];
for (uint y=0; y<h; y++) {
QRgb *b = (QRgb*)image.scanLine(y);
const QRgb *b = reinterpret_cast<const QRgb *>(image.constScanLine(y));
uchar *p = buf;
uchar *end = buf+bpl;
while (p < end) {

View File

@ -216,7 +216,7 @@ static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const
char *p = buf;
int bpl = (w+7)/8;
for (int y = 0; y < h; ++y) {
uchar *b = image.scanLine(y);
const uchar *b = image.constScanLine(y);
for (i = 0; i < bpl; ++i) {
*p++ = '0'; *p++ = 'x';
*p++ = hexrep[*b >> 4];

View File

@ -1104,7 +1104,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const
// build color table
for(y=0; y<h; y++) {
QRgb * yp = (QRgb *)image.scanLine(y);
const QRgb *yp = reinterpret_cast<const QRgb *>(image.constScanLine(y));
for(x=0; x<w; x++) {
QRgb color = *(yp + x);
if (!colorMap.contains(color))
@ -1150,7 +1150,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const
// write pixels, limit to 4 characters per pixel
line.truncate(cpp*w);
for(y=0; y<h; y++) {
QRgb * yp = (QRgb *) image.scanLine(y);
const QRgb *yp = reinterpret_cast<const QRgb *>(image.constScanLine(y));
int cc = 0;
for(x=0; x<w; x++) {
int color = (int)(*(yp + x));

View File

@ -3576,6 +3576,7 @@ static inline void formatTouchEvent(QDebug d, const QTouchEvent &t)
{
d << "QTouchEvent(";
QtDebugUtils::formatQEnum(d, t.type());
d << " device: " << t.device()->name();
d << " states: ";
QtDebugUtils::formatQFlags(d, t.touchPointStates());
d << ", " << t.touchPoints().size() << " points: " << t.touchPoints() << ')';

View File

@ -53,6 +53,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qmargins.h>
#include <QtCore/qmath.h>
#include <QtCore/qrect.h>
#include <QtCore/qvector.h>
#include <QtCore/qloggingcategory.h>
@ -389,6 +390,24 @@ inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *
return pointRegion;
}
// When mapping expose events to Qt rects: round top/left towards the origin and
// bottom/right away from the origin, making sure that we cover the whole window.
inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QWindow *window)
{
if (!QHighDpiScaling::isActive())
return pixelRegion;
const qreal scaleFactor = QHighDpiScaling::factor(window);
QRegion pointRegion;
foreach (const QRect &rect, pixelRegion.rects()) {
const QPointF topLeftP = QPointF(rect.topLeft()) / scaleFactor;
const QPointF bottomRightP = QPointF(rect.bottomRight()) / scaleFactor;
pointRegion += QRect(QPoint(qFloor(topLeftP.x()), qFloor(topLeftP.y())),
QPoint(qCeil(bottomRightP.x()), qCeil(bottomRightP.y())));
}
return pointRegion;
}
inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
{
if (!QHighDpiScaling::isActive())
@ -506,6 +525,8 @@ namespace QHighDpi {
template <typename T> inline
T fromNativeLocalRegion(const T &value, ...) { return value; }
template <typename T> inline
T fromNativeLocalExposedRegion(const T &value, ...) { return value; }
template <typename T> inline
T toNativeLocalRegion(const T &value, ...) { return value; }
template <typename T> inline

View File

@ -60,7 +60,7 @@
#include <QtGui/qopengl.h>
#include <QtGui/qopenglversionfunctions.h>
#if QT_DEPRECATED_SINCE(5, 5)
#if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h>
#endif
#include <QtCore/qhashfunctions.h>

View File

@ -490,8 +490,10 @@ QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) co
{
QPlatformScreen *currentScreen = screen();
QPlatformScreen *fallback = currentScreen;
//QRect::center can return a value outside the rectangle if it's empty
const QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center();
// QRect::center can return a value outside the rectangle if it's empty.
// Apply mapToGlobal() in case it is a foreign/embedded window.
const QPoint center =
mapToGlobal(newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center());
if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) {
const auto screens = currentScreen->virtualSiblings();

View File

@ -375,7 +375,7 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
{
Q_Q(QWindow);
if (parentWindow) {
qWarning() << this << '(' << newScreen << "): Attempt to set a screen on a child window.";
qWarning() << q << '(' << newScreen << "): Attempt to set a screen on a child window.";
return;
}
if (newScreen != topLevelScreen) {

View File

@ -588,7 +588,8 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region)
{
QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw));
QWindowSystemInterfacePrivate::ExposeEvent *e =
new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalExposedRegion(region, tlw));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@ -874,7 +875,7 @@ Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::Keybo
QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous);
}
Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1)
Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1)
{
#ifndef QT_NO_SHORTCUT

View File

@ -85,7 +85,7 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher()
if (!glGetStringi)
return;
GLint numExtensions;
GLint numExtensions = 0;
funcs->glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
for (int i = 0; i < numExtensions; ++i) {

View File

@ -53,7 +53,7 @@
#ifndef QT_NO_OPENGL
#if QT_DEPRECATED_SINCE(5, 5)
#if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h>
#endif
#include <QtCore/qhashfunctions.h>

View File

@ -112,7 +112,8 @@ void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &off
}
#endif
d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, d_ptr->window), offset);
d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, win),
QHighDpi::toNativeLocalPosition(offset, win));
}
/*!

View File

@ -3426,13 +3426,13 @@ static SourceFetchProc64 sourceFetch64[NBlendTypes][QImage::NImageFormats] = {
static uint qt_gradient_pixel_fixed(const QGradientData *data, int fixed_pos)
{
int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
return data->colorTable[qt_gradient_clamp(data, ipos)].toArgb32();
return data->colorTable32[qt_gradient_clamp(data, ipos)];
}
static const QRgba64& qt_gradient_pixel64_fixed(const QGradientData *data, int fixed_pos)
{
int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
return data->colorTable[qt_gradient_clamp(data, ipos)];
return data->colorTable64[qt_gradient_clamp(data, ipos)];
}
static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const QSpanData *data)

View File

@ -274,7 +274,8 @@ struct QGradientData
#define GRADIENT_STOPTABLE_SIZE 1024
#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
QRgba64* colorTable; //[GRADIENT_STOPTABLE_SIZE];
const QRgba64 *colorTable64; //[GRADIENT_STOPTABLE_SIZE];
const QRgb *colorTable32; //[GRADIENT_STOPTABLE_SIZE];
uint alphaColor : 1;
};
@ -382,13 +383,13 @@ static inline uint qt_gradient_clamp(const QGradientData *data, int ipos)
static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos)
{
int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
return data->colorTable[qt_gradient_clamp(data, ipos)].toArgb32();
return data->colorTable32[qt_gradient_clamp(data, ipos)];
}
static inline const QRgba64& qt_gradient_pixel64(const QGradientData *data, qreal pos)
{
int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
return data->colorTable[qt_gradient_clamp(data, ipos)];
return data->colorTable64[qt_gradient_clamp(data, ipos)];
}
static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c)
@ -556,7 +557,7 @@ public:
delta_det4_vec.v = Simd::v_add(delta_det4_vec.v, v_delta_delta_det16); \
b_vec.v = Simd::v_add(b_vec.v, v_delta_b4); \
for (int i = 0; i < 4; ++i) \
*buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable[index_vec.i[i]].toArgb32(); \
*buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable32[index_vec.i[i]]; \
}
#define FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP) \

View File

@ -3616,7 +3616,7 @@ QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color)
{
Q_ASSERT(image.depth() == 1);
QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB);
const QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB);
QImage dest = QImage(sourceImage.size(), QImage::Format_ARGB32_Premultiplied);
QRgb fg = qPremultiply(color.rgba());
@ -3625,7 +3625,7 @@ QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color)
int height = sourceImage.height();
int width = sourceImage.width();
for (int y=0; y<height; ++y) {
uchar *source = sourceImage.scanLine(y);
const uchar *source = sourceImage.constScanLine(y);
QRgb *target = reinterpret_cast<QRgb *>(dest.scanLine(y));
if (!source || !target)
QT_THROW(std::bad_alloc()); // we must have run out of memory
@ -4144,7 +4144,8 @@ class QGradientCache
{
inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) :
stops(qMove(s)), opacity(op), interpolationMode(mode) {}
QRgba64 buffer[GRADIENT_STOPTABLE_SIZE];
QRgba64 buffer64[GRADIENT_STOPTABLE_SIZE];
QRgb buffer32[GRADIENT_STOPTABLE_SIZE];
QGradientStops stops;
int opacity;
QGradient::InterpolationMode interpolationMode;
@ -4153,7 +4154,9 @@ class QGradientCache
typedef QMultiHash<quint64, CacheInfo> QGradientColorTableHash;
public:
inline const QRgba64 *getBuffer(const QGradient &gradient, int opacity) {
typedef QPair<const QRgb *, const QRgba64 *> ColorBufferPair;
inline ColorBufferPair getBuffer(const QGradient &gradient, int opacity) {
quint64 hash_val = 0;
const QGradientStops stops = gradient.stops();
@ -4169,7 +4172,8 @@ public:
do {
const CacheInfo &cache_info = it.value();
if (cache_info.stops == stops && cache_info.opacity == opacity && cache_info.interpolationMode == gradient.interpolationMode())
return cache_info.buffer;
return qMakePair(reinterpret_cast<const QRgb *>(cache_info.buffer32),
reinterpret_cast<const QRgba64 *>(cache_info.buffer64));
++it;
} while (it != cache.constEnd() && it.key() == hash_val);
// an exact match for these stops and opacity was not found, create new cache
@ -4183,14 +4187,18 @@ protected:
inline void generateGradientColorTable(const QGradient& g,
QRgba64 *colorTable,
int size, int opacity) const;
QRgba64 *addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) {
ColorBufferPair addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) {
if (cache.size() == maxCacheSize()) {
// may remove more than 1, but OK
cache.erase(cache.begin() + (qrand() % maxCacheSize()));
}
CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());
generateGradientColorTable(gradient, cache_entry.buffer, paletteSize(), opacity);
return cache.insert(hash_val, cache_entry).value().buffer;
generateGradientColorTable(gradient, cache_entry.buffer64, paletteSize(), opacity);
for (int i = 0; i < GRADIENT_STOPTABLE_SIZE; ++i)
cache_entry.buffer32[i] = cache_entry.buffer64[i].toArgb32();
CacheInfo &cache_value = cache.insert(hash_val, cache_entry).value();
return qMakePair(reinterpret_cast<const QRgb *>(cache_value.buffer32),
reinterpret_cast<const QRgba64 *>(cache_value.buffer64));
}
QGradientColorTableHash cache;
@ -4424,7 +4432,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
type = LinearGradient;
const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha));
QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha);
gradient.colorTable64 = colorBuffers.second;
gradient.colorTable32 = colorBuffers.first;
gradient.spread = g->spread();
QLinearGradientData &linearData = gradient.linear;
@ -4441,7 +4453,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
type = RadialGradient;
const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient());
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha));
QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha);
gradient.colorTable64 = colorBuffers.second;
gradient.colorTable32 = colorBuffers.first;
gradient.spread = g->spread();
QRadialGradientData &radialData = gradient.radial;
@ -4462,7 +4478,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
type = ConicalGradient;
const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient());
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha));
QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha);
gradient.colorTable64 = colorBuffers.second;
gradient.colorTable32 = colorBuffers.first;
gradient.spread = QGradient::RepeatSpread;
QConicalGradientData &conicalData = gradient.conical;

View File

@ -269,12 +269,14 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
QOpenGLTextureBlitter *blitter, const QPoint &offset)
{
const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
return;
QRect rectInWindow = textures->geometry(idx);
// relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust
rectInWindow.translate(-offset);
QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
clipRect = QRect(QPoint(0, 0), rectInWindow.size());
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
@ -520,7 +522,23 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
if (needsConversion)
image = image.convertToFormat(QImage::Format_RGBA8888);
// The image provided by the backingstore may have a stride larger than width * 4, for
// instance on platforms that manually implement client-side decorations.
static const int bytesPerPixel = 4;
const int strideInPixels = image.bytesPerLine() / bytesPerPixel;
const bool hasUnpackRowLength = !ctx->isOpenGLES() || ctx->format().majorVersion() >= 3;
QOpenGLFunctions *funcs = ctx->functions();
if (hasUnpackRowLength) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, strideInPixels);
} else if (strideInPixels != image.width()) {
// No UNPACK_ROW_LENGTH on ES 2.0 and yet we would need it. This case is typically
// hit with QtWayland which is rarely used in combination with a ES2.0-only GL
// implementation. Therefore, accept the performance hit and do a copy.
image = image.copy();
}
if (resized) {
if (d_ptr->textureId)
funcs->glDeleteTextures(1, &d_ptr->textureId);
@ -542,11 +560,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
QRect imageRect = image.rect();
QRect rect = dirtyRegion.boundingRect() & imageRect;
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
if (hasUnpackRowLength) {
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()) + rect.x() * 4);
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
image.constScanLine(rect.y()) + rect.x() * bytesPerPixel);
} else {
// if the rect is wide enough it's cheaper to just
// extend it instead of doing an image copy
@ -568,6 +584,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
}
}
if (hasUnpackRowLength)
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
return d_ptr->textureId;
}
#endif // QT_NO_OPENGL

View File

@ -3751,7 +3751,7 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)
QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap)
{
QImage image = bitmap.toImage();
const QImage image = bitmap.toImage();
QRegionPrivate *region = new QRegionPrivate;
@ -3769,7 +3769,7 @@ QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap)
int x,
y;
for (y = 0; y < image.height(); ++y) {
uchar *line = image.scanLine(y);
const uchar *line = image.constScanLine(y);
int w = image.width();
uchar all = zero;
int prev1 = -1;

View File

@ -345,7 +345,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP
uchar *dest = d + (c.y + y) *dbpl + c.x/8;
if (y < mh) {
uchar *src = mask.scanLine(y);
const uchar *src = mask.constScanLine(y);
for (int x = 0; x < c.w/8; ++x) {
if (x < (mw+7)/8)
dest[x] = src[x];
@ -367,7 +367,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP
for (int y = 0; y < c.h; ++y) {
uchar *dest = d + (c.y + y) *dbpl + c.x;
if (y < mh) {
uchar *src = (uchar *) mask.scanLine(y);
const uchar *src = mask.constScanLine(y);
for (int x = 0; x < c.w; ++x) {
if (x < mw)
dest[x] = (src[x >> 3] & (1 << (7 - (x & 7)))) > 0 ? 255 : 0;
@ -378,7 +378,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP
for (int y = 0; y < c.h; ++y) {
uchar *dest = d + (c.y + y) *dbpl + c.x;
if (y < mh) {
uchar *src = (uchar *) mask.scanLine(y);
const uchar *src = mask.constScanLine(y);
for (int x = 0; x < c.w; ++x) {
if (x < mw)
dest[x] = src[x];

View File

@ -829,7 +829,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp
}
}
}
const uchar *bitmap_data = bitmap.bits();
const uchar *bitmap_data = bitmap.constBits();
QFixedPoint offset = glyphs.offsets[i];
advanceX += offset.x;
advanceY += offset.y;
@ -886,12 +886,12 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, con
QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &t)
{
QImage alphaMask = alphaMapForGlyph(glyph, t);
const QImage alphaMask = alphaMapForGlyph(glyph, t);
QImage rgbMask(alphaMask.width(), alphaMask.height(), QImage::Format_RGB32);
for (int y=0; y<alphaMask.height(); ++y) {
uint *dst = (uint *) rgbMask.scanLine(y);
uchar *src = (uchar *) alphaMask.scanLine(y);
const uchar *src = alphaMask.constScanLine(y);
for (int x=0; x<alphaMask.width(); ++x) {
int val = src[x];
dst[x] = qRgb(val, val, val);
@ -979,7 +979,7 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph)
for (int y=0; y<im.height(); ++y) {
uchar *dst = (uchar *) alphaMap.scanLine(y);
uint *src = (uint *) im.scanLine(y);
const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y));
for (int x=0; x<im.width(); ++x)
dst[x] = qAlpha(src[x]);
}

View File

@ -1261,7 +1261,7 @@ QFixed QFontEngineFT::xHeight() const
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
if (os2 && os2->sxHeight) {
lockFace();
QFixed answer = QFixed(os2->sxHeight*freetype->face->size->metrics.y_ppem)/freetype->face->units_per_EM;
QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize();
unlockFace();
return answer;
}
@ -1273,7 +1273,7 @@ QFixed QFontEngineFT::averageCharWidth() const
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
if (os2 && os2->xAvgCharWidth) {
lockFace();
QFixed answer = QFixed(os2->xAvgCharWidth*freetype->face->size->metrics.x_ppem)/freetype->face->units_per_EM;
QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize();
unlockFace();
return answer;
}
@ -1301,7 +1301,7 @@ void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) c
kerning_pairs_loaded = true;
lockFace();
if (freetype->face->size->metrics.x_ppem != 0) {
QFixed scalingFactor(freetype->face->units_per_EM/freetype->face->size->metrics.x_ppem);
QFixed scalingFactor = emSquareSize() / QFixed(freetype->face->size->metrics.x_ppem);
unlockFace();
const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor);
} else {

View File

@ -795,7 +795,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te
\li Qt::TextSingleLine ignores newline characters.
\li Qt::TextExpandTabs expands tabs (see below)
\li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
\li Qt::TextWordBreak breaks the text to fit the rectangle.
\li Qt::TextWordWrap breaks the text to fit the rectangle.
\endlist
If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is
@ -1579,7 +1579,7 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString&
\li Qt::TextSingleLine ignores newline characters.
\li Qt::TextExpandTabs expands tabs (see below)
\li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
\li Qt::TextWordBreak breaks the text to fit the rectangle.
\li Qt::TextWordWrap breaks the text to fit the rectangle.
\endlist
These flags are defined in the \l{Qt::TextFlag} enum.

View File

@ -1078,8 +1078,8 @@ QTextCursor::QTextCursor(const QTextBlock &block)
/*!
\internal
*/
QTextCursor::QTextCursor(QTextDocumentPrivate &p, int pos)
: d(new QTextCursorPrivate(&p))
QTextCursor::QTextCursor(QTextDocumentPrivate *p, int pos)
: d(new QTextCursorPrivate(p))
{
d->adjusted_anchor = d->anchor = d->position = pos;

View File

@ -67,6 +67,8 @@ class Q_GUI_EXPORT QTextCursor
public:
QTextCursor();
explicit QTextCursor(QTextDocument *document);
QTextCursor(QTextDocumentPrivate *p, int pos);
explicit QTextCursor(QTextCursorPrivate *d);
explicit QTextCursor(QTextFrame *frame);
explicit QTextCursor(const QTextBlock &block);
QTextCursor(const QTextCursor &cursor);
@ -225,9 +227,6 @@ public:
QTextDocument *document() const;
private:
QTextCursor(QTextDocumentPrivate &p, int pos);
explicit QTextCursor(QTextCursorPrivate *d);
QSharedDataPointer<QTextCursorPrivate> d;
friend class QTextCursorPrivate;
friend class QTextDocumentPrivate;

View File

@ -107,7 +107,7 @@ public:
void aboutToRemoveCell(int from, int to);
static QTextCursor fromPosition(QTextDocumentPrivate *d, int pos)
{ return QTextCursor(*d, pos); }
{ return QTextCursor(d, pos); }
QTextDocumentPrivate *priv;
qreal x;

View File

@ -1710,7 +1710,7 @@ bool QTextDocumentPrivate::ensureMaximumBlockCount()
beginEditBlock();
const int blocksToRemove = blocks.numNodes() - maximumBlockCount;
QTextCursor cursor(*this, 0);
QTextCursor cursor(this, 0);
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, blocksToRemove);
unreachableCharacterCount += cursor.selectionEnd() - cursor.selectionStart();

View File

@ -1064,12 +1064,15 @@ QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const
QVector<quint32> indexes = oldGlyphRun.glyphIndexes();
QVector<QPointF> positions = oldGlyphRun.positions();
QRectF boundingRect = oldGlyphRun.boundingRect();
indexes += glyphRun.glyphIndexes();
positions += glyphRun.positions();
boundingRect = boundingRect.united(glyphRun.boundingRect());
oldGlyphRun.setGlyphIndexes(indexes);
oldGlyphRun.setPositions(positions);
oldGlyphRun.setBoundingRect(boundingRect);
} else {
glyphRunHash[key] = glyphRun;
}

View File

@ -300,19 +300,6 @@ static inline QAbstractSocket::SocketType qt_socket_getType(qintptr socketDescri
return QAbstractSocket::UnknownSocketType;
}
/*! \internal
*/
static inline int qt_socket_getMaxMsgSize(qintptr socketDescriptor)
{
int value = 0;
QT_SOCKLEN_T valueSize = sizeof(value);
if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *) &value, &valueSize) != 0) {
WS_ERROR_DEBUG(WSAGetLastError());
}
return value;
}
// MS Transport Provider IOCTL to control
// reporting PORT_UNREACHABLE messages
// on UDP sockets via recv/WSARecv/etc.

View File

@ -43,7 +43,7 @@
#include <QtCore/QtGlobal>
#include <QtCore/QString>
#include <QtCore/QMetaType>
#if QT_DEPRECATED_SINCE(5, 5)
#if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/QHash>
#endif
#include <QtCore/qhashfunctions.h>

View File

@ -145,7 +145,7 @@ public:
unsigned int tlsPskClientCallback(const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len);
#ifdef Q_OS_WIN
void fetchCaRootForCert(const QSslCertificate &cert);
void _q_caRootLoaded(QSslCertificate,QSslCertificate);
void _q_caRootLoaded(QSslCertificate,QSslCertificate) Q_DECL_OVERRIDE;
#endif
Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);

View File

@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
It is up to the platform plugin to manage the lifetime of the
compositor (instance(), destroy()), set the correct destination
context and window as early as possible (setTargetWindow()),
context and window as early as possible (setTarget()),
register the composited windows as they are shown, activated,
raised and lowered (addWindow(), moveToTop(), etc.), and to
schedule repaints (update()).
@ -183,11 +183,11 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter)
{
const QRect rectInWindow = textures->geometry(idx);
QRect clipRect = textures->clipRect(idx);
const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
clipRect = QRect(QPoint(0, 0), rectInWindow.size());
return;
const QRect rectInWindow = textures->geometry(idx);
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());

View File

@ -40,6 +40,7 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QWindow>
#include <QtGui/QPainter>
#include <QtGui/QOffscreenSurface>
#include <qpa/qplatformbackingstore.h>
#include <private/qwindow_p.h>
@ -88,13 +89,28 @@ QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore()
{
if (m_bsTexture) {
QOpenGLContext *ctx = QOpenGLContext::currentContext();
// With render-to-texture-widgets QWidget makes sure the TLW's shareContext() is
// made current before destroying backingstores. That is however not the case for
// windows with regular widgets only.
QScopedPointer<QOffscreenSurface> tempSurface;
if (!ctx) {
ctx = QOpenGLCompositor::instance()->context();
tempSurface.reset(new QOffscreenSurface);
tempSurface->setFormat(ctx->format());
tempSurface->create();
ctx->makeCurrent(tempSurface.data());
}
if (ctx && m_bsTextureContext && ctx->shareGroup() == m_bsTextureContext->shareGroup())
glDeleteTextures(1, &m_bsTexture);
else
qWarning("QOpenGLCompositorBackingStore: Texture is not valid in the current context");
if (tempSurface)
ctx->doneCurrent();
}
delete m_textures;
delete m_textures; // this does not actually own any GL resources
}
QPaintDevice *QOpenGLCompositorBackingStore::paintDevice()
@ -164,16 +180,15 @@ void QOpenGLCompositorBackingStore::updateTexture()
void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
// Called for ordinary raster windows. This is rare since RasterGLSurface
// support is claimed which leads to having all QWidget windows marked as
// RasterGLSurface instead of just Raster. These go through
// compositeAndFlush() instead of this function.
// Called for ordinary raster windows.
Q_UNUSED(region);
Q_UNUSED(offset);
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
QOpenGLContext *dstCtx = compositor->context();
Q_ASSERT(dstCtx);
QWindow *dstWin = compositor->targetWindow();
if (!dstWin)
return;
@ -190,7 +205,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi
QPlatformTextureList *textures, QOpenGLContext *context,
bool translucentBackground)
{
// QOpenGLWidget/QQuickWidget content provided as textures. The raster content should go on top.
// QOpenGLWidget/QQuickWidget content provided as textures. The raster content goes on top.
Q_UNUSED(region);
Q_UNUSED(offset);
@ -199,6 +214,12 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
QOpenGLContext *dstCtx = compositor->context();
Q_ASSERT(dstCtx); // setTarget() must have been called before, e.g. from QEGLFSWindow
// The compositor's context and the context to which QOpenGLWidget/QQuickWidget
// textures belong are not the same. They share resources, though.
Q_ASSERT(context->shareGroup() == dstCtx->shareGroup());
QWindow *dstWin = compositor->targetWindow();
if (!dstWin)
return;
@ -260,6 +281,7 @@ void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &sta
if (m_bsTexture) {
glDeleteTextures(1, &m_bsTexture);
m_bsTexture = 0;
m_bsTextureContext = Q_NULLPTR;
}
}

View File

@ -136,10 +136,6 @@ void QTuioHandler::processPackets()
if (size != datagram.size())
datagram.resize(size);
QOscBundle bundle(datagram);
if (!bundle.isValid())
continue;
// "A typical TUIO bundle will contain an initial ALIVE message,
// followed by an arbitrary number of SET messages that can fit into the
// actual bundle capacity and a concluding FSEQ message. A minimal TUIO
@ -147,7 +143,19 @@ void QTuioHandler::processPackets()
// messages. The FSEQ frame ID is incremented for each delivered bundle,
// while redundant bundles can be marked using the frame sequence ID
// -1."
QList<QOscMessage> messages = bundle.messages();
QList<QOscMessage> messages;
QOscBundle bundle(datagram);
if (bundle.isValid()) {
messages = bundle.messages();
} else {
QOscMessage msg(datagram);
if (!msg.isValid()) {
qCWarning(lcTuioSet) << "Got invalid datagram.";
continue;
}
messages.push_back(msg);
}
foreach (const QOscMessage &message, messages) {
if (message.addressPattern() != "/tuio/2Dcur") {
@ -320,6 +328,14 @@ void QTuioHandler::process2DCurFseq(const QOscMessage &message)
Q_UNUSED(message); // TODO: do we need to do anything with the frame id?
QWindow *win = QGuiApplication::focusWindow();
// With TUIO the first application takes exclusive ownership of the "device"
// we cannot attach more than one application to the same port anyway.
// Forcing delivery makes it easy to use simulators in the same machine
// and forget about headaches about unfocused TUIO windows.
static bool forceDelivery = qEnvironmentVariableIsSet("QT_TUIOTOUCH_DELIVER_WITHOUT_FOCUS");
if (!win && QGuiApplication::topLevelWindows().length() > 0 && forceDelivery)
win = QGuiApplication::topLevelWindows().at(0);
if (!win)
return;

View File

@ -59,7 +59,7 @@ QCocoaAccessibility::~QCocoaAccessibility()
void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
{
if (!isActive() || !event->accessibleInterface())
if (!isActive() || !event->accessibleInterface() || !event->accessibleInterface()->isValid())
return;
QMacAccessibilityElement *element = [QMacAccessibilityElement elementWithId: event->uniqueId()];
if (!element) {

View File

@ -126,7 +126,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
if (!element) {
QAccessibleInterface *iface = QAccessible::accessibleInterface(anId);
Q_ASSERT(iface);
if (!iface)
if (!iface || !iface->isValid())
return nil;
element = [[self alloc] initWithId:anId];
cache->insertElement(anId, element);
@ -178,7 +178,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
static NSArray *defaultAttributes = nil;
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface)
if (!iface || !iface->isValid())
return defaultAttributes;
if (defaultAttributes == nil) {
@ -232,7 +232,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (id)parentElement {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface)
if (!iface || !iface->isValid())
return nil;
if (QWindow *window = iface->window()) {
@ -265,7 +265,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (id)accessibilityAttributeValue:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) {
if (!iface || !iface->isValid()) {
qWarning() << "Called attribute on invalid object: " << axid;
return nil;
}
@ -344,9 +344,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
} else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) {
if (QAccessibleTextInterface *text = iface->textInterface()) {
int line = -1;
int position = text->cursorPosition();
convertLineOffset(text, &line, &position);
int line = 0; // true for all single line edits
if (iface->state().multiLine) {
int position = text->cursorPosition();
convertLineOffset(text, &line, &position);
}
return [NSNumber numberWithInt: line];
}
return nil;
@ -362,7 +364,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (NSArray *)accessibilityParameterizedAttributeNames {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) {
if (!iface || !iface->isValid()) {
qWarning() << "Called attribute on invalid object: " << axid;
return nil;
}
@ -387,7 +389,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) {
if (!iface || !iface->isValid()) {
qWarning() << "Called attribute on invalid object: " << axid;
return nil;
}
@ -454,7 +456,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface)
if (!iface || !iface->isValid())
return NO;
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
@ -473,7 +475,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface)
if (!iface || !iface->isValid())
return;
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
if (QAccessibleActionInterface *action = iface->actionInterface())
@ -502,7 +504,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (NSArray *)accessibilityActionNames {
NSMutableArray * nsActions = [NSMutableArray new];
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface)
if (!iface || !iface->isValid())
return nsActions;
const QStringList &supportedActionNames = QAccessibleBridgeUtils::effectiveActionNames(iface);
@ -517,7 +519,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (NSString *)accessibilityActionDescription:(NSString *)action {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface)
if (!iface || !iface->isValid())
return nil; // FIXME is that the right return type??
QString qtAction = QCocoaAccessible::translateAction(action, iface);
QString description;

View File

@ -134,7 +134,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
if ([mSavePanel respondsToSelector:@selector(setLevel:)])
[mSavePanel setLevel:NSModalPanelWindowLevel];
[mSavePanel setDelegate:self];
mReturnCode = -1;
mHelper = helper;
mNameFilterDropDownList = new QStringList(mOptions->nameFilters());
@ -155,7 +155,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
[self createTextField];
[self createAccessory];
[mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil];
// -setAccessoryView: can result in -panel:directoryDidChange:
// resetting our mCurrentDir, set the delegate
// here to make sure it gets the correct value.
[mSavePanel setDelegate:self];
if (mOptions->isLabelExplicitlySet(QFileDialogOptions::Accept))
[mSavePanel setPrompt:[self strip:options->labelText(QFileDialogOptions::Accept)]];

View File

@ -200,11 +200,8 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
// If there is a "root" window into which raster and QOpenGLWidget content is
// composited, all other contexts must share with its context.
QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context();
EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display();
QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle();
QPlatformOpenGLContext *share = context->shareHandle();
QVariant nativeHandle = context->nativeHandle();
QEglFSContext *ctx;

View File

@ -142,6 +142,14 @@ void QEglFSWindow::create()
if (Q_UNLIKELY(!context->create()))
qFatal("EGLFS: Failed to create compositing context");
compositor->setTarget(context, window());
// If there is a "root" window into which raster and QOpenGLWidget content is
// composited, all other contexts must share with its context.
if (!qt_gl_global_share_context()) {
qt_gl_set_global_share_context(context);
// What we set up here is in effect equivalent to the application setting
// AA_ShareOpenGLContexts. Set the attribute to be fully consistent.
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
}
}
}

View File

@ -162,7 +162,7 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
if (QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha)
m_alphaNeedsFill = true;
else // upgrade but here we know app painting does not rely on alpha hence no need to fill
format = qt_alphaVersionForPainting(format);
format = qt_maybeAlphaVersionWithSameDepth(format);
QWindowsNativeImage *oldwni = m_image.data();
QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format);

View File

@ -148,8 +148,8 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits,
QScopedArrayPointer<uchar> xMask(new uchar[height * n]);
int x = 0;
for (int i = 0; i < height; ++i) {
const uchar *bits = bbits.scanLine(i);
const uchar *mask = mbits.scanLine(i);
const uchar *bits = bbits.constScanLine(i);
const uchar *mask = mbits.constScanLine(i);
for (int j = 0; j < n; ++j) {
uchar b = bits[j];
uchar m = mask[j];
@ -179,8 +179,8 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits,
x += sysN;
} else {
int fillWidth = n > sysN ? sysN : n;
const uchar *bits = bbits.scanLine(i);
const uchar *mask = mbits.scanLine(i);
const uchar *bits = bbits.constScanLine(i);
const uchar *mask = mbits.constScanLine(i);
for (int j = 0; j < fillWidth; ++j) {
uchar b = bits[j];
uchar m = mask[j];

View File

@ -996,7 +996,7 @@ EGLConfig QWindowsEGLContext::chooseConfig(const QSurfaceFormat &format)
QVector<EGLConfig> configs(matching);
QWindowsEGLStaticContext::libEGL.eglChooseConfig(display, configureAttributes.constData(), configs.data(), configs.size(), &matching);
if (!cfg && matching > 0)
cfg = configs.first();
cfg = configs.constFirst();
EGLint red = 0;
EGLint green = 0;

View File

@ -877,14 +877,13 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
static const int SMOOTH_SCALABLE = 0xffff;
const QString foundryName; // No such concept.
const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric;
const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH);
const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE);
const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight;
const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal;
const bool fixed = !(textmetric->tmPitchAndFamily & TMPF_FIXED_PITCH);
const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE);
const bool scalable = textmetric->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
const int size = scalable ? SMOOTH_SCALABLE : textmetric->tmHeight;
const QFont::Style style = textmetric->tmItalic ? QFont::StyleItalic : QFont::StyleNormal;
const bool antialias = false;
const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(tm->tmWeight);
const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(textmetric->tmWeight);
const QFont::Stretch stretch = QFont::Unstretched;
#ifndef QT_NO_DEBUG_OUTPUT
@ -964,18 +963,21 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
return true;
}
static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
int type, LPARAM registerAlias)
static int QT_WIN_CALLBACK storeFont(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
DWORD type, LPARAM lParam)
{
const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont);
const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
const uchar charSet = f->elfLogFont.lfCharSet;
const bool registerAlias = bool(lParam);
const FONTSIGNATURE signature = textmetric->ntmFontSig;
// NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
// identical to a TEXTMETRIC except for the last four members, which we don't use
// anyway
addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type, registerAlias);
// NEWTEXTMETRICEX (passed for TT fonts) is a NEWTEXTMETRIC, which according
// to the documentation is identical to a TEXTMETRIC except for the last four
// members, which we don't use anyway
const FONTSIGNATURE *signature = Q_NULLPTR;
if (type & TRUETYPE_FONTTYPE)
signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig;
addFontToDatabase(familyName, charSet, textmetric, signature, type, registerAlias);
// keep on enumerating
return 1;
@ -994,7 +996,7 @@ void QWindowsFontDatabase::populateFamily(const QString &familyName, bool regist
familyName.toWCharArray(lf.lfFaceName);
lf.lfFaceName[familyName.size()] = 0;
lf.lfPitchAndFamily = 0;
EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, (LPARAM)registerAlias, 0);
EnumFontFamiliesEx(dummy, &lf, storeFont, LPARAM(registerAlias), 0);
ReleaseDC(0, dummy);
}
@ -1015,9 +1017,11 @@ struct PopulateFamiliesContext
};
} // namespace
static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam)
static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
DWORD, LPARAM lparam)
{
// the "@family" fonts are just the same as "family". Ignore them.
const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont);
const wchar_t *faceNameW = f->elfLogFont.lfFaceName;
if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) {
const QString faceName = QString::fromWCharArray(faceNameW);
@ -1027,7 +1031,7 @@ static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICE
context->seenSystemDefaultFont = true;
// Register current font's english name as alias
const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE);
const bool ttf = textmetric->tmPitchAndFamily & TMPF_TRUETYPE;
if (ttf && localizedName(faceName)) {
const QString englishName = getEnglishName(faceName);
if (!englishName.isEmpty()) {
@ -1051,7 +1055,7 @@ void QWindowsFontDatabase::populateFontDatabase()
lf.lfFaceName[0] = 0;
lf.lfPitchAndFamily = 0;
PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family());
EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0);
EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0);
ReleaseDC(0, dummy);
// Work around EnumFontFamiliesEx() not listing the system font.
if (!context.seenSystemDefaultFont)

View File

@ -396,14 +396,13 @@ static bool addFontToDatabase(const QString &faceName,
static const int SMOOTH_SCALABLE = 0xffff;
const QString foundryName; // No such concept.
const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric;
const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH);
const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE);
const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight;
const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal;
const bool fixed = !(textmetric->tmPitchAndFamily & TMPF_FIXED_PITCH);
const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE);
const bool scalable = textmetric->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
const int size = scalable ? SMOOTH_SCALABLE : textmetric->tmHeight;
const QFont::Style style = textmetric->tmItalic ? QFont::StyleItalic : QFont::StyleNormal;
const bool antialias = false;
const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(tm->tmWeight);
const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(textmetric->tmWeight);
const QFont::Stretch stretch = QFont::Unstretched;
#ifndef QT_NO_DEBUG_STREAM
@ -520,19 +519,21 @@ static QByteArray getFntTable(HFONT hfont, uint tag)
}
#endif
static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
int type, LPARAM)
static int QT_WIN_CALLBACK storeFont(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
DWORD type, LPARAM)
{
const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont);
const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
const QString fullName = QString::fromWCharArray(f->elfFullName);
const uchar charSet = f->elfLogFont.lfCharSet;
const FONTSIGNATURE signature = textmetric->ntmFontSig;
// NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
// identical to a TEXTMETRIC except for the last four members, which we don't use
// anyway
addFontToDatabase(faceName, fullName, charSet, (TEXTMETRIC *)textmetric, &signature, type, false);
// NEWTEXTMETRICEX (passed for TT fonts) is a NEWTEXTMETRIC, which according
// to the documentation is identical to a TEXTMETRIC except for the last four
// members, which we don't use anyway
const FONTSIGNATURE *signature = Q_NULLPTR;
if (type & TRUETYPE_FONTTYPE)
signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig;
addFontToDatabase(faceName, fullName, charSet, textmetric, signature, type, false);
// keep on enumerating
return 1;
@ -559,7 +560,7 @@ void QWindowsFontDatabaseFT::populateFamily(const QString &familyName)
familyName.toWCharArray(lf.lfFaceName);
lf.lfFaceName[familyName.size()] = 0;
lf.lfPitchAndFamily = 0;
EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, 0, 0);
EnumFontFamiliesEx(dummy, &lf, storeFont, 0, 0);
ReleaseDC(0, dummy);
}
@ -579,17 +580,20 @@ struct PopulateFamiliesContext
// Delayed population of font families
static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam)
static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
DWORD, LPARAM lparam)
{
const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont);
// the "@family" fonts are just the same as "family". Ignore them.
const wchar_t *faceNameW = f->elfLogFont.lfFaceName;
if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) {
// Register only font families for which a font file exists for delayed population
const bool ttf = textmetric->tmPitchAndFamily & TMPF_TRUETYPE;
const QString faceName = QString::fromWCharArray(faceNameW);
const FontKey *key = findFontKey(faceName);
if (!key) {
key = findFontKey(QString::fromWCharArray(f->elfFullName));
if (!key && (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE) && localizedName(faceName))
if (!key && ttf && localizedName(faceName))
key = findFontKey(getEnglishName(faceName));
}
if (key) {
@ -599,7 +603,6 @@ static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICE
context->seenSystemDefaultFont = true;
// Register current font's english name as alias
const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE);
if (ttf && localizedName(faceName)) {
const QString englishName = getEnglishName(faceName);
if (!englishName.isEmpty()) {
@ -623,7 +626,7 @@ void QWindowsFontDatabaseFT::populateFontDatabase()
lf.lfFaceName[0] = 0;
lf.lfPitchAndFamily = 0;
PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family());
EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0);
EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0);
ReleaseDC(0, dummy);
// Work around EnumFontFamiliesEx() not listing the system font
if (!context.seenSystemDefaultFont)

View File

@ -1181,11 +1181,11 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo
for (int y=0; y<mask->height(); ++y) {
uchar *dest = alphaMap.scanLine(y);
if (mask->image().format() == QImage::Format_RGB16) {
const qint16 *src = (qint16 *) ((const QImage &) mask->image()).scanLine(y);
const qint16 *src = reinterpret_cast<const qint16 *>(mask->image().constScanLine(y));
for (int x=0; x<mask->width(); ++x)
dest[x] = 255 - qGray(src[x]);
} else {
const uint *src = (uint *) ((const QImage &) mask->image()).scanLine(y);
const uint *src = reinterpret_cast<const uint *>(mask->image().constScanLine(y));
for (int x=0; x<mask->width(); ++x) {
if (QWindowsNativeImage::systemFormat() == QImage::Format_RGB16)
dest[x] = 255 - qGray(src[x]);
@ -1230,7 +1230,7 @@ QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTra
QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32);
for (int y=0; y<mask->height(); ++y) {
uint *dest = (uint *) rgbMask.scanLine(y);
const uint *src = (uint *) source.scanLine(y);
const uint *src = reinterpret_cast<const uint *>(source.constScanLine(y));
for (int x=0; x<mask->width(); ++x) {
dest[x] = 0xffffffff - (0x00ffffff & src[x]);
}

View File

@ -499,7 +499,7 @@ QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed sub
QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8);
for (int y=0; y<im.height(); ++y) {
uint *src = (uint*) im.scanLine(y);
const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y));
uchar *dst = alphaMap.scanLine(y);
for (int x=0; x<im.width(); ++x) {
*dst = 255 - (m_fontEngineData->pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.);
@ -765,12 +765,17 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
transform.m21 = matrix.m21();
transform.m22 = matrix.m22();
DWRITE_RENDERING_MODE renderMode =
fontDef.hintingPreference == QFont::PreferNoHinting
? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC
: DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
&glyphRun,
1.0f,
&transform,
DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
renderMode,
DWRITE_MEASURING_MODE_NATURAL,
0.0, 0.0,
&glyphAnalysis

View File

@ -181,8 +181,8 @@ static bool qt_write_dibv5(QDataStream &s, QImage image)
memset(buf, 0, bpl_bmp);
for (int y=image.height()-1; y>=0; y--) {
// write the image bits
QRgb *p = (QRgb *)image.scanLine(y);
QRgb *end = p + image.width();
const QRgb *p = reinterpret_cast<const QRgb *>(image.constScanLine(y));
const QRgb *end = p + image.width();
b = buf;
while (p < end) {
int alpha = qAlpha(*p);

View File

@ -189,7 +189,7 @@ static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point)
return QPoint(0, 0);
const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager();
const QWindowsScreen *screen = screenManager.screens().size() == 1
? screenManager.screens().first() : screenManager.screenAtDp(point);
? screenManager.screens().constFirst() : screenManager.screenAtDp(point);
if (screen)
return screen->availableGeometry().topLeft() - screen->geometry().topLeft();
#else

View File

@ -47,6 +47,9 @@
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaBackingStore, "qt.qpa.backingstore")
Q_LOGGING_CATEGORY(lcQpaBackingStoreVerbose, "qt.qpa.backingstore.verbose")
class QWinRTBackingStorePrivate
{
public:
@ -62,6 +65,7 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
: QPlatformBackingStore(window), d_ptr(new QWinRTBackingStorePrivate)
{
Q_D(QWinRTBackingStore);
qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window;
d->initialized = false;
d->screen = static_cast<QWinRTScreen*>(window->screen()->handle());
@ -73,6 +77,7 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
bool QWinRTBackingStore::initialize()
{
Q_D(QWinRTBackingStore);
qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << d->initialized;
if (d->initialized)
return true;
@ -94,6 +99,7 @@ bool QWinRTBackingStore::initialize()
QWinRTBackingStore::~QWinRTBackingStore()
{
qCDebug(lcQpaBackingStore) << __FUNCTION__ << this;
}
QPaintDevice *QWinRTBackingStore::paintDevice()
@ -107,6 +113,8 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
Q_D(QWinRTBackingStore);
Q_UNUSED(offset)
qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << window << region;
if (d->size.isEmpty())
return;
@ -140,6 +148,8 @@ void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents
Q_D(QWinRTBackingStore);
Q_UNUSED(staticContents)
qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << size;
if (!initialize())
return;
@ -169,11 +179,14 @@ QImage QWinRTBackingStore::toImage() const
void QWinRTBackingStore::beginPaint(const QRegion &region)
{
qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << region;
resize(window()->size(), region);
}
void QWinRTBackingStore::endPaint()
{
qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this;
}
QT_END_NAMESPACE

View File

@ -39,9 +39,13 @@
#include <qpa/qplatformbackingstore.h>
#include <QtCore/QScopedPointer>
#include <QtCore/QLoggingCategory>
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStore)
Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStoreVerbose)
class QWinRTScreen;
class QWinRTBackingStorePrivate;

View File

@ -0,0 +1,185 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later 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 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwinrtclipboard.h"
#include <QtCore/QCoreApplication>
#include <QtCore/qfunctions_winrt.h>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
#include <Windows.ApplicationModel.datatransfer.h>
#include <functional>
using namespace ABI::Windows::ApplicationModel::DataTransfer;
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
typedef IEventHandler<IInspectable *> ContentChangedHandler;
#define RETURN_NULLPTR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return nullptr)
QT_BEGIN_NAMESPACE
QWinRTClipboard::QWinRTClipboard()
{
#ifndef Q_OS_WINPHONE
QEventDispatcherWinRT::runOnXamlThread([this]() {
HRESULT hr;
hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard).Get(),
&m_nativeClipBoard);
Q_ASSERT_SUCCEEDED(hr);
EventRegistrationToken tok;
hr = m_nativeClipBoard->add_ContentChanged(Callback<ContentChangedHandler>(this, &QWinRTClipboard::onContentChanged).Get(), &tok);
Q_ASSERT_SUCCEEDED(hr);
return hr;
});
#endif // !Q_OS_WINPHONE
}
QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode)
{
if (!supportsMode(mode))
return nullptr;
#ifndef Q_OS_WINPHONE
ComPtr<IDataPackageView> view;
HRESULT hr;
hr = m_nativeClipBoard->GetContent(&view);
RETURN_NULLPTR_IF_FAILED("Could not get clipboard content.");
ComPtr<IAsyncOperation<HSTRING>> op;
HString result;
// This throws a security exception (WinRT originate error / 0x40080201.
// Unfortunately there seems to be no way to avoid this, neither
// running on the XAML thread, nor some other way. Stack Overflow
// confirms this problem since Windows (Phone) 8.0.
hr = view->GetTextAsync(&op);
RETURN_NULLPTR_IF_FAILED("Could not get clipboard text.");
hr = QWinRTFunctions::await(op, result.GetAddressOf());
RETURN_NULLPTR_IF_FAILED("Could not get clipboard text content");
quint32 size;
const wchar_t *textStr = result.GetRawBuffer(&size);
QString text = QString::fromWCharArray(textStr, size);
text.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
m_mimeData.setText(text);
return &m_mimeData;
#else // Q_OS_WINPHONE
return QPlatformClipboard::mimeData(mode);
#endif // Q_OS_WINPHONE
}
// Inspired by QWindowsMimeText::convertFromMime
inline QString convertToWindowsLineEnding(const QString &text)
{
const QChar *u = text.unicode();
QString res;
const int s = text.length();
int maxsize = s + s / 40 + 3;
res.resize(maxsize);
int ri = 0;
bool cr = false;
for (int i = 0; i < s; ++i) {
if (*u == QLatin1Char('\r'))
cr = true;
else {
if (*u == QLatin1Char('\n') && !cr)
res[ri++] = QLatin1Char('\r');
cr = false;
}
res[ri++] = *u;
if (ri+3 >= maxsize) {
maxsize += maxsize / 4;
res.resize(maxsize);
}
++u;
}
res.truncate(ri);
return res;
}
void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
{
if (!supportsMode(mode))
return;
#ifndef Q_OS_WINPHONE
const QString text = data->text();
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, text]() {
HRESULT hr;
ComPtr<IDataPackage> package;
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_DataPackage).Get(),
&package);
const QString nativeString = convertToWindowsLineEnding(text);
HStringReference textRef(reinterpret_cast<LPCWSTR>(nativeString.utf16()), nativeString.length());
hr = package->SetText(textRef.Get());
RETURN_HR_IF_FAILED("Could not set text to clipboard data package.");
hr = m_nativeClipBoard->SetContent(package.Get());
RETURN_HR_IF_FAILED("Could not set clipboard content.");
return S_OK;
});
RETURN_VOID_IF_FAILED("Could not set clipboard text.");
emitChanged(mode);
#else // Q_OS_WINPHONE
QPlatformClipboard::setMimeData(data, mode);
#endif // Q_OS_WINPHONE
}
bool QWinRTClipboard::supportsMode(QClipboard::Mode mode) const
{
#ifndef Q_OS_WINPHONE
return mode == QClipboard::Clipboard;
#else
return QPlatformClipboard::supportsMode(mode);
#endif
}
HRESULT QWinRTClipboard::onContentChanged(IInspectable *, IInspectable *)
{
emitChanged(QClipboard::Clipboard);
return S_OK;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,78 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later 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 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWINRTPLATFORMCLIPBOARD_H
#define QWINRTPLATFORMCLIPBOARD_H
#include <qpa/qplatformclipboard.h>
#include <QMimeData>
#include <wrl.h>
#ifndef Q_OS_WINPHONE
namespace ABI {
namespace Windows {
namespace ApplicationModel {
namespace DataTransfer {
struct IClipboardStatics;
}
}
}
}
#endif // !Q_OS_WINPHONE
QT_BEGIN_NAMESPACE
class QWinRTClipboard: public QPlatformClipboard
{
public:
QWinRTClipboard();
QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE;
HRESULT onContentChanged(IInspectable *, IInspectable *);
private:
#ifndef Q_OS_WINPHONE
Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::DataTransfer::IClipboardStatics> m_nativeClipBoard;
#endif
QMimeData m_mimeData;
};
QT_END_NAMESPACE
#endif // QWINRTPLATFORMCLIPBOARD_H

View File

@ -49,6 +49,7 @@
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
QT_BEGIN_NAMESPACE
@ -148,14 +149,17 @@ bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface)
Q_D(QWinRTEGLContext);
Q_ASSERT(windowSurface->surface()->supportsOpenGL());
if (windowSurface->surface()->surfaceClass() == QSurface::Offscreen)
return false;
EGLSurface surface;
if (windowSurface->surface()->surfaceClass() == QSurface::Window) {
QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
if (window->eglSurface() == EGL_NO_SURFACE)
window->createEglSurface(g->eglDisplay, d->eglConfig);
QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
if (window->eglSurface() == EGL_NO_SURFACE)
window->createEglSurface(g->eglDisplay, d->eglConfig);
surface = window->eglSurface();
} else { // Offscreen
surface = static_cast<QEGLPbuffer *>(windowSurface)->pbuffer();
}
EGLSurface surface = window->eglSurface();
if (surface == EGL_NO_SURFACE)
return false;
@ -346,4 +350,9 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
return eglGetProcAddress(procName.constData());
}
EGLDisplay QWinRTEGLContext::display()
{
return g->eglDisplay;
}
QT_END_NAMESPACE

View File

@ -38,6 +38,7 @@
#define QWINDOWSEGLCONTEXT_H
#include <qpa/qplatformopenglcontext.h>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@ -57,6 +58,7 @@ public:
QSurfaceFormat format() const Q_DECL_OVERRIDE;
QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
static EGLDisplay display();
private:
QScopedPointer<QWinRTEGLContextPrivate> d_ptr;
Q_DECLARE_PRIVATE(QWinRTEGLContext)

View File

@ -47,6 +47,20 @@ using namespace Microsoft::WRL;
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
QDebug operator<<(QDebug d, const QFontDef &def)
{
QDebugStateSaver saver(d);
d.nospace();
d << "Family=" << def.family << " Stylename=" << def.styleName
<< " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize
<< " styleHint=" << def.styleHint << " weight=" << def.weight
<< " stretch=" << def.stretch << " hintingPreference="
<< def.hintingPreference;
return d;
}
// Based on unicode range tables at http://www.microsoft.com/typography/otspec/os2.htm#ur
static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_UNICODE_RANGE &range)
{
@ -114,6 +128,7 @@ static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_U
QString QWinRTFontDatabase::fontDir() const
{
qCDebug(lcQpaFonts) << __FUNCTION__;
QString fontDirectory = QBasicFontDatabase::fontDir();
if (!QFile::exists(fontDirectory)) {
// Fall back to app directory + fonts, and just app directory after that
@ -130,6 +145,8 @@ QString QWinRTFontDatabase::fontDir() const
QWinRTFontDatabase::~QWinRTFontDatabase()
{
qCDebug(lcQpaFonts) << __FUNCTION__;
foreach (IDWriteFontFile *fontFile, m_fonts.keys())
fontFile->Release();
@ -149,6 +166,8 @@ bool QWinRTFontDatabase::fontsAlwaysScalable() const
void QWinRTFontDatabase::populateFontDatabase()
{
qCDebug(lcQpaFonts) << __FUNCTION__;
ComPtr<IDWriteFactory1> factory;
HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory1), &factory);
if (FAILED(hr)) {
@ -204,6 +223,8 @@ void QWinRTFontDatabase::populateFontDatabase()
void QWinRTFontDatabase::populateFamily(const QString &familyName)
{
qCDebug(lcQpaFonts) << __FUNCTION__ << familyName;
IDWriteFontFamily *fontFamily = m_fontFamilies.value(familyName);
if (!fontFamily) {
qWarning("The font family %s was not found.", qPrintable(familyName));
@ -367,6 +388,8 @@ void QWinRTFontDatabase::populateFamily(const QString &familyName)
QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
{
qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << handle;
if (!handle) // Happens if a font family population failed
return 0;
@ -436,6 +459,8 @@ QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont:
Q_UNUSED(styleHint)
Q_UNUSED(script)
qCDebug(lcQpaFonts) << __FUNCTION__ << family;
QStringList result;
if (family == QLatin1String("Helvetica"))
result.append(QStringLiteral("Arial"));
@ -445,6 +470,8 @@ QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont:
void QWinRTFontDatabase::releaseHandle(void *handle)
{
qCDebug(lcQpaFonts) << __FUNCTION__ << handle;
if (!handle)
return;

View File

@ -38,12 +38,15 @@
#define QWINRTFONTDATABASE_H
#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
#include <QtCore/QLoggingCategory>
struct IDWriteFontFile;
struct IDWriteFontFamily;
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts)
struct FontDescription
{
quint32 index;

View File

@ -54,6 +54,8 @@ typedef ITypedEventHandler<InputPane*, InputPaneVisibilityEventArgs*> InputPaneV
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods")
inline QRectF getInputPaneRect(IInputPane *pane, qreal scaleFactor)
{
Rect rect;
@ -78,6 +80,8 @@ inline QRectF getInputPaneRect(IInputPane *pane, qreal scaleFactor)
QWinRTInputContext::QWinRTInputContext(QWinRTScreen *screen)
: m_screen(screen)
{
qCDebug(lcQpaInputMethods) << __FUNCTION__ << screen;
IInputPaneStatics *statics;
if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(),
&statics))) {
@ -114,6 +118,7 @@ bool QWinRTInputContext::isInputPanelVisible() const
HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEventArgs *)
{
qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane;
m_isInputPanelVisible = true;
emitInputPanelVisibleChanged();
return handleVisibilityChange(pane);
@ -121,6 +126,7 @@ HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEven
HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEventArgs *)
{
qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane;
m_isInputPanelVisible = false;
emitInputPanelVisibleChanged();
return handleVisibilityChange(pane);
@ -128,6 +134,7 @@ HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEvent
HRESULT QWinRTInputContext::handleVisibilityChange(IInputPane *pane)
{
qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane;
const QRectF keyboardRect = getInputPaneRect(pane, m_screen->scaleFactor());
if (m_keyboardRect != keyboardRect) {
m_keyboardRect = keyboardRect;
@ -165,31 +172,35 @@ static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2)
void QWinRTInputContext::showInputPanel()
{
qCDebug(lcQpaInputMethods) << __FUNCTION__;
QEventDispatcherWinRT::runOnXamlThread([&]() {
ComPtr<IInputPane2> inputPane;
HRESULT hr = getInputPane(&inputPane);
if (FAILED(hr))
return hr;
return S_OK;
boolean success;
hr = inputPane->TryShow(&success);
if (FAILED(hr) || !success)
qErrnoWarning(hr, "Failed to show input panel.");
return hr;
return S_OK;
});
}
void QWinRTInputContext::hideInputPanel()
{
qCDebug(lcQpaInputMethods) << __FUNCTION__;
QEventDispatcherWinRT::runOnXamlThread([&]() {
ComPtr<IInputPane2> inputPane;
HRESULT hr = getInputPane(&inputPane);
if (FAILED(hr))
return hr;
return S_OK;
boolean success;
hr = inputPane->TryHide(&success);
if (FAILED(hr) || !success)
qErrnoWarning(hr, "Failed to hide input panel.");
return hr;
return S_OK;
});
}

View File

@ -39,6 +39,7 @@
#include <qpa/qplatforminputcontext.h>
#include <QtCore/QRectF>
#include <QtCore/QLoggingCategory>
#include <wrl.h>
@ -58,6 +59,8 @@ namespace ABI {
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods)
class QWinRTScreen;
class QWinRTInputContext : public QPlatformInputContext
{

View File

@ -44,13 +44,19 @@
#include "qwinrteglcontext.h"
#include "qwinrtfontdatabase.h"
#include "qwinrttheme.h"
#include "qwinrtclipboard.h"
#include <QtGui/QSurface>
#include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext>
#include <qfunctions_winrt.h>
#include <QtGui/QSurface>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformoffscreensurface.h>
#include <qfunctions_winrt.h>
#include <functional>
#include <wrl.h>
#include <windows.ui.xaml.h>
@ -106,6 +112,7 @@ class QWinRTIntegrationPrivate
public:
QPlatformFontDatabase *fontDatabase;
QPlatformServices *platformServices;
QPlatformClipboard *clipboard;
QWinRTScreen *mainScreen;
QScopedPointer<QWinRTInputContext> inputContext;
@ -190,6 +197,7 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
screenAdded(d->mainScreen);
d->platformServices = new QWinRTServices;
d->clipboard = new QWinRTClipboard;
}
QWinRTIntegration::~QWinRTIntegration()
@ -295,6 +303,12 @@ QPlatformServices *QWinRTIntegration::services() const
return d->platformServices;
}
QPlatformClipboard *QWinRTIntegration::clipboard() const
{
Q_D(const QWinRTIntegration);
return d->clipboard;
}
Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
{
Q_D(const QWinRTIntegration);
@ -385,11 +399,20 @@ HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *)
QPlatformOffscreenSurface *QWinRTIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
// This is only used for shutdown of applications.
// In case we do not return an empty surface the scenegraph will try
// to create a new native window during application exit causing crashes
// or assertions.
return new QPlatformOffscreenSurface(surface);
QEGLPbuffer *pbuffer = nullptr;
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([&pbuffer, surface]() {
pbuffer = new QEGLPbuffer(QWinRTEGLContext::display(), surface->requestedFormat(), surface);
return S_OK;
});
if (hr == UI_E_WINDOW_CLOSED) {
// This is only used for shutdown of applications.
// In case we do not return an empty surface the scenegraph will try
// to create a new native window during application exit causing crashes
// or assertions.
return new QPlatformOffscreenSurface(surface);
}
return pbuffer;
}

View File

@ -93,6 +93,7 @@ public:
QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE;
QPlatformServices *services() const Q_DECL_OVERRIDE;
QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE;
Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE;
QStringList themeNames() const Q_DECL_OVERRIDE;

View File

@ -56,6 +56,8 @@ using namespace ABI::Windows::UI::ViewManagement;
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaTheme, "qt.qpa.theme")
static IUISettings *uiSettings()
{
static ComPtr<IUISettings> settings;
@ -285,12 +287,14 @@ QWinRTTheme::QWinRTTheme()
: d_ptr(new QWinRTThemePrivate)
{
Q_D(QWinRTTheme);
qCDebug(lcQpaTheme) << __FUNCTION__;
nativeColorSettings(d->palette);
}
bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const
{
qCDebug(lcQpaTheme) << __FUNCTION__ << type;
static bool useNativeDialogs = qEnvironmentVariableIsSet("QT_USE_WINRT_NATIVE_DIALOGS")
? qEnvironmentVariableIntValue("QT_USE_WINRT_NATIVE_DIALOGS") : true;
@ -301,6 +305,7 @@ bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const
QPlatformDialogHelper *QWinRTTheme::createPlatformDialogHelper(DialogType type) const
{
qCDebug(lcQpaTheme) << __FUNCTION__ << type;
switch (type) {
case FileDialog:
return new QWinRTFileDialogHelper;
@ -314,6 +319,7 @@ QPlatformDialogHelper *QWinRTTheme::createPlatformDialogHelper(DialogType type)
QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint)
{
qCDebug(lcQpaTheme) << __FUNCTION__ << hint;
HRESULT hr;
switch (hint) {
case QPlatformIntegration::CursorFlashTime: {
@ -363,6 +369,7 @@ QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint)
const QPalette *QWinRTTheme::palette(Palette type) const
{
Q_D(const QWinRTTheme);
qCDebug(lcQpaTheme) << __FUNCTION__ << type;
if (type == SystemPalette)
return &d->palette;
return QPlatformTheme::palette(type);

View File

@ -39,9 +39,12 @@
#include <qpa/qplatformtheme.h>
#include <qpa/qplatformintegration.h>
#include <QtCore/QLoggingCategory>
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaTheme)
class QWinRTThemePrivate;
class QWinRTTheme : public QPlatformTheme
{

View File

@ -69,6 +69,8 @@ using namespace ABI::Windows::UI::Xaml::Controls;
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows");
static void setUIElementVisibility(IUIElement *uiElement, bool visibility)
{
Q_ASSERT(uiElement);
@ -101,6 +103,7 @@ QWinRTWindow::QWinRTWindow(QWindow *window)
, d_ptr(new QWinRTWindowPrivate)
{
Q_D(QWinRTWindow);
qCDebug(lcQpaWindows) << __FUNCTION__ << this;
d->surface = EGL_NO_SURFACE;
d->display = EGL_NO_DISPLAY;
@ -133,6 +136,15 @@ QWinRTWindow::QWinRTWindow(QWindow *window)
hr = d->swapChainPanel.As(&d->uiElement);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<Xaml::IFrameworkElement> frameworkElement;
hr = d->swapChainPanel.As(&frameworkElement);
Q_ASSERT_SUCCEEDED(hr);
const QSizeF size = QSizeF(d->screen->geometry().size()) / d->screen->scaleFactor();
hr = frameworkElement->put_Width(size.width());
Q_ASSERT_SUCCEEDED(hr);
hr = frameworkElement->put_Height(size.height());
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IDependencyObject> canvas = d->screen->canvas();
ComPtr<IPanel> panel;
hr = canvas.As(&panel);
@ -152,6 +164,7 @@ QWinRTWindow::QWinRTWindow(QWindow *window)
QWinRTWindow::~QWinRTWindow()
{
Q_D(QWinRTWindow);
qCDebug(lcQpaWindows) << __FUNCTION__ << this;
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
@ -178,6 +191,8 @@ QWinRTWindow::~QWinRTWindow()
if (!d->surface)
return;
qCDebug(lcQpaWindows) << __FUNCTION__ << ": Destroying surface";
EGLBoolean value = eglDestroySurface(d->display, d->surface);
d->surface = EGL_NO_SURFACE;
if (Q_UNLIKELY(value == EGL_FALSE))
@ -205,12 +220,15 @@ bool QWinRTWindow::isExposed() const
void QWinRTWindow::setGeometry(const QRect &rect)
{
Q_D(QWinRTWindow);
qCDebug(lcQpaWindows) << __FUNCTION__ << this << rect;
const Qt::WindowFlags windowFlags = window()->flags();
const Qt::WindowFlags windowType = windowFlags & Qt::WindowType_Mask;
if (window()->isTopLevel() && (windowType == Qt::Window || windowType == Qt::Dialog)) {
QPlatformWindow::setGeometry(windowFlags & Qt::MaximizeUsingFullscreenGeometryHint
? d->screen->geometry() : d->screen->availableGeometry());
const QRect screenRect = windowFlags & Qt::MaximizeUsingFullscreenGeometryHint
? d->screen->geometry() : d->screen->availableGeometry();
qCDebug(lcQpaWindows) << __FUNCTION__ << "top-level, overwrite" << screenRect;
QPlatformWindow::setGeometry(screenRect);
QWindowSystemInterface::handleGeometryChange(window(), geometry());
} else {
QPlatformWindow::setGeometry(rect);
@ -234,6 +252,8 @@ void QWinRTWindow::setGeometry(const QRect &rect)
Q_ASSERT_SUCCEEDED(hr);
hr = frameworkElement->put_Height(size.height());
Q_ASSERT_SUCCEEDED(hr);
qCDebug(lcQpaWindows) << __FUNCTION__ << "(setGeometry Xaml)" << this
<< topLeft << size;
return S_OK;
});
Q_ASSERT_SUCCEEDED(hr);
@ -242,6 +262,8 @@ void QWinRTWindow::setGeometry(const QRect &rect)
void QWinRTWindow::setVisible(bool visible)
{
Q_D(QWinRTWindow);
qCDebug(lcQpaWindows) << __FUNCTION__ << this << visible;
if (!window()->isTopLevel())
return;
if (visible) {
@ -263,6 +285,7 @@ void QWinRTWindow::setWindowTitle(const QString &title)
void QWinRTWindow::raise()
{
Q_D(QWinRTWindow);
qCDebug(lcQpaWindows) << __FUNCTION__ << this;
if (!window()->isTopLevel())
return;
d->screen->raise(window());
@ -271,6 +294,7 @@ void QWinRTWindow::raise()
void QWinRTWindow::lower()
{
Q_D(QWinRTWindow);
qCDebug(lcQpaWindows) << __FUNCTION__ << this;
if (!window()->isTopLevel())
return;
d->screen->lower(window());
@ -290,6 +314,8 @@ qreal QWinRTWindow::devicePixelRatio() const
void QWinRTWindow::setWindowState(Qt::WindowState state)
{
Q_D(QWinRTWindow);
qCDebug(lcQpaWindows) << __FUNCTION__ << this << state;
if (d->state == state)
return;

View File

@ -37,12 +37,15 @@
#ifndef QWINRTWINDOW_H
#define QWINRTWINDOW_H
#include <QtCore/QLoggingCategory>
#include <qpa/qplatformwindow.h>
#include <qpa/qwindowsysteminterface.h>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaWindows)
class QWinRTWindowPrivate;
class QWinRTWindow : public QPlatformWindow
{

View File

@ -16,6 +16,7 @@ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include
SOURCES = \
main.cpp \
qwinrtbackingstore.cpp \
qwinrtclipboard.cpp \
qwinrtcursor.cpp \
qwinrteglcontext.cpp \
qwinrteventdispatcher.cpp \
@ -33,6 +34,7 @@ SOURCES = \
HEADERS = \
qwinrtbackingstore.h \
qwinrtclipboard.h \
qwinrtcursor.h \
qwinrteglcontext.h \
qwinrteventdispatcher.h \

View File

@ -185,7 +185,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI
m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha;
if (!m_hasAlpha)
format = qt_alphaVersionForPainting(format);
format = qt_maybeAlphaVersionWithSameDepth(format);
m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
m_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage);

View File

@ -488,31 +488,23 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName);
break;
case WhereStatement:
if (preparedStatement) {
for (int i = 0; i < rec.count(); ++i) {
s.append(prepareIdentifier(rec.fieldName(i), FieldName,this));
if (rec.isNull(i))
s.append(QLatin1String(" IS NULL"));
else
s.append(QLatin1String(" = ?"));
s.append(QLatin1String(" AND "));
}
} else {
for (i = 0; i < rec.count(); ++i) {
s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this));
QString val = formatValue(rec.field(i));
if (val == QLatin1String("NULL"))
s.append(QLatin1String(" IS NULL"));
else
s.append(QLatin1String(" = ")).append(val);
s.append(QLatin1String(" AND "));
}
}
if (!s.isEmpty()) {
s.prepend(QLatin1String("WHERE "));
s.chop(5); // remove tailing AND
{
const QString tableNamePrefix = tableName.isEmpty()
? QString()
: prepareIdentifier(tableName, QSqlDriver::TableName, this) + QLatin1Char('.');
for (int i = 0; i < rec.count(); ++i) {
s.append(QLatin1String(i? " AND " : "WHERE "));
s.append(tableNamePrefix);
s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this));
if (rec.isNull(i))
s.append(QLatin1String(" IS NULL"));
else if (preparedStatement)
s.append(QLatin1String(" = ?"));
else
s.append(QLatin1String(" = ")).append(formatValue(rec.field(i)));
}
break;
}
case UpdateStatement:
s.append(QLatin1String("UPDATE ")).append(tableName).append(
QLatin1String(" SET "));

Some files were not shown because too many files have changed in this diff Show More