Skip to content

Commit 5724418

Browse files
committed
webOS: wl_proxy_marshal_constructor_versioned workaround for older versions
1 parent 937f13b commit 5724418

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

input/common/wayland_common_webos.c

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <poll.h>
2424
#include <unistd.h>
2525
#include <string/stdstring.h>
26+
#include <dlfcn.h>
2627

2728
#include "wayland_common.h"
2829
#include "wayland_common_webos.h"
@@ -864,3 +865,127 @@ void shutdown_webos_contexts()
864865
}
865866
#endif
866867
}
868+
869+
/*
870+
Backwards compatibility for older versions of libwayland-client that
871+
do not have wl_proxy_marshal_constructor_versioned and
872+
wl_proxy_marshal_array_constructor_versioned.
873+
*/
874+
875+
/* Simple DirectMedia Layer
876+
Copyright (C) 1997-2023 Sam Lantinga <[email protected] */
877+
static int parse_msg_signature(const char *signature, int *new_id_index)
878+
{
879+
int count = 0;
880+
for (; *signature; ++signature) {
881+
switch (*signature) {
882+
case 'n':
883+
*new_id_index = count;
884+
// Intentional fallthrough
885+
case 'i':
886+
case 'u':
887+
case 'f':
888+
case 's':
889+
case 'o':
890+
case 'a':
891+
case 'h':
892+
++count;
893+
}
894+
}
895+
return count;
896+
}
897+
898+
struct wl_proxy *RA_wl_proxy_marshal_constructor_versioned(
899+
struct wl_proxy *proxy, uint32_t opcode,
900+
const struct wl_interface *iface, uint32_t version, ...)
901+
{
902+
static struct wl_proxy *(*fn)(struct wl_proxy *, uint32_t,
903+
const struct wl_interface *, uint32_t, ...) = NULL;
904+
static int dlsym_called = 0;
905+
906+
if (!dlsym_called) {
907+
fn = dlsym(RTLD_NEXT, "wl_proxy_marshal_constructor_versioned");
908+
dlsym_called = 1;
909+
}
910+
911+
if (fn) {
912+
/* real symbol exists, just call it */
913+
va_list ap;
914+
va_start(ap, version);
915+
struct wl_proxy *ret = fn(proxy, opcode, iface, version, ap);
916+
va_end(ap);
917+
return ret;
918+
}
919+
920+
/* fallback path: reconstruct arguments */
921+
void *varargs[WL_CLOSURE_MAX_ARGS];
922+
int num_args;
923+
int new_id_index = -1;
924+
struct wl_interface *proxy_interface;
925+
struct wl_proxy *id = wl_proxy_create(proxy, iface);
926+
if (!id)
927+
return NULL;
928+
929+
proxy_interface = (*(struct wl_interface **)proxy);
930+
if (opcode > proxy_interface->method_count)
931+
return NULL;
932+
933+
num_args = parse_msg_signature(proxy_interface->methods[opcode].signature,
934+
&new_id_index);
935+
if (new_id_index < 0)
936+
return NULL;
937+
938+
memset(varargs, 0, sizeof(varargs));
939+
940+
va_list ap;
941+
va_start(ap, version);
942+
for (int i = 0; i < num_args; i++)
943+
varargs[i] = va_arg(ap, void *);
944+
va_end(ap);
945+
946+
varargs[new_id_index] = id;
947+
948+
wl_proxy_marshal(proxy, opcode,
949+
varargs[0], varargs[1], varargs[2], varargs[3], varargs[4],
950+
varargs[5], varargs[6], varargs[7], varargs[8], varargs[9],
951+
varargs[10], varargs[11], varargs[12], varargs[13], varargs[14],
952+
varargs[15], varargs[16], varargs[17], varargs[18], varargs[19]);
953+
954+
return id;
955+
}
956+
957+
struct wl_proxy *RA_wl_proxy_marshal_array_constructor_versioned(
958+
struct wl_proxy *proxy, uint32_t opcode,
959+
union wl_argument *args,
960+
const struct wl_interface *iface, uint32_t version)
961+
{
962+
static struct wl_proxy *(*fn)(struct wl_proxy *, uint32_t,
963+
union wl_argument *, const struct wl_interface *, uint32_t) = NULL;
964+
static int dlsym_called = 0;
965+
966+
if (!dlsym_called) {
967+
fn = dlsym(RTLD_NEXT, "wl_proxy_marshal_array_constructor_versioned");
968+
dlsym_called = 1;
969+
}
970+
971+
if (!fn) {
972+
return wl_proxy_marshal_array_constructor(proxy, opcode, args, iface);
973+
}
974+
975+
return fn(proxy, opcode, args, iface, version);
976+
}
977+
978+
struct wl_proxy *wl_proxy_marshal_constructor_versioned(
979+
struct wl_proxy *proxy, uint32_t opcode,
980+
const struct wl_interface *iface, uint32_t version, ...)
981+
{
982+
return RA_wl_proxy_marshal_constructor_versioned(proxy, opcode, iface, version);
983+
}
984+
985+
struct wl_proxy *wl_proxy_marshal_array_constructor_versioned(
986+
struct wl_proxy *proxy, uint32_t opcode,
987+
union wl_argument *args,
988+
const struct wl_interface *iface, uint32_t version)
989+
{
990+
return RA_wl_proxy_marshal_array_constructor_versioned(proxy, opcode, args, iface, version);
991+
}

input/common/wayland_common_webos.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,8 @@ enum webos_wl_special_keymap
3737
extern uint8_t webos_wl_special_keymap[webos_wl_key_size];
3838
extern void shutdown_webos_contexts();
3939

40+
/* Backwards compatibility for webOS 3 */
41+
#define WL_CLOSURE_MAX_ARGS 20
42+
/* end: backwards compatibility for webOS 3 */
43+
4044
#endif

0 commit comments

Comments
 (0)