1 // Key binding interface
2 // Copyright (C) 2000 Core Technologies.
3
4 // This file is part of e93.
5 //
6 // e93 is free software; you can redistribute it and/or modify
7 // it under the terms of the e93 LICENSE AGREEMENT.
8 //
9 // e93 is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // e93 LICENSE AGREEMENT for more details.
13 //
14 // You should have received a copy of the e93 LICENSE AGREEMENT
15 // along with e93; see the file "LICENSE.TXT".
16
17 #include "includes.h"
18
19 typedef struct keyBinding
20 {
21 UINT32
22 keyCode,
23 modifierMask,
24 modifierValue;
25 struct keyBinding
26 *previousBinding, // pointer to previous binding in the global binding list
27 *nextBinding, // pointer to next binding in the global binding list (in user defined order)
28 *nextHashBinding; // pointer to next binding in local hash list
29 char
30 dataText[1]; // variable length array of characters of data (would like to declare as dataText[0] but some compilers complain)
31 } EDITOR_KEY_BINDING;
32
GetBindingHashListHead(UINT32 keyCode)33 static EDITOR_KEY_BINDING **GetBindingHashListHead(UINT32 keyCode)
34 // perform hashing function on keyCode, return pointer to list head
35 // for bindings
36 {
37 return(&(keyBindingTable[keyCode&0xFF]));
38 }
39
GetKeyBindingText(EDITOR_KEY_BINDING * binding)40 char *GetKeyBindingText(EDITOR_KEY_BINDING *binding)
41 // return a pointer to the key binding text for binding
42 {
43 return(binding->dataText);
44 }
45
GetKeyBindingCodeAndModifiers(EDITOR_KEY_BINDING * binding,UINT32 * keyCode,UINT32 * modifierMask,UINT32 * modifierValue)46 void GetKeyBindingCodeAndModifiers(EDITOR_KEY_BINDING *binding,UINT32 *keyCode,UINT32 *modifierMask,UINT32 *modifierValue)
47 // return the key binding information
48 {
49 *keyCode=binding->keyCode;
50 *modifierMask=binding->modifierMask;
51 *modifierValue=binding->modifierValue;
52 }
53
LocateKeyBinding(UINT32 keyCode,UINT32 modifierMask,UINT32 modifierValue,EDITOR_KEY_BINDING *** hashListHead,EDITOR_KEY_BINDING ** previousHashEntry,EDITOR_KEY_BINDING ** entry)54 static bool LocateKeyBinding(UINT32 keyCode,UINT32 modifierMask,UINT32 modifierValue,EDITOR_KEY_BINDING ***hashListHead,EDITOR_KEY_BINDING **previousHashEntry,EDITOR_KEY_BINDING **entry)
55 // locate a key binding in the binding table, return pointers to important entries
56 {
57 bool
58 found;
59 EDITOR_KEY_BINDING
60 *currentEntry;
61
62 *entry=NULL; // keep gcc quiet
63 currentEntry=*(*hashListHead=GetBindingHashListHead(keyCode)); // point to the head of the linked list at this hash entry
64 *previousHashEntry=NULL;
65 found=false;
66 while(currentEntry&&!found)
67 {
68 if((currentEntry->keyCode==keyCode)&&(currentEntry->modifierMask==modifierMask)&&(currentEntry->modifierValue==modifierValue))
69 {
70 found=true;
71 *entry=currentEntry;
72 }
73 else
74 {
75 *previousHashEntry=currentEntry;
76 currentEntry=currentEntry->nextHashBinding;
77 }
78 }
79 return(found);
80 }
81
LocateNextKeyBinding(EDITOR_KEY_BINDING * currentBinding)82 EDITOR_KEY_BINDING *LocateNextKeyBinding(EDITOR_KEY_BINDING *currentBinding)
83 // return the next key binding from the current one
84 // if there is none, return NULL
85 {
86 return(currentBinding->nextBinding);
87 }
88
LocateKeyBindingMatch(UINT32 keyCode,UINT32 modifierValue)89 EDITOR_KEY_BINDING *LocateKeyBindingMatch(UINT32 keyCode,UINT32 modifierValue)
90 // find a key binding that matches the keyCode, and modifierValue, and return it
91 // if there is none, return NULL
92 {
93 bool
94 found;
95 EDITOR_KEY_BINDING
96 *currentEntry;
97
98 currentEntry=*GetBindingHashListHead(keyCode); // point to the head of the linked list at this hash entry
99 found=false;
100 while(currentEntry&&!found)
101 {
102 if((currentEntry->keyCode==keyCode)&&((currentEntry->modifierMask&modifierValue)==currentEntry->modifierValue))
103 {
104 found=true;
105 }
106 else
107 {
108 currentEntry=currentEntry->nextHashBinding;
109 }
110 }
111 return(currentEntry);
112 }
113
DeleteEditorKeyBinding(UINT32 keyCode,UINT32 modifierMask,UINT32 modifierValue)114 bool DeleteEditorKeyBinding(UINT32 keyCode,UINT32 modifierMask,UINT32 modifierValue)
115 // attempt to locate the given binding in the key bindings table, and
116 // remove it if it is found
117 // if it is not located, return false
118 {
119 EDITOR_KEY_BINDING
120 **hashListHead,
121 *previousHashEntry,
122 *entry;
123
124 if(LocateKeyBinding(keyCode,modifierMask,modifierValue,&hashListHead,&previousHashEntry,&entry))
125 {
126 if(previousHashEntry)
127 {
128 previousHashEntry->nextHashBinding=entry->nextHashBinding; // unlink the located entry
129 }
130 else
131 {
132 *hashListHead=entry->nextHashBinding;
133 }
134 if(entry->previousBinding)
135 {
136 if((entry->previousBinding->nextBinding=entry->nextBinding))
137 {
138 entry->nextBinding->previousBinding=entry->previousBinding;
139 }
140 }
141 else
142 {
143 if((keyBindingListHead=entry->nextBinding))
144 {
145 keyBindingListHead->previousBinding=NULL;
146 }
147 }
148 MDisposePtr(entry);
149 return(true);
150 }
151 return(false);
152 }
153
CreateEditorKeyBinding(UINT32 keyCode,UINT32 modifierMask,UINT32 modifierValue,char * dataText)154 bool CreateEditorKeyBinding(UINT32 keyCode,UINT32 modifierMask,UINT32 modifierValue,char *dataText)
155 // search the key binding table for an entry that matches the one given, and delete it if
156 // it exists. Then add this entry to the table
157 // if there is a problem, SetError, and return false
158 {
159 EDITOR_KEY_BINDING
160 **hashListHead,
161 *newEntry;
162
163 DeleteEditorKeyBinding(keyCode,modifierMask,modifierValue); // try to delete one if it exists
164 hashListHead=GetBindingHashListHead(keyCode); // point to head of list in hash table where this binding will go
165 if((newEntry=(EDITOR_KEY_BINDING *)MNewPtr(sizeof(EDITOR_KEY_BINDING)+strlen(dataText)+1)))
166 {
167 newEntry->keyCode=keyCode;
168 newEntry->modifierMask=modifierMask;
169 newEntry->modifierValue=modifierValue;
170 newEntry->nextHashBinding=*hashListHead;
171 strcpy(&(newEntry->dataText[0]),dataText); // copy in the data
172 *hashListHead=newEntry; // link to head of hash list
173 newEntry->previousBinding=NULL;
174 if((newEntry->nextBinding=keyBindingListHead)) // point to the next entry
175 {
176 keyBindingListHead->previousBinding=newEntry;
177 }
178 keyBindingListHead=newEntry;
179 return(true);
180 }
181 return(false);
182 }
183
InitKeyBindingTable()184 bool InitKeyBindingTable()
185 // clear the key binding table so that there are no bindings present
186 // if there is a problem, SetError, and return false
187 {
188 int
189 i;
190
191 for(i=0;i<256;i++)
192 {
193 keyBindingTable[i]=NULL;
194 }
195 keyBindingListHead=NULL;
196 return(true);
197 }
198
UnInitKeyBindingTable()199 void UnInitKeyBindingTable()
200 // remove all key bindings from the bindings table
201 {
202 int
203 i;
204 EDITOR_KEY_BINDING
205 *currentEntry,
206 *nextEntry;
207
208 for(i=0;i<256;i++)
209 {
210 currentEntry=keyBindingTable[i];
211 while(currentEntry)
212 {
213 nextEntry=currentEntry->nextHashBinding;
214 MDisposePtr(currentEntry);
215 currentEntry=nextEntry;
216 }
217 keyBindingTable[i]=NULL;
218 }
219 keyBindingListHead=NULL;
220 }
221