2004-10-19 18:45:41 +00:00
|
|
|
/* updateiconcache.c
|
|
|
|
* Copyright (C) 2004 Anders Carlsson <andersca@gnome.org>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
2012-02-27 13:01:10 +00:00
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
2004-10-19 18:45:41 +00:00
|
|
|
*/
|
|
|
|
|
2008-06-22 14:28:52 +00:00
|
|
|
#include "config.h"
|
2005-02-22 21:49:42 +00:00
|
|
|
|
2007-01-02 23:23:32 +00:00
|
|
|
#include <locale.h>
|
2004-10-19 18:45:41 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2008-05-25 23:41:43 +00:00
|
|
|
#include <fcntl.h>
|
2005-04-11 18:59:05 +00:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2004-10-19 18:45:41 +00:00
|
|
|
#include <unistd.h>
|
2005-04-11 18:59:05 +00:00
|
|
|
#endif
|
2004-10-19 18:45:41 +00:00
|
|
|
#include <errno.h>
|
2005-04-11 18:59:05 +00:00
|
|
|
#ifdef _MSC_VER
|
2008-05-29 18:22:38 +00:00
|
|
|
#include <io.h>
|
2005-04-11 18:59:05 +00:00
|
|
|
#include <sys/utime.h>
|
|
|
|
#else
|
2004-10-19 18:45:41 +00:00
|
|
|
#include <utime.h>
|
2005-04-11 18:59:05 +00:00
|
|
|
#endif
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
#include <glib.h>
|
2004-12-12 21:09:13 +00:00
|
|
|
#include <glib/gstdio.h>
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
#include <gdk-pixbuf/gdk-pixdata.h>
|
2006-06-19 22:32:03 +00:00
|
|
|
#include <glib/gi18n.h>
|
2007-05-01 20:00:17 +00:00
|
|
|
#include "gtkiconcachevalidator.h"
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2005-02-01 13:55:08 +00:00
|
|
|
static gboolean force_update = FALSE;
|
2005-08-26 19:05:31 +00:00
|
|
|
static gboolean ignore_theme_index = FALSE;
|
2005-02-01 13:55:08 +00:00
|
|
|
static gboolean quiet = FALSE;
|
updateiconcache: Don't include image data by default anymore
Since large images are in the icon cache, and apps don't tend to use that
many icons anymore, simply don't include image data and instead make apps
load files from disk. Additionally, since they're stored in GdkPixbuf data,
that means that we have to first convert them either to a cairo_surface_t,
which requires converting pixel data to be premulitplied, or an OpenGL
texture, which requires a whole GPU upload anyway.
So, even with the icon cache, the goal of icons through zero-copy, mmap()'d
data from disk just isn't doable with the icon cache format we have. The
icon cache on my disk is nearing 100MB, since we include a bunch of
high-resolution application icons, that I doubt would be used by apps at all.
Removing this inefficient pixel data makes memory usage for all applications
go down, with no speed loss.
The icon cache also, however, has an index of what icons are in each folder,
which prevents a readdir() and allows GTK+ to know what icon is where without
having to do a bunch of stat(); calls. Keeping this data is good for GTK+,
so we should still keep the index.
It doesn't make sense to remove any code for mapping pixel data from the icon
cache. There's a plan in the works to have a symbolic icon cache that does
pixel math on 16x16 icons to prevent slow SVG rendering. 16x16 pixels are
fairly small, and such images are flat colors, which should compress easily,
so the icon cache would be worthwhile here. So let's keep the code around
in preparation for that case.
https://bugzilla.gnome.org/show_bug.cgi?id=721895
2014-01-10 17:14:41 +00:00
|
|
|
static gboolean index_only = TRUE;
|
2007-05-01 20:00:17 +00:00
|
|
|
static gboolean validate = FALSE;
|
2005-11-04 15:43:40 +00:00
|
|
|
static gchar *var_name = "-";
|
2005-02-01 13:55:08 +00:00
|
|
|
|
2007-05-01 20:00:17 +00:00
|
|
|
/* Quite ugly - if we just add the c file to the
|
|
|
|
* list of sources in Makefile.am, libtool complains.
|
|
|
|
*/
|
|
|
|
#include "gtkiconcachevalidator.c"
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
#define CACHE_NAME "icon-theme.cache"
|
|
|
|
|
|
|
|
#define HAS_SUFFIX_XPM (1 << 0)
|
|
|
|
#define HAS_SUFFIX_SVG (1 << 1)
|
|
|
|
#define HAS_SUFFIX_PNG (1 << 2)
|
|
|
|
#define HAS_ICON_FILE (1 << 3)
|
|
|
|
|
|
|
|
#define MAJOR_VERSION 1
|
|
|
|
#define MINOR_VERSION 0
|
|
|
|
#define HASH_OFFSET 12
|
|
|
|
|
|
|
|
#define ALIGN_VALUE(this, boundary) \
|
|
|
|
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
|
|
|
|
|
2007-01-27 04:27:38 +00:00
|
|
|
#ifdef HAVE_FTW_H
|
|
|
|
|
|
|
|
#include <ftw.h>
|
|
|
|
|
2011-10-03 15:25:33 +00:00
|
|
|
static GStatBuf cache_stat;
|
2007-01-27 04:27:38 +00:00
|
|
|
static gboolean cache_up_to_date;
|
|
|
|
|
|
|
|
static int check_dir_mtime (const char *dir,
|
2011-10-03 15:25:33 +00:00
|
|
|
const GStatBuf *sb,
|
2007-01-27 04:27:38 +00:00
|
|
|
int tf)
|
|
|
|
{
|
|
|
|
if (tf != FTW_NS && sb->st_mtime > cache_stat.st_mtime)
|
|
|
|
{
|
|
|
|
cache_up_to_date = FALSE;
|
|
|
|
/* stop tree walk */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-10-02 17:23:29 +00:00
|
|
|
static gboolean
|
|
|
|
is_cache_up_to_date (const gchar *path)
|
|
|
|
{
|
2007-01-27 04:27:38 +00:00
|
|
|
gchar *cache_path;
|
|
|
|
gint retval;
|
|
|
|
|
|
|
|
cache_path = g_build_filename (path, CACHE_NAME, NULL);
|
|
|
|
retval = g_stat (cache_path, &cache_stat);
|
|
|
|
g_free (cache_path);
|
|
|
|
|
|
|
|
if (retval < 0)
|
|
|
|
{
|
|
|
|
/* Cache file not found */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
cache_up_to_date = TRUE;
|
|
|
|
|
|
|
|
ftw (path, check_dir_mtime, 20);
|
|
|
|
|
|
|
|
return cache_up_to_date;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* !HAVE_FTW_H */
|
|
|
|
|
|
|
|
gboolean
|
2004-10-19 18:45:41 +00:00
|
|
|
is_cache_up_to_date (const gchar *path)
|
|
|
|
{
|
2011-10-03 15:25:33 +00:00
|
|
|
GStatBuf path_stat, cache_stat;
|
2004-10-19 18:45:41 +00:00
|
|
|
gchar *cache_path;
|
2007-01-27 04:27:38 +00:00
|
|
|
int retval;
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2004-12-12 21:09:13 +00:00
|
|
|
retval = g_stat (path, &path_stat);
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2007-01-27 04:27:38 +00:00
|
|
|
if (retval < 0)
|
2004-10-19 18:45:41 +00:00
|
|
|
{
|
|
|
|
/* We can't stat the path,
|
|
|
|
* assume we have a updated cache */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
cache_path = g_build_filename (path, CACHE_NAME, NULL);
|
2004-12-12 21:09:13 +00:00
|
|
|
retval = g_stat (cache_path, &cache_stat);
|
2004-10-19 18:45:41 +00:00
|
|
|
g_free (cache_path);
|
|
|
|
|
2005-04-07 18:46:19 +00:00
|
|
|
if (retval < 0)
|
2004-10-19 18:45:41 +00:00
|
|
|
{
|
|
|
|
/* Cache file not found */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check mtime */
|
2005-04-07 12:41:40 +00:00
|
|
|
return cache_stat.st_mtime >= path_stat.st_mtime;
|
2004-10-19 18:45:41 +00:00
|
|
|
}
|
|
|
|
|
2007-01-27 04:27:38 +00:00
|
|
|
#endif /* !HAVE_FTW_H */
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static gboolean
|
2005-08-23 15:18:08 +00:00
|
|
|
has_theme_index (const gchar *path)
|
|
|
|
{
|
|
|
|
gboolean result;
|
|
|
|
gchar *index_path;
|
|
|
|
|
|
|
|
index_path = g_build_filename (path, "index.theme", NULL);
|
|
|
|
|
|
|
|
result = g_file_test (index_path, G_FILE_TEST_IS_REGULAR);
|
|
|
|
|
|
|
|
g_free (index_path);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-15 03:52:34 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GdkPixdata pixdata;
|
2007-02-15 16:56:11 +00:00
|
|
|
gboolean has_pixdata;
|
2005-08-15 03:52:34 +00:00
|
|
|
guint32 offset;
|
2007-02-15 16:56:11 +00:00
|
|
|
guint size;
|
2005-08-15 03:52:34 +00:00
|
|
|
} ImageData;
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int has_embedded_rect;
|
|
|
|
int x0, y0, x1, y1;
|
|
|
|
|
|
|
|
int n_attach_points;
|
|
|
|
int *attach_points;
|
|
|
|
|
|
|
|
int n_display_names;
|
|
|
|
char **display_names;
|
|
|
|
|
|
|
|
guint32 offset;
|
|
|
|
gint size;
|
|
|
|
} IconData;
|
|
|
|
|
2005-08-15 03:52:34 +00:00
|
|
|
static GHashTable *image_data_hash = NULL;
|
2007-02-15 16:56:11 +00:00
|
|
|
static GHashTable *icon_data_hash = NULL;
|
2005-08-15 03:52:34 +00:00
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int flags;
|
|
|
|
int dir_index;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2005-08-15 03:52:34 +00:00
|
|
|
ImageData *image_data;
|
|
|
|
guint pixel_data_size;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
IconData *icon_data;
|
|
|
|
guint icon_data_size;
|
2004-10-19 18:45:41 +00:00
|
|
|
} Image;
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
static gboolean
|
|
|
|
foreach_remove_func (gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
2004-10-21 18:44:08 +00:00
|
|
|
Image *image = (Image *)value;
|
2004-10-19 18:45:41 +00:00
|
|
|
GHashTable *files = user_data;
|
|
|
|
GList *list;
|
2004-10-21 18:44:08 +00:00
|
|
|
gboolean free_key = FALSE;
|
|
|
|
|
|
|
|
if (image->flags == HAS_ICON_FILE)
|
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
/* just a .icon file, throw away */
|
2004-10-21 18:44:08 +00:00
|
|
|
g_free (key);
|
2005-09-14 03:11:05 +00:00
|
|
|
g_free (image);
|
2004-10-21 18:44:08 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
list = g_hash_table_lookup (files, key);
|
|
|
|
if (list)
|
|
|
|
free_key = TRUE;
|
|
|
|
|
|
|
|
list = g_list_prepend (list, value);
|
|
|
|
g_hash_table_insert (files, key, list);
|
|
|
|
|
|
|
|
if (free_key)
|
|
|
|
g_free (key);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
static IconData *
|
|
|
|
load_icon_data (const char *path)
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
{
|
|
|
|
GKeyFile *icon_file;
|
|
|
|
char **split;
|
|
|
|
gsize length;
|
|
|
|
char *str;
|
|
|
|
char *split_point;
|
|
|
|
int i;
|
|
|
|
gint *ivalues;
|
|
|
|
GError *error = NULL;
|
|
|
|
gchar **keys;
|
|
|
|
gsize n_keys;
|
2007-02-15 16:56:11 +00:00
|
|
|
IconData *data;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
|
|
|
icon_file = g_key_file_new ();
|
|
|
|
g_key_file_set_list_separator (icon_file, ',');
|
|
|
|
g_key_file_load_from_file (icon_file, path, G_KEY_FILE_KEEP_TRANSLATIONS, &error);
|
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
g_error_free (error);
|
2007-02-15 16:56:11 +00:00
|
|
|
g_key_file_free (icon_file);
|
|
|
|
|
|
|
|
return NULL;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
data = g_new0 (IconData, 1);
|
|
|
|
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
ivalues = g_key_file_get_integer_list (icon_file,
|
|
|
|
"Icon Data", "EmbeddedTextRectangle",
|
|
|
|
&length, NULL);
|
|
|
|
if (ivalues)
|
|
|
|
{
|
|
|
|
if (length == 4)
|
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
data->has_embedded_rect = TRUE;
|
|
|
|
data->x0 = ivalues[0];
|
|
|
|
data->y0 = ivalues[1];
|
|
|
|
data->x1 = ivalues[2];
|
|
|
|
data->y1 = ivalues[3];
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_free (ivalues);
|
|
|
|
}
|
|
|
|
|
|
|
|
str = g_key_file_get_string (icon_file, "Icon Data", "AttachPoints", NULL);
|
|
|
|
if (str)
|
|
|
|
{
|
|
|
|
split = g_strsplit (str, "|", -1);
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
data->n_attach_points = g_strv_length (split);
|
|
|
|
data->attach_points = g_new (int, 2 * data->n_attach_points);
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
|
|
|
i = 0;
|
2007-02-15 16:56:11 +00:00
|
|
|
while (split[i] != NULL && i < data->n_attach_points)
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
{
|
|
|
|
split_point = strchr (split[i], ',');
|
|
|
|
if (split_point)
|
|
|
|
{
|
|
|
|
*split_point = 0;
|
|
|
|
split_point++;
|
2007-02-15 16:56:11 +00:00
|
|
|
data->attach_points[2 * i] = atoi (split[i]);
|
|
|
|
data->attach_points[2 * i + 1] = atoi (split_point);
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_strfreev (split);
|
|
|
|
g_free (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
keys = g_key_file_get_keys (icon_file, "Icon Data", &n_keys, &error);
|
2007-02-15 16:56:11 +00:00
|
|
|
data->display_names = g_new0 (gchar *, 2 * n_keys + 1);
|
|
|
|
data->n_display_names = 0;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
|
|
|
for (i = 0; i < n_keys; i++)
|
|
|
|
{
|
|
|
|
gchar *lang, *name;
|
|
|
|
|
|
|
|
if (g_str_has_prefix (keys[i], "DisplayName"))
|
|
|
|
{
|
|
|
|
gchar *open, *close = NULL;
|
|
|
|
|
|
|
|
open = strchr (keys[i], '[');
|
|
|
|
|
|
|
|
if (open)
|
|
|
|
close = strchr (open, ']');
|
|
|
|
|
|
|
|
if (open && close)
|
|
|
|
{
|
|
|
|
lang = g_strndup (open + 1, close - open - 1);
|
|
|
|
name = g_key_file_get_locale_string (icon_file,
|
|
|
|
"Icon Data", "DisplayName",
|
|
|
|
lang, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lang = g_strdup ("C");
|
|
|
|
name = g_key_file_get_string (icon_file,
|
|
|
|
"Icon Data", "DisplayName",
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
data->display_names[2 * data->n_display_names] = lang;
|
|
|
|
data->display_names[2 * data->n_display_names + 1] = name;
|
|
|
|
data->n_display_names++;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_strfreev (keys);
|
|
|
|
|
|
|
|
g_key_file_free (icon_file);
|
2007-02-15 16:56:11 +00:00
|
|
|
|
|
|
|
/* -1 means not computed yet, the real value depends
|
|
|
|
* on string pool state, and will be computed
|
|
|
|
* later
|
|
|
|
*/
|
|
|
|
data->size = -1;
|
|
|
|
|
|
|
|
return data;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
|
|
|
|
2005-08-15 03:52:34 +00:00
|
|
|
/*
|
|
|
|
* This function was copied from gtkfilesystemunix.c, it should
|
|
|
|
* probably go to GLib
|
|
|
|
*/
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
static void
|
2005-08-15 03:52:34 +00:00
|
|
|
canonicalize_filename (gchar *filename)
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
{
|
2005-08-15 03:52:34 +00:00
|
|
|
gchar *p, *q;
|
|
|
|
gboolean last_was_slash = FALSE;
|
|
|
|
|
|
|
|
p = filename;
|
|
|
|
q = filename;
|
|
|
|
|
|
|
|
while (*p)
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
{
|
2005-08-15 03:52:34 +00:00
|
|
|
if (*p == G_DIR_SEPARATOR)
|
|
|
|
{
|
|
|
|
if (!last_was_slash)
|
|
|
|
*q++ = G_DIR_SEPARATOR;
|
|
|
|
|
|
|
|
last_was_slash = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (last_was_slash && *p == '.')
|
|
|
|
{
|
|
|
|
if (*(p + 1) == G_DIR_SEPARATOR ||
|
|
|
|
*(p + 1) == '\0')
|
|
|
|
{
|
|
|
|
if (*(p + 1) == '\0')
|
|
|
|
break;
|
|
|
|
|
|
|
|
p += 1;
|
|
|
|
}
|
|
|
|
else if (*(p + 1) == '.' &&
|
|
|
|
(*(p + 2) == G_DIR_SEPARATOR ||
|
|
|
|
*(p + 2) == '\0'))
|
|
|
|
{
|
|
|
|
if (q > filename + 1)
|
|
|
|
{
|
|
|
|
q--;
|
|
|
|
while (q > filename + 1 &&
|
|
|
|
*(q - 1) != G_DIR_SEPARATOR)
|
|
|
|
q--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*(p + 2) == '\0')
|
|
|
|
break;
|
|
|
|
|
|
|
|
p += 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*q++ = *p;
|
|
|
|
last_was_slash = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*q++ = *p;
|
|
|
|
last_was_slash = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
|
|
|
|
q--;
|
|
|
|
|
|
|
|
*q = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
static gchar *
|
|
|
|
follow_links (const gchar *path)
|
|
|
|
{
|
|
|
|
gchar *target;
|
|
|
|
gchar *d, *s;
|
|
|
|
gchar *path2 = NULL;
|
|
|
|
|
|
|
|
path2 = g_strdup (path);
|
|
|
|
while (g_file_test (path2, G_FILE_TEST_IS_SYMLINK))
|
|
|
|
{
|
|
|
|
target = g_file_read_link (path2, NULL);
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2005-08-15 03:52:34 +00:00
|
|
|
if (target)
|
|
|
|
{
|
2005-08-15 14:53:00 +00:00
|
|
|
if (g_path_is_absolute (target))
|
|
|
|
path2 = target;
|
2005-08-15 03:52:34 +00:00
|
|
|
else
|
|
|
|
{
|
2005-08-15 14:53:00 +00:00
|
|
|
d = g_path_get_dirname (path2);
|
|
|
|
s = g_build_filename (d, target, NULL);
|
|
|
|
g_free (d);
|
2005-08-15 03:52:34 +00:00
|
|
|
g_free (target);
|
|
|
|
g_free (path2);
|
|
|
|
path2 = s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp (path, path2) == 0)
|
|
|
|
{
|
|
|
|
g_free (path2);
|
|
|
|
path2 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return path2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
maybe_cache_image_data (Image *image,
|
|
|
|
const gchar *path)
|
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
if (!index_only && !image->image_data &&
|
|
|
|
(g_str_has_suffix (path, ".png") || g_str_has_suffix (path, ".xpm")))
|
2005-08-15 03:52:34 +00:00
|
|
|
{
|
|
|
|
GdkPixbuf *pixbuf;
|
|
|
|
ImageData *idata;
|
|
|
|
gchar *path2;
|
|
|
|
|
|
|
|
idata = g_hash_table_lookup (image_data_hash, path);
|
|
|
|
path2 = follow_links (path);
|
|
|
|
|
|
|
|
if (path2)
|
|
|
|
{
|
|
|
|
ImageData *idata2;
|
|
|
|
|
|
|
|
canonicalize_filename (path2);
|
|
|
|
|
|
|
|
idata2 = g_hash_table_lookup (image_data_hash, path2);
|
|
|
|
|
|
|
|
if (idata && idata2 && idata != idata2)
|
2011-04-29 14:24:21 +00:00
|
|
|
g_error ("different idatas found for symlinked '%s' and '%s'\n",
|
2005-08-15 03:52:34 +00:00
|
|
|
path, path2);
|
|
|
|
|
|
|
|
if (idata && !idata2)
|
|
|
|
g_hash_table_insert (image_data_hash, g_strdup (path2), idata);
|
|
|
|
|
|
|
|
if (!idata && idata2)
|
|
|
|
{
|
|
|
|
g_hash_table_insert (image_data_hash, g_strdup (path), idata2);
|
|
|
|
idata = idata2;
|
|
|
|
}
|
|
|
|
}
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2005-08-15 03:52:34 +00:00
|
|
|
if (!idata)
|
|
|
|
{
|
|
|
|
idata = g_new0 (ImageData, 1);
|
|
|
|
g_hash_table_insert (image_data_hash, g_strdup (path), idata);
|
|
|
|
if (path2)
|
|
|
|
g_hash_table_insert (image_data_hash, g_strdup (path2), idata);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!idata->has_pixdata)
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
{
|
2005-08-15 03:52:34 +00:00
|
|
|
pixbuf = gdk_pixbuf_new_from_file (path, NULL);
|
|
|
|
|
|
|
|
if (pixbuf)
|
|
|
|
{
|
|
|
|
gdk_pixdata_from_pixbuf (&idata->pixdata, pixbuf, FALSE);
|
2007-02-15 16:56:11 +00:00
|
|
|
idata->size = idata->pixdata.length + 8;
|
2005-08-15 03:52:34 +00:00
|
|
|
idata->has_pixdata = TRUE;
|
|
|
|
}
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
2005-08-15 03:52:34 +00:00
|
|
|
|
|
|
|
image->image_data = idata;
|
|
|
|
|
2007-03-09 21:57:37 +00:00
|
|
|
g_free (path2);
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
static void
|
|
|
|
maybe_cache_icon_data (Image *image,
|
|
|
|
const gchar *path)
|
|
|
|
{
|
|
|
|
if (g_str_has_suffix (path, ".icon"))
|
|
|
|
{
|
|
|
|
IconData *idata = NULL;
|
|
|
|
gchar *path2 = NULL;
|
|
|
|
|
|
|
|
idata = g_hash_table_lookup (icon_data_hash, path);
|
|
|
|
path2 = follow_links (path);
|
|
|
|
|
|
|
|
if (path2)
|
|
|
|
{
|
|
|
|
IconData *idata2;
|
|
|
|
|
|
|
|
canonicalize_filename (path2);
|
|
|
|
|
|
|
|
idata2 = g_hash_table_lookup (icon_data_hash, path2);
|
|
|
|
|
|
|
|
if (idata && idata2 && idata != idata2)
|
2011-04-29 14:24:21 +00:00
|
|
|
g_error ("different idatas found for symlinked '%s' and '%s'\n",
|
2007-02-15 16:56:11 +00:00
|
|
|
path, path2);
|
|
|
|
|
|
|
|
if (idata && !idata2)
|
|
|
|
g_hash_table_insert (icon_data_hash, g_strdup (path2), idata);
|
|
|
|
|
|
|
|
if (!idata && idata2)
|
|
|
|
{
|
|
|
|
g_hash_table_insert (icon_data_hash, g_strdup (path), idata2);
|
|
|
|
idata = idata2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!idata)
|
|
|
|
{
|
|
|
|
idata = load_icon_data (path);
|
|
|
|
g_hash_table_insert (icon_data_hash, g_strdup (path), idata);
|
|
|
|
if (path2)
|
|
|
|
g_hash_table_insert (icon_data_hash, g_strdup (path2), idata);
|
|
|
|
}
|
|
|
|
|
|
|
|
image->icon_data = idata;
|
|
|
|
|
2007-03-09 21:57:37 +00:00
|
|
|
g_free (path2);
|
2007-02-15 16:56:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-20 23:53:58 +00:00
|
|
|
/*
|
2014-02-07 19:03:49 +00:00
|
|
|
* Finds all dir separators and replaces them with “/”.
|
2013-02-21 18:25:21 +00:00
|
|
|
* This makes sure that only /-separated paths are written in cache files,
|
|
|
|
* maintaining compatibility with theme index files that use slashes as
|
|
|
|
* directory separators on all platforms.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
replace_backslashes_with_slashes (gchar *path)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
if (path == NULL)
|
|
|
|
return;
|
|
|
|
for (i = 0; path[i]; i++)
|
|
|
|
if (G_IS_DIR_SEPARATOR (path[i]))
|
|
|
|
path[i] = '/';
|
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static GList *
|
2004-10-19 18:45:41 +00:00
|
|
|
scan_directory (const gchar *base_path,
|
|
|
|
const gchar *subdir,
|
|
|
|
GHashTable *files,
|
|
|
|
GList *directories,
|
|
|
|
gint depth)
|
|
|
|
{
|
|
|
|
GHashTable *dir_hash;
|
|
|
|
GDir *dir;
|
|
|
|
const gchar *name;
|
|
|
|
gchar *dir_path;
|
|
|
|
gboolean dir_added = FALSE;
|
|
|
|
guint dir_index = 0xffff;
|
|
|
|
|
2013-02-21 18:25:21 +00:00
|
|
|
dir_path = g_build_path ("/", base_path, subdir, NULL);
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
/* FIXME: Use the gerror */
|
|
|
|
dir = g_dir_open (dir_path, 0, NULL);
|
|
|
|
|
|
|
|
if (!dir)
|
|
|
|
return directories;
|
|
|
|
|
|
|
|
dir_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
|
|
|
|
while ((name = g_dir_read_name (dir)))
|
|
|
|
{
|
|
|
|
gchar *path;
|
|
|
|
gboolean retval;
|
|
|
|
int flags = 0;
|
|
|
|
Image *image;
|
|
|
|
gchar *basename, *dot;
|
|
|
|
|
|
|
|
path = g_build_filename (dir_path, name, NULL);
|
2013-02-21 18:25:21 +00:00
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
retval = g_file_test (path, G_FILE_TEST_IS_DIR);
|
|
|
|
if (retval)
|
|
|
|
{
|
|
|
|
gchar *subsubdir;
|
|
|
|
|
|
|
|
if (subdir)
|
2013-02-21 18:25:21 +00:00
|
|
|
subsubdir = g_build_path ("/", subdir, name, NULL);
|
2004-10-19 18:45:41 +00:00
|
|
|
else
|
|
|
|
subsubdir = g_strdup (name);
|
|
|
|
directories = scan_directory (base_path, subsubdir, files,
|
|
|
|
directories, depth + 1);
|
|
|
|
g_free (subsubdir);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-02-05 22:20:12 +00:00
|
|
|
/* ignore images in the toplevel directory */
|
|
|
|
if (subdir == NULL)
|
|
|
|
continue;
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
retval = g_file_test (path, G_FILE_TEST_IS_REGULAR);
|
|
|
|
if (retval)
|
|
|
|
{
|
|
|
|
if (g_str_has_suffix (name, ".png"))
|
|
|
|
flags |= HAS_SUFFIX_PNG;
|
|
|
|
else if (g_str_has_suffix (name, ".svg"))
|
|
|
|
flags |= HAS_SUFFIX_SVG;
|
|
|
|
else if (g_str_has_suffix (name, ".xpm"))
|
|
|
|
flags |= HAS_SUFFIX_XPM;
|
|
|
|
else if (g_str_has_suffix (name, ".icon"))
|
|
|
|
flags |= HAS_ICON_FILE;
|
|
|
|
|
|
|
|
if (flags == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
basename = g_strdup (name);
|
|
|
|
dot = strrchr (basename, '.');
|
|
|
|
*dot = '\0';
|
|
|
|
|
|
|
|
image = g_hash_table_lookup (dir_hash, basename);
|
2007-02-15 16:56:11 +00:00
|
|
|
if (!image)
|
2004-10-19 18:45:41 +00:00
|
|
|
{
|
|
|
|
if (!dir_added)
|
|
|
|
{
|
|
|
|
dir_added = TRUE;
|
|
|
|
if (subdir)
|
|
|
|
{
|
|
|
|
dir_index = g_list_length (directories);
|
|
|
|
directories = g_list_append (directories, g_strdup (subdir));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
dir_index = 0xffff;
|
|
|
|
}
|
|
|
|
|
|
|
|
image = g_new0 (Image, 1);
|
|
|
|
image->dir_index = dir_index;
|
|
|
|
g_hash_table_insert (dir_hash, g_strdup (basename), image);
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
image->flags |= flags;
|
|
|
|
|
|
|
|
maybe_cache_image_data (image, path);
|
|
|
|
maybe_cache_icon_data (image, path);
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
g_free (basename);
|
|
|
|
}
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
|
|
|
g_free (path);
|
2004-10-19 18:45:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_dir_close (dir);
|
|
|
|
|
|
|
|
/* Move dir into the big file hash */
|
|
|
|
g_hash_table_foreach_remove (dir_hash, foreach_remove_func, files);
|
|
|
|
|
|
|
|
g_hash_table_destroy (dir_hash);
|
|
|
|
|
|
|
|
return directories;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct _HashNode HashNode;
|
|
|
|
|
|
|
|
struct _HashNode
|
|
|
|
{
|
|
|
|
HashNode *next;
|
|
|
|
gchar *name;
|
|
|
|
GList *image_list;
|
2007-02-15 16:56:11 +00:00
|
|
|
gint offset;
|
2004-10-19 18:45:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static guint
|
|
|
|
icon_name_hash (gconstpointer key)
|
|
|
|
{
|
2005-04-07 18:46:19 +00:00
|
|
|
const signed char *p = key;
|
|
|
|
guint32 h = *p;
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
if (h)
|
|
|
|
for (p += 1; *p != '\0'; p++)
|
|
|
|
h = (h << 5) - h + *p;
|
|
|
|
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
gint size;
|
|
|
|
HashNode **nodes;
|
|
|
|
} HashContext;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
convert_to_hash (gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
|
|
|
HashContext *context = user_data;
|
|
|
|
guint hash;
|
|
|
|
HashNode *node;
|
|
|
|
|
|
|
|
hash = icon_name_hash (key) % context->size;
|
|
|
|
|
|
|
|
node = g_new0 (HashNode, 1);
|
|
|
|
node->next = NULL;
|
|
|
|
node->name = key;
|
|
|
|
node->image_list = value;
|
|
|
|
|
|
|
|
if (context->nodes[hash] != NULL)
|
|
|
|
node->next = context->nodes[hash];
|
|
|
|
|
|
|
|
context->nodes[hash] = node;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
static GHashTable *string_pool = NULL;
|
|
|
|
|
|
|
|
static int
|
|
|
|
find_string (const gchar *n)
|
|
|
|
{
|
|
|
|
return GPOINTER_TO_INT (g_hash_table_lookup (string_pool, n));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
add_string (const gchar *n, int offset)
|
|
|
|
{
|
2008-01-30 15:06:06 +00:00
|
|
|
g_hash_table_insert (string_pool, (gpointer) n, GINT_TO_POINTER (offset));
|
2007-02-15 16:56:11 +00:00
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static gboolean
|
2004-10-19 18:45:41 +00:00
|
|
|
write_string (FILE *cache, const gchar *n)
|
|
|
|
{
|
|
|
|
gchar *s;
|
|
|
|
int i, l;
|
|
|
|
|
|
|
|
l = ALIGN_VALUE (strlen (n) + 1, 4);
|
|
|
|
|
|
|
|
s = g_malloc0 (l);
|
|
|
|
strcpy (s, n);
|
|
|
|
|
|
|
|
i = fwrite (s, l, 1, cache);
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
g_free (s);
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
return i == 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static gboolean
|
2004-10-19 18:45:41 +00:00
|
|
|
write_card16 (FILE *cache, guint16 n)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2005-04-07 19:10:11 +00:00
|
|
|
n = GUINT16_TO_BE (n);
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2005-04-07 19:10:11 +00:00
|
|
|
i = fwrite ((char *)&n, 2, 1, cache);
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
return i == 1;
|
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static gboolean
|
2004-10-19 18:45:41 +00:00
|
|
|
write_card32 (FILE *cache, guint32 n)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2005-04-07 19:10:11 +00:00
|
|
|
n = GUINT32_TO_BE (n);
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2005-04-07 19:10:11 +00:00
|
|
|
i = fwrite ((char *)&n, 4, 1, cache);
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
return i == 1;
|
|
|
|
}
|
|
|
|
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static gboolean
|
2007-02-15 16:56:11 +00:00
|
|
|
write_image_data (FILE *cache, ImageData *image_data, int offset)
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
{
|
|
|
|
guint8 *s;
|
2005-08-15 03:52:34 +00:00
|
|
|
guint len;
|
|
|
|
gint i;
|
2007-02-15 16:56:11 +00:00
|
|
|
GdkPixdata *pixdata = &image_data->pixdata;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
|
|
|
/* Type 0 is GdkPixdata */
|
|
|
|
if (!write_card32 (cache, 0))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
s = gdk_pixdata_serialize (pixdata, &len);
|
|
|
|
|
|
|
|
if (!write_card32 (cache, len))
|
|
|
|
{
|
|
|
|
g_free (s);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = fwrite (s, len, 1, cache);
|
|
|
|
|
|
|
|
g_free (s);
|
|
|
|
|
|
|
|
return i == 1;
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
static gboolean
|
|
|
|
write_icon_data (FILE *cache, IconData *icon_data, int offset)
|
|
|
|
{
|
|
|
|
int ofs = offset + 12;
|
|
|
|
int j;
|
|
|
|
int tmp, tmp2;
|
|
|
|
|
|
|
|
if (icon_data->has_embedded_rect)
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, ofs))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
ofs += 8;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, 0))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (icon_data->n_attach_points > 0)
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, ofs))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
ofs += 4 + 4 * icon_data->n_attach_points;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, 0))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (icon_data->n_display_names > 0)
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, ofs))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, 0))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (icon_data->has_embedded_rect)
|
|
|
|
{
|
|
|
|
if (!write_card16 (cache, icon_data->x0) ||
|
|
|
|
!write_card16 (cache, icon_data->y0) ||
|
|
|
|
!write_card16 (cache, icon_data->x1) ||
|
|
|
|
!write_card16 (cache, icon_data->y1))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (icon_data->n_attach_points > 0)
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, icon_data->n_attach_points))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (j = 0; j < 2 * icon_data->n_attach_points; j++)
|
|
|
|
{
|
|
|
|
if (!write_card16 (cache, icon_data->attach_points[j]))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (icon_data->n_display_names > 0)
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, icon_data->n_display_names))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
ofs += 4 + 8 * icon_data->n_display_names;
|
|
|
|
|
|
|
|
tmp = ofs;
|
|
|
|
for (j = 0; j < 2 * icon_data->n_display_names; j++)
|
|
|
|
{
|
|
|
|
tmp2 = find_string (icon_data->display_names[j]);
|
|
|
|
if (tmp2 == 0 || tmp2 == -1)
|
|
|
|
{
|
|
|
|
tmp2 = tmp;
|
|
|
|
tmp += ALIGN_VALUE (strlen (icon_data->display_names[j]) + 1, 4);
|
|
|
|
/* We're playing a little game with negative
|
|
|
|
* offsets here to handle duplicate strings in
|
|
|
|
* the array.
|
|
|
|
*/
|
|
|
|
add_string (icon_data->display_names[j], -tmp2);
|
|
|
|
}
|
|
|
|
else if (tmp2 < 0)
|
|
|
|
{
|
|
|
|
tmp2 = -tmp2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!write_card32 (cache, tmp2))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
g_assert (ofs == ftell (cache));
|
|
|
|
for (j = 0; j < 2 * icon_data->n_display_names; j++)
|
|
|
|
{
|
|
|
|
tmp2 = find_string (icon_data->display_names[j]);
|
|
|
|
g_assert (tmp2 != 0 && tmp2 != -1);
|
|
|
|
if (tmp2 < 0)
|
|
|
|
{
|
|
|
|
tmp2 = -tmp2;
|
|
|
|
g_assert (tmp2 == ftell (cache));
|
|
|
|
add_string (icon_data->display_names[j], tmp2);
|
|
|
|
if (!write_string (cache, icon_data->display_names[j]))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
static gboolean
|
|
|
|
write_header (FILE *cache, guint32 dir_list_offset)
|
|
|
|
{
|
|
|
|
return (write_card16 (cache, MAJOR_VERSION) &&
|
|
|
|
write_card16 (cache, MINOR_VERSION) &&
|
|
|
|
write_card32 (cache, HASH_OFFSET) &&
|
|
|
|
write_card32 (cache, dir_list_offset));
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
static gint
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
get_image_meta_data_size (Image *image)
|
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
/* The complication with storing the size in both
|
|
|
|
* IconData and Image is necessary since we attribute
|
|
|
|
* the size of the IconData only to the first Image
|
|
|
|
* using it (at which time it is written out in the
|
|
|
|
* cache). Later Images just refer to the written out
|
|
|
|
* IconData via the offset.
|
|
|
|
*/
|
|
|
|
if (image->icon_data_size == 0)
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
if (image->icon_data && image->icon_data->size < 0)
|
|
|
|
{
|
|
|
|
IconData *data = image->icon_data;
|
|
|
|
|
|
|
|
data->size = 0;
|
|
|
|
|
|
|
|
if (data->has_embedded_rect ||
|
2007-09-07 19:57:33 +00:00
|
|
|
data->n_attach_points > 0 ||
|
2007-02-15 16:56:11 +00:00
|
|
|
data->n_display_names > 0)
|
|
|
|
data->size += 12;
|
|
|
|
|
|
|
|
if (data->has_embedded_rect)
|
|
|
|
data->size += 8;
|
|
|
|
|
|
|
|
if (data->n_attach_points > 0)
|
|
|
|
data->size += 4 + data->n_attach_points * 4;
|
|
|
|
|
|
|
|
if (data->n_display_names > 0)
|
|
|
|
{
|
|
|
|
data->size += 4 + 8 * data->n_display_names;
|
|
|
|
|
|
|
|
for (i = 0; data->display_names[i]; i++)
|
|
|
|
{
|
|
|
|
int poolv;
|
|
|
|
if ((poolv = find_string (data->display_names[i])) == 0)
|
|
|
|
{
|
|
|
|
data->size += ALIGN_VALUE (strlen (data->display_names[i]) + 1, 4);
|
|
|
|
/* Adding the string to the pool with -1
|
|
|
|
* to indicate that it hasn't been written out
|
|
|
|
* to the cache yet. We still need it in the
|
|
|
|
* pool in case the same string occurs twice
|
|
|
|
* during a get_single_node_size() calculation.
|
|
|
|
*/
|
|
|
|
add_string (data->display_names[i], -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
image->icon_data_size = data->size;
|
|
|
|
data->size = 0;
|
|
|
|
}
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
g_assert (image->icon_data_size % 4 == 0);
|
|
|
|
|
|
|
|
return image->icon_data_size;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
static gint
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
get_image_pixel_data_size (Image *image)
|
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
/* The complication with storing the size in both
|
|
|
|
* ImageData and Image is necessary since we attribute
|
|
|
|
* the size of the ImageData only to the first Image
|
|
|
|
* using it (at which time it is written out in the
|
|
|
|
* cache). Later Images just refer to the written out
|
|
|
|
* ImageData via the offset.
|
|
|
|
*/
|
2005-08-15 03:52:34 +00:00
|
|
|
if (image->pixel_data_size == 0)
|
|
|
|
{
|
|
|
|
if (image->image_data &&
|
|
|
|
image->image_data->has_pixdata)
|
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
image->pixel_data_size = image->image_data->size;
|
|
|
|
image->image_data->size = 0;
|
2005-08-15 03:52:34 +00:00
|
|
|
}
|
|
|
|
}
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
g_assert (image->pixel_data_size % 4 == 0);
|
|
|
|
|
2005-08-15 03:52:34 +00:00
|
|
|
return image->pixel_data_size;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
}
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
static gint
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
get_image_data_size (Image *image)
|
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
gint len;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
|
|
|
len = 0;
|
|
|
|
|
|
|
|
len += get_image_pixel_data_size (image);
|
|
|
|
len += get_image_meta_data_size (image);
|
2007-02-15 16:56:11 +00:00
|
|
|
|
|
|
|
/* Even if len is zero, we need to reserve space to
|
|
|
|
* write the ImageData, unless this is an .svg without
|
|
|
|
* .icon, in which case both image_data and icon_data
|
|
|
|
* are NULL.
|
|
|
|
*/
|
|
|
|
if (len > 0 || image->image_data || image->icon_data)
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
len += 8;
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
static void
|
|
|
|
get_single_node_size (HashNode *node, int *node_size, int *image_data_size)
|
2004-10-19 18:45:41 +00:00
|
|
|
{
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
GList *list;
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
/* Node pointers */
|
2007-02-15 16:56:11 +00:00
|
|
|
*node_size = 12;
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
/* Name */
|
2007-02-15 16:56:11 +00:00
|
|
|
if (find_string (node->name) == 0)
|
|
|
|
{
|
|
|
|
*node_size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
add_string (node->name, -1);
|
|
|
|
}
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
/* Image list */
|
2007-02-15 16:56:11 +00:00
|
|
|
*node_size += 4 + g_list_length (node->image_list) * 8;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
|
|
|
/* Image data */
|
2007-02-15 16:56:11 +00:00
|
|
|
*image_data_size = 0;
|
|
|
|
for (list = node->image_list; list; list = list->next)
|
2004-10-19 18:45:41 +00:00
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
Image *image = list->data;
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
*image_data_size += get_image_data_size (image);
|
2004-10-19 18:45:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static gboolean
|
2004-10-19 18:45:41 +00:00
|
|
|
write_bucket (FILE *cache, HashNode *node, int *offset)
|
|
|
|
{
|
|
|
|
while (node != NULL)
|
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
int node_size, image_data_size;
|
|
|
|
int next_offset, image_data_offset;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
int data_offset;
|
2007-02-15 16:56:11 +00:00
|
|
|
int name_offset;
|
|
|
|
int name_size;
|
|
|
|
int image_list_offset;
|
|
|
|
int i, len;
|
2004-10-19 18:45:41 +00:00
|
|
|
GList *list;
|
2007-02-15 16:56:11 +00:00
|
|
|
|
|
|
|
g_assert (*offset == ftell (cache));
|
|
|
|
|
|
|
|
node->offset = *offset;
|
2011-01-24 02:50:39 +00:00
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
get_single_node_size (node, &node_size, &image_data_size);
|
|
|
|
g_assert (node_size % 4 == 0);
|
|
|
|
g_assert (image_data_size % 4 == 0);
|
|
|
|
image_data_offset = *offset + node_size;
|
|
|
|
next_offset = *offset + node_size + image_data_size;
|
2004-10-19 18:45:41 +00:00
|
|
|
/* Chain offset */
|
|
|
|
if (node->next != NULL)
|
2011-01-24 02:50:39 +00:00
|
|
|
{
|
|
|
|
if (!write_card32 (cache, next_offset))
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-10-19 18:45:41 +00:00
|
|
|
else
|
2011-01-24 02:50:39 +00:00
|
|
|
{
|
|
|
|
if (!write_card32 (cache, 0xffffffff))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
name_size = 0;
|
|
|
|
name_offset = find_string (node->name);
|
|
|
|
if (name_offset <= 0)
|
|
|
|
{
|
|
|
|
name_offset = *offset + 12;
|
|
|
|
name_size = ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
add_string (node->name, name_offset);
|
|
|
|
}
|
|
|
|
if (!write_card32 (cache, name_offset))
|
2011-01-24 02:50:39 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
image_list_offset = *offset + 12 + name_size;
|
|
|
|
if (!write_card32 (cache, image_list_offset))
|
2011-01-24 02:50:39 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
/* Icon name */
|
2007-02-15 16:56:11 +00:00
|
|
|
if (name_size > 0)
|
|
|
|
{
|
|
|
|
if (!write_string (cache, node->name))
|
2011-01-24 02:50:39 +00:00
|
|
|
return FALSE;
|
2007-02-15 16:56:11 +00:00
|
|
|
}
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
/* Image list */
|
|
|
|
len = g_list_length (node->image_list);
|
|
|
|
if (!write_card32 (cache, len))
|
2011-01-24 02:50:39 +00:00
|
|
|
return FALSE;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
list = node->image_list;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
data_offset = image_data_offset;
|
2004-10-19 18:45:41 +00:00
|
|
|
for (i = 0; i < len; i++)
|
2011-01-24 02:50:39 +00:00
|
|
|
{
|
|
|
|
Image *image = list->data;
|
|
|
|
int image_data_size = get_image_data_size (image);
|
2005-08-15 03:52:34 +00:00
|
|
|
|
2011-01-24 02:50:39 +00:00
|
|
|
/* Directory index */
|
|
|
|
if (!write_card16 (cache, image->dir_index))
|
|
|
|
return FALSE;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2011-01-24 02:50:39 +00:00
|
|
|
/* Flags */
|
|
|
|
if (!write_card16 (cache, image->flags))
|
|
|
|
return FALSE;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2011-01-24 02:50:39 +00:00
|
|
|
/* Image data offset */
|
|
|
|
if (image_data_size > 0)
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, data_offset))
|
|
|
|
return FALSE;
|
|
|
|
data_offset += image_data_size;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, 0))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
list = list->next;
|
|
|
|
}
|
2004-10-19 18:45:41 +00:00
|
|
|
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
/* Now write the image data */
|
|
|
|
list = node->image_list;
|
|
|
|
for (i = 0; i < len; i++, list = list->next)
|
2011-01-24 02:50:39 +00:00
|
|
|
{
|
|
|
|
Image *image = list->data;
|
|
|
|
int pixel_data_size = get_image_pixel_data_size (image);
|
|
|
|
int meta_data_size = get_image_meta_data_size (image);
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2011-01-24 02:50:39 +00:00
|
|
|
if (get_image_data_size (image) == 0)
|
|
|
|
continue;
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2011-01-24 02:50:39 +00:00
|
|
|
/* Pixel data */
|
|
|
|
if (pixel_data_size > 0)
|
|
|
|
{
|
|
|
|
image->image_data->offset = image_data_offset + 8;
|
|
|
|
if (!write_card32 (cache, image->image_data->offset))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, (guint32) (image->image_data ? image->image_data->offset : 0)))
|
|
|
|
return FALSE;
|
|
|
|
}
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2011-01-24 02:50:39 +00:00
|
|
|
if (meta_data_size > 0)
|
|
|
|
{
|
|
|
|
image->icon_data->offset = image_data_offset + pixel_data_size + 8;
|
|
|
|
if (!write_card32 (cache, image->icon_data->offset))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!write_card32 (cache, image->icon_data ? image->icon_data->offset : 0))
|
|
|
|
return FALSE;
|
|
|
|
}
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2011-01-24 02:50:39 +00:00
|
|
|
if (pixel_data_size > 0)
|
|
|
|
{
|
|
|
|
if (!write_image_data (cache, image->image_data, image->image_data->offset))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (meta_data_size > 0)
|
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
if (!write_icon_data (cache, image->icon_data, image->icon_data->offset))
|
|
|
|
return FALSE;
|
|
|
|
}
|
Update spec.
2005-03-15 Anders Carlsson <andersca@imendio.com>
* docs/iconcache.txt:
Update spec.
* gtk/gtkiconcache.c: (find_image_offset),
(_gtk_icon_cache_get_icon_flags), (_gtk_icon_cache_add_icons),
(_gtk_icon_cache_get_icon), (_gtk_icon_cache_get_icon_data):
* gtk/gtkiconcache.h:
Update to be able to fetch pixbuf data and icon metadata.
* gtk/gtkicontheme.c: (theme_lookup_icon), (gtk_icon_info_free),
(icon_info_ensure_scale_and_pixbuf):
Use new cache functions.
* gtk/updateiconcache.c: (foreach_remove_func), (load_icon_data),
(maybe_cache_image_data), (scan_directory), (write_pixdata),
(get_image_meta_data_size), (get_image_pixel_data_size),
(get_image_data_size), (get_single_node_size), (get_bucket_size),
(write_bucket), (main):
Update to write pixbuf data as well as information from .icon
files.
2005-03-15 13:18:25 +00:00
|
|
|
|
2011-01-24 02:50:39 +00:00
|
|
|
image_data_offset += pixel_data_size + meta_data_size + 8;
|
|
|
|
}
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
*offset = next_offset;
|
|
|
|
node = node->next;
|
|
|
|
}
|
2011-01-24 02:50:39 +00:00
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static gboolean
|
2004-10-19 18:45:41 +00:00
|
|
|
write_hash_table (FILE *cache, HashContext *context, int *new_offset)
|
|
|
|
{
|
|
|
|
int offset = HASH_OFFSET;
|
|
|
|
int node_offset;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!(write_card32 (cache, context->size)))
|
|
|
|
return FALSE;
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
offset += 4;
|
|
|
|
node_offset = offset + context->size * 4;
|
|
|
|
/* Just write zeros here, we will rewrite this later */
|
2004-10-19 18:45:41 +00:00
|
|
|
for (i = 0; i < context->size; i++)
|
|
|
|
{
|
2007-02-15 16:56:11 +00:00
|
|
|
if (!write_card32 (cache, 0))
|
|
|
|
return FALSE;
|
2004-10-19 18:45:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Now write the buckets */
|
|
|
|
for (i = 0; i < context->size; i++)
|
|
|
|
{
|
|
|
|
if (!context->nodes[i])
|
|
|
|
continue;
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
g_assert (node_offset % 4 == 0);
|
2004-10-19 18:45:41 +00:00
|
|
|
if (!write_bucket (cache, context->nodes[i], &node_offset))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
*new_offset = node_offset;
|
|
|
|
|
|
|
|
/* Now write out the bucket offsets */
|
|
|
|
|
|
|
|
fseek (cache, offset, SEEK_SET);
|
|
|
|
|
|
|
|
for (i = 0; i < context->size; i++)
|
|
|
|
{
|
|
|
|
if (context->nodes[i] != NULL)
|
|
|
|
node_offset = context->nodes[i]->offset;
|
|
|
|
else
|
|
|
|
node_offset = 0xffffffff;
|
|
|
|
if (!write_card32 (cache, node_offset))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
fseek (cache, 0, SEEK_END);
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static gboolean
|
2004-10-19 18:45:41 +00:00
|
|
|
write_dir_index (FILE *cache, int offset, GList *directories)
|
|
|
|
{
|
|
|
|
int n_dirs;
|
|
|
|
GList *d;
|
|
|
|
char *dir;
|
2007-02-15 16:56:11 +00:00
|
|
|
int tmp, tmp2;
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
n_dirs = g_list_length (directories);
|
|
|
|
|
|
|
|
if (!write_card32 (cache, n_dirs))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
offset += 4 + n_dirs * 4;
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
tmp = offset;
|
2004-10-19 18:45:41 +00:00
|
|
|
for (d = directories; d; d = d->next)
|
|
|
|
{
|
|
|
|
dir = d->data;
|
2007-02-15 16:56:11 +00:00
|
|
|
|
|
|
|
tmp2 = find_string (dir);
|
|
|
|
|
|
|
|
if (tmp2 == 0 || tmp2 == -1)
|
|
|
|
{
|
|
|
|
tmp2 = tmp;
|
|
|
|
tmp += ALIGN_VALUE (strlen (dir) + 1, 4);
|
|
|
|
/* We're playing a little game with negative
|
|
|
|
* offsets here to handle duplicate strings in
|
|
|
|
* the array, even though that should not
|
|
|
|
* really happen for the directory index.
|
|
|
|
*/
|
|
|
|
add_string (dir, -tmp2);
|
|
|
|
}
|
|
|
|
else if (tmp2 < 0)
|
|
|
|
{
|
|
|
|
tmp2 = -tmp2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!write_card32 (cache, tmp2))
|
2004-10-19 18:45:41 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
g_assert (offset == ftell (cache));
|
2004-10-19 18:45:41 +00:00
|
|
|
for (d = directories; d; d = d->next)
|
|
|
|
{
|
|
|
|
dir = d->data;
|
|
|
|
|
2007-02-15 16:56:11 +00:00
|
|
|
tmp2 = find_string (dir);
|
|
|
|
g_assert (tmp2 != 0 && tmp2 != -1);
|
|
|
|
if (tmp2 < 0)
|
|
|
|
{
|
|
|
|
tmp2 = -tmp2;
|
|
|
|
g_assert (tmp2 == ftell (cache));
|
|
|
|
add_string (dir, tmp2);
|
|
|
|
if (!write_string (cache, dir))
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-10-19 18:45:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static gboolean
|
2004-10-19 18:45:41 +00:00
|
|
|
write_file (FILE *cache, GHashTable *files, GList *directories)
|
|
|
|
{
|
|
|
|
HashContext context;
|
|
|
|
int new_offset;
|
|
|
|
|
|
|
|
/* Convert the hash table into something looking a bit more
|
|
|
|
* like what we want to write to disk.
|
|
|
|
*/
|
|
|
|
context.size = g_spaced_primes_closest (g_hash_table_size (files) / 3);
|
|
|
|
context.nodes = g_new0 (HashNode *, context.size);
|
|
|
|
|
|
|
|
g_hash_table_foreach_remove (files, convert_to_hash, &context);
|
|
|
|
|
|
|
|
/* Now write the file */
|
|
|
|
/* We write 0 as the directory list offset and go
|
|
|
|
* back and change it later */
|
|
|
|
if (!write_header (cache, 0))
|
|
|
|
{
|
2006-06-19 22:32:03 +00:00
|
|
|
g_printerr (_("Failed to write header\n"));
|
2004-10-19 18:45:41 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!write_hash_table (cache, &context, &new_offset))
|
|
|
|
{
|
2006-06-19 22:32:03 +00:00
|
|
|
g_printerr (_("Failed to write hash table\n"));
|
2004-10-19 18:45:41 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!write_dir_index (cache, new_offset, directories))
|
|
|
|
{
|
2007-01-02 19:52:48 +00:00
|
|
|
g_printerr (_("Failed to write folder index\n"));
|
2004-10-19 18:45:41 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
rewind (cache);
|
|
|
|
|
|
|
|
if (!write_header (cache, new_offset))
|
|
|
|
{
|
2006-06-19 22:32:03 +00:00
|
|
|
g_printerr (_("Failed to rewrite header\n"));
|
2004-10-19 18:45:41 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2007-05-01 20:00:17 +00:00
|
|
|
static gboolean
|
|
|
|
validate_file (const gchar *file)
|
|
|
|
{
|
|
|
|
GMappedFile *map;
|
|
|
|
CacheInfo info;
|
|
|
|
|
|
|
|
map = g_mapped_file_new (file, FALSE, NULL);
|
|
|
|
if (!map)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
info.cache = g_mapped_file_get_contents (map);
|
|
|
|
info.cache_size = g_mapped_file_get_length (map);
|
|
|
|
info.n_directories = 0;
|
|
|
|
info.flags = CHECK_OFFSETS|CHECK_STRINGS|CHECK_PIXBUFS;
|
|
|
|
|
|
|
|
if (!_gtk_icon_cache_validate (&info))
|
|
|
|
{
|
2009-06-18 19:11:57 +00:00
|
|
|
g_mapped_file_unref (map);
|
2007-05-01 20:00:17 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-06-18 19:11:57 +00:00
|
|
|
g_mapped_file_unref (map);
|
2007-05-01 20:00:17 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-11-22 19:42:50 +00:00
|
|
|
/**
|
|
|
|
* safe_fclose:
|
|
|
|
* @f: A FILE* stream, must have underlying fd
|
|
|
|
*
|
|
|
|
* Unix defaults for data preservation after system crash
|
|
|
|
* are unspecified, and many systems will eat your data
|
|
|
|
* in this situation unless you explicitly fsync().
|
|
|
|
*
|
|
|
|
* Returns: %TRUE on success, %FALSE on failure, and will set errno()
|
|
|
|
*/
|
|
|
|
static gboolean
|
|
|
|
safe_fclose (FILE *f)
|
|
|
|
{
|
|
|
|
int fd = fileno (f);
|
|
|
|
g_assert (fd >= 0);
|
|
|
|
if (fflush (f) == EOF)
|
|
|
|
return FALSE;
|
2010-11-24 12:36:18 +00:00
|
|
|
#ifndef G_OS_WIN32
|
2010-11-22 19:42:50 +00:00
|
|
|
if (fsync (fd) < 0)
|
|
|
|
return FALSE;
|
2010-11-24 12:36:18 +00:00
|
|
|
#endif
|
2010-11-22 19:42:50 +00:00
|
|
|
if (fclose (f) == EOF)
|
|
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static void
|
2004-10-19 18:45:41 +00:00
|
|
|
build_cache (const gchar *path)
|
|
|
|
{
|
|
|
|
gchar *cache_path, *tmp_cache_path;
|
2005-11-06 06:27:01 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
gchar *bak_cache_path = NULL;
|
|
|
|
#endif
|
2004-10-19 18:45:41 +00:00
|
|
|
GHashTable *files;
|
|
|
|
FILE *cache;
|
2011-10-03 15:25:33 +00:00
|
|
|
GStatBuf path_stat, cache_stat;
|
2004-10-19 18:45:41 +00:00
|
|
|
struct utimbuf utime_buf;
|
|
|
|
GList *directories = NULL;
|
2008-05-25 23:41:43 +00:00
|
|
|
int fd;
|
2009-05-11 16:02:06 +00:00
|
|
|
int retry_count = 0;
|
2008-05-27 13:03:49 +00:00
|
|
|
#ifndef G_OS_WIN32
|
2008-05-25 23:41:43 +00:00
|
|
|
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
2008-05-27 13:03:49 +00:00
|
|
|
#else
|
|
|
|
int mode = _S_IWRITE | _S_IREAD;
|
|
|
|
#endif
|
|
|
|
#ifndef _O_BINARY
|
|
|
|
#define _O_BINARY 0
|
|
|
|
#endif
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
tmp_cache_path = g_build_filename (path, "."CACHE_NAME, NULL);
|
2008-07-18 19:28:13 +00:00
|
|
|
cache_path = g_build_filename (path, CACHE_NAME, NULL);
|
2008-05-25 23:41:43 +00:00
|
|
|
|
2009-05-11 16:02:06 +00:00
|
|
|
opentmp:
|
2008-06-03 11:04:33 +00:00
|
|
|
if ((fd = g_open (tmp_cache_path, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | _O_BINARY, mode)) == -1)
|
2008-05-25 23:41:43 +00:00
|
|
|
{
|
2009-05-11 16:02:06 +00:00
|
|
|
if (force_update && retry_count == 0)
|
|
|
|
{
|
|
|
|
retry_count++;
|
|
|
|
g_remove (tmp_cache_path);
|
|
|
|
goto opentmp;
|
|
|
|
}
|
2008-05-25 23:41:43 +00:00
|
|
|
g_printerr (_("Failed to open file %s : %s\n"), tmp_cache_path, g_strerror (errno));
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
cache = fdopen (fd, "wb");
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
if (!cache)
|
|
|
|
{
|
2006-06-19 22:32:03 +00:00
|
|
|
g_printerr (_("Failed to write cache file: %s\n"), g_strerror (errno));
|
2004-10-19 18:45:41 +00:00
|
|
|
exit (1);
|
|
|
|
}
|
2008-05-25 23:41:43 +00:00
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
files = g_hash_table_new (g_str_hash, g_str_equal);
|
2005-08-15 03:52:34 +00:00
|
|
|
image_data_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
2007-02-15 16:56:11 +00:00
|
|
|
icon_data_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
string_pool = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
directories = scan_directory (path, NULL, files, NULL, 0);
|
|
|
|
|
|
|
|
if (g_hash_table_size (files) == 0)
|
|
|
|
{
|
|
|
|
/* Empty table, just close and remove the file */
|
|
|
|
|
|
|
|
fclose (cache);
|
2004-12-12 21:09:13 +00:00
|
|
|
g_unlink (tmp_cache_path);
|
2008-07-18 19:28:13 +00:00
|
|
|
g_unlink (cache_path);
|
2004-10-19 18:45:41 +00:00
|
|
|
exit (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Handle failure */
|
2010-11-22 19:42:50 +00:00
|
|
|
if (!write_file (cache, files, directories))
|
|
|
|
{
|
|
|
|
g_unlink (tmp_cache_path);
|
|
|
|
exit (1);
|
|
|
|
}
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2010-11-22 19:42:50 +00:00
|
|
|
if (!safe_fclose (cache))
|
2004-10-19 18:45:41 +00:00
|
|
|
{
|
2010-11-22 19:42:50 +00:00
|
|
|
g_printerr (_("Failed to write cache file: %s\n"), g_strerror (errno));
|
2004-12-12 21:09:13 +00:00
|
|
|
g_unlink (tmp_cache_path);
|
2004-10-19 18:45:41 +00:00
|
|
|
exit (1);
|
|
|
|
}
|
2010-11-22 19:42:50 +00:00
|
|
|
cache = NULL;
|
|
|
|
|
2012-01-02 03:20:59 +00:00
|
|
|
g_list_free_full (directories, g_free);
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2007-05-01 20:00:17 +00:00
|
|
|
if (!validate_file (tmp_cache_path))
|
|
|
|
{
|
|
|
|
g_printerr (_("The generated cache was invalid.\n"));
|
2009-05-11 16:02:06 +00:00
|
|
|
/*g_unlink (tmp_cache_path);*/
|
2007-05-01 20:00:17 +00:00
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
2005-11-06 06:27:01 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
if (g_file_test (cache_path, G_FILE_TEST_EXISTS))
|
|
|
|
{
|
|
|
|
bak_cache_path = g_strconcat (cache_path, ".bak", NULL);
|
|
|
|
g_unlink (bak_cache_path);
|
|
|
|
if (g_rename (cache_path, bak_cache_path) == -1)
|
|
|
|
{
|
2009-08-20 13:32:22 +00:00
|
|
|
int errsv = errno;
|
|
|
|
|
2006-06-19 22:32:03 +00:00
|
|
|
g_printerr (_("Could not rename %s to %s: %s, removing %s then.\n"),
|
2005-11-06 06:27:01 +00:00
|
|
|
cache_path, bak_cache_path,
|
2009-08-20 13:32:22 +00:00
|
|
|
g_strerror (errsv),
|
2005-11-06 06:27:01 +00:00
|
|
|
cache_path);
|
|
|
|
g_unlink (cache_path);
|
|
|
|
bak_cache_path = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-12-12 21:09:13 +00:00
|
|
|
if (g_rename (tmp_cache_path, cache_path) == -1)
|
2004-10-19 18:45:41 +00:00
|
|
|
{
|
2009-08-20 13:32:22 +00:00
|
|
|
int errsv = errno;
|
|
|
|
|
2006-06-19 22:32:03 +00:00
|
|
|
g_printerr (_("Could not rename %s to %s: %s\n"),
|
2005-11-06 06:27:01 +00:00
|
|
|
tmp_cache_path, cache_path,
|
2009-08-20 13:32:22 +00:00
|
|
|
g_strerror (errsv));
|
2004-12-12 21:09:13 +00:00
|
|
|
g_unlink (tmp_cache_path);
|
2005-11-06 06:27:01 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
if (bak_cache_path != NULL)
|
|
|
|
if (g_rename (bak_cache_path, cache_path) == -1)
|
2009-08-20 13:32:22 +00:00
|
|
|
{
|
|
|
|
errsv = errno;
|
|
|
|
|
|
|
|
g_printerr (_("Could not rename %s back to %s: %s.\n"),
|
|
|
|
bak_cache_path, cache_path,
|
|
|
|
g_strerror (errsv));
|
|
|
|
}
|
2005-11-06 06:27:01 +00:00
|
|
|
#endif
|
2004-10-19 18:45:41 +00:00
|
|
|
exit (1);
|
|
|
|
}
|
2005-11-06 06:27:01 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
if (bak_cache_path != NULL)
|
|
|
|
g_unlink (bak_cache_path);
|
|
|
|
#endif
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
/* Update time */
|
|
|
|
/* FIXME: What do do if an error occurs here? */
|
2005-04-07 18:46:19 +00:00
|
|
|
if (g_stat (path, &path_stat) < 0 ||
|
|
|
|
g_stat (cache_path, &cache_stat))
|
|
|
|
exit (1);
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
utime_buf.actime = path_stat.st_atime;
|
|
|
|
utime_buf.modtime = cache_stat.st_mtime;
|
2008-05-29 18:22:38 +00:00
|
|
|
#if GLIB_CHECK_VERSION (2, 17, 1)
|
|
|
|
g_utime (path, &utime_buf);
|
|
|
|
#else
|
2004-10-19 18:45:41 +00:00
|
|
|
utime (path, &utime_buf);
|
2008-05-29 18:22:38 +00:00
|
|
|
#endif
|
|
|
|
|
2005-02-01 13:55:08 +00:00
|
|
|
if (!quiet)
|
2006-06-19 22:32:03 +00:00
|
|
|
g_printerr (_("Cache file created successfully.\n"));
|
2004-10-19 18:45:41 +00:00
|
|
|
}
|
|
|
|
|
2006-10-08 05:07:55 +00:00
|
|
|
static void
|
2005-11-04 15:43:40 +00:00
|
|
|
write_csource (const gchar *path)
|
|
|
|
{
|
|
|
|
gchar *cache_path;
|
|
|
|
gchar *data;
|
|
|
|
gsize len;
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
cache_path = g_build_filename (path, CACHE_NAME, NULL);
|
|
|
|
if (!g_file_get_contents (cache_path, &data, &len, NULL))
|
|
|
|
exit (1);
|
|
|
|
|
|
|
|
g_printf ("#ifdef __SUNPRO_C\n");
|
|
|
|
g_printf ("#pragma align 4 (%s)\n", var_name);
|
|
|
|
g_printf ("#endif\n");
|
|
|
|
|
|
|
|
g_printf ("#ifdef __GNUC__\n");
|
|
|
|
g_printf ("static const guint8 %s[] __attribute__ ((__aligned__ (4))) = \n", var_name);
|
|
|
|
g_printf ("#else\n");
|
|
|
|
g_printf ("static const guint8 %s[] = \n", var_name);
|
|
|
|
g_printf ("#endif\n");
|
2005-11-23 15:09:47 +00:00
|
|
|
|
|
|
|
g_printf ("{\n");
|
|
|
|
for (i = 0; i < len - 1; i++)
|
2005-11-04 15:43:40 +00:00
|
|
|
{
|
2005-11-23 15:09:47 +00:00
|
|
|
if (i %12 == 0)
|
|
|
|
g_printf (" ");
|
|
|
|
g_printf ("0x%02x, ", (guint8)data[i]);
|
|
|
|
if (i % 12 == 11)
|
|
|
|
g_printf ("\n");
|
2005-11-04 15:43:40 +00:00
|
|
|
}
|
2005-11-23 15:09:47 +00:00
|
|
|
|
|
|
|
g_printf ("0x%02x\n};\n", (guint8)data[i]);
|
2005-11-04 15:43:40 +00:00
|
|
|
}
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
static GOptionEntry args[] = {
|
2006-09-10 05:01:32 +00:00
|
|
|
{ "force", 'f', 0, G_OPTION_ARG_NONE, &force_update, N_("Overwrite an existing cache, even if up to date"), NULL },
|
2006-06-19 22:32:03 +00:00
|
|
|
{ "ignore-theme-index", 't', 0, G_OPTION_ARG_NONE, &ignore_theme_index, N_("Don't check for the existence of index.theme"), NULL },
|
|
|
|
{ "index-only", 'i', 0, G_OPTION_ARG_NONE, &index_only, N_("Don't include image data in the cache"), NULL },
|
2014-06-14 23:30:17 +00:00
|
|
|
{ "include-image-data", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &index_only, N_("Include image data in the cache"), NULL },
|
2006-06-19 22:32:03 +00:00
|
|
|
{ "source", 'c', 0, G_OPTION_ARG_STRING, &var_name, N_("Output a C header file"), "NAME" },
|
|
|
|
{ "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, N_("Turn off verbose output"), NULL },
|
2007-05-01 20:00:17 +00:00
|
|
|
{ "validate", 'v', 0, G_OPTION_ARG_NONE, &validate, N_("Validate existing icon cache"), NULL },
|
2004-10-19 18:45:41 +00:00
|
|
|
{ NULL }
|
|
|
|
};
|
|
|
|
|
2008-02-05 18:35:54 +00:00
|
|
|
static void
|
|
|
|
printerr_handler (const gchar *string)
|
|
|
|
{
|
|
|
|
const gchar *charset;
|
|
|
|
|
|
|
|
fputs (g_get_prgname (), stderr);
|
|
|
|
fputs (": ", stderr);
|
|
|
|
if (g_get_charset (&charset))
|
|
|
|
fputs (string, stderr); /* charset is UTF-8 already */
|
|
|
|
else
|
|
|
|
{
|
2008-02-05 21:43:26 +00:00
|
|
|
gchar *result;
|
|
|
|
|
|
|
|
result = g_convert_with_fallback (string, -1, charset, "UTF-8", "?", NULL, NULL, NULL);
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
fputs (result, stderr);
|
|
|
|
g_free (result);
|
|
|
|
}
|
|
|
|
|
2008-02-05 18:35:54 +00:00
|
|
|
fflush (stderr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
int
|
|
|
|
main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
gchar *path;
|
|
|
|
GOptionContext *context;
|
|
|
|
|
2004-12-12 21:09:13 +00:00
|
|
|
if (argc < 2)
|
|
|
|
return 0;
|
2008-02-05 18:35:54 +00:00
|
|
|
|
|
|
|
g_set_printerr_handler (printerr_handler);
|
2006-06-19 22:32:03 +00:00
|
|
|
|
2007-01-02 19:52:48 +00:00
|
|
|
setlocale (LC_ALL, "");
|
|
|
|
|
2009-09-03 09:30:12 +00:00
|
|
|
#ifdef ENABLE_NLS
|
2006-06-19 22:32:03 +00:00
|
|
|
bindtextdomain (GETTEXT_PACKAGE, GTK_LOCALEDIR);
|
2009-09-03 09:30:12 +00:00
|
|
|
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
|
2006-06-19 22:32:03 +00:00
|
|
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
2009-09-03 09:30:12 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2004-12-12 21:09:13 +00:00
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
context = g_option_context_new ("ICONPATH");
|
2006-06-19 22:32:03 +00:00
|
|
|
g_option_context_add_main_entries (context, args, GETTEXT_PACKAGE);
|
2004-10-19 18:45:41 +00:00
|
|
|
|
|
|
|
g_option_context_parse (context, &argc, &argv, NULL);
|
|
|
|
|
|
|
|
path = argv[1];
|
2004-12-12 21:09:13 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
path = g_locale_to_utf8 (path, -1, NULL, NULL, NULL);
|
|
|
|
#endif
|
2004-10-19 18:45:41 +00:00
|
|
|
|
2007-05-01 20:00:17 +00:00
|
|
|
if (validate)
|
|
|
|
{
|
|
|
|
gchar *file = g_build_filename (path, CACHE_NAME, NULL);
|
|
|
|
|
|
|
|
if (!g_file_test (file, G_FILE_TEST_IS_REGULAR))
|
|
|
|
{
|
|
|
|
if (!quiet)
|
|
|
|
g_printerr (_("File not found: %s\n"), file);
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
if (!validate_file (file))
|
|
|
|
{
|
|
|
|
if (!quiet)
|
|
|
|
g_printerr (_("Not a valid icon cache: %s\n"), file);
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
exit (0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-26 19:05:31 +00:00
|
|
|
if (!ignore_theme_index && !has_theme_index (path))
|
2005-08-23 15:18:08 +00:00
|
|
|
{
|
2008-05-25 23:41:43 +00:00
|
|
|
if (path)
|
|
|
|
{
|
2009-06-12 14:21:42 +00:00
|
|
|
g_printerr (_("No theme index file.\n"));
|
2008-05-25 23:41:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_printerr (_("No theme index file in '%s'.\n"
|
2006-06-19 22:32:03 +00:00
|
|
|
"If you really want to create an icon cache here, use --ignore-theme-index.\n"), path);
|
2008-05-25 23:41:43 +00:00
|
|
|
}
|
|
|
|
|
2005-08-23 15:18:08 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
if (!force_update && is_cache_up_to_date (path))
|
|
|
|
return 0;
|
|
|
|
|
2013-02-21 18:25:21 +00:00
|
|
|
replace_backslashes_with_slashes (path);
|
2004-10-19 18:45:41 +00:00
|
|
|
build_cache (path);
|
2005-08-15 03:52:34 +00:00
|
|
|
|
2005-11-04 15:43:40 +00:00
|
|
|
if (strcmp (var_name, "-") != 0)
|
|
|
|
write_csource (path);
|
|
|
|
|
2004-10-19 18:45:41 +00:00
|
|
|
return 0;
|
|
|
|
}
|