Mercurial > kinput2.yaz
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/cachedatom.c Mon Mar 08 04:44:30 2010 +0900 @@ -0,0 +1,210 @@ +#ifndef lint +static char *rcsid = "$Id: cachedatom.c,v 1.9 1994/05/17 04:48:01 ishisone Rel $"; +#endif +/* + * Copyright (c) 1991 Software Research Associates, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Software Research Associates not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Software Research + * Associates makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * Author: Makoto Ishisone, Software Research Associates, Inc., Japan + * + * neither R5 Xlib nor Xmu doesn't do what I want, so I wrote one myself. + */ + +#include <X11/Intrinsic.h> +#include "CachedAtom.h" + +#define DEBUG_VAR debug_cachedatom +#include "DebugPrint.h" + +typedef struct _atomrec_ { + Atom atom; /* atom number */ + Display *dpy; + String name; /* for obtaining atom name */ + struct _atomrec_ *nextOfName; /* next element of atom name list */ + struct _atomrec_ *nextOfNumber; /* next element of atom number list */ +} CachedAtomRec; + +typedef struct _cAtomNameRec_ { + String name; /* atom name */ + CachedAtomRec atomrec; /* caution: not a pointer! */ + struct _cAtomNameRec_ *next; /* next entry of the same hash value */ +} CachedAtomNameRec; + +#define NAMEHASHSIZE 128 +#define NUMBERHASHSIZE 128 + +static CachedAtomNameRec *nameHash[NAMEHASHSIZE]; + /* for searching by name */ +static CachedAtomRec *numberHash[NUMBERHASHSIZE]; + /* for searching by number */ + + +/* + * iternal functions + */ + +static int +nameHashFunc(s) +String s; +{ + register String sp = s; + register int c, sum; + + sum = 0; + while ((c = *sp++) != '\0') sum += c; + + return (sum ^ (sp - s)) % NAMEHASHSIZE; +} + +#define numberHashFunc(atom) ((int)((atom) % NUMBERHASHSIZE)) + +static CachedAtomRec * +newAtomRec(dpy, atom, arp, nrp) +Display *dpy; +Atom atom; +CachedAtomRec *arp; /* NULL (create new rec) or &nrp->atomrec */ +CachedAtomNameRec *nrp; +{ + int hashvalue; + + if (arp == NULL) arp = XtNew(CachedAtomRec); + arp->atom = atom; + arp->dpy = dpy; + arp->name = nrp->name; + + if (arp == &(nrp->atomrec)) { + arp->nextOfName = NULL; + } else { + arp->nextOfName = nrp->atomrec.nextOfName; + nrp->atomrec.nextOfName = arp; + } + + /* insert it in numberHash */ + hashvalue = numberHashFunc(atom); + arp->nextOfNumber = numberHash[hashvalue]; + numberHash[numberHashFunc(atom)] = arp; + + return arp; +} + +static CachedAtomNameRec * +newNameRec(name, hashvalue) +String name; +int hashvalue; +{ + CachedAtomNameRec *nrp = XtNew(CachedAtomNameRec); + + nrp->name = XtNewString(name); + nrp->next = nameHash[hashvalue]; + nameHash[hashvalue] = nrp; + return nrp; +} + +/* + * public functions + */ + +Atom +CachedInternAtom(dpy, name, exists) +Display *dpy; +char *name; +Bool exists; +{ + int hashvalue = nameHashFunc(name); + CachedAtomNameRec *nrp = nameHash[hashvalue]; + Atom atom; + + TRACE(("CachedInternAtom(name:%s)... ", name)); + while (nrp != NULL) { + if (!strcmp(nrp->name, name)) { + CachedAtomRec *arp = &(nrp->atomrec); + + do { + if (arp->dpy == dpy) { + TRACE(("found in the cache (%ld)\n", arp->atom)); + return arp->atom; + } + arp = arp->nextOfName; + } while (arp != NULL); + + TRACE(("not in the cache\n")); + if ((atom = XInternAtom(dpy, name, exists)) == None) return None; + (void)newAtomRec(dpy, atom, (CachedAtomRec *)NULL, nrp); + return atom; + } + nrp = nrp->next; + } + + TRACE(("not in the cache\n")); + if ((atom = XInternAtom(dpy, name, exists)) == None) return None; + nrp = newNameRec(name, hashvalue); + (void)newAtomRec(dpy, atom, &(nrp->atomrec), nrp); + + return atom; +} + +String +CachedGetAtomName(dpy, atom) +Display *dpy; +Atom atom; +{ + int hashvalue = numberHashFunc(atom); + CachedAtomRec *arp = numberHash[hashvalue]; + CachedAtomNameRec *nrp; + String name; + + TRACE(("CachedGetAtomName(atom=%ld)... ", atom)); + while (arp != NULL) { + if (arp->atom == atom && arp->dpy == dpy) { + TRACE(("found in the cache (%s)\n", arp->name)); + return arp->name; + } + arp = arp->nextOfNumber; + } + TRACE(("not in the cache\n")); + if ((name = XGetAtomName(dpy, atom)) == NULL) return NULL; + hashvalue = nameHashFunc(name); + nrp = newNameRec(name, hashvalue); + XFree(name); + (void)newAtomRec(dpy, atom, &(nrp->atomrec), nrp); + return nrp->name; +} + +#ifdef DEBUG +void +dumpAtomCache() +{ + int i; + + for (i = 0; i < NAMEHASHSIZE; i++) { + CachedAtomNameRec *nrp = nameHash[i]; + int n = 0; + + while (nrp != NULL) { + n++; + nrp = nrp->next; + } + printf("nameHash[%3d]: %d\n", i, n); + } + for (i = 0; i < NUMBERHASHSIZE; i++) { + CachedAtomRec *arp = numberHash[i]; + int n = 0; + + while (arp != NULL) { + n++; + arp = arp->nextOfNumber; + } + printf("numberHash[%3d]: %d\n", i, n); + } +} +#endif