Home | History | Annotate | Line # | Download | only in src
      1 /*
      2 
      3 Copyright 1985, 1987, 1990, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in 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 
     48 static Bool initialized;
     49 static XrmDatabase keysymdb;
     50 static XrmQuark Qkeysym[2];
     51 
     52 XrmDatabase
     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 
     73 KeySym
     74 XStringToKeysym(_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