Skip to content

Commit 8689b34

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

File tree

6 files changed

+167
-18
lines changed

6 files changed

+167
-18
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

gfx/common/egl_common.c

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -470,12 +470,19 @@ static bool check_egl_client_extension(const char *name, size_t name_len)
470470

471471
static EGLDisplay get_egl_display(EGLenum platform, void *native)
472472
{
473+
RARCH_LOG("[EGL] get_egl_display(platform=0x%x, native=%p)\n", (unsigned)platform, native);
474+
475+
RARCH_LOG("[EGL] DISPLAY=%s\n", getenv("DISPLAY"));
476+
RARCH_LOG("[EGL] EGL_PLATFORM=%s\n", getenv("EGL_PLATFORM"));
477+
RARCH_LOG("[EGL] WAYLAND_DISPLAY=%s\n", getenv("WAYLAND_DISPLAY"));
478+
RARCH_LOG("[EGL] XDG_DIR=%s\n", getenv("XDG_DIR"));
479+
RARCH_LOG("[EGL] XDG_RUNTIME_DIR=%s\n", getenv("XDG_RUNTIME_DIR"));
480+
RARCH_LOG("[EGL] XKB_CONFIG_ROOT=%s\n", getenv("XKB_CONFIG_ROOT"));
481+
473482
if (platform != EGL_NONE)
474483
{
475-
/* If the client library supports at least EGL 1.5, then we can call
476-
* eglGetPlatformDisplay. Otherwise, see if eglGetPlatformDisplayEXT
477-
* is available. */
478484
#if defined(EGL_VERSION_1_5)
485+
RARCH_LOG("[EGL] Checking for EGL 1.5 support...\n");
479486
if (check_egl_version(1, 5))
480487
{
481488
typedef EGLDisplay (EGLAPIENTRY * pfn_eglGetPlatformDisplay)
@@ -485,40 +492,66 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native)
485492
RARCH_LOG("[EGL] Found EGL client version >= 1.5, trying eglGetPlatformDisplay.\n");
486493
ptr_eglGetPlatformDisplay = (pfn_eglGetPlatformDisplay)
487494
_egl_get_proc_address("eglGetPlatformDisplay");
495+
RARCH_LOG("[EGL] eglGetPlatformDisplay symbol=%p\n", (void*)ptr_eglGetPlatformDisplay);
488496

489497
if (ptr_eglGetPlatformDisplay)
490498
{
491499
EGLDisplay dpy = ptr_eglGetPlatformDisplay(platform, native, NULL);
492500
if (dpy != EGL_NO_DISPLAY)
501+
{
502+
RARCH_LOG("[EGL] eglGetPlatformDisplay succeeded: %p\n", (void*)dpy);
493503
return dpy;
504+
}
505+
else
506+
{
507+
EGLint err = eglGetError();
508+
RARCH_ERR("[EGL] eglGetPlatformDisplay failed, error=0x%x\n", err);
509+
}
494510
}
495511
}
496512
#endif /* defined(EGL_VERSION_1_5) */
497513

498514
#if defined(EGL_EXT_platform_base)
515+
RARCH_LOG("[EGL] Checking for EGL_EXT_platform_base...\n");
499516
if (check_egl_client_extension("EGL_EXT_platform_base", STRLEN_CONST("EGL_EXT_platform_base")))
500517
{
501518
PFNEGLGETPLATFORMDISPLAYEXTPROC ptr_eglGetPlatformDisplayEXT;
502519

503520
RARCH_LOG("[EGL] Found EGL_EXT_platform_base, trying eglGetPlatformDisplayEXT.\n");
504521
ptr_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
505522
_egl_get_proc_address("eglGetPlatformDisplayEXT");
523+
RARCH_LOG("[EGL] eglGetPlatformDisplayEXT symbol=%p\n", (void*)ptr_eglGetPlatformDisplayEXT);
506524

507525
if (ptr_eglGetPlatformDisplayEXT)
508526
{
509527
EGLDisplay dpy = ptr_eglGetPlatformDisplayEXT(platform, native, NULL);
510528
if (dpy != EGL_NO_DISPLAY)
529+
{
530+
RARCH_LOG("[EGL] eglGetPlatformDisplayEXT succeeded: %p\n", (void*)dpy);
511531
return dpy;
532+
}
533+
else
534+
{
535+
EGLint err = eglGetError();
536+
RARCH_ERR("[EGL] eglGetPlatformDisplayEXT failed, error=0x%x\n", err);
537+
}
512538
}
513539
}
514540
#endif /* defined(EGL_EXT_platform_base) */
515541
}
516542

517-
/* Either the caller didn't provide a platform type, or the EGL
518-
* implementation doesn't support eglGetPlatformDisplay. In this case, try
519-
* eglGetDisplay and hope for the best. */
520-
RARCH_LOG("[EGL] Falling back to eglGetDisplay.\n");
521-
return _egl_get_display((EGLNativeDisplayType) native);
543+
RARCH_LOG("[EGL] Falling back to eglGetDisplay(native=%p)\n", native);
544+
EGLDisplay dpy = _egl_get_display((EGLNativeDisplayType) native);
545+
if (dpy == EGL_NO_DISPLAY)
546+
{
547+
EGLint err = eglGetError();
548+
RARCH_ERR("[EGL] eglGetDisplay failed, error=0x%x\n", err);
549+
}
550+
else
551+
{
552+
RARCH_LOG("[EGL] eglGetDisplay succeeded: %p\n", (void*)dpy);
553+
}
554+
return dpy;
522555
}
523556

524557
bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value)

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: 109 additions & 5 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>
@@ -88,7 +92,7 @@ bool LunaRequest(const char *uri,
8892
#ifdef HAVE_USERLAND
8993
static bool registerAppCallback(LSHandle* sh, LSMessage* msg, void* context)
9094
{
91-
RARCH_DBG("[LunaRequest] registerAppCallback returned.\n");
95+
RARCH_LOG("[LunaRequest] registerAppCallback returned.\n");
9296
return true;
9397
}
9498

@@ -217,7 +221,7 @@ static void wl_registry_handle_global_webos(void *data,
217221
{
218222
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
219223

220-
RARCH_DBG("[Wayland/webOS] Registry: %s (id=%u, version=%u)\n",
224+
RARCH_LOG("[Wayland/webOS] Registry: %s (id=%u, version=%u)\n",
221225
interface, id, version);
222226

223227
if (string_is_equal(interface, "wl_compositor"))
@@ -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)
@@ -674,7 +682,7 @@ static bool screenSaverCallback(LSHandle* sh, LSMessage* reply, void* context)
674682
? (const char *)((HContext*)context)->userdata
675683
: "";
676684

677-
RARCH_DBG("[LunaRequest] screenSaverCallback: %s\n", msg ? msg : "(null)");
685+
RARCH_LOG("[LunaRequest] screenSaverCallback: %s\n", msg ? msg : "(null)");
678686
if (!msg || !len)
679687
return true;
680688

@@ -721,8 +729,7 @@ static bool screenSaverCallback(LSHandle* sh, LSMessage* reply, void* context)
721729
rjsonwriter_raw(w, "}", 1);
722730

723731
char *resp = rjsonwriter_get_memory_buffer(w, NULL);
724-
RARCH_DBG("[LunaRequest] responseScreenSaverRequest payload: %s\n", resp);
725-
732+
RARCH_LOG("[LunaRequest] responseScreenSaverRequest payload: %s\n", resp);
726733
HContext response_ctx;
727734
memset(&response_ctx, 0, sizeof(response_ctx));
728735
response_ctx.multiple = false;
@@ -864,3 +871,100 @@ void shutdown_webos_contexts()
864871
}
865872
#endif
866873
}
874+
875+
/*
876+
Backwards compatibility for older versions of libwayland-client that
877+
do not have wl_proxy_marshal_constructor_versioned and
878+
wl_proxy_marshal_array_constructor_versioned.
879+
*/
880+
static int parse_msg_signature(const char *signature, int *new_id_index)
881+
{
882+
int count = 0;
883+
if (new_id_index) *new_id_index = -1;
884+
if (!signature) return 0;
885+
886+
for (; *signature; ++signature) {
887+
switch (*signature) {
888+
case 'n':
889+
if (new_id_index) *new_id_index = count;
890+
/* fallthrough */
891+
case 'i': case 'u': case 'f':
892+
case 's': case 'o': case 'a': case 'h':
893+
++count;
894+
break;
895+
default:
896+
break;
897+
}
898+
}
899+
return count;
900+
}
901+
902+
static void wl_marshal_20(struct wl_proxy *proxy, uint32_t opcode, void **varargs)
903+
{
904+
wl_proxy_marshal(proxy, opcode,
905+
varargs[0], varargs[1], varargs[2], varargs[3], varargs[4],
906+
varargs[5], varargs[6], varargs[7], varargs[8], varargs[9],
907+
varargs[10], varargs[11], varargs[12], varargs[13], varargs[14],
908+
varargs[15], varargs[16], varargs[17], varargs[18], varargs[19]);
909+
}
910+
911+
struct wl_proxy *wl_proxy_marshal_constructor(struct wl_proxy *proxy,
912+
uint32_t opcode,
913+
const struct wl_interface *interface, ...)
914+
{
915+
va_list ap;
916+
void *varargs[WL_CLOSURE_MAX_ARGS];
917+
int num_args, new_id_index = -1;
918+
919+
struct wl_proxy *id = wl_proxy_create(proxy, interface);
920+
if (!id) return NULL;
921+
922+
struct wl_interface *proxy_iface = (*(struct wl_interface **)proxy);
923+
if (!proxy_iface) return NULL;
924+
if (opcode >= proxy_iface->method_count) return NULL;
925+
926+
const char *sig = proxy_iface->methods[opcode].signature;
927+
num_args = parse_msg_signature(sig, &new_id_index);
928+
if (new_id_index < 0) return NULL;
929+
930+
memset(varargs, 0, sizeof(varargs));
931+
va_start(ap, interface);
932+
for (int i = 0; i < num_args; i++)
933+
varargs[i] = va_arg(ap, void *);
934+
va_end(ap);
935+
936+
varargs[new_id_index] = id;
937+
wl_marshal_20(proxy, opcode, varargs);
938+
return id;
939+
}
940+
941+
struct wl_proxy *wl_proxy_marshal_constructor_versioned(struct wl_proxy *proxy,
942+
uint32_t opcode,
943+
const struct wl_interface *interface,
944+
uint32_t version, ...)
945+
{
946+
va_list ap;
947+
void *varargs[WL_CLOSURE_MAX_ARGS];
948+
int num_args, new_id_index = -1;
949+
950+
struct wl_proxy *id = wl_proxy_create(proxy, interface);
951+
if (!id) return NULL;
952+
953+
struct wl_interface *proxy_iface = (*(struct wl_interface **)proxy);
954+
if (!proxy_iface) return NULL;
955+
if (opcode >= proxy_iface->method_count) return NULL;
956+
957+
const char *sig = proxy_iface->methods[opcode].signature;
958+
num_args = parse_msg_signature(sig, &new_id_index);
959+
if (new_id_index < 0) return NULL;
960+
961+
memset(varargs, 0, sizeof(varargs));
962+
va_start(ap, version);
963+
for (int i = 0; i < num_args; i++)
964+
varargs[i] = va_arg(ap, void *);
965+
va_end(ap);
966+
967+
varargs[new_id_index] = id;
968+
wl_marshal_20(proxy, opcode, varargs);
969+
return id;
970+
}

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)