qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

x_keymap.c (3625B)


      1 /*
      2  * QEMU X11 keymaps
      3  *
      4  * Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com>
      5  * Copyright (C) 2017 Red Hat, Inc
      6  *
      7  * This program is free software; you can redistribute it and/or modify
      8  * it under the terms of the GNU Lesser General Public License version 2.1 as
      9  * published by the Free Software Foundation.
     10  */
     11 
     12 #include "qemu/osdep.h"
     13 
     14 #include "x_keymap.h"
     15 #include "trace.h"
     16 #include "qemu/notify.h"
     17 #include "ui/input.h"
     18 
     19 #include <X11/XKBlib.h>
     20 #include <X11/Xutil.h>
     21 
     22 static gboolean check_for_xwin(Display *dpy)
     23 {
     24     const char *vendor = ServerVendor(dpy);
     25 
     26     trace_xkeymap_vendor(vendor);
     27 
     28     if (strstr(vendor, "Cygwin/X")) {
     29         return TRUE;
     30     }
     31 
     32     return FALSE;
     33 }
     34 
     35 static gboolean check_for_xquartz(Display *dpy)
     36 {
     37     int nextensions;
     38     int i;
     39     gboolean match = FALSE;
     40     char **extensions = XListExtensions(dpy, &nextensions);
     41     for (i = 0 ; extensions != NULL && i < nextensions ; i++) {
     42         trace_xkeymap_extension(extensions[i]);
     43         if (strcmp(extensions[i], "Apple-WM") == 0 ||
     44             strcmp(extensions[i], "Apple-DRI") == 0) {
     45             match = TRUE;
     46         }
     47     }
     48     if (extensions) {
     49         XFreeExtensionList(extensions);
     50     }
     51 
     52     return match;
     53 }
     54 
     55 const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen)
     56 {
     57     XkbDescPtr desc;
     58     const gchar *keycodes = NULL;
     59     const guint16 *map;
     60 
     61     /* There is no easy way to determine what X11 server
     62      * and platform & keyboard driver is in use. Thus we
     63      * do best guess heuristics.
     64      *
     65      * This will need more work for people with other
     66      * X servers..... patches welcomed.
     67      */
     68 
     69     desc = XkbGetMap(dpy,
     70                      XkbGBN_AllComponentsMask,
     71                      XkbUseCoreKbd);
     72     if (desc) {
     73         if (XkbGetNames(dpy, XkbKeycodesNameMask, desc) == Success) {
     74             keycodes = XGetAtomName (dpy, desc->names->keycodes);
     75             if (!keycodes) {
     76                 g_warning("could not lookup keycode name");
     77             } else {
     78                 trace_xkeymap_keycodes(keycodes);
     79             }
     80         }
     81         XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True);
     82     }
     83 
     84     if (check_for_xwin(dpy)) {
     85         trace_xkeymap_keymap("xwin");
     86         *maplen = qemu_input_map_xorgxwin_to_qcode_len;
     87         map = qemu_input_map_xorgxwin_to_qcode;
     88     } else if (check_for_xquartz(dpy)) {
     89         trace_xkeymap_keymap("xquartz");
     90         *maplen = qemu_input_map_xorgxquartz_to_qcode_len;
     91         map = qemu_input_map_xorgxquartz_to_qcode;
     92     } else if ((keycodes && g_str_has_prefix(keycodes, "evdev")) ||
     93                (XKeysymToKeycode(dpy, XK_Page_Up) == 0x70)) {
     94         trace_xkeymap_keymap("evdev");
     95         *maplen = qemu_input_map_xorgevdev_to_qcode_len;
     96         map = qemu_input_map_xorgevdev_to_qcode;
     97     } else if ((keycodes && g_str_has_prefix(keycodes, "xfree86")) ||
     98                (XKeysymToKeycode(dpy, XK_Page_Up) == 0x63)) {
     99         trace_xkeymap_keymap("kbd");
    100         *maplen = qemu_input_map_xorgkbd_to_qcode_len;
    101         map = qemu_input_map_xorgkbd_to_qcode;
    102     } else {
    103         trace_xkeymap_keymap("NULL");
    104         g_warning("Unknown X11 keycode mapping '%s'.\n"
    105                   "Please report to qemu-devel@nongnu.org\n"
    106                   "including the following information:\n"
    107                   "\n"
    108                   "  - Operating system\n"
    109                   "  - X11 Server\n"
    110                   "  - xprop -root\n"
    111                   "  - xdpyinfo\n",
    112                   keycodes ? keycodes : "<null>");
    113         map = NULL;
    114     }
    115     if (keycodes) {
    116         XFree((void *)keycodes);
    117     }
    118     return map;
    119 }