Mercurial > kinput2.yaz
comparison lib/cachedatom.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 #ifndef lint | |
2 static char *rcsid = "$Id: cachedatom.c,v 1.9 1994/05/17 04:48:01 ishisone Rel $"; | |
3 #endif | |
4 /* | |
5 * Copyright (c) 1991 Software Research Associates, Inc. | |
6 * | |
7 * Permission to use, copy, modify, and distribute this software and its | |
8 * documentation for any purpose and without fee is hereby granted, provided | |
9 * that the above copyright notice appear in all copies and that both that | |
10 * copyright notice and this permission notice appear in supporting | |
11 * documentation, and that the name of Software Research Associates not be | |
12 * used in advertising or publicity pertaining to distribution of the | |
13 * software without specific, written prior permission. Software Research | |
14 * Associates makes no representations about the suitability of this software | |
15 * for any purpose. It is provided "as is" without express or implied | |
16 * warranty. | |
17 * | |
18 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan | |
19 * | |
20 * neither R5 Xlib nor Xmu doesn't do what I want, so I wrote one myself. | |
21 */ | |
22 | |
23 #include <X11/Intrinsic.h> | |
24 #include "CachedAtom.h" | |
25 | |
26 #define DEBUG_VAR debug_cachedatom | |
27 #include "DebugPrint.h" | |
28 | |
29 typedef struct _atomrec_ { | |
30 Atom atom; /* atom number */ | |
31 Display *dpy; | |
32 String name; /* for obtaining atom name */ | |
33 struct _atomrec_ *nextOfName; /* next element of atom name list */ | |
34 struct _atomrec_ *nextOfNumber; /* next element of atom number list */ | |
35 } CachedAtomRec; | |
36 | |
37 typedef struct _cAtomNameRec_ { | |
38 String name; /* atom name */ | |
39 CachedAtomRec atomrec; /* caution: not a pointer! */ | |
40 struct _cAtomNameRec_ *next; /* next entry of the same hash value */ | |
41 } CachedAtomNameRec; | |
42 | |
43 #define NAMEHASHSIZE 128 | |
44 #define NUMBERHASHSIZE 128 | |
45 | |
46 static CachedAtomNameRec *nameHash[NAMEHASHSIZE]; | |
47 /* for searching by name */ | |
48 static CachedAtomRec *numberHash[NUMBERHASHSIZE]; | |
49 /* for searching by number */ | |
50 | |
51 | |
52 /* | |
53 * iternal functions | |
54 */ | |
55 | |
56 static int | |
57 nameHashFunc(s) | |
58 String s; | |
59 { | |
60 register String sp = s; | |
61 register int c, sum; | |
62 | |
63 sum = 0; | |
64 while ((c = *sp++) != '\0') sum += c; | |
65 | |
66 return (sum ^ (sp - s)) % NAMEHASHSIZE; | |
67 } | |
68 | |
69 #define numberHashFunc(atom) ((int)((atom) % NUMBERHASHSIZE)) | |
70 | |
71 static CachedAtomRec * | |
72 newAtomRec(dpy, atom, arp, nrp) | |
73 Display *dpy; | |
74 Atom atom; | |
75 CachedAtomRec *arp; /* NULL (create new rec) or &nrp->atomrec */ | |
76 CachedAtomNameRec *nrp; | |
77 { | |
78 int hashvalue; | |
79 | |
80 if (arp == NULL) arp = XtNew(CachedAtomRec); | |
81 arp->atom = atom; | |
82 arp->dpy = dpy; | |
83 arp->name = nrp->name; | |
84 | |
85 if (arp == &(nrp->atomrec)) { | |
86 arp->nextOfName = NULL; | |
87 } else { | |
88 arp->nextOfName = nrp->atomrec.nextOfName; | |
89 nrp->atomrec.nextOfName = arp; | |
90 } | |
91 | |
92 /* insert it in numberHash */ | |
93 hashvalue = numberHashFunc(atom); | |
94 arp->nextOfNumber = numberHash[hashvalue]; | |
95 numberHash[numberHashFunc(atom)] = arp; | |
96 | |
97 return arp; | |
98 } | |
99 | |
100 static CachedAtomNameRec * | |
101 newNameRec(name, hashvalue) | |
102 String name; | |
103 int hashvalue; | |
104 { | |
105 CachedAtomNameRec *nrp = XtNew(CachedAtomNameRec); | |
106 | |
107 nrp->name = XtNewString(name); | |
108 nrp->next = nameHash[hashvalue]; | |
109 nameHash[hashvalue] = nrp; | |
110 return nrp; | |
111 } | |
112 | |
113 /* | |
114 * public functions | |
115 */ | |
116 | |
117 Atom | |
118 CachedInternAtom(dpy, name, exists) | |
119 Display *dpy; | |
120 char *name; | |
121 Bool exists; | |
122 { | |
123 int hashvalue = nameHashFunc(name); | |
124 CachedAtomNameRec *nrp = nameHash[hashvalue]; | |
125 Atom atom; | |
126 | |
127 TRACE(("CachedInternAtom(name:%s)... ", name)); | |
128 while (nrp != NULL) { | |
129 if (!strcmp(nrp->name, name)) { | |
130 CachedAtomRec *arp = &(nrp->atomrec); | |
131 | |
132 do { | |
133 if (arp->dpy == dpy) { | |
134 TRACE(("found in the cache (%ld)\n", arp->atom)); | |
135 return arp->atom; | |
136 } | |
137 arp = arp->nextOfName; | |
138 } while (arp != NULL); | |
139 | |
140 TRACE(("not in the cache\n")); | |
141 if ((atom = XInternAtom(dpy, name, exists)) == None) return None; | |
142 (void)newAtomRec(dpy, atom, (CachedAtomRec *)NULL, nrp); | |
143 return atom; | |
144 } | |
145 nrp = nrp->next; | |
146 } | |
147 | |
148 TRACE(("not in the cache\n")); | |
149 if ((atom = XInternAtom(dpy, name, exists)) == None) return None; | |
150 nrp = newNameRec(name, hashvalue); | |
151 (void)newAtomRec(dpy, atom, &(nrp->atomrec), nrp); | |
152 | |
153 return atom; | |
154 } | |
155 | |
156 String | |
157 CachedGetAtomName(dpy, atom) | |
158 Display *dpy; | |
159 Atom atom; | |
160 { | |
161 int hashvalue = numberHashFunc(atom); | |
162 CachedAtomRec *arp = numberHash[hashvalue]; | |
163 CachedAtomNameRec *nrp; | |
164 String name; | |
165 | |
166 TRACE(("CachedGetAtomName(atom=%ld)... ", atom)); | |
167 while (arp != NULL) { | |
168 if (arp->atom == atom && arp->dpy == dpy) { | |
169 TRACE(("found in the cache (%s)\n", arp->name)); | |
170 return arp->name; | |
171 } | |
172 arp = arp->nextOfNumber; | |
173 } | |
174 TRACE(("not in the cache\n")); | |
175 if ((name = XGetAtomName(dpy, atom)) == NULL) return NULL; | |
176 hashvalue = nameHashFunc(name); | |
177 nrp = newNameRec(name, hashvalue); | |
178 XFree(name); | |
179 (void)newAtomRec(dpy, atom, &(nrp->atomrec), nrp); | |
180 return nrp->name; | |
181 } | |
182 | |
183 #ifdef DEBUG | |
184 void | |
185 dumpAtomCache() | |
186 { | |
187 int i; | |
188 | |
189 for (i = 0; i < NAMEHASHSIZE; i++) { | |
190 CachedAtomNameRec *nrp = nameHash[i]; | |
191 int n = 0; | |
192 | |
193 while (nrp != NULL) { | |
194 n++; | |
195 nrp = nrp->next; | |
196 } | |
197 printf("nameHash[%3d]: %d\n", i, n); | |
198 } | |
199 for (i = 0; i < NUMBERHASHSIZE; i++) { | |
200 CachedAtomRec *arp = numberHash[i]; | |
201 int n = 0; | |
202 | |
203 while (arp != NULL) { | |
204 n++; | |
205 arp = arp->nextOfNumber; | |
206 } | |
207 printf("numberHash[%3d]: %d\n", i, n); | |
208 } | |
209 } | |
210 #endif |