static FILE * XcursorScanTheme (const char *theme, const char *name) { FILE *f = NULL; char *full; char *dir; const char *path; char *inherits = NULL; const char *i; if (!theme || !name) return NULL; /* * XCURSOR_CORE_THEME is a magic name; cursors from the core set * are never found in any directory. Instead, a magic value is * returned which truncates any search so that overlying functions * can switch to equivalent core cursors */ if (!strcmp (theme, XCURSOR_CORE_THEME) && XcursorLibraryShape (name) >= 0) return XCURSOR_SCAN_CORE; /* * Scan this theme */ for (path = XcursorLibraryPath (); path && f == NULL; path = _XcursorNextPath (path)) { dir = _XcursorBuildThemeDir (path, theme); if (dir) { full = _XcursorBuildFullname (dir, "cursors", name); if (full) { f = fopen (full, "r"); free (full); } if (!f && !inherits) { full = _XcursorBuildFullname (dir, "", "index.theme"); if (full) { inherits = _XcursorThemeInherits (full); free (full); } } free (dir); } } /* * Recurse to scan inherited themes */ for (i = inherits; i && f == NULL; i = _XcursorNextPath (i)) f = XcursorScanTheme (i, name); if (inherits != NULL) free (inherits); return f; }
const QStringList CursorThemeModel::searchPaths() { if (!baseDirs.isEmpty()) return baseDirs; #if XCURSOR_LIB_MAJOR == 1 && XCURSOR_LIB_MINOR < 1 // These are the default paths Xcursor will scan for cursor themes QString path("~/.icons:/usr/share/icons:/usr/share/pixmaps:/usr/X11R6/lib/X11/icons"); // If XCURSOR_PATH is set, use that instead of the default path char *xcursorPath = std::getenv("XCURSOR_PATH"); if (xcursorPath) path = xcursorPath; #else // Get the search path from Xcursor QString path = XcursorLibraryPath(); #endif // Separate the paths baseDirs = path.split(':', QString::SkipEmptyParts); // Remove duplicates QMutableStringListIterator i(baseDirs); while (i.hasNext()) { const QString path = i.next(); QMutableStringListIterator j(i); while (j.hasNext()) if (j.next() == path) j.remove(); } // Expand all occurrences of ~/ to the home dir baseDirs.replaceInStrings(QRegExp("^~\\/"), QDir::home().path() + '/'); return baseDirs; }
GtkListStore * mouse_settings_themes_populate_store (void) { const gchar *path; gchar **basedirs; gint i; gchar *homedir; GDir *dir; const gchar *theme; gchar *filename; gchar *index_file; GKeyFile *rc; const gchar *name; const gchar *comment; GtkTreeIter iter; gint position = 0; GdkPixbuf *pixbuf; gchar *active_theme = NULL; GtkTreePath *active_path = NULL; GtkListStore *store; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GObject *treeview; GtkTreeSelection *selection; gchar *comment_escaped; /* get the cursor paths */ #if XCURSOR_LIB_MAJOR == 1 && XCURSOR_LIB_MINOR < 1 path = "~/.icons:/usr/share/icons:/usr/share/pixmaps:/usr/X11R6/lib/X11/icons"; #else path = XcursorLibraryPath (); #endif /* split the paths */ basedirs = g_strsplit (path, ":", -1); /* get the active theme */ //active_theme = xfconf_channel_get_string (xsettings_channel, "/Gtk/CursorThemeName", "default"); /* create the store */ store = gtk_list_store_new (N_THEME_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); /* insert default */ gtk_list_store_insert_with_values (store, &iter, position++, COLUMN_THEME_NAME, "default", COLUMN_THEME_DISPLAY_NAME, _("Default"), -1); /* store the default path, so we always select a theme */ active_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); if (G_LIKELY (basedirs)) { /* walk the base directories */ for (i = 0; basedirs[i] != NULL; i++) { /* init */ homedir = NULL; /* parse the homedir if needed */ if (strstr (basedirs[i], "~/") != NULL) path = homedir = g_strconcat (g_get_home_dir (), basedirs[i] + 1, NULL); else path = basedirs[i]; /* open directory */ dir = g_dir_open (path, 0, NULL); if (G_LIKELY (dir)) { for (;;) { /* get the directory name */ theme = g_dir_read_name (dir); if (G_UNLIKELY (theme == NULL)) break; /* build the full cursor path */ filename = g_build_filename (path, theme, "cursors", NULL); /* check if it looks like a cursor theme */ if (g_file_test (filename, G_FILE_TEST_IS_DIR)) { /* try to load a pixbuf */ pixbuf = mouse_settings_themes_preview_icon (filename); /* insert in the store */ gtk_list_store_insert_with_values (store, &iter, position++, COLUMN_THEME_PIXBUF, pixbuf, COLUMN_THEME_NAME, theme, COLUMN_THEME_DISPLAY_NAME, theme, COLUMN_THEME_PATH, filename, -1); /* check if this is the active theme, set the path */ if (active_theme && strcmp (active_theme, theme) == 0) { gtk_tree_path_free (active_path); active_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); } /* release pixbuf */ if (G_LIKELY (pixbuf)) g_object_unref (G_OBJECT (pixbuf)); /* check for a index.theme file for additional information */ index_file = g_build_filename (path, theme, "index.theme", NULL); if (g_file_test (index_file, G_FILE_TEST_IS_REGULAR)) { /* open theme desktop file */ rc = g_key_file_new (); if (G_LIKELY (g_key_file_load_from_file (rc, index_file, G_KEY_FILE_NONE, NULL))) { /* check for the theme group */ if (g_key_file_has_group (rc, "Icon Theme")) { /* read values */ name = g_key_file_get_string (rc, "Icon Theme", "Name", NULL); comment = g_key_file_get_string (rc, "Icon Theme", "Comment", NULL); /* escape the comment */ comment_escaped = comment ? g_markup_escape_text (comment, -1) : NULL; /* update store */ gtk_list_store_set (store, &iter, COLUMN_THEME_DISPLAY_NAME, name, COLUMN_THEME_COMMENT, comment_escaped, -1); /* cleanup */ g_free (comment_escaped); } /* close rc file */ g_key_file_free (rc); } } /* cleanup */ g_free (index_file); } /* cleanup */ g_free (filename); } /* close directory */ g_dir_close (dir); } /* cleanup */ g_free (homedir); } /* cleanup */ g_strfreev (basedirs); } /* cleanup */ g_free (active_theme); /* setup the columns */ renderer = gtk_cell_renderer_pixbuf_new (); column = gtk_tree_view_column_new_with_attributes ("", renderer, "pixbuf", COLUMN_THEME_PIXBUF, NULL); renderer = gtk_cell_renderer_text_new (); g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); /* sort the store */ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), COLUMN_THEME_DISPLAY_NAME, mouse_settings_themes_sort_func, NULL, NULL); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), COLUMN_THEME_DISPLAY_NAME, GTK_SORT_ASCENDING); /* release the store */ return store; }