summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile5
-rw-r--r--TOOLS/gen-x11-icon.sh15
-rw-r--r--etc/mpv-icon-8bit-16x16.pngbin0 -> 759 bytes
-rw-r--r--etc/mpv-icon-8bit-32x32.pngbin0 -> 2124 bytes
-rw-r--r--etc/mpv-icon-8bit-64x64.pngbin0 -> 5686 bytes
-rw-r--r--video/out/x11_common.c104
-rw-r--r--video/out/x11_common.h1
-rw-r--r--video/out/x11_icon.binbin0 -> 8486 bytes
9 files changed, 126 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index b38112e747..3dd965bfba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/Makefile b/Makefile
index 440820b281..d40f890790 100644
--- a/Makefile
+++ b/Makefile
@@ -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
./$^ >$@
@@ -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
diff --git a/TOOLS/gen-x11-icon.sh b/TOOLS/gen-x11-icon.sh
new file mode 100644
index 0000000000..0faf2c1f5e
--- /dev/null
+++ b/TOOLS/gen-x11-icon.sh
@@ -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
diff --git a/etc/mpv-icon-8bit-16x16.png b/etc/mpv-icon-8bit-16x16.png
new file mode 100644
index 0000000000..ac2cb81909
--- /dev/null
+++ b/etc/mpv-icon-8bit-16x16.png
Binary files differ
diff --git a/etc/mpv-icon-8bit-32x32.png b/etc/mpv-icon-8bit-32x32.png
new file mode 100644
index 0000000000..bfb5f9cf44
--- /dev/null
+++ b/etc/mpv-icon-8bit-32x32.png
Binary files differ
diff --git a/etc/mpv-icon-8bit-64x64.png b/etc/mpv-icon-8bit-64x64.png
new file mode 100644
index 0000000000..46bb33d88e
--- /dev/null
+++ b/etc/mpv-icon-8bit-64x64.png
Binary files differ
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 00c0f7625d..af83c6a53e 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -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"
@@ -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);
@@ -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);
@@ -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;
@@ -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);
}
diff --git a/video/out/x11_common.h b/video/out/x11_common.h
index 53ca553a72..c2735ad82f 100644
--- a/video/out/x11_common.h
+++ b/video/out/x11_common.h
@@ -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;
diff --git a/video/out/x11_icon.bin b/video/out/x11_icon.bin
new file mode 100644
index 0000000000..957d9fcffe
--- /dev/null
+++ b/video/out/x11_icon.bin
Binary files differ