Tartalomjegyzék

< Linux

NCurses

Bevezetés

Az ncurses a POSIX szabványon alapuló operációs rendszereken használható. Az ncurses programozói könyvtár megkönnyíti a szöveges alapú programok létrehozását. Segítségével a GUI-hoz hasonló felület hozható létre, amely terminál emulátorban fut. Könnyen létrehozhatunk vele vonalakat, kereteket, menüket, szövegeket a képernyő különböző helyein.

Az ncurses „n” betűje a „new” szóból van. Az ncurses így System V Release 4.0 (SVr4) curses és szabványos XPG4 curses (XSI curses) klónja. Az első curses megvalósítás a University of California egyetemen készült Berkeleyben BSD operációs rendszerre, a screen orientált játékok támogatására. Előtte a Termcap programozói könyvtárat használták, amellyel a vi szövegszerkesztő is készült. Az ncurseshez hasonló megoldás volt a DOS rendszerekre a conio.h programozói könyvtár.

Az ncruses szabadon terjeszthető, nyílt forráskódú változat. A kompatibilitás érdekében az „n” elhagyható a használat során.

Telepítés

apt-get install libncurses5-dev

A csomag települése után az /usr/include könyvtárba telepszik a curses.h fejállomány. Az ncurses.h pedig egy link lesz a curses.h állományra.

A magyar ékezetes karakterek ábrázolásához libncursesw könyvtárra van szükség:

apt-get install libncursesw5-dev

Telepítés után a használható könyvtárakat a következő helyen találjuk:

/usr/include/ncursesw/

Helló Világ

prog01.c
#include <ncurses.h>
 
int main() {
	initscr();
	printw("Helló Világ");
	refresh();
	getch();
	endwin();
 
	return 0;
}

Fordítsuk le:

gcc program01.c -o program -lncurses

De írhatunk egy Makefile is:

CC=gcc
LIBS=ncurses
SRC=program01.c
BIN=program01
 
all:
	${CC} ${SRC} -l${LIBS} -o ${BIN} 

Az initscr() curses módba kapcsolja a terminált. Néhány implementációban a képernyőt is törli ez az utasítás.

A printw() függvény hasonló a printf()-hez. A képernyőre küldi a megadott karaktersorozatot, a bal felső sarokba, amely a 0,0 pozíció.

A printw() valójában egy képzeletbeli ablakba ír, amely nem frissül azonnal. Az adatok elsőként egy ideiglenes tárolóba kerülnek. A refresh()függvény kiüríti a tárolót, az adatokat a képernyőre küldi.

Az endwin() befejezi a curses módot.

Alapfogalmak

Az ablak fogalma az ncurses-ben: Mindig létezik egy alapértelmezett ablak. Ez a képernyő teljes területe, alapesetben a 80×25-ös képernyő terület. Az alapértelmezett ablakot „stdscr” rövidítéssel jelöljük, vagyis így hivatkozunk rá. Az alapképernyőn (vagy ablakon) újabb ablakokat hozhatunk létre. Egy-egy újabb ablak névvel rendelkezik, így az egyes függvényekben ezzel a névvel tudunk rájuk hivatkozni. Ha egy ablakot nem kívánunk használni, akkor megszüntethető.

Ncurses program előkészítése

Van néhány program előkészítő függvény, amelyeket az initscr() után kell meghívni. Meghívásuk természetesen nem kötelező. A következőkben áttekintjük ezeket az előkészítő függvényeket.

raw() és cbreak()

Normál terminál meghajtó addig raktározza el a leütött karaktereket, amíg egy kocsi vissza vagy egy új sor karaktert nem ütünk. Csak azután férhetünk hozzá a leütött karakterekhez. Ezt nevezzük sorszerkesztő üzemmódnak. A programozó néha, a leütött billentyűket azonnal szeretné elkapni, még kocsi vissza vagy új sor karakter bevitele nélkül.

Két funkcióval szakítható meg a karakterek elraktározása, amelyek a következő vezérlőbillentyűkkel érhetők el: Ctrl + Z (megszakítás), Ctrl + C (kilépés). A cbreak() függvény meghívása kikapcsolja a sorszerkesztő üzemmódot, így a leütött karaktert azonnal felhasználhatjuk. A raw() ugyancsak letiltja a sorszerkesztő üzemmódot, viszont a függvény hatására a szignálok küldése is tiltva lesz. Tehát a Ctrl + C hatására a program nem kapja meg a kilépés szignált, helyette a Ctrl + C billentyűkombinációt adja vissza.

echo() és noecho()

A beütött karakterek képernyőre történő visszhangozását szabályozza. A noecho() kikapcsolja a visszhangot, az echo() pedig bekapcsolja a getch() függvény hívásánál. A leütött karakter után a kurzor poziciója sem változik.

keypad()

Engedélyezi a funkció, a kurzormozgató és a többi billentyű olvasását. A keypad-nek két paramétere van. Az első, az az ablak amelyben el akarjuk érni a hatást. Ez lehet az alapértelmezett képernyő is: stdscr. A második paraméter egy logikai kifejezés. Értéke TRUE ha bekapcsoljuk, és FALSE ha ki.

halfdelay()

Half-delay mód bekapcsolása. A függvény felfüggeszti a program futását a paraméterben megadott tizedmásodpercig. A függvénynek ez az egyetlen paramétere van, amely egy egész szám. Bármely billentyűnyomásra a program tovább lép. Jelszó promptnál lehet hasznos. Például:

halfdelay(30); /* három másodpercig vár */ 

Példa

A következő program bemutatja az eddig megismerteket:

prog01.c
#include <ncurses.h>
 
main() {
 
     int ch;
 
     initscr();                 /* ncurses módba kapcsol */
     raw();                     /* kikapcsolja a sorszerkesztést */
     keypad(stdscr, TRUE);      /* engedélyezi a funkcióbillentyűk 
                                   figyelését */
     noecho();                  /* getch függvény használatakor a leütött
                                   karaktereket, nem visszhangozza a képernyőre */
     ch = getch();              /* ha a raw() függvény nincs meghívva, akkor
                                   a leütött billentyűt csak egy Enter után
                                   kapja meg a program */
     if (ch == KEY_F(1))        /* az F1-s funkcióbillentyű lekérdezése */
          printw("F1 lett lenyomva");
     else
          printw("A lenyomott billentyű %c", ch);
 
     refresh();                 /* a képernyőn való megjelenítés aktualizálása */
     endwin();                  /* kilépés a curses módból */
}

Egyéb különleges billentyűk

Más különleges billentyűk is elérhetők:

A Definiált állandók benne vannak a /usr/include/ncurses.h állományban.

Megjegyzés: A különleges billenytűk közzül nekem csak a funkcióbillentyűk működnek helyesen, grafikus felületen.

move()

A szabványos képernyőn beállíthatjuk a paranccsal a kurzor pozícióját. Az első paraméter a függőleges koordináta (hányadik sor), a második paraméter vízszintes koordináta (hányadik oszlop). (Figyelem! A DOS-os conio.h-ban ez fordítva van.)

prog01.c
#include <ncurses.h>
main() {
    initscr();
    move(10, 20);
    printw("Szöveg");
    refresh();
    endwin()
}

Parancsok ablakokhoz rendelése

Alapesetben egy 80×25-ös szabványos képernyőn dolgozunk. Ennek a neve „stdscr”, ezzel a névvel hivatkozunk rá, mint azt a példában szereplő keypad függvény argumentumaként is megadtuk. A legtöbb függvénynél a szabványos képernyőt nem kötelező jelezni. Ilyen a példákban megismert printw() függvény. Az alaphelyzetben meglévő 80×25-ös képernyőn belül mi magunk is definiálhatunk újabb ablakokat. Ezeket az ablakokat névvel látjuk el, később pedig ezzel a névvel hivatkozunk rájuk.

Példa: A printf(„Helló”); az alapértelmezett (80×25-ös) képernyőre írja a „Helló” szöveget, annak is az aktuális kurzorpozíciójába. Ha az alapképernyőn újabb ablakot jelölünk ki, az adott ablakon belüli képernyő kurzorpozíciójába az alábbi paranccsal írhatunk:

wprintw(foablak, "Helló"); 

Látjuk, hogy egy dupla w betűt írtunk a függvény neve elé, ezzel jelezzük, hogy paraméterként megkívánjuk adni az ablak nevét, amelyikbe írni akarunk. A fenti példában a „foablak” nevű ablak kurzorpozíciójától kezdve írjuk ki a „Helló” szöveget.

Ekkor a refresh() parancs helyett is ezt használjuk:

wrefresh(foablak); 

Az alapképernyőre írással együtt meghatározhatjuk a kurzor helyét is „mv” tag elhelyezésével:

mvprintw(y, x, szoveg); 

Ugyanez egy ablakra vonatkoztatva:

mvwprintw(foablak, y, x, szoveg); 

Kiírató függvények

Minden kiírató függvénynél használhatjuk a már C-ben megismert escape szekvenciákat.

addch()

Egy karaktert ír a képernyőre. Pl. :

addch('a'); 

Ennek a teljes példaprogramja így néz ki:

prog01.c
#include <ncurses.h>
 
main() {
    initscr();
    addch('a');
    refresh();
    endwin();
}

mvaddch()

Egyetlen karaktert ír a képernyőre, de itt meg kell adni hova akarjuk kiírni. Valójában a move() függvény van beépítve. Például, ha az ötödik sor, tizedik oszlopába akarom kiíratni az 'a' karaktert, akkor azt így tehetem meg:

mvaddch(5, 10, 'a');

waddch()

Egyetlen karaktert ír a képernyőre, azonban egy ablakhoz is hozzárendeljük a kiírást.

Pl.:

waddch(ablak, 'A');

mvwaddch()

Egyetlen karakteret ír a képernyőre. Meg kell adnunk melyik ablakba akarunk írni, és az adott ablak milyen pozíciójába.

Pl.:

mvwaddch(ablak, 5, 5, 'A');

printw()

Fentebb már találkoztunk vele. Formázott adatkivitelt tesz lehetővé, mint a szabványos printf(). Ugyanúgy kell használni mint a printf() függvényt. Például:

prog01.c
#include <ncurses.h>
main() {
    int ch='v';
    initscr();
    printw("ch tartalma %c", ch);
    refresh();
    endwin();
}

Beállíthatjuk a karakterek kiírásának stílusát. Lehet például vastagon írt, vagy aláhúzott. Ezeket a tulajdonságokat az addch() paramétereként adjuk meg, a kiírandó karakter után, attól „|” karakterrel elválasztva:

addch('a' | A_BOLD); 

vagy

addch('a' | A_BOLD | A_UNDERLINE); 

Ez azonban nekem karakteres felületen nem működik, csak a grafikus felület termináljában. Karakteres felületen a normál és a vastagbetűs írás más színnel jelenik meg. A megjelenítés stílusát állíthatjuk külön paranccsal is. Ezek az attrset(), attron() és attroff().

Linkek