29 #define G_LOG_DOMAIN "Helpers.IconFetcher"
33 #include <xcb/xproto.h>
44 #include "nkutils-enum.h"
45 #include "nkutils-xdg-theme.h"
50 #include <gdk-pixbuf/gdk-pixbuf.h>
97 for (GList *iter = g_list_first(entry->
sizes); iter;
98 iter = g_list_next(iter)) {
101 cairo_surface_destroy(sentry->
surface);
105 g_list_free(entry->
sizes);
112 static const gchar *
const icon_fallback_themes[] = {
"Adwaita",
"gnome", NULL};
118 nk_xdg_theme_context_new(icon_fallback_themes, NULL);
122 g_hash_table_new(g_direct_hash, g_direct_equal);
126 GSList *l = gdk_pixbuf_get_formats();
127 for (GSList *li = l; li != NULL; li = g_slist_next(li)) {
129 gdk_pixbuf_format_get_extensions((GdkPixbufFormat *)li->data);
131 for (
unsigned int i = 0; exts && exts[i]; i++) {
134 g_info(
"Add image extension: %s", exts[i]);
143 static void free_wrapper(gpointer data, G_GNUC_UNUSED gpointer user_data) {
169 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
198 return ((t >> 8) + t) >> 8;
202 static cairo_surface_t *
205 const guchar *pixels;
209 if (pixbuf == NULL) {
213 width = gdk_pixbuf_get_width(pixbuf);
214 height = gdk_pixbuf_get_height(pixbuf);
215 pixels = gdk_pixbuf_read_pixels(pixbuf);
216 stride = gdk_pixbuf_get_rowstride(pixbuf);
217 alpha = gdk_pixbuf_get_has_alpha(pixbuf);
219 cairo_surface_t *surface = NULL;
224 const guchar *pixels_end, *line;
227 pixels_end = pixels + height * stride;
231 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
232 cpixels = cairo_image_surface_get_data(surface);
233 cstride = cairo_image_surface_get_stride(surface);
235 cairo_surface_flush(surface);
236 while (pixels < pixels_end) {
238 const guchar *line_end = line + lo;
239 guchar *cline = cpixels;
241 while (line < line_end) {
257 cairo_surface_mark_dirty(surface);
258 cairo_surface_flush(surface);
267 const char *suf = strrchr(path,
'.');
274 iter = g_list_next(iter)) {
275 if (g_ascii_strcasecmp(iter->data, suf) == 0) {
283 G_GNUC_UNUSED gpointer user_data) {
284 g_debug(
"starting up icon fetching thread.");
290 const gchar *icon_path;
291 gchar *icon_path_ = NULL;
293 if (g_path_is_absolute(sentry->
entry->
name)) {
296 icon_path = icon_path_ = nk_xdg_theme_get_icon(
299 if (icon_path_ == NULL) {
300 g_debug(
"failed to get icon %s(%dx%d): n/a", sentry->
entry->
name,
303 const char *ext = g_strrstr(sentry->
entry->
name,
".");
307 if (icon_path == NULL) {
311 g_debug(
"found icon %s(%dx%d): %s", sentry->
entry->
name, sentry->
wsize,
312 sentry->
hsize, icon_path);
315 cairo_surface_t *icon_surf = NULL;
317 const char *suf = strrchr(icon_path,
'.');
322 GError *error = NULL;
323 GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_scale(
324 icon_path, sentry->
wsize, sentry->
hsize, TRUE, &error);
326 g_warning(
"Failed to load image: %s", error->message);
343 g_debug(
"Query: %s(%dx%d)", name, wsize, hsize);
348 entry->
name = g_strdup(name);
352 for (GList *iter = g_list_first(entry->
sizes); iter;
353 iter = g_list_next(iter)) {
355 if (sentry->
wsize == wsize && sentry->
hsize == hsize) {
363 sentry->
wsize = wsize;
364 sentry->
hsize = hsize;
365 sentry->
entry = entry;
368 entry->
sizes = g_list_prepend(entry->
sizes, sentry);
370 GINT_TO_POINTER(sentry->
uid), sentry);
374 g_thread_pool_push(
tpool, sentry, NULL);
379 g_debug(
"Query: %s(%d)", name, size);
384 entry->
name = g_strdup(name);
388 for (GList *iter = g_list_first(entry->
sizes); iter;
389 iter = g_list_next(iter)) {
391 if (sentry->
wsize == size && sentry->
hsize == size) {
399 sentry->
wsize = size;
400 sentry->
hsize = size;
401 sentry->
entry = entry;
404 entry->
sizes = g_list_prepend(entry->
sizes, sentry);
406 GINT_TO_POINTER(sentry->
uid), sentry);
410 g_thread_pool_push(
tpool, sentry, NULL);
char * helper_get_theme_path(const char *file, const char *ext)
uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, const int hsize)
gboolean rofi_icon_fetcher_file_is_image(const char *const path)
void rofi_icon_fetcher_destroy(void)
cairo_surface_t * rofi_icon_fetcher_get(const uint32_t uid)
uint32_t rofi_icon_fetcher_query(const char *name, const int size)
void rofi_icon_fetcher_init(void)
void rofi_view_reload(void)
static void rofi_icon_fetch_entry_free(gpointer data)
static void free_wrapper(gpointer data, G_GNUC_UNUSED gpointer user_data)
IconFetcher * rofi_icon_fetcher_data
static guchar alpha_mult(guchar c, guchar a)
static cairo_surface_t * rofi_icon_fetcher_get_surface_from_pixbuf(GdkPixbuf *pixbuf)
static void rofi_icon_fetcher_worker(thread_state *sdata, G_GNUC_UNUSED gpointer user_data)
IconFetcherNameEntry * entry
cairo_surface_t * surface
NkXdgThemeContext * xdg_context
GHashTable * icon_cache_uid
GList * supported_extensions
void(* callback)(struct _thread_state *t, gpointer data)