added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / tools / commodities / FKey.c
blob1ebf748cd7c0bf7303275da816d23c23b023ef5a
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*********************************************************************************************/
8 #include <intuition/classusr.h>
9 #include <graphics/layers.h>
10 #include <graphics/clip.h>
11 #include <libraries/asl.h>
12 #include <libraries/locale.h>
13 #include <libraries/gadtools.h>
14 #include <libraries/commodities.h>
15 #include <libraries/mui.h>
16 #include <workbench/startup.h>
17 #include <workbench/workbench.h>
18 #include <devices/inputevent.h>
19 #include <aros/asmcall.h>
21 #include <proto/exec.h>
22 #include <proto/dos.h>
23 #include <proto/locale.h>
24 #include <proto/muimaster.h>
25 #include <proto/intuition.h>
26 #include <proto/layers.h>
27 #include <proto/commodities.h>
28 #include <proto/alib.h>
29 #include <proto/icon.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
36 #define CATCOMP_ARRAY
37 #include "strings.h"
39 #include <aros/debug.h>
41 /*********************************************************************************************/
43 #define VERSION 1
44 #define REVISION 4
45 #define DATESTR "11.04.2006"
46 #define VERSIONSTR "$VER: FKey 1.4 (" DATESTR ")"
48 /*********************************************************************************************/
50 #define ARG_TEMPLATE "CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S,PORT/K,QUIET/S"
52 #define ARG_CXPRI 0
53 #define ARG_CXPOPKEY 1
54 #define ARG_CXPOPUP 2
55 #define ARG_CXPORT 3
56 #define ARG_QUIET 4
58 #define NUM_ARGS 5
60 /*********************************************************************************************/
62 #define ACTION_CYCLE_WIN 0
63 #define ACTION_CYCLE_SCR 1
64 #define ACTION_ENLARGE_WIN 2
65 #define ACTION_SHRINK_WIN 3
66 #define ACTION_TOGGLE_WIN 4
67 #define ACTION_RESCUE_WIN 5
68 #define ACTION_INSERT_TEXT 6
69 #define ACTION_RUN_PROG 7
70 #define ACTION_RUN_AREXX 8
72 #define RETURNID_NEWKEY 1
73 #define RETURNID_DELKEY 2
74 #define RETURNID_STRINGACK 3
75 #define RETURNID_LVACK 4
76 #define RETURNID_CMDACK 5
77 #define RETURNID_SAVE 6
78 #define RETURNID_DOUBLESTART 7
80 /*********************************************************************************************/
82 struct KeyInfo
84 struct InputEvent *translist;
85 CxObj *filter, *trans, *custom;
86 WORD action;
87 char descr[80];
88 char param[256];
91 /*********************************************************************************************/
93 struct LocaleBase *LocaleBase;
95 static char *cx_popkey = "ctrl alt f";
96 static LONG cx_pri = 0;
97 static BOOL cx_popup = FALSE;
99 static CxObj *broker, *activated_custom_cobj;
100 static Object *app, *wnd, *cmdcycle, *list, *liststr;
101 static Object *insertstr, *runprogstr, *runarexxstr;
102 static Object *cmdpage;
103 static struct Task *maintask;
104 static struct Hook keylist_construct_hook, keylist_destruct_hook, keylist_disp_hook;
105 static struct Hook broker_hook;
106 static struct MsgPort *brokermp;
107 static struct Catalog *catalog;
108 static struct RDArgs *myargs;
109 static struct WBStartup *wbstartup;
110 static LONG prog_exitcode;
111 static UBYTE **wbargs;
112 static IPTR args[NUM_ARGS];
113 static UBYTE s[257];
115 /*********************************************************************************************/
117 static void broker_func(struct Hook *hook, Object *obj, CxMsg *msg);
118 static UBYTE *BuildToolType(struct KeyInfo *ki);
119 static UBYTE **BuildToolTypes(UBYTE **src_ttypes);
120 static void Cleanup(CONST_STRPTR msg);
121 static void CleanupLocale(void);
122 static void CmdToKey(void);
123 static void DelKey(void);
124 static struct DiskObject *LoadProgIcon(BPTR *icondir, STRPTR iconname);
125 static void FreeArguments(void);
126 static void FreeToolTypes(UBYTE **ttypes);
127 static void GetArguments(int argc, char **argv);
128 static void HandleAction(void);
129 static void HandleAll(void);
130 static void InitCX(void);
131 static void InitLocale(STRPTR catname, ULONG version);
132 static void InitMenus(void);
133 static APTR keylist_construct_func(struct Hook *hook, APTR pool, struct KeyInfo *ki);
134 static void keylist_destruct_func(struct Hook *hook, APTR pool, struct KeyInfo *ki);
135 static void keylist_disp_func(struct Hook *hook, char **array, struct KeyInfo *ki);
136 static void KillCX(void);
137 static void KillGUI(void);
138 static void ListToString(void);
139 static void LoadSettings(void);
140 static void MakeGUI(void);
141 static CONST_STRPTR MSG(ULONG id);
142 static void NewKey(void);
143 static void RethinkAction(void);
144 static void RethinkKey(struct KeyInfo *ki);
145 static void SaveSettings(void);
146 static WORD ShowMessage(CONST_STRPTR title, CONST_STRPTR text, CONST_STRPTR gadtext);
147 static void StringToKey(void);
149 /*********************************************************************************************/
151 static WORD ShowMessage(CONST_STRPTR title, CONST_STRPTR text, CONST_STRPTR gadtext)
153 struct EasyStruct es;
155 es.es_StructSize = sizeof(es);
156 es.es_Flags = 0;
157 es.es_Title = title;
158 es.es_TextFormat = text;
159 es.es_GadgetFormat = gadtext;
161 return EasyRequestArgs(NULL, &es, NULL, NULL);
164 /*********************************************************************************************/
166 static void Cleanup(CONST_STRPTR msg)
168 if (msg)
170 if (IntuitionBase && !((struct Process *)FindTask(NULL))->pr_CLI)
172 ShowMessage("Fkey", msg, MSG(MSG_OK));
174 else
176 printf("FKey: %s\n", msg);
180 KillGUI();
181 FreeArguments();
182 KillCX();
183 CleanupLocale();
185 exit(prog_exitcode);
189 /*********************************************************************************************/
191 static void InitCX(void)
193 maintask = FindTask(NULL);
196 /*********************************************************************************************/
198 static void KillCX(void)
202 /*********************************************************************************************/
204 static void InitLocale(STRPTR catname, ULONG version)
206 LocaleBase = (struct LocaleBase *)OpenLibrary("locale.library", 39);
207 if (LocaleBase)
209 catalog = OpenCatalog(NULL, catname, OC_Version, version,
210 TAG_DONE);
214 /*********************************************************************************************/
216 static void CleanupLocale(void)
218 if (catalog) CloseCatalog(catalog);
219 if (LocaleBase) CloseLibrary((struct Library *)LocaleBase);
222 /*********************************************************************************************/
224 static CONST_STRPTR MSG(ULONG id)
226 if (catalog != NULL)
228 return GetCatalogStr(catalog, id, CatCompArray[id].cca_Str);
230 else
232 return CatCompArray[id].cca_Str;
236 /*********************************************************************************************/
238 static struct NewMenu nm[] =
240 {NM_TITLE, (STRPTR)MSG_MEN_PROJECT },
241 {NM_ITEM, (STRPTR)MSG_FKEY_MEN_PROJECT_SAVE },
242 {NM_ITEM, NM_BARLABEL },
243 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_HIDE },
244 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_ICONIFY },
245 {NM_ITEM, NM_BARLABEL },
246 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_QUIT },
247 {NM_END }
250 /*********************************************************************************************/
252 static void InitMenus(void)
254 struct NewMenu *actnm = nm;
256 for(actnm = nm; actnm->nm_Type != NM_END; actnm++)
258 if (actnm->nm_Label != NM_BARLABEL)
260 ULONG id = (ULONG)actnm->nm_Label;
261 CONST_STRPTR str = MSG(id);
263 if (actnm->nm_Type == NM_TITLE)
265 actnm->nm_Label = str;
266 } else {
267 actnm->nm_Label = str + 2;
268 if (str[0] != ' ') actnm->nm_CommKey = str;
270 actnm->nm_UserData = (APTR)id;
272 } /* if (actnm->nm_Label != NM_BARLABEL) */
274 } /* for(actnm = nm; nm->nm_Type != NM_END; nm++) */
278 /*********************************************************************************************/
280 static void FreeArguments(void)
282 if (myargs) FreeArgs(myargs);
283 ArgArrayDone();
286 /*********************************************************************************************/
288 static void KillGUI(void)
290 DisposeObject(app);
293 /*********************************************************************************************/
295 static void GetArguments(int argc, char **argv)
297 if (argc)
299 if (!(myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
301 Fault(IoErr(), 0, s, 256);
302 Cleanup(s);
305 if (args[ARG_CXPRI]) cx_pri = (LONG)*(IPTR *)args[ARG_CXPRI];
306 if (args[ARG_CXPOPKEY]) cx_popkey = (STRPTR)args[ARG_CXPOPKEY];
307 if (args[ARG_CXPOPUP]) cx_popup = TRUE;
309 else
311 wbstartup = (struct WBStartup *)argv;
312 wbargs = ArgArrayInit(argc, (UBYTE **)argv);
314 cx_pri = ArgInt(wbargs, "CX_PRIORITY", 0);
315 cx_popkey = ArgString(wbargs, "CX_POPKEY", cx_popkey);
317 if (strnicmp(ArgString(wbargs, "CX_POPUP", "NO"), "Y", 1) == 0)
319 cx_popup = TRUE;
324 /*********************************************************************************************/
326 static APTR keylist_construct_func(struct Hook *hook, APTR pool, struct KeyInfo *ki)
328 struct KeyInfo *new;
330 new = AllocPooled(pool, sizeof(*ki));
331 if (new) *new = *ki;
333 return new;
336 /*********************************************************************************************/
338 static void keylist_destruct_func(struct Hook *hook, APTR pool, struct KeyInfo *ki)
340 if (ki)
342 if (ki->filter) DeleteCxObjAll(ki->filter);
343 if (ki->translist) FreeIEvents(ki->translist);
345 FreePooled(pool, ki, sizeof(*ki));
349 /*********************************************************************************************/
351 static void keylist_disp_func(struct Hook *hook, char **array, struct KeyInfo *ki)
353 *array = ki->descr;
356 /*********************************************************************************************/
358 static void broker_func(struct Hook *hook, Object *obj, CxMsg *msg)
360 D(bug("FKey: broker_func called\n"));
361 if ( (CxMsgType(msg) == CXM_COMMAND) && (CxMsgID(msg) == CXCMD_APPEAR) )
363 // This opens the window if FKey was started with CX_POPUP=NO
364 set(wnd, MUIA_Window_Open, TRUE);
365 D(bug("FKey: CXCMD_APPEAR message\n"));
370 /*********************************************************************************************/
372 AROS_UFH2S(void, custom_func,
373 AROS_UFHA(CxMsg *, msg, A0),
374 AROS_UFHA(CxObj *, co, A1))
376 AROS_USERFUNC_INIT
378 activated_custom_cobj = co;
379 Signal(maintask, SIGBREAKF_CTRL_E);
381 AROS_USERFUNC_EXIT
385 /*********************************************************************************************/
387 static void MakeGUI(void)
389 static CONST_STRPTR cmdarray[] =
391 (CONST_STRPTR)MSG_FKEY_CMD_CYCLE_WIN,
392 (CONST_STRPTR)MSG_FKEY_CMD_CYCLE_SCR,
393 (CONST_STRPTR)MSG_FKEY_CMD_ENLARGE_WIN,
394 (CONST_STRPTR)MSG_FKEY_CMD_SHRINK_WIN,
395 (CONST_STRPTR)MSG_FKEY_CMD_TOGGLE_WIN_SIZE,
396 (CONST_STRPTR)MSG_FKEY_CMD_RESCUE_WIN,
397 (CONST_STRPTR)MSG_FKEY_CMD_INSERT_TEXT,
398 (CONST_STRPTR)MSG_FKEY_CMD_RUN_PROG,
399 (CONST_STRPTR)MSG_FKEY_CMD_RUN_AREXX,
402 static TEXT wintitle[100];
403 WORD i;
404 Object *menu, *newkey, *delkey, *savekey;
406 for(i = 0; cmdarray[i]; i++)
408 cmdarray[i] = MSG((ULONG) cmdarray[i]);
411 keylist_construct_hook.h_Entry = HookEntry;
412 keylist_construct_hook.h_SubEntry = (HOOKFUNC)keylist_construct_func;
414 keylist_destruct_hook.h_Entry = HookEntry;
415 keylist_destruct_hook.h_SubEntry = (HOOKFUNC)keylist_destruct_func;
417 keylist_disp_hook.h_Entry = HookEntry;
418 keylist_disp_hook.h_SubEntry = (HOOKFUNC)keylist_disp_func;
420 broker_hook.h_Entry = HookEntry;
421 broker_hook.h_SubEntry = (HOOKFUNC)broker_func;
423 menu = MUI_MakeObject(MUIO_MenustripNM, &nm, 0);
425 snprintf(wintitle, sizeof(wintitle), MSG(MSG_FKEY_WINTITLE), cx_popkey);
427 app = ApplicationObject,
428 MUIA_Application_Title, (IPTR)MSG(MSG_FKEY_CXNAME),
429 MUIA_Application_Version, (IPTR)VERSIONSTR,
430 MUIA_Application_Copyright, (IPTR)"Copyright © 1995-2006, The AROS Development Team",
431 MUIA_Application_Author, (IPTR)"The AROS Development Team",
432 MUIA_Application_Description, (IPTR)MSG(MSG_FKEY_CXDESCR),
433 MUIA_Application_BrokerPri, cx_pri,
434 MUIA_Application_BrokerHook, (IPTR)&broker_hook,
435 MUIA_Application_Base, (IPTR)"FKey",
436 MUIA_Application_SingleTask, TRUE,
437 menu ? MUIA_Application_Menustrip : TAG_IGNORE, menu,
438 SubWindow, wnd = WindowObject,
439 MUIA_Window_Title, (IPTR)wintitle,
440 MUIA_Window_ID, MAKE_ID('F','W','I','N'),
441 WindowContents, HGroup,
442 Child, VGroup,
443 GroupFrameT(MSG(MSG_FKEY_DEFINED_KEYS)),
444 Child, VGroup,
445 GroupSpacing(0),
446 Child, ListviewObject,
447 MUIA_Listview_List, list = ListObject,
448 InputListFrame,
449 MUIA_List_ConstructHook, (IPTR)&keylist_construct_hook,
450 MUIA_List_DestructHook, (IPTR)&keylist_destruct_hook,
451 MUIA_List_DisplayHook, (IPTR)&keylist_disp_hook,
452 End,
453 End,
454 Child, liststr = StringObject,
455 MUIA_Disabled, TRUE,
456 StringFrame,
457 End,
458 End,
459 Child, HGroup,
460 Child, newkey = SimpleButton(MSG(MSG_FKEY_NEW_KEY)),
461 Child, delkey = SimpleButton(MSG(MSG_FKEY_DELETE_KEY)),
462 End,
463 Child, savekey = SimpleButton(MSG(MSG_FKEY_SAVE_KEY)),
464 End,
465 Child, VGroup,
466 GroupFrameT(MSG(MSG_FKEY_COMMAND)),
467 Child, cmdcycle = MUI_MakeObject(MUIO_Cycle, NULL, cmdarray),
468 Child, cmdpage = PageGroup,
469 Child, HVSpace, /* cycle win */
470 Child, HVSpace, /* cycle scr */
471 Child, HVSpace, /* enlarge win */
472 Child, HVSpace, /* shrink win */
473 Child, HVSpace, /* Toggle win */
474 Child, HVSpace, /* rescue win */
475 Child, insertstr = StringObject, StringFrame, End, /* Insert text */
476 Child, PopaslObject, /* Run prog */
477 MUIA_Popstring_String, runprogstr = StringObject, StringFrame, End,
478 MUIA_Popstring_Button, PopButton(MUII_PopFile),
479 ASLFR_RejectIcons, TRUE,
480 End,
481 Child, PopaslObject, /* Run AREXX */
482 MUIA_Popstring_String, runarexxstr = StringObject, StringFrame, End,
483 MUIA_Popstring_Button, PopButton(MUII_PopFile),
484 ASLFR_RejectIcons, TRUE,
485 End,
486 End,
487 Child, HVSpace,
488 End,
489 End,
490 End,
491 End;
493 if (!app)
495 #if 1
496 Cleanup(NULL); /* Make no noise. Is ugly if FKey is double-started. */
497 #else
498 Cleanup(MSG(MSG_CANT_CREATE_GADGET));
499 #endif
502 get(app, MUIA_Application_Broker, &broker);
503 get(app, MUIA_Application_BrokerPort, &brokermp);
505 if (!broker || !brokermp)
506 Cleanup(MSG(MSG_CANT_CREATE_GADGET));
509 CxObj *popfilter = CxFilter(cx_popkey);
511 if (popfilter)
513 CxObj *popsig = CxSignal(maintask, SIGBREAKB_CTRL_F);
515 if (popsig)
517 CxObj *trans;
519 AttachCxObj(popfilter, popsig);
521 trans = CxTranslate(NULL);
522 if (trans) AttachCxObj(popsig, trans);
525 AttachCxObj(broker, popfilter);
530 set(liststr, MUIA_String_AttachedList, (IPTR)list);
532 DoMethod(app, MUIM_Notify, MUIA_Application_DoubleStart, TRUE, (IPTR) app, 2, MUIM_Application_ReturnID, RETURNID_DOUBLESTART);
534 //DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
535 DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 3, MUIM_Set, MUIA_Application_Iconified, TRUE);
537 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_QUIT, (IPTR) app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
538 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_HIDE, (IPTR) app, 3, MUIM_Set, MUIA_Application_Iconified, TRUE);
539 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_ICONIFY, (IPTR) app, 3, MUIM_Set, MUIA_Application_Iconified, TRUE);
540 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_FKEY_MEN_PROJECT_SAVE, (IPTR) app, 2, MUIM_Application_ReturnID, RETURNID_SAVE);
542 DoMethod(cmdcycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR)cmdpage, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue);
543 DoMethod(cmdcycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_CMDACK);
544 DoMethod(newkey, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_NEWKEY);
545 DoMethod(delkey, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_DELKEY);
546 DoMethod(savekey, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_SAVE);
547 DoMethod(list, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_LVACK);
548 DoMethod(liststr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_STRINGACK);
549 DoMethod(insertstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_CMDACK);
550 DoMethod(runprogstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_CMDACK);
551 DoMethod(runarexxstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_CMDACK);
555 /*********************************************************************************************/
557 static void RethinkKey(struct KeyInfo *ki)
559 if (ki->filter) DeleteCxObjAll(ki->filter);
560 if (ki->translist)
562 FreeIEvents(ki->translist);
563 ki->translist = NULL;
565 ki->custom = ki->trans = ki->filter = NULL;
567 if ((ki->filter = CxFilter(ki->descr)))
569 switch(ki->action)
571 case ACTION_INSERT_TEXT:
572 strrev(ki->param);
573 if ((ki->translist = InvertString(ki->param, NULL)))
575 if ((ki->trans = CxTranslate(ki->translist)))
577 AttachCxObj(ki->filter, ki->trans);
580 strrev(ki->param);
581 break;
583 default:
584 /* This CxCustom thing is hacky/ugly. A CxSender
585 would be better, but if want to send a pointer
586 with it then this would require some fixes in
587 commodities.library and it's header in case we are
588 running on 64 bit machines :-\ */
590 if ((ki->custom = CxCustom(custom_func, 0)))
592 if ((ki->trans = CxTranslate(NULL)))
594 AttachCxObj(ki->custom, ki->trans);
596 AttachCxObj(ki->filter, ki->custom);
598 break;
602 AttachCxObj(broker, ki->filter);
607 /*********************************************************************************************/
609 static void RethinkAction(void)
611 struct KeyInfo *ki = NULL;
613 DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
615 if (ki)
617 Object *str = NULL;
618 IPTR val;
620 get(cmdcycle, MUIA_Cycle_Active, &val);
621 ki->action = val;
623 switch(ki->action)
625 case ACTION_INSERT_TEXT:
626 str = insertstr;
627 break;
629 case ACTION_RUN_PROG:
630 str = runprogstr;
631 break;
633 case ACTION_RUN_AREXX:
634 str = runarexxstr;
635 break;
639 if (str)
641 STRPTR s;
643 get(str, MUIA_String_Contents, &s);
645 strncpy(ki->param, s, sizeof(ki->param));
648 RethinkKey(ki);
652 /*********************************************************************************************/
654 static void NewKey(void)
656 struct KeyInfo ki = {0};
658 StringToKey();
660 DoMethod(list, MUIM_List_InsertSingle, (IPTR)&ki, MUIV_List_Insert_Bottom);
661 nnset(list, MUIA_List_Active, MUIV_List_Active_Bottom);
662 nnset(liststr, MUIA_String_Contents, "");
663 nnset(liststr, MUIA_Disabled, FALSE);
664 set(wnd, MUIA_Window_ActiveObject, (IPTR)liststr);
666 RethinkAction();
669 /*********************************************************************************************/
671 static void DelKey(void)
673 struct KeyInfo *ki = NULL;
675 DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
677 if (ki)
679 DoMethod(list, MUIM_List_Remove, MUIV_List_Remove_Active);
680 DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
681 if (!ki)
683 nnset(liststr, MUIA_String_Contents, (IPTR)"");
684 nnset(liststr, MUIA_Disabled, TRUE);
686 ListToString();
691 /*********************************************************************************************/
693 static void StringToKey(void)
695 struct KeyInfo *ki = NULL;
696 STRPTR text;
698 DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
699 if (!ki) return;
701 get(liststr, MUIA_String_Contents, &text);
702 strncpy(ki->descr, text, sizeof(ki->descr));
704 DoMethod(list, MUIM_List_Redraw, MUIV_List_Redraw_Active);
706 RethinkKey(ki);
709 /*********************************************************************************************/
711 static void ListToString(void)
713 struct KeyInfo *ki = NULL;
715 DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
716 if (!ki) return;
718 nnset(liststr, MUIA_Disabled, FALSE);
719 nnset(liststr, MUIA_String_Contents, ki->descr);
721 switch(ki->action)
723 case ACTION_INSERT_TEXT:
724 nnset(insertstr, MUIA_String_Contents, ki->param);
725 break;
727 case ACTION_RUN_PROG:
728 nnset(runprogstr, MUIA_String_Contents, ki->param);
729 break;
731 case ACTION_RUN_AREXX:
732 nnset(runarexxstr, MUIA_String_Contents, ki->param);
733 break;
736 nnset(cmdcycle, MUIA_Cycle_Active, ki->action);
737 nnset(cmdpage, MUIA_Group_ActivePage, ki->action);
740 /*********************************************************************************************/
742 static void CmdToKey(void)
744 RethinkAction();
747 /*********************************************************************************************/
749 static void HandleAction(void)
751 struct KeyInfo *ki;
752 struct Window *win;
753 struct Screen *scr;
754 CxObj *cobj;
755 WORD i;
757 cobj = activated_custom_cobj;
758 activated_custom_cobj = NULL;
760 for(i = 0; ; i++)
762 DoMethod(list, MUIM_List_GetEntry, i, (IPTR)&ki);
763 if (!ki) break;
765 if (ki->custom == cobj) break;
768 if (!ki) return;
770 win = IntuitionBase->ActiveWindow;
771 scr = IntuitionBase->FirstScreen;
773 switch(ki->action)
775 case ACTION_CYCLE_WIN:
776 if (win)
778 struct Layer *lay;
780 scr = win->WScreen;
781 win = NULL;
783 LockLayerInfo(&scr->LayerInfo);
784 lay = scr->LayerInfo.top_layer;
785 while(lay)
787 if (lay->Window &&
788 (lay != scr->BarLayer) &&
789 !(lay->Flags & LAYERBACKDROP) &&
790 !(((struct Window *)lay->Window)->Flags & WFLG_BORDERLESS))
792 win = (struct Window *)lay->Window;
795 lay = lay->back;
797 UnlockLayerInfo(&scr->LayerInfo);
799 if (win)
801 WindowToFront(win);
802 ActivateWindow(win);
805 break;
807 case ACTION_CYCLE_SCR:
808 if (scr) ScreenToBack(scr);
809 break;
811 case ACTION_ENLARGE_WIN:
812 if (win && (win->Flags & WFLG_SIZEGADGET))
814 WORD neww = win->MaxWidth;
815 WORD newh = win->MaxHeight;
817 if (neww > win->WScreen->Width) neww = win->WScreen->Width;
818 if (newh > win->WScreen->Height) newh = win->WScreen->Height;
820 ChangeWindowBox(win, win->LeftEdge, win->TopEdge, neww, newh);
822 break;
824 case ACTION_SHRINK_WIN:
825 if (win && (win->Flags & WFLG_SIZEGADGET))
827 WORD neww = win->MinWidth;
828 WORD newh = win->MinHeight;
830 ChangeWindowBox(win, win->LeftEdge, win->TopEdge, neww, newh);
832 break;
834 case ACTION_RESCUE_WIN:
835 if (win)
837 WORD dx = 0, dy = 0;
838 if (win->LeftEdge < 0)
839 dx = -win->LeftEdge;
840 else if (win->LeftEdge + win->Width > win->WScreen->Width)
841 dx = win->WScreen->Width - win->Width - win->LeftEdge;
843 if (win->TopEdge + win->Height > win->WScreen->Height)
844 dy = win->WScreen->Height - win->Height - win->TopEdge;
845 else if (win->TopEdge < win->WScreen->BarHeight)
847 // try to keep the screen title bar visible
848 if (win->WScreen->BarHeight + win->Height < win->WScreen->Height)
849 dy = -win->TopEdge + win->WScreen->BarHeight;
850 else
851 dy = win->WScreen->Height - win->Height - win->TopEdge;
853 MoveWindow(win, dx, dy);
855 break;
857 case ACTION_TOGGLE_WIN:
858 if (win) ZipWindow(win);
859 break;
861 case ACTION_RUN_PROG:
862 if (ki->param)
864 BPTR infh;
866 infh = Open("CON:20/20/500/300/FKey/CLOSE/AUTO/WAIT", MODE_READWRITE);
867 if (infh)
869 struct TagItem systemtags[] =
871 {SYS_Asynch , TRUE },
872 {SYS_Input , (IPTR)infh},
873 {SYS_Output , 0 },
874 {TAG_DONE }
877 if (SystemTagList(ki->param, systemtags) == -1)
879 /* Error */
880 Close(infh);
884 break;
886 case ACTION_RUN_AREXX:
887 break;
889 } /* switch(ki->action) */
893 /*********************************************************************************************/
895 #define QUOTE_START 0xAB
896 #define QUOTE_END 0xBB
898 /*********************************************************************************************/
900 static UBYTE *BuildToolType(struct KeyInfo *ki)
902 static UBYTE ttstring[500];
903 UBYTE *param1 = "";
904 UBYTE *param2 = "";
906 switch(ki->action)
908 case ACTION_CYCLE_WIN:
909 param1 = "CYCLE";
910 break;
912 case ACTION_CYCLE_SCR:
913 param1 = "CYCLESCREEN";
914 break;
916 case ACTION_ENLARGE_WIN:
917 param1 = "MAKEBIG";
918 break;
920 case ACTION_SHRINK_WIN:
921 param1 = "MAKESMALL";
922 break;
924 case ACTION_TOGGLE_WIN:
925 param1 = "ZIPWINDOW";
926 break;
928 case ACTION_RESCUE_WIN:
929 param1 = "RESCUEWIN";
930 break;
932 case ACTION_INSERT_TEXT:
933 param1 = "INSERT ";
934 param2 = ki->param;
935 break;
937 case ACTION_RUN_PROG:
938 param1 = "RUN ";
939 param2 = ki->param;
940 break;
942 case ACTION_RUN_AREXX:
943 param1 = "AREXX ";
944 param2 = ki->param;
945 break;
949 snprintf(ttstring, sizeof(ttstring), "%c%s%c %s%s",
950 QUOTE_START,
951 ki->descr,
952 QUOTE_END,
953 param1,
954 param2);
956 return ttstring;
959 /*********************************************************************************************/
961 static UBYTE **BuildToolTypes(UBYTE **src_ttypes)
963 APTR pool = CreatePool(MEMF_CLEAR, 200, 200);
964 Object *listobj = list;
965 UBYTE *tt;
966 WORD list_index = 0, num_ttypes = 0, alloc_ttypes = 10;
968 UBYTE **dst_ttypes;
970 if (!pool) return NULL;
972 dst_ttypes = AllocPooled(pool, (alloc_ttypes + 2) * sizeof(UBYTE *));
973 if (!dst_ttypes)
975 DeletePool(pool);
976 return NULL;
979 /* Put together final tooltypes list based on old tooltypes and
980 new tooltypes all in one loop */
982 for(;;)
984 tt = NULL;
986 if (listobj)
988 /* New tooltypes */
990 struct KeyInfo *ki = NULL;
992 DoMethod(listobj, MUIM_List_GetEntry, list_index, (IPTR)&ki);
993 list_index++;
995 if (ki)
997 tt = BuildToolType(ki);
999 else
1001 listobj = NULL;
1005 if (!listobj)
1007 /* Old tooltypes */
1009 if (src_ttypes) tt = *src_ttypes++;
1010 if (!tt) break; /* Done. Skip out of "for(;;)" loop */
1012 if (tt[0] == QUOTE_START) continue; /* skip tooltype containing old settings */
1015 if (!tt) break; /* Paranoia. Should not happen. */
1017 if (num_ttypes >= alloc_ttypes)
1019 UBYTE **new_dst_ttypes = AllocPooled(pool, (alloc_ttypes + 10 + 2) * sizeof(UBYTE *));
1021 if (!new_dst_ttypes)
1023 DeletePool(pool);
1024 return NULL;
1027 CopyMem(dst_ttypes + 1, new_dst_ttypes + 1, alloc_ttypes * sizeof(UBYTE *));
1028 dst_ttypes = new_dst_ttypes;
1029 alloc_ttypes += 10;
1032 dst_ttypes[num_ttypes + 1] = AllocPooled(pool, strlen(tt) + 1);
1033 if (!dst_ttypes[num_ttypes + 1])
1035 DeletePool(pool);
1036 return NULL;
1039 CopyMem(tt, dst_ttypes[num_ttypes + 1], strlen(tt) + 1);
1040 num_ttypes++;
1044 dst_ttypes[0] = (APTR)pool;
1046 return dst_ttypes + 1;
1050 /*********************************************************************************************/
1052 static void FreeToolTypes(UBYTE **ttypes)
1054 if (ttypes)
1056 DeletePool((APTR)ttypes[-1]);
1060 /*********************************************************************************************/
1062 static struct DiskObject *LoadProgIcon(BPTR *icondir, STRPTR iconname)
1064 struct DiskObject *progicon;
1066 if (wbstartup)
1068 BPTR olddir;
1070 *icondir = wbstartup->sm_ArgList[0].wa_Lock;
1072 olddir = CurrentDir(*icondir);
1073 progicon = GetDiskObject(wbstartup->sm_ArgList[0].wa_Name);
1074 CurrentDir(olddir);
1076 strncpy(iconname, wbstartup->sm_ArgList[0].wa_Name, 255);
1078 else
1080 if (GetProgramName(iconname, 255))
1082 BPTR olddir;
1084 *icondir = GetProgramDir();
1086 olddir = CurrentDir(*icondir);
1087 progicon = GetDiskObject(iconname);
1088 CurrentDir(olddir);
1092 return progicon;
1095 /*********************************************************************************************/
1097 static void SaveSettings(void)
1099 struct DiskObject *progicon;
1100 UBYTE **ttypes, **old_ttypes;
1101 UBYTE iconname[256];
1102 BPTR icondir = NULL;
1104 progicon = LoadProgIcon(&icondir, iconname);
1106 if (!progicon) return;
1108 old_ttypes = (UBYTE **)progicon->do_ToolTypes;
1109 if ((ttypes = BuildToolTypes(old_ttypes)))
1111 BPTR olddir;
1113 #if 0 /* DEBUG */
1114 UBYTE *tt, **ttypes_copy = ttypes;
1116 while((tt = *ttypes_copy++))
1118 kprintf("TT: %s\n", tt);
1120 #endif
1122 olddir = CurrentDir(icondir);
1124 progicon->do_ToolTypes = ttypes;
1125 PutDiskObject(iconname, progicon);
1126 progicon->do_ToolTypes = old_ttypes;
1128 CurrentDir(olddir);
1130 FreeToolTypes(ttypes);
1133 FreeDiskObject(progicon);
1137 /*********************************************************************************************/
1139 static void LoadSettings(void)
1141 struct DiskObject *progicon;
1142 UBYTE iconname[256];
1143 BPTR icondir = NULL;
1144 UBYTE **ttypes, *tt;
1146 progicon = LoadProgIcon(&icondir, iconname);
1147 if (!progicon) return;
1149 if ((ttypes = (UBYTE **)progicon->do_ToolTypes))
1151 while((tt = *ttypes++))
1153 struct KeyInfo ki = {0};
1154 UBYTE *quote_end;
1156 ki.action = 0xFF;
1158 if ((tt[0] == QUOTE_START) && ((quote_end = strchr(tt, (char)QUOTE_END))))
1160 WORD len = quote_end - tt - 1;
1162 if (len >= sizeof(ki.descr)) continue;
1163 if (quote_end[1] != ' ') continue;
1165 strncpy(ki.descr, tt + 1, len);
1167 if (strncmp(quote_end + 2, "CYCLE", 5 + 1) == 0)
1169 ki.action = ACTION_CYCLE_WIN;
1171 else if (strncmp(quote_end + 2, "CYCLESCREEN", 11 + 1) == 0)
1173 ki.action = ACTION_CYCLE_SCR;
1175 else if (strncmp(quote_end + 2, "MAKEBIG", 7 + 1) == 0)
1177 ki.action = ACTION_ENLARGE_WIN;
1179 else if (strncmp(quote_end + 2, "MAKESMALL", 9 + 1) == 0)
1181 ki.action = ACTION_SHRINK_WIN;
1183 else if (strncmp(quote_end + 2, "ZIPWINDOW", 9 + 1) == 0)
1185 ki.action = ACTION_TOGGLE_WIN;
1187 else if (strncmp(quote_end + 2, "RESCUEWIN", 9 + 1) == 0)
1189 ki.action = ACTION_RESCUE_WIN;
1191 else if (strncmp(quote_end + 2, "INSERT ", 7) == 0)
1193 ki.action = ACTION_INSERT_TEXT;
1194 strncpy(ki.param, quote_end + 2 + 7, sizeof(ki.param) - 1);
1197 else if (strncmp(quote_end + 2, "RUN ", 4) == 0)
1199 ki.action = ACTION_RUN_PROG;
1200 strncpy(ki.param, quote_end + 2 + 4, sizeof(ki.param) - 1);
1202 else if (strncmp(quote_end + 2, "AREXX ", 6) == 0)
1204 ki.action = ACTION_RUN_AREXX;
1205 strncpy(ki.param, quote_end + 2 + 6, sizeof(ki.param) - 1);
1208 if (ki.action != 0xFF)
1210 DoMethod(list, MUIM_List_InsertSingle, (IPTR)&ki, MUIV_List_Insert_Bottom);
1213 } /* if ((tt[0] == QUOTE_START) && ((quote_end = strchr(tt, QUOTE_END)))) */
1215 } /* while((tt = *ttypes++)) */
1218 LONG index;
1220 for(index = 0; ; index++)
1222 struct KeyInfo *ki = NULL;
1224 DoMethod(list, MUIM_List_GetEntry, index, (IPTR)&ki);
1225 if (!ki) break;
1227 RethinkKey(ki);
1231 } /* if ((ttypes = (UBYTE **)progicon->do_ToolTypes)) */
1233 FreeDiskObject(progicon);
1236 /*********************************************************************************************/
1238 static void HandleAll(void)
1240 ULONG sigs = 0;
1241 LONG returnid;
1242 IPTR num_list_entries = 0;
1244 get(list, MUIA_List_Entries, &num_list_entries);
1245 if ((num_list_entries == 0) || cx_popup)
1247 set (wnd, MUIA_Window_Open, TRUE);
1250 for(;;)
1252 returnid = (LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR) &sigs);
1254 if (returnid == MUIV_Application_ReturnID_Quit) break;
1256 switch(returnid)
1258 case RETURNID_NEWKEY:
1259 NewKey();
1260 break;
1262 case RETURNID_DELKEY:
1263 DelKey();
1264 break;
1266 case RETURNID_LVACK:
1267 ListToString();
1268 break;
1270 case RETURNID_STRINGACK:
1271 StringToKey();
1272 break;
1274 case RETURNID_CMDACK:
1275 CmdToKey();
1276 break;
1278 case RETURNID_SAVE:
1279 SaveSettings();
1280 break;
1282 case RETURNID_DOUBLESTART:
1283 set(wnd, MUIA_Window_Open, TRUE);
1284 break;
1287 if (sigs)
1289 sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
1290 if (sigs & SIGBREAKF_CTRL_C) break;
1291 if (sigs & SIGBREAKF_CTRL_E) HandleAction();
1292 if (sigs & SIGBREAKF_CTRL_F)
1294 set(app, MUIA_Application_Iconified, FALSE);
1295 set(wnd, MUIA_Window_Open, TRUE);
1296 DoMethod(wnd, MUIM_Window_ToFront);
1303 /*********************************************************************************************/
1305 int main(int argc, char **argv)
1307 GetArguments(argc, argv);
1308 InitLocale("System/Tools/Commodities.catalog", 2);
1309 InitCX();
1310 InitMenus();
1311 MakeGUI();
1312 LoadSettings();
1313 HandleAll();
1314 Cleanup(NULL);
1316 return 0;