Skip to content

Commit

Permalink
x11: add window icon
Browse files Browse the repository at this point in the history
The png file added to etc/ are taken from the link mentioned in commit
303096b, except that they have been converted to 16 bit, sRGB (with
color profile info dropped, if there was one), and transparent pixels
reset for better compression.

The file x11_icon.bin is generated by gen-x11-icon.sh. I'm adding it to
the git repo directly, because the script requires ImageMagick, and we
don't want to make building even more complicated.

The way how this is done is basically a compromise between effort
required in x11_common.c and in gen-x11-icon.sh. Ideally, x11_icon.bin
would be directly in the format as required by _NET_WM_ICON, but trying
to write the binary width/height values from shell would probably be a
nightmare, so here we go.

The zlib code in x11_common.c is lifted from demux_mkv.c, with some
modifications (like accepting a gzip header, because I don't know how to
make gzip write raw compressed data).
  • Loading branch information
wm4 committed Sep 1, 2013
1 parent 7133518 commit a5183a7
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/tags
/TAGS
/video/out/gl_video_shaders.h
/video/out/vdpau_template.c
/video/out/x11_icon.inc
/demux/ebml_defs.c
/demux/ebml_types.h
/sub/osd_font.h
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,10 @@ video/out/gl_video.c: video/out/gl_video_shaders.h
video/out/gl_video_shaders.h: TOOLS/file2string.pl video/out/gl_video_shaders.glsl
./$^ >$@

video/out/x11_common.c: video/out/x11_icon.inc
video/out/x11_icon.inc: TOOLS/file2string.pl video/out/x11_icon.bin
./$^ >$@

sub/osd_libass.c: sub/osd_font.h
sub/osd_font.h: TOOLS/file2string.pl sub/osd_font.otf
./$^ >$@
Expand Down Expand Up @@ -446,6 +450,7 @@ clean:
-$(RM) video/out/vdpau_template.c
-$(RM) demux/ebml_types.h demux/ebml_defs.c
-$(RM) video/out/gl_video_shaders.h
-$(RM) video/out/x11_icon.inc
-$(RM) sub/osd_font.h

distclean: clean
Expand Down
15 changes: 15 additions & 0 deletions TOOLS/gen-x11-icon.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

# This script is expected to be called as TOOLS/gen-x11-icon.sh (it will access
# etc/mpv-icon...), and it will write video/out/x11_icon.bin.

conv() {
echo
identify -format "icon: %w %h" $1
convert $1 -depth 8 rgba:-
}

(echo "# File generated by gen-x11-icon.sh" ;
conv etc/mpv-icon-8bit-16x16.png ;
conv etc/mpv-icon-8bit-32x32.png ;
conv etc/mpv-icon-8bit-64x64.png) | gzip -c > video/out/x11_icon.bin
Binary file added etc/mpv-icon-8bit-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added etc/mpv-icon-8bit-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added etc/mpv-icon-8bit-64x64.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
104 changes: 104 additions & 0 deletions video/out/x11_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
#include <X11/XF86keysym.h>
#endif

#if CONFIG_ZLIB
#include <zlib.h>
#endif

#include "mpvcore/input/input.h"
#include "mpvcore/input/keycodes.h"

Expand Down Expand Up @@ -128,6 +132,10 @@ typedef struct
long state;
} MotifWmHints;

static const char x11_icon[] =
#include "video/out/x11_icon.inc"
;

static void vo_x11_update_geometry(struct vo *vo);
static void vo_x11_fullscreen(struct vo *vo);
static int vo_x11_get_fs_type(struct vo *vo);
Expand Down Expand Up @@ -371,6 +379,7 @@ static void init_atoms(struct vo_x11_state *x11)
XA_INIT(_NET_WM_PID);
XA_INIT(_NET_WM_NAME);
XA_INIT(_NET_WM_ICON_NAME);
XA_INIT(_NET_WM_ICON);
XA_INIT(_WIN_PROTOCOLS);
XA_INIT(_WIN_LAYER);
XA_INIT(_WIN_HINTS);
Expand Down Expand Up @@ -945,6 +954,100 @@ static void vo_x11_update_window_title(struct vo *vo)
vo_x11_set_property_utf8(vo, x11->XA_NET_WM_ICON_NAME, title);
}

#if CONFIG_ZLIB
static bstr decompress_gz(bstr in)
{
bstr res = {0};
z_stream zstream;
uint8_t *dest;
size_t size = in.len;
int result;

zstream.zalloc = (alloc_func) 0;
zstream.zfree = (free_func) 0;
zstream.opaque = (voidpf) 0;
// 32 for gzip header, 15 for max. window bits
if (inflateInit2(&zstream, 32 + 15) != Z_OK)
goto error;
zstream.next_in = (Bytef *) in.start;
zstream.avail_in = size;

dest = NULL;
zstream.avail_out = size;
do {
size += 4000;
dest = talloc_realloc_size(NULL, dest, size);
zstream.next_out = (Bytef *) (dest + zstream.total_out);
result = inflate(&zstream, Z_NO_FLUSH);
if (result != Z_OK && result != Z_STREAM_END) {
talloc_free(dest);
dest = NULL;
inflateEnd(&zstream);
goto error;
}
zstream.avail_out += 4000;
} while (zstream.avail_out == 4000 && zstream.avail_in != 0
&& result != Z_STREAM_END);

size = zstream.total_out;
inflateEnd(&zstream);

res.start = dest;
res.len = size;
error:
return res;
}
#else
static bstr decompress_gz(bstr in)
{
return (bstr){0};
}
#endif

#define MAX_ICONS 10

static void vo_x11_set_wm_icon(struct vo_x11_state *x11)
{
int num_icons = 0;
void *icon_data[MAX_ICONS];
int icon_w[MAX_ICONS], icon_h[MAX_ICONS];

bstr uncompressed = decompress_gz((bstr){(char *)x11_icon, sizeof(x11_icon)});
bstr data = uncompressed;
while (data.len && num_icons < MAX_ICONS) {
bstr line = bstr_getline(data, &data);
if (bstr_eatstart0(&line, "icon: ")) {
int w, h;
if (bstr_sscanf(line, "%d %d", &w, &h) == 2) {
int size = w * h * 4;
icon_w[num_icons] = w;
icon_h[num_icons] = h;
icon_data[num_icons] = data.start;
num_icons++;
data = bstr_cut(data, size);
}
}
}

size_t icon_size = 0;
for (int n = 0; n < num_icons; n++)
icon_size += sizeof(long) * (2 + icon_w[n] * icon_h[n]);
long *icon = talloc_array(NULL, long, icon_size);
long *cur = icon;
for (int n = 0; n < num_icons; n++) {
*cur++ = icon_w[n];
*cur++ = icon_h[n];
uint32_t *src = icon_data[n];
for (int i = 0; i < icon_h[n] * icon_w[n]; i++)
*cur++ = src[i];
}

XChangeProperty(x11->display, x11->window, x11->XA_NET_WM_ICON,
XA_CARDINAL, 32, PropModeReplace, (char *)icon, icon_size);
talloc_free(icon);
talloc_free(uncompressed.start);
}

static void find_default_visual(struct vo_x11_state *x11, XVisualInfo *vis)
{
Display *display = x11->display;
Expand Down Expand Up @@ -994,6 +1097,7 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis, int x, int y,
XNFocusWindow, x11->window,
NULL);

vo_x11_set_wm_icon(x11);
vo_x11_update_window_title(vo);
}

Expand Down
1 change: 1 addition & 0 deletions video/out/x11_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ struct vo_x11_state {
Atom XA_NET_WM_PID;
Atom XA_NET_WM_NAME;
Atom XA_NET_WM_ICON_NAME;
Atom XA_NET_WM_ICON;
Atom XA_WIN_PROTOCOLS;
Atom XA_WIN_LAYER;
Atom XA_WIN_HINTS;
Expand Down
Binary file added video/out/x11_icon.bin
Binary file not shown.

0 comments on commit a5183a7

Please sign in to comment.