mirror of https://github.com/mpv-player/mpv.git
x11: load icon differently
Now it's sourced from the etc/ PNG files directly, instead of preprocessing them with imagemagick. Add some ad-hoc code to decode PNG files with libavcodec. At least we can drop the zlib code in exchange.
This commit is contained in:
parent
aee81828e2
commit
9127939071
|
@ -1,15 +0,0 @@
|
|||
#!/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
|
||||
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
|
|
@ -0,0 +1,48 @@
|
|||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include "common/common.h"
|
||||
#include "mp_image.h"
|
||||
#include "image_writer.h"
|
||||
|
||||
#include "image_loader.h"
|
||||
|
||||
struct mp_image *load_image_png_buf(void *buffer, size_t buffer_size, int imgfmt)
|
||||
{
|
||||
const AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_PNG);
|
||||
if (!codec)
|
||||
return NULL;
|
||||
|
||||
AVCodecContext *avctx = avcodec_alloc_context3(codec);
|
||||
if (!avctx)
|
||||
return NULL;
|
||||
|
||||
if (avcodec_open2(avctx, codec, NULL) < 0) {
|
||||
avcodec_free_context(&avctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVPacket *pkt = av_packet_alloc();
|
||||
if (pkt) {
|
||||
if (av_new_packet(pkt, buffer_size) >= 0)
|
||||
memcpy(pkt->data, buffer, buffer_size);
|
||||
}
|
||||
|
||||
// (There is only 1 outcome: either it takes it and decodes it, or not.)
|
||||
avcodec_send_packet(avctx, pkt);
|
||||
avcodec_send_packet(avctx, NULL);
|
||||
|
||||
av_packet_free(&pkt);
|
||||
|
||||
struct mp_image *res = NULL;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
if (frame && avcodec_receive_frame(avctx, frame) >= 0) {
|
||||
struct mp_image *r = mp_image_from_av_frame(frame);
|
||||
if (r)
|
||||
res = convert_image(r, imgfmt, mp_null_log);
|
||||
talloc_free(r);
|
||||
}
|
||||
av_frame_free(&frame);
|
||||
|
||||
avcodec_free_context(&avctx);
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef MP_IMAGE_LOADER_H_
|
||||
#define MP_IMAGE_LOADER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct mp_image;
|
||||
struct mp_image *load_image_png_buf(void *buffer, size_t buffer_size, int imgfmt);
|
||||
|
||||
#endif
|
|
@ -38,8 +38,6 @@
|
|||
#include <X11/extensions/Xinerama.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "misc/bstr.h"
|
||||
#include "options/options.h"
|
||||
|
@ -48,6 +46,8 @@
|
|||
#include "common/msg.h"
|
||||
#include "input/input.h"
|
||||
#include "input/event.h"
|
||||
#include "video/image_loader.h"
|
||||
#include "video/mp_image.h"
|
||||
#include "x11_common.h"
|
||||
#include "mpv_talloc.h"
|
||||
|
||||
|
@ -57,9 +57,6 @@
|
|||
#include "osdep/timer.h"
|
||||
#include "osdep/subprocess.h"
|
||||
|
||||
// Specifically for mp_cancel
|
||||
#include "stream/stream.h"
|
||||
|
||||
#include "input/input.h"
|
||||
#include "input/keycodes.h"
|
||||
|
||||
|
@ -109,10 +106,26 @@ typedef struct
|
|||
long state;
|
||||
} MotifWmHints;
|
||||
|
||||
static const char x11_icon[] =
|
||||
#include "video/out/x11_icon.inc"
|
||||
static const char x11_icon_16[] =
|
||||
#include "video/out/x11_icon_16.inc"
|
||||
;
|
||||
|
||||
static const char x11_icon_32[] =
|
||||
#include "video/out/x11_icon_32.inc"
|
||||
;
|
||||
|
||||
static const char x11_icon_64[] =
|
||||
#include "video/out/x11_icon_64.inc"
|
||||
;
|
||||
|
||||
#define ICON_ENTRY(var) { (char *)var, sizeof(var) }
|
||||
static const struct bstr x11_icons[] = {
|
||||
ICON_ENTRY(x11_icon_16),
|
||||
ICON_ENTRY(x11_icon_32),
|
||||
ICON_ENTRY(x11_icon_64),
|
||||
{0}
|
||||
};
|
||||
|
||||
static struct mp_log *x11_error_output;
|
||||
static atomic_int x11_error_silence;
|
||||
|
||||
|
@ -1318,92 +1331,36 @@ static void vo_x11_xembed_send_message(struct vo_x11_state *x11, long m[4])
|
|||
XSendEvent(x11->display, x11->parent, False, NoEventMask, &ev);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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];
|
||||
int icon_size = 0;
|
||||
long *icon = talloc_array(NULL, long, 0);
|
||||
|
||||
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);
|
||||
for (int n = 0; x11_icons[n].start; n++) {
|
||||
struct mp_image *img =
|
||||
load_image_png_buf(x11_icons[n].start, x11_icons[n].len, IMGFMT_RGBA);
|
||||
if (!img)
|
||||
continue;
|
||||
int new_size = 2 + img->w * img->h;
|
||||
MP_RESIZE_ARRAY(NULL, icon, icon_size + new_size);
|
||||
long *cur = icon + icon_size;
|
||||
icon_size += new_size;
|
||||
*cur++ = img->w;
|
||||
*cur++ = img->h;
|
||||
for (int y = 0; y < img->h; y++) {
|
||||
uint8_t *s = (uint8_t *)img->planes[0] + img->stride[0] * y;
|
||||
for (int x = 0; x < img->w; x++) {
|
||||
*cur++ = s[x * 4 + 0] | (s[x * 4 + 1] << 8) |
|
||||
(s[x * 4 + 2] << 16) | ((unsigned)s[x * 4 + 3] << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int icon_size = 0;
|
||||
for (int n = 0; n < num_icons; n++)
|
||||
icon_size += 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];
|
||||
uint8_t *s = icon_data[n];
|
||||
for (int i = 0; i < icon_h[n] * icon_w[n]; i++, s += 4)
|
||||
*cur++ = s[0] | (s[1] << 8) | (s[2] << 16) | ((unsigned)s[3] << 24);
|
||||
talloc_free(img);
|
||||
}
|
||||
|
||||
XChangeProperty(x11->display, x11->window, XA(x11, _NET_WM_ICON),
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(unsigned char *)icon, icon_size);
|
||||
talloc_free(icon);
|
||||
talloc_free(uncompressed.start);
|
||||
}
|
||||
|
||||
static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis,
|
||||
|
|
Binary file not shown.
|
@ -59,8 +59,20 @@ def build(ctx):
|
|||
|
||||
ctx(
|
||||
features = "file2string",
|
||||
source = "video/out/x11_icon.bin",
|
||||
target = "video/out/x11_icon.inc",
|
||||
source = "etc/mpv-icon-8bit-16x16.png",
|
||||
target = "video/out/x11_icon_16.inc",
|
||||
)
|
||||
|
||||
ctx(
|
||||
features = "file2string",
|
||||
source = "etc/mpv-icon-8bit-32x32.png",
|
||||
target = "video/out/x11_icon_32.inc",
|
||||
)
|
||||
|
||||
ctx(
|
||||
features = "file2string",
|
||||
source = "etc/mpv-icon-8bit-64x64.png",
|
||||
target = "video/out/x11_icon_64.inc",
|
||||
)
|
||||
|
||||
ctx(
|
||||
|
@ -315,6 +327,7 @@ def build(ctx):
|
|||
( "video/csputils.c" ),
|
||||
( "video/fmt-conversion.c" ),
|
||||
( "video/gpu_memcpy.c", "sse4-intrinsics" ),
|
||||
( "video/image_loader.c" ),
|
||||
( "video/image_writer.c" ),
|
||||
( "video/img_format.c" ),
|
||||
( "video/hwdec.c" ),
|
||||
|
|
Loading…
Reference in New Issue