1 // This is the implementatation of an embedded qt.conf file.
2 //
3 // Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
4 //
5 // This file is part of PyQt5.
6 //
7 // This file may be used under the terms of the GNU General Public License
8 // version 3.0 as published by the Free Software Foundation and appearing in
9 // the file LICENSE included in the packaging of this file. Please review the
10 // following information to ensure the GNU General Public License version 3.0
11 // requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 //
13 // If you do not wish to use this file under the terms of the GPL version 3.0
14 // then you may purchase a commercial license. For more information contact
15 // info@riverbankcomputing.com.
16 //
17 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19
20
21 #include <Python.h>
22
23 #include <QByteArray>
24 #include <QDir>
25 #include <QFileInfo>
26 #include <QLatin1String>
27
28 #include "qpycore_api.h"
29
30
31 static const unsigned char qt_resource_name[] = {
32 // qt
33 0x0,0x2,
34 0x0,0x0,0x7,0x84,
35 0x0,0x71,
36 0x0,0x74,
37 // etc
38 0x0,0x3,
39 0x0,0x0,0x6c,0xa3,
40 0x0,0x65,
41 0x0,0x74,0x0,0x63,
42 // qt.conf
43 0x0,0x7,
44 0x8,0x74,0xa6,0xa6,
45 0x0,0x71,
46 0x0,0x74,0x0,0x2e,0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x66,
47
48 };
49
50 static const unsigned char qt_resource_struct[] = {
51 // :
52 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
53 // :/qt
54 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
55 // :/qt/etc
56 0x0,0x0,0x0,0xa,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,
57 // :/qt/etc/qt.conf
58 0x0,0x0,0x0,0x16,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
59
60 };
61
62
63 QT_BEGIN_NAMESPACE
64 bool qRegisterResourceData(int, const unsigned char *, const unsigned char *,
65 const unsigned char *);
66 QT_END_NAMESPACE
67
68
69 // Embed a qt.conf file.
qpycore_qt_conf()70 bool qpycore_qt_conf()
71 {
72 // Get PyQt5.__file__.
73 PyObject *pyqt5 = PyImport_ImportModule("PyQt5");
74
75 if (!pyqt5)
76 return false;
77
78 PyObject *init = PyObject_GetAttrString(pyqt5, "__file__");
79 Py_DECREF(pyqt5);
80
81 if (!init)
82 return false;
83
84 QString init_impl(qpycore_PyObject_AsQString(init));
85 Py_DECREF(init);
86
87 if (init_impl.isEmpty())
88 return false;
89
90 // Get the directory containing the PyQt5 extension modules.
91 QDir pyqt5_dir = QFileInfo(QDir::fromNativeSeparators(init_impl)).absoluteDir();
92 QString qt_dir_name = pyqt5_dir.absoluteFilePath(QLatin1String("Qt5"));
93
94 // Check if there is a bundled copy of Qt.
95 if (QFileInfo(qt_dir_name).exists())
96 {
97 // Get the prefix path with non-native separators.
98 static QByteArray qt_conf = qt_dir_name.toLocal8Bit();
99
100 qt_conf.prepend("[Paths]\nPrefix = ");
101 qt_conf.append("\n");
102
103 // Prepend the 4-byte size.
104 int size = qt_conf.size();
105
106 for (int i = 0; i < 4; ++i)
107 {
108 qt_conf.prepend(size & 0xff);
109 size >>= 8;
110 }
111
112 // Register the structures.
113 qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name,
114 (const unsigned char *)qt_conf.constData());
115 }
116
117 return true;
118 }
119