[Cleanup] clang-tidy rofi-icon-fetcher.c

This commit is contained in:
Dave Davenport 2021-08-18 00:32:04 +02:00 committed by Dave Davenport
parent c95ce86553
commit 9a62c5bc1a
1 changed files with 322 additions and 324 deletions

View File

@ -28,28 +28,28 @@
/** The log domain of this Helper. */ /** The log domain of this Helper. */
#define G_LOG_DOMAIN "Helpers.IconFetcher" #define G_LOG_DOMAIN "Helpers.IconFetcher"
#include <stdlib.h>
#include <config.h> #include <config.h>
#include <stdlib.h>
#include <xcb/xproto.h>
#include "helper.h"
#include "rofi-icon-fetcher.h" #include "rofi-icon-fetcher.h"
#include "rofi-types.h" #include "rofi-types.h"
#include "helper.h"
#include "settings.h" #include "settings.h"
#include "xcb.h"
#include "keyb.h" #include "keyb.h"
#include "view.h" #include "view.h"
#include "xcb.h"
#include "nkutils-xdg-theme.h"
#include "nkutils-enum.h" #include "nkutils-enum.h"
#include "nkutils-xdg-theme.h"
#include <stdint.h> #include <stdint.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "helper.h" #include "helper.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
typedef struct typedef struct {
{
// Context for icon-themes. // Context for icon-themes.
NkXdgThemeContext *xdg_context; NkXdgThemeContext *xdg_context;
@ -63,14 +63,12 @@ typedef struct
uint32_t last_uid; uint32_t last_uid;
} IconFetcher; } IconFetcher;
typedef struct typedef struct {
{
char *name; char *name;
GList *sizes; GList *sizes;
} IconFetcherNameEntry; } IconFetcherNameEntry;
typedef struct typedef struct {
{
thread_state state; thread_state state;
GCond *cond; GCond *cond;
@ -90,77 +88,76 @@ typedef struct
*/ */
IconFetcher *rofi_icon_fetcher_data = NULL; IconFetcher *rofi_icon_fetcher_data = NULL;
static void rofi_icon_fetch_entry_free ( gpointer data ) static void rofi_icon_fetch_entry_free(gpointer data) {
{ IconFetcherNameEntry *entry = (IconFetcherNameEntry *)data;
IconFetcherNameEntry *entry = (IconFetcherNameEntry *) data;
// Free name/key. // Free name/key.
g_free ( entry->name ); g_free(entry->name);
for ( GList *iter = g_list_first ( entry->sizes ); iter; iter = g_list_next ( iter ) ) { for (GList *iter = g_list_first(entry->sizes); iter;
IconFetcherEntry *sentry = (IconFetcherEntry *) ( iter->data ); iter = g_list_next(iter)) {
IconFetcherEntry *sentry = (IconFetcherEntry *)(iter->data);
cairo_surface_destroy ( sentry->surface ); cairo_surface_destroy(sentry->surface);
g_free ( sentry ); g_free(sentry);
} }
g_list_free ( entry->sizes ); g_list_free(entry->sizes);
g_free ( entry ); g_free(entry);
} }
void rofi_icon_fetcher_init ( void ) void rofi_icon_fetcher_init(void) {
{ g_assert(rofi_icon_fetcher_data == NULL);
g_assert ( rofi_icon_fetcher_data == NULL );
static const gchar * const icon_fallback_themes[] = { static const gchar *const icon_fallback_themes[] = {"Adwaita", "gnome", NULL};
"Adwaita", const char *themes[2] = {config.icon_theme, NULL};
"gnome",
NULL
};
const char *themes[2] = { config.icon_theme, NULL };
rofi_icon_fetcher_data = g_malloc0 ( sizeof ( IconFetcher ) ); rofi_icon_fetcher_data = g_malloc0(sizeof(IconFetcher));
rofi_icon_fetcher_data->xdg_context = nk_xdg_theme_context_new ( icon_fallback_themes, NULL ); rofi_icon_fetcher_data->xdg_context =
nk_xdg_theme_preload_themes_icon ( rofi_icon_fetcher_data->xdg_context, themes ); nk_xdg_theme_context_new(icon_fallback_themes, NULL);
nk_xdg_theme_preload_themes_icon(rofi_icon_fetcher_data->xdg_context, themes);
rofi_icon_fetcher_data->icon_cache_uid = g_hash_table_new ( g_direct_hash, g_direct_equal ); rofi_icon_fetcher_data->icon_cache_uid =
rofi_icon_fetcher_data->icon_cache = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, rofi_icon_fetch_entry_free ); g_hash_table_new(g_direct_hash, g_direct_equal);
rofi_icon_fetcher_data->icon_cache = g_hash_table_new_full(
g_str_hash, g_str_equal, NULL, rofi_icon_fetch_entry_free);
GSList *l = gdk_pixbuf_get_formats (); GSList *l = gdk_pixbuf_get_formats();
for ( GSList *li = l; li != NULL; li = g_slist_next ( li ) ) { for (GSList *li = l; li != NULL; li = g_slist_next(li)) {
gchar **exts = gdk_pixbuf_format_get_extensions ( (GdkPixbufFormat *) li->data ); gchar **exts =
gdk_pixbuf_format_get_extensions((GdkPixbufFormat *)li->data);
for ( unsigned int i = 0; exts && exts[i]; i++ ) { for (unsigned int i = 0; exts && exts[i]; i++) {
rofi_icon_fetcher_data->supported_extensions = g_list_append ( rofi_icon_fetcher_data->supported_extensions, exts[i] ); rofi_icon_fetcher_data->supported_extensions =
g_info ( "Add image extension: %s", exts[i] ); g_list_append(rofi_icon_fetcher_data->supported_extensions, exts[i]);
g_info("Add image extension: %s", exts[i]);
exts[i] = NULL; exts[i] = NULL;
} }
g_free ( exts ); g_free(exts);
} }
g_slist_free ( l ); g_slist_free(l);
} }
static void free_wrapper ( gpointer data, G_GNUC_UNUSED gpointer user_data ) static void free_wrapper(gpointer data, G_GNUC_UNUSED gpointer user_data) {
{ g_free(data);
g_free ( data ) ;
} }
void rofi_icon_fetcher_destroy ( void ) void rofi_icon_fetcher_destroy(void) {
{ if (rofi_icon_fetcher_data == NULL) {
if ( rofi_icon_fetcher_data == NULL ) {
return; return;
} }
nk_xdg_theme_context_free ( rofi_icon_fetcher_data->xdg_context ); nk_xdg_theme_context_free(rofi_icon_fetcher_data->xdg_context);
g_hash_table_unref ( rofi_icon_fetcher_data->icon_cache_uid ); g_hash_table_unref(rofi_icon_fetcher_data->icon_cache_uid);
g_hash_table_unref ( rofi_icon_fetcher_data->icon_cache ); g_hash_table_unref(rofi_icon_fetcher_data->icon_cache);
g_list_foreach ( rofi_icon_fetcher_data->supported_extensions, free_wrapper, NULL ); g_list_foreach(rofi_icon_fetcher_data->supported_extensions, free_wrapper,
g_list_free ( rofi_icon_fetcher_data->supported_extensions ); NULL);
g_free ( rofi_icon_fetcher_data ); g_list_free(rofi_icon_fetcher_data->supported_extensions);
g_free(rofi_icon_fetcher_data);
} }
/* /*
@ -189,38 +186,35 @@ void rofi_icon_fetcher_destroy ( void )
#define ALPHA_BYTE 0 #define ALPHA_BYTE 0
#endif #endif
static inline guchar alpha_mult ( guchar c, guchar a ) static inline guchar alpha_mult(guchar c, guchar a) {
{
guint16 t; guint16 t;
switch ( a ) switch (a) {
{
case 0xff: case 0xff:
return c; return c;
case 0x00: case 0x00:
return 0x00; return 0x00;
default: default:
t = c * a + 0x7f; t = c * a + 0x7f;
return ( ( t >> 8 ) + t ) >> 8; return ((t >> 8) + t) >> 8;
} }
} }
static cairo_surface_t * rofi_icon_fetcher_get_surface_from_pixbuf ( GdkPixbuf static cairo_surface_t *
*pixbuf ) rofi_icon_fetcher_get_surface_from_pixbuf(GdkPixbuf *pixbuf) {
{
gint width, height; gint width, height;
const guchar *pixels; const guchar *pixels;
gint stride; gint stride;
gboolean alpha; gboolean alpha;
if ( pixbuf == NULL ) { if (pixbuf == NULL) {
return NULL; return NULL;
} }
width = gdk_pixbuf_get_width ( pixbuf ); width = gdk_pixbuf_get_width(pixbuf);
height = gdk_pixbuf_get_height ( pixbuf ); height = gdk_pixbuf_get_height(pixbuf);
pixels = gdk_pixbuf_read_pixels ( pixbuf ); pixels = gdk_pixbuf_read_pixels(pixbuf);
stride = gdk_pixbuf_get_rowstride ( pixbuf ); stride = gdk_pixbuf_get_rowstride(pixbuf);
alpha = gdk_pixbuf_get_has_alpha ( pixbuf ); alpha = gdk_pixbuf_get_has_alpha(pixbuf);
cairo_surface_t *surface = NULL; cairo_surface_t *surface = NULL;
@ -234,23 +228,23 @@ static cairo_surface_t * rofi_icon_fetcher_get_surface_from_pixbuf ( GdkPixbuf
o = alpha ? 4 : 3; o = alpha ? 4 : 3;
lo = o * width; lo = o * width;
surface = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, width, height ); surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cpixels = cairo_image_surface_get_data ( surface ); cpixels = cairo_image_surface_get_data(surface);
cstride = cairo_image_surface_get_stride ( surface ); cstride = cairo_image_surface_get_stride(surface);
cairo_surface_flush ( surface ); cairo_surface_flush(surface);
while ( pixels < pixels_end ) { while (pixels < pixels_end) {
line = pixels; line = pixels;
const guchar *line_end = line + lo; const guchar *line_end = line + lo;
guchar *cline = cpixels; guchar *cline = cpixels;
while ( line < line_end ) { while (line < line_end) {
if ( alpha ) { if (alpha) {
a = line[3]; a = line[3];
} }
cline[RED_BYTE] = alpha_mult ( line[0], a ); cline[RED_BYTE] = alpha_mult(line[0], a);
cline[GREEN_BYTE] = alpha_mult ( line[1], a ); cline[GREEN_BYTE] = alpha_mult(line[1], a);
cline[BLUE_BYTE] = alpha_mult ( line[2], a ); cline[BLUE_BYTE] = alpha_mult(line[2], a);
cline[ALPHA_BYTE] = a; cline[ALPHA_BYTE] = a;
line += o; line += o;
@ -260,165 +254,169 @@ static cairo_surface_t * rofi_icon_fetcher_get_surface_from_pixbuf ( GdkPixbuf
pixels += stride; pixels += stride;
cpixels += cstride; cpixels += cstride;
} }
cairo_surface_mark_dirty ( surface ); cairo_surface_mark_dirty(surface);
cairo_surface_flush ( surface ); cairo_surface_flush(surface);
return surface; return surface;
} }
gboolean rofi_icon_fetcher_file_is_image ( const char * const path ) gboolean rofi_icon_fetcher_file_is_image(const char *const path) {
{ if (path == NULL) {
if ( path == NULL ) {
return FALSE; return FALSE;
} }
const char *suf = strrchr ( path, '.' ); const char *suf = strrchr(path, '.');
if ( suf == NULL ) { if (suf == NULL) {
return FALSE; return FALSE;
} }
suf++; suf++;
for ( GList *iter = rofi_icon_fetcher_data->supported_extensions; iter != NULL; iter = g_list_next ( iter ) ) { for (GList *iter = rofi_icon_fetcher_data->supported_extensions; iter != NULL;
if ( g_ascii_strcasecmp ( iter->data, suf ) == 0 ) { iter = g_list_next(iter)) {
if (g_ascii_strcasecmp(iter->data, suf) == 0) {
return TRUE; return TRUE;
} }
} }
return FALSE; return FALSE;
} }
static void rofi_icon_fetcher_worker ( thread_state *sdata, G_GNUC_UNUSED gpointer user_data ) static void rofi_icon_fetcher_worker(thread_state *sdata,
{ G_GNUC_UNUSED gpointer user_data) {
g_debug ( "starting up icon fetching thread." ); g_debug("starting up icon fetching thread.");
// as long as dr->icon is updated atomicly.. (is a pointer write atomic?) // as long as dr->icon is updated atomicly.. (is a pointer write atomic?)
// this should be fine running in another thread. // this should be fine running in another thread.
IconFetcherEntry *sentry = (IconFetcherEntry *) sdata; IconFetcherEntry *sentry = (IconFetcherEntry *)sdata;
const gchar *themes[] = { const gchar *themes[] = {config.icon_theme, NULL};
config.icon_theme,
NULL
};
const gchar *icon_path; const gchar *icon_path;
gchar *icon_path_ = NULL; gchar *icon_path_ = NULL;
if ( g_path_is_absolute ( sentry->entry->name ) ) { if (g_path_is_absolute(sentry->entry->name)) {
icon_path = sentry->entry->name; icon_path = sentry->entry->name;
} } else {
else { icon_path = icon_path_ = nk_xdg_theme_get_icon(
icon_path = icon_path_ = nk_xdg_theme_get_icon ( rofi_icon_fetcher_data->xdg_context, themes, NULL, sentry->entry->name, MIN(sentry->wsize,sentry->hsize), 1, TRUE ); rofi_icon_fetcher_data->xdg_context, themes, NULL, sentry->entry->name,
if ( icon_path_ == NULL ) { MIN(sentry->wsize, sentry->hsize), 1, TRUE);
g_debug ( "failed to get icon %s(%dx%d): n/a", sentry->entry->name, sentry->wsize, sentry->hsize ); if (icon_path_ == NULL) {
g_debug("failed to get icon %s(%dx%d): n/a", sentry->entry->name,
sentry->wsize, sentry->hsize);
const char *ext = g_strrstr(sentry->entry->name, "."); const char *ext = g_strrstr(sentry->entry->name, ".");
if ( ext ) { if (ext) {
printf("%s %s\r\n", sentry->entry->name, ext); printf("%s %s\r\n", sentry->entry->name, ext);
icon_path = helper_get_theme_path ( sentry->entry->name, ext ); icon_path = helper_get_theme_path(sentry->entry->name, ext);
} }
if ( icon_path == NULL ) { if (icon_path == NULL) {
return; return;
} }
} } else {
else{ g_debug("found icon %s(%dx%d): %s", sentry->entry->name, sentry->wsize,
g_debug ( "found icon %s(%dx%d): %s", sentry->entry->name, sentry->wsize, sentry->hsize, icon_path ); sentry->hsize, icon_path);
} }
} }
cairo_surface_t *icon_surf = NULL; cairo_surface_t *icon_surf = NULL;
const char *suf = strrchr ( icon_path, '.' ); const char *suf = strrchr(icon_path, '.');
if ( suf == NULL ) { if (suf == NULL) {
return; return;
} }
GError *error = NULL; GError *error = NULL;
GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_scale ( icon_path, sentry->wsize, sentry->hsize, TRUE, &error ); GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_scale(
if ( error != NULL ) { icon_path, sentry->wsize, sentry->hsize, TRUE, &error);
g_warning ( "Failed to load image: %s", error->message ); if (error != NULL) {
g_error_free ( error ); g_warning("Failed to load image: %s", error->message);
if ( pb ) { g_error_free(error);
g_object_unref ( pb ); if (pb) {
g_object_unref(pb);
} }
} } else {
else { icon_surf = rofi_icon_fetcher_get_surface_from_pixbuf(pb);
icon_surf = rofi_icon_fetcher_get_surface_from_pixbuf ( pb ); g_object_unref(pb);
g_object_unref ( pb );
} }
sentry->surface = icon_surf; sentry->surface = icon_surf;
g_free ( icon_path_ ); g_free(icon_path_);
rofi_view_reload (); rofi_view_reload();
} }
uint32_t rofi_icon_fetcher_query_advanced ( const char *name, const int wsize, const int hsize ) uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize,
{ const int hsize) {
g_debug ( "Query: %s(%dx%d)", name, wsize, hsize ); g_debug("Query: %s(%dx%d)", name, wsize, hsize);
IconFetcherNameEntry *entry = g_hash_table_lookup ( rofi_icon_fetcher_data->icon_cache, name ); IconFetcherNameEntry *entry =
if ( entry == NULL ) { g_hash_table_lookup(rofi_icon_fetcher_data->icon_cache, name);
entry = g_new0 ( IconFetcherNameEntry, 1 ); if (entry == NULL) {
entry->name = g_strdup ( name ); entry = g_new0(IconFetcherNameEntry, 1);
g_hash_table_insert ( rofi_icon_fetcher_data->icon_cache, entry->name, entry ); entry->name = g_strdup(name);
g_hash_table_insert(rofi_icon_fetcher_data->icon_cache, entry->name, entry);
} }
IconFetcherEntry *sentry; IconFetcherEntry *sentry;
for ( GList *iter = g_list_first ( entry->sizes ); iter; iter = g_list_next ( iter ) ) { for (GList *iter = g_list_first(entry->sizes); iter;
iter = g_list_next(iter)) {
sentry = iter->data; sentry = iter->data;
if ( sentry->wsize == wsize && sentry->hsize == hsize ) { if (sentry->wsize == wsize && sentry->hsize == hsize) {
return sentry->uid; return sentry->uid;
} }
} }
// Not found. // Not found.
sentry = g_new0 ( IconFetcherEntry, 1 ); sentry = g_new0(IconFetcherEntry, 1);
sentry->uid = ++( rofi_icon_fetcher_data->last_uid ); sentry->uid = ++(rofi_icon_fetcher_data->last_uid);
sentry->wsize = wsize; sentry->wsize = wsize;
sentry->hsize = hsize; sentry->hsize = hsize;
sentry->entry = entry; sentry->entry = entry;
sentry->surface = NULL; sentry->surface = NULL;
entry->sizes = g_list_prepend ( entry->sizes, sentry ); entry->sizes = g_list_prepend(entry->sizes, sentry);
g_hash_table_insert ( rofi_icon_fetcher_data->icon_cache_uid, GINT_TO_POINTER ( sentry->uid ), sentry ); g_hash_table_insert(rofi_icon_fetcher_data->icon_cache_uid,
GINT_TO_POINTER(sentry->uid), sentry);
// Push into fetching queue. // Push into fetching queue.
sentry->state.callback = rofi_icon_fetcher_worker; sentry->state.callback = rofi_icon_fetcher_worker;
g_thread_pool_push ( tpool, sentry, NULL ); g_thread_pool_push(tpool, sentry, NULL);
return sentry->uid; return sentry->uid;
} }
uint32_t rofi_icon_fetcher_query ( const char *name, const int size ) uint32_t rofi_icon_fetcher_query(const char *name, const int size) {
{ g_debug("Query: %s(%d)", name, size);
g_debug ( "Query: %s(%d)", name, size ); IconFetcherNameEntry *entry =
IconFetcherNameEntry *entry = g_hash_table_lookup ( rofi_icon_fetcher_data->icon_cache, name ); g_hash_table_lookup(rofi_icon_fetcher_data->icon_cache, name);
if ( entry == NULL ) { if (entry == NULL) {
entry = g_new0 ( IconFetcherNameEntry, 1 ); entry = g_new0(IconFetcherNameEntry, 1);
entry->name = g_strdup ( name ); entry->name = g_strdup(name);
g_hash_table_insert ( rofi_icon_fetcher_data->icon_cache, entry->name, entry ); g_hash_table_insert(rofi_icon_fetcher_data->icon_cache, entry->name, entry);
} }
IconFetcherEntry *sentry; IconFetcherEntry *sentry;
for ( GList *iter = g_list_first ( entry->sizes ); iter; iter = g_list_next ( iter ) ) { for (GList *iter = g_list_first(entry->sizes); iter;
iter = g_list_next(iter)) {
sentry = iter->data; sentry = iter->data;
if ( sentry->wsize == size && sentry->hsize == size ) { if (sentry->wsize == size && sentry->hsize == size) {
return sentry->uid; return sentry->uid;
} }
} }
// Not found. // Not found.
sentry = g_new0 ( IconFetcherEntry, 1 ); sentry = g_new0(IconFetcherEntry, 1);
sentry->uid = ++( rofi_icon_fetcher_data->last_uid ); sentry->uid = ++(rofi_icon_fetcher_data->last_uid);
sentry->wsize = size; sentry->wsize = size;
sentry->hsize = size; sentry->hsize = size;
sentry->entry = entry; sentry->entry = entry;
sentry->surface = NULL; sentry->surface = NULL;
entry->sizes = g_list_prepend ( entry->sizes, sentry ); entry->sizes = g_list_prepend(entry->sizes, sentry);
g_hash_table_insert ( rofi_icon_fetcher_data->icon_cache_uid, GINT_TO_POINTER ( sentry->uid ), sentry ); g_hash_table_insert(rofi_icon_fetcher_data->icon_cache_uid,
GINT_TO_POINTER(sentry->uid), sentry);
// Push into fetching queue. // Push into fetching queue.
sentry->state.callback = rofi_icon_fetcher_worker; sentry->state.callback = rofi_icon_fetcher_worker;
g_thread_pool_push ( tpool, sentry, NULL ); g_thread_pool_push(tpool, sentry, NULL);
return sentry->uid; return sentry->uid;
} }
cairo_surface_t * rofi_icon_fetcher_get ( const uint32_t uid ) cairo_surface_t *rofi_icon_fetcher_get(const uint32_t uid) {
{ IconFetcherEntry *sentry = g_hash_table_lookup(
IconFetcherEntry *sentry = g_hash_table_lookup ( rofi_icon_fetcher_data->icon_cache_uid, GINT_TO_POINTER ( uid ) ); rofi_icon_fetcher_data->icon_cache_uid, GINT_TO_POINTER(uid));
if ( sentry ) { if (sentry) {
return sentry->surface; return sentry->surface;
} }
return NULL; return NULL;