4#include <QCoreApplication>
6#include <QXmlStreamReader>
22 struct WaylandEnumEntry {
31 std::vector<WaylandEnumEntry> entries;
34 struct WaylandArgument {
49 struct WaylandInterface {
53 std::vector<WaylandEnum> enums;
54 std::vector<WaylandEvent> events;
62 int intValue(
const QXmlStreamReader &
xml,
const char *
name,
int defaultValue = 0);
63 bool boolValue(
const QXmlStreamReader &
xml,
const char *
name);
64 WaylandEvent readEvent(QXmlStreamReader &
xml,
bool request);
65 Scanner::WaylandEnum readEnum(QXmlStreamReader &
xml);
66 Scanner::WaylandInterface readInterface(QXmlStreamReader &
xml);
69 const Scanner::WaylandArgument *newIdArgument(
const std::vector<WaylandArgument> &
arguments);
71 void printEvent(
const WaylandEvent &
e,
bool omitNames =
false,
bool withResource =
false);
72 void printEventHandlerSignature(
const WaylandEvent &
e,
const char *interfaceName,
bool deepIndent =
true);
73 void printEnums(
const std::vector<WaylandEnum> &enums);
91 QList <QByteArray> m_includes;
92 QXmlStreamReader *m_xml =
nullptr;
99 for (
int i = 0;
i < argc; ++
i)
102 m_scannerName =
args[0];
104 if (argc <= 2 || !parseOption(
args[1]))
107 m_protocolFilePath =
args[2];
109 if (argc > 3 && !
args[3].startsWith(
'-')) {
111 m_headerPath =
args[3];
120 if (
option.startsWith(
"--header-path=")) {
122 }
else if (
option.startsWith(
"--prefix=")) {
124 }
else if (
option.startsWith(
"--build-macro=")) {
126 }
else if (
option.startsWith(
"--add-include=")) {
128 if (!include.isEmpty())
129 m_includes << include;
141 fprintf(stderr,
"Usage: %s [client-header|server-header|client-code|server-code] specfile [--header-path=<path>] [--prefix=<prefix>] [--add-include=<include>]\n", m_scannerName.
constData());
144bool Scanner::isServerSide()
146 return m_option == ServerHeader || m_option == ServerCode;
151 if (
str ==
"client-header")
152 m_option = ClientHeader;
153 else if (
str ==
"server-header")
154 m_option = ServerHeader;
155 else if (
str ==
"client-code")
156 m_option = ClientCode;
157 else if (
str ==
"server-code")
158 m_option = ServerCode;
167 if (
xml.attributes().hasAttribute(
name))
168 return xml.attributes().value(
name).toUtf8();
172int Scanner::intValue(
const QXmlStreamReader &
xml,
const char *
name,
int defaultValue)
179bool Scanner::boolValue(
const QXmlStreamReader &
xml,
const char *
name)
181 return byteArrayValue(
xml,
name) ==
"true";
184Scanner::WaylandEvent Scanner::readEvent(QXmlStreamReader &
xml,
bool request)
186 WaylandEvent
event = {
188 .name = byteArrayValue(
xml,
"name"),
189 .type = byteArrayValue(
xml,
"type"),
192 while (
xml.readNextStartElement()) {
193 if (
xml.name() == u
"arg") {
195 .name = byteArrayValue(
xml,
"name"),
196 .type = byteArrayValue(
xml,
"type"),
197 .interface = byteArrayValue(
xml,
"interface"),
198 .summary = byteArrayValue(
xml,
"summary"),
199 .allowNull = boolValue(
xml,
"allowNull"),
201 event.arguments.push_back(std::move(
argument));
204 xml.skipCurrentElement();
209Scanner::WaylandEnum Scanner::readEnum(QXmlStreamReader &
xml)
212 .name = byteArrayValue(
xml,
"name"),
216 while (
xml.readNextStartElement()) {
217 if (
xml.name() == u
"entry") {
218 WaylandEnumEntry
entry = {
219 .name = byteArrayValue(
xml,
"name"),
220 .value = byteArrayValue(
xml,
"value"),
221 .summary = byteArrayValue(
xml,
"summary"),
226 xml.skipCurrentElement();
232Scanner::WaylandInterface Scanner::readInterface(QXmlStreamReader &
xml)
234 WaylandInterface
interface = {
235 .name = byteArrayValue(
xml,
"name"),
236 .version = intValue(
xml,
"version", 1),
242 while (
xml.readNextStartElement()) {
243 if (
xml.name() == u
"event")
245 else if (
xml.name() == u
"request")
247 else if (
xml.name() == u
"enum")
250 xml.skipCurrentElement();
258 if (waylandType ==
"string")
259 return "const char *";
260 else if (waylandType ==
"int")
262 else if (waylandType ==
"uint")
264 else if (waylandType ==
"fixed")
266 else if (waylandType ==
"fd")
268 else if (waylandType ==
"array")
270 else if (waylandType ==
"object" || waylandType ==
"new_id") {
272 return "struct ::wl_resource *";
274 return "struct ::wl_object *";
275 return "struct ::" +
interface + " *
";
280QByteArray Scanner::waylandToQtType(const QByteArray &waylandType, const QByteArray &interface, bool cStyleArray)
282 if (waylandType == "string")
284 else if (waylandType == "array")
285 return cStyleArray ? "wl_array *
" : "const QByteArray &
";
287 return waylandToCType(waylandType, interface);
290const Scanner::WaylandArgument *Scanner::newIdArgument(const std::vector<WaylandArgument> &arguments)
292 for (const WaylandArgument &a : arguments) {
293 if (a.type == "new_id
")
299void Scanner::printEvent(const WaylandEvent &e, bool omitNames, bool withResource)
301 printf("%
s(
", e.name.constData());
302 bool needsComma = false;
303 if (isServerSide()) {
305 printf("Resource *%
s", omitNames ? "" : "resource
");
307 } else if (withResource) {
308 printf("struct ::wl_resource *%
s", omitNames ? "" : "resource
");
312 for (const WaylandArgument &a : e.arguments) {
313 bool isNewId = a.type == "new_id
";
314 if (isNewId && !isServerSide() && (a.interface.isEmpty() != e.request))
320 if (isServerSide()) {
324 printf(" %
s", a.name.constData());
329 printf("const struct ::wl_interface *%
s, uint32_t%
s", omitNames ? "" : "interface", omitNames ? "" : " version
");
335 QByteArray qtType = waylandToQtType(a.type, a.interface, e.request == isServerSide());
336 printf("%
s%
s%
s", qtType.constData(), qtType.endsWith("&
") || qtType.endsWith("*
") ? "" : " ", omitNames ? "" : a.name.constData());
341void Scanner::printEventHandlerSignature(const WaylandEvent &e, const char *interfaceName, bool deepIndent)
343 const char *indent = deepIndent ? " " : "";
344 printf("handle_%
s(\
n", e.name.constData());
345 if (isServerSide()) {
346 printf(" %s::wl_client *client,\
n", indent);
347 printf(" %sstruct wl_resource *resource
", indent);
349 printf(" %svoid *
data,\
n", indent);
350 printf(" %sstruct ::%
s *
object", indent, interfaceName);
352 for (const WaylandArgument &a : e.arguments) {
354 bool isNewId = a.type == "new_id
";
355 if (isServerSide() && isNewId) {
356 printf(" %suint32_t %
s", indent, a.name.constData());
358 QByteArray cType = waylandToCType(a.type, a.interface);
359 printf(" %
s%
s%
s%
s", indent, cType.constData(), cType.endsWith("*
") ? "" : " ", a.name.constData());
365void Scanner::printEnums(const std::vector<WaylandEnum> &enums)
367 for (const WaylandEnum &e : enums) {
369 printf(" enum %
s {\
n", e.name.constData());
370 for (const WaylandEnumEntry &entry : e.entries) {
371 printf(" %s_%
s = %
s,
", e.name.constData(), entry.name.constData(), entry.value.constData());
372 if (!entry.summary.isNull())
382 if (!m_prefix.
isEmpty() &&
name.startsWith(m_prefix))
384 if (
name.startsWith(
"qt_") ||
name.startsWith(
"wl_"))
392 return name ==
"wl_display"
393 || (isServerSide() &&
name ==
"wl_registry");
400 fprintf(stderr,
"Unable to open file %s\n", m_protocolFilePath.
constData());
404 m_xml =
new QXmlStreamReader(&
file);
405 if (!m_xml->readNextStartElement())
408 if (m_xml->name() != u
"protocol") {
409 m_xml->raiseError(
QStringLiteral(
"The file is not a wayland protocol file."));
413 m_protocolName = byteArrayValue(*m_xml,
"name");
415 if (m_protocolName.
isEmpty()) {
425 std::vector<WaylandInterface> interfaces;
427 while (m_xml->readNextStartElement()) {
428 if (m_xml->name() == u
"interface")
429 interfaces.
push_back(readInterface(*m_xml));
431 m_xml->skipCurrentElement();
434 if (m_xml->hasError())
437 printf(
"// This file was generated by qtwaylandscanner\n");
438 printf(
"// source file is %s\n\n",
qPrintable(m_protocolFilePath));
440 for (
auto b : std::as_const(m_includes))
441 printf(
"#include %s\n",
b.constData());
443 auto printExportMacro = [
this](
const char *prefix,
const QByteArray &preProcessorProtocolName) {
444 QByteArray exportMacro = prefix + preProcessorProtocolName +
"_EXPORT";
445 printf(
"#if !defined(%s)\n", exportMacro.
constData());
446 printf(
"# if defined(QT_SHARED) && !defined(QT_STATIC)\n");
448 printf(
"# define %s Q_DECL_EXPORT\n", exportMacro.
constData());
450 printf(
"# if defined(%s)\n", m_buildMacro.
constData());
451 printf(
"# define %s Q_DECL_EXPORT\n", exportMacro.
constData());
453 printf(
"# define %s Q_DECL_IMPORT\n", exportMacro.
constData());
457 printf(
"# define %s\n", exportMacro.
constData());
463 if (m_option == ServerHeader) {
465 printf(
"#ifndef %s\n", inclusionGuard.
constData());
466 printf(
"#define %s\n", inclusionGuard.
constData());
468 printf(
"#include \"wayland-server-core.h\"\n");
470 printf(
"#include \"wayland-%s-server-protocol.h\"\n",
QByteArray(m_protocolName).replace(
'_',
'-').constData());
472 printf(
"#include <%s/wayland-%s-server-protocol.h>\n", m_headerPath.
constData(),
QByteArray(m_protocolName).replace(
'_',
'-').constData());
473 printf(
"#include <QByteArray>\n");
474 printf(
"#include <QMultiMap>\n");
475 printf(
"#include <QString>\n");
478 printf(
"#ifndef WAYLAND_VERSION_CHECK\n");
479 printf(
"#define WAYLAND_VERSION_CHECK(major, minor, micro) \\\n");
480 printf(
" ((WAYLAND_VERSION_MAJOR > (major)) || \\\n");
481 printf(
" (WAYLAND_VERSION_MAJOR == (major) && WAYLAND_VERSION_MINOR > (minor)) || \\\n");
482 printf(
" (WAYLAND_VERSION_MAJOR == (major) && WAYLAND_VERSION_MINOR == (minor) && WAYLAND_VERSION_MICRO >= (micro)))\n");
486 printf(
"QT_BEGIN_NAMESPACE\n");
487 printf(
"QT_WARNING_PUSH\n");
488 printf(
"QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n");
489 printf(
"QT_WARNING_DISABLE_CLANG(\"-Wmissing-field-initializers\")\n");
491 if (m_headerPath.
size())
492 serverExport = printExportMacro(
"Q_WAYLAND_SERVER_", preProcessorProtocolName);
494 printf(
"namespace QtWaylandServer {\n");
496 bool needsNewLine =
false;
497 for (
const WaylandInterface &
interface : interfaces) {
506 const char *interfaceName =
interface.name.constData();
509 const char *interfaceNameStripped =
stripped.constData();
511 printf(
" class %s %s\n {\n", serverExport.
constData(), interfaceName);
512 printf(
" public:\n");
513 printf(
" %s(struct ::wl_client *client, uint32_t id, int version);\n", interfaceName);
514 printf(
" %s(struct ::wl_display *display, int version);\n", interfaceName);
515 printf(
" %s(struct ::wl_resource *resource);\n", interfaceName);
516 printf(
" %s();\n", interfaceName);
518 printf(
" virtual ~%s();\n", interfaceName);
520 printf(
" class Resource\n");
522 printf(
" public:\n");
523 printf(
" Resource() : %s_object(nullptr), handle(nullptr) {}\n", interfaceNameStripped);
524 printf(
" virtual ~Resource() {}\n");
526 printf(
" %s *%s_object;\n", interfaceName, interfaceNameStripped);
527 printf(
" %s *object() { return %s_object; } \n", interfaceName, interfaceNameStripped);
528 printf(
" struct ::wl_resource *handle;\n");
530 printf(
" struct ::wl_client *client() const { return wl_resource_get_client(handle); }\n");
531 printf(
" int version() const { return wl_resource_get_version(handle); }\n");
533 printf(
" static Resource *fromResource(struct ::wl_resource *resource);\n");
536 printf(
" void init(struct ::wl_client *client, uint32_t id, int version);\n");
537 printf(
" void init(struct ::wl_display *display, int version);\n");
538 printf(
" void init(struct ::wl_resource *resource);\n");
540 printf(
" Resource *add(struct ::wl_client *client, int version);\n");
541 printf(
" Resource *add(struct ::wl_client *client, uint32_t id, int version);\n");
542 printf(
" Resource *add(struct wl_list *resource_list, struct ::wl_client *client, uint32_t id, int version);\n");
544 printf(
" Resource *resource() { return m_resource; }\n");
545 printf(
" const Resource *resource() const { return m_resource; }\n");
547 printf(
" QMultiMap<struct ::wl_client*, Resource*> resourceMap() { return m_resource_map; }\n");
548 printf(
" const QMultiMap<struct ::wl_client*, Resource*> resourceMap() const { return m_resource_map; }\n");
550 printf(
" bool isGlobal() const { return m_global != nullptr; }\n");
551 printf(
" bool isResource() const { return m_resource != nullptr; }\n");
553 printf(
" static const struct ::wl_interface *interface();\n");
554 printf(
" static QByteArray interfaceName() { return interface()->name; }\n");
555 printf(
" static int interfaceVersion() { return interface()->version; }\n");
560 bool hasEvents = !
interface.events.empty();
564 for (
const WaylandEvent &
e :
interface.events) {
565 printf(
" void send_");
568 printf(
" void send_");
569 printEvent(
e,
false,
true);
575 printf(
" protected:\n");
576 printf(
" virtual Resource *%s_allocate();\n", interfaceNameStripped);
578 printf(
" virtual void %s_bind_resource(Resource *resource);\n", interfaceNameStripped);
579 printf(
" virtual void %s_destroy_resource(Resource *resource);\n", interfaceNameStripped);
581 bool hasRequests = !
interface.requests.empty();
585 for (
const WaylandEvent &
e :
interface.requests) {
586 printf(
" virtual void %s_", interfaceNameStripped);
593 printf(
" private:\n");
594 printf(
" static void bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id);\n");
595 printf(
" static void destroy_func(struct ::wl_resource *client_resource);\n");
596 printf(
" static void display_destroy_func(struct ::wl_listener *listener, void *data);\n");
598 printf(
" Resource *bind(struct ::wl_client *client, uint32_t id, int version);\n");
599 printf(
" Resource *bind(struct ::wl_resource *handle);\n");
603 printf(
" static const struct ::%s_interface m_%s_interface;\n", interfaceName, interfaceName);
606 for (
const WaylandEvent &
e :
interface.requests) {
607 printf(
" static void ");
609 printEventHandlerSignature(
e, interfaceName);
615 printf(
" QMultiMap<struct ::wl_client*, Resource*> m_resource_map;\n");
616 printf(
" Resource *m_resource;\n");
617 printf(
" struct ::wl_global *m_global;\n");
618 printf(
" struct DisplayDestroyedListener : ::wl_listener {\n");
619 printf(
" %s *parent;\n", interfaceName);
621 printf(
" DisplayDestroyedListener m_displayDestroyedListener;\n");
627 printf(
"QT_WARNING_POP\n");
628 printf(
"QT_END_NAMESPACE\n");
633 if (m_option == ServerCode) {
635 printf(
"#include \"qwayland-server-%s.h\"\n",
QByteArray(m_protocolName).replace(
'_',
'-').constData());
637 printf(
"#include <%s/qwayland-server-%s.h>\n", m_headerPath.
constData(),
QByteArray(m_protocolName).replace(
'_',
'-').constData());
639 printf(
"QT_BEGIN_NAMESPACE\n");
640 printf(
"QT_WARNING_PUSH\n");
641 printf(
"QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n");
642 printf(
"QT_WARNING_DISABLE_CLANG(\"-Wmissing-field-initializers\")\n");
644 printf(
"namespace QtWaylandServer {\n");
646 bool needsNewLine =
false;
647 for (
const WaylandInterface &
interface : interfaces) {
657 const char *interfaceName =
interface.name.constData();
660 const char *interfaceNameStripped =
stripped.constData();
662 printf(
" %s::%s(struct ::wl_client *client, uint32_t id, int version)\n", interfaceName, interfaceName);
663 printf(
" : m_resource_map()\n");
664 printf(
" , m_resource(nullptr)\n");
665 printf(
" , m_global(nullptr)\n");
667 printf(
" init(client, id, version);\n");
671 printf(
" %s::%s(struct ::wl_display *display, int version)\n", interfaceName, interfaceName);
672 printf(
" : m_resource_map()\n");
673 printf(
" , m_resource(nullptr)\n");
674 printf(
" , m_global(nullptr)\n");
676 printf(
" init(display, version);\n");
680 printf(
" %s::%s(struct ::wl_resource *resource)\n", interfaceName, interfaceName);
681 printf(
" : m_resource_map()\n");
682 printf(
" , m_resource(nullptr)\n");
683 printf(
" , m_global(nullptr)\n");
685 printf(
" init(resource);\n");
689 printf(
" %s::%s()\n", interfaceName, interfaceName);
690 printf(
" : m_resource_map()\n");
691 printf(
" , m_resource(nullptr)\n");
692 printf(
" , m_global(nullptr)\n");
697 printf(
" %s::~%s()\n", interfaceName, interfaceName);
699 printf(
" for (auto resource : std::as_const(m_resource_map))\n");
700 printf(
" resource->%s_object = nullptr;\n", interfaceNameStripped);
702 printf(
" if (m_resource)\n");
703 printf(
" m_resource->%s_object = nullptr;\n", interfaceNameStripped);
705 printf(
" if (m_global) {\n");
706 printf(
" wl_global_destroy(m_global);\n");
707 printf(
" wl_list_remove(&m_displayDestroyedListener.link);\n");
712 printf(
" void %s::init(struct ::wl_client *client, uint32_t id, int version)\n", interfaceName);
714 printf(
" m_resource = bind(client, id, version);\n");
718 printf(
" void %s::init(struct ::wl_resource *resource)\n", interfaceName);
720 printf(
" m_resource = bind(resource);\n");
724 printf(
" %s::Resource *%s::add(struct ::wl_client *client, int version)\n", interfaceName, interfaceName);
726 printf(
" Resource *resource = bind(client, 0, version);\n");
727 printf(
" m_resource_map.insert(client, resource);\n");
728 printf(
" return resource;\n");
732 printf(
" %s::Resource *%s::add(struct ::wl_client *client, uint32_t id, int version)\n", interfaceName, interfaceName);
734 printf(
" Resource *resource = bind(client, id, version);\n");
735 printf(
" m_resource_map.insert(client, resource);\n");
736 printf(
" return resource;\n");
740 printf(
" void %s::init(struct ::wl_display *display, int version)\n", interfaceName);
742 printf(
" m_global = wl_global_create(display, &::%s_interface, version, this, bind_func);\n", interfaceName);
743 printf(
" m_displayDestroyedListener.notify = %s::display_destroy_func;\n", interfaceName);
744 printf(
" m_displayDestroyedListener.parent = this;\n");
745 printf(
" wl_display_add_destroy_listener(display, &m_displayDestroyedListener);\n");
749 printf(
" const struct wl_interface *%s::interface()\n", interfaceName);
751 printf(
" return &::%s_interface;\n", interfaceName);
755 printf(
" %s::Resource *%s::%s_allocate()\n", interfaceName, interfaceName, interfaceNameStripped);
757 printf(
" return new Resource;\n");
761 printf(
" void %s::%s_bind_resource(Resource *)\n", interfaceName, interfaceNameStripped);
766 printf(
" void %s::%s_destroy_resource(Resource *)\n", interfaceName, interfaceNameStripped);
771 printf(
" void %s::bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id)\n", interfaceName);
773 printf(
" %s *that = static_cast<%s *>(data);\n", interfaceName, interfaceName);
774 printf(
" that->add(client, id, version);\n");
778 printf(
" void %s::display_destroy_func(struct ::wl_listener *listener, void *data)\n", interfaceName);
780 printf(
" Q_UNUSED(data);\n");
781 printf(
" %s *that = static_cast<%s::DisplayDestroyedListener *>(listener)->parent;\n", interfaceName, interfaceName);
782 printf(
" that->m_global = nullptr;\n");
786 printf(
" void %s::destroy_func(struct ::wl_resource *client_resource)\n", interfaceName);
788 printf(
" Resource *resource = Resource::fromResource(client_resource);\n");
789 printf(
" Q_ASSERT(resource);\n");
790 printf(
" %s *that = resource->%s_object;\n", interfaceName, interfaceNameStripped);
791 printf(
" if (Q_LIKELY(that)) {\n");
792 printf(
" that->m_resource_map.remove(resource->client(), resource);\n");
793 printf(
" that->%s_destroy_resource(resource);\n", interfaceNameStripped);
795 printf(
" that = resource->%s_object;\n", interfaceNameStripped);
796 printf(
" if (that && that->m_resource == resource)\n");
797 printf(
" that->m_resource = nullptr;\n");
799 printf(
" delete resource;\n");
803 bool hasRequests = !
interface.requests.empty();
809 printf(
" %s::Resource *%s::bind(struct ::wl_client *client, uint32_t id, int version)\n", interfaceName, interfaceName);
811 printf(
" Q_ASSERT_X(!wl_client_get_object(client, id), \"QWaylandObject bind\", QStringLiteral(\"binding to object %%1 more than once\").arg(id).toLocal8Bit().constData());\n");
812 printf(
" struct ::wl_resource *handle = wl_resource_create(client, &::%s_interface, version, id);\n", interfaceName);
813 printf(
" return bind(handle);\n");
817 printf(
" %s::Resource *%s::bind(struct ::wl_resource *handle)\n", interfaceName, interfaceName);
819 printf(
" Resource *resource = %s_allocate();\n", interfaceNameStripped);
820 printf(
" resource->%s_object = this;\n", interfaceNameStripped);
822 printf(
" wl_resource_set_implementation(handle, %s, resource, destroy_func);", interfaceMember.
constData());
824 printf(
" resource->handle = handle;\n");
825 printf(
" %s_bind_resource(resource);\n", interfaceNameStripped);
826 printf(
" return resource;\n");
829 printf(
" %s::Resource *%s::Resource::fromResource(struct ::wl_resource *resource)\n", interfaceName, interfaceName);
831 printf(
" if (Q_UNLIKELY(!resource))\n");
832 printf(
" return nullptr;\n");
833 printf(
" if (wl_resource_instance_of(resource, &::%s_interface, %s))\n", interfaceName, interfaceMember.
constData());
834 printf(
" return static_cast<Resource *>(wl_resource_get_user_data(resource));\n");
835 printf(
" return nullptr;\n");
840 printf(
" const struct ::%s_interface %s::m_%s_interface = {", interfaceName, interfaceName, interfaceName);
841 bool needsComma =
false;
842 for (
const WaylandEvent &
e :
interface.requests) {
847 printf(
" %s::handle_%s", interfaceName,
e.name.constData());
852 for (
const WaylandEvent &
e :
interface.requests) {
854 printf(
" void %s::%s_", interfaceName, interfaceNameStripped);
862 for (
const WaylandEvent &
e :
interface.requests) {
864 printf(
" void %s::", interfaceName);
866 printEventHandlerSignature(
e, interfaceName,
false);
870 printf(
" Q_UNUSED(client);\n");
871 printf(
" Resource *r = Resource::fromResource(resource);\n");
872 printf(
" if (Q_UNLIKELY(!r->%s_object)) {\n", interfaceNameStripped);
873 if (
e.type ==
"destructor")
874 printf(
" wl_resource_destroy(resource);\n");
875 printf(
" return;\n");
877 printf(
" static_cast<%s *>(r->%s_object)->%s_%s(\n", interfaceName, interfaceNameStripped, interfaceNameStripped,
e.name.constData());
879 for (
const WaylandArgument &
a :
e.arguments) {
882 QByteArray qtType = waylandToQtType(
a.type,
a.interface,
e.request);
883 const char *argumentName =
a.name.constData();
885 printf(
" %s", argumentName);
886 else if (
a.type ==
"string")
887 printf(
" QString::fromUtf8(%s)", argumentName);
894 for (
const WaylandEvent &
e :
interface.events) {
896 printf(
" void %s::send_", interfaceName);
900 printf(
" Q_ASSERT_X(m_resource, \"%s::%s\", \"Uninitialised resource\");\n", interfaceName,
e.name.constData());
901 printf(
" if (Q_UNLIKELY(!m_resource)) {\n");
902 printf(
" qWarning(\"could not call %s::%s as it's not initialised\");\n", interfaceName,
e.name.constData());
903 printf(
" return;\n");
905 printf(
" send_%s(\n",
e.name.constData());
906 printf(
" m_resource->handle");
907 for (
const WaylandArgument &
a :
e.arguments) {
909 printf(
" %s",
a.name.constData());
915 printf(
" void %s::send_", interfaceName);
916 printEvent(
e,
false,
true);
920 for (
const WaylandArgument &
a :
e.arguments) {
921 if (
a.type !=
"array")
925 const char *variableName =
a.name.constData();
926 printf(
" struct wl_array %s;\n", arrayName);
927 printf(
" %s.size = %s.size();\n", arrayName, variableName);
928 printf(
" %s.data = static_cast<void *>(const_cast<char *>(%s.constData()));\n", arrayName, variableName);
929 printf(
" %s.alloc = 0;\n", arrayName);
933 printf(
" %s_send_%s(\n", interfaceName,
e.name.constData());
936 for (
const WaylandArgument &
a :
e.arguments) {
939 QByteArray qtType = waylandToQtType(
a.type,
a.interface,
e.request);
940 if (
a.type ==
"string")
941 printf(
" %s.toUtf8().constData()",
a.name.constData());
942 else if (
a.type ==
"array")
943 printf(
" &%s_data",
a.name.constData());
944 else if (cType == qtType)
945 printf(
" %s",
a.name.constData());
955 printf(
"QT_WARNING_POP\n");
956 printf(
"QT_END_NAMESPACE\n");
959 if (m_option == ClientHeader) {
961 printf(
"#ifndef %s\n", inclusionGuard.
constData());
962 printf(
"#define %s\n", inclusionGuard.
constData());
965 printf(
"#include \"wayland-%s-client-protocol.h\"\n",
QByteArray(m_protocolName).replace(
'_',
'-').constData());
967 printf(
"#include <%s/wayland-%s-client-protocol.h>\n", m_headerPath.
constData(),
QByteArray(m_protocolName).replace(
'_',
'-').constData());
968 printf(
"#include <QByteArray>\n");
969 printf(
"#include <QString>\n");
971 printf(
"struct wl_registry;\n");
973 printf(
"QT_BEGIN_NAMESPACE\n");
974 printf(
"QT_WARNING_PUSH\n");
975 printf(
"QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n");
976 printf(
"QT_WARNING_DISABLE_CLANG(\"-Wmissing-field-initializers\")\n");
979 if (m_headerPath.
size())
980 clientExport = printExportMacro(
"Q_WAYLAND_CLIENT_", preProcessorProtocolName);
983 printf(
"namespace QtWayland {\n");
985 bool needsNewLine =
false;
986 for (
const WaylandInterface &
interface : interfaces) {
995 const char *interfaceName =
interface.name.constData();
998 const char *interfaceNameStripped =
stripped.constData();
1000 printf(
" class %s %s\n {\n", clientExport.
constData(), interfaceName);
1001 printf(
" public:\n");
1002 printf(
" %s(struct ::wl_registry *registry, uint32_t id, int version);\n", interfaceName);
1003 printf(
" %s(struct ::%s *object);\n", interfaceName, interfaceName);
1004 printf(
" %s();\n", interfaceName);
1006 printf(
" virtual ~%s();\n", interfaceName);
1008 printf(
" void init(struct ::wl_registry *registry, uint32_t id, int version);\n");
1009 printf(
" void init(struct ::%s *object);\n", interfaceName);
1011 printf(
" struct ::%s *object() { return m_%s; }\n", interfaceName, interfaceName);
1012 printf(
" const struct ::%s *object() const { return m_%s; }\n", interfaceName, interfaceName);
1013 printf(
" static %s *fromObject(struct ::%s *object);\n", interfaceName, interfaceName);
1015 printf(
" bool isInitialized() const;\n");
1017 printf(
" uint32_t version() const;");
1019 printf(
" static const struct ::wl_interface *interface();\n");
1025 for (
const WaylandEvent &
e :
interface.requests) {
1026 const WaylandArgument *new_id = newIdArgument(
e.arguments);
1029 if (new_id->interface.isEmpty())
1030 new_id_str =
"void *";
1032 new_id_str =
"struct ::" + new_id->interface +
" *";
1040 bool hasEvents = !
interface.events.empty();
1044 printf(
" protected:\n");
1045 for (
const WaylandEvent &
e :
interface.events) {
1046 printf(
" virtual void %s_", interfaceNameStripped);
1053 printf(
" private:\n");
1055 printf(
" void init_listener();\n");
1056 printf(
" static const struct %s_listener m_%s_listener;\n", interfaceName, interfaceName);
1057 for (
const WaylandEvent &
e :
interface.events) {
1058 printf(
" static void ");
1060 printEventHandlerSignature(
e, interfaceName);
1064 printf(
" struct ::%s *m_%s;\n", interfaceName, interfaceName);
1069 printf(
"QT_WARNING_POP\n");
1070 printf(
"QT_END_NAMESPACE\n");
1075 if (m_option == ClientCode) {
1077 printf(
"#include \"qwayland-%s.h\"\n",
QByteArray(m_protocolName).replace(
'_',
'-').constData());
1079 printf(
"#include <%s/qwayland-%s.h>\n", m_headerPath.
constData(),
QByteArray(m_protocolName).replace(
'_',
'-').constData());
1081 printf(
"QT_BEGIN_NAMESPACE\n");
1082 printf(
"QT_WARNING_PUSH\n");
1083 printf(
"QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n");
1084 printf(
"QT_WARNING_DISABLE_CLANG(\"-Wmissing-field-initializers\")\n");
1086 printf(
"namespace QtWayland {\n");
1091 printf(
"static inline void *wlRegistryBind(struct ::wl_registry *registry, uint32_t name, const struct ::wl_interface *interface, uint32_t version)\n");
1093 printf(
" const uint32_t bindOpCode = 0;\n");
1094 printf(
" return (void *) wl_proxy_marshal_constructor_versioned((struct wl_proxy *) registry,\n");
1095 printf(
" bindOpCode, interface, version, name, interface->name, version, nullptr);\n");
1099 bool needsNewLine =
false;
1100 for (
const WaylandInterface &
interface : interfaces) {
1107 needsNewLine =
true;
1109 const char *interfaceName =
interface.name.constData();
1112 const char *interfaceNameStripped =
stripped.constData();
1114 bool hasEvents = !
interface.events.empty();
1116 printf(
" %s::%s(struct ::wl_registry *registry, uint32_t id, int version)\n", interfaceName, interfaceName);
1118 printf(
" init(registry, id, version);\n");
1122 printf(
" %s::%s(struct ::%s *obj)\n", interfaceName, interfaceName, interfaceName);
1123 printf(
" : m_%s(obj)\n", interfaceName);
1126 printf(
" init_listener();\n");
1130 printf(
" %s::%s()\n", interfaceName, interfaceName);
1131 printf(
" : m_%s(nullptr)\n", interfaceName);
1136 printf(
" %s::~%s()\n", interfaceName, interfaceName);
1141 printf(
" void %s::init(struct ::wl_registry *registry, uint32_t id, int version)\n", interfaceName);
1143 printf(
" m_%s = static_cast<struct ::%s *>(wlRegistryBind(registry, id, &%s_interface, version));\n", interfaceName, interfaceName, interfaceName);
1145 printf(
" init_listener();\n");
1149 printf(
" void %s::init(struct ::%s *obj)\n", interfaceName, interfaceName);
1151 printf(
" m_%s = obj;\n", interfaceName);
1153 printf(
" init_listener();\n");
1157 printf(
" %s *%s::fromObject(struct ::%s *object)\n", interfaceName, interfaceName, interfaceName);
1160 printf(
" if (wl_proxy_get_listener((struct ::wl_proxy *)object) != (void *)&m_%s_listener)\n", interfaceName);
1161 printf(
" return nullptr;\n");
1163 printf(
" return static_cast<%s *>(%s_get_user_data(object));\n", interfaceName, interfaceName);
1167 printf(
" bool %s::isInitialized() const\n", interfaceName);
1169 printf(
" return m_%s != nullptr;\n", interfaceName);
1173 printf(
" uint32_t %s::version() const\n", interfaceName);
1175 printf(
" return wl_proxy_get_version(reinterpret_cast<wl_proxy*>(m_%s));\n", interfaceName);
1179 printf(
" const struct wl_interface *%s::interface()\n", interfaceName);
1181 printf(
" return &::%s_interface;\n", interfaceName);
1184 for (
const WaylandEvent &
e :
interface.requests) {
1186 const WaylandArgument *new_id = newIdArgument(
e.arguments);
1189 if (new_id->interface.isEmpty())
1190 new_id_str =
"void *";
1192 new_id_str =
"struct ::" + new_id->interface +
" *";
1194 printf(
" %s%s::", new_id_str.
constData(), interfaceName);
1198 for (
const WaylandArgument &
a :
e.arguments) {
1199 if (
a.type !=
"array")
1203 const char *variableName =
a.name.constData();
1204 printf(
" struct wl_array %s;\n", arrayName);
1205 printf(
" %s.size = %s.size();\n", arrayName, variableName);
1206 printf(
" %s.data = static_cast<void *>(const_cast<char *>(%s.constData()));\n", arrayName, variableName);
1207 printf(
" %s.alloc = 0;\n", arrayName);
1210 int actualArgumentCount = new_id ? int(
e.arguments.size()) - 1 : int(
e.arguments.size());
1211 printf(
" %s::%s_%s(\n", new_id ?
"return " :
"", interfaceName,
e.name.constData());
1212 printf(
" m_%s%s", interfaceName, actualArgumentCount > 0 ?
"," :
"");
1213 bool needsComma =
false;
1214 for (
const WaylandArgument &
a :
e.arguments) {
1215 bool isNewId =
a.type ==
"new_id";
1216 if (isNewId && !
a.interface.isEmpty())
1223 printf(
" interface,\n");
1226 QByteArray cType = waylandToCType(
a.type,
a.interface);
1227 QByteArray qtType = waylandToQtType(
a.type,
a.interface,
e.request);
1228 if (
a.type ==
"string")
1229 printf(
" %s.toUtf8().constData()",
a.name.constData());
1230 else if (
a.type ==
"array")
1231 printf(
" &%s_data",
a.name.constData());
1232 else if (cType == qtType)
1233 printf(
" %s",
a.name.constData());
1237 if (
e.type ==
"destructor")
1238 printf(
" m_%s = nullptr;\n", interfaceName);
1244 for (
const WaylandEvent &
e :
interface.events) {
1245 printf(
" void %s::%s_", interfaceName, interfaceNameStripped);
1246 printEvent(
e,
true);
1251 printf(
" void %s::", interfaceName);
1252 printEventHandlerSignature(
e, interfaceName,
false);
1255 printf(
" Q_UNUSED(object);\n");
1256 printf(
" static_cast<%s *>(data)->%s_%s(", interfaceName, interfaceNameStripped,
e.name.constData());
1257 bool needsComma =
false;
1258 for (
const WaylandArgument &
a :
e.arguments) {
1263 const char *argumentName =
a.name.constData();
1264 if (
a.type ==
"string")
1265 printf(
" QString::fromUtf8(%s)", argumentName);
1267 printf(
" %s", argumentName);
1274 printf(
" const struct %s_listener %s::m_%s_listener = {\n", interfaceName, interfaceName, interfaceName);
1275 for (
const WaylandEvent &
e :
interface.events) {
1276 printf(
" %s::handle_%s,\n", interfaceName,
e.name.constData());
1281 printf(
" void %s::init_listener()\n", interfaceName);
1283 printf(
" %s_add_listener(m_%s, &m_%s_listener, this);\n", interfaceName, interfaceName, interfaceName);
1289 printf(
"QT_WARNING_POP\n");
1290 printf(
"QT_END_NAMESPACE\n");
1298 if (m_xml->hasError())
1299 fprintf(stderr,
"XML error: %s\nLine %lld, column %lld\n", m_xml->errorString().toLocal8Bit().constData(), m_xml->lineNumber(), m_xml->columnNumber());
1309 return EXIT_FAILURE;
1314 return EXIT_FAILURE;
1317 return EXIT_SUCCESS;
DarwinBluetooth::RequestQueue requests
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
QByteArray toUpper() const &
int toInt(bool *ok=nullptr, int base=10) const
Returns the byte array converted to an int using base base, which is ten by default.
void push_back(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
QByteArray mid(qsizetype index, qsizetype len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos.
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
void reserve(qsizetype size)
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool parseArguments(int argc, char **argv)
QList< QVariant > arguments
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char * interface
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static glyph_t stripped(glyph_t glyph)
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
#define qPrintable(string)
#define QStringLiteral(str)
QApplication app(argc, argv)
[0]
QNetworkRequest request(url)