簡體   English   中英

在 XLIB 的標題欄上繪制圖標

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

我的目的是在我嘗試創建的基本 wm 的標題欄中繪制一個圖標。

我已經用谷歌搜索過,並嘗試了不同的解決方案,但到目前為止都沒有奏效(可能只是因為我缺乏知識),我設法從圖標中顯示了一些東西,但它甚至與圖標的內容相差甚遠:

電流輸出

圖標是一個軟盤(帶顏色)所以我用來顯示它的代碼如下:

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

有幾個問題我沒有在任何地方找到答案,

  • 在我搜索的許多解決方案中,我注意到圖標數據存儲在 WM_HINTS 中,但不清楚該結構是否只是保存圖標信息以供將來參考,或者實際上以某種方式顯示圖標(我認為更多第一種情況適用,在示例中我發現顯示了一個圖標,我認為是因為當前的窗口管理器正在添加它)。
  • 我使用類似的代碼將背景設置為 wm,並且在這種情況下它起作用了(在這里查看: https : //github.com/inuyasha82/uwm/blob/master/src/background.c )所以我想我應該做類似的事情,但顯然不是,有什么問題?
  • 我嘗試使用 .bmp 和 .ico 格式,但我注意到輸出不同(但總是 2 種顏色,而且完全錯誤)

所以我很確定我的代碼都是錯誤的,但是我找不到任何關於如何在窗口上繪制圖標的好例子,有人可以幫我嗎?

所以終於在一年多之后我找到了這個問題的解決方案(或多或少)。

我在一個類似的問題上找到了答案: How to load bmp file using x11 window background

所以基本上我的代碼的第一部分是非常正確的(使用 imlib 加載圖像)。

但是整個 WM_Hints 部分並不是必需的,而且為了繪制我使用的 GC 的像素圖(可能也有一種方法可以用它來繪制,但我不知道)。

加載圖像后唯一需要的就是使用 XSetWindowBackgroundPixmap:

XSetWindowBackgroundPixmap(dpy, root, pix);

所以現在更新的功能是:

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();
}

它基本上:

  • 使用 imlib 加載圖像(在這種情況下是 default.bmp)
  • 它在圖像大小的窗口 win 上創建一個像素圖
  • 設置圖像將作為創建的像素圖渲染到的 X 可繪制對象。
  • 將像素圖設置為窗口的背景。
  • 完成后釋放資源

通過這種方式,圖像在窗口上正確顯示。 我不知道這是否不是正確的方法,但至少它是有效的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM