2004-11-24 19:37:45 -08:00
|
|
|
#include "e.h"
|
|
|
|
|
|
|
|
/* TODO List:
|
|
|
|
*
|
2004-12-01 20:24:54 -08:00
|
|
|
* * if a application .eapp file is added in a different location in a monitored app tree but has the same filename as an existing one somewhere else, the existing one gets a changed callback, not an dded callback for the new one
|
2004-11-24 19:37:45 -08:00
|
|
|
* * track app execution state, visibility state etc. and call callbacks
|
|
|
|
* * calls to execute an app or query its runing/starting state etc.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* local subsystem functions */
|
|
|
|
typedef struct _E_App_Change_Info E_App_Change_Info;
|
|
|
|
typedef struct _E_App_Callback E_App_Callback;
|
|
|
|
|
|
|
|
struct _E_App_Change_Info
|
|
|
|
{
|
|
|
|
E_App *app;
|
|
|
|
E_App_Change change;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _E_App_Callback
|
|
|
|
{
|
|
|
|
void (*func) (void *data, E_App *a, E_App_Change ch);
|
|
|
|
void *data;
|
|
|
|
unsigned char delete_me : 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void _e_app_free (E_App *a);
|
|
|
|
static void _e_app_fields_fill (E_App *a, char *path);
|
|
|
|
static void _e_app_fields_empty (E_App *a);
|
|
|
|
static Evas_List *_e_app_dir_file_list_get (E_App *a, char *path);
|
|
|
|
static E_App *_e_app_subapp_path_find (E_App *a, char *subpath);
|
|
|
|
static void _e_app_monitor (void);
|
|
|
|
static void _e_app_change (E_App *a, E_App_Change ch);
|
|
|
|
static int _e_app_check (void *data);
|
|
|
|
static Evas_Bool _e_app_check_each (Evas_Hash *hash, const char *key, void *data, void *fdata);
|
|
|
|
static int _e_apps_cb_exit (void *data, int type, void *event);
|
|
|
|
|
|
|
|
/* local subsystem globals */
|
|
|
|
static Evas_Hash *_e_apps = NULL;
|
2004-12-02 02:07:51 -08:00
|
|
|
static Evas_List *_e_apps_list = NULL;
|
2004-11-24 19:37:45 -08:00
|
|
|
static Ecore_Timer *_e_apps_checker = NULL;
|
|
|
|
static int _e_apps_callbacks_walking = 0;
|
|
|
|
static int _e_apps_callbacks_delete_me = 0;
|
|
|
|
static Evas_List *_e_apps_change_callbacks = NULL;
|
|
|
|
static Ecore_Event_Handler *_e_apps_exit_handler = NULL;
|
2004-12-01 22:35:37 -08:00
|
|
|
static Evas_List *_e_apps_repositories = NULL;
|
2004-12-02 02:07:51 -08:00
|
|
|
static E_App *_e_apps_all = NULL;
|
2004-11-24 19:37:45 -08:00
|
|
|
|
|
|
|
/* externally accessible functions */
|
|
|
|
int
|
|
|
|
e_app_init(void)
|
|
|
|
{
|
2004-12-01 22:35:37 -08:00
|
|
|
char *home;
|
|
|
|
char buf[4096];
|
|
|
|
|
|
|
|
home = e_user_homedir_get();
|
|
|
|
snprintf(buf, sizeof(buf), "%s/.e/e/applications/all", home);
|
2004-12-02 02:07:51 -08:00
|
|
|
free(home);
|
2004-12-01 22:35:37 -08:00
|
|
|
_e_apps_repositories = evas_list_append(_e_apps_repositories, strdup(buf));
|
2004-11-24 19:37:45 -08:00
|
|
|
_e_apps_exit_handler = ecore_event_handler_add(ECORE_EVENT_EXE_EXIT, _e_apps_cb_exit, NULL);
|
2004-12-02 02:07:51 -08:00
|
|
|
_e_apps_all = e_app_new(buf, 1);
|
2004-11-24 19:37:45 -08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
e_app_shutdown(void)
|
|
|
|
{
|
2004-12-02 02:07:51 -08:00
|
|
|
if (_e_apps_all)
|
|
|
|
{
|
|
|
|
e_object_unref(E_OBJECT(_e_apps_all));
|
|
|
|
_e_apps_all = NULL;
|
|
|
|
}
|
2004-12-01 22:35:37 -08:00
|
|
|
while (_e_apps_repositories)
|
|
|
|
{
|
|
|
|
free(_e_apps_repositories->data);
|
|
|
|
_e_apps_repositories = evas_list_remove_list(_e_apps_repositories, _e_apps_repositories);
|
|
|
|
}
|
2004-11-24 19:37:45 -08:00
|
|
|
if (_e_apps_exit_handler)
|
|
|
|
{
|
|
|
|
ecore_event_handler_del(_e_apps_exit_handler);
|
|
|
|
_e_apps_exit_handler = NULL;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
E_App *
|
|
|
|
e_app_new(char *path, int scan_subdirs)
|
|
|
|
{
|
|
|
|
E_App *a;
|
2004-12-01 23:00:30 -08:00
|
|
|
|
2004-11-24 19:37:45 -08:00
|
|
|
a = evas_hash_find(_e_apps, path);
|
|
|
|
if (a)
|
|
|
|
{
|
|
|
|
e_object_ref(E_OBJECT(a));
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
a = E_OBJECT_ALLOC(E_App, _e_app_free);
|
|
|
|
a->mod_time = e_file_mod_time(path);
|
|
|
|
if (e_file_is_dir(path))
|
|
|
|
{
|
|
|
|
char buf[4096];
|
|
|
|
|
|
|
|
a->path = strdup(path);
|
2004-12-01 20:24:54 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%s/.directory.eapp", path);
|
2004-11-24 19:37:45 -08:00
|
|
|
a->directory_mod_time = e_file_mod_time(buf);
|
|
|
|
if (e_file_exists(buf))
|
|
|
|
_e_app_fields_fill(a, buf);
|
|
|
|
else
|
|
|
|
a->name = strdup(e_file_get_file(path));
|
|
|
|
if (scan_subdirs) e_app_subdir_scan(a, scan_subdirs);
|
|
|
|
}
|
|
|
|
else if (e_file_exists(path))
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
2004-12-01 20:24:54 -08:00
|
|
|
/* check if file ends in .eapp */
|
2004-11-24 19:37:45 -08:00
|
|
|
p = strrchr(path, '.');
|
|
|
|
if (!p)
|
|
|
|
{
|
|
|
|
free(a);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
p++;
|
2004-12-01 22:35:37 -08:00
|
|
|
if ((strcasecmp(p, "eapp")))
|
2004-11-24 19:37:45 -08:00
|
|
|
{
|
|
|
|
free(a);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* record the path */
|
|
|
|
a->path = strdup(path);
|
|
|
|
|
|
|
|
/* get the field data */
|
|
|
|
_e_app_fields_fill(a, path);
|
|
|
|
|
|
|
|
/* no exe field.. not valid. drop it */
|
|
|
|
if (!a->exe)
|
|
|
|
{
|
|
|
|
if (a->name) free(a->name);
|
|
|
|
if (a->generic) free(a->generic);
|
|
|
|
if (a->comment) free(a->comment);
|
|
|
|
if (a->exe) free(a->exe);
|
|
|
|
if (a->path) free(a->path);
|
|
|
|
if (a->win_name) free(a->win_name);
|
|
|
|
if (a->win_class) free(a->win_class);
|
|
|
|
free(a);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
free(a);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
_e_apps = evas_hash_add(_e_apps, a->path, a);
|
2004-12-02 02:07:51 -08:00
|
|
|
_e_apps_list = evas_list_prepend(_e_apps_list, a);
|
2004-11-24 19:37:45 -08:00
|
|
|
_e_app_monitor();
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
e_app_subdir_scan(E_App *a, int scan_subdirs)
|
|
|
|
{
|
|
|
|
Evas_List *files, *files2 = NULL;
|
|
|
|
FILE *f;
|
|
|
|
char buf[4096];
|
|
|
|
|
|
|
|
E_OBJECT_CHECK(a);
|
|
|
|
if (a->exe) return;
|
|
|
|
if (a->scanned)
|
|
|
|
{
|
|
|
|
Evas_List *l;
|
|
|
|
|
|
|
|
if (!scan_subdirs) return;
|
|
|
|
for (l = a->subapps; l; l = l->next)
|
|
|
|
e_app_subdir_scan(l->data, scan_subdirs);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
a->scanned = 1;
|
|
|
|
files = _e_app_dir_file_list_get(a, a->path);
|
|
|
|
while (files)
|
|
|
|
{
|
|
|
|
E_App *a2;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
s = files->data;
|
2004-12-01 22:35:37 -08:00
|
|
|
a2 = NULL;
|
2004-11-24 19:37:45 -08:00
|
|
|
if (s[0] != '.')
|
|
|
|
{
|
2004-12-01 22:35:37 -08:00
|
|
|
Evas_List *pl;
|
|
|
|
|
2004-11-24 19:37:45 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", a->path, s);
|
2004-12-02 02:07:51 -08:00
|
|
|
if (e_file_exists(buf)) a2 = e_app_new(buf, scan_subdirs);
|
2004-12-01 22:35:37 -08:00
|
|
|
pl = _e_apps_repositories;
|
|
|
|
while ((!a2) && (pl))
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", (char *)pl->data, s);
|
|
|
|
a2 = e_app_new(buf, scan_subdirs);
|
|
|
|
pl = pl->next;
|
|
|
|
}
|
2004-11-24 19:37:45 -08:00
|
|
|
if (a2)
|
|
|
|
{
|
|
|
|
a->subapps = evas_list_append(a->subapps, a2);
|
|
|
|
a2->parent = a;
|
|
|
|
}
|
2004-12-01 22:35:37 -08:00
|
|
|
free(s);
|
2004-11-24 19:37:45 -08:00
|
|
|
}
|
|
|
|
files = evas_list_remove_list(files, files);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
e_app_exec(E_App *a)
|
|
|
|
{
|
|
|
|
Ecore_Exe *exe;
|
|
|
|
|
|
|
|
E_OBJECT_CHECK_RETURN(a, 0);
|
|
|
|
if (!a->exe) return 0;
|
|
|
|
exe = ecore_exe_run(a->exe, a);
|
|
|
|
if (!exe) return 0;
|
|
|
|
a->instances = evas_list_append(a->instances, exe);
|
|
|
|
if (a->startup_notify) a->starting = 1;
|
|
|
|
_e_app_change(a, E_APP_EXEC);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
e_app_starting_get(E_App *a)
|
|
|
|
{
|
|
|
|
E_OBJECT_CHECK_RETURN(a, 0);
|
|
|
|
return a->starting;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
e_app_running_get(E_App *a)
|
|
|
|
{
|
|
|
|
E_OBJECT_CHECK_RETURN(a, 0);
|
|
|
|
if (a->instances) return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
e_app_change_callback_add(void (*func) (void *data, E_App *a, E_App_Change ch), void *data)
|
|
|
|
{
|
|
|
|
E_App_Callback *cb;
|
|
|
|
|
|
|
|
cb = calloc(1, sizeof(E_App_Callback));
|
|
|
|
cb->func = func;
|
|
|
|
cb->data = data;
|
|
|
|
_e_apps_change_callbacks = evas_list_append(_e_apps_change_callbacks, cb);
|
|
|
|
_e_app_monitor();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
e_app_change_callback_del(void (*func) (void *data, E_App *a, E_App_Change ch), void *data)
|
|
|
|
{
|
|
|
|
Evas_List *l;
|
|
|
|
|
|
|
|
for (l = _e_apps_change_callbacks; l; l = l->next)
|
|
|
|
{
|
|
|
|
E_App_Callback *cb;
|
|
|
|
|
|
|
|
cb = l->data;
|
|
|
|
if ((cb->func == func) && (cb->data == data))
|
|
|
|
{
|
|
|
|
if (_e_apps_callbacks_walking)
|
|
|
|
{
|
|
|
|
cb->delete_me = 1;
|
|
|
|
_e_apps_callbacks_delete_me = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_e_apps_change_callbacks = evas_list_remove_list(_e_apps_change_callbacks, l);
|
|
|
|
free(cb);
|
|
|
|
_e_app_monitor();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-02 02:07:51 -08:00
|
|
|
E_App *
|
|
|
|
e_app_window_name_class_find(char *name, char *class)
|
|
|
|
{
|
|
|
|
Evas_List *l;
|
|
|
|
|
|
|
|
for (l = _e_apps_list; l; l = l->next)
|
|
|
|
{
|
|
|
|
E_App *a;
|
|
|
|
|
|
|
|
a = l->data;
|
|
|
|
if ((a->win_name) || (a->win_class))
|
|
|
|
{
|
|
|
|
int ok = 0;
|
|
|
|
|
|
|
|
// printf("%s.%s == %s.%s\n", name, class, a->win_name, a->win_class);
|
|
|
|
if ((!a->win_name) ||
|
|
|
|
((a->win_name) && (!strcmp(a->win_name, name))))
|
|
|
|
ok++;
|
|
|
|
if ((!a->win_class) ||
|
|
|
|
((a->win_class) && (!strcmp(a->win_class, class))))
|
|
|
|
ok++;
|
|
|
|
if (ok >= 2)
|
|
|
|
{
|
|
|
|
_e_apps_list = evas_list_remove_list(_e_apps_list, l);
|
|
|
|
_e_apps_list = evas_list_prepend(_e_apps_list, a);
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-11-24 19:37:45 -08:00
|
|
|
/* local subsystem functions */
|
|
|
|
static void
|
|
|
|
_e_app_free(E_App *a)
|
|
|
|
{
|
|
|
|
while (a->instances)
|
|
|
|
{
|
|
|
|
Ecore_Exe *exe;
|
|
|
|
|
|
|
|
exe = a->instances->data;
|
|
|
|
ecore_exe_free(exe);
|
|
|
|
a->instances = evas_list_remove_list(a->instances, a->instances);
|
|
|
|
}
|
|
|
|
while (a->subapps)
|
|
|
|
{
|
|
|
|
E_App *a2;
|
|
|
|
|
|
|
|
a2 = a->subapps->data;
|
|
|
|
a->subapps = evas_list_remove(a->subapps, a2);
|
2004-12-02 02:07:51 -08:00
|
|
|
a2->parent = NULL;
|
|
|
|
e_object_unref(E_OBJECT(a2));
|
2004-11-24 19:37:45 -08:00
|
|
|
}
|
|
|
|
if (a->parent)
|
|
|
|
a->parent->subapps = evas_list_remove(a->parent->subapps, a);
|
|
|
|
_e_apps = evas_hash_del(_e_apps, a->path, a);
|
2004-12-02 02:07:51 -08:00
|
|
|
_e_apps_list = evas_list_remove(_e_apps_list, a);
|
2004-11-24 19:37:45 -08:00
|
|
|
if (a->name) free(a->name);
|
|
|
|
if (a->generic) free(a->generic);
|
|
|
|
if (a->comment) free(a->comment);
|
|
|
|
if (a->exe) free(a->exe);
|
|
|
|
if (a->path) free(a->path);
|
|
|
|
if (a->win_name) free(a->win_name);
|
|
|
|
if (a->win_class) free(a->win_class);
|
|
|
|
free(a);
|
|
|
|
_e_app_monitor();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_app_fields_fill(E_App *a, char *path)
|
|
|
|
{
|
2004-12-01 20:24:54 -08:00
|
|
|
Eet_File *ef;
|
2004-11-24 19:37:45 -08:00
|
|
|
char buf[4096];
|
2004-12-01 20:24:54 -08:00
|
|
|
char *str, *v;
|
2004-11-24 19:37:45 -08:00
|
|
|
char *lang;
|
2004-12-01 20:24:54 -08:00
|
|
|
int size;
|
2004-11-24 19:37:45 -08:00
|
|
|
|
|
|
|
/* get our current language */
|
|
|
|
lang = getenv("LANG");
|
|
|
|
/* if its "C" its the default - so drop it */
|
|
|
|
if ((lang) && (!strcmp(lang, "C")))
|
|
|
|
lang = NULL;
|
2004-12-01 20:24:54 -08:00
|
|
|
ef = eet_open(a->path, EET_FILE_MODE_READ);
|
|
|
|
if (!ef) return;
|
2004-12-10 08:34:36 -08:00
|
|
|
|
2004-12-10 08:24:00 -08:00
|
|
|
if (lang)
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "app/info/name[%s]", lang);
|
|
|
|
v = eet_read(ef, buf, &size);
|
2004-12-10 20:02:26 -08:00
|
|
|
if (!v) v = eet_read(ef, "app/info/name", &size);
|
2004-12-10 08:24:00 -08:00
|
|
|
}
|
|
|
|
else
|
2004-12-10 08:34:36 -08:00
|
|
|
v = eet_read(ef, "app/info/name", &size);
|
|
|
|
|
2004-12-01 20:24:54 -08:00
|
|
|
if (v)
|
2004-11-24 19:37:45 -08:00
|
|
|
{
|
2004-12-01 20:24:54 -08:00
|
|
|
str = malloc(size + 1);
|
|
|
|
memcpy(str, v, size);
|
|
|
|
str[size] = 0;
|
|
|
|
a->name = str;
|
|
|
|
free(v);
|
2004-11-24 19:37:45 -08:00
|
|
|
}
|
2004-12-10 08:34:36 -08:00
|
|
|
|
2004-12-10 08:24:00 -08:00
|
|
|
if (lang)
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "app/info/generic[%s]", lang);
|
|
|
|
v = eet_read(ef, buf, &size);
|
2004-12-10 20:02:26 -08:00
|
|
|
if (!v) v = eet_read(ef, "app/info/generic", &size);
|
2004-12-10 08:24:00 -08:00
|
|
|
}
|
|
|
|
else
|
2004-12-10 08:34:36 -08:00
|
|
|
v = eet_read(ef, "app/info/generic", &size);
|
|
|
|
|
2004-12-01 20:24:54 -08:00
|
|
|
if (v)
|
2004-11-24 19:37:45 -08:00
|
|
|
{
|
2004-12-01 20:24:54 -08:00
|
|
|
str = malloc(size + 1);
|
|
|
|
memcpy(str, v, size);
|
|
|
|
str[size] = 0;
|
|
|
|
a->generic = str;
|
|
|
|
free(v);
|
2004-11-24 19:37:45 -08:00
|
|
|
}
|
2004-12-10 08:34:36 -08:00
|
|
|
|
2004-12-10 08:24:00 -08:00
|
|
|
if (lang)
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "app/info/comment[%s]", lang);
|
|
|
|
v = eet_read(ef, buf, &size);
|
2004-12-10 20:02:26 -08:00
|
|
|
if (!v) v = eet_read(ef, "app/info/comment", &size);
|
2004-12-10 08:24:00 -08:00
|
|
|
}
|
|
|
|
else
|
2004-12-10 08:34:36 -08:00
|
|
|
v = eet_read(ef, "app/info/comment", &size);
|
|
|
|
|
2004-12-01 20:24:54 -08:00
|
|
|
if (v)
|
|
|
|
{
|
|
|
|
str = malloc(size + 1);
|
|
|
|
memcpy(str, v, size);
|
|
|
|
str[size] = 0;
|
|
|
|
a->comment = str;
|
|
|
|
free(v);
|
|
|
|
}
|
2004-12-10 08:34:36 -08:00
|
|
|
|
2004-12-01 20:24:54 -08:00
|
|
|
v = eet_read(ef, "app/info/exe", &size);
|
|
|
|
if (v)
|
|
|
|
{
|
|
|
|
str = malloc(size + 1);
|
|
|
|
memcpy(str, v, size);
|
|
|
|
str[size] = 0;
|
|
|
|
a->exe = str;
|
|
|
|
free(v);
|
|
|
|
}
|
|
|
|
v = eet_read(ef, "app/window/name", &size);
|
|
|
|
if (v)
|
|
|
|
{
|
|
|
|
str = malloc(size + 1);
|
|
|
|
memcpy(str, v, size);
|
|
|
|
str[size] = 0;
|
|
|
|
a->win_name = str;
|
|
|
|
free(v);
|
|
|
|
}
|
|
|
|
v = eet_read(ef, "app/window/class", &size);
|
|
|
|
if (v)
|
|
|
|
{
|
|
|
|
str = malloc(size + 1);
|
|
|
|
memcpy(str, v, size);
|
|
|
|
str[size] = 0;
|
|
|
|
a->win_class = str;
|
|
|
|
free(v);
|
|
|
|
}
|
|
|
|
v = eet_read(ef, "app/info/startup_notify", &size);
|
|
|
|
if (v)
|
2004-11-24 19:37:45 -08:00
|
|
|
{
|
2004-12-01 20:24:54 -08:00
|
|
|
a->startup_notify = *v;
|
|
|
|
free(v);
|
2004-11-24 19:37:45 -08:00
|
|
|
}
|
2004-12-09 05:56:06 -08:00
|
|
|
v = eet_read(ef, "app/info/wait_exit", &size);
|
|
|
|
if (v)
|
|
|
|
{
|
|
|
|
a->wait_exit = *v;
|
|
|
|
free(v);
|
|
|
|
}
|
2004-12-01 20:24:54 -08:00
|
|
|
eet_close(ef);
|
2004-11-24 19:37:45 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_app_fields_empty(E_App *a)
|
|
|
|
{
|
|
|
|
if (a->name)
|
|
|
|
{
|
|
|
|
free(a->name);
|
|
|
|
a->name = NULL;
|
|
|
|
}
|
|
|
|
if (a->generic)
|
|
|
|
{
|
|
|
|
free(a->generic);
|
|
|
|
a->generic = NULL;
|
|
|
|
}
|
|
|
|
if (a->comment)
|
|
|
|
{
|
|
|
|
free(a->comment);
|
|
|
|
a->comment = NULL;
|
|
|
|
}
|
|
|
|
if (a->exe)
|
|
|
|
{
|
|
|
|
free(a->exe);
|
|
|
|
a->exe = NULL;
|
|
|
|
}
|
|
|
|
if (a->win_name)
|
|
|
|
{
|
|
|
|
free(a->win_name);
|
|
|
|
a->win_name = NULL;
|
|
|
|
}
|
|
|
|
if (a->win_class)
|
|
|
|
{
|
|
|
|
free(a->win_class);
|
|
|
|
a->win_class = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_List *
|
|
|
|
_e_app_dir_file_list_get(E_App *a, char *path)
|
|
|
|
{
|
|
|
|
Evas_List *files, *files2 = NULL, *l;
|
|
|
|
FILE *f;
|
|
|
|
char buf[4096];
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/.order", path);
|
|
|
|
a->order_mod_time = e_file_mod_time(buf);
|
|
|
|
files = e_file_ls(path);
|
|
|
|
f = fopen(buf, "rb");
|
|
|
|
if (f)
|
|
|
|
{
|
|
|
|
while (fgets(buf, sizeof(buf), f))
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
|
|
|
|
len = strlen(buf);
|
|
|
|
if (len > 0)
|
|
|
|
{
|
|
|
|
int ok = 0;
|
|
|
|
|
2004-12-01 23:00:30 -08:00
|
|
|
if (buf[len - 1] == '\n')
|
|
|
|
{
|
|
|
|
buf[len - 1] = 0;
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
if (len > 0)
|
2004-11-24 19:37:45 -08:00
|
|
|
{
|
2004-12-01 23:00:30 -08:00
|
|
|
for (l = files; l; l = l->next)
|
2004-11-24 19:37:45 -08:00
|
|
|
{
|
2004-12-01 23:00:30 -08:00
|
|
|
if (!strcmp(buf, l->data))
|
|
|
|
{
|
|
|
|
free(l->data);
|
|
|
|
files = evas_list_remove_list(files, l);
|
|
|
|
break;
|
|
|
|
}
|
2004-11-24 19:37:45 -08:00
|
|
|
}
|
2004-12-01 23:00:30 -08:00
|
|
|
files2 = evas_list_append(files2, strdup(buf));
|
2004-11-24 19:37:45 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
files2 = files;
|
|
|
|
files = NULL;
|
|
|
|
}
|
|
|
|
while (files)
|
|
|
|
{
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
s = files->data;
|
|
|
|
if (s[0] != '.')
|
|
|
|
files2 = evas_list_append(files2, s);
|
|
|
|
else
|
|
|
|
free(s);
|
|
|
|
files = evas_list_remove_list(files, files);
|
|
|
|
}
|
|
|
|
files = files2;
|
|
|
|
return files;
|
|
|
|
}
|
|
|
|
|
|
|
|
static E_App *
|
|
|
|
_e_app_subapp_path_find(E_App *a, char *subpath)
|
|
|
|
{
|
|
|
|
Evas_List *l;
|
|
|
|
|
|
|
|
for (l = a->subapps; l; l = l->next)
|
|
|
|
{
|
|
|
|
E_App *a2;
|
|
|
|
|
|
|
|
a2 = l->data;
|
|
|
|
if (!strcmp(a2->path, subpath)) return a2;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_app_monitor(void)
|
|
|
|
{
|
|
|
|
if ((_e_apps) && (_e_apps_change_callbacks))
|
|
|
|
{
|
|
|
|
if (!_e_apps_checker)
|
|
|
|
_e_apps_checker = ecore_timer_add(1.0, _e_app_check, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (_e_apps_checker)
|
|
|
|
{
|
|
|
|
ecore_timer_del(_e_apps_checker);
|
|
|
|
_e_apps_checker = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_app_change(E_App *a, E_App_Change ch)
|
|
|
|
{
|
|
|
|
Evas_List *l;
|
|
|
|
|
|
|
|
_e_apps_callbacks_walking = 1;
|
|
|
|
for (l = _e_apps_change_callbacks; l; l = l->next)
|
|
|
|
{
|
|
|
|
E_App_Callback *cb;
|
|
|
|
|
|
|
|
cb = l->data;
|
|
|
|
if (!cb->delete_me)
|
|
|
|
{
|
|
|
|
cb->func(cb->data, a, ch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_e_apps_callbacks_walking = 0;
|
|
|
|
if (_e_apps_callbacks_delete_me)
|
|
|
|
{
|
|
|
|
for (l = _e_apps_change_callbacks; l;)
|
|
|
|
{
|
|
|
|
E_App_Callback *cb;
|
|
|
|
Evas_List *pl;
|
|
|
|
|
|
|
|
cb = l->data;
|
|
|
|
pl = l;
|
|
|
|
l = l->next;
|
|
|
|
if (cb->delete_me)
|
|
|
|
{
|
|
|
|
_e_apps_change_callbacks = evas_list_remove_list(_e_apps_change_callbacks, pl);
|
|
|
|
free(cb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_e_apps_callbacks_delete_me = 0;
|
|
|
|
_e_app_monitor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_e_app_check(void *data)
|
|
|
|
{
|
|
|
|
Evas_List *changes = NULL;
|
|
|
|
|
|
|
|
evas_hash_foreach(_e_apps, _e_app_check_each, &changes);
|
|
|
|
|
|
|
|
while (changes)
|
|
|
|
{
|
|
|
|
E_App_Change_Info *ch;
|
|
|
|
Evas_List *l;
|
|
|
|
|
|
|
|
ch = changes->data;
|
|
|
|
changes = evas_list_remove_list(changes, changes);
|
|
|
|
_e_app_change(ch->app, ch->change);
|
|
|
|
e_object_unref(E_OBJECT(ch->app));
|
|
|
|
free(ch);
|
|
|
|
}
|
|
|
|
if (_e_apps_checker) return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Bool
|
|
|
|
_e_app_check_each(Evas_Hash *hash, const char *key, void *data, void *fdata)
|
|
|
|
{
|
|
|
|
Evas_List **changes;
|
|
|
|
E_App *a;
|
|
|
|
E_App_Change_Info *ch;
|
|
|
|
|
|
|
|
changes = fdata;
|
|
|
|
a = data;
|
|
|
|
if (a->exe)
|
|
|
|
{
|
|
|
|
time_t mod_time;
|
|
|
|
|
|
|
|
mod_time = e_file_mod_time(a->path);
|
|
|
|
if (mod_time != a->mod_time)
|
|
|
|
{
|
|
|
|
a->mod_time = mod_time;
|
|
|
|
if (e_file_exists(a->path))
|
|
|
|
{
|
|
|
|
_e_app_fields_empty(a);
|
|
|
|
_e_app_fields_fill(a, a->path);
|
|
|
|
if (!a->exe)
|
|
|
|
{
|
|
|
|
ch = calloc(1, sizeof(E_App_Change_Info));
|
|
|
|
ch->app = a;
|
|
|
|
ch->change = E_APP_DEL;
|
|
|
|
e_object_ref(E_OBJECT(ch->app));
|
|
|
|
*changes = evas_list_append(*changes, ch);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ch = calloc(1, sizeof(E_App_Change_Info));
|
|
|
|
ch->app = a;
|
|
|
|
ch->change = E_APP_CHANGE;
|
|
|
|
e_object_ref(E_OBJECT(ch->app));
|
|
|
|
*changes = evas_list_append(*changes, ch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ch = calloc(1, sizeof(E_App_Change_Info));
|
|
|
|
ch->app = a;
|
|
|
|
ch->change = E_APP_DEL;
|
|
|
|
e_object_ref(E_OBJECT(ch->app));
|
|
|
|
*changes = evas_list_append(*changes, ch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
time_t mod_time, order_mod_time, directory_mod_time;
|
|
|
|
char buf[4096];
|
|
|
|
|
|
|
|
mod_time = e_file_mod_time(a->path);
|
|
|
|
snprintf(buf, sizeof(buf), "%s/.order", a->path);
|
|
|
|
order_mod_time = e_file_mod_time(buf);
|
2004-12-01 20:24:54 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%s/.directory.eapp", a->path);
|
2004-11-24 19:37:45 -08:00
|
|
|
directory_mod_time = e_file_mod_time(buf);
|
|
|
|
if ((mod_time != a->mod_time) ||
|
|
|
|
(order_mod_time != a->order_mod_time) ||
|
|
|
|
(directory_mod_time != a->directory_mod_time))
|
|
|
|
{
|
|
|
|
a->mod_time = mod_time;
|
|
|
|
if (!e_file_is_dir(a->path))
|
|
|
|
{
|
|
|
|
ch = calloc(1, sizeof(E_App_Change_Info));
|
|
|
|
ch->app = a;
|
|
|
|
ch->change = E_APP_DEL;
|
|
|
|
e_object_ref(E_OBJECT(ch->app));
|
|
|
|
*changes = evas_list_append(*changes, ch);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (order_mod_time != a->order_mod_time)
|
|
|
|
{
|
|
|
|
ch = calloc(1, sizeof(E_App_Change_Info));
|
|
|
|
ch->app = a;
|
|
|
|
ch->change = E_APP_ORDER;
|
|
|
|
e_object_ref(E_OBJECT(ch->app));
|
|
|
|
*changes = evas_list_append(*changes, ch);
|
|
|
|
}
|
|
|
|
if (directory_mod_time != a->directory_mod_time)
|
|
|
|
{
|
2004-12-01 20:24:54 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%s/.directory.eapp", a->path);
|
2004-11-24 19:37:45 -08:00
|
|
|
_e_app_fields_empty(a);
|
|
|
|
_e_app_fields_fill(a, buf);
|
|
|
|
ch = calloc(1, sizeof(E_App_Change_Info));
|
|
|
|
ch->app = a;
|
|
|
|
ch->change = E_APP_CHANGE;
|
|
|
|
e_object_ref(E_OBJECT(ch->app));
|
|
|
|
*changes = evas_list_append(*changes, ch);
|
|
|
|
}
|
|
|
|
a->order_mod_time = order_mod_time;
|
|
|
|
a->directory_mod_time = directory_mod_time;
|
|
|
|
if (a->scanned)
|
|
|
|
{
|
|
|
|
Evas_List *l, *files;
|
|
|
|
|
|
|
|
files = _e_app_dir_file_list_get(a, a->path);
|
|
|
|
for (l = files; l; l = l->next)
|
|
|
|
{
|
|
|
|
E_App *a2;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
s = l->data;
|
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", a->path, s);
|
|
|
|
if (!_e_app_subapp_path_find(a, buf))
|
|
|
|
{
|
|
|
|
a2 = e_app_new(buf, 0);
|
|
|
|
if (a2)
|
|
|
|
{
|
|
|
|
a2->parent = a;
|
|
|
|
a->subapps = evas_list_append(a->subapps, a2);
|
|
|
|
ch = calloc(1, sizeof(E_App_Change_Info));
|
|
|
|
ch->app = a2;
|
|
|
|
ch->change = E_APP_ADD;
|
|
|
|
e_object_ref(E_OBJECT(ch->app));
|
|
|
|
*changes = evas_list_append(*changes, ch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (l = files; l; l = l->next)
|
|
|
|
{
|
|
|
|
E_App *a2;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
s = l->data;
|
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", a->path, s);
|
|
|
|
a2 = _e_app_subapp_path_find(a, buf);
|
|
|
|
if (a2)
|
|
|
|
{
|
|
|
|
a->subapps = evas_list_remove(a->subapps, a2);
|
|
|
|
a->subapps = evas_list_append(a->subapps, a2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (files)
|
|
|
|
{
|
|
|
|
free(files->data);
|
|
|
|
files = evas_list_remove_list(files, files);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_e_apps_cb_exit(void *data, int type, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Event_Exe_Exit *ev;
|
|
|
|
E_App *a;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
if (ev->exe)
|
|
|
|
{
|
|
|
|
a = ecore_exe_data_get(ev->exe);
|
|
|
|
if (a)
|
|
|
|
{
|
|
|
|
a->instances = evas_list_remove(a->instances, ev->exe);
|
|
|
|
_e_app_change(a, E_APP_EXIT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|