简体   繁体   English

在 XLIB 的标题栏上绘制图标

[英]Draw an icon on a title bar in XLIB

My purpose is to draw an icon into the title bar of a basic wm i'm trying to create.我的目的是在我尝试创建的基本 wm 的标题栏中绘制一个图标。

I already googled, and tried different solutions, but so far none is working (maybe just because of my lack of knowledge), i managed to display something from an icon, but it is not even close to what the icon is:我已经用谷歌搜索过,并尝试了不同的解决方案,但到目前为止都没有奏效(可能只是因为我缺乏知识),我设法从图标中显示了一些东西,但它甚至与图标的内容相差甚远:

电流输出

The icon was a floppy disk (with colours) So the code i used to display it is the following:图标是一个软盘(带颜色)所以我用来显示它的代码如下:

void get_system_icon(char* icon_name, Display *display, Window win){
    printf("Placeholder");
    unsigned int img_h;
    unsigned int img_w;
    unsigned int hotspot_x;
    unsigned int hotspot_y;

    Pixmap icon;
    XTextProperty icon_name_property;
    
    int width, height;
    int h_x, h_y;
    char *filename = "../default.ico";
    Imlib_Image img;
    img = imlib_load_image(filename);
    if(img == NULL){
            printf("Error loading imlibimage");
    }
    ScreenInfos infos = get_screen_informations(display);
    Screen *screen = DefaultScreenOfDisplay(display);
    imlib_context_set_image(img);
    img_w = imlib_image_get_width();
    img_h = imlib_image_get_height();
    printf("Img size: %d - %d\n", img_w, img_h);
    imlib_blend_image_onto_image(img,0,0,0, img_w, img_h, 0,0, infos.width,infos.height);
    Pixmap my_pix;
    my_pix = XCreatePixmap(display, win, img_w, img_h, DefaultDepthOfScreen(screen));
    imlib_context_set_display(display);
    imlib_context_set_visual(DefaultVisualOfScreen(screen));
    imlib_context_set_colormap(DefaultColormapOfScreen(screen));
    imlib_context_set_drawable(my_pix);
    imlib_render_image_on_drawable(0, 0);

    XSizeHints* win_size_hints;
    XWMHints* win_hints;
    int return_code;
    return_code = XStringListToTextProperty(&icon_name,
                               1,
                               &icon_name_property);
    if(return_code == 0) {
        printf("Error");
    }
    XSetWMIconName(display, win, &icon_name_property);
    win_hints = XAllocWMHints();
    if (!win_size_hints) {
        fprintf(stderr, "XAllocSizeHints - out of memory\n");
        exit(1);
    }
    win_hints->flags = IconPixmapHint | StateHint | IconPositionHint;
    win_hints->icon_pixmap = my_pix;
    win_hints->initial_state = IconicState;
    win_hints->icon_x = 0;
    win_hints->icon_y = 0;

    /* pass the hints to the window manager. */
    XSetWMHints(display, win, win_hints);

    /* finally, we can free the WM hints structure. */
    GC gc;
    gc = XCreateGC(display, win, 0, NULL);
    //XPutImage(display, win, gc, 
    XSetBackground(display, gc, WhitePixel(display, DefaultScreen(display)));   
    //WhitePixel(display, DefaultScreen(display));

    XCopyPlane(display, my_pix, win, gc,
                0, 0,
                30, 30,
                0, 0,
                1); 

    XFree(win_hints);
XFlush(display);
}

there are several question that i didn't found an answer anywhere,有几个问题我没有在任何地方找到答案,

  • in many of the solution that i searched, i noticed that the icon data was stored into the WM_HINTS, but it was not clear if that structure was just holding the icon information for future references, or was actually displaying the icon somehow (i think more the first case applies, and in the examples i found that displayed an icon i suppose was because the current window manager was adding it).在我搜索的许多解决方案中,我注意到图标数据存储在 WM_HINTS 中,但不清楚该结构是否只是保存图标信息以供将来参考,或者实际上以某种方式显示图标(我认为更多第一种情况适用,在示例中我发现显示了一个图标,我认为是因为当前的窗口管理器正在添加它)。
  • I used a similar code to set the background to the wm, and it that case it worked (check here: https://github.com/inuyasha82/uwm/blob/master/src/background.c ) so i supposed i should do something similar, but apparently not, what is wrong?我使用类似的代码将背景设置为 wm,并且在这种情况下它起作用了(在这里查看: https : //github.com/inuyasha82/uwm/blob/master/src/background.c )所以我想我应该做类似的事情,但显然不是,有什么问题?
  • I tried to use .bmp and .ico format and what i noticed is that the output was different (but always 2 colors, and completely wrong)我尝试使用 .bmp 和 .ico 格式,但我注意到输出不同(但总是 2 种颜色,而且完全错误)

So I'm pretty sure that my code is all wrong, but i can't find anywhere a good example of how to draw an icon on a window, can someone help me please?所以我很确定我的代码都是错误的,但是我找不到任何关于如何在窗口上绘制图标的好例子,有人可以帮我吗?

So finally after more than one year I found a solution (more or less) to this issue.所以终于在一年多之后我找到了这个问题的解决方案(或多或少)。

I found the answer on a similar SO question: How to load bmp file using x11 window background我在一个类似的问题上找到了答案: How to load bmp file using x11 window background

So basically the first part of my code was pretty correct (the image loading using imlib).所以基本上我的代码的第一部分是非常正确的(使用 imlib 加载图像)。

But the wholse WM_Hints part was not necessary, and also to draw the pixmap i was using a GC (probably there is a way to draw with it too, but i don't know).但是整个 WM_Hints 部分并不是必需的,而且为了绘制我使用的 GC 的像素图(可能也有一种方法可以用它来绘制,但我不知道)。

Tshe only thing needed once the image is loaded is to use XSetWindowBackgroundPixmap:加载图像后唯一需要的就是使用 XSetWindowBackgroundPixmap:

XSetWindowBackgroundPixmap(dpy, root, pix);

So the updated function now is:所以现在更新的功能是:

void get_system_icon(char* icon_name, Display *display, Window win){
    unsigned int img_h;
    unsigned int img_w;
    char *filename = "../default.bmp";
    Pixmap my_pix;
    Imlib_Image img;

    img = imlib_load_image(filename);
    if(img == NULL){
            printf("Error loading imlibimage");
    }
    Screen *screen = DefaultScreenOfDisplay(display);
    imlib_context_set_image(img);
    img_w = imlib_image_get_width();
    img_h = imlib_image_get_height();
    printf("Img size: %d - %d\n", img_w, img_h);
    my_pix = XCreatePixmap(display, win, img_w, img_h, DefaultDepthOfScreen(screen));
    imlib_context_set_display(display);
    imlib_context_set_visual(DefaultVisualOfScreen(screen));
    imlib_context_set_colormap(DefaultColormapOfScreen(screen));
    imlib_context_set_drawable(my_pix);
    imlib_render_image_on_drawable(0, 0);
    XSetWindowBackgroundPixmap(display, win, my_pix);
    XClearWindow(display, win);
    XFreePixmap(display, my_pix);
    imlib_free_image();
}

It basically:它基本上:

  • loads an image using imlib (in this case is default.bmp)使用 imlib 加载图像(在这种情况下是 default.bmp)
  • It creates a pixmap on the window win of the size of the image它在图像大小的窗口 win 上创建一个像素图
  • sets the X drawable to which images will be rendered as the pixmap created.设置图像将作为创建的像素图渲染到的 X 可绘制对象。
  • Set the pixmap as a background of the window.将像素图设置为窗口的背景。
  • It frees the resources once done完成后释放资源

In this way the image is showed correctly on the window.通过这种方式,图像在窗口上正确显示。 I don't know if it isn't the correct way to do it, but at least it is working.我不知道这是否不是正确的方法,但至少它是有效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM