04.06.2013 Views

Gruppo Editoriale - Amiga Magazine Online

Gruppo Editoriale - Amiga Magazine Online

Gruppo Editoriale - Amiga Magazine Online

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Le pagine di<br />

1 Tmnsactor per AMIGA<br />

duate dalle abbreviazioni "ie-X" e "ie-Y"); oppure come un<br />

singolo APTR: "ie-position.ie-addr" (abbreviato come<br />

"ieEventAddress").<br />

Questo ultimo caso, che serve ad individuare l'indirizzo di<br />

oggetti manipolati da Intuition, come i Gadget, non ha<br />

riscontro per gli input handler che intercettano gli eventi<br />

prima di Intuition.<br />

I1 primo caso ha significato quando la classe è<br />

IECLASS-RAWMOUSE e il qualificatore contiene il valore<br />

IEQUALIFIER-RELATIVEMOUSE: in tal caso, la prima<br />

word esprime il movimento del mouse rispetto all'asse delle<br />

x (positivo verso destra, negativo verso sinistra) e la secon-<br />

da quello rispetto all'asse delle y (positivo verso il basso e<br />

negativo verso l'alto).<br />

Quando invece la classe è IECLASS-RAWKEY, il campo<br />

ie-X va interpretato come la sequenza di due byte in cui il<br />

primo esprime il valore ie-Code del tasto premuto prima<br />

dell'attuale e il secondo i suoi qualificatori (limitatamente a<br />

quelli il cui valore è inferiore a $100). Il campo ie-Y contie-<br />

ne lo stesso tipo di valori per il penultimo tasto premuto.<br />

Queste informazioni vengono trasmesse solo quando l'e-<br />

vento riguarda la pressione di un tasto, non al momento del<br />

suo rilascio (e non appare quando si preme un singolo<br />

qualificatore).<br />

In definitiva, dall'evento che riporta informazioni su un<br />

tasto si possono ricavare i valori dei due tasti che l'hanno<br />

preceduto. Ad esempio, se viene premuta la sequenza di<br />

tasti: "Shift-A B C", l'evento che segnala la pressione del<br />

tasto "C" avrà nel campo ie-Y il valore $2001 in cui $20<br />

corrisponde all'ie-Code del tasto "A" e $01 al qualificatore<br />

Shift-sx; nel campo ie-X si troverà $3500 che indica il tasto<br />

raw $35 ("B") senza alcun qualificatore. Va osservato che<br />

questo comportamento non sembra essere documentato<br />

nella prima edizione del ROM Kernel Manual e, pertanto,<br />

non deve essere considerato sicuro.<br />

Le ultime due longword costituiscono una struttura timeval<br />

(ieTimeStamp). La struttura timeval, descritta nel file inclu-<br />

de "devices/timer.h", contiene il valore del tempo di siste-<br />

ma espresso in secondi (tv-secs) e microsecondi<br />

(W-micro).<br />

Come diventare "input handler"<br />

Per poter ricevere ed eventualmente modificare il flusso di<br />

eventi in input occorre richiedere all'input.device di diven-<br />

tare un "input handler" (gestore di input), indicando la<br />

priorità che si intende assumere. I1 device mantiene una lista<br />

di tutti gli input handler, ordinata gerarchicamente secondo<br />

la priorità segnalata al momento della richiesta. Intuition ha<br />

priorità 50, dunque, per ricevere i dati prima, occorre<br />

specificare una priorità più alta, compresa tra 51 e 127.<br />

Inoltre, bisogna specificare l'indirizzo della propria routine,<br />

che verrà chiamata per gestire il flusso dei dati e un indirizzo<br />

(opzionale) di memoria che costituirà una area dati privata<br />

per la nostra routine.<br />

La nostra funzione sarà chiamata, dal task dell'input.device,<br />

tutte le volte che awiene un nuovo evento, con l'indirizzo<br />

del flusso di input nel registro A0 e quello della nostra area<br />

dati nel registro Al; il task, inoltre, attende come valore di<br />

ritorno, nel registro DO, I'indirizzo del flusso di input da<br />

passare agli altri input handler. Se noi scriviamo la routine<br />

in C, dobbiamo risolvere il problema di trasferire i dati dai<br />

registri allo stack.<br />

Questo può essere fatto in due modi diversi: prima di tutto<br />

scrivendo un brevissimo programma in assembler che tra-<br />

sferisca il contenuto dei registri sullo stack (con un'istruzio-<br />

ne del tipo M0VEM.L AO/Al,-(A7) ), chiami poi la nostra<br />

routine in C e, infine, ripristini il valore dello Stack Pointer;<br />

oppure, per chi possiede la versione 5.x del compilatore<br />

Lattice, definendo la propria routine con la keyword -asm<br />

e specificando i parametri come register A0 e register Al (si<br />

veda sorgente su disco).<br />

Si tenga presente, inoltre, che la routine, pur appartenendo<br />

fisicamente al segmento dimemoria del nostro programma,<br />

viene eseguita come parte del task dell'input.device; per-<br />

tanto, in primo luogo, utilizzerà il suo stack (di cui non si<br />

dovrà abusare); in secondo luogo, la routine NON verrà<br />

chiamata con I'indirizzo della base dei dati nel registro A4.<br />

La presenza di tale valore è necessaria quando si compila un<br />

programma C con indirizzamento relativo dei dati, cosa che<br />

permette di risparmiare molta memoria e che awiene di<br />

default sul Lattice C 5.0; è necessario quindi caricare l'indi-<br />

rizzo della base dei dati nel registro A4: ciò può avvenire<br />

specificando l'opzione -y (in qualsiasi versione del Lattice)<br />

oppure, nella versione 5.x del Lattice, utilizzando la key-<br />

word -saveds al momento della dichiarazione della fun-<br />

zione o la funzione di libreria geta4().<br />

In terzo luogo, il nostro programma principale non può<br />

terminare finché l'handler resta in funzione, in quanto<br />

ArnigaDos libererebbe sia la nostra memoria che quella<br />

dell'input handler.<br />

Per far entrare in funzione l'input handler, si deve dapprima<br />

creare un Port con la funzione CreatePort; poi uno IOSt-<br />

dReq con la funzione CreateStdIO e aprire il device con<br />

OpenDevice.<br />

A questo punto occorre inserire in una struttura Interrupt i<br />

dati relativi al nostro handler: un puntatore alla funzione nel<br />

campo is-Code, uno all'area dati in quello is-Data e la<br />

priorità richiesta nel campo is-Node.ln-Pri. Infine, una<br />

volta posto il puntatore alla struttura Interrupt nel campo<br />

io-Data dell'IOStdReq e il comando IND-ADDHANDLER<br />

nel campo io-Command, si puo inviare la richiesta<br />

alllinput.device con la funzione DOIO().<br />

Come al solito, ad ogni passo occorre controllare i valori di<br />

ritorno delle funzioni, per assicurarsi che ogni nostra ope-<br />

razione abbia avuto successo. Da questo momento l'han-<br />

dler è attivato e lo rimarrà fino a quando il device non<br />

riceverà la richiesta di eseguire un comando<br />

IND-REMHANDLER. Prima di terminare occorre ricordarsi<br />

di liberare tutte le risorse allocate.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!