본문 바로가기
프로그래밍/C·C++

리눅스 curses.h 설명

by ITPro 2010. 8. 11.

원문 [리눅스프로그래밍]6.Curses

Curses
Curses를 사용한 프로그램의 컴파일 방법
끝에 '-lncurses'를 추가해서 컴파일한다.

개념
stdscr구조체는 표준화면이다. stdout와 비슷하다고 할 수 있다.
윈도우에 대한 출력은 refresh를 호출하기 전까지는 실제 화면에 나타나지 않는다.
curses 라이브러리는 stdscr과 curscr을 비교해서 수행한다.
curses 프로그램에서 문자출력처리는 (1)curses함수를 사용하여 논리적인 화면을 갱신하고, (2)curses에게 요청하여 물리적인 화면을 refresh로 갱신한다.
curses 프로그램은 실제 사용 이전에 initscr로 라이브러리를 초기화하여야 하며, 사용 이후에는 endwin으로 설정을 복구하도록 해야 한다.

기본적인 출력의 특징
초기화와 종료

curses 프로그램은 모두 initscr로 시작하여 endwin으로 끝나야 한다.
initscr의 리턴은 WINDOW 구조체인데 curses가 화면 디스플레이를 저장하는데 사용되는 구조체이다. 
curses는 WINDOW 내부에 접근할 방법을 제공하지 않는다.(임의로 바꿀수 없다.)

출력

curses에는 chtype라는 문자데이터형이 있다. 
chtype는 Linux에서  unsigned long이다.
addch, addchstr - 지정된 문자나 문자열을 현재의 위치에 출력
printw - 문자열을 형식화해서 현재위치에 출력
refresh - 물리적인 화면을 갱신
box - 윈도우 둘레에 상자를 그림
insch, insertln - 하나의 문자를 삽입, 하나의 공백 라인 삽입
delch. deleteln - 하나의 문자 제거, 하나의 공백라인 제거
beep - 비프
flash - 화면 플래시

화면에서 읽어들이기
inch - 현재 커서가 있는 화면상의 위치에서 문자와 속성정보를 반환(chtype으로)
instr, innstr - 읽어들인 문자를 지정한 char배열에 쓴다.

화면 지우기
erase - 공백을 화면 전체에 쓴다.
clear - 화면 전체를 지우고 clearok를 호출하여 화면을 다시 디스플레이한다. 주로 clear다음에 refresh를 붙여 사용한다.
clrtobot - 커서위치부터 화면 끝까지 지운다.
clrtoeol - 커서위치에서 라인의 끝까지 지운다.

화면 이동
move - 커서를 지정된 위치로 이동시킨다.
leaveok - 화면을 갱신한 이후 물리적 커서를 어디에 둘 것인가를 제어하는 플레그를 설정한다.

속성
정의된 속성은 A_BLINK, A_BOLD, A_DIM, A_REVERSE, A_STANDOUT, A_UNDERLINE 이다.
attrset - curses속성을 설정
attron, attroff - 지정한 속성을 켜거나 끔.
standout, standend - 대부분의 터미널에서 역상 비디오 속성으로 맵핑

키보드
키보드 모드
echo, noecho - 입력된 문자를 화면상에 출력하거나 출력하지 않는 함수
cbreak - 프로그램의 입력모드를 Cbreak mode로 설정. 입력되는 문자는 즉시 프로그램에 의해 사용가능.
nocbreak - 입력모드를 Cooked mode로 설정. 사용자가 리턴키를 눌렀을 때 입력이 가능.
raw - 특수문자 처리를 하지 않는다.
noraw - 입력모드를 Cooked mode와 특수문자처리 가능으로 복구한다.
키보드 입력
getch - getchar과 비슷
getstr - gets와 비슷, 반환되는 문자열의 길이를 제한할 방법이 없다.(주의요망)
getnstr - fgets와 비슷, 읽어들일 문자수를 제한할 수 있다.(getstr대신 사용바람)
scanw - scanf와 비슷

다중 윈도우
WINDOW 구조체

stdscr은 WINDOW구조체의 특별한 경우이다.
WINDOW구조체는 curses.h에 정의되어 있다.
WINDOW구조체는 직접 접근할 수 없고 함수로 간접접근만 허용된다.
newwin과 delwin함수는 윈도우를 생성하거나 제거하는 함수이다.
stdscr과 curscr을 제거하는 일은 결코 없도록 하자..

일반적인 함수
addch와 printw함수에 변형판이 있다.
위 함수명에 w가 붙이면 특정한 윈도우를 지정할 수 있고, mv가 붙으면 커서 이동을 설정할 수 있으며, mvw가 붙으면 커서의 이용과 윈도우를 함께 지정할 수 있다.
addch, waddch, mvaddch, mvwaddch
printw, wprintw, mvprintw, mvwprintw
그외 inch와 같은 함수도 위와 비슷하다.

윈도우의 이동과 갱신
mvwin - 화면상에서 윈도우를 이동한다.
wrefresh, wclear, werase - 일반화된 버전..
touchwin - 지정한 윈도우의 내용이 바뀌었다는 것을 curses라이브러리에 통지. 즉, 다음에 wrefresh를 호출하면 curses라이브러리는 항상 지정한 윈도우를 다시 그린다.
touchwin함수는 여러 윈도우가 화면상에 겹쳐있을 때, 어느 윈도우를 디스플레이 할 것인지를 결정할 때 유용하다.
scrollok, scroll - 스크롤 함수로서 윈도우의 스크롤을 제어한다.

화면 리플래시의 최적화
화면에 출력되는 문자의 분량을 최소화하기위해 curses는 wnoutrefresh와 doupdate를 제공한다.
wnoutrefresh는 화면으로 보낼 문자를 결정하지만 실제로 문자를 보내지는 않는다. 문자는 doupdate함수가 보내고 터미널을 변경한다.
즉, wnoutrefresh를 여러번 호출하고 마지막에 doupdate를 호출하면 curses가 전송하는 문자의 갯수를 최소화 할 수 있는 것이다.

보조윈도우
보조윈도우는 다중윈도우의 특별한 경우리고 subwin함수로 생성하고 delwin함수로 제거한다.
보조윈도우는 부모윈도우와 문자저장공간을 공유하기 때문에 보조윈도우에서 변화가 일어난다면 부모윈도우에 영향을 미치게 된다.   따라서 보조윈도우가 제거되더라도 화면은 그대로 있는다.
보조윈도우의 제한사랑은 응용프로그램은 화면을 리플래시하기 전에 부모윈도우 상에서 touchwin을 호출하여야 한다는 점이다.

키패드
키보드는 보통 escape로 시작하는 문자열을 전달한다.
응용 프로그램 상에서 하나의 excape키를 눌렀을 때의 코드와 키능키를 눌렀을 때 발생하는 문자열을 서로 구별하는것은 쉽지 않다.
curses의 keypad함수를 사용하여 Keypad mode를 설정하면 키보드에서 읽어들일 때 KEY_로 정의되어 있는 논리키를 받을 수 있다.
이러한 Keypad mode 사용시 세가지 제한사항을 감수해야만 한다.(p235참조)

색깔
curses에서 문자와 배경의 색상은 항상 하나의 쌍이다.
curses에서 색깔을 사용하려면 터미널 지원여부를 검사해야 하는데 이는 has_colors함수와 start_color함수로 처리한다.
색깔을 실제로 사용하기 이전에 init_pair함수를 사용해서 초기화해야 한다.
색깔 속성은 COLOR_PAIR함수로 한다.

색상 재정의
init_color함수로 색상을 재정의 할 수 있다.

발전된 주제 : 패드
지금까지의 방법으로는 논리적인 화면이 물리적인 화면보다 클 수가 없다.  항상 물리적인 화면 내에서만 출력을 생각해야 한다.
그러나 물리적인 화면보다 더 크게 논리적인 화면을 설계하고 그 일부를 물리적인 화면에 보여주는 방식으로 작업을 할 수도 있다.  이것은 패드라는 특별한 데이터구조를 사용함으로서 가능하다.  패드는 윈도우 내부에 들어가지 않는 논리적인 화면 정보를 처리한다.
패드는 newpad함수로 생성하고 delwin으로 제거할 수 있다.
패드는 특정한 화면의 위치에 구속되지 않기 때문에 화면상에 출력위치(패드영역)을 지정해서 리플래시해야 한다.  prefresh함수는 이때 사용하는 함수이다.
패드는 pnoutrefresh함수도 제공하며 효율적인 화면갱신을 위해 wnoutrefresh함수도 제공한다.

반응형

'프로그래밍 > C·C++' 카테고리의 다른 글

ncurses 프로그래밍  (0) 2010.08.11
리눅스 로케일 세팅  (0) 2010.08.11
리눅스 curses.h 사용 예  (0) 2010.08.11
전역변수&extern  (0) 2010.08.11
char ch = getchar();의 문제의 원인  (0) 2010.08.11