Gruppo Editoriale - Amiga Magazine Online
Gruppo Editoriale - Amiga Magazine Online
Gruppo Editoriale - Amiga Magazine Online
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.