Missing flags and a typo
[AROS.git] / workbench / prefs / input / prefs.c
blob460fce7b59b54d07f6c1b89d1c4250cb9e8cf970
1 /*
2 Copyright © 1995-2011, 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 <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 {"al" , "Albanian" , NULL },
44 {"usa" , "American" , "United_States" },
45 {"usa0" , "American" , "United_States" },
46 {"us" , "American" , "United_States" },
47 {"usx" , "American" , "United_States" },
48 {"d" , "Deutsch" , "Deutschland" },
49 {"b" , "Belge" , "Belgique" },
50 {"by" , "Belarussian" , NULL },
51 {"br" , "Brasileiro" , "Brasil" },
52 {"gb" , "British" , "United_Kingdom" },
53 {"gbx" , "British Extended" , "United_Kingdom" },
54 {"bg" , "Bulgarian" , "Bulgarija" },
55 {"ca" , "Canadien Français" , "Canada_Français" },
56 {"cz" , "Czech" , "Cesko" },
57 {"dk" , "Dansk" , "Danmark" },
58 {"nl" , "Dutch" , "Nederland" },
59 {"dvx" , "Dvorak" , NULL },
60 {"usa2" , "Dvorak" , NULL },
61 {"dvl" , "Dvorak Left-handed" , NULL },
62 {"dvr" , "Dvorak Right-handed" , NULL },
63 {"el" , "Ellinikí" , "Hellas" },
64 {"irl" , "English Ireland" , "Ireland" },
65 {"e" , "Español" , "España" },
66 {"sp" , "Español no deadkeys" , "España" },
67 {"est" , "Estonian" , "Eesti" },
68 {"fin" , "Finnish" , "Suomi" },
69 {"f" , "Français" , "France" },
70 {"hr" , "Hrvatski" , "Hrvatska" },
71 {"is" , "Íslenska" , "Island" },
72 {"i" , "Italiana" , "Italia" },
73 {"la" , "Latin American" , NULL },
74 {"lv" , "Latvian" , NULL },
75 {"lt" , "Lithuanian" , "Lietuva" },
76 {"hu" , "Magyar" , "Magyarország" },
77 {"n" , "Norsk" , "Norge" },
78 {"pl" , "Polski" , "Polska" },
79 {"p" , "Português" , "Portugal" },
80 {"rus" , "Russian" , "Rossija" },
81 {"ch2" , "Suisse" , "Suisse" },
82 {"sl" , "Slovak" , "Slovakia" },
83 {"ch1" , "Schweiz" , "Suisse" },
84 {"s" , "Svenskt" , "Sverige" },
85 {"ua" , "Ukranian" , "Ukrajina" },
86 {NULL , NULL , NULL }
89 static const struct typeexp type_expansion_table[] = {
90 {"amiga", "Amiga" },
91 {"pc104", "PC 104"},
92 {"pc105", "PC 105"},
93 {"sun" , "Sun" },
94 {NULL , NULL }
97 /*********************************************************************************************/
99 static BOOL Prefs_Load(STRPTR from)
101 BOOL retval = FALSE;
103 BPTR fh = Open(from, MODE_OLDFILE);
104 if (fh)
106 retval = Prefs_ImportFH(fh);
107 Close(fh);
110 return retval;
113 /*********************************************************************************************/
115 static void ExpandName(struct ListviewEntry *entry)
117 char *sp;
118 char *type = NULL;
119 const struct nameexp *exp;
121 strcpy(entry->layoutname, entry->realname);
123 sp = strchr(entry->realname, '_');
124 if (sp)
127 * We have several variants of US keyboard, so
128 * we append type name.
130 if ((sp[1] == 'u' && sp[2] == 's'))
132 const struct typeexp *te;
134 *sp = 0;
135 for (te = type_expansion_table; te->shortname; te++)
137 if (!strcmp(entry->realname, te->shortname))
139 type = te->longname;
140 break;
143 *sp = '_';
145 sp++;
147 else
148 sp = entry->realname;
150 for (exp = layout_expansion_table; exp->shortname; exp++)
152 if (stricmp(exp->shortname, sp) == 0)
154 if (type)
155 snprintf(entry->layoutname, sizeof(entry->layoutname), "%s (%s)", exp->longname, type);
156 else
157 strcpy(entry->layoutname, exp->longname);
159 if (exp->flag != NULL)
161 #if SHOWFLAGS == 1
162 sprintf(entry->displayflag, "\033I[5:Locale:Flags/Countries/%s]", exp->flag);
163 #else
164 entry->displayflag[0] = '\0';
165 #endif
167 break;
174 /*********************************************************************************************/
177 void SortInNode(struct List *list, struct Node *node)
179 struct Node *sort, *prev = NULL;
181 ForeachNode(list, sort)
183 if (Stricmp(node->ln_Name, sort->ln_Name) < 0) break;
184 prev = sort;
187 Insert(list, node, prev);
190 void Prefs_ScanDirectory(STRPTR pattern, struct List *list, LONG entrysize)
192 struct AnchorPath ap;
193 struct ListviewEntry *entry, *entry2;
194 struct List templist;
195 STRPTR sp;
196 LONG error;
198 memset(&ap, 0, sizeof(ap));
199 NewList(&templist);
202 * Add default keymap.
203 * CHECKME: possibly too hacky. May be we should verify its presence in keymap.resource?
204 * How is it done in classic AmigaOS(tm) ?
206 entry = AllocPooled(mempool, entrysize);
207 if (entry)
209 strcpy(entry->layoutname, "American (Default)");
210 strcpy(entry->realname , DEFAULT_KEYMAP);
211 #if SHOWFLAGS == 1
212 strcpy(entry->displayflag, "\033I[5:Locale:Flags/Countries/United_States]");
213 #else
214 entry->displayflag[0] = '\0';
215 #endif
217 entry->node.ln_Name = entry->layoutname;
218 AddTail(&templist, &entry->node);
221 error = MatchFirst(pattern, &ap);
222 while((error == 0))
224 if (ap.ap_Info.fib_DirEntryType < 0)
226 entry = (struct ListviewEntry *)AllocPooled((APTR)mempool, entrysize);
227 if (entry)
229 entry->node.ln_Name = entry->layoutname;
230 strncpy(entry->realname, ap.ap_Info.fib_FileName, sizeof(entry->realname));
232 sp = strchr(entry->realname, '_');
233 if (sp)
234 sp++;
235 else
236 sp = entry->realname;
237 strcpy(entry->layoutname, sp);
239 ExpandName(entry);
240 AddTail(&templist, &entry->node);
243 error = MatchNext(&ap);
245 MatchEnd(&ap);
247 /* Sort by Layout Name */
249 ForeachNodeSafe(&templist, entry, entry2)
251 Remove(&entry->node);
252 SortInNode(list, &entry->node);
256 /*********************************************************************************************/
258 static LONG stopchunks[] =
260 ID_PREF, ID_INPT,
261 ID_PREF, ID_KMSW
264 BOOL Prefs_ImportFH(BPTR fh)
266 struct FileInputPrefs loadprefs;
267 struct FileKMSPrefs loadkmsprefs;
268 struct IFFHandle *iff;
269 ULONG size;
270 BOOL retval = FALSE;
272 memset(&loadprefs, 0, sizeof(loadprefs));
274 if ((iff = AllocIFF()))
276 iff->iff_Stream = (IPTR)fh;
277 if (fh != BNULL)
279 D(Printf("LoadPrefs: stream opened.\n"));
281 InitIFFasDOS(iff);
283 if (!OpenIFF(iff, IFFF_READ))
285 D(Printf("LoadPrefs: OpenIFF okay.\n"));
287 if (!StopChunks(iff, stopchunks, 2))
289 D(Printf("LoadPrefs: StopChunk okay.\n"));
290 retval = TRUE;
292 while (!ParseIFF(iff, IFFPARSE_SCAN))
294 struct ContextNode *cn;
296 D(Printf("LoadPrefs: ParseIFF okay.\n"));
298 cn = CurrentChunk(iff);
299 size = cn->cn_Size;
301 switch (cn->cn_ID)
303 case ID_INPT:
304 D(Printf("LoadPrefs: INPT chunk\n"));
306 if (size > sizeof(struct FileInputPrefs))
307 size = sizeof(struct FileInputPrefs);
309 if (ReadChunkBytes(iff, &loadprefs, size) == size)
311 D(Printf("LoadPrefs: Reading chunk successful.\n"));
313 CopyMem(loadprefs.ip_Keymap, inputprefs.ip_Keymap, sizeof(loadprefs.ip_Keymap));
314 inputprefs.ip_PointerTicks = ARRAY_TO_WORD(loadprefs.ip_PointerTicks);
315 inputprefs.ip_DoubleClick.tv_secs = ARRAY_TO_LONG(loadprefs.ip_DoubleClick_secs);
316 inputprefs.ip_DoubleClick.tv_micro = ARRAY_TO_LONG(loadprefs.ip_DoubleClick_micro);
317 inputprefs.ip_KeyRptDelay.tv_secs = ARRAY_TO_LONG(loadprefs.ip_KeyRptDelay_secs);
318 inputprefs.ip_KeyRptDelay.tv_micro = ARRAY_TO_LONG(loadprefs.ip_KeyRptDelay_micro);
319 inputprefs.ip_KeyRptSpeed.tv_secs = ARRAY_TO_LONG(loadprefs.ip_KeyRptSpeed_secs);
320 inputprefs.ip_KeyRptSpeed.tv_micro = ARRAY_TO_LONG(loadprefs.ip_KeyRptSpeed_micro);
321 inputprefs.ip_MouseAccel = ARRAY_TO_WORD(loadprefs.ip_MouseAccel);
322 inputprefs.ip_ClassicKeyboard = ARRAY_TO_LONG(loadprefs.ip_ClassicKeyboard);
323 CopyMem(loadprefs.ip_KeymapName, inputprefs.ip_KeymapName, sizeof(loadprefs.ip_KeymapName));
324 inputprefs.ip_SwitchMouseButtons = loadprefs.ip_SwitchMouseButtons[3];
326 D(Printf("LoadPrefs: SwitchMouseButtons: %ld\n", inputprefs.ip_SwitchMouseButtons));
328 else
329 retval = FALSE;
330 break;
332 case ID_KMSW:
333 D(Printf("LoadPrefs: KMSW chunk\n"));
335 if (size > sizeof(struct FileKMSPrefs))
336 size = sizeof(struct FileKMSPrefs);
338 if (ReadChunkBytes(iff, &loadkmsprefs, size) == size)
340 D(Printf("LoadPrefs: Reading chunk successful.\n"));
342 kmsprefs.kms_Enabled = loadkmsprefs.kms_Enabled;
343 kmsprefs.kms_Reserved = loadkmsprefs.kms_Reserved;
344 kmsprefs.kms_SwitchQual = ARRAY_TO_WORD(loadkmsprefs.kms_SwitchQual);
345 kmsprefs.kms_SwitchCode = ARRAY_TO_WORD(loadkmsprefs.kms_SwitchCode);
346 CopyMem(loadkmsprefs.kms_AltKeymap, kmsprefs.kms_AltKeymap, sizeof(kmsprefs.kms_AltKeymap));
348 else
349 retval = FALSE;
350 break;
352 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
353 } /* if (!StopChunk(iff, ID_PREF, ID_INPT)) */
354 CloseIFF(iff);
355 } /* if (!OpenIFF(iff, IFFF_READ)) */
356 } /* if (fh != NULL) */
357 FreeIFF(iff);
358 } /* if ((iff = AllocIFF())) */
360 return retval;
363 /*********************************************************************************************/
365 BOOL Prefs_ExportFH(BPTR fh)
367 struct FileInputPrefs saveprefs;
368 struct FileKMSPrefs savekmsprefs;
369 struct IFFHandle *iff;
370 BOOL retval = FALSE;
371 #if 0 /* unused */
372 BOOL delete_if_error = FALSE;
373 #endif
375 D(Printf("SavePrefs: SwitchMouseButtons: %ld\n", inputprefs.ip_SwitchMouseButtons));
377 CopyMem(inputprefs.ip_Keymap, saveprefs.ip_Keymap, sizeof(saveprefs.ip_Keymap));
378 WORD_TO_ARRAY(inputprefs.ip_PointerTicks, saveprefs.ip_PointerTicks);
379 LONG_TO_ARRAY(inputprefs.ip_DoubleClick.tv_secs , saveprefs.ip_DoubleClick_secs);
380 LONG_TO_ARRAY(inputprefs.ip_DoubleClick.tv_micro, saveprefs.ip_DoubleClick_micro);
381 LONG_TO_ARRAY(inputprefs.ip_KeyRptDelay.tv_secs , saveprefs.ip_KeyRptDelay_secs);
382 LONG_TO_ARRAY(inputprefs.ip_KeyRptDelay.tv_micro, saveprefs.ip_KeyRptDelay_micro);
383 LONG_TO_ARRAY(inputprefs.ip_KeyRptSpeed.tv_secs , saveprefs.ip_KeyRptSpeed_secs);
384 LONG_TO_ARRAY(inputprefs.ip_KeyRptSpeed.tv_micro, saveprefs.ip_KeyRptSpeed_micro);
385 WORD_TO_ARRAY(inputprefs.ip_MouseAccel, saveprefs.ip_MouseAccel);
386 LONG_TO_ARRAY(inputprefs.ip_ClassicKeyboard, saveprefs.ip_ClassicKeyboard);
387 CopyMem(inputprefs.ip_KeymapName, saveprefs.ip_KeymapName, sizeof(saveprefs.ip_KeymapName));
388 saveprefs.ip_SwitchMouseButtons[0] = 0;
389 saveprefs.ip_SwitchMouseButtons[1] = 0;
390 saveprefs.ip_SwitchMouseButtons[2] = 0;
391 saveprefs.ip_SwitchMouseButtons[3] = inputprefs.ip_SwitchMouseButtons;
393 savekmsprefs.kms_Enabled = kmsprefs.kms_Enabled;
394 savekmsprefs.kms_Reserved = kmsprefs.kms_Reserved;
395 WORD_TO_ARRAY(kmsprefs.kms_SwitchQual, savekmsprefs.kms_SwitchQual);
396 WORD_TO_ARRAY(kmsprefs.kms_SwitchCode, savekmsprefs.kms_SwitchCode);
397 CopyMem(kmsprefs.kms_AltKeymap, savekmsprefs.kms_AltKeymap, sizeof(savekmsprefs.kms_AltKeymap));
399 if ((iff = AllocIFF()))
401 iff->iff_Stream = (IPTR)fh;
402 if (iff->iff_Stream)
404 D(Printf("SavePrefs: stream opened.\n"));
406 #if 0 /* unused */
407 delete_if_error = TRUE;
408 #endif
410 InitIFFasDOS(iff);
412 if (!OpenIFF(iff, IFFF_WRITE))
414 D(Printf("SavePrefs: OpenIFF okay.\n"));
416 if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN))
418 D(Printf("SavePrefs: PushChunk(FORM) okay.\n"));
420 if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct FilePrefHeader)))
422 struct FilePrefHeader head;
424 D(Printf("SavePrefs: PushChunk(PRHD) okay.\n"));
426 head.ph_Version = 0; // FIXME: shouold be PHV_CURRENT, but see <prefs/prefhdr.h>
427 head.ph_Type = 0;
428 head.ph_Flags[0] =
429 head.ph_Flags[1] =
430 head.ph_Flags[2] =
431 head.ph_Flags[3] = 0;
433 if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head))
435 D(Printf("SavePrefs: WriteChunkBytes(PRHD) okay.\n"));
437 PopChunk(iff);
439 if (!PushChunk(iff, ID_PREF, ID_INPT, sizeof(saveprefs)))
441 D(Printf("SavePrefs: PushChunk(INPT) okay.\n"));
443 if (WriteChunkBytes(iff, &saveprefs, sizeof(saveprefs)) == sizeof(saveprefs))
445 D(Printf("SavePrefs: WriteChunkBytes(INPT) okay.\n"));
447 retval = TRUE;
450 PopChunk(iff);
452 } /* if (!PushChunk(iff, ID_PREF, ID_INPT, sizeof(saveprefs))) */
454 if (!PushChunk(iff, ID_PREF, ID_KMSW, sizeof(savekmsprefs)))
456 if (WriteChunkBytes(iff, &savekmsprefs, sizeof(savekmsprefs)) == sizeof(savekmsprefs))
457 retval = retval && TRUE;
459 PopChunk(iff);
461 } /* if (!PushChunk(iff, ID_PREF, ID_INPT, sizeof(saveprefs))) */
463 } /* if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head)) */
464 else
466 PopChunk(iff);
469 } /* if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct PrefHeader))) */
471 PopChunk(iff);
473 } /* if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN)) */
475 CloseIFF(iff);
477 } /* if (!OpenIFF(iff, IFFFWRITE)) */
480 } /* if (iff->iff_Stream)) */
482 FreeIFF(iff);
484 } /* if ((iff = AllocIFF())) */
486 #if 0 /* unused */
487 if (!retval && delete_if_error)
489 DeleteFile(filename);
491 #endif
493 return retval;
496 /*********************************************************************************************/
498 BOOL Prefs_HandleArgs(STRPTR from, BOOL use, BOOL save)
500 BPTR fh;
502 if (from)
504 if (!Prefs_Load(from))
506 ShowMessage("Can't read from input file");
507 return FALSE;
510 else
512 if (!Prefs_Load(PREFS_PATH_ENV))
514 if (!Prefs_Load(PREFS_PATH_ENVARC))
516 ShowMessage
518 "Can't read from file " PREFS_PATH_ENVARC
519 ".\nUsing default values."
521 Prefs_Default();
526 if (use || save)
528 fh = Open(PREFS_PATH_ENV, MODE_NEWFILE);
529 if (fh)
531 Prefs_ExportFH(fh);
532 Close(fh);
534 else
536 ShowMessage("Can't open " PREFS_PATH_ENV " for writing.");
539 if (save)
541 fh = Open(PREFS_PATH_ENVARC, MODE_NEWFILE);
542 if (fh)
544 Prefs_ExportFH(fh);
545 Close(fh);
547 else
549 ShowMessage("Can't open " PREFS_PATH_ENVARC " for writing.");
552 return TRUE;
555 /*********************************************************************************************/
557 BOOL Prefs_Default(void)
559 strcpy(inputprefs.ip_Keymap, DEFAULT_KEYMAP);
560 inputprefs.ip_PointerTicks = 1;
561 inputprefs.ip_DoubleClick.tv_secs = 0;
562 inputprefs.ip_DoubleClick.tv_micro = 500000;
563 inputprefs.ip_KeyRptDelay.tv_secs = 0;
564 inputprefs.ip_KeyRptDelay.tv_micro = 500000;
565 inputprefs.ip_KeyRptSpeed.tv_secs = 0;
566 inputprefs.ip_KeyRptSpeed.tv_micro = 40000;
567 inputprefs.ip_MouseAccel = 1;
568 inputprefs.ip_ClassicKeyboard = 0;
569 strcpy(inputprefs.ip_KeymapName, DEFAULT_KEYMAP);
570 inputprefs.ip_SwitchMouseButtons = FALSE;
572 kmsprefs.kms_Enabled = FALSE;
573 kmsprefs.kms_SwitchQual = KMS_QUAL_DISABLE;
574 kmsprefs.kms_SwitchCode = KMS_CODE_NOKEY;
575 kmsprefs.kms_AltKeymap[0] = 0;
577 return TRUE;