[Bf-blender-cvs] [f3427cbc981] master: GHOST/X11: support accessing physical keycodes

Campbell Barton noreply at git.blender.org
Sat Jun 9 11:26:10 CEST 2018


Commit: f3427cbc981e5ad530d1a73ab4ecbf6b64751774
Author: Campbell Barton
Date:   Sat Jun 9 11:23:41 2018 +0200
Branches: master
https://developer.blender.org/rBf3427cbc981e5ad530d1a73ab4ecbf6b64751774

GHOST/X11: support accessing physical keycodes

This means we can check keys such as tilde in a generic way.

===================================================================

M	intern/ghost/intern/GHOST_SystemX11.cpp
M	intern/ghost/intern/GHOST_SystemX11.h

===================================================================

diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 191f4f5408c..6d28310baaf 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -95,7 +95,12 @@
  * See T47228 and D1746 */
 #define USE_NON_LATIN_KB_WORKAROUND
 
-static GHOST_TKey convertXKey(KeySym key);
+static GHOST_TKey ghost_key_from_keysym(
+        const KeySym key);
+static GHOST_TKey ghost_key_from_keycode(
+        const XkbDescPtr xkb_descr, const KeyCode keycode);
+static GHOST_TKey ghost_key_from_keysym_or_keycode(
+        const KeySym key, const XkbDescPtr xkb_descr, const KeyCode keycode);
 
 /* these are for copy and select copy */
 static char *txt_cut_buffer = NULL;
@@ -111,6 +116,7 @@ GHOST_SystemX11::
 GHOST_SystemX11(
         )
     : GHOST_System(),
+      m_xkb_descr(NULL),
       m_start_time(0)
 {
 	m_display = XOpenDisplay(NULL);
@@ -185,6 +191,11 @@ GHOST_SystemX11(
 	use_xkb = XkbQueryExtension(m_display, &xkb_opcode, &xkb_event, &xkb_error, &xkb_major, &xkb_minor);
 	if (use_xkb) {
 		XkbSetDetectableAutoRepeat(m_display, true, NULL);
+
+		m_xkb_descr = XkbGetMap(m_display, 0, XkbUseCoreKbd);
+		if (m_xkb_descr) {
+			XkbGetNames(m_display, XkbKeyNamesMask, m_xkb_descr);
+		}
 	}
 
 #ifdef WITH_XWAYLAND_HACK
@@ -242,6 +253,10 @@ GHOST_SystemX11::
 		XCloseDevice(m_display, m_xtablet.EraserDevice);
 #endif /* WITH_X11_XINPUT */
 
+	if (m_xkb_descr) {
+		XkbFreeNames(m_xkb_descr, XkbKeyNamesMask, false);
+	}
+
 	XCloseDisplay(m_display);
 }
 
@@ -626,7 +641,7 @@ processEvents(
 									              getMilliSeconds(),
 									              GHOST_kEventKeyDown,
 									              window,
-									              convertXKey(modifiers[i]),
+									              ghost_key_from_keysym(modifiers[i]),
 									              '\0',
 									              NULL));
 								}
@@ -883,7 +898,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
 			 *       is unmodified (or anyone swapping the keys with xmodmap).
 			 *
 			 *     - XLookupKeysym seems to always use first defined keymap (see T47228), which generates
-			 *       keycodes unusable by convertXKey for non-latin-compatible keymaps.
+			 *       keycodes unusable by ghost_key_from_keysym for non-latin-compatible keymaps.
 			 *
 			 * To address this, we:
 			 *
@@ -921,7 +936,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
 
 			/* Only allow a limited set of keys from XLookupKeysym, all others we take from XLookupString,
 			 * unless it gives unknown key... */
-			gkey = convertXKey(key_sym);
+			gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode);
 			switch (gkey) {
 				case GHOST_kKeyRightAlt:
 				case GHOST_kKeyLeftAlt:
@@ -958,10 +973,12 @@ GHOST_SystemX11::processEvent(XEvent *xe)
 				case GHOST_kKeyNumpadSlash:
 					break;
 				default:
-					GHOST_TKey gkey_str = convertXKey(key_sym_str);
+				{
+					GHOST_TKey gkey_str = ghost_key_from_keysym(key_sym_str);
 					if (gkey_str != GHOST_kKeyUnknown) {
 						gkey = gkey_str;
 					}
+				}
 			}
 #else
 			/* In keyboards like latin ones,
@@ -983,7 +1000,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
 				key_sym = XLookupKeysym(xke, 0);
 			}
 
-			gkey = convertXKey(key_sym);
+			gkey = ghost_key_from_keysym(key_sym);
 
 			if (!XLookupString(xke, &ascii, 1, NULL, NULL)) {
 				ascii = '\0';
@@ -1632,10 +1649,22 @@ generateWindowExposeEvents()
 	return anyProcessed;
 }
 
+static GHOST_TKey
+ghost_key_from_keysym_or_keycode(const KeySym keysym, XkbDescPtr xkb_descr, const KeyCode keycode)
+{
+	GHOST_TKey type = ghost_key_from_keysym(keysym);
+	if (type == GHOST_kKeyUnknown) {
+		if (xkb_descr) {
+			type = ghost_key_from_keycode(xkb_descr, keycode);
+		}
+	}
+	return type;
+}
+
 #define GXMAP(k, x, y) case x: k = y; break
 
 static GHOST_TKey
-convertXKey(KeySym key)
+ghost_key_from_keysym(const KeySym key)
 {
 	GHOST_TKey type;
 
@@ -1743,11 +1772,6 @@ convertXKey(KeySym key)
 			GXMAP(type, XF86XK_AudioForward, GHOST_kKeyMediaLast);
 #endif
 #endif
-			/* Non US keyboard layouts: avoid 'UnknownKey' - TODO(campbell): lookup scan-codes. */
-			GXMAP(type, XK_dead_circumflex, GHOST_kKeyAccentGrave);         /* 'de' */
-			GXMAP(type, XK_masculine, GHOST_kKeyAccentGrave);               /* 'es' */
-			GXMAP(type, XK_onehalf, GHOST_kKeyAccentGrave);                 /* 'dk' */
-			GXMAP(type, XK_twosuperior, GHOST_kKeyAccentGrave);             /* 'fr' */
 			default:
 #ifdef GHOST_DEBUG
 				printf("%s: unknown key: %lu / 0x%lx\n", __func__, key, key);
@@ -1762,6 +1786,29 @@ convertXKey(KeySym key)
 
 #undef GXMAP
 
+#define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
+
+static GHOST_TKey
+ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode)
+{
+	GHOST_ASSERT(XkbKeyNameLength == 4, "Name length is invalid!");
+	if (keycode >= xkb_descr->min_key_code && keycode <= xkb_descr->max_key_code) {
+		const char *id_str = xkb_descr->names->keys[keycode].name;
+		const uint32_t id = MAKE_ID(id_str[0], id_str[1], id_str[2], id_str[3]);
+		// printf("scancode is: %.*s\n", XkbKeyNameLength, id_str);
+		switch (id) {
+			case MAKE_ID('T', 'L', 'D', 'E'):
+				return GHOST_kKeyAccentGrave;
+		}
+	}
+	else {
+		GHOST_ASSERT(false, "KeyCode out of range!");
+	}
+	return GHOST_kKeyUnknown;
+}
+
+#undef MAKE_ID
+
 /* from xclip.c xcout() v0.11 */
 
 #define XCLIB_XCOUT_NONE            0 /* no context */
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index 004856c221b..de9a2cdcce9 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -34,6 +34,7 @@
 #define __GHOST_SYSTEMX11_H__
 
 #include <X11/Xlib.h>
+#include <X11/XKBlib.h> /* allow detectable autorepeate */
 
 #include "GHOST_System.h"
 #include "../GHOST_Types.h"
@@ -353,6 +354,10 @@ public:
 private:
 
 	Display *m_display;
+
+	/* Use for scancode lookups. */
+	XkbDescRec *m_xkb_descr;
+
 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
 	XIM m_xim;
 #endif



More information about the Bf-blender-cvs mailing list