Add support for cursor themes (GnomeThemeCursorInfo); probably still a bit
2007-07-01 Denis Washington <denisw@svn.gnome.org> * gnome-theme-info.[ch]: Add support for cursor themes (GnomeThemeCursorInfo); probably still a bit rough around the edges, but it works. svn path=/trunk/; revision=7823
This commit is contained in:
parent
aba35d4e9b
commit
bbee377d3f
3 changed files with 204 additions and 0 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2007-07-01 Denis Washington <denisw@svn.gnome.org>
|
||||||
|
|
||||||
|
* gnome-theme-info.[ch]:
|
||||||
|
Add support for cursor themes (GnomeThemeCursorInfo); probably still a bit
|
||||||
|
rough around the edges, but it works.
|
||||||
|
|
||||||
2007-07-01 Jens Granseuer <jensgr@gmx.net>
|
2007-07-01 Jens Granseuer <jensgr@gmx.net>
|
||||||
|
|
||||||
* gconf-property-editor.c: (peditor_string_value_changed),
|
* gconf-property-editor.c: (peditor_string_value_changed),
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
#include <libgnomevfs/gnome-vfs-init.h>
|
#include <libgnomevfs/gnome-vfs-init.h>
|
||||||
#include <libgnomevfs/gnome-vfs-ops.h>
|
#include <libgnomevfs/gnome-vfs-ops.h>
|
||||||
#include <libgnomevfs/gnome-vfs-utils.h>
|
#include <libgnomevfs/gnome-vfs-utils.h>
|
||||||
|
@ -74,6 +76,8 @@ static GHashTable *meta_theme_hash_by_uri;
|
||||||
static GHashTable *meta_theme_hash_by_name;
|
static GHashTable *meta_theme_hash_by_name;
|
||||||
static GHashTable *icon_theme_hash_by_uri;
|
static GHashTable *icon_theme_hash_by_uri;
|
||||||
static GHashTable *icon_theme_hash_by_name;
|
static GHashTable *icon_theme_hash_by_name;
|
||||||
|
static GHashTable *cursor_theme_hash_by_uri;
|
||||||
|
static GHashTable *cursor_theme_hash_by_name;
|
||||||
static GHashTable *theme_hash_by_uri;
|
static GHashTable *theme_hash_by_uri;
|
||||||
static GHashTable *theme_hash_by_name;
|
static GHashTable *theme_hash_by_name;
|
||||||
static gboolean initting = FALSE;
|
static gboolean initting = FALSE;
|
||||||
|
@ -98,6 +102,8 @@ get_priority_from_data_by_hash (GHashTable *hash_table,
|
||||||
theme_priority = ((GnomeThemeMetaInfo *)data)->priority;
|
theme_priority = ((GnomeThemeMetaInfo *)data)->priority;
|
||||||
else if (hash_table == icon_theme_hash_by_name)
|
else if (hash_table == icon_theme_hash_by_name)
|
||||||
theme_priority = ((GnomeThemeIconInfo *)data)->priority;
|
theme_priority = ((GnomeThemeIconInfo *)data)->priority;
|
||||||
|
else if (hash_table == cursor_theme_hash_by_name)
|
||||||
|
theme_priority = ((GnomeThemeCursorInfo *)data)->priority;
|
||||||
else if (hash_table == theme_hash_by_name)
|
else if (hash_table == theme_hash_by_name)
|
||||||
theme_priority = ((GnomeThemeInfo *)data)->priority;
|
theme_priority = ((GnomeThemeInfo *)data)->priority;
|
||||||
else
|
else
|
||||||
|
@ -931,6 +937,112 @@ add_common_theme_dir_monitor (GnomeVFSURI *theme_dir_uri,
|
||||||
return GNOME_VFS_OK;
|
return GNOME_VFS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GdkPixbuf*
|
||||||
|
gdk_pixbuf_from_xcursor_image(XcursorImage* cursor) {
|
||||||
|
GdkPixbuf* pixbuf;
|
||||||
|
#define BUF_SIZE sizeof(guint32) * cursor->width * cursor->height
|
||||||
|
guchar* buf = malloc(BUF_SIZE);
|
||||||
|
guchar* it;
|
||||||
|
memset(buf, '\0', BUF_SIZE);
|
||||||
|
|
||||||
|
for(it = buf; it < (buf + BUF_SIZE); it += 4) {
|
||||||
|
// can we get rid of this by using guint32 ?
|
||||||
|
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||||
|
// on little endianess it's BGRA to RGBA
|
||||||
|
it[0] = ((guchar*)(cursor->pixels))[it - buf + 2];
|
||||||
|
it[1] = ((guchar*)(cursor->pixels))[it - buf + 1];
|
||||||
|
it[2] = ((guchar*)(cursor->pixels))[it - buf + 0];
|
||||||
|
it[3] = ((guchar*)(cursor->pixels))[it - buf + 3];
|
||||||
|
#else
|
||||||
|
// on big endianess it's ARGB to RGBA
|
||||||
|
it[0] = ((guchar*)cursor->pixels)[it - buf + 1];
|
||||||
|
it[1] = ((guchar*)cursor->pixels)[it - buf + 2];
|
||||||
|
it[2] = ((guchar*)cursor->pixels)[it - buf + 3];
|
||||||
|
it[3] = ((guchar*)cursor->pixels)[it - buf + 0];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
pixbuf = gdk_pixbuf_new_from_data((const guchar *)buf,
|
||||||
|
GDK_COLORSPACE_RGB, TRUE, 8,
|
||||||
|
cursor->width, cursor->height,
|
||||||
|
cursor->width * 4,
|
||||||
|
(GdkPixbufDestroyNotify)g_free,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if(!pixbuf) {
|
||||||
|
g_free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
look_for_cursor_theme (GnomeVFSURI *theme_dir_uri)
|
||||||
|
{
|
||||||
|
GnomeVFSURI *cursors_dir_uri;
|
||||||
|
GnomeVFSFileInfo *file_info;
|
||||||
|
GnomeVFSResult result;
|
||||||
|
|
||||||
|
cursors_dir_uri = gnome_vfs_uri_append_file_name (theme_dir_uri, "cursors");
|
||||||
|
file_info = gnome_vfs_file_info_new ();
|
||||||
|
result = gnome_vfs_get_file_info_uri (cursors_dir_uri, file_info, GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
|
||||||
|
if (result == GNOME_VFS_OK && file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY)
|
||||||
|
{
|
||||||
|
gchar *dir_name;
|
||||||
|
gchar *name;
|
||||||
|
gint i;
|
||||||
|
GArray *available_sizes;
|
||||||
|
XcursorImage *cursor;
|
||||||
|
GdkPixbuf *thumbnail = NULL;
|
||||||
|
GnomeThemeCursorInfo *cursor_theme_info;
|
||||||
|
gint sizes[] = { 12, 16, 24, 32, 36, 40, 48, 64, 0 };
|
||||||
|
|
||||||
|
dir_name = gnome_vfs_uri_to_string (theme_dir_uri, GNOME_VFS_URI_HIDE_NONE);
|
||||||
|
name = g_path_get_basename (dir_name);
|
||||||
|
|
||||||
|
available_sizes = g_array_sized_new (FALSE, FALSE, sizeof (gint), 8);
|
||||||
|
|
||||||
|
for (i = 0; sizes[i] != 0; i++)
|
||||||
|
{
|
||||||
|
cursor = XcursorLibraryLoadImage ("left_ptr", name, sizes[i]);
|
||||||
|
|
||||||
|
if (cursor)
|
||||||
|
{
|
||||||
|
if (cursor->size != sizes[i])
|
||||||
|
{
|
||||||
|
XcursorImageDestroy (cursor);
|
||||||
|
cursor = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_array_append_val (available_sizes, sizes[i]);
|
||||||
|
|
||||||
|
if (thumbnail == NULL && i >= 1)
|
||||||
|
thumbnail = gdk_pixbuf_from_xcursor_image (cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!thumbnail)
|
||||||
|
{
|
||||||
|
cursor = XcursorLibraryLoadImage ("left_ptr", name, g_array_index (available_sizes, gint, 0));
|
||||||
|
thumbnail = gdk_pixbuf_from_xcursor_image (cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor_theme_info = gnome_theme_cursor_info_new ();
|
||||||
|
cursor_theme_info->path = dir_name;
|
||||||
|
cursor_theme_info->name = name;
|
||||||
|
cursor_theme_info->sizes = available_sizes;
|
||||||
|
cursor_theme_info->thumbnail = thumbnail;
|
||||||
|
cursor_theme_info->priority = 0;
|
||||||
|
|
||||||
|
g_hash_table_insert (cursor_theme_hash_by_uri, dir_name, cursor_theme_info);
|
||||||
|
add_data_to_hash_by_name (cursor_theme_hash_by_name, name, cursor_theme_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GnomeVFSResult
|
static GnomeVFSResult
|
||||||
add_common_icon_theme_dir_monitor (GnomeVFSURI *theme_dir_uri,
|
add_common_icon_theme_dir_monitor (GnomeVFSURI *theme_dir_uri,
|
||||||
gboolean *monitor_not_added,
|
gboolean *monitor_not_added,
|
||||||
|
@ -942,6 +1054,9 @@ add_common_icon_theme_dir_monitor (GnomeVFSURI *theme_dir_uri
|
||||||
gboolean real_monitor_not_added = FALSE;
|
gboolean real_monitor_not_added = FALSE;
|
||||||
GnomeVFSURI *index_uri;
|
GnomeVFSURI *index_uri;
|
||||||
|
|
||||||
|
/* Look for cursor theme in the theme directory */
|
||||||
|
look_for_cursor_theme (theme_dir_uri);
|
||||||
|
|
||||||
/* Add the handle for this directory */
|
/* Add the handle for this directory */
|
||||||
index_uri = gnome_vfs_uri_append_file_name (theme_dir_uri, "index.theme");
|
index_uri = gnome_vfs_uri_append_file_name (theme_dir_uri, "index.theme");
|
||||||
update_icon_theme_index (index_uri, monitor_data->priority);
|
update_icon_theme_index (index_uri, monitor_data->priority);
|
||||||
|
@ -1333,6 +1448,67 @@ gnome_theme_icon_info_compare (GnomeThemeIconInfo *a,
|
||||||
return safe_strcmp (a->name, b->name);
|
return safe_strcmp (a->name, b->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cursor themes */
|
||||||
|
GnomeThemeCursorInfo *
|
||||||
|
gnome_theme_cursor_info_new (void)
|
||||||
|
{
|
||||||
|
GnomeThemeCursorInfo *cursor_theme_info;
|
||||||
|
|
||||||
|
cursor_theme_info = g_new0 (GnomeThemeCursorInfo, 1);
|
||||||
|
|
||||||
|
return cursor_theme_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gnome_theme_cursor_info_free (GnomeThemeCursorInfo *cursor_theme_info)
|
||||||
|
{
|
||||||
|
g_free (cursor_theme_info->name);
|
||||||
|
g_free (cursor_theme_info->path);
|
||||||
|
g_array_free (cursor_theme_info->sizes, TRUE);
|
||||||
|
g_object_unref (cursor_theme_info->thumbnail);
|
||||||
|
g_free (cursor_theme_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
GnomeThemeCursorInfo *
|
||||||
|
gnome_theme_cursor_info_find (const gchar *cursor_theme_name)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (cursor_theme_name != NULL, NULL);
|
||||||
|
|
||||||
|
return get_data_from_hash_by_name (cursor_theme_hash_by_name, cursor_theme_name, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnome_theme_cursor_info_find_all_helper (gchar *key,
|
||||||
|
GList *list,
|
||||||
|
GList **themes)
|
||||||
|
{
|
||||||
|
*themes = g_list_prepend (*themes, list->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
GList *
|
||||||
|
gnome_theme_cursor_info_find_all (void)
|
||||||
|
{
|
||||||
|
GList *list = NULL;
|
||||||
|
|
||||||
|
g_hash_table_foreach (cursor_theme_hash_by_name,
|
||||||
|
(GHFunc) gnome_theme_cursor_info_find_all_helper,
|
||||||
|
&list);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
gnome_theme_cursor_info_compare (GnomeThemeCursorInfo *a,
|
||||||
|
GnomeThemeCursorInfo *b)
|
||||||
|
{
|
||||||
|
gint cmp;
|
||||||
|
|
||||||
|
cmp = safe_strcmp (a->path, b->path);
|
||||||
|
if (cmp != 0) return cmp;
|
||||||
|
|
||||||
|
return safe_strcmp (a->name, b->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Meta themes*/
|
/* Meta themes*/
|
||||||
GnomeThemeMetaInfo *
|
GnomeThemeMetaInfo *
|
||||||
|
@ -1480,6 +1656,9 @@ gnome_theme_is_writable (const gpointer theme, GnomeThemeType type) {
|
||||||
case GNOME_THEME_TYPE_ICON:
|
case GNOME_THEME_TYPE_ICON:
|
||||||
theme_path = ((const GnomeThemeIconInfo *) theme)->path;
|
theme_path = ((const GnomeThemeIconInfo *) theme)->path;
|
||||||
break;
|
break;
|
||||||
|
case GNOME_THEME_TYPE_CURSOR:
|
||||||
|
theme_path = ((const GnomeThemeIconInfo *) theme)->path;
|
||||||
|
break;
|
||||||
case GNOME_THEME_TYPE_METATHEME:
|
case GNOME_THEME_TYPE_METATHEME:
|
||||||
theme_path = ((const GnomeThemeMetaInfo *) theme)->path;
|
theme_path = ((const GnomeThemeMetaInfo *) theme)->path;
|
||||||
break;
|
break;
|
||||||
|
@ -1538,6 +1717,8 @@ gnome_theme_init (gboolean *monitor_not_added)
|
||||||
meta_theme_hash_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
meta_theme_hash_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
icon_theme_hash_by_uri = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
icon_theme_hash_by_uri = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
icon_theme_hash_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
icon_theme_hash_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
cursor_theme_hash_by_uri = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
cursor_theme_hash_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
theme_hash_by_uri = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
theme_hash_by_uri = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
theme_hash_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
theme_hash_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GNOME_THEME_TYPE_METATHEME,
|
GNOME_THEME_TYPE_METATHEME,
|
||||||
GNOME_THEME_TYPE_ICON,
|
GNOME_THEME_TYPE_ICON,
|
||||||
|
GNOME_THEME_TYPE_CURSOR,
|
||||||
GNOME_THEME_TYPE_REGULAR
|
GNOME_THEME_TYPE_REGULAR
|
||||||
} GnomeThemeType;
|
} GnomeThemeType;
|
||||||
|
|
||||||
|
@ -67,6 +68,15 @@ struct _GnomeThemeIconInfo
|
||||||
gint priority;
|
gint priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _GnomeThemeCursorInfo GnomeThemeCursorInfo;
|
||||||
|
struct _GnomeThemeCursorInfo {
|
||||||
|
gchar *path;
|
||||||
|
gchar *name;
|
||||||
|
gint priority;
|
||||||
|
GArray *sizes;
|
||||||
|
GdkPixbuf *thumbnail;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _GnomeThemeMetaInfo GnomeThemeMetaInfo;
|
typedef struct _GnomeThemeMetaInfo GnomeThemeMetaInfo;
|
||||||
struct _GnomeThemeMetaInfo
|
struct _GnomeThemeMetaInfo
|
||||||
{
|
{
|
||||||
|
@ -113,6 +123,13 @@ GList *gnome_theme_icon_info_find_all (void);
|
||||||
gint gnome_theme_icon_info_compare (GnomeThemeIconInfo *a,
|
gint gnome_theme_icon_info_compare (GnomeThemeIconInfo *a,
|
||||||
GnomeThemeIconInfo *b);
|
GnomeThemeIconInfo *b);
|
||||||
|
|
||||||
|
/* Cursor Themes */
|
||||||
|
GnomeThemeCursorInfo *gnome_theme_cursor_info_new (void);
|
||||||
|
void gnome_theme_cursor_info_free (GnomeThemeCursorInfo *icon_theme_info);
|
||||||
|
GnomeThemeCursorInfo *gnome_theme_cursor_info_find (const gchar *icon_theme_name);
|
||||||
|
GList *gnome_theme_cursor_info_find_all (void);
|
||||||
|
gint gnome_theme_cursor_info_compare (GnomeThemeCursorInfo *a,
|
||||||
|
GnomeThemeCursorInfo *b);
|
||||||
|
|
||||||
/* Meta themes*/
|
/* Meta themes*/
|
||||||
GnomeThemeMetaInfo *gnome_theme_meta_info_new (void);
|
GnomeThemeMetaInfo *gnome_theme_meta_info_new (void);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue