add icon support for glava window

This commit is contained in:
Jarcode
2019-09-04 15:36:25 -07:00
parent 7d6d7e2987
commit 4bfbc859f8
6 changed files with 88 additions and 7 deletions

View File

@@ -350,10 +350,10 @@ return function()
model:remove(iter) model:remove(iter)
end end
end end
function window:on_destroy() os.exit(0) end function window:on_destroy() os.exit(0) end
window:show_all() window:show_all()
window:set_icon_from_file(glava.resource_path .. "glava.ico") window:set_icon_from_file(glava.resource_path .. "glava.bmp")
Gtk.main() Gtk.main()
end end

View File

@@ -1354,9 +1354,10 @@ struct glava_renderer* rd_new(const char** paths, const char* entry,
glava_abort(); glava_abort();
} }
gl->w = gl->wcb->create_and_bind(wintitle, "GLava", xwintype, (const char**) xwinstates, xwinstates_sz, gl->w = gl->wcb->create_and_bind(
gl->geometry[2], gl->geometry[3], gl->geometry[0], gl->geometry[1], wintitle, "GLava", xwintype, (const char**) xwinstates, xwinstates_sz,
context_version_major, context_version_minor, gl->clickthrough, test_mode); gl->geometry[2], gl->geometry[3], gl->geometry[0], gl->geometry[1],
context_version_major, context_version_minor, gl->clickthrough, test_mode);
if (!gl->w) abort(); if (!gl->w) abort();
for (size_t t = 0; t < xwinstates_sz; ++t) for (size_t t = 0; t < xwinstates_sz; ++t)
@@ -1366,6 +1367,8 @@ struct glava_renderer* rd_new(const char** paths, const char* entry,
if (xwinstates) free(xwinstates); if (xwinstates) free(xwinstates);
if (wintitle && wintitle != wintitle_default) free(wintitle); if (wintitle && wintitle != wintitle_default) free(wintitle);
xwin_assign_icon_bmp(gl->wcb, gl->w, GLAVA_RESOURCE_PATH "/glava.bmp");
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDisable(GL_DEPTH_CLAMP); glDisable(GL_DEPTH_CLAMP);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);

View File

@@ -7,11 +7,15 @@
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include <time.h> #include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/shm.h> #include <sys/shm.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
@@ -25,6 +29,79 @@
#include "render.h" #include "render.h"
#include "xwin.h" #include "xwin.h"
/* BMP Image header */
struct __attribute__((packed)) bmp_header {
uint16_t header;
uint32_t size;
uint16_t reserved0, reserved1;
uint32_t offset;
/* BITMAPINFOHEADER */
uint32_t header_size, width, height;
uint16_t planes, bits_per_pixel;
uint32_t compression, image_size, hres, vres, colors, colors_used;
};
#define BMP_HEADER_MAGIC 0x4D42
#define BMP_BITFIELDS 3
void xwin_assign_icon_bmp(struct gl_wcb* wcb, void* impl, const char* path) {
int fd = open(path, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "failed to load icon '%s': %s\n", path, strerror(errno));
return;
}
Display* d = wcb->get_x11_display();
Window w = wcb->get_x11_window(impl);
struct stat st;
fstat(fd, &st);
const struct bmp_header* header = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (header->header != BMP_HEADER_MAGIC) {
fprintf(stderr, "failed to load icon '%s': invalid BMP header.\n", path);
close(fd);
return;
}
if (header->bits_per_pixel != 32) {
fprintf(stderr, "failed to load icon '%s': wrong bit depth (%d).\n",
path, (int) header->bits_per_pixel);
close(fd);
return;
}
if (header->planes != 1 || header->compression != BMP_BITFIELDS) {
fprintf(stderr, "failed to load icon '%s': invalid BMP format, requires RGBA bitfields.\n", path);
close(fd);
return;
}
/* Obtain image data pointer from offset */
const char* data = (const char*) (((const uint8_t*) header) + header->offset);
/* Assign icon using the older WMHints. Most window managers don't actually use this. */
XWMHints hints = {};
hints.flags = IconPixmapHint;
hints.icon_pixmap = XCreateBitmapFromData(d, w, data, header->width, header->height);
XSetWMHints(d, w, &hints);
/* To assign the icon property we need to convert the image data to `unsigned long`, which
can be 64-bits and padded depending on the architecture. Additionally we need to flip the
Y-axis due to how BMP data is stored. */
size_t sz = header->width * header->height;
size_t asz = sz + 2;
unsigned long* off = malloc(asz * sizeof(unsigned long));
for (size_t x = 0; x < header->width; ++x) {
for (size_t y = 0; y < header->height; ++y) {
off[x + (((header->height - 1) - y) * header->height) + 2]
= ((const uint32_t*) data)[x + (y * header->height)];
}
}
/* The first two elements represent the icon dimensions */
off[0] = header->width;
off[1] = header->height;
XChangeProperty(d, w, XInternAtom(d, "_NET_WM_ICON", true),
XA_CARDINAL, 32, PropModeReplace, (const unsigned char*) off, asz);
free(off);
close(fd);
};
/* Note: currently unused */ /* Note: currently unused */
Window* __attribute__ ((unused)) xwin_get_desktop_layer(struct gl_wcb* wcb) { Window* __attribute__ ((unused)) xwin_get_desktop_layer(struct gl_wcb* wcb) {
static Window desktop; static Window desktop;

View File

@@ -6,6 +6,7 @@
typedef unsigned long int Window; typedef unsigned long int Window;
void xwin_assign_icon_bmp(struct gl_wcb* wcb, void* impl, const char* path);
bool xwin_should_render(struct gl_wcb* wcb, void* impl); bool xwin_should_render(struct gl_wcb* wcb, void* impl);
void xwin_wait_for_wm(void); void xwin_wait_for_wm(void);
bool xwin_settype(struct gl_wcb* wcb, void* impl, const char* type); bool xwin_settype(struct gl_wcb* wcb, void* impl, const char* type);

BIN
resources/glava.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B