[libvirt] [PATCH 11/13] send-key: support KEY_XXX names for the linux keycode

Daniel P. Berrange berrange at redhat.com
Wed May 25 20:30:55 UTC 2011


On Wed, May 25, 2011 at 05:37:53PM +0800, Lai Jiangshan wrote:
> It make send-key command more friendly for user.
> 
> Signed-off-by: Lai Jiangshan <laijs at fujitsu.com>
> ---
>  include/libvirt/virtkeys.h |  253 ++++++++++++++++++++++++++++++++++++++++++++
>  tools/virsh.c              |   21 ++++
>  2 files changed, 274 insertions(+), 0 deletions(-)
> 
> diff --git a/include/libvirt/virtkeys.h b/include/libvirt/virtkeys.h
> index eb07129..7893450 100644
> --- a/include/libvirt/virtkeys.h
> +++ b/include/libvirt/virtkeys.h
> @@ -20,4 +20,257 @@ enum libvirt_keycode_set {
>  
>  #define MAX_SEND_KEY  16
>  
> +#define ITEM_KEYCODE(KEY_XXX) VIRT##KEY_XXX
> +#define KEYCODES()                     \
> +    keycode(KEY_ESC,                 1)\
> +    keycode(KEY_1,                   2)\
> +    keycode(KEY_2,                   3)\
> +    keycode(KEY_3,                   4)\
> +    keycode(KEY_4,                   5)\
> +    keycode(KEY_5,                   6)\
> +    keycode(KEY_6,                   7)\
> +    keycode(KEY_7,                   8)\
> +    keycode(KEY_8,                   9)\
> +    keycode(KEY_9,                   10)\
> +    keycode(KEY_0,                   11)\
> +    keycode(KEY_MINUS,               12)\
> +    keycode(KEY_EQUAL,               13)\
> +    keycode(KEY_BACKSPACE,           14)\
> +    keycode(KEY_TAB,                 15)\
> +    keycode(KEY_Q,                   16)\
> +    keycode(KEY_W,                   17)\
> +    keycode(KEY_E,                   18)\
> +    keycode(KEY_R,                   19)\
> +    keycode(KEY_T,                   20)\
> +    keycode(KEY_Y,                   21)\
> +    keycode(KEY_U,                   22)\
> +    keycode(KEY_I,                   23)\
> +    keycode(KEY_O,                   24)\
> +    keycode(KEY_P,                   25)\
> +    keycode(KEY_LEFTBRACE,           26)\
> +    keycode(KEY_RIGHTBRACE,          27)\
> +    keycode(KEY_ENTER,               28)\
> +    keycode(KEY_LEFTCTRL,            29)\
> +    keycode(KEY_A,                   30)\
> +    keycode(KEY_S,                   31)\
> +    keycode(KEY_D,                   32)\
> +    keycode(KEY_F,                   33)\
> +    keycode(KEY_G,                   34)\
> +    keycode(KEY_H,                   35)\
> +    keycode(KEY_J,                   36)\
> +    keycode(KEY_K,                   37)\
> +    keycode(KEY_L,                   38)\
> +    keycode(KEY_SEMICOLON,           39)\
> +    keycode(KEY_APOSTROPHE,          40)\
> +    keycode(KEY_GRAVE,               41)\
> +    keycode(KEY_LEFTSHIFT,           42)\
> +    keycode(KEY_BACKSLASH,           43)\
> +    keycode(KEY_Z,                   44)\
> +    keycode(KEY_X,                   45)\
> +    keycode(KEY_C,                   46)\
> +    keycode(KEY_V,                   47)\
> +    keycode(KEY_B,                   48)\
> +    keycode(KEY_N,                   49)\
> +    keycode(KEY_M,                   50)\
> +    keycode(KEY_COMMA,               51)\
> +    keycode(KEY_DOT,                 52)\
> +    keycode(KEY_SLASH,               53)\
> +    keycode(KEY_RIGHTSHIFT,          54)\
> +    keycode(KEY_KPASTERISK,          55)\
> +    keycode(KEY_LEFTALT,             56)\
> +    keycode(KEY_SPACE,               57)\
> +    keycode(KEY_CAPSLOCK,            58)\
> +    keycode(KEY_F1,                  59)\
> +    keycode(KEY_F2,                  60)\
> +    keycode(KEY_F3,                  61)\
> +    keycode(KEY_F4,                  62)\
> +    keycode(KEY_F5,                  63)\
> +    keycode(KEY_F6,                  64)\
> +    keycode(KEY_F7,                  65)\
> +    keycode(KEY_F8,                  66)\
> +    keycode(KEY_F9,                  67)\
> +    keycode(KEY_F10,                 68)\
> +    keycode(KEY_NUMLOCK,             69)\
> +    keycode(KEY_SCROLLLOCK,          70)\
> +    keycode(KEY_KP7,                 71)\
> +    keycode(KEY_KP8,                 72)\
> +    keycode(KEY_KP9,                 73)\
> +    keycode(KEY_KPMINUS,             74)\
> +    keycode(KEY_KP4,                 75)\
> +    keycode(KEY_KP5,                 76)\
> +    keycode(KEY_KP6,                 77)\
> +    keycode(KEY_KPPLUS,              78)\
> +    keycode(KEY_KP1,                 79)\
> +    keycode(KEY_KP2,                 80)\
> +    keycode(KEY_KP3,                 81)\
> +    keycode(KEY_KP0,                 82)\
> +    keycode(KEY_KPDOT,               83)\
> +    keycode(KEY_ZENKAKUHANKAKU,      85)\
> +    keycode(KEY_102ND,               86)\
> +    keycode(KEY_F11,                 87)\
> +    keycode(KEY_F12,                 88)\
> +    keycode(KEY_RO,                  89)\
> +    keycode(KEY_KATAKANA,            90)\
> +    keycode(KEY_HIRAGANA,            91)\
> +    keycode(KEY_HENKAN,              92)\
> +    keycode(KEY_KATAKANAHIRAGANA,    93)\
> +    keycode(KEY_MUHENKAN,            94)\
> +    keycode(KEY_KPJPCOMMA,           95)\
> +    keycode(KEY_KPENTER,             96)\
> +    keycode(KEY_RIGHTCTRL,           97)\
> +    keycode(KEY_KPSLASH,             98)\
> +    keycode(KEY_SYSRQ,               99)\
> +    keycode(KEY_RIGHTALT,            100)\
> +    keycode(KEY_LINEFEED,            101)\
> +    keycode(KEY_HOME,                102)\
> +    keycode(KEY_UP,                  103)\
> +    keycode(KEY_PAGEUP,              104)\
> +    keycode(KEY_LEFT,                105)\
> +    keycode(KEY_RIGHT,               106)\
> +    keycode(KEY_END,                 107)\
> +    keycode(KEY_DOWN,                108)\
> +    keycode(KEY_PAGEDOWN,            109)\
> +    keycode(KEY_INSERT,              110)\
> +    keycode(KEY_DELETE,              111)\
> +    keycode(KEY_MACRO,               112)\
> +    keycode(KEY_MUTE,                113)\
> +    keycode(KEY_VOLUMEDOWN,          114)\
> +    keycode(KEY_VOLUMEUP,            115)\
> +    keycode(KEY_POWER,               116)\
> +    keycode(KEY_KPEQUAL,             117)\
> +    keycode(KEY_KPPLUSMINUS,         118)\
> +    keycode(KEY_PAUSE,               119)\
> +    keycode(KEY_SCALE,               120)\
> +    keycode(KEY_KPCOMMA,             121)\
> +    keycode(KEY_HANGEUL,             122)\
> +    keycode(KEY_HANGUEL,             122)\
> +    keycode(KEY_HANJA,               123)\
> +    keycode(KEY_YEN,                 124)\
> +    keycode(KEY_LEFTMETA,            125)\
> +    keycode(KEY_RIGHTMETA,           126)\
> +    keycode(KEY_COMPOSE,             127)\
> +    keycode(KEY_STOP,                128)\
> +    keycode(KEY_AGAIN,               129)\
> +    keycode(KEY_PROPS,               130)\
> +    keycode(KEY_UNDO,                131)\
> +    keycode(KEY_FRONT,               132)\
> +    keycode(KEY_COPY,                133)\
> +    keycode(KEY_OPEN,                134)\
> +    keycode(KEY_PASTE,               135)\
> +    keycode(KEY_FIND,                136)\
> +    keycode(KEY_CUT,                 137)\
> +    keycode(KEY_HELP,                138)\
> +    keycode(KEY_MENU,                139)\
> +    keycode(KEY_CALC,                140)\
> +    keycode(KEY_SETUP,               141)\
> +    keycode(KEY_SLEEP,               142)\
> +    keycode(KEY_WAKEUP,              143)\
> +    keycode(KEY_FILE,                144)\
> +    keycode(KEY_SENDFILE,            145)\
> +    keycode(KEY_DELETEFILE,          146)\
> +    keycode(KEY_XFER,                147)\
> +    keycode(KEY_PROG1,               148)\
> +    keycode(KEY_PROG2,               149)\
> +    keycode(KEY_WWW,                 150)\
> +    keycode(KEY_MSDOS,               151)\
> +    keycode(KEY_COFFEE,              152)\
> +    keycode(KEY_SCREENLOCK,          152)\
> +    keycode(KEY_DIRECTION,           153)\
> +    keycode(KEY_CYCLEWINDOWS,        154)\
> +    keycode(KEY_MAIL,                155)\
> +    keycode(KEY_BOOKMARKS,           156)\
> +    keycode(KEY_COMPUTER,            157)\
> +    keycode(KEY_BACK,                158)\
> +    keycode(KEY_FORWARD,             159)\
> +    keycode(KEY_CLOSECD,             160)\
> +    keycode(KEY_EJECTCD,             161)\
> +    keycode(KEY_EJECTCLOSECD,        162)\
> +    keycode(KEY_NEXTSONG,            163)\
> +    keycode(KEY_PLAYPAUSE,           164)\
> +    keycode(KEY_PREVIOUSSONG,        165)\
> +    keycode(KEY_STOPCD,              166)\
> +    keycode(KEY_RECORD,              167)\
> +    keycode(KEY_REWIND,              168)\
> +    keycode(KEY_PHONE,               169)\
> +    keycode(KEY_ISO,                 170)\
> +    keycode(KEY_CONFIG,              171)\
> +    keycode(KEY_HOMEPAGE,            172)\
> +    keycode(KEY_REFRESH,             173)\
> +    keycode(KEY_EXIT,                174)\
> +    keycode(KEY_MOVE,                175)\
> +    keycode(KEY_EDIT,                176)\
> +    keycode(KEY_SCROLLUP,            177)\
> +    keycode(KEY_SCROLLDOWN,          178)\
> +    keycode(KEY_KPLEFTPAREN,         179)\
> +    keycode(KEY_KPRIGHTPAREN,        180)\
> +    keycode(KEY_NEW,                 181)\
> +    keycode(KEY_REDO,                182)\
> +    keycode(KEY_F13,                 183)\
> +    keycode(KEY_F14,                 184)\
> +    keycode(KEY_F15,                 185)\
> +    keycode(KEY_F16,                 186)\
> +    keycode(KEY_F17,                 187)\
> +    keycode(KEY_F18,                 188)\
> +    keycode(KEY_F19,                 189)\
> +    keycode(KEY_F20,                 190)\
> +    keycode(KEY_F21,                 191)\
> +    keycode(KEY_F22,                 192)\
> +    keycode(KEY_F23,                 193)\
> +    keycode(KEY_F24,                 194)\
> +    keycode(KEY_PLAYCD,              200)\
> +    keycode(KEY_PAUSECD,             201)\
> +    keycode(KEY_PROG3,               202)\
> +    keycode(KEY_PROG4,               203)\
> +    keycode(KEY_DASHBOARD,           204)\
> +    keycode(KEY_SUSPEND,             205)\
> +    keycode(KEY_CLOSE,               206)\
> +    keycode(KEY_PLAY,                207)\
> +    keycode(KEY_FASTFORWARD,         208)\
> +    keycode(KEY_BASSBOOST,           209)\
> +    keycode(KEY_PRINT,               210)\
> +    keycode(KEY_HP,                  211)\
> +    keycode(KEY_CAMERA,              212)\
> +    keycode(KEY_SOUND,               213)\
> +    keycode(KEY_QUESTION,            214)\
> +    keycode(KEY_EMAIL,               215)\
> +    keycode(KEY_CHAT,                216)\
> +    keycode(KEY_SEARCH,              217)\
> +    keycode(KEY_CONNECT,             218)\
> +    keycode(KEY_FINANCE,             219)\
> +    keycode(KEY_SPORT,               220)\
> +    keycode(KEY_SHOP,                221)\
> +    keycode(KEY_ALTERASE,            222)\
> +    keycode(KEY_CANCEL,              223)\
> +    keycode(KEY_BRIGHTNESSDOWN,      224)\
> +    keycode(KEY_BRIGHTNESSUP,        225)\
> +    keycode(KEY_MEDIA,               226)\
> +    keycode(KEY_SWITCHVIDEOMODE,     227)\
> +    keycode(KEY_KBDILLUMTOGGLE,      228)\
> +    keycode(KEY_KBDILLUMDOWN,        229)\
> +    keycode(KEY_KBDILLUMUP,          230)\
> +    keycode(KEY_SEND,                231)\
> +    keycode(KEY_REPLY,               232)\
> +    keycode(KEY_FORWARDMAIL,         233)\
> +    keycode(KEY_SAVE,                234)\
> +    keycode(KEY_DOCUMENTS,           235)\
> +    keycode(KEY_BATTERY,             236)\
> +    keycode(KEY_BLUETOOTH,           237)\
> +    keycode(KEY_WLAN,                238)\
> +    keycode(KEY_UWB,                 239)\
> +    keycode(KEY_UNKNOWN,             240)\
> +    keycode(KEY_VIDEO_NEXT,          241)\
> +    keycode(KEY_VIDEO_PREV,          242)\
> +    keycode(KEY_BRIGHTNESS_CYCLE,    243)\
> +    keycode(KEY_BRIGHTNESS_ZERO,     244)\
> +    keycode(KEY_DISPLAY_OFF,         245)\
> +    keycode(KEY_WIMAX,               246)\
> +    keycode(KEY_RFKILL,              247)
> +
> +/* define keycode constants */
> +enum {
> +#define keycode(KEY_XXX, value) ITEM_KEYCODE(KEY_XXX) = value,
> +    KEYCODES()
> +#undef keycode
> +};




> +
>  #endif
> diff --git a/tools/virsh.c b/tools/virsh.c
> index 505a821..3bccc08 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -3017,9 +3017,16 @@ cmdInjectNMI(vshControl *ctl, const vshCmd *cmd)
>  static const vshCmdInfo info_send_key[] = {
>      {"help", N_("Send keycodes to the guest")},
>      {"desc", N_("Send keycodes to the guest, the keycodes must be integers\n"
> +                "    or the KEY_* strings listed below for the \"linux\" codeset.\n\n"
>                  "    Examples:\n\n"
>                  "        virsh # send-key <domain> 37 18 21\n"
>                  "        virsh # send-key <domain> --holdtime 1000 0x15 18 0xf\n"
> +                "        virsh # send-eky <domain> KEY_LEFTCTRL KEY_LEFTALT KEY_F1\n"
> +                "\n"
> +                "    KEY_XXX strings for the \"linux\" codeset:\n"
> +#define keycode(var, value) "    "  #var " = " #value "\n"
> +                KEYCODES())},
> +#undef keycode
>      {NULL, NULL}
>  };
>  
> @@ -3032,6 +3039,17 @@ static const vshCmdOptDef opts_send_key[] = {
>      {NULL, 0, 0, NULL}
>  };
>  
> +static int get_linux_keycode(const char *key_name)
> +{
> +    if (key_name[0] == 'K' && key_name[1] == 'E' && key_name[2] == 'Y' &&
> +        key_name[3] == '_') {
> +#define keycode(var, value) if (STREQ(#var + 4, key_name + 4)) return value;
> +        KEYCODES()
> +#undef  keycode
> +    }
> +    return -1;
> +}
> +
>  static int get_integer_keycode(const char *key_name)
>  {
>      long val;
> @@ -3092,6 +3110,9 @@ cmdSendKey(vshControl *ctl, const vshCmd *cmd)
>              goto free_domain;
>          }
>  
> +        if ((keycode = get_linux_keycode(opt->data)) > 0)
> +            goto get_keycode;
> +
>          if ((keycode = get_integer_keycode(opt->data)) > 0)
>              goto get_keycode;

Rather than hardcode two big tables in the source code I would like to
have all these keycode tables automatically generated, from a master
data file in the source tree.

For the GTK-VNC application, I constructed a giant CSV data file which
has mappings for all common keycode sets.

   http://git.gnome.org/browse/gtk-vnc/tree/src/keymaps.csv

Copy this csv file into the libvirt source tree.

I also have a script which takes the CSV file and can generate big
tables for mapping between 2 different keycode sets:

  http://git.gnome.org/browse/gtk-vnc/tree/src/keymap-gen.pl

You can take that keymap-gen.pl script and extend the code, so that it
can also generate the data for virtkeys.h

Eventually, I'll move the keymaps.csv/keymap-gen.pl into a separate
project, which can be packaged up & shared between libvirt, gtk-vnc
and spice-gtk, so we only have one place to update keycode mappings

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list