LINUX.ORG.RU

Как корректно завершить xlib программу?

 ,


1

1

Код:

 #include <X11/Xlib.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 
 extern int errno;
 
 int main(void) {
   Display *d;
   Window w;
   XEvent e;
   char *msg = "Hello, World!";
   int s;
 
   /* Соединиться с X сервером, если X сервер на удаленной машине
    * следует разрешить на машине, где запущен X Server 
    * удаленные соединения командой xhost+ (см. man xhost)
    */
    if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
        printf("Can't connect X server: %s\n", strerror(errno));
        exit(1);
    }
 
   s = DefaultScreen(d);
 
   /* Создать окно */
   w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 200, 1,
                           BlackPixel(d, s), WhitePixel(d, s));
 
   /* На какие события будем реагировать */
   XSelectInput(d, w, ExposureMask | KeyPressMask);
 
  /* Вывести окно на экран */
   XMapWindow(d, w);
 
   /* Бесконечный цикл обработки событий */
   while (1) {
     XNextEvent(d, &e);
 
    /* Перерисовать окно */
     if (e.type == Expose) {
       XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10);
       XDrawString(d, w, DefaultGC(d, s), 50, 50, msg, strlen(msg));
     }
   /* При нажатии кнопки-выход */
     if (e.type == KeyPress)
       break;
   }
 
  /* Закрыть соединение с X сервером */
   XCloseDisplay(d);
 
   return 0;
 }

Консоль (если закрыть окно «крестиком»):

~/Prog/C/Xlib$ ./test 
XIO:  fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
      after 13 requests (11 known processed) with 0 events remaining.
Как избавиться от этого сообщения?

Дополнение: Пробую ставить маску StructureNotifyMask, чтобы ловить событие DestroyNotify. Фиг там - по ресайзу\муву событие появляется, по крестику - нет.



Последнее исправление: inn (всего исправлений: 1)
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>

int
main(void)
{
        Display        *d;
        Window          w;
        XEvent          e;
        Atom            delwin;
        char           *msg = "Hello, World!";
        int             s;
        int             die = 0;

        if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
                err(1, "Can't connect X server");

        s = DefaultScreen(d);

        w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 200, 1,
                                BlackPixel(d, s), WhitePixel(d, s));

        delwin = XInternAtom(d, "WM_DELETE_WINDOW", 0);
        XSetWMProtocols(d, w, &delwin, 1);

        XSelectInput(d, w, ExposureMask|KeyPressMask);

        XMapWindow(d, w);

        while (!die) {
                if (XPending(d)) {
                        XNextEvent(d, &e);
                        switch (e.type) {
                        case Expose:
                                XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10);
                                XDrawString(d, w, DefaultGC(d, s), 50, 50, msg, strlen(msg));
                                break;
                        case KeyPress:
                                break;
                        case ClientMessage:
                                die = *e.xclient.data.l == delwin;
                                break;
                        default:
                                break;
                        }
                }
        }

        XCloseDisplay(d);

        return 0;
}
beastie ★★★★★
()
Ответ на: комментарий от beastie

Хм. Спасибо, действительно работает. А скажите, это и магазине... В смысле если нет WM или какой0нибудь нестандартный, то работать будет?

inn
() автор топика
Ответ на: комментарий от inn

WM_DELETE_WINDOW гдето в ICCCM описан, его все что угодно поддерживает.

x0r ★★★★★
()
Ответ на: комментарий от inn

Я уже всех подробностей теории не помню. В общем случае программа умирает или сама или по сигналу или её «просят умереть».

Закрывание «красным крестиком» это и есть последний случай. Соответствующий event должен соответственно корректно обрабатываться.

Подробности смотри в ICCCM — это протокол X11, который полностью или частично поддерживаться каждым WM.

Совсем без WM программа может умереть только или сама или по сигналу (некому ей сказать «умри»). Иначе опять таки ICCCM.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.