C dla kaûdego (cz. 4.) ---------------------- OTWIERANIE EKRANÓW Kamil Iskra, Dariusz Ûbik Bez zbëdnego wstëpu przejdúmy do przykîadu, nawiâzujâcego do poprzedniego odcinka. Chodzi o listing 7. Program demonstruje otwarcie ekranu publicznego. Uûytkownik moûe sam wybraê tryb, w jakim ma byê wyôwietlany ekran, podajâc programowi w linii argumentowej identyfikator trybu wyôwietlania, czyli odpowiedniâ liczbë, zdefiniowanâ w pliku "graphics/modeid.h". Liczbë të program otrzymuje w formie napisu (w argv[1]) -- konwersjâ na wartoôê liczbowâ zajmie sië za nas standardowa funkcja strtoul(), która przy uûytych przez nas parametrach akceptuje liczby podane w trybie szesnastkowym (poprzedzone znakiem 0x bâdú 0X), ósemkowym (poprzedzone zerem) bâdú dziesiëtnym -- jej dokîadny opis znajdziesz w Zalecanej Literaturze ("Jëzyk ANSI C"). Jeûeli uûytkownik nie poda tego parametru, to ekran zostanie otwarty w trybie hi-res, przy uûyciu standardowego monitora (a wiëc w wypadku wiëkszoôci Amig w Polsce -- PAL). Program sprawdza, czy podana wartoôê jest sensowna (ModeNotAvailable()), otwiera ekran (OpenScreenTagList()) i uaktywnia go (PubScreenStatus()). Nastëpnie czeka na naciôniëcie [Return] i zamyka ekran. Chcâc sprawdziê, czy program rzeczywiôcie dziaîa tak, jak powinien, uruchom go, a nastëpnie uruchom listing 6. z parametrem LISTING7 -- okno powinno sië otworzyê na naszym ekranie z listingu 7. Warto teû sprawdziê, czy dziaîa otwieranie ekranu w róûnych rozdzielczoôciach. Uruchom listing 7. tak: Listing7 0x11000 Szybkie spojrzenie do "graphics/modeid.h" i juû wiesz, co to za tryb: NTSC_MONITOR_ID. Uruchamiamy wiëc, a tu: Podano nieznany identyfikator trybu wyôwietlania! Czyûby coô byîo nie tak? Nie, wszystko jest w porzâdku! Po prostu nie moûna uûywaê trybów, których sterowniki nie sâ uruchomione. Uruchom wiëc program "Storage/Monitors/NTSC" i... tym razem dziaîa, tzn. ekran wariuje (przynajmniej u mnie -- mój monitor wyôwietla tylko obraz w trybie PAL). A co sië stanie, gdy sië uruchomi dwa listingi 7 na raz -- np. z dwóch Shelli? Nie mogë otworzyê ekranu! Jest to zwiâzane z tym, ûe w systemie nie mogâ istnieê dwa ekrany publiczne o tej samej nazwie. Z tego wîaônie powodu wiëkszoôê aplikacji ma na koïcu nazwy ekranu publicznego cyfrë -- normalnie jest to "1", ale gdy uruchomisz kolejne kopie tego samego programu, to w nazwie bëdzie "2", "3" itd. Moûesz wprowadziê odpowiednie modyfikacje w listingu 7., aby i on tak sië zachowywaî -- sugerujemy "wrzuciê" OpenScreenTags() w pëtlë i stworzyê zmiennâ, zawierajâcâ nazwë ekranu publicznego, która powinna byê po kaûdym nieudanym OpenScreenTags() modyfikowana -- poprzez zwiëkszanie sië cyferki na jej koïcu. Program powinien jednak wiedzieê, dlaczego nie udaîo sië otworzyê ekranu. Moûe wcale nie dlatego, ûe jest juû inny o tej samej nazwie, ale dlatego, ûe brakuje pamiëci? Przewidzieli to twórcy systemu -- sîuûy do tego tag: SA_ErrorCode -- jego parametrem jest adres zmiennej typu ULONG, do której zostanie zapisane, dlaczego ekranu nie moûna byîo otworzyê, np. gdy ekran publiczny o tej nazwie juû istnieje, zostanie tam odnotowana staîa OSERR_PUBNOTUNIQUE, gdy brakuje pamiëci -- OSERR_NOMEM bâdú OSERR_NOCHIPMEM. Staîe sâ zdefiniowane w pliku "intuition/screens.h". Otwarty przez nas ekran bëdzie uûywaî standardowej czcionki systemowej, ustawionej przez uûytkownika w systemowym programie Font. Czcionka ta jest zawsze nieproporcjonalna (fixed width), tzn. szerokoôê wszystkich liter jest taka sama. Istniejâ dwa tagi kontrolujâce to, jaka czcionka ma zostaê uûyta na ekranie: SA_SysFont -- ustala, która z ustawionych przez uûytkownika w Font czcionek ma byê uûyta: przy parametrze 0 (wartoôê domyôlna) uûyta zostanie czcionka systemowa, a przy 1 -- czcionka ekranu Workbencha (która moûe byê proporcjonalna). SA_Font -- parametrem jest struktura "TextAttr", którâ omówimy za dwa miesiâce -- specyfikuje ona dokîadnie nazwë i rozmiar czcionki, która ma zostaê uûyta na ekranie. I znów powtórzë mój maîy apel (tak, wiem, ûe robië sië nudny, ale bëdë to powtarzaî tak dîugo, aû wejdzie Wam to w krew!): nie uûywajcie tego tagu bez waûnego powodu, a jeûeli chcecie go uûyê, to dajcie uûytkownikowi moûliwoôê wybrania dowolnej czcionki. Szczególnie denerwujâca jest sytuacja, gdy posiadacz monitora o rozdzielczoôci 800 x 600 pikseli musi wypatrywaê oczy, bo program uûywa maciupeïkiej czcionki topaz 8. Powinniôcie jeszcze wiedzieê, w jaki sposób zmienia sië ustawienie kolorów ekranu (tylko pamiëtajcie o naszym apelu!). Robi sië to za pomocâ nastëpujâcych funkcji z biblioteki "graphics.library": void SetRGB4( struct ViewPort *vp, long index, unsigned long red, unsigned long green, unsigned long blue ); void SetRGB32( struct ViewPort *vp, unsigned long n, unsigned long r, unsigned long g, unsigned long b ); Pierwsza z nich jest starâ funkcjâ, która umoûliwia ustawienie kolorów w wypadku palety 12 bitów (po 4 bity na kaûdâ skîadowâ). Druga funkcja pojawiîa sië razem z nowymi koôêmi graficznymi w OS 3.0 i jest ona stworzona zdecydowanie na wyrost -- obsîuguje 96-bitowâ paletë (po 32 bity na kaûdâ skîadowâ). Rzecz jasna, obecne ukîady graficzne nie majâ takich moûliwoôci, wiëc parametry sâ "zaokrâglane". Znaczenie parametrów jest nastëpujâce: vp -- adres struktury "ViewPort", wchodzâcej w skîad struktury "Screen" -- pole "ViewPort". W strukturze tej sâ zapisane ustawienia kolorów, tryb wyôwietlania ekranu itp. index, n -- numer koloru, który ma zostaê zmieniony red, green, blue -- (w funkcji SetRGB4()) nowe wartoôci poszczególnych skîadowych -- od 0 do 15 r, g, b -- (w funkcji SetRGB32()) nowe wartoôci poszczególnych skîadowych -- od 0 (minimum nasycenia) do 0xFFFFFFFF (maksimum nasycenia). Przydatna jest moûliwoôê otwarcia ekranu o takich samych atrybutach, jak Workbench, jako ûe atrybuty Workbencha uûytkownik moûe îatwo dostosowaê do wîasnego "widzimisië". Pomyôleli o tym twórcy systemu: SA_LikeWorkbench -- powoduje, ûe otwarty ekran bëdzie kopiâ ekranu Workbencha -- bëdzie miaî jego rozmiar, liczbë kolorów, tryb wyôwietlania, czcionkë itp. Niestety, twórcy systemu pomyôleli o tym nieco zbyt póúno -- tag ten jest dostëpny dopiero od OS 3.0. W OS 2.04 trzeba go wiëc emulowaê. Aby zrobiê to dobrze, musicie poznaê jeszcze trzy funkcje: struct DrawInfo *GetScreenDrawInfo( struct Screen *screen ); Funkcja zwraca adres struktury "DrawInfo", naleûâcej do ekranu "screen", bâdú 0, gdy nie moûna tego zrobiê. Struktura "DrawInfo" jest zdefiniowana w pliku "intuition/screens.h" -- nas interesuje w niej pole "dri_Pens", bëdâce wskaúnikiem na tablicë "penów" oraz "dri_Depth", zawierajâce informacjë o liczbie kolorów na ekranie. Gdy struktura "DrawInfo" nie jest nam juû dîuûej potrzebna, naleûy uûyê funkcji: void FreeScreenDrawInfo( struct Screen *screen, struct DrawInfo *drawInfo ); Trzecia funkcja jest zawarta w "graphics.library": LONG GetVPModeID( struct ViewPort *vp ); Zwraca ona tryb wyôwietlania danego ViewPortu (patrz wyûej -- opis SetRGB4()) bâdú INVALID_ID, gdy nie moûe tego zrobiê. SA_AutoScroll -- jeûeli parametrem jest TRUE i szerokoôê/wysokoôê ekranu jest na tyle duûa, ûe niecaîy ekran moûemy na raz zobaczyê, to po przesuniëciu myszy do krawëdzi ekranu bëdzie on przewijany (moûna to najlepiej zrozumieê, eksperymentujâc w systemowym programie ScreenMode z opcjâ AUTOSCROLL oraz szerokoôciâ i wysokoôciâ ekranu). Czas wiëc przetestowaê to wszystko -- patrz listing 8. Gdy program wykryje obecnoôê systemu 3.0 bâdú nowszego, to idzie na îatwiznë i po prostu uûywa tagu "WA_LikeWorkbench". W wypadku systemu 2.x pobiera informacje o "penach" i liczbie kolorów (GetScreenDrawInfo()) oraz trybie wyôwietlania (GetVPModeID()), pozostaîe zaô informacje bierze po prostu ze struktury "Screen" ekranu Workbencha. Gdy ekran ma wîâczony AutoScroll, to w polu "Flags" struktury "Screen" jest ustawiona flaga AUTOSCROLL. Na dziô wystarczy. W nastëpnej czëôci trochë sobie porysujemy po okienkach. Przypominam, ûe mojâ stronë WWW moûna obejrzeê w Internecie pod adresem: http://www.uci.agh.edu.pl/student/infgrp/iskra/public_html/index.htm. Znajdujâ sië tam m.in. listing z kursu. Wszelkie e-maile proszë kierowaê pod adresem: iskra@student.uci.agh.edu.pl.