CnUnix

[알림판목록 I] [알림판목록 II] [글목록][이 전][다 음]
[ CnUnix ] in KIDS
글 쓴 이(By): Asteau (Paranoia)
날 짜 (Date): 1996년07월19일(금) 13시52분16초 KDT
제 목(Title): [A] X Program에서..


가장 간단한 방법은 변수선언부와 XCretaeWindowAttributes 다음에

다음의 루틴을 추가 하는 것입니다.

...
XSetWindowAttributes a;
...

a.override_redirect = 1;
XChangeWindowAttributes(d, w, CWOverrideRedirect, &a);


앞의 루틴만으로 그림이 그려지지 않는 이유를 이해하기 위해서는

Window의 drawing 방법에 대한 이해가 필요합니다.

보통의 DOS Graphic 프로그램에서는 drawing 명령을 한 순간 바로

그려주는게 일반적이지만.. Window에서는 이것이 event와 함께 해야

합니다.

즉.. X에서 제대로 된 drawing 루틴은 다음과 같습니다.

...
XEvent e;
...
XSetInput(d, w, ExposureMask);
...
while (1) {
    XNextEvent(d, &e);
    if (e.type == Expose) {
        XDrawLine ...
        ...
    }
}

위의 루틴은 w라는 window에 Expose 라는 event를 handling하겠다고

등록을 하고.. while 루프를 돌면서 이 expose event가 발생했을때

실재 drawing을 하는 내용입니다.

expose란 처음 window가 뜨거나 뒷면에 가려졌던 window가 앞으로

드러나게 되는 등.. window를 다시 그릴 필요가 있을때 발생하는

event입니다.

X에서는 Window Manager가 중간에서 Event를 발생시키거나 간섭하므로

라인 하나를 그릴려는데도 위와 같이 조금 이상한 방식으로 해줘야

합니다. 즉.. Manager가 window가 처음 뜰때 expose event를 발생시켜

이 윈도우가 다시 그려야 됨을 알려주고(XSelectInput으로 알려달라고

미리 등록을 해놓은 거고..) window program에서는 event들을 계속

기다리다가 필요한 동작을 해주는 것입니다(button input을 등록해뒀다면

button이 눌러졌을때의 처리도 같은 방식으로 놓일 것이다.)

제일 처음 가르쳐 준 방법은.. 이런 Window Manager가 중간에서 window

의 동작을 제어하지 못하게 하고 직접 화면에 그리는 것입니다. 단

그 덕분에 Window Manager가 만들어 주는 window 둘레의 테두리들.. 누르면

아이콘이 되거나 resize되는 것들이 없는 민밋한 window로 떠버리는

겁니다.

Motif나 XView 등은 위의 복잡한 event처리.. 즉 button같이 생긴 window

을 눌렀을때는 어떤 루틴을 실행 시키고.. 하는 내용을 몇줄로 간단히

등록시키고 처리하게 도와 주는 Xlib위에 다시 한단계 구축된 library라고

생각하면 됩니다.

XView의 경우 위의 while 문과 그 밑의 복잡한 if (event == ...) 의 처리가

xv_main_loop(frame);

이라는 한줄로 처리되어 버립니다.

그리고.. 위의 두가지 방법 말고.. 또다른 방법이 있긴 합니다.

gnuplot에서 힌트를 얻었는데.. gnuplot에서는 한번 윈도우가 뜨고 나서도

계속해서 text input을 받을 수 있읍니다. 보통 이런 방법은 event handling

으로는 힘들기 때문에.. 무언가 다른 방법이 더 있을 거라는 생각에서 결국 

찾아 낸겁니다. 그것은..

...
XSelectInput(d, w, ExposureMask);
XMapWindow(d, w);
do
    XNextEvent(d, &e);
while (event.type != Expose && event.xexpose.count != 0);

를 추가하는 것입니다.

하지만 이것은 event처리가 아니기 때문에 다른 윈도우에 가려졌다 나타나도

다시 그려주지 않습니다. 그래서 가능하면 다음의 루틴을 추가하면 좋습니다.

XSetWindowAttributes att;
att.backing_store = Always;
XChangeWindowAttributes(d, w, CWBackingStore, &att);

단 backing store는 윈도우에 다시 그려야 할때마다 필요한 루틴을 부르는

것이 아니라 계속 메모리에 저장해야 하므로.. 메모리 낭비가 클 수 있습니다.

그럼.. 이상.
[알림판목록 I] [알림판목록 II] [글 목록][이 전][다 음]
키 즈 는 열 린 사 람 들 의 모 임 입 니 다.