added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / prefs / input / prefs.c
blobacd70f0e371cec6004102308a31339c82d75b339
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /*********************************************************************************************/
11 #define SHOWFLAGS 1 /* Set to 1 to show Flags in the keylist */
13 #include <proto/keymap.h>
15 #define DEBUG 0
16 #include <aros/debug.h>
18 #include "prefs.h"
20 /*********************************************************************************************/
22 IPTR mempool;
23 BOOL inputdev_changed = FALSE;
24 struct List keymap_list;
25 struct InputPrefs inputprefs;
26 struct InputPrefs restore_prefs;
27 struct MsgPort *InputMP;
28 struct timerequest *InputIO;
29 BPTR testkeymap_seg = NULL;
31 /*********************************************************************************************/
33 struct nameexp layout_expansion_table[] =
35 {"al" , "Albanian" , NULL },
36 {"usa" , "American (Sun 5c)" , "United_States" },
37 {"us" , "American (PC 104)" , "United_States" },
38 {"usx" , "American (PC 105)" , "United_States" },
39 {"d" , "Deutsch" , "Deutschland" },
40 {"be" , "Belge" , "Belgique" },
41 {"br" , "Brasileiro" , "Brasil" },
42 {"gb" , "British" , "United_Kingdom" },
43 {"gbx" , "British Extended" , "United_Kingdom" },
44 {"cdn" , "Canadien Français" , "Canada" },
45 {"ca" , "Canadien Français" , "Canada_Français" },
46 {"cz" , "Czech" , "Cesko" },
47 {"dk" , "Dansk" , "Danmark" },
48 {"ne" , "Dutch" , "Nederland" },
49 {"dvx" , "Dvorak" , "Espana" },
50 {"usa2" , "Dvorak" , NULL },
51 {"dvl" , "Dvorak Left-handed" , NULL },
52 {"dvr" , "Dvorak Right-handed" , NULL },
53 {"ir" , "English Ireland" , "Ireland" },
54 {"e" , "Español" , "España" },
55 {"sp" , "Español no deadkeys" , "España" },
56 {"et" , "Estonian" , NULL },
57 {"fi" , "Finnish" , "Suomi" },
58 {"f" , "Français" , "France" },
59 {"ic" , "Icelandic" , "Island" },
60 {"i" , "Italiana" , "Italia" },
61 {"la" , "Latin American" , NULL },
62 {"lv" , "Latvian" , NULL },
63 {"lt" , "Lithuanian" , NULL },
64 {"hu" , "Magyar" , NULL },
65 {"n" , "Norsk" , "Norge" },
66 {"pl" , "Polski" , "Polska" },
67 {"po" , "Português" , "Portugal" },
68 {"ru" , "Russian" , "Rossija" },
69 {"sg" , "Schweiz" , "Suisse" },
70 {"ch2" , "Schweiz" , "Suisse" },
71 {"sl" , "Slovak" , "Slovakia" },
72 {"sf" , "Suisse" , "Suisse" },
73 {"ch1" , "Suisse" , "Suisse" },
74 {"s" , "Svenskt" , "Sverige" },
75 {"ur" , "Ucranian" , "Ukrajina" },
76 {NULL , NULL , NULL }
79 /*********************************************************************************************/
81 static void ExpandName(STRPTR name, STRPTR flag, struct nameexp *exp)
83 for(; exp->shortname; exp++)
85 if (stricmp(exp->shortname, name) == 0)
87 strcpy(name, exp->longname);
88 if (exp->flag != NULL) strcpy(flag, exp->flag);
89 break;
94 /*********************************************************************************************/
97 void SortInNode(struct List *list, struct Node *node)
99 struct Node *sort, *prev = NULL;
101 ForeachNode(list, sort)
103 if (Stricmp(node->ln_Name, sort->ln_Name) < 0) break;
104 prev = sort;
107 Insert(list, node, prev);
110 void ScanDirectory(STRPTR pattern, struct List *list, LONG entrysize)
112 struct AnchorPath ap;
113 struct ListviewEntry *entry, *entry2;
114 struct List templist;
115 STRPTR sp;
116 LONG error;
118 memset(&ap, 0, sizeof(ap));
119 NewList(&templist);
121 error = MatchFirst(pattern, &ap);
122 while((error == 0))
124 if (ap.ap_Info.fib_DirEntryType < 0)
126 entry = (struct ListviewEntry *)AllocPooled(mempool, entrysize);
127 if (entry)
129 entry->node.ln_Name = entry->layoutname;
130 strncpy(entry->realname, ap.ap_Info.fib_FileName, sizeof(entry->realname));
132 sp = strchr(entry->realname, '_');
133 if (sp)
135 sp[0] = '\0';
136 strcpy(entry->layoutname, sp + 1);
137 sp[0] = '_';
139 else
140 strcpy(entry->layoutname, entry->realname);
142 ExpandName(entry->layoutname, entry->flagname, layout_expansion_table);
143 AddTail(&templist, &entry->node);
146 error = MatchNext(&ap);
148 MatchEnd(&ap);
150 /* Sort by Layout Name */
152 ForeachNodeSafe(&templist, entry, entry2)
154 Remove(&entry->node);
155 SortInNode(list, &entry->node);
158 ForeachNode(list, entry)
160 #if SHOWFLAGS == 1
161 sprintf(entry->displayname, "\033I[5:Locale:Flags/Countries/%s]%s", entry->flagname, entry->node.ln_Name);
162 #else
163 sprintf(entry->displayname, "%s", entry->node.ln_Name);
164 #endif
165 D(bug("IPrefs: kbd entry flag: %s\n", entry->flagname));
169 /*********************************************************************************************/
171 BOOL LoadPrefs(BPTR fh)
173 static struct FileInputPrefs loadprefs;
174 struct IFFHandle *iff;
175 BOOL retval = FALSE;
177 if ((iff = AllocIFF()))
179 iff->iff_Stream = fh;
180 if (fh != NULL)
182 D(bug("LoadPrefs: stream opened.\n"));
184 InitIFFasDOS(iff);
186 if (!OpenIFF(iff, IFFF_READ))
188 D(bug("LoadPrefs: OpenIFF okay.\n"));
190 if (!StopChunk(iff, ID_PREF, ID_INPT))
192 D(bug("LoadPrefs: StopChunk okay.\n"));
194 if (!ParseIFF(iff, IFFPARSE_SCAN))
196 struct ContextNode *cn;
198 D(bug("LoadPrefs: ParseIFF okay.\n"));
200 cn = CurrentChunk(iff);
202 if (cn->cn_Size == sizeof(struct FileInputPrefs))
204 D(bug("LoadPrefs: ID_INPT chunk size okay.\n"));
206 if (ReadChunkBytes(iff, &loadprefs, sizeof(struct FileInputPrefs)) == sizeof(struct FileInputPrefs))
208 D(bug("LoadPrefs: Reading chunk successful.\n"));
210 CopyMem(loadprefs.ip_Keymap, inputprefs.ip_Keymap, sizeof(loadprefs.ip_Keymap));
211 inputprefs.ip_PointerTicks = ARRAY_TO_WORD(loadprefs.ip_PointerTicks);
212 inputprefs.ip_DoubleClick.tv_secs = ARRAY_TO_LONG(loadprefs.ip_DoubleClick_secs);
213 inputprefs.ip_DoubleClick.tv_micro = ARRAY_TO_LONG(loadprefs.ip_DoubleClick_micro);
214 inputprefs.ip_KeyRptDelay.tv_secs = ARRAY_TO_LONG(loadprefs.ip_KeyRptDelay_secs);
215 inputprefs.ip_KeyRptDelay.tv_micro = ARRAY_TO_LONG(loadprefs.ip_KeyRptDelay_micro);
216 inputprefs.ip_KeyRptSpeed.tv_secs = ARRAY_TO_LONG(loadprefs.ip_KeyRptSpeed_secs);
217 inputprefs.ip_KeyRptSpeed.tv_micro = ARRAY_TO_LONG(loadprefs.ip_KeyRptSpeed_micro);
218 inputprefs.ip_MouseAccel = ARRAY_TO_WORD(loadprefs.ip_MouseAccel);
220 D(bug("LoadPrefs: Everything okay :-)\n"));
222 retval = TRUE;
226 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
228 } /* if (!StopChunk(iff, ID_PREF, ID_INPT)) */
230 CloseIFF(iff);
232 } /* if (!OpenIFF(iff, IFFF_READ)) */
234 } /* if (fh != NULL) */
236 FreeIFF(iff);
238 } /* if ((iff = AllocIFF())) */
240 return retval;
243 /*********************************************************************************************/
245 BOOL SavePrefs(BPTR fh)
247 static struct FileInputPrefs saveprefs;
248 struct IFFHandle *iff;
249 BOOL retval = FALSE, delete_if_error = FALSE;
251 CopyMem(inputprefs.ip_Keymap, saveprefs.ip_Keymap, sizeof(saveprefs.ip_Keymap));
252 WORD_TO_ARRAY(inputprefs.ip_PointerTicks, saveprefs.ip_PointerTicks);
253 LONG_TO_ARRAY(inputprefs.ip_DoubleClick.tv_secs , saveprefs.ip_DoubleClick_secs);
254 LONG_TO_ARRAY(inputprefs.ip_DoubleClick.tv_micro, saveprefs.ip_DoubleClick_micro);
255 LONG_TO_ARRAY(inputprefs.ip_KeyRptDelay.tv_secs , saveprefs.ip_KeyRptDelay_secs);
256 LONG_TO_ARRAY(inputprefs.ip_KeyRptDelay.tv_micro, saveprefs.ip_KeyRptDelay_micro);
257 LONG_TO_ARRAY(inputprefs.ip_KeyRptSpeed.tv_secs , saveprefs.ip_KeyRptSpeed_secs);
258 LONG_TO_ARRAY(inputprefs.ip_KeyRptSpeed.tv_micro, saveprefs.ip_KeyRptSpeed_micro);
259 WORD_TO_ARRAY(inputprefs.ip_MouseAccel, saveprefs.ip_MouseAccel);
261 if ((iff = AllocIFF()))
263 iff->iff_Stream = fh;
264 if (iff->iff_Stream)
266 D(bug("SavePrefs: stream opened.\n"));
268 delete_if_error = TRUE;
270 InitIFFasDOS(iff);
272 if (!OpenIFF(iff, IFFF_WRITE))
274 D(bug("SavePrefs: OpenIFF okay.\n"));
276 if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN))
278 D(bug("SavePrefs: PushChunk(FORM) okay.\n"));
280 if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct FilePrefHeader)))
282 struct FilePrefHeader head;
284 D(bug("SavePrefs: PushChunk(PRHD) okay.\n"));
286 head.ph_Version = 0; // FIXME: shouold be PHV_CURRENT, but see <prefs/prefhdr.h>
287 head.ph_Type = 0;
288 head.ph_Flags[0] =
289 head.ph_Flags[1] =
290 head.ph_Flags[2] =
291 head.ph_Flags[3] = 0;
293 if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head))
295 D(bug("SavePrefs: WriteChunkBytes(PRHD) okay.\n"));
297 PopChunk(iff);
299 if (!PushChunk(iff, ID_PREF, ID_INPT, sizeof(saveprefs)))
301 D(bug("SavePrefs: PushChunk(INPT) okay.\n"));
303 if (WriteChunkBytes(iff, &saveprefs, sizeof(saveprefs)) == sizeof(saveprefs))
305 D(bug("SavePrefs: WriteChunkBytes(INPT) okay.\n"));
306 D(bug("SavePrefs: Everything okay :-)\n"));
308 retval = TRUE;
311 PopChunk(iff);
313 } /* if (!PushChunk(iff, ID_PREF, ID_INPT, sizeof(saveprefs))) */
315 } /* if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head)) */
316 else
318 PopChunk(iff);
321 } /* if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct PrefHeader))) */
323 PopChunk(iff);
325 } /* if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN)) */
327 CloseIFF(iff);
329 } /* if (!OpenIFF(iff, IFFFWRITE)) */
332 } /* if (iff->iff_Stream)) */
334 FreeIFF(iff);
336 } /* if ((iff = AllocIFF())) */
338 // if (!retval && delete_if_error)
339 // {
340 // DeleteFile(filename);
341 // }
343 return retval;
346 /*********************************************************************************************/
348 BOOL DefaultPrefs(void)
350 strcpy(inputprefs.ip_Keymap, "amiga_usa0");
351 inputprefs.ip_PointerTicks = 1;
352 inputprefs.ip_DoubleClick.tv_secs = 0;
353 inputprefs.ip_DoubleClick.tv_micro = 500000;
354 inputprefs.ip_KeyRptDelay.tv_secs = 0;
355 inputprefs.ip_KeyRptDelay.tv_micro = 500000;
356 inputprefs.ip_KeyRptSpeed.tv_secs = 0;
357 inputprefs.ip_KeyRptSpeed.tv_micro = 40000;
358 inputprefs.ip_MouseAccel = 1;
360 return TRUE;
363 /*********************************************************************************************/
365 void CopyPrefs(struct InputPrefs *s, struct InputPrefs *d)
367 CopyMem(s, d, sizeof(struct InputPrefs));
370 void RestorePrefs(void)
372 CopyPrefs(&restore_prefs, &inputprefs);
375 /*********************************************************************************************/
377 void update_inputdev(void)
379 if (InputIO)
381 if (InputIO->tr_node.io_Device)
383 InputIO->tr_node.io_Command = IND_SETPERIOD;
384 InputIO->tr_time = inputprefs.ip_KeyRptSpeed;
385 DoIO(&InputIO->tr_node);
387 InputIO->tr_node.io_Command = IND_SETTHRESH;
388 InputIO->tr_time = inputprefs.ip_KeyRptDelay;
389 DoIO(&InputIO->tr_node);
391 inputdev_changed = TRUE;
397 void try_setting_mousespeed(void)
399 struct Preferences p;
401 GetPrefs(&p, sizeof(p));
402 p.PointerTicks = inputprefs.ip_PointerTicks;
403 p.DoubleClick = inputprefs.ip_DoubleClick;
404 p.KeyRptDelay = inputprefs.ip_KeyRptDelay;
405 p.KeyRptSpeed = inputprefs.ip_KeyRptSpeed;
406 if (inputprefs.ip_MouseAccel)
408 p.EnableCLI |= MOUSE_ACCEL;
410 else
412 p.EnableCLI &= ~MOUSE_ACCEL;
415 SetPrefs(&p, sizeof(p), FALSE);
418 void try_setting_test_keymap(void)
420 struct KeyMapResource *KeyMapResource;
421 struct Library *KeymapBase;
422 struct KeyMapNode *kmn = NULL;
423 struct Node *node;
424 BPTR lock, seg, olddir, oldseg = 0;
426 if ((KeyMapResource = OpenResource("keymap.resource")))
428 Forbid();
430 ForeachNode(&KeyMapResource->kr_List, node)
432 if (!stricmp(inputprefs.ip_Keymap, node->ln_Name))
434 kmn = (struct KeyMapNode *)node;
435 break;
439 Permit();
443 if (!kmn)
445 lock = Lock("DEVS:Keymaps", SHARED_LOCK);
447 if (lock)
449 olddir = CurrentDir(lock);
451 if ((seg = LoadSeg(inputprefs.ip_Keymap)))
453 kmn = (struct KeyMapNode *) (((UBYTE *)BADDR(seg)) + sizeof(APTR));
454 oldseg = testkeymap_seg;
455 testkeymap_seg = seg;
459 CurrentDir(olddir);
460 UnLock(lock);
464 if (kmn)
466 KeymapBase = OpenLibrary("keymap.library", 0);
467 if (KeymapBase)
469 SetKeyMapDefault((IPTR)&kmn->kn_KeyMap);
470 CloseLibrary(KeymapBase);
473 if (oldseg) UnLoadSeg(oldseg);
477 void kbd_cleanup(void)
479 if (inputdev_changed)
481 InputIO->tr_node.io_Command = IND_SETPERIOD;
482 InputIO->tr_time = restore_prefs.ip_KeyRptSpeed;
483 DoIO(&InputIO->tr_node);
485 InputIO->tr_node.io_Command = IND_SETTHRESH;
486 InputIO->tr_time = restore_prefs.ip_KeyRptDelay;
487 DoIO(&InputIO->tr_node);
488 inputdev_changed = FALSE;
491 if (testkeymap_seg)
493 UnLoadSeg(testkeymap_seg);