I want to make splash screen and now I have two problems?

懵懂的女人 提交于 2019-12-23 04:39:31

问题


1: I want to have a splash screen but I only have a window?so,how to do with sth like parm

2: I've used a while(!done) to draw the window so how to break out with a function or sth else

here is my code and much thx to you

g++ -o m_splash m_splash.cpp -lX11 -lImlib2

#include <stdio.h>
#include <X11/Xlib.h>
#include <Imlib2.h>
#include <unistd.h>

int main()
{
    Imlib_Image  m_img;
    Display     *m_dpy;
    Pixmap       m_pix;
    Window       m_root;
    Screen      *scn;
    int m_width, m_height;
    const char *filename = "/home/ang/so_zt/w.png";

    m_img = imlib_load_image(filename);
    if(!m_img)
    {
        printf("%s\n","init m_img faild");
    }
    imlib_context_set_image(m_img);
    m_width = imlib_image_get_width();
    m_height = imlib_image_get_height();

    m_dpy = XOpenDisplay(NULL);
    if(!m_dpy)
    {
        printf("%s\n","open display failed");
    }
    scn = DefaultScreenOfDisplay(m_dpy);
    int s = DefaultScreen(m_dpy);
    m_root = XCreateSimpleWindow(m_dpy, RootWindow(m_dpy,s),10,10,m_width,m_height,0,
                                 BlackPixel(m_dpy, s), WhitePixel(m_dpy, s));
    m_pix = XCreatePixmap(m_dpy, m_root, m_width, m_height, DefaultDepthOfScreen(scn));

    imlib_context_set_display(m_dpy);
    imlib_context_set_visual(DefaultVisualOfScreen(scn));
    imlib_context_set_colormap(DefaultColormapOfScreen(scn));
    imlib_context_set_drawable(m_pix);

    imlib_render_image_on_drawable(0,0);
    XSetWindowBackgroundPixmap(m_dpy, m_root, m_pix);
    XClearWindow(m_dpy, m_root);
    Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False);
    XSetWMProtocols(m_dpy, m_root, &wmDeleteMessage, 1);

    XSelectInput(m_dpy, m_root, ExposureMask | KeyPressMask | StructureNotifyMask);
    XMapWindow(m_dpy, m_root);
    bool done = false;
    while (!done)
    {
        XEvent m_ev;
        XNextEvent(m_dpy, &m_ev);
        /* draw or redraw the window */
        if (m_ev.type == Expose)
        {
            XFillRectangle(m_dpy, m_root, DefaultGC(m_dpy, DefaultScreen(m_dpy)), 20, 20, 10, 10);
        }

    /* exit on key press */
        //usleep(1000000);
        //done = true;
        switch(m_ev.type)
        {
        case KeyPress:
            XDestroyWindow(m_dpy, m_root);
        break;

        case DestroyNotify:
            done = true;
        break;
        case ClientMessage:
            if (m_ev.xclient.data.l[0] == wmDeleteMessage)
            {
                done = true;
            }
        break;
        }
    }

    //XFreePixmap(m_dpy, m_pix);
    //imlib_free_image();
    //XCloseDisplay(m_dpy);
}

回答1:


To make it a splash screen, use extended window manager hints.

#include <X11/Xatom.h>

Atom type = XInternAtom(m_dpy, "_NET_WM_WINDOW_TYPE", False);
Atom value = XInternAtom(m_dpy, "_NET_WM_WINDOW_TYPE_SPLASH", False);
XChangeProperty(m_dpy, m_root, type, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char*>(&value), 1);

The window then appears without decorations and stays until clicked.

When clicked you get an UnmapNotify event, so this what you should use to set done.

To avoid having to get events, add

XFlush(m_dpy);

after mapping the window to display it and

XUnmapWindow(m_dpy, m_root);

when you want to get rid of it.

In this example the program just sleeps for 5 seconds before continuing:

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <Imlib2.h>
#include <unistd.h>

int main()
{
    Imlib_Image  m_img;
    Display     *m_dpy;
    Pixmap       m_pix;
    Window       m_root;
    Screen      *scn;
    int m_width, m_height;
    const char *filename = "w.png";

    m_img = imlib_load_image(filename);
    if(!m_img)
    {
        printf("%s\n","init m_img faild");
    }
    imlib_context_set_image(m_img);
    m_width = imlib_image_get_width();
    m_height = imlib_image_get_height();

    m_dpy = XOpenDisplay(NULL);
    if(!m_dpy)
    {
        printf("%s\n","open display failed");
    }
    scn = DefaultScreenOfDisplay(m_dpy);
    int s = DefaultScreen(m_dpy);
    m_root = XCreateSimpleWindow(m_dpy, RootWindow(m_dpy,s),10,10,m_width,m_height,0,
                                 BlackPixel(m_dpy, s), WhitePixel(m_dpy, s));
    m_pix = XCreatePixmap(m_dpy, m_root, m_width, m_height, DefaultDepthOfScreen(scn));

    Atom type = XInternAtom(m_dpy, "_NET_WM_WINDOW_TYPE", False);
    Atom value = XInternAtom(m_dpy, "_NET_WM_WINDOW_TYPE_SPLASH", False);
    XChangeProperty(m_dpy, m_root, type, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char*>(&value), 1);

    imlib_context_set_display(m_dpy);
    imlib_context_set_visual(DefaultVisualOfScreen(scn));
    imlib_context_set_colormap(DefaultColormapOfScreen(scn));
    imlib_context_set_drawable(m_pix);

    imlib_render_image_on_drawable(0,0);
    XSetWindowBackgroundPixmap(m_dpy, m_root, m_pix);
    XClearWindow(m_dpy, m_root);
    Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False);
    XSetWMProtocols(m_dpy, m_root, &wmDeleteMessage, 1);

    XMapWindow(m_dpy, m_root);
    XFlush(m_dpy);
    sleep(5);
    XUnmapWindow(m_dpy, m_root);
}



回答2:


and this program can have a splash with hello world alse I do not know how to jump out of the while(!done) so much thx to U

g++ -o test_chr test_chr.cpp -lX11

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(void)
{
    Display *d;
    Window w;
    XEvent e;
    const char *msg = "Hello, World!";
    int s;
    bool done = false;

    /* open connection with the server */
    d = XOpenDisplay(NULL);
    if (d == NULL)
    {
        fprintf(stderr, "Cannot open display\n");
        exit(1);
    }
    s = DefaultScreen(d);

    /* create window */
    w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 480, 320, 0,BlackPixel(d, s), WhitePixel(d, s));
    Atom type = XInternAtom(d,"_NET_WM_WINDOW_TYPE", False);
    Atom value = XInternAtom(d,"_NET_WM_WINDOW_TYPE_SPLASH", False);
    XChangeProperty(d, w, type, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char*>(&value), 1);
    /* register interest in the delete window message */
    Atom wmDeleteMessage = XInternAtom(d, "WM_DELETE_WINDOW", False);
    XSetWMProtocols(d, w, &wmDeleteMessage, 1);

    /* select kind of events we are interested in */
    XSelectInput(d, w, ExposureMask | KeyPressMask | StructureNotifyMask);

    /* map (show) the window */
    XMapWindow(d, w);
    /* event loop */
    while (!done)
    {
        XNextEvent(d, &e);
        /* draw or redraw the window */
        if (e.type == Expose)
        {
            XDrawString(d, w, DefaultGC(d, s), 50, 50, msg, strlen(msg));
        }

        /* exit on key press */
        switch(e.type)
        {
        case KeyPress:
            XDestroyWindow(d, w);

        break;

        case DestroyNotify:
            done = true;
        break;

        case ClientMessage:
            if (e.xclient.data.l[0] == wmDeleteMessage)
            {
                done = true;
            }
        break;
        }
    }
    /* close connection to server */
    XCloseDisplay(d);

    return 0;
}


来源:https://stackoverflow.com/questions/16603525/i-want-to-make-splash-screen-and-now-i-have-two-problems

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!