
              -----------------------------------------------

                ProgED V2.x by Giovanni Lambiase (C) 1995-97

                         Note per i programmatori

              -----------------------------------------------


-------------------------
 1. Strutture principali
-------------------------

    Per una breve spiegazione sulle varie strutture e relativi campi
vedi il file PED.h.



------------
 2. Scanner
------------

    Uno scanner deve essere scritto tramite una funzione assembler o una
funzione C che prende gli argomenti nei registri. Il codice risultante
deve essere linkato SENZA alcun modulo di startup, in modo tale che la
prima locazione eseguibile sia l'inizio della funzione scritta. La
funzione di ricerca riceve due argomenti nei seguenti registri:

    A0: Indirizzo della linea su cui effettuare la ricerca. Punta ad una
        stringa terminata con 0.

    A1: Indirizzo del buffer che conterr il riferimento, se trovato.

    La funzione deve ritornare nel registro D0 la lunghezza della stringa
creata nel buffer puntato da A1. Nel caso la funzione non abbia trovato
nulla deve ritornare 0.

    NOTA: E' necessario salvare tutti i registri all'ingresso della
          funzione e ripristarli all'uscita.



-----------
 3. Folder
-----------

    Una funzione di ricerca dei fold deve essere scritta tramite una funzione
assembler o una funzione C che prende gli argomenti nei registri. Il codice
risultante deve essere linkato SENZA alcun modulo di startup, in modo tale
che la prima locazione eseguibile sia l'inizio della funzione scritta. La
funzione di ricerca riceve due argomenti nei seguenti registri:

    A0: E' l'indirizzo della struttura PEDWindow relativa al testo su
        cui effettuare la ricerca.

    D0: Contiene il numero della colonna su cui  posizionato il cursore.
        (0=prima colonna).

    D1: Contiene il numero della linea su cui  posizionato il cursore.
        Tale numero  assoluto. Ci significa che non tiene conto dei
        fold eventualmente presenti nel testo. (0=prima linea).

    A1: Contiene l'indirizzo di una long-word. In tale long-word la funzione
        deve scrivere il numero della linea iniziale del fold, se trovato.
        Anche in questo caso la funzione non deve considerare eventuali
        fold gi presenti nel testo. (0=prima linea).

    A2: Contiene l'indirizzo di una long-word. In tale long-word la funzione
        deve scrivere il numero della linea finale del fold, se trovato.
        Anche in questo caso la funzione non deve considerare eventuali
        fold gi presenti nel testo. (0=prima linea).

    A3: Punta ad un buffer in cui la funzione deve scrivere la stringa
        che ProgED scriver a fianco dell'indicatore ">FOLD". Generalmente
        il nome della funzione C, ecc.

    La funzione deve ritornare in D0 il valore 1 se ha trovato un fold, 0
altrimenti. Nel primo caso la funzione deve anche fornire, tramite A1 e A2
i numeri di linea iniziali e finali del fold e, tramite A3, la stringa
rappresentante il fold. E' necessario,infine, salvare tutti i registri
all'ingresso della funzione e ripristinarli all'uscita.

    NOTA: la funzione 'FOLD ALL' viene eseguita eseguendo una chiamata
alla funzione su tutte le linee (dalla prima all'ultima) e con il
numero di colonna pari a 0 (prima colonna).



----------------
 4. Clienti API
----------------

    ProgED consente ad applicazioni esterne (chiamate "clienti") di
 "agganciarsi" ad esso. Un cliente API  semplicemente un normale
programma (scritto in qualsiasi linguaggio). Tale programma deve
essere scritto in modo tale da "registrarsi" presso il ProgED. Ci
consente al ProgED di tracciare tutti i clienti e di mandar loro
messaggi sulle operazioni che devono effettuare.

I messaggi che un cliente deve inviare a ProgED (nella sua porta
API di nome "PED_API") hannno la seguente struttura:



    struct APIMessage
    {
        struct Message     am_Message;
        ULONG              am_MsgType,
                           am_MsgArg[10],
                           am_RC;
    }

    am_Message:

         E' un campo contenente un messaggio standard Exec.

    am_MsgType:

         Contiene il tipo di messaggio da inviare.

    am_MsgArg[]:

         E' un vettore contenente un massimo di 10 argomenti
         dipendenti dal tipo del messaggio

    am_RC:

         E' il codice di ritorno che ProgED restituisce al cliente
         per informarlo sul successo dell'operazione.




    I tipi di messaggi che un cliente pu spedire a ProgED sono, per ora:

    PED_API_REGISTER:

          Registra un cliente presso ProgED. Richiede un puntatore ad una
          struttura di tipo APIClient in am_MsgArg[0]. Non ritorna nessun
          risultato in am_RC.

    PED_API_UNREGISTER:

          Informa ProgED che il cliente vuole andarsene (!?). Richiede lo
          STESSO puntatore dato al momento della registrazione, con il
          messaggio PED_API_REGISTER, in am_MsgArg[0]. Non ritorna nessun
          risultato in am_RC.

    PED_API_ADD_INTERNAL_COMMAND:

          Consente di espandere le funzionalit del ProgED aggiungendo un
          nuovo comando interno. A tale scopo  necessario allocare e
          riempire una struttura ArexxExtCmds e fornire il suo puntatore
          in am_MsgArg[0]. Nessun risultato in am_RC.

    PED_API_REM_INTERNAL_COMMAND:

          Rimuove un comando precedentemente aggiunto tramite il messaggio
          PED_API_ADD_INTERNAL_COMMAND. E' necessario fornire in am_MsgArg[0]
          lo STESSO puntatore dato al momento dell'aggiunta del comando.
          Non ritorna risultati in am_RC.

    PED_API_GET_ACTIVE_WINDOW:

        Ottiene, in am_RC, l'indirizzo della struttura PEDWindow associata
        alla finestra attualmente attiva.

    PED_API_GET_WINDOW_LIST:

        Ottiene, in am_RC, l'indirizzo iniziale della lista di strutture
        PEDWindow corrispondenti ai testi in memoria.

    PED_API_GET_SCREEN_ADDRESS:

        Ottiene, in am_RC, l'indirizzo dello schermo del ProgED. Se il ProgED
         attualmente iconificato ritorna NULL.

    PED_API_GET_PREFS_ADDRESS:

        Ottiene, in am_RC, l'indirizzo della struttura Prefs.

    PED_API_GET_PUBSCRNAME:

        Ottiene, in am_RC, un puntatore al nome dello schermo pubblico
        aperto dal ProgED.

    NOTA: La struttura ArexxExtCmds (e tutti gli oggetti a cui puntano i
          suoi campi), fornita al momento dell'aggiunta del comando, deve
          rimanere valida in memoria. E' possibile riutilizzarla (o
          liberare la memoria associata solo DOPO aver utilizzato un
          messaggio di tipo PED_REM_INTERNAL_COMMAND.
          Lo stesso vale per la struttura APIClient utilizzata per il
          messaggio PED_API_ADD_INTERNAL_COMMAND. In questo caso 
          possibile riutilizzare la struttura dopo il corrispondente
          messaggio PED_API_REM_INTERNAL_COMMAND.




    I messaggi che ProgED pu inviare ad un cliente sono, per ora:

    PED_API_SHOW:

        ProgED ha riaperto il suo schermo. L'indirizzo dello schermo
        pu essere ottenuto nel campo am_MsgArg[0]. Nel campo am_MsgArg[1],
        invece, si trova un puntatore al nome dello schermo pubblico
        utilizzato. Il cliente puo' utilizzare queste due informazioni
        per aprire eventuali finestre sullo schermo del ProgED. Questo
        messaggio viene spedito solo se, al momento della registrazione,
        il cliente ha settato il flag NOTIFY_ON_SHOWHIDE.

    PED_API_HIDE:

        ProgED st per chiudere il suo schermo. Questo messaggio viene
        spedito solo se, al momento della registrazione, il cliente ha
        settato il flag NOTIFY_ON_SHOWHIDE.


    PED_API_KEY:

        L'utente ha battuto un tasto. Il cliente pu ottenere la struttura
        IntuiMessage relativa leggendo il campo am_MsgArg[0]. Tale campo
        conterr il puntatore alla struttura IntuiMessage contenente il
        messaggio di tipo RAWKEY ricevuto dal ProgED. Nel campo am_MsgArg[1],
	invece, il cliente pu leggere l'indirizzo della struttura
        PEDWindow associata alla finestra che ha ricevuto il messaggio.
	Questo messaggio viene spedito solo se, al momento della registrazione,
        il cliente ha settato il flag NOTIFY_ON_KEY.

        NOTA: In ogni caso, al termine della gestione di questo messaggio,
        ProgED eseguir l'azione legata al tasto. Inoltre il cliente
        NON DEVE modificare il messaggio stesso, perch  un messaggio
        proveniente da Intuition!

    PED_API_TRANSLATE:

        Questo messaggio viene ricevuto solo se si  specificato il flag
        NOTIFY_ON_TRANSLATE. La ricezione di questo messaggio significa che
        l'utente ha battuto uno o pi tasti. Il cliente, in tal caso, riceve un
        puntatore al buffer statico di ProgED (lungo KEYBUFLEN bytes in am_MsgArg[0]),
        un puntatore ad un ULONG contenente il numero di caratteri nel buffer
        (nel campo am_MsgArg[1]) e il puntatore alla struttura PEDWindow
        relativa alla finestra interessata (nel campo am_MsgArg[2]). Alla
        ricezione di questo messaggio il cliente pu MODIFICARE lo stato
        del buffer di ProgED inserendo i caratteri da inserire nel testo
        e modificando di conseguenza il numero di caratteri tramite
        l'apposito puntatore ad ULONG. Appena replicato al messaggio ProgED
        scriver nella finestra i caratteri trovati nel buffer, permettendoti
        di "tradurre" (ovvero modificare) i caratteri battuti dall'utente.
        In ogni caso NON SUPERARE la lunghezza consentita (KEYBUFLEN).

    PED_API_OPEN:

        Questo messaggio viene ricevuto solo se si  specificato il flag
        NOTIFY_ON_OPEN_CLOSE. ProgED manda questo messaggio per avvertire
        il cliente che una nuova finestra di testo  stata aperta. Gli
        argomenti del messaggio sono i seguenti: in am_MsgArg[0] l'indirizzo
        della struttura PEDWindow corrispondente alla finestra aperta,
        in am_MsgArg[1] l'indirizzo dello schermo usato e in am_MsgArg[2]
        un puntatore al nome dello schermo pubblico usato.

        NOTA: Questo messaggio segnala l'apertura delle FINESTRE e non
        dei buffer di testo.

    PED_API_CLOSE:

        Riguarda la chiusura di una finestra di testo. Vedi PED_API_OPEN
        per gli argomenti.

    PED_API_QUIT:

        ProgED sta per terminare. Alla ricezione di questo messaggio (che
        viene SEMPRE inviato a prescindere dai flag NOTIFY_xxx) il cliente
        deve chiudere le eventuali finestre e terminare. E' VIETATO
        UTILIZZARE LA PORTA API DOPO LA RICEZIONE DI QUESTO MESSAGGIO !!!!!
        Questo implica che, dopo la ricezione di questo messaggio, il
        cliente NON DEVE tentare di togliere la registrazione e/o la
        definizione di comandi esterni.



    Qui di seguito sono riportate le spiegazioni riguardanti i campi delle
diverse strutture utilizzate.


    struct APIClient
    {
        struct MsgPort          *ac_ClientPort;
        ULONG                    ac_Notify;
        char                    *ac_name;
        struct APIClient        *ac_Next;
    }

    ac_ClientPort:

        Indica l'indirizzo di una porta messaggi a cui ProgED invier i
        messaggi informativi al cliente. Questo tipo di messaggi verr
        spiegato successivamente.

    ac_Notify:

        Indica quali tipi di messaggi il cliente vuole ricevere dal ProgED.
        Gli unici tipi di messaggi selezionabili attualmente sono indicati
        dai flag NOTIFY_ON_SHOW_HIDE, NOTIFY_ON_KEY, NOTIFY_ON_TRANSLATE e
        NOTIFY_ON_OPEN_CLOSE. Il primo obbliga ProgED a spedire i messaggi
        di tipo PED_API_SHOW e PED_API_HIDE. Il secondo obbliga ProgED a
        spedire i messaggi di tipo PED_API_KEY. NOTIFY_ON_TRANSLATE permette
        di ricevere i messaggi di tipo PED_API_TRANSLATE mentre
        NOTIFY_ON_OPEN_CLOSE permette di ricevere i messaggi PED_API_OPEN
        e PED_API_CLOSE. Si noti che il messaggio PED_API_QUIT viene
        comunque mandato a prescindere dai flag qui specificati.

    ac_Name:

        Punta al nome del cliente.

    ac_Next:

        Porre a NULL. Conterr il successore cliente della lista interna
        del ProgED.




    struct ArexxExtCmds
    {
        UBYTE                    External;
        char                    *Name;
        char                    *Template;
        void                    *Defaults[MAXREXXARGS];
        LONG ASM                (*CommFunc)( RG(a0) struct CommandData *);
        struct ArexxExtCmds     *NextCmd;
    }

    External:

        Indica che il comando  gestito da un cliente. Porre SEMPRE a TRUE.

    Name:

        Nome del comando. Specificare sempre in lettere maiuscole.

    Template:

        E' il template AmigaDOS del comando.

    Default[]:

        Indica il vettore di puntatori che deve essere passato alla
        funzione ReadArgs della dos.library. Deve contenere i valori
        di default dei parametri del template. Per ulteriori informazioni
        leggere la documentazione della funzione ReadArgs.

    CommFunc:

        Indica il puntatore alla funzione che realizza il comando. Tale
        funzione deve essere scritta in assembler (o ricevere i parametri
        come una funzione assembler). Essa deve ricevere un puntatore ad
        una struttura CommandData in A0 e ritornare il codice d'errore
        risultante dall'esecuzione in D0. In seguito analizzeremo la
        struttura CommandData.

    NextCmd:

        Porre a NULL. ProgED ne modificher il valore portandolo a
        puntare al prossimo comando fornito dallo stesso cliente o da
        un altro.




    struct CommandData
    {
        char              *CommandLine;
        void             **CommandArgs;
        struct MyWindow   *CurrentWindow,
                          *FirstWindow;
        struct Prefs      *CurrentPrefs;
        LONG ASM (*ExecuteInternalCommand)(RG(a0) char *);
	struct Screen	  *Screen;
    }

    CommandLine:

        Punta ad una stringa riportante l'intera linea di comando riguardante
        il comando.

    CommandArgs:

        Punta ad un vettore di (void *). Ogni puntatore deve essere utilizzato
        secondo le norme dettate dalla ReadArgs. Questo vettore, infatti, 
        il risultato della applicazione della stessa funzione alla linea di
        comando (tenendo presente i default dati nella struttura ArexxExtCmds).

    CurrentWindow:

        Indica il puntatore alla struttura PEDWindow indicante la finestra
        attualmente attiva.

    FirstWindow:

        Indica il puntatore alla prima struttura PEDWindow della lista di
        finestre mantenuta dal ProgED.

    CurrentPrefs:

	Punta ad una struttura Prefs contenente le preferenze attuali.

    ExecuteInternalCommand:

        E' un puntatore ad una funzione assembler. Chiamando questa
        funzione (specificando in A0 il puntatore ad una stringa) 
        possibile eseguire i comandi interni del ProgED. A tale scopo
        la stringa puntata da A0 deve contenere la linea di comando
        desiderata. In D0 viene ritornato il codice d'errore risultante.

        NOTA: Non utilizzare la porta ARexx di ProgED per eseguire i
        comandi interni! Cos facendo, infatti, si bloccherebbero
        sia ProgED che il cliente. Ci  dovuto al fatto che, mentre
        ProgED esegue la funzione che implementa il comando, NON PU
        rispondere ai messaggi provenienti da s stesso!

    Screen:

        E' il puntatore allo schermo utilizzato da ProgED. Pu essere
        uno schermo pubblico aperto da ProgED o un qualunque altro
        schermo pubblico. Questo campo  presente a partire dalla
        versione 2.3.



-------------------
 5. Funzioni utili
-------------------

    Le funzioni C che seguono sono utili per la scrittura di folder e
scanner. Esse riguardano la ricerca di linee. Potete utilizzarle
tagliandole da questo testo e inserendole nei vostri programmi.



/*****
 *
 * FUNZIONE:	struct Line *SearchLine(struct Line *line,int y)
 *
 * SCOPO:	Cerca l'indirizzo della linea "y-esima" (0=prima) a partire
 *		dalla prima linea del file data da line.
 *		NB: Tiene conto dei FOLDS.
 *
 * RESTITUISCE: Un puntatore alla linea cercata.
 *
 ****/

struct Line *SearchLine(struct Line *line,int y)
{
	while(((y--)>0)&&(line))	line=NextLine(line);
	return(line);
}



/*****
 *
 * FUNZIONE:	int SearchLine2(struct Line *line,int y)
 *
 * SCOPO:	Cerca il # della linea (tenendo conto dei FOLD)
 *		della linea ASSOLUTA y.
 *
 * RESTITUISCE: Il # della linea cercata.
 *
 ****/

int SearchLine2(struct Line *line,int y)
{
	int	n=0;

	while(((y--)>0)&&(line))
	{
		if (!line->Folder)	n++;
		else	if (line->NextLine)
				if (!line->NextLine->Folder)	n++;
		line=line->NextLine;
	}
	if (line)	return(n);
	else		return(0);
}



/*****
 *
 * FUNZIONE:	int SearchLine3(struct Line *first,struct Line *line)
 *
 * SCOPO:	Cerca il # assoluto della linea line a partire
 *		dalla prima linea del file data da first.
 *		NB: NON tiene conto dei FOLDS.
 *
 * RESTITUISCE: Il # della linea cercata.
 *
 ****/

int SearchLine3(struct Line *first,struct Line *line)
{
	long	n=0;

	while(first)
	{
		if (first==line)	break;
		n++;
		first=first->NextLine;
	}
	return(n);
}



/*****
 *
 * FUNZIONE:	struct Line *SearchLine4(struct Line *line,int y)
 *
 * SCOPO:	Cerca l'indirizzo della linea "y-esima" (0=prima) a partire
 *		dalla prima linea del file data da line.
 *		NB: NON tiene conto dei FOLDS.
 *
 * RESTITUISCE: Un puntatore alla linea cercata.
 *
 ****/

struct Line *SearchLine4(struct Line *line,int y)
{
	while(((y--)>0)&&(line))	line=line->NextLine;
	return(line);
}



