1 // This is the implementation of the QPyQuickFramebufferObject classes.
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 <QQmlListProperty>
24 
25 #include "qpyquickframebufferobject.h"
26 
27 #include "sipAPIQtQuick.h"
28 
29 
30 #if QT_VERSION >= 0x050200
31 
32 // The maximum number of Python QQuickFramebufferObject types.
33 const int NrOfQuickFramebufferObjectTypes = 30;
34 
35 // The list of registered Python types.
36 static QList<PyTypeObject *> pyqt_types;
37 
38 // The registration data for the canned types.
39 static QQmlPrivate::RegisterType canned_types[NrOfQuickFramebufferObjectTypes];
40 
41 // External declarations.
42 extern const QMetaObject *qpyquick_pick_metaobject(const QMetaObject *super_mo,
43         const QMetaObject *static_mo);
44 
45 
46 #define QPYQUICKFRAMEBUFFEROBJECT_INIT(n) \
47     case n##U: \
48         QPyQuickFramebufferObject##n::staticMetaObject = *mo; \
49         rt->typeId = qRegisterNormalizedMetaType<QPyQuickFramebufferObject##n *>(ptr_name.constData()); \
50         rt->listId = qRegisterNormalizedMetaType<QQmlListProperty<QPyQuickFramebufferObject##n> >(list_name.constData()); \
51         rt->objectSize = sizeof(QPyQuickFramebufferObject##n); \
52         rt->create = QQmlPrivate::createInto<QPyQuickFramebufferObject##n>; \
53         rt->metaObject = mo; \
54         rt->attachedPropertiesFunction = QQmlPrivate::attachedPropertiesFunc<QPyQuickFramebufferObject##n>(); \
55         rt->attachedPropertiesMetaObject = QQmlPrivate::attachedPropertiesMetaObject<QPyQuickFramebufferObject##n>(); \
56         rt->parserStatusCast = QQmlPrivate::StaticCastSelector<QPyQuickFramebufferObject##n,QQmlParserStatus>::cast(); \
57         rt->valueSourceCast = QQmlPrivate::StaticCastSelector<QPyQuickFramebufferObject##n,QQmlPropertyValueSource>::cast(); \
58         rt->valueInterceptorCast = QQmlPrivate::StaticCastSelector<QPyQuickFramebufferObject##n,QQmlPropertyValueInterceptor>::cast(); \
59         break
60 
61 
62 // The ctor.
QPyQuickFramebufferObject(QQuickItem * parent)63 QPyQuickFramebufferObject::QPyQuickFramebufferObject(QQuickItem *parent)
64         : sipQQuickFramebufferObject(parent)
65 {
66 }
67 
68 
69 // Add a new Python type and return its number.
addType(PyTypeObject * type,const QMetaObject * mo,const QByteArray & ptr_name,const QByteArray & list_name)70 QQmlPrivate::RegisterType *QPyQuickFramebufferObject::addType(
71         PyTypeObject *type, const QMetaObject *mo, const QByteArray &ptr_name,
72         const QByteArray &list_name)
73 {
74     int type_nr = pyqt_types.size();
75 
76     // Check we have a spare canned type.
77     if (type_nr >= NrOfQuickFramebufferObjectTypes)
78     {
79         PyErr_Format(PyExc_TypeError,
80                 "a maximum of %d QQuickFramebufferObject types may be registered with QML",
81                 NrOfQuickFramebufferObjectTypes);
82         return 0;
83     }
84 
85     pyqt_types.append(type);
86 
87     QQmlPrivate::RegisterType *rt = &canned_types[type_nr];
88 
89     // Initialise those members that depend on the C++ type.
90     switch (type_nr)
91     {
92         QPYQUICKFRAMEBUFFEROBJECT_INIT(0);
93         QPYQUICKFRAMEBUFFEROBJECT_INIT(1);
94         QPYQUICKFRAMEBUFFEROBJECT_INIT(2);
95         QPYQUICKFRAMEBUFFEROBJECT_INIT(3);
96         QPYQUICKFRAMEBUFFEROBJECT_INIT(4);
97         QPYQUICKFRAMEBUFFEROBJECT_INIT(5);
98         QPYQUICKFRAMEBUFFEROBJECT_INIT(6);
99         QPYQUICKFRAMEBUFFEROBJECT_INIT(7);
100         QPYQUICKFRAMEBUFFEROBJECT_INIT(8);
101         QPYQUICKFRAMEBUFFEROBJECT_INIT(9);
102         QPYQUICKFRAMEBUFFEROBJECT_INIT(10);
103         QPYQUICKFRAMEBUFFEROBJECT_INIT(11);
104         QPYQUICKFRAMEBUFFEROBJECT_INIT(12);
105         QPYQUICKFRAMEBUFFEROBJECT_INIT(13);
106         QPYQUICKFRAMEBUFFEROBJECT_INIT(14);
107         QPYQUICKFRAMEBUFFEROBJECT_INIT(15);
108         QPYQUICKFRAMEBUFFEROBJECT_INIT(16);
109         QPYQUICKFRAMEBUFFEROBJECT_INIT(17);
110         QPYQUICKFRAMEBUFFEROBJECT_INIT(18);
111         QPYQUICKFRAMEBUFFEROBJECT_INIT(19);
112         QPYQUICKFRAMEBUFFEROBJECT_INIT(20);
113         QPYQUICKFRAMEBUFFEROBJECT_INIT(21);
114         QPYQUICKFRAMEBUFFEROBJECT_INIT(22);
115         QPYQUICKFRAMEBUFFEROBJECT_INIT(23);
116         QPYQUICKFRAMEBUFFEROBJECT_INIT(24);
117         QPYQUICKFRAMEBUFFEROBJECT_INIT(25);
118         QPYQUICKFRAMEBUFFEROBJECT_INIT(26);
119         QPYQUICKFRAMEBUFFEROBJECT_INIT(27);
120         QPYQUICKFRAMEBUFFEROBJECT_INIT(28);
121         QPYQUICKFRAMEBUFFEROBJECT_INIT(29);
122     }
123 
124     return rt;
125 }
126 
127 
128 // Create the Python instance.
createPyObject(QQuickItem * parent)129 void QPyQuickFramebufferObject::createPyObject(QQuickItem *parent)
130 {
131     SIP_BLOCK_THREADS
132 
133     // Assume C++ owns everything.
134     PyObject *obj = sipConvertFromNewPyType(this, pyqt_types.at(typeNr()),
135             NULL, &sipPySelf, "D", parent, sipType_QQuickItem, NULL);
136 
137     if (!obj)
138         pyqt5_qtquick_err_print();
139 
140     SIP_UNBLOCK_THREADS
141 }
142 
143 
144 // The canned type implementations.
145 #define QPYQUICKFRAMEBUFFEROBJECT_IMPL(n) \
146 QPyQuickFramebufferObject##n::QPyQuickFramebufferObject##n(QQuickItem *parent) : QPyQuickFramebufferObject(parent) \
147 { \
148     createPyObject(parent); \
149 } \
150 const QMetaObject *QPyQuickFramebufferObject##n::metaObject() const \
151 { \
152     return qpyquick_pick_metaobject(QPyQuickFramebufferObject::metaObject(), &staticMetaObject); \
153 } \
154 QMetaObject QPyQuickFramebufferObject##n::staticMetaObject
155 
156 
157 QPYQUICKFRAMEBUFFEROBJECT_IMPL(0);
158 QPYQUICKFRAMEBUFFEROBJECT_IMPL(1);
159 QPYQUICKFRAMEBUFFEROBJECT_IMPL(2);
160 QPYQUICKFRAMEBUFFEROBJECT_IMPL(3);
161 QPYQUICKFRAMEBUFFEROBJECT_IMPL(4);
162 QPYQUICKFRAMEBUFFEROBJECT_IMPL(5);
163 QPYQUICKFRAMEBUFFEROBJECT_IMPL(6);
164 QPYQUICKFRAMEBUFFEROBJECT_IMPL(7);
165 QPYQUICKFRAMEBUFFEROBJECT_IMPL(8);
166 QPYQUICKFRAMEBUFFEROBJECT_IMPL(9);
167 QPYQUICKFRAMEBUFFEROBJECT_IMPL(10);
168 QPYQUICKFRAMEBUFFEROBJECT_IMPL(11);
169 QPYQUICKFRAMEBUFFEROBJECT_IMPL(12);
170 QPYQUICKFRAMEBUFFEROBJECT_IMPL(13);
171 QPYQUICKFRAMEBUFFEROBJECT_IMPL(14);
172 QPYQUICKFRAMEBUFFEROBJECT_IMPL(15);
173 QPYQUICKFRAMEBUFFEROBJECT_IMPL(16);
174 QPYQUICKFRAMEBUFFEROBJECT_IMPL(17);
175 QPYQUICKFRAMEBUFFEROBJECT_IMPL(18);
176 QPYQUICKFRAMEBUFFEROBJECT_IMPL(19);
177 QPYQUICKFRAMEBUFFEROBJECT_IMPL(20);
178 QPYQUICKFRAMEBUFFEROBJECT_IMPL(21);
179 QPYQUICKFRAMEBUFFEROBJECT_IMPL(22);
180 QPYQUICKFRAMEBUFFEROBJECT_IMPL(23);
181 QPYQUICKFRAMEBUFFEROBJECT_IMPL(24);
182 QPYQUICKFRAMEBUFFEROBJECT_IMPL(25);
183 QPYQUICKFRAMEBUFFEROBJECT_IMPL(26);
184 QPYQUICKFRAMEBUFFEROBJECT_IMPL(27);
185 QPYQUICKFRAMEBUFFEROBJECT_IMPL(28);
186 QPYQUICKFRAMEBUFFEROBJECT_IMPL(29);
187 
188 #endif
189