X 윈도우 프로그래밍 > 리눅스 스터디

본문 바로가기
사이트 내 전체검색

리눅스 스터디

X 윈도우 프로그래밍

페이지 정보

본문

X 윈도우 프로그래밍 기초과정
  이만용, geoman@nownuri.net
  1996년 3월 19일
  ____________________________________________________________

  목차

  1. 시작하면서
    1.1 강의의 대상
    1.2 대략적인 강의 내용 소개

  2. X 프로그래밍 기초 : Xlib
    2.1 X 윈도우 프로그래밍에 들어가기 앞서
    2.2 X 윈도우 프로그래밍이란 ?
    2.3 알아두어야 할 사실
    2.4 자, 이제 시작해볼까요?
        2.4.1 Display란?
        2.4.2 XOpenDisplay 함수
        2.4.3 XCloseDisplay 함수
    2.5 간단한 창 하나 만들어 봅시다.
        2.5.1 Window 형 변수
        2.5.2 창 생성, 표시 ...
        2.5.3 XCreateSimpleWindow 함수에 대하여...
        2.5.4 XMapWindow()
        2.5.5 XFlush()
        2.5.6 컴파일
        2.5.7 실행
    2.6 창 안에 또 창을 만들어 봅시다.
        2.6.1 모든 창은 자식창을 여러 개 가질 수 있다.
        2.6.2 자식창들을 한꺼번에 나타내자.
        2.6.3 쓸모없는 자원은 없애자.
    2.7 이제는 흑백이 아니라 칼라 창을 만들어봅시다.
        2.7.1 컬러맵이란?
        2.7.2 원하는 색을 선택하기 위해 거치는 과정
        2.7.3 요약
    2.8 만들어 놓은 창 가지고 놀기
        2.8.1 이미 만들어 놓은 창 색깔 바꾸기
        2.8.2 창에 대한 여러 정보를 알아냅시다.
        2.8.3 이제는 창의 geometry를 바꾸어 봅시다.

  3. 휴식강의 : 리소스(Resource)
    3.1 리소스(Resource)란 무엇인가?
    3.2 리소스 Name과 Class
    3.3 객체의 리소스
    3.4 Xlib의 리소스 매니져
    3.5 어플리케이션 디폴트 화일 다루기
    3.6 사용자 리소스 화일 .Xdefaults
    3.7 xterm 의 리소스에 관하여
    3.8 멀티 리소스 셋팅 가지기
    3.9 기 타

  4. X 프로그래밍 기초 : 그래픽
    4.1 X 윈도우 그래픽의 기본 개념
        4.1.1 그래픽의 기본 절차
        4.1.2 우선 GC 를 만들자.
        4.1.3 GC의 스타일 설정하기
        4.1.4 이제 물감에 적신 붓으로 그려봅시다.
          4.1.4.1 점 그리는 함수
          4.1.4.2 직선 그리는 함수
          4.1.4.3 직사각형 그리는 함수
          4.1.4.4 나머지
    4.2 그래픽의 연습

  5. X 프로그래밍 기초 : 폰트
    5.1 폰트 출력에 대하여 ...
    5.2 X 윈도우의 폰트 시스템을 알아봅시다.
    5.3 X Logical Font Descriptio : XLFD 에 대하여
    5.4 영문 텍스트 출력 연습

  6. X 프로그래밍 기초 : 한글폰트
    6.1 한글 출력에 관한 몇 가지 이야기
        6.1.1 시작하는 지루한 이야기
        6.1.2 한글 출력! 무엇이 다른가?
        6.1.3 X 윈도우에서 한글 어플을 개발하는 방법
    6.2 한글 출력 과정
        6.2.1 무엇이 또 문제인가?
        6.2.2 아직도 남은 문제가 있다!
        6.2.3 한글과 영문을 구별해서 찍기
        6.2.4 폰트에 대한 중요한 정보 알아내기
          6.2.4.1 가장 간단한 방법
          6.2.4.2 더 좋은 방법

  7. X 프로그래밍 기초 : 이벤트처리
    7.1 이벤트 처리 방식과 순차적인 처리 방식 차이점
    7.2 복잡한 일은 X 서버가 처리합니다. 우리는 단지...
    7.3 일반적인 코드 형태를 보고 눈에 익힙시다.
    7.4 패턴 분석
    7.5 이벤트 자료형 사용법
    7.6 창마다 자기가 원하는 이벤트만을 예약하기

  8. X 프로그래밍, X 로케일 이용 출력
    8.1 X 윈도우 자체의 로케일 기능을 사용한 한글 출력
        8.1.1 X 윈도우에서의 한글 출력 방식에 대하여
        8.1.2 X 윈도우 시스템이 지원하는 I18N, L10N 이용하기

  9. 마감하면서

  ______________________________________________________________________

  1.  시작하면서

  리눅서들은 단지 기성제품을 사용하는데 만족하지 않고, 뜯어고치고
  창조하는 일을 좋아하는 굉장한 유저들입니다. 리눅스 커널버전과 슬랙버전
  만큼 빨리 변하는 운영체제 소프트웨어가 어디 있겠습니까? 또 이만큼
  운영체제의 "기본기"에 충실한 체제가 어디 있겠습니까? 그래서 우리
  리눅서들은 어떤 유저들보다도 자부심이 대단합니다.

  리눅스여, 만세 만세 만만세!

  리눅스를 사용하면서 컴파일을 안해보신 분이라면 아직 리눅스의 진가를
  맛보지 못하신 분이라고 할 수 있지요. 리눅스를 사용하면서 자기 스스로
  프로그램을 짜보지 못하신 분들은 리눅스의 진짜 진짜 진가를 맛보지
  못하는 분이라고 할 수 있습니다.  이제부터는 리눅스의 참맛을 만끽해볼까
  합니다.

  1.1.  강의의 대상

  제목에서도 분명하게 나타나는 것처럼, 제가 다루고자 하는 내용은
  프로그래밍 일반에 관한 것이 아닙니다. 그것은 제가 다룰 수 있는 한도를
  벗어납니다. 이 강좌를 읽고자 하시는 분들은 기본적으로 다음과 같은
  사항에 모두 해당되시는 분들이셔야 원할한 학습이 이루어질 것이라고
  생각합니다.

  ? 기본적인 C 프로그래밍을 하실 수 있는 분

  ? SHELL 스크립트에 대해 아시는 분

  ? 유닉스 계열의 프로세스/화일처리/시그널 등의 개념을 아시는 분

  좀 사양이 높죠? 그래서 그 동안 망설이게 되었습니다. 우선은 리눅스
  대중화에 기여할 수 있는 기본적인 것들에 대해서만 강의를 진행할까? 하는
  생각도 수없이 많이 해보았습니다. 그러나 리눅스동의 많은 분들께서도
  양적변화 뿐 아니라 이젠 질적변화를 서서히 추구해야 한다는 문제의식을
  가지신 것 같아서 용기를 내어 해봅니다.

  1.2.  대략적인 강의 내용 소개

  재차 말씀드리지만 강의내용은 리눅스 프로그래밍 일반에 대하여 다루지
  않습니다.  저는 X 윈도우 시스템의 GUI 자원을 자신의 프로그램에서
  이용하는데 대하여, 즉 X 윈도우용 프로그램의 "인터페이스"에 관한 내용만
  다루고자 합니다.

  ? X 내에서 창의 생성과 소멸, 관리

  ? X 그래픽

  ? X Event 처리하기

  ? 키보드/마우스 등의 입력

  ? 기타 등등

  MS 윈도우즈 같은 GUI 체제에서의 프로그래밍을 해보신 분들은 아실겁니다.
  거의 시중에 있는 대부분의 책들이 이러한 내용을 다루고 있지요. 위
  내용만 익히신다고 해서 완전한 의미의 X 윈도우용 프로그램을 만드실 수는
  없을 겁니다. 하지만 위의 내용을 모르신다면 X 윈도우용 프로그램은
  절대로 만드실 수 없습니다. 그 정도로 아주 기초적인 내용만을 담고
  있습니다.  더욱 심도깊은 X 윈도우 프로그래밍 강좌는 이번 기초 강좌가
  끝난 후에야 가능할 것 같습니다. ( 그 유명한 위젯 같은 것 등등 )

  2.  X 프로그래밍 기초 : Xlib

  X 윈도우 프로그래밍에 도전하시는 여러분을 환영합니다. 저도 아는 것은
  많이 없지만 여러분을 조금이라도 도울 수 있다면, 그리고 저의 강좌를
  계기로 더욱 더 많은 수준높은 X 윈도우 프로그래밍 강좌들이 생겨나길
  기대하면서 X 윈도우 프로그래밍 기초과정을 시작할까 합니다. 어렵더라도
  포기하지 마시고 끝까지 저와 함께 가셔서 당당한 X 윈도우 프로그래머로
  우뚝 서십시요. 그리고 리눅스를 빛내줍니다.

  2.1.  X 윈도우 프로그래밍에 들어가기 앞서

  여러분의 선택은 정말로 탁월합니다. X 윈도우 시스템은 MS 윈도우즈 95와
  같은 엉터리에다 단명하는 체제와는 전혀 다른 수준의 안정되고 표준적인
  시스템입니다.  여러분께서 미래를 생각하신다면, 바로 X 윈도우
  프로그래밍을 선택하십시요.

  자, 우선 점검해야 할 것들이 있습니다. 여러분의 시스템이 X 프로그래밍을
  할 준비가 되어 있는지 알아봐야 하지 않을까요? 이 글을 읽는 분들은
  최소한 X 윈도우가 작동하고 계신 선택받은(?) 분들일 것이고, 남은 것은
  여러분이 슬랙웨어 설치시 X 프로그래밍을 할 수 있는 헤더 파일 등을
  제대로 설치하셨는지 확인해 보시기 바랍니다. /usr/include/X11 ㅤ그리고
  /usr/X11/lib 에 화일들이 있는지 말입니다.

  모두 이상없다고요? 네, 그러면 시작합시다.

  2.2.  X 윈도우 프로그래밍이란 ?

  X 윈도우 프로그램이란 X 윈도우의 '자원(Resource)'을 이용하는
  프로그램입니다.  X의 자원들은 대표적으로 창(Window), 색상(Color Map),
  폰트(font) 등이 있습니다.  이러한 자원들을 X 윈도우 서버(Server)라고
  하는 녀석이 전권을 가지고 관리하고 있습니다. 우리의 역할은 이미 정해져
  있는 '규칙'에 따라서, 자원을 관리하고 있는 서버에 연결하여, 서버더러
  우리가 원하는 자원을 서비스해달라고 요청하는 일입니다. 바로 우리는
  서버라는 놈과 어떻게 연결할 것인지, 그리고 어떻게 서버더러 이것 저것
  우리가 원하는 것을 달라고 하는지를 배우는 것을 목표로 하게 됩니다.

  이러한 프로그램을 클라이언트(Client)라고 하지요. 서버/클라이언트
  개념이라고 해서 항상 프로그램을 "무엇이 무엇에 연결하여 원하는 일을
  한다"라는 사고방식 하에 모든 프로그램을 짜게 됩니다. 이는 더 나아가
  세계 저편에 있는 서버에 우리집의 클라이언트가 연결을 하여 서비스를
  받는다는 "네트워크 지향적"이고 미래 지향적인 프로그래밍이 됩니다.
  인터넷 시대를 살고 있는 우리에게는 아주 중요한 개념이라고 할 수
  있습니다. 여러분께서 저와 함께 X 프로그래밍의 세계를 탐험하시다 보면
  아주 자연스럽게 멋진 네트워크 프로그램에 도전하실 수 있을 겁니다.

  우리는 단지 정해진 규칙에 따라 서버에 연결하고, 서비스를 받고, 연결을
  해제 하는 것을 배우는 것일 뿐이라는 사실을 항상 명심해주세요!

  2.3.  알아두어야 할 사실

  여러분 모두 당장에 실제적인 X 윈도우 프로그래밍을 하고 싶으실 겁니다.
  하지만, 이러한 사실들은 알고 들어가셔야 더욱 더 빨리 프로그래밍에
  익숙해지실 수 있다고 생각합니다.

  cd /usr/X11/lib 해보세요. 그리고 ls ... lib라는 문자로 시작하는 많은
  화일들이 있는 것을 확인하실 수 있을 겁니다. 이 녀석들 '라이브러리'는
  우리를 항상 도와주는 놈들입니다. 이들이 없으면 아무 것도 할 수가
  없습니다. 이 녀석들을 여러분께 소개시켜 드리고자 합니다.

  ? libX11 : 이름에도 드러나듯이 가장 기본적인 라이브러리입니다. 모?    친구들은 이 친구 없이는 무용지물입니다. 가장 중요한, 그리고 가장
    본질적인 X 의 기능을 실현해주는 Xlib 입니다.

  ? libXt  : X 툴킷(X Toolkit Intrinsic)이라고 부릅니다. Xlib 위에서
    구현되어 있는 아주 유용한 루틴들입니다. 나중에 위젯이라고 하는 X
    인터페이스에서 아주 중요한 놈들을 다룰 때 많이 사용합니다. 이것을
    자유자재로 사용하실 수 있는 수준이 되시면 X 프로그래밍은 끝난 거나
    다름없죠.

  ? libXaw : Athena Widget 입니다. 앞글자를 따서 aw 입니다. 지금 현재는
    거의 상용 모티프(Motif)만이 사용되어 거의 씌이지 않는 것 같습니다.
    하지만 X를 개발한 MIT가 만든 것으로서 Free 이므로, 저는 여러분과
    미흡하나마 이 친구를 가지고 예쁜 프로그램 인터페이스를 만들어
    볼까합니다. 모티프에 관한 것은 서점에 책이 온통 깔려 있으니 그것을
    참고하시면 됩니다. 어찌 되었든 알아두시면, 모티프도 금방 사용하실
    수 있습니다. 요즘 libXaw3d가 나와있는데, 원판 libXaw가 워낙
    초라해서 한계가 있기는 하지만, 제 개인적인 견해는 그래도 설치하시는
    것이 더 좋다입니다.  세연이나 고스트스크립트의 버튼이 약간
    3차원적으로, 그리고 모티프 냄새를 풍기더군요.

  ? libXmu : Miscellaneous Utilities의 앞글자들만 따서 mu 입니다. 기타
    등등의 기능을 구현해주는 녀석이지만, 없어서는 안될 녀석입니다. 그
    기타 등등이라고 하는 것이 하도 많이 쓰여서...

  ? libXpm : 확장자가 xpm인 화일들 보신 적 있으시죠? 컬러 비트맵 화일
    지원 등의 그래픽 지원 라이브러리입니다. 안 중요할 리가 있을까요?

  나머지 친구들은 소개시켜 드리기 힘들군요. 아직 때가 되지 않아서...
  나중에 소개시켜 드릴 기회가 올 지...

  2.4.  자, 이제 시작해볼까요?

  클라이언트가 제일 먼저 해야 할 일은 무엇일까요? ...  서버에 접속하는
  일입니다.

  과연 나는 어떤 서버를 선택할 것인가? 하는 문제를 해결해야 합니다. 보통
  도스, 윈도우즈 환경에 익숙하신 분들은 좀 생소한 개념이지요. 하지만
  요즘은 인터넷을 많이 하시기 때문에 이해하시기 어렵지는 않을 겁니다.
  리눅스 X 윈도우 환경에서는 아주 간단한 문장들로 여러분 옆에 있는
  컴퓨터 말고도 세상 저편에 있는 컴퓨터의 모니터에다 하나의 창을 띄우는
  일 정도는 너무도 쉽게 할 수 있거든요.

  vi, emacs와 같은 에디터를 이용해서 다음과 같은 내용이 들어 있는 화일을
  하나 만들어 보세요.

  ? 예제 1

        #include <X11/Xlib.h>

        main()
        {
              Display *d ;

              d = XOpenDisplay ("localhost:0.0") ;

              XCloseDisplay (d) ;
        }

  만약 위의 내용을 ex01.c라는 이름으로 저장하셨다면,

      cc -o ex01 ex01.c -lX11 해보십시요.

  컴파일이 잘됩니까? 안된다구요? 왜 그럴까요? 힘든 영어지만 에러 사유를
  잘 보시면 아마도 헤더파일을 못찾는다고 그러지 않나요?

  그러면 다음과 같이 INCLUDE 디렉토리를 지정해주십시요.

      cc -o ex01 ex01.c -I/usr/include/X11 -lX11

  컴파일은 되도 링크가 안되다면 라이브러리 디렉토리도 지정해주세요.
  -L/usr/X11/lib 를 명령행에 추가시키시면 됩니다.

  제대로 컴파일이 이루어졌다면, 실행을 시켜보죠. ex10 엔터!

  여러분께서 실망하시는 것을 느낄 수 있습니다. :) 이게 뭐냐?

  하지만! 이 프로그램은 X 윈도우 프로그래밍의 거의 모든 것을 보여주는
  것이나 다름없는 아주 중요한 프로그램입니다. 저는 그렇게 우기고 싶네요.
  :)

  이 엉터리(?) X 윈도우 프로그램에 대한 설명을 드리고자 합니다.

  첫줄 INCLUDE 문장은 XOpenDisplay, XCloseDisplay, Display 변수가
  선언되어 있는 헤더화일 Xlib.h를 포함시키는 문장입니다. 다음으로 당연히
  main 함수가 정의되어야겠죠?

  Display형 포인터 d 를 선언합니다.

  2.4.1.  Display란?

  디스플레이가 무엇인지 잘 아실 겁니다. 여러분께서 바로 눈 앞에 두고
  계신 것이 모니터라고 하는 '디스플레이'입니다. 그런데 여기서
  Display라고 하는 것은 X 윈도우 시스템에서 약간 확장된 의미로
  생각합니다.

  정의 : Display란 하나의 서버가 관리하고 있는 1개 이상의
  스크린(Screen), 1개의 키보드, 마우스 등등으로 구성되어 있는 집합체이며
  워크스테이션(Workstation) 이라고 부르기도 한다.

  이러한 디스플레이는 보통 모니터 하나 전체를 나타내는 스크린을 하나
  갖는 경우가 보통이지만 특수한 경우 2개 이상의 스크린을 갖는 경우도
  있을 수 있습니다. 하나의 컴퓨터에 두 개의 모니터를 쓰는 "듀얼 모니터"
  시스템도 종종 볼 수 있습니다. 그 경우 하드웨어가 받쳐준다면, X
  시스템은 두 개의 화면을 각각 이용할 수도 있습니다. 이런 프로그램 하나
  만들면 정말 재미있겠죠? X 윈도우 시스템에서는 너무도 쉽게
  이루어집니다.

  2.4.2.  XOpenDisplay 함수

  자, 이제 우리가 원하는 디스플레이 서버에 접속을 해봅시다.

      XOpenDisplay ("localhost:0.0");

  이 문장은 localhost의 0번 디스플레이(즉, 첫번째 디스플레이)의 0번
  스크린(즉, 첫번째 스크린)에 접속하라는 뜻입니다. localhost는 바로
  여러분 컴퓨터를 지칭하는 호스트명입니다. 이것을 만약 다른 인터넷
  호스트 주소로 써준다면, 어떻겠니까?  여러분의 컴퓨터가 네트워크에
  물려있고, 상대방 호스트를 사용할 권한이 주어져 있다면, 우리 프로그램은
  저 멀리에 있는 호스트 서버와 연결을 하게 됩니다. 아니, 이렇게 간단할
  수가!!! 인터넷 프로그램이라는 것이 별 것 아니군요.

  localhost:0.0 과 같은 표현식을 눈여겨 보아주십시요. 명령행에서 한 번
  set 이라고 쳐보세요. 아마 내용이 많아서 more 를 해주셔야 할 겁니다. 한
  번 그 내용을 주루룩 살펴보시면 DISPLAY=:0.0이라는 표현식을 찾으실 수
  있을 겁니다. 그 다음으로 HOSTDISPLAY=freeyong:0.0 이런 표현도 보실 수
  있을 겁니다. 물론 freeyong과 같은 부분은 여러분마다 다르지요.
  여러분께서 지정해주신 이름이 나타날 겁니다.  localhost:0.0 을
  freeyong:0.0등으로 바꾸어 주셔도 됩니다. 하지만 일부러 아무 의미도
  없는 이름을 주어보십시요. 컴파일하고 실행을 시켜 보시면 그 결과를 아실
  수 있을 겁니다. 꼭! 확인해보세요. 보통은 표현식 부분에 NULL을 주면
  현재 DISPLAY라는 환경변수의 값을 읽어서 서버로 사용합니다.

  2.4.3.  XCloseDisplay 함수

  접속해서 한 일은 하나도 없지만, 이제 접속을 마쳐야 하지 않을까요?  그
  함수가 바로 XCloseDisplay 함수입니다.

  오늘은 아주 아주 간단하지만, 또한 아주 아주 근본적인 프로그램을 하나
  짜보았습니다. 모든 X 윈도우 프로그램은 기본적으로 예제 1 프로그램과 그
  형식이 같습니다. 서버에 연결하고 서비스 받은 후, 접속을 해제합니다.
  모든 유용한 작업은 XOpenDisplay 함수와 XCloseDisplay 함수 사이에
  적어주시면 됩니다.

  이 글을 다 읽으신 후, 꼭 Xlib.h 화일의 내용을 살펴보십시요. 예를 들어
  Display 형 변수는 어떻게 선언, 정의되어 있는지 보시면, 정말로 많은
  정보를지니고 있는 구조체(struct)라는 것을 확인하실 수 있습니다.

  2.5.  간단한 창 하나 만들어 봅시다.

  앞에서 만든 원초적(?) 프로그램은 단지 서버와 접속하자 마자 접속을
  끊어버리는 경우였습니다. 그럼, 이제는 서버에 접속하고 나서 아주 간단한
  일을 하나 시켜보도록 합시다. 바로 창 하나를 만들어서 표시해보는
  겁니다.

  ? 예제 2

        #include <X11/Xlib.h>

        main()
        {
              Display *d ;
              Window  w, root ;

              d = XOpenDisplay(NULL) ;

              root = XDefaultRootWindow (d);
              w = XCreateSimpleWindow ( d, root, 50, 50, 400, 300,
                                        2, BlackPixel (d,0), WhitePixel(d,0) );
              XMapWindow (d, w);
              XFlush (d);

              getchar();

              XCloseDisplay (d);
        }

  이번 예제에서는 Window 라는 새로운 자료형과 XDefaultRootWindow(),
  XCreateSimpleWindow(), XMapWindow(), XFlush() 등의 새로운 함수들이
  나오는군요.  앗! BlackPixel(), WhitePixel()과 같은 매크로도
  보이는군요. 하지만 이 매크로들은 나중에 설명드리기로 하겠습니다.
  하루에 너무 많은 것을 배우면 머리가 아프잖아요?

  2.5.1.  Window 형 변수

  우리가 창을 만들고 싶을 때는 창 하나마다 위의 예에서 나온 Window 형
  변수 하나가 필요하다고 생각하시면 됩니다. Window 형 변수 하나는 그
  창에 대한 모든 정보를 지니고 있는 복잡한 구조체 정도라고 생각하시면
  됩니다. 예상할 수 있는 것으로는 창의 크기, 위치, 색상 등이 있습니다.

  2.5.2.  창 생성, 표시 ...

  지금부터 설명드리는 기본적인 절차를 꼭 머리 속에 넣어두세요.  어떤
  창을 만들든지 우리는 우선적으로 그 창에 대한 정보를 저장하고 있을 변수
  하나를 이미 만들어놓야야 합니다. 즉 Window 형 변수 하나를. 그 다음
  서버더러 창을 하나 만들겠다고 서비스 요청을 합니다. (조금 뒤에
  설명드리는 함수를 통해) 이변이 없는 한 서버는 창이라는 자원 하나를
  서버 측(!!!)에 만들어 놓습니다.  그리고 창 자원에 대한 자원
  고유번호(Resource ID)를 아까 클라이언트 쪽에서 만들어 놓은 변수에
  반환해줍니다. 이 변수는 바로 클라이언트와 서버 측에 만들어진 한 창에
  대한 연결통로 역할을 해줍니다. 무지 중요하죠?

  이렇게 서버 측에다 창 자원 하나를 만들어놓고, 그 다음에는 ㈆?隙?  원하는 때에 그 창을 화면에 표시해달라고 요청하면 서버가 알아서 그 창을
  표시해줍니다. 물론 요청에 따라 화면에서 사라지게 만들 수도 있습니다.

  또는 현재 나타내져 있는 창에 대하여 배경색과 테두리색을 바꾼다든지
  하는 수정 작업 또한 아까의 Window 형 변수를 통해서 행할 수 있습니다.

  우리는 앞으로 모든 자원에 대하여 서버 측에 자원을 만들어 놓고 우리
  클라이언트 프로그램에서는 단지 그 자원에 대한 ID만을 변수에다
  저장해놓고 있습니다. 그리고 원하는 때에 그 자원을 표시한다든지,
  수정한다든지, 또는 없앤다든지 하는 작업을 행합니다. 그리고 나중에 정말
  필요가 없어진 자원에 대해서는 서버 측에다 삭제하라고 통고합니다.

  제가 이렇게 길게 설명드린 개념을 꼭 숙지해주십시요. 어떻게 보면 우리가
  앞으로 하는 일의 거의 대부분을 말씀드린 것이나 다름없습니다.

  2.5.3.  XCreateSimpleWindow 함수에 대하여...

  함수 이름 그대로 해석해보면 "간단한 창을 생성한다"이지 않습니까?
  우리가 영어 문화권에 살고 있다면, 이것만큼 식은 죽 먹기가 어디
  있겠습니까 만은...  간단한 창을 만드는 함수에 대하여 알아보도록
  하지요.

        함수의 원형(Prototype)

        Window XCreateSimpleWindow (  Display*        display,
                                      Window          parent,
                                      int            x,
                                      int            y,
                                      unsigned int    width,
                                      unsigned int    height,
                                      unsigned int    border_width,
                                      unsigned long  border_color,
                                      unsigned long  background_color );

  함수 한 번 정말 거창하군요. 앞으로 나오는 함수들 대부분이 거의
  이렇다고 생각 하셔도 무방합니다. 정말로 많은 정보를 전달해주어야 하는
  것을 보실 수 있을 겁니다. 짐 캐리처럼 숨을 크게 들이쉰 후, 다다다 쉴
  새 없이 얘기해보자면, 1번째 Display 형 포인터는 XOpenDisplay()에서
  접속한 디스플레이를 가리키는 포인터이며, 2번째 Window는 현재 만들고자
  하는 창의 소속되는 부모 창이며, 3번째, 4번째는 각각 x, y 좌표를
  뜻하고, 5번째는 픽셀 단위의 가로폭, 6번째는 픽셀 단위의 세로폭, 그리고
  7번째는 테두리의 두께, 마지막으로 8번째와 9번째는 테두리 색과 창의
  기본적인 배경색을 카리키는 unsigned long 형 수치값입니다.

  보통 하나의 디스플레이에서 대부분의 일을 해치우니까 1번째 인수가
  상당히 귀찮을 수도 있지만, 생각해보세요, 여러분의 클라이언트
  프로그램이 다중 디스플레이 접속 프로그램이 될 수도 있지 않습니까?
  그러면, 여기 저기 두 개 이상의 디스플레이를 간단하게 제어할 수
  있습니다. 바로 요 첫번째 인수를 가지고 말입니다.  2번째, 부모 창은
  무엇인가? --- X 윈도우의 모든 창은 항상 어떤 창에 속해 있거나, 어떤
  창들을 자기 자식(Child)으로 갖습니다. 아주 근본적으로는 X 윈도우가
  뜨자마자 생기는 창은 바로 테두리도 없는 창, 루트(root)창입니다. 바로
  이 창에 모든 창들이 속하는 것입니다. 어떤 프로그램이든 처음 창은 바로
  루트창의 자식창이 됩니다. 그 창은 다시 자기 자식창들을 얼마든지 가질
  수 있지요. 어찌 되었든간에 새로 생성되는 창은 족보(?)를 가져야 합니다.
  자기 부모창은 알아야 하지 않겠어요?  여기서 잠깐
  XDefaultRootWindow()라는 함수에 대하여 알아봅시다.

  함수의 원형

  Window XDefaultRootWindow ( Display *display );

  이 녀석의 기능은 Display 형 포인터가 가리키는 서버의 기본(Default)
  루트창의 창 ID를 알아다가 ID를 Window 형 변수에다 되돌려 주는
  역할입니다.

  우리가 만들고자 하는 창은 직접적으로 루트창의 바로 아래 자식창이
  되므로, 위에서 나온 XCreateSimpleWindow()의 두번째에서 부모창 ID를
  지정해주어야 하기 때문에 필요한 함수입니다.

  나머지는 자명하므로 8번째, 9번째 색상 지정 부분에 대한 설명만
  드립니다.

  X 윈도우에서 색상은 또한 서버가 제공하는 하나의 자원으로서 서버가
  관리를 하고 있습니다. 따라서 우리가 생각하는 것 만큼 쉽게 색상을
  쓰거나 할 수는 없습니다.  혹시 여러분은 XV 와 같은 그래픽 프로그램을
  쓰면서 그래픽 화면의 질이 어떨 때는 다르게 나타나는 것을 경험해보신 적
  있습니까? 그 경우엔 XV가 원하는 만큼의 색상 자원을 서버에게서 공급받지
  못하기 때문입니다. 어떤 이유에서든...

  예에서 드러나듯 그냥 검정과 흰색을 지칭하는 쉬운 숫자를 쓰는 게
  아니라, BlackPixel(), WhitePixel()이라는 매크로를 썼습니다. 이번
  강좌에서는 색상을 쓰는 과정이 그렇게 간단하지는 않다는 사실만
  기억해주시기 바랍니다. 조만간에 색상에 대한 얘기가 이어집니다. 그
  때까지만 참아주십시요.

  2.5.4.  XMapWindow()

  이 녀석은 무엇인가 하면, 위에서 서버측에 만들라고 통보한 창을 실제로
  나타내라는 지시를 서버에 보내는 녀석입니다. 창의 생성과 표시는 별개의
  과정이지요.

        함수의 원형

        XMapWindow ( Display *display, Window w );

  특정 디스플레이 서버에서 w라는 창을 화면에 실제로 표시합니다.  여기서
  영어 Map은 동사로서 "지도로 그리다","배치하다"의 뜻입니다. 제가 다니는
  지질과학과에서는 지질도 그리는 것을 매핑(Mapping)한다라고 말합니다.

  2.5.5.  XFlush()

  아니, 이건 또 뭘까요? 플러쉬(flush)는 화장실에서 볼 일을 다 본 후,
  변기의 물을 내리는 것을 말합니다. 한꺼번에 물을 좍 흘려보내는 그런
  일입니다. X 윈도우에 뭐 그런 일이 필요하냐구요? 거참 이상하군요.

  C 프로그램을 공부해보시면, printf와 같은 많은 출력문들이 실행 직후에
  출력이 이루어지는 것은 아니라는 사실을 아실 겁니다. 실제는 매번 출력
  명령을 받을 때 마다 출력을 하는 것보다는 한꺼번에 버퍼에 모아놓고 때가
  되면 단 한 번의 실행으로 효율성을 높이는 기술을 채택합니다. X 윈도우도
  또한 그렇습니다. 그 수많은 클라이언트들로부터의 서비스 요청을 그 때 그
  때 실행하게 되면 능률이 떨어지게 되므로, 서버는 버퍼를 마련하고 그
  버퍼가 차거나 버퍼를 비우라는 명시적인 요구가 있을 때만 실행을 하게
  됩니다.
  이번 예는 X 윈도우 서버에게는 콧방귀도 뀔 필요가 업을 만큼, 자잘한
  요구이기 때문에 그런 명령을 내린다고 해서 버퍼가 찰 리 만무합니다.
  그러니, 강제로 '변기 물을 쫙 내려야겠죠?'

        함수의 원형

        XFlush ( Display *display );

  2.5.6.  컴파일

  위 예제를 ex02.c라고 저장하셨다면,

        cc -o ex02 ex02.c -lX11 -I/usr/X11/include -L/usr/X11/lib

  보통 -I, -L 옵션은 주지 않으셔도 되지만 제대로 헤더화일과 라이브러리를
  찾지 못할 때는 명시적으로 주시면 됩니다.

  2.5.7.  실행

  자, 이제 X 터미널 상에서 실행을 해볼까요?  우리가 예상했던 것과는 좀
  다를 것입니다. 왜냐구요? 여러분께서 fvwm과 같은 윈도우 관리자를 쓰고
  계시면, 우리가 의도하지는 않았지만 그 놈이 우리가 만들고자 하는 창의
  모양에 개입하고 들어오기 때문입니다. 이 부분에 대한 설명 또한 다음
  번으로 미루기로 하고 단지 창이 만들어졌다는 것만 확인하고 넘어가죠. :)

  종료는 실행시킨 터미널 창에서 엔터키를 한 번 눌러주시면 됩니다.

  아참! 예제에서 왜 getchar()를 썼는지 한 번 생각해보세요. 그리고,
  위에서 엔터 키가 아니라 스페이스바 같은 것을 누르면 왜 종료하지
  않는지도 생각해보세요.  아래에서 그 답을 드리겠습니다.

  2.6.  창 안에 또 창을 만들어 봅시다.

  바로 앞에서 아주 간단한 창 하나를 만들어 보았지요. 이번에는 그 창
  안에다 다른 작은 창들을 여러 개 만들어 보기로 하겠습니다.

  ? 예제 3

  #include <X11/Xlib.h>

  main()
  {
          Display *d ;
          Window root, p, w1, w2, w3 ;
          unsigned long Black, White ;

          d = XOpenDisplay (NULL);

          /* 주 프로그램 부분 시작 */
          root = DefaultRootWindow(d);
          Black = BlackPixel(d,0);
          White = WhitePixel(d,0);

          p  = XCreateSimpleWindow (d, root, 100, 100,
                                          600, 400, 2, Black, White );
          w1 = XCreateSimpleWindow (d, p, 50, 50,
                                          200, 150, 2, Black, White );
          w2 = XCreateSimpleWindow (d, p, 200, 100,
                                          200, 150, 2, Black, White );
          w3 = XCreateSimpleWindow (d, p, 350, 200,
                                          200, 150, 2, Black, White );
          XMapWindow(d, p);
          XMapWindow(d, w1);
          XMapWindow(d, w2);
          XMapWindow(d, w3);

          XFlush(d);
          sleep(3);

          XDestroySubwindows(d, p);
          XDestoryWindow(d, p);
          /* 주 프로그램 부분 끝 */

          XCloseDisplay (d);
  }

  이제는 예제 프로그램이 점점 복잡해지는 것 같고, 실제 프로그램
  같아지는군요.  하지만 기본 뼈대는 변함이 없습니다! 제가 /* */로 표시한
  부분만이 늘었을 뿐, 우리는 항상 1. 서버에 접속, 2. 서버에 요청, 3.
  서버와 접속 해제 라는 기본적인 등식을 머리 속에 두고 있어야 합니다.

  2.6.1.  모든 창은 자식창을 여러 개 가질 수 있다.

  모든 창의 부모창은 결국 루트창입니다. 그 창 안에서 모든 자식창들이
  생성되고 표시됩니다. 또 그 자식창들은 바로 똑같은 과정을 통해서 자기
  자신의 자식창들을 가질 수 있습니다. 마지막 단계의 자식창들도 또한
  마찬가지로... 그러한 원리를 이번 예에서 확인하실 수 있습니다. 산아제한
  같은 건 필요없겠죠? :)

  Window 형 변수 root, p, w1, w2, w3 이렇게 다섯개를 선언해두었습니다.
  root는 DefaultRootWindow()라는 매크로를 통해서 현재 루트창의 ID를
  기억하고 있습니다. 첫번째 XCreateSimpleWindow 함수를 통해서 루트창의
  자식창으로서 p 창을 만들었습니다. 두번째 같은 함수를 통해서 이번에는
  위에서 만들어 놓은 p 창을 부모창으로 하는 자식창 w1 을 만들었습니다.
  같은 과정을 통해서 p 창의 자식창들 w2, w3를 서버 측에 만들어
  놓았습니다.  귀찮으시더라도 창생성 함수들에 주어진 XY 좌표, 창 크기를
  보시고 창이 어떻게 나타날 것인지를 예측해보십시요.

  << 잠깐 생각중... >>

  컴파일 방법은 이전과 동일합니다.

  이번 예제에서는 Black, White라는 unsigned long 형 변수 두 개를
  선언해놓고는 전번 예제에서도 선보인 적이 있는 BlackPixel(),
  WhitePixel()이라는 매크로를 써서 각각 검정과 흰색을 나타내는 수치를
  저장하고 있습니다. 창 생성함수가 여러 번 쓰였으므로 그 때마다 색상
  지정부분에 매크로를 써주기 보다는 변수에 저장해두고 그 변수의 저장값을
  사용하고자 했습니다. 별 건 아니죠.

  자, 서버측에 만들어 놓은 창들을 나타내 봐야겠죠? :)

  XMapWindow 함수를 통해서 디스플레이 d 에 자식창 p 를 표현합니다.  그
  다음 3개의 문장도 마찬가지입니다. 디스플레이 d 에 w1, w2, w3를
  표현합니다.  w1, w2, w3는 p 창의 자식창들로 등록,생성되어 있기 때문에
  p 창 안에 표현됩니다.  그리고, 말씀은 안드렸지만 자식창들의 좌표계는
  바로 전 부모창의 좌표계를 기준으로 합니다. 부모창의 왼쪽 윗구석이
  자식창들의 원점(0,0)이 되는 것이지요.

  2.6.2.  자식창들을 한꺼번에 나타내자.

  사실 마지막 3개의 문장은 약간 소비적인 문장입니다. 창의 생성과
  표시라는 과정은 별개의 과정이므로, 일단 사용을 위해서 몇 개를
  생성시켜놓은 후, 그 때 그 때 원하는 자식창들만 표시할 때는 XMapWindow
  함수를 써야 하겠지만, 많은 경우 한꺼번에 자식창들을 몽땅 표시하고자 할
  때가 많고, 그 경우에는 참 번거롭죠?  그래서 여기서 새로운 함수 하나를
  소개시켜 드리고자 합니다.

        함수의 원형

        XMapSubwindows ( Display * d, Window w );

  디스플레이 d 에서 창 w 의 모든 자식창들을 일괄적으로 화면에
  표시합니다.  편리를 위해 제공되는 함수이지요.

  앞으로도 많은 함수들이 기능은 거의 같으면서 이렇게 사소하게 다른 여러
  가지들로 마련되어 있다는 것을 보실 수 있습니다.

  2.6.3.  쓸모없는 자원은 없애자.

        함수의 원형 : XDestroyWindow ( Display *d, Window p );
        함수의 원형 : XDestroySubwindows ( Display *d, Window p );

  창을 파괴해버리라고(Destory) 요청하는 함수입니다. 더 이상 표시할
  필요가 없어진 창들은 자원절약을 위해서라도(메모리를 차지하고
  있으니까요) 제 때 없애주는 것이 필요합니다. 위에서보면 두 종류의
  유사한 함수가 있는데, 첫번째 것은 지정된 하나의 창을 없애는 것이고,
  두번째는 그 창이 포함하고 있는 모든 자식창들을 찾아서 없애주는
  것입니다. 물론 자식창들 중에서 선별해서 없애려고 하신다면 당연히
  하나씩 없애는 함수인 첫번째 것을 쓰실 수 밖에 없습니다.

  [바로 전 강의 질문에 대한 답]

  키보드 입력 또한 버퍼방식이므로 스페이스바를 몇 번 쳐보았자 실제로
  프로그램 에는 전달이 되지 않다가 리턴키를 받으면 일시에 플러쉬됩니다.

  [오늘 강의를 마치면서...]

  정말 보잘 것 없는 프로그램 예라고 생각하실 지 모르겠지만, 제가
  보기에는 X 윈도우 프로그래밍에서 창을 표시할 줄 아신다면 거의 반은
  배우신 것이라고 확실히 말씀드릴 수 있습니다. 더욱 고차원적으로 버튼,
  대화상자, 메뉴 등의 그래픽 인터페이스도 결국엔 자그마한 창들의 결합일
  뿐입니다. 나중에 손쉽게 바로 우리 곁에 있는 Athena Widget 이라고 하는
  편리한 인터페이스 보따리를 사용해보게 될 텐데요, 아마도 여러분 스스로
  정말 색다른 인터페이스를 만들고 싶다는 생각이 들게 되실 겁니다. 엄청난
  인터페이스의 자유! 이것은 X 윈도우가 다른 어떤 GUI 시스템 보다도
  개방적임을 증명해보이게 될 겁니다. 기대해주세요.

  이 짤막한 예를, 이 예에서 보이는 순서를 꼭 이해하시고 머리 속에 항상
  기억해 주십시요. 아주 중요한 패턴 중에 하나입니다.

  2.7.  이제는 흑백이 아니라 칼라 창을 만들어봅시다.

  오늘은 어떻게 색상(Color)을 서버로부터 얻어내고 사용할 수 있는지에
  대해서 알아보기로 하겠습니다. 그 동안 계속 미뤄왔던 일이기도 하구요...

  지금까지 아무 설명없이 저는 BlackPixel(), WhitePixel()등의 매크로를
  예제에서 써왔습니다. 이름이 나타내듯 검정색/백색을 구하여 사용할 수
  있었지요. 이제는 이것 말고도 우리가 원하는 색들을 일반적으로 어떻게
  사용하는지에 대해서 알아봅니다.

  색상 또한 서버가 관리하고 있는 자원의 하나입니다. 따라서 창을 만들어
  달라고 서버에 요청하고, 표시하라고 요청하는 작업들과 마찬가지의 과정을
  거치게 됩니다.

  서버는 컬러맵(Color Map)이라고 하는 것을 가지고 있습니다. 색상을
  나타내는 지도 또는 도표를 뜻하지요. 이것이 어떤 의미를 가지는지 잠깐
  알아보겠습니다.

  2.7.1.  컬러맵이란?

  컴퓨터가 사용하고 있는 출력장치 중에 비트맵 디스플레이에 속하는
  CRT라는 것이 있습니다. 바로 여러분께서 눈 앞에 두고 계신 모니터이지요.
  이 모니터의 원리는 여러분 모두 아시다시피 빛의 3원색에 대응하는 3개의
  전자총이 모니터 표면에 발라져 있는 RGB 형광물질에 알맞게 비춰짐으로써
  우리가 원하는 모든 색을 얻는 것입니다. 우리가 노랑/보라/자주색 등을
  원할 때는 빛의 3원색을 알맞게 써서 전자총을 발사하지요. 그런데, 바로
  여기서 노랑/보라/자주색 등을 구현할 때 과연 노랑은 RGB 를 각각 어떤
  농도로 섞어야 하는가? 보라/자주색은 어떠한가를 저장하고 있는 표가
  필요한데요, 바로 그것이 컬러맵입니다.

  서버는 인간이 아니라 기계이기 때문에 우리가 yellow라고 말하면 어떤
  것인지 전혀 알 방법이 없습니다. 단지 자기가 가지고 있는 컬러맵에서
  yellow에 해당되는 것을 찾아서 모니터에게 적당한 양의 RGB 조합을 전달할
  뿐입니다. 어떻습니까?  컬러맵이라는 것이 정말 중요한 위치를 차지하고
  있지요? 이것이 엉망이 되면 어떻게 될까요? 컴퓨터가 정신못차리고 노랑을
  원할 때 분홍을 표시할 지도 모릅니다.

  서버는 기본적인 컬러맵을 가지고 있습니다.

  2.7.2.  원하는 색을 선택하기 위해 거치는 과정

  앞으로 색상을 이용하는 어떤 작업도 다음과 같은 과정을 거쳐야 합니다.

  1. 기본 컬러맵(Default ColorMap)의 ID를 알아낸다.

  2. 위 기본 컬러맵으로부터 원하는 색의 픽셀값(Pixel Value)를 알아낸다.

  ? 예제 4

        #include <X11/Xlib.h>

        main()
        {
              Display *d;
              Window Root, w;
              /* 색상값을 알아낼 때 쓸 변수들 */
              Colormap CMap;
              XColor color, color_exact;
              unsigned long Black, Blue;

              d = XOpenDisplay ( NULL );

              /* 원하는 색상 검정/파랑을 얻는 부분 */
              CMap = XDefaultColormap ( d, 0 );
              XAllocNamedColor ( d, CMap, "black", &color, &color_exact );
              Black = color.pixel;
              XAllocNamedColor ( d, CMap, "blue",  &color, &color_exact );
              Blue  = color.pixel;

              Root = DefaultRootWindow ( d );
              w = XCreateSimpleWindow ( d, Root, 100, 100, 600, 400,
                                              2, Black, Blue );

              XMapWindow ( d, w );
              XFlush ( d );
              sleep(10);

              XDestroyWindow ( d, w );
              XCloseDisplay ( d );
        }

  위의 예를 살펴보시면, 색상값(unsigned long형 값) 하나 얻는게 그렇게
  쉬운 것은 아니라는 사실을 발견하셨을 겁니다.

  맨 먼저 해야할 일은 컬러맵의 ID를 서버로부터 알아내는 것입니다.
  Colormap 형 변수 CMap을 하나 선언해두었습니다. 그리고 나서
  XDefaultColormap() 함수를 써서 현재의 서버, 현재의 기본 화면(0번
  화면)의 기본 컬러맵 ID를 반환받습니다.

        함수의 원형

        Colormap XDefaultColormap ( Display *d, int screen_no );

  이제 컬러맵을 알아냈으니, 우리가 원하는 색의 픽셀값을 알아내봅시다.
  이 때에는 XColor 형 변수 두 개가 필요합니다. 그리고 XAllocnamedColor
  함수를 써서 서버더러 함수에 주어진 컬러맵에서 우리가 원하는 색상이름을
  찾아서 그 색상 이름에 해당하는 정보를 XColor형 변수에 저장하도록
  요청합니다.
        함수의 원형

        Status XAllocNamedColor( Display *d,
                                  Colormap cmap,
                                  _XConst char* color_name,
                                  XColor *screen_def_return,
                                  XColor *exact_def_return );

  여기서 나오는 새로운 자료형에 대해서 지금 모두 아실 필요는 없습니다.
  아셔야 한다고 생각할 때 꼭 자세히 설명드리겠습니다.  함수의 이름
  자체가 상당히 길고 설명적이기 때문에 그 내용을 알아보기 좋습니다.
  물론 타이핑하기는 여간 힘든게 아니죠? 이 함수는 이름에서도 드러나듯이
  Named Color 즉 이름이 붙어 있는 색상에 대하여, 우리가 이 함수에 주소로
  전달해주는 XColor 형 변수 두 개에 알맞는 정보를
  할당(Allocation)해줍니다. 하나는 스크린 기본값으로서 하드웨어적으로
  가장 근사하게 실현시킬 수 있는 정보가 들어가고, 나머지 하나는 지정한
  색의 정확한 정보가 들어간다고 합니다. 우리는 전자만 사용하도록
  하겠습니다. 쓸만한 그래픽 프로그램을 만들기 위해서는 아주 정확하게
  알아야 하겠지만 지금 제가 하고자 하는 강의는 재빨리 X 프로그래밍
  전반에 대하여 훑어보는 수준이니 이해하세요.

  으잉? 그런데 이름이 있는 색상이라니... 하실 분들이 계실 것 같군요.
  전번 fvwm 강의 중 색상설정 강의 때 showrgb 라는 명령을 기억하십니까?
  쉘 상태에서 showrgb 해보십시요. 그러면 현재 서버가 이해할 수 있는
  이름붙은 색상들 목록이 RGB 값과 함께 주루룩 나타나게 될 겁니다. 바로
  그 목록에 있는 것들만을 말합니다. 우리가 알고 있는 red, yellow, blue,
  green 등이 바로 그것입니다.

  이변이 없는 한, 실패하지 않을테니 사실은 int 형 변수인 Status에는 0이
  아닌 True 값이 반환되어 옵니다. 만약에 문제가 발생했다면 False, 0
  입니다.

  이제는 정보를 지니고 있는 XColor 형 변수를 써서 결국에 우리가 알고
  싶었던 값을 알아내봅시다. XColor 형 변수는 Xlib.h 파일에 정의되어 있는
  구조체 변수로서 몇 개의 색상에 대한 정보를 지니고 있다고 보시면
  됩니다. 우리가 사용할것은 그 중에 unsigned long 형 멤버인 pixel
  멤버입니다. 그 값을 Black 이나 Blue 변수에 저장시켜 놓으면 되는
  것이지요.

  2.7.3.  요약

  색상은 서버가 관리하는 자원입니다. 이를 사용하기 위해서는
  XDefaultColormap 함수를 써서 기본적인 컬러맵 ID를 알아낸 후,
  XAllocNamedColor 함수를 통해서 특정 이름의 색상에 대한 XColor 정보를
  알아냅니다. 그리고 나서 XColor 구조체의 pixel 멤버값을 읽어내시면
  됩니다.

  그런데, 색상 하나의 픽셀값을 알기 위해서 항상 이렇게 많은 과정을
  거쳐야 하다니, 좀 너무한 것 같죠? 그렇다면, 여러분께서 색상이름을
  전달해주면, 그 색상에 관한 픽셀값을 반환해주는 사용자 정의 함수를
  작성하시면 될 겁니다.  꼭 한 번 만들어보세요. 책을 가지고 계신 분들은
  아실 지도 모르겠네요. :)

  2.8.  만들어 놓은 창 가지고 놀기

  오늘은 우리가 이미 만들어 놓은 창들에 대해서 이리저리 마음껏
  놀아보겠습니다.  창의 색깔을 바꾼다든지, 창의 크기를 바꾼다든지,
  없앴다가 다시 나타나게 한다든지 ... 뭐 이런 놀이를 하려고 합니다.

  2.8.1.  이미 만들어 놓은 창 색깔 바꾸기

  일단 창을 만드실 때 배경색과 테두리색을 결정해놓기는 했지만,
  사람이란게 마음이 달라질 때도 있는 것 아니겠어요? 자, 이미 표시되어
  있는 창을 그대로 놔둔 채 색깔만 한 번 바꾸어 봅시다. 여러분이 마음에
  드는 색을 골라보세요. 바로 전 시간에 말씀드린 색상 정보 알아내기는
  기억하고 계시죠?

  1. 테두리(Border)색 변화

          XSetWindowBorder ( Display *d, Window w, unsigned long border_pixel );

  2. 배경(Background)색 변화

        XSetWindowBackground ( Display *d, Window w, unsigned long background_pixel );

  설명이 필요한가요? 인수로 주어지는 Window 형 변수는 우리가 색을
  변화시키고자 하는 대상 창을 나타내는 변수를 쓰면 되고요, 픽셀값은
  여러분께서 원하시는 색의 픽셀값을 저번 강의에서처럼 구하셔서
  전달하시면 되고...

  자, 예제 3 번의 10초 간 지연 함수(sleep) 뒤에다 여러분께서 한번 이
  함수들을 이용해서 색상을 바꾸어보십시요. 잊지 마실 것은 XFlush를
  해주셔야 한다는 것입니다. XFlush를 해주시고 나서 또 다시 sleep 함수를
  쓰셔야 그 결과를 확인하실 수있겠지요?

  << 생각 중... >>

  여러분, 좀 어려운가요? 그러면 제가 해본 결과를 보여드리겠습니다.

  예제 3 에 추가 sleep(10); 문장 다음부터입니다.

        XAllocNamedColor( d, CMap, "green", &color, &ExactColor );
        XSetWindowBorder( d, w, color.pixel );

        XAllocNamedColor( d, CMap, "peachpuff", &color, &ExactColor );
        XSetWindowBackground( d, w, color.pixel );

        /* ??? */

        XFlush ( d );

        sleep(5);

  등등...

  설명을 드리자면, 전반부에서는 green 색의 픽셀값을 알아내서 테두리색을
  변화시켰고, 후반부에서는 peachpuff 색으로 배경색을 바꾸라고
  지시했습니다.  그리고 꼭 물내리는 것 잊지 마십시요.(flush)

  하지만 이렇게 한다고 해서 원하는 결과를 얻을 수 있는 것은 아닙니다.
  아직 부족한 것이 하나 있습니다. 그것은 다음과 같은 함수입니다.
  3. 창 배경을 지우는 함수, 아니 다시 칠하는 함수!!!

        XClearWindow ( Display *d, Window w );

  함수의 이름에서 보이듯, 창을 지우는, 정확히 말해서 창의 배경을 지우는
  함수입니다. 더욱 상세히 말씀드리자면, 현재의 배경을 지우고, 현재 창의
  정보 중 배경색에 해당하는 색으로 다시 칠해주는 역할을 합니다. 배경을
  바꾸시고자 할 때는 한 번 창을 지워주시던가 아니면 그와 똑같은 효과를
  갖는 일을 해주시면 됩니다.  그것이 무엇이냐구요? 창을 UnMap 했다가
  다시 Map하시면 됩니다.

  따라서 제가 위에서 /* ??? */ 라고 한 부분에 다음과 같이
  써넣어주십시요.

        XClearWindow ( d , w );

  창의 테두리와 배경색을 바꾸는 행위는 창 조작에 있어서 아주 기본적인
  행위임은 물론이거니와 아주 중요한 행위이기도 합니다. 여러분이 X 윈도우
  프로그램에서 매일 보시는 버튼들을 보세요. 포인터를 가져다 대면
  테두리나 그 자체 색이 변하는 것을 보실 수 있습니다. 결국에는 그 버튼도
  하나 또는 그 이상의 창으로 이루어져 있는 것에 불과합니다. 메뉴도
  그러하고요. X 윈도우는 그야말로 아주 쬐끄만 창부터 시작해서 터미널
  창과 같은 큰 창들을 포함하고 있습니다.

  2.8.2.  창에 대한 여러 정보를 알아냅시다.

  많은 분들께서 geometry라는 단어를 보신 적이 있을 겁니다. Geometry라
  함은 창에 대한 다음과 같은 정보를 말합니다.  창의 좌표(물론 창의 왼쪽
  윗구석 좌표를 말하겠죠?), 폭과 높이, 테두리 두께 등.

  사각형 창의 기본 요소들이라고 할 수 있는 것이죠. 창 전반에 대한 정보를
  가져다 주는 역할을 하는 함수 하나를 먼저 소개하겠습니다.

        함수의 원형 : <X11/Xlib.h>에 선언

        Status XGetGeometry ( Display *display,
                              Window drawable_object,
                              Window root_ID,
                              int *x,
                              int *y,
                              unsigned *width,
                              unsigned *height,
                              unsigned *border_width,
                              unsigned *depth
                              )

    함수에 대한 설명 :
        Geometry 정보를 가져오는(Get) 함수입니다. 첫번째 Display 형
        포인터는 현재 작업 중인 디스플레이 ID이고, 두번째 Window 형
        변수는 바로 우리가 geometry 정보를 알아내고자 하는 대상 창의
        ID입니다. 그 다음 변수들은 하나같이 포인터 변수들입니다.
        여러분도 C 프로그래밍을 해보셔서 아시겠지만, 어떤 함수든
        반환값은 하나 밖에 없습니다. 하지만 그 함수를 통해 여러 개의
        반환값을 가지고자 할 때 쓰는 기술이 바로 그 함수에게 주소 지정
        방식의 호출(Call by Reference), 즉 포인터로 변수를 전달해주는
        방식입니다. 그 함수에서 그 변수의 내용에 알맞는 값을 써주면
        되니까요. 그렇습니다. 세번째 변수들부터는 우리가 알고 싶은
        정보들을 가지고 올 변수들입니다. 세번째 Window형 변수는 두번째
        인수에서 주어진 ID를 갖는 창이 속한 ROOT 창의 ID를 반환합니다.
        저로서는 아직도 왜 세번째 인수를 주어야 하는지 그 필요성을
        이해할 수는 없지만, 혼동하셔서는 안되는 것은 어떤 창이 속하는
        자신의 부모창 ID가 반환되는 것이 아니라 절대적으로 ROOT 창의
        ID가 반환된다는 사실입니다. 네번째 인수는 x 좌표, 다섯번째
        인수는 y 좌표, 그 다음은 폭, 높이, 테두리 두께입니다.  그리고
        마지막은 Depth 즉 깊이를 말하는데, 이것은 현재 창에서 색깔을
        구현하는데 있어 몇 비트를 사용하고 있는가를 말해줍니다.  이
        숫자가 8이면 8 비트 칼라(8bpp) 즉 256 칼라가 되겠죠? 16 bpp는
        65536 칼라, 24 bpp는 16만 7천 칼라(16,777,216)를 말합니다.

        자, 웃기는 사실은 위에서 알아낼 수 있는 x, y 좌표는 그 창이 속한
        부모창의 좌표계를 기준으로 한다는 사실입니다. 만약 루트창이 A
        창을 포함하고, A 창이 다시 B 창을 포함한다고 합시다. B 창에
        대하여 XGetGeometry 하시면, 세번째 인수에는 ROOT창의 ID가, x, y
        변수에는 A 창의 왼쪽 윗구석을 (0,0)으로 하는 좌표계를 쓰는
        상대적인 B 창의 좌표계가 반환되어 옵니다.

    덧붙이는 말 한 마디 :
        마지막으로 덧붙이고자 하는 사실은 이렇습니다. 여러분께서 Xlib.h
        화일에서 XGetGeometry 함수를 찾아서 실제 내용을 보시면 두번째
        변수의 자료형은 Window 형이 아니라 실제로는 Drawable 즉
        무엇인가를 그릴 수 있는 대상으로 되어 있다는 것을 발견하실 수
        있습니다. 그것에 대한 설명은 다시 뒤로 미룹니다. 어찌 되었든
        Drawable 형 자료에는 Window 형이 포함되어 있습니다.

  2.8.3.  이제는 창의 geometry를 바꾸어 봅시다.

  창의 geometry를 바꾸는 함수들을 여기에 소개합니다.

        함수의 원형 : <X11/Xlib.h>에 선언

        XMoveWindow ( Display *display, Window w, int x, int y );
        XResizeWindow ( Display *display, Window w,
                              unsigned int width, unsigned int height );
        XSetWindowBorderWidth ( Display *display, Window w,
                                      unsigned int border_width );

  첫번째 함수는 창의 위치를 주어진 x, y 좌표값에 따라 이동시키는
  녀석입니다.  물론 좌표는 부모창 좌표계를 기준으로 합니다. 두번째
  함수는 Resize 즉 크기 변화시키는 함수로서 주어진 폭&높이 값에 따라
  크기를 변화시킵니다. 세번째는 무슨 일을 하는지 설명해드려야 하나요?
  네, 맞습니다. 테두리 폭을 변화시킵니다.

  오늘의 모든 내용을 담고 있는 예제를 적어드리고 오늘 강의를 마칠까
  합니다.  한 번 여러분들께서 분석해보세요.

  ? 예제 6

  /* 창의 색상 변화와 Geometry 변화 */

  #include <X11/Xlib.h>

  /* 함수 선언 */
  unsigned long UsrColorPixel( Display*, char* );

  int main()
  {
          Display *d;
          Window w0, w1, w2; /* One TopLevel Window & Two Child Windows */
          unsigned long black_pixel;
          int w_X1, w_Y1, w_X2, w_Y2;    /* 두 자식창의 위치 좌표 */
          unsigned int width, height, I; /* 자식창의 폭 & 높이 */

          /* 서버와 접속하기 그리고 변수들을 초기화 */
          d = XOpenDisplay ( NULL );

          black_pixel = BlackPixel ( d, 0 );
          width = 200; height = 100;
          w_X1 = 10; w_Y1 = 10; w_X2 = width - 10; w_Y2 = height - 10;

          /* 자, 시작해볼까요? */
          printf( "I will make windows.\n" );
          sleep( 2 );

          /* 창 하나 그리고 자식창 2개 생성 */
          w0 = XCreateSimpleWindow ( d, DefaultRootWindow( d ),
                                    100, 100, width*2, height*2, 1,
                                    black_pixel, WhitePixel( d, 0 ) );
          w1 = XCreateSimpleWindow ( d, w0, w_X1, w_Y1, width, height, 1,
                                    black_pixel, UsrColorPixel( d, "magenta" ) );
          w2 = XCreateSimpleWindow ( d, w0, w_X2, w_Y2, width, height, 3,
                                    black_pixel, UsrColorPixel( d, "blue" ) );

          /* 창과 자식창을 화면상에 표시 */
          XMapWindow( d, w0 );
          XMapSubwindows( d, w0 );
          XFlush( d );

          printf( "Unmap & Map.\n" );
          sleep( 3 );

          /* 창 하나를 UNMAP, MAP */
          XUnmapWindow( d, w1 ); XFlush( d );
          sleep( 1 );
          XMapWindow( d, w1 ); XFlush ( d );
          printf( "I will change the color of windows.\n" );
          sleep( 3 );

          /* 창 하나의 색상을 변경 */
          XSetWindowBorder( d, w2, UsrColorPixel( d, "red" ) );
          XSetWindowBackground( d, w2, UsrColorPixel( d, "green" ) );
          XClearWindow( d, w2 );
          XFlush( d ); sleep( 1 );
          XSetWindowBackground( d, w0, UsrColorPixel( d, "yellow" ) );
          XClearWindow( d, w0 );
          XFlush( d );
          printf( "I will move windows.\n" );
          sleep( 3 );

          /* 창 하나씩 이동 */
          for ( ; w_X1 < width - 10 ; )
          {
                  XMoveWindow( d, w1, w_X1++, w_Y1 );
                  XFlush( d );
          }
          for ( ;  w_X1 > 10 ; )
          {
                  XMoveWindow( d, w1, w_X1--, w_Y1 );
                  XFlush( d );
          }
          for ( ;  w_Y2 > 10 ; )
          {
                  XMoveWindow( d, w2, w_X2, w_Y2-- );
                  XFlush( d );
          }
          for ( ;  w_Y2 < height - 10 ; )
          {
                  XMoveWindow( d, w2, w_X2, w_Y2++ );
                  XFlush( d );
          }
          printf( "I will change the size of windows.\n" );
          sleep( 3 );

          /* 창의 크기를 확장/축소 */
          XResizeWindow ( d, w1, width + 100, height + 50 );
          XMoveResizeWindow ( d, w2, w_X2 + 50, w_Y1 + 20,
                                  width - 100, height - 50 );
          /* XMoveResize !!! */
          XFlush ( d );
          printf( "At last, I will change the width of borders.\n" );
          sleep( 3 );

          /* 창의 테두리 확장 */
          for ( I = 1 ; I < 20 ; I++ )
          {
                  XSetWindowBorderWidth ( d, w2, I );
                  XFlush( d );
          }
          printf( "Jobs done. Merci.\n" );
          sleep( 3 );

          /* 창 파괴 & 서버와의 접속 해제 */
          XUnmapWindow( d, w0 );
          XUnmapSubwindows( d, w0 );
          XDestroySubwindows( d, w0 );
          XDestroyWindow( d, w0 );

          XCloseDisplay( d );

          return 0; /* 성공적으로 프로그램을 수행 */
  }

  /*

    UsrColorPixel() : 주어진 이름의 색상에 대한 기본 컬러맵의 픽셀값 반환

  */
  unsigned long UsrColorPixel( display, name )
  Display *display;
  char *name;
  {
          Colormap cmap;
          XColor c0, c1;

          cmap = DefaultColormap( display, 0 );

          XAllocNamedColor( display, cmap, name, &c0, &c1 );
          /* 여기서 우리는 c1 을 아직 이용하지 않습니다. */

          return ( c0.pixel );
  }

  여기까지가 예제 6 입니다. 마지막에 사용자 정의함수 UsrColorPixel()은
  바로 전 시간에 제가 문제로 내드렸던 것에 대한 답 중 하나입니다.
  여러분들께서 각자 자신만의 정의함수를 만들어 놓으셨겠지요? 저랑 비교해
  보십시요.

  이 예제를 보시면서 한 줄 한 줄이 어떤 일을 하게 될 것인지 미리 머리
  속에서 그려보시고, 번거로우시더라도 꼭 예제를 자기 손으로
  타이핑하시면서( 상당한 노가다죠? :) ) 함수 하나하나를 익히시기
  바랍니다. 모든 함수들이 왜 그렇게 씌여져야 하는가, 왜 그렇게 밖에
  만들지 못했는가에 대해서도 생각해주시면 더욱 좋구요. 그 다음, 이 예제
  속에는 제가 설명드리지 않은 함수가 있습니다. 그 함수는 여러분께서
  힘들이지 않고 그 의미와 사용법을 아실 수 있을 거라고 생각합니다.

  여러분도 잘 아실 겁니다. 프로그래밍은 짜증날 정도로 많은 실수들의 연발
  속에서 그 실력이 늘어간다는 사실, 그리고 엉뚱한 실수 속에서 중요한
  문제들을 파악해 나갈 수 있다는 사실 말입니다. 다음과 같은 문장이
  예제에 있죠?

        XSetWindowBackground( d, w0, UsrColorPixel( d, "yellow" ) );

  요 문장을 /* */으로 주석문 처리하시거나 지우신 다음 컴파일하고
  실행시켜 보세요. 자, 어떤 일이 일어납니까?

  X 윈도우 프로그래밍 별 것 아닙니다. 창을 가지고 노는 장난이라고나
  할까요?

  3.  휴식강의 : 리소스(Resource)

  이번에는 Xlib 프로그래밍을 떠나서 잠시 기분전환을 할까 합니다. 계속
  똑같은 패턴의 프로그래밍 공부를 하다보면 지치죠? 그래서 재미있는 일 한
  가지를 오늘 해보려고 합니다.

  X윈도는 사용자에게 무한한 자유를 주는 시스템입니다. 윈도 3.1와 윈 95만
  쓰고 살아온 우리들에게는 처음에 상당히 겁먹게 하지만, 알아가면 알아
  갈수록 이해하기가 그렇게 어려운 것은 아니며, 한 번 알고 나면 이것만큼
  편리한 것이 없습니다. 컴퓨터를 사용한다는 것이 단순반복 작업을
  실수없이 빠르게 해낸다는 기본 취지도 있지만, 컬러 디스플레이의 개발
  등으로부터 시작된 컴퓨터의 멀티미디어화는 시각적 이미지에 대한 많은
  관심을 가지게 해왔습니다. 특히 컴퓨터 그래픽 분야는 현대에 없어서는
  안될 중요한 컴퓨터 활용 분야이지요.

  X 윈도는 하나로 정의된 인터페이스 제한사항 같은 것이 없습니다.
  여러분의 fvwm 윈도관리자를 다른 윈도관리자로 바꾸어주기만 하면 아주
  색다른 분위기를 느낄 수 있습니다. 다양성과 함께 분위기는 달리 하면서도
  모든 기능은 변함없는 일관성도 가지고 있는 것이 X 윈도입니다.

  시작하는 말이 좀 길었죠? 오늘 우리는 자원(Resource)이라고 하는 X
  윈도의 중요 한 개념에 대하여 알아보고, 몇 가지 재미있는 실습을 해볼까
  합니다. 오늘 실습을 통해 여러분은 X 프로그램을 여러분의 취향에 맞도록
  변화시키는 즐거움을 누리실 수 있습니다. 그럼, 시작해보도록 하죠.

  3.1.  리소스(Resource)란 무엇인가?

  앞서도 간략하게 설명드렸지만, 다시금 설명을 드리겠습니다. 리소스라는
  개념은 X 윈도 시스템에서 몇 가지 다른 의미로 사용되고 있습니다.

  첫번째로 X Server Resource라는 개념인데, 우리가 지금 하고 있는 Xlib
  프로그래밍에서도 나왔듯이, 서버가 관리하는 대상으로서의 창(window),
  폰트(font), 색상(color), 그래픽 컨텍스트(GC) 등이 바로 그것들입니다.
  전술한 바와 같이 클라이언트는 단지 리소스 ID 만을 가지고 이리저리
  서버에게 원하는 서비스를 요청할 뿐 입니다.

  두번째로 Xlib 보다 한 단계 상위의 Xt(X Toolkit) 프로그래밍을 하다보면
  나오는 내용으로서 사용자가 이리저리 셋팅을 할 수 있는 위젯(Widget)의
  속성이라고 말할 수

댓글목록

등록된 댓글이 없습니다.

Total 87건 1 페이지
리눅스 스터디 목록
번호 제목 글쓴이 조회 날짜
87 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 3310 11-08
86 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 3586 11-05
85 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 3534 11-05
84 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 4887 11-05
83 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 3351 11-05
82 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 3988 11-05
81 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 4974 11-05
80 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 3210 08-22
79 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 2430 06-16
열람중 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 2325 06-16
77 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 3710 05-31
76 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 1908 03-12
75 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 5478 08-13
74 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 3168 04-09
73 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 2126 04-04
72 no_profile 이즈쪽지보내기 자기소개 아이디로 검색 전체게시물 3597 04-01

검색

회원로그인

회원가입

사이트 정보

컴퓨터 정보,윈도우즈,리눅스,포토샵,3ds
맥스,프로그래밍 강좌팁

접속자집계

오늘
139
어제
724
최대
5,287
전체
637,138
Copyright © www.qdata.co.kr All rights reserved.