xkbatom.c revision 4e411241
1/* $Xorg: xkbatom.c,v 1.4 2001/02/09 02:04:05 xorgcvs Exp $ */
2/***********************************************************
3
4Copyright 1987, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26
27Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
28
29                        All Rights Reserved
30
31Permission to use, copy, modify, and distribute this software and its
32documentation for any purpose and without fee is hereby granted,
33provided that the above copyright notice appear in all copies and that
34both that copyright notice and this permission notice appear in
35supporting documentation, and that the name of Digital not be
36used in advertising or publicity pertaining to distribution of the
37software without specific, written prior permission.
38
39DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45SOFTWARE.
46
47******************************************************************/
48
49/************************************************************
50 Copyright 1994 by Silicon Graphics Computer Systems, Inc.
51
52 Permission to use, copy, modify, and distribute this
53 software and its documentation for any purpose and without
54 fee is hereby granted, provided that the above copyright
55 notice appear in all copies and that both that copyright
56 notice and this permission notice appear in supporting
57 documentation, and that the name of Silicon Graphics not be
58 used in advertising or publicity pertaining to distribution
59 of the software without specific prior written permission.
60 Silicon Graphics makes no representation about the suitability
61 of this software for any purpose. It is provided "as is"
62 without any express or implied warranty.
63
64 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
65 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
66 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
67 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
68 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
69 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
70 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
71 THE USE OR PERFORMANCE OF THIS SOFTWARE.
72
73 ********************************************************/
74/* $XFree86: xc/lib/xkbfile/xkbatom.c,v 3.8 2001/12/14 19:57:03 dawes Exp $ */
75
76#ifdef HAVE_CONFIG_H
77#include <config.h>
78#endif
79#include <stdio.h>
80#include <ctype.h>
81#include <stdlib.h>
82#include <X11/Xos.h>
83#include <X11/Xlib.h>
84#include <X11/XKBlib.h>
85
86#include "XKMformat.h"
87#include "XKBfileInt.h"
88
89/***====================================================================***/
90
91#define InitialTableSize 100
92
93typedef struct _Node {
94    struct _Node   *left,   *right;
95    Atom a;
96    unsigned int fingerPrint;
97    char   *string;
98} NodeRec, *NodePtr;
99
100#define BAD_RESOURCE 0xe0000000
101
102static Atom lastAtom = None;
103static NodePtr atomRoot = (NodePtr)NULL;
104static unsigned long tableLength;
105static NodePtr *nodeTable;
106
107static Atom
108_XkbMakeAtom(char *string,unsigned len,Bool makeit)
109{
110    register    NodePtr * np;
111    unsigned i;
112    int     comp;
113    register unsigned int   fp = 0;
114
115    np = &atomRoot;
116    for (i = 0; i < (len+1)/2; i++)
117    {
118	fp = fp * 27 + string[i];
119	fp = fp * 27 + string[len - 1 - i];
120    }
121    while (*np != (NodePtr) NULL)
122    {
123	if (fp < (*np)->fingerPrint)
124	    np = &((*np)->left);
125	else if (fp > (*np)->fingerPrint)
126	    np = &((*np)->right);
127	else
128	{			       /* now start testing the strings */
129	    comp = strncmp(string, (*np)->string, (int)len);
130	    if ((comp < 0) || ((comp == 0) && (len < strlen((*np)->string))))
131		np = &((*np)->left);
132	    else if (comp > 0)
133		np = &((*np)->right);
134	    else
135		return(*np)->a;
136	    }
137    }
138    if (makeit)
139    {
140	register NodePtr nd;
141
142	nd = (NodePtr) _XkbAlloc(sizeof(NodeRec));
143	if (!nd)
144	    return BAD_RESOURCE;
145	nd->string = (char *) _XkbAlloc(len + 1);
146	if (!nd->string) {
147	    _XkbFree(nd);
148	    return BAD_RESOURCE;
149	}
150	strncpy(nd->string, string, (int)len);
151	nd->string[len] = 0;
152	if ((lastAtom + 1) >= tableLength) {
153	    NodePtr *table;
154
155	    table = (NodePtr *) _XkbRealloc(nodeTable,
156					 tableLength * (2 * sizeof(NodePtr)));
157	    if (!table) {
158		if (nd->string != string)
159		    _XkbFree(nd->string);
160		_XkbFree(nd);
161		return BAD_RESOURCE;
162	    }
163	    tableLength <<= 1;
164	    nodeTable = table;
165	}
166	*np = nd;
167	nd->left = nd->right = (NodePtr) NULL;
168	nd->fingerPrint = fp;
169	nd->a = (++lastAtom);
170	*(nodeTable+lastAtom) = nd;
171	return nd->a;
172    }
173    else
174	return None;
175}
176
177static char *
178_XkbNameForAtom(Atom atom)
179{
180    NodePtr node;
181    if (atom > lastAtom) return NULL;
182    if ((node = nodeTable[atom]) == (NodePtr)NULL) return NULL;
183    return strdup(node->string);
184}
185
186static void
187_XkbInitAtoms(void)
188{
189    tableLength = InitialTableSize;
190    nodeTable = (NodePtr *)_XkbAlloc(InitialTableSize*sizeof(NodePtr));
191    nodeTable[None] = (NodePtr)NULL;
192}
193
194/***====================================================================***/
195
196char *
197XkbAtomGetString(Display *dpy,Atom atm)
198{
199    if (atm==None)
200	return NULL;
201    if (dpy==NULL)
202	return _XkbNameForAtom(atm);
203    return XGetAtomName(dpy,atm);
204}
205
206/***====================================================================***/
207
208Atom
209XkbInternAtom(Display *dpy,char *name,Bool onlyIfExists)
210{
211    if (name==NULL)
212	return None;
213    if (dpy==NULL) {
214	return _XkbMakeAtom(name, strlen(name), (!onlyIfExists));
215    }
216    return XInternAtom(dpy,name,onlyIfExists);
217}
218
219/***====================================================================***/
220
221Atom
222XkbChangeAtomDisplay(Display *oldDpy,Display *newDpy,Atom atm)
223{
224char *tmp;
225
226    if (atm!=None) {
227	tmp= XkbAtomGetString(oldDpy,atm);
228	if (tmp!=NULL)
229	    return XkbInternAtom(newDpy,tmp,False);
230    }
231    return None;
232}
233
234/***====================================================================***/
235
236void
237XkbInitAtoms(Display *dpy)
238{
239static int been_here= 0;
240    if ((dpy==NULL)&&(!been_here)) {
241	_XkbInitAtoms();
242	been_here= 1;
243    }
244    return;
245}
246