Commit 7e54248b authored by Owen Taylor's avatar Owen Taylor Committed by Owen Taylor

auto-ize.

Wed Jul 16 16:50:31 2003  Owen Taylor  <otaylor@redhat.com>

        * configure.ac Makefile.am: auto-ize.

        * xdgmime/: Add freedesktop.org MIME spec implementatin
        by Jonathan Blandford.

        * gtkfilesystem.[ch]: Add gtk_file_info_render_icon()
        gtk_file_info_set/get_icon_type to do icon handling
        based on MIME type. Add a simple icon caching system.

        * gtkfilesystemgnomevfs.c: Implement ensure_types()
        so that extending the set of types for a loaded
        directory works. Set the MIME type to get the default
        icon handling.

        * gtkfilesystemunix.c: Look up the MIME type using
        xdgmime.

        * gtkfilechooserimpldefault.c: Display icons in the list.
parent bc8567d4
......@@ -25,10 +25,12 @@
#include "gtkfilechooser.h"
#include "gtkfilesystemmodel.h"
#include <gtk/gtkcellrendererpixbuf.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkhpaned.h>
#include <gtk/gtkicontheme.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtktreeview.h>
......@@ -119,6 +121,11 @@ static void tree_name_data_func (GtkTreeViewColumn *tree_column,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data);
static void list_icon_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data);
static void list_name_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
......@@ -130,7 +137,7 @@ static void list_size_data_func (GtkTreeViewColumn *tree_column,
GtkTreeIter *iter,
gpointer data);
GObjectClass *parent_class;
static GObjectClass *parent_class;
GType
_gtk_file_chooser_impl_default_get_type (void)
......@@ -174,6 +181,8 @@ gtk_file_chooser_impl_default_class_init (GtkFileChooserImplDefaultClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
parent_class = g_type_class_peek_parent (class);
gobject_class->finalize = gtk_file_chooser_impl_default_finalize;
gobject_class->constructor = gtk_file_chooser_impl_default_constructor;
gobject_class->set_property = gtk_file_chooser_impl_default_set_property;
......@@ -350,11 +359,19 @@ gtk_file_chooser_impl_default_constructor (GType type,
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (column, "File name");
renderer = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func (column, renderer,
list_icon_data_func, impl, NULL);
gtk_tree_view_column_set_sort_column_id (column, 0);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func (column, renderer,
list_name_data_func, impl, NULL);
gtk_tree_view_column_set_sort_column_id (column, 0);
gtk_tree_view_append_column (GTK_TREE_VIEW (impl->list), column);
column = gtk_tree_view_column_new ();
......@@ -822,6 +839,7 @@ tree_selection_changed (GtkTreeSelection *selection,
impl->list_model = _gtk_file_system_model_new (impl->file_system,
file_path, 0,
GTK_FILE_INFO_ICON |
GTK_FILE_INFO_DISPLAY_NAME |
GTK_FILE_INFO_SIZE);
_gtk_file_system_model_set_show_folders (impl->list_model, FALSE);
......@@ -915,7 +933,7 @@ entry_activate (GtkEntry *entry,
}
}
const GtkFileInfo *
static const GtkFileInfo *
get_list_file_info (GtkFileChooserImplDefault *impl,
GtkTreeIter *iter)
{
......@@ -946,6 +964,30 @@ tree_name_data_func (GtkTreeViewColumn *tree_column,
}
}
static void
list_icon_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gpointer data)
{
GtkFileChooserImplDefault *impl = data;
const GtkFileInfo *info = get_list_file_info (impl, iter);
if (info)
{
GtkWidget *widget = GTK_TREE_VIEW_COLUMN (tree_column)->tree_view;
GdkPixbuf *pixbuf = gtk_file_info_render_icon (info, widget, 36);
g_object_set (cell,
"pixbuf", pixbuf,
NULL);
if (pixbuf)
g_object_unref (pixbuf);
}
}
static void
list_name_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
......
......@@ -50,7 +50,7 @@ static void gtk_file_chooser_dialog_get_property (GObject *obj
GValue *value,
GParamSpec *pspec);
GObjectClass *parent_class;
static GObjectClass *parent_class;
GType
gtk_file_chooser_dialog_get_type (void)
......
......@@ -67,8 +67,8 @@ static void gtk_file_chooser_entry_do_insert_text (GtkEditable *editabl
static void clear_completion_callback (GtkFileChooserEntry *chooser_entry,
GParamSpec *pspec);
GObjectClass *parent_class;
GtkEditableClass *parent_editable_iface;
static GObjectClass *parent_class;
static GtkEditableClass *parent_editable_iface;
GType
_gtk_file_chooser_entry_get_type (void)
......
......@@ -48,7 +48,7 @@ static void gtk_file_chooser_widget_get_property (GObject *obj
GValue *value,
GParamSpec *pspec);
GObjectClass *parent_class;
static GObjectClass *parent_class;
GType
gtk_file_chooser_widget_get_type (void)
......@@ -130,7 +130,7 @@ gtk_file_chooser_widget_constructor (GType type,
gtk_widget_push_composite_child ();
if (!priv->file_system)
priv->file_system = _gtk_file_system_unix_new ();
priv->file_system = gtk_file_system_unix_new ();
priv->impl = _gtk_file_chooser_impl_default_new (priv->file_system);
gtk_box_pack_start (GTK_BOX (object), priv->impl, TRUE, TRUE, 0);
......
......@@ -18,6 +18,8 @@
* Boston, MA 02111-1307, USA.
*/
#include <gtk/gtkicontheme.h>
#include "gtkfilesystem.h"
#include <string.h>
......@@ -29,7 +31,7 @@ struct _GtkFileInfo
gchar *display_name;
gchar *display_key;
gchar *mime_type;
GdkPixbuf *icon;
GtkFileIconType icon_type : 4;
guint is_folder : 1;
guint is_hidden : 1;
};
......@@ -84,8 +86,6 @@ gtk_file_info_copy (GtkFileInfo *info)
new_info->display_name = g_strdup (new_info->display_name);
if (new_info->mime_type)
new_info->mime_type = g_strdup (new_info->mime_type);
if (new_info->icon)
g_object_ref (new_info->icon);
return new_info;
}
......@@ -99,8 +99,6 @@ gtk_file_info_free (GtkFileInfo *info)
g_free (info->display_name);
if (info->mime_type)
g_free (info->mime_type);
if (info->icon)
g_object_unref (info->icon);
}
G_CONST_RETURN gchar *
......@@ -134,7 +132,6 @@ gtk_file_info_get_display_key (const GtkFileInfo *info)
((GtkFileInfo *)info)->display_key = g_utf8_collate_key (info->display_name, -1);
}
return info->display_key;
}
......@@ -244,31 +241,166 @@ gtk_file_info_set_size (GtkFileInfo *info,
info->size = size;
}
GdkPixbuf *
gtk_file_info_get_icon (const GtkFileInfo *info)
void
gtk_file_info_set_icon_type (GtkFileInfo *info,
GtkFileIconType icon_type)
{
g_return_val_if_fail (info != NULL, NULL);
g_return_if_fail (info != NULL);
return info->icon;
info->icon_type = icon_type;
}
void
gtk_file_info_set_icon (GtkFileInfo *info,
GdkPixbuf *icon)
GtkFileIconType
gtk_file_info_get_icon_type (const GtkFileInfo *info)
{
g_return_if_fail (info != NULL);
g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
g_return_val_if_fail (info != NULL, GTK_FILE_ICON_REGULAR);
return info->icon_type;
}
if (icon != info->icon)
typedef struct _IconCacheElement IconCacheElement;
struct _IconCacheElement
{
gint size;
GdkPixbuf *pixbuf;
};
static void
icon_cache_element_free (IconCacheElement *element)
{
if (element->pixbuf)
g_object_unref (element->pixbuf);
g_free (element);
}
static void
icon_theme_changed (GtkIconTheme *icon_theme)
{
GHashTable *cache;
/* Difference from the initial creation is that we don't
* reconnect the signal
*/
cache = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)icon_cache_element_free);
g_object_set_data_full (G_OBJECT (icon_theme), "gtk-file-icon-cache",
cache, (GDestroyNotify)g_hash_table_destroy);
}
static GdkPixbuf *
get_cached_icon (GtkWidget *widget,
const gchar *name,
gint pixel_size)
{
GtkIconTheme *icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
GHashTable *cache = g_object_get_data (G_OBJECT (icon_theme), "gtk-file-icon-cache");
IconCacheElement *element;
if (!cache)
{
cache = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)icon_cache_element_free);
g_object_set_data_full (G_OBJECT (icon_theme), "gtk-file-icon-cache",
cache, (GDestroyNotify)g_hash_table_destroy);
g_signal_connect (icon_theme, "changed",
G_CALLBACK (icon_theme_changed), NULL);
}
element = g_hash_table_lookup (cache, name);
if (!element)
{
if (info->icon)
g_object_unref (info->icon);
element = g_new0 (IconCacheElement, 1);
g_hash_table_insert (cache, g_strdup (name), element);
}
if (element->size != pixel_size)
{
if (element->pixbuf)
g_object_unref (element->pixbuf);
element->size = pixel_size;
element->pixbuf = gtk_icon_theme_load_icon (icon_theme, name,
pixel_size, 0, NULL);
}
info->icon = icon;
return element->pixbuf ? g_object_ref (element->pixbuf) : NULL;
}
GdkPixbuf *
gtk_file_info_render_icon (const GtkFileInfo *info,
GtkWidget *widget,
gint pixel_size)
{
const gchar *separator;
GdkPixbuf *pixbuf;
GString *icon_name;
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (widget != NULL, NULL);
g_return_val_if_fail (pixel_size > 0, NULL);
if (info->icon_type != GTK_FILE_ICON_REGULAR)
{
const char *name = NULL; /* Quiet gcc */
if (info->icon)
g_object_ref (info->icon);
switch (info->icon_type)
{
case GTK_FILE_ICON_BLOCK_DEVICE:
name ="gnome-fs-blockdev";
break;
case GTK_FILE_ICON_BROKEN_SYMBOLIC_LINK:
name = "gnome-fs-symlink";
break;
case GTK_FILE_ICON_CHARACTER_DEVICE:
name = "gnome-fs-chardev";
break;
case GTK_FILE_ICON_DIRECTORY:
name = "gnome-fs-directory";
break;
case GTK_FILE_ICON_EXECUTABLE:
name ="gnome-fs-executable";
break;
case GTK_FILE_ICON_FIFO:
name = "gnome-fs-fifo";
break;
case GTK_FILE_ICON_SOCKET:
name = "gnome-fs-socket";
break;
case GTK_FILE_ICON_REGULAR:
g_assert_not_reached ();
}
return get_cached_icon (widget, name, pixel_size);
}
if (!info->mime_type)
return NULL;
separator = strchr (info->mime_type, '/');
if (!separator)
return NULL;
icon_name = g_string_new ("gnome-mime-");
g_string_append_len (icon_name, info->mime_type, separator - info->mime_type);
g_string_append_c (icon_name, '-');
g_string_append (icon_name, separator + 1);
pixbuf = get_cached_icon (widget, icon_name->str, pixel_size);
g_string_free (icon_name, TRUE);
if (pixbuf)
return pixbuf;
icon_name = g_string_new ("gnome-mime-");
g_string_append_len (icon_name, info->mime_type, separator - info->mime_type);
pixbuf = get_cached_icon (widget, icon_name->str, pixel_size);
g_string_free (icon_name, TRUE);
if (pixbuf)
return pixbuf;
return get_cached_icon (widget, "gnome-fs-regular", pixel_size);
}
/*****************************************
......
......@@ -22,7 +22,7 @@
#define __GTK_FILE_SYSTEM_H__
#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtkwidget.h> /* For icon handling */
G_BEGIN_DECLS
......@@ -50,6 +50,19 @@ typedef enum {
GTK_FILE_INFO_ALL = (1 << 7) - 1
} GtkFileInfoType;
/* Icon type, supplemented by MIME type
*/
typedef enum {
GTK_FILE_ICON_REGULAR, /* Use mime type for icon */
GTK_FILE_ICON_BLOCK_DEVICE,
GTK_FILE_ICON_BROKEN_SYMBOLIC_LINK,
GTK_FILE_ICON_CHARACTER_DEVICE,
GTK_FILE_ICON_DIRECTORY,
GTK_FILE_ICON_EXECUTABLE,
GTK_FILE_ICON_FIFO,
GTK_FILE_ICON_SOCKET
} GtkFileIconType;
/* GError enumeration for GtkFileSystem
*/
......@@ -96,9 +109,12 @@ void gtk_file_info_set_modification_time (GtkFileInfo *in
gint64 gtk_file_info_get_size (const GtkFileInfo *info);
void gtk_file_info_set_size (GtkFileInfo *info,
gint64 size);
GdkPixbuf * gtk_file_info_get_icon (const GtkFileInfo *info);
void gtk_file_info_set_icon (GtkFileInfo *info,
GdkPixbuf *icon);
void gtk_file_info_set_icon_type (GtkFileInfo *info,
GtkFileIconType icon_type);
GtkFileIconType gtk_file_info_get_icon_type (const GtkFileInfo *info);
GdkPixbuf * gtk_file_info_render_icon (const GtkFileInfo *info,
GtkWidget *widget,
gint pixel_size);
/* The base GtkFileSystem interface
*/
......
......@@ -35,7 +35,7 @@ typedef struct _GtkFileSystemModel GtkFileSystemModel;
GType _gtk_file_system_model_get_type (void);
enum {
typedef enum {
GTK_FILE_SYSTEM_MODEL_INFO,
GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME,
GTK_FILE_SYSTEM_MODEL_N_COLUMNS
......
......@@ -21,6 +21,8 @@
#include "gtkfilesystem.h"
#include "gtkfilesystemunix.h"
#include "xdgmime/xdgmime.h"
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
......@@ -66,8 +68,8 @@ struct _GtkFileFolderUnix
gchar *filename;
};
GObjectClass *system_parent_class;
GObjectClass *folder_parent_class;
static GObjectClass *system_parent_class;
static GObjectClass *folder_parent_class;
static void gtk_file_system_unix_class_init (GtkFileSystemUnixClass *class);
static void gtk_file_system_unix_iface_init (GtkFileSystemIface *iface);
......@@ -135,7 +137,7 @@ static GtkFileInfo *filename_get_info (const gchar *filename,
* GtkFileSystemUnix
*/
GType
_gtk_file_system_unix_get_type (void)
gtk_file_system_unix_get_type (void)
{
static GType file_system_unix_type = 0;
......@@ -173,7 +175,7 @@ _gtk_file_system_unix_get_type (void)
}
/**
* _gtk_file_system_unix_new:
* gtk_file_system_unix_new:
*
* Creates a new #GtkFileSystemUnix object. #GtkFileSystemUnix
* implements the #GtkFileSystem interface with direct access to
......@@ -182,7 +184,7 @@ _gtk_file_system_unix_get_type (void)
* Return value: the new #GtkFileSystemUnix object
**/
GtkFileSystem *
_gtk_file_system_unix_new (void)
gtk_file_system_unix_new (void)
{
return g_object_new (GTK_TYPE_FILE_SYSTEM_UNIX, NULL);
}
......@@ -678,6 +680,7 @@ filename_get_info (const gchar *filename,
GError **error)
{
GtkFileInfo *info;
GtkFileIconType icon_type = GTK_FILE_ICON_REGULAR;
struct stat statbuf;
/* If stat fails, try to fall back to lstat to catch broken links
......@@ -735,9 +738,36 @@ filename_get_info (const gchar *filename,
gtk_file_info_set_is_folder (info, S_ISDIR (statbuf.st_mode));
}
if (types & GTK_FILE_INFO_MIME_TYPE)
if (types & GTK_FILE_INFO_ICON)
{
if (S_ISBLK (statbuf.st_mode))
icon_type = GTK_FILE_ICON_BLOCK_DEVICE;
else if (S_ISLNK (statbuf.st_mode))
icon_type = GTK_FILE_ICON_BROKEN_SYMBOLIC_LINK;
else if (S_ISCHR (statbuf.st_mode))
icon_type = GTK_FILE_ICON_CHARACTER_DEVICE;
else if (S_ISDIR (statbuf.st_mode))
icon_type = GTK_FILE_ICON_DIRECTORY;
else if (S_ISFIFO (statbuf.st_mode))
icon_type = GTK_FILE_ICON_FIFO;
else if (S_ISSOCK (statbuf.st_mode))
icon_type = GTK_FILE_ICON_SOCKET;
gtk_file_info_set_icon_type (info, icon_type);
}
if ((types & GTK_FILE_INFO_MIME_TYPE) ||
((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR))
{
gtk_file_info_set_mime_type (info, "application/octet-stream");
const char *mime_type = xdg_mime_get_mime_type_for_file (filename);
gtk_file_info_set_mime_type (info, mime_type);
if ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR &&
(statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) &&
(strcmp (mime_type, XDG_MIME_TYPE_UNKNOWN) == 0 ||
strcmp (mime_type, "application/x-executable") == 0 ||
strcmp (mime_type, "application/x-shellscript") == 0))
gtk_file_info_set_icon_type (info, GTK_FILE_ICON_EXECUTABLE);
}
if (types & GTK_FILE_INFO_MODIFICATION_TIME)
......@@ -750,11 +780,6 @@ filename_get_info (const gchar *filename,
gtk_file_info_set_size (info, (gint64)statbuf.st_size);
}
if (types & GTK_FILE_INFO_ICON)
{
/* NOT YET IMPLEMENTED */
}
return info;
}
......
......@@ -26,14 +26,14 @@
G_BEGIN_DECLS
#define GTK_TYPE_FILE_SYSTEM_UNIX (_gtk_file_system_unix_get_type ())
#define GTK_TYPE_FILE_SYSTEM_UNIX (gtk_file_system_unix_get_type ())
#define GTK_FILE_SYSTEM_UNIX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_SYSTEM_UNIX, GtkFileSystemUnix))
#define GTK_IS_FILE_SYSTEM_UNIX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_SYSTEM_UNIX))
typedef struct _GtkFileSystemUnix GtkFileSystemUnix;
GtkFileSystem *_gtk_file_system_unix_new (void);
GType _gtk_file_system_unix_get_type (void);
GtkFileSystem *gtk_file_system_unix_new (void);
GType gtk_file_system_unix_get_type (void);
G_END_DECLS
......
INCLUDES = -DXDG_PREFIX=_xdg
noinst_LTLIBRARIES = libxdgmime.la
libxdgmime_la_SOURCES = \
xdgmime.c \
xdgmimeglob.c \
xdgmimeint.c \
xdgmimemagic.c
noinst_PROGRAMS = test-mime
test_mime_LDADD = libxdgmime.la
test_mime_SOURCES = test-mime.c
#include "xdgmime.h"
#include "xdgmimeglob.h"
#include <string.h>
#include <stdio.h>
static void
test_individual_glob (const char *glob,
XdgGlobType expected_type)
{
XdgGlobType test_type;
test_type = _xdg_glob_determine_type (glob);
if (test_type != expected_type)
{
printf ("Test Failed: %s is of type %s, but %s is expected\n",
glob,
((test_type == XDG_GLOB_LITERAL)?"XDG_GLOB_LITERAL":
((test_type == XDG_GLOB_SIMPLE)?"XDG_GLOB_SIMPLE":"XDG_GLOB_FULL")),
((expected_type == XDG_GLOB_LITERAL)?"XDG_GLOB_LITERAL":
((expected_type == XDG_GLOB_SIMPLE)?"XDG_GLOB_SIMPLE":"XDG_GLOB_COMPLEX")));
}
}
static void
test_glob_type (void)
{
test_individual_glob ("*.gif", XDG_GLOB_SIMPLE);
test_individual_glob ("Foo*.gif", XDG_GLOB_FULL);
test_individual_glob ("*[4].gif", XDG_GLOB_FULL);
test_individual_glob ("Makefile", XDG_GLOB_LITERAL);
test_individual_glob ("sldkfjvlsdf\\\\slkdjf", XDG_GLOB_FULL);
test_individual_glob ("tree.[ch]", XDG_GLOB_FULL);
}
int
main (int argc, char *argv[])
{
const char *result;
const char *file_name;
int i;
test_glob_type ();
for (i = 1; i < argc; i++)
{
file_name = argv[i];
result = xdg_mime_get_mime_type_for_file (file_name);
printf ("File \"%s\" has a mime-type of %s\n", file_name, result);
}
return 0;
}
/* -*- mode: C; c-file-style: "gnu" -*- */
/* xdgmime.c: XDG Mime Spec mime resolver. Based on version 0.11 of the spec.
*
* More info can be found at http://www.freedesktop.org/standards/
*
* Copyright (C) 2003 Red Hat, Inc.
* Copyright (C) 2003 Jonathan Blandford <jrb@alum.mit.edu>
*
* Licensed under the Academic Free License version 1.2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "xdgmime.h"
#include "xdgmimeint.h"
#include "xdgmimeglob.h"
#include "xdgmimemagic.h"
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
XdgGlobHash *global_hash = NULL;
XdgMimeMagic *global_magic = NULL;
static void
_xdg_mime_init_from_directory (const char *directory)
{
char *file_name;
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
strcpy (file_name, directory);
strcat (file_name, "/mime/globs");
_xdg_mime_glob_read_from_file (global_hash, file_name);
free (file_name);
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
strcpy (file_name, directory);
strcat (file_name, "/mime/magic");
_xdg_mime_magic_read_from_file (global_magic, file_name);
free (file_name);
}
static void
xdg_mime_init (void)
{
static int initted = 0;
if (initted == 0)
{
const char *xdg_config_home;
const char *xdg_data_dirs;
const char *ptr;
global_hash = _xdg_glob_hash_new ();
global_magic = _xdg_mime_magic_new ();
/* We look for globs and magic files based upon the XDG Base Directory
* Specification
*/
xdg_config_home = getenv ("XDG_CONFIG_HOME");
if (xdg_config_home)
{
_xdg_mime_init_from_directory (xdg_config_home);
}
else
{
const char *home;
home = getenv ("HOME");
if (home != NULL)
{
char *guessed_xdg_home;
guessed_xdg_home = malloc (strlen (home) + strlen ("/.local/share/") + 1);
strcpy (guessed_xdg_home, home);
strcat (guessed_xdg_home, "/.local/share/");
_xdg_mime_init_from_directory (guessed_xdg_home);
free (guessed_xdg_home);
}
}
xdg_data_dirs = getenv ("XDG_DATA_DIRS");
if (xdg_data_dirs == NULL)
xdg_data_dirs = "/usr/local/share/:/usr/share/";
ptr = xdg_data_dirs;
while (*ptr != '\000')
{
const char *end_ptr;
char *dir;
int len;
end_ptr = ptr;
while (*end_ptr != ':' && *end_ptr != '\000')
end_ptr ++;
if (end_ptr == ptr)
{
ptr++;
continue;
}
if (*end_ptr == ':')
len = end_ptr - ptr;
else
len = end_ptr - ptr + 1;
dir = malloc (len);
strncpy (dir, ptr, len);
_xdg_mime_init_from_directory (dir);
free (dir);
ptr = end_ptr;
}