VYSOK ´
E U ˇ
CEN´I TECHNICK ´
E V BRN ˇ
E
BRNO UNIVERSITY OF TECHNOLOGYFAKULTA INFORMA ˇ
CN´ICH TECHNOLOGI´I
´
USTAV PO ˇ
C´ITA ˇ
COV ´
E GRAFIKY A MULTIM ´
EDI´I
FACULTY OF INFORMATION TECHNOLOGYDEPARTMENT OF COMPUTER GRAPHICS AND MULTIMEDIA
MOST MEZI GLUT A KNIHOVNOU PRO TVORBU
U ˇ
ZIVATELSK ´
YCH ROZHRAN´I
BRIDGE BETWEEN GLUT AND GRAPHICAL USER INTERFACE LIBRARY
DIPLOMOV ´
A PR ´
ACE
MASTER’S THESIS
AUTOR PR ´
ACE
Bc. JAN FRIESSE
AUTHOR
VEDOUC´I PR ´
ACE
Ing. MICHAL VYSKO ˇ
CIL
SUPERVISOR
Abstrakt
Tato pr´ace se zab´yv´a problematikou tvorby grafick´ych 3D aplikac´ı s pouˇzit´ım knihovny OpenGL. Jsou zde vysvˇetleny z´aklady architektury knihovny GLUT, jej´ı hlavn´ı v´yhody a nev´yhody a pops´any alternativn´ı implementace GLUT API. D´ale je zde popis nejzn´amˇejˇs´ıch grafick´ych knihoven pro tvorbu uˇzivatelsk´eho rozhran´ı, ve kter´ych je moˇzn´e tvoˇrit aplikace vyuˇz´ıvaj´ıc´ı OpenGL spolu s jejich hlavn´ımi v´yhodami a nev´yhodami. N´asleduje n´avrh ar-chitektury nov´e implementace knihovny GLUT s pouˇzit´ım vybran´e knihovny pro tvorbu uˇzivatelsk´ych rozhran´ı. Nejd˚uleˇzitˇejˇs´ı ˇc´ast pr´ace se zab´yv´a popisem vlastn´ı implementace, kter´a se nach´az´ı na pˇriloˇzen´em CD. Nakonec jsou pops´any moˇznosti dalˇs´ıho v´yvoje imple-mentovan´e knihovny.
Kl´ıˇ
cov´
a slova
OpenGL, GLUT, GTK+, GtkGLArea, GtkGLExt, Motif, QT, Fox Toolkit, FLTK, LessTif, wxWidgets, FreeGLUT, OpenGLUT, GtkGLUT
Abstract
This document describes a major problems with creating 3D applications in a graphic library named OpenGL. There are some basic informations about a GLUT library including main advantages and disadvantages and a description of alternative implementations of a GLUT API. Further content is focused on the most familiar graphic libraries for creating user interfaces which should be used to develop the OpenGL applications and with their advantages and disadvanteges too. The next part describes a draft of a new GLUT API implementation based on the selected user interface library. Major part of thesis is about implementation of GtkGLUT library. Reader can find this implementation on CD. Last part describes future development plans.
Keywords
OpenGL, GLUT, GTK+, GtkGLArea, GtkGLExt, Motif, QT, Fox Toolkit, FLTK, LessTif, wxWidgets, FreeGLUT, OpenGLUT, GtkGLUT
Citace
Jan Friesse: Most mezi GLUT a knihovnou pro tvorbu uˇzivatelsk´ych rozhran´ı, diplomov´a pr´ace, Brno, FIT VUT v Brnˇe, 2008
Most mezi GLUT a knihovnou pro tvorbu uˇ
zivatelsk´
ych
rozhran´ı
Prohl´
aˇ
sen´ı
Prohlaˇsuji, ˇze jsem tuto bakal´aˇrskou pr´aci vypracoval samostatnˇe pod veden´ım pana Ing. Michala Vyskoˇcila
. . . . Jan Friesse 6. kvˇetna 2008
c
Jan Friesse, 2008.
Tato pr´ace vznikla jako ˇskoln´ı d´ılo na Vysok´em uˇcen´ı technick´em v Brnˇe, Fakultˇe in-formaˇcn´ıch technologi´ı. Pr´ace je chr´anˇena autorsk´ym z´akonem a jej´ı uˇzit´ı bez udˇelen´ı opr´avnˇen´ı autorem je nez´akonn´e, s v´yjimkou z´akonem definovan´ych pˇr´ıpad˚u.
Obsah
1 Uvod´ 2
2 GLUT 3
3 Knihovny pro v´yvoj uˇzivatelsk´ych rozhran´ı 5
3.1 GTK+ . . . 5
3.1.1 Rozˇs´ıˇren´ı GtkGLArea . . . 6
3.1.2 Rozˇs´ıˇren´ı GtkGLExt . . . 6
3.2 QT . . . 7
3.3 FLTK . . . 8
3.4 FOX Toolkit . . . 8
3.5 Motif. . . 9
3.6 wxWidgets . . . 10
4 N´avrh ˇreˇsen´ı 12 5 Implementace 15 5.1 Pouˇzit´e konvence a datov´e struktury knihovny . . . 15
5.2 Inicializaˇcn´ı funkce . . . 19
5.3 Funkce pro spr´avu oken . . . 21
5.4 Funkce pro spr´avu menu . . . 23
5.5 Funkce pro registraci a obsluhu ud´alost´ı . . . 25
5.6 Funkce pro vykreslen´ı textu . . . 28
5.7 Neimplementovan´e funkce . . . 28
5.8 Kompatibilita . . . 29
5.9 Uspoˇr´ad´an´ı a sestaven´ı knihovny . . . 30
6 Budouc´ı v´yvoj 32
7 Z´avˇer 34
Kapitola 1
´
Uvod
Je tomu jiˇz 27 let od roku 1981, kdy se na poˇc´ıtaˇc´ıch tˇr´ıdy PC objevila prvn´ı grafick´a karta standardu CGA. Jednalo se o jednoduchou kartu s n´ızk´ym rozliˇsen´ım, kter´a byla ˇr´ızena procesorem. Tento koncept nebyl vhodn´y a proto se o tˇri roky pozdˇeji objevily karty se standardem VGA, kter´e jiˇz obsahovaly akceleraˇcn´ı funkce pˇr´ımo na kartˇe (samoˇcinn´e vykreslen´ı ´useˇcky, obdeln´ıka a operaci pˇresunu bitmapy). V jin´em segmentu trhu existovaly pracovn´ı stanice, kter´e nejenˇze umˇely 2D, ale tak´e 3D grafiku. Postupem ˇcasu PC svou n´ızkou cenou a dostateˇcn´ym v´ykonem pracovn´ı stanice vytlaˇcilo. Proto se zaˇcaly zhruba kolem roku 1998 na PC objevovat prvn´ı ´uspˇeˇsnˇejˇs´ı 3D akceler´atory, jako napˇr´ıklad S3 Savage3D, NVidia Riva TNT, ATI RAGE 128, . . .
K tomu, aby bylo moˇzn´e programovat 3D grafick´e aplikace nez´avisle na pouˇzit´e grafick´e kartˇe, zaˇcaly vznikat standardn´ı rozhran´ı. Z roku 1980 poch´az´ı prvn´ı a jedin´y ofici´aln´ı standard jm´enem PHIGS. Byl zaloˇzen na kompletn´ım popisu sc´eny (tzv. retained mode) a dnes se jiˇz nepouˇz´ıv´a. Mnohem zaj´ımavˇejˇs´ı je sledovat v´yvoj standardu OpenGL. Ten poch´az´ı z roku 1990 a vytvoˇrila jej firma SGI pro operaˇcn´ı syst´em IRIX, kter´y byl pouˇz´ıv´an jejich pracovn´ımi stanicemi. Od standardu PHIGS se liˇsil hlavnˇe t´ım, ˇze stavˇel na popisu jednotliv´ych objekt˚u (tzv. immediate mode). OpenGL tvoˇr´ı velice ´uspˇeˇsnou platformu pro v´yvoj profesion´aln´ıch aplikac´ı typu CAD syst´emy, ale je pouˇz´ıv´ano tak´e v´yvoj´aˇri her.
Firma SGI kromˇe samotn´eho OpenGL vytvoˇrila tak´e knihovnu GLUT (The OpenGL Utility Toolkit), kter´a slouˇz´ı pro zajiˇstˇen´ı platformovˇe nez´avisl´e inicializace OpenGL a interakc´ı s uˇzivatelem. Knihovna GLUT se d´ıky sv´emu jednoduch´emu rozhran´ı, kter´e je modelov´ano dle rozhran´ı OpenGL stala velice obl´ıben´a, hlavnˇe pro jednoduˇsˇs´ı aplikace.
Pr´avˇe knihovna GLUT je ´ustˇredn´ım t´ematem t´eto pr´ace. C´ılem je implementovat kni-hovnu GLUT v nˇekter´e ze standardn´ıch knihoven pro tvorbu uˇzivatelsk´ych rozhran´ı.
Kapitola 2 na stranˇe 3 je vˇenov´ana popisu knihovny GLUT, jej´ıch hlavn´ıch v´yhod a nev´yhod. D´ale jsou zde rozebr´any r˚uzn´e implementace t´eto knihovny.
Kapitola3na stranˇe5pojedn´av´a o r˚uzn´ych grafick´ych knihovn´ach a jejich vlastnostech se zvl´aˇstn´ım pˇrihl´ednut´ım na podporu OpenGL.
V kapitole 4 na stranˇe 12 je pops´ana problematika integrace k´odu napsan´eho pomoc´ı knihovny GLUT do projektu, pouˇz´ıvaj´ıc´ıho vybranou knihovnu pro tvorbu uˇzivatelsk´ych rozhran´ı. Pr´avˇe zde je tak´e uvedeno, kter´a knihovna je pouˇzita pro reimplementaci knihovny GLUT a jak´e z toho plynou v´yhody a nev´yhody.
Pˇredchoz´ı kapitoly slouˇz´ı jako ´uvod do problematiky a byly zpracov´any v r´amci Semestr-´
aln´ıho projektu. Implementace knihovny byla vytvoˇrena v r´amci Diplomov´eho projektu a jej´ı zevrubn´y popis se nach´az´ı v kapitole 5na stranˇe15.
Kapitola 2
GLUT
Jak jiˇz bylo zm´ınˇeno v ´uvodu je GLUT (The OpenGL Utility Toolkit), knihovna pro tvorbu pˇrenositeln´ych OpenGL aplikac´ı. Samo OpenGL poskytuje velice dobrou multiplatformn´ı pˇrenositelnost, avˇsak neˇreˇs´ı podporu vstupu a v´ystupu. Na program´atorovy aplikace tedy z˚ust´avaj´ı vˇeci jako napˇr´ıklad vytvoˇren´ı okna, podpora kl´avesnice a podpora myˇsi, kde vˇsak neexistovala moˇznost vytvoˇrit aplikaci opravdu multiplatformnˇe. Proto vznikl GLUT, kter´y kromˇe dˇr´ıve popsan´ych vˇec´ı pˇrid´av´a i nˇekter´e nov´e, mezi kter´e patˇr´ı vytvoˇren´ı modelu kostky, koule, nebo slavn´e ˇcajov´e konvice 2.1, kter´a je pouˇz´ıv´ana takˇrka v kaˇzd´e demon-straˇcn´ı OpenGL aplikaci a stala se jeho symbolem. Nav´ıc je k dispozici i tvorba velice jednoduch´ych menu.
Mezi hlavn´ı v´yhody GLUTu patˇr´ı:
• Multiplatformnost. To pˇrin´aˇs´ı hlavn´ı v´yhodu v podobˇe jednoduch´e portovatelnosti na jinou softwarovou a hardwarovou platformu a do velk´e m´ıry tak´e dlouhou ˇzivotnost programu.
• Jednoduch´e API, kter´e je modelov´ano podobnˇe jako OpenGL, pˇriˇcemˇz za prefix je zvoleno glut.
• Relativnˇe vysok´a ´uroveˇn API. Pro vytvoˇren´ı prvn´ıho programu nen´ı tˇreba napsat 100 ˇr´adk˚u, jako v pˇr´ıpadˇe WinAPI, nebo X-lib. Staˇc´ı nˇekolik m´alo ˇr´adk˚u.
• Je pouˇz´ıv´ano na FIT.
• Staˇc´ı pouze standardn´ı C. T´ım je zajiˇstˇena velice snadn´a tvorba knihoven pro jin´e jazyky, kter´e GLUT pouˇz´ıvaj´ı.
Ovˇsem jako kaˇzd´a vˇec m´a i GLUT svoje stinn´e str´anky, napˇr´ıklad: • Jiˇz neprob´ıh´a aktivn´ı v´yvoj.
• Licence GLUTu je relativnˇe restriktivn´ı a nedovoluje distribuovat modifikovanou verzi knihovny.
• Pokud program zavol´a funkci glutMainLoop, neexistuje ˇz´adn´a moˇznost, jak se z t´eto funkce dostat zpˇet.
• Neexistuje ˇz´adn´y callback, kter´y by byl zavol´an, pokud je ukonˇcena aplikace. To by bylo vhodn´e zejm´ena pro vyˇciˇstˇen´ı pamˇeti, zavˇren´ı soubor˚u, . . .
• Neexistence podpory pro nˇekter´e novˇejˇs´ı hardware vymoˇzenosti (napˇr´ıklad koleˇcko myˇsi).
• Neabstrahuje nˇekter´e vˇeci, kter´e by mohli b´yt potencion´alnˇe pˇr´ınosn´e pro program´atory (napˇr´ıklad vl´akna).
• Pod Windows pouˇz´ıv´a pro kreslen´ı menu nativn´ı menu WinAPI, avˇsak pod X kresl´ı pˇr´ımo do OpenGL plochy, coˇz m˚uˇze zp˚usobovat probl´emy.
Protoˇze vˇsak existuje relativnˇe poˇcetn´a skupina lid´ı, kteˇr´ı GLUT pouˇz´ıvaj´ı, vznikly svo-bodn´e implementace GLUTu, kter´e se snaˇz´ı nˇekter´e chyby p˚uvodn´ı verze odstranit. Mezi nejzn´amˇejˇs´ı patˇr´ı FreeGLUT a OpenGLUT.
FreeGLUT se snaˇz´ı o co nejlepˇs´ı kompatibilitu s p˚uvodn´ım GLUTem, avˇsak pˇrid´av´a nˇekter´e nov´e vˇeci. Mezi nejd˚uleˇzitˇejˇs´ı patˇr´ı:
• Funkce glutMainLoopEvent provede jednu iteraci zpracov´an´ı zpr´av. T´ım je moˇzn´e vytvoˇrit smyˇcku zpr´av zcela ve vlastn´ı reˇzii.
• Funkce glutLeaveMainLoop umoˇzˇnuje opustit funkci glutMainLoop.
• Pˇrid´ana moˇznost urˇcit akci, kter´a bude provedena pˇri zavˇren´ı okna GLUT aplikace (obvykle kliknut´ım na tlaˇc´ıtko x).
• Pˇrid´ano mnoho nov´ych callback˚u, napˇr´ıklad zpr´ava o uvolnˇen´ı kl´avesy, callback urˇcuj´ıc´ı stav menu,. . .
• Moˇznost vyrendrovat cel´y ˇretˇezec, m´ısto nutnosti renderovat cel´y text po p´ısmenech ve vlastn´ı reˇzii.
OpenGLUT je odvozen z FreeGLUTu a pˇrid´av´a nˇekter´e experiment´aln´ı nov´e funkce do API.
Kapitola 3
Knihovny pro v´
yvoj uˇ
zivatelsk´
ych
rozhran´ı
V t´eto kapitole se nach´az´ı porovn´an´ı nˇekolika nejzn´amˇejˇs´ıch grafick´ych knihoven pro tvorbu uˇzivatelsk´ych rozhran´ı. Jsou pops´any jednotliv´e v´yhody a nev´yhody a zvl´aˇstn´ı pozornost je vˇenov´ana jejich schopnosti pracovat s OpenGL. Mezi v´yznamn´a krit´eria patˇr´ı i uˇzivatelsk´a z´akladna. Pokud je knihovna hodnˇe pouˇz´ıvan´a, je takˇrka jistˇe zaruˇcen dostatek dokumen-tace i r˚uzn´ych uˇzivatelsk´ych f´or, kam je moˇzn´e se v pˇr´ıpadˇe probl´em˚u obr´atit, a kde je z´aroveˇn jiˇz mnoho probl´em˚u vyˇreˇseno. Dalˇs´ım krit´eriem je i implementaˇcn´ı jazyk. Protoˇze c´ılem pr´ace je udrˇzet co moˇzn´a nejlepˇs´ı kompatibilitu se st´avaj´ıc´ımi OpenGL aplikacemi, bylo by l´epe vybrat knihovnu, kter´a m´a sv´e API prim´arnˇe navrˇzeno pro ANSI C. Pokud by vˇsak ˇz´adn´a takov´a vhodn´a neexistovala, bylo by nutn´e z tohoto poˇzadavku slevit. Protoˇze by byla vhodn´a ˇsirok´a podpora r˚uzn´ych platforem, mˇela by i samotn´a knihovna b´yt pokud moˇzno co nejv´ıce multiplatformn´ı.
3.1
GTK+
GTK+ (The GIMP Toolkit) dostupn´y na http://www.gtk.org/ byl vytvoˇren (jak jiˇz n´azev napov´ıd´a) kv˚uli grafick´emu editoru GIMP (GNU Image Manipulation Program) v roce 1997. GTK+ bylo vytvoˇreno a prim´arnˇe je st´ale urˇceno pro syst´emy s X Windows (dnes zejm´ena Linux), avˇsak existuje i port pro operaˇcn´ı syst´em Windows a Mac OS X. Prvn´ı verze se snaˇzila odstranit nev´yhody knihovny Motif (v t´eto knihovnˇe byly tak´e naps´any prvn´ı verze programu GIMP), ale API bylo modelov´ano velice podobnˇe. S druhou verz´ı GTK+ se API podstatnˇe zmˇenilo coˇz znamenalo pˇrepis mnoha aplikac´ı, ale od t´e doby (2002) je zpˇetnˇe kompatibiln´ı.
Mezi hlavn´ı vlastnosti GTK+ patˇr´ı:
• Komunitn´ı projekt, kter´y je vˇsak podporov´an mnoha velk´ymi firmami (IBM, Red Hat, Sun, Novell, . . . ).
• Velice rozˇs´ıˇren´a a pouˇz´ıvan´a knihovna. Nejen ˇze je na n´ı postaven GIMP, ale tak´e dvˇe ze tˇr´ı nejobl´ıbenˇejˇs´ıch pracovn´ıch prostˇred´ı OS Linux (Gnome, XFCE), vektorov´y grafick´y editor Inkscape, a mnoho dalˇs´ıch program˚u.
• Svobodn´a licence GNU LGPL, kter´a umoˇzˇnuje stavˇet na t´eto knihovnˇe i komerˇcn´ı aplikace, avˇsak z´aroveˇn zaruˇcuje n´avrat pˇr´ıpadn´ych vylepˇsen´ı zpˇet do knihovny .
• V´yborn´a podpora ˇceˇstiny a jin´ych svˇetov´ych jazyk˚u. GTK+ 2.0 je kompletnˇe postaveno na UTF-8.
• Implementaˇcn´ım jazykem je C.
• Existuje mnoˇzstv´ı binding˚u do jin´ych jazyk˚u, mezi nejv´yznamnˇejˇs´ımi jsou C++ (gtkmm, wxWidgets), Java (java-gnome, nebo SWT), Perl (gtk2-perl),
Python (PyGTK), . . .
Bohuˇzel vˇsak ve standardn´ım GTK+ neexistuje ˇz´adn´a podpora pro OpenGL aplikace. Tento probl´em ovˇsem ˇreˇs´ı rozˇs´ıˇren´ı GtkGLArea a GtkGLExt, kter´a budou pops´ana v podkapi-tol´ach 3.1.2na stranˇe 6a 3.1.1na stranˇe 6.
Pro bliˇzˇs´ı popis knihovny GTK+ viz [5].
3.1.1 Rozˇs´ıˇren´ı GtkGLArea
Toto rozˇs´ıˇren´ı vzniklo v roce 1998. V dneˇsn´ı dobˇe jiˇz nen´ı p˚uvodn´ım autorem vyv´ıjeno (dokonce jiˇz neexistuje ani ofici´aln´ı str´anka, avˇsak bal´ıˇcek je st´alo moˇzn´e naj´ıt napˇr´ıklad na adrese http://www.mono-project.com/GtkGLArea) Protoˇze jej vˇsak pouˇz´ıv´a relativnˇe hodnˇe projekt˚u a je k dispozici v repozit´aˇr´ıch vˇetˇsiny Linuxov´ych distribuc´ı, je dobr´e se o nˇem zm´ınit.
Hlavn´ı vlastnosti:
• Relativnˇe mal´a knihovna (kompletn´ı zdrojov´y k´od ˜ 30KB).
• Licence GNU GPL , kter´a je sice svobodn´a, ale pro komerˇcn´ı v´yvoj aplikac´ı nevhodn´a. • Multiplatformn´ı, funkˇcn´ı v OS Linux a Windows.
• Implementaˇcn´ım jazykem je C.
• Existuj´ı bindingy do jin´ych jazyk˚u, jako napˇr´ıklad C++ a Mono C#.
3.1.2 Rozˇs´ıˇren´ı GtkGLExt
Toto rozˇs´ıˇren´ı je novˇejˇs´ı neˇz GtkGLArea (2003). Je moˇzn´e jej z´ıskat z domovsk´e str´anky na adrese http://www.k-3d.org/gtkglext/Main Page. Narozd´ıl od pˇredchoz´ıho rozˇs´ıˇren´ı je toto aktivnˇe vyv´ıjeno. M´a ponˇekud jinou filosofii neˇz GtkGLArea, kter´e d´avalo v´yvoj´aˇri jednu komponentu, kter´a slouˇzila pro vykreslov´an´ı OpenGL. U t´eto knihovny je moˇzn´e udˇelat z jak´ekoli komponenty plochu pro zobrazov´an´ı OpenGL (takˇze vytvoˇren´ı tlaˇc´ıtka s animuj´ıc´ı se konvic´ı nen´ı probl´em).
Mezi hlavn´ı vlastnosti patˇr´ı:
• Podstatnˇe vˇetˇs´ı knihovna neˇz pˇredchoz´ı.
• Licence GNU LGPL , takˇze m´a stejn´e v´yhody jako GTK+.
• Multiplatformn´ı, funkˇcn´ı v OS Linux, FreeBSD, IRIX, Mac OS X a Windows. • Implementaˇcn´ım jazykem je C.
• Existuj´ı bindingy do jin´ych jazyk˚u, jako napˇr´ıklad C++, Python, Ruby, Perl, Scheme (Gauche Scheme), coˇz jsou jazyky (na rozd´ıl od C#, pro kter´y binding k dispozici nen´ı) v Linuxov´e a Mac OS X komunitˇe velice obl´ıben´e.
3.2
QT
Knihovnu je moˇzn´e nal´ezt na str´ance http://trolltech.com/products/qt. Prvn´ı verze t´eto knihovny spatˇrila svˇetlo svˇeta v roce 1991. O tˇri roky pozdˇeji zaloˇzili hlavn´ı v´yvoj´aˇri t´eto knihovny firmu Trolltech, kter´a pokraˇcuje ve v´yvoji dodnes. Prvn´ı verze byly dis-tribuov´any pod licenc´ı FreeQt, kter´a mnoha v´yvoj´aˇr˚um svobodn´eho software nepˇripadala dostateˇcnˇe liber´aln´ı, proto tak´e doˇslo k odchodu nˇekter´ych v´yvoj´aˇr˚u a zaloˇzen´ı vlastn´ıho projektu GTK+. Na t´eto knihovnˇe je zaloˇzeno mnoho projekt˚u, ovˇsem mezi nejv´yznamnˇejˇs´ı patˇr´ı uˇzivatelsk´e prostˇred´ı KDE, kter´e patˇr´ı k jednomu ze tˇr´ı nejpouˇz´ıvanˇejˇs´ıch v OS Linux. OpenGL je moˇzn´e pouˇz´ıvat velice snadno, a to odvozen´ım nov´e tˇr´ıdy ze tˇr´ıdy QGLWidget, a pˇredefinov´an´ım metod initializeGL, resizeGL, . . .
Hlavn´ı vlastnosti knihovny:
• Je vyv´ıjeno komerˇcn´ı firmou. To sebou nese mnoh´e v´yhody, jako napˇr´ıklad dostupnost komerˇcn´ı podpory, ale tak´e nˇekter´e nev´yhody.
• Velmi kvalitnˇe zpracovan´a dokumentace.
• ˇSirok´a komunita v´yvoj´aˇr˚u, dostupnost mnoha f´or. • V´yborn´a podpora OpenGL.
• V´yborn´a podpora ˇceˇstiny, je podporov´ano mnoˇzstv´ı k´odov´ych str´anek vˇcetnˇe UTF-8. • Velice rozˇs´ıˇren´a knihovna, nejen mezi komerˇcn´ımi v´yvoj´aˇri (Opera, Skype, Adobe Photoshop Album,. . . ), ale tak´e v´yvoj´aˇri otevˇren´eho software (KDE a vˇsechny pro-gramy v nˇem obsaˇzen´e, coˇz d´av´a k dispozici obrovsk´e mnoˇzstv´ı studijn´ıho materi´alu). • Implementaˇcn´ım jazykem je C++, avˇsak je tˇreba pouˇz´ıvat moc (Meta object com-piler), kter´y implementuje mechanizmus sign´al˚u/slot˚u, introspekc´ı a jin´ych vlastnost´ı kter´e ve standardn´ım C++ nejsou. To vˇsak ˇcin´ı v´yvoj knihoven na QT postaven´ych znaˇcnˇe sloˇzitˇejˇs´ı a prakticky znemoˇzˇnuje pouˇzit´ı ˇcist´eho C++.
• Knihovna m´a du´aln´ı zp˚usob licencov´an´ı. Pro komerˇcn´ı v´yvoj je nutn´e si knihovnu koupit, pro v´yvoj otevˇren´eho software existuje verze ˇs´ıˇren´a pod GPL, pˇresto je vˇsak nˇekter´ymi v´yvoj´aˇri otevˇren´eho software odm´ıt´ana.
• Knihovna je multiplatformn´ı. Existuje verze pro X Windows Syst´em (dnes pˇrev´aˇznˇe OS Linux a Solaris), MS Windows, Mac OS X.
• Doned´avna neexistovala svobodn´a implementace pro MS Windows. Ve verzi 4 vˇsak byla svobodn´a verze vypuˇstˇena i pro tuto platformu.
• Knihovna proˇz´ıv´a moˇzn´a aˇz pˇr´ıliˇs pˇrekotn´y v´yvoj. Kaˇzd´e vyd´an´ı nov´e verze (do dneˇsn´ıho dne 4 hlavn´ı verze) znamen´a radik´aln´ı zmˇeny v API, kter´e nut´ı v´yvoj´aˇre pˇrepisovat aplikace. Na zpˇetnou kompatibilitu se takˇrka v˚ubec nehled´ı.
• Existuje mnoˇzstv´ı binding˚u pro jin´e jazyky, napˇr´ıklad Python (PyQT), C# (QT#), PHP (PHP-Qt), Ruby (RubyQT), . . .
3.3
FLTK
FLTK (Fast Light Toolkit) je moˇzn´e z´ıskat z adresy http://www.fltk.org/. Hlavn´ım c´ılem v´yvoj´aˇr˚u bylo vytvoˇrit malou, jednoduˇse pouˇzitelnou knihovnu pro v´yvoj grafick´ych uˇzivatelsk´ych rozhran´ı, zejm´ena s podporou 3D, kter´a bude co nejrychlejˇs´ı. Zaj´ımav´e na nˇem je, ˇze obsahuje vlastn´ı implementaci emulace knihovny GLUT.
Mezi hlavn´ı vlastnosti patˇr´ı:
• Knihovna je ps´ana v jazyce C++, avˇsak nepouˇz´ıv´a ˇsablony a v´yjimky. To do jist´e m´ıry zjednoduˇsuje v´yvoj pˇr´ıpadn´ych n´astaveb.
• API knihovny je kompaktn´ı a srozumitelnˇe navrˇzen´e.
• Knihovna sama o sobˇe je velice mal´a (zabalen´y zdrojov´y k´od je jen o ˜ 200KB vˇetˇs´ı neˇz GtkGLExt, staticky slinkovan´a aplikace typu Hello World, m´a asi 100KB). • Knihovna je multiplatformn´ı. Existuje verze pro X Windows Syst´em (dnes pˇrev´aˇznˇe
OS Linux a Solaris) a MS Windows.
• Dobr´a podpora OpenGL. Je moˇzn´e pouˇz´ıt bud’ emulaci knihovny GLUT, nebo vytvoˇrit odvozenou tˇr´ıdu ze tˇr´ıdy Fl Gl Window, kde se pot´e pˇredefinuje metoda draw, slouˇz´ıc´ı pro vykreslen´ı obsahu. Zde je jiˇz moˇzn´e pouˇz´ıt standardn´ı OpenGL funkce.
• Knihovna je ˇs´ıˇrena pod GNU LGPL licenc´ı s v´yjimkou, kter´a umoˇzˇnuje statick´e linkov´an´ı knihovny k aplikaci. Je tedy vhodn´a i pro komerˇcn´ı v´yvoj.
• Relativnˇe nedostateˇcn´a, roztˇr´ıˇstˇen´a dokumentace. Jako nejlepˇs´ı zdroj informac´ı poslouˇz´ı samotn´e zdrojov´e k´ody, jej´ıchˇz studov´an´ı je mnohem snadnˇejˇs´ı, neˇz u jin´ych knihoven. • Ve standardn´ı knihovnˇe neexistuje podpora pro UTF-8. Existuje sice neofici´aln´ı verze, kter´a tento probl´em ˇreˇs´ı, nebo je tak´e moˇzn´e pouˇz´ıt v´yvojovou verzi FLTK 2, nicm´enˇe pokud je poˇzadov´ana ofici´aln´ı stabiln´ı verze, nen´ı moˇzn´e je pouˇz´ıt.
• Nefunguje zad´av´an´ı ˇcesk´ych znak˚u (znak˚u zad´avan´e pˇres mrtvou kl´avesu) v syst´emech s X Windows. Tento probl´em ˇreˇs´ı v´yvojov´a verze FLTK 2.
• M´alo aktivn´ıch v´yvoj´aˇr˚u. Po vyd´an´ı prvn´ı verze opadlo prvotn´ı nadˇsen´ı a nyn´ı vyv´ıjen´a verze FLTK 2 je dlouhodobˇe nedokonˇcena a nic nenasvˇedˇcuje tomu, ˇze by se tato nepˇr´ıjemn´a situace mˇela v brzk´e dobˇe zmˇenit. FLTK 2 se nav´ıc vyznaˇcuje znaˇcn´ym mnoˇzstv´ım chyb, proto je nepouˇziteln´a tam, kde je poˇzadov´ana stabilita.
• Menˇs´ı komunita uˇzivatel˚u. Pokud ˇclovˇek naraz´ı na probl´em, je mnohdy lepˇs´ı neˇz se pokouˇset pt´at na f´orech, prostudovat zdrojov´y k´od knihovny.
Pro podrobnˇejˇs´ı informace o knihovnˇe viz [3].
3.4
FOX Toolkit
Tuto knihovnu je moˇzn´e z´ıskat z adresy http://www.fox-toolkit.org/. Tato knihovna pro tvorbu grafick´ych uˇzivatelsk´ych rozhran´ı je zvl´aˇstˇe obl´ıben´a u tv˚urc˚u profesion´aln´ıch syst´em˚u (ˇr´ıd´ıc´ı syst´emy, informaˇcn´ı syst´emy,. . . ). Jedn´a se v podstatˇe o d´ılo jednoho ˇclovˇeka, avˇsak v´yvoj´aˇrsk´a komunita postupnˇe nar˚ust´a. Podpora pro OpenGL je obsaˇzena ve tˇr´ıdˇe
FXGLCanvas. Instanci t´eto tˇr´ıdy je moˇzn´e zaslat zpr´avu makeCurrent, a potom je jak´ekoli vykreslov´an´ı OpenGL smˇeˇrov´ano do t´eto instance.
Hlavn´ı vlastnosti knihovny:
• Kompaktn´ı a ucelen´e API, kter´e je relativnˇe jednoduch´e na nauˇcen´ı. Protoˇze se jedn´a o projekt (v podstatˇe) jednoho ˇclovˇeka, je API velice jednotn´e.
• Dobr´a podpora OpenGL.
• Knihovna je multiplatformn´ı. Mˇela by b´yt provozovateln´a na syst´emech s X Windows (OS Linux, Solaris, FreeBSD, . . . ), Mac OS X a Windows.
• Hlavn´ım implementaˇcn´ım jazykem je C++. Existuje vˇsak mnoho binding˚u do jin´ych jazyk˚u, nam´atkou napˇr´ıklad Ruby (u program´ator˚u v tomto jazyce je FOX Toolkit asi nejobl´ıbenˇejˇs´ı knihovna uˇzivatelsk´eho rozhran´ı), Python, Eiffel, . . .
• Relativnˇe nedostateˇcn´a, roztˇr´ıˇstˇen´a dokumentace. Zdrojov´y k´od je ovˇsem srozumiteln´y, a slouˇz´ı jako dobr´a dokumentace.
• Knihovna je ˇs´ıˇrena pod GNU LGPL licenc´ı.
• Menˇs´ı komunita uˇzivatel˚u, pˇri probl´emu opˇet plat´ı, ˇze je nejlepˇs´ı prostudovat zdrojov´e k´ody.
• V posledn´ıch verz´ıch pˇribyla podpora UTF-8, avˇsak z nezn´am´ych d˚uvod˚u nen´ı moˇzn´e v syst´emech s X Windows zad´avat ˇcesk´e znaky (l´epe ˇreˇceno obecnˇe veˇsker´e znaky zad´avan´e pˇres mrtvou kl´avesu). Ve starˇs´ıch verz´ıch (aˇz do 1.4 vˇcetnˇe) sice nebyla podpora UTF-8, ale zad´av´an´ı ˇcesk´ych znak˚u fungovalo. Ve Windows tento probl´em nen´ı.
Pro podrobnˇejˇs´ı informace o knihovnˇe viz [4].
3.5
Motif
Tato grafick´a knihovna je ze vˇsech jmenovan´ych nejstarˇs´ı (vznikla kolem roku 1980). Jej´ı API je definov´ana standardem IEEE 1295. Motif byl nejrozˇs´ıˇrenˇejˇs´ı knihovna pro tvorbu grafick´ych uˇzivatelsk´ych rozhran´ı pro komerˇcn´ı Unixov´e syst´emy. Jedna z posledn´ıch verz´ı 2.1 pˇrinesla dokonce podporu pro Unicode. Na jej´ım z´akladˇe st´aly dalˇs´ı ´uspˇeˇsn´e projekty, jako napˇr´ıklad grafick´e uˇzivatelsk´e rozhran´ı CDE (Solaris OS), nebo 4Dwm (IRIX). Ne-jzn´amˇejˇs´ı implementace byly komerˇcn´ı, avˇsak existuje i klon jm´enem LessTif, kter´y je ˇs´ıˇren pod licenc´ı GNU LGPL. Tato implementace je obsaˇzena ve vˇetˇsinˇe repozit´aˇr˚u svobodn´ych Unixov´ych syst´em˚u, nebo je moˇzn´e ji z´ıskat z adresy http://www.lesstif.org/. Imple-mentace t´eto knihovny se jiˇz na novˇejˇs´ı projekty nepouˇz´ıvaj´ı a lze ˇr´ıct, ˇze byla nahrazena knihovnou GTK+.
Hlavn´ı rysy standardu Motif, respektive knihovny LessTif:
• Ucelen´e propracovan´e API, na kter´em je vidˇet dlouholet´y v´yvoj, a to jak pozitivnˇe, tak negativnˇe.
• Existence velk´eho mnoˇzstv´ı komponent tˇret´ıch stran, kter´e je moˇzn´e st´ahnout, pˇ r´ıpad-nˇe zakoupit.
• Sama specifikace je multiplatformn´ı, ovˇsem do operaˇcn´ıho syst´emu MS Windows a Mac OS jej´ı implementace pˇr´ıliˇs nepronikly. LessTif je urˇcen pro syst´emy s X Windows (tedy OS Linux, FreeBSD, v Solaris OS existuje komerˇcn´ı implementace dod´avan´a rovnou se syst´emem) a popˇr´ıpadˇe Windows, na kter´em je nainstalov´an Cygwin spolu s nˇejak´ym X Windows Serverem (napˇr´ıklad Cygwin X.org).
• Hlavn´ım implementaˇcn´ım jazykem je C. Knihovna ovˇsem vyˇzaduje docela dobr´e porozumˇen´ı knihovn´am XLib a Xt, protoˇze stav´ı na jejich programovac´ım modelu. • Existuje velice dobr´a dokumentace, kter´e je obrovsk´e mnoˇzstv´ı (vˇcetnˇe tiˇst´en´ych
manu´al˚u). Jedn´a se asi o jedinou knihovnu pro tvorbu grafick´ych uˇzivatelsk´ych rozhran´ı, kter´a m´a k dispozici n´apovˇedu v podobˇe manu´alov´ych str´anek.
• Komunita uˇzivatel˚u je dnes jiˇz velice mal´a, f´ora jsou velice m´alo aktivn´ı. Vˇetˇsina odpovˇed´ı na ot´azky se vˇsak d´a naj´ıt v archivech.
• Knihovna mˇela po celou dobu relativnˇe stabiln´ı API, takˇze starˇs´ı programy funguj´ı bez probl´em˚u.
• Dobr´a podpora OpenGL. Z´akladem je komponenta GLwMDrawingArea, kter´a pˇ redstav-uje kresl´ıc´ı plochu pro OpenGL pˇr´ıkazy. Pot´e jen staˇc´ı tuto komponentu nastavit jako aktivn´ı pomoc´ı funkce GLwDrawingAreaMakeCurrent a volat pˇr´ıkazy OpenGL. Pro podrobnˇejˇs´ı informace o knihovnˇe viz [7].
3.6
wxWidgets
Tato knihovna se od pˇredeˇsl´ych liˇs´ı hlavnˇe v tom, ˇze se jedn´a jen o C++ n´astavbu nad jin´ymi knihovnami, konkr´etnˇe pod X Windows jde o GTK+ a Motif, pod Windows Win32API a pod Mac OS X rozhran´ı Cocoa nebo starˇs´ı Carbon. Zaj´ımavost´ı je tak´e podpora syst´emu OS/2. Knihovnu je moˇzn´e z´ıskat z adresy http://wxwidgets.org/. Knihovna vznikla v roce 1992 pod n´azvem wxWindows, avˇsak v roce 2004 musela b´yt pˇrejmenov´ana, kv˚uli vlastnictv´ı pojmu Windows firmou Microsoft.
Mezi hlavn´ı vlastnosti knihovny patˇr´ı:
• Implementaˇcn´ım jazykem je C++. Ovˇsem kv˚uli st´aˇr´ı knihovny, nejsou pouˇzity pokroˇ cil-ejˇs´ı vlastnosti tohoto jazyka, nav´ıc si mnoho vlastnost´ı pozdˇejˇs´ıch standard˚u C++ implementuje sama a vˇetˇsinou nekompatibilnˇe (napˇr´ıklad typ String).
• Existuje relativnˇe hodnˇe binding˚u do jin´ych jazyk˚u, nam´atkou Python, Haskell, Lua, Smalltalk, . . . ovˇsem ne vˇzdy je kvalita stejn´a. Zaj´ımavost´ı je tak´e implementace jazyka Scheme s n´azvem PLT Scheme, kter´a pouˇz´ıv´a svou vlastn´ı nekompatibiln´ı implementaci wxWindows, kter´a vych´az´ı ze starˇs´ı verze, avˇsak je velice hluboce in-tegrov´ana do jazyka. T´ım se liˇs´ı od jin´ych binding˚u, kter´e jsou vˇetˇsinou jen tenk´e a mnohdy pˇr´ıliˇs nezapadaj´ı do konceptu jazyka.
• Dokumentace je kvalitn´ı, existuje dokonce kniha o programov´an´ı v t´eto knihovnˇe zdarma.
• Komunita uˇzivatel˚u je poˇcetn´a, f´ora jsou velice aktivn´ı. Je relativnˇe hodnˇe pouˇz´ıv´ana i v´yvoj´aˇri komerˇcn´ıho software (pˇr´ıkladem je napˇr´ıklad antivirov´y syst´em AVG).
• V´yvoj knihovny nedˇel´a velk´e skoky a API je relativnˇe stabiln´ı. V´yvoj je vˇsak dostateˇcnˇe ˇziv´y.
• Licence t´eto knihovny je velice podobn´a GNU LGPL s v´yjimkou, kter´a umoˇzˇnuje redistribuovat odvozen´e d´ılo v bin´arn´ı formˇe pod jinou licenc´ı
• Podpora pro OpenGL je dobr´a. Jej´ım z´akladem je tˇr´ıda wxGLCanvas, od kter´e je nutno odvodit novou tˇr´ıdu, kde je pˇredefinov´ana metoda OnPaint. V t´eto metodˇe je moˇzn´e pouˇz´ıvat vol´an´ı OpenGL.
Kapitola 4
N´
avrh ˇ
reˇ
sen´ı
Tato kapitola se zab´yv´a n´avrhem vlastn´ıho ˇreˇsen´ı GLUT knihovny nad knihovnou pro tvorbu uˇzivatelsk´ych rozhran´ı. Nejprve bude detailnˇe rozebr´ano, kter´a knihovna pro tvorbu uˇzivatelsk´ych rozhran´ı byla zvolena a proˇc. N´aslednˇe bude uvedena z´akladn´ı architektura, na kter´e by cel´a knihovna mˇela stavˇet, doplnˇen´a o v´yhody a nev´yhody takov´eho postupu.
Prvn´ı vlastnost´ı, kterou by knihovna mˇela splˇnovat je dostateˇcn´a podpora OpenGL. Tedy mˇelo by b´yt moˇzn´e vytvoˇrit nˇejakou vykreslovac´ı plochu, ve kter´e bude moˇzno pouˇz´ıvat pˇr´ıkazy OpenGL API. Rozhodnˇe by se nemˇelo jednat o n´astavbu (napˇr´ıklad objektovou) bez moˇznosti pˇr´ıstupu k origin´aln´ım funkc´ım OpenGL, t´ım by se situace stala mnohem sloˇzitˇejˇs´ı. D´ale je nutn´e podpora v´ıce oken v aplikaci vˇcetnˇe vykreslovac´ıch ploch a z toho vypl´yvaj´ıc´ı moˇznosti volby aktivn´ı vykreslovac´ı plochy. Tyto vlastnosti splˇnuj´ı vˇsechny pop-san´e knihovny pro tvorbu uˇzivatelsk´eho rozhran´ı.
Dalˇs´ı vlastnost´ı, kter´a jiˇz vˇsak nen´ı ´uplnˇe nezbytn´a, je co nejvˇetˇs´ı multiplatformnost knihovny. L´epe ˇreˇceno by knihovna mˇela podporovat alespoˇn tˇri nejv´yznamnˇejˇs´ı syst´emy, tedy X Windows System (reprezentovan´y dnes nejv´ıce OS Linux, FreeBSD a Solaris), Mac OS X a Windows. Tato vlastnost ze seznamu vyˇrad´ı knihovnu Motif. Ostatn´ı knihovny tuto vlastnost splˇnuj´ı.
Podstatnou vlastnost´ı je tak´e pouˇzit´a licence knihovny. Protoˇze autor t´eto pr´ace je fanouˇskem otevˇren´eho software, mˇelo by se jednat o otevˇrenou knihovnu, v ide´aln´ım pˇr´ıpadˇe vyv´ıjenou komunitou v´yvoj´aˇr˚u svobodn´eho software. Z´aroveˇn by vˇsak autor byl relativnˇe r´ad, pokud by se knihovna rozˇs´ıˇrila, tud´ıˇz se jako nejlepˇs´ı licence jev´ı GNU LGPL, nebo BSD/MIT. Tuto vlastnost nesplˇnuje jedin´a knihovna a to QT.
Posledn´ı vlastnost´ı je pouˇzit´y implementaˇcn´ı jazyk. Ten do velk´e m´ıry ovlivn´ı pod-poru starˇs´ıch program˚u. I kdyˇz je C++ s C velice kompatibiln´ı, tato kompatibilita se t´yk´a jen program˚u, psan´ych v normˇe ANSI. Mnoho starˇs´ıch program˚u je ps´ano v normˇe K&R coˇz bude pro C++ probl´em. Bohuˇzel jeˇstˇe vˇetˇs´ı mnoˇzstv´ı nov´ych program˚u je ps´ano tak, ˇ
ze ANSI normu nedodrˇzuj´ı, a pˇreklad pod C++ je moˇzn´y jen s obt´ıˇzemi. C m´a nav´ıc podstatnou v´yhodu v tom, ˇze pro nˇej existuje vˇetˇs´ı mnoˇzstv´ı kompil´ator˚u, kter´e vˇetˇsinou normu implementuj´ı l´epe a celou. Naopak u C++ v podstatˇe neexistuje pˇrekladaˇc, kter´y by normu tohoto jazyka implementoval se vˇsemi jej´ımi vlastnostmi. Proto tedy bude lepˇs´ı pouˇz´ıt knihovnu, psanou v ˇcist´em jazyce C. Toto splˇnuje grafick´a knihovna GTK+ a Motif. Motif jsme jiˇz vylouˇcili, takˇze m´ame na v´ybˇer mezi GtkGLArea a GtkGLExt. Protoˇze je knihovna GtkGLExt ˇzivˇejˇs´ı, m´a vˇetˇs´ı komunitu a kvalitnˇejˇs´ı dokumentaci, poslouˇz´ı jako vhodn´y z´aklad.
Nyn´ı nast´av´a vhodn´y ˇcas detailnˇe rozebrat n´avrh nov´e knihovny. Zjednoduˇsen´e sch´ema knihovny GLUT je zobrazeno na obr´azku4.1.
Obrazovka uživatele X OpenGL
#include <GL/glut.h> Kód aplikace
Win OpenGL
Volání Glut API
X Server Win API (glBegin, glVertex3f,...)
Volání OpenGL API
libGlut (glutInit,glutMainLoop,...)
Platformově nezávislé Platformově závislé
Obr´azek 4.1: Sch´ema aplikace pouˇz´ıvaj´ıc´ı knihovnu GLUT
Jak je vidˇet, aplikace sama o sobˇe je platformovˇe nez´avisl´a, pokud pouˇz´ıv´a jen vol´an´ı knihoven OpenGL a GLUT. Tato vol´an´ı jsou pˇred´ana na bedra jednotliv´ych knihoven, kter´e jsou platformovˇe z´avisl´e. Vol´an´ı OpenGL jsou pˇred´ana v z´avislosti na platformˇe bud’ X Serveru (tato cesta m˚uˇze b´yt nejen v r´amci lok´aln´ıho poˇc´ıtaˇce, ale tak´e po s´ıti poˇc´ıtaˇci jin´emu), kter´y je m˚uˇze pˇred´avat d´al napˇr´ıklad DRI, odkud putuj´ı do grafick´e karty, kter´a provede vykreslen´ı. Na Windows je postup obdobn´y, jen jsou vol´an´ı pˇred´ana Win API, kter´e je pos´ıl´a ovladaˇci grafick´e karty. Zaj´ımavost´ı OpenGL je tak´e to, ˇze pokud n´ahodou nˇejak´a funkce nen´ı podporov´ana, mus´ı b´yt implementov´ana softwarovˇe, kter´a se na t´eto cestˇe nach´az´ı tak´e. N´as vˇsak mnohem v´ıce zaj´ım´a, co se dˇeje v knihovnˇe GLUT. Ta je nucena komunikovat nejen se samotnou implementac´ı OpenGL, ale nav´ıc tak´e X Serverem, nebo Win API za ´uˇcelem implementace operac´ı pro vytvoˇren´ı okna, zpracov´an´ı vstupn´ıch ud´alost´ı, nastaven´ı vlastnost´ı okna, . . . To cel´e ˇcin´ı knihovnu GLUT relativnˇe sloˇzitou na implementaci, ale tak´e pozdˇejˇs´ı spr´avu a studium zdrojov´ych k´od˚u.
D´ıky n´avrhu nov´e knihovny bude odstranˇeno nejen licenˇcn´ı omezen´ı p˚uvodn´ı knihovny GLUT, ale tak´e technick´a omezen´ı spojen´a se sloˇzitost´ı. Pokud bude knihovna dostateˇcnˇe jednoduch´a, bude tak´e jednoduˇseji spravovateln´a a pˇr´ıpadnˇe l´epe upraviteln´a ke speci´aln´ım ´
uˇcel˚um. Zjednoduˇsen´e sch´ema architektury je na obr´azku 4.2.
Jak je vidˇet, v diagramu pˇribyla vybran´a knihovna pro tvorbu grafick´eho uˇzivatelsk´eho rozhran´ı. Co je vˇsak mnohem d˚uleˇzitˇejˇs´ı, nov´a knihovna GLUT se stala platformovˇe nez´ avisl-ou. P˚uvodn´ı spr´ava oken, kterou knihovna zajiˇst’ovala, je nyn´ı ponech´ana na GTK+. Ko-munikace s OpenGL je ponech´ana na knihovnˇe GtkGLExt. T´ım byl zajiˇstˇen´y relativnˇe rychl´y v´yvoj knihovny, spojen´y s celkovou jednoduchost´ı implementace a ˇcistotou zdro-jov´ych k´od˚u (t´ım je myˇsleno hlavnˇe minimalizov´an´ı pouˇz´ıt´ı preprocesoru). Dalˇs´ı v´yhodou je tak´e moˇznost pˇrirozenˇe oddˇelen´eho v´yvoje jednotliv´ych ˇc´ast´ı. K pˇr´ıpadn´emu studiu kni-hovny by mˇela b´yt dostaˇcuj´ıc´ı znalost GTK+, coˇz je podm´ınka splniteln´a za mnohem kratˇs´ı ˇ
casov´y interval, neˇz studium Xlib, Win API, . . .
Snahou tak´e je, aby knihovna pokryla co moˇzn´a nejv´ıce funkc´ı z p˚uvodn´ı knihovny GLUT a dos´ahla maxim´aln´ı kompatibility. Jej´ı c´ıle jsou tedy podobn´e jako u knihovny FreeGLUT. Za referenˇcn´ı knihovnu lze povaˇzovat pr´avˇe FreeGLUT, kter´y postupnˇe nahrazuje p˚uvodn´ı GLUT a m´a svobodnˇejˇs´ı licenci. Co se t´yˇce rozˇs´ıˇren´ı, kter´e knihovna FreeGLUT zavedla, bylo by maxim´alnˇe vhodn´e je implementovat tak´e, jelikoˇz se nejedn´a jen o jak´esi
#ifdef GLUT_GTK #include <GL/glut.h> #else #include "glut_gtk.h" #endif X OpenGL Win OpenGL
Volání Glut API (glBegin, glVertex3f,...)
Volání OpenGL API
(glutInit,glutMainLoop,...) libGTKGlut
GTKGLExt
GTK
Platformově nezávislé Platformově závislé
Správa oken
Win API X Server
Obrazovka uživatele Kód aplikace
Obr´azek 4.2: Sch´ema aplikace pouˇz´ıvaj´ıc´ı novou knihovnu GtkGLUT
ad-hoc vlastnosti, ale o implementaci velice ˇz´adan´ych rozˇs´ıˇren´ı.
Knihovna FreeGLUT z´aroveˇn slouˇz´ı jako zdroj nˇekter´ych zdrojov´ych k´od˚u, kter´e ned´av´a smysl ps´at znovu (napˇr´ıklad popis GLUT konvice, popis vektorov´ych font˚u,. . . ) a z´aroveˇn demonstraˇcn´ı pˇr´ıklady dod´avan´e s knihovnou poslouˇz´ı jako dobr´y test kompatibility imple-mentace.
Kapitola 5
Implementace
V t´eto kapitole bude podrobnˇe pops´ana implementace vlastn´ı knihovny. U popis˚u funkc´ı bude uveden zejm´ena zp˚usob implementace, hlavn´ı probl´emy kter´e pˇri implementaci nastaly a jejich ˇreˇsen´ı. Pokud je implementace trivi´aln´ı, nen´ı funkce zm´ınˇena v˚ubec, nebo je zm´ınˇena nepˇr´ımo, napˇr´ıklad v popisu datov´ych struktur. Dokumentace tedy neslouˇz´ı jako referenˇcn´ı pˇr´ıruˇcka pro pouˇzit´ı knihovny. Jelikoˇz vˇsak byla knihovna prim´arnˇe vyv´ıjena za ´uˇcelem dosaˇzen´ı maxim´aln´ı kompatibility s knihovnou GLUT verze 3.7 a rozˇs´ıˇren´ımi implemento-van´e v knihovnˇe FreeGLUT 2.4.0, je moˇzn´e pouˇz´ıt jako referenˇcn´ı dokumentaci origin´aln´ı popis GLUT API (ve verzi 3 viz [1]), nebo dokumentaci ke knihovnˇe OpenGLUT (viz [9]), jelikoˇz FreeGLUT bohuˇzel dokumentaci API neobsahuje.
5.1
Pouˇ
zit´
e konvence a datov´
e struktury knihovny
Kaˇzd´a exportovan´a funkce m´a, stejnˇe jako v origin´aln´ı knihovnˇe GLUT, za prefix zvolen glut, exportovan´a makra potom GLUT . Intern´ı funkce, glob´aln´ı promˇenn´e, definice struktur a makra zaˇc´ınaj´ı vˇzdy ˇretˇezcem gtkglut a GTKGLUT. Takto oznaˇcen´e souˇc´asti by uˇzivatel knihovny nemˇel ve sv´em programu nikdy pouˇz´ıt.
Podle pravidla “Ukaˇz mi sv˚uj k´od a skryj datov´e struktury a nebudu rozumˇet. Ukaˇz mi datov´e struktury a obyˇcejnˇe nebudu potˇrebovat tv˚uj k´od, vˇetˇsinou mi bude jasn´y” je nyn´ı spr´avn´y ˇcas popsat co nejd˚ukladnˇeji vnitˇrn´ı datov´e struktury knihovny obsaˇzen´e v souboru gtkglut internal.h.
Intern´ı stav knihovny je uloˇzen v glob´aln´ı promˇenn´e gtkglut context (d´ale jen kon-text knihovny), kter´a je ukazatelem na strukturu gtkglut context struct. Mezi hlavn´ı poloˇzky t´eto struktury patˇr´ı:
• is inicialized - Urˇcuje, zda byla knihovna zinicializov´ana vol´an´ım funkce glutInit. • window init geometry - Struktura gtkglut geometry struct obsahuj´ıc´ı poˇc´ateˇcn´ı
pozici a velikost novˇe vytvoˇren´ych hlavn´ıch oken.
• window init iconic - Promˇenn´a ud´avaj´ıc´ı, zda se nov´a hlavn´ı okna maj´ı vytv´aˇret minimalizovan´a.
• gl debug - Urˇcuje, zda byl zad´an parametr -gldebug, ˇc´ımˇz dojde k otestov´an´ı chyb OpenGL funkc´ı glGetError a pˇr´ıpadn´y v´ypis chyby v ˇciteln´e podobˇe po kaˇzd´em zpracov´an´ı ud´alosti.
• direct render - Pokud je tato hodnota nastavena na TRUE, je pouˇzito pˇr´ım´e ren-derov´an´ı OpenGL (tj. hardware). Pˇri FALSE je pouˇzita software emulace. Existuje tak´e speci´aln´ı hodnota GTKGLUT DIRECT RENDER NOT SET, kdy je nejprve proveden pokus o pˇr´ım´e renderov´an´ı a v pˇr´ıpadˇe ne´uspˇechu je pouˇzito nepˇr´ım´e.
• display mode - Urˇcuje v´ychoz´ı vykreslovac´ı m´od, se kter´ym budou vytv´aˇrena nov´a okna.
• elapsed time timer - ˇCasovaˇc, kter´y ud´av´a d´elku bˇehu programu od prvn´ı inicial-izace knihovny.
• callback idle - Zde je uloˇzena funkce, kter´a m´a b´yt zavol´ana v klidov´em stavu knihovny. Registrace se provede vol´an´ım funkce glutIdleFunc.
• actual gl config - Objekt knihovny GtkGLExt, kter´y reprezentuje aktu´aln´ı konfig-uraci OpenGL. Je tvoˇrena z promˇenn´e display mode. Pokud obsahuje NULL, nebyl nastaven m´od podporovan´y grafickou kartou.
• window array, menu array - Dynamick´e pole vˇsech aktivn´ıch oken a menu. Pokud je v poli nˇekter´a z hodnot NULL, doˇslo ke zruˇsen´ı poloˇzky.
• current gl drawable, current gl context - Objekty knihovny GtkGLExt. Urˇcuj´ı aktu´aln´ı GDK kresl´ıc´ı okno a OpenGL kontext. Vnitˇrnˇe se tyto promˇenn´e nastavuj´ı ve funkci glutSetWindow. V pˇr´ıpadˇe ˇze je zruˇseno aktivn´ı okno jsou tyto promˇenn´e nastaveny na NULL.
• current window, current menu - Aktivn´ı okno a menu. Tyto hodnoty vracej´ı funkce glutGetWindow, glutGetMenu a jsou nastavov´any pomoc´ı funkc´ı glutSetWindow a glutSetMenu.
• cursors cache - Vyrovn´avac´ı pamˇet’ pro kurzory myˇsi. Jedn´a se o pole, kter´e je pˇri startu aplikace naplnˇeno hodnotami NULL. Pokud uˇzivatel poˇzaduje zmˇenu kur-zoru vol´an´ım funkce glutSetCursor, je nejprve nalezena poloˇzka v poli kter´a n´aleˇz´ı poˇzadovan´emu kurzoru, a v pˇr´ıpadˇe hodnoty NULL je vytvoˇren nov´y objekt kurzoru, jehoˇz odkaz je uloˇzen do pole. Pˇri pˇr´ıˇst´ım vol´an´ı je pouˇzit jiˇz vytvoˇren´y kurzor. Speci´aln´ı postaven´ı m´a pr´azdn´y (neviditeln´y) kurzor. Ten, na rozd´ıl od ostatn´ıch typ˚u kurzor˚u, nen´ı standardnˇe pˇreddefinov´an v knihovnˇe GTK+ a mus´ı b´yt vytvoˇren za bˇehu z pixmapy. Po vytvoˇren´ı je odkaz na nˇej uloˇzen do promˇenn´e cursor none. • keyboard modifiers - Modifik´atory kl´avesnice. Standardnˇe je nastavena na hodnotu
GTKGLUT UNDEFINED. V pˇr´ıpadˇe vol´an´ı uˇzivatelsk´ych funkc´ı pro zpracov´an´ı vstupu z kl´avesnice a myˇsi je nastavena na spr´avnou hodnotu a je moˇzn´e ji z´ıskat vol´an´ım funkce glutGetModifiers. Po dokonˇcen´ı vol´an´ı uˇzivatelsk´e funkce je opˇet nastavena na nedefinovanou hodnotu.
• menu status func, menu state func - Zde jsou uloˇzeny odkazy na uˇzivatelem defino-van´e funkce, kter´e maj´ı b´yt vol´any v pˇr´ıpadˇe zmˇeny stavu menu. Nastaven´ı se provede vol´an´ım funkce glutMenuStatusFunc a glutMenuStateFunc.
• action on window close - Promˇenn´a zaveden´a v souvislosti s dosaˇzen´ım kompat-ibility s knihovnou FreeGLUT. Ud´av´a, co se m´a st´at, pokud uˇzivatel v okenn´ım manaˇzeru uzavˇre okno (obvykle stiskem tlaˇc´ıtka se symbolem kˇr´ıˇzku). Standardn´ı
GLUT provede ukonˇcen´ı aplikace. FreeGLUT pˇrid´av´a moˇznosti vyskoˇcen´ı z hlavn´ı smyˇcky a pokraˇcov´an´ı v bˇehu, aˇz do uzavˇren´ı posledn´ıho okna, kdy vˇzdy provede vyskoˇcen´ı z hlavn´ı smyˇcky. Promˇenn´a se v uˇzivatelsk´em programu nastavuje vol´an´ım funkce glutSetOption.
• no active toplevel windows - Poloˇzka slouˇz´ıc´ı zejm´ena ke zv´yˇsen´ı v´ykonu. Ud´av´a poˇcet aktivn´ıch oken nejvyˇsˇs´ı ´urovnˇe. Pokud hodnota klesne na nulu, je provedena akce definovan´a v action on window close. Poloˇzku by bylo moˇzn´e vypustit a prov´est v´ypoˇcet poˇctu oken po kaˇzd´em zavˇren´ı okna, avˇsak v aplikac´ıch pracuj´ıc´ıch s mnoha okny by se jednalo o velmi neefektivn´ı operaci.
• current active menu window id - Okno, ze kter´eho bylo vyvol´ano otevˇren´ı menu. Pouˇz´ıv´a se k vol´an´ı uˇzivatelsk´e funkce definovan´e pˇri zvolen´ı poloˇzky menu k nastaven´ı aktivn´ıho okna. Tato promˇenn´a m˚uˇze b´yt glob´aln´ı, jelikoˇz je aktivn´ı vˇzdy maxim´alnˇe jedno menu.
Veˇsker´e informace uloˇzen´e o oknech jsou, jak jiˇz bylo dˇr´ıve ˇreˇceno, k dispozici v promˇenn´e window array. Jedn´a se o dynamicky rostouc´ı pole struktur gtkglut window struct. Ta obsahuje n´asleduj´ıc´ı poloˇzky:
• window, drawing area, event box, fixed - GTK+ komponenty kter´e vytv´aˇr´ı vlastn´ı okno a kresl´ıc´ı plochu. V´ıce o zp˚usobu uspoˇr´ad´an´ı a vnoˇren´ı komponent bude pops´ano v ˇc´asti5.3 na stranˇe 21zab´yvaj´ıc´ı se okny.
• parent window - ˇC´ıslo rodiˇcovsk´eho okna. Pokud se jedn´a o okno nejvyˇsˇs´ı ´urovnˇe, je tato promˇenn´a nastavena na hodnotu -1.
• first displayed - Urˇcuje, zda bylo okno jiˇz nˇekdy zobrazeno. Pokud je okno zo-brazeno ´uplnˇe poprv´e, je dle definice nutn´e zavolat uˇzivatelskou funkci pro obsluhu zmˇeny velikosti okna. Pˇred prvn´ım zobrazen´ım okna je promˇenn´a nastavena na FALSE, pak uˇz vˇzdy na TRUE.
• fullscreen - Promˇenn´a pouˇziteln´a pouze u oken nejvyˇsˇs´ı ´urovnˇe. Pokud je vol´ana funkce glutFullScreen, je tato promˇenn´a nastavena na TRUE. Po zmˇenˇe velikosti je zpˇet nastavena na standardn´ı hodnotu FALSE.
• child list - Spojitˇe v´azan´y seznam potomk˚u okna. Standardnˇe je NULL, coˇz znaˇc´ı nepˇr´ıtomnost podoken. Pokud je promˇenn´a nepr´azdn´a, ud´avaj´ı jednotliv´e poloˇzky seznamu ˇc´ısla oken (nejsou to tedy pˇr´ım´e odkazy na strukturu).
• window visible - Urˇcuje zda je okno viditeln´e. Kromˇe oˇcek´avan´ych hodnot TRUE a FALSE, m˚uˇze tak´e nab´yvat hodnoty GTKGLUT UNDEFINED. Ta znamen´a, ˇze bud’ souˇcasn´y stav okna jeˇstˇe nen´ı zn´am, nebo uˇzivatel pr´avˇe provedl registraci funkce glutVisibilityFunc. Tehdy mus´ı b´yt zaruˇceno doruˇcen´ı zpr´avy o zmˇenˇe viditelnosti okna uˇzivatelsk´e funkci ihned, jakmile se tak stane. Jelikoˇz vˇsak uvnitˇr knihovny doch´az´ı k odstraˇnov´an´ı duplicitn´ıch zpr´av o viditelnosti okna, je nutn´e nastavit pr´avˇe tuto hodnotu, kter´a nen´ı ani TRUE, ani FALSE a zp˚usob´ı zavol´an´ı uˇzivatelsk´e funkce. • current cursor - Identifik´ator kurzoru, kter´y je oknu pˇriˇrazen. Uˇzivatelem je nepˇr´ımo
nastavov´an funkc´ı glutSetCursor, avˇsak hodnota t´eto promˇenn´e se vyuˇz´ıv´a pouze ve funkci glutGet.
• damaged - Urˇcuje, zda je okno poˇskozeno a potˇrebuje pˇrekreslit. Nastavuje se pˇri zmˇenˇe velikosti okna a pˇri vytvoˇren´ı okna.
• iconified - Pouze pro okna nejvyˇsˇs´ı ´urovnˇe. Pokud je okno ikonifikov´ano (minimal-izovan´e), je promˇenn´a nastavena na TRUE, jinak FALSE.
• callback display - Uˇzivatelsk´a funkce, kter´a se vol´a pˇri poˇzadavku na pˇrekreslen´ı okna (expose). Tato hodnota je pˇri vytvoˇren´ı nastavena na NULL, ale jako jedin´a mus´ı b´yt uˇzivatelem nastavena na jinou hodnotu pomoc´ı funkce glutDisplayFunc, jinak dojde k ukonˇcen´ı programu.
• callback reshape - Uˇzivatelsk´a funkce, kter´a se vol´a pˇri zmˇenˇe velikosti okna. Uˇzivatel hodnotu nastavuje pomoc´ı funkce glutReshapeFunc. Pokud nen´ı nastavena, tedy jej´ı hodnota je NULL, doch´az´ı k vol´an´ı standardn´ıho k´odu kter´y provede zavol´an´ı OpenGL funkce glViewport s parametry 0, 0, nov´a ˇs´ıˇrka okna, nov´a v´yˇska okna. • signal * - Mnoˇzina promˇenn´ych, kter´ymi se nastavuj´ı jednotliv´e uˇzivatelsk´e funkce.
Struktura bude podrobnˇeji rozebr´ana d´ale.
• callback close - Rozˇs´ıˇren´ı zaveden´e knihovnou FreeGLUT. Tato funkce je vol´ana pˇri uzavˇren´ı okna, a to jak v pˇr´ıpadˇe uˇzivatelsk´eho, tedy v okenn´ım manaˇzeru, tak i vol´an´ım glutDestroyWindow.
• mouse button menu - Pole menu asociovan´ych k jednotliv´ym tlaˇc´ıtk˚um myˇsi. Kaˇzd´a poloˇzka pole reprezentuje jedno tlaˇc´ıtko (v knihovnˇe GtkGLUT m´a uˇzivatel moˇznost vyuˇz´ıt aˇz 5 tlaˇc´ıtek) a jeho hodnota je identifik´ator menu, kter´e m´a b´yt zobrazeno. • user data - Libovoln´a, uˇzivatelsky definovateln´a hodnota typu odkaz. Tato poloˇzka
je rozˇs´ıˇren´ım zaveden´ym v knihovnˇe FreeGLUT. Pro nastaven´ı a ˇcten´ı jsou urˇceny funkce glutSetWindowData a glutGetWindowData. Standardn´ı hodnota je NULL. Jednotliv´e poloˇzky typu signal *, jsou struktury typu gtkglut signal struct, jej´ıˇz poloˇzky jsou n´asleduj´ıc´ı:
• gtk event handler - Urˇcuje GTK+ handler, se kter´ym m´a b´yt asociov´ana urˇcen´a GTK+ ud´alost. Ve sv´e podstatˇe se jedn´a o nadbyteˇcnou poloˇzku. Ve funkc´ıch, kter´e prov´ad´ı vlastn´ı registraci by mohla b´yt zad´ana pˇr´ımo hodnota funkce, nicm´enˇe takto jsou vˇsechny poloˇzky nastavov´any na jednom m´ıstˇe ve zdrojov´em k´odu, konkr´etnˇe ve funkci pro vytvoˇren´ı okna, a pˇr´ıpadn´a zmˇena je tedy snadnˇejˇs´ı.
• glut callback handler - Uˇzivatelem definovan´a funkce, kter´a m´a b´yt provedena. • signal id - GTK+ identifikaˇcn´ıˇc´ıslo sign´alu. Nastavuje se pˇri zaregistrov´an´ı ud´alosti.
Pouˇz´ıv´a se pro odregistrov´an´ı ud´alosti.
• event added - Urˇcuje, zda jiˇz byla GTK+ ud´alost pˇrid´ana do masky ud´alost´ı a je tedy moˇznost prov´adˇet pˇr´ıjem.
Jak jiˇz bylo ˇreˇceno dˇr´ıve, v kontextu knihovny se tak´e nach´az´ı dynamick´e pole jednotliv´ych menu. Ta jsou tvoˇrena strukturou gtkglut menu struct, kter´a m´a n´asleduj´ıc´ı poloˇzky:
• cached gtk menu - Poloˇzka ve kter´e je uloˇzeno dˇr´ıve vytvoˇren´e GTK+ menu. Pokud je poloˇzka naplnˇena a nedoˇslo k ˇz´adn´e zmˇenˇe poloˇzek menu, nebo podmenu, pouˇzije se tato promˇenn´a rovnou pro zobrazen´ı na obrazovce. Jinak doch´az´ı k nov´emu vytvoˇren´ı GTK+ menu, kter´e je uloˇzeno pr´avˇe do popisovan´e promˇenn´e.
• func - Uˇzivatelsk´a funkce, kter´a m´a b´yt vol´ana pˇri aktivaci poloˇzky menu. • child items - Seznam poloˇzek menu.
• in use - Urˇcuje, zda je menu aktu´alnˇe zobrazeno. Pokud je zobrazeno, nemˇelo by b´yt s menu ˇz´adn´ym zp˚usobem manipulov´ano.
• popuped from window id - Identifik´ator okna ze kter´eho doˇslo k zobrazen´ı menu. • need refresh - Poloˇzka je nastavena, pokud doˇslo k jak´ekoli zmˇenˇe v menu, nebo
jeho podmenu.
• parent menus - Seznam odkaz˚u na menu, kter´e maj´ı aktu´aln´ı menu zaregistrov´ano jako svoje podmenu.
• user data - Stejn´a poloˇzka jako v pˇr´ıpadˇe okna. Pro nastaven´ı a ˇcten´ı jsou urˇceny funkce glutSetMenuData a glutGetMenuData.
Jednotliv´e poloˇzky menu jsou struktury typu gtkglut menu item struct a obsahuj´ı: • label - Textov´y ˇretˇezec, kter´y slouˇz´ı jako popiska poloˇzky.
• parent menu id - Rodiˇcovsk´e menu, kter´emu dan´a poloˇzka n´aleˇz´ı. Poloˇzka je index, nikoli pˇr´ım´y odkaz.
• submenu id - Pokud je poloˇzka typu podmenu, je hodnota rozd´ıln´a od 0. Pro stan-dardn´ı poloˇzky je hodnota nastavena pr´avˇe na 0.
• value - Hodnota, kter´a je nastavena uˇzivatelem pˇri vytv´aˇren´ı poloˇzky menu. Tato je pˇred´av´ana do uˇzivatelem definovan´e funkce pˇri aktivaci poloˇzky.
5.2
Inicializaˇ
cn´ı funkce
Inicializaˇcn´ı funkce jsou vol´any zejm´ena na zaˇc´atku programu. Jednotliv´e definice se nach´az´ı v souboru gtkglut init.c.
Ve vˇetˇsinˇe program˚u bude jako jedna z prvn´ıch funkc´ı pouˇzita glutInit. Ta prov´ad´ı inicializaci knihovny. Jej´ımi argumenty jsou argcp, coˇz je ukazatel na poˇcet parametr˚u pˇr´ıkazov´eho ˇr´adku a argv, kter´y je pole ˇretˇezc˚u pˇr´ıkazov´eho ˇr´adku. Obˇe hodnoty mohou b´yt po dokonˇcen´ı vol´an´ı t´eto funkce zmˇenˇeny.
Parametry pˇr´ıkazov´eho ˇr´adku jsou stejn´e jako u knihovny GLUT, tedy:
• -display DISPLAY - Urˇcuje display, na kter´em m´a b´yt prov´adˇeno vykreslov´an´ı. Tento parametr je pˇreveden na --display a pˇred´an na bedra funkce gtk init. Hodnota m´a efekt pouze u syst´em˚u s X Windows a pokud nen´ı zpracov´ana, je na konci vol´an´ı funkce z parametr˚u odstranˇena.
• -geometry WxH+X+Y - Urˇcuje poˇc´ateˇcn´ı pozici a velikost oken hlavn´ıch oken. Internˇe je ˇretˇezec zpracov´an funkc´ı sscanf a z´ıskan´e hodnoty jsou uloˇzeny do kontextu knihovny.
• -iconic - Novˇe vytv´aˇren´a hlavn´ı okna budou na poˇc´atku minimalizovan´a. • -indirect - Vynut´ı pouˇzit´ı software renderingu OpenGL.
• -direct - Vynut´ı pouˇzit´ı hardware renderingu OpenGL. Pokud nen´ı uvedena ani jedna ze dvou pˇredchoz´ıch hodnot, pokus´ı se knihovna pouˇz´ıt rychlejˇs´ı hardware ren-dering a v pˇr´ıpadˇe ne´uspˇechu pouˇzije pomalejˇs´ı software rendering. Tento i pˇredchoz´ı parametr nastavuj´ı poloˇzku direct render v kontextu knihovny.
• -gldebug - Nastav´ı poloˇzku gl debug v kontextu knihovny.
• -sync - Vynut´ı synchronizovan´y reˇzim zobrazen´ı. Internˇe se pˇrev´ad´ı na parametr --sync a pˇred´av´a se knihovnˇe GTK.
Funkce nejprve inicializuje kontext knihovny (pokud jiˇz nebyl zinicializov´an) a pot´e provede zpracov´an´ı parametr˚u funkc´ı gtkglut parse params. Nakonec jsou zavol´any inicializaˇcn´ı funkce GTK (gtk init) a GtkGLExt (gtk gl init).
Zaj´ımav´a je funkce pro zpracov´an´ı parametr˚u. Ta nˇekter´e parametry zpracuje ve sv´e reˇzii, ovˇsem dva parametry pˇred´av´a d´al, a proto dojde k uloˇzen´ı tˇechto parametr˚u do listu, kter´y je na ´upln´em konci funkce odstranˇen a jednotliv´e parametry jsou ze seznamu odstranˇeny. O odstranˇen´ı parametr˚u se star´a funkce gtkglut remove null params, kter´a mˇen´ı hodnotu poˇctu parametr˚u a poloˇzky NULL (coˇz je identifik´ator toho, ˇze poloˇzka byla odstranˇena) nahrazuje nepr´azdn´ymi poloˇzkami (dojde k defragmentaci pole).
Za povˇsimnut´ı tak´e stoj´ı zpracov´an´ı geometrie. V ˇretˇezci s geometri´ı mohou b´yt zad´ana tak´e z´aporn´a ˇc´ısla poˇc´ateˇcn´ı pozice, coˇz znamen´a posun okna od prav´eho doln´ıho rohu. Ke spr´avn´emu v´ypoˇctu pozice je potˇreba zjistit ˇs´ıˇrku a v´yˇsku obrazovky. To je zajiˇstˇeno pomoc´ı objektu GdkScreen, kter´y ovˇsem existuje teprve po zavol´an´ı funkce gtk init. Proto je zpracov´an´ı tohoto parametru prov´adˇeno nadvakr´at. Nejprve je zpracov´ana pˇr´ıkazov´a ˇr´adka a hodnoty jsou uloˇzeny v pomocn´e promˇenn´e geometry a teprve po zavol´an´ı gtk init dojde k jejich vyhodnocen´ı a aplikov´an´ı.
Funkce glutInitWindowPosition a glutInitWindowSize nastavuj´ı poˇc´ateˇcn´ı pozici a rozmˇery novˇe vytv´aˇren´ych oken nejvyˇsˇs´ı ´urovnˇe. Obˇe funkce pouze nastavuj´ı promˇennou window init geometry v kontextu knihovny. Zvl´aˇstn´ı ´ulohu hraje pˇri nastaven´ı pozice hod-nota -1. Jedn´a se o standardn´ı hodnotu a znamen´a, ˇze um´ıstˇen´ı okna bude ponech´ano na okenn´ım syst´emu.
Relativnˇe zaj´ımavou funkc´ı je glutInitDisplayMode. Ta nastavuje zobrazovac´ı m´od, kter´y bude pouˇzit pro novˇe vytvoˇren´a okna. M´a jedin´y parametr mode. Ten je v uˇzivatelsk´em programu moˇzn´e vytvoˇrit pouˇzit´ım bitov´e operace OR na hodnoty GLUT RGBA, GLUT RGB, GLUT INDEX,. . . Hodnoty jsou stejn´e jako v GLUT API 3. GtkGLExt pouˇz´ıv´a podobn´e poj-menov´an´ı hodnot jen nahrazuje prefix GLUT za GDK GL MODE (napˇr´ıklad GDK GL MODE RGB, GDK GL MODE RGBA, GDK GL MODE INDEX,. . . ). Nejvˇetˇs´ım probl´emem bylo, ˇze nˇekter´a makra maj´ı definov´any jin´e ˇc´ıseln´e hodnoty (napˇr´ıklad GDK GL MODE STEREO m´a hodnotu 4, ale GLUT STEREO m´a hodnotu 256). ˇReˇsen´ı tohoto probl´emu jsou v podstatˇe tˇri:
• Makra pro knihovnu definovat stejnˇe jako v origin´aln´ı GLUT knihovnˇe a vytvoˇrit k´od, kter´y se soustavou if test˚u postar´a o spr´avn´e nastaven´ı pˇri vytv´aˇren´ı OpenGL kontextu. V koneˇcn´e verzi je zvoleno toto ˇreˇsen´ı. Funkce, kter´a se star´a o popsan´y pˇrevod se jmenuje gtkglut convert glut mode to gtkglext.
• Makra pro knihovnu opˇet definovat stejnˇe jako GLUT a vytvoˇrit funkci kter´a vhodnou manipulac´ı bit˚u pˇrevede jeden form´at na druh´y. Toto je asi nejhorˇs´ı ˇreˇsen´ı, protoˇze v pˇr´ıpadˇe zmˇeny hodnot v GtkGLExt dojde ke ztr´atˇe kompatibility.
• Makra pro knihovnu definovat stejnˇe jako v GtkGLExt. Toto ˇreˇsen´ı trp´ı moˇzn´ym probl´emem niˇzˇs´ı kompatibility s programy, kter´e nepouˇz´ıvaj´ı symbolick´a jm´ena, ale rovnou hodnoty a samozˇrejmˇe znamen´a ztr´atu bin´arn´ı kompatibility. Takˇrka do konce v´yvoje bylo zvoleno pr´avˇe toto ˇreˇsen´ı. Jelikoˇz se na konci jednalo o jedinou pˇrek´aˇzku v dosaˇzen´ı bin´arn´ı kompatibility s origin´aln´ı knihovnou GLUT, byla tato varianta opuˇstˇena na ´ukor prvn´ı.
Hlavn´ı nekompatibilitou je nedostupnost m´odu luminance (GLUT LUMINANCE), protoˇze v Gtk-GLExt nen´ı podporov´an.
Internˇe tato funkce nastavuje promˇennou display mode v kontextu knihovny. Ta je standardnˇe nastavena na kombinaci GLUT RGB | GLUT SINGLE | GLUT DEPTH. V mnoh´e literatuˇre se lze doˇc´ıst, ˇze hodnota GLUT DEPTH nen´ı nastavena. Nen´ı to ovˇsem pravda. Podle zdrojov´ych k´od˚u maj´ı knihovny GLUT 3.7 i FreeGLUT 2.4.0 standardnˇe hodnotu GLUT DEPTH nastavenu.
Knihovna GLUT verze 3.4 pˇrinesla zaj´ımavou alternativu k pˇredeˇsl´e metodˇe s podob-nou funkcionalitou v podobˇe funkce glutInitDisplayString. V knihovnˇe je pouˇzita imple-mentace z FreeGLUT, kter´a nab´ız´ı menˇs´ı moˇznosti, neˇz origin´aln´ı GLUT, avˇsak pro valnou vˇetˇsinu probl´em˚u je dostateˇcnˇe pouˇziteln´a. Hlavn´ı nekompatibilitou je absence zpracov´an´ı oper´ator˚u. Po zpracov´an´ı ˇretˇezce vol´a pˇredchoz´ı funkci a jej´ı moˇznosti jsou tedy stejn´e.
Nakonec je vhodn´e zm´ınit rozˇs´ıˇren´ı knihovny FreeGLUT a to funkci glutSetOption. V implementaci GtkGLUT je implementov´ana jako obal pro dˇr´ıve zm´ınˇenou skupinu funkc´ı glutInitDisplayMode, glutInitWindowSize, glutInitWindowPosition. Nav´ıc poskytuje stejnou funkcionalitu jako glutSetCursor. Nakonec se tak´e jedn´a o jedinou moˇznost, jak nastavit akci, kter´a m´a b´yt provedena pˇri uzavˇren´ı okna. Tato funkce by v budoucnu mohla slouˇzit jako n´ahrada dˇr´ıve zm´ınˇen´ych funkc´ı.
5.3
Funkce pro spr´
avu oken
Spr´ava oken byla z´akladn´ı a tak´e zˇrejmˇe nejsloˇzitˇejˇs´ı ˇc´ast knihovny. Veˇsker´a funkˇcnost je obsaˇzena v souboru gtkglut window.c.
Knihovna GLUT rozezn´av´a dva typy oken a to okna nejvyˇsˇs´ı ´urovnˇe a podokna (sub-window). Okna nejvyˇsˇs´ı ´urovnˇe jsou spravov´ana okenn´ım manaˇzerem dan´eho grafick´eho prostˇred´ı, mezit´ım co podokna jsou spravov´ana pˇr´ımo knihovnou GLUT. GTK+ pˇristupuje k okn˚um podobnˇe, avˇsak bohuˇzel ne stejnˇe. Tak´e zde jsou okna nejvyˇsˇs´ı ´urovnˇe spravov´ana okenn´ım manaˇzerem a podokna jsou spravov´ana v r´amci knihovny. U GTK+ plat´ı, ˇze ne kaˇzd´e podokno mus´ı b´yt fyzicky mapovan´ym oknem a takov´e okno nem´a sv˚uj vlastn´ı kon-text. Dalˇs´ım probl´emem je, ˇze GTK+ bylo navrhov´ano zejm´ena pro tvorbu uˇzivatelsk´ych rozhran´ı, kde se takˇrka v˚ubec neobjevuj´ı pˇrekr´yvaj´ıc´ı se podokna, ˇc´ımˇz se znaˇcnˇe liˇs´ı od kni-hovny GLUT. Neposledn´ım probl´emem byl spr´avce rozloˇzen´ı. Pro usnadnˇen´ı tvorby GUI poskytuje GTK+, podobnˇe jako vˇetˇsina modern´ıch knihoven, pr´avˇe tento n´astroj, kter´y podokna s´am rozm´ıst’uje a mˇen´ı jejich velikost dle velikosti rodiˇcovsk´eho okna. Z´akladn´ı filozofie pr´ace s GTK+ je takov´a, ˇze hlavn´ı okno se chov´a jako kontejner, do kter´eho lze vloˇzit pr´avˇe jednu komponentu. To vˇetˇsinou b´yv´a pr´avˇe spr´avce rozloˇzen´ı, do kter´eho se umist’uj´ı dalˇs´ı komponenty.
Pokud by GLUT nepodporoval podokna, pr´ace by byla jednoduch´a. Nejprve by se vytvoˇrilo hlavn´ı okno typu GtkWindow, a do nˇej by se vloˇzila pr´avˇe jedna komponenta, kter´a by slouˇzila pro vykreslov´an´ı OpenGL. Vhodnou komponentou je GtkDrawingArea. T´ım pr´ace byla hotov´a.
Jelikoˇz vˇsak GLUT podokna podporuje, bylo tˇreba hledat jinou cestu. Nejprve bylo tˇreba naj´ıt vhodn´eho spr´avce rozloˇzen´ı, kter´y by umoˇzˇnoval, tak jak je poˇzadov´ano GLUT funkcemi, fixn´ı um´ıstˇen´ı podoken. Takov´ym spr´avcem je GtkFixed. Tento je moˇzn´e vloˇzit do hlavn´ıho okna a do nˇej vkl´adat komponenty GtkDrawingArea. Bohuˇzel vˇsak GLUT se chov´a transparentnˇe a do podokna lze vloˇzit dalˇs´ı podokno, coˇz je navrˇzen´ym ˇreˇsen´ım nerealizovateln´e a je nutn´e minul´y n´avrh pˇrehodnotit. Necht’ je tedy kaˇzd´e podokno sv´az´ano se sv´ym fixn´ım spr´avcem rozloˇzen´ı. Toto ˇreˇsen´ı je moˇzn´e a bude i v´ıcem´enˇe funkˇcn´ı aˇz na jeden detail. GtkFixed patˇr´ı do skupiny komponent, kter´e nemaj´ı sv´e vlastn´ı okno. Takˇze bohuˇzel neexistuje moˇznost, jak nastavit v´yˇsku a ˇs´ıˇrku t´eto komponenty. To by nemusel b´yt probl´em, avˇsak pˇredstavme si n´asleduj´ıc´ı situaci. Vytvoˇr´ıme hlavn´ı okno, do nˇej vloˇz´ıme podokno a do nˇej opˇet vloˇz´ıme podokno, kter´e bude vˇetˇs´ı neˇz jeho pˇredek. Standardn´ı chov´an´ı GLUT je takov´e, jak je oˇcek´av´ano. Tedy posledn´ı podokno bude oˇr´ıznuto sv´ym rodiˇcovsk´ym oknem. Avˇsak v pˇr´ıpadˇe naˇseho pˇredchoz´ıho n´avrhu toto fungovat nebude a okno bude oˇr´ıznuto pouze hlavn´ım oknem. Je tedy tˇreba naj´ıt komponentu, kter´a bude m´ıt sv´e vlastn´ı fyzicky mapovan´e okno a do nˇej vkl´adat pˇredchoz´ı dvˇe komponenty. Tuto vlastnost takˇrka ide´alnˇe splˇnuje GtkEventBox. Z´avˇereˇcn´e ˇreˇsen´ı je plnˇe funkˇcn´ı a pr´avˇe popsan´ym zp˚usobem je spr´ava oken zajiˇstˇena v knihovnˇe GtkGLUT.
Pro objasnˇen´ı je nejl´epe uv´est pˇr´ıklad. C´ılem je vytvoˇrit okno, v nˇemˇz budou dvˇe podokna a v jednom z podoken bude dalˇs´ı podokno. Celkov´e rozloˇzen´ı komponent je vidˇet na obr´azku 5.1.
I kdyˇz popsan´e rozloˇzen´ı funguje dobˇre, nen´ı dokonal´e. Probl´em nast´av´a s tzv. z-orderingem, tedy poˇrad´ım komponent. Pokud bychom se rozhodli podokno um´ıstit ne-jhloubˇeji, dojde k tomu ˇze by bylo pˇrekryto komponentou GtkDrawingArea jeho pˇredka. Takto se GLUT aplikace nechovaj´ı, a proto je v knihovnˇe implementov´ano jednoduch´e ˇreˇsen´ı. Pokud si uˇzivatel vyˇz´ad´a zmˇenu poˇrad´ı oken pomoc´ı funkce glutPushWindow, je vˇzdy do pozad´ı pˇresunuta i komponenta GtkDrawingArea rodiˇcovsk´eho okna. U opaˇcn´e funkce glutPopWindow tento probl´em logicky nenast´av´a.
Jedn´ım z posledn´ıch vˇetˇs´ıch probl´em˚u byla automatick´a zmˇena velikosti hlavn´ıho okna dle velikosti do nˇej vloˇzen´ych komponent. Tato vlastnost je pro tvorbu vˇetˇsiny uˇzivatelsk´ych rozhran´ı velice vhodn´a, jelikoˇz staˇc´ı na zaˇc´atku aplikace nastavit hlavn´ı okno dostateˇcnˇe mal´e, pˇridat do nˇej komponenty a okno se samo zvˇetˇs´ı tak, aby vˇsechny komponenty byly zobrazeny viditeln´e a schopn´e zobrazit sv˚uj obsah. Hlavn´ı okno tak´e neumoˇzn´ı zmenˇsen´ı pod hranici program´atorem nastaven´e velikosti. Obvykle se tedy po vygenerov´an´ı hlavn´ıho okna nastav´ı jeho velikost na aktu´aln´ı velikost, ˇc´ımˇz je zaruˇcena minim´aln´ı velikost okna takov´a, ˇ
ze jsou vˇsechny komponenty zobrazeny. Toto chov´an´ı se ovˇsem v˚ubec nehod´ı pro emulaci knihovny GLUT, kter´a umoˇzˇnuje tvoˇrit podokna, kter´a jsou vetˇs´ı neˇz hlavn´ı okno, ale nedojde ke zmˇenˇe velikosti hlavn´ıho okna. Z´aroveˇn umoˇzˇnuje programovˇe nastavit velikost hlavn´ıho okna, ale okno je st´ale moˇzno uˇzivatelem zmenˇsit. Naˇstˇest´ı GTK+ obsahuje funkci gtk window set policy, kter´a pˇredchoz´ı vlastnosti umoˇzˇnuje vypnout. V knihovnˇe je tedy touto funkc´ı nastavena moˇznost uˇzivatelem libovolnˇe zvˇetˇsit i zmenˇsit okno a z´aroveˇn je zak´az´ana automatick´a zmˇena velikosti.
Po vyˇreˇsen´ı pˇredchoz´ıch probl´emu byla implementace vlastn´ıch funkc´ı relativnˇe snadn´a a ve vˇetˇsinˇe pˇr´ıpad˚u se jedn´a pouze o vhodn´a vol´an´ı ekvivalentn´ıch GTK+ funkc´ı.
GLUT Window
GLUT Window GLUT Window
GLUT Window GtkWindow
GtkEventBox
GtkFixed
GtkDrawingArea GtkEventBox GtkEventBox
GtkFixed GtkDrawingArea GtkFixed GtkDrawingArea GtkEventBox GtkFixed GtkDrawingArea
Obr´azek 5.1: Pˇr´ıklad rozloˇzen´ı GTK+ komponent tvoˇr´ıc´ı GLUT okno s podokny
5.4
Funkce pro spr´
avu menu
Menu je v GLUT aplikac´ıch prakticky jedin´y vysoko´urovˇnov´y prvek uˇzivatelsk´eho rozhran´ı. Kompletn´ı implementace se nach´az´ı v souboru gtkglut menu.c.
Aˇckoli je v GTK+ podpora menu na velice vysok´e ´urovni, pˇrece jen nebyla implementace pr´avˇe jednoduch´a. Samotn´y k´od byl bˇehem v´yvoje tˇrikr´at takˇrka kompletnˇe pˇreps´an, aby splˇnoval poˇzadavky na nˇej kladen´e.
Prvn´ı implementace byla naivn´ı a jednalo se v podstatˇe pouze o transformaci GLUT API do GTK+ API. Kaˇzd´e menu tedy bylo vytvoˇreno jako objekt GtkMenu, do kter´eho byly pˇrid´av´any poloˇzky. Pokud mˇelo b´yt do menu pˇrid´ano podmenu, byl pˇrid´an pˇr´ımo odkaz na komponentu GtkMenu. Vˇse fungovalo relativnˇe dobˇre, aˇz na dva probl´emy. Prvn´ı probl´em nastal, pokud nˇekter´e menu bylo z´aroveˇn samostatn´ym menu a podmenu jin´eho menu. Pokud doˇslo ke zruˇsen´ı rodiˇcovsk´eho menu ve kter´em bylo vloˇzeno podmenu, doˇslo z´aroveˇn i ke zruˇsen´ı onoho podmenu.
Pro pochopen´ı pˇr´ıˇciny tohoto chov´an´ı je nutno se ponoˇrit hloubˇeji do mechanism˚u fun-gov´an´ı knihovny GTK+. Ta obsahuje implementaci mechanismu reference counting. Ten je vhodn´y zejm´ena kv˚uli tomu, aby uˇzivatel nemusel uvolˇnovat vˇsechny komponenty kter´e v aplikaci vytvoˇr´ı. Pokud je tedy nˇekter´a komponenta pˇrid´ana do jin´e, napˇr´ıklad tlaˇc´ıtko do okna, st´av´a se okno zodpovˇedn´e za ono tlaˇc´ıtko. To je dosaˇzeno pr´avˇe pouˇzit´ım referenc´ı. Reference v GTK+ jsou dvoj´ıho druhu. Prvn´ı druh, naz´yvan´y fluid, je urˇcen pouze pro pr-votn´ı vytvoˇren´ı komponenty, kdy je hodnota nastavena na 1. Tato reference existuje proto, aby nedoˇslo ke zruˇsen´ı komponenty pˇred t´ım, neˇz je pˇrid´ana do komponenty jin´e. Druh´y typ referenc´ı jsou regul´ern´ı reference a vˇetˇsina komponent m´a pˇri vytvoˇren´ı nastavenu tuto
hodnotu na 0. Pokud vˇsak dojde k pˇrid´an´ı jedn´e komponenty do jin´e, je pˇridan´e kompo-nentˇe zv´yˇsen poˇcet regul´ern´ıch referenc´ı o jedniˇcku a poˇcet fluid referenc´ı je nastaven na 0. V t´eto chv´ıli by jiˇz p˚uvodn´ı ukazatel na komponentu nemˇel b´yt v uˇzivatelsk´em programu nikdy pouˇzit. Jak je vidˇet, v GTK+ aplikaci tedy staˇc´ı zruˇsit vˇsechna hlavn´ı okna a t´ım dojde ke kompletn´ımu uvolnˇen´ı pamˇeti.
Koneˇcnˇe jsme se dostali k j´adru probl´emu. Jelikoˇz menu je tak´e kontejner, je tedy tak´e zodpovˇedn´y za svoje podˇr´ızen´e komponenty a pˇri sv´em zruˇsen´ı ruˇs´ı i je. N´aprava t´eto chyby je relativnˇe jednoduch´a. Kaˇzd´e menu referencovat ve funkci pro vytvoˇren´ı menu a ve funkci pro zruˇsen´ı menu prov´est odreferencov´an´ı.
Druh´y probl´em byl mnohem z´avaˇznˇejˇs´ı a nedal se jiˇz vyˇreˇsit. GLUT podporuje vkl´ad´an´ı jednoho menu jako podmenu do jin´eho menu v´ıcekr´at a tak´e vloˇzen´ı jednoho menu do v´ıce jin´ych menu. GTK+ vˇsak v´ıcen´asobn´e vloˇzen´ı menu nepodporuje a myˇslenka naivn´ı implementace tedy musela b´yt zavrˇzena.
Bylo jasn´e, ˇze funkce pro pr´aci s menu musej´ı b´yt realizov´any ve vlastn´ı reˇzii pouze vhodnou manipulac´ı datov´ych struktur a GTK+ reprezentace menu mus´ı b´yt vytvoˇrena aˇz pˇred samotn´ym zobrazen´ım. Hloup´a metoda vytv´aˇren´ı menu pokaˇzd´e pˇri jeho vyvol´an´ı byla znaˇcnˇe neefektivn´ı, a proto bylo tˇreba zav´est optimalizaci.
Ta spoˇc´ıv´a v n´asleduj´ıc´ı myˇslence. Pokud menu od jeho posledn´ıho zobrazen´ı nebylo zmˇenˇeno, nen´ı tˇreba jej generovat znovu a je moˇzn´e pouˇz´ıt dˇr´ıve vygenerovan´y objekt GtkMenu. Star´a verze menu se ukl´ad´a v promˇenn´e cached gtk menu. Pokud uˇzivatel mˇen´ı menu, kter´e nem´a ˇz´adn´e podmenu, nen´ı s implementac´ı probl´em. Jednoduˇse se nastav´ı promˇenn´a need refresh ud´avaj´ıc´ı, ˇze menu bylo zmˇenˇeno a je tˇreba jej pˇregenerovat. Pokud ovˇsem uˇzivatel mˇen´ı menu, kter´e je souˇc´ast´ı jin´eho menu, je tˇreba aby se nadˇrazen´e menu pˇri sv´em vyvol´an´ı tak´e pˇregenerovalo. Pr´avˇe proto m´a kaˇzd´e menu poloˇzku parent menus, ve kter´e jsou uloˇzena nadˇrazen´a menu. Pokud jsou tedy prov´adˇeny zmˇeny v menu, ne-dojde k nastaven´ı promˇenn´e need refresh jen u mˇenˇen´eho menu, ale tak´e rekurzivnˇe u vˇsech nadˇrazen´ych menu. K dosaˇzen´ı tohoto stavu je vˇsak tˇreba vyˇreˇsit nˇekolik vˇec´ı. Pˇri pˇrid´av´an´ı poloˇzky menu, kter´a je podmenu, je tˇreba v dan´eho podmenu rozˇs´ıˇrit poloˇzku parent menus. Pˇri ruˇsen´ı menu je naopak tˇreba poloˇzku z promˇenn´e parent menus odstranit. Z´aroveˇn je tˇreba myslet i na GLUT funkce mˇen´ıc´ı poloˇzku menu na podmenu a naopak, tedy glutChangeToSubMenu a glutChangeToMenuEntry. Zde je nutno tak´e nakl´adat s promˇennou parent menus obezˇretnˇe, aby nedoch´azelo k tomu, ˇze nadˇrazen´e menu bude informov´ano o zmˇenˇe menu, kter´e jiˇz nen´ı jeho podmenu, nebo naopak nebude informov´ano o zmˇenˇe sv´eho podmenu.
Na promˇennou parent menus je vhodn´e se pod´ıvat jeˇstˇe z jin´eho ´uhlu a to na volbu da-tov´e struktury. Je jasn´e, ˇze mus´ı podporovat pˇrid´an´ı, odeb´ır´an´ı a pr˚uchod poloˇzkami. Nav´ıc vˇsak mus´ı oˇsetˇrit pˇr´ıpad v´ıcen´asobn´eho vloˇzen´ı menu do jin´eho menu. V tomto pˇr´ıpadˇe nen´ı moˇzn´e uloˇzit hodnotu jen jednou. To by mohlo v´est k situaci, kdy by pˇri odebr´an´ı jednoho podmenu pˇrestal mechanizmus fungovat. Jin´e, nepˇr´ıliˇs efektivn´ı ˇreˇsen´ı by bylo uloˇzit jednu hodnotu v´ıcekr´at. V takov´em pˇr´ıpadˇe by bud’ doch´azelo k v´ıcen´asobn´emu upozorˇnov´an´ı jednoho menu, nebo by se znaˇcnˇe zt´ıˇzil k´od vykon´avaj´ıc´ı upozorˇnov´an´ı nadˇrazen´ych menu.
ˇ
Reˇsen´ı, kter´e bylo nakonec zvoleno a implementov´ano vych´az´ı z metody reference counting. O celou z´aleˇzitost se star´a datov´a struktura, autorem pojmenovan´a refset. N´azev je sloˇzen ze slov reference a set, tedy mnoˇzina. Opravdu se jedn´a o mnoˇzinu, kde kaˇzd´a poloˇzka obsahuje hodnotu a poˇcet referenc´ı na danou hodnotu. Implementace se nach´az´ı v souboru gtkglut refset.c. Z´akladn´ı operace t´eto datov´e struktury je ref, kter´a prov´ad´ı zv´yˇsen´ı poˇctu referenc´ı a unref, kter´a naopak prov´ad´ı sn´ıˇzen´ı poˇctu referenc´ı. Struktura je postavena na datov´e struktuˇre seznamu. O vhodnosti t´eto datov´e struktury by bylo moˇzno diskutovat,