Tartalomjegyzék
NCurses
- Szerző: Sallai András
- Copyright © Sallai András, 2003, 2015, 2020
- 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
- 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:
- 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.)
- 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().