From 3f22a0c26da52e60a42ee2e685ba7031edcbd629 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Wed, 22 Jan 2020 20:39:19 +0000 Subject: [PATCH] e - wallpaper gen - generate multiple resolutions for wallpapers pre-scale a bunch of resolutions for generated wallpaper files that intersect with common resolution sizes so e will automatically load the nearest resolution to be more efficient on load to only decode what is needed. a bi-product is that e now has a wallapper gen tool that is simpler than writing your own edc files... :) @feature --- TODO | 5 +- src/bin/e_import_config_dialog.c | 301 ++++--------------- src/bin/e_import_config_dialog.h | 17 +- src/bin/e_wallpaper_gen_main.c | 499 +++++++++++++++++++++++++++++++ src/bin/meson.build | 6 +- 5 files changed, 570 insertions(+), 258 deletions(-) create mode 100644 src/bin/e_wallpaper_gen_main.c diff --git a/TODO b/TODO index 604f1ee29..4c2a72f57 100644 --- a/TODO +++ b/TODO @@ -119,9 +119,8 @@ TODO: * set user password * user cron front-end config/editor * allow separate LC_MESSAGES, LC_TIME, LC_NUMERIC, LC_NAME, etc. -* wallpaper: gen wp files with multiple common resolutions in image set - * edje needs logic to handle max texture size and to downsize to work - * rpi max texture size is 2048... +* edje needs logic to handle max texture size to fix big img problems + * rpi max texture size is 2048... * dnd: remove e_dnd and use elm's dnd instead * new gadgets: * be able to move, resize etc. without alt move/resize mode like old) diff --git a/src/bin/e_import_config_dialog.c b/src/bin/e_import_config_dialog.c index 87db60c35..0ffa6d518 100644 --- a/src/bin/e_import_config_dialog.c +++ b/src/bin/e_import_config_dialog.c @@ -13,24 +13,16 @@ static Eina_Bool _import_cb_edje_cc_exit(void *data, int type, void *event); static void _import_edj_gen(E_Import_Config_Dialog *import) { - Evas *evas; - Evas_Object *img; - Eina_Bool anim = EINA_FALSE; - int fd, num = 1; - int w = 0, h = 0; - const char *file, *locale; - char buf[PATH_MAX], fbuf[PATH_MAX], cmd[PATH_MAX + PATH_MAX + 40], tmpn[PATH_MAX], ipart[PATH_MAX], enc[128]; - Eina_Tmpstr *path = NULL; - char *imgdir = NULL, *fstrip; - int cr, cg, cb, ca; - FILE *f; + const char *file, *fill, *s; + char buf[PATH_MAX], fbuf[PATH_MAX], cmd[PATH_MAX + PATH_MAX + 40]; + char *fstrip, *infile, *outfile; + int num, cr, cg, cb; size_t len, off; - evas = evas_object_evas_get(import->dia->win); file = ecore_file_file_get(import->file); fstrip = ecore_file_strip_ext(file); if (!fstrip) return; - len = e_user_dir_snprintf(buf, sizeof(buf), "backgrounds/%s.edj", fstrip); + len = e_user_dir_snprintf(buf, sizeof(buf), "backgrounds/.tmp.%s.edj", fstrip); if (len >= sizeof(buf)) { free(fstrip); @@ -43,238 +35,47 @@ _import_edj_gen(E_Import_Config_Dialog *import) cr = import->color.r; cg = import->color.g; cb = import->color.b; - ca = import->color.a; if (num == 100) { printf("Couldn't come up with another filename for %s\n", buf); return; } - - strcpy(tmpn, "e_bgdlg_new.edc-tmp-XXXXXX"); - fd = eina_file_mkstemp(tmpn, &path); - if (fd < 0) - { - printf("Error Creating tmp file: %s\n", strerror(errno)); - return; - } - - f = fdopen(fd, "w"); - if (!f) - { - printf("Cannot open %s for writing\n", tmpn); - return; - } - - anim = eina_str_has_extension(import->file, "gif"); - imgdir = ecore_file_dir_get(import->file); - if (!imgdir) ipart[0] = '\0'; - else - { - snprintf(ipart, sizeof(ipart), "-id %s", e_util_filename_escape(imgdir)); - free(imgdir); - } - - img = evas_object_image_add(evas); - evas_object_image_file_set(img, import->file, NULL); - evas_object_image_size_get(img, &w, &h); - evas_object_del(img); - - if (import->external) - { - const char *esc = e_util_filename_escape(import->file); - fstrip = memcpy(fbuf, esc, strlen(esc) + 1); - snprintf(enc, sizeof(enc), "USER"); - } - else - { - const char *esc = e_util_filename_escape(file); - fstrip = memcpy(fbuf, esc, strlen(esc) + 1); - if (import->quality == 100) - snprintf(enc, sizeof(enc), "COMP"); - else - snprintf(enc, sizeof(enc), "LOSSY %i", import->quality); - } switch (import->method) { - case IMPORT_STRETCH: - fprintf(f, - "images { image: \"%s\" %s; }\n" - "collections {\n" - "group { name: \"e/desktop/background\";\n" - "%s" - "data { item: \"style\" \"0\"; }\n" - "parts {\n" - "part { name: \"bg\"; mouse_events: 0;\n" - "description { state: \"default\" 0.0;\n" - "image { normal: \"%s\"; scale_hint: STATIC; }\n" - "} } } } }\n" - , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", fstrip); - break; - - case IMPORT_TILE: - fprintf(f, - "images { image: \"%s\" %s; }\n" - "collections {\n" - "group { name: \"e/desktop/background\";\n" - "data { item: \"style\" \"1\"; }\n" - "%s" - "parts {\n" - "part { name: \"bg\"; mouse_events: 0;\n" - "description { state: \"default\" 0.0;\n" - "image { normal: \"%s\"; }\n" - "fill { size {\n" - "relative: 0.0 0.0;\n" - "offset: %i %i;\n" - "} } } } } } }\n" - , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", fstrip, w, h); - break; - - case IMPORT_CENTER: - fprintf(f, - "images { image: \"%s\" %s; }\n" - "collections {\n" - "group { name: \"e/desktop/background\";\n" - "data { item: \"style\" \"2\"; }\n" - "%s" - "parts {\n" - "part { name: \"col\"; type: RECT; mouse_events: 0;\n" - "description { state: \"default\" 0.0;\n" - "color: %i %i %i %i;\n" - "} }\n" - "part { name: \"bg\"; mouse_events: 0;\n" - "description { state: \"default\" 0.0;\n" - "min: %i %i; max: %i %i;\n" - "image { normal: \"%s\"; }\n" - "} } } } }\n" - , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", cr, cg, cb, ca, w, h, w, h, fstrip); - break; - - case IMPORT_SCALE_ASPECT_IN: - locale = e_intl_language_get(); - setlocale(LC_NUMERIC, "C"); - fprintf(f, - "images { image: \"%s\" %s; }\n" - "collections {\n" - "group { name: \"e/desktop/background\";\n" - "data { item: \"style\" \"3\"; }\n" - "%s" - "parts {\n" - "part { name: \"col\"; type: RECT; mouse_events: 0;\n" - "description { state: \"default\" 0.0;\n" - "color: %i %i %i %i;\n" - "} }\n" - "part { name: \"bg\"; mouse_events: 0;\n" - "description { state: \"default\" 0.0;\n" - "aspect: %1.9f %1.9f; aspect_preference: BOTH;\n" - "image { normal: \"%s\"; scale_hint: STATIC; }\n" - "} } } } }\n" - , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", - cr, cg, cb, ca, (double)w / (double)h, (double)w / (double)h, fstrip); - setlocale(LC_NUMERIC, locale); - break; - - case IMPORT_SCALE_ASPECT_OUT: - locale = e_intl_language_get(); - setlocale(LC_NUMERIC, "C"); - fprintf(f, - "images { image: \"%s\" %s; }\n" - "collections {\n" - "group { name: \"e/desktop/background\";\n" - "data { item: \"style\" \"4\"; }\n" - "%s" - "parts {\n" - "part { name: \"bg\"; mouse_events: 0;\n" - "description { state: \"default\" 0.0;\n" - "aspect: %1.9f %1.9f; aspect_preference: NONE;\n" - "image { normal: \"%s\"; scale_hint: STATIC; }\n" - "} } } } }\n" - , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", - (double)w / (double)h, (double)w / (double)h, fstrip); - setlocale(LC_NUMERIC, locale); - break; - - case IMPORT_PAN: - locale = e_intl_language_get(); - setlocale(LC_NUMERIC, "C"); - fprintf(f, - "images { image: \"%s\" %s; }\n" - "collections {\n" - "group { name: \"e/desktop/background\";\n" - "data { item: \"style\" \"4\"; }\n" - "%s" - "script {\n" - "public cur_anim; public cur_x; public cur_y; public prev_x;\n" - "public prev_y; public total_x; public total_y; \n" - "public pan_bg(val, Float:v) {\n" - "new Float:x, Float:y, Float:px, Float: py;\n" - - "px = get_float(prev_x); py = get_float(prev_y);\n" - "if (get_int(total_x) > 1) {\n" - "x = float(get_int(cur_x)) / (get_int(total_x) - 1);\n" - "x = px - (px - x) * v;\n" - "} else { x = 0.0; v = 1.0; }\n" - "if (get_int(total_y) > 1) {\n" - "y = float(get_int(cur_y)) / (get_int(total_y) - 1);\n" - "y = py - (py - y) * v;\n" - "} else { y = 0.0; v = 1.0; }\n" - - "set_state_val(PART:\"bg\", STATE_ALIGNMENT, x, y);\n" - - "if (v >= 1.0) {\n" - "set_int(cur_anim, 0); set_float(prev_x, x);\n" - "set_float(prev_y, y); return 0;\n" - "}\n" - "return 1;\n" - "}\n" - "public message(Msg_Type:type, id, ...) {\n" - "if ((type == MSG_FLOAT_SET) && (id == 0)) {\n" - "new ani;\n" - - "get_state_val(PART:\"bg\", STATE_ALIGNMENT, prev_x, prev_y);\n" - "set_int(cur_x, round(getfarg(3))); set_int(total_x, round(getfarg(4)));\n" - "set_int(cur_y, round(getfarg(5))); set_int(total_y, round(getfarg(6)));\n" - - "ani = get_int(cur_anim); if (ani > 0) cancel_anim(ani);\n" - "ani = anim(getfarg(2), \"pan_bg\", 0); set_int(cur_anim, ani);\n" - "} } }\n" - "parts {\n" - "part { name: \"bg\"; mouse_events: 0;\n" - "description { state: \"default\" 0.0;\n" - "aspect: %1.9f %1.9f; aspect_preference: NONE;\n" - "image { normal: \"%s\"; scale_hint: STATIC; }\n" - "} } }\n" - "programs { program {\n" - " name: \"init\";\n" - " signal: \"load\";\n" - " source: \"\";\n" - " script { custom_state(PART:\"bg\", \"default\", 0.0);\n" - " set_state(PART:\"bg\", \"custom\", 0.0);\n" - " set_float(prev_x, 0.0); set_float(prev_y, 0.0);\n" - "} } } } }\n" - , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", - (double)w / (double)h, (double)w / (double)h, fstrip); - setlocale(LC_NUMERIC, locale); - break; - - default: - /* won't happen */ - break; + case IMPORT_STRETCH: fill = "stretch"; break; + case IMPORT_TILE: fill = "tile"; break; + case IMPORT_CENTER: fill = "center"; break; + case IMPORT_SCALE_ASPECT_IN: fill = "scale_in"; break; + case IMPORT_SCALE_ASPECT_OUT: fill = "scale_out"; break; + case IMPORT_PAN: fill = "pan"; break; + default: return; break; } - - fclose(f); - - snprintf(cmd, sizeof(cmd), "%s/edje_cc -v %s %s %s", e_prefix_bin_get(), - ipart, path, e_util_filename_escape(buf)); - - import->tmpf = strdup(tmpn); + s = e_util_filename_escape(import->file); + if (s) infile = strdup(s); + else return; + s = e_util_filename_escape(buf); + if (s) outfile = strdup(s); + else + { + free(infile); + return; + } + snprintf(fbuf, sizeof(fbuf), "%s/edje_cc", e_prefix_bin_get()); + if (!ecore_file_can_exec(fbuf)) + snprintf(fbuf, sizeof(fbuf), "edje_cc"); + snprintf(cmd, sizeof(cmd), + "%s/enlightenment/utils/enlightenment_wallpaper_gen " + "%s %s %s %s %i %i %i %i", + e_prefix_lib_get(), + fbuf, fill, infile, outfile, import->quality, cr, cg, cb); + free(infile); + free(outfile); import->fdest = eina_stringshare_add(buf); - import->exe_handler = - ecore_event_handler_add(ECORE_EXE_EVENT_DEL, - _import_cb_edje_cc_exit, import); + import->exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, + _import_cb_edje_cc_exit, + import); import->exe = ecore_exe_run(cmd, import); - - eina_tmpstr_del(path); } static Eina_Bool @@ -298,6 +99,29 @@ _import_cb_edje_cc_exit(void *data, EINA_UNUSED int type, void *event) if (r && import->ok) { + char *p, *newfile = strdup(import->fdest); + + if (!newfile) + { + e_object_del(E_OBJECT(import)); + return ECORE_CALLBACK_DONE; + } + p = strrchr(newfile, '/'); + if (!p) + { + e_object_del(E_OBJECT(import)); + return ECORE_CALLBACK_DONE; + } + // strip out the .tmp. before the name + for (p = p + 1; ; p++) + { + *p = p[5]; + if (*p == 0) break; + } + ecore_file_mv(import->fdest, newfile); + eina_stringshare_replace(&(import->fdest), newfile); + free(newfile); + e_object_ref(E_OBJECT(import)); import->ok((void *)import->fdest, import); e_object_del(E_OBJECT(import)); @@ -409,9 +233,6 @@ _e_import_config_dialog_del(void *data) if (import->exe_handler) ecore_event_handler_del(import->exe_handler); import->exe_handler = NULL; - if (import->tmpf && (unlink(import->tmpf) < 0)) - ERR("Could not delete tmpfile '%s'", import->tmpf); - free(import->tmpf); eina_stringshare_del(import->fdest); import->exe = NULL; eina_stringshare_del(import->file); @@ -462,12 +283,10 @@ e_import_config_dialog_show(Evas_Object *parent, const char *path, Ecore_End_Cb dia->data = import; import->dia = dia; import->ok = ok, import->cancel = cancel; - import->path = eina_stringshare_add(path); e_object_del_attach_func_set(E_OBJECT(dia), _e_import_config_dia_del); evas_object_event_callback_add(dia->win, EVAS_CALLBACK_DEL, _e_import_config_dialog_win_del, dia); import->method = IMPORT_SCALE_ASPECT_OUT; - import->external = 0; import->quality = 90; import->file = eina_stringshare_add(path); @@ -522,11 +341,9 @@ e_import_config_dialog_show(Evas_Object *parent, const char *path, Ecore_End_Cb ol = e_widget_list_add(evas, 0, 1); of = e_widget_frametable_add(evas, _("File Quality"), 0); - ord = e_widget_check_add(evas, _("Use original file"), &(import->external)); - e_widget_frametable_object_append(of, ord, 0, 0, 1, 1, 1, 0, 1, 0); ord = e_widget_slider_add(evas, 1, 0, _("%3.0f%%"), 0.0, 100.0, 1.0, 0, NULL, &(import->quality), 150); - e_widget_frametable_object_append(of, ord, 0, 1, 1, 1, 1, 0, 1, 0); + e_widget_frametable_object_append(of, ord, 0, 0, 1, 1, 1, 0, 1, 0); e_widget_list_object_append(ol, of, 1, 1, 0); of = e_widget_framelist_add(evas, _("Fill Color"), 0); diff --git a/src/bin/e_import_config_dialog.h b/src/bin/e_import_config_dialog.h index 3cc80cf44..0b87b626e 100644 --- a/src/bin/e_import_config_dialog.h +++ b/src/bin/e_import_config_dialog.h @@ -7,21 +7,18 @@ typedef struct _E_Import_Config_Dialog E_Import_Config_Dialog; #define E_IMPORT_CONFIG_DIALOG_TYPE 0xE0b01040 struct _E_Import_Config_Dialog { - E_Object e_obj_inherit; - Ecore_End_Cb ok; - Ecore_Cb cancel; + E_Object e_obj_inherit; + Ecore_End_Cb ok; + Ecore_Cb cancel; - const char *file; - int method; - int external; - int quality; + const char *file; + int method; + int quality; E_Color color; Ecore_Exe *exe; Ecore_Event_Handler *exe_handler; - const char *path; - char *tmpf; - const char *fdest; + const char *fdest; E_Dialog *dia; }; diff --git a/src/bin/e_wallpaper_gen_main.c b/src/bin/e_wallpaper_gen_main.c new file mode 100644 index 000000000..cd3c075ad --- /dev/null +++ b/src/bin/e_wallpaper_gen_main.c @@ -0,0 +1,499 @@ +#include +#include "config.h" + +// a set of commonly found resolution buckets to try size the image down +// to to match width OR height so we can avoid decoding a larger image from +// disk making startup time faster by picking the right res that's encoded +// already in the file... the more resolutions we encode the bigger +// the file so it's a tradeoff, thus commenting out a lot of the resolutions +// because they are so close or can just miildly crop another res... +// only encode resolutiosn less than the original image a well as throw in +// the original as the highest res option +// pick onne of each y resolution and scale accordingly so e.g. Nx480, Nx600, +// Nx720, Nx788, Nx800, Nx900, ... +static const int resolutions[] = +{ + // not bothering below 640x480 +// 640, 480, +// 800, 480, + 854, 480, +// 768, 576, +// 1024, 576, +// 800, 600, + 1024, 600, + 1280, 720, +// 1024, 768, +// 1152, 768 +// 1280, 768 + 1366, 768, + 1280, 800, +// 1280, 854, +// 1152, 864, +// 1152, 900, +// 1440, 900, + 1600, 900, +// 1280, 960, + 1440, 960, +// 1280, 1024, +// 1400, 1050, +// 1680, 1050, +// 1440, 1080, +// 1920, 1080, +// 2048, 1080, +// 2880, 1080, + 3840, 1080, +// 1600, 1200, + 1920, 1200, +// 1920, 1280, + 2560, 1440, +// 3840, 1440, +// 5120, 1440, +// 2048, 1536, + 2560, 1600, +// 2880, 1620, +// 2880, 1800, + 3200, 1800, +// 2560, 2048, +// 3840, 2160, + 4096, 2160, +// 5120, 2160, + 5120, 2880, + 6016, 3384, +// 7680, 4320, + 8192, 4320, + +// one day... we may have to add more resolutions here. when that day comes... +// we'll do that. until then... I think 8k is "good enough" + 0, 0 // sentinel +}; +// when we have more res's above bump this to be that + 1 at a minimum +#define MAX_RES_NUM 20 + +#define ETC1 -1 +#define ETC2 -2 + +static Evas_Object *win = NULL, *subwin = NULL, *image = NULL, *rend = NULL; + +typedef struct +{ + int from_w, from_h, to_w, to_h; + Eina_Bool last : 1; +} Mip; + +static Mip * +_resolutions_calc(int w, int h) +{ + int i, j = 0; + int nw, nh, pw = 0, ph = 0; + Mip *mips = calloc(1, sizeof(Mip) * MAX_RES_NUM); + + if (!mips) return NULL; + for (i = 0; resolutions[i]; i += 2) + { + nh = resolutions[i + 1]; + nw = (w * nh) / h; + if ((nh >= h) || (nw >= w)) + { + mips[j].from_w = pw; + mips[j].from_h = ph; + mips[j].to_w = 1000000000; + mips[j].to_h = 1000000000; + mips[j].last = EINA_TRUE; + break; + } + + mips[j].from_w = pw; + mips[j].from_h = ph; + mips[j].to_w = nw; + mips[j].to_h = nh; + + j++; + pw = nw + 1; + ph = nh + 1; + } + return mips; +} + +EAPI int +elm_main(int argc, char **argv) +{ + const char *edje_cc, *mode, *file, *outfile; + int bg_r = 64; + int bg_g = 64; + int bg_b = 64; + char dir_buf[128], img_buf[256], edc_buf[256], cmd_buf[1024], qual_buf[64]; + const char *dir, *quality_string = NULL, *img_name = NULL; + Mip *mips = NULL; + int i, imw, imh, w, h, quality; + int ret = 0, mips_num = 0; + Eina_Bool alpha; + FILE *f; + + if (argc <= 1) + { + printf("USAGE: enlightenment_wallpaper_gen EDJE FILL INPUT OUT QUALITY [R G B]\n" + "\n" + " EDJE is edje_cc command to use (full path or in $PATH)\n" + " FILL is one of:\n" + " stretch\n" + " tile\n" + " center (requires R G B)\n" + " scale_in (requires R G B)\n" + " scale_out\n" + " pan\n" + " INPUT is some image file to put into the wallpaper edj\n" + " OUT is the paht/location of the wallpaper edj output\n" + " QUALITY is:\n" + " 0-100 (0-99 is lossy, 100 is lossless compression)\n" + " etc1\n" + " etc2\n" + " R, G, B are Red, Green and Blue values 0 to 255\n" + "\n" + " e.g.\n" + " enlightenment_wallpaper_gen edje_cc scale_out cat.jpg wallpaper.edj 80\n" + " enlightenment_wallpaper_gen edje_cc center mylogo.png wallpaper.edj 100 48 64 64\n" + " enlightenment_wallpaper_gen /usr/local/bin/edje_cc tile pattern.jpg wallpaper.edj 98\n" + " enlightenment_wallpaper_gen /opt/e/bin/edje_cc scale_out hugeimg.jpg wallpaper.edj etc1\n" + ); + return 1; + } + + elm_config_preferred_engine_set("buffer"); + win = elm_win_add(NULL, "Wallpaper-Gen", ELM_WIN_BASIC); + elm_win_norender_push(win); + evas_object_show(win); + + subwin = elm_win_add(win, "inlined", ELM_WIN_INLINED_IMAGE); + rend = elm_win_inlined_image_object_get(subwin); + elm_win_norender_push(subwin); + evas_object_show(subwin); + + if (argc < 6) return 2; + edje_cc = argv[1]; + mode = argv[2]; + file = argv[3]; + outfile = argv[4]; + if (!strcmp(argv[5], "etc1")) quality = ETC1; + else if (!strcmp(argv[5], "etc2")) quality = ETC2; + else + { + quality = atoi(argv[5]); + if (quality < 0) quality = 0; + else if (quality > 100) quality = 100; + } + + image = evas_object_image_filled_add(evas_object_evas_get(subwin)); + evas_object_image_file_set(image, file, NULL); + evas_object_image_size_get(image, &w, &h); + if ((w <= 0) || (h <= 0)) return 3; + alpha = evas_object_image_alpha_get(image); + elm_win_alpha_set(subwin, alpha); + evas_object_show(image); + + snprintf(dir_buf, sizeof(dir_buf), "/tmp/e_bg-XXXXXX"); + dir = mkdtemp(dir_buf); + if (!dir) return 4; + + if ((!strcmp(mode, "center")) || + (!strcmp(mode, "scale_in"))) + { // need backing rgb color here + if (argc < 9) return 5; + bg_r = atoi(argv[6]); + bg_g = atoi(argv[7]); + bg_b = atoi(argv[8]); + } + if ((!strcmp(mode, "stretch")) || + (!strcmp(mode, "scale_in")) || + (!strcmp(mode, "scale_out")) || + (!strcmp(mode, "pan"))) + { // need to produce multiple scaled versions + mips = _resolutions_calc(w, h); + if (!mips) return 6; + for (i = 0; mips[i].to_w; i++) + { + mips_num++; + if (mips[i].last) + { + imw = w; + imh = h; + } + else + { + imw = mips[i].to_w; + imh = mips[i].to_h; + } + evas_object_resize(subwin, imw, imh); + evas_object_resize(image, imw, imh); + elm_win_render(subwin); + if (mips[i].last) + snprintf(img_buf, sizeof(img_buf), "%s/img.png", + dir); + else + snprintf(img_buf, sizeof(img_buf), "%s/img-%ix%i.png", + dir, imw, imh); + if (!evas_object_image_save(rend, img_buf, NULL, "compress=0")) + { + ret = 7; + goto cleanup; + } + } + } + // no multiple resolutions -0 save out original + if (!mips) + { + evas_object_resize(subwin, w, h); + evas_object_resize(image, w, h); + elm_win_render(subwin); + snprintf(img_buf, sizeof(img_buf), "%s/img.png", dir); + if (!evas_object_image_save(rend, img_buf, NULL, "compress=0")) + { + ret = 8; + goto cleanup; + } + } + if ((quality == ETC1) && (alpha)) quality = ETC2; // etc1 -> etc2 if alpha + if (quality == 100) quality_string = "COMP"; + else + { + if (quality == ETC1) quality_string = "LOSSY_ETC1"; + else if (quality == ETC2) quality_string = "LOSSY_ETC2"; + else + { + snprintf(qual_buf, sizeof(qual_buf), "LOSSY %i", quality); + quality_string = qual_buf; + } + } + // generate edc + snprintf(edc_buf, sizeof(edc_buf), "%s/bg.edc", dir); + f = fopen(edc_buf, "w"); + if (!f) goto cleanup; + if ((mips) && (mips_num > 1)) + { + fprintf(f, + "images {\n" + " set { name: \"img\";\n"); + for (i = mips_num - 1; i >= 0; i--) + { + fprintf(f, + " image {\n"); + if (mips[i].last) + { + imw = w; + imh = h; + fprintf(f, + " image: \"img.png\" %s;\n", + quality_string); + } + else + { + imw = mips[i].to_w; + imh = mips[i].to_h; + fprintf(f, + " image: \"img-%ix%i.png\" %s;\n", + imw, imh, quality_string); + } + fprintf(f, + " size: %i %i %i %i;\n" + " }\n", + mips[i].from_w, mips[i].from_h, + mips[i].to_w, mips[i].to_h); + } + fprintf(f, + " }\n" + "}\n"); + img_name = "img"; + } + else + { + fprintf(f, "images.image: \"img.png\" %s;\n", quality_string); + img_name = "img.png"; + } + fprintf(f, + "collections {\n" + " group { name: \"e/desktop/background\";\n" + " data.item: \"noanimation\" \"1\";\n"); + if (!strcmp(mode, "stretch")) + { + fprintf(f, " data { item: \"style\" \"0\"; }\n"); + fprintf(f, + " parts {\n" + " part { name: \"bg\"; mouse_events: 0;\n" + " description { state: \"default\" 0;\n" + " image {\n" + " normal: \"%s\";\n" + " scale_hint: STATIC;\n" + " }\n" + " }\n" + " }\n" + " }\n" + , img_name); + } + else if (!strcmp(mode, "tile")) + { + fprintf(f, " data { item: \"style\" \"1\"; }\n"); + fprintf(f, + " parts {\n" + " part { name: \"bg\"; mouse_events: 0;\n" + " description { state: \"default\" 0;\n" + " image {\n" + " normal: \"%s\";\n" + " }\n" + " fill.size.relative: 0 0;\n" + " fill.size.offset: %i %i;\n" + " }\n" + " }\n" + " }\n" + , img_name, w, h); + } + else if (!strcmp(mode, "center")) + { + fprintf(f, " data { item: \"style\" \"2\"; }\n"); + fprintf(f, + " parts {\n" + " part { name: \"col\"; type: RECT; mouse_events: 0;\n" + " description { state: \"default\" 0;\n" + " color: %i %i %i 255;\n" + " }\n" + " }\n" + " part { name: \"bg\"; mouse_events: 0;\n" + " description { state: \"default\" 0;\n" + " image {\n" + " normal: \"%s\";\n" + " }\n" + " min: %i %i; max: %i %i;\n" + " }\n" + " }\n" + " }\n" + , bg_r, bg_g, bg_b, img_name, w, h, w, h); + } + else if (!strcmp(mode, "scale_in")) + { + fprintf(f, " data { item: \"style\" \"3\"; }\n"); + fprintf(f, + " parts {\n" + " part { name: \"col\"; type: RECT; mouse_events: 0;\n" + " description { state: \"default\" 0;\n" + " color: %i %i %i 255;\n" + " }\n" + " }\n" + " part { name: \"bg\"; mouse_events: 0;\n" + " description { state: \"default\" 0;\n" + " image {\n" + " normal: \"%s\";\n" + " scale_hint: STATIC;\n" + " }\n" + " aspect: (%i/%i) (%i/%i); aspect_preference: BOTH;\n" + " }\n" + " }\n" + " }\n" + , bg_r, bg_g, bg_b, img_name, w, h, w, h); + } + else if (!strcmp(mode, "scale_out")) + { + fprintf(f, " data { item: \"style\" \"4\"; }\n"); + fprintf(f, + " parts {\n" + " part { name: \"bg\"; mouse_events: 0;\n" + " description { state: \"default\" 0;\n" + " image {\n" + " normal: \"%s\";\n" + " scale_hint: STATIC;\n" + " }\n" + " aspect: (%i/%i) (%i/%i); aspect_preference: NONE;\n" + " }\n" + " }\n" + " }\n" + , img_name, w, h, w, h); + } + else if (!strcmp(mode, "pan")) + { + fprintf(f, " data { item: \"style\" \"5\"; }\n"); + fprintf(f, + " script {\n" + " public cur_anim; public cur_x; public cur_y;\n" + " public prev_x; public prev_y;\n" + " public total_x; public total_y;\n" + " public pan_bg(val, Float:v) {\n" + " new Float:x, Float:y, Float:px, Float: py;\n" + " px = get_float(prev_x);\n" + " py = get_float(prev_y);\n" + " if (get_int(total_x) > 1) {\n" + " x = float(get_int(cur_x)) / (get_int(total_x) - 1);\n" + " x = px - (px - x) * v;\n" + " } else {\n" + " x = 0.0;\n" + " v = 1.0;\n" + " }\n" + " if (get_int(total_y) > 1) {\n" + " y = float(get_int(cur_y)) / (get_int(total_y) - 1);\n" + " y = py - (py - y) * v;\n" + " } else {\n" + " y = 0.0;\n" + " v = 1.0; }\n" + " set_state_val(PART:\"bg\", STATE_ALIGNMENT, x, y);\n" + " if (v >= 1.0) {\n" + " set_int(cur_anim, 0);\n" + " set_float(prev_x, x);\n" + " set_float(prev_y, y);\n" + " return 0;\n" + " }\n" + " return 1;\n" + " }\n" + " public message(Msg_Type:type, id, ...) {\n" + " if ((type == MSG_FLOAT_SET) && (id == 0)) {\n" + " new ani;\n" + " get_state_val(PART:\"bg\", STATE_ALIGNMENT, prev_x, prev_y);\n" + " set_int(cur_x, round(getfarg(3)));\n" + " set_int(total_x, round(getfarg(4)));\n" + " set_int(cur_y, round(getfarg(5)));\n" + " set_int(total_y, round(getfarg(6)));\n" + " ani = get_int(cur_anim);\n" + " if (ani > 0) cancel_anim(ani);\n" + " ani = anim(getfarg(2), \"pan_bg\", 0);\n" + " set_int(cur_anim, ani);\n" + " }\n" + " }\n" + " }\n" + " parts {\n" + " part { name: \"bg\"; mouse_events: 0;\n" + " description { state: \"default\" 0.0;\n" + " image {\n" + " normal: \"%s\";\n" + " scale_hint: STATIC;\n" + " }\n" + " aspect: (%i/%i) (%i/%i); aspect_preference: NONE;\n" + " }\n" + " }\n" + " program {\n" + " signal: \"load\"; source: \"\";\n" + " script {\n" + " custom_state(PART:\"bg\", \"default\", 0.0);\n" + " set_state(PART:\"bg\", \"custom\", 0.0);\n" + " set_float(prev_x, 0.0);\n" + " set_float(prev_y, 0.0);\n" + " }\n" + " }\n" + " }\n" + , img_name, w, h, w, h); + } + fprintf(f, + " }\n" + "}\n"); + fclose(f); + free(mips); + if (snprintf(cmd_buf, sizeof(cmd_buf), + "%s -fastdecomp -id %s -fd %s -sd %s -vd %s -dd %s -md %s " + "%s/bg.edc %s", + edje_cc, dir, dir, dir, dir, dir, dir, + dir, outfile) >= (int)sizeof(cmd_buf)) + { + ret = 9; + goto cleanup; + } + ret = system(cmd_buf); +cleanup: + ecore_file_recursive_rm(dir); + evas_object_del(win); + return ret; +} +ELM_MAIN() diff --git a/src/bin/meson.build b/src/bin/meson.build index 1de73fe21..a3173eb6d 100644 --- a/src/bin/meson.build +++ b/src/bin/meson.build @@ -513,10 +513,10 @@ executable('enlightenment_elm_cfgtool', install : true ) -executable('enlightenment_static_grabber', - [ 'e_static_grab.c' ], +executable('enlightenment_wallpaper_gen', + [ 'e_wallpaper_gen_main.c' ], include_directories: include_directories('../..'), - dependencies : [ dep_eina, dep_eet ], + dependencies : [ dep_elementary ], install_dir : dir_e_utils, install : true )