| 
									
										
										
										
											2007-01-24 21:40:21 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |  * QEMU X11 keymaps | 
					
						
							| 
									
										
										
										
											2007-01-24 21:40:21 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |  * Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com> | 
					
						
							|  |  |  |  * Copyright (C) 2017 Red Hat, Inc | 
					
						
							| 
									
										
										
										
											2007-01-24 21:40:21 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2020-10-23 12:44:24 +00:00
										 |  |  |  * it under the terms of the GNU Lesser General Public License version 2.1 as | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |  * published by the Free Software Foundation. | 
					
						
							| 
									
										
										
										
											2007-01-24 21:40:21 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-29 17:49:51 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-03 17:37:21 +00:00
										 |  |  | #include "x_keymap.h"
 | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  | #include "trace.h"
 | 
					
						
							|  |  |  | #include "qemu/notify.h"
 | 
					
						
							|  |  |  | #include "ui/input.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  | #include <X11/XKBlib.h>
 | 
					
						
							| 
									
										
										
										
											2018-03-13 10:42:35 +00:00
										 |  |  | #include <X11/Xutil.h>
 | 
					
						
							| 
									
										
										
										
											2007-01-24 21:40:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  | static gboolean check_for_xwin(Display *dpy) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *vendor = ServerVendor(dpy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     trace_xkeymap_vendor(vendor); | 
					
						
							| 
									
										
										
										
											2009-03-03 17:37:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |     if (strstr(vendor, "Cygwin/X")) { | 
					
						
							|  |  |  |         return TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-03-03 17:37:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean check_for_xquartz(Display *dpy) | 
					
						
							| 
									
										
										
										
											2009-03-03 17:37:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |     int nextensions; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     gboolean match = FALSE; | 
					
						
							|  |  |  |     char **extensions = XListExtensions(dpy, &nextensions); | 
					
						
							|  |  |  |     for (i = 0 ; extensions != NULL && i < nextensions ; i++) { | 
					
						
							|  |  |  |         trace_xkeymap_extension(extensions[i]); | 
					
						
							|  |  |  |         if (strcmp(extensions[i], "Apple-WM") == 0 || | 
					
						
							|  |  |  |             strcmp(extensions[i], "Apple-DRI") == 0) { | 
					
						
							|  |  |  |             match = TRUE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (extensions) { | 
					
						
							|  |  |  |         XFreeExtensionList(extensions); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return match; | 
					
						
							| 
									
										
										
										
											2009-03-03 17:37:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  | const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen) | 
					
						
							| 
									
										
										
										
											2007-01-24 21:40:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |     XkbDescPtr desc; | 
					
						
							|  |  |  |     const gchar *keycodes = NULL; | 
					
						
							| 
									
										
										
										
											2021-04-30 17:50:09 +02:00
										 |  |  |     const guint16 *map; | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* There is no easy way to determine what X11 server
 | 
					
						
							|  |  |  |      * and platform & keyboard driver is in use. Thus we | 
					
						
							|  |  |  |      * do best guess heuristics. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * This will need more work for people with other | 
					
						
							|  |  |  |      * X servers..... patches welcomed. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     desc = XkbGetMap(dpy, | 
					
						
							|  |  |  |                      XkbGBN_AllComponentsMask, | 
					
						
							|  |  |  |                      XkbUseCoreKbd); | 
					
						
							|  |  |  |     if (desc) { | 
					
						
							|  |  |  |         if (XkbGetNames(dpy, XkbKeycodesNameMask, desc) == Success) { | 
					
						
							|  |  |  |             keycodes = XGetAtomName (dpy, desc->names->keycodes); | 
					
						
							|  |  |  |             if (!keycodes) { | 
					
						
							|  |  |  |                 g_warning("could not lookup keycode name"); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 trace_xkeymap_keycodes(keycodes); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (check_for_xwin(dpy)) { | 
					
						
							|  |  |  |         trace_xkeymap_keymap("xwin"); | 
					
						
							|  |  |  |         *maplen = qemu_input_map_xorgxwin_to_qcode_len; | 
					
						
							| 
									
										
										
										
											2021-04-30 17:50:09 +02:00
										 |  |  |         map = qemu_input_map_xorgxwin_to_qcode; | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |     } else if (check_for_xquartz(dpy)) { | 
					
						
							|  |  |  |         trace_xkeymap_keymap("xquartz"); | 
					
						
							|  |  |  |         *maplen = qemu_input_map_xorgxquartz_to_qcode_len; | 
					
						
							| 
									
										
										
										
											2021-04-30 17:50:09 +02:00
										 |  |  |         map = qemu_input_map_xorgxquartz_to_qcode; | 
					
						
							| 
									
										
										
										
											2018-03-13 10:42:35 +00:00
										 |  |  |     } else if ((keycodes && g_str_has_prefix(keycodes, "evdev")) || | 
					
						
							|  |  |  |                (XKeysymToKeycode(dpy, XK_Page_Up) == 0x70)) { | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |         trace_xkeymap_keymap("evdev"); | 
					
						
							|  |  |  |         *maplen = qemu_input_map_xorgevdev_to_qcode_len; | 
					
						
							| 
									
										
										
										
											2021-04-30 17:50:09 +02:00
										 |  |  |         map = qemu_input_map_xorgevdev_to_qcode; | 
					
						
							| 
									
										
										
										
											2018-03-13 10:42:35 +00:00
										 |  |  |     } else if ((keycodes && g_str_has_prefix(keycodes, "xfree86")) || | 
					
						
							|  |  |  |                (XKeysymToKeycode(dpy, XK_Page_Up) == 0x63)) { | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |         trace_xkeymap_keymap("kbd"); | 
					
						
							|  |  |  |         *maplen = qemu_input_map_xorgkbd_to_qcode_len; | 
					
						
							| 
									
										
										
										
											2021-04-30 17:50:09 +02:00
										 |  |  |         map = qemu_input_map_xorgkbd_to_qcode; | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         trace_xkeymap_keymap("NULL"); | 
					
						
							|  |  |  |         g_warning("Unknown X11 keycode mapping '%s'.\n" | 
					
						
							|  |  |  |                   "Please report to qemu-devel@nongnu.org\n" | 
					
						
							|  |  |  |                   "including the following information:\n" | 
					
						
							|  |  |  |                   "\n" | 
					
						
							|  |  |  |                   "  - Operating system\n" | 
					
						
							|  |  |  |                   "  - X11 Server\n" | 
					
						
							|  |  |  |                   "  - xprop -root\n" | 
					
						
							|  |  |  |                   "  - xdpyinfo\n", | 
					
						
							|  |  |  |                   keycodes ? keycodes : "<null>"); | 
					
						
							| 
									
										
										
										
											2021-04-30 17:50:09 +02:00
										 |  |  |         map = NULL; | 
					
						
							| 
									
										
										
										
											2018-01-17 16:47:15 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-30 17:50:09 +02:00
										 |  |  |     if (keycodes) { | 
					
						
							|  |  |  |         XFree((void *)keycodes); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return map; | 
					
						
							| 
									
										
										
										
											2007-01-24 21:40:21 +00:00
										 |  |  | } |