5 /* TODO: add no_display check, as we might want only displayable items */
10 #elif defined __GNUC__
11 # define alloca __builtin_alloca
13 # define alloca __alloca
14 #elif defined _MSC_VER
16 # define alloca _alloca
22 void *alloca (size_t);
27 #include <Ecore_File.h>
29 /* define macros and variable for using the eina logging system */
30 #define EFREET_MODULE_LOG_DOM _efreet_utils_log_dom
31 static int _efreet_utils_log_dom = -1;
34 #include "efreet_private.h"
36 static char *efreet_util_path_in_default(const char *section, const char *path);
38 static int efreet_util_glob_match(const char *str, const char *glob);
40 static Eina_List *efreet_util_menus_find_helper(Eina_List *menus, const char *config_dir);
42 static Efreet_Desktop *efreet_util_cache_find(const char *search, const char *what1, const char *what2);
43 static Eina_List *efreet_util_cache_list(const char *search, const char *what);
44 static Eina_List *efreet_util_cache_glob_list(const char *search, const char *what);
46 static Eina_Hash *file_id_by_desktop_path = NULL;
51 efreet_util_init(void)
53 if (init++) return init;
54 _efreet_utils_log_dom = eina_log_domain_register
55 ("efreet_util", EFREET_DEFAULT_LOG_COLOR);
56 if (_efreet_utils_log_dom < 0)
58 EINA_LOG_ERR("Efreet: Could not create a log domain for efreet_util");
62 file_id_by_desktop_path = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
68 efreet_util_shutdown(void)
70 if (--init) return init;
72 eina_log_domain_unregister(_efreet_utils_log_dom);
73 _efreet_utils_log_dom = -1;
74 IF_FREE_HASH(file_id_by_desktop_path);
80 efreet_util_path_in_default(const char *section, const char *path)
86 dirs = efreet_default_dirs_get(efreet_data_home_get(), efreet_data_dirs_get(),
89 EINA_LIST_FREE(dirs, dir)
91 if (!strncmp(path, dir, strlen(dir)))
94 eina_stringshare_del(dir);
101 efreet_util_path_to_file_id(const char *path)
108 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
110 file_id = eina_hash_find(file_id_by_desktop_path, path);
111 if (file_id) return file_id;
113 base = efreet_util_path_in_default("applications", path);
114 if (!base) return NULL;
117 if (strlen(path) <= len)
119 eina_stringshare_del(base);
122 if (strncmp(path, base, len))
124 eina_stringshare_del(base);
128 len2 = strlen(path + len + 1) + 1;
130 memcpy(tmp, path + len + 1, len2);
134 if (*p == '/') *p = '-';
137 eina_stringshare_del(base);
138 file_id = eina_stringshare_add(tmp);
139 eina_hash_add(file_id_by_desktop_path, path, (void *)file_id);
144 efreet_util_desktop_mime_list(const char *mime)
146 EINA_SAFETY_ON_NULL_RETURN_VAL(mime, NULL);
147 return efreet_util_cache_list("mime_types", mime);
150 EAPI Efreet_Desktop *
151 efreet_util_desktop_wm_class_find(const char *wmname, const char *wmclass)
153 EINA_SAFETY_ON_TRUE_RETURN_VAL((!wmname) && (!wmclass), NULL);
154 return efreet_util_cache_find("startup_wm_class", wmname, wmclass);
157 EAPI Efreet_Desktop *
158 efreet_util_desktop_file_id_find(const char *file_id)
160 Efreet_Cache_Hash *hash;
161 Efreet_Desktop *ret = NULL;
164 EINA_SAFETY_ON_NULL_RETURN_VAL(file_id, NULL);
166 hash = efreet_cache_util_hash_string("file_id");
167 if (!hash) return NULL;
168 str = eina_hash_find(hash->hash, file_id);
170 ret = efreet_desktop_get(str);
174 EAPI Efreet_Desktop *
175 efreet_util_desktop_exec_find(const char *exec)
177 Efreet_Cache_Hash *hash = NULL;
178 Efreet_Desktop *ret = NULL;
179 Efreet_Cache_Array_String *names = NULL;
182 EINA_SAFETY_ON_NULL_RETURN_VAL(exec, NULL);
184 names = efreet_cache_util_names("exec_list");
185 if (!names) return NULL;
186 for (i = 0; i < names->array_count; i++)
191 Efreet_Cache_Array_String *array;
193 exe = ecore_file_app_exe_get(names->array[i]);
195 file = ecore_file_file_get(exe);
197 if (strcmp(exec, exe) && strcmp(exec, file))
205 hash = efreet_cache_util_hash_array_string("exec_hash");
206 if (!hash) return NULL;
207 array = eina_hash_find(hash->hash, names->array[i]);
208 if (!array) continue;
209 for (j = 0; j < array->array_count; j++)
211 ret = efreet_desktop_get(array->array[j]);
219 EAPI Efreet_Desktop *
220 efreet_util_desktop_name_find(const char *name)
222 EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
223 return efreet_util_cache_find("name", name, NULL);
226 EAPI Efreet_Desktop *
227 efreet_util_desktop_generic_name_find(const char *generic_name)
229 EINA_SAFETY_ON_NULL_RETURN_VAL(generic_name, NULL);
230 return efreet_util_cache_find("generic_name", generic_name, NULL);
234 efreet_util_desktop_name_glob_list(const char *glob)
236 EINA_SAFETY_ON_NULL_RETURN_VAL(glob, NULL);
237 return efreet_util_cache_glob_list("name", glob);
241 efreet_util_desktop_exec_glob_list(const char *glob)
243 Efreet_Cache_Hash *hash = NULL;
244 Eina_List *ret = NULL;
245 Efreet_Cache_Array_String *names = NULL;
248 EINA_SAFETY_ON_NULL_RETURN_VAL(glob, NULL);
250 if (!strcmp(glob, "*"))
253 names = efreet_cache_util_names("exec_list");
254 if (!names) return NULL;
255 for (i = 0; i < names->array_count; i++)
257 Efreet_Cache_Array_String *array;
260 Efreet_Desktop *desk;
262 exe = ecore_file_app_exe_get(names->array[i]);
264 if (glob && !efreet_util_glob_match(exe, glob))
272 hash = efreet_cache_util_hash_array_string("exec_hash");
273 if (!hash) return NULL;
275 array = eina_hash_find(hash->hash, names->array[i]);
276 if (!array) continue;
277 for (j = 0; j < array->array_count; j++)
279 desk = efreet_desktop_get(array->array[j]);
281 ret = eina_list_append(ret, desk);
288 efreet_util_desktop_generic_name_glob_list(const char *glob)
290 EINA_SAFETY_ON_NULL_RETURN_VAL(glob, NULL);
291 return efreet_util_cache_glob_list("generic_name", glob);
295 efreet_util_desktop_comment_glob_list(const char *glob)
297 EINA_SAFETY_ON_NULL_RETURN_VAL(glob, NULL);
298 return efreet_util_cache_glob_list("comment", glob);
302 efreet_util_desktop_categories_list(void)
304 Efreet_Cache_Array_String *array;
305 Eina_List *ret = NULL;
308 array = efreet_cache_util_names("categories_list");
309 if (!array) return NULL;
310 for (i = 0; i < array->array_count; i++)
311 ret = eina_list_append(ret, array->array[i]);
316 efreet_util_desktop_category_list(const char *category)
318 EINA_SAFETY_ON_NULL_RETURN_VAL(category, NULL);
319 return efreet_util_cache_list("categories", category);
323 efreet_util_glob_match(const char *str, const char *glob)
329 if (str[0] == '\0') return 1;
332 if (!strcmp(glob, "*")) return 1;
333 if (!fnmatch(glob, str, 0)) return 1;
338 efreet_util_menus_find(void)
340 Eina_List *menus = NULL;
344 menus = efreet_util_menus_find_helper(menus, efreet_config_home_get());
346 dirs = efreet_config_dirs_get();
347 EINA_LIST_FOREACH(dirs, l, dir)
348 menus = efreet_util_menus_find_helper(menus, dir);
354 efreet_util_menus_find_helper(Eina_List *menus, const char *config_dir)
357 Eina_File_Direct_Info *info;
360 snprintf(dbuf, sizeof(dbuf), "%s/menus", config_dir);
361 it = eina_file_direct_ls(dbuf);
362 if (!it) return menus;
363 EINA_ITERATOR_FOREACH(it, info)
366 exten = strrchr(info->path + info->name_start, '.');
367 if (!exten) continue;
368 if (strcmp(".menu", exten)) continue;
370 if (ecore_file_is_dir(info->path)) continue;
372 menus = eina_list_append(menus, strdup(info->path));
374 eina_iterator_free(it);
378 static Efreet_Desktop *
379 efreet_util_cache_find(const char *search, const char *what1, const char *what2)
381 Efreet_Cache_Hash *hash;
382 Efreet_Desktop *ret = NULL;
383 Efreet_Cache_Array_String *array = NULL;
386 if ((!what1) && (!what2)) return NULL;
388 snprintf(key, sizeof(key), "%s_hash", search);
389 hash = efreet_cache_util_hash_array_string(key);
390 if (!hash) return NULL;
392 array = eina_hash_find(hash->hash, what1);
393 if (!array && what2) array = eina_hash_find(hash->hash, what2);
398 for (i = 0; i < array->array_count; i++)
400 ret = efreet_desktop_get(array->array[i]);
408 efreet_util_cache_list(const char *search, const char *what)
410 Efreet_Cache_Hash *hash;
411 Efreet_Cache_Array_String *array;
412 Eina_List *ret = NULL;
415 if (!what) return NULL;
417 snprintf(key, sizeof(key), "%s_hash", search);
418 hash = efreet_cache_util_hash_array_string(key);
419 if (!hash) return NULL;
420 array = eina_hash_find(hash->hash, what);
424 Efreet_Desktop *desk;
426 for (i = 0; i < array->array_count; i++)
428 desk = efreet_desktop_get(array->array[i]);
430 ret = eina_list_append(ret, desk);
437 efreet_util_cache_glob_list(const char *search, const char *what)
439 Efreet_Cache_Hash *hash = NULL;
440 Eina_List *ret = NULL;
441 Efreet_Cache_Array_String *names = NULL;
445 if (!what) return NULL;
446 if (!strcmp(what, "*"))
449 snprintf(key, sizeof(key), "%s_list", search);
450 names = efreet_cache_util_names(key);
451 if (!names) return NULL;
452 for (i = 0; i < names->array_count; i++)
454 Efreet_Cache_Array_String *array;
456 Efreet_Desktop *desk;
458 if (what && !efreet_util_glob_match(names->array[i], what)) continue;
462 snprintf(key, sizeof(key), "%s_hash", search);
463 hash = efreet_cache_util_hash_array_string(key);
465 if (!hash) return NULL;
467 array = eina_hash_find(hash->hash, names->array[i]);
468 if (!array) continue;
469 for (j = 0; j < array->array_count; j++)
471 desk = efreet_desktop_get(array->array[j]);
473 ret = eina_list_append(ret, desk);
480 * Needs EAPI because of helper binaries
483 efreet_hash_free(Eina_Hash *hash, Eina_Free_Cb free_cb)
485 eina_hash_free_cb_set(hash, free_cb);
486 eina_hash_free(hash);