Updated.
[AROS.git] / workbench / tools / KeyShow / keyboardgroup_class.c
blob9a9a5f5a7180e5eb7d36623b724222c183e4d90e
1 /*
2 Copyright © 2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 //#include <proto/dos.h>
7 #include <proto/muimaster.h>
8 #include <proto/intuition.h>
9 #include <proto/keymap.h>
10 //#include <proto/asl.h>
11 //#include <proto/utility.h>
12 #include <proto/alib.h>
14 #define DEBUG 1
15 #include <aros/debug.h>
17 #include <libraries/mui.h>
18 #include <zune/customclasses.h>
20 #include "keyboardgroup_class.h"
21 #include "locale.h"
23 #define KEY(n) Child, keybtn[n]
25 #define KBUFSIZE (12)
27 struct Key
29 TEXT alone[KBUFSIZE];
30 TEXT shift[KBUFSIZE];
31 TEXT alt[KBUFSIZE];
32 TEXT ctrl[KBUFSIZE];
33 TEXT shift_alt[KBUFSIZE];
34 TEXT ctrl_alt[KBUFSIZE];
35 TEXT ctrl_shift[KBUFSIZE];
36 BOOL immutable;
39 struct KeyboardGroup_DATA
41 struct Key *key;
42 Object *keybutton[128]; // 64-127 are high keys
43 struct Hook change_qualifier_hook;
47 static void set_immutable_key(struct Key *key, ULONG idx, CONST_STRPTR content)
49 strlcpy(key[idx].alone, content, KBUFSIZE);
50 key[idx].immutable = TRUE;
54 static struct Key *read_keymap(void)
56 struct Key *key = AllocVec(sizeof(struct Key) * 128, MEMF_CLEAR);
57 if (key)
59 struct KeyMap *km = AskKeyMapDefault();
60 LONG i;
61 for (i = 0; i < 64; i++)
63 ULONG value = km->km_LoKeyMap[i];
64 switch (km->km_LoKeyMapTypes[i])
66 case KC_NOQUAL:
67 key[i].alone[0] = value & 0xff;
68 break;
69 case KCF_SHIFT:
70 key[i].alone[0] = value & 0xff;
71 key[i].shift[0] = (value >> 8) & 0xff;
72 break;
73 case KCF_ALT:
74 key[i].alone[0] = value & 0xff;
75 key[i].alt[0] = (value >> 8) & 0xff;
76 break;
77 case KCF_CONTROL:
78 key[i].alone[0] = value & 0xff;
79 key[i].ctrl[0] = (value >> 8) & 0xff;
80 break;
81 case KCF_ALT + KCF_SHIFT:
82 key[i].alone[0] = value & 0xff;
83 key[i].shift[0] = (value >> 8) & 0xff;
84 key[i].alt[0] = (value >> 16) & 0xff;
85 key[i].shift_alt[0] = (value >> 24) & 0xff;
86 break;
87 case KCF_CONTROL + KCF_ALT:
88 key[i].alone[0] = value & 0xff;
89 key[i].alt[0] = (value >> 8) & 0xff;
90 key[i].ctrl[0] = (value >> 16) & 0xff;
91 key[i].ctrl_alt[0] = (value >> 24) & 0xff;
92 break;
93 case KCF_CONTROL + KCF_SHIFT:
94 key[i].alone[0] = value & 0xff;
95 key[i].shift[0] = (value >> 8) & 0xff;
96 key[i].ctrl[0] = (value >> 16) & 0xff;
97 key[i].ctrl_shift[0]= (value >> 24) & 0xff;
98 break;
99 case KC_VANILLA:
100 key[i].alone[0] = value & 0xff;
101 key[i].shift[0] = (value >> 8) & 0xff;
102 key[i].alt[0] = (value >> 16) & 0xff;
103 key[i].shift_alt[0] = (value >> 24) & 0xff;
104 key[i].ctrl[0] = '^';
105 key[i].ctrl[1] = value & 0xff;
106 break;
109 // Qualifier keys
110 set_immutable_key(key, 96, _(MSG_KEY_SHIFT)); // Left Shift
111 set_immutable_key(key, 97, _(MSG_KEY_SHIFT)); // Right Shift
112 set_immutable_key(key, 98, _(MSG_KEY_LOCK)); // Caps Lock
113 set_immutable_key(key, 99, _(MSG_KEY_CTRL)); // (Left) Ctrl
114 set_immutable_key(key, 100, _(MSG_KEY_ALT)); // Left Alt
115 set_immutable_key(key, 101, _(MSG_KEY_ALT)); // Right Alt
117 // Special keys
118 set_immutable_key(key, 76, "\033I[6:11]"); // Cursor
119 set_immutable_key(key, 77, "\033I[6:12]");
120 set_immutable_key(key, 78, "\033I[6:14]");
121 set_immutable_key(key, 79, "\033I[6:13]");
123 set_immutable_key(key, 65, "^H"); // Backspace
124 set_immutable_key(key, 66, "^I"); // Tab
125 set_immutable_key(key, 68, "^M"); // Enter
126 set_immutable_key(key, 69, "^["); // Esc
127 set_immutable_key(key, 95, _(MSG_KEY_HELP));
128 set_immutable_key(key, 80, "F1");
129 set_immutable_key(key, 81, "F2");
130 set_immutable_key(key, 82, "F3");
131 set_immutable_key(key, 83, "F4");
132 set_immutable_key(key, 84, "F5");
133 set_immutable_key(key, 85, "F6");
134 set_immutable_key(key, 86, "F7");
135 set_immutable_key(key, 87, "F8");
136 set_immutable_key(key, 88, "F9");
137 set_immutable_key(key, 89, "F10");
138 set_immutable_key(key, 75, "F11");
139 set_immutable_key(key, 111, "F12");
140 set_immutable_key(key, 102, _(MSG_KEY_A)); // Left A
141 set_immutable_key(key, 103, _(MSG_KEY_A)); // Right A
143 set_immutable_key(key, 71, _(MSG_KEY_INSERT));
144 set_immutable_key(key, 112, _(MSG_KEY_HOME));
145 set_immutable_key(key, 72, _(MSG_KEY_PAGEUP));
146 set_immutable_key(key, 70, _(MSG_KEY_DELETE));
147 set_immutable_key(key, 113, _(MSG_KEY_END));
148 set_immutable_key(key, 73, _(MSG_KEY_PAGEDOWN));
150 set_immutable_key(key, 90, _(MSG_KEY_NUM));
151 set_immutable_key(key, 91, "/");
152 set_immutable_key(key, 92, "*");
153 set_immutable_key(key, 93, "-");
154 set_immutable_key(key, 94, "+");
155 set_immutable_key(key, 67, "^M"); // Numpad Enter
157 set_immutable_key(key, 127, _(MSG_KEY_CTRL)); // Pseudo right Ctrl
159 return key;
162 AROS_UFH3S(void, change_qualifier_func,
163 AROS_UFHA(struct Hook *, h, A0),
164 AROS_UFHA(Object *, obj, A2),
165 AROS_UFHA(APTR, msg, A1))
167 AROS_USERFUNC_INIT
169 struct KeyboardGroup_DATA *data = h->h_Data;
171 ULONG i;
172 BOOL shift = XGET(data->keybutton[96], MUIA_Pressed) | XGET(data->keybutton[97], MUIA_Pressed);
173 BOOL alt = XGET(data->keybutton[100], MUIA_Pressed) | XGET(data->keybutton[101], MUIA_Pressed);
174 BOOL ctrl = XGET(data->keybutton[99], MUIA_Pressed) | XGET(data->keybutton[127], MUIA_Pressed);
176 D(bug("[keyshow/change_qualifier_func] shift %d alt %d ctrl %d\n", shift, alt, ctrl));
178 if (shift && !alt && !ctrl)
180 for (i = 0; i < 128; i++)
182 if (!data->key[i].immutable)
183 SET(data->keybutton[i], MUIA_Text_Contents, data->key[i].shift);
186 else if (!shift && alt && !ctrl)
188 for (i = 0; i < 128; i++)
190 if (!data->key[i].immutable)
191 SET(data->keybutton[i], MUIA_Text_Contents, data->key[i].alt);
194 else if (!shift && !alt && ctrl)
196 for (i = 0; i < 128; i++)
198 if (!data->key[i].immutable)
199 SET(data->keybutton[i], MUIA_Text_Contents, data->key[i].ctrl);
202 else if (shift && alt && !ctrl)
204 for (i = 0; i < 128; i++)
206 if (!data->key[i].immutable)
207 SET(data->keybutton[i], MUIA_Text_Contents, data->key[i].shift_alt);
210 else if (!shift && alt && ctrl)
212 for (i = 0; i < 128; i++)
214 if (!data->key[i].immutable)
215 SET(data->keybutton[i], MUIA_Text_Contents, data->key[i].ctrl_alt);
218 else if (shift && !alt && ctrl)
220 for (i = 0; i < 128; i++)
222 if (!data->key[i].immutable)
223 SET(data->keybutton[i], MUIA_Text_Contents, data->key[i].ctrl_shift);
226 else
228 for (i = 0; i < 128; i++)
230 if (!data->key[i].immutable)
231 SET(data->keybutton[i], MUIA_Text_Contents, data->key[i].alone);
235 AROS_USERFUNC_EXIT
239 Object *KeyboardGroup__OM_NEW(Class *CLASS, Object *self, struct opSet *message)
241 LONG i;
242 Object *keybtn[128];
243 struct Key *key = read_keymap();
245 //struct TagItem *tstate = message->ops_AttrList;
246 //struct TagItem *tag = NULL;
248 #if 0
249 while ((tag = NextTagItem(&tstate)) != NULL)
251 switch (tag->ti_Tag)
253 case MUIA_UnarcWindow_Archive:
254 archive = (STRPTR)tag->ti_Data;
255 break;
257 case MUIA_UnarcWindow_Destination:
258 destination = (STRPTR)tag->ti_Data;
259 break;
262 #endif
264 for (i = 0; i < 128; i++)
266 if ((i < 96 || i > 101) && i != 127 && i != 98)
268 keybtn[i] = MUI_NewObject(MUIC_Text,
269 ButtonFrame,
270 MUIA_Font, MUIV_Font_Tiny,
271 MUIA_Text_Contents, key[i].alone,
272 MUIA_Text_PreParse, "\33c",
273 TAG_DONE);
275 else
277 // Qualifier keys
278 keybtn[i] = MUI_NewObject(MUIC_Text,
279 ButtonFrame,
280 MUIA_Font, MUIV_Font_Tiny,
281 MUIA_Text_Contents, key[i].alone,
282 MUIA_Text_PreParse, "\33c",
283 MUIA_InputMode , MUIV_InputMode_Toggle,
284 MUIA_Background , MUII_ButtonBack,
285 TAG_DONE);
289 self = (Object *) DoSuperNewTags
291 CLASS, self, NULL,
292 MUIA_Group_Horiz, TRUE,
293 Child, VGroup,
294 GroupFrame,
295 Child, HGroup,
296 MUIA_Group_SameSize, TRUE,
297 KEY(69), KEY(80), KEY(81), KEY(82), KEY(83), KEY(84), KEY(85), KEY(86), KEY(87), KEY(88), KEY(89), KEY(75), KEY(111),
298 End,
299 Child, VSpace(5),
300 Child, HGroup,
301 Child, HGroup,
302 MUIA_Group_SameSize, TRUE,
303 KEY(0), KEY(1), KEY(2), KEY(3), KEY(4), KEY(5), KEY(6), KEY(7), KEY(8), KEY(9), KEY(10), KEY(11), KEY(12), KEY(13),
304 End,
305 KEY(65),
306 End,
307 Child, HGroup,
308 KEY(66),
309 Child, HGroup,
310 MUIA_Group_SameSize, TRUE,
311 KEY(16), KEY(17), KEY(18), KEY(19), KEY(20), KEY(21), KEY(22), KEY(23), KEY(24), KEY(25), KEY(26), KEY(27),
312 End,
313 KEY(68),
314 End,
315 Child, HGroup,
316 KEY(98),
317 Child, HGroup,
318 MUIA_Group_SameSize, TRUE,
319 KEY(32), KEY(33), KEY(34), KEY(35), KEY(36), KEY(37), KEY(38), KEY(39), KEY(40), KEY(41), KEY(42), KEY(43),
320 End,
321 Child, HVSpace,
322 End,
323 Child, HGroup,
324 KEY(96),
325 Child, HGroup,
326 MUIA_Group_SameSize, TRUE,
327 KEY(48), KEY(49), KEY(50), KEY(51), KEY(52), KEY(53), KEY(54), KEY(55), KEY(56), KEY(57), KEY(58),
328 End,
329 KEY(97),
330 End,
331 Child, HGroup,
332 Child, HGroup,
333 MUIA_Group_SameSize, TRUE,
334 KEY(99), KEY(102), KEY(100),
335 End,
336 KEY(64),
337 Child, HGroup,
338 MUIA_Group_SameSize, TRUE,
339 KEY(101), KEY(103), KEY(95), KEY(127),
340 End,
341 End,
342 End,
343 Child, VGroup,
344 Child, ColGroup(3),
345 GroupFrame,
346 MUIA_Group_SameSize, TRUE,
347 KEY(71), KEY(112), KEY(72),
348 KEY(70), KEY(113), KEY(73),
349 End,
350 Child, HVSpace,
351 Child, ColGroup(3),
352 GroupFrame,
353 MUIA_Group_SameSize, TRUE,
354 Child, HVSpace,
355 KEY(76),
356 Child, HVSpace,
357 KEY(79), KEY(77), KEY(78),
358 End,
359 End,
360 Child, VGroup,
361 Child, HVSpace,
362 Child, ColGroup(4),
363 GroupFrame,
364 MUIA_Group_SameSize, TRUE,
365 KEY(90), KEY(91), KEY(92), KEY(93),
366 KEY(61), KEY(62), KEY(63), KEY(94),
367 KEY(45), KEY(46), KEY(47), Child, HVSpace,
368 KEY(29), KEY(30), KEY(31), KEY(67),
369 KEY(15), Child, HVSpace, KEY(60), Child, HVSpace,
370 End,
371 End,
372 TAG_DONE
375 if (self)
377 struct KeyboardGroup_DATA *data = INST_DATA(CLASS, self);
379 data->key = key;
380 for (i = 0; i < 128; i++)
382 data->keybutton[i] = keybtn[i];
385 data->change_qualifier_hook.h_Entry = (HOOKFUNC)change_qualifier_func;
386 data->change_qualifier_hook.h_Data = data;
388 // add notifications to the qualifier keys
389 for (i = 96; i < 104; i++)
391 DoMethod
393 data->keybutton[i], MUIM_Notify, MUIA_Pressed, MUIV_EveryTime,
394 self, 2, MUIM_CallHook, &data->change_qualifier_hook
397 DoMethod
399 data->keybutton[127], MUIM_Notify, MUIA_Pressed, MUIV_EveryTime,
400 self, 2, MUIM_CallHook, &data->change_qualifier_hook
403 return self;
407 IPTR KeyboardGroup__OM_DISPOSE(Class *CLASS, Object *self, Msg message)
409 struct KeyboardGroup_DATA *data = INST_DATA(CLASS, self);
411 FreeVec(data->key);
413 return DoSuperMethodA(CLASS, self, message);
417 IPTR KeyboardGroup__MUIM_Setup(Class *CLASS, Object *obj, struct MUIP_HandleInput *msg)
419 if (!DoSuperMethodA(CLASS, obj, msg))
420 return FALSE;
422 MUI_RequestIDCMP(obj, IDCMP_RAWKEY);
424 return TRUE;
428 IPTR KeyboardGroup__MUIM_Cleanup(Class *CLASS, Object *obj, struct MUIP_HandleInput *msg)
430 MUI_RejectIDCMP(obj,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY);
431 return DoSuperMethodA(CLASS, obj, msg);
435 IPTR KeyboardGroup__MUIM_HandleInput(Class *CLASS, Object *obj, struct MUIP_HandleInput *msg)
437 struct KeyboardGroup_DATA *data = INST_DATA(CLASS, obj);
439 if (msg->imsg)
441 switch (msg->imsg->Class)
443 case IDCMP_RAWKEY:
445 D(bug("Rawkey %d\n", msg->imsg->Code));
446 if (msg->imsg->Code > 95 && msg->imsg->Code < 102) // Qualifier key
448 Object *btn = data->keybutton[msg->imsg->Code];
449 if (btn)
451 SET(btn, MUIA_Selected, XGET(btn, MUIA_Selected) ? FALSE : TRUE); // FIXME: this doesn't trigger the callback hook
452 MUI_Redraw(obj, MADF_DRAWUPDATE);
456 break;
460 return 0;
463 ZUNE_CUSTOMCLASS_5
465 KeyboardGroup, NULL, MUIC_Group, NULL,
466 OM_NEW, struct opSet *,
467 OM_DISPOSE, Msg,
468 MUIM_Setup, struct MUIP_HandleInput *,
469 MUIM_Cleanup, struct MUIP_HandleInput *,
470 MUIM_HandleInput, struct MUIP_HandleInput *