File indexing completed on 2025-02-02 05:18:49
0001 /* 0002 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #ifndef KWAYLAND_TOOLS_GENERATOR_H 0007 #define KWAYLAND_TOOLS_GENERATOR_H 0008 0009 #include <QMap> 0010 #include <QMutex> 0011 #include <QObject> 0012 #include <QThreadStorage> 0013 #include <QWaitCondition> 0014 #include <QXmlStreamReader> 0015 0016 class QTextStream; 0017 0018 namespace KWayland 0019 { 0020 namespace Tools 0021 { 0022 class Argument 0023 { 0024 public: 0025 explicit Argument(); 0026 explicit Argument(const QXmlStreamAttributes &attributes); 0027 ~Argument(); 0028 0029 enum class Type { 0030 Unknown, 0031 NewId, 0032 Destructor, 0033 Object, 0034 FileDescriptor, 0035 Fixed, 0036 Uint, 0037 Int, 0038 String, 0039 }; 0040 0041 QString name() const 0042 { 0043 return m_name; 0044 } 0045 Type type() const 0046 { 0047 return m_type; 0048 } 0049 bool isNullAllowed() const 0050 { 0051 return m_allowNull; 0052 } 0053 QString interface() const 0054 { 0055 return m_inteface; 0056 } 0057 QString typeAsQt() const; 0058 QString typeAsServerWl() const; 0059 0060 private: 0061 Type parseType(const QStringView type); 0062 QString m_name; 0063 Type m_type = Type::Unknown; 0064 bool m_allowNull = false; 0065 QString m_inteface; 0066 }; 0067 0068 class Request 0069 { 0070 public: 0071 explicit Request(); 0072 explicit Request(const QString &name); 0073 ~Request(); 0074 0075 void addArgument(const Argument &arg) 0076 { 0077 m_arguments << arg; 0078 } 0079 0080 QString name() const 0081 { 0082 return m_name; 0083 } 0084 0085 QList<Argument> arguments() const 0086 { 0087 return m_arguments; 0088 } 0089 0090 bool isDestructor() const 0091 { 0092 return m_destructor; 0093 } 0094 bool isFactory() const; 0095 0096 void markAsDestructor() 0097 { 0098 m_destructor = true; 0099 } 0100 0101 private: 0102 QString m_name; 0103 QList<Argument> m_arguments; 0104 bool m_destructor = false; 0105 }; 0106 0107 class Event 0108 { 0109 public: 0110 explicit Event(); 0111 explicit Event(const QString &name); 0112 ~Event(); 0113 0114 void addArgument(const Argument &arg) 0115 { 0116 m_arguments << arg; 0117 } 0118 0119 QString name() const 0120 { 0121 return m_name; 0122 } 0123 0124 QList<Argument> arguments() const 0125 { 0126 return m_arguments; 0127 } 0128 0129 private: 0130 QString m_name; 0131 QList<Argument> m_arguments; 0132 }; 0133 0134 class Interface 0135 { 0136 public: 0137 explicit Interface(); 0138 explicit Interface(const QXmlStreamAttributes &attributes); 0139 virtual ~Interface(); 0140 0141 void addRequest(const Request &request) 0142 { 0143 m_requests << request; 0144 } 0145 void addEvent(const Event &event) 0146 { 0147 m_events << event; 0148 } 0149 0150 QString name() const 0151 { 0152 return m_name; 0153 } 0154 quint32 version() const 0155 { 0156 return m_version; 0157 } 0158 QString kwaylandClientName() const 0159 { 0160 return m_clientName; 0161 } 0162 QString kwaylandServerName() const 0163 { 0164 return m_clientName + QStringLiteral("Interface"); 0165 } 0166 0167 QList<Request> requests() const 0168 { 0169 return m_requests; 0170 } 0171 0172 QList<Event> events() const 0173 { 0174 return m_events; 0175 } 0176 0177 void markAsGlobal() 0178 { 0179 m_global = true; 0180 } 0181 bool isGlobal() const 0182 { 0183 return m_global; 0184 } 0185 void setFactory(Interface *factory) 0186 { 0187 m_factory = factory; 0188 } 0189 Interface *factory() const 0190 { 0191 return m_factory; 0192 } 0193 0194 bool isUnstableInterface() const 0195 { 0196 return m_name.startsWith(QLatin1String("zwp")); 0197 } 0198 0199 private: 0200 QString m_name; 0201 QString m_clientName; 0202 quint32 m_version; 0203 QList<Request> m_requests; 0204 QList<Event> m_events; 0205 bool m_global = false; 0206 Interface *m_factory; 0207 }; 0208 0209 class Generator : public QObject 0210 { 0211 Q_OBJECT 0212 public: 0213 explicit Generator(QObject *parent = nullptr); 0214 ~Generator() override; 0215 0216 void setXmlFileName(const QString &name) 0217 { 0218 m_xmlFileName = name; 0219 } 0220 void setBaseFileName(const QString &name) 0221 { 0222 m_baseFileName = name; 0223 } 0224 void start(); 0225 0226 private: 0227 void generateCopyrightHeader(); 0228 void generateStartIncludeGuard(); 0229 void generateEndIncludeGuard(); 0230 void generateStartNamespace(); 0231 void generateEndNamespace(); 0232 void generateHeaderIncludes(); 0233 void generateCppIncludes(); 0234 void generatePrivateClass(const Interface &interface); 0235 void generateClientPrivateClass(const Interface &interface); 0236 void generateClientPrivateResourceClass(const Interface &interface); 0237 void generateClientPrivateGlobalClass(const Interface &interface); 0238 void generateServerPrivateGlobalClass(const Interface &interface); 0239 void generateServerPrivateResourceClass(const Interface &interface); 0240 void generateServerPrivateInterfaceClass(const Interface &interface); 0241 void generateServerPrivateGlobalCtorBindClass(const Interface &interface); 0242 void generateServerPrivateResourceCtorDtorClass(const Interface &interface); 0243 void generateServerPrivateCallbackDefinitions(const Interface &interface); 0244 void generateServerPrivateCallbackImpl(const Interface &interface); 0245 void generateClientCpp(const Interface &interface); 0246 void generateClass(const Interface &interface); 0247 void generateClientGlobalClass(const Interface &interface); 0248 void generateClientResourceClass(const Interface &interface); 0249 void generateServerGlobalClass(const Interface &interface); 0250 void generateServerGlobalClassUnstable(const Interface &interface); 0251 void generateServerResourceClass(const Interface &interface); 0252 void generateServerResourceClassUnstable(const Interface &interface); 0253 void generateClientClassQObjectDerived(const Interface &interface); 0254 void generateClientGlobalClassDoxy(const Interface &interface); 0255 void generateClientGlobalClassCtor(const Interface &interface); 0256 void generateClientGlobalClassSetup(const Interface &interface); 0257 void generateClientResourceClassSetup(const Interface &interface); 0258 void generateClientClassDtor(const Interface &interface); 0259 void generateClientClassReleaseDestroy(const Interface &interface); 0260 void generateClientClassStart(const Interface &interface); 0261 void generateClientClassCasts(const Interface &interface); 0262 void generateClientClassSignals(const Interface &interface); 0263 void generateClientClassDptr(const Interface &interface); 0264 void generateClientGlobalClassEnd(const Interface &interface); 0265 void generateClientResourceClassEnd(const Interface &interface); 0266 void generateClientClassRequests(const Interface &interface); 0267 void generateClientCppRequests(const Interface &interface); 0268 void generateWaylandForwardDeclarations(); 0269 void generateNamespaceForwardDeclarations(); 0270 void startParseXml(); 0271 void startAuthorNameProcess(); 0272 void startAuthorEmailProcess(); 0273 void startGenerateHeaderFile(); 0274 void startGenerateCppFile(); 0275 void startGenerateServerHeaderFile(); 0276 void startGenerateServerCppFile(); 0277 0278 void checkEnd(); 0279 0280 void parseProtocol(); 0281 Interface parseInterface(); 0282 Request parseRequest(); 0283 Event parseEvent(); 0284 0285 QString projectToName() const; 0286 0287 QThreadStorage<QTextStream *> m_stream; 0288 QString m_xmlFileName; 0289 enum class Project { 0290 Client, 0291 Server, 0292 }; 0293 QThreadStorage<Project> m_project; 0294 QString m_authorName; 0295 QString m_authorEmail; 0296 QString m_baseFileName; 0297 0298 QMutex m_mutex; 0299 QWaitCondition m_waitCondition; 0300 QXmlStreamReader m_xmlReader; 0301 QList<Interface> m_interfaces; 0302 0303 int m_finishedCounter = 0; 0304 }; 0305 0306 } 0307 } 0308 0309 #endif