libwayland_variadic_support.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // This file contains a subset of wayland's connection.c. It's necessary to
  5. // provide implementations of variadic functions which generate_stubs.py cannot
  6. // generate forwarding functions for. Fortunately, libwayland-client exposes
  7. // non-variadic equivalents for these functions that we can forward to.
  8. #include <wayland-client.h>
  9. #include <wayland-server.h>
  10. #include <cstdarg>
  11. #include <cstdint>
  12. #define WL_CLOSURE_MAX_ARGS 20
  13. extern "C" {
  14. struct argument_details {
  15. char type;
  16. int nullable;
  17. };
  18. const char* get_next_argument(const char* signature,
  19. struct argument_details* details) {
  20. details->nullable = 0;
  21. for (; *signature; ++signature) {
  22. switch (*signature) {
  23. case 'i':
  24. case 'u':
  25. case 'f':
  26. case 's':
  27. case 'o':
  28. case 'n':
  29. case 'a':
  30. case 'h':
  31. details->type = *signature;
  32. return signature + 1;
  33. case '?':
  34. details->nullable = 1;
  35. }
  36. }
  37. details->type = '\0';
  38. return signature;
  39. }
  40. void wl_argument_from_va_list(const char* signature,
  41. union wl_argument* args,
  42. int count,
  43. va_list ap) {
  44. int i;
  45. const char* sig_iter;
  46. struct argument_details arg;
  47. sig_iter = signature;
  48. for (i = 0; i < count; i++) {
  49. sig_iter = get_next_argument(sig_iter, &arg);
  50. switch (arg.type) {
  51. case 'i':
  52. args[i].i = va_arg(ap, int32_t);
  53. break;
  54. case 'u':
  55. args[i].u = va_arg(ap, uint32_t);
  56. break;
  57. case 'f':
  58. args[i].f = va_arg(ap, wl_fixed_t);
  59. break;
  60. case 's':
  61. args[i].s = va_arg(ap, const char*);
  62. break;
  63. case 'o':
  64. args[i].o = va_arg(ap, struct wl_object*);
  65. break;
  66. case 'n':
  67. args[i].o = va_arg(ap, struct wl_object*);
  68. break;
  69. case 'a':
  70. args[i].a = va_arg(ap, struct wl_array*);
  71. break;
  72. case 'h':
  73. args[i].h = va_arg(ap, int32_t);
  74. break;
  75. case '\0':
  76. return;
  77. }
  78. }
  79. }
  80. void wl_proxy_marshal(struct wl_proxy* proxy, uint32_t opcode, ...) {
  81. union wl_argument args[WL_CLOSURE_MAX_ARGS];
  82. va_list ap;
  83. va_start(ap, opcode);
  84. wl_argument_from_va_list(
  85. reinterpret_cast<wl_object*>(proxy)->interface->methods[opcode].signature,
  86. args, WL_CLOSURE_MAX_ARGS, ap);
  87. va_end(ap);
  88. wl_proxy_marshal_array_constructor(proxy, opcode, args, nullptr);
  89. }
  90. struct wl_proxy* wl_proxy_marshal_constructor(
  91. struct wl_proxy* proxy,
  92. uint32_t opcode,
  93. const struct wl_interface* interface,
  94. ...) {
  95. union wl_argument args[WL_CLOSURE_MAX_ARGS];
  96. va_list ap;
  97. va_start(ap, interface);
  98. wl_argument_from_va_list(
  99. reinterpret_cast<wl_object*>(proxy)->interface->methods[opcode].signature,
  100. args, WL_CLOSURE_MAX_ARGS, ap);
  101. va_end(ap);
  102. return wl_proxy_marshal_array_constructor(proxy, opcode, args, interface);
  103. }
  104. struct wl_proxy* wl_proxy_marshal_constructor_versioned(
  105. struct wl_proxy* proxy,
  106. uint32_t opcode,
  107. const struct wl_interface* interface,
  108. uint32_t version,
  109. ...) {
  110. union wl_argument args[WL_CLOSURE_MAX_ARGS];
  111. va_list ap;
  112. va_start(ap, version);
  113. wl_argument_from_va_list(
  114. reinterpret_cast<wl_object*>(proxy)->interface->methods[opcode].signature,
  115. args, WL_CLOSURE_MAX_ARGS, ap);
  116. va_end(ap);
  117. return wl_proxy_marshal_array_constructor_versioned(proxy, opcode, args,
  118. interface, version);
  119. }
  120. }