Commit 83f198f1ae5c26a2d9a37579c9590c0aaab0416a

Dan Nicholson 2009-01-20T07:46:12

Initial implementation of keysym handlers Add the xkbcommon implementations of XKeysymToString and XStringToKeysym. These symbols have the namespace prefix of Xkbc and are declared in X11/XkbCommon.h. The implementation is taken directly from Xlib, but does not include the XKeysymDB parsing and hashing yet (if it ever will). A couple type conversions were needed to keep from using Xlib.h. See original files: libX11/src/KeysymStr.c libX11/src/StrKeysym.c

diff --git a/.gitignore b/.gitignore
index 4eca397..0f8ca90 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+*.lo
+*.o
 INSTALL
 Makefile
 Makefile.in
diff --git a/Makefile.am b/Makefile.am
index 308357b..e418f40 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = src
+SUBDIRS = include src
 
 EXTRA_DIST = ChangeLog
 
diff --git a/configure.ac b/configure.ac
index d0f1735..c71c5bd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,5 +75,6 @@ XORG_CHANGELOG
 
 AC_OUTPUT([
 Makefile
+include/Makefile
 src/Makefile
 ])
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 0000000..c5394cf
--- /dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,2 @@
+x11includedir = $(includedir)/X11
+x11include_HEADERS = X11/XkbCommon.h
diff --git a/include/X11/XkbCommon.h b/include/X11/XkbCommon.h
new file mode 100644
index 0000000..16cca77
--- /dev/null
+++ b/include/X11/XkbCommon.h
@@ -0,0 +1,40 @@
+/*
+Copyright 1985, 1987, 1990, 1998  The Open Group
+Copyright 2008  Dan Nicholson
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the authors or their
+institutions shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from the authors.
+*/
+
+#ifndef _XKBCOMMON_H_
+#define _XKBCOMMON_H_
+
+#include <X11/X.h>
+#include <X11/keysymdef.h>
+
+extern char *
+XkbcKeysymToString(KeySym ks);
+
+extern KeySym
+XkbcStringToKeysym(const char *s);
+
+#endif /* _XKBCOMMON_H_ */
diff --git a/src/.gitignore b/src/.gitignore
index 6251fb4..2f94b37 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,2 +1,3 @@
 ks_tables.h
+libxkbcommon.la
 makekeys
diff --git a/src/Makefile.am b/src/Makefile.am
index 85cddbd..309cc04 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,9 +1,16 @@
+INCLUDES = -I$(top_srcdir)/include
+
 noinst_PROGRAMS = makekeys
 makekeys_CFLAGS = $(X11_CFLAGS)
 makekeys: CC = $(CC_FOR_BUILD)
 
-#BUILT_SOURCES = ks_tables.h
-noinst_HEADERS = ks_tables.h
+BUILT_SOURCES = ks_tables.h
 ks_tables.h: makekeys
 	@rm -f $@
 	cat $(KEYSYMDEF_H) $(XF86KEYSYM_H) | $(builddir)/makekeys$(EXEEXT) >$@
+
+lib_LTLIBRARIES = libxkbcommon.la
+libxkbcommon_la_CFLAGS = $(X11_CFLAGS)
+libxkbcommon_la_SOURCES = \
+	ks_tables.h \
+	keysym.c
diff --git a/src/keysym.c b/src/keysym.c
new file mode 100644
index 0000000..216d6e0
--- /dev/null
+++ b/src/keysym.c
@@ -0,0 +1,158 @@
+/*
+Copyright 1985, 1987, 1990, 1998  The Open Group
+Copyright 2008  Dan Nicholson
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the authors or their
+institutions shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from the authors.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/X.h>
+#include <X11/keysymdef.h>
+#include "X11/XkbCommon.h"
+#include <stdlib.h>
+#include <string.h>
+
+#include "ks_tables.h"
+
+char *XkbcKeysymToString(KeySym ks)
+{
+    register int i, n;
+    int h;
+    register int idx;
+    const unsigned char *entry;
+    unsigned char val1, val2, val3, val4;
+
+    if (!ks || (ks & ((unsigned long) ~0x1fffffff)) != 0)
+	return ((char *)NULL);
+    if (ks == XK_VoidSymbol)
+	ks = 0;
+    if (ks <= 0x1fffffff)
+    {
+	val1 = ks >> 24;
+	val2 = (ks >> 16) & 0xff;
+	val3 = (ks >> 8) & 0xff;
+	val4 = ks & 0xff;
+	i = ks % VTABLESIZE;
+	h = i + 1;
+	n = VMAXHASH;
+	while ((idx = hashKeysym[i]))
+	{
+	    entry = &_XkeyTable[idx];
+	    if ((entry[0] == val1) && (entry[1] == val2) &&
+                (entry[2] == val3) && (entry[3] == val4))
+		return ((char *)entry + 4);
+	    if (!--n)
+		break;
+	    i += h;
+	    if (i >= VTABLESIZE)
+		i -= VTABLESIZE;
+	}
+    }
+
+    if (ks >= 0x01000100 && ks <= 0x0110ffff) {
+        KeySym val = ks & 0xffffff;
+        char *s;
+        int i;
+        if (val & 0xff0000)
+            i = 10;
+        else
+            i = 6;
+        s = malloc(i);
+        if (s == NULL)
+            return s;
+        i--;
+        s[i--] = '\0';
+        for (; i; i--){
+            val1 = val & 0xf;
+            val >>= 4;
+            if (val1 < 10)
+                s[i] = '0'+ val1;
+            else
+                s[i] = 'A'+ val1 - 10;
+        }
+        s[i] = 'U';
+        return s;
+    }
+    return ((char *) NULL);
+}
+
+KeySym
+XkbcStringToKeysym(const char *s)
+{
+    register int i, n;
+    int h;
+    register unsigned long sig = 0;
+    register const char *p = s;
+    register int c;
+    register int idx;
+    const unsigned char *entry;
+    unsigned char sig1, sig2;
+    KeySym val;
+
+    while ((c = *p++))
+	sig = (sig << 1) + c;
+    i = sig % KTABLESIZE;
+    h = i + 1;
+    sig1 = (sig >> 8) & 0xff;
+    sig2 = sig & 0xff;
+    n = KMAXHASH;
+    while ((idx = hashString[i]))
+    {
+	entry = &_XkeyTable[idx];
+	if ((entry[0] == sig1) && (entry[1] == sig2) &&
+	    !strcmp(s, (char *)entry + 6))
+	{
+	    val = (entry[2] << 24) | (entry[3] << 16) |
+	          (entry[4] << 8)  | entry[5];
+	    if (!val)
+		val = XK_VoidSymbol;
+	    return val;
+	}
+	if (!--n)
+	    break;
+	i += h;
+	if (i >= KTABLESIZE)
+	    i -= KTABLESIZE;
+    }
+
+    if (*s == 'U') {
+    	val = 0;
+        for (p = &s[1]; *p; p++) {
+            c = *p;
+	    if ('0' <= c && c <= '9') val = (val<<4)+c-'0';
+	    else if ('a' <= c && c <= 'f') val = (val<<4)+c-'a'+10;
+	    else if ('A' <= c && c <= 'F') val = (val<<4)+c-'A'+10;
+	    else return NoSymbol;
+	    if (val > 0x10ffff)
+		return NoSymbol;
+	}
+	if (val < 0x20 || (val > 0x7e && val < 0xa0))
+	    return NoSymbol;
+	if (val < 0x100)
+	    return val;
+        return val | 0x01000000;
+    }
+    return NoSymbol;
+}