Programowanie z ncurses (index)


Programowanie z ncurses (1) - wprowadzenie

ZADANIE 1.1

W katalogu domowym utworzyć podkatalog hello. Utworzyć w nim plik hello.c postaci:


/*
*  hello.c (initscr)
*/

#include <stdlib.h>   /* exit() */
#include <unistd.h>   /* sleep() */
#include <curses.h>

int main(void) 
{
int xmax, ymax;

if (initscr() == NULL) {
	fprintf(stderr,"Error: initscr()\n");
	exit(1);
}
getmaxyx(stdscr,ymax,xmax);
printw("Hello!\n");
printw("Liczba wierszy okna = %d\n",ymax);
printw("Liczba kolumn okna = %d\n",xmax);
refresh();
sleep(2);
endwin();
return 0;
}

Skompilować program poleceniem: gcc -Wall -ansi -lncurses -o hello hello.c

Stworzyć plik Makefile wspomagający kompilację.

ZADANIE 1.2

W katalogu hello stworzyć plik hello2.c korzystającego z innej metody tworzenia okien.


/*
*  hello2.c (newterm)
*/

#include <stdlib.h>   /* exit() */
#include <unistd.h>   /* sleep() */
#include <curses.h>

int main(void) 
{
SCREEN *ekran;

ekran= newterm(NULL, stdout, stdin);
if (ekran == NULL) {
	fprintf(stderr,"Error: newterm()\n");
	exit(1);
}
/* Ustawienie "ekran" jako biezacego terminalu */
if (set_term(ekran) == NULL) {
/* Jezeli sie nie uda, to i tak trzeba zwolnic pamiec */
	endwin();
	delscreen(ekran);  /* zwolnienie pamieci  */
	fprintf(stderr,"Error: set_term()\n");
	exit(1);
}
printw("Hello! To okno curses stworzono przez newterm()\n");
refresh();
sleep(2);

printw("Koniec pracy...\n");
refresh();
sleep(2);

endwin();
delscreen(ekran);
return 0;
}

FUNKCJE


initscr();
endwin();
refresh();  /* jedna z rodziny */
getmaxyx();
printw();  /* jedna z rodziny */

newterm();
set_term();
delscreen();

CHARAKTERYSTYKA BIBLIOTEKI NCURSES

ncurses to darmowa implementacja klasycznej uniksowej biblioteki obsługi ekranu curses. Udostępnia ona prosty wysokopoziomowy interfejs do kontroli i zarządzania ekranem. Zawiera również bardzo użyteczne procedury służące do obsługi klawiatury i wejścia myszy, tworzenia i zarządzania wieloma oknami, obsługi menu, formularzy i panelów.

ncurses uogólnia interfejs pomiędzy programem aplikacji i ekranem lub terminalem, na którym aplikacja jest uruchamiana. ncurses używa terminfo, czyli formatu bazodanowego do opisu właściwości tysięcy różnych terminali.

API curses wydaje się być archaizmem w czasach, gdy dominuje X, Motif i Tcl/Tk. Jednak UNIX wciąż wspiera linie poleceń, a w X mamy xterm. Główne zalety API curses to prostota i wsteczna przenośność na terminale o stałej szerokości znaków.

Wybrane programy napisane w ncurses: nvi (edytor), lynx (web browser), Midnight Commander (menedżer plików), mutt (mail client), pinfo (czytnik info), tin (newsreader), dselect (zarządzanie pakietami deb), aptitude, w3m (przeglądarka WWW), calcurse (kalendarz).

Debian Sarge ma ncurses w wersji 5.4-4. Pliki nagłówkowe znajdują się w katalogu /usr/include/. Dokumentacja jest w katalogu /usr/share/doc/libncurses5-dev.

KOMPILACJA Z ncurses

Aby skompilować program z ncurses, musimy włączyć do kodu źródłowego nagłówek curses.h. W Debianie ncurses.h to link symboliczny do curses.h. Przy scalaniu trzeba dołączyć opcję -lcurses. ncurses automatycznie włącza stdio.h.

TERMINOLOGIA I PODSTAWOWE KONCEPCJE

Ekran (screen) to konsola lub fizyczny ekran terminala w trybie znakowym. Wg Introduction: jest to podzbiór okien o wielkości ekranu terminala.

Okno (window) to niezależny prostokątny obszar wyświetlany na ekranie. Nie musi mieć rozmiaru takiego jak ekran.

Mamy dwa wskaźniki do struktur danych WINDOW: stdscr (standard screen, ekran do modyfikowania) i curscr (current screen, bieżący ekran). Oba mają rozmiar całego ekranu.

Odświeżenie odnosi się do wywołania funkcji refresh() [lub wrefresh()] lub procesu logicznego. Jest to proces dostosowania ekranu fizycznego tak, aby odzwierciedlał zawartość struktury WINDOW. Programista nanosi zmiany na stdscr (nigdy bezpośrednio na curscr), a funkcja refresh() [lub wrefresh()] uaktualnia curscr. W praktyce dla polepszenia wydajności odświeżane są tylko te części okna, które zostały zmienione.

Kursor odnosi się do miejsca, w którym zostanie wyświetlony następny znak. Pewne funkcje przesuwają położenie kursora po wykonaniu swojej pracy, np. po wyświetleniu znaku czy napisu.

Lewy górny róg okna ma współrzędne (0,0), a prawy dolny (LINE-1,COLUMNS-1), czyli mamy współrzędne (y,x).

ncurses utrzymuje dwie zmienne globalne LINES i COLUMNS, które zawierają liczbę wierszy i kolumn dla rozmiaru bieżącego okna. Jednak do określenia rozmiaru okna, z którym w danym momencie pracujemy, lepiej użyć funkcji getmaxyx(). ncurses definiuje wiele stałych, np.


#define  TRUE   1
#define  FALSE  0
#define ERR     (-1)
#define OK      (0)

KONWENCJA NAZW FUNKCJI

Wiele funkcji ncurses domyślnie używa okna stdscr. Nazwy funkcji, które mogą działać na dowolnym oknie, są poprzedzone znakiem w, a pierwszy argument funkcji ma typ WINDOW *.

Inna konwencja to łączenie przesunięcia z inną akcją w jedną funkcję, np. move(y,x) i addch(ch) możemy wykonać łącznie funkcją mvaddch(y,x,ch). Podobnie wmove(win,y,x) i waddch(win,ch) możemy wykonać łącznie funkcją mvwaddch(win,y,x,ch) [najpierw win, potem (y,x)].

Funkcje zwracające wartość całkowitą, zwykle zwracają OK w przypadku powodzenia i ERR w przypadku błędu. Funkcje zwracające wskaźnik zwykle zwracają NULL w przypadku niepowodzenia.

INICJALIZACJA I KOŃCZENIE DZIAŁANIA

Inicjalizacja: initscr() lub newterm() [jeżeli będziemy korzystać z więcej niż jednego terminala].

Jeżeli użyliśmy tylko initscr(), to na końcu potrzeba tylko uruchomić endwin().

Jeżeli było newterm(), to trzeba dla każdego terminala wywołać endwin() i delscreen() [zwolnienie pamięci].


Programowanie z ncurses (index)