1 /* vim: set sw=4 ts=4 sts=4 et: */
3 #include "efreet_private.h"
5 typedef struct Efreet_Cache_Fill Efreet_Cache_Fill;
6 typedef struct Efreet_Cache_Fill_Dir Efreet_Cache_Fill_Dir;
7 typedef struct Efreet_Cache_Search Efreet_Cache_Search;
8 typedef struct Efreet_Cache_Search_List Efreet_Cache_Search_List;
9 typedef struct Efreet_Monitor Efreet_Monitor;
10 typedef struct Efreet_Util_Desktop Efreet_Util_Desktop;
12 struct Efreet_Cache_Fill
15 Efreet_Cache_Fill_Dir *current;
19 struct Efreet_Cache_Fill_Dir
26 struct Efreet_Cache_Search
28 Efreet_Util_Desktop *result;
33 struct Efreet_Cache_Search_List
42 Ecore_File_Monitor *monitor;
46 struct Efreet_Util_Desktop
48 Efreet_Desktop *desktop;
52 static char *efreet_util_path_in_default(const char *section, const char *path);
54 static int efreet_util_cache_fill(void *data);
55 static void efreet_util_cache_add(const char *path, const char *file_id, int priority, int event);
56 static void efreet_util_cache_remove(const char *path, const char *file_id, int priority);
57 static void efreet_util_cache_reload(const char *path, const char *file_id, int priority);
58 static void efreet_util_cache_dir_free(void *data);
60 static Eina_Bool efreet_util_cache_search_mime(const Eina_Hash *hash, void *value, void *fdata);
61 static Eina_Bool efreet_util_cache_search_wm_class(const Eina_Hash *hash, void *value, void *fdata);
62 static Eina_Bool efreet_util_cache_search_exec(const Eina_Hash *hash, void *value, void *fdata);
63 static Eina_Bool efreet_util_cache_search_name(const Eina_Hash *hash, void *value, void *fdata);
64 static Eina_Bool efreet_util_cache_search_generic_name(const Eina_Hash *hash, void *value, void *fdata);
66 static Eina_Bool efreet_util_cache_search_name_glob(const Eina_Hash *hash, void *value, void *fdata);
67 static Eina_Bool efreet_util_cache_search_exec_glob(const Eina_Hash *hash, void *value, void *fdata);
68 static Eina_Bool efreet_util_cache_search_generic_name_glob(const Eina_Hash *hash, void *value, void *fdata);
69 static Eina_Bool efreet_util_cache_search_comment_glob(const Eina_Hash *hash, void *value, void *fdata);
71 static int efreet_util_glob_match(const char *str, const char *glob);
73 static void efreet_util_monitor(const char *path, const char *file_id, int priority);
74 static void efreet_util_monitor_cb(void *data, Ecore_File_Monitor *monitor,
75 Ecore_File_Event event, const char *path);
76 static void efreet_util_monitor_free(void *data);
77 static void efreet_util_menus_find_helper(Eina_List *menus, const char *config_dir);
79 static void efreet_util_desktops_by_category_add(Efreet_Desktop *desktop);
80 static void efreet_util_desktops_by_category_remove(Efreet_Desktop *desktop);
82 static void efreet_util_desktop_free(Efreet_Util_Desktop *ud);
83 static void efreet_event_desktop_change_free(void *data, void *ev);
85 static Eina_Hash *desktop_by_file_id = NULL;
86 static Eina_Hash *file_id_by_desktop_path = NULL;
87 static Eina_Hash *desktops_by_category = NULL;
89 static Ecore_Idler *idler = NULL;
90 static Efreet_Cache_Fill *fill = NULL;
92 static Eina_List *monitors = NULL;
96 EAPI int EFREET_EVENT_DESKTOP_LIST_CHANGE = 0;
97 EAPI int EFREET_EVENT_DESKTOP_CHANGE = 0;
100 efreet_util_init(void)
104 if (init++) return init;
106 if (!EFREET_EVENT_DESKTOP_LIST_CHANGE)
107 EFREET_EVENT_DESKTOP_LIST_CHANGE = ecore_event_type_new();
108 if (!EFREET_EVENT_DESKTOP_CHANGE)
109 EFREET_EVENT_DESKTOP_CHANGE = ecore_event_type_new();
110 desktop_by_file_id = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_util_desktop_free));
111 file_id_by_desktop_path = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
112 desktops_by_category = eina_hash_string_superfast_new(EINA_FREE_CB(eina_list_free));
116 fill = NEW(Efreet_Cache_Fill, 1);
117 dirs = efreet_default_dirs_get(efreet_data_home_get(), efreet_data_dirs_get(),
121 Efreet_Cache_Fill_Dir *dir;
127 path = eina_list_data_get(dirs);
128 dir = NEW(Efreet_Cache_Fill_Dir, 1);
130 dir->priority = priority++;
131 fill->dirs = eina_list_append(fill->dirs, dir);
132 dirs = eina_list_remove_list(dirs, dirs);
135 idler = ecore_idler_add(efreet_util_cache_fill, NULL);
140 efreet_util_shutdown(void)
143 Efreet_Cache_Fill_Dir *dir;
145 if (--init) return init;
149 ecore_idler_del(idler);
152 dir = eina_list_data_get(fill->dirs);
153 efreet_util_cache_dir_free(dir);
154 fill->dirs = eina_list_remove_list(fill->dirs, fill->dirs);
157 if (fill->current) efreet_util_cache_dir_free(fill->current);
158 if (fill->files) closedir(fill->files);
163 IF_FREE_HASH(desktop_by_file_id);
164 IF_FREE_HASH(file_id_by_desktop_path);
168 em = eina_list_data_get(monitors);
169 efreet_util_monitor_free(em);
170 monitors = eina_list_remove_list(monitors, monitors);
173 IF_FREE_HASH(desktops_by_category);
179 efreet_util_path_in_default(const char *section, const char *path)
185 dirs = efreet_default_dirs_get(efreet_data_home_get(), efreet_data_dirs_get(),
188 EINA_LIST_FREE(dirs, dir)
193 if (!strncmp(path, dir, strlen(dir)))
201 EINA_LIST_FREE(dirs, dir)
202 if (ret != dir) free(dir);
208 efreet_util_path_to_file_id(const char *path)
213 const char *file_id = NULL;
215 if (!path) return NULL;
216 file_id = eina_hash_find(file_id_by_desktop_path, path);
217 if (file_id) return file_id;
219 base = efreet_util_path_in_default("applications", path);
220 if (!base) return NULL;
223 if (strlen(path) <= len)
228 if (strncmp(path, base, len))
234 tmp = strdup(path + len + 1);
238 if (*p == '/') *p = '-';
242 file_id = eina_stringshare_add(tmp);
244 eina_hash_del(file_id_by_desktop_path, path, NULL);
245 eina_hash_add(file_id_by_desktop_path, path, (void *)file_id);
250 efreet_util_desktop_mime_list(const char *mime)
252 Efreet_Cache_Search_List search;
256 search.what = eina_stringshare_add(mime);
258 it = eina_hash_iterator_data_new(desktop_by_file_id);
259 eina_iterator_foreach(it, EINA_EACH(efreet_util_cache_search_mime), &search);
260 eina_iterator_free(it);
262 eina_stringshare_del(search.what);
267 EAPI Efreet_Desktop *
268 efreet_util_desktop_wm_class_find(const char *wmname, const char *wmclass)
270 Efreet_Cache_Search search;
271 Efreet_Util_Desktop *ud;
274 if ((!wmname) && (!wmclass)) return NULL;
275 search.what1 = wmname;
276 search.what2 = wmclass;
277 search.result = NULL;
279 it = eina_hash_iterator_data_new(desktop_by_file_id);
280 eina_iterator_foreach(it, EINA_EACH(efreet_util_cache_search_wm_class), &search);
281 eina_iterator_free(it);
286 efreet_desktop_ref(ud->desktop);
292 EAPI Efreet_Desktop *
293 efreet_util_desktop_file_id_find(const char *file_id)
295 Efreet_Desktop *desktop = NULL;
296 Efreet_Util_Desktop *ud = NULL;
301 if (!file_id) return NULL;
302 ud = eina_hash_find(desktop_by_file_id, file_id);
303 if (ud) return ud->desktop;
305 dirs = efreet_default_dirs_get(efreet_data_home_get(), efreet_data_dirs_get(),
307 if (!dirs) return NULL;
309 EINA_LIST_FOREACH(dirs, l, dir)
314 tmp = strdup(file_id);
319 snprintf(buf, sizeof(buf), "%s/%s", dir, tmp);
320 desktop = efreet_desktop_get(buf);
331 free(eina_list_data_get(dirs));
332 dirs = eina_list_remove_list(dirs, dirs);
336 Efreet_Event_Desktop_Change *ev;
338 ud = NEW(Efreet_Util_Desktop, 1);
339 ud->priority = priority;
340 ud->desktop = desktop;
342 eina_hash_del(desktop_by_file_id, file_id, NULL);
343 eina_hash_add(desktop_by_file_id, file_id, ud);
344 efreet_util_desktops_by_category_add(desktop);
346 ev = NEW(Efreet_Event_Desktop_Change, 1);
347 ev->current = desktop;
348 efreet_desktop_ref(ev->current);
349 ev->change = EFREET_DESKTOP_CHANGE_ADD;
350 ecore_event_add(EFREET_EVENT_DESKTOP_CHANGE, ev, efreet_event_desktop_change_free, NULL);
355 EAPI Efreet_Desktop *
356 efreet_util_desktop_exec_find(const char *exec)
358 Efreet_Cache_Search search;
361 if (!exec) return NULL;
364 search.result = NULL;
366 it = eina_hash_iterator_data_new(desktop_by_file_id);
367 eina_iterator_foreach(it, EINA_EACH(efreet_util_cache_search_exec), &search);
368 eina_iterator_free(it);
370 if (!search.result) return NULL;
372 efreet_desktop_ref(search.result->desktop);
373 return search.result->desktop;
376 EAPI Efreet_Desktop *
377 efreet_util_desktop_name_find(const char *name)
379 Efreet_Cache_Search search;
382 if (!name) return NULL;
385 search.result = NULL;
387 it = eina_hash_iterator_data_new(desktop_by_file_id);
388 eina_iterator_foreach(it, EINA_EACH(efreet_util_cache_search_name), &search);
389 eina_iterator_free(it);
391 if (!search.result) return NULL;
393 efreet_desktop_ref(search.result->desktop);
394 return search.result->desktop;
397 EAPI Efreet_Desktop *
398 efreet_util_desktop_generic_name_find(const char *generic_name)
400 Efreet_Cache_Search search;
403 if (!generic_name) return NULL;
404 search.what1 = generic_name;
406 search.result = NULL;
408 it = eina_hash_iterator_data_new(desktop_by_file_id);
409 eina_iterator_foreach(it, EINA_EACH(efreet_util_cache_search_generic_name), &search);
410 eina_iterator_free(it);
412 if (!search.result) return NULL;
414 efreet_desktop_ref(search.result->desktop);
415 return search.result->desktop;
419 efreet_util_desktop_name_glob_list(const char *glob)
421 Efreet_Cache_Search_List search;
427 it = eina_hash_iterator_data_new(desktop_by_file_id);
428 eina_iterator_foreach(it, EINA_EACH(efreet_util_cache_search_name_glob), &search);
429 eina_iterator_free(it);
435 efreet_util_desktop_exec_glob_list(const char *glob)
437 Efreet_Cache_Search_List search;
443 it = eina_hash_iterator_data_new(desktop_by_file_id);
444 eina_iterator_foreach(it, EINA_EACH(efreet_util_cache_search_exec_glob), &search);
445 eina_iterator_free(it);
451 efreet_util_desktop_generic_name_glob_list(const char *glob)
453 Efreet_Cache_Search_List search;
459 it = eina_hash_iterator_data_new(desktop_by_file_id);
460 eina_iterator_foreach(it, EINA_EACH(efreet_util_cache_search_generic_name_glob), &search);
461 eina_iterator_free(it);
467 efreet_util_desktop_comment_glob_list(const char *glob)
469 Efreet_Cache_Search_List search;
475 it = eina_hash_iterator_data_new(desktop_by_file_id);
476 eina_iterator_foreach(it, EINA_EACH(efreet_util_cache_search_comment_glob), &search);
477 eina_iterator_free(it);
483 _hash_keys(Eina_Hash *hash __UNUSED__, const void *key, void *fdata)
485 Eina_List **l = fdata;
487 *l = eina_list_append(*l, key);
492 * Find all desktop categories
493 * This list must be freed using ecore_list_destroy()
495 * @return an Eina_List of category names (const char *)
498 efreet_util_desktop_categories_list(void)
501 Eina_List *list = NULL;
503 it = eina_hash_iterator_key_new(desktops_by_category);
506 eina_iterator_foreach(it, EINA_EACH(_hash_keys), &list);
507 eina_iterator_free(it);
514 * Find all desktops in a given category
516 * Note: this returns a pointer to an internal list. Do not add to, remove from, or delete this list.
518 * @param category the category name
519 * @return a list of desktops
522 efreet_util_desktop_category_list(const char *category)
524 return eina_hash_find(desktops_by_category, category);
529 dump(Eina_Hash *hash, const char *key, void *value, __UNUSED__ void *data)
531 printf("%s -> %p\n", (char *)key, value);
536 efreet_util_cache_fill(__UNUSED__ void *data)
538 Efreet_Cache_Fill_Dir *dir;
539 struct dirent *file = NULL;
543 if ((!fill->dirs) && (!fill->files))
548 efreet_cache_clear();
549 ecore_event_add(EFREET_EVENT_DESKTOP_LIST_CHANGE, NULL, NULL, NULL);
555 fill->current = eina_list_data_get(fill->dirs);
556 fill->dirs = eina_list_remove_list(fill->dirs, fill->dirs);
561 dir = eina_list_data_get(fill->dirs);
562 efreet_util_cache_dir_free(dir);
563 fill->dirs = eina_list_remove_list(fill->dirs, fill->dirs);
570 eina_hash_foreach(desktop_by_file_id, dump, NULL);
571 eina_hash_foreach(file_id_by_desktop_path, dump, NULL);
572 printf("%d\n", eina_hash_population(desktop_by_file_id));
574 efreet_cache_clear();
575 ecore_event_add(EFREET_EVENT_DESKTOP_LIST_CHANGE, NULL, NULL, NULL);
581 start = ecore_time_get();
584 fill->files = opendir(fill->current->path);
588 /* Couldn't open this dir, continue to next */
589 efreet_util_cache_dir_free(fill->current);
590 fill->current = NULL;
596 char file_id[PATH_MAX];
598 file = readdir(fill->files);
600 if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) continue;
602 snprintf(buf, PATH_MAX, "%s/%s", fill->current->path, file->d_name);
603 if (fill->current->file_id)
604 snprintf(file_id, PATH_MAX, "%s-%s", fill->current->file_id, file->d_name);
606 strcpy(file_id, file->d_name);
608 if (ecore_file_is_dir(buf))
610 Efreet_Cache_Fill_Dir *dir;
612 dir = NEW(Efreet_Cache_Fill_Dir, 1);
613 dir->path = strdup(buf);
614 dir->file_id = strdup(file_id);
615 dir->priority = fill->current->priority;
616 fill->dirs = eina_list_append(fill->dirs, dir);
619 efreet_util_cache_add(buf, file_id, fill->current->priority, 0);
620 } while ((ecore_time_get() - start) < 0.01);
624 /* This dir has been search through */
625 efreet_util_monitor(fill->current->path, fill->current->file_id,
626 fill->current->priority);
627 efreet_util_cache_dir_free(fill->current);
628 fill->current = NULL;
629 closedir(fill->files);
638 efreet_util_cache_add(const char *path, const char *file_id, int priority, int event)
640 Efreet_Desktop *desktop;
641 Efreet_Util_Desktop *ud;
644 ext = strrchr(path, '.');
645 if (!ext || strcmp(ext, ".desktop")) return;
646 desktop = efreet_desktop_get(path);
648 if (!desktop || desktop->type != EFREET_DESKTOP_TYPE_APPLICATION)
650 if (desktop) efreet_desktop_free(desktop);
654 if (!eina_hash_find(file_id_by_desktop_path, desktop->orig_path))
656 eina_hash_add(file_id_by_desktop_path,
658 (void *)eina_stringshare_add(file_id));
662 ud = eina_hash_find(desktop_by_file_id, file_id);
665 ud = NEW(Efreet_Util_Desktop, 1);
666 ud->priority = priority;
667 ud->desktop = desktop;
669 eina_hash_add(desktop_by_file_id, file_id, ud);
670 efreet_util_desktops_by_category_add(desktop);
674 Efreet_Event_Desktop_Change *ev;
676 ev = NEW(Efreet_Event_Desktop_Change, 1);
677 ev->current = desktop;
678 efreet_desktop_ref(ev->current);
679 ev->change = EFREET_DESKTOP_CHANGE_ADD;
680 efreet_cache_clear();
681 ecore_event_add(EFREET_EVENT_DESKTOP_CHANGE, ev, efreet_event_desktop_change_free, NULL);
684 else if (priority < ud->priority)
686 efreet_util_desktops_by_category_remove(ud->desktop);
687 efreet_util_desktops_by_category_add(desktop);
691 Efreet_Event_Desktop_Change *ev;
693 ev = NEW(Efreet_Event_Desktop_Change, 1);
694 ev->current = desktop;
695 efreet_desktop_ref(ev->current);
696 ev->previous = ud->desktop;
697 efreet_desktop_ref(ev->previous);
698 ev->change = EFREET_DESKTOP_CHANGE_UPDATE;
699 efreet_desktop_free(ud->desktop);
700 ud->desktop = desktop;
701 efreet_cache_clear();
702 ecore_event_add(EFREET_EVENT_DESKTOP_CHANGE, ev, efreet_event_desktop_change_free, NULL);
706 efreet_desktop_free(ud->desktop);
707 ud->desktop = desktop;
711 efreet_desktop_free(desktop);
715 efreet_util_cache_remove(const char *path, const char *file_id, int priority)
717 Efreet_Util_Desktop *ud;
720 ext = strrchr(path, '.');
721 if (!ext || strcmp(ext, ".desktop")) return;
722 ud = eina_hash_find(desktop_by_file_id, file_id);
723 if (ud && (ud->priority >= priority))
725 Efreet_Event_Desktop_Change *ev;
727 efreet_util_desktops_by_category_remove(ud->desktop);
729 ev = NEW(Efreet_Event_Desktop_Change, 1);
730 ev->current = ud->desktop;
731 efreet_desktop_ref(ev->current);
732 ev->change = EFREET_DESKTOP_CHANGE_REMOVE;
733 efreet_cache_clear();
734 ecore_event_add(EFREET_EVENT_DESKTOP_CHANGE, ev, efreet_event_desktop_change_free, NULL);
736 eina_hash_del(desktop_by_file_id, file_id, ud);
738 /* This call will search application dirs and add the file to cache if it
740 efreet_util_desktop_file_id_find(file_id);
742 eina_hash_del(file_id_by_desktop_path, path, eina_hash_find(file_id_by_desktop_path, path));
746 efreet_util_cache_reload(const char *path, const char *file_id, int priority)
748 Efreet_Desktop *desktop;
749 Efreet_Util_Desktop *ud;
752 ext = strrchr(path, '.');
753 if (!ext || strcmp(ext, ".desktop")) return;
754 desktop = efreet_desktop_get(path);
756 if (!desktop || desktop->type != EFREET_DESKTOP_TYPE_APPLICATION)
758 if (desktop) efreet_desktop_free(desktop);
762 ud = eina_hash_find(desktop_by_file_id, file_id);
765 Efreet_Event_Desktop_Change *ev;
767 if (ud->priority < priority)
769 efreet_desktop_free(desktop);
773 efreet_util_desktops_by_category_remove(ud->desktop);
774 efreet_util_desktops_by_category_add(desktop);
776 ev = NEW(Efreet_Event_Desktop_Change, 1);
777 ev->current = desktop;
778 efreet_desktop_ref(ev->current);
779 ev->previous = ud->desktop;
780 efreet_desktop_ref(ev->previous);
781 ev->change = EFREET_DESKTOP_CHANGE_UPDATE;
782 efreet_cache_clear();
783 ecore_event_add(EFREET_EVENT_DESKTOP_CHANGE, ev, efreet_event_desktop_change_free, NULL);
785 efreet_desktop_free(ud->desktop);
786 ud->desktop = desktop;
790 Efreet_Event_Desktop_Change *ev;
792 ud = NEW(Efreet_Util_Desktop, 1);
793 ud->priority = priority;
794 ud->desktop = desktop;
796 eina_hash_add(desktop_by_file_id, file_id, ud);
797 efreet_util_desktops_by_category_remove(ud->desktop);
798 efreet_util_desktops_by_category_add(desktop);
800 ev = NEW(Efreet_Event_Desktop_Change, 1);
801 ev->current = desktop;
802 efreet_desktop_ref(ev->current);
803 ev->change = EFREET_DESKTOP_CHANGE_ADD;
804 efreet_cache_clear();
805 ecore_event_add(EFREET_EVENT_DESKTOP_CHANGE, ev, efreet_event_desktop_change_free, NULL);
810 efreet_util_cache_dir_free(void *data)
812 Efreet_Cache_Fill_Dir *dir;
816 IF_FREE(dir->file_id);
821 efreet_util_cache_search_mime(__UNUSED__ const Eina_Hash *hash, void *value, void *fdata)
823 Efreet_Cache_Search_List *search;
824 Efreet_Util_Desktop *ud;
831 if (!ud->desktop->mime_types) return EINA_TRUE;
832 EINA_LIST_FOREACH(ud->desktop->mime_types, l, mime)
833 if (search->what == mime)
835 efreet_desktop_ref(ud->desktop);
836 search->list = eina_list_append(search->list, ud->desktop);
843 efreet_util_cache_search_wm_class(__UNUSED__ const Eina_Hash *hash, void *value, void *fdata)
845 Efreet_Cache_Search *search;
846 Efreet_Util_Desktop *ud;
851 if (!ud->desktop) return EINA_TRUE;
852 if (!ud->desktop->startup_wm_class) return EINA_TRUE;
853 if ((search->what2) && (!strcmp(ud->desktop->startup_wm_class, search->what2)))
858 else if ((search->what1) && (!strcmp(ud->desktop->startup_wm_class, search->what1)))
867 efreet_util_cache_search_exec(__UNUSED__ const Eina_Hash *hash, void *value, void *fdata)
869 Efreet_Cache_Search *search;
870 Efreet_Util_Desktop *ud;
877 if (!ud->desktop->exec) return EINA_TRUE;
878 exec = ecore_file_app_exe_get(ud->desktop->exec);
879 if (!exec) return EINA_TRUE;
880 if (!strcmp(exec, search->what1))
887 file = ecore_file_file_get(exec);
888 if (file && !strcmp(file, search->what1))
899 efreet_util_cache_search_name(__UNUSED__ const Eina_Hash *hash, void *value, void *fdata)
901 Efreet_Cache_Search *search;
902 Efreet_Util_Desktop *ud;
907 if (!ud->desktop->name) return EINA_TRUE;
908 if (!strcmp(ud->desktop->name, search->what1))
917 efreet_util_cache_search_generic_name(__UNUSED__ const Eina_Hash *hash, void *value, void *fdata)
919 Efreet_Cache_Search *search;
920 Efreet_Util_Desktop *ud;
925 if (!ud->desktop->generic_name) return EINA_TRUE;
926 if (!strcmp(ud->desktop->generic_name, search->what1))
935 efreet_util_cache_search_name_glob(__UNUSED__ const Eina_Hash *hash, void *value, void *fdata)
937 Efreet_Cache_Search_List *search;
938 Efreet_Util_Desktop *ud;
943 if (!ud->desktop) return EINA_TRUE;
944 if (efreet_util_glob_match(ud->desktop->name, search->what))
946 efreet_desktop_ref(ud->desktop);
947 search->list = eina_list_append(search->list, ud->desktop);
953 efreet_util_cache_search_exec_glob(__UNUSED__ const Eina_Hash *hash, void *value, void *fdata)
955 Efreet_Cache_Search_List *search;
956 Efreet_Util_Desktop *ud;
962 if (!ud->desktop->exec) return EINA_TRUE;
963 exec = ecore_file_app_exe_get(ud->desktop->exec);
964 if (!exec) return EINA_TRUE;
966 if (efreet_util_glob_match(exec, search->what))
968 efreet_desktop_ref(ud->desktop);
969 search->list = eina_list_append(search->list, ud->desktop);
976 efreet_util_cache_search_generic_name_glob(__UNUSED__ const Eina_Hash *hash, void *value, void *fdata)
978 Efreet_Cache_Search_List *search;
979 Efreet_Util_Desktop *ud;
984 if (efreet_util_glob_match(ud->desktop->generic_name, search->what))
986 efreet_desktop_ref(ud->desktop);
987 search->list = eina_list_append(search->list, ud->desktop);
993 efreet_util_cache_search_comment_glob(__UNUSED__ const Eina_Hash *hash, void *value, void *fdata)
995 Efreet_Cache_Search_List *search;
996 Efreet_Util_Desktop *ud;
1001 if (efreet_util_glob_match(ud->desktop->comment, search->what))
1003 efreet_desktop_ref(ud->desktop);
1004 search->list = eina_list_append(search->list, ud->desktop);
1010 efreet_util_glob_match(const char *str, const char *glob)
1014 if (glob[0] == '\0')
1016 if (str[0] == '\0') return 1;
1019 if (!strcmp(glob, "*")) return 1;
1020 if (!fnmatch(glob, str, 0)) return 1;
1025 efreet_util_monitor(const char *path, const char *file_id, int priority)
1029 em = NEW(Efreet_Monitor, 1);
1030 em->monitor = ecore_file_monitor_add(path, efreet_util_monitor_cb, em);
1031 if (file_id) em->file_id = strdup(file_id);
1032 em->priority = priority;
1033 monitors = eina_list_append(monitors, em);
1037 efreet_util_monitor_cb(void *data, Ecore_File_Monitor *monitor __UNUSED__,
1038 Ecore_File_Event event, const char *path)
1041 char file_id[PATH_MAX];
1045 snprintf(file_id, sizeof(file_id), "%s-%s", em->file_id, ecore_file_file_get(path));
1047 strcpy(file_id, ecore_file_file_get(path));
1050 case ECORE_FILE_EVENT_NONE:
1053 case ECORE_FILE_EVENT_CREATED_FILE:
1054 efreet_util_cache_add(path, file_id, em->priority, 1);
1056 case ECORE_FILE_EVENT_CREATED_DIRECTORY:
1058 Efreet_Cache_Fill_Dir *dir;
1062 fill = NEW(Efreet_Cache_Fill, 1);
1065 dir = NEW(Efreet_Cache_Fill_Dir, 1);
1066 dir->path = strdup(path);
1067 dir->file_id = strdup(file_id);
1068 dir->priority = em->priority;
1069 fill->dirs = eina_list_append(fill->dirs, dir);
1072 idler = ecore_idler_add(efreet_util_cache_fill, NULL);
1075 case ECORE_FILE_EVENT_DELETED_FILE:
1076 efreet_util_cache_remove(path, file_id, em->priority);
1078 case ECORE_FILE_EVENT_DELETED_DIRECTORY:
1079 /* Ignore, we should already have a monitor on any subdir */
1081 case ECORE_FILE_EVENT_DELETED_SELF:
1082 if (eina_list_data_find(monitors, em))
1083 eina_list_remove(monitors, em);
1084 efreet_util_monitor_free(em);
1086 case ECORE_FILE_EVENT_MODIFIED:
1087 efreet_util_cache_reload(path, file_id, em->priority);
1093 efreet_util_monitor_free(void *data)
1098 if (em->monitor) ecore_file_monitor_del(em->monitor);
1099 IF_FREE(em->file_id);
1104 * Returns a list of .menu files found in the various config dirs.
1105 * @return An ecore list of menu file paths (const char *). This must be freed with ecore_list_destroy().
1108 efreet_util_menus_find(void)
1110 Eina_List *menus = NULL;
1111 Eina_List *dirs, *l;
1114 efreet_util_menus_find_helper(menus, efreet_config_home_get());
1116 dirs = efreet_config_dirs_get();
1117 EINA_LIST_FOREACH(dirs, l, dir)
1118 efreet_util_menus_find_helper(menus, dir);
1124 efreet_util_menus_find_helper(Eina_List *menus, const char *config_dir)
1127 struct dirent *file = NULL;
1128 char dbuf[PATH_MAX], fbuf[PATH_MAX];
1130 snprintf(dbuf, sizeof(dbuf), "%s/menus", config_dir);
1131 files = opendir(dbuf);
1133 while ((file = readdir(files))) {
1135 exten = strrchr(file->d_name, '.');
1136 if (!exten) continue;
1137 if (strcmp(".menu", exten)) continue;
1139 snprintf(fbuf, PATH_MAX, "%s/%s", dbuf, file->d_name);
1140 if (ecore_file_is_dir(fbuf)) continue;
1142 menus = eina_list_append(menus, strdup(fbuf));
1148 efreet_util_desktops_by_category_add(Efreet_Desktop *desktop)
1151 const char *category;
1153 if (!desktop->categories) return;
1155 EINA_LIST_FOREACH(desktop->categories, l, category)
1159 list = eina_hash_find(desktops_by_category, category);
1160 if (!list) newlist = 1;
1161 if (!eina_list_data_find(list, desktop))
1162 list = eina_list_append(list, desktop);
1164 eina_hash_add(desktops_by_category, category, list);
1166 eina_hash_modify(desktops_by_category, category, list);
1171 efreet_util_desktops_by_category_remove(Efreet_Desktop *desktop)
1174 const char *category;
1176 if (!desktop->categories) return;
1178 EINA_LIST_FOREACH(desktop->categories, l, category)
1181 list = eina_hash_find(desktops_by_category, category);
1182 if (!list) continue;
1183 if (eina_list_data_find(list, desktop))
1184 list = eina_list_remove(list, desktop);
1186 eina_hash_del(desktops_by_category, category, list);
1188 eina_hash_modify(desktops_by_category, category, list);
1193 efreet_util_desktop_free(Efreet_Util_Desktop *ud)
1197 efreet_desktop_free(ud->desktop);
1202 efreet_event_desktop_change_free(void *data __UNUSED__, void *ev)
1204 Efreet_Event_Desktop_Change *event;
1207 if (event->current) efreet_desktop_free(event->current);
1208 if (event->previous) efreet_desktop_free(event->previous);