mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-25 13:55:34 -05:00
[IconLoader] add optional gif loader.
This commit is contained in:
parent
d8a420c952
commit
5994df7f04
5 changed files with 115 additions and 3 deletions
|
@ -168,6 +168,7 @@ rofi_LDADD=\
|
||||||
$(cairo_LIBS)\
|
$(cairo_LIBS)\
|
||||||
$(librsvg_LIBS)\
|
$(librsvg_LIBS)\
|
||||||
$(libjpeg_LIBS)\
|
$(libjpeg_LIBS)\
|
||||||
|
$(libgif_LIBS)\
|
||||||
$(LIBS)
|
$(LIBS)
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
31
configure.ac
31
configure.ac
|
@ -165,7 +165,38 @@ dnl Gets the resource compile tool path.
|
||||||
dnl ---------------------------------------------------------------------
|
dnl ---------------------------------------------------------------------
|
||||||
AM_PATH_GLIB_2_0
|
AM_PATH_GLIB_2_0
|
||||||
|
|
||||||
|
dnl Test for libgif or libungif
|
||||||
|
AC_ARG_WITH([libgif],
|
||||||
|
AS_HELP_STRING([--with-libgif=PREFIX],
|
||||||
|
[Prefix where libgif is installed, or 'no' to disable]),
|
||||||
|
[libgif_prefix="$withval"], [libgif_prefix="${prefix}"])
|
||||||
|
|
||||||
|
if test x$with_libgif != xno && test -z "$libgif_LIBS"; then
|
||||||
|
GIF_CFLAGS="-I${libgif_prefix}/include"
|
||||||
|
GIF_LIBS="-L${libgif_prefix}/lib"
|
||||||
|
save_cflags=$CFLAGS; CFLAGS=$GIF_CFLAGS
|
||||||
|
save_libs=$LIBS; LIBS=$GIF_LIBS
|
||||||
|
AC_CHECK_LIB(gif, DGifOpenFileName,
|
||||||
|
[AC_CHECK_HEADER(gif_lib.h,
|
||||||
|
GIF='gif'; libgif_LIBS='-lgif'; gif_ok=yes,
|
||||||
|
AC_MSG_WARN(*** GIF loader will not be built (giflibrary not found) ***))],
|
||||||
|
AC_MSG_WARN(*** GIF loader will not be built (giflibrary not found) ***))
|
||||||
|
|
||||||
|
AC_CHECK_LIB(ungif, DGifOpenFileName,
|
||||||
|
[AC_CHECK_HEADER(gif_lib.h,
|
||||||
|
GIF='ungif'; libgif_LIBS='-lungif'; gif_ok=yes,
|
||||||
|
AC_MSG_WARN(*** GIF loader will not be built (ungiflibrary not found) ***))],
|
||||||
|
AC_MSG_WARN(*** GIF loader will not be built (ungiflibrary not found) ***))
|
||||||
|
CFLAGS+=$save_cflags
|
||||||
|
LIBS+=$save_libs
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$GIF != x; then
|
||||||
|
AC_SUBST(libgif_LIBS)
|
||||||
|
AC_DEFINE(HAVE_LIBGIF, 1, Define if gif support is available)
|
||||||
|
else
|
||||||
|
gif_ok="no (See http://sourceforge.net/projects/libgif)"
|
||||||
|
fi
|
||||||
dnl ---------------------------------------------------------------------
|
dnl ---------------------------------------------------------------------
|
||||||
dnl Add extra compiler flags
|
dnl Add extra compiler flags
|
||||||
dnl ---------------------------------------------------------------------
|
dnl ---------------------------------------------------------------------
|
||||||
|
|
|
@ -69,6 +69,9 @@ deps += [
|
||||||
dependency('libstartup-notification-1.0'),
|
dependency('libstartup-notification-1.0'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
libgif = c_compiler.find_library('libgif', required: false)
|
||||||
|
deps += [ libgif ]
|
||||||
|
|
||||||
check = dependency('check', version: '>= 0.11.0', required: get_option('check'))
|
check = dependency('check', version: '>= 0.11.0', required: get_option('check'))
|
||||||
|
|
||||||
header_conf = configuration_data()
|
header_conf = configuration_data()
|
||||||
|
@ -88,6 +91,7 @@ header_conf.set('GLIB_VERSION_MIN_REQUIRED', '(G_ENCODE_VERSION(@0@,@1@))'.forma
|
||||||
header_conf.set('GLIB_VERSION_MAX_ALLOWED', '(G_ENCODE_VERSION(@0@,@1@))'.format(glib_min_major, glib_min_minor))
|
header_conf.set('GLIB_VERSION_MAX_ALLOWED', '(G_ENCODE_VERSION(@0@,@1@))'.format(glib_min_major, glib_min_minor))
|
||||||
|
|
||||||
header_conf.set('ENABLE_DRUN', get_option('drun'))
|
header_conf.set('ENABLE_DRUN', get_option('drun'))
|
||||||
|
header_conf.set('HAVE_LIBGIF', libgif.found())
|
||||||
header_conf.set('WINDOW_MODE', get_option('window'))
|
header_conf.set('WINDOW_MODE', get_option('window'))
|
||||||
|
|
||||||
header_conf.set_quoted('MANPAGE_PATH', join_paths(get_option('prefix'), get_option('mandir')))
|
header_conf.set_quoted('MANPAGE_PATH', join_paths(get_option('prefix'), get_option('mandir')))
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include "mode.h"
|
#include "mode.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include "mode-private.h"
|
#include "mode-private.h"
|
||||||
|
@ -341,7 +344,11 @@ static int file_browser_token_match ( const Mode *sw, rofi_int_matcher **tokens,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char * const image_exts[] = {".png",".PNG",".jpg",".JPG",".jpeg",".JPEG",".svg",".SVG"};
|
const char * const image_exts[] = {".png",".PNG",".jpg",".JPG",".jpeg",".JPEG",".svg",".SVG"
|
||||||
|
#ifdef HAVE_LIBGIF
|
||||||
|
,".gif",".GIF"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
static gboolean file_browser_is_image ( const char * const path )
|
static gboolean file_browser_is_image ( const char * const path )
|
||||||
{
|
{
|
||||||
if ( path == NULL ) {
|
if ( path == NULL ) {
|
||||||
|
@ -351,7 +358,7 @@ static gboolean file_browser_is_image ( const char * const path )
|
||||||
if ( suf == NULL ) {
|
if ( suf == NULL ) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
for ( uint32_t i = 0; i < (sizeof (image_exts)/sizeof(char*)); i++ ) {
|
for ( uint32_t i = 0; i < G_N_ELEMENTS(image_exts); i++ ) {
|
||||||
if ( g_strcmp0(suf,image_exts[i]) == 0 ) {
|
if ( g_strcmp0(suf,image_exts[i]) == 0 ) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
/** 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 "rofi-icon-fetcher.h"
|
#include "rofi-icon-fetcher.h"
|
||||||
#include "rofi-types.h"
|
#include "rofi-types.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
@ -44,6 +45,7 @@
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// Context for icon-themes.
|
// Context for icon-themes.
|
||||||
|
@ -187,7 +189,7 @@ static void jpegErrorExit (j_common_ptr cinfo)
|
||||||
|
|
||||||
/* Create the message */
|
/* Create the message */
|
||||||
( *(cinfo->err->format_message) ) (cinfo, jpegLastErrorMsg);
|
( *(cinfo->err->format_message) ) (cinfo, jpegLastErrorMsg);
|
||||||
g_warning ( jpegLastErrorMsg );
|
g_warning ( jpegLastErrorMsg, NULL );
|
||||||
|
|
||||||
/* Jump to the setjmp point */
|
/* Jump to the setjmp point */
|
||||||
longjmp(myerr->setjmp_buffer, 1);
|
longjmp(myerr->setjmp_buffer, 1);
|
||||||
|
@ -224,6 +226,68 @@ static cairo_surface_t* cairo_image_surface_create_from_jpeg ( const char* file
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGIF
|
||||||
|
#include <gif_lib.h>
|
||||||
|
|
||||||
|
static cairo_surface_t* cairo_image_surface_create_from_gif(const char* file )
|
||||||
|
{
|
||||||
|
cairo_surface_t* img = NULL;
|
||||||
|
|
||||||
|
int err;
|
||||||
|
GifFileType* gif = DGifOpenFileName(file, &err);
|
||||||
|
if (!gif) {
|
||||||
|
g_warning( "[%i] %s", err, GifErrorString(err));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decode with high-level API
|
||||||
|
if (DGifSlurp(gif) != GIF_OK) {
|
||||||
|
g_warning("Decoder error: %s", GifErrorString(gif->Error));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (!gif->SavedImages) {
|
||||||
|
g_warning("No saved images");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create canvas
|
||||||
|
img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, gif->SWidth, gif->SHeight);
|
||||||
|
if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) {
|
||||||
|
g_warning("Unable to create surface: %s",
|
||||||
|
cairo_status_to_string(cairo_surface_status(img)));
|
||||||
|
cairo_surface_destroy(img);
|
||||||
|
img = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we don't support animation, show the first frame only
|
||||||
|
const GifImageDesc* frame = &gif->SavedImages->ImageDesc;
|
||||||
|
const GifColorType* colors = gif->SColorMap ? gif->SColorMap->Colors :
|
||||||
|
frame->ColorMap->Colors;
|
||||||
|
uint32_t* base = (uint32_t*)(cairo_image_surface_get_data(img) +
|
||||||
|
frame->Top * cairo_image_surface_get_stride(img));
|
||||||
|
for (int y = 0; y < frame->Height; ++y) {
|
||||||
|
uint32_t* pixel = base + y * gif->SWidth + frame->Left;
|
||||||
|
const uint8_t* raster = &gif->SavedImages->RasterBits[y * gif->SWidth];
|
||||||
|
for (int x = 0; x < frame->Width; ++x) {
|
||||||
|
const uint8_t color = raster[x];
|
||||||
|
if (color != gif->SBackGroundColor) {
|
||||||
|
const GifColorType* rgb = &colors[color];
|
||||||
|
*pixel = 0xff000000 |
|
||||||
|
rgb->Red << 16 | rgb->Green << 8 | rgb->Blue;
|
||||||
|
}
|
||||||
|
++pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_surface_mark_dirty(img);
|
||||||
|
|
||||||
|
done:
|
||||||
|
DGifCloseFile(gif, NULL);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
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." );
|
||||||
|
@ -255,6 +319,11 @@ static void rofi_icon_fetcher_worker ( thread_state *sdata, G_GNUC_UNUSED gpoint
|
||||||
if ( g_str_has_suffix ( icon_path, ".png" ) || g_str_has_suffix ( icon_path, ".PNG" ) ) {
|
if ( g_str_has_suffix ( icon_path, ".png" ) || g_str_has_suffix ( icon_path, ".PNG" ) ) {
|
||||||
icon_surf = cairo_image_surface_create_from_png ( icon_path );
|
icon_surf = cairo_image_surface_create_from_png ( icon_path );
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_LIBGIF
|
||||||
|
else if ( g_str_has_suffix ( icon_path, ".gif" ) || g_str_has_suffix ( icon_path, ".GIF" ) ) {
|
||||||
|
icon_surf = cairo_image_surface_create_from_gif ( icon_path );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if ( g_str_has_suffix ( icon_path, ".jpeg" ) || g_str_has_suffix ( icon_path, ".jpg" ) ||
|
else if ( g_str_has_suffix ( icon_path, ".jpeg" ) || g_str_has_suffix ( icon_path, ".jpg" ) ||
|
||||||
g_str_has_suffix ( icon_path, ".JPEG" ) || g_str_has_suffix ( icon_path, ".JPG" )
|
g_str_has_suffix ( icon_path, ".JPEG" ) || g_str_has_suffix ( icon_path, ".JPG" )
|
||||||
) {
|
) {
|
||||||
|
|
Loading…
Reference in a new issue