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