From 2d65683658d975df8c88f024b6ad6e63c2f1646b Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Tue, 21 May 2019 21:59:23 +0900 Subject: [PATCH] ximagesink, xvimagesink: don't use XkbKeycodeToKeysym if Xkb is unavailable ximagesink and xvimagesink use XkbKeycodeToKeysym when the key event is received. However, this function returns NoSymbol if Xkb is unavailable. This causes all key events to be translated to "unknown" key when running ximagsink under some VNC. Fix it by using XKeycodeToKeysym if Xkb is unavailable. --- sys/ximage/meson.build | 8 +++++++- sys/ximage/ximagesink.c | 19 +++++++++++++++++-- sys/ximage/ximagesink.h | 3 +++ sys/xvimage/meson.build | 8 +++++++- sys/xvimage/xvcontext.c | 10 ++++++++++ sys/xvimage/xvcontext.h | 3 +++ sys/xvimage/xvimagesink.c | 9 +++++++-- 7 files changed, 54 insertions(+), 6 deletions(-) diff --git a/sys/ximage/meson.build b/sys/ximage/meson.build index f01bc20187..c2ce79546b 100644 --- a/sys/ximage/meson.build +++ b/sys/ximage/meson.build @@ -1,6 +1,12 @@ +no_warn_args = [] +# XKeycodeToKeysym is deprecated, but we use it when Xkb is unavailable +if cc.has_argument ('-Wno-deprecated-declarations') + no_warn_args += '-Wno-deprecated-declarations' +endif + gstximage = library('gstximagesink', 'ximagesink.c', 'ximage.c', 'ximagepool.c', - c_args : gst_plugins_base_args, + c_args : gst_plugins_base_args + no_warn_args, include_directories: [configinc, libsinc], dependencies : glib_deps + [video_dep, gst_base_dep, gst_dep, x11_dep, xshm_dep], install : true, diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index 2881acb648..36e678d19d 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -631,8 +631,13 @@ gst_x_image_sink_handle_xevents (GstXImageSink * ximagesink) /* Key pressed/released over our window. We send upstream events for interactivity/navigation */ g_mutex_lock (&ximagesink->x_lock); - keysym = XkbKeycodeToKeysym (ximagesink->xcontext->disp, - e.xkey.keycode, 0, 0); + if (ximagesink->xcontext->use_xkb) { + keysym = XkbKeycodeToKeysym (ximagesink->xcontext->disp, + e.xkey.keycode, 0, 0); + } else { + keysym = XKeycodeToKeysym (ximagesink->xcontext->disp, + e.xkey.keycode, 0); + } if (keysym != NoSymbol) { key_str = XKeysymToString (keysym); } else { @@ -844,6 +849,9 @@ gst_x_image_sink_xcontext_get (GstXImageSink * ximagesink) gint endianness; GstVideoFormat vformat; guint32 alpha_mask; + int opcode, event, err; + int major = XkbMajorVersion; + int minor = XkbMinorVersion; g_return_val_if_fail (GST_IS_X_IMAGE_SINK (ximagesink), NULL); @@ -915,6 +923,13 @@ gst_x_image_sink_xcontext_get (GstXImageSink * ximagesink) xcontext->use_xshm = FALSE; GST_DEBUG ("ximagesink is not using XShm extension"); } + if (XkbQueryExtension (xcontext->disp, &opcode, &event, &err, &major, &minor)) { + xcontext->use_xkb = TRUE; + GST_DEBUG ("ximagesink is using Xkb extension"); + } else { + xcontext->use_xkb = FALSE; + GST_DEBUG ("ximagesink is not using Xkb extension"); + } /* extrapolate alpha mask */ if (xcontext->depth == 32) { diff --git a/sys/ximage/ximagesink.h b/sys/ximage/ximagesink.h index 1f29050cb2..8574ef3c13 100644 --- a/sys/ximage/ximagesink.h +++ b/sys/ximage/ximagesink.h @@ -81,6 +81,8 @@ typedef struct _GstXImageSinkClass GstXImageSinkClass; * @heightmm ratio * @use_xshm: used to known whether of not XShm extension is usable or not even * if the Extension is present + * @use_xkb: used to known wether of not Xkb extension is usable or not even + * if the Extension is present * @caps: the #GstCaps that Display @disp can accept * * Structure used to store various information collected/calculated for a @@ -107,6 +109,7 @@ struct _GstXContext GValue *par; /* calculated pixel aspect ratio */ gboolean use_xshm; + gboolean use_xkb; GstCaps *caps; GstCaps *last_caps; diff --git a/sys/xvimage/meson.build b/sys/xvimage/meson.build index 17a736a1d6..b8b8f00478 100644 --- a/sys/xvimage/meson.build +++ b/sys/xvimage/meson.build @@ -6,13 +6,19 @@ xvimage_sources = [ 'xvimagesink.c', ] +no_warn_args = [] +# XKeycodeToKeysym is deprecated, but we use it when Xkb is unavailable +if cc.has_argument ('-Wno-deprecated-declarations') + no_warn_args += '-Wno-deprecated-declarations' +endif + xvideo_dep = dependency('xv', required : get_option('xvideo')) core_conf.set('HAVE_XVIDEO', x11_dep.found() and xvideo_dep.found()) if xvideo_dep.found() gstxvimage = library('gstxvimagesink', xvimage_sources, - c_args : gst_plugins_base_args, + c_args : gst_plugins_base_args + no_warn_args, include_directories: [configinc, libsinc], dependencies : glib_deps + [video_dep, gst_base_dep, gst_dep, x11_dep, xshm_dep, xvideo_dep, libm], install : true, diff --git a/sys/xvimage/xvcontext.c b/sys/xvimage/xvcontext.c index ec87cc8661..7b2cc44902 100644 --- a/sys/xvimage/xvcontext.c +++ b/sys/xvimage/xvcontext.c @@ -636,6 +636,9 @@ gst_xvcontext_new (GstXvContextConfig * config, GError ** error) const char *channels[4] = { "XV_HUE", "XV_SATURATION", "XV_BRIGHTNESS", "XV_CONTRAST" }; + int opcode, event, err; + int major = XkbMajorVersion; + int minor = XkbMinorVersion; g_return_val_if_fail (config != NULL, NULL); @@ -718,6 +721,13 @@ gst_xvcontext_new (GstXvContextConfig * config, GError ** error) context->use_xshm = FALSE; GST_DEBUG ("xvimagesink is not using XShm extension"); } + if (XkbQueryExtension (context->disp, &opcode, &event, &err, &major, &minor)) { + context->use_xkb = TRUE; + GST_DEBUG ("xvimagesink is using Xkb extension"); + } else { + context->use_xkb = FALSE; + GST_DEBUG ("xvimagesink is not using Xkb extension"); + } xv_attr = XvQueryPortAttributes (context->disp, context->xv_port_id, &N_attr); diff --git a/sys/xvimage/xvcontext.h b/sys/xvimage/xvcontext.h index 83886687ea..4efe3f009b 100644 --- a/sys/xvimage/xvcontext.h +++ b/sys/xvimage/xvcontext.h @@ -110,6 +110,8 @@ struct _GstXvImageFormat * @heightmm ratio * @use_xshm: used to known whether of not XShm extension is usable or not even * if the Extension is present + * @use_xkb: used to known wether of not Xkb extension is usable or not even + * if the Extension is present * @xv_port_id: the XVideo port ID * @im_format: used to store at least a valid format for XShm calls checks * @formats_list: list of supported image formats on @xv_port_id @@ -145,6 +147,7 @@ struct _GstXvContext GValue *par; /* calculated pixel aspect ratio */ gboolean use_xshm; + gboolean use_xkb; XvPortID xv_port_id; guint nb_adaptors; diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c index 50d9dd28ce..babf51514e 100644 --- a/sys/xvimage/xvimagesink.c +++ b/sys/xvimage/xvimagesink.c @@ -485,8 +485,13 @@ gst_xv_image_sink_handle_xevents (GstXvImageSink * xvimagesink) /* Key pressed/released over our window. We send upstream events for interactivity/navigation */ g_mutex_lock (&xvimagesink->context->lock); - keysym = XkbKeycodeToKeysym (xvimagesink->context->disp, - e.xkey.keycode, 0, 0); + if (xvimagesink->context->use_xkb) { + keysym = XkbKeycodeToKeysym (xvimagesink->context->disp, + e.xkey.keycode, 0, 0); + } else { + keysym = XKeycodeToKeysym (xvimagesink->context->disp, + e.xkey.keycode, 0); + } if (keysym != NoSymbol) { key_str = XKeysymToString (keysym); } else {