This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository efm2.
View the commit online.
commit ce0776c5fb5ea8d88499a7907b3bb3ad8297af84
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
AuthorDate: Wed May 29 22:09:44 2024 +0100
add an efm task watcher with super basic ui
thuis starts a task/op/status watcher with a gui that can show tasks
with progress and some status. status is properly written out.
scanning and progress is properly calculated. it's beginning to really
work and be controllable.
---
src/backends/default/fs.c | 15 ++-
src/backends/default/mv.c | 33 +++++-
src/backends/default/open.c | 1 -
src/backends/default/status.c | 53 ++++++++--
src/backends/default/status.h | 1 +
src/efm/efm_back_end.c | 4 +-
src/efm/efm_tasks.c | 238 ++++++++++++++++++++++++++++++++++++++++++
src/efm/meson.build | 10 ++
src/shared/status_mon.c | 223 +++++++++++++++++++++++++++++++++++++++
src/shared/status_mon.h | 17 +++
10 files changed, 574 insertions(+), 21 deletions(-)
diff --git a/src/backends/default/fs.c b/src/backends/default/fs.c
index affe9b3..2da4b64 100644
--- a/src/backends/default/fs.c
+++ b/src/backends/default/fs.c
@@ -148,6 +148,7 @@ again_write:
}
else if (ret2 == ret)
{
+ status_pos(ret2, src);
off_ou += ret;
if (ret < size) break; // end of file
}
@@ -171,7 +172,11 @@ again_write:
goto err;
}
}
- else if (ret < size) break; // end of file
+ else
+ {
+ status_pos(ret, src);
+ if (ret < size) break; // end of file
+ }
}
}
}
@@ -433,16 +438,15 @@ fs_mv(const char *src, const char *dst, Eina_Bool report_err)
int ret;
const char *op = "Move";
- status_op("mv");
- status_count(1, src);
ret = rename(src, dst);
- if (ret == 0) return res;
+ if (ret == 0) goto done;
else
{
switch (errno)
{
case EXDEV: // revert to cp + rm
- return fs_cp_rm(src, dst, report_err, EINA_TRUE, EINA_TRUE);
+ res = fs_cp_rm(src, dst, report_err, EINA_TRUE, EINA_TRUE);
+ goto done;
break;
default:
if (report_err) _error_handle(src, dst, op, errno);
@@ -450,6 +454,7 @@ fs_mv(const char *src, const char *dst, Eina_Bool report_err)
break;
}
}
+done:
status_pos(1, src);
return res;
}
diff --git a/src/backends/default/mv.c b/src/backends/default/mv.c
index ff7a44c..e8287ec 100644
--- a/src/backends/default/mv.c
+++ b/src/backends/default/mv.c
@@ -98,6 +98,8 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
if (!buf) goto err;
status_begin();
+ status_op("mv");
+
EINA_LIST_FOREACH(files, l, fs)
{
struct stat stsrc, stdst;
@@ -113,12 +115,16 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
fname = ecore_file_file_get(fs->src);
if (!fname) break;
+ // when monitoring/watching a status file dst dst=xxx allows you to place
+ // progress in the right dst dir
+ status_dst(fs->dst);
eina_strbuf_reset(buf);
eina_strbuf_append(buf, fs->dst);
eina_strbuf_append(buf, "/");
eina_strbuf_append(buf, fname);
+ // mv the file ...
if (fs_mv(fs->src, eina_strbuf_string_get(buf), EINA_TRUE))
- {
+ { // it worked so deal with meta/thumbs
Eina_Bool src_can_write, dst_can_write;
const char *dstfile;
char *src_meta, *dst_meta;
@@ -133,15 +139,36 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
if (dst_can_write) dst_meta = meta_path_find(dstfile, "meta.efm");
else dst_meta = meta_path_user_find(dstfile, "meta.efm");
if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
- fs_mv(src_meta, dst_meta, EINA_FALSE);
+ {
+ status_count(1, src_meta);
+ fs_mv(src_meta, dst_meta, EINA_FALSE);
+ // XXX: how do we force a re-read of the meta file? also how to
+ // merge? e.g. we dnd an icon into a dir - we may or may not at that
+ // point write x,y to the meta file - but we have other fields we
+ // will want to merge in ... so we don't want to mv here - we want
+ // to merge sensibly... so ugh... bug already here ... we want
+ // to also trigger an update of meta data for any efm backends
+ // telling the front-ends...
+ }
free(src_meta);
free(dst_meta);
+
if (src_can_write) src_meta = meta_path_find(fs->src, "thumb.efm");
else src_meta = meta_path_user_find(fs->src, "thumb.efm");
if (dst_can_write) dst_meta = meta_path_find(dstfile, "thumb.efm");
else dst_meta = meta_path_user_find(dstfile, "thumb.efm");
if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
- fs_mv(src_meta, dst_meta, EINA_FALSE);
+ {
+ status_count(1, src_meta);
+ fs_mv(src_meta, dst_meta, EINA_FALSE);
+ // XXX: we seem to have any open active re-gen thumbs here as
+ // opposed to use the thumb we mv'd across. we need to do something
+ // like block any thumbnailing while in progress andf tyhen the
+ // thumb has to have its statinfo replaced with valid statinfo
+ // from the new finished cp/mv'd file as its valid... also when
+ // the thumb is finished copying/updating/mvind we need active
+ // opens know to send updates to the views
+ }
free(src_meta);
free(dst_meta);
}
diff --git a/src/backends/default/open.c b/src/backends/default/open.c
index ecce45d..72685cd 100644
--- a/src/backends/default/open.c
+++ b/src/backends/default/open.c
@@ -17,7 +17,6 @@
#include <pwd.h>
#include <grp.h>
-#include "Ecore_Common.h"
#include "cmd.h"
#include "eina_types.h"
#include "sha.h"
diff --git a/src/backends/default/status.c b/src/backends/default/status.c
index cad830e..08bf315 100644
--- a/src/backends/default/status.c
+++ b/src/backends/default/status.c
@@ -13,6 +13,7 @@
typedef enum
{
MSG_OP,
+ MSG_DST,
MSG_COUNT,
MSG_POS,
MSG_ERR,
@@ -34,6 +35,12 @@ typedef struct
char *op;
} Msg_Op;
+typedef struct
+{
+ MSG_HEAD;
+ char *dst;
+} Msg_Dst;
+
typedef struct
{
MSG_HEAD;
@@ -66,6 +73,7 @@ static unsigned long long op_pos = 0;
static unsigned long long op_count_prev = 0;
static unsigned long long op_pos_prev = 0;
static Eina_Bool op_end = EINA_FALSE;
+static Eina_Bool op_end_prev = EINA_FALSE;
static char *op_str = NULL;
static int status_fd = -1;
static char *status_file = NULL;
@@ -91,15 +99,19 @@ _fd_printf(int fd, const char *fmt, ...)
static void
_status_flush(void)
{
- if ((op_count == op_count_prev) && (op_pos == op_pos_prev)) return;
- op_count_prev = op_count;
- op_pos_prev = op_pos;
- _fd_printf(status_fd, "CMD progress pos=%llu count=%llu\n", op_pos,
- op_count);
+ if ((op_count == op_count_prev) && (op_pos == op_pos_prev)
+ && (op_end == op_end_prev))
+ return;
+ if ((op_count != op_count_prev) || (op_pos != op_pos_prev))
+ _fd_printf(status_fd, "CMD progress pos=%llu count=%llu\n", op_pos,
+ op_count);
if (op_str) _fd_printf(status_fd, "CMD progress str=%s\n", op_str);
- if (op_end) _fd_printf(status_fd, "CMD end\n");
+ if ((op_end) && (op_end != op_end_prev)) _fd_printf(status_fd, "CMD end\n");
free(op_str);
- op_str = NULL;
+ op_str = NULL;
+ op_count_prev = op_count;
+ op_pos_prev = op_pos;
+ op_end_prev = op_end;
}
static void *
@@ -124,11 +136,19 @@ _cb_status_thread(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED)
{
Msg_Op *msg2 = (Msg_Op *)msg;
// write this out immediately
- _fd_printf(status_fd, "CMD op %s\n", msg2->op);
- _fd_printf(status_fd, "CMD pid %i\n", (int)getpid());
+ _fd_printf(status_fd, "CMD op op=%s\n", msg2->op);
+ _fd_printf(status_fd, "CMD pid pid=%i\n", (int)getpid());
free(msg2->op);
}
break;
+ case MSG_DST:
+ {
+ Msg_Dst *msg2 = (Msg_Dst *)msg;
+ // write this out immediately
+ _fd_printf(status_fd, "CMD dst dst=%s\n", msg2->dst);
+ free(msg2->dst);
+ }
+ break;
case MSG_COUNT:
{
Msg_Count *msg2 = (Msg_Count *)msg;
@@ -152,7 +172,7 @@ _cb_status_thread(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED)
_fd_printf(status_fd, "CMD error err=%s\n", msg2->str);
if (msg2->src) _fd_printf(status_fd, "CMD error src="" msg2->src);
if (msg2->dst) _fd_printf(status_fd, "CMD error dst=%s\n", msg2->dst);
- _fd_printf(status_fd, "CMD error done\n");
+ _fd_printf(status_fd, "CMD error-done\n");
free(msg2->src);
free(msg2->dst);
free(msg2->str);
@@ -162,6 +182,7 @@ _cb_status_thread(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED)
break;
case MSG_END:
{
+ op_end = EINA_TRUE;
_status_flush();
if (status_fd >= 0)
{
@@ -229,6 +250,18 @@ status_op(const char *op)
eina_thread_queue_send_done(status_thq, ref);
}
+void
+status_dst(const char *dst)
+{
+ Msg_Dst *msg;
+ void *ref;
+
+ msg = eina_thread_queue_send(status_thq, sizeof(Msg_Dst), &ref);
+ msg->type = MSG_DST;
+ msg->dst = dst ? escape(dst) : NULL;
+ eina_thread_queue_send_done(status_thq, ref);
+}
+
void
status_count(unsigned long long num_inc, const char *str)
{
diff --git a/src/backends/default/status.h b/src/backends/default/status.h
index 4fd21b2..378ec00 100644
--- a/src/backends/default/status.h
+++ b/src/backends/default/status.h
@@ -24,6 +24,7 @@
void status_begin(void);
void status_end(void);
void status_op(const char *op);
+void status_dst(const char *dst);
void status_count(unsigned long long num_inc, const char *str);
void status_pos(unsigned long long pos_inc, const char *str);
// this call will cause the status thread to report the error then exit(1)
diff --git a/src/efm/efm_back_end.c b/src/efm/efm_back_end.c
index 20d6ef9..c53cc89 100644
--- a/src/efm/efm_back_end.c
+++ b/src/efm/efm_back_end.c
@@ -345,7 +345,7 @@ _icon_add_mod_props_get(Icon *icon, Cmd *c, const char *label)
eina_stringshare_replace(&(icon->info.label_selected), s);
s = cmd_key_find(c, "mime");
if (s) eina_stringshare_replace(&(icon->info.mime), s);
- if (s) printf("XXXXX mime=%s\n", icon->info.mime);
+// if (s) printf("XXXXX mime=%s\n", icon->info.mime);
s = cmd_key_find(c, "desktop-icon");
if (!s) s = cmd_key_find(c, "link-desktop-icon");
if (s) eina_stringshare_replace(&(icon->info.pre_lookup_icon), s);
@@ -576,7 +576,7 @@ _cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg)
// below commands all send a path for a specific file
path = file = cmd_key_find(c, "path");
- printf("XXXXX [%s] [%s]\n", c->command, file);
+// printf("XXXXX [%s] [%s]\n", c->command, file);
if (file)
{
s = strrchr(file, '/');
diff --git a/src/efm/efm_tasks.c b/src/efm/efm_tasks.c
new file mode 100644
index 0000000..60c3bb9
--- /dev/null
+++ b/src/efm/efm_tasks.c
@@ -0,0 +1,238 @@
+#include <Elementary.h>
+
+#include "status_mon.h"
+
+static Evas_Object *tasks_box = NULL;
+static Eina_List *tasks = NULL;
+
+typedef struct
+{
+ Status_Op *op;
+ Evas_Object *o_base, *o_progress, *o_label, *o_label_dst, *o_label_str;
+} Task;
+
+static Task *
+task_find(Status_Op *op)
+{
+ Eina_List *l;
+ Task *t;
+
+ EINA_LIST_FOREACH(tasks, l, t)
+ {
+ if (t->op == op) return t;
+ }
+ return NULL;
+}
+
+static Task *
+task_add(Status_Op *op)
+{
+ Task *t = calloc(1, sizeof(Task));
+
+ if (!t) return NULL;
+ tasks = eina_list_append(tasks, t);
+ t->op = op;
+ return t;
+}
+
+static void
+task_del(Task *t)
+{
+ Eina_List *l;
+ Task *t2;
+
+ EINA_LIST_FOREACH(tasks, l, t2)
+ {
+ if (t == t2)
+ {
+ tasks = eina_list_remove(tasks, t);
+ free(t);
+ return;
+ }
+ }
+}
+
+static void
+task_new(Task *t)
+{
+ Evas_Object *o, *bx;
+
+ bx = o = elm_box_add(tasks_box);
+ evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0);
+ elm_box_horizontal_set(o, EINA_FALSE);
+ elm_box_pack_end(tasks_box, o);
+ evas_object_show(o);
+ t->o_base = o;
+
+ o = elm_label_add(tasks_box);
+ evas_object_size_hint_fill_set(o, 0, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0);
+ elm_box_pack_end(bx, o);
+ evas_object_show(o);
+ t->o_label = o;
+
+ o = elm_label_add(tasks_box);
+ evas_object_size_hint_fill_set(o, 0, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0);
+ elm_box_pack_end(bx, o);
+ evas_object_show(o);
+ t->o_label_dst = o;
+
+ o = elm_label_add(tasks_box);
+ evas_object_size_hint_fill_set(o, 0, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0);
+ elm_box_pack_end(bx, o);
+ evas_object_show(o);
+ t->o_label_str = o;
+
+ o = elm_progressbar_add(tasks_box);
+ evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0);
+ elm_progressbar_horizontal_set(o, EINA_TRUE);
+ elm_progressbar_unit_format_set(o, "%1.1f%%");
+ elm_progressbar_span_size_set(o, ELM_SCALE_SIZE(200));
+ elm_box_pack_end(bx, o);
+ evas_object_show(o);
+ t->o_progress = o;
+}
+
+static void
+_cb_status(void *data EINA_UNUSED, Status_Op *op, Cmd *cmd)
+{
+ Task *t;
+ const char *s, *s2;
+
+ t = task_find(op);
+ if (!t)
+ {
+ t = task_add(op);
+ if (!t) return;
+ task_new(t);
+ }
+ if (!cmd)
+ {
+ evas_object_del(t->o_base);
+ task_del(t);
+ return;
+ }
+ if (!strcmp(cmd->command, "op"))
+ {
+ s = cmd_key_find(cmd, "op");
+ if (s)
+ {
+ if (!strcmp(s, "mv")) elm_object_text_set(t->o_label, "Move");
+ }
+ }
+ else if (!strcmp(cmd->command, "dst"))
+ {
+ s = cmd_key_find(cmd, "dst");
+ if (s)
+ {
+ elm_object_text_set(t->o_label_dst, s);
+ }
+ }
+ else if (!strcmp(cmd->command, "progress"))
+ {
+ s = cmd_key_find(cmd, "str");
+ if (s)
+ {
+ elm_object_text_set(t->o_label_str, s);
+ }
+ s = cmd_key_find(cmd, "pos");
+ if (s)
+ {
+ s2 = cmd_key_find(cmd, "count");
+ if (s2)
+ {
+ unsigned long long pos, count;
+
+ pos = atoll(s);
+ count = atoll(s2);
+
+ if ((pos > 0) && (count > 0))
+ {
+ double v = (double)pos / (double)count;
+
+ elm_progressbar_value_set(t->o_progress, v);
+ }
+ }
+ }
+ }
+ else if (!strcmp(cmd->command, "end"))
+ {
+ evas_object_del(t->o_base);
+ task_del(t);
+ }
+ // handle "error"
+}
+
+static void
+_cb_exit(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ elm_exit();
+}
+
+EAPI_MAIN int
+elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
+{
+ Evas_Object *o, *win, *bx, *sc, *bx2;
+
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
+ win = o = elm_win_util_standard_add("Main", "Tasks");
+ elm_win_icon_name_set(o, "Tasks");
+ elm_win_role_set(o, "efm_win_tasks");
+ elm_win_autodel_set(o, EINA_TRUE);
+
+ bx = o = elm_box_add(win);
+ evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_box_horizontal_set(o, EINA_FALSE);
+ elm_win_resize_object_add(win, o);
+ evas_object_show(o);
+
+ sc = o = elm_scroller_add(win);
+ evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_box_pack_end(bx, o);
+ evas_object_show(o);
+
+ tasks_box = o = elm_box_add(win);
+ evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, 0);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0);
+ elm_box_homogeneous_set(o, EINA_TRUE);
+ elm_box_horizontal_set(o, EINA_FALSE);
+ elm_object_content_set(sc, o);
+ evas_object_show(o);
+
+ bx2 = o = elm_box_add(win);
+ evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, 0);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0);
+ elm_box_homogeneous_set(o, EINA_TRUE);
+ elm_box_horizontal_set(o, EINA_TRUE);
+ elm_box_pack_end(bx, o);
+ evas_object_show(o);
+
+ o = elm_button_add(win);
+ evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, 0);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0);
+ elm_object_text_set(o, "Exit");
+ evas_object_smart_callback_add(o, "clicked", _cb_exit, NULL);
+ elm_box_pack_end(bx2, o);
+ evas_object_show(o);
+
+ evas_object_resize(win, ELM_SCALE_SIZE(480), ELM_SCALE_SIZE(640));
+ evas_object_show(win);
+
+ status_mon_init();
+ status_mon_callback_add(_cb_status, NULL);
+ status_mon_begin();
+
+ elm_run();
+
+ status_mon_shutdown();
+
+ return 0;
+}
+ELM_MAIN()
\ No newline at end of file
diff --git a/src/efm/meson.build b/src/efm/meson.build
index e1ded60..08692bd 100644
--- a/src/efm/meson.build
+++ b/src/efm/meson.build
@@ -21,3 +21,13 @@ executable('efm', [
dependencies: deps,
install: true,
install_dir: dir)
+
+executable('efm_tasks', [
+ '../shared/cmd.c',
+ '../shared/status_mon.c',
+ 'efm_tasks.c',
+ ],
+ include_directories: inc,
+ dependencies: deps,
+ install: true,
+ install_dir: dir)
diff --git a/src/shared/status_mon.c b/src/shared/status_mon.c
new file mode 100644
index 0000000..514830e
--- /dev/null
+++ b/src/shared/status_mon.c
@@ -0,0 +1,223 @@
+#include "eina_list.h"
+#include <stdio.h>
+#define EFL_BETA_API_SUPPORT 1
+
+#include <Eina.h>
+#include <Ecore_File.h>
+
+#include "status_mon.h"
+
+struct _Status_Op
+{
+ const char *path;
+ FILE *file;
+};
+
+typedef struct
+{
+ Status_Mon_Callback cb;
+ void *data;
+ Eina_Bool delete_me : 1;
+} Status_Callback;
+
+static Ecore_File_Monitor *mon = NULL;
+static Eina_List *ops = NULL;
+static Eina_List *cbs = NULL;
+static int cbs_walk = 0;
+static int cbs_del = 0;
+
+static void
+status_callback_clean(void)
+{
+ Eina_List *l, *ll;
+ Status_Callback *sc;
+
+ if ((cbs_walk > 0) || (cbs_del <= 0)) return;
+ EINA_LIST_FOREACH_SAFE(cbs, l, ll, sc)
+ {
+ if (sc->delete_me)
+ {
+ cbs = eina_list_remove_list(cbs, l);
+ free(sc);
+ }
+ }
+ cbs_del = 0;
+}
+
+static Status_Op *
+status_op_add(const char *path)
+{
+ Status_Op *so = calloc(1, sizeof(Status_Op));
+
+ if (!so) return NULL;
+ so->path = eina_stringshare_add(path);
+ so->file = fopen(so->path, "r");
+ ops = eina_list_append(ops, so);
+ printf(" NEW %p\n", so->file);
+ return so;
+}
+
+static void
+status_op_del(Status_Op *so)
+{
+ ops = eina_list_remove(ops, so);
+ fclose(so->file);
+ eina_stringshare_del(so->path);
+ free(so);
+}
+
+static Status_Op *
+status_op_find(const char *path)
+{
+ Eina_List *l;
+ Status_Op *so;
+
+ EINA_LIST_FOREACH(ops, l, so)
+ {
+ if (!strcmp(so->path, path)) return so;
+ }
+ return NULL;
+}
+
+static void
+status_op_read(Status_Op *so)
+{
+ // XXX: move this to a thread, although these status files SHOULD
+ // be in a ramdisk or cache and thus immediately readable without
+ // any blocking, so i can do this later as an optimmization if needed
+ char buf[PATH_MAX + 256];
+ Cmd *cmd;
+ long pos;
+
+ pos = ftell(so->file);
+ fseek(so->file, pos, SEEK_SET);
+ while (fgets(buf, sizeof(buf), so->file))
+ {
+ size_t sz = strlen(buf);
+
+ if (sz < 1) continue;
+ buf[sz - 1] = 0; // nuke \n
+ printf(" READ CMD [%s]\n", buf);
+ cmd = cmd_parse(buf);
+ if (cmd)
+ {
+ Eina_List *l;
+ Status_Callback *sc;
+
+ cbs_walk++;
+ EINA_LIST_FOREACH(cbs, l, sc) sc->cb(sc->data, so, cmd);
+ cbs_walk--;
+ status_callback_clean();
+ cmd_free(cmd);
+ }
+ }
+}
+
+static void
+_file_add(const char *path)
+{
+ Status_Op *so;
+
+ fprintf(stderr, "ADD %s\n", path);
+ so = status_op_add(path);
+ if (so) status_op_read(so);
+}
+
+static void
+_file_del(const char *path)
+{
+ Status_Op *so;
+
+ fprintf(stderr, "DEL %s\n", path);
+ so = status_op_find(path);
+ if (so)
+ {
+ Eina_List *l;
+ Status_Callback *sc;
+
+ cbs_walk++;
+ EINA_LIST_FOREACH(cbs, l, sc) sc->cb(sc->data, so, NULL);
+ cbs_walk--;
+ status_callback_clean();
+ status_op_del(so);
+ }
+}
+
+static void
+_file_mod(const char *path)
+{
+ Status_Op *so;
+
+ fprintf(stderr, "MOD %s\n", path);
+ so = status_op_find(path);
+ if (so) status_op_read(so);
+}
+
+static void
+_cb_mon(void *data EINA_UNUSED, Ecore_File_Monitor *em EINA_UNUSED,
+ Ecore_File_Event event, const char *path)
+{
+ if ((event == ECORE_FILE_EVENT_CREATED_FILE)
+ || (event == ECORE_FILE_EVENT_CREATED_DIRECTORY))
+ _file_add(path);
+ else if ((event == ECORE_FILE_EVENT_DELETED_FILE)
+ || (event == ECORE_FILE_EVENT_DELETED_DIRECTORY))
+ _file_del(path);
+ else if (event == ECORE_FILE_EVENT_MODIFIED) _file_mod(path);
+}
+
+void status_mon_init(void)
+{
+}
+
+void
+status_mon_callback_add(Status_Mon_Callback cb, void *data)
+{
+ Status_Callback *sc = calloc(1, sizeof(Status_Callback));
+
+ if (!sc) return;
+ sc->cb = cb;
+ sc->data = ""
+ cbs = eina_list_append(cbs, sc);
+}
+
+void
+status_mon_callback_del(Status_Mon_Callback cb, void *data)
+{
+ Eina_List *l;
+ Status_Callback *sc;
+
+ EINA_LIST_FOREACH(cbs, l, sc)
+ {
+ if ((cb == sc->cb) && (data == sc->data))
+ {
+ if (cbs_walk <= 0)
+ {
+ cbs = eina_list_remove_list(cbs, l);
+ free(sc);
+ }
+ else
+ {
+ sc->delete_me = EINA_TRUE;
+ cbs_del++;
+ }
+ break;
+ }
+ }
+}
+
+void
+status_mon_begin(void)
+{
+ char buf[PATH_MAX];
+
+ eina_vpath_resolve_snprintf(buf, sizeof(buf), "(:usr.run:)/efm/ops");
+ ecore_file_mkpath(buf);
+ mon = ecore_file_monitor_add(buf, _cb_mon, NULL);
+}
+
+void status_mon_shutdown(void)
+{
+ if (mon) ecore_file_monitor_del(mon);
+ mon = NULL;
+}
\ No newline at end of file
diff --git a/src/shared/status_mon.h b/src/shared/status_mon.h
new file mode 100644
index 0000000..9ec833b
--- /dev/null
+++ b/src/shared/status_mon.h
@@ -0,0 +1,17 @@
+#ifndef STATUS_MON_H
+#define STATUS_MON_H
+
+#include <Eina.h>
+#include "cmd.h"
+
+typedef struct _Status_Op Status_Op;
+
+typedef void (*Status_Mon_Callback) (void *data, Status_Op *op, Cmd *cmd);
+
+void status_mon_init(void);
+void status_mon_callback_add(Status_Mon_Callback cb, void *data);
+void status_mon_callback_del(Status_Mon_Callback cb, void *data);
+void status_mon_begin(void);
+void status_mon_shutdown(void);
+
+#endif
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.