diff --git a/src/backends/default/open.c b/src/backends/default/open.c index 9437f5d..04d2be2 100644 --- a/src/backends/default/open.c +++ b/src/backends/default/open.c @@ -7,6 +7,8 @@ // itself at all and do everything via fs handlers for open, delete, rename // copy, import, export etc. #include "cmd.h" +#include "ecore_exe_eo.legacy.h" +#include "eina_stringshare.h" #include "eina_types.h" #include "sha.h" #include "meta.h" @@ -42,6 +44,235 @@ static Eina_List *thumb_busy_queue = NULL; static unsigned int thumb_busy_max = 8; static double thumb_update_delay = 0.25; +typedef struct +{ + const char *op; + const char *src; + const char *dst; + const char *uuid; + Ecore_Exe *exe; +} Op; + +//static Eina_List *op_queue = NULL; + +typedef struct +{ + const char *path; + Ecore_Event_Handler *handler_exe_del; + Ecore_Event_Handler *handler_exe_data; + Ecore_Exe *exe; + Eina_List *cmd_pending; + Eina_List *timers; + Eina_Bool ready : 1; +} Sub; + +typedef struct +{ + Sub *sub; + Eina_Stringshare *name; + Ecore_Timer *timer; + double delay; + Eina_Bool repeat : 1; +} Sub_Timer; + +static Eina_List *sub_queue = NULL; + +static Sub *_sub_open(const char *path, const char *backend); + +static Eina_Bool +_cb_sub_timer(void *data) +{ + Sub_Timer *st = data; + Eina_Strbuf *buf = cmd_strbuf_new("timer"); + + cmd_strbuf_append(buf, "name", st->name); + cmd_strbuf_exe_consume(buf, st->sub->exe); + if (st->repeat) return EINA_TRUE; + st->sub->timers = eina_list_remove(st->sub->timers, st); + eina_stringshare_del(st->name); + free(st); + return EINA_FALSE; +} + +static void +_sub_del(Sub *sub) +{ + sub_queue = eina_list_remove(sub_queue, sub); + eina_stringshare_replace(&(sub->path), NULL); + ecore_event_handler_del(sub->handler_exe_del); + ecore_event_handler_del(sub->handler_exe_data); + ecore_exe_free(sub->exe); + free(sub); +} + +static void +_sub_cmd_flush(Sub *sub) +{ + Eina_Strbuf *buf; + + if ((!sub->ready) || (!sub->cmd_pending)) return; + + EINA_LIST_FREE(sub->cmd_pending, buf) + { + cmd_strbuf_exe_consume(buf, sub->exe); + } +} + +static void +_sub_cmd_send(Sub *sub, Eina_Strbuf *buf) +{ + if (!sub->ready) + { + sub->cmd_pending = eina_list_append(sub->cmd_pending, buf); + return; + } + cmd_strbuf_exe_consume(buf, sub->exe); +} + +static void +_sub_command(Sub *sub, const char *str) +{ + Eina_Strbuf *buf; + Cmd *c = cmd_parse(str); + + if (!c) return; + + if (!strcmp(c->command, "backend-set")) + { // *** must call before list-begin + const char *backend = cmd_key_find(c, "backend"); + + if (backend) + { + Sub *sub2 = _sub_open(sub->path, backend); + EINA_LIST_FREE(sub->cmd_pending, buf) + { + _sub_cmd_send(sub2, buf); + } + ecore_exe_kill(sub->exe); + _sub_del(sub); + } + } + else if (!strcmp(c->command, "list-end")) + { + sub->ready = EINA_TRUE; + _sub_cmd_flush(sub); + } + else if (!strcmp(c->command, "timer-add")) + { + const char *name = cmd_key_find(c, "name"); + const char *delay = cmd_key_find(c, "delay"); + const char *repeat = cmd_key_find(c, "repeat"); + + if (name && delay) + { + Sub_Timer *st = calloc(1, sizeof(Sub_Timer)); + + if (st) + { + st->sub = sub; + st->name = eina_stringshare_add(name); + st->repeat = repeat ? EINA_TRUE : EINA_FALSE; + st->delay = (double)atoi(delay) / 1000.0; + st->timer = ecore_timer_add(st->delay, _cb_sub_timer, st); + sub->timers = eina_list_append(sub->timers, st); + } + } + } + else if (!strcmp(c->command, "timer-del")) + { + const char *name = cmd_key_find(c, "name"); + Sub_Timer *st; + Eina_List *l; + + if (name) + { + EINA_LIST_FOREACH(sub->timers, l, st) + { + if (!strcmp(st->name, name)) + { + sub->timers = eina_list_remove_list(sub->timers, l); + eina_stringshare_del(st->name); + ecore_timer_del(st->timer); + free(st); + } + } + } + } + // XXX: handle: dir-request + cmd_free(c); +} + +static Eina_Bool +_cb_sub_exe_del(void *data, int ev_type EINA_UNUSED, void *event) +{ + Sub *sub = data; + Ecore_Exe_Event_Del *ev = event; + + if (sub->exe != ev->exe) return ECORE_CALLBACK_PASS_ON; + // XXX: handle anything on sub del + _sub_del(sub); + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_cb_sub_exe_data(void *data, int ev_type EINA_UNUSED, void *event) +{ + Sub *sub = data; + Ecore_Exe_Event_Data *ev = event; + int i; + + if (sub->exe != ev->exe) return ECORE_CALLBACK_PASS_ON; + for (i = 0; ev->lines[i].line; i++) _sub_command(sub, ev->lines[i].line); + return ECORE_CALLBACK_DONE; +} + +static Sub * +_sub_open(const char *path, const char *backend) +{ + Eina_Strbuf *buf; + const char *s; + Sub *sub = calloc(1, sizeof(Sub)); + + if (!sub) return NULL; + sub->path = eina_stringshare_add(path); + buf = eina_strbuf_new(); + s = getenv("E_HOME_DIR"); + if (s) eina_strbuf_append(buf, s); + else + { + s = getenv("HOME"); + eina_strbuf_append(buf, s); + eina_strbuf_append(buf, "/.e/e"); + } + eina_strbuf_append(buf, "/efm/backends/"); + eina_strbuf_append(buf, backend); + eina_strbuf_append(buf, "/open"); + if (!ecore_file_can_exec(eina_strbuf_string_get(buf))) + { + eina_strbuf_reset(buf); + + eina_strbuf_append(buf, elm_app_lib_dir_get()); + eina_strbuf_append(buf, "/efm/backends/"); + eina_strbuf_append(buf, backend); + eina_strbuf_append(buf, "/open"); + } + sub->handler_exe_del = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, + _cb_sub_exe_del, sub); + sub->handler_exe_data = ecore_event_handler_add(ECORE_EXE_EVENT_DATA, + _cb_sub_exe_data, sub); + sub->exe = ecore_exe_pipe_run(eina_strbuf_string_get(buf), + ECORE_EXE_PIPE_READ | + ECORE_EXE_PIPE_READ_LINE_BUFFERED | + ECORE_EXE_PIPE_WRITE, + sub); + eina_strbuf_free(buf); + buf = cmd_strbuf_new("dir-set"); + cmd_strbuf_append(buf, "path", path); + cmd_strbuf_exe_consume(buf, sub->exe); + sub_queue = eina_list_append(sub_queue, sub); + return sub; +} + static Eina_Bool _file_add_mod_info(Eina_Strbuf *strbuf, const char *path, Eina_Bool delay); @@ -954,11 +1185,18 @@ _path_in_mon_dir(const char *path) static void _handle_drop_paste(const char *over, const char *action, const char *path) { + const char *mondir; + + if (!mon) return; + mondir = ecore_file_monitor_path_get(mon); + if (!mondir) return; if (over) fprintf(stderr, "DROP over=[%s] action=[%s] > [%s]\n", over, action, path); else fprintf(stderr, "DROP action=[%s] > [%s]\n", action, path); // XXX: decide what to do with file and tell frontend + // XXX: action = copy, move, ask, list, link, description + // XXX: if over, then spin up backedn for that over dir and hand work to that } void diff --git a/src/efm/efm_back_end.c b/src/efm/efm_back_end.c index 56ec21a..31a26ed 100644 --- a/src/efm/efm_back_end.c +++ b/src/efm/efm_back_end.c @@ -447,7 +447,7 @@ _cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg) CMD_DONE; } else if (!strcmp(c->command, "timer-add")) - { // *** must call before list-begin + { const char *name = cmd_key_find(c, "name"); const char *delay = cmd_key_find(c, "delay"); const char *repeat = cmd_key_find(c, "repeat"); @@ -469,7 +469,7 @@ _cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg) CMD_DONE; } else if (!strcmp(c->command, "timer-del")) - { // *** must call before list-begin + { const char *name = cmd_key_find(c, "name"); Smart_Data_Timer *st; Eina_List *l; diff --git a/src/efm/efm_structs.h b/src/efm/efm_structs.h index cfb852b..78edbe8 100644 --- a/src/efm/efm_structs.h +++ b/src/efm/efm_structs.h @@ -30,8 +30,8 @@ struct _Smart_Data_Timer Eina_Bool repeat : 1; }; - // an icon view gui data - struct _Smart_Data +// an icon view gui data +struct _Smart_Data { Evas_Object_Smart_Clipped_Data __clipped_data;