Ошибка XOpenDisplay

Я пишу простой класс окна, который не может вернуть отображение. Вот краткая версия:

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>

class WindowImpl
{
    public:
        WindowImpl()
        {
            open = true;
        }

        WindowImpl(float width, float height)
        {
            if(!create(width, height))
            {
                fprintf(stderr, "Could not open display\n");
                exit(1);
            }

            open = true;
        }

        ~WindowImpl()
        {
            XCloseDisplay(display);
        };

        bool create(float width, float height)
        {
            display = XOpenDisplay(NULL);
            if(display == NULL)
                return false;

            int displayID = DefaultScreen(display);

            window = XCreateSimpleWindow(display, RootWindow(display, displayID), 10, 10, width, height, 1, BlackPixel(display, displayID), WhitePixel(display, displayID));
            XMapWindow(display, window);

            return true;
        }

        bool isOpen()
        {
            return open;
        }

        void close()
        {
            open == false;
        }

    private:
        Display* display;
        Window window;
        bool open;
};


int main()
{
    WindowImpl myWindow(1920, 1080);
    char* cmd;

    while(myWindow.isOpen())
    {
        if(gets(cmd) == "close")
            myWindow.close();
    }

    return 0;
}

WindowImpl::create не работает, XOpenDisplay возвращает NULL, но я не уверен, почему. Надеюсь, кто-то может пролить свет на проблему здесь.

Редактировать: изменение WindowImpl::create для возврата true и false вместо 0 и 1 приводит к тому, что он проходит, но окно все еще не открывается;

В целях разъяснения:

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    Display* display;
    Window window;
    XEvent event;
    char* message = "Hello";
    int screenSize;

    display = XOpenDisplay(NULL);
    if(display == NULL)
    {
        fprintf(stderr, "Cannot open display\n");
        exit(1);
    }

    screenSize = DefaultScreen(display);
    window = XCreateSimpleWindow(display, RootWindow(display, screenSize), 10, 10, 1920, 1080, 1, BlackPixel(display, screenSize), WhitePixel(display, screenSize));
    XSelectInput(display, window, ExposureMask | KeyPressMask);
    XMapWindow(display, window);

    KeySym keysym = XK_Escape;
    KeyCode keycode = XKeysymToKeycode(display, keysym);

    while(true)
    {
        XNextEvent(display, &event);
        if(event.type == KeyPress && event.xkey.keycode == keycode)
            break;
    }

    XCloseDisplay(display);
    return 0;
}

Компилируется и работает нормально.


person user2941616    schedule 26.01.2014    source источник
comment
Определена ли ваша переменная среды DISPLAY?   -  person Amadeus    schedule 27.01.2014
comment
Да, и я могу открыть окно, если делаю все это внутри основного, по какой-то причине помещение его в класс беспокоит.   -  person user2941616    schedule 27.01.2014
comment
Немного оффтоп, но вы что, для каждого окна будете открывать новое подключение? Имейте в виду, что максимальное общее количество соединений на сервер обычно очень мало, часто всего 256 (все XOpenDisplay вызовы в вашей системе).   -  person Andrey Sidorov    schedule 27.01.2014
comment
Смотрите изменения, пожалуйста, я добавил пример, который компилируется и работает, как задумано.   -  person user2941616    schedule 27.01.2014
comment
@AndreySidorov Это то, что я подумаю в будущем, но для моих текущих целей я просто пытаюсь открыть окно.   -  person user2941616    schedule 27.01.2014


Ответы (1)


Когда вы создаете окна, вам нужно позволить X-серверу обрабатывать выходной буфер. Обычно это делается, когда вы входите в цикл событий окна, т.е. вызываете любую функцию, в имени которой есть EVENT.

Если вы не имеете дело с событиями в своем коде, другим способом очистки выходного буфера является вызов XFlush, как сказано в его руководстве:

Функция XFlush очищает выходной буфер. Большинству клиентских приложений не требуется использовать эту функцию, поскольку буфер вывода автоматически очищается при необходимости вызовами XPending, XNextEvent и XWindowEvent. События, сгенерированные сервером, могут быть помещены в очередь событий библиотеки.

Функция XSync сбрасывает буфер вывода, а затем ждет, пока все запросы не будут получены и обработаны X-сервером.

Итак, чтобы решить вашу проблему, я предлагаю поместить эту строку кода:

        window = XCreateSimpleWindow(display, RootWindow(display, displayID), 10, 10, width, height, 1, BlackPixel(display, displayID), WhitePixel(display, displayID));
        XMapWindow(display, window);

        XFlush(display);   // <------------

        return true;
person Amadeus    schedule 26.01.2014