ecore_evas_convert: Implement hacky solution for Ctrl+C

Problem: evas_object_image_save() can't be interrupted.
But, with ETC1/ETC2 encoding, it might be terribly long and
the user has no way to cancel encoding (except SIGKILL).

The proper solution would be to tell evas that the save
operation has been cancelled. And run that in a thread,
in a non-blocking way. I guess Efl.File.async could be
used for that, which means maybe also introduce
Efl.File.async_cancel? This will have to wait for
EFL 1.15 I'm afraid.

Note: edje_cc still can't be cancelled during ETC encoding.
This commit is contained in:
Jean-Philippe Andre 2015-04-07 16:48:49 +09:00
parent 18d5e04bb5
commit e9cd816839
1 changed files with 58 additions and 7 deletions

View File

@ -36,6 +36,54 @@ const Ecore_Getopt optdesc = {
}
};
struct Save_Job {
const char *output;
const char *flags;
Ecore_Thread *th;
Evas_Object *im;
int ret, cancel;
};
static void
_save_do(void *data, Ecore_Thread *thread EINA_UNUSED)
{
struct Save_Job *job = data;
job->ret = 0;
if (!evas_object_image_save(job->im, job->output, NULL, job->flags))
{
EINA_LOG_ERR("Could not convert file to '%s'.", job->output);
job->ret = 1;
}
}
static void
_save_end(void *data EINA_UNUSED, Ecore_Thread *thread EINA_UNUSED)
{
ecore_main_loop_quit();
}
static Eina_Bool
exit_func(void *data, int ev_type EINA_UNUSED, void *ev)
{
Ecore_Event_Signal_Exit *e = ev;
struct Save_Job *job = data;
if (!job->cancel && !e->quit && !e->terminate)
{
// this won't do anything, really...
fprintf(stderr, "Cancellation requested. Press Ctrl+C again to kill.\n");
fflush(stderr);
job->cancel = 1;
ecore_thread_cancel(job->th);
}
else
{
fprintf(stderr, "Terminated.");
exit(1);
}
return ECORE_CALLBACK_RENEW;
}
int
main(int argc, char *argv[])
{
@ -49,6 +97,7 @@ main(int argc, char *argv[])
Eina_Bool compress = 1;
Eina_Bool quit_option = EINA_FALSE;
Eina_Strbuf *flags = NULL;
struct Save_Job job = {0};
Ecore_Getopt_Value values[] = {
ECORE_GETOPT_VALUE_INT(quality),
@ -107,14 +156,16 @@ main(int argc, char *argv[])
goto end;
}
if (!evas_object_image_save(im, argv[arg_index + 1], NULL,
eina_strbuf_string_get(flags)))
{
EINA_LOG_ERR("Could not convert file to '%s'.", argv[arg_index + 1]);
goto end;
}
// NOTE: DO NOT DO THIS AT HOME -- HACK for Ctrl+C
// This makes Ctrl+C work but the Evas Object may not be deleted cleanly
job.output = argv[arg_index + 1];
job.flags = eina_strbuf_string_get(flags);
job.im = im;
job.th = ecore_thread_run(_save_do, _save_end, _save_end, &job);
ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, &job);
ecore_main_loop_begin();
r = 0;
r = job.ret;
end:
if (flags) eina_strbuf_free(flags);