[Spice-devel] [spice-gtk 1/3] Send Zenkaku_Hankaku key in JP keyboard.

Frediano Ziglio fziglio at redhat.com
Thu Mar 31 13:12:33 UTC 2016


> 
> From: Takao Fujiwara <tfujiwar at redhat.com>
> 
> MapVirtualKey() returns the scancode of the released Zenkaku_Hankaku key
> but does not pressed one and modifiered one. Any cases should be sent
> to use input method engines.
> ---
>  src/spice-widget-priv.h |  1 +
>  src/spice-widget.c      | 37 +++++++++++++++++++++++++++++++++++--
>  2 files changed, 36 insertions(+), 2 deletions(-)
> 
> diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h
> index 95bca8a..05f6a90 100644
> --- a/src/spice-widget-priv.h
> +++ b/src/spice-widget-priv.h
> @@ -119,6 +119,7 @@ struct _SpiceDisplayPrivate {
>      HHOOK                   keyboard_hook;
>      int                     win_mouse[3];
>      int                     win_mouse_speed;
> +    HKL                     keyboard_layout;
>  #endif
>      guint                   keypress_delay;
>      gint                    zoom_level;
> diff --git a/src/spice-widget.c b/src/spice-widget.c
> index f605439..4e026f3 100644
> --- a/src/spice-widget.c
> +++ b/src/spice-widget.c
> @@ -644,6 +644,9 @@ static void spice_display_init(SpiceDisplay *display)
>      d->grabseq = spice_grab_sequence_new_from_string("Control_L+Alt_L");
>      d->activeseq = g_new0(gboolean, d->grabseq->nkeysyms);
>      d->mouse_cursor = get_blank_cursor();
> +#ifdef G_OS_WIN32
> +    d->keyboard_layout = GetKeyboardLayout(0);
> +#endif
>  }
>  

You should handle WM_INPUTLANGCHANGE so use can change layout while using
remote-viewer. Another option is not cache the value but just call
GetKeyboardLayout(0) every time.

>  static GObject *
> @@ -1418,6 +1421,7 @@ static gboolean key_event(GtkWidget *widget,
> GdkEventKey *key)
>      SpiceDisplay *display = SPICE_DISPLAY(widget);
>      SpiceDisplayPrivate *d = display->priv;
>      int scancode;
> +    int native_scancode;
>  
>  #ifdef G_OS_WIN32
>      /* on windows, we ought to ignore the reserved key event? */
> @@ -1464,9 +1468,38 @@ static gboolean key_event(GtkWidget *widget,
> GdkEventKey *key)
>      scancode = vnc_display_keymap_gdk2xtkbd(d->keycode_map,
>      d->keycode_maplen,
>                                              key->hardware_keycode);
>  #ifdef G_OS_WIN32
> +    native_scancode = MapVirtualKey(key->hardware_keycode, MAPVK_VK_TO_VSC);
> +
> +    /* Some OEM virtual-key codes are missed in MapVirtualKey(). */
> +    switch (HIWORD(d->keyboard_layout)) {

As documented in GetKeyboardLayout the language id is in the low word
so you should use LOWORD.

> +    case 0x411:                         /* JP keyboard */

You can use MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN) instead of 0x411

> +        if (native_scancode == 0) {
> +            switch (key->hardware_keycode) {
> +            case VK_OEM_ENLW:           /* from Pressed Zenkaku_Hankaku */

The Japanese layout is a Microsoft keyboard, there are VK_DBE_ constants
in ime.h, in this case

VK_OEM_ENLW -> VK_DBE_DBCSCHAR
VK_OEM_AUTO -> VK_DBE_SBCSCHAR
VK_OEM_ATTN -> VK_DBE_ALPHANUMERIC
VK_OEM_BACKTAB -> VK_DBE_ROMAN
VK_OEM_COPY -> VK_DBE_HIRAGANA

> +            case VK_KANJI:              /* from Alt + Zenkaku_Hankaku */
> +                scancode = MapVirtualKey(VK_OEM_AUTO, MAPVK_VK_TO_VSC);
> +                                        /* to Released Zenkaku_Hankaku */
> +                goto got_scancode;
> +            case VK_CAPITAL:            /* from Alt + Eisu_toggle */

VK_CAPITAL is Shift + Eisu_toggle

> +                scancode = MapVirtualKey(VK_OEM_ATTN, MAPVK_VK_TO_VSC);
> +                                        /* to Eisu_toggle */
> +                goto got_scancode;
> +            case VK_OEM_BACKTAB:        /* from Alt + Hiragana_Katakana */
> +                scancode = MapVirtualKey(VK_OEM_COPY, MAPVK_VK_TO_VSC);
> +                                        /* to Hiragana_Katakana */
> +                goto got_scancode;
> +            default:;
> +            }
> +        }
> +        break;
> +    default:;
> +    }
> +

You probably want to support also

VK_DBE_CODEINPUT (Control + Alt + Eisu)
VK_DBE_ENTERIMECONFIGMODE (Control + Alt + Zenkaku_Hankaku)
VK_KANA (Shift + Control + Hiragana_Katakana)
VK_DBE_ENTERWORDREGISTERMODE (Control+Alt+Muhenkan)

Note that also some combinations (like Control+Alt+Shift+Hiragana) produce no events.

I'm not sure this patch is portable between Windows 7 and Windows 10.

>      /* MapVirtualKey doesn't return scancode with needed higher byte */
> -    scancode = MapVirtualKey(key->hardware_keycode, MAPVK_VK_TO_VSC) |
> -        (scancode & 0xff00);
> +    scancode = native_scancode | (scancode & 0xff00);
> +
> +got_scancode:
> +
>  #endif
>  
>      switch (key->type) {

Frediano


More information about the Spice-devel mailing list