401 fprintf(stderr,
"Unable to open file %s\n", m_protocolFilePath.
constData());
405 m_xml =
new QXmlStreamReader(&
file);
406 if (!m_xml->readNextStartElement())
409 if (m_xml->name() != u
"protocol") {
410 m_xml->raiseError(
QStringLiteral(
"The file is not a wayland protocol file."));
414 m_protocolName = byteArrayValue(*m_xml,
"name");
416 if (m_protocolName.
isEmpty()) {
428 std::vector<WaylandInterface> interfaces;
430 while (m_xml->readNextStartElement()) {
431 if (m_xml->name() == u
"interface")
432 interfaces.
push_back(readInterface(*m_xml));
434 m_xml->skipCurrentElement();
437 if (m_xml->hasError())
440 printf(
"// This file was generated by qtwaylandscanner\n");
443 for (
auto b : std::as_const(m_includes))
444 printf(
"#include %s\n",
b.constData());
446 auto printExportMacro = [
this](
const char *prefix,
const QByteArray &preProcessorProtocolName) {
447 QByteArray exportMacro = prefix + preProcessorProtocolName +
"_EXPORT";
448 printf(
"#if !defined(%s)\n", exportMacro.constData());
449 printf(
"# if defined(QT_SHARED) && !defined(QT_STATIC)\n");
451 printf(
"# define %s Q_DECL_EXPORT\n", exportMacro.constData());
453 printf(
"# if defined(%s)\n", m_buildMacro.
constData());
454 printf(
"# define %s Q_DECL_EXPORT\n", exportMacro.constData());
456 printf(
"# define %s Q_DECL_IMPORT\n", exportMacro.constData());
460 printf(
"# define %s\n", exportMacro.constData());
466 if (m_option == ServerHeader) {
467 QByteArray inclusionGuard =
QByteArray(
"QT_WAYLAND_SERVER_") + preProcessorProtocolName.constData();
468 printf(
"#ifndef %s\n", inclusionGuard.constData());
469 printf(
"#define %s\n", inclusionGuard.constData());
471 printf(
"#include \"wayland-server-core.h\"\n");
473 printf(
"#include \"wayland-%s-server-protocol.h\"\n", fileBaseName.constData());
475 printf(
"#include <%s/wayland-%s-server-protocol.h>\n", m_headerPath.
constData(), fileBaseName.constData());
476 printf(
"#include <QByteArray>\n");
477 printf(
"#include <QMultiMap>\n");
478 printf(
"#include <QString>\n");
481 printf(
"#ifndef WAYLAND_VERSION_CHECK\n");
482 printf(
"#define WAYLAND_VERSION_CHECK(major, minor, micro) \\\n");
483 printf(
" ((WAYLAND_VERSION_MAJOR > (major)) || \\\n");
484 printf(
" (WAYLAND_VERSION_MAJOR == (major) && WAYLAND_VERSION_MINOR > (minor)) || \\\n");
485 printf(
" (WAYLAND_VERSION_MAJOR == (major) && WAYLAND_VERSION_MINOR == (minor) && WAYLAND_VERSION_MICRO >= (micro)))\n");
489 printf(
"QT_BEGIN_NAMESPACE\n");
490 printf(
"QT_WARNING_PUSH\n");
491 printf(
"QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n");
492 printf(
"QT_WARNING_DISABLE_CLANG(\"-Wmissing-field-initializers\")\n");
494 if (m_headerPath.
size())
495 serverExport = printExportMacro(
"Q_WAYLAND_SERVER_", preProcessorProtocolName);
497 printf(
"namespace QtWaylandServer {\n");
499 bool needsNewLine =
false;
500 for (
const WaylandInterface &
interface : interfaces) {
512 const char *interfaceNameStripped =
stripped.constData();
514 printf(
" class %s %s\n {\n", serverExport.constData(),
interfaceName);
515 printf(
" public:\n");
516 printf(
" %s(struct ::wl_client *client, uint32_t id, int version);\n",
interfaceName);
517 printf(
" %s(struct ::wl_display *display, int version);\n",
interfaceName);
518 printf(
" %s(struct ::wl_resource *resource);\n",
interfaceName);
523 printf(
" class Resource\n");
525 printf(
" public:\n");
526 printf(
" Resource() : %s_object(nullptr), handle(nullptr) {}\n", interfaceNameStripped);
527 printf(
" virtual ~Resource() {}\n");
529 printf(
" %s *%s_object;\n",
interfaceName, interfaceNameStripped);
530 printf(
" %s *object() { return %s_object; } \n",
interfaceName, interfaceNameStripped);
531 printf(
" struct ::wl_resource *handle;\n");
533 printf(
" struct ::wl_client *client() const { return wl_resource_get_client(handle); }\n");
534 printf(
" int version() const { return wl_resource_get_version(handle); }\n");
536 printf(
" static Resource *fromResource(struct ::wl_resource *resource);\n");
539 printf(
" void init(struct ::wl_client *client, uint32_t id, int version);\n");
540 printf(
" void init(struct ::wl_display *display, int version);\n");
541 printf(
" void init(struct ::wl_resource *resource);\n");
543 printf(
" Resource *add(struct ::wl_client *client, int version);\n");
544 printf(
" Resource *add(struct ::wl_client *client, uint32_t id, int version);\n");
545 printf(
" Resource *add(struct wl_list *resource_list, struct ::wl_client *client, uint32_t id, int version);\n");
547 printf(
" Resource *resource() { return m_resource; }\n");
548 printf(
" const Resource *resource() const { return m_resource; }\n");
550 printf(
" QMultiMap<struct ::wl_client*, Resource*> resourceMap() { return m_resource_map; }\n");
551 printf(
" const QMultiMap<struct ::wl_client*, Resource*> resourceMap() const { return m_resource_map; }\n");
553 printf(
" bool isGlobal() const { return m_global != nullptr; }\n");
554 printf(
" bool isResource() const { return m_resource != nullptr; }\n");
556 printf(
" static const struct ::wl_interface *interface();\n");
557 printf(
" static QByteArray interfaceName() { return interface()->name; }\n");
558 printf(
" static int interfaceVersion() { return interface()->version; }\n");
563 bool hasEvents = !
interface.events.empty();
567 for (
const WaylandEvent &e :
interface.events) {
568 printf(
" void send_");
571 printf(
" void send_");
572 printEvent(e,
false,
true);
578 printf(
" protected:\n");
579 printf(
" virtual Resource *%s_allocate();\n", interfaceNameStripped);
581 printf(
" virtual void %s_bind_resource(Resource *resource);\n", interfaceNameStripped);
582 printf(
" virtual void %s_destroy_resource(Resource *resource);\n", interfaceNameStripped);
584 bool hasRequests = !
interface.requests.empty();
588 for (
const WaylandEvent &e :
interface.requests) {
589 printf(
" virtual void %s_", interfaceNameStripped);
596 printf(
" private:\n");
597 printf(
" static void bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id);\n");
598 printf(
" static void destroy_func(struct ::wl_resource *client_resource);\n");
599 printf(
" static void display_destroy_func(struct ::wl_listener *listener, void *data);\n");
601 printf(
" Resource *bind(struct ::wl_client *client, uint32_t id, int version);\n");
602 printf(
" Resource *bind(struct ::wl_resource *handle);\n");
609 for (
const WaylandEvent &e :
interface.requests) {
610 printf(
" static void ");
618 printf(
" QMultiMap<struct ::wl_client*, Resource*> m_resource_map;\n");
619 printf(
" Resource *m_resource;\n");
620 printf(
" struct ::wl_global *m_global;\n");
621 printf(
" struct DisplayDestroyedListener : ::wl_listener {\n");
624 printf(
" DisplayDestroyedListener m_displayDestroyedListener;\n");
630 printf(
"QT_WARNING_POP\n");
631 printf(
"QT_END_NAMESPACE\n");
636 if (m_option == ServerCode) {
638 printf(
"#include \"qwayland-server-%s.h\"\n", fileBaseName.constData());
640 printf(
"#include <%s/qwayland-server-%s.h>\n", m_headerPath.
constData(), fileBaseName.constData());
642 printf(
"QT_BEGIN_NAMESPACE\n");
643 printf(
"QT_WARNING_PUSH\n");
644 printf(
"QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n");
645 printf(
"QT_WARNING_DISABLE_CLANG(\"-Wmissing-field-initializers\")\n");
647 printf(
"namespace QtWaylandServer {\n");
649 bool needsNewLine =
false;
650 for (
const WaylandInterface &
interface : interfaces) {
663 const char *interfaceNameStripped =
stripped.constData();
666 printf(
" : m_resource_map()\n");
667 printf(
" , m_resource(nullptr)\n");
668 printf(
" , m_global(nullptr)\n");
670 printf(
" init(client, id, version);\n");
675 printf(
" : m_resource_map()\n");
676 printf(
" , m_resource(nullptr)\n");
677 printf(
" , m_global(nullptr)\n");
679 printf(
" init(display, version);\n");
684 printf(
" : m_resource_map()\n");
685 printf(
" , m_resource(nullptr)\n");
686 printf(
" , m_global(nullptr)\n");
688 printf(
" init(resource);\n");
693 printf(
" : m_resource_map()\n");
694 printf(
" , m_resource(nullptr)\n");
695 printf(
" , m_global(nullptr)\n");
702 printf(
" for (auto resource : std::as_const(m_resource_map))\n");
703 printf(
" resource->%s_object = nullptr;\n", interfaceNameStripped);
705 printf(
" if (m_resource)\n");
706 printf(
" m_resource->%s_object = nullptr;\n", interfaceNameStripped);
708 printf(
" if (m_global) {\n");
709 printf(
" wl_global_destroy(m_global);\n");
710 printf(
" wl_list_remove(&m_displayDestroyedListener.link);\n");
715 printf(
" void %s::init(struct ::wl_client *client, uint32_t id, int version)\n",
interfaceName);
717 printf(
" m_resource = bind(client, id, version);\n");
721 printf(
" void %s::init(struct ::wl_resource *resource)\n",
interfaceName);
723 printf(
" m_resource = bind(resource);\n");
729 printf(
" Resource *resource = bind(client, 0, version);\n");
730 printf(
" m_resource_map.insert(client, resource);\n");
731 printf(
" return resource;\n");
737 printf(
" Resource *resource = bind(client, id, version);\n");
738 printf(
" m_resource_map.insert(client, resource);\n");
739 printf(
" return resource;\n");
743 printf(
" void %s::init(struct ::wl_display *display, int version)\n",
interfaceName);
745 printf(
" m_global = wl_global_create(display, &::%s_interface, version, this, bind_func);\n",
interfaceName);
746 printf(
" m_displayDestroyedListener.notify = %s::display_destroy_func;\n",
interfaceName);
747 printf(
" m_displayDestroyedListener.parent = this;\n");
748 printf(
" wl_display_add_destroy_listener(display, &m_displayDestroyedListener);\n");
752 printf(
" const struct wl_interface *%s::interface()\n",
interfaceName);
760 printf(
" return new Resource;\n");
764 printf(
" void %s::%s_bind_resource(Resource *)\n",
interfaceName, interfaceNameStripped);
769 printf(
" void %s::%s_destroy_resource(Resource *)\n",
interfaceName, interfaceNameStripped);
774 printf(
" void %s::bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id)\n",
interfaceName);
777 printf(
" that->add(client, id, version);\n");
781 printf(
" void %s::display_destroy_func(struct ::wl_listener *listener, void *data)\n",
interfaceName);
783 printf(
" Q_UNUSED(data);\n");
785 printf(
" that->m_global = nullptr;\n");
789 printf(
" void %s::destroy_func(struct ::wl_resource *client_resource)\n",
interfaceName);
791 printf(
" Resource *resource = Resource::fromResource(client_resource);\n");
792 printf(
" Q_ASSERT(resource);\n");
793 printf(
" %s *that = resource->%s_object;\n",
interfaceName, interfaceNameStripped);
794 printf(
" if (Q_LIKELY(that)) {\n");
795 printf(
" that->m_resource_map.remove(resource->client(), resource);\n");
796 printf(
" that->%s_destroy_resource(resource);\n", interfaceNameStripped);
798 printf(
" that = resource->%s_object;\n", interfaceNameStripped);
799 printf(
" if (that && that->m_resource == resource)\n");
800 printf(
" that->m_resource = nullptr;\n");
802 printf(
" delete resource;\n");
806 bool hasRequests = !
interface.requests.empty();
814 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");
815 printf(
" struct ::wl_resource *handle = wl_resource_create(client, &::%s_interface, version, id);\n",
interfaceName);
816 printf(
" return bind(handle);\n");
822 printf(
" Resource *resource = %s_allocate();\n", interfaceNameStripped);
823 printf(
" resource->%s_object = this;\n", interfaceNameStripped);
825 printf(
" wl_resource_set_implementation(handle, %s, resource, destroy_func);", interfaceMember.constData());
827 printf(
" resource->handle = handle;\n");
828 printf(
" %s_bind_resource(resource);\n", interfaceNameStripped);
829 printf(
" return resource;\n");
834 printf(
" if (Q_UNLIKELY(!resource))\n");
835 printf(
" return nullptr;\n");
836 printf(
" if (wl_resource_instance_of(resource, &::%s_interface, %s))\n",
interfaceName, interfaceMember.constData());
837 printf(
" return static_cast<Resource *>(wl_resource_get_user_data(resource));\n");
838 printf(
" return nullptr;\n");
844 bool needsComma =
false;
845 for (
const WaylandEvent &e :
interface.requests) {
855 for (
const WaylandEvent &e :
interface.requests) {
857 printf(
" void %s::%s_",
interfaceName, interfaceNameStripped);
865 for (
const WaylandEvent &e :
interface.requests) {
873 printf(
" Q_UNUSED(client);\n");
874 printf(
" Resource *r = Resource::fromResource(resource);\n");
875 printf(
" if (Q_UNLIKELY(!r->%s_object)) {\n", interfaceNameStripped);
876 if (e.type ==
"destructor")
877 printf(
" wl_resource_destroy(resource);\n");
878 printf(
" return;\n");
880 printf(
" static_cast<%s *>(r->%s_object)->%s_%s(\n",
interfaceName, interfaceNameStripped, interfaceNameStripped, e.name.constData());
882 for (
const WaylandArgument &
a : e.arguments) {
885 QByteArray qtType = waylandToQtType(
a.type,
a.interface, e.request);
886 const char *argumentName =
a.name.constData();
888 printf(
" %s", argumentName);
889 else if (
a.type ==
"string")
890 printf(
" QString::fromUtf8(%s)", argumentName);
897 for (
const WaylandEvent &e :
interface.events) {
903 printf(
" Q_ASSERT_X(m_resource, \"%s::%s\", \"Uninitialised resource\");\n",
interfaceName, e.name.constData());
904 printf(
" if (Q_UNLIKELY(!m_resource)) {\n");
905 printf(
" qWarning(\"could not call %s::%s as it's not initialised\");\n",
interfaceName, e.name.constData());
906 printf(
" return;\n");
908 printf(
" send_%s(\n", e.name.constData());
909 printf(
" m_resource->handle");
910 for (
const WaylandArgument &
a : e.arguments) {
912 printf(
" %s",
a.name.constData());
919 printEvent(e,
false,
true);
923 for (
const WaylandArgument &
a : e.arguments) {
924 if (
a.type !=
"array")
928 const char *variableName =
a.name.constData();
929 printf(
" struct wl_array %s;\n", arrayName);
930 printf(
" %s.size = %s.size();\n", arrayName, variableName);
931 printf(
" %s.data = static_cast<void *>(const_cast<char *>(%s.constData()));\n", arrayName, variableName);
932 printf(
" %s.alloc = 0;\n", arrayName);
939 for (
const WaylandArgument &
a : e.arguments) {
942 QByteArray qtType = waylandToQtType(
a.type,
a.interface, e.request);
943 if (
a.type ==
"string") {
946 printf(
"%s.isNull() ? nullptr : ",
a.name.constData());
947 printf(
"%s.toUtf8().constData()",
a.name.constData());
948 }
else if (
a.type ==
"array")
949 printf(
" &%s_data",
a.name.constData());
950 else if (cType == qtType)
951 printf(
" %s",
a.name.constData());
961 printf(
"QT_WARNING_POP\n");
962 printf(
"QT_END_NAMESPACE\n");
965 if (m_option == ClientHeader) {
967 printf(
"#ifndef %s\n", inclusionGuard.constData());
968 printf(
"#define %s\n", inclusionGuard.constData());
971 printf(
"#include \"wayland-%s-client-protocol.h\"\n", fileBaseName.constData());
973 printf(
"#include <%s/wayland-%s-client-protocol.h>\n", m_headerPath.
constData(), fileBaseName.constData());
974 printf(
"#include <QByteArray>\n");
975 printf(
"#include <QString>\n");
977 printf(
"struct wl_registry;\n");
979 printf(
"QT_BEGIN_NAMESPACE\n");
980 printf(
"QT_WARNING_PUSH\n");
981 printf(
"QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n");
982 printf(
"QT_WARNING_DISABLE_CLANG(\"-Wmissing-field-initializers\")\n");
985 if (m_headerPath.
size())
986 clientExport = printExportMacro(
"Q_WAYLAND_CLIENT_", preProcessorProtocolName);
989 printf(
"namespace QtWayland {\n");
991 bool needsNewLine =
false;
992 for (
const WaylandInterface &
interface : interfaces) {
1004 const char *interfaceNameStripped =
stripped.constData();
1006 printf(
" class %s %s\n {\n", clientExport.constData(),
interfaceName);
1007 printf(
" public:\n");
1008 printf(
" %s(struct ::wl_registry *registry, uint32_t id, int version);\n",
interfaceName);
1014 printf(
" void init(struct ::wl_registry *registry, uint32_t id, int version);\n");
1015 printf(
" void init(struct ::%s *object);\n",
interfaceName);
1021 printf(
" bool isInitialized() const;\n");
1023 printf(
" uint32_t version() const;");
1025 printf(
" static const struct ::wl_interface *interface();\n");
1031 for (
const WaylandEvent &e :
interface.requests) {
1032 const WaylandArgument *new_id = newIdArgument(e.arguments);
1035 if (new_id->interface.isEmpty())
1036 new_id_str =
"void *";
1038 new_id_str =
"struct ::" + new_id->interface +
" *";
1040 printf(
" %s", new_id_str.constData());
1046 bool hasEvents = !
interface.events.empty();
1050 printf(
" protected:\n");
1051 for (
const WaylandEvent &e :
interface.events) {
1052 printf(
" virtual void %s_", interfaceNameStripped);
1059 printf(
" private:\n");
1061 printf(
" void init_listener();\n");
1063 for (
const WaylandEvent &e :
interface.events) {
1064 printf(
" static void ");
1075 printf(
"QT_WARNING_POP\n");
1076 printf(
"QT_END_NAMESPACE\n");
1081 if (m_option == ClientCode) {
1083 printf(
"#include \"qwayland-%s.h\"\n", fileBaseName.constData());
1085 printf(
"#include <%s/qwayland-%s.h>\n", m_headerPath.
constData(), fileBaseName.constData());
1087 printf(
"QT_BEGIN_NAMESPACE\n");
1088 printf(
"QT_WARNING_PUSH\n");
1089 printf(
"QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n");
1090 printf(
"QT_WARNING_DISABLE_CLANG(\"-Wmissing-field-initializers\")\n");
1092 printf(
"namespace QtWayland {\n");
1097 printf(
"static inline void *wlRegistryBind(struct ::wl_registry *registry, uint32_t name, const struct ::wl_interface *interface, uint32_t version)\n");
1099 printf(
" const uint32_t bindOpCode = 0;\n");
1100 printf(
" return (void *) wl_proxy_marshal_constructor_versioned((struct wl_proxy *) registry,\n");
1101 printf(
" bindOpCode, interface, version, name, interface->name, version, nullptr);\n");
1105 bool needsNewLine =
false;
1106 for (
const WaylandInterface &
interface : interfaces) {
1113 needsNewLine =
true;
1118 const char *interfaceNameStripped =
stripped.constData();
1120 bool hasEvents = !
interface.events.empty();
1124 printf(
" init(registry, id, version);\n");
1132 printf(
" init_listener();\n");
1147 printf(
" void %s::init(struct ::wl_registry *registry, uint32_t id, int version)\n",
interfaceName);
1151 printf(
" init_listener();\n");
1159 printf(
" init_listener();\n");
1166 printf(
" if (wl_proxy_get_listener((struct ::wl_proxy *)object) != (void *)&m_%s_listener)\n",
interfaceName);
1167 printf(
" return nullptr;\n");
1181 printf(
" return wl_proxy_get_version(reinterpret_cast<wl_proxy*>(m_%s));\n",
interfaceName);
1185 printf(
" const struct wl_interface *%s::interface()\n",
interfaceName);
1190 for (
const WaylandEvent &e :
interface.requests) {
1192 const WaylandArgument *new_id = newIdArgument(e.arguments);
1195 if (new_id->interface.isEmpty())
1196 new_id_str =
"void *";
1198 new_id_str =
"struct ::" + new_id->interface +
" *";
1204 for (
const WaylandArgument &
a : e.arguments) {
1205 if (
a.type !=
"array")
1209 const char *variableName =
a.name.constData();
1210 printf(
" struct wl_array %s;\n", arrayName);
1211 printf(
" %s.size = %s.size();\n", arrayName, variableName);
1212 printf(
" %s.data = static_cast<void *>(const_cast<char *>(%s.constData()));\n", arrayName, variableName);
1213 printf(
" %s.alloc = 0;\n", arrayName);
1216 int actualArgumentCount = new_id ? int(e.arguments.size()) - 1 : int(e.arguments.size());
1217 printf(
" %s::%s_%s(\n", new_id ?
"return " :
"",
interfaceName, e.name.constData());
1218 printf(
" m_%s%s",
interfaceName, actualArgumentCount > 0 ?
"," :
"");
1219 bool needsComma =
false;
1220 for (
const WaylandArgument &
a : e.arguments) {
1221 bool isNewId =
a.type ==
"new_id";
1222 if (isNewId && !
a.interface.isEmpty())
1229 printf(
" interface,\n");
1232 QByteArray cType = waylandToCType(
a.type,
a.interface);
1233 QByteArray qtType = waylandToQtType(
a.type,
a.interface, e.request);
1234 if (
a.type ==
"string") {
1237 printf(
"%s.isNull() ? nullptr : ",
a.name.constData());
1238 printf(
"%s.toUtf8().constData()",
a.name.constData());
1239 }
else if (
a.type ==
"array")
1240 printf(
" &%s_data",
a.name.constData());
1241 else if (cType == qtType)
1242 printf(
" %s",
a.name.constData());
1246 if (e.type ==
"destructor")
1253 for (
const WaylandEvent &e :
interface.events) {
1254 printf(
" void %s::%s_",
interfaceName, interfaceNameStripped);
1255 printEvent(e,
true);
1264 printf(
" Q_UNUSED(object);\n");
1265 printf(
" static_cast<%s *>(data)->%s_%s(",
interfaceName, interfaceNameStripped, e.name.constData());
1266 bool needsComma =
false;
1267 for (
const WaylandArgument &
a : e.arguments) {
1272 const char *argumentName =
a.name.constData();
1273 if (
a.type ==
"string")
1274 printf(
" QString::fromUtf8(%s)", argumentName);
1276 printf(
" %s", argumentName);
1284 for (
const WaylandEvent &e :
interface.events) {
1285 printf(
" %s::handle_%s,\n",
interfaceName, e.name.constData());
1298 printf(
"QT_WARNING_POP\n");
1299 printf(
"QT_END_NAMESPACE\n");