Programming,  Unix/Linux/Mac

[X Window] Top-level widget의 종속 관계 지정하기

[ CnUnix ] in KIDS
글 쓴 이(By): burp (spider)
날 짜 (Date): 2000년 12월 12일 화요일 오후 08시 23분 41초
제 목(Title): [Q] Multiple Top-Level Windows

제가 아래처럼 동시에 창이 두개 뜨도록 Motif를 사용하여 프로그램을 구성하였읍니다. create_window()과 create_textShell()는 각각 그림을 그리는 창과 메시지를
보여주는 창을 구현하는 제가 정의한 함수 입니다.

Widget m_TopLevel, m_TextShell;

int main()
{
m_TopLevel = XtVaAppInitialize(&app, "XDWT", (XrmOptionDescList) NULL,
0, (int*) &argc, argv, fallbackResources, NULL, 0);
create_window(m_TopLevel);

m_TextShell = XtVaAppCreateShell(NULL, "XDWT-MESSAGE",
topLevelShellWidgetClass, XtDisplay(m_TopLevel),
XmNallowResize, True, NULL);
create_textShell(m_TextShell, "output message");

XtRealizeWidget(m_TopLevel);
XtRealizeWidget(m_TextShell);

XtAppMainLoop(app);

return 0; /* ANSI C requires main to return int. */
}

이 프로그램을 실행하면 두개의 창이 뜹니다. 그런데 텍스트 출력을 위한 m_TextShell을 윈도우 타이틀 옆에있는 ‘X’표를 눌러 죽이면 “Warning: XtRemoveGrab asked to remove a widget not on the list”라는 Warning이 나옵니다.

저는 m_TextShell에 pushbutton을 달아서 이걸 누르면 XtUnrealizeWidget(m_TextShell)을 실행하여 창을 보이게 했다 안보이게 했다하는데 사용자가 앞에서 언급한 것 처럼 ‘X’표를 눌러버리면 XtRealizeWidget(m_TextShell) 실행시 프로그램이 죽게 됩니다. 이러한 경우는 어떻게 해야 합니까?

제가 가지고 있는 책에서는 답이 보이지를 않는군요. 옆에 Motif를 하는 사람도
없고 …TT…

고수님들 도와주십시오..
읽어주신 분들께 감사를 드리며.

[ CnUnix ] in KIDS
글 쓴 이(By): terzeron (microkid)
날 짜 (Date): 2000년 12월 13일 수요일 오후 04시 47분 32초
제 목(Title): Re: [Q] Multiple Top-Level Windows

코드가 일부만 있어서 create_textShell에서 어떤 API를 사용하는지 알 수 없으나, 지금 있는 코드만 가지고 짐작하기에는 top level 위짓과 text shell 위짓과의 종속관계가 명시되지 않아서 그런 문제가 발생하는 것이 아닐까 짐작해 봅니다.

대개는 top level 위짓과 text shell 위짓이 *CreateManagedWidget()을 이용하여 종속관계를 명시하게 되는데, 여기서는 top level 위짓이 text shell을 모르기 때문에 그런 경고메시지가 뜨는 것 같군요.

그러나 이 경고 메시지 자체는 크리티컬한 것은 아닙니다. 여러 응용 프로그램에서 이런 메시지가 나오기도 하고 심지어는 모티프의 클론인 lesstif에서도 이런 경고가 자주 뜨기도 합니다만, 무시해도 된다고 하는군요. 팝업계열의 위짓을 관리하는 코드에서 이런 경고 메시지가 많이 발생하는 것으로 알고 있습니다.

완전한 소스코드를 올려보시면 다른 분들도 손쉽게 테스트하실 수 있지 않을까요?

만약, XtVaCreateManagedWidget()함수를 쓰지 않으신다면 XtVaCreateManagedWidget() 함수를 써보시는 것도 좋을 듯 싶습니다.

[ CnUnix ] in KIDS
글 쓴 이(By): burp (spider)
날 짜 (Date): 2000년 12월 13일 수요일 오후 05시 12분 11초
제 목(Title): Re: [Q] Multiple Top-Level Windows

terzeron 님이 말씀하신대로 m_TopLevel과 m_TextShell과의 종속관계가 코드에
명시되어있지 않았네요.

두 위젯사이의 관계라고는 달랑

m_TextShell = XtVaAppCreateShell(NULL, "XDWT-MESSAGE",
topLevelShellWidgetClass, XtDisplay(m_TopLevel), XmNallowResize, True, NULL);

에서 m_TopLevel의 display만 가져오는 걸로 되어있군요.

앞글에서 생략했던 함수 내용입니다.

void create_textShell(Widget parent, char *app_class)
{
Arg args[10];
Cardinal n;
Widget pane, push;

// Create paned window
n = 0;
pane = XmCreatePanedWindow(parent, "pane", args, n);
// Attach text window to paned window
n = 0;
XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
XtSetArg(args[n], XmNeditable, False); n++;
XtSetArg(args[n], XmNcolumns, 80); n++;
XtSetArg(args[n], XmNrows, 7); n++;
m_textarea = XmCreateScrolledText(pane, app_class, args, n);
XtManageChild(m_textarea);
// Attach pushbutton to paned window.
n = 0;
push = XmCreatePushButton(pane, "close", args, n);
// Add pushbutton callback function
XtAddCallback(push, XmNactivateCallback, close_text, m_textarea);
// Manage unmanaged child window
XtManageChild(push);
XtManageChild(pane);
// Handle WM_DELETE_WINDOW message <- 제가 추가해 바로잡은 부분입니다
handle_WM_DELETE_WINDOW_message(parent, pane);
}

게다가 저는 lesstif를 쓰고 있으니.. ^^;;;; 여기저기 삽질하니 해결책이 나오긴 했읍니다. 아래의 함수를 만들어 위에서처럼 해주니 'X'표를 누를때 생성되는 WM_DELETE_WINDOW 메시지가 발생하면 제가 만든 close_text() 함수를 실행하도록 할 수 있었읍니다.

static Atom wm_delete_window = (Atom) None;

void handle_WM_DELETE_WINDOW_message(Widget parent, Widget child)
{
XtVaSetValues(parent, XmNdeleteResponse, XmDO_NOTHING);
set_WMProtocols(parent, (XtCallbackProc)close_text, (XtPointer)child);
}

void set_WMProtocols(Widget shell, XtCallbackProc callback, XtPointer
client_data)
{
// Intern atom if necessary
if(wm_delete_window == (Atom) None) {
wm_delete_window =
XmInternAtom(XtDisplay(shell), "WM_DELETE_WINDOW", False);
}
// Check if interned
if(wm_delete_window == (Atom) None)
return;
// Setup protocol
XmAddWMProtocols(shell, &wm_delete_window, 1);
// Setup protocol callback
XmAddWMProtocolCallback(shell, wm_delete_window, callback, client_data);
}

혹시 XtVaAppCreateShell로 생성한 텍스트 윈도우의 위치를 (0,0)이 아닌 곳에서
시작하려면 어찌해야 하는지 알고계신 분 있나요?

에궁 질문만 하는구나 .. 당분간 질문을 자제해야 겠네요.. 제가 하는 방향이 맞는건지 삐꾸로 가는건지 혼자 공부하는거라 확신이 안서는군요.

답글 남기기