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
applicazione.
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 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
Server
Processo responsabile di tutti i dispositivi di I/O
(schermo, tastiera, mouse):
- crea e manipola finestre
- produce testo e grafica
- gestisce i dispositivi di input (mouse e tastiera)
Server di solito sulla stessa macchina a cui sono collegati i
dispositivi.
Client
Applicazione che puo' anche girare su una macchina diversa da quella
del server e che comunica con il server via rete attraverso un
protocollo comune.
Tutto l'I/O dell'applicazione e' gestito dal server.
Il client fa richieste al server (es. chiede di
scrivere o visualizzare qualcosa) e riceve dal server sia
risposte alle sue richieste che eventi
generati dalle azioni dell'utente.
Comunicazione fra client e server
Client invia richieste al server.
Server invia al client risorse sotto forma di link a strutture dati
che risiedono sul server.
Client puo' agire su queste strutture mediante determinate operazioni
primitive fornite dalla API.
Server invia al client anche eventi che possono essere prodotti
in conseguenze delle azioni compiute dall'utente sui dispositivi.
Il computer su cui risiede i client non ha bisogno di tutto lo strato
di software che costituisce il WMS, ma solo delle librerie che
costituiscono l'API e del relativo protocollo di comunicazione.
- 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.
Notare che i ruoli di client e server qui sono invertiti
rispetto ad altri contesti.
Risorse
Risorsa: struttura dati mantenuta e gestita dal server
per conto di uno o piu' client.
Risorse possono essere:
- 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 il client puo' produrre l'output.
Nota: per l'applicazione una risorsa e' una struttura dati.
Per l'utente e' un potenziale output grafico. Es: una
finestra che 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.
Richieste tipiche:
- 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
Gli esempi di richieste precedenti sono fatti riferendosi a
risorsa 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.
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.
Finestre
Finestra: area rettangolare sullo schermo.
Componenti di una finestra:
- bordo (spessore, colore, trama)
- interno (colore e trama)
Finestra 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:
- 1. gerarchia delle finestre
- 2. stack delle finestre
1. Gerarchia delle finestre
Le finestre sono organizzate secondo una struttura ad albero
(albero delle finestre) che implementa il concetto di
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.
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. iconificata
o ricoperta da altre).
Una finestra e' visibile solo se le finestre da cui discende
sono visibili.
2. 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 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.
Una sottofinestra deve seguire 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 da
cui discende
- 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.
La visualizzazione ha effetto 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.
Quando faccio unmapping di una finestra questo provoca
automaticamente unmapping delle sue discendenti.
Esempio: iconificazione di una finestra = unmapping della
finestra e contemporaneo mapping dell'icona.
Mantenimento del contenuto delle finestre
Quando una finestra viene oscurata o resa
invisibile e poi torna visibile, e' necessario rispristinare
il suo contenuto.
Alcune possibilita':
- Backing store:
server tiene copia del contenuto della finestra (gli
aggiornamenti eventuali vengono eseguiti anche sulla copia).
Sistema oneroso per il server (non e' standard in X windows).
- Save unders:
server salva solo il contenuto dell'area della finestra che
cade sotto ad una particolare finestra F quando F viene
mappata (uso limitato, e per finestre transitorie, es. menu' pop-up).
- Responsabilita' lasciata all'applicazione:
- applicazione avvisata di ogni cambio di stato della finestra
- programmatore deve preoccuparsi di scrivere una
procedura per il ritracciamento del contenuto (refresh)
della finestra
Soluzione piu' laboriosa per programmatore e client.
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 e' sempre collegato ad una finestra (event window)
che e' quella a cui si riferisce l'azione dell'utente oppure
quella 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
Azioni del server quando accade una potenziale causa di evento
- individuare tipo di evento e finestra a cui si riferisce
(source window)
- se ci sono client interessati a tale tipo di evento
per la source window, allora l'event window viene identificata
con la source window e l'evento e' notificato a tutti i
client interessati
- se non ci sono client interessati, l'evento viene
propagato verso l'alto nella gerarchia delle finestre
(solo gli eventi generati dall'utente sono propagati)
Notifica di un evento a un client
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 generato (source window)
- numero dell'ultima richiesta a cui il server ha risposto
(serve per sincronizzazione)
- flag che indica se l'evento e' stato generato dal server
o da un altro client (nel secondo caso l'evento e' stato
rediretto dal server)
- informazioni specifiche legate al tipo di evento
(es. posizione del cursore per un evento dal mouse,
codice del tasto per un evento da tastiera, ed altro...)
Gestione dei dispositivi di input
Il server puo' gestire diversi dispositivi di input.
I piu' comuni sono mouse e tastiera.
Mouse
Il mouse permette essenzialmente di:
- puntare posizioni sullo schermo
- inviare comandi tramite i suoi bottoni
Presenza di 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 doopio 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).
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 questo tipo 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.
In questa modalita' la focus window puo' essere
cambiata su richiesta del client.
Window manager (WM)
Window manager: e' un client particolare
che ha il compito di gestire l'assetto delle finestre 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.
WM puo' chiedere al server di ridirigergli tutte le richieste
provenienti da altri client e riguardanti la struttura di una
finestra.
Esempio:
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.
PROGRAMMAZIONE GUIDATA DA EVENTI
(event-driven programming)
Applicazione interattiva implementata come client nel contesto
di un WMS.
Il comportamento dell'applicazione e' di tipo reattivo.
Le reazioni sono scatenate dagli eventi prodotti dal WMS a seguito
delle azioni dell'utente.
Gli eventi determinano il flusso del programma.
Tipi di interazione:
- a. bloccante
- b. non bloccante
a. Interazione bloccante
L'applicazione si pone in attesa di un evento e interrompe
ogni altra attivita' (liberando la CPU).
Schema di funzionamento di un programma guidato da eventi
con interazione bloccante:
- 1. Inizializzazione del collegamento con il WMS
- 2. Creazione e visualizzazione dell'interfaccia
grafica: creare e mappare le finestre necessarie
ed abilitare i tipi di eventi di interesse
- 3. Attesa (con blocco del flusso del programma) che
giunga un evento
- 4. Interpretazione dell'evento e reazione
(puo' comportare richieste di output)
- 5. Ritorno a 3.
I passi 3,4 e 5 costituiscono il ciclo degli eventi.
Il ciclo degli eventi puo' essere implementato come un loop
infinito o come un loop che prevede una condizione di uscita
corrispondente alla terminazione dell'applicazione.
All'interno del ciclo si effettua una selezione (case o switch)
che puo' dipendere sia dal tipo di evento che dallo stato
in cui si trova il programma.
Ad ogni scelta corrisponde un insieme di istruzioni (procedura)
che costituisce la reazione del programma all'evento.
Tale reazione puo' comportare:
- cambiamento dello stato interno del programma
- attivazione di una procedura di calcolo con produzione
din risultati
- visualizzazione dei risultati attraverso l'interfaccia
grafica o comunque feedback per confermare il completamento
dell'operazione
- cambiamenti nell'interfaccia grafica con richieste di creazione
o distruzione o modifica di finestre, attivazione e disattivazione
di tipi di eventi
- eventuale generazione di eventi diretti ad altre applicazioni
Schema dellinterazione:

Nota: importante che l'attesa del programma sia bloccante
in contesti di time-sharing.
Procedure callback
Alternativa a scrivere uno switch nell'event loop.
Callback: procedura dell'applicazione che viene eseguita
al verificarsi di un dato evento
In fase di inizializzazione, la procedura viene definita e
registrata cioe' collegata all'evento in questione.
L'interfaccia di programmazione puo' fornire un meccanismo che
gestisce l'associazione evento-callback e implementa
automaticamente il ciclo degli eventi.
Ciclo degli eventi consiste dei passi:
- 3. attesa che giunga un evento
- 4. attivazione della callback corrispondente
- 5. ritorno al passo 3.
Il programmatore deve:
- prevedere quali sono gli eventi di interesse
- collegare a ciascun evento una callback
b. Interazione non bloccante
Necessita' di un programma di gestire sia operazioni di reazione ad
eventi, sia operazioni autonome (che il programma esegue anche quando
l'utente non produce eventi.
L'applicazione monitora se arrivano eventi e nel frattempo
esegue le sue operazioni (consumando CPU).
Se arriva un evento, allora interrompe la sua normale
attivita' per reagire all'evento.
Due possibilita':
-
Gli eventi sono occazionali, mentre la procedura indipendente
da questi ha la massima priorita'.
Ciclo degli eventi diventa:
- 3. controlla se ci sono eventi nella coda
- 4. se c'e' un evento, esegui la callback corrispondente
- 5. Ritorno a 3.
-
Interazione ha la massima priorita', mentre la procedura indipendente
viene eseguita solo se e quando c'e' tempo.
Si puo' introdurre un evento nullo, a cui
e' collegata una callback che si incarica di eseguire la
procedura indipendente.
Ciclo degli eventi diventa:
- 3. attesa per un tempo max fissato che giunga un evento;
se non arriva niente, genera l'evento nullo
- 4. attivazione dellaa callback corrispondente
- 5. Ritorno a 3.
Questo sistema libera la CPU proporzionalmente
al tempo che il programma puo' aspettare prima di invocare
la procedura indipendente.
Toolkit
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'...).
Dal punto di vista del programmatore un widget e' una
struttura dati caratterizzata da:
- una o piu' finestre che costituiscono l'apparenza del
widget
- un insieme di dati propri (stato del widget)
- un insieme di funzioni che manipolano le finestre e lo stato
- un insieme di eventi che possono essere prodotti dal widget
- un meccanismo per registrare le procedure callback
in corrispondenza degli eventi
In genere widget di un toolkit sono organizzati in classi
secondo la filosofia object oriented.
Creare un widget = creare un'istanza della classe opportuna.
Due tipi findamentali 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.
Gestione degli eventi nei widget
Eventi dispatching:
in un programma realizzato tramite un toolkit, gli eventi inviati
dal WMS non sono visibili direttamente, ma solo attraverso i
widget.
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).
Esempi:
-
Gestione di un potenziometro come valuator
in modalita' sample
- widget che non prevede azioni ma fornisce un metodo per
testare la misura corrente del potenziometro
- eventi generati dall'utente agendo sul cursore
sono gestiti internamente al widget sia per variare la
misura che per aggiornare l'eco
-
Gestione di un dialog modale in modalita' request
- widget che filtra tutti gli eventi diretti all'applicazione
e associa azioni solo agli eventi corrispondenti alla pressione
dei bottoni della finestra di dialogo
Toolkit per la progettazione di interfacce grafiche
(GUI Designer)
Programma interattivo che permette la progettazione di interfacce grafiche
basate su un dato toolkit.
Esempi:
- si possono creare finestre, bottoni, slider, menu'
istanziando degli schemi predefiniti
- si puo' associare direttamente alla pressione di un tasto
in un menu' l'attivazione di sottomenu', finestre di dialogo...
Il GUI Designer produce il codice relativo all'interfaccia.
Il programmatore deve solo riempire il corpo delle procedure
callback che corrispondono alle azioni dei widget istanziati.