FoundationsofGTKDevelopment:Chapter 01
- 제 1 장 시작하기
시작하기
GTK+로 개발하기를 읽게 된 것을 환영한다! 본 저서를 통해 당신은 전문적인 그래픽 프로그래머가 되도록 도와줄 수 있는 GIMP Toolkit(GTK+)에 대한 전반적인 이해를 요한다. 다음으로 넘어가기 전에, 본 저서는 C 프로그래머를 겨냥하였음을 인식해야 하며, 그에 따라 GTK+의 사용으로 바로 넘어갈 것이다. 이미 알고 있는 내용은 별도로 다루지 않을 것이다.
본 저서를 대체적으로 이해하기 위해서는 각 예제를 따라해 보고 각 장의 끝에 실린 연습문제를 시도해야 한다. Linux에서 GTK+를 시작하기란 꽤 간단한데, 현재 배포판 대다수는 일반적으로 필수 라이브러리와 툴이 함께 제공되기 때문이다.
그럼에도 불구하고 GNU 컴파일러 컬렉션(GCC), GTK+ 2.0 라이브러리, 연관된 개발 패키지를 포함해 몇 가지 툴은 미리 설치해두어야 한다. 본 장의 뒷 부분에서는 이러한 애플리케이션을 어떻게 설치하는지 학습할 것이다. 컴파일러가 없더라도 이 책을 이용할 수는 있으며, 연습문제를 실행한다면 더 많은 것을 얻게 될 것이다. GTK+를 학습하는 최선의 방법은 직접 사용해 보는 것이다!
이 책에 선택된 컴파일러는 GCC로, http://gcc.gnu.org 에서 다운로드할 수 있다. 표준 C 또는 C++ 컴파일러라면 어떤 것이든 작동하겠지만 제공된 것과 다른 명령 집합을 이용해야 할 것이다. 그러한 컴파일러 명령은 본문에서 다루지 않을 것이다.
대부분 장의 마지막 부분에는 그 시점까지 학습한 내용을 설명하는 연습문제가 한 두 개 정도 실려 있을 것이다. 다음 장으로 넘어가기 전에는 자신의 지식을 재확인하도록 각 연습문제를 완료하도록 한다. 각 장은 앞의 장들에서 제시한 개념들을 바탕으로 구축하므로 좀 더 복잡한 예제들을 이해하려면 탄탄한 기반이 필요할 것이다.
이번 장에서 학습할 내용은 다음과 같다.
- GTK+와 X Window System의 역사는 두 가지 기술이 개발자들에게 미치는 엄청난 영향력과 관련해 맥락을 제공할 것이다.
- GTK+와 그것이 지원하는 라이브러리는 그래픽 애플리케이션 개발자에게 무엇을 제공하는가
- 이용 가능한 GTK+ 언어 바인딩은 무엇이며 어디서 다운로드할 수 있는가
- 자신의 컴퓨터에 GTK+와 그것이 의존하는 패키지를 어떻게 설치하는가
GTK+의 간략한 역사
GIMP 툴킷(GTK+)은 본래 GNU 이미지 조작 프로그램(GIMP)이라 불리는 래스터 그래픽 에디터를 대상으로 설계되었다. Peter Mattis, Spencer Kimball, Josh MacDonald는 버클리의 캘리포니아 대학에서 1997년 eXperimental Computing Facility를 작업하면서 GTK+를 만들었다.
Lesser General Public License(LGPL)를 따르는 GTK+는 가장 유명한 Linux 데스크톱 환경인 GNOME과 XFCE의 기본 그래픽 툴킷으로 채택되었다. 본래 GTK+는 Linux 운영체제에서 사용되었는데 이후 Microsoft Windows, BeOS, Solaris, Mac OS X 등 다른 유사 유닉스 운영체제에서도 지원하도록 확장되었다.
참고. LGPL은 GTK+를 다른 오픈 소스 그래픽 툴킷으로부터 구별하는 사항들 중 하나에 속한다. LGPL은 유명한 다른 오픈 소스 라이센스와 달리 특허 소프트웨어와 함께 사용하기 쉽다. 이러한 점이 바로 GTK+를 활용하는 GNOME 데스크톱 환경이 상업적 사회에서 많이 선택되는 이유이다.
GTK+는 최근 두 번째 안정된 배포판 주기인 GTK+2에 있다. 새로운 기능을 포함시킴과 동시 개발자들이 API 호환성을 중단하는 것이 옳다고 결정함에 따라 원본 branch인 GTK+1에 극적인 변화를 줄 필요가 있었다.
GTK+의 두 가지 branch는 호환되지 않기 때문에 동시에 설치가 가능하다. 애플리케이션을 빌드할 때 첫 번째 branch 대신 두 번째 branch를 사용하고 싶다면 컴파일러를 구별할 필요가 있는데, GCC를 이용하는 방법은 다음 장에서 학습할 것이다.
이 책에서는 모든 코드 예제에 대해 GTK+의 버전 2를 사용한다. GTK+ 2.10이 이미 배포되었지만 대부분의 예제는 두 번째 branch에선 어떤 버전과도 작동할 것이다. GTK+2는 이전 기종과 호환성을 유지하므로, GTK+2의 초기 배포판에서 작동하는 애플리케이션이라면 버전 2의 후반기 배포판과도 작동할 것이다.
X Window System
1984년 Jim Getty와 Bob Scheifler는 메사추세츠 공과대학에서 Argus 시스템의 디버깅을 위한 플랫폼 의존적 디스플레이 환경으로서 X Window System(X11)을 만들었다. 현재 The X.Org Foundation에서 개발 중인 X11은 Linux 및 다른 유사 유닉스 운영체제에서 표준 디스플레이 매니저에 해당한다. 한 마디로 말하자면, X11은 비트맵 디스플레이를 위한 윈도잉 기능을 제공한다.
X Windows System은 Linux에서는 사용되지만 Microfot Windows와 같은 다른 운영체제에서는 사용되지 않는다. 따라서 GTK+의 또 다른 이점으로, 기본이 되는 렌더링 시스템이 무엇이든 상관없이 그와 상호작용 해야 한다는 의무가 사라진다는 점을 들 수 있다. Linux, Windows, Mac OS X 에 대한 코드를 작성한다면 운영체제가 무엇이든 코드 모양은 동일할 것이다.
Linux로 돌아와, X11은 창을 가장 기본적이고 추상적인 형태로 관리한다. 화면에 창을 그리고 창의 움직임을 처리한다. X11은 마우스나 키보드와 같은 입력 장치를 그래픽 환경에서 제어한다.
X11의 기본 프로그래밍 인터페이스인 Xlib는 그래픽 사용자 인터페이스를 생성하는 데에 필요한 툴을 제공한다. Xlib를 이용한 개발도 가능하지만 대부분 프로그래머들은 GTK+ 와 같은 그래픽 툴킷을 사용하는 편을 선호하는데, 저수준 호출은 모두 라이브러리의 메서드에 의해 숨겨지고 관리되기 때문이다.
X11이 다른 디스플레이 매니저들에 비해 가진 독특한 주요 기능들 중 하나는, 클라이언트와 서버가 서로 관계 없이 처리된다고 가정한다는 점이다. 이로 인해 클라이언트는 서버와 상관없이 원격 위치에 존재할 수 있다.
X Windows System 내 클라이언트와 서버에 대한 정의는 전형적인 정의와 다르다. 클라이언트는 애플리케이션이 실행되는 머신이다. 서버는 사용자의 원격 머신이 아니라 로컬 디스플레이를 의미한다.
X Window System의 또 다른 장점은 사용자 인터페이스를 의무적으로 지시하지 않는다는 것이다. 따라서 윈도 관리자(window manager)의 그래픽 사용자 인터페이스(GUI)에 대한 맞춤설정이 매우 유연하다. 윈도 관리자가 그렇게 상이한 인터페이스와 테마를 제공할 수 있는 이유이기도 하다. 이는 Linux 사용자가 오늘날 선택의 자유를 즐기도록 해준다.
아이러니하게도 이러한 자유는 X11에 쏟아지는 비평 중 가장 큰 부분을 차지하기도 한다. 많은 사람들은 이것이 Linux 개발자 공동체 내에서 분열을 조장할 것이라고 두려워한다. 하지만 지금으로선 자신의 요구에 가장 알맞은 윈도 관리자를 선택할 수 있는 기능을 즐기면 되겠다.
GTK+ 라이브러리는 프로그래머로서 X Window System과 직접 상호작용하지 않아도 되도록 생성되었다. 창과 위젯을 생성하고, 위젯과 사용자 간 상호작용을 처리할 수는 있지만 Xlib 함수 호출과 화면으로의 모든 직접 렌더링은 자동으로 처리된다.
따라서 본 저서는 X Window System을 더 이상 다루지 않을 것이며, 대신 GTK+ 라이브러리에 초점을 둘 것이다. X11과 X.Org Foundation에 관한 추가 정보는 http://www.x.org 에서 찾을 수 있다.
GTK+와 지원 라이브러리
GTK+는 다수의 라이브러리에 의존하며, 각 라이브러리는 그래픽 애플리케이션 개발자에게 기능에 대한 구체적인 클래스를 제공한다.
GTK+는 C 프로그래밍 언어로 작성된 객체 지향 애플리케이션 프로그래밍 인터페이스(API)다. 이는 염두에 둔 클래스의 개념을 이용해, 자체에서 빌드되는 확장 가능 시스템을 생성하도록 구현된다. 사용된 객체 지향 프레임워크는 본래 GTK+ 라이브러리 자체의 일부로서 개발되었지만 이후 GTK+에서 분리되어 GObject라 불리는 다른 지원 라이브러리로서 GLib에 추가되었다. GObject는 객체 상속, 다형성, C에서 허용하는 한계인 데이터 은닉(data hiding)까지 포함해 C에서 모든 객체 지향 개발을 가능하게 한다.
GTK+ 라이브러리는 고유의 API를 통해 다른 라이브러리의 수많은 기능을 만들 수도 있다는 사실이 분명하지만 그보다는 그래픽 사용자 인터페이스를 빌드해야 하는 필요성을 제공하는 데에 중점을 둔다. GTK+ 자체에서 구현된 요소로는 버튼, 라벨, 텍스트 박스, 창과 같은 위젯이 있다. 이는 애플리케이션 레이아웃에 사용된 추상적 구성요소를 더 제공하고, 이벤트 캡처링(event capturing) 기능을 확장한다. 예를 들어, 그림 1-1은 GTK+를 사용하는 GIMP 애플리케이션의 스냅샷이다.
그 외에 동기식 및 비동기식 이벤트 프로세싱과 같이 GUI 개발에서 덜 시각적인 기본사항은 주로 다른 라이브러리에 의해 지원된다. 여전히 GTK+는 고유의 API를 통해 그 중 많은 기능으로 접근성을 제공한다.
Cairo라 불리는 2-D 벡터 그래픽 렌더링 라이브러리는 버전 2.8의 배포판부터 GTK+에 렌더링 기능을 제공해오고 있다. Cairo는 모든 플랫폼과 시스템에 걸쳐 일관되게 벡터 그래픽을 렌더링하도록 생성되었다. 또 윈도 관리자로 하여금 가능한 위치에서 하드웨어 가속의 이용을 허용한다.
Cairo 자체는 이 책에서 다루지 않을 것이지만 GTK+의 인쇄 API와 어떻게 연관되는지는 살펴볼 것인데 그 호출들은 당신이 상호작용하게 될 GTK+의 계층 아래에 존재하기 때문이다. 후에 GTK+ 소스 코드를 해킹하기로 결정한다면 살펴보고 싶을 법한 중요한 내용이다. Cairo에 대한 추가 정보는 http://www.cairographics.org 를 방문한다.
GLib
GLib는 다목적 유틸리티 라이브러리로, 많은 유용한 비그래픽 기능의 구현에 사용된다. GTK+에서 필요로 하지만 독자적으로 사용할 수도 있다. 이로 인해 일부 애플리케이션은 다른 GTK+ 라이브러리 없이 GLib가 제공하는 많은 기능 덕분에 GLib만 사용한다.
GLib를 이용 시 주요 장점은 코드를 재작성하지 않고 지원하는 운영체제에서 본인의 코드를 실행하도록 허용하는 크로스 플랫폼 인터페이스를 제공한다는 점이다! 또 다른 GLib의 장점으로는 개발자에게 제공하는 엄청난 수의 데이터 타입을 들 수 있다. GLib가 제공하는 데이터 타입 몇 가지를 열거할 것인데, 상세한 내용은 제 6장에서 다룰 것이다.
- GLib는 C 프로그래머들에게 보통 다른 언어에 기본 값으로 포함되어 있는 데이터 타입을 다수 제공하는데, 단일 연결 리스트와 이중 연결 리스트를 예로 들 수 있겠다. 그 외 기본 데이터 타입으로는 양단(double-ended) 큐, 자체적으로 균형을 이룬(self-balancing) 이진 트리, 불균형 n-ary 트리가 있다.
- 해시 테이블은 데이터에 대한 포인터의 리스트를 생성하도록 해준다. 이는 연결 리스트와는 차이가 있는데, 정수 참조에 의한 요소 접근 대신 두 번째 포인터를 키로서 명시하기 때문이다.
- GLib에서 문자열은 C++에서 문자열과 유사한데, 데이터가 추가되면 자동으로 증가하는 텍스트 버퍼이기 때문이다. 이들은 또 printf( ) 함수 계열로의 호출과 쉽게 통합된다.
- 메모리 슬라이스는 크기가 모두 동일한 메모리 청크를 효율적으로 생성하는 방법이다. 메모리 슬라이스를 이용해 균일한 크기의 요소로 된 배열을 생성할 수 있다. 이러한 구조는 GLib 2.10 배포판에서 메모리 청크를 대신해 도입되었다.
- 캐시는 쉬운 API에서 크고 복잡한 데이터 구조를 공유하도록 해주기 때문에 공간을 절약하는 데 도움이 된다. 이들은 스타일과 그래픽 컨텍스트를 위해 GTK+에 의해 사용되기도 하는데, 두 객체 모두 많은 자원을 소모하기 때문이다.
GLib는 다른 데이터 타입도 제공하는데, 그 중 다수는 제 6장에서 소개할 것이다. 뿐만 아니라 GLib는 데이터 타입 외의 기능들도 구현한다. 그리고 수많은 타입의 유틸리티 함수를 제공하기도 한다. 몇 가지만 예를 들자면 파일 조작, 국제화 지원, 문자열, 경고, 디버깅 플래그, 동적 모듈 로딩, 자동 문자열 완성 등등에 대한 유틸리티 함수를 찾을 수 있을 것이다.
제 6장에서는 idle 함수, time-out 함수, 타이머에 관해 학습할 것인데, 이들은 모두 개발자들에게 흥미롭고 다양한 가능성을 열어준다. idle 함수는 프로세서가 애플리케이션을 위해 어떤 일도 하고 있지 않을 때 함수를 호출하도록 해준다. timeout 함수들은 당신이 제공한 시간 간격으로 함수를 호출할 때 사용된다. 타이머는 그것이 초기화된 후 시간이 얼마나 경과했는지 추적한다. 이러한 함수들은 애플리케이션이 각각 idle 상태일 때 업데이트를 검사하거나, 자동 저장 기능을 구현하거나, 경과 시간을 추적하는 데에 사용되기도 한다.
GLib는 그 크로스 플랫폼 특성 덕분에 프로세스 띄우기, 파일 조작, 메모리 할당, 스레드를 대상으로 사용하기 쉽다. 이들 중 어떤 것이든 다수의 플랫폼을 대상으로 개발을 시도한다면 악몽이 될지도 모른다. GLib는 이러한 귀찮은 일을 알아서 처리하므로 독자는 크로스 플랫폼의 호환성 문제를 염려하지 않아도 된다.
GObject
GLib 객체 시스템(GObject)은 본래 GtkObject 클래스의 형태로 GTK+1의 일부였다. GTK+ 2.0이 배포되면서 고유의 라이브러리로 이동되었고 GLib와 함께 배포되었다.
GObject는 그 복잡성 때문에 비평을 받곤 했는데, 그 API들이 극단적으로 길어지는 것처럼 보였기 때문이다. 하지만 본래는 다른 프로그래밍 언어로부터 C 객체로 쉽게 접근하도록 생성된 것이다. 다른 프로그래밍 언어로부터 C 객체로 쉽게 접근하는 기능이 C에서 구현된다 하더라도 다른 프로그래밍 언어에 이용 가능한 바인딩의 범위가 거대해지는 결과를 야기한다.
각 프로그래밍 언어는 데이터 타입에 대해 서로 다른 접근법을 제공하기 때문에 까다로운 일인데, 그러한 차이는 표면에 드러나거나 각 언어의 내부에 나타난다. 가령, C에서는 char, long, integer를 포함한 데이터 타입을 갖는다. Perl을 비롯한 다른 언어들에서는 이와 유사한 데이터 타입을 찾을 수 없는데, 각 객체의 타입은 그것이 어떻게 사용되느냐에 따라 결정되기 때문이다. GObject는 이러한 한계점은 해결했지만 새로운 객체를 파생하는 과정이 대단히 복잡하다는 단점이 있다.
GObject는 C에서 완전한 기능을 갖춘 객체 지향 인터페이스를 구현하기도 하는데, 이는 이번 절과 본 저서의 나머지 부분에 걸쳐 세부적으로 다룰 것이다. 이 시스템은 GTK+ 위젯 계층구조뿐만 아니라 GTK+가 지원하는 라이브러리에 구현된 다수의 객체에도 기반이 된다. GObject의 객체 지향 인터페이스는 GType이라고 불리는, 포괄적이고 동적인 타입의 시스템에 의해 일부 구현된다. GType은 프로그래머들이 단일 상속된(singly-inherited) 클래스 구조를 통해 서로 다른 다수의 동적 데이터 타입을 구현하도록 허용한다. 단일 상속된 클래스는 객체 계층구조로서, 각 자식(child) 클래스는 하나의 부모 클래스로부터 직접적으로 파생되어야만 한다. 이는 GTK+ 위젯을 소개한 후 제 2장에서 상세히 논할 것이다.
확장 가능한 데이터 타입의 생성 기능 외에도 GObject는 프로그래머들에게 많은 클래스가 아닌 (또는 기본적인) 데이터 타입을 제공한다. 클래스가 아닌 데이터 타입은 루트 클래스로서, 다른 클래스들은 이로부터 파생된다. 루트 클래스 자체는 어떤 클래스로부터도 파생되지 않음을 명심하는 것이 중요하다.
표 1-1 은 가장 중요한 클래스가 아닌 데이터 타입의 목록을 제공한다. GType 매크로, C 변수 디스크립터, 설명이 각각 설명되어 있으며, 해당하는 경우 범위도 표시한다.
GType | C Type | 설명 |
G_TYPE-NONE | void와 동일한 빈 타입. | |
G_TYPE_CHAR | gchar | 표준 C char 타입과 동일. |
G_TYPE_INT | gint | 표준 C int 타입과 동일. 값은 G_MININT와 G_MAXINT 사이여야 함. |
G_TYPE_LONG | glong | 표준 C long 타입과 동일. 값은 G_MINILONG과 G_MAXLONG 사이여야 함. |
G_TYPE_BOOLEAN | gboolean | 표준 Boolean 타입으로, TRUE 또는 FALSE를 보유. |
G_TYPE_ENUM | GEnumClass | C enum 타입과 동일한 표준 열거. |
G_TYPE_FLAGS | GFlagsClass | Boolean 플래그를 보유하는 비트 필드. |
G_TYPE_FLOAT | gfloat | 표준 C float 타입과 동일. 값은 음의 G_MAXFLOAT과 G_MAXFLOAT 사이여야 함. |
G_TYPE_DOUBLE | gdouble | 표준 C double 타입과 동일. 값은 음의 G_MAXDOUBLE과 G_MAXDOUBLE 사이여야 함. |
G_TYPE_STRING | gchar* | NULL로 끝나는 C 문자열과 동일. |
G_TYPE_POINTER | gpointer | 타입이 정해지지 않은 포인터 타입으로, void*와 유사. |
표 1-1. 클래스가 아닌 표준 GObject 데이터 타입 |
GObject는 두 가지 중요한 또 다른 데이터 타입인 GValue와 GObject도 GTK+에 포함하여 제공한다. GValue는 일반적 컨테이너로서, 시스템이 이미 인식하는 구조라면 무엇이든 보유할 수 있다. 이는 함수가 임의 타입의 데이터 조각을 리턴하도록 허용한다. GValue가 없이는 GTK+의 객체 지향 특성이 불가능할 수 있다.
G_TYPE_GOBJECT 또는 GObject는 GTK+의 위젯 클래스 상속 구조가 기반으로 하는 기본적인 타입이다. 이는 위젯들로 하여금 그들 부모의 프로퍼티를 상속하도록 허용하는데, 스타일 프로퍼티와 시그널도 이에 포함된다.
GObject는 단일 상속 시스템으로서, 각 자식 클래스는 하나의 부모 클래스만 가질 수 있다. 파생된 자식은 부모의 모든 특성을 상속 받는데, 어떤 점에서든 자식은 또 부모에 "해당하기" 때문이다. 이러한 시스템을 이용해 커스텀 GTK+ 위젯을 파생하는 방법은 제 11장에서 학습할 것이다.
GObject는 또한 위젯에게 시그널 시스템, 객체 프로퍼티 시스템, 메모리 관리를 제공하기도 한다. 이 세 가지 개념은 다음 장에서 살펴볼 것이다.
GDK
GIMP 드로잉 키트(GDK)는 본래 X Windows System용으로 설계된 컴퓨터 그래픽 라이브러리로서, 저수준 드로잉과 윈도우 함수를 다룬다. GDK 는 Xlib와 GTK+의 매개체 역할을 한다.
이는 모든 GTK+ 애플리케이션에서 드로잉, 래스터 그래픽, 커서, 글꼴을 렌더링한다. 또 모든 GTK+ 프로그램에서 구현되기 때문에 GDK는 드래그 앤 드롭 지원과 윈도우 이벤트도 제공한다.
GDK는 GTK+ 위젯에게 화면에 그림을 그릴 수 있는 기능을 제공한다. 이를 위해선 모든 위젯이 연관된 GdkWindow 객체를 가져야 하지만 몇 가지 예외에 속하는 위젯이 있는데 이는 후에 다른 장에서 논할 것이다. GdkWindow는 기본적으로 위젯이 그려지는 화면에 위치한 직사각형 모양의 영역이다. GdkWindow 객체는 위젯이 X Windows System 이벤트를 감지하도록 허용하기도 하는데, 이와 관련된 내용도 다음 장에서 다룰 것이다.
GDK는 Windows와 Mac OS X로 이식되었다. GTK+ 2.8 배포판 이후로는 Cairo를 지원하기도 한다.
GdkPixbuf
GdkPixbuf는 작은 라이브러리로, 클라이언트 측 이미지 조작 함수를 제공한다. 이것은 GNOME 이미징 모델(Imlib)을 대신해 생성되었다. 이미지는 파일로부터 로딩될 수도 있고, 이미지 데이터가 라이브러리 함수로 직접 입력될 수도 있다. 후에 이미지를 트리 뷰로 추가하거나 새로운 GtkImage 위젯을 생성할 때도 해당 라이브러리를 사용할 것이다.
GdkPixbuf 이미지의 한 가지 장점으로, 이미지를 참조 계수(reference-counted)할 수 있다는 점을 들 수 있다. 이는 GdkPixbuf 이미지를 메모리에 한 번만 보관하면서 여러 위치에 표시할 수 있음을 의미한다. 모든 참조 계수가 감소할 경우에만 메모리 해제될 것이다.
GdkPixbuf 라이브러리는 GNOME과 함께 배포되는 2-D 드로잉 라이브러리인 Libart의 장점을 취해 이미지로의 변형(transformation)을 지원한다. 이 때문에 프로그래머는 이미지를 원하는 대로 기울이고(shear), 크기를 조정하며(scale), 회전시킬 수 있는 것이다. 이후 이미지는 GdkRGB 라이브러리와 드로잉 가능한 영역을 이용해 렌더링이 가능하다. GdkPixbuf는 이렇게 다양한 범위의 특수 툴을 이용함으로써 상당히 높은 클래스의 이미지 렌더링을 제공할 수 있는 것이다.
GdkPixbuf는 소규모 라이브러리임에도 불구하고 이미지의 조작과 표시에 다양한 범위의 함수를 제공한다. 라이브러리는 본문에서 가장 기초적으로만 사용될 것이다. GdkPixbuf 의 고급 주제에 관한 정보는 그에 대한 API 문서를 참조하도록 한다.
Pango
GDK는 창과 이미지 렌더링을 처리하는 반면 Pango는 GTK+ 버전에 따라 Cairo 또는 Xft와 함께 텍스트 및 글꼴 출력을 제어한다. 또 부수적 라이브러리를 사용하지 않고 in-memory 버퍼로 직접 렌더링이 가능하다.
Pango는 "모두"를 뜻하는 그리스어 pan과, "언어"를 뜻하는 일본어 go에서 기원한 것이다. 이러한 용어가 선택된 이유는 완전히 국제화된 글꼴 렌더링 시스템을 생성함으로써 모든 언어를 지원하는 것이 Pango의 디자인 목표 중 하나에 해당하기 때문이다.
Linux에서 Pango는 클라이언트 측 글꼴에 대해 FreeType과 fontconfig 라이브러리를 사용한다. Pango를 다른 것과 비교할 때 두드러지는 점은 광범위한 언어 집합을 지원한다는 것이다. 사실상 세계 거의 모든 언어를 지원하므로 애플리케이션에서 국제화된 텍스트를 렌더링하는 것은 문제가 되지 않는다.
Pango 내의 모든 텍스트는 UTF-8 인코딩으로 내부적으로 표현된다. UTF-8은 유닉스 플랫폼에서 일반적으로 볼 수 있는 8 비트 소프트웨어와 호환된다. UTF-8에서 오프셋은 비트가 아니라 문자를 기반으로 계산되는데, 각 문자가 1 바이트 이상 차지할 수도 있기 때문이다. 이는 GtkTextView를 사용하는 방식을 학습하게 될 제 7장에서 중요해지는데, 문자 오프셋마다 비교해야 하나 항상 1 바이트인 것은 아니기 때문이다.
Pango는 광범위한 텍스트 속성을 지원한다. 이러한 속성으로는 언어, 폰트 패밀리, 스타일, 굵기(weight), 폭(stretch), 크기, 전면색, 배경색, 밑줄, 취소선, rise, 모양(shape), 크기조정(scale)을 들 수 있지만 이에 국한되진 않는다. 이러한 속성들 중 다수는 자체적으로 다중 옵션을 지원한다.
편의상 Pango Text Markup Language는 HTML과 유사한 형태로 텍스트 속성을 나타내는 간단한 태그 집합을 제공한다. 이러한 markup 언어를 이용하면 위젯 내 임의의 텍스트 부분에 대해 글꼴 스타일을 쉽게 변경할 수 있다. 이는 특히 Glade 사용자 인터페이스 빌더(Glade User Interface Builder)로 사용자 인터페이스를 생성 시 유용한데, 위젯의 텍스트 내용 필드에 직접 태그를 입력할 수 있기 때문이다.
후에 여러 장에 걸쳐 위젯의 글꼴을 사용자의 기본값 외의 글꼴로 변경하는 다수의 예제에서는 Pango를 사용할 것이다. PangoFontDescription 객체 또는 Pango Text Markup Language를 이용하면 되겠다.
ATK
애플리케이션을 디자인할 경우에는 자신이 경험할 수 있는 장애를 고려하는 것이 중요하다. 그에 따라 접근성 툴킷(ATK)은 GTK+ 위젯에게 접근성 문제를 처리하기 위한 내장된 방식을 제공한다.
그 외에 ATK가 지원하는 몇 가지 예로는 시각적으로 장애가 있는 이들을 위한 스크린 리더와 고대비 시각 테마, 그리고 운동 제어가 안 되는 사람들을 위해 고정키(sticky key)와 같은 키보드 행위 수정자(behavior modifiers)가 있다.
이는 생산용 애플리케이션의 디자인에 있어 중요한 부분이긴 하나 이번 책에서는 ATK를 다루지 않을 것이다. 우리는 GTK+ 위젯을 생성하는 방법과 ATK를 사용하기 전에 자신만의 커스텀 위젯을 생성하는 방법을 학습할 필요가 있다. 따라서 필자는 GTK+와 다른 필수 요소에 중점을 두고자 한다.
접근성을 항상 유념하고, 자신의 애플리케이션에서 ATK를 처리할 준비가 되었을 때 라이브러리를 다시 찾는 것이 중요하겠다.
언어 바인딩
원본 형태로 된 GTK+는 C 프로그래밍 언어와 함께 사용이 가능하지만 바인딩은 다수의 다른 목적을 위해 생성되었다. 가장 유명한 언어 바인딩을 열거하자면 아래와 같지만 전체 목록은 http://www.gtk.org/bindings.html 에서 찾을 수 있다.
- Gtkmm은 공식 C++ 바인딩 집합이다. 기존 버전과 호환이 가능하기 때문에 C++와 함께 GTK+를 이용 가능하지만 Gtkmm은 일련의 클래스에서 모든 GTK+ 기능을 제공하며, 그 스타일은 모든 C++ 프로그래머에게 익숙할 것이다. Gtkmm, GLibmm, Libglademm, 기타 의존 패키지에 대한 소스는 http://www.gtkmm.org 에서 이용할 수 있다.
- http://www.pygtk.org 에서 이용 가능한 PyGTK는 GTK+ 라이브러리에 대해 Python 바인딩을 제공한다. PyGTK를 이용 시 장점은 메모리 관리와 타입 캐스팅을 처리한다는 점이다. 이는 다른 언어 바인딩을 사용하는 프로그래머에게 불편할 수 있는 문제들을 완화시켜준다.
- http://gtk2-perl.sf.net 에서 이용 가능한 Gtk2-perl은 객체 지향 Perl 툴킷에 모든 GTK+ 라이브러리를 제공한다. 각 라이브러리는 Glib, Gtk2, Gtk2::GladeXML 이라 불리는 모듈로 나뉜다. 스크립팅 언어에 대한 대부분의 GTK+ 바인딩과 마찬가지로 메모리 관리는 언어의 기능들에 의해 처리된다.
- PHP-GTK는 GTK+에 대한 PHP 언어 바인딩의 처리를 허용한다. PHP 바인딩은 클라이언트 측 크로스 플랫폼 GUI 애플리케이션을 생성하도록 해준다. PHP-GTK는 http://gtk.php.net 에서 이용할 수 있다. 이 주제는 Apress에서 출판한 Scott Mattocks의 저서 Pro PHP-GTK 에서도 다룬다 (Berkeley, 2006).
- Gtkmm 과 많이 비슷한 Java-Gnome은 GTK+ 라이브러리를 위해 진정한 객체 지향의 플랫폼을 제공한다. http://java-gnome.sf.net 에서 이용 가능하며, Java에서 GTK+ 애플리케이션을 개발 시 필요한 모든 라이브러리를 제공한다.
- Gtk#은 광범위한 운영체제에서 C# 애플리케이션에 대한 GTK+ 바인딩을 제공한다. 이는 http://www.mono-project.com 에서 Mono Project에 의해 제공된다.
GTK+ 설치하기
프로그래밍을 시작하기 전에 우선 자신의 시스템에 GTK+와 그것이 의존하는 패키지를 설치해야 한다. 이번 절은 Linux와 유사 유닉스 운영체제에서 GTK+를 설치하는 것을 다룬다.
Ubuntu, Debian, Fedora Core 등 다수를 포함해 패키지 매니저가 있는 Linux 배포판을 사용 중이라면 제공되는 사전 컴파일된 바이너리를 설치해야 한다. GTK+2 라이브러리, pkg-config, 그리고 그들이 의존하는 패키지들이 필요할 것이다.
GTK+의 개발 패키지, 그리고 각 패키지가 의존하는 패키지도 필요하다. Debian과 Debian을 기반으로 한 배포판에서 이러한 패키지들은 -dev에서 끝이 난다. RedHat Package Manager(RPM)를 사용하는 Fedora Core와 다른 배포판에서는 -devel에서 끝날 것이다. GTK+의 개발 패키지를 설치할 경우 필요로 하는 의존 패키지들은 가장 최신 패키지 매니저가 모두 자동으로 처리할 것이다. 배포된 패키지의 설치에 관한 상세한 정보는 자신의 Linux 배포판 문서를 참조해야 한다.
소스 아카이브에서 GTK+와 그것이 의존하는 패키지들을 설치하려면 지금부터 잘 살펴보도록 한다. GTK+는 컴파일에 표준 GNU 툴을 사용하는데, autoconfig는 설정을 비롯해 이식성 문제의 처리에 사용되고, automake는 makefiles 의 빌드, libtool은 공유 라이브러리의 빌드, make는 바이너리의 컴파일과 설치 시 사용할 수 있다.
가장 최신 GTK+ 소스는 http://www.gtk.org/download 에서 찾을 수 있다. ATK, GLib, GTK+, Pango의 최신 버전도 다운로드 해야 한다. 의존하는 패키지 디렉터리의 Cairo, JPEG, libpng, pkg-config, tiff도 필요할 것이다.
Linux의 오래된 버전을 사용할 것이라면 libiconv를 설치해야 한다. 대부분의 시스템은 이미 해당 패키지를 갖고 있으므로 이것이 없이 시작하여 향후 문제에 직면하면 라이브러리를 설치하는 편이 안전하다. 대부분 현대 Linux 배포판에서 표준으로 제공되긴 하지만 libintl, fontconfig, FreeType 패키지도 설치해야 할 것이다.
이러한 패키지들은 정확히 다음과 같은 순서대로 설치"해야만" 작동함을 주목해야 한다. GTK+ FTP 사이트에서 의존 패키지 디렉터리로부터 모든 패키지를 설치했다면 GLib, Pango, ATK, GTK+ 순으로 설치해야 한다.
아래 프로시저는 한 번에 하나의 소스 패키지에서 사용되어야 한다. 다음으로 넘어가기 전에 각 라이브러리가 성공적으로 설치되어야 하며, 그렇지 않으면 프로시저가 작동하지 않을 것이다.
GTK+를 설치할 준비가 되면 이제 시작해보자. GTK+ FTP 사이트에서 패키지를 다운로드 했다면 자신이 다운로드한 아카이브 유형에 따라 파일을 압축해제(extract)하는 다음 명령 중 하나를 사용할 수 있다.
tar -xvzf package-name.tar.gz
tar -xvjf package-name.tar.bz2
압축해제된 아카이브의 디렉터리로 이동시키면 configure라 불리는 셸 스크립트를 확인할 것이다. 해당 스크립트는 소스 배포판 내 각 디렉터리를 통해 재귀적으로 파싱할 것이며, 자신의 운영체제에 맞춤설정된 템플릿 makefiles를 생성할 것이다. 각 템플릿 파일은 Makefile.in으로 명명될 것이다. 아래는 당신이 사용할 수 있는 설정 명령의 예제이다.
./configure --prefix=/usr
설정 스크립트는 옵션 개수로 전달할 수 있다. --prefix=/usr을 이용하면 앞의 예제는 make에게 /usr이 있는 패키지를 루트 디렉터리로서 설치할 것을 알린다. GTK+ 설정 스크립트로 전달할 수 있는 옵션에는 그 외에도 여러 가지가 있다.
표 1-2는 구체적으로 GTK+ 설정에 전달 가능한 매개변수의 목록을 짧게 보여준다. 어떤 패키지든 매개변수의 전체 목록을 확인하려면 ./configure --help를 이용할 수 있다.
옵션 | 설명 | |
--enable-debug | no로 설정 시 디버깅과 asserts가 비활성화된다. yes로 설정 시 런타임 디버깅이 활성화된다. 기본값은 minimum으로, cast 검사만 비활성화한다. | |
--enable-shm | 이용 가능할 경우 공유 메모리를 켜고, --disable-shm을 이용해 비활성화한다. | |
--enable-xkb | X Window System 키보드 확장을 지원하고, --disable-xkb를 이용해 비활성화한다. | |
--disable-rebuilds | 모든 소스 자동생성 규칙을 비활성화하고, --enable-rebuilts를 이용해 활성화한다. | |
--enable-visibility | ELF 시각성 속성을 이용하고, --disable-visibility를 이용해 비활성화한다. | |
--with-xinput | yes를 이용해 자신의 애플리케이션에 XInput 확장을 지원하고, no를 이용해 비활성화한다. | |
--with-gdktarget= | non-default GDK 대상을 선택한다. 해당 매개변수에 대한 옵션으로 x11, linux-fb, win32, quartz, directfb가 있다. | |
--disable-shadowfb | linux-fb에서 shadowfb에 대한 지원을 비활성화하거나 --enable-shadowfb를 이용해 활성화한다. | |
--enable-fbmanager | GtkFB를 통해 프레임 버퍼 매니저 지원을 활성화한다. | |
--disable-modules | 이는 GdkPixbuf에 대한 모든 이미지 파일 포맷 로더들이 GTK+ 라이브러리로 정적으로 빌드되어야 함을 나타낸다. --enable-modules를 이용해 이들을 공유 라이브러리로서 빌드할 수 있다. | |
--with-included-loaders | 이는 PNG나 JPEG와 같이 포함해야 할 이미지 로더를 명시하도록 해준다. | |
표 1-2. GTK+ 설정 옵션 |
패키지를 설정하고 나면 다음과 같은 명령 집합을 이용해 패키지를 빌드 및 설치할 수 있는데, make install과 ldconfig는 루트 사용자로서 실행될 필요가 있음을 인지하는 것이 중요하다.
make
make install
ldconfig
ldconfig 명령은 모든 시스템에서 필수적인 것은 아니지만 안전한 측에서 실행시키도록 해야 한다. 그래야만 다음 패키지를 컴파일하기 전에 본인이 설치한 라이브러리를 시스템이 확실히 인식할 수 있을 것이다.
연습 1-1. 설치 검증하기
소스 패키지로부터 GTK+ 라이브러리를 설치할 경우 성공적인 설치를 검증하는 간단한 방법이 제공된다. 이를 위해서는 /usr/bin에 설치된 gtk-demo 애플리케이션을 실행시켜야 한다. terminal에서 아래 명령을 실행하거나 실행 파일을 더블 클릭한다.
/usr/bin/gtk-demo
설치가 성공하면 "GTK+ Code Demos"라는 제목으로 된 창이 표시될 것이다. 그 창에서는 열거된 각 위젯에 대한 정보와 소스 코드를 확인할 수 있다. 이는 앞으로 학습하게 될 많은 위젯을 연구할 수 있는 기회를 제공한다.
애플리케이션을 시작 시 문제에 직면할 경우 terminal에 표시된 오류에 집중한다. 이는 어떤 라이브러리가 문제를 야기하는지를 알려줄 것이다.
GTK+ 라이브러리와 그것이 의존하는 패키지를 모두 설치했다면 다음 장으로 넘어갈 준비가 되었으며, 이제 모든 GTK+ 애플리케이션이 필요로 하는 가장 기본적인 요소를 보여주는 간단한 예부터 시작하겠다.
요약
이번 장에서는 GTK+ 라이브러리와 X Windows System의 역사와 그들의 사용 용도를 학습하였다.
또 그래픽 위젯 라이브러리뿐만 아니라 그 지원 라이브러리로서의 GTK+도 소개하였다. 이러한 라이브러리들은 다음과 같다.
- GLib는 다용도의 유틸리티 라이브러리로서, 데이터 타입, 파일 관리, 파이프, 스레드 등을 포함해 수많은 유용한 비그래픽 기능들을 구현하는 데 사용된다.
- GLib 객체 시스템(GObject)은 객체 지향 GType 시스템을 구현하며, 시그널 및 프로퍼티 시스템을 제공하기도 한다.
- GIMP 드로잉 키트(GDK)는 본래 X Window System용으로 설계된 컴퓨터 그래픽 라이브러리로서, 저수준 드로잉과 윈도우 함수를 다룬다.
- GdkPixbuf는 작은 라이브러리로, 클라이언트 측 이미지 조작 함수를 제공한다. 이는 Imlib를 대신해 생성되었다.
- Pango는 글꼴 렌더링에 사용된다. 이는 UTF-8 인코딩을 사용하므로 모든 국제화 텍스트 형태를 지원할 수 있다.
- 접근성 툴킷(ATK)은 모든 GTK+ 위젯에게 접근성을 처리하는 내장된 방식을 제공한다.
본 장의 마지막 두 절은 다른 프로그래밍 언어에서 GTK+를 구현하는 데 이용 가능한 모든 언어 바인딩과, GTK+ 라이브러리를 설치하는 방법을 보였다. 언어 바인딩은 본래부터 GObject가 설계된 방식 덕분에 가능하다.
제 2장에서는 창, 라벨, 버튼 위젯뿐만 아니라 위젯 계층구조 시스템도 함께 소개하고, 기본 GTK+ 애플리케이션에서 이러한 위젯을 사용하는 방법을 학습할 것이다.