Corso di AmigaOS

Torna all'elenco delle lezioniPer dubbi, consigli o richieste, potete mandare un'e-mail ad Andrea Carolfi.
Ringraziamo Amiga Transactor Mailing List per questo tangibile contributo!


La asl.library (Diciottesima lezione)

Nelle precedenti lezioni abbiamo trattato, in maniera più o meno approfondita, diverse librerie di Amiga: exec, dos, intuition, gadtools e graphics. Queste cinque librerie sono praticamente il cuore (oltre a layer) del nostro amato OS. Esistono però molte altre librerie che non sono fondamentali per il boot del sistema ma molto utili per creare applicazioni o giochi di un certo livello (oltre ad essere ovviamente usate dal resto del sistema).
Cominciamo dunque a vedere la prima di queste librerie di supporto: la asl.library. Le funzioni messe a disposizione sono:

APTR AllocAslRequest( unsigned long reqType, struct TagItem *tagList );
APTR AllocAslRequestTags( unsigned long reqType, Tag Tag1, ... );

BOOL AslRequest( APTR requester, struct TagItem *tagList );
BOOL AslRequestTags( APTR requester, Tag Tag1, ... );

void FreeAslRequest( APTR requester );

L'uso di queste funzioni è molto facile; a seconda del tipo di requester che ci serve, consultando il file libraries/asl.h, potremo decidere quali tag utilizzare e quali no.
Facciamo un esempio:

[...]

struct FileRequester *Req = NULL;
struct Window *win = NULL;

[...]

         /* Alloco un file requester con determinate caratteristiche */
         if((Req=AllocAslRequestTags(ASL_FileRequest,
                  ASLFR_Window,           win,     // finestra associata al requester
                  ASLFR_SleepWindow,      TRUE,    // puntatore d'attesa per la fin associata
                  ASLFR_RejectIcons,      TRUE,    // non mostrare le icone
                  TAG_DONE)))
         {
                  /* Modifico il tag per indicare il modo salvataggio */
                  if(AslRequestTags(Req,ASLFR_TitleText,"Scegli il file da salvare",
                                ASLFR_DoSaveMode,TRUE,TAG_DONE))
                  {
                                /* L'utente ha selezionato un file e premuto su Ok */
                  }
                  else
                                /* L'utente ha selezionato 'Annulla' */
                  FreeAslRequest(Req);
         }

Supponendo che questo codice sia in una vostra routine di salvataggio, ogni volta che viene chiamata, alloca usa e dealloca il filerequester. Questo presenta diversi svantaggi. Quello che l'utente nota, oltre al fatto che magari in determinate situazioni (poca memoria) il vostro programma non salva, è che il requester non si "ricorda" la posizione precedente, sia come finestra che come cassetto di lavoro.
E' quindi buona norma allocare un unico requester che utilizzeremo per le operazioni sui file e deallocarlo solo alla fine del programma. Infatti è possibile agire tramite la AslRequest() sui vari aspetti di un requester. Come nell'esempio, che imposta il modo salvataggio.
Ovviamente questo discorso é valido anche per gli altri due tipi di requester messi a disposizione da questa libreria.
Tenere presente, che le varie strutture FileRequester ScreenModeRequester e FontRequester sono a SOLA LETTURA, per modificarle è bene usare l'apposita funzione asl.

Vediamo quindi le strutture dei vari requester:

/* presa dal file workbench/startup.h serve al file requester */
struct WBArg {
          BPTR    wa_Lock; /* a lock descriptor */
          BYTE *     wa_Name; /* a string relative to that lock */
};


/*****************************************************************************
 *
 * ASL File Requester data structures and constants
 *
 * This structure must only be allocated by asl.library amd is READ-ONLY!
 * Control of the various fields is provided via tags when the requester
 * is created with AllocAslRequest() and when it is displayed via
 * AslRequest()
 */
struct FileRequester
{
          UBYTE     fr_Reserved0[4];
          STRPTR    fr_File;           /* Contents of File gadget on exit    */
          STRPTR    fr_Drawer;         /* Contents of Drawer gadget on exit  */
          UBYTE     fr_Reserved1[10];
          WORD      fr_LeftEdge;       /* Coordinates of requester on exit   */
          WORD      fr_TopEdge;
          WORD      fr_Width;
          WORD      fr_Height;
          UBYTE     fr_Reserved2[2];
          LONG      fr_NumArgs;        /* Number of files selected           */
          struct WBArg *fr_ArgList;    /* List of files selected             */
          APTR      fr_UserData;       /* You can store your own data here   */
          UBYTE     fr_Reserved3[8];
          STRPTR    fr_Pattern;        /* Contents of Pattern gadget on exit */
};

Credo che i commenti siano abbastanza esplicativi da soli. In pratica, nell'esempio di prima, dove c'è il commento /* L'utente ha selezionato un file... */ possiamo accedere ai campi della struttura per memorizzarli e/o utilizzarli per i nostri scopi.
TIP: Per utilizzare il nome del cassetto più quello del file per la Open() potete usare il seguente codice:

UBYTE *nomefile,len = strlen(Req -> fr_Drawer) + strlen(Req -> fr_File) + 1;
if(nomefile = AllocVec(len,MEMF_CLEAR))
{
        strcpy(nomefile,Req -> fr_Drawer);
        AddPart(nomefile,Req -> fr_File,len + 1);

        [...]

        FreeVec(nomefile);
}

che permette di creare il nome file richiesto senza preoccuparsi se il nome del cassetto è un nome di device (e quindi terminante con : ) o un cassetto (e quindi da aggiungere una / ).

/*****************************************************************************
 *
 * ASL Font Requester data structures and constants
 *
 * This structure must only be allocated by asl.library amd is READ-ONLY!
 * Control of the various fields is provided via tags when the requester
 * is created with AllocAslRequest() and when it is displayed via
 * AslRequest()
 */
struct FontRequester
{
          UBYTE        fo_Reserved0[8];
          struct TextAttr  fo_Attr;    /* Returned TextAttr          */
          UBYTE        fo_FrontPen;    /* Returned front pen          */
          UBYTE        fo_BackPen;     /* Returned back pen          */
          UBYTE        fo_DrawMode;    /* Returned drawing mode       */
          UBYTE        fo_Reserved1;
          APTR      fo_UserData;       /* You can store your own data here */
          WORD      fo_LeftEdge;       /* Coordinates of requester on exit */
          WORD      fo_TopEdge;
          WORD      fo_Width;
          WORD      fo_Height;
          struct TTextAttr fo_TAttr;      /* Returned TTextAttr          */
};

Stesso discorso per questa struttura, nella scorsa lezione abbiamo visto come utilizzare una struttura TextAttr per aprire ed usare un font nella nostra RastPort e non dovrebbe quindi presentare problemi di sorta.

/*****************************************************************************
 *
 * ASL Screen Mode Requester data structures and constants
 *
 * This structure must only be allocated by asl.library and is READ-ONLY!
 * Control of the various fields is provided via tags when the requester
 * is created with AllocAslRequest() and when it is displayed via
 * AslRequest()
 */
struct ScreenModeRequester
{
          ULONG sm_DisplayID;       /* Display mode ID                  */
          ULONG sm_DisplayWidth;    /* Width of display in pixels       */
          ULONG sm_DisplayHeight;   /* Height of display in pixels      */
          UWORD sm_DisplayDepth;    /* Number of bit-planes of display  */
          UWORD sm_OverscanType;    /* Type of overscan of display      */
          BOOL  sm_AutoScroll;      /* Display should auto-scroll?      */

          ULONG sm_BitMapWidth;     /* Used to create your own BitMap   */
          ULONG sm_BitMapHeight;

          WORD  sm_LeftEdge;        /* Coordinates of requester on exit */
          WORD  sm_TopEdge;
          WORD  sm_Width;
          WORD  sm_Height;

          BOOL  sm_InfoOpened;      /* Info window opened on exit?      */
          WORD  sm_InfoLeftEdge;    /* Last coordinates of Info window  */
          WORD  sm_InfoTopEdge;
          WORD  sm_InfoWidth;
          WORD  sm_InfoHeight;

          APTR  sm_UserData;        /* You can store your own data here */
};

Infine anche i campi di questa struttura sono di facile comprensione, in pratica i primi otto campi servono per determinare quale tipo di schermo aprire e con che dimensioni e profondità.

Listato di questa lezione

Lezione precedente Indice delle lezioni Lezione successiva
Copyright AMiWoRLD Ph0ton