Per dubbi, consigli o richieste, potete mandare un'e-mail ad Andrea Carolfi.
Ringraziamo Amiga Transactor Mailing List per questo tangibile contributo!
In questa lezione andremo a trattare un'utile caratteristica della libreria
ASL: i filtri. Per prima cosa dobbiamo includere nel nostro sorgente il file utility/hooks.h, questo serve perchè nel nostro codice dovremo dichiarare una struttura: struct Hook { struct MinNode h_MinNode; ULONG (*h_Entry)(); /* assembler entry point */ ULONG (*h_SubEntry)(); /* often HLL entry point */ APTR h_Data; /* owner specific */ }; che dovremo valorizzare. Ci sono delle convenzioni da rispettare per chiamare un hook. La funzione puntata da Hook.h_Entry è chiamata con i seguenti parametri: A0 - puntatore alla struttura dati hook stessa Il control sarà passato alla routine h_Entry. Per molti linguaggi ad alto livello (High-Level Languages = HLL), questa saranno alcune istruzioni in linguaggio assembly che scrivono i registri sullo stack, fanno altro setup, e quindi chiamano la funzione puntata da h_SubEntry. Il codice di ricezione in C standard è: HookFunc(struct Hook *hook, APTR object, APTR message) Notare che l'ordine naturale dei registri differisce da questa convenzione per l'ordine dei parametri in C che è A0, A2, e A1. La stub in linguaggio assembly per il C potrebbe essere: _hookEntry: move.l a1,-(sp) ; push message packet pointer move.l a2,-(sp) ; push object pointer move.l a0,-(sp) ; push hook pointer move.l h_SubEntry(a0),a0 ; fetch C entry point ... jsr (a0) ; ... and call it lea 12(sp),sp ; fix stack rts Con questa funzione come interfaccia, potete scrivere una funzione di setup per l'Hook così: InitHook(struct Hook *hook, ULONG (*c_function)(), APTR userdata) { ULONG (*hookEntry)(); hook->h_Entry = hookEntry; hook->h_SubEntry = c_function; hook->h_Data = userdata; } Con un compilatore capace di registerizzare i parametri, come il SAS C, potete mettere la funzione C nel campo h_Entry direttamente. Per esempio, per il SAS C: ULONG __saveds __asm HookFunc(register __a0 struct Hook *hook, register __a2 APTR object, register __a1 APTR message); Dunque, tornando ai nostri casi, vediamo un esempio specifico per il file requester: #include <exec/types.h> #include <dos/dosasl.h> #include <libraries/asl.h> #include <proto/exec.h> #include <proto/dos.h> #include <proto/asl.h> #define DESTPATLENGTH 20 UBYTE *sourcepattern = "(#?.jpg)"; UBYTE pat[DESTPATLENGTH]; struct Hook filter; struct FileRequester *fr; [...] /* Se ritorna TRUE il requester include il file nella lista, altrimenti no. */ ULONG __saveds __asm HookFunc(register __a0 struct Hook *hook, register __a2 struct FileRequester *fr, register __a1 struct AnchorPath *ap) { /* We got an AnchorPath structure, should ** the requester display this file? */ /* MatchPattern() is a dos.library function that ** compares a matching pattern (parsed by the ** ParsePattern() DOS function) to a string and ** returns true if they match. */ return MatchPattern(pat,ap -> ap_Info.fib_FileName); } void main(void) { filter.h_Entry = (HOOKFUNC)HookFunc; ParsePattern(sourcepattern, pat, DESTPATLENGTH); if((fr = AllocAslRequest(ASL_FileRequest, ASLFR_FilterFunc, &filter,TAG_DONE))) { if(AslRequestTags(fr,TAG_DONE)) { [...] } FreeAslRequest(fr); } } Ovviamente nella funzione di filtraggio, possiamo usare un qualsiasi metodo che riteniamo opportuno invece che basarci sull'estensione come fa in questo caso. Per quanto riguarda la funzione per i font requester: ULONG __saveds __asm HookFunc(register __a0 struct Hook *hook, register __a2 struct FontRequester *fr, register __a1 struct TextAttr *tr); mentre per gli screen requester: ULONG __saveds __asm HookFunc(register __a0 struct Hook *hook, register __a2 struct ScreenModeRequester *fr, register __a1 ULONg modeid) Ricordarsi che deve ritornare TRUE se l'elemento deve essere aggiunto oppure FALSE se deve essere ignorato. In allegato un sorgente di esempio su come filtrare gli schermi che hanno dimensione superiori o uguali a 640x480 pixel. Listato di questa lezione
|
![]() |
![]() |