Question about AppMessage hooks
I want a BOOPSI window to be able to receive AppMessages so that I can drag'n drop files from the Workbench into it and process them. I've read into the RKRM changes and additions and also the Backfill.c
example from the NDK3.2 and learned that to receive these messages the window object must be created with
WINDOW_AppPort, pAppWindowPort,
WINDOW_AppWindow, TRUE,
WINDOW_AppMsgHook, &apphook,
where the apphook
is defined like
struct Hook apphook;
and wired to the message function like
void __asm __saveds AppMsgFunc( register __a0 struct Hook *Hook,
register __a2 Object *Window,
register __a1 struct AppMessage *Msg )
{
printf("AppMessage\n");
}
apphook.h_Entry = (ULONG (* )())AppMsgFunc;
apphook.h_SubEntry = NULL;
In my exapmle application it works so far and it prints "AppMessage" for every file I drag into the window. But I have two questions regarding this behavior:
-
Is the
__asm __saveds
,register __a0
etc. stuff really necessary? And if yes, is it documented anywhere why it is? I've searched the RKRM Libraries but couldn't find an explanation yet. -
How would I get my application instance data (a pointer to a struct with all the needed objects / user data) into the
AppMsgFunc
without holding it globally? Is there a preferred way to do it?
Btw if the example is written like you pasted it we should probably change it to use the defines in clib/compiler-specific.h instead, as then every compiler will be able to build it.
Thank you much for explaining it:-)
Yes, in the NDK example Backfill.c
the function AppMsgFunc
is defined like I posted it. So, also thanks for the hint to clib/compiler-specific.h
. So I can get rid of the Copy'n pasted "code from the internet" which additionally added support for gcc 6.5 and which looked like that:
#ifdef __SASC
#define ASM __asm
#define ASMR(x) register __ ## x
#define ASMREG(x)
#define SAVEDS __saveds
#else /* __SASC */
#ifdef __GNUC__
#define ASM
#define ASMR(x) register
#define ASMREG(x) __asm("" #x "")
#define SAVEDS __saveds
#else /* __GNUC__ */
#ifdef __VBCC__
#define ASM
#define ASMR(x) __reg("" #x "")
#define ASMREG(x)
#define SAVEDS __saveds
#else /* __VBCC__ */
#error "Compiler not supported yet in asminterface.h"
#endif /* __VBCC__ */
#endif /* __GNUC__ */
#endif /* __SASC */
But regarding my 2nd question: Is there a way to get a pointer to my custom application data, which is currently not in global scope, into AppMsgFunc
? Or must I make the data global to access it in this function?
yes hook has a h_Data field that you can use
Online Status
Well the function takes its arguments in the specified registers so yes register __a0 is nessesary.
And in sas/c which the example code is your need the __asm to tell the compiler that __a0 etc is coming.
Only thing left is the __saveds. This may actually be left out, but that depends on how you build your program. If you build as data far then you don't need it if, but if you build it as data near then __savdes fetches your near pointer. If you are data far and specify __saveds it does nothing, so in general you can simply add it
Oh and the reason you need your near pointer is that you are called from somewhere else so the loaded near pointer when called is that of the calling program (or none if the calling program is data far) In any case you will not have your own near pointer, so that is why you need to ensure it is set up.