aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
Diffstat (limited to 'sources')
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_common.xml8
-rw-r--r--sources/pyside2/libpyside/CMakeLists.txt7
-rw-r--r--sources/pyside2/libpyside/pyside.cpp130
-rw-r--r--sources/pyside2/libpyside/pyside.h13
-rw-r--r--sources/pyside2/tests/CMakeLists.txt2
5 files changed, 155 insertions, 5 deletions
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
index 951d943ee..65f68882d 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
@@ -74,6 +74,10 @@
<function signature="qrand()" />
<function signature="qsrand(uint)" />
+ <inject-code class="native" position="beginning">
+ #include &lt;pyside.h&gt;
+ </inject-code>
+
<template name="use_stream_for_format_security">
// Uses the stream version for security reasons
// see gcc man page at -Wformat-security
@@ -1039,12 +1043,10 @@
Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "str");
Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QTCORE_QLIST_QVARIANT_IDX], "QVariantList");
+ PySide::registerInternalQtConf();
PySide::init(module);
Py_AtExit(QtCoreModuleExit);
</inject-code>
- <inject-code class="native" position="beginning">
- #include &lt;pyside.h&gt;
- </inject-code>
<inject-code class="native" position="beginning">
// Define a global variable to handle qInstallMessageHandler callback
diff --git a/sources/pyside2/libpyside/CMakeLists.txt b/sources/pyside2/libpyside/CMakeLists.txt
index 1cddebc07..de29269a4 100644
--- a/sources/pyside2/libpyside/CMakeLists.txt
+++ b/sources/pyside2/libpyside/CMakeLists.txt
@@ -111,6 +111,13 @@ if(QML_SUPPORT)
target_compile_definitions(pyside2 PUBLIC PYSIDE_QML_SUPPORT=1)
endif()
+if(PYSIDE_QT_CONF_PREFIX)
+ set_property(SOURCE pyside.cpp
+ APPEND
+ PROPERTY COMPILE_DEFINITIONS
+ PYSIDE_QT_CONF_PREFIX=${PYSIDE_QT_CONF_PREFIX})
+endif()
+
#
# install stuff
#
diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp
index 17366ce6e..b223edc6c 100644
--- a/sources/pyside2/libpyside/pyside.cpp
+++ b/sources/pyside2/libpyside/pyside.cpp
@@ -61,14 +61,20 @@
#include <typeinfo>
#include <cstring>
#include <cctype>
-#include <QStack>
+#include <QByteArray>
#include <QCoreApplication>
#include <QDebug>
+#include <QDir>
+#include <QFileInfo>
#include <QSharedPointer>
+#include <QStack>
static QStack<PySide::CleanupFunction> cleanupFunctionList;
static void* qobjectNextAddr;
+extern bool qRegisterResourceData(int, const unsigned char *, const unsigned char *,
+ const unsigned char *);
+
namespace PySide
{
@@ -387,5 +393,127 @@ void setQuickRegisterItemFunction(QuickRegisterItemFunction function)
}
#endif // PYSIDE_QML_SUPPORT
+// Inspired by Shiboken::String::toCString;
+QString pyStringToQString(PyObject *str) {
+ if (str == Py_None)
+ return QString();
+
+#ifdef IS_PY3K
+ if (PyUnicode_Check(str)) {
+ const char *unicodeBuffer = _PyUnicode_AsString(str);
+ if (unicodeBuffer)
+ return QString::fromUtf8(unicodeBuffer);
+ }
+#endif
+ if (PyBytes_Check(str)) {
+ const char *asciiBuffer = PyBytes_AS_STRING(str);
+ if (asciiBuffer)
+ return QString::fromLatin1(asciiBuffer);
+ }
+ return QString();
+}
+
+static const unsigned char qt_resource_name[] = {
+ // qt
+ 0x0,0x2,
+ 0x0,0x0,0x7,0x84,
+ 0x0,0x71,
+ 0x0,0x74,
+ // etc
+ 0x0,0x3,
+ 0x0,0x0,0x6c,0xa3,
+ 0x0,0x65,
+ 0x0,0x74,0x0,0x63,
+ // qt.conf
+ 0x0,0x7,
+ 0x8,0x74,0xa6,0xa6,
+ 0x0,0x71,
+ 0x0,0x74,0x0,0x2e,0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x66
+};
+
+static const unsigned char qt_resource_struct[] = {
+ // :
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
+ // :/qt
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
+ // :/qt/etc
+ 0x0,0x0,0x0,0xa,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,
+ // :/qt/etc/qt.conf
+ 0x0,0x0,0x0,0x16,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0
+};
+
+bool registerInternalQtConf()
+{
+ // Guard to ensure single registration.
+#ifdef PYSIDE_QT_CONF_PREFIX
+ static bool registrationAttempted = false;
+#else
+ static bool registrationAttempted = true;
+#endif
+ static bool isRegistered = false;
+ if (registrationAttempted)
+ return isRegistered;
+ registrationAttempted = true;
+
+ // Allow disabling the usage of the internal qt.conf. This is necessary for tests to work,
+ // because tests are executed before the package is installed, and thus the Prefix specified
+ // in qt.conf would point to a not yet existing location.
+ bool disableInternalQtConf =
+ qEnvironmentVariableIntValue("PYSIDE_DISABLE_INTERNAL_QT_CONF") > 0 ? true : false;
+ if (disableInternalQtConf) {
+ registrationAttempted = true;
+ return false;
+ }
+
+ PyObject *pysideModule = PyImport_ImportModule("PySide2");
+ if (!pysideModule)
+ return false;
+
+ // Querying __file__ should be done only for modules that have finished their initialization.
+ // Thus querying for the top-level PySide2 package works for us whenever any Qt-wrapped module
+ // is loaded.
+ PyObject *pysideInitFilePath = PyObject_GetAttrString(pysideModule, "__file__");
+ Py_DECREF(pysideModule);
+ if (!pysideInitFilePath)
+ return false;
+
+ QString initPath = pyStringToQString(pysideInitFilePath);
+ Py_DECREF(pysideInitFilePath);
+ if (initPath.isEmpty())
+ return false;
+
+ // pysideDir - absolute path to the directory containing the init file, which also contains
+ // the rest of the PySide2 modules.
+ // prefixPath - absolute path to the directory containing the installed Qt (prefix).
+ QDir pysideDir = QFileInfo(QDir::fromNativeSeparators(initPath)).absoluteDir();
+ QString setupPrefix;
+#ifdef PYSIDE_QT_CONF_PREFIX
+ setupPrefix = QStringLiteral(PYSIDE_QT_CONF_PREFIX);
+#endif
+ QString prefixPath = pysideDir.absoluteFilePath(setupPrefix);
+
+ // rccData needs to be static, otherwise when it goes out of scope, the Qt resource system
+ // will point to invalid memory.
+ static QByteArray rccData = QByteArray("[Paths]\nPrefix = ") + prefixPath.toLocal8Bit();
+ rccData.append('\n');
+
+ // The RCC data structure expects a 4-byte size value representing the actual data.
+ int size = rccData.size();
+
+ for (int i = 0; i < 4; ++i) {
+ rccData.prepend((size & 0xff));
+ size >>= 8;
+ }
+
+ const int version = 0x01;
+ isRegistered = qRegisterResourceData(version, qt_resource_struct, qt_resource_name,
+ reinterpret_cast<const unsigned char *>(
+ rccData.constData()));
+
+ return isRegistered;
+}
+
+
+
} //namespace PySide
diff --git a/sources/pyside2/libpyside/pyside.h b/sources/pyside2/libpyside/pyside.h
index 3619e2875..becb92208 100644
--- a/sources/pyside2/libpyside/pyside.h
+++ b/sources/pyside2/libpyside/pyside.h
@@ -150,6 +150,19 @@ PYSIDE_API QuickRegisterItemFunction getQuickRegisterItemFunction();
PYSIDE_API void setQuickRegisterItemFunction(QuickRegisterItemFunction function);
#endif // PYSIDE_QML_SUPPORT
+/**
+ * Given A PyObject repesenting ASCII or Unicode data, returns an equivalent QString.
+ */
+PYSIDE_API QString pyStringToQString(PyObject *str);
+
+/**
+ * Registers a dynamic "qt.conf" file with the Qt resource system.
+ *
+ * This is used in a standalone build, to inform QLibraryInfo of the Qt prefix (where Qt libraries
+ * are installed) so that plugins can be successfully loaded.
+ */
+PYSIDE_API bool registerInternalQtConf();
+
} //namespace PySide
diff --git a/sources/pyside2/tests/CMakeLists.txt b/sources/pyside2/tests/CMakeLists.txt
index 2b7e3b0e1..34a2e2501 100644
--- a/sources/pyside2/tests/CMakeLists.txt
+++ b/sources/pyside2/tests/CMakeLists.txt
@@ -43,7 +43,7 @@ else()
set_tests_properties(${TEST_NAME} PROPERTIES
TIMEOUT ${CTEST_TESTING_TIMEOUT}
WILL_FAIL ${EXPECT_TO_FAIL}
- ENVIRONMENT "PYTHONPATH=${TEST_PYTHONPATH};${LIBRARY_PATH_VAR}=${TEST_LIBRARY_PATH}")
+ ENVIRONMENT "PYTHONPATH=${TEST_PYTHONPATH};${LIBRARY_PATH_VAR}=${TEST_LIBRARY_PATH};PYSIDE_DISABLE_INTERNAL_QT_CONF=1")
endmacro()
add_subdirectory(pysidetest)