7 Versionstring: $VER: SDI_hook.h 1.9 (08.04.2005)
8 Author: SDI & Jens Langner
10 Description: defines to hide compiler specific hook stuff
12 1.0 21.06.02 : based on the work made for freeciv and YAM with
13 additional texts partly taken from YAM_hook.h changes made
14 by Jens Langner, largely reworked the mechanism
15 1.1 07.10.02 : added HOOKPROTONP and HOOKPROTONONP requested by Jens
16 1.2 18.10.02 : reverted to old MorphOS-method for GCC
17 1.3 08.02.04 : modified to get it compatible to AmigaOS4
18 1.4 17.02.04 : modified to get compatible to latest SDI_compiler.h changes
19 1.5 02.03.04 : added UNUSED define to OS4 hook specification so that the
20 compiler can ignore some warnings.
21 1.6 02.03.04 : added (APTR) casts to MorphOS prototype definition to
22 reduce compiler warnings.
23 1.7 04.07.04 : removed static from all DISPATCHERPROTO definitions as there
24 may dispatcher that are of course non static.
25 1.8 07.04.05 : added MakeHookWithData (Sebastian Bauer)
26 1.9 08.04.05 : changed MorphOS hooks to use HookEntry (Ilkka Lehtoranta)
30 ** This is PD (Public Domain). This means you can do with it whatever you want
31 ** without any restrictions. I only ask you to tell me improvements, so I may
32 ** fix the main line of this files as well.
34 ** To keep confusion level low: When changing this file, please note it in
35 ** above history list and indicate that the change was not made by myself
36 ** (e.g. add your name or nick name).
38 ** Jens Langner <Jens.Langner@light-speed.de> and
39 ** Dirk Stöcker <stoecker@epost.de>
42 #include "SDI_compiler.h"
45 ** Hook macros to handle the creation of Hooks/Dispatchers for different
46 ** Operating System versions.
47 ** Currently AmigaOS and MorphOS is supported.
49 ** For more information about hooks see include file <utility/hooks.h> or
50 ** the relevant descriptions in utility.library autodocs.
54 ** Creates a hook with the name "TestHook" that calls a corresponding
55 ** function "TestFunc" that will be called with a pointer "text"
56 ** (in register A1) and returns a long.
58 ** HOOKPROTONHNO(TestFunc, LONG, STRPTR text)
63 ** MakeHook(TestHook, TestFunc);
65 ** Every function that is created with HOOKPROTO* must have a MakeHook() or
66 ** MakeStaticHook() to create the corresponding hook. Best is to call this
67 ** directly after the hook function. This is required by the GCC macros.
69 ** The naming convention for the Hook Prototype macros is as followed:
71 ** HOOKPROTO[NH][NO][NP]
73 ** NoHook | NoParameter
76 ** So a plain HOOKPROTO() creates you a Hook function that requires
77 ** 4 parameters, the "name" of the hookfunction, the "obj" in REG_A2,
78 ** the "param" in REG_A1 and a "hook" in REG_A0. Usually you will always
79 ** use NH, as the hook structure itself is nearly never required.
81 ** The DISPATCHERPROTO macro is for MUI dispatcher functions. It gets the
82 ** functionname as argument. To supply this function for use by MUI, use
83 ** The ENTRY macro, which also gets the function name as argument.
86 #if !defined(__MORPHOS__) || !defined(__GNUC__)
87 #if defined(__amigaos4__)
88 #define HOOKPROTO(name, ret, obj, param) static SAVEDS ASM ret \
89 name(REG(a0, struct Hook *hook), REG(a2, obj), REG(a1, param))
90 #define HOOKPROTONO(name, ret, param) static SAVEDS ASM ret \
91 name(REG(a0, struct Hook *hook), REG(a2, UNUSED APTR obj), \
93 #define HOOKPROTONP(name, ret, obj) static SAVEDS ASM ret \
94 name(REG(a0, struct Hook *hook), REG(a2, obj), \
95 REG(a1, UNUSED APTR param))
96 #define HOOKPROTONONP(name, ret) static SAVEDS ASM ret \
97 name(REG(a0, struct Hook *hook), REG(a2, UNUSED APTR obj), \
98 REG(a1, UNUSED APTR param))
99 #define HOOKPROTONH(name, ret, obj, param) static SAVEDS ASM ret \
100 name(REG(a0, UNUSED struct Hook *hook), REG(a2, obj), REG(a1, param))
101 #define HOOKPROTONHNO(name, ret, param) static SAVEDS ASM ret \
102 name(REG(a0, UNUSED struct Hook *hook), REG(a2, UNUSED APTR obj), \
104 #define HOOKPROTONHNP(name, ret, obj) static SAVEDS ASM ret \
105 name(REG(a0, UNUSED struct Hook *hook), REG(a2, obj), \
106 REG(a1, UNUSED APTR param))
107 #define HOOKPROTONHNONP(name, ret) static SAVEDS ret name(void)
109 #define HOOKPROTO(name, ret, obj, param) static SAVEDS ASM ret \
110 name(REG(a0, struct Hook *hook), REG(a2, obj), REG(a1, param))
111 #define HOOKPROTONO(name, ret, param) static SAVEDS ASM ret \
112 name(REG(a0, struct Hook *hook), REG(a1, param))
113 #define HOOKPROTONP(name, ret, obj) static SAVEDS ASM ret \
114 name(REG(a0, struct Hook *hook), REG(a2, obj))
115 #define HOOKPROTONONP(name, ret) static SAVEDS ASM ret \
116 name(REG(a0, struct Hook *hook))
117 #define HOOKPROTONH(name, ret, obj, param) static SAVEDS ASM ret \
118 name(REG(a2, obj), REG(a1, param))
119 #define HOOKPROTONHNO(name, ret, param) static SAVEDS ASM ret \
121 #define HOOKPROTONHNP(name, ret, obj) static SAVEDS ASM ret \
123 #define HOOKPROTONHNONP(name, ret) static SAVEDS ret name(void)
127 #if defined(__MORPHOS__)
128 #include <proto/alib.h>
130 #define SDI_TRAP_LIB 0xFF00 /* SDI prefix to reduce conflicts */
132 struct SDI_EmulLibEntry
139 #define MakeHook(hookname, funcname) struct Hook hookname = {{NULL, NULL}, \
140 (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL}
141 #define MakeHookWithData(hookname, funcname, data) struct Hook hookname = \
142 {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, (APTR)data}
143 #define MakeStaticHook(hookname, funcname) static struct Hook hookname = \
144 {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL}
146 #if defined(__GNUC__)
147 #define HOOKPROTO(name, ret, obj, param) static SAVEDS ASM ret \
148 name(REG(a0, struct Hook *hook), REG(a2, obj), REG(a1, param))
149 #define HOOKPROTONO(name, ret, param) static SAVEDS ASM ret \
150 name(REG(a0, struct Hook *hook), REG(a2, UNUSED APTR obj), \
152 #define HOOKPROTONP(name, ret, obj) static SAVEDS ASM ret \
153 name(REG(a0, struct Hook *hook), REG(a2, obj), \
154 REG(a1, UNUSED APTR param))
155 #define HOOKPROTONONP(name, ret) static SAVEDS ASM ret \
156 name(REG(a0, struct Hook *hook), REG(a2, UNUSED APTR obj), \
157 REG(a1, UNUSED APTR param))
158 #define HOOKPROTONH(name, ret, obj, param) static SAVEDS ASM ret \
159 name(REG(a0, UNUSED struct Hook *hook), REG(a2, obj), REG(a1, param))
160 #define HOOKPROTONHNO(name, ret, param) static SAVEDS ASM ret \
161 name(REG(a0, UNUSED struct Hook *hook), REG(a2, UNUSED APTR obj), \
163 #define HOOKPROTONHNP(name, ret, obj) static SAVEDS ASM ret \
164 name(REG(a0, UNUSED struct Hook *hook), REG(a2, obj), \
165 REG(a1, UNUSED APTR param))
166 #define HOOKPROTONHNONP(name, ret) static SAVEDS ret name(void)
167 #define DISPATCHERPROTO(name) \
169 ULONG name(struct IClass * cl, Object * obj, Msg msg); \
170 static ULONG Trampoline_##name(void) {return name((struct IClass *) \
171 REG_A0, (Object *) REG_A2, (Msg) REG_A1);} \
172 static const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
173 (void(*)())Trampoline_##name}; \
174 ULONG name(struct IClass * cl, Object * obj, Msg msg)
176 #define DISPATCHERPROTO(name) \
178 ASM ULONG name(REG(a0, \
179 struct IClass * cl), REG(a2, Object * obj), REG(a1, Msg msg)); \
180 static const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
182 ASM ULONG name(REG(a0, \
183 struct IClass * cl), REG(a2, Object * obj), REG(a1, Msg msg))
186 #define ENTRY(func) (APTR)&Gate_##func
188 #define DISPATCHERPROTO(name) SAVEDS ASM ULONG name(REG(a0, \
189 struct IClass * cl), REG(a2, Object * obj), REG(a1, Msg msg))
190 #define ENTRY(func) (APTR)func
191 #define MakeHook(hookname, funcname) struct Hook hookname = {{NULL, NULL}, \
192 (HOOKFUNC)funcname, NULL, NULL}
193 #define MakeHookWithData(hookname, funcname, data) struct Hook hookname = \
194 {{NULL, NULL}, (HOOKFUNC)funcname, NULL, (APTR)data}
195 #define MakeStaticHook(hookname, funcname) static struct Hook hookname = \
196 {{NULL, NULL}, (HOOKFUNC)funcname, NULL, NULL}
199 #define InitHook(hook, orighook, data) ((hook)->h_Entry = (orighook).h_Entry,\
200 (hook)->h_SubEntry = (orighook).h_SubEntry,(hook)->h_Data = (APTR)(data))
202 #endif /* SDI_HOOK_H */