Skip to content

Commit

Permalink
notify: sending image data via image-data hint WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleksiy-Yakovenko committed Dec 29, 2023
1 parent 401c399 commit ed2ffd5
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 14 deletions.
11 changes: 10 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,16 @@ AS_IF([test "${enable_gme}" != "no" -a "${HAVE_ZLIB}" = "yes"], [
])

AS_IF([test "${HAVE_DBUS}" = "yes" -a "${enable_notify}" != "no"], [
HAVE_NOTIFY=yes
AS_IF([test "${enable_staticlink}" != "no"], [
HAVE_NOTIFY=yes
NOTIFY_DEPS_CFLAGS="${GTK3_310_CFLAGS}"
NOTIFY_DEPS_LIBS="${GTK3_310_LIBS}"
AC_SUBST(NOTIFY_DEPS_CFLAGS)
AC_SUBST(NOTIFY_DEPS_LIBS)
], [
PKG_CHECK_MODULES(NOTIFY_DEPS, glib-2.0 >= 2.26 gio-2.0 gdk-pixbuf-2.0, HAVE_NOTIFY=yes, HAVE_NOTIFY=no)
])
NOTIFY_LIBS="$DBUS_DEPS_LIBS"
NOTIFY_CFLAGS="$DBUS_DEPS_CFLAGS"
AC_SUBST(NOTIFY_LIBS)
Expand Down
33 changes: 26 additions & 7 deletions plugins/gtkui/covermanager/covermanager.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ static GdkPixbuf *
_load_image_from_cover (covermanager_t *impl, ddb_cover_info_t *cover, int want_default) {
GdkPixbuf *img = NULL;

if (!img && cover && cover->image_filename) {
if (cover && cover->image_filename) {
long size = 0;
char *buf = _buffer_from_file (cover->image_filename, &size);
if (buf != NULL) {
Expand Down Expand Up @@ -267,7 +267,8 @@ _cover_loaded_callback (int error, ddb_cover_query_t *query, ddb_cover_info_t *c
gtkui_dispatch_on_main (^{
// Prevent spurious loading of the same image. The load is already scheduled, so we should just wait for it.
char *key = _cache_key_for_track (impl, query->track);
gboolean should_wait = gobj_cache_get_should_wait (impl->cache, key) || (gobj_cache_get (impl->cache, key) != NULL);
gboolean should_wait =
gobj_cache_get_should_wait (impl->cache, key) || (gobj_cache_get (impl->cache, key) != NULL);

if (should_wait) {
// append to the end of loader queue
Expand Down Expand Up @@ -378,7 +379,12 @@ covermanager_free (covermanager_t *impl) {
}

static GdkPixbuf *
_cover_for_track (covermanager_t *impl, int want_default, DB_playItem_t *track, int64_t source_id, covermanager_completion_block_t completion_block) {
_cover_for_track (
covermanager_t *impl,
int want_default,
DB_playItem_t *track,
int64_t source_id,
covermanager_completion_block_t completion_block) {
if (!impl->plugin) {
completion_block (NULL);
return NULL;
Expand Down Expand Up @@ -418,12 +424,20 @@ _cover_for_track (covermanager_t *impl, int want_default, DB_playItem_t *track,
}

GdkPixbuf *
covermanager_cover_for_track_no_default (covermanager_t *impl, DB_playItem_t *track, int64_t source_id, covermanager_completion_block_t completion_block) {
covermanager_cover_for_track_no_default (
covermanager_t *impl,
DB_playItem_t *track,
int64_t source_id,
covermanager_completion_block_t completion_block) {
return _cover_for_track (impl, 0, track, source_id, completion_block);
}

GdkPixbuf *
covermanager_cover_for_track (covermanager_t *impl, DB_playItem_t *track, int64_t source_id, covermanager_completion_block_t completion_block) {
covermanager_cover_for_track (
covermanager_t *impl,
DB_playItem_t *track,
int64_t source_id,
covermanager_completion_block_t completion_block) {
return _cover_for_track (impl, 1, track, source_id, completion_block);
}

Expand Down Expand Up @@ -451,8 +465,13 @@ covermanager_create_scaled_image (covermanager_t *manager, GdkPixbuf *image, Gtk
}

GtkAllocation
covermanager_desired_size_for_image_size (covermanager_t *manager, GtkAllocation image_size, GtkAllocation availableSize) {
double scale = min ((double)availableSize.width / (double)image_size.width, (double)availableSize.height / (double)image_size.height);
covermanager_desired_size_for_image_size (
covermanager_t *manager,
GtkAllocation image_size,
GtkAllocation availableSize) {
double scale = min (
(double)availableSize.width / (double)image_size.width,
(double)availableSize.height / (double)image_size.height);

GtkAllocation a = { 0 };
a.width = image_size.width * scale;
Expand Down
4 changes: 2 additions & 2 deletions plugins/notify/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ pkglib_LTLIBRARIES = notify.la
notify_la_SOURCES = notify.c
notify_la_LDFLAGS = -module -avoid-version

notify_la_LIBADD = $(LDADD) $(NOTIFY_LIBS) $(DISPATCH_LIBS)
notify_la_CFLAGS = -std=c99 $(CFLAGS) $(NOTIFY_CFLAGS) $(DISPATCH_CFLAGS) -I@top_srcdir@/include
notify_la_LIBADD = $(LDADD) $(NOTIFY_LIBS) $(NOTIFY_DEPS_LIBS) $(DISPATCH_LIBS)
notify_la_CFLAGS = -std=c99 $(CFLAGS) $(NOTIFY_CFLAGS) $(NOTIFY_DEPS_CFLAGS) $(DISPATCH_CFLAGS) -I@top_srcdir@/include
endif
156 changes: 153 additions & 3 deletions plugins/notify/notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,90 @@ _cover_loaded_callback (int error, ddb_cover_query_t *query, ddb_cover_info_t *c
Block_release (completion_block);
}

static char *
_buffer_from_file (const char *fname, long *psize) {
char *buffer = NULL;
FILE *fp = fopen (fname, "rb");
if (fp == NULL) {
return NULL;
}
if (fseek (fp, 0, SEEK_END) < 0) {
goto error;
}
long size = ftell (fp);
if (size <= 0 || size > MAX_ALBUM_ART_FILE_SIZE) {
goto error; // we don't really want to load ultra-high-res images
}
rewind (fp);

buffer = malloc (size);
if (buffer == NULL) {
goto error;
}

if (fread (buffer, 1, size, fp) != size) {
goto error;
}

fclose (fp);

*psize = size;
return buffer;

error:
if (fp != NULL) {
fclose (fp);
}
free (buffer);
return NULL;
}

static GdkPixbuf *
_load_image_from_cover (const char *image_filename) {
GdkPixbuf *img = NULL;

long size = 0;
char *buf = _buffer_from_file (cover->image_filename, &size);
if (buf != NULL) {
GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
gdk_pixbuf_loader_write (loader, (const guchar *)buf, size, NULL);
gdk_pixbuf_loader_close (loader, NULL);
img = gdk_pixbuf_loader_get_pixbuf (loader);
free (buf);
}

// if (img) {
// const int max_image_size = impl->image_size;
//
// // downscale
// GtkAllocation size = {
// .width = gdk_pixbuf_get_width (img),
// .height = gdk_pixbuf_get_height (img),
// };
//
// if (size.width > max_image_size || size.height > max_image_size) {
// GtkAllocation new_size = {
// .width = max_image_size,
// .height = max_image_size,
// };
// new_size = covermanager_desired_size_for_image_size (impl, size, new_size);
//
// GdkPixbuf *scaled_img = covermanager_create_scaled_image (impl, img, new_size);
// gobj_unref (img);
// img = scaled_img;
// }
// }
//
// if (!img && want_default) {
// img = impl->default_cover;
// if (img != NULL) {
// gobj_ref (img);
// }
// }

return img;
}

static dbus_uint32_t
show_notification (DB_playItem_t *track, char *image_filename, dbus_uint32_t replaces_id, int force) {
char title[1024];
Expand Down Expand Up @@ -208,11 +292,36 @@ show_notification (DB_playItem_t *track, char *image_filename, dbus_uint32_t rep
// KDE won't re-display notification via reuse,
// so don't show it now and wait for cover callback.
if (!(should_wait_for_cover && should_apply_kde_fix)) {
char *v_iconname = image_filename ?: "deadbeef";
char *v_iconname = ""; // image_filename ?: "deadbeef";
const char *v_summary = title;
const char *v_body = esc_content;
dbus_int32_t v_timeout = -1;

// GdkPixbuf *img = _load_image_from_cover(image_filename);

struct {
dbus_int32_t width = 2;
dbus_int32_t height = 2;
dbus_int32_t stride = 8;
dbus_bool_t has_alpha = 0;
dbus_int32_t bits_per_sample = 32;
dbus_int32_t channels = 4;
uint32_t bytes[4];
} image_data;

image_data.width = 2;
image_data.height = 2;
image_data.stride = 8;
image_data.has_alpha = 0;
image_data.bits_per_sample = 32;
image_data.channels = 4;
image_data.bytes[0] = 0x00000000;
image_data.bytes[1] = 0xffffffff;
image_data.bytes[2] = 0x00000000;
image_data.bytes[3] = 0xffffffff;

DBusMessageIter iter, sub;

dbus_message_append_args (
msg,
DBUS_TYPE_STRING,
Expand All @@ -221,19 +330,60 @@ show_notification (DB_playItem_t *track, char *image_filename, dbus_uint32_t rep
&replaces_id,
DBUS_TYPE_STRING,
&v_iconname,
DBUS_TYPE_STRING,
DBUS_TYPE_VARIANT,
&v_summary,
DBUS_TYPE_STRING,
&v_body,
DBUS_TYPE_INVALID);

DBusMessageIter iter, sub;
// actions
dbus_message_iter_init_append (msg, &iter);
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s", &sub);
dbus_message_iter_close_container (&iter, &sub);

// hints
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &sub);

{

// image data needs to be inserted here, under image-data key
// NOTE: it's not guaranteed that image-data hint is supported by all notification daemons

const char v_image_data[] = "image-data";
dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, &v_image_data);

DBusMessageIter value_sub;

dbus_message_iter_open_container (&sub, DBUS_TYPE_VARIANT, "(iiibiiay)", &value_sub);

{

DBusMessageIter image_sub;
dbus_message_iter_open_container (&value_sub, DBUS_TYPE_STRUCT, NULL, &image_sub);

{

DBusMessageIter data_sub;

dbus_message_iter_append_basic (&image_sub, DBUS_TYPE_INT32, &image_data.width);
dbus_message_iter_append_basic (&image_sub, DBUS_TYPE_INT32, &image_data.height);
dbus_message_iter_append_basic (&image_sub, DBUS_TYPE_INT32, &image_data.stride);
dbus_message_iter_append_basic (&image_sub, DBUS_TYPE_BOOLEAN, &image_data.has_alpha);
dbus_message_iter_append_basic (&image_sub, DBUS_TYPE_INT32, &image_data.bits_per_sample);
dbus_message_iter_append_basic (&image_sub, DBUS_TYPE_INT32, &image_data.channels);

dbus_message_iter_open_container (&image_sub, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &data_sub);
{ dbus_message_iter_append_fixed_array (&data_sub, DBUS_TYPE_BYTE, &image_data.bytes, 16); }

dbus_message_iter_close_container (&image_sub, &data_sub);
}

dbus_message_iter_close_container (&value_sub, &image_sub);
}

dbus_message_iter_close_container (&sub, &value_sub);
}

dbus_message_iter_close_container (&iter, &sub);

dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &v_timeout);
Expand Down
2 changes: 1 addition & 1 deletion premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ project "notify_plugin"
files {
"plugins/notify/notify.c"
}
pkgconfig ("dbus-1")
pkgconfig ("dbus-1", "glib-2.0", "gio-2.0", "gdk-pixbuf-2.0")
buildoptions {"-fblocks"}
links {"dispatch", "BlocksRuntime"}
end
Expand Down

0 comments on commit ed2ffd5

Please sign in to comment.