Download presentation
Presentation is loading. Please wait.
1
ncurses Programming JunHyeon Mun
2
ncurses 정의 ncurses 는 UNIX System V 에서 사용하던 curses 라이브러리를 재 작성한 라이브러리로 curses 의 GNU 버전 텍스트모드에서 Window, Panel, Menu, Mouse, Color등을 쉽게 사용할 수 있도록 도와주는 라이브러리입니다. 콘솔 화면에서 메뉴 바 제어, 키보드제어, 윈도우 생성 등 대표적인 ncurses를 사용하는 응용프로그램은 mc(Midnight Commander)가 있음
3
ncurses 프로그래밍 ncurses의 기본 구성요소 화면제어 창(윈도우)제어 키보드 제어 마우스제어
4
NCURSES를 사용하려면? 소스파일에 ncurses.h를 추가 컴파일시
#include <ncurses.h> //소스파일 안에 추가 Unix의 경우 <ncurses/ncurses.h>를 추가해야 함 컴파일시 gcc 소스파일네임 -lncurses
5
함수 이름 규칙 함수명 앞에 w가 붙는 경우 함수명 앞에 w가 붙지 않은 경우는 함수의 사용방법도 동일
refresh/wrefresh, printw/wprintw, bkgd/wbkgd 함수명 앞에 w가 붙지 않은 경우는 특정 윈도우를 명시하지 않고, 기본윈도우(stdscr)를 사용하고자 할 때 사용 함수의 사용방법도 동일 단지 'w'가 붙은 함수일 경우 윈도우를 명시하기 위해서 첫 번째 아규먼트로 WINDOW 타입 포인터가 추가된다는 점이 다름 printw("헬로 월드"); wprintw(stdscr, "헬로 월드");
6
함수 이름 규칙-cont. 함수명 앞에 "mv" 가 붙는 경우 mvprintw 같은 함수가 대표적인 경우
mv 는 move 의 약자로써, 현재 커서의 위치가 아닌 특정 위치(y, x)에 커서를 위치하고, 위치된 커서에서 작업을 하기 위해서 사용함
7
초기화 및 종료 initscr() endwin() curses모드를 시작 curses를 사용하기 위해 반드시 써줘야 함
8
색상(Color) ncurses 에서 색은 전경색과 배경색의 2가지 색상으로 이루어짐
보통 이러한 색상은 프로그램의 일관성을 확보하기 위해서 전역으로 선언되게 됨 ncurses 는 이러한 전역적인 색상을 선언하기 위해서 init_pair() 이라는 함수를 제공한다.
9
색상(Color)-cont. init_pair() 첫 번째 아규먼트인 pair 은 나중에 이 색을 참조할 index
2번째 아규먼트는 전경색, 3번째 아규먼트는 배경색 전경색과 배경으로 사용할 수 있는 색은 다음의 8가지로, ncurses.h 에 define 되어 있다. 사용 가능한 색 int init_pair(short pair, short f, short b); COLOR_BLACK COLOR_RED 1 COLOR_GREEN 2 COLOR_YELLOW 3 COLOR_BLUE 4 COLOR_MAGENTA 5 COLOR_CYAN 6 COLOR_WHITE 7
10
색상(Color)-cont. 예제 전경색 흰색, 배경색 푸른색으로 설정하는 경우
이후로 위의 전/배경 색이 필요할 경우 참조번호 1 을 사용하면 됨 bkgd() 함수를 사용해서 배경색을 지정할 수 있음 예로 위의 init_pair 로 지정한 색 중 1번을 사용하길 원한다면 bkgd(1) 로 사용하면 됨 init_pair 로 지정한 색의 사용은 COLOR_PAIR() 라는 매크로를 이용해서 필요할 때 사용하면 됨 init_pair(1, COLOR_WHITE, COLOR_BLUE);
11
화면 업데이트 refresh() / wrefresh()
화면을 만들고 문자를 출력한다고 해서 이게 바로 화면에 뿌려지는 건 아니다. 화면에 대한 여러 가지 변경내용을 가지고 있다가 변경내용을 토대로 ‘화면을 만들어라’ 라고 명령을 해야지만 화면이 업데이트 된다. ncurses 는 가장 마지막 화면의 내용의 정보를 가지고 있다가, 화면 업데이트 명령이 떨이지면 전체 화면을 갱신하는 것이 아니라 변경된 창의 정보만을 갱신함 이로써 자원소모를 절약하고 좀더 빠른 반응속도를 보장할 수 있음
12
화면 업데이트-cont. touchwin() wrefresh 앞에 쓰이며 윈도우를 다시 그리기 위해서 사용
Wrefresh와 touchwin 은 윈도우의 내용을 다시 그리는 함수지만 touchwin 은 윈도우 자체를 다시 그린다는 점이 다름
13
윈도우(Window) 윈도우 생성, 이동, 삭제 ncurses 는 다중의 윈도우 환경을 제공함
즉 하나의 윈도우는 또 다른 윈도우를 만들 수 있도록 있음 윈도우가 생성되면, 그 윈도우가 생성된 원래의 윈도우가 부모윈도우가 된다. 이중 초기 initscr()을 이용해서 만들어진 화면이 모든 윈도우의 부모 윈도우가 된다. 모든 창은 명시적으로 이 부모윈도우 위에 만들어지게 되거나, 혹은 이미 만들어진 윈도우를 참조하는 subwindow 형태로 만들어지게 된다.
14
윈도우(Window)-cont. 이때 참조하는 윈도우 객체는 WINDOW 타입을 가지게 되며, 특별히 기본화면을 stdscr 이라고 명시해서 사용한다. stdscr 은 기본화면을 가리킨다. 윈도우 생성함수를 호출해서 새로운 윈도를 만들게 되면 새로 만들어진 윈도우를 가리키는 WINDOW 타입에 대한 포인터를 되돌려주게 된다.
15
윈도우(Window)-cont. 윈도우 생성 - newwin() / subwin()
nlines와 ncols 는 윈도우의 크기를 결정 begin_y, begin_x 는 화면 내에서 윈도우의 위치를 nlines 는 라인크기 nclols 는 컬럼 크기, begin_y, begin_x 는 화면 좌표 에서의 위치이다 화면 좌표는 모니터의 왼쪽 꼭대기가 (0,0)이며, 세로가 y축을 가로가 x 축을 나타낸다. newwin 은 기본 화면 즉 stdscr 위에 윈도우가 생성되며, subwin 은 이미 만들어진 다른 윈도우 위에 윈도우가 생성된다. WINDOW *newwin(int nlines, int ncols, int begin_y, int begin_x); WINDOW *subwin(WINDOW *roigint nlines, int ncols, int begin_y, int begin_x);
16
윈도우(Window)-cont. 윈도우 이동 - mvwin() win 이 가르키는 윈도우를 y, x 화면 좌표로 이동시킨다.
윈도우가 이동할 경우 기존에 있던 윈도우가 화면에 그대로 표시되게 되어서 결과적으로 2개의 윈도우가 보이게 된다. 그러므로 touchwin()을 사용해서 부모 윈도우 화면정보를 갱신시켜줘야 한다. int mvwin(WINDOW *win, int y, int x);
17
윈도우(Window)-cont. 윈도우 삭제 - wclear / werase, delwin
w가 안 붙는 것은 제어할 윈도우가 기본화면 즉 stdscr 이다. werase 는 wclear 은 윈도우를 하얀색 공백으로 채워버린다. 화면을 지워 버린다고 생각하면 될 것이다. delwin 윈도우 객체를 소멸시키고자 할 때 사용한다. int erase(void); int werase(WINDOW *win); int clear(void); int wclear(WINDOW *win); int delwin(WINDOW *win);
18
윈도우(Window)-cont. 윈도우주위에 테두리 만들기 첫 번째 아규먼트 그 다음에 가로와 세로의 경계선 스타일을 지정
verch 는 세로 경계선 스타일 horch 는 가로 경계선 스타일 int box(WINDOW *win, chtype verch, chtype horch);
19
키보드 제어 Function Keys F1-F9까지의 키를 말하며 getch() 등의 함수를 이용해서 키 입력을 받아들이면 이것이 F1-F9까지의 어떤 키 값과 동일한지 확인하는 방법을 취한다. int key=getch(); if(key==KEY_F(1)) // F1 키를 눌렀을 때 { 원하는 함수를 실행 } if (key==KEY_F(2)) // F2 키를 눌렀을 때
20
키보드 제어-cont. KEY_F는 ncurses.h 에 등록되어 있는 매크로 함수로 다음과 같은 모양을 가진다. 방향키 및 특수키들 방향키는 주로 메뉴의 이동을 위해서 사용됨 Function Key 와 마찬가지로 ncurses.h 에 방향키에 관련된 키 값이 등록되어 있다. 이 값은 KEY_DOWN, KEY_UP, KEY_LEFT, KEY_RIGHT 등이 있다. home, page up, page down, insert 등 의 키 입력 확인도 가능 #define KEY_F /* Function keys. Space for 64 */ #define KEY_F(n) (KEY_F0+(n)) /* Value of function key n */
21
문자출력 형식화된 문자열 출력 printw와 wprintw 는 현재 커서 위치에 출력
mvprintw, mvwprintw 는 y, x 좌표로 커서를 옮겨서 출력 int printw(char *fmt [, arg] ...); int wprintw(WINDOW *win, char *fmt [, arg] ...); int mvprintw(int y, int x, char *fmt [, arg] ...); int mvwprintw(WINDOW *win, int y, int x, char *fmt [, arg] ...);
22
문자출력-cont. 문자/개행 출력 ch 가 붙은 함수는 단일 문자 입력, str 은 문자열 입력과 관련된 함수. ln 이 붙은 함수는 개행 문자 입력관련 함수 int insch(chtype ch); int winsch(WINDOW *win, chtype ch); int mvinsch(int y, int x, chtype ch); int mvwinsch(WINDOW *win, int y, int x, chtype ch); int insertln(); int winsertln(WINDOW *win); int insstr(const char *str); int insnstr(const char *str, int n); int winsstr(WINDOW *win, const char *str); int winsnstr(WINDOW *win, const char *str, int n); int mvinsstr(int y, int x, const char *str); int mvinsnstr(int y, int x, const char *str, int n); int mvwinsstr(WINDOW *win, int y, int x, const char *str); int mvwinsnstr(WINDOW *win, int y, int x, const char *str, int n);
23
문자출력-cont. 문자/개행 삭제 단일문자나 줄 삭제를 위해서 사용
문자 삭제일 경우 커서는 왼쪽으로 한 칸 이동하며, 라인 삭제일 경우 커서는 위로 이동한다. int delch(void); int wdelch(WINDOW *win); int mvdelch(int y, int x); int mvwdelch(WINDOW *win, int y, int x);
24
문자출력-cont. Boxes 와 Line출력
boder, wboder, box 는 윈도우 경계를 구분하기 위한 테두리를 만들 때 사용 box 를 사용할 경우 기본적으로 사용되는 테두리 라인을 이용 border, wborder 을 사용할 경우 사용자 정의 테두리 문자를 지정할 수 있음 즉 border 을 사용하면 다음과 같은 테두리를 구성할 수 있다. int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br); int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br); int box(WINDOW *win, chtype verch, chtype horch);
25
문자출력-cont. 아래의 함수들은 수평 혹은 수직의 선을 화면에 그리기 위해서 사용한다.
이 함수들을 사용하면 현재 커서가 위치하는 곳에서 수직/수평 선을 그린다. ch 는 선을 그리기 위해서 사용할 문자이며, n 은 몇 개의 선 문자를 사용할 것인지 즉, 선의 길이를 얼마만큼 할 것인지를 결정하기 위해서 사용한다. int hline(chtype ch, int n); int vline(chtype ch, int n); int whline(WINDOW *win, chtype ch, int n); int wvline(WINDOW *win, chtype ch, int n);
26
입력 문자 / 문자열 입력 아래의 함수들은 하나의 키보드 입력을 받아들이기 위해서 사용된다.
넘어온 값은 "KEY_"를 정의된 값들과 비교함으로써, Function key, 방향키, 특수키 입력 등을 판단하기 위해서 유용하게 사용할 수 있다. int getch(void); int wgetch(WINDOW *win); int mvgetch(int y, int x); int mvwgetch(WINDOW *win, int y, int x);
27
입력-cont. 아래의 함수들은 문자열을 입력 받기 위해서 사용된다.
getch() 함수를 개행 문자를 만날 때까지 loop 돌리는 것이라고 생각할 수 있다. int getstr(char *str); int getnstr(char *str, int n); int wgetstr(WINDOW *win, char *str); int wgetnstr(WINDOW *win, char *str, int n); int mvgetstr(int y, int x, char *str); int mvwgetstr(WINDOW *win, int y, int x, char *str); int mvgetnstr(int y, int x, char *str, int n); int mvwgetnstr(WINDOW *, int y, int x, char *str, int n);
28
입력-cont. 'w' 가 붙은 것들은 win 이 가르키는 창에서 입력을 받는다.
getstr, getnstr 과 같이 'n' 이 붙은 것들과 그렇지 않은 것들이 있는데, 'n'이 들어간 함수는 int n 크기만큼만 입력을 받는다. 버퍼 오버플로우를 막기 위해서는 'n' 이 들어간 함수를 사용하도록 하자. "mv"가 앞에 붙은 함수는 입력 위치가 현재커서가 아닌 현재커서에서 y, x 만큼 움직인 위치에서 입력을 받는다.
29
입력-cont. 형식화된 입력 stdio.h 의 scanf와 같은 일을 한다.
int scanw(char *fmt [, arg] ...); int wscanw(WINDOW *win, char *fmt [, arg] ...); int mvscanw(int y, int x, char *fmt [, arg] ...); int mvwscanw(WINDOW *win, int y, int x, char *fmt [, arg] ...); int vw_scanw(WINDOW *win, char *fmt, va_list varglist); int vwscanw(WINDOW *win, char *fmt, va_list varglist);
30
ncurses Functions 설정 및 초기화 관련 함수 initscr() endwin() raw() and cbreak()
curses모드를 시작한다. curses를 사용하기 위해 반드시 써줘야 한다. endwin() curses모드를 종료한다. curses모드를 사용하고 종료할 때 반드시 써줘야 한다. 만약 endwin()을 하지 않고 프로그램이 종료됐을 경우 텍스트 모드의 이상을 가져 올 수 있다. raw() and cbreak() Line buffering을 사용할 지의 유무를 설정한다. 사용할 경우 cbreak, 사용하지 않고자 할 경우 raw를 사용하면 된다. 보통 기본설정은 사용을 하는 것으로 되어있다.
31
ncurses Functions-cont.
echo() and noecho() 사용자로부터 입력을 받은 문자를 출력할지 여부를 결정한다. echo는 출력 noecho는 출력을 하지 않는다. (getch 함수 사용시) keypad() F1, F2, 방향키 등과 같이 특수한 키들을 사용할 수 있게 해준다. keypad(stdscr, TRUE); KEY_F(1)~ KEY_F(12) KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN color_start() color모드를 시작한다. 색깔을 넣고자 할 때 그 전에 반드시 써주어야 하는 함수이다. (has_colors()의 리턴 값이 TRUE 일 때만 사용 가능하다.)
32
ncurses Functions-cont.
출력 관련 함수 refresh() 화면에 찍은 내용을 갱신한다. curses 모드에서는 출력함수를 이용해 출력해도 refresh()를 쓰기 전까지 화면에 나타나지 않는다. clear() 화면을 깨끗이 지운다.
33
ncurses Functions-cont.
printw printf와 쓰임새와 사용방법이 같다.(curses 모드가 시작된 이후 종료되기 전까지는 printf와 같은 일반 출력함수로는 화면에 출력할 수 없다.) ex) printw("string\n"); printw("%s\n", "string"); ....
34
ncurses Functions-cont.
addch putchar와 같이 char의 글자 하나를 출력할 때 사용한다. putchar와 다른 점이라면 curses 모드에서 사용할 수 있는 옵션 줄 수 있다. ex) #include<ncurses.h> int main(void){ int cnt; char s[] = "SPLUG"; initscr(); addch(s[0]|A_BOLD); for (cnt = 1; cnt < 5; cnt++) addch(s[cnt]); refresh(); endwin(); }
35
ncurses Functions-cont.
addstr() addstr(string) 해당 문자열을 출력한다. move(y,x) y줄 x번째로 커서를 이동시킨다. x, y의 값은 0~화면의 최대크기 의 int 값을 갖는다. 화면의 범위를 벋어날 경우 세그멘테이션 오류가 날 수 있다. mvprintw(), mvaddch() move한 뒤 printw, addch 한 것과 같은 결과를 출력한다. 예를 들면 move(10, 10); printw("This is 10, 10"); 이것은 아래와 같다. mvprintw(10, 10, "This is 10, 10");
36
ncurses Functions-cont.
입력 관련 함수 scanw() and mvscanw() scanw는 scanf와 사용방법과 쓰임이 같다. 해당 문자열이나 char int등을 입력 받는다. mvscanw는 mvprinw와 비슷하게 해당 좌표로 이동 후 입력을 받는다. mvscanw(row, col, "%d", int *); getstr() string입력을 받는다. ex) char str[10]; getstr(str); 이렇게 하면 ‘\n'를 입력 받기 전까지의 문자열을 str에 저장한다.
37
ncurses Functions-cont.
getch() 한 문자를 사용자로부터 입력을 받는다. getchar과는 달리 ‘\n'문자를 입력 받을 때까지 기다리지 않고 바로 입력 받은 문자 하나를 리턴 해주고 종료한다. 입력 받은 문자의 표기 유무는 echo() : 유 와 noecho() : 무로 선택한다.
38
ncurses Functions-cont.
Attributes - 글자에 특수한 효과를 주기 위해 사용 attron() and attrset() 글자에 특수한 효과를 준다. attron() 중첩 사용하면 중첩효과를 attrset()의 인자로 attrset() 하는 것과 같다. 사용 방법 attron(인자); 한꺼번에 여러 효과를 주고자 할 때 |(OR)를 이용하면 된다. attron(인자1| 인자2); 이렇게 하면 인자1과 인자2의 효과가 중첩되어 나타난다. 중첩 개수에 제한 없음.
39
ncurses Functions-cont.
인자들 A_NORMAL : Normal display (no highlight) A_STANDOUT : Best highlighting mode of the terminal. A_UNDERLINE : Underlining A_REVERSE : Reverse video A_BLINK : Blinking A_DIM : Half bright A_BOLD : Extra bright or bold A_PROTECT : Protected mode A_INVIS : Invisible or blank mode A_ALTCHARSET : Alternate character set A_CHARTEXT : Bit-mask to extract a character COLOR_PAIR(n) : Color-pair number n
40
ncurses Functions-cont.
attroff() attron()이나 attrset()으로 준 효과를 끈다. 인자는 attron(), attrset()과 동일하다. ex) attron(A_BLINK); printw("HI!!\n"); attroff(A_BLINK);
41
ncurses Functions-cont.
init_pair() 컬러를 설정할 때 쓰인다. init_pair(int index, int font_color, int blink_color); 여기서 index는 설정한 color쌍을 불러 낼 때 쓰이게 되는 번호이다. 1보다 크거나 같은 수 지정 가능 두 번째 인자는 글씨 색을 세 번째 색은 블록의 색깔을 의미한다. 여기서 색은 ncurse 라이브러리에 미리 정의 되어있다. COLOR_BLAACK 0 COLOR_RED COLOR_GREEN 2 COLOR_YELLOW 3 COLOR_BLUE COLOR_MAGENTA 5 COLOR_CYAN 6 COLOR_WHITE 7
42
ncurses Functions-cont.
init_color() 미리 정의되어 있는 색깔을 바꿀 수 있다. 예를 들어 COLOR_RED의 색깔을 재 정의 하고자 할 경우 init_color(COLOR_RED, r, g, b); 여기서 r, g, b는 각각 red, green, blue의 삼원색으로 0~ 1000사이의 값을 가진다. COLOR_PAIR(n) attron(), attset(), attroff()의 인자로 쓰인다. 여기서 n은 앞에서 init_pair()에서 첫 번째 인자로 숫자로 들어간 수와 일치 한다. 0은 보통 모양을 의미 한다.
43
ncurses Functions-cont.
mvchgat() attron(COLOR_PAIR(n))과 유사한 효과를 내는 데 쓰인다. mvchgat(int start_Y, int start_X, int char_num, Attribute, int index, NULL) 첫 번째와 두 번째는 효과를 주려고 하는 곳의 시작 부분을 세 번째 인자는 효과를 주고자 하는 문자의 숫자를 의미한다. 여기서 -1은 라인의 끝까지를 의미한다. Attribute는 A_BOLOD나 A_BLINK와 같은 효과를 의미한다. 네 번째 인자는 init_pair()에서 설정해준 color 쌍의 인덱스 번호와 일치한다. 역시 0은 기본 모양. 마지막 인자는 항상 NULL이다.
44
ncurses Functions-cont.
현재 정보를 얻는 함수들 getmaxyx() 현재 화면의 가로 세로의 크기를 구한다. getmaxyx( win, max_y, max_x); win의 y값의 크기와 x값의 크기를 구해 각각 max_y, max_x에 넣어준다. 여기서 win은 window포인터를 의미하며 표준화면은 stdscr을 넣어주면 된다. getyx() 현재 커서의 위치를 구한다. getyx(win, y, x); win(window pointer)의 커서의 위치를 찾아 y, x에 넣어준다.
45
ncurses Functions-cont.
ACS 문자들(특수문자) ncurses에서는 여러 가지 특수한 문자들을 ACS_xxx 이런 식으로 미리 정의해 놓았다. 여기서 원하는 문자를 찍고자 할 때 미리 정의된 것을 이용하면 손쉽게 찍을 수 있다.
46
ncurses Functions-cont.
커서 설정 curs_set() 이용하여 설정하며 0~2사이의 인자 값을 가진다. 0에 가까울수록 커서가 안 보인다. ex ) curs_set(0);
47
ncurses Functions-cont.
마우스 이벤트 이벤트 얻기(getmouse()) MEVENT event; ch = getch(); if(ch == KEY_MOUSE) if(getmouse(&event) == OK) { /*Do some thing with the event*/ }
48
ncurses Functions-cont.
ncurses에서는 MEVENT 라는 구조체가 미리 정의 되어있다. 구조체를 살펴보면 typedef struct { short id; //device id int x, y, z; //마우스의 커서 위치 mmask_t bstat; //버튼의 상태 비트를 나타낸다. } 사용방법은 event라고 선언된 구조체에 마우스 이벤트를 받았다면 마우스버튼 1을 눌렀는지를 검사하려면 다음과 같이 할 수 있다. if(event.bstat & BUTTON1_PRESSED) printw("Left button pressed");
49
ncurses Functions-cont.
Name Description BUTTON1_PRESSED mouse button 1 down BUTTON1_RELEASED mouse button 1 up BUTTON1_CLICKED mouse button 1 clicked BUTTON1_DOUBLE_CLICKED mouse button 1 double clicked BUTTON1_TRIPLE_CLICKED mouse button 1 triple clicked BUTTON2_PRESSED mouse button 2 down BUTTON2_RELEASED mouse button 2 up BUTTON2_CLICKED mouse button 2 clicked BUTTON2_DOUBLE_CLICKED mouse button 2 double clicked BUTTON2_TRIPLE_CLICKED mouse button 2 triple clicked BUTTON3_PRESSED mouse button 3 down BUTTON3_RELEASED mouse button 3 up BUTTON3_CLICKED mouse button 3 clicked
50
ncurses Functions-cont.
Name Description BUTTON3_DOUBLE_CLICKED mouse button 3 double clicked BUTTON4_PRESSED mouse button 4 down BUTTON4_RELEASED mouse button 4 up BUTTON4_CLICKED mouse button 4 clicked BUTTON4_DOUBLE_CLICKED mouse button 4 double clicked BUTTON4_TRIPLE_CLICKED mouse button 4 triple clicked BUTTON_SHIFT shift was down during button state change BUTTON_CTRL control was down during button state change BUTTON_ALT alt was down during button state change ALL_MOUSE_EVENTS report all button state changes REPORT_MOUSE_POSITION report mouse movement
Similar presentations