【问题标题】:XOpenDisplay failingXOpenDisplay 失败
【发布时间】:2014-01-27 07:15:04
【问题描述】:

我正在编写一个无法返回显示的简单窗口类。这是简短的版本:

#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;
}

编译并运行良好。

【问题讨论】:

  • 你的 DISPLAY 环境变量定义了吗?
  • 是的,如果在 main 中完成所有操作,我可以打开一个窗口,但出于某种原因,将其放入类中会很麻烦。
  • 有点跑题了,但是你要为每个窗口打开新的连接吗?请注意,每台服务器的最大连接总数通常非常小,通常只有 256 个(系统中的所有 XOpenDisplay 调用)
  • 请查看编辑,我添加了按预期编译和运行的示例。
  • @AndreySidorov 这是我以后会考虑的事情,但就我目前的目的而言,我只是想打开一个窗口。

标签: c++ x11


【解决方案1】:

当你创建一个windows时,你需要让X server来处理输出缓冲区。通常这是在您进入窗口事件循环时完成的,即调用名称中包含 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;

【讨论】:

    猜你喜欢
    • 2017-10-06
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 2011-02-27
    • 1970-01-01
    相关资源
    最近更新 更多