Hlavní navigace

GLUT (4): události

20. 5. 2003
Doba čtení: 5 minut

Sdílet

V dnešním dílu seriálu o knihovně GLUT si ukážeme, jakým způsobem se zpracovávají události (zprávy) došlé od operačního systému a od uživatele. Dále si předvedeme postup při obsluze základního vstupního zařízení, tedy klávesnice.

Zpracování zpráv a obsluha klávesnice

V klasických aplikacích, které jsou orientovány spíše na textové uživatelské rozhraní (Text User Interface – TUI) a příkazovou řádku, se pro komunikaci s uživatelem používá jednoduchý systém typu dotaz-odpověď. Pokud potřebuje programátor získat nějaké informace od uživatele aplikace, zavolá funkci pro vstup dat (například gets() nebo scanf()) a teprve po jejich zadání program pokračuje dále.

V operačních systémech s grafickým uživatelským rozhraním (Graphical User Interface – GUI) se používá dosti odlišný způsob ovládání aplikací. Uživatel má mnohem větší možnosti, jak aplikaci ovládat. Místo systému typu dotaz-odpověď, který je vhodný u příkazové řádky, se používají okna s mnoha ovládacími prvky – menu, tlačítka, rozbalovací nabídky, editační boxy apod. Při práci s prvky grafického uživatelského rozhraní vznikají takzvané události (events), na něž programátor aplikace musí umět reagovat. V tom mu pomáhá operační systém, jehož část starající se o GUI při vzniku události (například stisknutí tlačítka myši) většinou generuje pro aplikaci takzvanou zprávu. Zpráva je datová struktura, která jednoznačně identifikuje zdroj události a obsahuje i další důležité informace, například kód stisknuté klávesy či pozici kurzoru myši. Aplikace tyto zprávy vybírá z takzvané fronty událostí (event queue) či fronty zpráv (message queue) a postupně na ně reaguje.

Naprogramování vlastní smyčky, která reaguje na zprávy došlé od systému, je poměrně pracné a vyžaduje značné znalosti daného operačního systému. Aplikace, která používá takovouto smyčku zpráv, je nepřenositelná na jinou platformu. Proto knihovna GLUT disponuje vlastním systémem pro zpracovávání událostí (zpráv), které přijdou od operačního systému. Uvnitř knihovny GLUT je naprogramována smyčka zpráv určená pro právě používaný operační systém, ale tato smyčka je pro programátora aplikace neviditelná. Pro zpracovávání událostí se používají takzvané callback funkce, což jsou uživatelem nadefinované funkce zavolané až v době výskytu události (tedy asynchronně k běhu programu). Jednotlivé callback funkce musí být předem zaregistrovány a poté jsou volány až po spuštění funkce glutMainLoop().

Reakce na stisk kláves

Mezi základní požadavky při ovládání grafických aplikací stále patří reakce na stisk kláves. Ukazuje se, že pro některé operace je použití klávesnice nejrychlejší a nejpřesnější možností. V knihovně GLUT je možné zaregistrovat dva typy reakcí na stisk kláves – reakce na stisk klávesy, která generuje ASCII hodnotu, a reakce na stisk takzvaných speciálních kláves, mezi něž patří například funkční klávesy a klávesy určené pro ovládání kurzoru (šipky, PageUp, PageDown, Home a End). V novějších verzích knihovny GLUT se objevují i další typy událostí – událost generovaná při stisku klávesy a další událost generovaná při puštění klávesy – které se používají při programování interaktivních programů. Všechny zmíněné typy událostí jsou generovány pro každé okno zvlášť – je tedy možné mít pro každé okno zaregistrovánu jinou callback funkci pro obsluhu kláves.

Pro registraci callback funkce reagující na stisk klávesy generující ASCII kód se používá funkce glutKeyboardFun­c(void (*func)(unsigned char key, int x, int y)). Programátorem vytvořená callback funkce musí mít tři parametry. První parametr key je typu unsigned char a je do něj uložen ASCII kód stisknuté klávesy. Další dva parametry x,y jsou typu int a je do nich uložena pozice kurzoru myši v době vzniku události. Pozice kurzoru myši je reprezentována relativně k oknu, ve kterém událost vznikla. Levý horní roh uživatelské části okna má pozici 0, 0. Je důležité si uvědomit, že ASCII kód generují kromě alfanumerických kláves i klávesy mezerník, Enter, BackSpace a Escape. Také písmenné klávesy stlačené spolu s modifikátorem CTRL (Control) generují ASCII kód (kód klávesy zmenšený o hodnotu 32), a proto jsou touto callback funkcí také zpracovány. Problémy mohou nastat s klávesou Delete, která by měla generovat ASCII kód 127. V některých starších verzích knihovny GLUT však tento kód nikdy nebyl generován a klávesu Delete tedy nešlo v programech použít.

Druhý typ callback funkce reaguje na stisk klávesy, jež negeneruje ASCII hodnotu. Příklady takových kláves jsou uvedeny v tabulce níže. Pro registraci se používá funkce glutSpecialFun­c(void (*func)(int key, int x, int y)). Programátorem vytvořená callback funkce musí mít tři parametry. První parametr key je typu int a představuje kód stisknuté klávesy. Další dva parametry x a y mají stejný význam jako u funkceglutKe­yboardFunc().

Aby byla zajištěna platformová nezávislost, jsou kódy stisknutých kláves definovány jako symbolické konstanty v hlavičkovém souboru glut.h. Některé často používané konstanty ukazuje následující tabulka:

Tabulka č. 430
symbolická konstanta význam
GLUT_KEY_F1 funkční klávesa F1
GLUT_KEY_F2 funkční klávesa F2
GLUT_KEY_F3 funkční klávesa F3
GLUT_KEY_F4 funkční klávesa F4
GLUT_KEY_F5 funkční klávesa F5
GLUT_KEY_F6 funkční klávesa F6
GLUT_KEY_F7 funkční klávesa F7
GLUT_KEY_F8 funkční klávesa F8
GLUT_KEY_F9 funkční klávesa F9
GLUT_KEY_F10 funkční klávesa F10
GLUT_KEY_F11 funkční klávesa F11
GLUT_KEY_F12 funkční klávesa F12
GLUT_KEY_LEFT kurzorová klávesa šipka doleva
GLUT_KEY_RIGHT kurzorová klávesa šipka doprava
GLUT_KEY_UP kurzorová klávesa šipka nahoru
GLUT_KEY_DOWN kurzorová klávesa šipka dolů
GLUT_KEY_PAGE_UP kurzorová klávesa pro skok o stránku nahoru
GLUT_KEY_PAGE_DOWN kurzorová klávesa pro skok o stránku dolů
GLUT_KEY_HOME kurzorová klávesa pro skok na začátek řádku
GLUT_KEY_END kurzorová klávesa pro skok na konec řádku
GLUT_KEY_INSERT klávesa Insert (většinou řídí přepnutí Insert a Overwrite režimu)

Ukázkový příklad číslo 5

Tento příklad demonstruje použití callback funkce pro zpracování události, jež vznikne při stisknutí klávesy generující ASCII hodnotu. Po stisku je vypsán znak i odpovídající ASCII kód klávesy do titulkového pruhu okna. Všimněte si, že v rámci aplikace využívající GLUT nelze od sebe rozeznat některé kódy různých kláves – například CTRL+H a BackSpace nebo CTRL+M a Enter generují stejné ASCII kódy. K dispozici je zdrojový kód pátého příkladu a zdrojový kód se zvýrazněnou syntaxí.

ukázka programu číslo 5

Ukázkový příklad číslo 6

Tento příklad demonstruje použití callback funkce pro zpracování události, jež vznikne při stisknutí klávesy, která negeneruje ASCII hodnotu. Po stisku je do titulkového pruhu okna vypsán řetězec, který popisuje účel klávesy. Všimněte si skutečnosti, že kódy speciálních kláves jsou uspořádány vzestupně za sebou, takže pro výpis řetězce je možné použít přímé indexace pole. K dispozici je zdrojový kód šestého příkladu a zdrojový kód se zvýrazněnou syntaxí.

Cloud 24 - tip 1

ukázka programu číslo 6

V příštím pokračování si ukážeme ovládání dalšího důležitého vstupního zařízení – myši.

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.