본문 바로가기

Academy I/Tech Academy

Unix System Programming 10

10장 화면조작 :namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

10.1. 서론

 CRT/VDU 단말기의 화면을 다루는 도구들을 소개한다. 화면을  다루는 도구에는

밀접하게 관련된 두개의 C 라이브러리가 있다.

 

 1. curses 이것은 하드웨어에 의존하지 않고 화면을 조작하는 방법이다.

    라이브러리는 단말기의 하드웨어에 무관한 자료구조인 윈도우(window)

    제공한다. curses라는 이름 역시 최적화 커서 이동 (cursor motion

    optimization )에서 따온것이다. 이것은 AT&T 시스템 V 인터페이스 정의

    (SVID) Issue 2 에 정의되어 있다.

 2. terminfo 이 라이브러리는 curses 와는 달리 하드웨어와 밀접한 연관성을

    가진 루틴을 제공한다. terminfo 역시 SVID Issue 2 에 정의되어 있다.

 

 curses terminfo  둘다, 현재의 버전은 terminfo 라는 각각의  단말기의 특

성을 기록해 두는 데이타베이스(database)를 사용한다.

 

  /usr/lib/terminfo/<c>/<name>

 

 <name> 은 실제 단말기의 이름이고 <c> <name> 의 첫글자이다.

 

  /usr/lib/terminfo/v/vt100

 

 은 단말기  vt100 의 특성들을 기록해두는  화일이다. curses terminfo 

루틴들은 먼저 환경  변수(environment variable) TERM 을 보고 단말기의  이름

을 알아낸 다음,  terminfo 데이타베이스에서 그 단말기에 대응하는 화일을 

는다.

 

 termcap 라이브러리

  terminfo   AT&T 에서 새로이 만들어  낸 것이다. 어떤 UNIX  시스템에서는

terminfo  대신 termcap  이나 termlib 가 있을 수도 있다. termcap   단말기

명세가 /etc/termcap 이라는 화일에 기록되어있다. 새로운 단말기에  대한 명세

를 만들려면 그  화일을 사용자가 편집(edit)하면 된다. 소프트웨어 개발을 

게하기 위해 terminfo  라이브러리는 termcap 라이브러리보다 상위의  호환성을

가진다.

 

10.2. curses 라이브러리 : 개요

 프로그래머는 윈도우라는 자료구조를  통해서 모든 작업을 하게 된다.  윈도우

의 자료형은 WINDOW 인데, 이것은 표준 인크루드  화일(standard include file)

curses.h   정의가 되어있다. 프로그래머는 newwin 이라는 루틴을  사용해

서 새로운 윈도우를 만들 수 있다. 그리고 전역에서 사용할  수 있는 표준 윈도

stdscr 도 있다. curses 에 대해 자세하게 설명하기  전에 두가지 점을 먼저

지적하고 넘어 가려고 한다.

 1. curses 의 루틴들이 자동적으로 프로그램과 링크되는 것은 아니다. 따라서

    컴파일할 때, 사용자가 링크시켜야 한다.

 

   $cc -o scrnprog scrnprog.c -lcurses

 

   terminfo 에 대해서도 같은 방법으로 링크한다.

 2. curses C 언어의 매크로(macro)를 이용해서 정의되는 것이 많다. 따라

    서 프로그래머는 그것들을 사용할 때 주의해야 한다. 그리고 컴파일시 예

    상치 못한 오류 메시지에 대비해야 한다.

 

10.3. curses 의 일반적인 구조

 모든 curses 프로그램은 기본적인 구조로 구성된다.

 

 #include <curses.h>

 

 main()

 {

     initscr();

 

    

 

     endwin();

     exit(0);

 }

 

 curses.h curses 루틴을 사용하는 모든 프로그램에  항상 포함(include)

어야 한다. 시스템  V 에서는 curses.h 에 헤드화일 terminfo.h  가 자동적으로

포함된다. curses.h 에는 curses 의 자료구조와 중요한 매크로들이 들어있다.

 initscr  루틴은 모든  curses  함수에 앞서서  수행시켜야 한다.    루틴은

curses   자료구조를 초기화하고 UNIX 환경의  TERM 변수를 통하여  단말기의

종류를 결정한다. 그렇게 함으로서 원래의 단말기 상태로 돌아갈  수 있고 커서

는 맨 아래 왼쪽에 위치하게 된다.

 

 #include <curses.h>

 

 main()

 {

     initscr();

     refresh();

     endwin();

 }

 

 refresh 또는 더 일반적인 버전인 wrefresh   수행시켜야만 윈도우으 내용이

실제화면 (physical screen) 에 나타나게 된다. refresh  는 표준윈도우 stdscr

의 내용을 실제화면에 표시하고, wrefresh 는 특정 윈도우의  내용을  실제화면

에 표시한다.

 

10.4. 모드 지정

 curses 루틴을 사용하는  프로그램에서는 initscr 을 수행시킨 다음  단말기의

입출력 모드를 지정한다.

 

  echo();

  noecho();

 

 단말기의  반향(echo)  기능을   작동시키거나  정지시킬    있다.   디폴트

(default)로는 반향 기능을 작동시킨다.

 

  nl();

  monl();

 

 nl 은 출력시 개행문자(newline) newline/ carriage-return  으로 바뀌어서

출력되거나, 입력시  newline/carriage-return 이 개행문자로 바뀌어서  입력된

. default nl 이다.

 

  cbreak();

  nocbreak();

 

 cbreak 는 입력시,  인터럽트(interrupt) 와 흐름 제어 키(flow control  key)

를 제외하고는 입력자료에 어떠한 작용도 가하지 않는다.

 

  raw();

  noraw();

 

 raw 는 단말기를 RAW  모드로 만든다. 이 모드는 CBREAK 모드와  비슷한데,

른것은  신호처리(signal processing) 흐름제어마저 작동중지시킨  상태라는

점이다.

 

  savetty();

  resetty();

 

 단말기의 상태를 저장하거나 복구시킬 수 있다. savetty   현재 단말기 상태

curses 의 내부버퍼에  저장해 준다. restty 는 바로 전에 savetty   저장

해둔 상태를 복구시킨다.

 

10.5. 문자와 문자열 쓰기

 curses 는 윈도우 stdscr 에 문자와 문자열을 쓰는 4 개의 루틴을 제공한다.

  addch, mvaddch, addstr, mvaddstr 이다.

 

 #include <curses.h>

 

 int c, y, x;

 char *string;

 .

 .

 addch(c);

 

 mvaddch(y, x, c);

 

 addstr(string);

 

 mvaddstr(y, x, string);

 

 addch 루틴은 stdscr 상의  현재 커서 위치에 문자 c 를 쓴다. refresh  를 해

주어야만 실제  화면에 나타난다. CTRL-C   ^C 처럼 쓰인다. mvaddch  루틴은

커서를 세로로 y  번째 줄, 가로로 x 번째  열로 움직인 후에 글자를 쓴다. 

윗줄 왼쪽이  좌표(0,0)이다. addstr  mvaddstr  0  으로 끝나는  문자열

string 을 윈도우 stdscr 에 쓴다.

 

10.6. 형식화된 출력

 curses 에는 C 언어의  printf 와 비슷한 기능을 제공하는 루틴들이  있다.

준 윈도우 stdscr 에 쓰이는 루틴들로는 printw mvprintw 가 있다.

 

 #include <curses.h>

 

 char *fmt;

 int y, x;

 

 /* NB arg0, arg1 ... argn have arbitrary

    type */

 .

 .

 printw(fmt, arg0, arg1, ... argn);

 

 mvprintw(y, x, fmt, arg0, arg1, ... argn);

 

10.7. 커서 이동

 move 명령을 사용하여 표준 윈도우 stdscr 위에서 커서를 움직일 수 있다.

 

 #include <curses.h>

 

 int y, x;

 .

 .

 move(y, x);

 

 매개변수  y   x   사용하여  새로운 좌표에  커서를 위치시킬    있다.

refresh 가 수행되어야만 실제 커서 위치가 바뀐다.

 

 getyx 루틴을 사용하여 커서의 현재 위치를 알수 있다.

 

 #include <curses.h>

 

 int y, x;

 WINDOW *w;

 .

 .

 

 getyx WINDOW   대한 포인터가 첫번째 변수로 주어져야 한다.  첫번째 변

수로 표준 화면인  stdscr 을 사용하면 표준  화면상의 현재 커서 위치를  얻을

수 있다. 수행 결과는 y x 변수 에 주어진다. getyx 가 실제  C 함수가 아니

라 매크로(macro)이기 때문에 가능한 것이다.

 

10.8. 키보드 입력 : getch

 curses 에서 키보드로 부터 하나의 문자를 받아 들일 경우에  getch 를 사용한

. getch C 언어의 getc 루틴처럼 정수값을 돌려준다.

 

 #include <curses.h>

 

 int in_ch;

 .

 .

 in_ch = getch();

 

 기능키 입력

  처음 해야하는  작업은 curses  keypad 루틴을  수행시켜서 단말기의  키패드

(keypad)를 초기화시키는 것이다.

 

   keypad(stdscr, TRUE);

 

 특수키는 curses.h 에 정의된 값을 통해 돌려준다. ASCII  값과의 충돌을 막기

위해 이 값들은 8 진수 401 부터 시작된다.

 

  int in_ch;

  .

  .

  in_ch = getch();

 

  switch(in_ch){

     case KEY_DOWN;

         

          .

          .

     case KEY_UP;

         

          .

          .

  }

 

10.9. 화면 입력 : inch

 stdscr 의 특정 위치에 어떤 문자가 있는 지 알아야 될 경우가  있다. inch

화면의 현재 커서 위치에  있는 문자를 돌려준다. 그리고 mvinch   주어진 위

치의 문자를 돌려준다.

 

 #include <curses.h>

 

 int in_ch;

 .

 .

 in_ch = inch();

 

 in_ch = mvinch(y, x);

 

 화면상의 글자에는 하이라이트 타입(highlight type)  같은 속성(attribute)

지닌 경우가 있다. 이때  실제 문자만을 얻고 싶으면 curses.h 에서  정의된 상

A_CHARTEXT 와 비트단위 AND 를 해야한다.

 

  cvalue = ivalue & A_CHARTEXT;

 

10.10. 화면 편집

 이미 그려진 화면을  변화시켜야 하는 경우가 종종 있다. curses  에는 이러한

경우에 유용 한  여러가지 루틴들이 있다. 이러한 루틴들을 3가지로  구분할 수

있다.  화면을 백지화(clear)시키는  , 문자들을  지우고 화면을  재구성하는

, 화면을 전혀 지우는 것없이 문자를 끼워 넣는 것등이 있다.

 

 stdscr 상에서 화면의 일부분을 지우는 루틴

 

  #include <curses.h>

  .

  .

  erase();

 

  clear();

 

  clrtobot();

 

  clrtoeol();

 

  erase   clear 은 둘다 표준  윈도우 stdscr의 모든 위치에  공백(space)

쓴다. 다른점은  clear  는 또한 다음번 refresh 가 호출될 때   화면을 자동적

으로 백지화 시킨다는 점이다.  clrtobot 는 현재줄의 커서  오른쪽에 있는 

든 문자와 커서 아래에 있는 모든 줄을  지운다.  clrtoeol 은 현재줄에서 커서

  오른쪽에 있는 모든 문자를 지운다.

 

 화면상의 문자들을 지울 뿐만 아니라 문자를 지우면서 생긴  공백을 메꾸기 위

해서 화면을 이동시키는 루틴

 

  #include <curses.h>

 

  int y, x;

  .

  .

  delch();

  mvdelch(y, x);

 

  deleteln();

 

  delch 의 경우 현재  커서 위치에 있는 문자가  지워진다. 그리고 그  공백을

메꾸기 위해   커서의 오른쪽에 있는  문자들을 한 칸씩 왼쪽으로  이동시킨다.

mvdelch 도 기능이 거의   같다. 다만 먼저 커서를 주어진 위치에 이동시킨 

delch 와 같은 기능을 수행한다. deleteln 은 커서가  있는 줄을 지운다.

리고 나서 그 줄 밑에 있던 모든 줄을 한 칸씩 위로 이동시킨다.

 

 문자를 끼우는 데 관련된 루틴

 

  #include <curses.h>

 

  int c, y, x;

  .

  .

  insch(c);

  mvinsch(y, x, c);

 

  insertln();

 

  insch 는 현재  위치에 문자 c   끼운다. 현재 커서 위치의 오른쪽에  있는

글자들은 모두  한 칸씩 오른쪽으로 이동한다.  그 줄의 마지막에 있는  문자는

잃어버리게 된다. mvinsch   커서의 위치를 바꾼 다음 insch   같은 작용을

한다. insertln 은 커서가 있는 줄의 위에 빈 줄(blank  line)을 하나 집어넣는

. 그 줄 밑에 있는 줄들은 모두 한 줄씩 밑으로 이동한다.  따라서 화면의 맨

밑에 있던 줄은 화면상에서 사라지게 된다.

 

10.11. 영상 속성

 curses 에서는 특정 모드로 글자를 화면에 나타내고 싶으면  그 모드에 해당하

는 상수와 비트단위 OR 하면 된다.

 

  addch(ch|A_BOLD);

 

  ch 를 볼드체(bold;주위의 글들보다 더 밝은 모드)  로 나타낸다. 이외에도

여러가지 모드가 있다.

 

  A_STANDOUT   이 모드는 글자를 집중모드로 나타낼때 쓰인다.

  A_REVERSE    역전 모드

  A_BOLD       글자들이 보울드로 나타난다.

  A_DIM        글자들이 기본모드보다 약간 어둡게 나타난다.

  A_UNDERLINE  글자 밑에 밑줄이 그어진 형태로 나타난다.

  A_BLINK      글자들이 반짝인다.

 

  #include <curses.h>

 

  int atts;

  .

  .

  attrset(atts);

 

  attron(atts);

 

  attroff(atts);

 

  standout();

 

  standend();

 

  attrset 은 표준  화면상에서 모드를 작동시킬때 사용하는 루틴이다.  attron

루틴은 atts 에 주어진 모드들을 작동시킨다. 이 루틴은  앞에서 지정된 모드를

바꾸지는 않는다. 마찬가지로  attroff 는 선택된 모드를 해제한다. 그리고 

루틴  standout     standend     각각  attron(A_STANDOUT)     attroff

(A_STANDOUT) 와 동일한 기능을 한다.

 

10.12. 새 윈도우 화면의 생성과 조작

 새로운 윈도우를 다루는 방범을 소개한다. 윈도우를 위한  가장 기본적인 루틴

newwin 이다.

 

  #include <curses.h>

 

  WINDOW *win;

  int lines, cols, startline, startcol;

  .

  .

  win = newwin(lines, cols, startline,

       startcol);

 

  이 루틴을 수행시키면 세로 크기가 lines, 가로 크기가 cols  인 윈도우가 생

긴다.

 

  wmove(win, y, x);

 

  이 루틴을 수행하면  윈도우 win 상의 현재 커서 위치가  좌표(x,y)로 바뀌게

된다.  이 좌표는 표준  윈도우 stdscr 표가 아니라  윈도우 win   맨윗줄 맨

왼쪽을 기준으로  한 좌표이다.

 

  wrefresh(win);

 

  은 윈도우 win 에 있는 내용들이 실제 화면에 나타난다.

 

10.13. curses : domenu

  -- 생략

 

10.14. 하드웨어 의존 단말기 조정 : terminfo

 terminfo 라이브러리는 프로그래머가  직접 단말기의 하드웨어를 직접  제어하

는 기능을 제공한다.  terminfo 데이타베이스에는 각 단말기의 특성을 얻을 

있다.  가장 크게 문제가 발생하는 경우가  패딩(padding, 속도늦춤)을 할때다.

이단어는 단말기가  프로그램의 속도를  적당히 유지하도록 출력속도를  늦추는

것을 의미한다.

 

   #include <curses.h>

   #include <term.h>

 

   main()

   {

       setupterm(0, 1, 0);

       putp(clear_screen);

       reset_shell_mode();

       exit(0);

   }

 

   화면을 백지시키는 프로그램이다. term.h에는 clear_screen   포함하여 여

러가지 기능을 나타내는  매크로들이 정의되어있다. setr-pterm termino 

초기화루틴이다. putp 을 호출하면 화면을 백지화시키기는 문자열을  화면에 내

보낸다. putp 는 좀더  일반적인 기능을 갖는 루틴 tputs   제한된 버전이다.

reset_shell_mode 는 단말기를 원래의 상태로 되돌린다.


'Academy I > Tech Academy' 카테고리의 다른 글

Linux make 사용법 [II]  (0) 2014.12.22
VirtualBox의 Linux(CentOS)에서 공유폴더 설정  (0) 2014.12.22
Linux gdb 사용법 [I]  (0) 2014.12.19
Linux make 사용법 [I]  (0) 2014.12.18
Unix System Programming 9  (0) 2014.12.16
Unix System Programming 8  (0) 2014.12.16
Unix System Programming 7  (0) 2014.12.16
Unix System Programming 6  (0) 2014.12.16