2 Copyright © 1995-2016, The AROS Development Team. All rights reserved.
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>
20 #include <rexx/storage.h>
21 #include <rexx/errors.h>
22 #include <mui/HotkeyString_mcc.h>
24 #include <proto/exec.h>
25 #include <proto/dos.h>
26 #include <proto/locale.h>
27 #include <proto/muimaster.h>
28 #include <proto/intuition.h>
29 #include <proto/layers.h>
30 #include <proto/commodities.h>
31 #include <proto/alib.h>
32 #include <proto/icon.h>
33 #include <proto/utility.h>
34 #include <proto/rexxsyslib.h>
44 #define CATALOG_NAME "System/Tools/Commodities.catalog"
45 #define CATALOG_VERSION 3
47 #include <aros/debug.h>
49 /*********************************************************************************************/
53 #define DATESTR "05.04.2016"
54 #define VERSIONSTR "$VER: FKey 1.8 (" DATESTR ")"
56 /*********************************************************************************************/
58 #define ARG_TEMPLATE "CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S,PORT/K,QUIET/S"
61 #define ARG_CXPOPKEY 1
68 /*********************************************************************************************/
70 #define ACTION_CYCLE_WIN 0
71 #define ACTION_CYCLE_SCR 1
72 #define ACTION_ENLARGE_WIN 2
73 #define ACTION_SHRINK_WIN 3
74 #define ACTION_TOGGLE_WIN 4
75 #define ACTION_RESCUE_WIN 5
76 #define ACTION_INSERT_TEXT 6
77 #define ACTION_RUN_PROG 7
78 #define ACTION_RUN_AREXX 8
80 /*********************************************************************************************/
82 #define MAXPARAMLEN 256
84 /*********************************************************************************************/
88 struct InputEvent
*translist
;
89 CxObj
*filter
, *trans
, *custom
;
92 char param
[MAXPARAMLEN
+ 1];
95 /*********************************************************************************************/
97 struct LocaleBase
*LocaleBase
;
99 static char *cx_popkey
= "ctrl alt f";
100 static LONG cx_pri
= 0;
101 static BOOL cx_popup
= FALSE
;
103 static CxObj
*broker
, *activated_custom_cobj
;
104 static Object
*app
, *wnd
, *cmdcycle
, *list
, *liststr
, *recordkey
;
105 static Object
*insertstr
, *runprogstr
, *runarexxstr
;
106 static Object
*cmdpage
;
107 static struct Task
*maintask
;
108 static struct Hook keylist_construct_hook
, keylist_destruct_hook
, keylist_disp_hook
;
109 static struct Hook broker_hook
;
110 static struct Hook show_hook
;
111 static struct Hook newkey_hook
;
112 static struct Hook delkey_hook
;
113 static struct Hook lvack_hook
;
114 static struct Hook cmdack_hook
;
115 static struct Hook save_hook
;
116 static struct Hook recordkey_hook
;
117 static struct MsgPort
*brokermp
;
118 static struct Catalog
*catalog
;
119 static struct RDArgs
*myargs
;
120 static struct WBStartup
*wbstartup
;
121 static LONG prog_exitcode
;
122 static UBYTE
**wbargs
;
123 static IPTR args
[NUM_ARGS
];
126 /*********************************************************************************************/
130 AROS_UFPA(struct Hook
*, hook
, A0
),
131 AROS_UFPA(Object
*, obj
, A2
),
132 AROS_UFPA(CxMsg
*, msg
, A1
)
135 static UBYTE
*BuildToolType(struct KeyInfo
*ki
);
136 static UBYTE
**BuildToolTypes(UBYTE
**src_ttypes
);
137 static void Cleanup(CONST_STRPTR msg
);
138 static void CleanupLocale(void);
139 static void CmdToKey(void);
140 static void DelKey(void);
141 static struct DiskObject
*LoadProgIcon(BPTR
*icondir
, STRPTR iconname
);
142 static void FreeArguments(void);
143 static void FreeToolTypes(UBYTE
**ttypes
);
144 static void GetArguments(int argc
, char **argv
);
145 static void HandleAction(void);
146 static void HandleAll(void);
147 static void InitCX(void);
148 static void InitLocale(STRPTR catname
, ULONG version
);
149 static void InitMenus(void);
151 APTR
, keylist_construct_func
,
152 AROS_UFPA(struct Hook
*, hook
, A0
),
153 AROS_UFPA(APTR
, pool
, A2
),
154 AROS_UFPA(struct KeyInfo
*, ki
, A1
)
158 void, keylist_destruct_func
,
159 AROS_UFPA(struct Hook
*, hook
, A0
),
160 AROS_UFPA(APTR
, pool
, A2
),
161 AROS_UFPA(struct KeyInfo
*, ki
, A1
)
165 void, keylist_disp_func
,
166 AROS_UFPA(struct Hook
*, hook
, A0
),
167 AROS_UFPA(char **, array
, A2
),
168 AROS_UFPA(struct KeyInfo
*, ki
, A1
)
171 static void KillCX(void);
172 static void KillGUI(void);
173 static void ListToString(void);
174 static void LoadSettings(void);
175 static void MakeGUI(void);
176 static CONST_STRPTR
MSG(ULONG id
);
177 static void NewKey(void);
178 static void RethinkAction(void);
179 static void RethinkKey(struct KeyInfo
*ki
);
180 static void SaveSettings(void);
181 static WORD
ShowMessage(CONST_STRPTR title
, CONST_STRPTR text
, CONST_STRPTR gadtext
);
182 static void StringToKey(void);
183 static struct DiskObject
*disko
;
184 static void ExecuteArexx(struct KeyInfo
*ki
);
186 /*********************************************************************************************/
188 static WORD
ShowMessage(CONST_STRPTR title
, CONST_STRPTR text
, CONST_STRPTR gadtext
)
190 struct EasyStruct es
;
192 es
.es_StructSize
= sizeof(es
);
195 es
.es_TextFormat
= text
;
196 es
.es_GadgetFormat
= gadtext
;
198 return EasyRequestArgs(NULL
, &es
, NULL
, NULL
);
201 /*********************************************************************************************/
203 static void Cleanup(CONST_STRPTR msg
)
207 if (IntuitionBase
&& !((struct Process
*)FindTask(NULL
))->pr_CLI
)
209 ShowMessage("Fkey", msg
, MSG(MSG_OK
));
213 printf("FKey: %s\n", msg
);
218 FreeDiskObject(disko
);
227 /*********************************************************************************************/
229 static void InitCX(void)
231 maintask
= FindTask(NULL
);
234 /*********************************************************************************************/
236 static void KillCX(void)
240 /*********************************************************************************************/
242 static void InitLocale(STRPTR catname
, ULONG version
)
244 LocaleBase
= (struct LocaleBase
*)OpenLibrary("locale.library", 39);
247 catalog
= OpenCatalog(NULL
, catname
, OC_Version
, version
,
252 /*********************************************************************************************/
254 static void CleanupLocale(void)
256 if (catalog
) CloseCatalog(catalog
);
257 if (LocaleBase
) CloseLibrary((struct Library
*)LocaleBase
);
260 /*********************************************************************************************/
262 static CONST_STRPTR
MSG(ULONG id
)
266 return GetCatalogStr(catalog
, id
, CatCompArray
[id
].cca_Str
);
270 return CatCompArray
[id
].cca_Str
;
274 /*********************************************************************************************/
276 static struct NewMenu nm
[] =
278 {NM_TITLE
, (STRPTR
)MSG_MEN_PROJECT
},
279 {NM_ITEM
, (STRPTR
)MSG_FKEY_MEN_PROJECT_SAVE
},
280 {NM_ITEM
, NM_BARLABEL
},
281 {NM_ITEM
, (STRPTR
)MSG_MEN_PROJECT_HIDE
},
282 {NM_ITEM
, (STRPTR
)MSG_MEN_PROJECT_ICONIFY
},
283 {NM_ITEM
, NM_BARLABEL
},
284 {NM_ITEM
, (STRPTR
)MSG_MEN_PROJECT_QUIT
},
288 /*********************************************************************************************/
290 static void InitMenus(void)
292 struct NewMenu
*actnm
= nm
;
294 for(actnm
= nm
; actnm
->nm_Type
!= NM_END
; actnm
++)
296 if (actnm
->nm_Label
!= NM_BARLABEL
)
298 ULONG id
= (IPTR
)actnm
->nm_Label
;
299 CONST_STRPTR str
= MSG(id
);
301 if (actnm
->nm_Type
== NM_TITLE
)
303 actnm
->nm_Label
= str
;
305 actnm
->nm_Label
= str
+ 2;
306 if (str
[0] != ' ') actnm
->nm_CommKey
= str
;
308 actnm
->nm_UserData
= (APTR
)(IPTR
)id
;
310 } /* if (actnm->nm_Label != NM_BARLABEL) */
312 } /* for(actnm = nm; nm->nm_Type != NM_END; nm++) */
316 /*********************************************************************************************/
318 static void FreeArguments(void)
320 if (myargs
) FreeArgs(myargs
);
324 /*********************************************************************************************/
326 static void KillGUI(void)
331 /*********************************************************************************************/
333 static void GetArguments(int argc
, char **argv
)
335 static struct WBArg
*wb_arg
;
336 static STRPTR cxname
;
339 if (!(myargs
= ReadArgs(ARG_TEMPLATE
, args
, NULL
)))
341 Fault(IoErr(), 0, s
, 256);
345 if (args
[ARG_CXPRI
]) cx_pri
= (LONG
)*(IPTR
*)args
[ARG_CXPRI
];
346 if (args
[ARG_CXPOPKEY
]) cx_popkey
= (STRPTR
)args
[ARG_CXPOPKEY
];
347 if (args
[ARG_CXPOPUP
]) cx_popup
= TRUE
;
352 wbstartup
= (struct WBStartup
*)argv
;
353 wb_arg
= wbstartup
->sm_ArgList
;
354 cxname
= wb_arg
->wa_Name
;
355 wbargs
= ArgArrayInit(argc
, (UBYTE
**)argv
);
357 cx_pri
= ArgInt(wbargs
, "CX_PRIORITY", 0);
358 cx_popkey
= ArgString(wbargs
, "CX_POPKEY", cx_popkey
);
360 if (strnicmp(ArgString(wbargs
, "CX_POPUP", "NO"), "Y", 1) == 0)
365 disko
= GetDiskObject(cxname
);
368 /*********************************************************************************************/
370 APTR
, keylist_construct_func
,
371 AROS_UFHA(struct Hook
*, hook
, A0
),
372 AROS_UFHA(APTR
, pool
, A2
),
373 AROS_UFHA(struct KeyInfo
*, ki
, A1
)
380 new = AllocPooled(pool
, sizeof(*ki
));
388 /*********************************************************************************************/
390 void, keylist_destruct_func
,
391 AROS_UFHA(struct Hook
*, hook
, A0
),
392 AROS_UFHA(APTR
, pool
, A2
),
393 AROS_UFHA(struct KeyInfo
*, ki
, A1
)
400 if (ki
->filter
) DeleteCxObjAll(ki
->filter
);
401 if (ki
->translist
) FreeIEvents(ki
->translist
);
403 FreePooled(pool
, ki
, sizeof(*ki
));
409 /*********************************************************************************************/
412 void, keylist_disp_func
,
413 AROS_UFHA(struct Hook
*, hook
, A0
),
414 AROS_UFHA(char **, array
, A2
),
415 AROS_UFHA(struct KeyInfo
*, ki
, A1
)
420 *array
++ = ki
->descr
;
423 case ACTION_CYCLE_WIN
:
424 *array
= (STRPTR
)MSG(MSG_FKEY_CMD_CYCLE_WIN
);
426 case ACTION_CYCLE_SCR
:
427 *array
= (STRPTR
)MSG(MSG_FKEY_CMD_CYCLE_SCR
);
429 case ACTION_ENLARGE_WIN
:
430 *array
= (STRPTR
)MSG(MSG_FKEY_CMD_ENLARGE_WIN
);
432 case ACTION_SHRINK_WIN
:
433 *array
= (STRPTR
)MSG(MSG_FKEY_CMD_SHRINK_WIN
);
435 case ACTION_TOGGLE_WIN
:
436 *array
= (STRPTR
)MSG(MSG_FKEY_CMD_TOGGLE_WIN_SIZE
);
438 case ACTION_RESCUE_WIN
:
439 *array
= (STRPTR
)MSG(MSG_FKEY_CMD_RESCUE_WIN
);
441 case ACTION_INSERT_TEXT
:
442 *array
= (STRPTR
)MSG(MSG_FKEY_CMD_INSERT_TEXT
);
444 case ACTION_RUN_PROG
:
445 *array
= (STRPTR
)MSG(MSG_FKEY_CMD_RUN_PROG
);
447 case ACTION_RUN_AREXX
:
448 *array
= (STRPTR
)MSG(MSG_FKEY_CMD_RUN_AREXX
);
459 /*********************************************************************************************/
463 AROS_UFHA(struct Hook
*, hook
, A0
),
464 AROS_UFHA(Object
*, obj
, A2
),
465 AROS_UFHA(CxMsg
*, msg
, A1
)
470 D(bug("FKey: broker_func called\n"));
471 if (CxMsgType(msg
) == CXM_COMMAND
)
473 if (CxMsgID(msg
) == CXCMD_APPEAR
)
475 CallHookPkt(&show_hook
, NULL
, NULL
);
477 else if (CxMsgID(msg
) == CXCMD_DISAPPEAR
)
479 set(wnd
, MUIA_Window_Open
, FALSE
);
486 /*** show_func ************************************************************/
489 AROS_UFHA(struct Hook
*, hook
, A0
),
490 AROS_UFHA(APTR
*, obj
, A2
),
491 AROS_UFHA(APTR
, param
, A1
)
496 if (XGET(app
, MUIA_Application_Iconified
) == TRUE
)
497 set(app
, MUIA_Application_Iconified
, FALSE
);
499 set(wnd
, MUIA_Window_Open
, TRUE
);
504 /*********************************************************************************************/
506 AROS_UFH2S(void, custom_func
,
507 AROS_UFHA(CxMsg
*, msg
, A0
),
508 AROS_UFHA(CxObj
*, co
, A1
))
512 activated_custom_cobj
= co
;
513 Signal(maintask
, SIGBREAKF_CTRL_E
);
518 /*********************************************************************************************/
522 AROS_UFHA(struct Hook
*, hook
, A0
),
523 AROS_UFHA(Object
*, obj
, A2
),
524 AROS_UFHA(APTR
, param
, A1
)
534 /*********************************************************************************************/
538 AROS_UFHA(struct Hook
*, hook
, A0
),
539 AROS_UFHA(Object
*, obj
, A2
),
540 AROS_UFHA(APTR
, param
, A1
)
550 /*********************************************************************************************/
553 void, recordkey_func
,
554 AROS_UFHA(struct Hook
*, hook
, A0
),
555 AROS_UFHA(Object
*, obj
, A2
),
556 AROS_UFHA(APTR
, param
, A1
)
561 if (XGET(obj
, MUIA_Pressed
))
563 set(liststr
, MUIA_Disabled
, FALSE
);
564 set(_win(obj
), MUIA_Window_ActiveObject
, liststr
);
569 set(liststr
, MUIA_Disabled
, TRUE
);
570 set(_win(obj
), MUIA_Window_ActiveObject
, list
);
576 /*********************************************************************************************/
580 AROS_UFHA(struct Hook
*, hook
, A0
),
581 AROS_UFHA(Object
*, obj
, A2
),
582 AROS_UFHA(APTR
, param
, A1
)
588 if (XGET(list
, MUIA_List_Active
) == MUIV_List_Active_Off
)
590 set(recordkey
, MUIA_Disabled
, TRUE
);
594 set(recordkey
, MUIA_Disabled
, FALSE
);
600 /*********************************************************************************************/
604 AROS_UFHA(struct Hook
*, hook
, A0
),
605 AROS_UFHA(Object
*, obj
, A2
),
606 AROS_UFHA(APTR
, param
, A1
)
612 DoMethod(list
, MUIM_List_Redraw
, MUIV_List_Redraw_All
);
617 /*********************************************************************************************/
621 AROS_UFHA(struct Hook
*, hook
, A0
),
622 AROS_UFHA(Object
*, obj
, A2
),
623 AROS_UFHA(APTR
, param
, A1
)
633 /*********************************************************************************************/
635 static void MakeGUI(void)
637 static CONST_STRPTR cmdarray
[] =
639 (CONST_STRPTR
)MSG_FKEY_CMD_CYCLE_WIN
,
640 (CONST_STRPTR
)MSG_FKEY_CMD_CYCLE_SCR
,
641 (CONST_STRPTR
)MSG_FKEY_CMD_ENLARGE_WIN
,
642 (CONST_STRPTR
)MSG_FKEY_CMD_SHRINK_WIN
,
643 (CONST_STRPTR
)MSG_FKEY_CMD_TOGGLE_WIN_SIZE
,
644 (CONST_STRPTR
)MSG_FKEY_CMD_RESCUE_WIN
,
645 (CONST_STRPTR
)MSG_FKEY_CMD_INSERT_TEXT
,
646 (CONST_STRPTR
)MSG_FKEY_CMD_RUN_PROG
,
647 (CONST_STRPTR
)MSG_FKEY_CMD_RUN_AREXX
,
650 static TEXT wintitle
[100];
652 Object
*menu
, *newkey
, *delkey
, *savekey
;
654 for(i
= 0; cmdarray
[i
]; i
++)
656 cmdarray
[i
] = MSG((IPTR
) cmdarray
[i
]);
659 keylist_construct_hook
.h_Entry
= (HOOKFUNC
)keylist_construct_func
;
660 keylist_destruct_hook
.h_Entry
= (HOOKFUNC
)keylist_destruct_func
;
661 keylist_disp_hook
.h_Entry
= (HOOKFUNC
)keylist_disp_func
;
662 broker_hook
.h_Entry
= (HOOKFUNC
)broker_func
;
663 show_hook
.h_Entry
= (HOOKFUNC
)show_func
;
664 newkey_hook
.h_Entry
= (HOOKFUNC
)newkey_func
;
665 delkey_hook
.h_Entry
= (HOOKFUNC
)delkey_func
;
666 lvack_hook
.h_Entry
= (HOOKFUNC
)lvack_func
;
667 cmdack_hook
.h_Entry
= (HOOKFUNC
)cmdack_func
;
668 save_hook
.h_Entry
= (HOOKFUNC
)save_func
;
669 recordkey_hook
.h_Entry
= (HOOKFUNC
)recordkey_func
;
671 menu
= MUI_MakeObject(MUIO_MenustripNM
, &nm
, 0);
673 snprintf(wintitle
, sizeof(wintitle
), MSG(MSG_FKEY_WINTITLE
), cx_popkey
);
675 app
= ApplicationObject
,
676 MUIA_Application_Title
, (IPTR
)MSG(MSG_FKEY_CXNAME
),
677 MUIA_Application_Version
, (IPTR
)VERSIONSTR
,
678 MUIA_Application_Copyright
, (IPTR
)"Copyright © 1995-2016, The AROS Development Team",
679 MUIA_Application_Author
, (IPTR
)"The AROS Development Team",
680 MUIA_Application_Description
, (IPTR
)MSG(MSG_FKEY_CXDESCR
),
681 MUIA_Application_BrokerPri
, cx_pri
,
682 MUIA_Application_BrokerHook
, (IPTR
)&broker_hook
,
683 MUIA_Application_Base
, (IPTR
)"FKey",
684 MUIA_Application_SingleTask
, TRUE
,
685 menu
? MUIA_Application_Menustrip
: TAG_IGNORE
, menu
,
686 MUIA_Application_DiskObject
, (IPTR
)disko
,
687 SubWindow
, wnd
= WindowObject
,
688 MUIA_Window_Title
, (IPTR
)wintitle
,
689 MUIA_Window_ID
, MAKE_ID('F','W','I','N'),
690 WindowContents
, HGroup
,
692 GroupFrameT(MSG(MSG_FKEY_DEFINED_KEYS
)),
695 Child
, ListviewObject
,
696 MUIA_Listview_List
, list
= ListObject
,
698 MUIA_List_ConstructHook
, (IPTR
)&keylist_construct_hook
,
699 MUIA_List_DestructHook
, (IPTR
)&keylist_destruct_hook
,
700 MUIA_List_DisplayHook
, (IPTR
)&keylist_disp_hook
,
701 MUIA_List_Format
, "BAR,",
706 Child
, recordkey
= TextObject
,
708 MUIA_Font
, MUIV_Font_Button
,
709 MUIA_Text_HiCharIdx
, '_',
710 MUIA_Text_Contents
, "Record",
711 MUIA_Text_PreParse
, "\33c",
712 MUIA_InputMode
, MUIV_InputMode_Toggle
,
713 MUIA_Background
, MUII_ButtonBack
,
718 Child
, liststr
= HotkeyStringObject
,
725 Child
, newkey
= SimpleButton(MSG(MSG_FKEY_NEW_KEY
)),
726 Child
, delkey
= SimpleButton(MSG(MSG_FKEY_DELETE_KEY
)),
728 Child
, savekey
= SimpleButton(MSG(MSG_FKEY_SAVE_KEY
)),
731 GroupFrameT(MSG(MSG_FKEY_COMMAND
)),
732 Child
, cmdcycle
= MUI_MakeObject(MUIO_Cycle
, NULL
, cmdarray
),
733 Child
, cmdpage
= PageGroup
,
734 Child
, HVSpace
, /* cycle win */
735 Child
, HVSpace
, /* cycle scr */
736 Child
, HVSpace
, /* enlarge win */
737 Child
, HVSpace
, /* shrink win */
738 Child
, HVSpace
, /* Toggle win */
739 Child
, HVSpace
, /* rescue win */
740 Child
, insertstr
= StringObject
,
742 MUIA_String_MaxLen
, MAXPARAMLEN
,
743 End
, /* Insert text */
744 Child
, PopaslObject
, /* Run prog */
745 MUIA_Popstring_String
, runprogstr
= StringObject
,
747 MUIA_String_MaxLen
, MAXPARAMLEN
,
749 MUIA_Popstring_Button
, PopButton(MUII_PopFile
),
750 ASLFR_RejectIcons
, TRUE
,
752 Child
, PopaslObject
, /* Run AREXX */
753 MUIA_Popstring_String
, runarexxstr
= StringObject
,
755 MUIA_String_MaxLen
, MAXPARAMLEN
,
757 MUIA_Popstring_Button
, PopButton(MUII_PopFile
),
758 ASLFR_RejectIcons
, TRUE
,
769 Cleanup(NULL
); /* Make no noise. Is ugly if FKey is double-started. */
772 get(app
, MUIA_Application_Broker
, &broker
);
773 get(app
, MUIA_Application_BrokerPort
, &brokermp
);
775 if (!broker
|| !brokermp
)
776 Cleanup(MSG(MSG_CANT_CREATE_GADGET
));
779 CxObj
*popfilter
= CxFilter(cx_popkey
);
783 CxObj
*popsig
= CxSignal(maintask
, SIGBREAKB_CTRL_F
);
789 AttachCxObj(popfilter
, popsig
);
791 trans
= CxTranslate(NULL
);
792 if (trans
) AttachCxObj(popfilter
, trans
);
795 AttachCxObj(broker
, popfilter
);
800 DoMethod(app
, MUIM_Notify
, MUIA_Application_DoubleStart
, TRUE
, (IPTR
) app
, 2, MUIM_CallHook
, &show_hook
);
802 DoMethod(wnd
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
, (IPTR
) wnd
, 3, MUIM_Set
, MUIA_Window_Open
, FALSE
);
804 DoMethod(wnd
, MUIM_Notify
, MUIA_Window_MenuAction
, MSG_MEN_PROJECT_QUIT
, (IPTR
) app
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
805 DoMethod(wnd
, MUIM_Notify
, MUIA_Window_MenuAction
, MSG_MEN_PROJECT_HIDE
, (IPTR
) wnd
, 3, MUIM_Set
, MUIA_Window_Open
, FALSE
);
806 DoMethod(wnd
, MUIM_Notify
, MUIA_Window_MenuAction
, MSG_MEN_PROJECT_ICONIFY
, (IPTR
) app
, 3, MUIM_Set
, MUIA_Application_Iconified
, TRUE
);
807 DoMethod(wnd
, MUIM_Notify
, MUIA_Window_MenuAction
, MSG_FKEY_MEN_PROJECT_SAVE
, (IPTR
) app
, 2, MUIM_CallHook
, &save_hook
);
809 DoMethod(cmdcycle
, MUIM_Notify
, MUIA_Cycle_Active
, MUIV_EveryTime
, (IPTR
)cmdpage
, 3, MUIM_Set
, MUIA_Group_ActivePage
, MUIV_TriggerValue
);
810 DoMethod(cmdcycle
, MUIM_Notify
, MUIA_Cycle_Active
, MUIV_EveryTime
, (IPTR
)app
, 2, MUIM_CallHook
, &cmdack_hook
);
811 DoMethod(newkey
, MUIM_Notify
, MUIA_Pressed
, FALSE
, (IPTR
)app
, 2, MUIM_CallHook
, &newkey_hook
);
812 DoMethod(delkey
, MUIM_Notify
, MUIA_Pressed
, FALSE
, (IPTR
)app
, 2, MUIM_CallHook
, &delkey_hook
);
813 DoMethod(savekey
, MUIM_Notify
, MUIA_Pressed
, FALSE
, (IPTR
)app
, 2, MUIM_CallHook
, &save_hook
);
814 DoMethod(recordkey
, MUIM_Notify
, MUIA_Pressed
, MUIV_EveryTime
, (IPTR
)recordkey
, 2, MUIM_CallHook
, &recordkey_hook
);
816 DoMethod(list
, MUIM_Notify
, MUIA_List_Active
, MUIV_EveryTime
, (IPTR
)app
, 2, MUIM_CallHook
, &lvack_hook
);
817 DoMethod(insertstr
, MUIM_Notify
, MUIA_String_Acknowledge
, MUIV_EveryTime
, (IPTR
)app
, 2, MUIM_CallHook
, &cmdack_hook
);
818 DoMethod(runprogstr
, MUIM_Notify
, MUIA_String_Acknowledge
, MUIV_EveryTime
, (IPTR
)app
, 2, MUIM_CallHook
, &cmdack_hook
);
819 DoMethod(runarexxstr
, MUIM_Notify
, MUIA_String_Acknowledge
, MUIV_EveryTime
, (IPTR
)app
, 2, MUIM_CallHook
, &cmdack_hook
);
822 /*********************************************************************************************/
824 static void RethinkKey(struct KeyInfo
*ki
)
826 if (ki
->filter
) DeleteCxObjAll(ki
->filter
);
829 FreeIEvents(ki
->translist
);
830 ki
->translist
= NULL
;
832 ki
->custom
= ki
->trans
= ki
->filter
= NULL
;
834 if ((ki
->filter
= CxFilter(ki
->descr
)))
838 case ACTION_INSERT_TEXT
:
840 if ((ki
->translist
= InvertStringForwd(ki
->param
, NULL
)))
842 if ((ki
->trans
= CxTranslate(ki
->translist
)))
844 AttachCxObj(ki
->filter
, ki
->trans
);
851 /* This CxCustom thing is hacky/ugly. A CxSender
852 would be better, but if want to send a pointer
853 with it then this would require some fixes in
854 commodities.library and it's header in case we are
855 running on 64 bit machines :-\ */
857 if ((ki
->custom
= CxCustom(custom_func
, 0)))
859 AttachCxObj(ki
->filter
, ki
->custom
);
860 if ((ki
->trans
= CxTranslate(NULL
)))
862 AttachCxObj(ki
->filter
, ki
->trans
);
869 AttachCxObj(broker
, ki
->filter
);
874 /*********************************************************************************************/
876 static void RethinkAction(void)
878 struct KeyInfo
*ki
= NULL
;
880 DoMethod(list
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, (IPTR
)&ki
);
887 get(cmdcycle
, MUIA_Cycle_Active
, &val
);
892 case ACTION_INSERT_TEXT
:
896 case ACTION_RUN_PROG
:
900 case ACTION_RUN_AREXX
:
910 get(str
, MUIA_String_Contents
, &s
);
912 strncpy(ki
->param
, s
, sizeof(ki
->param
));
919 /*********************************************************************************************/
921 static void NewKey(void)
923 struct KeyInfo ki
= {0};
927 DoMethod(list
, MUIM_List_InsertSingle
, (IPTR
)&ki
, MUIV_List_Insert_Bottom
);
928 nnset(list
, MUIA_List_Active
, MUIV_List_Active_Bottom
);
929 nnset(liststr
, MUIA_String_Contents
, "");
930 nnset(recordkey
, MUIA_Disabled
, FALSE
);
931 set(wnd
, MUIA_Window_ActiveObject
, (IPTR
)liststr
);
936 /*********************************************************************************************/
938 static void DelKey(void)
940 struct KeyInfo
*ki
= NULL
;
942 DoMethod(list
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, (IPTR
)&ki
);
946 DoMethod(list
, MUIM_List_Remove
, MUIV_List_Remove_Active
);
947 DoMethod(list
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, (IPTR
)&ki
);
950 nnset(liststr
, MUIA_String_Contents
, (IPTR
)"");
951 nnset(recordkey
, MUIA_Disabled
, TRUE
);
958 /*********************************************************************************************/
960 static void StringToKey(void)
962 struct KeyInfo
*ki
= NULL
;
965 DoMethod(list
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, (IPTR
)&ki
);
968 get(liststr
, MUIA_String_Contents
, &text
);
969 strncpy(ki
->descr
, text
, sizeof(ki
->descr
));
971 DoMethod(list
, MUIM_List_Redraw
, MUIV_List_Redraw_Active
);
976 /*********************************************************************************************/
978 static void ListToString(void)
980 struct KeyInfo
*ki
= NULL
;
982 DoMethod(list
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, (IPTR
)&ki
);
985 nnset(liststr
, MUIA_String_Contents
, ki
->descr
);
989 case ACTION_INSERT_TEXT
:
990 nnset(insertstr
, MUIA_String_Contents
, ki
->param
);
993 case ACTION_RUN_PROG
:
994 nnset(runprogstr
, MUIA_String_Contents
, ki
->param
);
997 case ACTION_RUN_AREXX
:
998 nnset(runarexxstr
, MUIA_String_Contents
, ki
->param
);
1002 nnset(cmdcycle
, MUIA_Cycle_Active
, ki
->action
);
1003 nnset(cmdpage
, MUIA_Group_ActivePage
, ki
->action
);
1006 /*********************************************************************************************/
1008 static void CmdToKey(void)
1013 /*********************************************************************************************/
1015 static void ExecuteArexx(struct KeyInfo
*ki
)
1017 struct RexxMsg
*msg
= NULL
;
1018 struct MsgPort
*rexxport
= NULL
, *replyport
= NULL
;
1020 BOOL closestdout
= FALSE
;
1021 struct RexxMsg
*reply
;
1023 if (ki
->param
== NULL
)
1028 out
= ErrorOutput();
1034 rexxport
= FindPort("REXX");
1035 if (rexxport
== NULL
)
1037 if (SystemTags("RexxMast", SYS_Asynch
, TRUE
,
1038 SYS_Input
, BNULL
, SYS_Output
, BNULL
,
1043 SystemTags("WaitForPort REXX", TAG_DONE
);
1046 rexxport
= FindPort("REXX");
1047 if (rexxport
== NULL
)
1049 FPuts(out
, "Could not start RexxMast; no Rexx interpreter seems to be installed\n");
1053 replyport
= CreatePort(NULL
, 0);
1054 if (replyport
== NULL
)
1056 FPuts(out
, "Could not create a port\n");
1060 msg
= CreateRexxMsg(replyport
, NULL
, NULL
);
1063 FPuts(out
, "Could not create RexxMsg\n");
1066 msg
->rm_Action
= RXCOMM
| RXFF_RESULT
;
1067 msg
->rm_Stdin
= Input();
1068 Flush(msg
->rm_Stdin
); /* Remove command line arguments */
1069 msg
->rm_Stdout
= Output();
1071 out
= msg
->rm_Stdout
= Open("CON:////RX Output/CLOSE/WAIT/AUTO", MODE_READWRITE
);
1074 msg
->rm_Args
[0] = (IPTR
)CreateArgstring(ki
->param
, strlen(ki
->param
));
1075 msg
->rm_Action
|= 1;
1077 PutMsg(rexxport
, (struct Message
*)msg
);
1079 reply
= (struct RexxMsg
*)WaitPort(replyport
);
1080 } while (reply
!= msg
);
1082 if (msg
->rm_Result1
!= RC_OK
)
1084 FPrintf(out
, "Error executing script %ld/%ld\n",
1085 msg
->rm_Result1
, msg
->rm_Result2
1088 ClearRexxMsg(msg
, msg
->rm_Action
& RXARGMASK
);
1092 Close(msg
->rm_Stdout
);
1096 DeletePort(replyport
);
1099 /*********************************************************************************************/
1101 static void HandleAction(void)
1109 cobj
= activated_custom_cobj
;
1110 activated_custom_cobj
= NULL
;
1114 DoMethod(list
, MUIM_List_GetEntry
, i
, (IPTR
)&ki
);
1117 if (ki
->custom
== cobj
) break;
1122 win
= IntuitionBase
->ActiveWindow
;
1123 scr
= IntuitionBase
->FirstScreen
;
1127 case ACTION_CYCLE_WIN
:
1135 LockLayerInfo(&scr
->LayerInfo
);
1136 lay
= scr
->LayerInfo
.top_layer
;
1140 (lay
!= scr
->BarLayer
) &&
1141 !(lay
->Flags
& LAYERBACKDROP
) &&
1142 !(((struct Window
*)lay
->Window
)->Flags
& WFLG_BORDERLESS
))
1144 win
= (struct Window
*)lay
->Window
;
1149 UnlockLayerInfo(&scr
->LayerInfo
);
1154 ActivateWindow(win
);
1159 case ACTION_CYCLE_SCR
:
1160 if (scr
) ScreenToBack(scr
);
1163 case ACTION_ENLARGE_WIN
:
1164 if (win
&& (win
->Flags
& WFLG_SIZEGADGET
))
1166 WORD neww
= win
->MaxWidth
;
1167 WORD newh
= win
->MaxHeight
;
1169 if (neww
> win
->WScreen
->Width
) neww
= win
->WScreen
->Width
;
1170 if (newh
> win
->WScreen
->Height
) newh
= win
->WScreen
->Height
;
1172 ChangeWindowBox(win
, win
->LeftEdge
, win
->TopEdge
, neww
, newh
);
1176 case ACTION_SHRINK_WIN
:
1177 if (win
&& (win
->Flags
& WFLG_SIZEGADGET
))
1179 WORD neww
= win
->MinWidth
;
1180 WORD newh
= win
->MinHeight
;
1182 ChangeWindowBox(win
, win
->LeftEdge
, win
->TopEdge
, neww
, newh
);
1186 case ACTION_RESCUE_WIN
:
1189 WORD dx
= 0, dy
= 0;
1190 if (win
->LeftEdge
< 0)
1191 dx
= -win
->LeftEdge
;
1192 else if (win
->LeftEdge
+ win
->Width
> win
->WScreen
->Width
)
1193 dx
= win
->WScreen
->Width
- win
->Width
- win
->LeftEdge
;
1195 if (win
->TopEdge
+ win
->Height
> win
->WScreen
->Height
)
1196 dy
= win
->WScreen
->Height
- win
->Height
- win
->TopEdge
;
1197 else if (win
->TopEdge
< win
->WScreen
->BarHeight
)
1199 // try to keep the screen title bar visible
1200 if (win
->WScreen
->BarHeight
+ win
->Height
< win
->WScreen
->Height
)
1201 dy
= -win
->TopEdge
+ win
->WScreen
->BarHeight
;
1203 dy
= win
->WScreen
->Height
- win
->Height
- win
->TopEdge
;
1205 MoveWindow(win
, dx
, dy
);
1209 case ACTION_TOGGLE_WIN
:
1210 if (win
) ZipWindow(win
);
1213 case ACTION_RUN_PROG
:
1218 infh
= Open("CON:20/20/500/300/FKey/CLOSE/AUTO/WAIT", MODE_READWRITE
);
1221 struct TagItem systemtags
[] =
1223 {SYS_Asynch
, TRUE
},
1224 {SYS_Input
, (IPTR
)infh
},
1229 if (SystemTagList(ki
->param
, systemtags
) == -1)
1238 case ACTION_RUN_AREXX
:
1242 } /* switch(ki->action) */
1246 /*********************************************************************************************/
1248 #define QUOTE_START 0xAB
1249 #define QUOTE_END 0xBB
1251 /*********************************************************************************************/
1253 static UBYTE
*BuildToolType(struct KeyInfo
*ki
)
1255 static UBYTE ttstring
[500];
1261 case ACTION_CYCLE_WIN
:
1265 case ACTION_CYCLE_SCR
:
1266 param1
= "CYCLESCREEN";
1269 case ACTION_ENLARGE_WIN
:
1273 case ACTION_SHRINK_WIN
:
1274 param1
= "MAKESMALL";
1277 case ACTION_TOGGLE_WIN
:
1278 param1
= "ZIPWINDOW";
1281 case ACTION_RESCUE_WIN
:
1282 param1
= "RESCUEWIN";
1285 case ACTION_INSERT_TEXT
:
1290 case ACTION_RUN_PROG
:
1295 case ACTION_RUN_AREXX
:
1302 snprintf(ttstring
, sizeof(ttstring
), "%c%s%c %s%s",
1312 /*********************************************************************************************/
1314 static UBYTE
**BuildToolTypes(UBYTE
**src_ttypes
)
1316 APTR pool
= CreatePool(MEMF_CLEAR
, 200, 200);
1317 Object
*listobj
= list
;
1319 WORD list_index
= 0, num_ttypes
= 0, alloc_ttypes
= 10;
1323 if (!pool
) return NULL
;
1325 dst_ttypes
= AllocPooled(pool
, (alloc_ttypes
+ 2) * sizeof(UBYTE
*));
1332 /* Put together final tooltypes list based on old tooltypes and
1333 new tooltypes all in one loop */
1343 struct KeyInfo
*ki
= NULL
;
1345 DoMethod(listobj
, MUIM_List_GetEntry
, list_index
, (IPTR
)&ki
);
1350 tt
= BuildToolType(ki
);
1362 if (src_ttypes
) tt
= *src_ttypes
++;
1363 if (!tt
) break; /* Done. Skip out of "for(;;)" loop */
1365 if (tt
[0] == QUOTE_START
) continue; /* skip tooltype containing old settings */
1368 if (!tt
) break; /* Paranoia. Should not happen. */
1370 if (num_ttypes
>= alloc_ttypes
)
1372 UBYTE
**new_dst_ttypes
= AllocPooled(pool
, (alloc_ttypes
+ 10 + 2) * sizeof(UBYTE
*));
1374 if (!new_dst_ttypes
)
1380 CopyMem(dst_ttypes
+ 1, new_dst_ttypes
+ 1, alloc_ttypes
* sizeof(UBYTE
*));
1381 dst_ttypes
= new_dst_ttypes
;
1385 dst_ttypes
[num_ttypes
+ 1] = AllocPooled(pool
, strlen(tt
) + 1);
1386 if (!dst_ttypes
[num_ttypes
+ 1])
1392 CopyMem(tt
, dst_ttypes
[num_ttypes
+ 1], strlen(tt
) + 1);
1397 dst_ttypes
[0] = (APTR
)pool
;
1399 return dst_ttypes
+ 1;
1403 /*********************************************************************************************/
1405 static void FreeToolTypes(UBYTE
**ttypes
)
1409 DeletePool((APTR
)ttypes
[-1]);
1413 /*********************************************************************************************/
1415 static struct DiskObject
*LoadProgIcon(BPTR
*icondir
, STRPTR iconname
)
1417 struct DiskObject
*progicon
= NULL
;
1423 *icondir
= wbstartup
->sm_ArgList
[0].wa_Lock
;
1425 olddir
= CurrentDir(*icondir
);
1426 progicon
= GetDiskObject(wbstartup
->sm_ArgList
[0].wa_Name
);
1429 strncpy(iconname
, wbstartup
->sm_ArgList
[0].wa_Name
, 255);
1433 if (GetProgramName(iconname
, 255))
1437 *icondir
= GetProgramDir();
1439 olddir
= CurrentDir(*icondir
);
1440 progicon
= GetDiskObject(iconname
);
1448 /*********************************************************************************************/
1450 static void SaveSettings(void)
1452 struct DiskObject
*progicon
;
1453 UBYTE
**ttypes
, **old_ttypes
;
1454 UBYTE iconname
[256];
1455 BPTR icondir
= BNULL
;
1457 progicon
= LoadProgIcon(&icondir
, iconname
);
1459 if (!progicon
) return;
1461 old_ttypes
= (UBYTE
**)progicon
->do_ToolTypes
;
1462 if ((ttypes
= BuildToolTypes(old_ttypes
)))
1467 UBYTE
*tt
, **ttypes_copy
= ttypes
;
1469 while((tt
= *ttypes_copy
++))
1471 kprintf("TT: %s\n", tt
);
1475 olddir
= CurrentDir(icondir
);
1477 progicon
->do_ToolTypes
= ttypes
;
1478 PutDiskObject(iconname
, progicon
);
1479 progicon
->do_ToolTypes
= old_ttypes
;
1483 FreeToolTypes(ttypes
);
1486 FreeDiskObject(progicon
);
1490 /*********************************************************************************************/
1492 static void LoadSettings(void)
1494 struct DiskObject
*progicon
;
1495 UBYTE iconname
[256];
1496 BPTR icondir
= BNULL
;
1497 UBYTE
**ttypes
, *tt
;
1499 progicon
= LoadProgIcon(&icondir
, iconname
);
1500 if (!progicon
) return;
1502 if ((ttypes
= (UBYTE
**)progicon
->do_ToolTypes
))
1504 while((tt
= *ttypes
++))
1506 struct KeyInfo ki
= {0};
1511 if ((tt
[0] == QUOTE_START
) && ((quote_end
= strchr(tt
, (char)QUOTE_END
))))
1513 WORD len
= quote_end
- tt
- 1;
1515 if (len
>= sizeof(ki
.descr
)) continue;
1516 if (quote_end
[1] != ' ') continue;
1518 strncpy(ki
.descr
, tt
+ 1, len
);
1520 if (strncmp(quote_end
+ 2, "CYCLE", 5 + 1) == 0)
1522 ki
.action
= ACTION_CYCLE_WIN
;
1524 else if (strncmp(quote_end
+ 2, "CYCLESCREEN", 11 + 1) == 0)
1526 ki
.action
= ACTION_CYCLE_SCR
;
1528 else if (strncmp(quote_end
+ 2, "MAKEBIG", 7 + 1) == 0)
1530 ki
.action
= ACTION_ENLARGE_WIN
;
1532 else if (strncmp(quote_end
+ 2, "MAKESMALL", 9 + 1) == 0)
1534 ki
.action
= ACTION_SHRINK_WIN
;
1536 else if (strncmp(quote_end
+ 2, "ZIPWINDOW", 9 + 1) == 0)
1538 ki
.action
= ACTION_TOGGLE_WIN
;
1540 else if (strncmp(quote_end
+ 2, "RESCUEWIN", 9 + 1) == 0)
1542 ki
.action
= ACTION_RESCUE_WIN
;
1544 else if (strncmp(quote_end
+ 2, "INSERT ", 7) == 0)
1546 ki
.action
= ACTION_INSERT_TEXT
;
1547 strncpy(ki
.param
, quote_end
+ 2 + 7, sizeof(ki
.param
) - 1);
1549 else if (strncmp(quote_end
+ 2, "RUN ", 4) == 0)
1551 ki
.action
= ACTION_RUN_PROG
;
1552 strncpy(ki
.param
, quote_end
+ 2 + 4, sizeof(ki
.param
) - 1);
1554 else if (strncmp(quote_end
+ 2, "AREXX ", 6) == 0)
1556 ki
.action
= ACTION_RUN_AREXX
;
1557 strncpy(ki
.param
, quote_end
+ 2 + 6, sizeof(ki
.param
) - 1);
1560 if (ki
.action
!= 0xFF)
1562 DoMethod(list
, MUIM_List_InsertSingle
, (IPTR
)&ki
, MUIV_List_Insert_Bottom
);
1565 } /* if ((tt[0] == QUOTE_START) && ((quote_end = strchr(tt, QUOTE_END)))) */
1567 } /* while((tt = *ttypes++)) */
1572 for(index
= 0; ; index
++)
1574 struct KeyInfo
*ki
= NULL
;
1576 DoMethod(list
, MUIM_List_GetEntry
, index
, (IPTR
)&ki
);
1583 } /* if ((ttypes = (UBYTE **)progicon->do_ToolTypes)) */
1585 FreeDiskObject(progicon
);
1588 /*********************************************************************************************/
1590 static void HandleAll(void)
1593 IPTR num_list_entries
= 0;
1595 get(list
, MUIA_List_Entries
, &num_list_entries
);
1596 if ((num_list_entries
== 0) || cx_popup
)
1598 set(wnd
, MUIA_Window_Open
, TRUE
);
1602 set(wnd
, MUIA_Window_Open
, FALSE
);
1605 while (DoMethod(app
,MUIM_Application_NewInput
,&sigs
) !=MUIV_Application_ReturnID_Quit
)
1609 sigs
= Wait(sigs
| SIGBREAKF_CTRL_C
| SIGBREAKF_CTRL_E
| SIGBREAKF_CTRL_F
);
1610 if (sigs
& SIGBREAKF_CTRL_C
)
1614 if (sigs
& SIGBREAKF_CTRL_E
)
1618 if (sigs
& SIGBREAKF_CTRL_F
)
1620 CallHookPkt(&show_hook
, NULL
, NULL
);
1626 /*********************************************************************************************/
1628 int main(int argc
, char **argv
)
1630 GetArguments(argc
, argv
);
1631 InitLocale(CATALOG_NAME
, CATALOG_VERSION
);