grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / prefs / input / prefs.c
blob0a5b11a0000c1d42370d8f3ead5dbd944b0fc7cd
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Change your input preferences
6 Lang: English
7 */
9 /*********************************************************************************************/
11 #define SHOWFLAGS 1 /* Set to 1 to show Flags in the keylist */
13 #include <libraries/kms.h>
15 #include <proto/alib.h>
16 #include <proto/dos.h>
17 #include <proto/intuition.h>
18 #include <proto/iffparse.h>
19 #include <proto/utility.h>
21 #define DEBUG 0
22 #include <aros/debug.h>
24 #include "prefs.h"
25 #include "misc.h"
27 /*********************************************************************************************/
29 #define PREFS_PATH_ENVARC "ENVARC:SYS/input.prefs"
30 #define PREFS_PATH_ENV "ENV:SYS/input.prefs"
32 /*********************************************************************************************/
34 APTR mempool;
35 struct InputPrefs inputprefs;
36 struct KMSPrefs kmsprefs;
37 struct List keymap_list;
39 /*********************************************************************************************/
41 static const struct nameexp layout_expansion_table[] =
43 {"usa" , "American" , "Countries/United_States" },
44 {"usa0" , "American" , "Countries/United_States" },
45 {"us" , "American" , "Countries/United_States" },
46 {"usx" , "American" , "Countries/United_States" },
47 {"col" , "Colemak (US)" , "Countries/United_States" },
48 {"d" , "Deutsch" , "Countries/Germany" },
49 {"b" , "Belge" , "Countries/Belgium" },
50 {"by" , "Belarussian" , "Countries/Belarus" },
51 {"br" , "Brasileiro" , "Countries/Brazil" },
52 {"gb" , "British" , "Countries/United_Kingdom"},
53 {"gbx" , "British Extended" , "Countries/United_Kingdom"},
54 {"bg" , "Bulgarian" , "Countries/Bulgaria" },
55 {"cdn" , "Canadien Français" , "Countries/Quebec" },
56 {"cz" , "Czech" , "Countries/Czech_Republic"},
57 {"dk" , "Dansk" , "Countries/Denmark" },
58 {"nl" , "Dutch" , "Countries/Netherlands" },
59 {"dvx" , "Dvorak" , "Misc/Unknown" },
60 {"usa2" , "Dvorak" , "Misc/Unknown" },
61 {"dvl" , "Dvorak Left-handed" , "Misc/Unknown" },
62 {"dvr" , "Dvorak Right-handed" , "Misc/Unknown" },
63 {"irl" , "English Ireland" , "Countries/Ireland" },
64 {"e" , "Español" , "Countries/Spain" },
65 {"sp" , "Español no deadkeys" , "Countries/Spain" },
66 {"est" , "Eesti" , "Countries/Estonia" },
67 {"fin" , "Finnish" , "Countries/Finland" },
68 {"f" , "Français" , "Countries/France" },
69 {"il" , "Hebrew" , "Countries/Israel" },
70 {"gr" , "Hellenic" , "Countries/Greece" },
71 {"hr" , "Hrvatski" , "Countries/Croatia" },
72 {"is" , "Íslenska" , "Countries/Iceland" },
73 {"i" , "Italiana" , "Countries/Italy" },
74 {"la" , "Latin American" , "Misc/Unknown" },
75 {"lv" , "Latvijas" , "Countries/Latvia" },
76 {"lt" , "Lietuvos" , "Countries/Lithuania" },
77 {"h" , "Magyar" , "Countries/Hungary" },
78 {"n" , "Norsk" , "Countries/Norway" },
79 {"pl" , "Polski" , "Countries/Poland" },
80 {"p" , "Português" , "Countries/Portugal" },
81 {"ro" , "Românesc" , "Countries/Romania" },
82 {"rus" , "Russian" , "Countries/Russia" },
83 {"ch1" , "Schweizer" , "Countries/Switzerland" },
84 {"al" , "Shqip" , "Countries/Albania" },
85 {"sk" , "Slovak" , "Countries/Slovakia" },
86 {"ch2" , "Suisse" , "Countries/Switzerland" },
87 {"s" , "Svenskt" , "Countries/Sweden" },
88 {"tr" , "Türkçe" , "Countries/Turkey" },
89 {"ua" , "Ukranian" , "Countries/Ukraine" },
90 {NULL , NULL , NULL }
93 static const struct typeexp type_expansion_table[] = {
94 {"amiga", "Amiga" },
95 {"pc104", "PC 104"},
96 {"pc105", "PC 105"},
97 {"sun" , "Sun" },
98 {NULL , NULL }
101 /*********************************************************************************************/
103 static BOOL Prefs_Load(STRPTR from)
105 BOOL retval = FALSE;
107 BPTR fh = Open(from, MODE_OLDFILE);
108 if (fh)
110 retval = Prefs_ImportFH(fh);
111 Close(fh);
114 return retval;
117 /*********************************************************************************************/
119 static void ExpandName(struct ListviewEntry *entry)
121 char *sp;
122 char *type = NULL;
123 const struct nameexp *exp;
125 strcpy(entry->layoutname, entry->realname);
127 sp = strchr(entry->realname, '_');
128 if (sp)
131 * We have several variants of US keyboard, so
132 * we append type name.
134 if ((sp[1] == 'u' && sp[2] == 's'))
136 const struct typeexp *te;
138 *sp = 0;
139 for (te = type_expansion_table; te->shortname; te++)
141 if (!strcmp(entry->realname, te->shortname))
143 type = te->longname;
144 break;
147 *sp = '_';
149 sp++;
151 else
152 sp = entry->realname;
154 for (exp = layout_expansion_table; exp->shortname; exp++)
156 if (stricmp(exp->shortname, sp) == 0)
158 if (type)
159 snprintf(entry->layoutname, sizeof(entry->layoutname), "%s (%s)", exp->longname, type);
160 else
161 strcpy(entry->layoutname, exp->longname);
163 if (exp->flag != NULL)
165 #if SHOWFLAGS == 1
166 sprintf(entry->displayflag, "\033I[5:Locale:Flags/%s]", exp->flag);
167 #else
168 entry->displayflag[0] = '\0';
169 #endif
171 break;
178 /*********************************************************************************************/
181 void SortInNode(struct List *list, struct Node *node)
183 struct Node *sort, *prev = NULL;
185 ForeachNode(list, sort)
187 if (Stricmp(node->ln_Name, sort->ln_Name) < 0) break;
188 prev = sort;
191 Insert(list, node, prev);
194 void Prefs_ScanDirectory(STRPTR pattern, struct List *list, LONG entrysize)
196 struct AnchorPath ap;
197 struct ListviewEntry *entry, *entry2;
198 struct List templist;
199 STRPTR sp;
200 LONG error;
202 memset(&ap, 0, sizeof(ap));
203 NewList(&templist);
206 * Add default keymap.
207 * CHECKME: possibly too hacky. May be we should verify its presence in keymap.resource?
208 * How is it done in classic AmigaOS(tm) ?
210 entry = AllocPooled(mempool, entrysize);
211 if (entry)
213 strcpy(entry->layoutname, "American (Default)");
214 strcpy(entry->realname , DEFAULT_KEYMAP);
215 #if SHOWFLAGS == 1
216 strcpy(entry->displayflag, "\033I[5:Locale:Flags/Countries/United_States]");
217 #else
218 entry->displayflag[0] = '\0';
219 #endif
221 entry->node.ln_Name = entry->layoutname;
222 AddTail(&templist, &entry->node);
225 error = MatchFirst(pattern, &ap);
226 while((error == 0))
228 if (ap.ap_Info.fib_DirEntryType < 0)
230 entry = (struct ListviewEntry *)AllocPooled((APTR)mempool, entrysize);
231 if (entry)
233 entry->node.ln_Name = entry->layoutname;
234 strncpy(entry->realname, ap.ap_Info.fib_FileName, sizeof(entry->realname));
236 sp = strchr(entry->realname, '_');
237 if (sp)
238 sp++;
239 else
240 sp = entry->realname;
241 strcpy(entry->layoutname, sp);
243 ExpandName(entry);
244 AddTail(&templist, &entry->node);
247 error = MatchNext(&ap);
249 MatchEnd(&ap);
251 /* Sort by Layout Name */
253 ForeachNodeSafe(&templist, entry, entry2)
255 Remove(&entry->node);
256 SortInNode(list, &entry->node);
260 /*********************************************************************************************/
262 static LONG stopchunks[] =
264 ID_PREF, ID_INPT,
265 ID_PREF, ID_KMSW
268 BOOL Prefs_ImportFH(BPTR fh)
270 struct FileInputPrefs loadprefs;
271 struct FileKMSPrefs loadkmsprefs;
272 struct IFFHandle *iff;
273 ULONG size;
274 BOOL retval = FALSE;
276 memset(&loadprefs, 0, sizeof(loadprefs));
278 if ((iff = AllocIFF()))
280 iff->iff_Stream = (IPTR)fh;
281 if (fh != BNULL)
283 D(Printf("LoadPrefs: stream opened.\n"));
285 InitIFFasDOS(iff);
287 if (!OpenIFF(iff, IFFF_READ))
289 D(Printf("LoadPrefs: OpenIFF okay.\n"));
291 if (!StopChunks(iff, stopchunks, 2))
293 D(Printf("LoadPrefs: StopChunk okay.\n"));
294 retval = TRUE;
296 while (!ParseIFF(iff, IFFPARSE_SCAN))
298 struct ContextNode *cn;
300 D(Printf("LoadPrefs: ParseIFF okay.\n"));
302 cn = CurrentChunk(iff);
303 size = cn->cn_Size;
305 switch (cn->cn_ID)
307 case ID_INPT:
308 D(Printf("LoadPrefs: INPT chunk\n"));
310 if (size > sizeof(struct FileInputPrefs))
311 size = sizeof(struct FileInputPrefs);
313 if (ReadChunkBytes(iff, &loadprefs, size) == size)
315 D(Printf("LoadPrefs: Reading chunk successful.\n"));
317 CopyMem(loadprefs.ip_Keymap, inputprefs.ip_Keymap, sizeof(loadprefs.ip_Keymap));
318 inputprefs.ip_PointerTicks = ARRAY_TO_WORD(loadprefs.ip_PointerTicks);
319 inputprefs.ip_DoubleClick.tv_secs = ARRAY_TO_LONG(loadprefs.ip_DoubleClick_secs);
320 inputprefs.ip_DoubleClick.tv_micro = ARRAY_TO_LONG(loadprefs.ip_DoubleClick_micro);
321 inputprefs.ip_KeyRptDelay.tv_secs = ARRAY_TO_LONG(loadprefs.ip_KeyRptDelay_secs);
322 inputprefs.ip_KeyRptDelay.tv_micro = ARRAY_TO_LONG(loadprefs.ip_KeyRptDelay_micro);
323 inputprefs.ip_KeyRptSpeed.tv_secs = ARRAY_TO_LONG(loadprefs.ip_KeyRptSpeed_secs);
324 inputprefs.ip_KeyRptSpeed.tv_micro = ARRAY_TO_LONG(loadprefs.ip_KeyRptSpeed_micro);
325 inputprefs.ip_MouseAccel = ARRAY_TO_WORD(loadprefs.ip_MouseAccel);
326 inputprefs.ip_ClassicKeyboard = ARRAY_TO_LONG(loadprefs.ip_ClassicKeyboard);
327 CopyMem(loadprefs.ip_KeymapName, inputprefs.ip_KeymapName, sizeof(loadprefs.ip_KeymapName));
328 inputprefs.ip_SwitchMouseButtons = loadprefs.ip_SwitchMouseButtons[3];
330 D(Printf("LoadPrefs: SwitchMouseButtons: %ld\n", inputprefs.ip_SwitchMouseButtons));
332 else
333 retval = FALSE;
334 break;
336 case ID_KMSW:
337 D(Printf("LoadPrefs: KMSW chunk\n"));
339 if (size > sizeof(struct FileKMSPrefs))
340 size = sizeof(struct FileKMSPrefs);
342 if (ReadChunkBytes(iff, &loadkmsprefs, size) == size)
344 D(Printf("LoadPrefs: Reading chunk successful.\n"));
346 kmsprefs.kms_Enabled = loadkmsprefs.kms_Enabled;
347 kmsprefs.kms_Reserved = loadkmsprefs.kms_Reserved;
348 kmsprefs.kms_SwitchQual = ARRAY_TO_WORD(loadkmsprefs.kms_SwitchQual);
349 kmsprefs.kms_SwitchCode = ARRAY_TO_WORD(loadkmsprefs.kms_SwitchCode);
350 CopyMem(loadkmsprefs.kms_AltKeymap, kmsprefs.kms_AltKeymap, sizeof(kmsprefs.kms_AltKeymap));
352 else
353 retval = FALSE;
354 break;
356 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
357 } /* if (!StopChunk(iff, ID_PREF, ID_INPT)) */
358 CloseIFF(iff);
359 } /* if (!OpenIFF(iff, IFFF_READ)) */
360 } /* if (fh != NULL) */
361 FreeIFF(iff);
362 } /* if ((iff = AllocIFF())) */
364 return retval;
367 /*********************************************************************************************/
369 BOOL Prefs_ExportFH(BPTR fh)
371 struct FileInputPrefs saveprefs;
372 struct FileKMSPrefs savekmsprefs;
373 struct IFFHandle *iff;
374 BOOL retval = FALSE;
375 #if 0 /* unused */
376 BOOL delete_if_error = FALSE;
377 #endif
379 D(Printf("SavePrefs: SwitchMouseButtons: %ld\n", inputprefs.ip_SwitchMouseButtons));
381 CopyMem(inputprefs.ip_Keymap, saveprefs.ip_Keymap, sizeof(saveprefs.ip_Keymap));
382 WORD_TO_ARRAY(inputprefs.ip_PointerTicks, saveprefs.ip_PointerTicks);
383 LONG_TO_ARRAY(inputprefs.ip_DoubleClick.tv_secs , saveprefs.ip_DoubleClick_secs);
384 LONG_TO_ARRAY(inputprefs.ip_DoubleClick.tv_micro, saveprefs.ip_DoubleClick_micro);
385 LONG_TO_ARRAY(inputprefs.ip_KeyRptDelay.tv_secs , saveprefs.ip_KeyRptDelay_secs);
386 LONG_TO_ARRAY(inputprefs.ip_KeyRptDelay.tv_micro, saveprefs.ip_KeyRptDelay_micro);
387 LONG_TO_ARRAY(inputprefs.ip_KeyRptSpeed.tv_secs , saveprefs.ip_KeyRptSpeed_secs);
388 LONG_TO_ARRAY(inputprefs.ip_KeyRptSpeed.tv_micro, saveprefs.ip_KeyRptSpeed_micro);
389 WORD_TO_ARRAY(inputprefs.ip_MouseAccel, saveprefs.ip_MouseAccel);
390 LONG_TO_ARRAY(inputprefs.ip_ClassicKeyboard, saveprefs.ip_ClassicKeyboard);
391 CopyMem(inputprefs.ip_KeymapName, saveprefs.ip_KeymapName, sizeof(saveprefs.ip_KeymapName));
392 saveprefs.ip_SwitchMouseButtons[0] = 0;
393 saveprefs.ip_SwitchMouseButtons[1] = 0;
394 saveprefs.ip_SwitchMouseButtons[2] = 0;
395 saveprefs.ip_SwitchMouseButtons[3] = inputprefs.ip_SwitchMouseButtons;
397 savekmsprefs.kms_Enabled = kmsprefs.kms_Enabled;
398 savekmsprefs.kms_Reserved = kmsprefs.kms_Reserved;
399 WORD_TO_ARRAY(kmsprefs.kms_SwitchQual, savekmsprefs.kms_SwitchQual);
400 WORD_TO_ARRAY(kmsprefs.kms_SwitchCode, savekmsprefs.kms_SwitchCode);
401 CopyMem(kmsprefs.kms_AltKeymap, savekmsprefs.kms_AltKeymap, sizeof(savekmsprefs.kms_AltKeymap));
403 if ((iff = AllocIFF()))
405 iff->iff_Stream = (IPTR)fh;
406 if (iff->iff_Stream)
408 D(Printf("SavePrefs: stream opened.\n"));
410 #if 0 /* unused */
411 delete_if_error = TRUE;
412 #endif
414 InitIFFasDOS(iff);
416 if (!OpenIFF(iff, IFFF_WRITE))
418 D(Printf("SavePrefs: OpenIFF okay.\n"));
420 if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN))
422 D(Printf("SavePrefs: PushChunk(FORM) okay.\n"));
424 if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct FilePrefHeader)))
426 struct FilePrefHeader head;
428 D(Printf("SavePrefs: PushChunk(PRHD) okay.\n"));
430 head.ph_Version = 0; // FIXME: should be PHV_CURRENT, but see <prefs/prefhdr.h>
431 head.ph_Type = 0;
432 head.ph_Flags[0] =
433 head.ph_Flags[1] =
434 head.ph_Flags[2] =
435 head.ph_Flags[3] = 0;
437 if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head))
439 D(Printf("SavePrefs: WriteChunkBytes(PRHD) okay.\n"));
441 PopChunk(iff);
443 if (!PushChunk(iff, ID_PREF, ID_INPT, sizeof(saveprefs)))
445 D(Printf("SavePrefs: PushChunk(INPT) okay.\n"));
447 if (WriteChunkBytes(iff, &saveprefs, sizeof(saveprefs)) == sizeof(saveprefs))
449 D(Printf("SavePrefs: WriteChunkBytes(INPT) okay.\n"));
451 retval = TRUE;
454 PopChunk(iff);
456 } /* if (!PushChunk(iff, ID_PREF, ID_INPT, sizeof(saveprefs))) */
458 if (!PushChunk(iff, ID_PREF, ID_KMSW, sizeof(savekmsprefs)))
460 if (WriteChunkBytes(iff, &savekmsprefs, sizeof(savekmsprefs)) == sizeof(savekmsprefs))
461 retval = retval && TRUE;
463 PopChunk(iff);
465 } /* if (!PushChunk(iff, ID_PREF, ID_INPT, sizeof(saveprefs))) */
467 } /* if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head)) */
468 else
470 PopChunk(iff);
473 } /* if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct PrefHeader))) */
475 PopChunk(iff);
477 } /* if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN)) */
479 CloseIFF(iff);
481 } /* if (!OpenIFF(iff, IFFFWRITE)) */
484 } /* if (iff->iff_Stream)) */
486 FreeIFF(iff);
488 } /* if ((iff = AllocIFF())) */
490 #if 0 /* unused */
491 if (!retval && delete_if_error)
493 DeleteFile(filename);
495 #endif
497 return retval;
500 /*********************************************************************************************/
502 BOOL Prefs_HandleArgs(STRPTR from, BOOL use, BOOL save)
504 BPTR fh;
506 if (from)
508 if (!Prefs_Load(from))
510 ShowMessage("Can't read from input file");
511 return FALSE;
514 else
516 if (!Prefs_Load(PREFS_PATH_ENV))
518 if (!Prefs_Load(PREFS_PATH_ENVARC))
520 ShowMessage
522 "Can't read from file " PREFS_PATH_ENVARC
523 ".\nUsing default values."
525 Prefs_Default();
530 if (use || save)
532 fh = Open(PREFS_PATH_ENV, MODE_NEWFILE);
533 if (fh)
535 Prefs_ExportFH(fh);
536 Close(fh);
538 else
540 ShowMessage("Can't open " PREFS_PATH_ENV " for writing.");
543 if (save)
545 fh = Open(PREFS_PATH_ENVARC, MODE_NEWFILE);
546 if (fh)
548 Prefs_ExportFH(fh);
549 Close(fh);
551 else
553 ShowMessage("Can't open " PREFS_PATH_ENVARC " for writing.");
556 return TRUE;
559 /*********************************************************************************************/
561 BOOL Prefs_Default(void)
563 strcpy(inputprefs.ip_Keymap, DEFAULT_KEYMAP);
564 inputprefs.ip_PointerTicks = 1;
565 inputprefs.ip_DoubleClick.tv_secs = 0;
566 inputprefs.ip_DoubleClick.tv_micro = 500000;
567 inputprefs.ip_KeyRptDelay.tv_secs = 0;
568 inputprefs.ip_KeyRptDelay.tv_micro = 500000;
569 inputprefs.ip_KeyRptSpeed.tv_secs = 0;
570 inputprefs.ip_KeyRptSpeed.tv_micro = 40000;
571 inputprefs.ip_MouseAccel = 1;
572 inputprefs.ip_ClassicKeyboard = 0;
573 strcpy(inputprefs.ip_KeymapName, DEFAULT_KEYMAP);
574 inputprefs.ip_SwitchMouseButtons = FALSE;
576 kmsprefs.kms_Enabled = FALSE;
577 kmsprefs.kms_SwitchQual = KMS_QUAL_DISABLE;
578 kmsprefs.kms_SwitchCode = KMS_CODE_NOKEY;
579 kmsprefs.kms_AltKeymap[0] = 0;
581 return TRUE;