add icon support for glava window
This commit is contained in:
@@ -354,6 +354,6 @@ return function()
|
|||||||
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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
79
glava/xwin.c
79
glava/xwin.c
@@ -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;
|
||||||
|
|||||||
@@ -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
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 |
Reference in New Issue
Block a user