Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / classes / gadgets / texteditor / mcp / KeyStorage.c
blobd80e8f0094012a4059d30f66c78faf84e0ef41bf
1 /***************************************************************************
3 TextEditor.mcc - Textediting MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005 by TextEditor.mcc Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 TextEditor class Support Site: http://www.sf.net/projects/texteditor-mcc
19 $Id$
21 ***************************************************************************/
23 #include <math.h>
24 #include <string.h>
26 #include <clib/alib_protos.h>
27 #include <devices/inputevent.h>
28 #include <dos/dos.h>
29 #include <dos/dostags.h>
30 #include <dos/rdargs.h>
31 #include <exec/memory.h>
32 #include <libraries/mui.h>
33 #include <mui/HotkeyString_mcc.h>
34 #include <proto/dos.h>
35 #include <proto/exec.h>
36 #include <proto/intuition.h>
37 #include <proto/keymap.h>
38 #include <proto/muimaster.h>
40 #include "private.h"
41 #ifdef __AROS__
42 #include "../includes/newmouse.h"
43 #else
44 #include "newmouse.h"
45 #endif
47 #define KEYS_COUNT (64)
49 void ConvertKeyString (STRPTR keystring, UWORD action, struct KeyAction *storage)
51 LONG args[KEYS_COUNT];
52 struct RDArgs *ra_result;
53 struct RDArgs *myrdargs;
54 ULONG count = 0;
56 static const STRPTR ratemplate =
57 "LSHIFT/S,RSHIFT/S,CAPSLOCK/S,CONTROL=CTRL/S,LALT/S,RALT/S,LAMIGA=LCOMMAND/S,RAMIGA=RCOMMAND/S,NUMPAD=NUMERICPAD/S,SHIFT/S,ALT/S,AMIGA=COMMAND/S,"
58 "f1/S,f2/S,f3/S,f4/S,f5/S,f6/S,f7/S,f8/S,f9/S,f10/S,f11/S,f12/S"
59 "help/S,"
60 "up/S,down/S,right/S,left/S,"
61 "home/S,end/S,page_up=pageup/S,page_down=pagedown/S,insert/S,printscreen=prtscr/S,pause=break/S,numlock/S,"
62 #if defined(__amigaos4__)
63 "menu/S"
64 #elif defined(__MORPHOS__)
65 "scrolllock=scrlock/S"
66 #endif
67 "media_stop/S,media_play/S,media_prev/S,media_next/S,media_rewind/S,media_forward/S,"
68 "nm_wheel_up/S,nm_wheel_down/S,nm_wheel_left/S,nm_wheel_right/S,nm_wheel_button/S"
69 "escape=esc/S,tab/S,return=enter/S,space/S,backspace=bs/S,delete=del/S,key/F";
71 storage->vanilla = FALSE;
72 storage->key = 0;
73 storage->qualifier = 0;
74 storage->action = action;
76 // clear all args
77 while(count < KEYS_COUNT)
78 args[count++] = 0L;
80 if((myrdargs = AllocDosObject(DOS_RDARGS, NULL)))
82 ULONG length = strlen(keystring);
83 char *buffer;
85 if((buffer = AllocMem(length+2, MEMF_ANY)))
87 CopyMem(keystring, buffer, length);
88 buffer[length] = '\n';
89 buffer[length+1] = '\0';
90 myrdargs->RDA_Source.CS_Buffer = buffer;
91 myrdargs->RDA_Source.CS_Length = length+1;
92 myrdargs->RDA_Source.CS_CurChr = 0;
93 myrdargs->RDA_Flags |= RDAF_NOPROMPT;
95 if((ra_result = ReadArgs(ratemplate, args, myrdargs)))
97 ULONG qual = 1;
99 // Scan for 12 qualifier keys
100 for(count = 0;count < 12;count++)
102 if(args[count])
104 storage->qualifier |= qual;
106 qual = qual << 1;
109 // Scan for the 10 standard F-keys (f1-f10)
110 for(;count < 22;count++)
112 if(args[count])
113 storage->key = count+0x44;
116 // Scan for the 2 extended f-keys (f11,f12)
117 if(args[count++])
118 storage->key = RAWKEY_F11;
119 if(args[count++])
120 storage->key = RAWKEY_F12;
122 // Help
123 if(args[count++])
124 storage->key = RAWKEY_HELP;
126 // Scan for cursor-keys
127 for(;count < 27;count++)
129 if(args[count])
130 storage->key = count+0x35;
133 // scan for the other extended (non-standard) keys
134 if(args[count++])
135 storage->key = RAWKEY_HOME;
136 if(args[count++])
137 storage->key = RAWKEY_END;
138 if(args[count++])
139 storage->key = RAWKEY_PAGEUP;
140 if(args[count++])
141 storage->key = RAWKEY_PAGEDOWN;
142 if(args[count++])
143 storage->key = RAWKEY_INSERT;
144 if(args[count++])
145 storage->key = RAWKEY_PRINTSCR;
146 if(args[count++])
147 storage->key = RAWKEY_BREAK;
148 if(args[count++])
149 storage->key = RAWKEY_NUMLOCK;
151 // some keys are mutual excluse on some platforms
152 #if defined(__amigso4__)
153 if(args[count++])
154 storage->key = RAWKEY_MENU;
155 #elif defined(__MORPHOS__)
156 if(args[count++])
157 storage->key = RAWKEY_SCRLOCK;
158 #endif
160 // lets address the media/CDTV keys as well
161 if(args[count++])
162 storage->key = RAWKEY_AUD_STOP;
163 if(args[count++])
164 storage->key = RAWKEY_AUD_PLAY_PAUSE;
165 if(args[count++])
166 storage->key = RAWKEY_AUD_PREV_TRACK;
167 if(args[count++])
168 storage->key = RAWKEY_AUD_NEXT_TRACK;
169 if(args[count++])
170 storage->key = RAWKEY_AUD_SHUFFLE;
171 if(args[count++])
172 storage->key = RAWKEY_AUD_REPEAT;
174 // take respect of the NEWMOUSE RAWKEY based wheel events as well
175 if(args[count++])
176 storage->key = NM_WHEEL_UP;
177 if(args[count++])
178 storage->key = NM_WHEEL_DOWN;
179 if(args[count++])
180 storage->key = NM_WHEEL_LEFT;
181 if(args[count++])
182 storage->key = NM_WHEEL_RIGHT;
183 if(args[count++])
184 storage->key = NM_BUTTON_FOURTH;
186 if(!storage->key)
188 storage->vanilla = TRUE;
189 if(args[count++])
190 storage->key = 27; /* Esc */
191 if(args[count++])
192 storage->key = 9; /* Tab */
193 if(args[count++])
194 storage->key = 13; /* CR */
195 if(args[count++])
196 storage->key = ' '; /* Space */
197 if(args[count++])
198 storage->key = 8; /* Backspace */
199 if(args[count++])
200 storage->key = 0x7f; /* Delete */
202 if(!storage->key)
204 storage->key = (UWORD)*(STRPTR)args[count];
207 FreeArgs(ra_result);
209 FreeMem(buffer, length+2);
211 FreeDosObject(DOS_RDARGS, myrdargs);
215 void KeyToString (STRPTR buffer, struct KeyAction *ka)
217 buffer[0] = '\0';
219 // lets first put the qualifiers in our buffer string
220 if(ka->qualifier & IEQUALIFIER_LSHIFT)
221 strcat(buffer, "lshift ");
222 if(ka->qualifier & IEQUALIFIER_RSHIFT)
223 strcat(buffer, "rshift ");
224 if(ka->qualifier & IEQUALIFIER_CAPSLOCK)
225 strcat(buffer, "capslock ");
226 if(ka->qualifier & IEQUALIFIER_CONTROL)
227 strcat(buffer, "control ");
228 if(ka->qualifier & IEQUALIFIER_LALT)
229 strcat(buffer, "lalt ");
230 if(ka->qualifier & IEQUALIFIER_RALT)
231 strcat(buffer, "ralt ");
232 if(ka->qualifier & IEQUALIFIER_LCOMMAND)
233 strcat(buffer, "lcommand ");
234 if(ka->qualifier & IEQUALIFIER_RCOMMAND)
235 strcat(buffer, "rcommand ");
236 if(ka->qualifier & IEQUALIFIER_NUMERICPAD)
237 strcat(buffer, "numpad ");
238 if(ka->qualifier & IEQUALIFIER_SHIFT)
239 strcat(buffer, "shift ");
240 if(ka->qualifier & IEQUALIFIER_ALT)
241 strcat(buffer, "alt ");
242 if(ka->qualifier & IEQUALIFIER_COMMAND)
243 strcat(buffer, "command ");
245 // then we check wheter this are vanilla key codes or RAWKEY codes
246 if(ka->vanilla)
248 switch(ka->key)
250 case 8: strcat(buffer, "backspace"); break;
251 case 9: strcat(buffer, "tab"); break;
252 case 13: strcat(buffer, ((ka->qualifier & IEQUALIFIER_NUMERICPAD) ? "enter" : "return")); break;
253 case 27: strcat(buffer, "esc"); break;
254 case 32: strcat(buffer, "space"); break;
255 case 0x7f:strcat(buffer, "del"); break;
257 default:
259 char *p = &buffer[strlen(buffer)];
261 *p = ka->key;
262 p++;
263 *p = '\0';
267 else
269 switch(ka->key)
271 case RAWKEY_CRSRUP: strcat(buffer, "up"); break;
272 case RAWKEY_CRSRDOWN: strcat(buffer, "down"); break;
273 case RAWKEY_CRSRRIGHT: strcat(buffer, "right"); break;
274 case RAWKEY_CRSRLEFT: strcat(buffer, "left"); break;
275 case RAWKEY_F1: strcat(buffer, "f1"); break;
276 case RAWKEY_F2: strcat(buffer, "f2"); break;
277 case RAWKEY_F3: strcat(buffer, "f3"); break;
278 case RAWKEY_F4: strcat(buffer, "f4"); break;
279 case RAWKEY_F5: strcat(buffer, "f5"); break;
280 case RAWKEY_F6: strcat(buffer, "f6"); break;
281 case RAWKEY_F7: strcat(buffer, "f7"); break;
282 case RAWKEY_F8: strcat(buffer, "f8"); break;
283 case RAWKEY_F9: strcat(buffer, "f9"); break;
284 case RAWKEY_F10: strcat(buffer, "f10"); break;
285 case RAWKEY_F11: strcat(buffer, "f11"); break;
286 case RAWKEY_F12: strcat(buffer, "f12"); break;
287 case RAWKEY_HELP: strcat(buffer, "help"); break;
288 case RAWKEY_HOME: strcat(buffer, "home"); break;
289 case RAWKEY_END: strcat(buffer, "end"); break;
290 case RAWKEY_PAGEUP: strcat(buffer, "page_up"); break;
291 case RAWKEY_PAGEDOWN: strcat(buffer, "page_down"); break;
292 case RAWKEY_INSERT: strcat(buffer, "insert"); break;
293 case RAWKEY_PRINTSCR: strcat(buffer, "printscreen"); break;
294 case RAWKEY_BREAK: strcat(buffer, "pause"); break;
295 case RAWKEY_NUMLOCK: strcat(buffer, "numlock"); break;
297 #if defined(__amigaos4__)
298 case RAWKEY_MENU: strcat(buffer, "menu"); break;
299 #elif defined(__MORPHOS__)
300 case RAWKEY_SCRLOCK: strcat(buffer, "scrolllock"); break;
301 #endif
303 case RAWKEY_AUD_STOP: strcat(buffer, "media_stop"); break;
304 case RAWKEY_AUD_PLAY_PAUSE: strcat(buffer, "media_play"); break;
305 case RAWKEY_AUD_PREV_TRACK: strcat(buffer, "media_prev"); break;
306 case RAWKEY_AUD_NEXT_TRACK: strcat(buffer, "media_next"); break;
307 case RAWKEY_AUD_SHUFFLE: strcat(buffer, "media_rewind"); break;
308 case RAWKEY_AUD_REPEAT: strcat(buffer, "media_forward"); break;
310 case NM_WHEEL_UP: strcat(buffer, "nm_wheel_up"); break;
311 case NM_WHEEL_DOWN: strcat(buffer, "nm_wheel_down"); break;
312 case NM_WHEEL_LEFT: strcat(buffer, "nm_wheel_left"); break;
313 case NM_WHEEL_RIGHT: strcat(buffer, "nm_wheel_right"); break;
314 case NM_BUTTON_FOURTH: strcat(buffer, "nm_wheel_button"); break;
316 default:
317 strcat(buffer, "???");
322 void ImportKeys(void *config, struct InstData_MCP *data)
324 void *cfg_data;
326 DoMethod(data->keybindings, MUIM_List_Clear);
327 set(data->keybindings, MUIA_List_Quiet, TRUE);
328 if((cfg_data = (void *)DoMethod(config, MUIM_Dataspace_Find, MUICFG_TextEditor_Keybindings)))
330 struct te_key *entries = cfg_data;
332 while(entries->code != (UWORD)-1)
334 DoMethod(data->keybindings, MUIM_List_InsertSingle, entries++, MUIV_List_Insert_Bottom);
337 else
339 DoMethod(data->keybindings, MUIM_List_Insert, keybindings, (ULONG)-1, MUIV_List_Insert_Bottom);
341 set(data->keybindings, MUIA_List_Quiet, FALSE);
343 /* if(cfg_data = (void *)DoMethod(config, MUIM_Dataspace_Find, MUICFG_TextEditor_SuggestKey))
345 UBYTE buffer[100];
346 struct KeyAction *ka = cfg_data;
348 KeyToString(buffer, ka);
349 set(data->suggestkey, MUIA_Hotkey_Hotkey, buffer);
351 else
353 set(data->suggestkey, MUIA_Hotkey_Hotkey, "help");
357 void ExportKeys(void *config, struct InstData_MCP *data)
359 ULONG c, size;
360 struct te_key *entry;
361 struct te_key *entries;
363 get(data->keybindings, MUIA_List_Entries, &c);
364 size = (c+1) * sizeof(struct te_key);
366 if((entries = (struct te_key *)AllocMem(size, MEMF_ANY)))
368 struct te_key *buffer = entries+c;
370 buffer->code = -1;
371 while(c--)
373 DoMethod(data->keybindings, MUIM_List_GetEntry, c, &entry);
374 buffer--;
375 buffer->code = entry->code;
376 buffer->qual = entry->qual;
377 buffer->act = entry->act;
379 DoMethod(config, MUIM_Dataspace_Add, entries, size, MUICFG_TextEditor_Keybindings);
380 FreeMem((APTR)entries, size);