Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
115 user(s) are online (65 user(s) are browsing Forums)

Members: 0
Guests: 115

more...

Headlines

 
  Register To Post  

(1) 2 »
Migration to OS4 Hooks
Just can't stay away
Just can't stay away


See User information
Hello,

In my migration efforts I am now trying to understand how to rewrite the hooks in order to be compliant with OS4 (notably using CallHookPkt)
The Migration guide gives information that is probably sufficient for an experienced programmer, but not for me.

I don't find an example or a hook in the SDK/examples drawer.
Could somebody point me to an example source?

Thanks

Joseph

Go to top
Re: Migration to OS4 Hooks
Supreme Council
Supreme Council


See User information
@JosDuchIt

If you look at the CallHookPkt autodoc, it specifies the arguments a hook should expect.

Luckily, you can change the meaning of those parameters to suit what you need.

Firstly, you need to create a hook function that performs the duties you need:

uint32 myhhokfunc( struct Hook *hook, Object *o, APTR somedata )

The "hook" parameter is a pointer to the hook that you set up earlier (more on that below).

The "o" parameter usually referes to an object (usually the parent), but you can ignore this for your own hooks. You can alternatively use it to pass your own data strtucture.

The last parameter can be pretty much whatever you want it to be, you pass this pointer from CallHookPkt(), so you can pass some data structure that your hook needs.

You must only change the purpose of hook parameters if you are sure that you will only ever be calling your own hooks. System hooks will expect each parameter to be a certain type, and changing it will obviously lead to problems.

In order to set up the hook, you need a section of code like:

struct Hook *myhook;
myhook = IExec->AllocSysObject( ASOT_HOOK, ASOHOOK_Entry, myhookfunc, ASOHOOK_Data, mydatapointer, TAG_DONE);

Later on, you need to free this with:

IExec->FreeSysObject( ASOT_HOOK, myhook );

This is usually done in main() or some other high level function so that the "myhook" variable is valid for the life of the program.

You may have noticed that when setting up the hook, there is a "mydatapointer" variable passed in as the h_Data field. Again, this can be anything you like, I personally use it to pass the hook a pointer to my globaldata structure, this way the hook can access anything within the program.

Now, we have the hook set up, and ready to go, we need to call it. CallHookPkt( myhook, NULL, somedata ) will run the code in the hook. The supplied data can be accessed from within the hook like so:

uint32 myhookfunc( struct Hook *hook, Object *o, APTR myhookdata )
{
/* my hookdatat is the "somedata" pointer sent by CallHookPkt */
}

Remember the "mydatapointer" we passed in the AllocSysObject() call? Well, we can get that from inside the hook by using:

hookdata = hook->h_Data;

So now the hook has access to globaldata which is constant for the life of the hook, and we can access the "somedata" pointer which is specific to each call of the hook. This gives us two sets of data, one constant, and one which may change depending on the context the hook was called in (ie: You set the "somedata" pointer when you call the hook).

Hooks are very powerfull, but you must be carefull if you are going to change any data from a hook run by an asynchronous process. This may lead to two instances of the hook trying to change data at the same time. Under normal circumstances hooks are synchronous with the program so there is no problem unless you spawn processes which call the same hook. In this case, you should protect the data with a call to (Attempt)ObtainSemaphore(), but again, this can lead to deadlocks with multiple processes trying to obtain the same semaphore as it will be put to sleep while it waits for the semaphore. Also check out the mutex functions for protecting memory regions.

Anyway, I'm confusing you, have a go with the above information, and if you get into problems, ring technical support :)

Simon

Go to top
Re: Migration to OS4 Hooks
Just popping in
Just popping in


See User information
@JosDuchIt

You might want to use the SDI headers. This will not just ensure compatibility with future releases of OS4, but you automatically get working hooks with OS3, MOS and AROS. The biggest advantage for OS3 compatibility is the fact, that you don't have to crack your head which parameter belongs into which 68k register.

Just take a look at how YAM uses the SDI hook macros: http://yamos.svn.sourceforge.net/viewvc/yamos/trunk/src/

A full blown hook function will look like this:

HOOKPROTO(function name, return type, object spec, param spec)
{
// your function
// the hook itself can always be accessed via the passed in variable called "hook"
}

If your hook function doesn't need the object and/or param parameters you can just omit them by using the appropriate macro:

HOOKPROTONONP(function name, return type)
{
// your function
// "NO" means "no object"
// "NP" means "no param"
}

In case you want to compile your program not just for OS4 but for all possible target platforms you cannot make use of the AllocSysObject() call but have to create the struct Hook variables yourself. Even here the SDI macros make your life very simple and easy:

MakeHook(hook name, function name)

That's all to create a global accessible hook. MakeStaticHook() does exactly the same, except that the hook is static to one single source module.

Go to top
Re: Migration to OS4 Hooks
Supreme Council
Supreme Council


See User information
@JosDuchIt

Which ever method you use, just remember that the more abstraction you use, the slower it will get. Hooks invariably are used in loops, so speed is of the essence, inside the hook and in its interface.

Simon

Go to top
Re: Migration to OS4 Hooks
Just popping in
Just popping in


See User information
@Rigo

Using the SDI headers doesn't make things slower than doing the dirty work yourself. You just don't need to crack your head about the ugly details. Even better, the resulting binary will be the same, no matter which solution you choose. But the biggest advantage is the common "API" for different platforms: OS3, OS4, MOS and AROS, all covered under a uniform hood.

The speed thing just depends on the individual implementation of the hook function, but this is completely independend of how you define the prototype for the hook function. If you spend a million loop iterations inside the hook function this has nothing to do with the SDI headers.

Go to top
Re: Migration to OS4 Hooks
Supreme Council
Supreme Council


See User information
@tboeckel

Well, considering the topic is "OS4" hooks, I fail to see why an abstracton such as SDI is required. The hook interface in OS4 is hardly rocket science.

Of course, if the intended outcome is to support other platforms too, then your suggestion makes sense.

Simon

Go to top
Re: Migration to OS4 Hooks
Amigans Defender
Amigans Defender


See User information
@tboeckel
Quote:
You might want to use the SDI headers...

For code intended for AmigaOS 4.x I recommend against using the SDI headers because you just end up with yet more name pollution.

Even if your code is intended for multiple platforms, a good design should be factoring out the platform dependent code into independent source modules and not sprinkling macros all over the place IMHO.

ExecSG Team Lead
Go to top
Re: Migration to OS4 Hooks
Just popping in
Just popping in


See User information
@Rigo

I find SDI headers simpler in sintax for hook than each "native" solution (OS3, OS4, MOS and AROS), so it's a good start point for which wants convert/port/begin.

Go to top
Re: Migration to OS4 Hooks
Just can't stay away
Just can't stay away


See User information
@Rigo and others

@Rigo
and others:
Rght now i want to understand fully the OS4 way of doing things and have an OS4 source up and running. I did have a look at the SDI headers and right now it is a complementary source of confusion in my situation.

The hook concerned is a custom stringgadget hook.


After much labour investigating available documentation, headers and autodocs and the source ( which i did not develop ) my main question remains the CallHookPkt function: I don't know where to insert it. I don't find anything similar in the OS3 source.

I understand there are three things to do
- write a Hook function, this function exists and i think it will do (no errors)
<ULONG INTERRUPT SAVEDS TextInHook(struct Hook *hook, struct SGWork *sgw, ULONG *msg)>

- Use AllocSysObject: i think i found the line to change in ttne InitGadgets function
InitHook (&tid->hk, TextInHook, bt);
will become
&tid->hk=AllocSysObject( ASOT_HOOK, ASOHOOK_Entry, func, ASOHOOK_Data, bt, TAG_DONE)
-lastly insert
CallHookPkt( &tid->hk, NULL, somemsg )
but where?

I understand the somemsg info will then be given as third argument to TextInHook/
As i don't see an equivalent to CallHookPkt in the source i am also in doubt which second argument i should use in CallHookPkt

All help much appreciated

Joseph

Go to top
Re: Migration to OS4 Hooks
Quite a regular
Quite a regular


See User information
@JosDuchIt

I don't know what you are trying to do exactly but if you are for example trying to setup a Hook the stringgadget is supposed to use, then that's not your job to CallHookPkt() it will be done by the stringgadget itself when needed. For this you have to tell the stringgadget you have written a hook function for it, generally you either do it at stringgadget object creation, either at runtime using a SetAttrs() on one of its attribute, for example let's say you want to install an EditHook you'll write something like
SetAttrsstringGadgObjSTRINGA_EditHook, &tid->hkTAG_DONE)


PS: BTW your code with AllocSysObject won't work because as its name implies AllocSysObject *is* allocating the object, while it seems in your code the variable hk in the object tid is of type struct Hook rather than struct Hook *, which means it statically allocated at tid's creation. You should change its definition to struct Hook * and remove any '&' in front of tid->hk from the source but that should be no problem if you are familiar with C pointers and C in generall...

Back to a quiet home... At last
Go to top
Re: Migration to OS4 Hooks
Just can't stay away
Just can't stay away


See User information
@abalaban
Thanks for your help

The source is compiling just now.

I had a hell of a lot of time to remove some error "expected something at end of input." The missing brace was not in the the file the error pointed to (containing main() but in some other file included.
I also will from now on disapprove using the /* */ pair for just some line comment.

I also had to use AllocSysObjectTags since using __USE_INLINE__ makes the compiler think you are working with a macro with two arguments.


Thanks again

Joseph

Go to top
Re: Migration to OS4 Hooks
Just can't stay away
Just can't stay away


See User information
Hi all

I am struggling with a window backfillhook.
Can you tell me what might be wrong here?


__USE_INLINE__

struct BackFillData
{
struct Layer *l;
struct Rectangle bounds;
LONG offx, offy;
};

struct BackFill
{
char mode; /* s=solid, p=pattern, i=icon, I=image */
SHORT apen, bpen;
LONG top, left, width, height;
struct DiskObject *dobj;
struct BitMap BM;
struct imginfo *img;
};



ULONG INTERRUPT SAVEDS do_backfill(struct Hook *h, struct RastPort *rp, struct BackFillData *bfd)


int makewindow(struct BackFill *bf,) //??? args
{
struct TagItem *tags;
struct window *wn=NULL;
if (!(hk=AllocSysObjectTags( ASOT_HOOK, ASOHOOK_Entry, do_backfill, ASOHOOK_Data, NULL, TAG_DONE))) //OS4 Duch Added
return (0)


tags[c].ti_Tag = WA_BackFill;
tags[c].ti_Data = (LONG)hk


wn = OpenWindowTagList (NULL, tags)

etc

}
I derived theis from analogy with teh TextINHool (gadget string hook above. and from the original 68 k source.

What i don't understand is how the bfd are uused or found . I don't even find in the source where its values are set.
Does the do_backfil() hook function follows some template known to the system? If yes where is this described?

Thanks for help and calrification.

Joseph

Go to top
Re: Migration to OS4 Hooks
Not too shy to talk
Not too shy to talk


See User information
Quote:

ShInKurO wrote:
@Rigo

I find SDI headers simpler in sintax for hook than each "native" solution (OS3, OS4, MOS and AROS), so it's a good start point for which wants convert/port/begin.


I second that. For years, I used SDI headers that make hooks really simple to use and the source is readable and it supports all systems.
They perfectly fill my needs.

Go to top
Re: Migration to OS4 Hooks
Just can't stay away
Just can't stay away


See User information
@ssolie
Quote:

For code intended for AmigaOS 4.x I recommend against using the SDI headers because you just end up with yet more name pollution.

I noticed this thread when I was about to open a topic asking about hooks. I simply wanted to add a hook to a system function and found the autodocs somewhat confusing. Intuition and WorkBench show examples assigning hookEntry to the function HookEntry() in amiga_lib and hookSubEnty to the actual hook that is added. Some OS4 examples I found elsewhere assign the actual hook to hookEntry. Can someone explain what that's all about.

Go to top
Re: Migration to OS4 Hooks
Quite a regular
Quite a regular


See User information
@xenic

IIRC in pre OS4 teh OS wasn't able to directly jump to Hook address and execute the code (I think it was about argument passing, but not really sure) instead you had to jump to a helper function that would then jump to the desired address. So you were putting address of amigalib's HookEntry() into hookEntry and your actual hook into hookSubEntry now this is not needed anymore you only have to put your hook into hookEntry AOS 4 will handle everything for you (be it PPC or 68k code) when called via CallHookPkt()

Back to a quiet home... At last
Go to top
Re: Migration to OS4 Hooks
Just can't stay away
Just can't stay away


See User information
@xenic

For 680x0 hook functions the parameters are passed in registers a0, a2 and a1 but in 680x0 C ABI all parameters are passed on the stack.

HookEntry is simply a small assembler stub function that pushes the parameters passed in a0, a2 and a1 onto the stack and then calls the C function in h_SubEntry.

Some C compilers allow to specify that function parameters are passed in registers instead of on the stack. In this case you don't need to use the HookEntry function but can put your function pointer directly in h_Entry. Like in GCC f.e. you could define your hook function like:

ULONG hook_func (struct Hook *hook __asm("a0"), Object *o __asm("a2"), APTR msg __asm("a1"));

or using REG() macro from SDI_compiler.h:

ULONG hook_func (REG(a0, struct Hook *hook), REG(a2, Object *o), REG(a1, APTR msg));

On PPC AmigaOS 4 uses a standard PPC ABI for passing function parameters so there is no need at all for a stub function like HookEntry.

Go to top
Re: Migration to OS4 Hooks
Just can't stay away
Just can't stay away


See User information
@abalaban

Hello, i could solve the first problem , a string gadget hook, with the help you provided, especially that there was no need for the use of CallHookPkt since the call was done by giving the string gadget the appropriate hooktag.

I had to jump into the water though not understanding really what i was doing. I changed the soutce as folows

I commented out the functions hookEntry and InitHook belw

/******** Load Registers **********/
/* OS3
ULONG ASM hookEntry(REG(a0) struct Hook *h, REG(a2) VOID *o, REG(a1) VOID *msg)
//OS4E expected ')' before 'struct'
// macro "REG" requires 2 arguments, but only 1 given
{
return ((*(ULONG(*)(struct Hook *, VOID *, VOID *))(h->h_SubEntry))(h, o, msg));
}
######*/
/********* Initialise Hook **********/
/* OS3 #######
void InitHook(struct Hook *h, ULONG (*func)(), void *data)

{ if (h)
{ h->h_Entry = (ULONG(*)()) hookEntry;
h->h_SubEntry = func;
h->h_Data = data;
}
}
#### */



For the string gadget i had

1) the gadget tag
GTST_EditHook, tid->hk

2) the hookfunction
ULONG INTERRUPT SAVEDS TextInHook(struct Hook *hook, struct SGWork *sgw, ULONG *msg)
// OS4E was __interrupt __saveds

3) the hook initialisation
///InitHook (&tid->hk, TextInHook, bt); replaced with

if (!(tid->hk = AllocSysObjectTags( ASOT_HOOK, ASOHOOK_Entry, TextInHook, ASOHOOK_Data, bt, TAG_DONE))
========
For the window backfill hook i had)

1) the window tag
tags[c].ti_Tag = WA_BackFill;
tags[c].ti_Data = (LONG)hk

2) thehookfunction

ULONG INTERRUPT SAVEDS do_backfill(struct Hook *h, struct RastPort *rp, struct BackFillData *bfd)

3) the hook initialisation
// InitHook (hk, do_backfill, NULL); /* initialise hook */OS3
if (!(hk=AllocSysObjectTags( ASOT_HOOK, ASOHOOK_Entry, do_backfill, ASOHOOK_Data, NULL, TAG_DONE)))

A. The textinhook works ok as described
One thing i don't understand is that TextInhook requires apart from the hook two other arguments, and in the initialisation only one is given (bt)
So i am guessing that the first struct SGWork is created during the initialisation and the second is passed as bt

I can only understand this if a TextinHook function has a template where the two first arguments are of types struct Hook and struct SGW

I would expect then to find this template in the SDK, but i don't find it.


B. The backfillhook does not work and i probably mixed up some pointerbusyness
Here however the 68k initialisation InitHook apart from the hook and the hookfunction has no additional argument (NULL) whereas the do_backfill hook function needs apart from the rastport, which i suppose the initialisation will provide, also a struct BackFillData that does not seem to be system type. How is the do_backfill function provided with this argument? (Or how iscould it be created during the hook initialisation,?)

I am not doubting yet that the 68k InitHook initialisation is wrong, since this source used to compile well for 68k

Clarification of the above would help mme greatly;

Joseph

Go to top
Re: Migration to OS4 Hooks
Not too shy to talk
Not too shy to talk


See User information
@JosDuchIt

A)
The gadtools autodocs says that GTST_EditHook will be copied to the StringExtend->EditHook field.
If you now make a quick search in the includes you will find the file intuition/sghooks.h. Have you read it?

B)
A WA_BackFill hook is, as the autodoc says, a LayerHook that is described in Layers.doc InstallLayerHook() as

void LayerHookFunc(struct Hook *, struct RastPort *, struct BackFillMessage *);

BTW: The InstallLayerHook() autodocs needs a update, it still has a 68k-asm example.

Go to top
Re: Migration to OS4 Hooks
Just can't stay away
Just can't stay away


See User information
@ZeroG

This was very helpfull, thanks

I do understand the Backfiil hook now that does not work yet,

I do not fully understand the GTST Edithook, but it worked, i just wantrd to compare both.

>A)
>The gadtools autodocs says that GTST_EditHook will be copied to the StringExtend->EditHook >field.

I read this which is far less clear
"==========================================
GTST_EditHook (struct Hook *) - Hook to use as a custom string gadget
edit hook (StringExtend->EditHook) for this gadget. GadTools will
allocate the StringExtend->WorkBuffer for you. (defaults to NULL)
"==========================================


>If you now make a quick search in the includes you will find the file intuition/sghooks.h. Have >you read it?
I find the stuff below, however this does not tell me how my hookfunction gets its SGW argument. ??


"===================================

struct StringExtend
{
/* display specifications */
struct TextFont *Font; /* must be an open Font (not TextAttr) */
UBYTE Pens[2]; /* color of text/backgroun */
UBYTE ActivePens[2]; /* colors when gadget is active */

/* edit specifications */
ULONG InitialModes; /* initial mode flags, below */
struct Hook *EditHook; /* if non-NULL, must supply WorkBuffer */
STRPTR WorkBuffer; /* must be as large as StringInfo.Buffer*/

ULONG Reserved[4]; /* set to 0 */
};

struct SGWork
{
/* set up when gadget is first activated */
struct Gadget *Gadget; /* the contestant itself */
struct StringInfo *StringInfo; /* easy access to sinfo */
STRPTR WorkBuffer; /* intuition's planned result */
STRPTR PrevBuffer; /* what was there before */
ULONG Modes; /* current mode */

/* modified for each input event */
struct InputEvent *IEvent; /* actual event: do not change */
UWORD Code; /* character code, if one byte */
WORD BufferPos; /* cursor position */
WORD NumChars;
ULONG Actions; /* what Intuition will do */
LONG LongInt; /* temp storage for longint */

struct GadgetInfo *GadgetInfo; /* see cghooks.h */
UWORD EditOp; /* from constants below */
};
========================================


B)
>A WA_BackFill hook is, as the autodoc says, a LayerHook that is described in Layers.doc
>InstallLayerHook() as

>void LayerHookFunc(struct Hook *, struct RastPort *, struct BackFillMessage *);

>BTW: The InstallLayerHook() autodocs needs a update, it still has a 68k-asm example.

I found this
======================
/*
* The message a backfill hook receives
*/
struct BackFillMessage
{
struct Layer *Layer;
struct Rectangle Bounds;
LONG OffsetX;
LONG OffsetY;
};
=======================

In the source however i found

struct BackFillData
{
struct Layer *l;
struct Rectangle bounds;
LONG offx, offy;
};

which closely matches BackFillMessage

and the hookfunction referring to the latter
ULONG INTERRUPT SAVEDS do_backfill(struct Hook *h, struct RastPort *rp, struct BackFillData *bfd)

This was the source of my bewildering: i did not find this structure BackFillData in th includes, and i did not see where it was initialised.

Joseph

Go to top
Re: Migration to OS4 Hooks
Just popping in
Just popping in


See User information
@JosDuchIt

Having a working string edit hook is not really as hard as you might think. And you don't have to conjure up any obscure magic to make it work.

For example Scout's task signal window uses an edit hook to restrict the input to hexadecimal values only. All the "magic" happens in hex_editfunc().

Go to top

  Register To Post
(1) 2 »

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2023 The XOOPS Project