SISTEMI A FINESTRE
Window Management Systems (WMS)
Sistema a finestre: sistema software che poggia sul sistema
operativo e si pone fra le applicazioni ed i dispositivi di I/O
in modo da gestire le operazioni di interazione fra utente ed
applicazioni.
Nota: qui con "applicazione" si comprende anche la sua interfaccia.
Il sistema a finestre "implementa" l'ambiente desktop.
Compiti di un sistema a finestre:
- gestire i dispositivi di output tramite un'organizzazione a
finestre dello spazio schermo, in modo tale che nelle varie
finestre sia possibile
visualizzare testo e grafica provenienti da diverse applicazioni.
- gestire i dispositivi di input (tastiera, mouse...)
in modo da intercettare
gli eventi prodotti dall'utente agendo sui dispositivi stessi
ed indirizzarli verso l'applicazione opportuna.
- fornire un'interfaccia di programmazione (API = Application
Program Interface) attraverso la quale un'applicazione possa
usufruire delle risorse a disposizione (finestre, testo,
grafica) e ricevere l'input dell'utente.
Meccanismo generale della comunicazione tra WMS, utente ed applicazione:

L'utente compie azioni sui dispositivi di input.
In corrispondenza di tali azioni, il WMS genera eventi e li
smista alle applicazioni.
L'applicazione interpreta l'evento e si comporta di conseguenza.
L'applicazione fa richieste al WMS per ottenere risorse che
gli permettano di fornire l'output all'utente.
Le risorse sono strutture dati per l'applicazione, e appaiono
all'utente (tramite di dispositivi di output) come
finestre, testo, grafica.
L'utente vede cosi' i risultati e il feedback delle proprie azioni.
Architettura client/server
Un WMS puo' essere collegato as una singola piattaforma
sulla quale girano tutte le applicazioni che ne fanno uso,
oppure avere una architettura distribuita di tipo
client/server.
- Singola piattaforma: Microsoft Windows, Macintosh
- Client/server: X Windows
Ruoli di client e server
- Server:
Processo responsabile di tutti i dispositivi di I/O
(schermo, tastiera, mouse).
Risiede sulla stessa macchina a cui sono collegati i
dispositivi, davanti alla quale siede l'utente.
- Client:
Applicazione che puo' anche girare su una macchina diversa da quella
del server, quindi lontana da quella a cui siede l'utente,
e che comunica con il server via rete.
Il computer su cui risiede i client non ha bisogno di tutto lo strato
di software che costituisce il WMS, ma solo di un protocollo di
comunicazione e delle librerie che costituiscono l'API.
- un server puo' comunicare con piu' client ed eventualmente
gestire diversi dispositivi di input
- un client puo' comunicare con piu' server.

Il client e' quello che ci mette la CPU,
il server e' quello che ci mette schermo e dispositivi di input.
Il servizio offerto dal server e' la gestione dell'I/O.
NOTA BENE:
Qui i ruoli di client e server sono invertiti rispetto ad altri
contesti, nel quali come servizio offerto si intende la potenza di calcolo.
Comunicazione fra client e server
Tutto l'I/O dell'applicazione e' gestito dal server.
Il client invia richieste al server (es. chiede di aprire una
finestra sullo schermo, chiede di scrivere o visualizzare qualcosa
su una finestra...).
Il server invia al client:
- risposte alle sue richieste
- eventi generati dalle azioni compiute dall'utente
In base alle richieste, il server alloca e mantiene risorse
per conto del client:
-
La risorsa e' una struttura dati che risiede sul server,
il server comunica al client un identificatore della
risorsa (link).
-
Il client puo' agire su questa struttura mediante le operazioni
fornite dalla API, usando l'identificatore come parametro.
Il protocollo di cominicazione fra client e server e' asincrono.
Il client non aspetta la risposta alla richiesta ma va avanti
(anche con altre richieste).
Ci possono essere dei ritardi.
Risorse
Risorsa: struttura dati mantenuta e gestita dal server
per conto di uno o piu' client.
Contiene tutte le informazioni relative ad un potenziale strumento
disposibile al client per fare I/O sul server
Risorse possono corrispondere a:
- finestre
- bitmap (matrici booleane)
- font
- pixmap (immagini raster)
Il server puo' creare, modificare e distruggere le risorse su richiesta
del client.
-
Quando il client chiede al server una risorsa,
il server (se puo' soddisfare la richiesta) alloca la risorsa
corrispondente e fornisce al client un identificatore (link) attraverso
il quale il client puo' accedere alla risorsa stessa.
-
Ogni risorsa (in base al suo tipo) e' caratterizzata da un insieme di
parametri che il client puo' conoscere ed impostare attraverso
opportuni comandi della API.
-
Agendo sulle risorse (tramite le funzioni della API) il client
puo' produrre l'output.
Nota: una risorsa corrisponde ad un potenziale
strumento di I/O. Es: una finestra nello stato corrente
puo' essere mappata (visibile) oppure non mappata (nascosta).
Richieste
Quando il client ha bisogno di un servizio da parte del server,
manda una richiesta.
Esempi di richieste riferite a risorsa di tipo "finestra":
- creare una finestra
- distruggere una finestra
- riconfigurare una finestra (visualizzare, nascondere,
spostare, ridimensionare...)
- visualizzare testo in una finestra
- visualizzare output grafico in una finestra
- chiedere informazioni sullo stato corrente di una finestra
Vi sono richieste per altri tipi di risorse.
Per soddisfare una richiesta, il server puo' dover compiere una delle
operazioni seguenti:
- allocare/deallocare la struttura dati corrispondente alla
risorsa interessata
- modificare/leggere i parametri della struttura dati
- generare output sui dispositivi grafici
- generare eventi verso altri client (es. per riconfigurare
una finestra il server si rivolge al window manager, che e'
un particolare client)
Il server inserisce tutte le richieste provenienti dai vari client
in una coda e le prende in considerazione quando ha tempo.
Finestre
Finestra: area rettangolare sullo schermo, su cui e' possibile
visualizzare testo / grafica, catturare eventi.
Componenti di una finestra:
- bordo (spessore, colore, trama)
- interno (colore e trama)
Una finestra e' identificata dal server in modo univoco.
Client puo' agire su una finestra facendo richieste al server
tramite l'identificatore della finestra.
Non e' necessario che un client indirizzi solamente le finestre
da esso create. Puo' anche agire su altre finestre purche'
ne conosca l'identificatore (es: window manager e' un client che
gestisce posizione e dimensione di tutte le finestre di uno schermo -
ved. piu' avanti).
Relazioni tra finestre:
- gerarchia delle finestre
- stack delle finestre
Gerarchia delle finestre
Le finestre sono organizzate secondo una struttura ad albero
(albero delle finestre) che rispecchia la relazione di
contenimento o annidamento.

- Una finestra B e' discentente (o sotto-finestra)
di una finestra A se
l'area ricoperta da B e' vincolata ad essere contenuta
nell'area ricoperta da A.
- La radice dell'albero (root window) esiste sempre e
ricopre l'intero schermo.
- Le finestre discendenti dirette della radice si chiamano
finestre a top-level.
Una sottofinestra e' vincolata a rispettare l'annidamento.
Se spostata fuori dall'area della finestra da cui discende,
la parte esterna non e' visibile.
Una finestra puo' esistere ma non essere visibile (es. non mappata,
iconificata o ricoperta da altre finestre).
Una finestra e' visibile solo se le finestre da cui discende
sono visibili.
Stack delle finestre
Diverse finestre di diverse applicazioni possono coesistere su una stessa
porzione di schermo sovrapponendosi parzialmente o totalmente.
Nota: a differenza di quanto avviene nell'albero delle finestre, qui
la sovrapposizione fra due finestre e' accidentale e transitoria.

Le finestre sono tenute in una pila (stack) e visualizzate di consegnenza.
Su richiesta delle applicazioni o in conseguenza di azioni dell'utente
e' possibile cambiare l'ordine nella pila.
E' possibile modificare la posizione nella pila di una finestra rispetto
alle finestre che stanno al suo stesso livello nella gerarchia ad albero.
In genere si agisce sulle top-level.
Una sottofinestra segue la finestra da cui discende in ogni
suo spostamento nella pila.
Sistemi di coordinate
Ogni finestra ha un sistema di riferimento a coordinate intere.
Ogni pixel una unita'.
Una finestra e' caratterizzata da:
- posizione = coordinate di un angolo (convenzionale) del suo
bordo all'interno del sistema di riferimento della finestra sua
genitrice nella gerarchia di annidamento
- proprio sistema di coordinate con origine in uno degli angoli
(convenzionale) e due assi ortogonali, valori delle
coordinate sono tra 0 e il numero di pixel-1 in larghezza e altezza
La posizione cambia in corrispondenza di azioni di spostamento.
Il sistema di coordinate cambia in corrispondenza di azioni di
ridimensionamento.
In generale l'area occupata sullo schermo dalla finestra e' piu' grande
della dimensione effettiva della finestra a causa dello spessore del bordo.
Mapping di finestre
Creazione di una finestra da parte del server consiste nell'allocazione
ed inizializzazione della corrispondente struttura dati.
Una finestra creata non e' necessariamente visualizzata
sullo schermo.
Client puo' richiedere la visualizzazione di una finestra attraverso
mapping.
Una finestra mappata e' visibile ha purche':
- non ci siano altre finestre che oscurano (coprono)
la finestra in oggetto
- gli antenati della finestra siano mappati
- la finestra sia almeno parzialmente all'interno di tutti
i suoi antenati
Per rendere non piu' visualizzata una finestra: operazione
di unmapping.
Unmapping di una finestra provoca
automaticamente unmapping delle sue discendenti.
Esempio: iconificazione di una finestra = unmapping della
finestra e contemporaneo mapping dell'icona.
Mantenimento del contenuto delle finestre
Il contenuto (grafico, testuale) di una finestra e' il risultato
delle operazioni eseguite (mediante richieste al server) dal client
sulla finestra.
Quando una finestra viene oscurata o resa invisibile e poi torna visibile,
e' necessario ripristinare il suo contenuto. Di questo puo' incaricarsi:
-
Il server,
che deve avere tenuto copia locale del contenuto della
finestra (backing store), eseguendo tutti gli aggiornamenti anche
sulla copia.
Non richiede intervento del client, e' molto oneroso per il server.
-
Il client,
inviando al server le richieste necessarie a riprodurre
il contenuto della finestra:
- l'applicazione e' avvisata dal server
di ogni cambio di stato della finestra
- il programmatore deve scrivere una procedura per il
ritracciamento del contenuto (refresh) della finestra
E' piu' laborioso per programmatore e client.
La strategia 1 ha uso molto limitato e per finestre transitorie
(es. menu' pop-up):
server salva copia solo del contenuto dell'area della finestra che
cade sotto ad una particolare finestra che viene mappata temporaneamente
sopra di essa.
Ordinariamente e' usata la strategia 2.
Eventi
Evento: messaggio inviato da server a client per notificare
che qualcosa e' successo o qualche condizione e' cambiata.
Il server genera eventi come conseguenza di un'azione compiuta
dall'utente oppure come conseguenza di una richiesta fatta da
un client.
Azioni piu' comuni che generano eventi:
- premere o rilasciare un tasto della tastiera
- spostare il puntatore del mouse
- premere o rilasciare un tasto del mouse
- entrare o uscire da una finestra con il puntatore del mouse
Eventi possono anche essere utilizzati dal server per avvisare un
client del cambio di stato delle sue finestre.
Un evento accade sempre in una finestra (source window):
la finestra dove e' avvenuta l'azione
dell'utente oppure la finestra che ha cambiato stato.
Per essere abilitato a ricevere eventi, il client deve fare una richiesta
esplicita al server in cui indica:
- una finestra
- i tipi di eventi provenienti da quella finestra a cui e'
interessato
Quando accade una potenziale causa di evento, il server:
-
Individua il tipo di evento e la sua source window.
-
Se qualche client e' interessato a tale tipo di evento
per tale finestra, gli notifica l'evento.
-
Altrimenti, propaga l'evento verso l'alto nella gerarchia delle
finestre (alla finestra genitrice, e cosi' via).
La propagazione si arresta quando giunge ad una finestra per cui
qualche client si era dichiarato interessato al tipo di evento in
questione (l'evento viene notificato), oppure
quando si raggiunge la root (l'evento viene scartato).
Solo gli eventi generati dall'utente sono propagati.
La finestra sulla quale un evento viene intercettato e notificato
(che e' o la source window o una sua antenata nella gerarchia) e'
chiamata event window.
Il client ha una coda FIFO in cui raccoglie gli eventi che
gli vengono mandati dal server (sono solo gli eventi che
lo riguardano) nell'ordine in cui sono stati generati.
Informazioni associate a un evento
Un evento porta con se' un pacchetto di informazioni:
- il tipo di evento
- il server che lo ha generato
- la finestra in cui e' stato intercettato (event window)
- numero dell'ultima richiesta a cui il server ha risposto
(serve per sincronizzazione)
- informazioni specifiche legate al tipo di evento
(es. posizione del cursore per un evento dal mouse,
codice del tasto per un evento da tastiera...)
Eventi generati dai dispositivi di input
Il server puo' gestire diversi dispositivi di input.
I piu' comuni sono mouse e tastiera.
Eventi da mouse
Il mouse permette essenzialmente di:
- puntare posizioni sullo schermo
- inviare comandi tramite i suoi bottoni
Associato al mouse c'e' un cursore (eco)
descritto da una bitmap che viene mantenuta dal server e viene
visualizzata come immagine digitale sullo schermo.
Cursore e' caratterizzato da un suo punto interno (hotspot).
Questo punto rappresenta la posizione del mouse e
viene monitorato dal server.
Il client puo' chiedere al server di notificare eventi quando:
- un bottone viene premuto o rilasciato
- il cursore si sposta
- il cursore entra o esce dalla finestra
Eventi relativi a pressione di bottoni sono caratterizzati da un "time
stamp" per discriminare fra pressioni singole e sequenze tipo doppio click
o triplo click.
Sono distinti pressione e rilascio
(es. menu' pop-up, operazioni di drag).
Eventi di spostamento sono onerosi da gestire (client puo' chiedere al
server di generare un evento all'inizio e uno alla fine del movimento).
Eventi di entrata ed uscita sono utili per evitare che le applicazioni
debbano monitorare continuamente la posizione del mouse (es. comparsa
di menu' pull-down).
Eventi da tastiera
Server genera un evento ogni volta che un tasto viene premuto o rilasciato.
Evento e' caratterizzato dal codice del tasto piu' dalla presenza di
modificatori dovuti alla pressione contemporanea di piu' tasti
(es. control, alt...).
La finestra a cui si riferisce un evento di tastiera si chiama
focus window.
La focus window puo' essere stabilita in due modi a seconda della
modalita' di funzionamento del server:
- Modalita' real estate: la focus window e'
quella in cui si trova il cursore del mouse.
- Modalita' listener: la focus window e'
una finestra specifica, indipendente dalla posizione del mouse.
La focus window puo' essere cambiata su richiesta del client
(es. cliccando sulla finestra interessata).
Window manager (WM)
Window manager: e' un client particolare che ha il compito di gestire
l'assetto delle finestre top-level nell'ambito del desktop o workspace.
Compiti principali del WM:
- muovere le finestre sullo schermo
- cambiare le dimensioni delle finestre
- cambiare l'ordine delle finestre sullo stack
- effettuare conversioni finestra/icona
- far partire nuove applicazioni
- distruggere finestre e terminare le relative applicazioni
WM dialoga con il server attraverso richieste ed eventi (come tutti
i client).
Il server di ridirige al WM le richieste provenienti da altri client e
riguardanti la struttura di una finestra top-level.
Wm puo' fare mapping di finestre arricchendo la finestra
con un frame (bordo, cornice) che offre all'utente i controlli
sulla finestra stessa.
WM crea una finestra piu' grande di quella richiesta dal client
e ritaglia la finestra del client come sottofinestra.
Eventi che hanno origine nel frame sono mandati a WM.
Eventi che hanno origine nella finestra interna sono inviati al client.
Toolkit per lo sviluppo di interfacce grafiche
Toolkit:
API di livello piu' alto rispetto alla libreria di base fornita dal WMS.
Toolkit ha il compito di semplificare e standardizzare l'uso
di richieste ed eventi da parte dell'applicazione.
Widgets
Toolkit implementa l'interazione con l'utente attraverso oggetti di
finestra o widget (= window object: bottoni, menu'...).
Un widget e' caratterizzato da:
- una o piu' finestre che costituiscono la sua apparenza
- uno stato, descritto da un insieme di dati propri
- un insieme di funzioni che manipolano le finestre e lo stato
- un insieme di eventi che possono essere intercettati dal widget
e passati all'applicazione
- un meccanismo per "aggangiare" a tali eventi procedure
dell'applicazione (scritte dal programmatore), che il sistema chiamera'
automaticamente in occasione dell'evento (procedure callback)
Esempi:
-
Un widget di tipo "bottone semplice" e' costituito da una finestra
ed e' sensibile all'evento click del mouse.
-
Un widget di tipo "bottone con spia luminosa"
e' costituito da una finestra per il bottone ed una per la spia.
L'informazione se la spia e' accesa o spenta fa parte dello stato del
bottone.
Due categorie fondamentali di widget:
- display widget: servono per presentare
informazioni all'utente e/o ricevere input da questo.
- container widget: servono per raggruppare altri widget in un
contesto grafico.
In genere widget di un toolkit sono organizzati in classi
secondo la filosofia object oriented.
Creare un widget = creare un'istanza della classe opportuna.
Gestione degli eventi
Eventi dispatching:
in un programma realizzato tramite un toolkit, gli eventi inviati
dal WMS non sono visibili direttamente, ma solo attraverso i widget.
Il toolkit gestisce direttamente la coda degli eventi tramite
un event loop.
Quando arriva un evento dal WMS, il toolkit attiva il widget a cui l'evento
si riferisce (cioe' il widget che corrisponde alla event window).
Widget puo' gestire un evento come:
- evento interno:
widget utilizza evento per cambiare il proprio stato,
senza interessare l'applicazione
- azione:
widget utilizza evento per produrre un evento di widget che
scatena un'azione, ossia una callback dell'applicazione
Nota: evento di widget puo' essere causato anche da una sequenza
di eventi del WMS (es. doppio click).
Esempio:
In un widget di tipo "slider" (barra di scorrimento per l'immissione di un
valore numerico in un certo intervallo),
gli eventi generati dall'utente trascinando il cursore e cliccando
sulle frecce sono gestiti internamente al widget ed usati per
aggiornare la posizione del cursore.
Lo stato interno del widget comprende il valore della posizione corrente
e puo' essere interrogato dal programma.
Il programma puo' agganciare una callback che scatti ogni volta che
l'utente ha terminato di manipolare lo slider.
GUI Designer
Un toolkit puo' fornire un GUI Designer.
Programma interattivo che permette la progettazione di interfacce grafiche
basate sul detto toolkit.
- si possono creare finestre, bottoni, slider, menu'
istanziando degli schemi predefiniti (classi)
- si possono dimensionare, posizionare tali oggetti nell'interfaccia
usando manipolazione diretta
- si puo' associare direttamente alla pressione di un tasto
in un menu' l'attivazione di sottomenu', apertura di
finestre di dialogo...
Il GUI Designer produce il codice relativo all'interfaccia.
Il programmatore deve solo riempire il corpo delle procedure
callback associate ai widget.