2 Copyright 2003-2014, The AROS Development Team. All rights reserved.
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <devices/rawkeycodes.h>
9 #include <libraries/kms.h>
10 #include <mui/HotkeyString_mcc.h>
11 #include <zune/customclasses.h>
12 #include <zune/prefseditor.h>
14 #include <proto/alib.h>
15 #include <proto/dos.h>
16 #include <proto/commodities.h>
17 #include <proto/intuition.h>
18 #include <proto/muimaster.h>
21 #include <aros/debug.h>
28 #include "stringify.h"
30 static CONST_STRPTR InputTabs
[] = {NULL
, NULL
, NULL
, };
31 static CONST_STRPTR MouseSpeed
[] = {NULL
, NULL
, NULL
, NULL
, };
33 static struct Hook display_hook
;
35 /*** Instance Data **********************************************************/
38 Object
*iped_KeyTypesView
;
39 Object
*iped_KeyTypes
;
42 Object
*iped_SetDefKey
;
43 Object
*iped_SetAltKey
;
44 Object
*iped_RepeatRate
;
45 Object
*iped_RepeatDelay
;
46 Object
*iped_SwitchEnable
;
47 Object
*iped_SwitchKey
;
48 Object
*iped_Accelerated
;
49 Object
*iped_MouseSpeed
;
50 Object
*iped_DoubleClickDelay
;
51 Object
*iped_LeftHandedMouse
;
53 struct Hook iped_setHook
;
54 struct Hook iped_setEnableHook
;
55 struct Hook iped_switchEnableHook
;
58 /*** Local Functions ********************************************************/
59 static BOOL
InputPrefs2Gadgets(struct IPEditor_DATA
*data
);
60 static BOOL
Gadgets2InputPrefs(struct IPEditor_DATA
*data
);
62 /*** Macros *****************************************************************/
63 #define SETUP_INST_DATA struct IPEditor_DATA *data = INST_DATA(CLASS, self)
65 /****************************************************************
66 The display function for the KeyTypes listview
67 *****************************************************************/
68 static void keytypes_display_func(struct Hook
*h
, char **array
, struct ListviewEntry
* entry
)
70 *array
++ = entry
->displayflag
;
71 *array
= entry
->node
.ln_Name
;
74 AROS_UFH3(static void, setFunction
,
75 AROS_UFHA(struct Hook
*, h
, A0
),
76 AROS_UFHA(Object
*, obj
, A2
),
77 AROS_UFHA(APTR
*, msg
, A1
))
81 struct IPEditor_DATA
*data
= h
->h_Data
;
82 Object
*kmobj
= msg
[0];
83 struct ListviewEntry
*entry
= NULL
;
85 DoMethod(data
->iped_KeyTypes
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, &entry
);
86 SET(kmobj
, MUIA_Keymap_Keymap
, entry
);
87 SET(obj
, MUIA_PrefsEditor_Changed
, TRUE
);
92 AROS_UFH3(static void, setEnableFunction
,
93 AROS_UFHA(struct Hook
*, h
, A0
),
94 AROS_UFHA(Object
*, obj
, A2
),
95 AROS_UFHA(APTR
, msg
, A1
))
99 struct IPEditor_DATA
*data
= h
->h_Data
;
100 IPTR sw_enabled
= FALSE
;
102 SET(data
->iped_SetDefKey
, MUIA_Disabled
, FALSE
);
103 GET(data
->iped_SwitchEnable
, MUIA_Selected
, &sw_enabled
);
104 SET(data
->iped_SetAltKey
, MUIA_Disabled
, !sw_enabled
);
109 AROS_UFH3(static void, switchEnableFunction
,
110 AROS_UFHA(struct Hook
*, h
, A0
),
111 AROS_UFHA(Object
*, obj
, A2
),
112 AROS_UFHA(APTR
, msg
, A1
))
116 struct IPEditor_DATA
*data
= h
->h_Data
;
120 GET(data
->iped_SwitchEnable
, MUIA_Selected
, &disabled
);
121 disabled
= !disabled
;
122 SET(data
->iped_SwitchKey
, MUIA_Disabled
, disabled
);
123 SET(data
->iped_AltKey
, MUIA_Disabled
, disabled
);
124 GET(data
->iped_KeyTypes
, MUIA_List_Active
, &active
);
125 SET(data
->iped_SetAltKey
, MUIA_Disabled
, disabled
|| (active
== MUIV_List_Active_Off
));
127 SET(obj
, MUIA_PrefsEditor_Changed
, TRUE
);
134 /*** Methods ****************************************************************/
135 Object
*IPEditor__OM_NEW(Class
*CLASS
, Object
*self
, struct opSet
*message
)
137 Object
*keyTypesView
;
143 Object
*switchEnable
;
146 Object
*GadMouseSpeed
;
147 Object
*DoubleClickDelay
;
148 Object
*LeftHandedMouse
;
152 struct ListviewEntry
*entry
;
154 display_hook
.h_Entry
= HookEntry
;
155 display_hook
.h_SubEntry
= (HOOKFUNC
)keytypes_display_func
;
157 InputTabs
[0] = _(MSG_GAD_TAB_KEYBOARD
);
158 InputTabs
[1] = _(MSG_GAD_TAB_MOUSE
);
160 MouseSpeed
[0] = _(MSG_GAD_MOUSE_SPEED_SLOW
);
161 MouseSpeed
[1] = _(MSG_GAD_MOUSE_SPEED_NORMAL
);
162 MouseSpeed
[2] = _(MSG_GAD_MOUSE_SPEED_FAST
);
164 self
= (Object
*) DoSuperNewTags
168 MUIA_PrefsEditor_Name
, __(MSG_NAME
),
169 MUIA_PrefsEditor_Path
, (IPTR
) "SYS/input.prefs",
170 MUIA_PrefsEditor_IconTool
, (IPTR
) "SYS:Prefs/Input",
172 Child
, (IPTR
) RegisterGroup(InputTabs
),
176 GroupFrameT(__(MSG_GAD_KEY_TYPE
)),
178 Child
, (IPTR
)(keyTypesView
= ListviewObject
,
179 MUIA_Listview_List
, (IPTR
)(keyTypes
= (Object
*)ListObject
,
181 MUIA_List_AutoVisible
, TRUE
,
182 MUIA_List_MinLineHeight
, 19,
183 MUIA_List_Format
, (IPTR
)"P=\033c,",
184 MUIA_List_DisplayHook
, (IPTR
)&display_hook
,
187 Child
, (IPTR
)ColGroup(3),
188 Child
, (IPTR
)Label1(__(MSG_GAD_KEY_DEF
)),
189 Child
, (IPTR
)(defKey
= KeymapObject
,
192 Child
, (IPTR
)(setDefKey
= TextObject
,
194 MUIA_Font
, MUIV_Font_Button
,
195 MUIA_Text_HiCharIdx
, '_',
196 MUIA_Text_Contents
, __(MSG_GAD_KEY_SET
),
197 MUIA_Text_PreParse
, (IPTR
)"\33c",
198 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
199 MUIA_Background
, MUII_ButtonBack
,
200 MUIA_CycleChain
, TRUE
,
203 Child
, (IPTR
)Label1(__(MSG_GAD_KEY_ALT
)),
204 Child
, (IPTR
)(altKey
= KeymapObject
,
208 Child
, (IPTR
)(setAltKey
= TextObject
,
210 MUIA_Font
, MUIV_Font_Button
,
211 MUIA_Text_HiCharIdx
, '_',
212 MUIA_Text_Contents
, __(MSG_GAD_KEY_SET
),
213 MUIA_Text_PreParse
, (IPTR
)"\33c",
214 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
215 MUIA_Background
, MUII_ButtonBack
,
216 MUIA_CycleChain
, TRUE
,
224 GroupFrameT(__(MSG_GAD_KEY_REPEAT_RATE
)),
225 Child
, (IPTR
)(RepeatRate
= (Object
*)StringifyObject
,
226 MUIA_MyStringifyType
, STRINGIFY_RepeatRate
,
227 MUIA_Numeric_Value
, 0,
229 MUIA_Numeric_Max
, 12,
233 GroupFrameT(__(MSG_GAD_KEY_REPEAT_DELAY
)),
234 Child
, (IPTR
)(RepeatDelay
= (Object
*)StringifyObject
,
235 MUIA_MyStringifyType
, STRINGIFY_RepeatDelay
,
236 MUIA_Numeric_Value
, 0,
238 MUIA_Numeric_Max
, 74,
241 Child
, (IPTR
)ColGroup(2),
242 GroupFrameT(__(MSG_GAD_KEY_SWITCH
)),
243 Child
, (IPTR
)Label1(__(MSG_GAD_KEY_SWITCH_ENABLE
)),
245 Child
, (IPTR
)(switchEnable
= MUI_MakeObject(MUIO_Checkmark
, NULL
)),
246 Child
, (IPTR
)MUI_MakeObject(MUIO_HSpace
, 0),
248 Child
, (IPTR
)Label1(__(MSG_GAD_KEY_SWITCH_KEY
)),
249 Child
, (IPTR
)(switchKey
= MUI_NewObject("HotkeyString.mcc",
255 GroupFrameT(__(MSG_GAD_KEY_TEST
)),
256 Child
, (IPTR
)StringObject
,
260 Child
, (IPTR
)HVSpace
,
266 GroupFrameT(__(MSG_GAD_MOUSE_SPEED
)),
267 Child
, (IPTR
)(GadMouseSpeed
= MUI_MakeObject(MUIO_Cycle
, NULL
, MouseSpeed
)),
269 Child
, (IPTR
)HSpace(0),
270 Child
, (IPTR
)Label1(__(MSG_GAD_MOUSE_ACCELERATED
)),
271 Child
, (IPTR
)(Accelerated
= MUI_MakeObject(MUIO_Checkmark
, NULL
)),
275 GroupFrameT(__(MSG_GAD_MOUSE_BUTTON_SETTINGS
)),
276 Child
, (IPTR
)ColGroup(2),
277 Child
, (IPTR
)Label1(__(MSG_GAD_MOUSE_DOUBLE_CLICK_DELAY
)),
278 Child
, (IPTR
)(DoubleClickDelay
= (Object
*)StringifyObject
,
279 MUIA_MyStringifyType
, STRINGIFY_DoubleClickDelay
,
280 MUIA_Numeric_Value
, 0,
282 MUIA_Numeric_Max
, 199,
284 Child
, (IPTR
)Label1(__(MSG_GAD_LEFT_HANDED_MOUSE
)),
286 Child
, (IPTR
)(LeftHandedMouse
= MUI_MakeObject(MUIO_Checkmark
, NULL
)),
287 Child
, (IPTR
)HSpace(0),
301 data
->iped_RepeatRate
= RepeatRate
;
302 data
->iped_RepeatDelay
= RepeatDelay
;
303 data
->iped_KeyTypesView
= keyTypesView
;
304 data
->iped_KeyTypes
= keyTypes
;
305 data
->iped_DefKey
= defKey
;
306 data
->iped_AltKey
= altKey
;
307 data
->iped_SetDefKey
= setDefKey
;
308 data
->iped_SetAltKey
= setAltKey
;
309 data
->iped_SwitchEnable
= switchEnable
;
310 data
->iped_SwitchKey
= switchKey
;
311 data
->iped_Accelerated
= Accelerated
;
312 data
->iped_MouseSpeed
= GadMouseSpeed
;
313 data
->iped_DoubleClickDelay
= DoubleClickDelay
;
314 data
->iped_LeftHandedMouse
= LeftHandedMouse
;
316 data
->iped_setHook
.h_Entry
= (HOOKFUNC
)setFunction
;
317 data
->iped_setHook
.h_Data
= data
;
318 data
->iped_setEnableHook
.h_Entry
= (HOOKFUNC
)setEnableFunction
;
319 data
->iped_setEnableHook
.h_Data
= data
;
320 data
->iped_switchEnableHook
.h_Entry
= (HOOKFUNC
)switchEnableFunction
;
321 data
->iped_switchEnableHook
.h_Data
= data
;
325 ForeachNode(&keymap_list
, entry
)
330 MUIM_List_InsertSingle
,
332 MUIV_List_Insert_Bottom
336 /* TODO: Do we want to check for an error? */
342 RepeatRate
, MUIM_Notify
, MUIA_Numeric_Value
, MUIV_EveryTime
,
343 (IPTR
) self
, 3, MUIM_Set
, MUIA_PrefsEditor_Changed
, TRUE
348 RepeatDelay
, MUIM_Notify
, MUIA_Numeric_Value
, MUIV_EveryTime
,
349 (IPTR
) self
, 3, MUIM_Set
, MUIA_PrefsEditor_Changed
, TRUE
354 DoubleClickDelay
, MUIM_Notify
, MUIA_Numeric_Value
, MUIV_EveryTime
,
355 (IPTR
) self
, 3, MUIM_Set
, MUIA_PrefsEditor_Changed
, TRUE
360 GadMouseSpeed
, MUIM_Notify
, MUIA_Cycle_Active
, MUIV_EveryTime
,
361 (IPTR
) self
, 3, MUIM_Set
, MUIA_PrefsEditor_Changed
, TRUE
364 DoMethod(keyTypes
, MUIM_Notify
, MUIA_List_Active
, MUIV_EveryTime
,
365 self
, 2, MUIM_CallHook
, &data
->iped_setEnableHook
);
367 DoMethod(setDefKey
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
368 self
, 3, MUIM_CallHook
, &data
->iped_setHook
, defKey
);
370 DoMethod(keyTypesView
, MUIM_Notify
, MUIA_Listview_DoubleClick
,
371 MUIV_EveryTime
, self
, 3, MUIM_CallHook
, &data
->iped_setHook
,
374 DoMethod(setAltKey
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
375 self
, 3, MUIM_CallHook
, &data
->iped_setHook
, altKey
);
377 DoMethod(switchEnable
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
378 self
, 2, MUIM_CallHook
, &data
->iped_switchEnableHook
);
380 DoMethod(switchKey
, MUIM_Notify
, MUIA_String_Contents
, MUIV_EveryTime
,
381 self
, 3, MUIM_Set
, MUIA_PrefsEditor_Changed
, TRUE
);
385 Accelerated
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
386 (IPTR
) self
, 3, MUIM_Set
, MUIA_PrefsEditor_Changed
, TRUE
391 LeftHandedMouse
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
392 (IPTR
) self
, 3, MUIM_Set
, MUIA_PrefsEditor_Changed
, TRUE
399 static BOOL
Gadgets2InputPrefs(struct IPEditor_DATA
*data
)
404 struct InputXpression ix
= {IX_VERSION
, 0};
406 GET(data
->iped_RepeatRate
, MUIA_Numeric_Value
, &val
);
408 micros
= (12 - val
) * 20000;
410 inputprefs
.ip_KeyRptSpeed
.tv_micro
= micros
;
411 inputprefs
.ip_KeyRptSpeed
.tv_secs
= 0;
413 GET(data
->iped_RepeatDelay
, MUIA_Numeric_Value
, &val
);
415 micros
= 20000 + val
* 20000;
416 secs
= (int) (micros
/ 1000000);
417 micros
= micros
% 1000000;
419 inputprefs
.ip_KeyRptDelay
.tv_micro
= micros
;
420 inputprefs
.ip_KeyRptDelay
.tv_secs
= secs
;
422 GET(data
->iped_DoubleClickDelay
, MUIA_Numeric_Value
, &val
);
424 micros
= 20000 + val
* 20000;
425 secs
= (int) (micros
/ 1000000);
426 micros
= micros
% 1000000;
428 inputprefs
.ip_DoubleClick
.tv_micro
= micros
;
429 inputprefs
.ip_DoubleClick
.tv_secs
= secs
;
431 GET(data
->iped_Accelerated
, MUIA_Selected
, &val
);
434 inputprefs
.ip_MouseAccel
= ~0;
436 inputprefs
.ip_MouseAccel
= 0;
438 GET(data
->iped_MouseSpeed
, MUIA_Cycle_Active
, &val
);
440 inputprefs
.ip_PointerTicks
= 1 << (2 - val
);
442 struct ListviewEntry
*entry
= NULL
;
444 GET(data
->iped_DefKey
, MUIA_Keymap_Keymap
, &entry
);
448 D(Printf("Gadgets2Prefs: Default keymap: %s\n", entry
->realname
));
449 strncpy(inputprefs
.ip_KeymapName
, entry
->realname
, sizeof(inputprefs
.ip_KeymapName
));
453 strncpy(inputprefs
.ip_Keymap
, DEFAULT_KEYMAP
, sizeof(inputprefs
.ip_Keymap
));
454 strncpy(inputprefs
.ip_KeymapName
, DEFAULT_KEYMAP
, sizeof(inputprefs
.ip_KeymapName
));
457 GET(data
->iped_LeftHandedMouse
, MUIA_Selected
, &val
);
458 inputprefs
.ip_SwitchMouseButtons
= val
;
460 GET(data
->iped_SwitchEnable
, MUIA_Selected
, &val
);
461 kmsprefs
.kms_Enabled
= val
;
463 GET(data
->iped_AltKey
, MUIA_Keymap_Keymap
, &entry
);
465 strncpy(kmsprefs
.kms_AltKeymap
, entry
->realname
, sizeof(kmsprefs
.kms_AltKeymap
));
467 kmsprefs
.kms_AltKeymap
[0] = 0;
469 GET(data
->iped_SwitchKey
, MUIA_String_Contents
, &key
);
470 if (ParseIX(key
, &ix
))
472 D(Printf("Gadgets2Prefs: IX parse error\n"));
473 kmsprefs
.kms_SwitchQual
= KMS_QUAL_DISABLE
;
474 kmsprefs
.kms_SwitchCode
= KMS_CODE_NOKEY
;
478 D(Printf("Gadgets2Prefs: Switch qualifier 0x%04lX, code 0x%04lX\n", ix
.ix_Qualifier
, ix
.ix_Code
));
479 kmsprefs
.kms_SwitchQual
= ix
.ix_Qualifier
;
481 * ParseIX() sets ix_Code to zero if the expressions consists only of qualifiers.
482 * This can be considered a bug, because 0x00 is a valid code for RAWKEY_TILDE key.
483 * This means that this key can't be a hotkey.
484 * CHECKME: is it the same as in AmigaOS(tm), or it's AROS bug?
486 kmsprefs
.kms_SwitchCode
= ix
.ix_Code
? ix
.ix_Code
: KMS_CODE_NOKEY
;
492 static BOOL
InputPrefs2Gadgets(struct IPEditor_DATA
*data
)
494 ULONG rrate
= 12 -(inputprefs
.ip_KeyRptSpeed
.tv_micro
/ 20000);
495 ULONG rdelay
= ((inputprefs
.ip_KeyRptDelay
.tv_micro
+ (inputprefs
.ip_KeyRptDelay
.tv_secs
* 1000000)) / 20000) - 1;
496 ULONG dcdelay
= ((inputprefs
.ip_DoubleClick
.tv_micro
+ (inputprefs
.ip_DoubleClick
.tv_secs
* 1000000)) / 20000) - 1;
497 char *keymap
= inputprefs
.ip_KeymapName
;
498 struct InputXpression ix
=
504 kmsprefs
.kms_SwitchQual
,
509 D(Printf("Prefs2Gadgets: Switch qualifier 0x%04lX, code 0x%04lX\n", kmsprefs
.kms_SwitchQual
, kmsprefs
.kms_SwitchCode
));
512 * In order to specify qualifier-only hotkey any qualifier key code will do.
513 * We use RAWKEY_LAMIGA for this purpose.
514 * This is HotKeyString.mcc's feature.
516 if (kmsprefs
.kms_SwitchCode
!= KMS_CODE_NOKEY
)
517 ix
.ix_Code
= kmsprefs
.kms_SwitchCode
;
520 keymap
= inputprefs
.ip_Keymap
;
522 NNSET(data
->iped_RepeatRate
, MUIA_Numeric_Value
, (IPTR
) rrate
);
523 NNSET(data
->iped_RepeatDelay
, MUIA_Numeric_Value
, (IPTR
) rdelay
);
524 NNSET(data
->iped_DoubleClickDelay
, MUIA_Numeric_Value
, (IPTR
) dcdelay
);
525 NNSET(data
->iped_Accelerated
, MUIA_Selected
, (IPTR
) (inputprefs
.ip_MouseAccel
!= 0) ? TRUE
: FALSE
);
527 struct ListviewEntry
*entry
;
529 ForeachNode(&keymap_list
, entry
)
531 if (!stricmp(keymap
, entry
->realname
))
532 SET(data
->iped_DefKey
, MUIA_Keymap_Keymap
, entry
);
533 if (!stricmp(kmsprefs
.kms_AltKeymap
, entry
->realname
))
534 SET(data
->iped_AltKey
, MUIA_Keymap_Keymap
, entry
);
539 switch(inputprefs
.ip_PointerTicks
)
556 NNSET(data
->iped_MouseSpeed
, MUIA_Cycle_Active
, active
);
558 NNSET(data
->iped_LeftHandedMouse
, MUIA_Selected
, inputprefs
.ip_SwitchMouseButtons
);
560 SET(data
->iped_SwitchEnable
, MUIA_Selected
, kmsprefs
.kms_Enabled
);
561 NNSET(data
->iped_SwitchKey
, MUIA_HotkeyString_IX
, &ix
);
566 IPTR IPEditor__MUIM_PrefsEditor_ImportFH
568 Class
*CLASS
, Object
*self
,
569 struct MUIP_PrefsEditor_ImportFH
*message
574 if (Prefs_ImportFH(message
->fh
))
576 IPTR back
= InputPrefs2Gadgets(data
);
578 SET(self
, MUIA_PrefsEditor_Changed
, FALSE
);
579 SET(self
, MUIA_PrefsEditor_Testing
, FALSE
);
585 IPTR IPEditor__MUIM_PrefsEditor_ExportFH
587 Class
*CLASS
, Object
*self
,
588 struct MUIP_PrefsEditor_ExportFH
*message
593 if (Gadgets2InputPrefs(data
))
595 return Prefs_ExportFH(message
->fh
);
600 IPTR IPEditor__MUIM_PrefsEditor_SetDefaults
602 Class
*CLASS
, Object
*self
, Msg message
608 success
= Prefs_Default();
610 InputPrefs2Gadgets(data
);
615 /*** Setup ******************************************************************/
618 IPEditor
, NULL
, MUIC_PrefsEditor
, NULL
,
619 OM_NEW
, struct opSet
*,
620 MUIM_PrefsEditor_ImportFH
, struct MUIP_PrefsEditor_ImportFH
*,
621 MUIM_PrefsEditor_ExportFH
, struct MUIP_PrefsEditor_ExportFH
*,
622 MUIM_PrefsEditor_SetDefaults
, Msg