static char rcsid[] = "$Id: keytable.c,v 1.1 1992/09/14 13:02:14 mike Exp $"; /* $Log: keytable.c,v $ * Revision 1.1 1992/09/14 13:02:14 mike * Initial revision * */ /* keytable.c : deal with KeyTables. * A KeyTable is a dTable of Keys. Like so: * typedef struct { KeyCode ; ; } Key; * typedef declare_dTable_of(Key) KeyTable; * (you can use your own names - it don't matter to this code). * It is real important that a KeyCode is the first element of a Key. * C Durland */ /* Copyright 1990, 1991 Craig Durland * Distributed under the terms of the GNU General Public License. * Distributed "as is", without warranties of any kind, but comments, * suggestions and bug reports are welcome. */ #include #include #include "ed.h" char *Efind_key(kt,keycode) dTable *kt; register KeyCode keycode; { register char *key; register int n, keysize; key = kt->table; n = sizeof_dTable(kt); keysize = kt->blob_size; for (; n--; key += keysize) if (*(KeyCode *)key==keycode) return key; return NULL; } /* Allocate a key in the keytable. Reuse key if keycode already in the * table. * Returns: * ptr to key that needs to be filled in. * NULL: no memory */ char *Ekalloc(kt,kc) dTable *kt; KeyCode kc; { register char *key; if (!(key = Efind_key(kt,kc))) { /* key don't exist, make room in table */ if (!xpand_dTable(kt,1,10,10)) return NULL; key = &kt->table[(sizeof_dTable(kt) -1)*kt->blob_size]; } return key; } /* Pack a keytable. remove_key() is called with a pointer to a key. If * TRUE is returned, the key is taken out of the table. * Assume: Not many keys will be removed from key table. * Note: * This routine could be made a lot faster with this alg: * walk till dead key * 1: ptr = dead * walk while dead key * qtr = dead +1 * walk till dead key * blkmov(ptr,qtr,dead-qtr) ; an overlapping block move * goto 1 */ void Epack_keytable(kt,remove_key) dTable *kt; int (*remove_key)(); { register char *ptr, *key; register int keysize, k,n; n = sizeof_dTable(kt); key = kt->table; keysize = kt->blob_size; for (k = 0; n--; key += keysize, k++) if ((*remove_key)(key)) { for (ptr = key, key += keysize; n--; key += keysize) if (!(*remove_key)(key)) { memcpy(ptr,key,keysize); ptr += keysize; k++; } sizeof_dTable(kt) = k; break; } } static KeyCode zap_keycode; /* a bit of ugliness here */ static int zap_key(key) char *key; { return *(KeyCode *)key == zap_keycode; } void Eunbind_key(kt,keycode) dTable *kt; KeyCode keycode; { zap_keycode = keycode; Epack_keytable(kt,zap_key); }