StrKeysym.c revision 3233502e
1/*
2
3Copyright 1985, 1987, 1990, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#include <limits.h>
31#include "Xlibint.h"
32#include <X11/Xresource.h>
33#include <X11/keysymdef.h>
34#include "Xresinternal.h"
35
36#define NEEDKTABLE
37#include "ks_tables.h"
38#include "Key.h"
39
40#ifndef KEYSYMDB
41#ifndef XKEYSYMDB
42#define KEYSYMDB "/usr/lib/X11/XKeysymDB"
43#else
44#define KEYSYMDB XKEYSYMDB
45#endif
46#endif
47
48static Bool initialized;
49static XrmDatabase keysymdb;
50static XrmQuark Qkeysym[2];
51
52XrmDatabase
53_XInitKeysymDB(void)
54{
55    if (!initialized)
56    {
57	const char *dbname;
58
59	XrmInitialize();
60	/* use and name of this env var is not part of the standard */
61	/* implementation-dependent feature */
62	dbname = getenv("XKEYSYMDB");
63	if (!dbname)
64	    dbname = KEYSYMDB;
65	keysymdb = XrmGetFileDatabase(dbname);
66	if (keysymdb)
67	    Qkeysym[0] = XrmStringToQuark("Keysym");
68	initialized = True;
69    }
70    return keysymdb;
71}
72
73KeySym
74XStringToKeysym(_Xconst char *s)
75{
76    register int i, n;
77    int h;
78    register Signature sig = 0;
79    register const char *p = s;
80    register int c;
81    register int idx;
82    const unsigned char *entry;
83    unsigned char sig1, sig2;
84    KeySym val;
85
86    while ((c = *p++))
87	sig = (sig << 1) + c;
88    i = sig % KTABLESIZE;
89    h = i + 1;
90    sig1 = (sig >> 8) & 0xff;
91    sig2 = sig & 0xff;
92    n = KMAXHASH;
93    while ((idx = hashString[i]))
94    {
95	entry = &_XkeyTable[idx];
96	if ((entry[0] == sig1) && (entry[1] == sig2) &&
97	    !strcmp(s, (const char *)entry + 6))
98	{
99	    val = (entry[2] << 24) | (entry[3] << 16) |
100	          (entry[4] << 8)  | entry[5];
101	    if (!val)
102		val = XK_VoidSymbol;
103	    return val;
104	}
105	if (!--n)
106	    break;
107	i += h;
108	if (i >= KTABLESIZE)
109	    i -= KTABLESIZE;
110    }
111
112    if (!initialized)
113	(void)_XInitKeysymDB();
114    if (keysymdb)
115    {
116	XrmValue result;
117	XrmRepresentation from_type;
118	char d;
119	XrmQuark names[2];
120
121	names[0] = _XrmInternalStringToQuark(s, p - s - 1, sig, False);
122	names[1] = NULLQUARK;
123	(void)XrmQGetResource(keysymdb, names, Qkeysym, &from_type, &result);
124	if (result.addr && (result.size > 1))
125	{
126	    val = 0;
127	    for (i = 0; i < result.size - 1; i++)
128	    {
129		d = ((char *)result.addr)[i];
130		if ('0' <= d && d <= '9') val = (val<<4)+d-'0';
131		else if ('a' <= d && d <= 'f') val = (val<<4)+d-'a'+10;
132		else if ('A' <= d && d <= 'F') val = (val<<4)+d-'A'+10;
133		else return NoSymbol;
134	    }
135	    return val;
136	}
137    }
138
139    if (*s == 'U') {
140    	val = 0;
141        for (p = &s[1]; *p; p++) {
142            c = *p;
143	    if ('0' <= c && c <= '9') val = (val<<4)+c-'0';
144	    else if ('a' <= c && c <= 'f') val = (val<<4)+c-'a'+10;
145	    else if ('A' <= c && c <= 'F') val = (val<<4)+c-'A'+10;
146	    else return NoSymbol;
147	    if (val > 0x10ffff)
148		return NoSymbol;
149	}
150	if (val < 0x20 || (val > 0x7e && val < 0xa0))
151	    return NoSymbol;
152	if (val < 0x100)
153	    return val;
154        return val | 0x01000000;
155    }
156
157    if (strlen(s) > 2 && s[0] == '0' && s[1] == 'x') {
158        char *tmp = NULL;
159        val = strtoul(s, &tmp, 16);
160        if (val == ULONG_MAX || (tmp && *tmp != '\0'))
161            return NoSymbol;
162        else
163            return val;
164    }
165
166    /* Stupid inconsistency between the headers and XKeysymDB: the former has
167     * no separating underscore, while some XF86* syms in the latter did.
168     * As a last ditch effort, try without. */
169    if (strncmp(s, "XF86_", 5) == 0) {
170        KeySym ret;
171        char *tmp = strdup(s);
172        if (!tmp)
173            return NoSymbol;
174        memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1);
175        ret = XStringToKeysym(tmp);
176        free(tmp);
177        return ret;
178    }
179
180    return NoSymbol;
181}
182