Merge remote-tracking branch 'origin/5.3' into dev
Conflicts:
mkspecs/qnx-x86-qcc/qplatformdefs.h
src/corelib/global/qglobal.h
src/network/socket/qnativesocketengine_winrt.cpp
src/plugins/platforms/android/androidjniaccessibility.cpp
src/plugins/platforms/windows/qwindowswindow.cpp
Manually adjusted:
mkspecs/qnx-armle-v7-qcc/qplatformdefs.h
to include 9ce697f2d5
Thanks goes to Sergio for the qnx mkspecs adjustments.
Change-Id: I53b1fd6bc5bc884e5ee2c2b84975f58171a1cb8e
This commit is contained in:
commit
a09a8d509a
101
dist/changes-5.3.1
vendored
Normal file
101
dist/changes-5.3.1
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
Qt 5.3.1 is a bug-fix release. It maintains both forward and backward
|
||||
compatibility (source and binary) with Qt 5.3.0.
|
||||
|
||||
For more details, refer to the online documentation included in this
|
||||
distribution. The documentation is also available online:
|
||||
|
||||
http://qt-project.org/doc/qt-5.3
|
||||
|
||||
The Qt version 5.3 series is binary compatible with the 5.2.x series.
|
||||
Applications compiled for 5.2 will continue to run with 5.3.
|
||||
|
||||
Some of the changes listed in this file include issue tracking numbers
|
||||
corresponding to tasks in the Qt Bug Tracker:
|
||||
|
||||
http://bugreports.qt-project.org/
|
||||
|
||||
Each of these identifiers can be entered in the bug tracker to obtain more
|
||||
information about a particular change.
|
||||
|
||||
****************************************************************************
|
||||
* Library *
|
||||
****************************************************************************
|
||||
|
||||
QtCore
|
||||
------
|
||||
|
||||
- QAbstractProxyModel:
|
||||
* Fixed QAbstractProxyModel::sibling to work in the same manner as the
|
||||
Qt4 code used to behave. Previously, Qt5's implementation would treat
|
||||
the row and column as positions in the source model instead of a
|
||||
position in the proxy itself.
|
||||
|
||||
QtGui
|
||||
-----
|
||||
|
||||
- Text:
|
||||
* [QTBUG-36083] Respect QFont::fixedPitch() for fallbacks when font
|
||||
family cannot be matched.
|
||||
* [QTBUG-37190] Fixed crash when trying to load a font from invalid
|
||||
data.
|
||||
|
||||
QtSql
|
||||
-----
|
||||
|
||||
- QDB2 and QODBC
|
||||
* [QTBUG-39137] Fix error handling problem caused by unintialized variable
|
||||
passed to SQLNumResultCols.
|
||||
|
||||
- QPSQL
|
||||
* [QTBUG-12477] Fix PSQL column metadata.
|
||||
|
||||
- QSqlQuery
|
||||
* Fix misbehavior of seek in special query positions BeforeFirstRow and
|
||||
AfterLastRow. (commit 3e6e70bddd84536deaae69421d05785ae6ce28cd)
|
||||
* [QTBUG-33169] Fix for bindvalue(int) memory allocation problem.
|
||||
|
||||
QtWidgets
|
||||
---------
|
||||
|
||||
- QMenu:
|
||||
* [QTBUG-38498] Accessibility: Menus are now read by screen readers
|
||||
with more reliability.
|
||||
|
||||
****************************************************************************
|
||||
* Platform Specific Changes *
|
||||
****************************************************************************
|
||||
|
||||
Android
|
||||
-------
|
||||
|
||||
- [QTBUG-38960] Fixed regression where there would be flickering on
|
||||
startup and shutdown of the application.
|
||||
- [QTBUG-35975] Fixed repaint issues in drag and drop.
|
||||
|
||||
- Text:
|
||||
* [QTBUG-37844] Fall back to Droid Sans Mono for QFont::Courier style
|
||||
hint.
|
||||
|
||||
****************************************************************************
|
||||
* Tools *
|
||||
****************************************************************************
|
||||
|
||||
configure & build system
|
||||
------------------------
|
||||
|
||||
- [QTBUG-38445] Fixed build against static ICU on Unix
|
||||
- [QTBUG-38544] Fixed LLVM build with SIMD features
|
||||
- [QTBUG-39253] PDB files are now installed also for static libraries
|
||||
- Added support for -separate-debug-info on Windows
|
||||
- Added [-no]-pulseaudio and [-no]-alsa options on Unix
|
||||
- Several fixes to installed .pc and .prl files
|
||||
- Fixed MinGW build under MSYS
|
||||
- Fixed installation of unneeded static libraries in dynamic builds
|
||||
|
||||
qmake
|
||||
-----
|
||||
|
||||
- [QTBUG-37054] Fixed use of relative paths in QMAKE_BUNDLE_DATA with Xcode
|
||||
- [QTBUG-38260] Custom Info.plist supplied via QMAKE_INFO_PLIST is now used
|
||||
as-is, without placeholder replacement
|
||||
- QMAKE_TARGET_BUNDLE_PREFIX does not need a trailing dot any more
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
@ -28,31 +28,35 @@
|
||||
/*!
|
||||
\example layouts/basiclayouts
|
||||
\title Basic Layouts Example
|
||||
\brief Shows how to use the standard layout managers.
|
||||
|
||||
\brief The Basic Layouts example shows how to use the standard layout
|
||||
managers that are available in Qt: QBoxLayout, QGridLayout and
|
||||
QFormLayout.
|
||||
\e{Basic Layouts} shows how to use the standard layout managers that are
|
||||
available in Qt: QBoxLayout, QGridLayout, and QFormLayout.
|
||||
|
||||
\image basiclayouts-example.png Screenshot of the Basic Layouts example
|
||||
|
||||
The QBoxLayout class lines up widgets horizontally or vertically.
|
||||
QHBoxLayout and QVBoxLayout are convenience subclasses of QBoxLayout.
|
||||
QGridLayout lays out widgets in cells by dividing the available space
|
||||
into rows and columns. QFormLayout, on the other hand, lays out its
|
||||
into rows and columns. QFormLayout, on the other hand, sets its
|
||||
children in a two-column form with labels in the left column and
|
||||
input fields in the right column.
|
||||
|
||||
For more information, visit the \l{Layout Management} page.
|
||||
|
||||
\include examples-run.qdocinc
|
||||
|
||||
\section1 Dialog Class Definition
|
||||
|
||||
\snippet layouts/basiclayouts/dialog.h 0
|
||||
|
||||
The \c Dialog class inherits QDialog. It is a custom widget that
|
||||
displays its child widgets using the geometry managers:
|
||||
QHBoxLayout, QVBoxLayout, QGridLayout and QFormLayout.
|
||||
QHBoxLayout, QVBoxLayout, QGridLayout, and QFormLayout.
|
||||
|
||||
We declare four private functions to simplify the class
|
||||
constructor: The \c createMenu(), \c createHorizontalGroupBox(),
|
||||
\c createGridGroupBox() and \c createFormGroupBox() functions create
|
||||
There are four private functions to simplify the class
|
||||
constructor: the \c createMenu(), \c createHorizontalGroupBox(),
|
||||
\c createGridGroupBox(), and \c createFormGroupBox() functions create
|
||||
several widgets that the example uses to demonstrate how the layout
|
||||
affects their appearances.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
@ -28,9 +28,14 @@
|
||||
/*!
|
||||
\example layouts/borderlayout
|
||||
\title Border Layout Example
|
||||
\brief Shows how to arrange child widgets along a border.
|
||||
|
||||
\brief The Border Layout example shows how to create a custom layout that arranges
|
||||
child widgets according to a simple set of rules.
|
||||
\e{Border Layout} implements a layout that arranges child widgets to
|
||||
surround the main area.
|
||||
|
||||
\image borderlayout-example.png
|
||||
|
||||
For more information, visit the \l{Layout Management} page.
|
||||
|
||||
\include examples-run.qdocinc
|
||||
*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
@ -28,7 +28,13 @@
|
||||
/*!
|
||||
\example layouts/dynamiclayouts
|
||||
\title Dynamic Layouts Example
|
||||
\brief Shows how to re-orient widgets in running applications.
|
||||
|
||||
\brief The Dynamic Layouts example shows how to move widgets around in
|
||||
existing layouts.
|
||||
\e{Dynamic Layouts} implements dynamically placed widgets within running
|
||||
applications. The widget placement depends on whether \c Horizontal or \c
|
||||
Vertical is chosen.
|
||||
|
||||
For more information, visit the \l{Layout Management} page.
|
||||
|
||||
\include examples-run.qdocinc
|
||||
*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
@ -28,18 +28,19 @@
|
||||
/*!
|
||||
\example layouts/flowlayout
|
||||
\title Flow Layout Example
|
||||
\brief Shows how to arrange widgets for different window sizes.
|
||||
|
||||
\brief The Flow Layout example demonstrates a custom layout that arranges child
|
||||
widgets from left to right and top to bottom in a top-level widget.
|
||||
\e{Flow Layout} implements a layout that handles different window sizes. The
|
||||
widget placement changes depending on the width of the application window.
|
||||
|
||||
\image flowlayout-example.png Screenshot of the Flow Layout example
|
||||
|
||||
The items are first laid out horizontally and then vertically when each line
|
||||
in the layout runs out of space.
|
||||
|
||||
The Flowlayout class mainly uses QLayout and QWidgetItem, while the
|
||||
Window uses QWidget and QLabel. We will only document the definition
|
||||
and implementation of \c FlowLayout below.
|
||||
Window uses QWidget and QLabel.
|
||||
|
||||
For more information, visit the \l{Layout Management} page.
|
||||
|
||||
\include examples-run.qdocinc
|
||||
|
||||
\section1 FlowLayout Class Definition
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
@ -112,15 +112,19 @@
|
||||
{ImageViewer}'s appearance.
|
||||
|
||||
\snippet widgets/imageviewer/imageviewer.cpp 1
|
||||
|
||||
In the \c open() slot, we show a file dialog to the user. We compile
|
||||
a list of mime types for use as a filter by querying QImageReader
|
||||
for the available mime type names.
|
||||
|
||||
We show the file dialog until a valid file name is entered or
|
||||
the user cancels.
|
||||
|
||||
The function \c loadFile() is used to load the image.
|
||||
|
||||
\snippet widgets/imageviewer/imageviewer.cpp 2
|
||||
|
||||
In the \c open() slot, we show a file dialog to the user. The
|
||||
easiest way to create a QFileDialog is to use the static
|
||||
convenience functions. QFileDialog::getOpenFileName() returns an
|
||||
existing file selected by the user. If the user presses \uicontrol
|
||||
Cancel, QFileDialog returns an empty string.
|
||||
|
||||
Unless the file name is a empty string, we check if the file's
|
||||
In the \c loadFile() function, we check if the file's
|
||||
format is an image format by constructing a QImage which tries to
|
||||
load the image from the file. If the constructor returns a null
|
||||
image, we use a QMessageBox to alert the user.
|
||||
@ -135,7 +139,6 @@
|
||||
information message with an \uicontrol OK button (the default) is
|
||||
sufficient, since the message is part of a normal operation.
|
||||
|
||||
\snippet widgets/imageviewer/imageviewer.cpp 3
|
||||
\snippet widgets/imageviewer/imageviewer.cpp 4
|
||||
|
||||
If the format is supported, we display the image in \c imageLabel
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
@ -61,38 +61,60 @@ ImageViewer::ImageViewer()
|
||||
createActions();
|
||||
createMenus();
|
||||
|
||||
setWindowTitle(tr("Image Viewer"));
|
||||
resize(500, 400);
|
||||
resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);
|
||||
}
|
||||
|
||||
//! [0]
|
||||
//! [2]
|
||||
|
||||
bool ImageViewer::loadFile(const QString &fileName)
|
||||
{
|
||||
QImage image(fileName);
|
||||
if (image.isNull()) {
|
||||
QMessageBox::information(this, QGuiApplication::applicationDisplayName(),
|
||||
tr("Cannot load %1.").arg(QDir::toNativeSeparators(fileName)));
|
||||
setWindowFilePath(QString());
|
||||
imageLabel->setPixmap(QPixmap());
|
||||
imageLabel->adjustSize();
|
||||
return false;
|
||||
}
|
||||
//! [2] //! [3]
|
||||
imageLabel->setPixmap(QPixmap::fromImage(image));
|
||||
//! [3] //! [4]
|
||||
scaleFactor = 1.0;
|
||||
|
||||
printAct->setEnabled(true);
|
||||
fitToWindowAct->setEnabled(true);
|
||||
updateActions();
|
||||
|
||||
if (!fitToWindowAct->isChecked())
|
||||
imageLabel->adjustSize();
|
||||
|
||||
setWindowFilePath(fileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
//! [4]
|
||||
|
||||
//! [2]
|
||||
|
||||
//! [1]
|
||||
void ImageViewer::open()
|
||||
//! [1] //! [2]
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this,
|
||||
tr("Open File"), QDir::currentPath());
|
||||
if (!fileName.isEmpty()) {
|
||||
QImage image(fileName);
|
||||
if (image.isNull()) {
|
||||
QMessageBox::information(this, tr("Image Viewer"),
|
||||
tr("Cannot load %1.").arg(fileName));
|
||||
return;
|
||||
}
|
||||
//! [2] //! [3]
|
||||
imageLabel->setPixmap(QPixmap::fromImage(image));
|
||||
//! [3] //! [4]
|
||||
scaleFactor = 1.0;
|
||||
QStringList mimeTypeFilters;
|
||||
foreach (const QByteArray &mimeTypeName, QImageReader::supportedMimeTypes())
|
||||
mimeTypeFilters.append(mimeTypeName);
|
||||
mimeTypeFilters.sort();
|
||||
const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
|
||||
QFileDialog dialog(this, tr("Open File"),
|
||||
picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.first());
|
||||
dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||
dialog.setMimeTypeFilters(mimeTypeFilters);
|
||||
dialog.selectMimeTypeFilter("image/jpeg");
|
||||
|
||||
printAct->setEnabled(true);
|
||||
fitToWindowAct->setEnabled(true);
|
||||
updateActions();
|
||||
|
||||
if (!fitToWindowAct->isChecked())
|
||||
imageLabel->adjustSize();
|
||||
}
|
||||
while (dialog.exec() == QDialog::Accepted && !loadFile(dialog.selectedFiles().first())) {}
|
||||
}
|
||||
//! [4]
|
||||
//! [1]
|
||||
|
||||
//! [5]
|
||||
void ImageViewer::print()
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
@ -61,6 +61,7 @@ class ImageViewer : public QMainWindow
|
||||
|
||||
public:
|
||||
ImageViewer();
|
||||
bool loadFile(const QString &);
|
||||
|
||||
private slots:
|
||||
void open();
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
@ -39,13 +39,23 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
|
||||
#include "imageviewer.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QGuiApplication::setApplicationDisplayName(ImageViewer::tr("Image Viewer"));
|
||||
QCommandLineParser commandLineParser;
|
||||
commandLineParser.addHelpOption();
|
||||
commandLineParser.addPositionalArgument(ImageViewer::tr("[file]"), ImageViewer::tr("Image file to open."));
|
||||
commandLineParser.process(QCoreApplication::arguments());
|
||||
ImageViewer imageViewer;
|
||||
if (!commandLineParser.positionalArguments().isEmpty()
|
||||
&& !imageViewer.loadFile(commandLineParser.positionalArguments().front())) {
|
||||
return -1;
|
||||
}
|
||||
imageViewer.show();
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -166,8 +166,6 @@ contains(CONFIG, plugin) {
|
||||
return()
|
||||
}
|
||||
|
||||
contains($$list(network sql widgets gui), $$MODULE): CMAKE_LOAD_PLUGINS = true
|
||||
|
||||
unix:contains(QT_CONFIG, reduce_relocations):CMAKE_ADD_FPIE_FLAGS = "true"
|
||||
|
||||
CMAKE_MKSPEC = $$[QMAKE_XSPEC]
|
||||
@ -293,3 +291,14 @@ exists($$cmake_macros_file.input) {
|
||||
}
|
||||
|
||||
cmake_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5$${CMAKE_MODULE_NAME}
|
||||
|
||||
# We are generating cmake files. Most developers of Qt are not aware of cmake,
|
||||
# so we require automatic tests to be available. The only module which should
|
||||
# set CMAKE_MODULE_TESTS to '-' is enginio because that is known to be broken.
|
||||
# Other modules should either create proper tests in tests/auto/cmake or, as
|
||||
# a temporary measure, disable the generation of cmake files
|
||||
# with 'CONFIG -= create_cmake'
|
||||
!equals(CMAKE_MODULE_TESTS, -) {
|
||||
isEmpty(CMAKE_MODULE_TESTS): CMAKE_MODULE_TESTS = $$MODULE_BASE_INDIR/tests/auto/cmake
|
||||
!exists($$CMAKE_MODULE_TESTS): error("Missing CMake tests.")
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
|
||||
|
||||
!!ENDIF // CMAKE_DEBUG_TYPE
|
||||
|
||||
!!IF !isEmpty(CMAKE_LOAD_PLUGINS)
|
||||
file(GLOB pluginTargets \"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}_*Plugin.cmake\")
|
||||
|
||||
macro(_populate_$${CMAKE_MODULE_NAME}_plugin_properties Plugin Configuration PLUGIN_LOCATION)
|
||||
set_property(TARGET Qt5::${Plugin} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration})
|
||||
@ -299,11 +299,12 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
|
||||
)
|
||||
endmacro()
|
||||
|
||||
file(GLOB pluginTargets \"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}_*Plugin.cmake\")
|
||||
foreach(pluginTarget ${pluginTargets})
|
||||
include(${pluginTarget})
|
||||
endforeach()
|
||||
!!ENDIF
|
||||
if (pluginTargets)
|
||||
foreach(pluginTarget ${pluginTargets})
|
||||
include(${pluginTarget})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
!!IF !isEmpty(CMAKE_MODULE_EXTRAS)
|
||||
include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}ConfigExtras.cmake\")
|
||||
|
@ -128,7 +128,7 @@ contains(qt_module_deps, qml): \
|
||||
QML_IMPORT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_qml_plugin_import.cpp
|
||||
write_file($$QML_IMPORT_CPP, IMPORT_FILE_CONT)|error("Aborting.")
|
||||
SOURCES += $$QML_IMPORT_CPP
|
||||
QMAKE_CLEAN += $$QML_IMPORT_CPP
|
||||
QMAKE_DISTCLEAN += $$QML_IMPORT_CPP
|
||||
|
||||
# copy qml files. this part is platform spesific.
|
||||
mac {
|
||||
|
@ -22,7 +22,7 @@
|
||||
target.path = $$[QT_HOST_LIBS]
|
||||
else: \
|
||||
target.path = $$[QT_INSTALL_LIBS]
|
||||
target.CONFIG = no_dll
|
||||
!static: target.CONFIG = no_dll
|
||||
INSTALLS += target
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ qt_install_headers {
|
||||
!isEmpty(header_files_client) {
|
||||
wayland_generated_client_headers.files = $$header_files_client
|
||||
wayland_generated_client_headers.path = $$private_headers.path
|
||||
wayland_generated_client_headers.CONFIG = no_check_exist
|
||||
INSTALLS += wayland_generated_client_headers
|
||||
WAYLAND_CLIENT_HEADER_DEST = $$header_dest/
|
||||
WAYLAND_CLIENT_INCLUDE_DIR = $$MODULE_INCNAME/private
|
||||
@ -41,6 +42,7 @@ qt_install_headers {
|
||||
!isEmpty(header_files_server) {
|
||||
wayland_generated_server_headers.files = $$header_files_server
|
||||
wayland_generated_server_headers.path = $$private_headers.path
|
||||
wayland_generated_server_headers.CONFIG = no_check_exist
|
||||
INSTALLS += wayland_generated_server_headers
|
||||
WAYLAND_SERVER_HEADER_DEST = $$header_dest/
|
||||
WAYLAND_SERVER_INCLUDE_DIR = $$MODULE_INCNAME/private
|
||||
|
@ -3,7 +3,7 @@
|
||||
** Copyright (C) 2012 - 2014 BlackBerry Limited. All rights reserved.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
** This file is part of the qmake spec of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
@ -42,68 +42,6 @@
|
||||
#ifndef QPLATFORMDEFS_H
|
||||
#define QPLATFORMDEFS_H
|
||||
|
||||
// Get Qt defines/settings
|
||||
|
||||
#include "qglobal.h"
|
||||
|
||||
// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
|
||||
// We are hot - unistd.h should have turned on the specific APIs we requested
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/time.h>
|
||||
// QNX doesn't have the System V <sys/shm.h> header. This is not a standard
|
||||
// POSIX header, it's only documented in the Single UNIX Specification.
|
||||
// The preferred POSIX compliant way to share memory is to use the functions
|
||||
// in <sys/mman.h> that comply with the POSIX Real Time Interface (1003.1b).
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <netinet/in.h>
|
||||
#ifndef QT_NO_IPV6IFNAME
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
// for htonl
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define QT_USE_XOPEN_LFS_EXTENSIONS
|
||||
#if defined(__EXT_QNX__READDIR_R) && !defined(__EXT_QNX__READDIR64_R)
|
||||
#define QT_NO_READDIR64
|
||||
#endif
|
||||
#include "../common/posix/qplatformdefs.h"
|
||||
#if defined(__EXT_QNX__READDIR64_R)
|
||||
#define QT_EXT_QNX_READDIR_R ::_readdir64_r
|
||||
#elif defined(__EXT_QNX__READDIR_R)
|
||||
#define QT_EXT_QNX_READDIR_R ::_readdir_r
|
||||
#endif
|
||||
|
||||
#define QT_SNPRINTF ::snprintf
|
||||
#define QT_VSNPRINTF ::vsnprintf
|
||||
|
||||
// QNX6 doesn't have getpagesize()
|
||||
inline int getpagesize()
|
||||
{
|
||||
return ::sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define QT_QWS_TEMP_DIR QString::fromLatin1(qgetenv("TMP"))
|
||||
#include "../common/qnx/qplatformdefs.h"
|
||||
|
||||
#endif // QPLATFORMDEFS_H
|
||||
|
@ -208,17 +208,17 @@ QMakeEvaluator::~QMakeEvaluator()
|
||||
{
|
||||
}
|
||||
|
||||
void QMakeEvaluator::initFrom(const QMakeEvaluator &other)
|
||||
void QMakeEvaluator::initFrom(const QMakeEvaluator *other)
|
||||
{
|
||||
Q_ASSERT_X(&other, "QMakeEvaluator::visitProFile", "Project not prepared");
|
||||
m_functionDefs = other.m_functionDefs;
|
||||
m_valuemapStack = other.m_valuemapStack;
|
||||
Q_ASSERT_X(other, "QMakeEvaluator::visitProFile", "Project not prepared");
|
||||
m_functionDefs = other->m_functionDefs;
|
||||
m_valuemapStack = other->m_valuemapStack;
|
||||
m_valuemapInited = true;
|
||||
m_qmakespec = other.m_qmakespec;
|
||||
m_qmakespecName = other.m_qmakespecName;
|
||||
m_mkspecPaths = other.m_mkspecPaths;
|
||||
m_featureRoots = other.m_featureRoots;
|
||||
m_dirSep = other.m_dirSep;
|
||||
m_qmakespec = other->m_qmakespec;
|
||||
m_qmakespecName = other->m_qmakespecName;
|
||||
m_mkspecPaths = other->m_mkspecPaths;
|
||||
m_featureRoots = other->m_featureRoots;
|
||||
m_dirSep = other->m_dirSep;
|
||||
}
|
||||
|
||||
//////// Evaluator tools /////////
|
||||
@ -1355,7 +1355,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
|
||||
return ReturnFalse;
|
||||
#endif
|
||||
|
||||
initFrom(*baseEnv->evaluator);
|
||||
initFrom(baseEnv->evaluator);
|
||||
} else {
|
||||
if (!m_valuemapInited)
|
||||
loadDefaults();
|
||||
|
@ -167,7 +167,7 @@ public:
|
||||
bool prepareProject(const QString &inDir);
|
||||
bool loadSpecInternal();
|
||||
bool loadSpec();
|
||||
void initFrom(const QMakeEvaluator &other);
|
||||
void initFrom(const QMakeEvaluator *other);
|
||||
void setupProject();
|
||||
void evaluateCommand(const QString &cmds, const QString &where);
|
||||
void applyExtraConfigs();
|
||||
|
@ -252,8 +252,10 @@ int runQMake(int argc, char **argv)
|
||||
#endif
|
||||
if(!dir.isNull() && dir != ".")
|
||||
Option::output_dir = dir;
|
||||
if(QDir::isRelativePath(Option::output_dir))
|
||||
if (QDir::isRelativePath(Option::output_dir)) {
|
||||
Option::output.setFileName(fi.fileName());
|
||||
Option::output_dir.prepend(oldpwd + QLatin1Char('/'));
|
||||
}
|
||||
Option::output_dir = QDir::cleanPath(Option::output_dir);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ QMakeProject::QMakeProject()
|
||||
QMakeProject::QMakeProject(QMakeProject *p)
|
||||
: QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler)
|
||||
{
|
||||
initFrom(*p);
|
||||
initFrom(p);
|
||||
}
|
||||
|
||||
bool QMakeProject::boolRet(VisitReturn vr)
|
||||
|
3
src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
vendored
3
src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
vendored
@ -738,7 +738,8 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
||||
if (num_glyphs == 0)
|
||||
continue;
|
||||
|
||||
buffer->ensure (buffer->len + num_glyphs + (endWithPDF ? 1 : 0));
|
||||
const long ensureCount = DIV_CEIL(sizeof(CGGlyph) + sizeof(CGPoint) + sizeof(CFIndex), sizeof(*scratch));
|
||||
buffer->ensure (buffer->len + ensureCount * (num_glyphs + (endWithPDF ? 1 : 0)));
|
||||
|
||||
scratch = buffer->get_scratch_buffer (&scratch_size);
|
||||
|
||||
|
@ -53,6 +53,7 @@ import android.text.TextUtils;
|
||||
|
||||
import android.view.accessibility.*;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View.OnHoverListener;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@ -85,9 +86,19 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
|
||||
// the offset of the view on screen into account (eg status bar on top)
|
||||
private final int[] m_globalOffset = new int[2];
|
||||
|
||||
private class HoverEventListener implements View.OnHoverListener
|
||||
{
|
||||
@Override
|
||||
public boolean onHover(View v, MotionEvent event)
|
||||
{
|
||||
return dispatchHoverEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
public QtAccessibilityDelegate(View host)
|
||||
{
|
||||
m_view = host;
|
||||
m_view.setOnHoverListener(new HoverEventListener());
|
||||
m_manager = (AccessibilityManager) host.getContext()
|
||||
.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
|
||||
@ -103,7 +114,7 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
|
||||
|
||||
// For "explore by touch" we need all movement events here first
|
||||
// (user moves finger over screen to discover items on screen).
|
||||
public boolean dispatchHoverEvent(MotionEvent event)
|
||||
private boolean dispatchHoverEvent(MotionEvent event)
|
||||
{
|
||||
if (!m_manager.isTouchExplorationEnabled()) {
|
||||
return false;
|
||||
|
@ -110,24 +110,6 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
|
||||
}
|
||||
}
|
||||
|
||||
public boolean dispatchHoverEvent(MotionEvent event) {
|
||||
// Always attempt to dispatch hover events to accessibility first.
|
||||
if (m_accessibilityDelegate != null) {
|
||||
try {
|
||||
Method dispHoverA11y = m_accessibilityDelegate.getClass().getMethod("dispatchHoverEvent", MotionEvent.class);
|
||||
boolean ret = (Boolean) dispHoverA11y.invoke(m_accessibilityDelegate, event);
|
||||
if (ret)
|
||||
return true;
|
||||
SurfaceView view = (SurfaceView) this;
|
||||
Method dispHoverView = view.getClass().getMethod("dispatchHoverEvent", MotionEvent.class);
|
||||
return (Boolean) dispHoverView.invoke(view, event);
|
||||
} catch (Exception e) {
|
||||
Log.w("Qt A11y", "EXCEPTION in dispatchHoverEvent for Accessibility: " + e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
|
||||
{
|
||||
|
@ -67,8 +67,10 @@ template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> >
|
||||
return --_q_value != 0;
|
||||
}
|
||||
|
||||
static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
|
||||
static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW
|
||||
{
|
||||
if (currentValue)
|
||||
*currentValue = _q_value;
|
||||
if (_q_value == expectedValue) {
|
||||
_q_value = newValue;
|
||||
return true;
|
||||
@ -83,8 +85,8 @@ template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> >
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static
|
||||
T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
|
||||
template <typename AdditiveType> static
|
||||
T fetchAndAddRelaxed(T &_q_value, AdditiveType valueToAdd) Q_DECL_NOTHROW
|
||||
{
|
||||
T returnValue = _q_value;
|
||||
_q_value += valueToAdd;
|
||||
|
@ -42,7 +42,7 @@
|
||||
class MyStylePlugin : public QStylePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE mystyleplugin.json)
|
||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "mystyleplugin.json")
|
||||
public:
|
||||
QStyle *create(const QString &key);
|
||||
};
|
||||
|
@ -59,7 +59,11 @@
|
||||
#include <QtCore/qconfig.h>
|
||||
#include <QtCore/qfeatures.h>
|
||||
#endif
|
||||
#define QT_SUPPORTS(FEATURE) (!defined(QT_NO_##FEATURE))
|
||||
#if defined(Q_CC_MSVC) && _MSC_VER <= 1500 /* VS2008 */
|
||||
# define QT_SUPPORTS(FEATURE) (!defined QT_NO_##FEATURE)
|
||||
#else
|
||||
# define QT_SUPPORTS(FEATURE) (!defined(QT_NO_##FEATURE))
|
||||
#endif
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
# define QT_NO_UNSHARABLE_CONTAINERS
|
||||
#endif
|
||||
|
@ -566,7 +566,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
|
||||
|
||||
QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
|
||||
{
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
#if !defined(QT_BOOTSTRAPPED) && !defined(QT_NO_SETTINGS)
|
||||
if (const QSettings *settings = QLibraryInfoPrivate::findConfiguration()) {
|
||||
QString key = QLatin1String(platformsSection);
|
||||
key += QLatin1Char('/');
|
||||
@ -574,7 +574,7 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
|
||||
key += QLatin1String("Arguments");
|
||||
return settings->value(key).toStringList();
|
||||
}
|
||||
#endif // !QT_BOOTSTRAPPED
|
||||
#endif // !QT_BOOTSTRAPPED && !QT_NO_SETTINGS
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
|
@ -1395,8 +1395,7 @@ void qErrnoWarning(int code, const char *msg, ...)
|
||||
\since 5.0
|
||||
|
||||
Installs a Qt message \a handler which has been defined
|
||||
previously. Returns a pointer to the previous message handler
|
||||
(which may be 0).
|
||||
previously. Returns a pointer to the previous message handler.
|
||||
|
||||
The message handler is a function that prints out debug messages,
|
||||
warnings, critical and fatal error messages. The Qt library (debug
|
||||
|
@ -530,7 +530,8 @@ void QFileInfo::setFile(const QDir &dir, const QString &file)
|
||||
is true. In contrast to canonicalFilePath(), symbolic links or
|
||||
redundant "." or ".." elements are not necessarily removed.
|
||||
|
||||
If the QFileInfo is empty it returns QDir::currentPath().
|
||||
\warning If filePath() is empty the behavior of this function
|
||||
is undefined.
|
||||
|
||||
\sa filePath(), canonicalFilePath(), isRelative()
|
||||
*/
|
||||
@ -572,8 +573,8 @@ QString QFileInfo::canonicalFilePath() const
|
||||
In contrast to canonicalPath() symbolic links or redundant "." or
|
||||
".." elements are not necessarily removed.
|
||||
|
||||
\warning If the QFileInfo object was created with an empty QString,
|
||||
the behavior of this function is undefined.
|
||||
\warning If filePath() is empty the behavior of this function
|
||||
is undefined.
|
||||
|
||||
\sa absoluteFilePath(), path(), canonicalPath(), fileName(), isRelative()
|
||||
*/
|
||||
|
@ -64,6 +64,25 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace {
|
||||
class RaiiAutoreleasePool
|
||||
{
|
||||
Q_DISABLE_COPY(RaiiAutoreleasePool)
|
||||
|
||||
public:
|
||||
RaiiAutoreleasePool()
|
||||
: pool([[NSAutoreleasePool alloc] init])
|
||||
{}
|
||||
|
||||
~RaiiAutoreleasePool()
|
||||
{ [pool release]; }
|
||||
|
||||
private:
|
||||
NSAutoreleasePool *pool;
|
||||
};
|
||||
#define Q_AUTORELEASE_POOL(pool) RaiiAutoreleasePool pool; Q_UNUSED(pool);
|
||||
}
|
||||
|
||||
static void callBackFunction(ConstFSEventStreamRef streamRef,
|
||||
void *clientCallBackInfo,
|
||||
size_t numEvents,
|
||||
@ -71,6 +90,8 @@ static void callBackFunction(ConstFSEventStreamRef streamRef,
|
||||
const FSEventStreamEventFlags eventFlags[],
|
||||
const FSEventStreamEventId eventIds[])
|
||||
{
|
||||
Q_AUTORELEASE_POOL(pool)
|
||||
|
||||
char **paths = static_cast<char **>(eventPaths);
|
||||
QFseventsFileSystemWatcherEngine *engine = static_cast<QFseventsFileSystemWatcherEngine *>(clientCallBackInfo);
|
||||
engine->processEvent(streamRef, numEvents, paths, eventFlags, eventIds);
|
||||
@ -283,6 +304,7 @@ void QFseventsFileSystemWatcherEngine::doEmitDirectoryChanged(const QString path
|
||||
|
||||
void QFseventsFileSystemWatcherEngine::restartStream()
|
||||
{
|
||||
Q_AUTORELEASE_POOL(pool)
|
||||
QMutexLocker locker(&lock);
|
||||
stopStream();
|
||||
startStream();
|
||||
@ -313,6 +335,8 @@ QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *pare
|
||||
|
||||
QFseventsFileSystemWatcherEngine::~QFseventsFileSystemWatcherEngine()
|
||||
{
|
||||
Q_AUTORELEASE_POOL(pool)
|
||||
|
||||
if (stream)
|
||||
FSEventStreamStop(stream);
|
||||
|
||||
@ -327,6 +351,8 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
||||
QStringList *files,
|
||||
QStringList *directories)
|
||||
{
|
||||
Q_AUTORELEASE_POOL(pool)
|
||||
|
||||
if (stream) {
|
||||
DEBUG("Flushing, last id is %llu", FSEventStreamGetLatestEventId(stream));
|
||||
FSEventStreamFlushSync(stream);
|
||||
@ -413,6 +439,8 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
|
||||
QStringList *files,
|
||||
QStringList *directories)
|
||||
{
|
||||
Q_AUTORELEASE_POOL(pool)
|
||||
|
||||
QMutexLocker locker(&lock);
|
||||
|
||||
bool needsRestart = false;
|
||||
|
@ -50,6 +50,18 @@ const char qtDefaultCategoryName[] = "default";
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
|
||||
(qtDefaultCategoryName))
|
||||
|
||||
#ifndef Q_ATOMIC_INT8_IS_SUPPORTED
|
||||
static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
|
||||
{
|
||||
const int bit = 1 << shift;
|
||||
|
||||
if (enable)
|
||||
atomic->fetchAndOrRelaxed(bit);
|
||||
else
|
||||
atomic->fetchAndAndRelaxed(~bit);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\class QLoggingCategory
|
||||
\inmodule QtCore
|
||||
@ -129,13 +141,13 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
|
||||
|
||||
Order of evaluation:
|
||||
\list
|
||||
\li Rules from QtProject/qlogging.ini
|
||||
\li Rules from QtProject/qtlogging.ini
|
||||
\li Rules set by \l setFilterRules()
|
||||
\li Rules from file in \c QT_LOGGING_CONF
|
||||
\li Rules from environment variable QT_LOGGING_RULES
|
||||
\endlist
|
||||
|
||||
The \c QtProject/qlogging.ini file is looked up in all directories returned
|
||||
The \c QtProject/qtlogging.ini file is looked up in all directories returned
|
||||
by QStandardPaths::GenericConfigLocation, e.g.
|
||||
|
||||
\list
|
||||
@ -171,13 +183,11 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
|
||||
*/
|
||||
QLoggingCategory::QLoggingCategory(const char *category)
|
||||
: d(0),
|
||||
name(0),
|
||||
enabledDebug(true),
|
||||
enabledWarning(true),
|
||||
enabledCritical(true)
|
||||
name(0)
|
||||
{
|
||||
Q_UNUSED(d);
|
||||
Q_UNUSED(placeholder);
|
||||
enabled.store(0x01010101); // enabledDebug = enabledWarning = enabledCritical = true;
|
||||
|
||||
const bool isDefaultCategory
|
||||
= (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
|
||||
@ -249,9 +259,9 @@ QLoggingCategory::~QLoggingCategory()
|
||||
bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
|
||||
{
|
||||
switch (msgtype) {
|
||||
case QtDebugMsg: return enabledDebug;
|
||||
case QtWarningMsg: return enabledWarning;
|
||||
case QtCriticalMsg: return enabledCritical;
|
||||
case QtDebugMsg: return isDebugEnabled();
|
||||
case QtWarningMsg: return isWarningEnabled();
|
||||
case QtCriticalMsg: return isCriticalEnabled();
|
||||
case QtFatalMsg: return true;
|
||||
}
|
||||
return false;
|
||||
@ -270,9 +280,15 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
|
||||
void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
|
||||
{
|
||||
switch (type) {
|
||||
case QtDebugMsg: enabledDebug = enable; break;
|
||||
case QtWarningMsg: enabledWarning = enable; break;
|
||||
case QtCriticalMsg: enabledCritical = enable; break;
|
||||
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
|
||||
case QtDebugMsg: bools.enabledDebug.store(enable); break;
|
||||
case QtWarningMsg: bools.enabledWarning.store(enable); break;
|
||||
case QtCriticalMsg: bools.enabledCritical.store(enable); break;
|
||||
#else
|
||||
case QtDebugMsg: setBoolLane(&enabled, enable, DebugShift); break;
|
||||
case QtWarningMsg: setBoolLane(&enabled, enable, WarningShift); break;
|
||||
case QtCriticalMsg: setBoolLane(&enabled, enable, CriticalShift); break;
|
||||
#endif
|
||||
case QtFatalMsg: break;
|
||||
}
|
||||
}
|
||||
|
@ -57,10 +57,15 @@ public:
|
||||
bool isEnabled(QtMsgType type) const;
|
||||
void setEnabled(QtMsgType type, bool enable);
|
||||
|
||||
bool isDebugEnabled() const { return enabledDebug; }
|
||||
bool isWarningEnabled() const { return enabledWarning; }
|
||||
bool isCriticalEnabled() const { return enabledCritical; }
|
||||
|
||||
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
|
||||
bool isDebugEnabled() const { return bools.enabledDebug.load(); }
|
||||
bool isWarningEnabled() const { return bools.enabledWarning.load(); }
|
||||
bool isCriticalEnabled() const { return bools.enabledCritical.load(); }
|
||||
#else
|
||||
bool isDebugEnabled() const { return enabled.load() >> DebugShift & 1; }
|
||||
bool isWarningEnabled() const { return enabled.load() >> WarningShift & 1; }
|
||||
bool isCriticalEnabled() const { return enabled.load() >> CriticalShift & 1; }
|
||||
#endif
|
||||
const char *categoryName() const { return name; }
|
||||
|
||||
// allows usage of both factory method and variable in qCX macros
|
||||
@ -78,10 +83,24 @@ private:
|
||||
void *d; // reserved for future use
|
||||
const char *name;
|
||||
|
||||
bool enabledDebug;
|
||||
bool enabledWarning;
|
||||
bool enabledCritical;
|
||||
bool placeholder[5]; // reserve for future use
|
||||
#ifdef Q_BIG_ENDIAN
|
||||
enum { DebugShift = 0, WarningShift = 8, CriticalShift = 16 };
|
||||
#else
|
||||
enum { DebugShift = 24, WarningShift = 16, CriticalShift = 8 };
|
||||
#endif
|
||||
|
||||
struct AtomicBools {
|
||||
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
|
||||
QBasicAtomicInteger<bool> enabledDebug;
|
||||
QBasicAtomicInteger<bool> enabledWarning;
|
||||
QBasicAtomicInteger<bool> enabledCritical;
|
||||
#endif
|
||||
};
|
||||
union {
|
||||
AtomicBools bools;
|
||||
QBasicAtomicInt enabled;
|
||||
};
|
||||
bool placeholder[4]; // reserve for future use
|
||||
};
|
||||
|
||||
#define Q_DECLARE_LOGGING_CATEGORY(name) \
|
||||
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Intel Corporation
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -819,9 +820,6 @@ QProcessPrivate::QProcessPrivate()
|
||||
emittedBytesWritten = false;
|
||||
#ifdef Q_OS_WIN
|
||||
notifier = 0;
|
||||
stdoutReader = 0;
|
||||
stderrReader = 0;
|
||||
pipeWriter = 0;
|
||||
processFinishedNotifier = 0;
|
||||
#endif // Q_OS_WIN
|
||||
#ifdef Q_OS_UNIX
|
||||
@ -889,9 +887,9 @@ void QProcessPrivate::cleanup()
|
||||
notifier = 0;
|
||||
}
|
||||
#endif
|
||||
destroyChannel(&stdoutChannel);
|
||||
destroyChannel(&stderrChannel);
|
||||
destroyChannel(&stdinChannel);
|
||||
closeChannel(&stdoutChannel);
|
||||
closeChannel(&stderrChannel);
|
||||
closeChannel(&stdinChannel);
|
||||
destroyPipe(childStartedPipe);
|
||||
destroyPipe(deathPipe);
|
||||
#ifdef Q_OS_UNIX
|
||||
@ -901,49 +899,63 @@ void QProcessPrivate::cleanup()
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Returns true if we emitted readyRead().
|
||||
*/
|
||||
bool QProcessPrivate::_q_canReadStandardOutput()
|
||||
bool QProcessPrivate::tryReadFromChannel(Channel *channel)
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
qint64 available = bytesAvailableFromStdout();
|
||||
if (available == 0) {
|
||||
if (stdoutChannel.notifier)
|
||||
stdoutChannel.notifier->setEnabled(false);
|
||||
destroyChannel(&stdoutChannel);
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::canReadStandardOutput(), 0 bytes available");
|
||||
#endif
|
||||
if (channel->pipe[0] == INVALID_Q_PIPE)
|
||||
return false;
|
||||
|
||||
qint64 available = bytesAvailableInChannel(channel);
|
||||
if (available == 0)
|
||||
available = 1; // always try to read at least one byte
|
||||
|
||||
char *ptr = channel->buffer.reserve(available);
|
||||
qint64 readBytes = readFromChannel(channel, ptr, available);
|
||||
if (readBytes <= 0)
|
||||
channel->buffer.chop(available);
|
||||
if (readBytes == -2) {
|
||||
// EWOULDBLOCK
|
||||
return false;
|
||||
}
|
||||
|
||||
char *ptr = outputReadBuffer.reserve(available);
|
||||
qint64 readBytes = readFromStdout(ptr, available);
|
||||
if (readBytes == -1) {
|
||||
processError = QProcess::ReadError;
|
||||
q->setErrorString(QProcess::tr("Error reading from process"));
|
||||
emit q->error(processError);
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::canReadStandardOutput(), failed to read from the process");
|
||||
qDebug("QProcessPrivate::tryReadFromChannel(%d), failed to read from the process", channel - &stdinChannel);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
if (readBytes == 0) {
|
||||
// EOF
|
||||
if (channel->notifier)
|
||||
channel->notifier->setEnabled(false);
|
||||
closeChannel(channel);
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::tryReadFromChannel(%d), 0 bytes available", channel - &stdinChannel);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::canReadStandardOutput(), read %d bytes from the process' output",
|
||||
qDebug("QProcessPrivate::tryReadFromChannel(%d), read %d bytes from the process' output", channel - &stdinChannel
|
||||
int(readBytes));
|
||||
#endif
|
||||
|
||||
if (stdoutChannel.closed) {
|
||||
outputReadBuffer.chop(readBytes);
|
||||
if (channel->closed) {
|
||||
channel->buffer.chop(readBytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
outputReadBuffer.chop(available - readBytes);
|
||||
channel->buffer.chop(available - readBytes);
|
||||
|
||||
bool didRead = false;
|
||||
bool isStdout = channel == &stdoutChannel;
|
||||
if (readBytes == 0) {
|
||||
if (stdoutChannel.notifier)
|
||||
stdoutChannel.notifier->setEnabled(false);
|
||||
} else if (processChannel == QProcess::StandardOutput) {
|
||||
if (channel->notifier)
|
||||
channel->notifier->setEnabled(false);
|
||||
} else if ((processChannel == QProcess::StandardOutput) == isStdout) {
|
||||
didRead = true;
|
||||
if (!emittedReadyRead) {
|
||||
emittedReadyRead = true;
|
||||
@ -951,53 +963,27 @@ bool QProcessPrivate::_q_canReadStandardOutput()
|
||||
emittedReadyRead = false;
|
||||
}
|
||||
}
|
||||
emit q->readyReadStandardOutput(QProcess::QPrivateSignal());
|
||||
if (isStdout)
|
||||
emit q->readyReadStandardOutput(QProcess::QPrivateSignal());
|
||||
else
|
||||
emit q->readyReadStandardError(QProcess::QPrivateSignal());
|
||||
return didRead;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
bool QProcessPrivate::_q_canReadStandardOutput()
|
||||
{
|
||||
return tryReadFromChannel(&stdoutChannel);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
bool QProcessPrivate::_q_canReadStandardError()
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
qint64 available = bytesAvailableFromStderr();
|
||||
if (available == 0) {
|
||||
if (stderrChannel.notifier)
|
||||
stderrChannel.notifier->setEnabled(false);
|
||||
destroyChannel(&stderrChannel);
|
||||
return false;
|
||||
}
|
||||
|
||||
char *ptr = errorReadBuffer.reserve(available);
|
||||
qint64 readBytes = readFromStderr(ptr, available);
|
||||
if (readBytes == -1) {
|
||||
processError = QProcess::ReadError;
|
||||
q->setErrorString(QProcess::tr("Error reading from process"));
|
||||
emit q->error(processError);
|
||||
return false;
|
||||
}
|
||||
if (stderrChannel.closed) {
|
||||
errorReadBuffer.chop(readBytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
errorReadBuffer.chop(available - readBytes);
|
||||
|
||||
bool didRead = false;
|
||||
if (readBytes == 0) {
|
||||
if (stderrChannel.notifier)
|
||||
stderrChannel.notifier->setEnabled(false);
|
||||
} else if (processChannel == QProcess::StandardError) {
|
||||
didRead = true;
|
||||
if (!emittedReadyRead) {
|
||||
emittedReadyRead = true;
|
||||
emit q->readyRead();
|
||||
emittedReadyRead = false;
|
||||
}
|
||||
}
|
||||
emit q->readyReadStandardError(QProcess::QPrivateSignal());
|
||||
return didRead;
|
||||
return tryReadFromChannel(&stderrChannel);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1009,17 +995,17 @@ bool QProcessPrivate::_q_canWrite()
|
||||
if (stdinChannel.notifier)
|
||||
stdinChannel.notifier->setEnabled(false);
|
||||
|
||||
if (writeBuffer.isEmpty()) {
|
||||
if (stdinChannel.buffer.isEmpty()) {
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::canWrite(), not writing anything (empty write buffer).");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
qint64 written = writeToStdin(writeBuffer.readPointer(),
|
||||
writeBuffer.nextDataBlockSize());
|
||||
qint64 written = writeToStdin(stdinChannel.buffer.readPointer(),
|
||||
stdinChannel.buffer.nextDataBlockSize());
|
||||
if (written < 0) {
|
||||
destroyChannel(&stdinChannel);
|
||||
closeChannel(&stdinChannel);
|
||||
processError = QProcess::WriteError;
|
||||
q->setErrorString(QProcess::tr("Error writing to process"));
|
||||
emit q->error(processError);
|
||||
@ -1031,16 +1017,16 @@ bool QProcessPrivate::_q_canWrite()
|
||||
#endif
|
||||
|
||||
if (written != 0) {
|
||||
writeBuffer.free(written);
|
||||
stdinChannel.buffer.free(written);
|
||||
if (!emittedBytesWritten) {
|
||||
emittedBytesWritten = true;
|
||||
emit q->bytesWritten(written);
|
||||
emittedBytesWritten = false;
|
||||
}
|
||||
}
|
||||
if (stdinChannel.notifier && !writeBuffer.isEmpty())
|
||||
if (stdinChannel.notifier && !stdinChannel.buffer.isEmpty())
|
||||
stdinChannel.notifier->setEnabled(true);
|
||||
if (writeBuffer.isEmpty() && stdinChannel.closed)
|
||||
if (stdinChannel.buffer.isEmpty() && stdinChannel.closed)
|
||||
closeWriteChannel();
|
||||
return true;
|
||||
}
|
||||
@ -1163,7 +1149,7 @@ void QProcessPrivate::closeWriteChannel()
|
||||
// instead.
|
||||
flushPipeWriter();
|
||||
#endif
|
||||
destroyChannel(&stdinChannel);
|
||||
closeChannel(&stdinChannel);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1308,10 +1294,10 @@ void QProcess::setReadChannel(ProcessChannel channel)
|
||||
QByteArray buf = d->buffer.readAll();
|
||||
if (d->processChannel == QProcess::StandardOutput) {
|
||||
for (int i = buf.size() - 1; i >= 0; --i)
|
||||
d->outputReadBuffer.ungetChar(buf.at(i));
|
||||
d->stdoutChannel.buffer.ungetChar(buf.at(i));
|
||||
} else {
|
||||
for (int i = buf.size() - 1; i >= 0; --i)
|
||||
d->errorReadBuffer.ungetChar(buf.at(i));
|
||||
d->stderrChannel.buffer.ungetChar(buf.at(i));
|
||||
}
|
||||
}
|
||||
d->processChannel = channel;
|
||||
@ -1359,7 +1345,7 @@ void QProcess::closeWriteChannel()
|
||||
{
|
||||
Q_D(QProcess);
|
||||
d->stdinChannel.closed = true; // closing
|
||||
if (d->writeBuffer.isEmpty())
|
||||
if (d->stdinChannel.buffer.isEmpty())
|
||||
d->closeWriteChannel();
|
||||
}
|
||||
|
||||
@ -1589,8 +1575,8 @@ bool QProcess::canReadLine() const
|
||||
{
|
||||
Q_D(const QProcess);
|
||||
const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
|
||||
? &d->errorReadBuffer
|
||||
: &d->outputReadBuffer;
|
||||
? &d->stderrChannel.buffer
|
||||
: &d->stdoutChannel.buffer;
|
||||
return readBuffer->canReadLine() || QIODevice::canReadLine();
|
||||
}
|
||||
|
||||
@ -1618,8 +1604,8 @@ bool QProcess::atEnd() const
|
||||
{
|
||||
Q_D(const QProcess);
|
||||
const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
|
||||
? &d->errorReadBuffer
|
||||
: &d->outputReadBuffer;
|
||||
? &d->stderrChannel.buffer
|
||||
: &d->stdoutChannel.buffer;
|
||||
return QIODevice::atEnd() && (!isOpen() || readBuffer->isEmpty());
|
||||
}
|
||||
|
||||
@ -1636,8 +1622,8 @@ qint64 QProcess::bytesAvailable() const
|
||||
{
|
||||
Q_D(const QProcess);
|
||||
const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
|
||||
? &d->errorReadBuffer
|
||||
: &d->outputReadBuffer;
|
||||
? &d->stderrChannel.buffer
|
||||
: &d->stdoutChannel.buffer;
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcess::bytesAvailable() == %i (%s)", readBuffer->size(),
|
||||
(d->processChannel == QProcess::StandardError) ? "stderr" : "stdout");
|
||||
@ -1650,7 +1636,7 @@ qint64 QProcess::bytesAvailable() const
|
||||
qint64 QProcess::bytesToWrite() const
|
||||
{
|
||||
Q_D(const QProcess);
|
||||
qint64 size = d->writeBuffer.size();
|
||||
qint64 size = d->stdinChannel.buffer.size();
|
||||
#ifdef Q_OS_WIN
|
||||
size += d->pipeWriterBytesToWrite();
|
||||
#endif
|
||||
@ -1897,8 +1883,8 @@ qint64 QProcess::readData(char *data, qint64 maxlen)
|
||||
if (!maxlen)
|
||||
return 0;
|
||||
QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
|
||||
? &d->errorReadBuffer
|
||||
: &d->outputReadBuffer;
|
||||
? &d->stderrChannel.buffer
|
||||
: &d->stdoutChannel.buffer;
|
||||
|
||||
if (maxlen == 1 && !readBuffer->isEmpty()) {
|
||||
int c = readBuffer->getChar();
|
||||
@ -1961,7 +1947,7 @@ qint64 QProcess::writeData(const char *data, qint64 len)
|
||||
}
|
||||
|
||||
if (len == 1) {
|
||||
d->writeBuffer.putChar(*data);
|
||||
d->stdinChannel.buffer.putChar(*data);
|
||||
if (d->stdinChannel.notifier)
|
||||
d->stdinChannel.notifier->setEnabled(true);
|
||||
#if defined QPROCESS_DEBUG
|
||||
@ -1971,7 +1957,7 @@ qint64 QProcess::writeData(const char *data, qint64 len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *dest = d->writeBuffer.reserve(len);
|
||||
char *dest = d->stdinChannel.buffer.reserve(len);
|
||||
memcpy(dest, data, len);
|
||||
if (d->stdinChannel.notifier)
|
||||
d->stdinChannel.notifier->setEnabled(true);
|
||||
@ -2112,8 +2098,8 @@ void QProcessPrivate::start(QIODevice::OpenMode mode)
|
||||
qDebug() << "QProcess::start(" << program << ',' << arguments << ',' << mode << ')';
|
||||
#endif
|
||||
|
||||
outputReadBuffer.clear();
|
||||
errorReadBuffer.clear();
|
||||
stdoutChannel.buffer.clear();
|
||||
stderrChannel.buffer.clear();
|
||||
|
||||
if (stdinChannel.type != QProcessPrivate::Channel::Normal)
|
||||
mode &= ~QIODevice::WriteOnly; // not open for writing
|
||||
|
@ -253,6 +253,9 @@ public:
|
||||
{
|
||||
pipe[0] = INVALID_Q_PIPE;
|
||||
pipe[1] = INVALID_Q_PIPE;
|
||||
#ifdef Q_OS_WIN
|
||||
reader = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void clear();
|
||||
@ -282,6 +285,13 @@ public:
|
||||
QString file;
|
||||
QProcessPrivate *process;
|
||||
QSocketNotifier *notifier;
|
||||
#ifdef Q_OS_WIN
|
||||
union {
|
||||
QWindowsPipeReader *reader;
|
||||
QWindowsPipeWriter *writer;
|
||||
};
|
||||
#endif
|
||||
QRingBuffer buffer;
|
||||
Q_PIPE pipe[2];
|
||||
|
||||
unsigned type : 2;
|
||||
@ -316,8 +326,10 @@ public:
|
||||
Channel stdinChannel;
|
||||
Channel stdoutChannel;
|
||||
Channel stderrChannel;
|
||||
bool createChannel(Channel &channel);
|
||||
bool openChannel(Channel &channel);
|
||||
void closeChannel(Channel *channel);
|
||||
void closeWriteChannel();
|
||||
bool tryReadFromChannel(Channel *channel); // obviously, only stdout and stderr
|
||||
|
||||
QString program;
|
||||
QStringList arguments;
|
||||
@ -326,14 +338,9 @@ public:
|
||||
#endif
|
||||
QProcessEnvironment environment;
|
||||
|
||||
QRingBuffer outputReadBuffer;
|
||||
QRingBuffer errorReadBuffer;
|
||||
QRingBuffer writeBuffer;
|
||||
|
||||
Q_PIPE childStartedPipe[2];
|
||||
Q_PIPE deathPipe[2];
|
||||
void destroyPipe(Q_PIPE pipe[2]);
|
||||
void destroyChannel(Channel *channel);
|
||||
|
||||
QSocketNotifier *startupSocketNotifier;
|
||||
QSocketNotifier *deathNotifier;
|
||||
@ -341,9 +348,6 @@ public:
|
||||
#ifdef Q_OS_WIN
|
||||
// the wonderful windows notifier
|
||||
QTimer *notifier;
|
||||
QWindowsPipeReader *stdoutReader;
|
||||
QWindowsPipeReader *stderrReader;
|
||||
QWindowsPipeWriter *pipeWriter;
|
||||
QWinEventNotifier *processFinishedNotifier;
|
||||
#endif
|
||||
|
||||
@ -383,10 +387,8 @@ public:
|
||||
bool waitForFinished(int msecs = 30000);
|
||||
bool waitForWrite(int msecs = 30000);
|
||||
|
||||
qint64 bytesAvailableFromStdout() const;
|
||||
qint64 bytesAvailableFromStderr() const;
|
||||
qint64 readFromStdout(char *data, qint64 maxlen);
|
||||
qint64 readFromStderr(char *data, qint64 maxlen);
|
||||
qint64 bytesAvailableInChannel(const Channel *channel) const;
|
||||
qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen);
|
||||
qint64 writeToStdin(const char *data, qint64 maxlen);
|
||||
|
||||
void cleanup();
|
||||
|
@ -377,7 +377,7 @@ void QProcessPrivate::destroyPipe(int *pipe)
|
||||
}
|
||||
}
|
||||
|
||||
void QProcessPrivate::destroyChannel(Channel *channel)
|
||||
void QProcessPrivate::closeChannel(Channel *channel)
|
||||
{
|
||||
destroyPipe(channel->pipe);
|
||||
}
|
||||
@ -387,7 +387,7 @@ void QProcessPrivate::destroyChannel(Channel *channel)
|
||||
|
||||
This function must be called in order: stdin, stdout, stderr
|
||||
*/
|
||||
bool QProcessPrivate::createChannel(Channel &channel)
|
||||
bool QProcessPrivate::openChannel(Channel &channel)
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
|
||||
@ -573,9 +573,9 @@ void QProcessPrivate::startProcess()
|
||||
processManager()->start();
|
||||
|
||||
// Initialize pipes
|
||||
if (!createChannel(stdinChannel) ||
|
||||
!createChannel(stdoutChannel) ||
|
||||
!createChannel(stderrChannel) ||
|
||||
if (!openChannel(stdinChannel) ||
|
||||
!openChannel(stdoutChannel) ||
|
||||
!openChannel(stderrChannel) ||
|
||||
qt_create_pipe(childStartedPipe) != 0 ||
|
||||
qt_create_pipe(deathPipe) != 0) {
|
||||
processError = QProcess::FailedToStart;
|
||||
@ -963,47 +963,32 @@ bool QProcessPrivate::processStarted()
|
||||
return i <= 0;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::bytesAvailableFromStdout() const
|
||||
qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
|
||||
{
|
||||
Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
|
||||
int nbytes = 0;
|
||||
qint64 available = 0;
|
||||
if (::ioctl(stdoutChannel.pipe[0], FIONREAD, (char *) &nbytes) >= 0)
|
||||
if (::ioctl(channel->pipe[0], FIONREAD, (char *) &nbytes) >= 0)
|
||||
available = (qint64) nbytes;
|
||||
#if defined (QPROCESS_DEBUG)
|
||||
qDebug("QProcessPrivate::bytesAvailableFromStdout() == %lld", available);
|
||||
qDebug("QProcessPrivate::bytesAvailableInChannel(%d) == %lld", channel - &stdinChannel, available);
|
||||
#endif
|
||||
return available;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::bytesAvailableFromStderr() const
|
||||
qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
|
||||
{
|
||||
int nbytes = 0;
|
||||
qint64 available = 0;
|
||||
if (::ioctl(stderrChannel.pipe[0], FIONREAD, (char *) &nbytes) >= 0)
|
||||
available = (qint64) nbytes;
|
||||
#if defined (QPROCESS_DEBUG)
|
||||
qDebug("QProcessPrivate::bytesAvailableFromStderr() == %lld", available);
|
||||
#endif
|
||||
return available;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
|
||||
{
|
||||
qint64 bytesRead = qt_safe_read(stdoutChannel.pipe[0], data, maxlen);
|
||||
Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
|
||||
qint64 bytesRead = qt_safe_read(channel->pipe[0], data, maxlen);
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::readFromStdout(%p \"%s\", %lld) == %lld",
|
||||
data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead);
|
||||
#endif
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
|
||||
{
|
||||
qint64 bytesRead = qt_safe_read(stderrChannel.pipe[0], data, maxlen);
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::readFromStderr(%p \"%s\", %lld) == %lld",
|
||||
int save_errno = errno;
|
||||
qDebug("QProcessPrivate::readFromChannel(%d, %p \"%s\", %lld) == %lld",
|
||||
channel - &stdinChannel,
|
||||
data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead);
|
||||
errno = save_errno;
|
||||
#endif
|
||||
if (bytesRead == -1 && errno == EWOULDBLOCK)
|
||||
return -2;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
@ -1126,7 +1111,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
|
||||
if (stderrChannel.pipe[0] != -1)
|
||||
add_fd(nfds, stderrChannel.pipe[0], &fdread);
|
||||
|
||||
if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
|
||||
if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
|
||||
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
|
||||
|
||||
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
|
||||
@ -1188,7 +1173,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
|
||||
QList<QSocketNotifier *> notifiers = defaultNotifiers();
|
||||
#endif
|
||||
|
||||
while (!writeBuffer.isEmpty()) {
|
||||
while (!stdinChannel.buffer.isEmpty()) {
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
|
||||
@ -1207,7 +1192,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
|
||||
add_fd(nfds, stderrChannel.pipe[0], &fdread);
|
||||
|
||||
|
||||
if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
|
||||
if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
|
||||
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
|
||||
|
||||
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
|
||||
@ -1282,7 +1267,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
|
||||
if (processState == QProcess::Running)
|
||||
add_fd(nfds, deathPipe[0], &fdread);
|
||||
|
||||
if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
|
||||
if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
|
||||
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
|
||||
|
||||
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
|
||||
|
@ -158,7 +158,7 @@ static void duplicateStdWriteChannel(Q_PIPE *pipe, DWORD nStdHandle)
|
||||
|
||||
This function must be called in order: stdin, stdout, stderr
|
||||
*/
|
||||
bool QProcessPrivate::createChannel(Channel &channel)
|
||||
bool QProcessPrivate::openChannel(Channel &channel)
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
|
||||
@ -180,34 +180,31 @@ bool QProcessPrivate::createChannel(Channel &channel)
|
||||
&channel.pipe[0], 0, TRUE, DUPLICATE_SAME_ACCESS);
|
||||
}
|
||||
} else {
|
||||
QWindowsPipeReader *pipeReader = 0;
|
||||
if (&channel == &stdoutChannel) {
|
||||
if (processChannelMode != QProcess::ForwardedChannels
|
||||
&& processChannelMode != QProcess::ForwardedOutputChannel) {
|
||||
if (!stdoutReader) {
|
||||
stdoutReader = new QWindowsPipeReader(q);
|
||||
q->connect(stdoutReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardOutput()));
|
||||
if (!stdoutChannel.reader) {
|
||||
stdoutChannel.reader = new QWindowsPipeReader(q);
|
||||
q->connect(stdoutChannel.reader, SIGNAL(readyRead()), SLOT(_q_canReadStandardOutput()));
|
||||
}
|
||||
pipeReader = stdoutReader;
|
||||
} else {
|
||||
duplicateStdWriteChannel(channel.pipe, STD_OUTPUT_HANDLE);
|
||||
}
|
||||
} else /* if (&channel == &stderrChannel) */ {
|
||||
if (processChannelMode != QProcess::ForwardedChannels
|
||||
&& processChannelMode != QProcess::ForwardedErrorChannel) {
|
||||
if (!stderrReader) {
|
||||
stderrReader = new QWindowsPipeReader(q);
|
||||
q->connect(stderrReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardError()));
|
||||
if (!stderrChannel.reader) {
|
||||
stderrChannel.reader = new QWindowsPipeReader(q);
|
||||
q->connect(stderrChannel.reader, SIGNAL(readyRead()), SLOT(_q_canReadStandardError()));
|
||||
}
|
||||
pipeReader = stderrReader;
|
||||
} else {
|
||||
duplicateStdWriteChannel(channel.pipe, STD_ERROR_HANDLE);
|
||||
}
|
||||
}
|
||||
if (pipeReader) {
|
||||
if (channel.reader) {
|
||||
qt_create_pipe(channel.pipe, false);
|
||||
pipeReader->setHandle(channel.pipe[0]);
|
||||
pipeReader->startAsyncRead();
|
||||
channel.reader->setHandle(channel.pipe[0]);
|
||||
channel.reader->startAsyncRead();
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,25 +329,15 @@ void QProcessPrivate::destroyPipe(Q_PIPE pipe[2])
|
||||
}
|
||||
}
|
||||
|
||||
void QProcessPrivate::destroyChannel(Channel *channel)
|
||||
void QProcessPrivate::closeChannel(Channel *channel)
|
||||
{
|
||||
if (channel == &stdinChannel) {
|
||||
if (pipeWriter) {
|
||||
delete pipeWriter;
|
||||
pipeWriter = 0;
|
||||
}
|
||||
} else if (channel == &stdoutChannel) {
|
||||
if (stdoutReader) {
|
||||
stdoutReader->stop();
|
||||
stdoutReader->deleteLater();
|
||||
stdoutReader = 0;
|
||||
}
|
||||
} else if (channel == &stderrChannel) {
|
||||
if (stderrReader) {
|
||||
stderrReader->stop();
|
||||
stderrReader->deleteLater();
|
||||
stderrReader = 0;
|
||||
}
|
||||
delete stdinChannel.writer;
|
||||
stdinChannel.writer = 0;
|
||||
} else if (channel->reader) {
|
||||
channel->reader->stop();
|
||||
channel->reader->deleteLater();
|
||||
channel->reader = 0;
|
||||
}
|
||||
destroyPipe(channel->pipe);
|
||||
}
|
||||
@ -486,9 +473,9 @@ void QProcessPrivate::startProcess()
|
||||
|
||||
q->setProcessState(QProcess::Starting);
|
||||
|
||||
if (!createChannel(stdinChannel) ||
|
||||
!createChannel(stdoutChannel) ||
|
||||
!createChannel(stderrChannel))
|
||||
if (!openChannel(stdinChannel) ||
|
||||
!openChannel(stdoutChannel) ||
|
||||
!openChannel(stderrChannel))
|
||||
return;
|
||||
|
||||
QString args = qt_create_commandline(program, arguments);
|
||||
@ -577,47 +564,25 @@ bool QProcessPrivate::processStarted()
|
||||
return processState == QProcess::Running;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::bytesAvailableFromStdout() const
|
||||
qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
|
||||
{
|
||||
if (stdoutChannel.pipe[0] == INVALID_Q_PIPE)
|
||||
return 0;
|
||||
Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
|
||||
Q_ASSERT(channel->reader);
|
||||
|
||||
if (!stdoutReader)
|
||||
return 0;
|
||||
|
||||
DWORD bytesAvail = stdoutReader->bytesAvailable();
|
||||
DWORD bytesAvail = channel->reader->bytesAvailable();
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::bytesAvailableFromStdout() == %d", bytesAvail);
|
||||
qDebug("QProcessPrivate::bytesAvailableInChannel(%d) == %d", channel - &stdinChannel, bytesAvail);
|
||||
#endif
|
||||
return bytesAvail;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::bytesAvailableFromStderr() const
|
||||
qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
|
||||
{
|
||||
if (stderrChannel.pipe[0] == INVALID_Q_PIPE)
|
||||
return 0;
|
||||
|
||||
if (!stderrReader)
|
||||
return 0;
|
||||
|
||||
DWORD bytesAvail = stderrReader->bytesAvailable();
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::bytesAvailableFromStderr() == %d", bytesAvail);
|
||||
#endif
|
||||
return bytesAvail;
|
||||
Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
|
||||
Q_ASSERT(channel->reader);
|
||||
return channel->reader->read(data, maxlen);
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
|
||||
{
|
||||
return stdoutReader ? stdoutReader->read(data, maxlen) : 0;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
|
||||
{
|
||||
return stderrReader ? stderrReader->read(data, maxlen) : 0;
|
||||
}
|
||||
|
||||
|
||||
static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)
|
||||
{
|
||||
DWORD currentProcId = 0;
|
||||
@ -659,20 +624,20 @@ bool QProcessPrivate::waitForStarted(int)
|
||||
|
||||
bool QProcessPrivate::drainOutputPipes()
|
||||
{
|
||||
if (!stdoutReader && !stderrReader)
|
||||
if (!stdoutChannel.reader && !stderrChannel.reader)
|
||||
return false;
|
||||
|
||||
bool someReadyReadEmitted = false;
|
||||
forever {
|
||||
bool readyReadEmitted = false;
|
||||
bool readOperationActive = false;
|
||||
if (stdoutReader) {
|
||||
readyReadEmitted |= stdoutReader->waitForReadyRead(0);
|
||||
readOperationActive = stdoutReader && stdoutReader->isReadOperationActive();
|
||||
if (stdoutChannel.reader) {
|
||||
readyReadEmitted |= stdoutChannel.reader->waitForReadyRead(0);
|
||||
readOperationActive = stdoutChannel.reader && stdoutChannel.reader->isReadOperationActive();
|
||||
}
|
||||
if (stderrReader) {
|
||||
readyReadEmitted |= stderrReader->waitForReadyRead(0);
|
||||
readOperationActive |= stderrReader && stderrReader->isReadOperationActive();
|
||||
if (stderrChannel.reader) {
|
||||
readyReadEmitted |= stderrChannel.reader->waitForReadyRead(0);
|
||||
readOperationActive |= stderrChannel.reader && stderrChannel.reader->isReadOperationActive();
|
||||
}
|
||||
someReadyReadEmitted |= readyReadEmitted;
|
||||
if (!readOperationActive || !readyReadEmitted)
|
||||
@ -690,13 +655,13 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
|
||||
QIncrementalSleepTimer timer(msecs);
|
||||
|
||||
forever {
|
||||
if (!writeBuffer.isEmpty() && !_q_canWrite())
|
||||
if (!stdinChannel.buffer.isEmpty() && !_q_canWrite())
|
||||
return false;
|
||||
if (pipeWriter && pipeWriter->waitForWrite(0))
|
||||
if (stdinChannel.writer && stdinChannel.writer->waitForWrite(0))
|
||||
timer.resetIncrements();
|
||||
|
||||
if ((stdoutReader && stdoutReader->waitForReadyRead(0))
|
||||
|| (stderrReader && stderrReader->waitForReadyRead(0)))
|
||||
if ((stdoutChannel.reader && stdoutChannel.reader->waitForReadyRead(0))
|
||||
|| (stderrChannel.reader && stderrChannel.reader->waitForReadyRead(0)))
|
||||
return true;
|
||||
|
||||
if (!pid)
|
||||
@ -726,12 +691,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
|
||||
forever {
|
||||
// Check if we have any data pending: the pipe writer has
|
||||
// bytes waiting to written, or it has written data since the
|
||||
// last time we called pipeWriter->waitForWrite().
|
||||
bool pendingDataInPipe = pipeWriter && (pipeWriter->bytesToWrite() || pipeWriter->hadWritten());
|
||||
// last time we called stdinChannel.writer->waitForWrite().
|
||||
bool pendingDataInPipe = stdinChannel.writer && (stdinChannel.writer->bytesToWrite() || stdinChannel.writer->hadWritten());
|
||||
|
||||
// If we don't have pending data, and our write buffer is
|
||||
// empty, we fail.
|
||||
if (!pendingDataInPipe && writeBuffer.isEmpty())
|
||||
if (!pendingDataInPipe && stdinChannel.buffer.isEmpty())
|
||||
return false;
|
||||
|
||||
// If we don't have pending data and we do have data in our
|
||||
@ -746,21 +711,21 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
|
||||
// written. This will succeed if either the pipe writer has
|
||||
// already written the data, or if it manages to write data
|
||||
// within the given timeout. If the write buffer was non-empty
|
||||
// and the pipeWriter is now dead, that means _q_canWrite()
|
||||
// and the stdinChannel.writer is now dead, that means _q_canWrite()
|
||||
// destroyed the writer after it successfully wrote the last
|
||||
// batch.
|
||||
if (!pipeWriter || pipeWriter->waitForWrite(0))
|
||||
if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(0))
|
||||
return true;
|
||||
|
||||
// If we wouldn't write anything, check if we can read stdout.
|
||||
if (bytesAvailableFromStdout() != 0) {
|
||||
_q_canReadStandardOutput();
|
||||
if (bytesAvailableInChannel(&stdoutChannel) != 0) {
|
||||
tryReadFromChannel(&stdoutChannel);
|
||||
timer.resetIncrements();
|
||||
}
|
||||
|
||||
// Check if we can read stderr.
|
||||
if (bytesAvailableFromStderr() != 0) {
|
||||
_q_canReadStandardError();
|
||||
if (bytesAvailableInChannel(&stderrChannel) != 0) {
|
||||
tryReadFromChannel(&stderrChannel);
|
||||
timer.resetIncrements();
|
||||
}
|
||||
|
||||
@ -795,13 +760,13 @@ bool QProcessPrivate::waitForFinished(int msecs)
|
||||
QIncrementalSleepTimer timer(msecs);
|
||||
|
||||
forever {
|
||||
if (!writeBuffer.isEmpty() && !_q_canWrite())
|
||||
if (!stdinChannel.buffer.isEmpty() && !_q_canWrite())
|
||||
return false;
|
||||
if (pipeWriter && pipeWriter->waitForWrite(0))
|
||||
if (stdinChannel.writer && stdinChannel.writer->waitForWrite(0))
|
||||
timer.resetIncrements();
|
||||
if (stdoutReader && stdoutReader->waitForReadyRead(0))
|
||||
if (stdoutChannel.reader && stdoutChannel.reader->waitForReadyRead(0))
|
||||
timer.resetIncrements();
|
||||
if (stderrReader && stderrReader->waitForReadyRead(0))
|
||||
if (stderrChannel.reader && stderrChannel.reader->waitForReadyRead(0))
|
||||
timer.resetIncrements();
|
||||
|
||||
if (!pid) {
|
||||
@ -837,33 +802,32 @@ void QProcessPrivate::findExitCode()
|
||||
|
||||
void QProcessPrivate::flushPipeWriter()
|
||||
{
|
||||
if (pipeWriter && pipeWriter->bytesToWrite() > 0) {
|
||||
pipeWriter->waitForWrite(ULONG_MAX);
|
||||
}
|
||||
if (stdinChannel.writer && stdinChannel.writer->bytesToWrite() > 0)
|
||||
stdinChannel.writer->waitForWrite(ULONG_MAX);
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::pipeWriterBytesToWrite() const
|
||||
{
|
||||
return pipeWriter ? pipeWriter->bytesToWrite() : qint64(0);
|
||||
return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0);
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
|
||||
if (!pipeWriter) {
|
||||
pipeWriter = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
|
||||
pipeWriter->start();
|
||||
if (!stdinChannel.writer) {
|
||||
stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
|
||||
stdinChannel.writer->start();
|
||||
}
|
||||
|
||||
return pipeWriter->write(data, maxlen);
|
||||
return stdinChannel.writer->write(data, maxlen);
|
||||
}
|
||||
|
||||
bool QProcessPrivate::waitForWrite(int msecs)
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
|
||||
if (!pipeWriter || pipeWriter->waitForWrite(msecs))
|
||||
if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(msecs))
|
||||
return true;
|
||||
|
||||
processError = QProcess::Timedout;
|
||||
@ -875,7 +839,7 @@ void QProcessPrivate::_q_notified()
|
||||
{
|
||||
notifier->stop();
|
||||
|
||||
if (!writeBuffer.isEmpty() && (!pipeWriter || pipeWriter->waitForWrite(0)))
|
||||
if (!stdinChannel.buffer.isEmpty() && (!stdinChannel.writer || stdinChannel.writer->waitForWrite(0)))
|
||||
_q_canWrite();
|
||||
|
||||
if (processState != QProcess::NotRunning)
|
||||
|
@ -62,7 +62,7 @@ void QProcessPrivate::destroyPipe(Q_PIPE pipe[2])
|
||||
Q_UNUSED(pipe);
|
||||
}
|
||||
|
||||
void QProcessPrivate::destroyChannel(Channel *channel)
|
||||
void QProcessPrivate::closeChannel(Channel *channel)
|
||||
{
|
||||
Q_UNUSED(channel);
|
||||
}
|
||||
@ -174,22 +174,12 @@ bool QProcessPrivate::processStarted()
|
||||
return processState == QProcess::Running;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::bytesAvailableFromStdout() const
|
||||
qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::bytesAvailableFromStderr() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
|
||||
qint64 QProcessPrivate::readFromChannel(const Channel *, char *data, qint64 maxlen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -104,14 +104,23 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
case GenericCacheLocation:
|
||||
return writableLocation(GenericDataLocation) + QLatin1String("/cache");
|
||||
|
||||
case RuntimeLocation:
|
||||
case HomeLocation:
|
||||
result = QDir::homePath();
|
||||
break;
|
||||
|
||||
case TempLocation:
|
||||
result = QDir::tempPath();
|
||||
break;
|
||||
|
||||
case ApplicationsLocation:
|
||||
case DesktopLocation:
|
||||
case FontsLocation:
|
||||
case HomeLocation:
|
||||
case RuntimeLocation:
|
||||
// these are read-only
|
||||
break;
|
||||
|
||||
case DocumentsLocation:
|
||||
case MusicLocation:
|
||||
case MoviesLocation:
|
||||
case PicturesLocation:
|
||||
case DownloadLocation:
|
||||
default:
|
||||
Q_UNIMPLEMENTED();
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ qint64 QWindowsPipeReader::bytesAvailable() const
|
||||
qint64 QWindowsPipeReader::read(char *data, qint64 maxlen)
|
||||
{
|
||||
if (pipeBroken && actualReadBufferSize == 0)
|
||||
return -1; // signal EOF
|
||||
return 0; // signal EOF
|
||||
|
||||
qint64 readSoFar;
|
||||
// If startAsyncRead() has read data, copy it to its destination.
|
||||
@ -159,6 +159,8 @@ qint64 QWindowsPipeReader::read(char *data, qint64 maxlen)
|
||||
emitReadyReadTimer->stop();
|
||||
if (!readSequenceStarted)
|
||||
startAsyncRead();
|
||||
if (readSoFar == 0)
|
||||
return -2; // signal EWOULDBLOCK
|
||||
}
|
||||
|
||||
return readSoFar;
|
||||
|
@ -325,8 +325,6 @@ QEventDispatcherWin32Private::~QEventDispatcherWin32Private()
|
||||
{
|
||||
if (internalHwnd)
|
||||
DestroyWindow(internalHwnd);
|
||||
QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
|
||||
UnregisterClass((wchar_t*)className.utf16(), qWinAppInst());
|
||||
}
|
||||
|
||||
void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen)
|
||||
@ -486,10 +484,26 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
|
||||
#endif
|
||||
}
|
||||
|
||||
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
|
||||
// Provide class name and atom for the message window used by
|
||||
// QEventDispatcherWin32Private via Q_GLOBAL_STATIC shared between threads.
|
||||
struct QWindowsMessageWindowClassContext
|
||||
{
|
||||
QWindowsMessageWindowClassContext();
|
||||
~QWindowsMessageWindowClassContext();
|
||||
|
||||
ATOM atom;
|
||||
wchar_t *className;
|
||||
};
|
||||
|
||||
QWindowsMessageWindowClassContext::QWindowsMessageWindowClassContext()
|
||||
: atom(0), className(0)
|
||||
{
|
||||
// make sure that multiple Qt's can coexist in the same process
|
||||
QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
|
||||
const QString qClassName = QStringLiteral("QEventDispatcherWin32_Internal_Widget")
|
||||
+ QString::number(quintptr(qt_internal_proc));
|
||||
className = new wchar_t[qClassName.size() + 1];
|
||||
qClassName.toWCharArray(className);
|
||||
className[qClassName.size()] = 0;
|
||||
|
||||
WNDCLASS wc;
|
||||
wc.style = 0;
|
||||
@ -501,16 +515,37 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch
|
||||
wc.hCursor = 0;
|
||||
wc.hbrBackground = 0;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = reinterpret_cast<const wchar_t *> (className.utf16());
|
||||
wc.lpszClassName = className;
|
||||
atom = RegisterClass(&wc);
|
||||
if (!atom) {
|
||||
qErrnoWarning("%s: RegisterClass() failed", Q_FUNC_INFO, qPrintable(qClassName));
|
||||
delete [] className;
|
||||
className = 0;
|
||||
}
|
||||
}
|
||||
|
||||
RegisterClass(&wc);
|
||||
QWindowsMessageWindowClassContext::~QWindowsMessageWindowClassContext()
|
||||
{
|
||||
if (className) {
|
||||
UnregisterClass(className, qWinAppInst());
|
||||
delete [] className;
|
||||
}
|
||||
}
|
||||
|
||||
Q_GLOBAL_STATIC(QWindowsMessageWindowClassContext, qWindowsMessageWindowClassContext)
|
||||
|
||||
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
|
||||
{
|
||||
QWindowsMessageWindowClassContext *ctx = qWindowsMessageWindowClassContext();
|
||||
if (!ctx->atom)
|
||||
return 0;
|
||||
#ifdef Q_OS_WINCE
|
||||
HWND parent = 0;
|
||||
#else
|
||||
HWND parent = HWND_MESSAGE;
|
||||
#endif
|
||||
HWND wnd = CreateWindow(wc.lpszClassName, // classname
|
||||
wc.lpszClassName, // window name
|
||||
HWND wnd = CreateWindow(ctx->className, // classname
|
||||
ctx->className, // window name
|
||||
0, // style
|
||||
0, 0, 0, 0, // geometry
|
||||
parent, // parent
|
||||
@ -519,7 +554,8 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch
|
||||
0); // windows creation data.
|
||||
|
||||
if (!wnd) {
|
||||
qWarning("QEventDispatcher: Failed to create QEventDispatcherWin32 internal window: %d\n", (int)GetLastError());
|
||||
qErrnoWarning("%s: CreateWindow() for QEventDispatcherWin32 internal window failed", Q_FUNC_INFO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef GWLP_USERDATA
|
||||
@ -620,7 +656,9 @@ void QEventDispatcherWin32::createInternalHwnd()
|
||||
// setup GetMessage hook needed to drive our posted events
|
||||
d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
|
||||
if (!d->getMessageHook) {
|
||||
qFatal("Qt: INTERNALL ERROR: failed to install GetMessage hook");
|
||||
int errorCode = GetLastError();
|
||||
qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s",
|
||||
errorCode, qPrintable(qt_error_string(errorCode)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -113,10 +113,8 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
|
||||
{
|
||||
jclass jQtNative = env->FindClass("org/qtproject/qt5/android/QtNative");
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionClear();
|
||||
if (exceptionCheck(env))
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
jmethodID activityMethodID = env->GetStaticMethodID(jQtNative,
|
||||
"activity",
|
||||
|
@ -3238,7 +3238,7 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
|
||||
int method_index_absolute = method_index + method_offset;
|
||||
|
||||
while (c2) {
|
||||
if (c2->receiver == receiver && c2->method() == method_index_absolute)
|
||||
if (!c2->isSlotObject && c2->receiver == receiver && c2->method() == method_index_absolute)
|
||||
return 0;
|
||||
c2 = c2->nextConnectionList;
|
||||
}
|
||||
|
@ -622,7 +622,7 @@ namespace QtPrivate {
|
||||
static char test(...);
|
||||
enum {
|
||||
Ok = sizeof(test(dummy<Functor>())) == sizeof(int),
|
||||
Value = Ok ? sizeof...(ArgList) : int(ComputeFunctorArgumentCountHelper<Functor, List<ArgList...>, Ok>::Value)
|
||||
Value = Ok ? int(sizeof...(ArgList)) : int(ComputeFunctorArgumentCountHelper<Functor, List<ArgList...>, Ok>::Value)
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
static const char boilerplate_supported_but_time_limited[] =
|
||||
"\nQt %1 Evaluation License\n"
|
||||
"Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).\n"
|
||||
"Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n"
|
||||
"This trial version may only be used for evaluation purposes\n"
|
||||
"and will shut down after 120 minutes.\n"
|
||||
"Registered to:\n"
|
||||
@ -65,7 +65,7 @@ static const char boilerplate_supported_but_time_limited[] =
|
||||
|
||||
static const char boilerplate_supported[] =
|
||||
"\nQt %1 Evaluation License\n"
|
||||
"Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).\n"
|
||||
"Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n"
|
||||
"This trial version may only be used for evaluation purposes\n"
|
||||
"Registered to:\n"
|
||||
" Licensee: %2\n\n"
|
||||
|
@ -359,7 +359,7 @@ class QLibraryStore
|
||||
{
|
||||
public:
|
||||
inline ~QLibraryStore();
|
||||
static inline QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version);
|
||||
static inline QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version, QLibrary::LoadHints loadHints);
|
||||
static inline void releaseLibrary(QLibraryPrivate *lib);
|
||||
|
||||
static inline void cleanup();
|
||||
@ -438,17 +438,21 @@ QLibraryStore *QLibraryStore::instance()
|
||||
return qt_library_data;
|
||||
}
|
||||
|
||||
inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, const QString &version)
|
||||
inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, const QString &version,
|
||||
QLibrary::LoadHints loadHints)
|
||||
{
|
||||
QMutexLocker locker(&qt_library_mutex);
|
||||
QLibraryStore *data = instance();
|
||||
|
||||
// check if this library is already loaded
|
||||
QLibraryPrivate *lib = 0;
|
||||
if (Q_LIKELY(data))
|
||||
if (Q_LIKELY(data)) {
|
||||
lib = data->libraryMap.value(fileName);
|
||||
if (lib)
|
||||
lib->mergeLoadHints(loadHints);
|
||||
}
|
||||
if (!lib)
|
||||
lib = new QLibraryPrivate(fileName, version);
|
||||
lib = new QLibraryPrivate(fileName, version, loadHints);
|
||||
|
||||
// track this library
|
||||
if (Q_LIKELY(data))
|
||||
@ -479,21 +483,34 @@ inline void QLibraryStore::releaseLibrary(QLibraryPrivate *lib)
|
||||
delete lib;
|
||||
}
|
||||
|
||||
QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version)
|
||||
QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints)
|
||||
: pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0),
|
||||
loadHints(0),
|
||||
loadHints(loadHints),
|
||||
libraryRefCount(0), libraryUnloadCount(0), pluginState(MightBeAPlugin)
|
||||
{ }
|
||||
|
||||
QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, const QString &version)
|
||||
{
|
||||
return QLibraryStore::findOrCreate(fileName, version);
|
||||
if (canonicalFileName.isEmpty())
|
||||
errorString = QLibrary::tr("The shared library was not found.");
|
||||
}
|
||||
|
||||
QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, const QString &version,
|
||||
QLibrary::LoadHints loadHints)
|
||||
{
|
||||
return QLibraryStore::findOrCreate(fileName, version, loadHints);
|
||||
}
|
||||
|
||||
QLibraryPrivate::~QLibraryPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh)
|
||||
{
|
||||
// if the library is already loaded, we can't change the load hints
|
||||
if (pHnd)
|
||||
return;
|
||||
|
||||
loadHints = lh;
|
||||
}
|
||||
|
||||
QFunctionPointer QLibraryPrivate::resolve(const char *symbol)
|
||||
{
|
||||
if (!pHnd)
|
||||
|
@ -94,7 +94,8 @@ public:
|
||||
void release();
|
||||
QFunctionPointer resolve(const char *);
|
||||
|
||||
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString());
|
||||
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString(),
|
||||
QLibrary::LoadHints loadHints = 0);
|
||||
static QStringList suffixes_sys(const QString &fullVersion);
|
||||
static QStringList prefixes_sys();
|
||||
|
||||
@ -117,8 +118,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version);
|
||||
explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints);
|
||||
~QLibraryPrivate();
|
||||
void mergeLoadHints(QLibrary::LoadHints loadHints);
|
||||
|
||||
bool load_sys();
|
||||
bool unload_sys();
|
||||
|
@ -352,11 +352,8 @@ void QPluginLoader::setFileName(const QString &fileName)
|
||||
else
|
||||
fn = locatePlugin(fileName);
|
||||
|
||||
d = QLibraryPrivate::findOrCreate(fn);
|
||||
d->loadHints = lh;
|
||||
if (fn.isEmpty())
|
||||
d->errorString = QLibrary::tr("The shared library was not found.");
|
||||
else
|
||||
d = QLibraryPrivate::findOrCreate(fn, QString(), lh);
|
||||
if (!fn.isEmpty())
|
||||
d->updatePluginState();
|
||||
|
||||
#else
|
||||
|
@ -58,6 +58,7 @@
|
||||
\inmodule QtCore
|
||||
\brief The QAtomicInteger class provides platform-independent atomic operations on integers.
|
||||
\ingroup thread
|
||||
\since 5.3
|
||||
|
||||
For atomic operations on pointers, see the QAtomicPointer class.
|
||||
|
||||
|
@ -380,7 +380,7 @@ bool QBasicMutex::isRecursive()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QMutex *QMutexLocker::mutex()
|
||||
\fn QMutex *QMutexLocker::mutex() const
|
||||
|
||||
Returns the mutex on which the QMutexLocker is operating.
|
||||
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
return fastTryLock();
|
||||
}
|
||||
|
||||
bool isRecursive();
|
||||
bool isRecursive(); //### Qt6: mark const
|
||||
|
||||
private:
|
||||
inline bool fastTryLock() Q_DECL_NOTHROW {
|
||||
@ -186,10 +186,10 @@ public:
|
||||
|
||||
inline explicit QMutex(RecursionMode mode = NonRecursive) { Q_UNUSED(mode); }
|
||||
|
||||
static inline void lock() {}
|
||||
static inline bool tryLock(int timeout = 0) { Q_UNUSED(timeout); return true; }
|
||||
static inline void unlock() {}
|
||||
static inline bool isRecursive() { return true; }
|
||||
inline void lock() {}
|
||||
inline bool tryLock(int timeout = 0) { Q_UNUSED(timeout); return true; }
|
||||
inline void unlock() {}
|
||||
inline bool isRecursive() { return true; }
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QMutex)
|
||||
@ -201,9 +201,9 @@ public:
|
||||
inline explicit QMutexLocker(QMutex *) {}
|
||||
inline ~QMutexLocker() {}
|
||||
|
||||
static inline void unlock() {}
|
||||
static void relock() {}
|
||||
static inline QMutex *mutex() { return 0; }
|
||||
inline void unlock() {}
|
||||
void relock() {}
|
||||
inline QMutex *mutex() const { return 0; }
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QMutexLocker)
|
||||
|
@ -75,10 +75,17 @@ void QCollator::setCaseSensitivity(Qt::CaseSensitivity cs)
|
||||
{
|
||||
detach();
|
||||
|
||||
UColAttributeValue val = (cs == Qt::CaseSensitive) ? UCOL_UPPER_FIRST : UCOL_OFF;
|
||||
// The strength attribute in ICU is rather badly documented. Basically UCOL_PRIMARY
|
||||
// ignores differences between base characters and accented characters as well as case.
|
||||
// So A and A-umlaut would compare equal.
|
||||
// UCOL_SECONDARY ignores case differences. UCOL_TERTIARY is the default in most languages
|
||||
// and does case sensitive comparison.
|
||||
// UCOL_QUATERNARY is used as default in a few languages such as Japanese to take care of some
|
||||
// additional differences in those languages.
|
||||
UColAttributeValue val = (cs == Qt::CaseSensitive) ? UCOL_DEFAULT_STRENGTH : UCOL_SECONDARY;
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
ucol_setAttribute(d->collator, UCOL_CASE_FIRST, val, &status);
|
||||
ucol_setAttribute(d->collator, UCOL_STRENGTH, val, &status);
|
||||
if (U_FAILURE(status))
|
||||
qWarning("ucol_setAttribute: Case First failed: %d", status);
|
||||
}
|
||||
|
@ -128,12 +128,15 @@ bool QCollator::ignorePunctuation() const
|
||||
int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
|
||||
{
|
||||
SInt32 result;
|
||||
return UCCompareText(d->collator.collator,
|
||||
Boolean equivalent;
|
||||
UCCompareText(d->collator.collator,
|
||||
reinterpret_cast<const UniChar *>(s1), len1,
|
||||
reinterpret_cast<const UniChar *>(s2), len2,
|
||||
NULL,
|
||||
&equivalent,
|
||||
&result);
|
||||
return result;
|
||||
if (equivalent)
|
||||
return 0;
|
||||
return result < 0 ? -1 : 1;
|
||||
}
|
||||
int QCollator::compare(const QString &str1, const QString &str2) const
|
||||
{
|
||||
|
@ -90,7 +90,7 @@ public:
|
||||
|
||||
// special case: it is in the first buffer
|
||||
int nextDataBlockSizeValue = nextDataBlockSize();
|
||||
if (pos - head < nextDataBlockSizeValue) {
|
||||
if (pos < nextDataBlockSizeValue) {
|
||||
length = nextDataBlockSizeValue - pos;
|
||||
return buffers.at(0).constData() + head + pos;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
|
||||
\since 4.8
|
||||
\ingroup misc
|
||||
|
||||
The QScopedAssignment class can be used to revert state when an
|
||||
The QScopedValueRollback class can be used to revert state when an
|
||||
exception is thrown without needing to write try-catch blocks.
|
||||
|
||||
It can also be used to manage variables that are temporarily set,
|
||||
|
@ -220,8 +220,10 @@
|
||||
|| (defined(Q_CC_CLANG) && (__clang_major__ * 100 + __clang_minor__ >= 208)) \
|
||||
|| defined(Q_CC_INTEL))
|
||||
# define QT_COMPILER_SUPPORTS_X86INTRIN
|
||||
# ifndef Q_CC_INTEL
|
||||
# ifdef Q_CC_INTEL
|
||||
// The Intel compiler has no <x86intrin.h> -- all intrinsics are in <immintrin.h>;
|
||||
# include <immintrin.h>
|
||||
# else
|
||||
// GCC 4.4 and Clang 2.8 added a few more intrinsics there
|
||||
# include <x86intrin.h>
|
||||
# endif
|
||||
|
@ -9894,9 +9894,7 @@ QString QString::toHtmlEscaped() const
|
||||
the read-only segment of the compiled object file.
|
||||
|
||||
For compilers not supporting the creation of compile time strings, QStringLiteral will fall back to
|
||||
QLatin1String.
|
||||
|
||||
The result of the QStringLiteral expression can be cast into a QString.
|
||||
QString::fromUtf8().
|
||||
|
||||
If you have code looking like:
|
||||
\code
|
||||
|
@ -256,7 +256,7 @@ private:
|
||||
void deliverCall(QObject *object, int flags, const QDBusMessage &msg,
|
||||
const QVector<int> &metaTypes, int slotIdx);
|
||||
|
||||
bool isServiceRegisteredByThread(const QString &serviceName) const;
|
||||
bool isServiceRegisteredByThread(const QString &serviceName);
|
||||
|
||||
QString getNameOwnerNoCache(const QString &service);
|
||||
|
||||
|
@ -73,8 +73,8 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static bool isDebugging;
|
||||
#define qDBusDebug if (!::isDebugging); else qDebug
|
||||
static QBasicAtomicInt isDebugging = Q_BASIC_ATOMIC_INITIALIZER(-1);
|
||||
#define qDBusDebug if (::isDebugging == 0); else qDebug
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, orgFreedesktopDBusString, (QLatin1String(DBUS_SERVICE_DBUS)))
|
||||
|
||||
@ -1022,13 +1022,12 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
|
||||
anonymousAuthenticationAllowed(false)
|
||||
{
|
||||
static const bool threads = q_dbus_threads_init_default();
|
||||
static const int debugging = qgetenv("QDBUS_DEBUG").toInt();
|
||||
::isDebugging = debugging;
|
||||
if (::isDebugging == -1)
|
||||
::isDebugging = qgetenv("QDBUS_DEBUG").toInt();
|
||||
Q_UNUSED(threads)
|
||||
Q_UNUSED(debugging)
|
||||
|
||||
#ifdef QDBUS_THREAD_DEBUG
|
||||
if (debugging > 1)
|
||||
if (::isDebugging > 1)
|
||||
qdbusThreadDebug = qdbusDefaultThreadDebug;
|
||||
#endif
|
||||
|
||||
@ -2488,12 +2487,15 @@ void QDBusConnectionPrivate::unregisterServiceNoLock(const QString &serviceName)
|
||||
serviceNames.removeAll(serviceName);
|
||||
}
|
||||
|
||||
bool QDBusConnectionPrivate::isServiceRegisteredByThread(const QString &serviceName) const
|
||||
bool QDBusConnectionPrivate::isServiceRegisteredByThread(const QString &serviceName)
|
||||
{
|
||||
if (!serviceName.isEmpty() && serviceName == baseService)
|
||||
return true;
|
||||
QStringList copy = serviceNames;
|
||||
return copy.contains(serviceName);
|
||||
if (serviceName == dbusServiceString())
|
||||
return false;
|
||||
|
||||
QDBusReadLocker locker(UnregisterServiceAction, this);
|
||||
return serviceNames.contains(serviceName);
|
||||
}
|
||||
|
||||
void QDBusConnectionPrivate::postEventToThread(int action, QObject *object, QEvent *ev)
|
||||
|
@ -1713,10 +1713,6 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface)
|
||||
/*! \internal */
|
||||
QDebug operator<<(QDebug d, const QAccessibleEvent &ev)
|
||||
{
|
||||
if (!&ev) {
|
||||
d << "QAccessibleEvent(null)";
|
||||
return d;
|
||||
}
|
||||
d.nospace() << "QAccessibleEvent(";
|
||||
if (ev.object()) {
|
||||
d.nospace() << "object=" << hex << ev.object() << dec;
|
||||
|
@ -64,7 +64,7 @@ template<> Q_INLINE_TEMPLATE QQuaternion _q_interpolate(const QQuaternion &f,con
|
||||
return QQuaternion::slerp(f, t, progress);
|
||||
}
|
||||
|
||||
static void qRegisterGuiGetInterpolator()
|
||||
void qRegisterGuiGetInterpolator()
|
||||
{
|
||||
qRegisterAnimationInterpolator<QColor>(_q_interpolateVariant<QColor>);
|
||||
qRegisterAnimationInterpolator<QVector2D>(_q_interpolateVariant<QVector2D>);
|
||||
|
@ -674,7 +674,7 @@ void QGIFFormat::scan(QIODevice *device, QVector<QSize> *imageSizes, int *loopCo
|
||||
return;
|
||||
|
||||
qint64 oldPos = device->pos();
|
||||
if (!device->seek(0))
|
||||
if (device->isSequential() || !device->seek(0))
|
||||
return;
|
||||
|
||||
int colorCount = 0;
|
||||
|
@ -363,44 +363,93 @@ void QPixmapIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon
|
||||
}
|
||||
}
|
||||
|
||||
void QPixmapIconEngine::addFile(const QString &fileName, const QSize &_size, QIcon::Mode mode, QIcon::State state)
|
||||
// Read out original image depth as set by ICOReader
|
||||
static inline int origIcoDepth(const QImage &image)
|
||||
{
|
||||
if (!fileName.isEmpty()) {
|
||||
QString abs = fileName;
|
||||
if (fileName.at(0) != QLatin1Char(':'))
|
||||
abs = QFileInfo(fileName).absoluteFilePath();
|
||||
QImageReader reader(abs);
|
||||
const QString s = image.text(QStringLiteral("_q_icoOrigDepth"));
|
||||
return s.isEmpty() ? 32 : s.toInt();
|
||||
}
|
||||
|
||||
do {
|
||||
QSize size = _size;
|
||||
QPixmap pixmap;
|
||||
|
||||
for (int i = 0; i < pixmaps.count(); ++i) {
|
||||
if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) {
|
||||
QPixmapIconEngineEntry *pe = &pixmaps[i];
|
||||
if (size == QSize()) {
|
||||
pixmap.convertFromImage(reader.read());
|
||||
size = pixmap.size();
|
||||
}
|
||||
if (pe->size == QSize() && pe->pixmap.isNull()) {
|
||||
pe->pixmap = QPixmap(pe->fileName);
|
||||
// Reset the devicePixelRatio. The pixmap may be loaded from a @2x file,
|
||||
// but be used as a 1x pixmap by QIcon.
|
||||
pe->pixmap.setDevicePixelRatio(1.0);
|
||||
pe->size = pe->pixmap.size();
|
||||
}
|
||||
if (pe->size == size) {
|
||||
pe->pixmap = pixmap;
|
||||
pe->fileName = abs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
QPixmapIconEngineEntry e(abs, size, mode, state);
|
||||
e.pixmap = pixmap;
|
||||
pixmaps += e;
|
||||
} while (reader.jumpToNextImage());
|
||||
static inline int findBySize(const QList<QImage> &images, const QSize &size)
|
||||
{
|
||||
for (int i = 0; i < images.size(); ++i) {
|
||||
if (images.at(i).size() == size)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Convenience class providing a bool read() function.
|
||||
namespace {
|
||||
class ImageReader
|
||||
{
|
||||
public:
|
||||
ImageReader(const QString &fileName) : m_reader(fileName), m_atEnd(false) {}
|
||||
|
||||
QByteArray format() const { return m_reader.format(); }
|
||||
|
||||
bool read(QImage *image)
|
||||
{
|
||||
if (m_atEnd)
|
||||
return false;
|
||||
*image = m_reader.read();
|
||||
if (!image->size().isValid()) {
|
||||
m_atEnd = true;
|
||||
return false;
|
||||
}
|
||||
m_atEnd = !m_reader.jumpToNextImage();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
QImageReader m_reader;
|
||||
bool m_atEnd;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
void QPixmapIconEngine::addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
const QString abs = fileName.startsWith(QLatin1Char(':')) ? fileName : QFileInfo(fileName).absoluteFilePath();
|
||||
const bool ignoreSize = !size.isValid();
|
||||
ImageReader imageReader(abs);
|
||||
const QByteArray format = imageReader.format();
|
||||
if (format.isEmpty()) // Device failed to open or unsupported format.
|
||||
return;
|
||||
QImage image;
|
||||
if (format != "ico") {
|
||||
if (ignoreSize) { // No size specified: Add all images.
|
||||
while (imageReader.read(&image))
|
||||
pixmaps += QPixmapIconEngineEntry(abs, image, mode, state);
|
||||
} else {
|
||||
// Try to match size. If that fails, add a placeholder with the filename and empty pixmap for the size.
|
||||
while (imageReader.read(&image) && image.size() != size) {}
|
||||
pixmaps += image.size() == size ?
|
||||
QPixmapIconEngineEntry(abs, image, mode, state) : QPixmapIconEngineEntry(abs, size, mode, state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Special case for reading Windows ".ico" files. Historically (QTBUG-39287),
|
||||
// these files may contain low-resolution images. As this information is lost,
|
||||
// ICOReader sets the original format as an image text key value. Read all matching
|
||||
// images into a list trying to find the highest quality per size.
|
||||
QList<QImage> icoImages;
|
||||
while (imageReader.read(&image)) {
|
||||
if (ignoreSize || image.size() == size) {
|
||||
const int position = findBySize(icoImages, image.size());
|
||||
if (position >= 0) { // Higher quality available? -> replace.
|
||||
if (origIcoDepth(image) > origIcoDepth(icoImages.at(position)))
|
||||
icoImages[position] = image;
|
||||
} else {
|
||||
icoImages.append(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (const QImage &i, icoImages)
|
||||
pixmaps += QPixmapIconEngineEntry(abs, i, mode, state);
|
||||
if (icoImages.isEmpty() && !ignoreSize) // Add placeholder with the filename and empty pixmap for the size.
|
||||
pixmaps += QPixmapIconEngineEntry(abs, size, mode, state);
|
||||
}
|
||||
|
||||
QString QPixmapIconEngine::key() const
|
||||
|
@ -89,6 +89,7 @@ struct QPixmapIconEngineEntry
|
||||
:pixmap(pm), size(pm.size()), mode(m), state(s){}
|
||||
QPixmapIconEngineEntry(const QString &file, const QSize &sz = QSize(), QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
|
||||
:fileName(file), size(sz), mode(m), state(s){}
|
||||
QPixmapIconEngineEntry(const QString &file, const QImage &image, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off);
|
||||
QPixmap pixmap;
|
||||
QString fileName;
|
||||
QSize size;
|
||||
@ -97,7 +98,14 @@ struct QPixmapIconEngineEntry
|
||||
bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); }
|
||||
};
|
||||
|
||||
|
||||
inline QPixmapIconEngineEntry::QPixmapIconEngineEntry(const QString &file, const QImage &image, QIcon::Mode m, QIcon::State s)
|
||||
: fileName(file), size(image.size()), mode(m), state(s)
|
||||
{
|
||||
pixmap.convertFromImage(image);
|
||||
// Reset the devicePixelRatio. The pixmap may be loaded from a @2x file,
|
||||
// but be used as a 1x pixmap by QIcon.
|
||||
pixmap.setDevicePixelRatio(1.0);
|
||||
}
|
||||
|
||||
class QPixmapIconEngine : public QIconEngine {
|
||||
public:
|
||||
|
@ -1662,11 +1662,14 @@ void QImage::fill(uint pixel)
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->format == Format_RGB32 || d->format == Format_RGBX8888)
|
||||
if (d->format == Format_RGB32)
|
||||
pixel |= 0xff000000;
|
||||
|
||||
if (d->format == Format_RGBX8888 || d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied)
|
||||
pixel = ARGB2RGBA(pixel);
|
||||
if (d->format == Format_RGBX8888)
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
pixel |= 0xff000000;
|
||||
#else
|
||||
pixel |= 0x000000ff;
|
||||
#endif
|
||||
|
||||
qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel,
|
||||
0, 0, d->width, d->height, d->bytes_per_line);
|
||||
@ -1716,22 +1719,27 @@ void QImage::fill(const QColor &color)
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
if (d->depth == 32) {
|
||||
uint pixel = color.rgba();
|
||||
if (d->format == QImage::Format_ARGB32_Premultiplied || d->format == QImage::Format_RGBA8888_Premultiplied)
|
||||
pixel = qPremultiply(pixel);
|
||||
fill((uint) pixel);
|
||||
|
||||
} else if (d->format == QImage::Format_RGB16) {
|
||||
switch (d->format) {
|
||||
case QImage::Format_RGB32:
|
||||
case QImage::Format_ARGB32:
|
||||
fill(color.rgba());
|
||||
break;
|
||||
case QImage::Format_ARGB32_Premultiplied:
|
||||
fill(qPremultiply(color.rgba()));
|
||||
break;
|
||||
case QImage::Format_RGBX8888:
|
||||
fill(ARGB2RGBA(color.rgba() | 0xff000000));
|
||||
break;
|
||||
case QImage::Format_RGBA8888:
|
||||
fill(ARGB2RGBA(color.rgba()));
|
||||
break;
|
||||
case QImage::Format_RGBA8888_Premultiplied:
|
||||
fill(ARGB2RGBA(qPremultiply(color.rgba())));
|
||||
break;
|
||||
case QImage::Format_RGB16:
|
||||
fill((uint) qConvertRgb32To16(color.rgba()));
|
||||
|
||||
} else if (d->depth == 1) {
|
||||
if (color == Qt::color1)
|
||||
fill((uint) 1);
|
||||
else
|
||||
fill((uint) 0);
|
||||
|
||||
} else if (d->depth == 8) {
|
||||
break;
|
||||
case QImage::Format_Indexed8: {
|
||||
uint pixel = 0;
|
||||
for (int i=0; i<d->colortable.size(); ++i) {
|
||||
if (color.rgba() == d->colortable.at(i)) {
|
||||
@ -1740,20 +1748,24 @@ void QImage::fill(const QColor &color)
|
||||
}
|
||||
}
|
||||
fill(pixel);
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
case QImage::Format_Mono:
|
||||
case QImage::Format_MonoLSB:
|
||||
if (color == Qt::color1)
|
||||
fill((uint) 1);
|
||||
else
|
||||
fill((uint) 0);
|
||||
break;
|
||||
default: {
|
||||
QPainter p(this);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.fillRect(rect(), color);
|
||||
}
|
||||
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
Inverts all pixel values in the image.
|
||||
|
||||
@ -2685,13 +2697,6 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
|
||||
return maskImage;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This code is contributed by Philipp Lang,
|
||||
GeneriCom Software Germany (www.generi.com)
|
||||
under the terms of the QPL, Version 1.0
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) const
|
||||
Returns a mirror of the image, mirrored in the horizontal and/or
|
||||
@ -2703,61 +2708,108 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
|
||||
\sa {QImage#Image Transformations}{Image Transformations}
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
inline void mirrored_helper_loop(int w, int h, int dxi, int dxs, int dyi, int dy, const uchar* sdata, uchar* ddata, int sbpl, int dbpl)
|
||||
template<class T> inline void do_mirror_data(QImageData *dst, QImageData *src,
|
||||
int dstX0, int dstY0,
|
||||
int dstXIncr, int dstYIncr,
|
||||
int w, int h)
|
||||
{
|
||||
for (int sy = 0; sy < h; sy++, dy += dyi) {
|
||||
const T* ssl = (T*)(sdata + sy*sbpl);
|
||||
T* dsl = (T*)(ddata + dy*dbpl);
|
||||
int dx = dxs;
|
||||
for (int sx = 0; sx < w; sx++, dx += dxi)
|
||||
dsl[dx] = ssl[sx];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void mirrored_helper_loop_inplace(int w, int h, int dxi, int dxs, int dyi, int dy, uchar* sdata, int sbpl)
|
||||
{
|
||||
for (int sy = 0; sy < h; sy++, dy += dyi) {
|
||||
T* ssl = (T*)(sdata + sy*sbpl);
|
||||
T* dsl = (T*)(sdata + dy*sbpl);
|
||||
int dx = dxs;
|
||||
for (int sx = 0; sx < w; sx++, dx += dxi)
|
||||
std::swap(dsl[dx], ssl[sx]);
|
||||
}
|
||||
}
|
||||
|
||||
inline void mirror_horizonal_bitmap(int w, int h, int dxs, uchar* data, int bpl, bool monolsb)
|
||||
{
|
||||
int shift = w % 8;
|
||||
const uchar* bitflip = qt_get_bitflip_array();
|
||||
for (int y = h-1; y >= 0; y--) {
|
||||
quint8* a0 = (quint8*)(data + y*bpl);
|
||||
// Swap bytes
|
||||
quint8* a = a0+dxs;
|
||||
while (a >= a0) {
|
||||
*a = bitflip[*a];
|
||||
a--;
|
||||
if (dst == src) {
|
||||
// When mirroring in-place, stop in the middle for one of the directions, since we
|
||||
// are swapping the bytes instead of merely copying.
|
||||
const int srcXEnd = dstX0 ? w / 2 : w;
|
||||
const int srcYEnd = !dstX0 && dstY0 ? h / 2 : h;
|
||||
for (int srcY = 0, dstY = dstY0; srcY < srcYEnd; ++srcY, dstY += dstYIncr) {
|
||||
T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
|
||||
T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
|
||||
for (int srcX = 0, dstX = dstX0; srcX < srcXEnd; ++srcX, dstX += dstXIncr)
|
||||
std::swap(srcPtr[srcX], dstPtr[dstX]);
|
||||
}
|
||||
// Shift bits if unaligned
|
||||
if (shift != 0) {
|
||||
a = a0+dxs;
|
||||
quint8 c = 0;
|
||||
if (monolsb) {
|
||||
while (a >= a0) {
|
||||
quint8 nc = *a << shift;
|
||||
*a = (*a >> (8-shift)) | c;
|
||||
--a;
|
||||
c = nc;
|
||||
}
|
||||
} else {
|
||||
while (a >= a0) {
|
||||
quint8 nc = *a >> shift;
|
||||
*a = (*a << (8-shift)) | c;
|
||||
--a;
|
||||
c = nc;
|
||||
} else {
|
||||
for (int srcY = 0, dstY = dstY0; srcY < h; ++srcY, dstY += dstYIncr) {
|
||||
T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
|
||||
T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
|
||||
for (int srcX = 0, dstX = dstX0; srcX < w; ++srcX, dstX += dstXIncr)
|
||||
dstPtr[dstX] = srcPtr[srcX];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool vertical)
|
||||
{
|
||||
Q_ASSERT(src->width == dst->width && src->height == dst->height && src->depth == dst->depth);
|
||||
int w = src->width;
|
||||
int h = src->height;
|
||||
int depth = src->depth;
|
||||
|
||||
if (src->depth == 1) {
|
||||
w = (w + 7) / 8; // byte aligned width
|
||||
depth = 8;
|
||||
}
|
||||
|
||||
int dstX0 = 0, dstXIncr = 1;
|
||||
int dstY0 = 0, dstYIncr = 1;
|
||||
if (horizontal) {
|
||||
// 0 -> w-1, 1 -> w-2, 2 -> w-3, ...
|
||||
dstX0 = w - 1;
|
||||
dstXIncr = -1;
|
||||
}
|
||||
if (vertical) {
|
||||
// 0 -> h-1, 1 -> h-2, 2 -> h-3, ...
|
||||
dstY0 = h - 1;
|
||||
dstYIncr = -1;
|
||||
}
|
||||
|
||||
switch (depth) {
|
||||
case 32:
|
||||
do_mirror_data<quint32>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
|
||||
break;
|
||||
case 24:
|
||||
do_mirror_data<quint24>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
|
||||
break;
|
||||
case 16:
|
||||
do_mirror_data<quint16>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
|
||||
break;
|
||||
case 8:
|
||||
do_mirror_data<quint8>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
// The bytes are now all in the correct place. In addition, the bits in the individual
|
||||
// bytes have to be flipped too when horizontally mirroring a 1 bit-per-pixel image.
|
||||
if (horizontal && dst->depth == 1) {
|
||||
Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
|
||||
const int shift = 8 - (dst->width % 8);
|
||||
const uchar *bitflip = qt_get_bitflip_array();
|
||||
for (int y = 0; y < h; ++y) {
|
||||
uchar *begin = dst->data + y * dst->bytes_per_line;
|
||||
uchar *end = begin + dst->bytes_per_line;
|
||||
for (uchar *p = begin; p < end; ++p) {
|
||||
*p = bitflip[*p];
|
||||
// When the data is non-byte aligned, an extra bit shift (of the number of
|
||||
// unused bits at the end) is needed for the entire scanline.
|
||||
if (shift != 8 && p != begin) {
|
||||
if (dst->format == QImage::Format_Mono) {
|
||||
for (int i = 0; i < shift; ++i) {
|
||||
p[-1] <<= 1;
|
||||
p[-1] |= (*p & (128 >> i)) >> (7 - i);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < shift; ++i) {
|
||||
p[-1] >>= 1;
|
||||
p[-1] |= (*p & (1 << i)) << (7 - i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shift != 8) {
|
||||
if (dst->format == QImage::Format_Mono)
|
||||
end[-1] <<= shift;
|
||||
else
|
||||
end[-1] >>= shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2773,8 +2825,6 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
|
||||
if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
|
||||
return *this;
|
||||
|
||||
int w = d->width;
|
||||
int h = d->height;
|
||||
// Create result image, copy colormap
|
||||
QImage result(d->width, d->height, d->format);
|
||||
QIMAGE_SANITYCHECK_MEMORY(result);
|
||||
@ -2787,29 +2837,8 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
|
||||
result.d->has_alpha_clut = d->has_alpha_clut;
|
||||
result.d->devicePixelRatio = d->devicePixelRatio;
|
||||
|
||||
if (d->depth == 1)
|
||||
w = (w+7)/8;
|
||||
int dxi = horizontal ? -1 : 1;
|
||||
int dxs = horizontal ? w-1 : 0;
|
||||
int dyi = vertical ? -1 : 1;
|
||||
int dys = vertical ? h-1 : 0;
|
||||
do_mirror(result.d, d, horizontal, vertical);
|
||||
|
||||
// 1 bit, 8 bit
|
||||
if (d->depth == 1 || d->depth == 8)
|
||||
mirrored_helper_loop<quint8>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
|
||||
// 16 bit
|
||||
else if (d->depth == 16)
|
||||
mirrored_helper_loop<quint16>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
|
||||
// 24 bit
|
||||
else if (d->depth == 24)
|
||||
mirrored_helper_loop<quint24>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
|
||||
// 32 bit
|
||||
else if (d->depth == 32)
|
||||
mirrored_helper_loop<quint32>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
|
||||
|
||||
// special handling of 1 bit images for horizontal mirroring
|
||||
if (horizontal && d->depth == 1)
|
||||
mirror_horizonal_bitmap(d->width, d->height, dxs, result.d->data, result.d->bytes_per_line, d->format == Format_MonoLSB);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2818,45 +2847,12 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
|
||||
*/
|
||||
void QImage::mirrored_inplace(bool horizontal, bool vertical)
|
||||
{
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
|
||||
if (!d || (d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
|
||||
return;
|
||||
|
||||
detach();
|
||||
|
||||
int w = d->width;
|
||||
int h = d->height;
|
||||
|
||||
if (d->depth == 1)
|
||||
w = (w+7)/8;
|
||||
int dxi = horizontal ? -1 : 1;
|
||||
int dxs = horizontal ? w-1 : 0;
|
||||
int dyi = vertical ? -1 : 1;
|
||||
int dys = vertical ? h-1 : 0;
|
||||
|
||||
if (vertical)
|
||||
h = h/2;
|
||||
else if (horizontal)
|
||||
w = w/2;
|
||||
|
||||
// 1 bit, 8 bit
|
||||
if (d->depth == 1 || d->depth == 8)
|
||||
mirrored_helper_loop_inplace<quint8>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
|
||||
// 16 bit
|
||||
else if (d->depth == 16)
|
||||
mirrored_helper_loop_inplace<quint16>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
|
||||
// 24 bit
|
||||
else if (d->depth == 24)
|
||||
mirrored_helper_loop_inplace<quint24>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
|
||||
// 32 bit
|
||||
else if (d->depth == 32)
|
||||
mirrored_helper_loop_inplace<quint32>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
|
||||
|
||||
// special handling of 1 bit images for horizontal mirroring
|
||||
if (horizontal && d->depth == 1)
|
||||
mirror_horizonal_bitmap(d->width, d->height, dxs, d->data, d->bytes_per_line, d->format == Format_MonoLSB);
|
||||
do_mirror(d, d, horizontal, vertical);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1098,6 +1098,7 @@ bool QPixmap::isDetached() const
|
||||
*/
|
||||
bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags)
|
||||
{
|
||||
detach();
|
||||
if (image.isNull() || !data)
|
||||
*this = QPixmap::fromImage(image, flags);
|
||||
else
|
||||
|
@ -363,10 +363,12 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC
|
||||
}
|
||||
is_null = (w <= 0 || h <= 0);
|
||||
|
||||
image.d->devicePixelRatio = sourceImage.devicePixelRatio();
|
||||
if (image.d)
|
||||
image.d->devicePixelRatio = sourceImage.devicePixelRatio();
|
||||
//ensure the pixmap and the image resulting from toImage() have the same cacheKey();
|
||||
setSerialNumber(image.cacheKey() >> 32);
|
||||
setDetachNumber(image.d->detach_no);
|
||||
if (image.d)
|
||||
setDetachNumber(image.d->detach_no);
|
||||
}
|
||||
|
||||
QImage* QRasterPlatformPixmap::buffer()
|
||||
|
@ -171,6 +171,7 @@ bool QGuiApplicationPrivate::noGrab = false;
|
||||
static qreal fontSmoothingGamma = 1.7;
|
||||
|
||||
extern void qRegisterGuiVariant();
|
||||
extern void qRegisterGuiGetInterpolator();
|
||||
extern void qInitDrawhelperAsm();
|
||||
extern void qInitImageConversions();
|
||||
|
||||
@ -489,6 +490,12 @@ static QWindowGeometrySpecification windowGeometrySpecification;
|
||||
\li \c{-platformtheme} \e platformTheme, specifies the platform theme.
|
||||
|
||||
Overridden by the \c QT_QPA_PLATFORMTHEME environment variable.
|
||||
|
||||
\li \c{-plugin} \e plugin, specifies additional plugins to load. The argument
|
||||
may appear multiple times.
|
||||
|
||||
Overridden by the \c QT_QPA_GENERIC_PLUGINS environment variable.
|
||||
|
||||
\li \c{-qmljsdebugger=}, activates the QML/JS debugger with a specified port.
|
||||
The value must be of format \c{port:1234}\e{[,block]}, where
|
||||
\e block is optional
|
||||
@ -1281,6 +1288,9 @@ void QGuiApplicationPrivate::init()
|
||||
// trigger registering of QVariant's GUI types
|
||||
qRegisterGuiVariant();
|
||||
|
||||
// trigger registering of animation interpolators
|
||||
qRegisterGuiGetInterpolator();
|
||||
|
||||
QWindowSystemInterfacePrivate::eventTime.start();
|
||||
|
||||
is_app_running = true;
|
||||
|
@ -123,7 +123,8 @@ bool QPlatformClipboard::ownsMode(QClipboard::Mode mode) const
|
||||
|
||||
void QPlatformClipboard::emitChanged(QClipboard::Mode mode)
|
||||
{
|
||||
QGuiApplication::clipboard()->emitChanged(mode);
|
||||
if (!QGuiApplicationPrivate::is_app_closing) // QTBUG-39317, prevent emission when closing down.
|
||||
QGuiApplication::clipboard()->emitChanged(mode);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -443,9 +443,10 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
|
||||
samples = qBound(0, int(samples), int(maxSamples));
|
||||
}
|
||||
|
||||
samples = qMax(0, samples);
|
||||
requestedSamples = samples;
|
||||
size = sz;
|
||||
target = texture_target;
|
||||
// texture dimensions
|
||||
|
||||
QT_RESET_GLERROR(); // reset error state
|
||||
GLuint fbo = 0;
|
||||
@ -477,6 +478,9 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
|
||||
valid = checkFramebufferStatus(ctx);
|
||||
|
||||
if (valid) {
|
||||
// Query the actual number of samples. This can be greater than the requested
|
||||
// value since the typically supported values are 0, 4, 8, ..., and the
|
||||
// requests are mapped to the next supported value.
|
||||
funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
|
||||
color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
|
||||
}
|
||||
@ -546,7 +550,10 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal
|
||||
|
||||
void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment)
|
||||
{
|
||||
int samples = format.samples();
|
||||
// Use the same sample count for all attachments. format.samples() already contains
|
||||
// the actual number of samples for the color attachment and is not suitable. Use
|
||||
// requestedSamples instead.
|
||||
const int samples = requestedSamples;
|
||||
|
||||
// free existing attachments
|
||||
if (depth_buffer_guard) {
|
||||
|
@ -131,6 +131,7 @@ public:
|
||||
GLenum target;
|
||||
QSize size;
|
||||
QOpenGLFramebufferObjectFormat format;
|
||||
int requestedSamples;
|
||||
uint valid : 1;
|
||||
QOpenGLFramebufferObject::Attachment fbo_attachment;
|
||||
QOpenGLExtensions funcs;
|
||||
|
@ -283,46 +283,48 @@ static int qt_gl_resolve_features()
|
||||
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
|
||||
// Recognize features by extension name.
|
||||
if (extensions.match("GL_ARB_multitexture"))
|
||||
features |= QOpenGLFunctions::Multitexture;
|
||||
if (extensions.match("GL_ARB_shader_objects"))
|
||||
features |= QOpenGLFunctions::Shaders;
|
||||
if (extensions.match("GL_EXT_framebuffer_object") ||
|
||||
extensions.match("GL_ARB_framebuffer_object"))
|
||||
features |= QOpenGLFunctions::Framebuffers;
|
||||
if (extensions.match("GL_EXT_blend_color"))
|
||||
features |= QOpenGLFunctions::BlendColor;
|
||||
if (extensions.match("GL_EXT_blend_equation_separate"))
|
||||
features |= QOpenGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_EXT_blend_func_separate"))
|
||||
features |= QOpenGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_EXT_blend_subtract"))
|
||||
features |= QOpenGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_ARB_texture_compression"))
|
||||
features |= QOpenGLFunctions::CompressedTextures;
|
||||
if (extensions.match("GL_ARB_multisample"))
|
||||
features |= QOpenGLFunctions::Multisample;
|
||||
if (extensions.match("GL_ARB_texture_non_power_of_two"))
|
||||
features |= QOpenGLFunctions::NPOTTextures |
|
||||
QOpenGLFunctions::NPOTTextureRepeat;
|
||||
|
||||
// assume version 2.0 or higher
|
||||
features |= QOpenGLFunctions::BlendColor |
|
||||
QOpenGLFunctions::BlendEquation |
|
||||
QOpenGLFunctions::Multitexture |
|
||||
QOpenGLFunctions::CompressedTextures |
|
||||
QOpenGLFunctions::Multisample |
|
||||
QOpenGLFunctions::BlendFuncSeparate |
|
||||
QOpenGLFunctions::Buffers |
|
||||
QOpenGLFunctions::Shaders |
|
||||
QOpenGLFunctions::StencilSeparate |
|
||||
QOpenGLFunctions::BlendEquationSeparate |
|
||||
QOpenGLFunctions::NPOTTextures |
|
||||
QOpenGLFunctions::NPOTTextureRepeat;
|
||||
|
||||
if (format.majorVersion() >= 3)
|
||||
features |= QOpenGLFunctions::Framebuffers;
|
||||
else if (extensions.match("GL_EXT_framebuffer_object") ||
|
||||
extensions.match("GL_ARB_framebuffer_object"))
|
||||
features |= QOpenGLFunctions::Framebuffers;
|
||||
|
||||
if (format.majorVersion() >= 2) {
|
||||
features |= QOpenGLFunctions::BlendColor |
|
||||
QOpenGLFunctions::BlendEquation |
|
||||
QOpenGLFunctions::BlendSubtract |
|
||||
QOpenGLFunctions::Multitexture |
|
||||
QOpenGLFunctions::CompressedTextures |
|
||||
QOpenGLFunctions::Multisample |
|
||||
QOpenGLFunctions::BlendFuncSeparate |
|
||||
QOpenGLFunctions::Buffers |
|
||||
QOpenGLFunctions::Shaders |
|
||||
QOpenGLFunctions::StencilSeparate |
|
||||
QOpenGLFunctions::BlendEquationSeparate |
|
||||
QOpenGLFunctions::NPOTTextures |
|
||||
QOpenGLFunctions::NPOTTextureRepeat;
|
||||
} else {
|
||||
// Recognize features by extension name.
|
||||
if (extensions.match("GL_ARB_multitexture"))
|
||||
features |= QOpenGLFunctions::Multitexture;
|
||||
if (extensions.match("GL_ARB_shader_objects"))
|
||||
features |= QOpenGLFunctions::Shaders;
|
||||
if (extensions.match("GL_EXT_blend_color"))
|
||||
features |= QOpenGLFunctions::BlendColor;
|
||||
if (extensions.match("GL_EXT_blend_equation_separate"))
|
||||
features |= QOpenGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_EXT_blend_subtract"))
|
||||
features |= QOpenGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_EXT_blend_func_separate"))
|
||||
features |= QOpenGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_ARB_texture_compression"))
|
||||
features |= QOpenGLFunctions::CompressedTextures;
|
||||
if (extensions.match("GL_ARB_multisample"))
|
||||
features |= QOpenGLFunctions::Multisample;
|
||||
if (extensions.match("GL_ARB_texture_non_power_of_two"))
|
||||
features |= QOpenGLFunctions::NPOTTextures |
|
||||
QOpenGLFunctions::NPOTTextureRepeat;
|
||||
}
|
||||
|
||||
const QPair<int, int> version = format.version();
|
||||
if (version < qMakePair(3, 0)
|
||||
|
@ -1798,71 +1798,6 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
|
||||
}
|
||||
fx = v_fx.i[0];
|
||||
fy = v_fy.i[0];
|
||||
#elif defined(__ARM_NEON__)
|
||||
BILINEAR_ROTATE_BOUNDS_PROLOG
|
||||
|
||||
const int16x8_t colorMask = vdupq_n_s16(0x00ff);
|
||||
const int16x8_t invColorMask = vmvnq_s16(colorMask);
|
||||
const int16x8_t v_256 = vdupq_n_s16(256);
|
||||
int32x4_t v_fdx = vdupq_n_s32(fdx*4);
|
||||
int32x4_t v_fdy = vdupq_n_s32(fdy*4);
|
||||
|
||||
const uchar *textureData = data->texture.imageData;
|
||||
const int bytesPerLine = data->texture.bytesPerLine;
|
||||
|
||||
union Vect_buffer { int32x4_t vect; quint32 i[4]; };
|
||||
Vect_buffer v_fx, v_fy;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
v_fx.i[i] = fx;
|
||||
v_fy.i[i] = fy;
|
||||
fx += fdx;
|
||||
fy += fdy;
|
||||
}
|
||||
|
||||
const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
|
||||
|
||||
while (b < boundedEnd) {
|
||||
if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2)
|
||||
break;
|
||||
if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1)
|
||||
break;
|
||||
if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2)
|
||||
break;
|
||||
if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1)
|
||||
break;
|
||||
|
||||
Vect_buffer tl, tr, bl, br;
|
||||
|
||||
Vect_buffer v_fx_shifted, v_fy_shifted;
|
||||
v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16);
|
||||
v_fy_shifted.vect = vshrq_n_s32(v_fy.vect, 16);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
const int x1 = v_fx_shifted.i[i];
|
||||
const int y1 = v_fy_shifted.i[i];
|
||||
const uchar *sl = textureData + bytesPerLine * y1;
|
||||
const uint *s1 = (const uint *)sl;
|
||||
const uint *s2 = (const uint *)(sl + bytesPerLine);
|
||||
tl.i[i] = s1[x1];
|
||||
tr.i[i] = s1[x1+1];
|
||||
bl.i[i] = s2[x1];
|
||||
br.i[i] = s2[x1+1];
|
||||
}
|
||||
|
||||
int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12);
|
||||
int32x4_t v_disty = vshrq_n_s32(vandq_s32(v_fy.vect, v_ffff_mask), 12);
|
||||
v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
|
||||
v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16));
|
||||
int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
|
||||
|
||||
interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b);
|
||||
b+=4;
|
||||
v_fx.vect = vaddq_s32(v_fx.vect, v_fdx);
|
||||
v_fy.vect = vaddq_s32(v_fy.vect, v_fdy);
|
||||
}
|
||||
fx = v_fx.i[0];
|
||||
fy = v_fy.i[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -6318,6 +6253,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
|
||||
}
|
||||
}
|
||||
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
static void qt_alphamapblit_rgba8888(QRasterBuffer *rasterBuffer,
|
||||
int x, int y, quint32 color,
|
||||
const uchar *map,
|
||||
@ -6326,6 +6262,7 @@ static void qt_alphamapblit_rgba8888(QRasterBuffer *rasterBuffer,
|
||||
{
|
||||
qt_alphamapblit_argb32(rasterBuffer, x, y, ARGB2RGBA(color), map, mapWidth, mapHeight, mapStride, clip);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
|
||||
int x, int y, quint32 color,
|
||||
|
@ -761,7 +761,7 @@ void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
|
||||
bool((painter()->renderHints() & QPainter::TextAntialiasing)
|
||||
&& !(painter()->font().styleStrategy() & QFont::NoAntialias)));
|
||||
painter()->translate(p.x(), p.y());
|
||||
painter()->fillPath(path, state->pen().brush());
|
||||
painter()->fillPath(path, painter()->pen().brush());
|
||||
painter()->restore();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
@ -830,6 +830,8 @@ void QPaintEngineEx::drawEllipse(const QRectF &r)
|
||||
|
||||
int point_count = 0;
|
||||
x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count);
|
||||
if (point_count == 0)
|
||||
return;
|
||||
QVectorPath vp((qreal *) pts, point_count + 1, qpaintengineex_ellipse_types, QVectorPath::EllipseHint);
|
||||
draw(vp);
|
||||
}
|
||||
|
@ -181,9 +181,13 @@ static const HB_FontClass hb_fontClass = {
|
||||
|
||||
static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length)
|
||||
{
|
||||
QFontEngine *fe = (QFontEngine *)font;
|
||||
Q_ASSERT(fe->faceData.get_font_table);
|
||||
if (!fe->faceData.get_font_table(fe->faceData.user_data, tableTag, buffer, length))
|
||||
QFontEngine::FaceData *data = (QFontEngine::FaceData *)font;
|
||||
Q_ASSERT(data);
|
||||
|
||||
qt_get_font_table_func_t get_font_table = data->get_font_table;
|
||||
Q_ASSERT(get_font_table);
|
||||
|
||||
if (!get_font_table(data->user_data, tableTag, buffer, length))
|
||||
return HB_Err_Invalid_Argument;
|
||||
return HB_Err_Ok;
|
||||
}
|
||||
@ -291,8 +295,11 @@ void *QFontEngine::harfbuzzFont() const
|
||||
#endif
|
||||
if (!font_) {
|
||||
HB_Face hbFace = (HB_Face)harfbuzzFace();
|
||||
if (hbFace->font_for_init != 0)
|
||||
if (hbFace->font_for_init) {
|
||||
void *data = hbFace->font_for_init;
|
||||
q_check_ptr(qHBLoadFace(hbFace));
|
||||
free(data);
|
||||
}
|
||||
|
||||
HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec));
|
||||
Q_CHECK_PTR(hbFont);
|
||||
@ -323,7 +330,12 @@ void *QFontEngine::harfbuzzFace() const
|
||||
return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this));
|
||||
#endif
|
||||
if (!face_) {
|
||||
HB_Face hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable);
|
||||
QFontEngine::FaceData *data = (QFontEngine::FaceData *)malloc(sizeof(QFontEngine::FaceData));
|
||||
Q_CHECK_PTR(data);
|
||||
data->user_data = faceData.user_data;
|
||||
data->get_font_table = faceData.get_font_table;
|
||||
|
||||
HB_Face hbFace = qHBNewFace(data, hb_getSFntTable);
|
||||
Q_CHECK_PTR(hbFace);
|
||||
hbFace->isSymbolFont = symbol;
|
||||
|
||||
@ -376,8 +388,11 @@ bool QFontEngine::supportsScript(QChar::Script script) const
|
||||
}
|
||||
#endif
|
||||
HB_Face hbFace = (HB_Face)harfbuzzFace();
|
||||
if (hbFace->font_for_init != 0)
|
||||
if (hbFace->font_for_init) {
|
||||
void *data = hbFace->font_for_init;
|
||||
q_check_ptr(qHBLoadFace(hbFace));
|
||||
free(data);
|
||||
}
|
||||
return hbFace->supported_scripts[script_to_hbscript(script)];
|
||||
}
|
||||
|
||||
|
@ -295,8 +295,7 @@ int QFontMetrics::descent() const
|
||||
/*!
|
||||
Returns the height of the font.
|
||||
|
||||
This is always equal to ascent()+descent()+1 (the 1 is for the
|
||||
base line).
|
||||
This is always equal to ascent()+descent().
|
||||
|
||||
\sa leading(), lineSpacing()
|
||||
*/
|
||||
@ -1159,8 +1158,7 @@ qreal QFontMetricsF::descent() const
|
||||
/*!
|
||||
Returns the height of the font.
|
||||
|
||||
This is always equal to ascent()+descent()+1 (the 1 is for the
|
||||
base line).
|
||||
This is always equal to ascent()+descent().
|
||||
|
||||
\sa leading(), lineSpacing()
|
||||
*/
|
||||
|
@ -1219,8 +1219,8 @@ QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QS
|
||||
d->init();
|
||||
}
|
||||
#else
|
||||
QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QObject *parent,
|
||||
QHttpNetworkConnection::ConnectionType connectionType)
|
||||
QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt,
|
||||
QHttpNetworkConnection::ConnectionType connectionType, QObject *parent)
|
||||
: QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt , connectionType)), parent)
|
||||
{
|
||||
Q_D(QHttpNetworkConnection);
|
||||
|
@ -110,8 +110,8 @@ public:
|
||||
ConnectionType connectionType = ConnectionTypeHTTP);
|
||||
#else
|
||||
explicit QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false,
|
||||
QObject *parent = 0,
|
||||
ConnectionType connectionType = ConnectionTypeHTTP);
|
||||
ConnectionType connectionType = ConnectionTypeHTTP,
|
||||
QObject *parent = 0);
|
||||
QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80,
|
||||
bool encrypt = false, QObject *parent = 0,
|
||||
ConnectionType connectionType = ConnectionTypeHTTP);
|
||||
|
@ -338,7 +338,7 @@ void QNetworkAccessBackend::error(QNetworkReply::NetworkError code, const QStrin
|
||||
void QNetworkAccessBackend::proxyAuthenticationRequired(const QNetworkProxy &proxy,
|
||||
QAuthenticator *authenticator)
|
||||
{
|
||||
manager->proxyAuthenticationRequired(proxy, synchronous, authenticator, &reply->lastProxyAuthentication);
|
||||
manager->proxyAuthenticationRequired(QUrl(), proxy, synchronous, authenticator, &reply->lastProxyAuthentication);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -99,13 +99,13 @@ bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString&
|
||||
bool retValue = false;
|
||||
SecProtocolType protocolType = kSecProtocolTypeAny;
|
||||
if (scheme.compare(QLatin1String("ftp"),Qt::CaseInsensitive)==0) {
|
||||
protocolType = kSecProtocolTypeFTP;
|
||||
protocolType = kSecProtocolTypeFTPProxy;
|
||||
} else if (scheme.compare(QLatin1String("http"),Qt::CaseInsensitive)==0
|
||||
|| scheme.compare(QLatin1String("preconnect-http"),Qt::CaseInsensitive)==0) {
|
||||
protocolType = kSecProtocolTypeHTTP;
|
||||
protocolType = kSecProtocolTypeHTTPProxy;
|
||||
} else if (scheme.compare(QLatin1String("https"),Qt::CaseInsensitive)==0
|
||||
|| scheme.compare(QLatin1String("preconnect-https"),Qt::CaseInsensitive)==0) {
|
||||
protocolType = kSecProtocolTypeHTTPS;
|
||||
protocolType = kSecProtocolTypeHTTPSProxy;
|
||||
}
|
||||
QByteArray proxyHostnameUtf8(proxyHostname.toUtf8());
|
||||
err = SecKeychainFindInternetPassword(NULL,
|
||||
@ -1392,21 +1392,6 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QAuthenticator *authen
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
#if defined(Q_OS_MACX)
|
||||
//now we try to get the username and password from keychain
|
||||
//if not successful signal will be emitted
|
||||
QString username;
|
||||
QString password;
|
||||
if (getProxyAuth(proxy.hostName(),reply->request().url().scheme(),username,password)) {
|
||||
authenticator->setUser(username);
|
||||
authenticator->setPassword(password);
|
||||
authenticationManager->cacheProxyCredentials(proxy, authenticator);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif //QT_NO_NETWORKPROXY
|
||||
|
||||
// if we emit a signal here in synchronous mode, the user might spin
|
||||
// an event loop, which might recurse and lead to problems
|
||||
if (synchronous)
|
||||
@ -1419,7 +1404,8 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QAuthenticator *authen
|
||||
}
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(const QNetworkProxy &proxy,
|
||||
void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(const QUrl &url,
|
||||
const QNetworkProxy &proxy,
|
||||
bool synchronous,
|
||||
QAuthenticator *authenticator,
|
||||
QNetworkProxy *lastProxyAuthentication)
|
||||
@ -1435,6 +1421,26 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(const QNetworkPro
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(Q_OS_OSX)
|
||||
//now we try to get the username and password from keychain
|
||||
//if not successful signal will be emitted
|
||||
QString username;
|
||||
QString password;
|
||||
if (getProxyAuth(proxy.hostName(), url.scheme(), username, password)) {
|
||||
// only cache the system credentials if they are correct (or if they have changed)
|
||||
// to not run into an endless loop in case they are wrong
|
||||
QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy);
|
||||
if (!priv->hasFailed || cred.user != username || cred.password != password) {
|
||||
authenticator->setUser(username);
|
||||
authenticator->setPassword(password);
|
||||
authenticationManager->cacheProxyCredentials(proxy, authenticator);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(url);
|
||||
#endif
|
||||
|
||||
// if we emit a signal here in synchronous mode, the user might spin
|
||||
// an event loop, which might recurse and lead to problems
|
||||
if (synchronous)
|
||||
|
@ -113,7 +113,8 @@ public:
|
||||
const QAuthenticator *auth = 0);
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
void proxyAuthenticationRequired(const QNetworkProxy &proxy,
|
||||
void proxyAuthenticationRequired(const QUrl &url,
|
||||
const QNetworkProxy &proxy,
|
||||
bool synchronous,
|
||||
QAuthenticator *authenticator,
|
||||
QNetworkProxy *lastProxyAuthentication);
|
||||
|
@ -975,6 +975,9 @@ void QNetworkReplyHttpImplPrivate::initCacheSaveDevice()
|
||||
|
||||
cacheSaveDevice = managerPrivate->networkCache->prepare(metaData);
|
||||
|
||||
if (cacheSaveDevice)
|
||||
q->connect(cacheSaveDevice, SIGNAL(aboutToClose()), SLOT(_q_cacheSaveDeviceAboutToClose()));
|
||||
|
||||
if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) {
|
||||
if (cacheSaveDevice && !cacheSaveDevice->isOpen())
|
||||
qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- "
|
||||
@ -1220,7 +1223,7 @@ void QNetworkReplyHttpImplPrivate::httpAuthenticationRequired(const QHttpNetwork
|
||||
void QNetworkReplyHttpImplPrivate::proxyAuthenticationRequired(const QNetworkProxy &proxy,
|
||||
QAuthenticator *authenticator)
|
||||
{
|
||||
managerPrivate->proxyAuthenticationRequired(proxy, synchronous, authenticator, &lastProxyAuthentication);
|
||||
managerPrivate->proxyAuthenticationRequired(request.url(), proxy, synchronous, authenticator, &lastProxyAuthentication);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1708,6 +1711,13 @@ void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingDataFinished()
|
||||
QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void QNetworkReplyHttpImplPrivate::_q_cacheSaveDeviceAboutToClose()
|
||||
{
|
||||
// do not keep a dangling pointer to the device around (device
|
||||
// is closing because e.g. QAbstractNetworkCache::remove() was called).
|
||||
cacheSaveDevice = 0;
|
||||
}
|
||||
|
||||
void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData()
|
||||
{
|
||||
Q_Q(QNetworkReplyHttpImpl);
|
||||
|
@ -130,6 +130,7 @@ public:
|
||||
Q_PRIVATE_SLOT(d_func(), void wantUploadDataSlot(qint64))
|
||||
Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64))
|
||||
Q_PRIVATE_SLOT(d_func(), void emitReplyUploadProgress(qint64, qint64))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_cacheSaveDeviceAboutToClose())
|
||||
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
@ -179,6 +180,8 @@ public:
|
||||
void _q_bufferOutgoingData();
|
||||
void _q_bufferOutgoingDataFinished();
|
||||
|
||||
void _q_cacheSaveDeviceAboutToClose();
|
||||
|
||||
#ifndef QT_NO_BEARERMANAGEMENT
|
||||
void _q_networkSessionConnected();
|
||||
void _q_networkSessionFailed();
|
||||
|
@ -90,6 +90,7 @@ public:
|
||||
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value);
|
||||
void setRawHeader(const QByteArray &headerName, const QByteArray &value);
|
||||
void setError(QNetworkReply::NetworkError errorCode, const QString &errorString);
|
||||
void setAttribute(QNetworkRequest::Attribute code, const QVariant &value);
|
||||
};
|
||||
|
||||
@interface QtNSURLConnectionDelegate : NSObject
|
||||
@ -140,6 +141,7 @@ QNetworkReplyNSURLConnectionImplPrivate::~QNetworkReplyNSURLConnectionImplPrivat
|
||||
void QNetworkReplyNSURLConnectionImplPrivate::setFinished()
|
||||
{
|
||||
q_func()->setFinished(true);
|
||||
QMetaObject::invokeMethod(q_func(), "finished", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void QNetworkReplyNSURLConnectionImplPrivate::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
|
||||
@ -157,6 +159,11 @@ void QNetworkReplyNSURLConnectionImplPrivate::setError(QNetworkReply::NetworkErr
|
||||
q_func()->setError(errorCode, errorString);
|
||||
}
|
||||
|
||||
void QNetworkReplyNSURLConnectionImplPrivate::setAttribute(QNetworkRequest::Attribute code, const QVariant &value)
|
||||
{
|
||||
q_func()->setAttribute(code, value);
|
||||
}
|
||||
|
||||
void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData()
|
||||
{
|
||||
Q_D(QNetworkReplyNSURLConnectionImpl);
|
||||
@ -269,6 +276,9 @@ void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData()
|
||||
NSString *value = [headers objectForKey:key];
|
||||
replyprivate->setRawHeader(QString::fromNSString(key).toUtf8(), QString::fromNSString(value).toUtf8());
|
||||
}
|
||||
|
||||
int code = [httpResponse statusCode];
|
||||
replyprivate->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, code);
|
||||
} else {
|
||||
if ([aResponse expectedContentLength] != NSURLResponseUnknownLength)
|
||||
replyprivate->setHeader(QNetworkRequest::ContentLengthHeader, [aResponse expectedContentLength]);
|
||||
@ -317,8 +327,7 @@ void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData()
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
|
||||
{
|
||||
Q_UNUSED(connection)
|
||||
replyprivate->setFinished();
|
||||
QMetaObject::invokeMethod(replyprivate->q_func(), "finished", Qt::QueuedConnection);
|
||||
replyprivate->setFinished();
|
||||
}
|
||||
|
||||
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection
|
||||
|
@ -160,9 +160,11 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
|
||||
Q_CHECK_PTR(ns);
|
||||
state._u._ext.nsaddrs[0] = ns;
|
||||
}
|
||||
#ifndef __UCLIBC__
|
||||
// Set nsmap[] to indicate that nsaddrs[0] is an IPv6 address
|
||||
// See: https://sourceware.org/ml/libc-hacker/2002-05/msg00035.html
|
||||
state._u._ext.nsmap[0] = MAXNS + 1;
|
||||
#endif
|
||||
state._u._ext.nscount6 = 1;
|
||||
ns->sin6_family = AF_INET6;
|
||||
ns->sin6_port = htons(53);
|
||||
@ -370,11 +372,11 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
|
||||
void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
|
||||
{
|
||||
Q_UNUSED(requestType)
|
||||
Q_UNUSED(requestName)
|
||||
Q_UNUSED(nameserver)
|
||||
reply->error = QDnsLookup::ResolverError;
|
||||
reply->errorString = tr("Resolver library can't be loaded: No runtime library loading support");
|
||||
return;
|
||||
|
@ -85,7 +85,7 @@ public:
|
||||
explicit QHostAddress(quint32 ip4Addr);
|
||||
explicit QHostAddress(quint8 *ip6Addr);
|
||||
explicit QHostAddress(const Q_IPV6ADDR &ip6Addr);
|
||||
explicit QHostAddress(const sockaddr *sockaddr);
|
||||
explicit QHostAddress(const sockaddr *address);
|
||||
explicit QHostAddress(const QString &address);
|
||||
QHostAddress(const QHostAddress ©);
|
||||
QHostAddress(SpecialAddress address);
|
||||
@ -97,7 +97,7 @@ public:
|
||||
void setAddress(quint32 ip4Addr);
|
||||
void setAddress(quint8 *ip6Addr);
|
||||
void setAddress(const Q_IPV6ADDR &ip6Addr);
|
||||
void setAddress(const sockaddr *sockaddr);
|
||||
void setAddress(const sockaddr *address);
|
||||
bool setAddress(const QString &address);
|
||||
|
||||
QAbstractSocket::NetworkLayerProtocol protocol() const;
|
||||
|
@ -53,6 +53,7 @@
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <winsock2.h>
|
||||
#include <qt_windows.h>
|
||||
#include <time.h>
|
||||
|
@ -202,7 +202,17 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize)
|
||||
if (!maxSize)
|
||||
return 0;
|
||||
|
||||
return d->pipeReader->read(data, maxSize);
|
||||
qint64 ret = d->pipeReader->read(data, maxSize);
|
||||
|
||||
// QWindowsPipeReader::read() returns error codes that don't match what we need
|
||||
switch (ret) {
|
||||
case 0: // EOF -> transform to error
|
||||
return -1;
|
||||
case -2: // EWOULDBLOCK -> no error, just no bytes
|
||||
return 0;
|
||||
default:
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
qint64 QLocalSocket::writeData(const char *data, qint64 maxSize)
|
||||
|
@ -246,8 +246,11 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::
|
||||
d->tcp = handler->pendingTcpSockets.take(socketDescriptor);
|
||||
d->socketType = QAbstractSocket::TcpSocket;
|
||||
|
||||
if (!d->tcp || !d->fetchConnectionParameters())
|
||||
if (!d->tcp || !d->fetchConnectionParameters()) {
|
||||
d->setError(QAbstractSocket::UnsupportedSocketOperationError,
|
||||
d->InvalidSocketErrorString);
|
||||
return false;
|
||||
}
|
||||
|
||||
d->socketState = socketState;
|
||||
return true;
|
||||
@ -475,9 +478,9 @@ void QNativeSocketEngine::close()
|
||||
Q_D(QNativeSocketEngine);
|
||||
if (d->socketDescriptor != -1) {
|
||||
ComPtr<IClosable> socket;
|
||||
if (d->socketType == QAbstractSocket::TcpSocket)
|
||||
if (d->socketType == QAbstractSocket::TcpSocket && d->tcp)
|
||||
d->tcp.As(&socket);
|
||||
else if (d->socketType == QAbstractSocket::UdpSocket)
|
||||
else if (d->socketType == QAbstractSocket::UdpSocket && d->udp)
|
||||
d->udp.As(&socket);
|
||||
|
||||
if (socket) {
|
||||
|
@ -153,6 +153,8 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData()
|
||||
{
|
||||
QList<QByteArray> certificateData;
|
||||
@ -177,3 +179,5 @@ QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData()
|
||||
|
||||
return certificateData;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -84,32 +84,22 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay
|
||||
int visualRedSize = qPopulationCount(chosenVisualInfo->red_mask);
|
||||
int visualGreenSize = qPopulationCount(chosenVisualInfo->green_mask);
|
||||
int visualBlueSize = qPopulationCount(chosenVisualInfo->blue_mask);
|
||||
int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size
|
||||
int visualAlphaSize = chosenVisualInfo->depth == 32 ? 8 : 0;
|
||||
|
||||
bool visualMatchesConfig = false;
|
||||
if ( visualRedSize == configRedSize &&
|
||||
visualGreenSize == configGreenSize &&
|
||||
visualBlueSize == configBlueSize )
|
||||
{
|
||||
// We need XRender to check the alpha channel size of the visual. If we don't have
|
||||
// the alpha size, we don't check it against the EGL config's alpha size.
|
||||
if (visualAlphaSize >= 0)
|
||||
visualMatchesConfig = visualAlphaSize == configAlphaSize;
|
||||
else
|
||||
visualMatchesConfig = true;
|
||||
}
|
||||
const bool visualMatchesConfig = visualRedSize == configRedSize
|
||||
&& visualGreenSize == configGreenSize
|
||||
&& visualBlueSize == configBlueSize
|
||||
&& visualAlphaSize == configAlphaSize;
|
||||
|
||||
// In some cases EGL tends to suggest a 24-bit visual for 8888
|
||||
// configs. In such a case we have to fall back to XGetVisualInfo.
|
||||
if (!visualMatchesConfig) {
|
||||
if (visualAlphaSize >= 0) {
|
||||
qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable",
|
||||
(int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize,
|
||||
configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize);
|
||||
} else {
|
||||
qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable",
|
||||
(int)visualId, visualRedSize, visualGreenSize, visualBlueSize,
|
||||
configId, configRedSize, configGreenSize, configBlueSize);
|
||||
}
|
||||
visualId = 0;
|
||||
#ifdef QT_DEBUG_X11_VISUAL_SELECTION
|
||||
qWarning("Warning: EGL suggested using X Visual ID %d (%d %d %d depth %d) for EGL config %d (%d %d %d %d), but this is incompatible",
|
||||
(int)visualId, visualRedSize, visualGreenSize, visualBlueSize, chosenVisualInfo->depth,
|
||||
configId, configRedSize, configGreenSize, configBlueSize, configAlphaSize);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID",
|
||||
@ -133,8 +123,7 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay
|
||||
return visualId;
|
||||
}
|
||||
|
||||
// Finally, try to
|
||||
// use XGetVisualInfo and only use the bit depths to match on:
|
||||
// Finally, try to use XGetVisualInfo and only use the bit depths to match on:
|
||||
if (!visualId) {
|
||||
XVisualInfo visualInfoTemplate;
|
||||
memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
|
||||
|
@ -517,6 +517,8 @@ void ICOReader::read16_24_32BMP(QImage & image)
|
||||
}
|
||||
}
|
||||
|
||||
static const char icoOrigDepthKey[] = "_q_icoOrigDepth";
|
||||
|
||||
QImage ICOReader::iconAt(int index)
|
||||
{
|
||||
QImage img;
|
||||
@ -535,7 +537,9 @@ QImage ICOReader::iconAt(int index)
|
||||
|
||||
if (isPngImage) {
|
||||
iod->seek(iconEntry.dwImageOffset);
|
||||
return QImage::fromData(iod->read(iconEntry.dwBytesInRes), "png");
|
||||
QImage image = QImage::fromData(iod->read(iconEntry.dwBytesInRes), "png");
|
||||
image.setText(QLatin1String(icoOrigDepthKey), QString::number(iconEntry.wBitCount));
|
||||
return image;
|
||||
}
|
||||
|
||||
BMP_INFOHDR header;
|
||||
@ -598,6 +602,7 @@ QImage ICOReader::iconAt(int index)
|
||||
}
|
||||
}
|
||||
}
|
||||
img.setText(QLatin1String(icoOrigDepthKey), QString::number(iconEntry.wBitCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,21 +111,17 @@ void TableGenerator::findComposeFile()
|
||||
}
|
||||
// check for the system provided compose files
|
||||
if (!found && cleanState()) {
|
||||
QByteArray loc = locale().toUpper().toUtf8();
|
||||
QString table = readLocaleMappings(loc);
|
||||
if (table.isEmpty())
|
||||
table = readLocaleMappings(readLocaleAliases(loc));
|
||||
|
||||
QString table = composeTableForLocale();
|
||||
if (cleanState()) {
|
||||
if (table.isEmpty())
|
||||
// no table mappings for the system's locale in the compose.dir
|
||||
m_state = UnsupportedLocale;
|
||||
else
|
||||
found = processFile(systemComposeDir() + QLatin1String("/") + table);
|
||||
found = processFile(systemComposeDir() + QLatin1Char('/') + table);
|
||||
#ifdef DEBUG_GENERATOR
|
||||
if (found)
|
||||
qDebug() << "Using Compose file from: " <<
|
||||
systemComposeDir() + QLatin1String("/") + table;
|
||||
systemComposeDir() + QLatin1Char('/') + table;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -137,6 +133,15 @@ void TableGenerator::findComposeFile()
|
||||
m_state = MissingComposeFile;
|
||||
}
|
||||
|
||||
QString TableGenerator::composeTableForLocale()
|
||||
{
|
||||
QByteArray loc = locale().toUpper().toUtf8();
|
||||
QString table = readLocaleMappings(loc);
|
||||
if (table.isEmpty())
|
||||
table = readLocaleMappings(readLocaleAliases(loc));
|
||||
return table;
|
||||
}
|
||||
|
||||
bool TableGenerator::findSystemComposeDir()
|
||||
{
|
||||
bool found = false;
|
||||
@ -311,7 +316,7 @@ void TableGenerator::parseIncludeInstruction(QString line)
|
||||
|
||||
// expand substitutions if present
|
||||
line.replace(QLatin1String("%H"), QString(qgetenv("HOME")));
|
||||
line.replace(QLatin1String("%L"), locale());
|
||||
line.replace(QLatin1String("%L"), systemComposeDir() + QLatin1Char('/') + composeTableForLocale());
|
||||
line.replace(QLatin1String("%S"), systemComposeDir());
|
||||
|
||||
processFile(line);
|
||||
|
@ -118,13 +118,14 @@ protected:
|
||||
void findComposeFile();
|
||||
bool findSystemComposeDir();
|
||||
QString systemComposeDir();
|
||||
QString composeTableForLocale();
|
||||
|
||||
ushort keysymToUtf8(quint32 sym);
|
||||
|
||||
QString readLocaleMappings(const QByteArray &locale);
|
||||
QByteArray readLocaleAliases(const QByteArray &locale);
|
||||
void initPossibleLocations();
|
||||
bool cleanState() const { return ((m_state & NoErrors) == NoErrors); }
|
||||
bool cleanState() const { return m_state == NoErrors; }
|
||||
QString locale() const;
|
||||
|
||||
private:
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "qrect.h"
|
||||
#include "QtGui/qaccessible.h"
|
||||
#include <QtCore/qmath.h>
|
||||
#include <QtCore/private/qjnihelpers_p.h>
|
||||
|
||||
#include "qdebug.h"
|
||||
|
||||
@ -56,6 +57,8 @@ static const char m_qtTag[] = "Qt A11Y";
|
||||
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
|
||||
static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtAndroidAccessibility
|
||||
{
|
||||
static jmethodID m_addActionMethodID = 0;
|
||||
@ -227,7 +230,7 @@ if (!clazz) { \
|
||||
if (desc.isEmpty())
|
||||
desc = iface->text(QAccessible::Description);
|
||||
if (QAccessibleTextInterface *textIface = iface->textInterface()) {
|
||||
if (textIface->selectionCount() > 0) {
|
||||
if (m_setTextSelectionMethodID && textIface->selectionCount() > 0) {
|
||||
int startSelection;
|
||||
int endSelection;
|
||||
textIface->selection(0, &startSelection, &endSelection);
|
||||
@ -286,12 +289,15 @@ if (!clazz) { \
|
||||
|
||||
bool registerNatives(JNIEnv *env)
|
||||
{
|
||||
if (QtAndroidPrivate::androidSdkVersion() < 16)
|
||||
return true; // We need API level 16 or higher
|
||||
|
||||
jclass clazz;
|
||||
FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/accessibility/QtNativeAccessibility");
|
||||
jclass appClass = static_cast<jclass>(env->NewGlobalRef(clazz));
|
||||
|
||||
if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
|
||||
__android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
|
||||
__android_log_print(ANDROID_LOG_FATAL,"Qt A11y", "RegisterNatives failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -305,9 +311,14 @@ if (!clazz) { \
|
||||
GET_AND_CHECK_STATIC_METHOD(m_setFocusableMethodID, nodeInfoClass, "setFocusable", "(Z)V");
|
||||
GET_AND_CHECK_STATIC_METHOD(m_setFocusedMethodID, nodeInfoClass, "setFocused", "(Z)V");
|
||||
GET_AND_CHECK_STATIC_METHOD(m_setScrollableMethodID, nodeInfoClass, "setScrollable", "(Z)V");
|
||||
GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
|
||||
GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V");
|
||||
|
||||
if (QtAndroidPrivate::androidSdkVersion() >= 18) {
|
||||
GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -42,10 +42,15 @@
|
||||
#ifndef ANDROIDJNIACCESSIBILITY_H
|
||||
#define ANDROIDJNIACCESSIBILITY_H
|
||||
#include <jni.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtAndroidAccessibility
|
||||
{
|
||||
bool registerNatives(JNIEnv *env);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // ANDROIDJNIINPUT_H
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "androidjniclipboard.h"
|
||||
#include "androidjnimain.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QtAndroid;
|
||||
namespace QtAndroidClipboard
|
||||
{
|
||||
@ -118,3 +120,5 @@ namespace QtAndroidClipboard
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -45,6 +45,8 @@
|
||||
#include <jni.h>
|
||||
#include <QString>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAndroidPlatformClipboard;
|
||||
namespace QtAndroidClipboard
|
||||
{
|
||||
@ -58,4 +60,6 @@ namespace QtAndroidClipboard
|
||||
bool registerNatives(JNIEnv *env);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // ANDROIDJNICLIPBOARD_H
|
||||
|
@ -49,6 +49,8 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QtAndroid;
|
||||
|
||||
namespace QtAndroidInput
|
||||
@ -758,3 +760,5 @@ namespace QtAndroidInput
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -42,6 +42,9 @@
|
||||
#ifndef ANDROIDJNIINPUT_H
|
||||
#define ANDROIDJNIINPUT_H
|
||||
#include <jni.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtAndroidInput
|
||||
{
|
||||
@ -56,4 +59,6 @@ namespace QtAndroidInput
|
||||
bool registerNatives(JNIEnv *env);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // ANDROIDJNIINPUT_H
|
||||
|
@ -76,6 +76,8 @@
|
||||
|
||||
Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static JavaVM *m_javaVM = NULL;
|
||||
static jclass m_applicationClass = NULL;
|
||||
static jobject m_classLoaderObject = NULL;
|
||||
@ -423,6 +425,7 @@ namespace QtAndroid
|
||||
m_destroySurfaceMethodID,
|
||||
surfaceId);
|
||||
}
|
||||
|
||||
} // namespace QtAndroid
|
||||
|
||||
|
||||
@ -548,7 +551,7 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface,
|
||||
}
|
||||
|
||||
static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
|
||||
jint /*widthPixels*/, jint /*heightPixels*/,
|
||||
jint widthPixels, jint heightPixels,
|
||||
jint desktopWidthPixels, jint desktopHeightPixels,
|
||||
jdouble xdpi, jdouble ydpi, jdouble scaledDensity)
|
||||
{
|
||||
@ -557,13 +560,17 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
|
||||
m_scaledDensity = scaledDensity;
|
||||
|
||||
if (!m_androidPlatformIntegration) {
|
||||
QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels,desktopHeightPixels,
|
||||
qRound(double(desktopWidthPixels) / xdpi * 25.4),
|
||||
qRound(double(desktopHeightPixels) / ydpi * 25.4));
|
||||
QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels,
|
||||
desktopHeightPixels,
|
||||
qRound(double(desktopWidthPixels) / xdpi * 25.4),
|
||||
qRound(double(desktopHeightPixels) / ydpi * 25.4),
|
||||
widthPixels,
|
||||
heightPixels);
|
||||
} else {
|
||||
m_androidPlatformIntegration->setDisplayMetrics(qRound(double(desktopWidthPixels) / xdpi * 25.4),
|
||||
qRound(double(desktopHeightPixels) / ydpi * 25.4));
|
||||
m_androidPlatformIntegration->setDesktopSize(desktopWidthPixels, desktopHeightPixels);
|
||||
m_androidPlatformIntegration->setScreenSize(widthPixels, heightPixels);
|
||||
}
|
||||
}
|
||||
|
||||
@ -743,17 +750,11 @@ static int registerNatives(JNIEnv *env)
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
jint androidApiLevel(JNIEnv *env)
|
||||
{
|
||||
jclass clazz;
|
||||
FIND_AND_CHECK_CLASS("android/os/Build$VERSION");
|
||||
jfieldID fieldId;
|
||||
GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "SDK_INT", "I");
|
||||
return env->GetStaticIntField(clazz, fieldId);
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|
||||
{
|
||||
QT_USE_NAMESPACE
|
||||
typedef union {
|
||||
JNIEnv *nativeEnvironment;
|
||||
void *venv;
|
||||
@ -774,17 +775,12 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|
||||
|| !QtAndroidInput::registerNatives(env)
|
||||
|| !QtAndroidClipboard::registerNatives(env)
|
||||
|| !QtAndroidMenu::registerNatives(env)
|
||||
|| !QtAndroidAccessibility::registerNatives(env)
|
||||
|| !QtAndroidDialogHelpers::registerNatives(env)) {
|
||||
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
jint apiLevel = androidApiLevel(env);
|
||||
if (apiLevel >= 16 && !QtAndroidAccessibility::registerNatives(env)) {
|
||||
__android_log_print(ANDROID_LOG_FATAL, "Qt A11y", "registerNatives failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_javaVM = vm;
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user