diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/egl-helpers.c | 58 | ||||
-rw-r--r-- | ui/vnc.c | 17 |
2 files changed, 62 insertions, 13 deletions
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c index 584dd1b04d..b7b6b2e3cc 100644 --- a/ui/egl-helpers.c +++ b/ui/egl-helpers.c @@ -192,6 +192,56 @@ EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win) /* ---------------------------------------------------------------------- */ +/* + * Taken from glamor_egl.h from the Xorg xserver, which is MIT licensed + * + * Create an EGLDisplay from a native display type. This is a little quirky + * for a few reasons. + * + * 1: GetPlatformDisplayEXT and GetPlatformDisplay are the API you want to + * use, but have different function signatures in the third argument; this + * happens not to matter for us, at the moment, but it means epoxy won't alias + * them together. + * + * 2: epoxy 1.3 and earlier don't understand EGL client extensions, which + * means you can't call "eglGetPlatformDisplayEXT" directly, as the resolver + * will crash. + * + * 3: You can't tell whether you have EGL 1.5 at this point, because + * eglQueryString(EGL_VERSION) is a property of the display, which we don't + * have yet. So you have to query for extensions no matter what. Fortunately + * epoxy_has_egl_extension _does_ let you query for client extensions, so + * we don't have to write our own extension string parsing. + * + * 4. There is no EGL_KHR_platform_base to complement the EXT one, thus one + * needs to know EGL 1.5 is supported in order to use the eglGetPlatformDisplay + * function pointer. + * We can workaround this (circular dependency) by probing for the EGL 1.5 + * platform extensions (EGL_KHR_platform_gbm and friends) yet it doesn't seem + * like mesa will be able to advertise these (even though it can do EGL 1.5). + */ +static EGLDisplay qemu_egl_get_display(void *native) +{ + EGLDisplay dpy = EGL_NO_DISPLAY; + +#ifdef EGL_MESA_platform_gbm + /* In practise any EGL 1.5 implementation would support the EXT extension */ + if (epoxy_has_egl_extension(NULL, "EGL_EXT_platform_base")) { + PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplayEXT = + (void *) eglGetProcAddress("eglGetPlatformDisplayEXT"); + if (getPlatformDisplayEXT) { + dpy = getPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, native, NULL); + } + } +#endif + + if (dpy == EGL_NO_DISPLAY) { + /* fallback */ + dpy = eglGetDisplay(native); + } + return dpy; +} + int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug) { static const EGLint conf_att_gl[] = { @@ -222,12 +272,8 @@ int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug) setenv("LIBGL_DEBUG", "verbose", true); } - egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy); -#ifdef EGL_MESA_platform_gbm - qemu_egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, dpy, NULL); -#else - qemu_egl_display = eglGetDisplay(dpy); -#endif + egl_dbg("qemu_egl_get_display (dpy %p) ...\n", dpy); + qemu_egl_display = qemu_egl_get_display(dpy); if (qemu_egl_display == EGL_NO_DISPLAY) { error_report("egl: eglGetDisplay failed"); return -1; @@ -3401,6 +3401,7 @@ vnc_display_create_creds(bool x509, static int vnc_display_get_address(const char *addrstr, bool websocket, + bool reverse, int displaynum, int to, bool has_ipv4, @@ -3480,21 +3481,22 @@ static int vnc_display_get_address(const char *addrstr, inet->port = g_strdup(port); } } else { + int offset = reverse ? 0 : 5900; if (parse_uint_full(port, &baseport, 10) < 0) { error_setg(errp, "can't convert to a number: %s", port); goto cleanup; } if (baseport > 65535 || - baseport + 5900 > 65535) { + baseport + offset > 65535) { error_setg(errp, "port %s out of range", port); goto cleanup; } inet->port = g_strdup_printf( - "%d", (int)baseport + 5900); + "%d", (int)baseport + offset); if (to) { inet->has_to = true; - inet->to = to + 5900; + inet->to = to + offset; } } @@ -3516,6 +3518,7 @@ static int vnc_display_get_address(const char *addrstr, } static int vnc_display_get_addresses(QemuOpts *opts, + bool reverse, SocketAddress ***retsaddr, size_t *retnsaddr, SocketAddress ***retwsaddr, @@ -3555,7 +3558,7 @@ static int vnc_display_get_addresses(QemuOpts *opts, qemu_opt_iter_init(&addriter, opts, "vnc"); while ((addr = qemu_opt_iter_next(&addriter)) != NULL) { int rv; - rv = vnc_display_get_address(addr, false, 0, to, + rv = vnc_display_get_address(addr, false, reverse, 0, to, has_ipv4, has_ipv6, ipv4, ipv6, &saddr, errp); @@ -3580,7 +3583,7 @@ static int vnc_display_get_addresses(QemuOpts *opts, qemu_opt_iter_init(&addriter, opts, "websocket"); while ((addr = qemu_opt_iter_next(&addriter)) != NULL) { - if (vnc_display_get_address(addr, true, displaynum, to, + if (vnc_display_get_address(addr, true, reverse, displaynum, to, has_ipv4, has_ipv6, ipv4, ipv6, &wsaddr, errp) < 0) { @@ -3777,7 +3780,8 @@ void vnc_display_open(const char *id, Error **errp) return; } - if (vnc_display_get_addresses(opts, &saddr, &nsaddr, + reverse = qemu_opt_get_bool(opts, "reverse", false); + if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr, &wsaddr, &nwsaddr, errp) < 0) { goto fail; } @@ -3803,7 +3807,6 @@ void vnc_display_open(const char *id, Error **errp) } } - reverse = qemu_opt_get_bool(opts, "reverse", false); lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true); key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1); sasl = qemu_opt_get_bool(opts, "sasl", false); |