[Spice-devel] [PATCH spice-gtk v2 2/2] Send keyboard description
Marc-André Lureau
mlureau at redhat.com
Wed Nov 5 05:48:28 PST 2014
----- Original Message -----
> The keyboard description of the client will be sent to the guest
> when the connection is established.
>
> RFE: https://bugs.freedesktop.org/show_bug.cgi?id=85332
> ---
> v2:
> - reduced indentation level
> - removed checking all the channels
> ---
> gtk/spice-gtk-session-priv.h | 1 +
> gtk/spice-gtk-session.c | 62
> ++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 63 insertions(+)
>
> diff --git a/gtk/spice-gtk-session-priv.h b/gtk/spice-gtk-session-priv.h
> index 91304b2..571f91f 100644
> --- a/gtk/spice-gtk-session-priv.h
> +++ b/gtk/spice-gtk-session-priv.h
> @@ -28,6 +28,7 @@ gboolean spice_gtk_session_get_read_only(SpiceGtkSession
> *self);
> void spice_gtk_session_sync_keyboard_modifiers(SpiceGtkSession *self);
> void spice_gtk_session_set_pointer_grabbed(SpiceGtkSession *self, gboolean
> grabbed);
> gboolean spice_gtk_session_get_pointer_grabbed(SpiceGtkSession *self);
> +void spice_gtk_session_sync_keyboard_layout(SpiceGtkSession *self);
>
> G_END_DECLS
>
> diff --git a/gtk/spice-gtk-session.c b/gtk/spice-gtk-session.c
> index 52ad597..cc02ec8 100644
> --- a/gtk/spice-gtk-session.c
> +++ b/gtk/spice-gtk-session.c
> @@ -178,6 +178,13 @@ static void
> spice_gtk_session_sync_keyboard_modifiers_for_channel(SpiceGtkSessio
> }
> }
>
> +static void keymap_layout_changed(GdkKeymap *keymap, gpointer data)
> +{
> + SpiceGtkSession *self = data;
> +
> + spice_gtk_session_sync_keyboard_layout(self);
> +}
> +
> static void keymap_modifiers_changed(GdkKeymap *keymap, gpointer data)
> {
> SpiceGtkSession *self = data;
> @@ -207,6 +214,8 @@ static void spice_gtk_session_init(SpiceGtkSession *self)
> G_CALLBACK(clipboard_owner_change), self);
> spice_g_signal_connect_object(keymap, "state-changed",
> G_CALLBACK(keymap_modifiers_changed),
> self, 0);
> + spice_g_signal_connect_object(keymap, "keys-changed",
> + G_CALLBACK(keymap_layout_changed), self,
> 0);
> }
>
> static GObject *
> @@ -1001,6 +1010,15 @@ static void channel_new(SpiceSession *session,
> SpiceChannel *channel,
> G_CALLBACK(clipboard_request), self);
> g_signal_connect(channel, "main-clipboard-selection-release",
> G_CALLBACK(clipboard_release), self);
> + gboolean agent_connected;
> + g_object_get(channel, "agent-connected", &agent_connected, NULL);
> + if (agent_connected) {
> + spice_gtk_session_sync_keyboard_layout(self);
> + } else {
> + g_signal_connect_swapped(channel, "notify::agent-connected",
> +
> G_CALLBACK(spice_gtk_session_sync_keyboard_layout),
> + self);
> + }
> }
> if (SPICE_IS_INPUTS_CHANNEL(channel)) {
> spice_g_signal_connect_object(channel, "inputs-modifiers",
> @@ -1195,3 +1213,47 @@ gboolean
> spice_gtk_session_get_pointer_grabbed(SpiceGtkSession *self)
>
> return self->priv->pointer_grabbed;
> }
> +
> +static gchar *get_keyboard_description(void)
> +{
> + gchar *keyboard_description = NULL;
> +#ifdef HAVE_X11_XKBLIB_H
> + Display *dpy;
> + XkbDescPtr xkb;
> + int major = XkbMajorVersion, minor = XkbMinorVersion;
> +
> + dpy = XkbOpenDisplay(NULL, NULL, NULL, &major, &minor, NULL);
> + g_return_val_if_fail(dpy != NULL, NULL);
> +
> + xkb = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
> + g_return_val_if_fail(xkb != NULL, NULL);
Actually here you must not return with g_return_val_if_fail(), so you should first g_warn_if_fail() and then cleanup the dpy and return.
> +
> + keyboard_description = g_strdelimit(
> + g_strdup_printf("%s", XGetAtomName(dpy, xkb->names->symbols)),
> "_",'+');
> + XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
> + XCloseDisplay(dpy);
> +#elif defined(G_OS_WIN32)
> + gchar *locale, *region;
> + locale = g_win32_getlocale();
> + region = g_ascii_strdown(g_strrstr(locale, "_")+1, -1);
> + g_free(locale);
> + keyboard_description = g_strdup_printf("pc+%s", region);
> + g_free(region);
> +#endif
> + return keyboard_description;
> +}
> +
> +G_GNUC_INTERNAL
> +void spice_gtk_session_sync_keyboard_layout(SpiceGtkSession *self)
> +{
> + SpiceGtkSessionPrivate *s = self->priv;
> + gchar *keyboard_description = get_keyboard_description();
> + gboolean agent_connected;
> +
> + if (keyboard_description == NULL)
> + return;
> + g_object_get(s->main, "agent-connected", &agent_connected, NULL);
> + if (agent_connected)
> + spice_main_send_keyboard_description(s->main, keyboard_description);
> + g_free(keyboard_description);
> +}
> --
> 1.9.3
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
>
More information about the Spice-devel
mailing list