programowanie
Diagram części
Twojego komputera
Marek Sawerwain
tym miesiącu zajmiemy Pętla GUI jest realizowana samo-
się napisaniem programu, dzielnie przez GNOME, więc tuż po wy-
który będzie wyświetlał konaniu funkcji gtk_main() kontrolę nad
Wkilka podstawowych in- naszym programem przejmuje środo-
formacji o komputerze, na którym został wisko graficzne. Nie musimy się trosz-
uruchomiony (będą one dotyczyć typu pro- czyć np. o przewijanie zawartości okna
cesora, karty graficznej oraz muzycznej). z diagramem bądz jego odświeżanie
Nie będziemy tych danych wyświetlać  tym zajmuje się GNOME oraz biblio-
w postaci tylko i wyłączenie tekstowej, teka GTK+.
ale postaramy się o utworzenie nieskompli-
kowanego diagramu. Utworzenie interfejsu
Program napiszemy dla środowiska Interfejs programu, podobnie jak w po-
GNOME.  Wielka stopa posiada w swym przednich aplikacjach, które opisywali-
arsenale jeden bardzo przydatny widget śmy na łamach Linux+, tworzymy za
 jest nim obiekt Canvas. Znakomicie pomocą Glade i nie korzystamy z pliku
nadaje się on do tworzenia diagramów, glade, ale z kodu wygenerowanego samo-
więc warto wykorzystać bogate możli- czynnie przez  budowniczego interfejsu
wości tej kontrolki we własnym pro- po wybraniu przycisku Buduj (ang. Build).
gramie. Tym razem jest to projekt GNOME, więc
nie ograniczamy się tylko i wyłącznie do
Budowa naszego programu biblioteki GTK+. Z tego powodu inicjali-
Na początku warto dokładnie prześle- zacja systemu GUI dokonywana w fun-
dzić, jakie czynności należy wykonać kcji main zaczyna się w następujący spo-
w tworzonym programie. Pokazuje to sób:
Rysunek 1. Tym razem nie musimy kon-
struować specjalnej pętli, aby śledzić zda- gnome_program_init
S
rzenia pojawiające się w trakcie funk- ("harddraw", "1.0",
S
cjonowania programu, gdyż nasz pro- LIBGNOMEUI_MODULE,
S
gram tylko raz rysuje diagram. Z tego argc, argv, GNOME_PARAM_
powodu pierwsze czynności to inicjaliza- APP_DATADIR, NULL, NULL);
cja biblioteki Kudzu oraz interfejsu użyt-
DVD
kownika. Najważniejsze zagadnienie to W ten sposób nasz program staje się peł-
Po uruchomieniu Linux+ Live
odczyt informacji, które mają pojawić się noprawnym programem dla środowiska
DVD można przetestować
na tworzonym diagramie, oraz naryso- GNOME. Po wywołaniu tej funkcji two-
stworzoną aplikację oraz ją
wanie samego diagramu. W związku rzymy okno główne naszej aplikacji:
samodzielnie przekompilować.
z tym, z obiektu  rysowanie diagramu
wychodzi pięć pozostałych obiektów, które MainWin = create_MainWin ();
Na płycie CD/DVD
reprezentują funkcje odpowiedzialne za
Na płycie CD/DVD znajduje się
kod zródłowy programu. zbieranie informacji o poszczególnych Jest to, jak widać, identyczna czynność
komponentach. jak przy programach korzystających tylko
38 luty 2006
programowanie
C/C++/Canvas/Kudzu
Podczas tworzenia interfejsu w Glade nie
Listing 1. Odczyt ilości dostępnej
Kompilacja programu
zostały określone wymiary diagramu,
pamięci RAM
Do kompilacji programu wszystkie po-
a dokładniej obszaru, na jakim będzie on
trzebne pakiety z pewnością znajdują się
rysowany. Robimy to teraz w następują-
w dystrybucji używanej przez Czytelni-
cy sposób: void total_memory_get() {
czkę/Czytelnika. GNOME to element stały
int linelen;
dla znakomitej większości dystrybucji, po-
S
gnome_canvas_set_scroll_region FILE *f=NULL;
dobnie jak biblioteka Kudzu. Jest ona sto-
S
(GNOME_CANVAS (CanvasArea), f=fopen("/proc/meminfo", "r");
sowana do wykrywania sprzętu i jego
-300, 0, 800, 400); if(f!=NULL) {
konfiguracji podczas inicjacji systemu.
S
getline(&tmp01,
Z tego powodu warto sprawdzić, czy w sys-
Kolejne czynności to uzyskiwanie infor- &linelen, f);
temie, w którym chcemy skompilować
macji oraz rysowanie samego diagramu tmp01[strlen(tmp01)-1]=0;
opisywany w artykule program, znajdują
S
(funkcja canvas_setup()). Po narysowaniu strcpy(&totalmemory[0],
się pakiety dla developerów.
diagramu podłączamy dodatkowe sygna- strstr(tmp01,":")+7);
Najprostszy skrypt makefile, który
ły. Jest to m.in. obsługa przycisku zamy- if(tmp01) free(tmp01);
przeprowadzi kompilację, może przedsta-
kania okienka. Funkcją gtk_widget_show }
wiać się następująco:
(MainWin); wyświetlamy okno programu fclose(f);
na ekranie. Ostatnim krokiem jest urucho- }
all:
mienie głównej pętli GUI, jak zwykle funk-
S
gcc -c src/interface.c
cją gtk_main();. Następne wyrażenie, jak widzimy z Listin-
S
-I./src `pkg-config --cflags
gu 1, wpisuje 0 na końcu zmiennej tmp01,
S
gtk+-2.0 libgnomeui-2.0`
Odczytanie informacji w której jest przechowywana informa-
-I./include
o dostępnej pamięci RAM cja o dostępnej pamięci  przedstawia
S
gcc -c src/support.c
i procesorze się ona w następujący sposób tekst :
S
-I./src `pkg-config --cflags
Uzyskanie informacji o dostępnej pamię- liczba. Naszym zadaniem jest uzyska-
S
gtk+-2.0 libgnomeui-2.0`
ci RAM oraz podstawowych informacji nie liczby, więc wystarczy odczytać tekst
-I./include
o procesorze to zadania względnie łatwe, leżący na prawo od dwukropka. W tym
S
gcc -c maincode.c
pod warunkiem, że wiemy, gdzie szukać celu znakomicie nadaje się funkcja strstr.
S
-I./src `pkg-config --cflags
tego typu informacji. Najlepszym zródłem Ostatecznie, umieszczenie w zmiennej
S
gtk+-2.0 libgnomeui-2.0`
jest katalog /proc oraz dwa następują- totalmemory poprawnej wartości sprowa-
-I./include
ce pliki: meminfo, w którym, zgodnie z naz- dza się do następującej linii kodu:
S
gcc -o harddraw maincode.o
wą, znajdują się informacje o pamięci,
S
interface.o support.o -lkudzu
S
oraz cpuinfo, gdzie zawarte są wszystkie strcpy(&totalmemory[0],
S
-lpci `pkg-config --libs
najważniejsze informacje na temat proce- strstr(tmp01,":")+7);
gthread-2.0 gtk+-2.0 libgnomeui-2.0`
sora.
Listing 1 przedstawia kod krótkiej Warto jeszcze dopowiedzieć, w jakim
Dwie pierwsze linie kompilują kod wygene
funkcji, która odczytuje informacje o dos- celu należy do wyniku strstr dodać war-
rowany przez program Glade. Trzecia li-
tępnej pamięci RAM. Plik /proc/meminfo tość siedem  w ten sposób przesuwa-
nia reguły all jest odpowiedzialna za kom-
to plik tekstowy, a potrzebne nam infor- my wskaznik o siedem znaków, które są
pilację kodu naszej aplikacji. Ostatnia
macje znajdują się w pierwszej linii pli- w rzeczywistości spacjami.
czwarta linia dokonuje konsolidacji osta-
ku. Odczytanie informacji o procesorze
tecznej postaci programu. Ponieważ używa-
Każdy, kto po raz pierwszy zajrzy odbywa się w dość podobny sposób, co
my biblioteki Kudzu, musimy dołączyć dwie
do katalogu proc, zawsze się dziwi, iż potwierdza Listing 2. Tym razem musimy
istotne biblioteki: -lkudzu -lpci. Pierwsza
większość plików jest zerowej długo- odczytać więcej linii tekstu, ale potrzebne
z nich jest bezpośrednio odpowiedzial-
ści. Plik meminfo także posiada taki roz- będą nam tylko cztery.
na za bibliotekę, a druga dołącza funk-
miar, ale zawiera cenne informacje. Ich Sposób postępowania w tym przy-
cje do poprawnej obsługi szyny PCI, gdyż
wydobycie zaczynamy od otworzenia padku różni się tylko obecnością pętli
większość urządzeń jest podłączona wła-
pliku, tak jak to czynimy z każdym in- for, w której odczytujemy linię tekstu za
śnie za pomocą PCI (w pewnym sensie
nym plikiem: pomocą getline. Umieszczamy zero na
nawet karta graficzna, choć podłączona
końcu tekstu, a następnie przydzielamy
przez AGP, jest także widziana z poziomu
f=fopen("/proc/meminfo", "r"); pamięć odpowiedniemu elementowi w ta-
szyny PCI).
blicy info:
Po sprawdzeniu, czy udało się ten plik
i wyłączenie z GTK+. Następnym krokiem otworzyć, wystarczy odczytać jedną linię info[i]=malloc(strlen(tmp01)-1);
jest uzyskanie referencji do widgetu: tekstu za pomocą funkcji getline (jest to
funkcja standardowa, a jej prototyp znaj- Pozostaje nam jeszcze tylko skopiować
S
CanvasArea=lookup_widget duje się w pliku stdio.h): fragment tekstu na prawo od dwukropka:
(MainWin, "CanvasArea");
getline(&tmp01, &linelen, f); strcpy(info[i], strstr(tmp01,":")+2);
www.lpmagazine.org 39
programowanie
S
wszystkich urządzeń, gdyż skupimy się for (x = 0; devlist[x]; x++)
Listing 2. Odczyt informacji o procesorze
na napędach optycznych, dyskach twar- {// treść pętli }
z pliku /proc/cpuinfo
dych, kartach dzwiękowych oraz kartach
graficznych. Funkcja probeDevices tak konstruuje listę,
void get_cpu_info() { W programie funkcje zajmujące się iż po ostatnim wpisie zostaje umieszczona
int i, linelen; uzyskaniem tych informacji posiadają wartość NULL. W pętli, jak widać, wyko-
FILE *f=NULL; następujące nazwy: cdrom_list(), hd_ rzystujemy ten fakt, aby opisać warunek
f=fopen("/proc/cpuinfo", "r"); list(), audio_list() oraz video_list(). zakończenia pętli, podając tylko wyraże-
if(f!=NULL) { Wszystkie funkcje są zbudowane w dość nie devlist[x].
tmp01=NULL; podobny sposób, jak zostało to pokazane Treść pętli dla urządzeń typu CD-
for(i=0;i<18;i++) { na Listingu 3. Dla przykładu opiszę, w jaki ROM przedstawia się następująco:
getline(&tmp01, &linelen, f); sposób odczytujemy informacje o dostęp-
S
tmp01[strlen(tmp01)-1]=0; nych napędach optycznych. sprintf(tmptxt, "device: /dev/
S S
info[i]=malloc(strlen W pierwszej kolejności należy odpo- %s\ndesc: %s\n", devlist[x]
S
(tmp01)-1); wiednio zadeklarować zmienną, w której ->device, devlist[x]
S S
strcpy(info[i], znajdzie się lista dostępnych urządzeń: ->desc); strcat(&cdromdesc[0],
strstr(tmp01,":")+2); struct device **devlist;. Kolejnym &tmptxt[0]); cdrom_count++;
} ważnym krokiem jest uzyskanie listy
if(tmp01) free(tmp01); urządzeń należących do potrzebnej klasy. W pierwszej linii kodu instrukcją sprintf
} Ponieważ interesują nas napędy optyczne, tworzymy dwie linie tekstu, gdzie umie-
fclose(f); to ta klasa urządzeń jest reprezentowana szczamy nazwę urządzenia, do którego
} przez stałą CLASS_CDROM. Ostatecznie, aby podłączony jest napęd CD-ROM. Od-
uzyskać listę urządzeń, wystarczy skorzy- czytujemy także nazwę symboliczną, przy-
stać z funkcji probeDevices. Sprawdzi ona, czym zazwyczaj będzie to nazwa pro-
W ten sposób odczytamy wszystkie osiem- czy w systemie są dostępne urządzenia ducenta, oznaczenie napędu itd. Uzyskane
naści linii z pliku. określonego typu bez ich inicjalizacji oraz dwie linie tekstu są umieszczane w zmien-
konfiguracji: nej tmptxt, a jej zawartość jest dołącza-
Informacje na do zmiennej tekstowej cdromdesc.
S
z systemu Kudzu devlist = probeDevices Zwiększamy także licznik napędów CD-ROM
Pozostałe informacje o tym, co znajduje ( CLASS_CDROM, probeBus, PROBE_ALL); dostępnych w systemie  cdrom_count.
się w komputerze, uzyskamy za pomocą W ten sposób za pomocą Kudzu uzyska-
biblioteki Kudzu. W naszym programie, Wszystkie dostępne urządzenia znajdą się my informacje o tym, ile napędów jest
aby zastosować pochodzące z niej funkcje, w tablicy devlist, którą możemy przeglą- dostępnych w systemie, w którym został
należy dołączyć odpowiedni plik nagłów- dać oraz odczytywać potrzebne informa- uruchomiony program.
kowy: cje. Najłatwiej tę czynność wykonać za W podobny sposób uzyskujemy in-
pomocą pętli for: formacje o pozostałych komponentach.
#include
Zanim uzyskamy listę urządzeń znajdu-
jących się w komputerze, należy zaini-
cjalizować w odpowiedni sposób system
Kudzu:
initializeDeviceList();
initializeBusDeviceList(probeBus);
Warto zwrócić uwagę na to, w jaki sposób
została zadeklarowana zmienna probeBus:
S
enum deviceBus probeBus =
BUS_UNSPEC & ~BUS_SERIAL;
Oznacza to, iż Kudzu będzie przeszuki-
wać urządzenia znajdujące się na dowol-
nej szynie, ale nie będzie to złącze sze-
regowe (tzw. porty COM, które ostat-
nio już wychodzą z użycia). Po inicjali-
zacji Kudzu jesteśmy gotowi do odczy-
Rysunek 1. Najważniejsze zdarzenia w programie
tu urządzeń. Nie będziemy odczytywać
40 luty 2006
programowanie
C/C++/Canvas/Kudzu
Zanim przystąpimy do rysowania dia-
Listing 3. Odczyt informacji o karcie graficznej z systemu Kudzu
gramu, należy dysponować wskazaniem
na obiekt root widgetu AreaCanvas, w któ-
void video_list() { rym jest rysowany cały diagram. Uzys-
struct device **devlist; kanie obiektu root jest łatwe i przedstawia
int x; się następująco:
char tmptxt[512];
S
devlist = probeDevices( CLASS_VIDEO, probeBus, PROBE_ALL); root = gnome_canvas_root
if (devlist) { (GNOME_CANVAS (CanvasArea));
for (x = 0; devlist[x]; x++) {
if(strcmp(devlist[x]->driver, "unknown")) { Pózniej musimy wywołać funkcję video_
S
sprintf(tmptxt, "driver: %s\ndesc: %s\n", list. Jej zadaniem jest wykrycie typu
devlist[x]->driver, devlist[x]->desc); karty graficznej oraz utworzenie komu-
S
if(strlen(devlist[x]->device) > video_strlen) nikatu tekstowego, który znajduje się
video_strlen=strlen(devlist[x]->device); w diagramie. Bezpośrednio po wywoła-
S
if(strlen(devlist[x]->desc) > video_strlen) niu tej funkcji sprawdzamy, czy zmien-
video_strlen=strlen(devlist[x]->desc); na video_count jest większa od zera, co
strcat(&videodesc[0], &tmptxt[0]); oznacza, iż musimy wiedzieć, czy jakakol-
video_count++; wiek karta graficzna została wykryta przez
} Kudzu. Jeśli udało się poprawnie wykryć
} kartę, to obliczamy przesunięcie wzglę-
} dem osi Y. Jest to istotne, ponieważ wcze-
freeDeviceList(); śniej wyświetlamy informacje o napędach
} i dyskach. Ich ilość w systemie nie jest
naturalnie stała i można mieć np. jeden
napęd CDROM i dwa albo trzy dyski
Potwierdza to także Listing 3. Względem wdę dwie czynności: odczytujemy infor- twarde. Ponieważ wszystkie informacje
przykładu, który omówiłem powyżej, macje o sprzęcie (w sposób opisany o napędach są wyrównane do prawej
dodatkowo sprawdzamy długość ciągu w poprzednich akapitach) oraz doko- strony, to zmienia się tylko ich pozycja
znaków opisujących urządzenie. Infor- nujemy wizualizacji tych informacji. pionowa zapisywana w zmiennej last_y.
macja ta jest przydatna, aby na rysunku Jej fragmenty zostały przedstawione Odstęp pomiędzy poszczególnymi warto-
utworzyć prostokąt odpowiedniej wiel- na Listingu 4. Funkcja ta jest znacznie ściami wynosi dokładnie 10 punktów (nie
kości, w którym zmieści się cały komu- dłuższa, ale technika rysowania poszcze- są to piksele, ale wewnętrzne jednostki
nikat. gólnych fragmentów diagramy jest po- obiektu Canvas).
dobna, więc przedstawię ją na przykła- Narysowanie prostokąta jest równo-
Rysujemy diagram dzie karty graficznej. ważne utworzeniu obiektu i w tym celu
Wiemy już, w jaki sposób odczytać po-
trzebne informacje  dzięki Kudzu może-
my uzyskać jeszcze więcej informacji
o sprzęcie, więc zachęcam do modyfikacji
programu, np. dodając informację o karcie
sieciowej. Teraz należy zastanowić się,
w jaki sposób narysować diagram.
Jeden ze sposobów zdradza Rysunek 2.
Jak widać, w lewej dolnej części znajduje
się ikona komputera, z której za pomo-
cą strzałek wskazujemy na pozosta-
łe części diagramu. W odpowiednich
prostokątach prezentujemy informacje
o karcie graficznej i dzwiękowej, wyświe-
tlamy ilość dostępnej pamięci RAM
oraz kilka informacji o procesorze.
Dwa najwyżej umieszczone prostokąty
po prawej stronie odnoszą się do na-
pędów optycznych oraz twardych dys-
ków.
Funkcja, która zajmuje się rysowa-
niem diagramu, nosi nazwę canvas_
Rysunek 2. Przykładowy diagram sprzętowy wygenerowany przez program HardDraw
setup(). Wykonujemy w niej tak napra-
www.lpmagazine.org 41
programowanie
poprawne określenie szerokości prosto-
Listing 4. Najważniejsze fragmenty funkcji rysującej diagram
kąta. Warto w tym momencie raz jesz-
void canvas_setup() { cze przeczytać Listing 3, aby zobaczyć,
char txt[512]; w jaki sposób nadawana jest wartość tej
double last_x=0, last_y=0; zmiennej.
root = gnome_canvas_root (GNOME_CANVAS (CanvasArea)); Gdy prostokąt jest narysowany, to
/* usunięte fragmenty */ drugie wywołanie konstruktora z funk-
cją gnome_canvas_text_get_type, która
/* video list box */ odpowiada za obiekt reprezentujący
video_list(); tekst, spowoduje, że w narysowanym
video_strlen=(video_strlen+4)*10; prostokącie zostanie umieszczony tekst
if(video_count>0) { z krótkim opisem typu karty graficz-
videos_x=210; nej. W przypadku obiektu canvas ważna
if( last_y == 0 ) jest kolejność rysowania obiektów, gdyż
last_y=30; ten narysowany wcześniej może zostać
else zakryty przez ten narysowany pózniej.
last_y+=10; W naszym przypadku celowo rysuje-
videos_y=last_y; my w pierwszej kolejności prostokąt,
last_y=videos_y+(audio_count)*50; a dopiero pózniej dodajemy komunikat
S
videos_box=gnome_canvas_item_new (root, gnome_canvas_ tekstowy.
S
rect_get_type (), "x1",videos_x,"y1", videos_y,
S
"x2", videos_x+video_strlen, "y2", videos_y+(video_count)*50, Strzałki
S
"outline_color", "black", "fill_color", "white", Ostatnie zadanie, które wykonujemy w funk-
"width_pixels", 2, NULL); cji canvas_setup, to narysowanie strzałek
S
gnome_canvas_item_new (root, gnome_canvas_text_get_type (), pomiędzy ikoną komputera a poszcze-
S
"text", &videodesc[0], gólnymi prostokątami. Jak widać na Ry-
S
"x", videos_x+video_strlen/2, sunku 2, w zależności od miejsca umiesz-
S
"y", videos_y+(video_count)*30, czenia prostokąta, strzałki są skierowa-
S
"font", "monospace bold 10", ne albo w ścianę dolną, albo w lewą.
S
"justification", GTK_JUSTIFY_CENTER, Przykładowe wywołanie funkcji draw_
S
"fill_color", "firebrick", arrow jest następujące:
NULL);
} draw_arrow(cpu_box, -95, 290,0);
/* usunięte fragmenty */
/* arrow to boxes */ Pierwszy argument to obiekt prostokąt, do
draw_arrow(cpu_box, -95, 290,0); którego chcemy skierować strzałkę. Dwie
/* pozostałe strzałki */ następne wielkości to współrzędne począt-
} ku. W ostatnim argumencie umieszcza-
my numer ściany, do której ma być skiero-
wana strzałka. Zero oznacza ścianę dolną,
wykorzystujemy uniwersalny konstruktor prostokąt umieścić pod poprawnymi a jedynka ścianę lewą.
o nazwie gnome_canvas_item_new: współrzędnymi. Lewy górny róg to Technika rysowania strzałki jest dość
parametry o nazwach x1,y1, natomiast prosta i sprowadza się odczytania współ-
S
videos_box = gnome_canvas_item_new x2,y2 to prawy dolny róg. Jak widać, rzędnych x1, y1, x2, y2 obiektu, do którego
S
(root, gnome_canvas_rect_ wykorzystujemy zmienną video_count, chcemy skierować strzałkę:
S
get_type (), choć naturalnie w przypadku kart gra-
S S
"x1",videos_x,"y1", videos_y, ficznych zazwyczaj mamy do czynie- tx1 = GNOME_CANVAS_RECT
S
"x2", videos_x+video_strlen, nia tylko z jedną. Podobna zmienna (dst_box)->re.x1;
S S
"y2", videos_y+(video_count)*50, jest potrzebna w przypadku twardych ty1 = GNOME_CANVAS_RECT
S
"outline_color", "black", dysków oraz dla napędów optycznych. (dst_box)->re.y1;
S S
"fill_color", "white", Jej wartość decyduje o wysokości prosto- tx2 = GNOME_CANVAS_RECT
"width_pixels", 2, NULL); kąta. W ten sposób opis urządzeń będzie (dst_box)->re.x2;
S
w całości mieścił się w rysowanym pro- ty2 = GNOME_CANVAS_RECT
Pierwszy argument to obiekt root, stokącie. Podobne znaczenie pełni (dst_box)->re.y2;
a następnym jest typ zwracany przez zmienna video_strlen. Ponieważ kartę
funkcję. W naszym przypadku funkcja graficzną opisujemy dwiema liniami Drugi etap to wyznaczenie dwóch punk-
gnome_canvas_rect_get_type reprezen- tekstu, w zmiennej video_strlen jest tów: początkowego i końcowego. GNOME
tuje prostokąt (ang. rectangle). Pózniej zawarta ilość znaków dłuższej z linii. wykorzystuje typ GnomeCanvasPoints,
następują parametry niezbędne, aby Znajomość tej wartości pozwala nam na aby przechowywać kolejne współrzę-
42 luty 2006
programowanie
C/C++/Canvas/Kudzu
Tabela 1. Niektóre parametry obiektów rysunkowych widgetu Canvas
Nazwa parametru Typ Opis
Obiekt prostokąt
x1,y1 double współrzędne lewego górnego rogu
prostokąta
x2,y2 double współrzędne prawego dolnego rogu
prostokąta
outline_color char* nazwa koloru ramki
fill_color char* nazwa koloru wypełnienia
width_pixels double grubość ramki
Obiekt tekst
text char* treść komunikatu
x,y double współrzędne tekstu
font char* nazwa czcionki, styl oraz rozmiar
justification GtkJustification typ wyrównania tekstu
fill_color char* kolor atramentu
Obiekt linia
points GnomeCanvasPoints* współrzędne poszczególnych punktów
należących do krzywej
fill_color char* nazwa koloru wypełnienia linii
first_arrowhead boolean określa, czy strzałka ma być rysowana
na początku
last_arrowhead boolean określa, czy strzałka ma być rysowana
na końcu
arrow_shape_a, double wymiary poszczególnych elementów
arrow_shape_b, strzałki
arrow_shape_c
S
dne. Deklaracja oraz przydział pamię- "points", points,
S
ci jest wykonywany w następujący spo- "fill_color", "black",
S
sób: "first_arrowhead", FALSE,
S
"last_arrowhead", TRUE,
S
GnomeCanvasPoints *points; "arrow_shape_a", 10.0,
S
... "arrow_shape_b", 10.0,
points = gnome_canvas_points_new (2); "arrow_shape_c", 6.0, NULL);
Wyznaczenie współrzędnych docelowych, Podsumowanie
jeśli interesuje nas ściana dolna, jest wyko- Jak każdy program, również nasz nie-
nywane w następujący sposób: wielki projekt można znacznie polepszyć
dodając więcej funkcji. Ponadto, można
points->coords[2] = tx1+(tx2-tx1)/2.0; na podstawie podanego kodu utworzyć
points->coords[3] = ty1+(ty2-ty1); własny nowy widget, aby pózniej we wła-
snej aplikacji korzystać z gotowej kon-
Ostatecznie, aby narysować linię, korzy- trolki, która narysuje diagram opisujący
stamy z odpowiedniego obiektu rysunko- podstawowe elementy sprzętowe, które
wego. Funkcja odpowiedzialna za ten typ  siedzą w komputerze. Zachęcam do eks-
posiada następującą nazwę: gnome_canvas_ perymentów.
line_get_type. Zaletą tego obiektu, oprócz
faktu, iż reprezentuje on linię, jest możli-
W Internecie:
wość dorysowania strzałki. Ostatecznie,
polecenia rysujące linię przyjmują nastę-
" Strona domowa środowiska GNOME:
pującą postać:
http://www.gnome.org/
" Strona domowa biblioteki Kudzu:
S
item = gnome_canvas_item_new
http://fedora.redhat.com/projects/
S
(root,gnome_canvas_line_
additional-projects/kudzu/
S
get_type (),
www.lpmagazine.org 43