Standardize License information
[openafs.git] / src / gtx / keymap.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afs/param.h>
11 #include "gtxkeymap.h"
12
13 struct keymap_map *keymap_Create() {
14     register struct keymap_map *tmap;
15
16     tmap = (struct keymap_map *) malloc(sizeof(struct keymap_map));
17     if (tmap != (struct keymap_map *)0)
18       bzero(tmap, sizeof(*tmap));
19     return(tmap);
20 }
21
22 /* make a copy of a string; generic utility */
23 char *gtx_CopyString(aval)
24 register char *aval; {
25     register char *tp;
26
27     if (!aval) return (char *) 0;       /* propagate null strings around */
28     tp = (char *) malloc(strlen(aval)+1);
29     if (tp != (char *)0)
30       strcpy(tp, aval);
31     return(tp);
32 }
33
34 static int BindIt(amap, aslot, atype, aproc, aname, arock)
35 struct keymap_map *amap;
36 char *arock;
37 int aslot;
38 int atype;
39 char *aproc;
40 char *aname; {
41     register char *tp;
42     register struct keymap_entry *tentry;
43
44     if (aslot < 0 || aslot >= KEYMAP_NENTRIES) return -1;
45     tentry = &amap->entries[aslot];
46     tentry->type = atype;
47     if (tp=tentry->name)
48         free(tp);
49     if (atype == KEYMAP_EMPTY) {
50         tentry->u.generic = (char *) 0;
51         tentry->name = (char *) 0;
52     }
53     else {
54         tentry->name = gtx_CopyString(aname);
55         tentry->u.generic = aproc;
56     }
57     tentry->rock = arock;
58     return 0;
59 }
60
61 keymap_BindToString(amap, astring, aproc, aname, arock)
62 register struct keymap_map *amap;
63 char *astring;
64 char *arock;
65 int (*aproc)();
66 char *aname; {
67     register char *cptr;
68     register int tc;
69     register afs_int32 code;
70     struct keymap_map *tmap;
71
72     cptr = astring;
73     /* walk down string, building submaps if possible, until we get to function
74        at the end */
75     while (tc = *cptr++) {
76         /* see if we should do submap or final function */
77         if (*cptr == 0) {       /* we're peeking: already skipped command char */
78             /* last character, do final function */
79             if (!aproc) /* delete the entry */
80                 code = BindIt(amap, tc, KEYMAP_EMPTY, (char *) 0,
81                               (char *) 0, (char *) 0);
82             else
83                 code = BindIt(amap, tc, KEYMAP_PROC, (char *) aproc, aname, arock);
84             if (code) return code;
85         }
86         else {
87             /* more characters after this; do submap */
88             if (amap->entries[tc].type != KEYMAP_SUBMAP) {
89                 tmap = keymap_Create();
90                 code = BindIt(amap, tc, KEYMAP_SUBMAP, (char *) tmap,
91                               (char *) 0, (char *) 0);
92             }
93             else {
94                 tmap = amap->entries[tc].u.submap;
95                 code = 0;
96             }
97             if (code) return code;
98             amap = tmap;        /* continue processing this map */
99         }
100     }   /* while loop */
101     /* here when all characters are gone */
102     return 0;
103 }
104
105 /* delete a keymap and all of its recursively-included maps */
106 keymap_Delete(amap)
107 register struct keymap_map *amap; {
108     register int i;
109     register struct keymap_entry *tentry;
110
111     for(i=0;i<KEYMAP_NENTRIES;i++) {
112         tentry = &amap->entries[i];
113         if (tentry->name) free(tentry->name);
114         if (tentry->type == KEYMAP_SUBMAP)
115             keymap_Delete(tentry->u.submap);
116     }
117     free(amap);
118     return 0;
119 }
120
121 keymap_InitState(astate, amap)
122 register struct keymap_state *astate;
123 struct keymap_map *amap; {
124     bzero(astate, sizeof(*astate));
125     astate->initMap = amap;
126     astate->currentMap = amap;
127     return 0;
128 }
129
130 keymap_ProcessKey(astate, akey, arock)
131 register struct keymap_state *astate;
132 char *arock;
133 register int akey; {
134     register struct keymap_entry *tentry;
135     register afs_int32 code;
136
137     if (akey < 0 || akey >= KEYMAP_NENTRIES) return -1;
138     tentry = &astate->currentMap->entries[akey];
139     code = 0;
140     switch(tentry->type) {
141       case KEYMAP_EMPTY:
142         keymap_ResetState(astate);
143         return -1;
144         /* break; */
145         /* break commented out because of return above causing compiler warnings */
146
147       case KEYMAP_SUBMAP:
148         astate->currentMap = tentry->u.submap;
149         break;
150
151       case KEYMAP_PROC:
152         code = (*tentry->u.proc)(arock, tentry->rock);
153         keymap_ResetState(astate);
154         break;
155     }
156     return code;
157 }
158
159 keymap_ResetState(astate)
160 register struct keymap_state *astate; {
161     return keymap_InitState(astate, astate->initMap);
162 }