< Linux

NCurses

Szerző: Sallai András

Copyright © Sallai András, 2003, 2015

Licenc: GNU Free Documentation License 1.3

Web: http://szit.hu

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

#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:

#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:

KEY_DOWN

KEY_UP

KEY_LEFT

KEY_RIGHT

KEY_HOME

KEY_BACKSPACE

KEY_ENTER

stb.

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.)

#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:

#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:

#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

http://www.gnu.org/software/ncurses/

http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/init.html