Skip to content

Commit ea6ea6a

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

File tree

5 files changed

+149
-5
lines changed

5 files changed

+149
-5
lines changed

Makefile.common

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,11 +1290,13 @@ ifeq ($(HAVE_WAYLAND), 1)
12901290
endif
12911291

12921292
ifeq ($(WEBOS), 1)
1293-
OBJ += input/common/wayland_common_webos.o
1294-
OBJ += gfx/common/wayland/webos-foreign.o
1295-
OBJ += gfx/common/wayland/webos-input-manager.o
1296-
OBJ += gfx/common/wayland/webos-shell.o
1297-
OBJ += gfx/common/wayland/webos-surface-group.o
1293+
OBJ += input/common/wayland_common_webos.o
1294+
OBJ += gfx/common/wayland/webos-shell.o
1295+
ifeq ($(HAVE_WEBOS_EXTRA_PROTOS), 1)
1296+
OBJ += gfx/common/wayland/webos-foreign.o
1297+
OBJ += gfx/common/wayland/webos-input-manager.o
1298+
OBJ += gfx/common/wayland/webos-surface-group.o
1299+
endif
12981300
endif
12991301

13001302
DEF_FLAGS += $(WAYLAND_CFLAGS) $(WAYLAND_CURSOR_CFLAGS)

Makefile.webos

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ HAVE_UPDATE_ASSETS = 1
132132
HAVE_UPDATE_CORES = 1
133133
HAVE_UPDATE_CORE_INFO = 1
134134
HAVE_USERLAND ?= 0
135+
HAVE_WEBOS_EXTRA_PROTOS ?= 0
135136
HAVE_CORE_INFO_CACHE = 1
136137
HAVE_WAYLAND ?= 0
137138

@@ -187,6 +188,9 @@ ifeq ($(HAVE_WAYLAND),1)
187188
DEFINES += -DHAVE_WAYLAND=1
188189
WAYLAND_LIBS = -lwayland-client -lwayland-cursor -lwayland-egl
189190
endif
191+
ifeq ($(HAVE_WEBOS_EXTRA_PROTOS),1)
192+
DEFINES += -DHAVE_WEBOS_EXTRA_PROTOS=1
193+
endif
190194
ifeq ($(HAVE_USERLAND),1)
191195
DEFINES += -DHAVE_USERLAND
192196
WAYLAND_LIBS += -lhelpers

input/common/wayland_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,11 @@ typedef struct gfx_ctx_wayland_data
180180
struct wl_shell_surface *shell_surface;
181181
struct wl_webos_shell *webos_shell;
182182
struct wl_webos_shell_surface *webos_shell_surface;
183+
#ifdef HAVE_WEBOS_EXTRA_PROTOS
183184
struct wl_webos_foreign *webos_foreign;
184185
struct wl_webos_surface_group_compositor *webos_surface_group_compositor;
185186
struct wl_webos_input_manager *webos_input_manager;
187+
#endif
186188
#endif
187189
data_offer_ctx *current_drag_offer;
188190
#ifdef HAVE_LIBDECOR_H

input/common/wayland_common_webos.c

Lines changed: 132 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"
@@ -34,9 +35,12 @@
3435
#include "../input_keymaps.h"
3536

3637
#include "../../gfx/common/wayland/webos-shell.h"
38+
39+
#ifdef HAVE_WEBOS_EXTRA_PROTOS
3740
#include "../../gfx/common/wayland/webos-foreign.h"
3841
#include "../../gfx/common/wayland/webos-surface-group.h"
3942
#include "../../gfx/common/wayland/webos-input-manager.h"
43+
#endif
4044

4145
#ifdef HAVE_USERLAND
4246
#include <webos-helpers/libhelpers.h>
@@ -260,6 +264,7 @@ static void wl_registry_handle_global_webos(void *data,
260264
wl->webos_shell = (struct wl_webos_shell*)wl_registry_bind(reg,
261265
id, &wl_webos_shell_interface, 1);
262266
}
267+
#ifdef HAVE_WEBOS_EXTRA_PROTOS
263268
else if (string_is_equal(interface, "wl_webos_foreign"))
264269
{
265270
wl->webos_foreign = (struct wl_webos_foreign*)wl_registry_bind(reg,
@@ -276,6 +281,7 @@ static void wl_registry_handle_global_webos(void *data,
276281
wl->webos_input_manager = (struct wl_webos_input_manager*)wl_registry_bind(reg,
277282
id, &wl_webos_input_manager_interface, 1);
278283
}
284+
#endif
279285
}
280286

281287
static void wl_registry_handle_global_remove_webos(void *data,
@@ -385,12 +391,14 @@ void gfx_ctx_wl_destroy_resources_webos(gfx_ctx_wayland_data_t *wl)
385391
if (wl->surface)
386392
wl_surface_destroy(wl->surface);
387393

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

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)