summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2020-01-22 20:39:19 +0000
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2020-01-22 20:39:19 +0000
commit3f22a0c26da52e60a42ee2e685ba7031edcbd629 (patch)
tree50ef03322e11f58b18bffd01f27942ea970cc42f
parent1c237e4c3eb2bd0d426ad693b73f9ccca62adb68 (diff)
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
Diffstat (limited to '')
-rw-r--r--TODO5
-rw-r--r--src/bin/e_import_config_dialog.c297
-rw-r--r--src/bin/e_import_config_dialog.h17
-rw-r--r--src/bin/e_wallpaper_gen_main.c499
-rw-r--r--src/bin/meson.build6
5 files changed, 568 insertions, 256 deletions
diff --git a/TODO b/TODO
index 604f1ee29..4c2a72f57 100644
--- a/TODO
+++ b/TODO
@@ -119,9 +119,8 @@ TODO:
119 * set user password 119 * set user password
120 * user cron front-end config/editor 120 * user cron front-end config/editor
121 * allow separate LC_MESSAGES, LC_TIME, LC_NUMERIC, LC_NAME, etc. 121 * allow separate LC_MESSAGES, LC_TIME, LC_NUMERIC, LC_NAME, etc.
122* wallpaper: gen wp files with multiple common resolutions in image set 122* edje needs logic to handle max texture size to fix big img problems
123 * edje needs logic to handle max texture size and to downsize to work 123 * rpi max texture size is 2048...
124 * rpi max texture size is 2048...
125* dnd: remove e_dnd and use elm's dnd instead 124* dnd: remove e_dnd and use elm's dnd instead
126* new gadgets: 125* new gadgets:
127 * be able to move, resize etc. without alt move/resize mode like old) 126 * 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);
13static void 13static void
14_import_edj_gen(E_Import_Config_Dialog *import) 14_import_edj_gen(E_Import_Config_Dialog *import)
15{ 15{
16 Evas *evas; 16 const char *file, *fill, *s;
17 Evas_Object *img; 17 char buf[PATH_MAX], fbuf[PATH_MAX], cmd[PATH_MAX + PATH_MAX + 40];
18 Eina_Bool anim = EINA_FALSE; 18 char *fstrip, *infile, *outfile;
19 int fd, num = 1; 19 int num, cr, cg, cb;
20 int w = 0, h = 0;
21 const char *file, *locale;
22 char buf[PATH_MAX], fbuf[PATH_MAX], cmd[PATH_MAX + PATH_MAX + 40], tmpn[PATH_MAX], ipart[PATH_MAX], enc[128];
23 Eina_Tmpstr *path = NULL;
24 char *imgdir = NULL, *fstrip;
25 int cr, cg, cb, ca;
26 FILE *f;
27 size_t len, off; 20 size_t len, off;
28 21
29 evas = evas_object_evas_get(import->dia->win);
30 file = ecore_file_file_get(import->file); 22 file = ecore_file_file_get(import->file);
31 fstrip = ecore_file_strip_ext(file); 23 fstrip = ecore_file_strip_ext(file);
32 if (!fstrip) return; 24 if (!fstrip) return;
33 len = e_user_dir_snprintf(buf, sizeof(buf), "backgrounds/%s.edj", fstrip); 25 len = e_user_dir_snprintf(buf, sizeof(buf), "backgrounds/.tmp.%s.edj", fstrip);
34 if (len >= sizeof(buf)) 26 if (len >= sizeof(buf))
35 { 27 {
36 free(fstrip); 28 free(fstrip);
@@ -43,238 +35,47 @@ _import_edj_gen(E_Import_Config_Dialog *import)
43 cr = import->color.r; 35 cr = import->color.r;
44 cg = import->color.g; 36 cg = import->color.g;
45 cb = import->color.b; 37 cb = import->color.b;
46 ca = import->color.a;
47 38
48 if (num == 100) 39 if (num == 100)
49 { 40 {
50 printf("Couldn't come up with another filename for %s\n", buf); 41 printf("Couldn't come up with another filename for %s\n", buf);
51 return; 42 return;
52 } 43 }
53 44 switch (import->method)
54 strcpy(tmpn, "e_bgdlg_new.edc-tmp-XXXXXX");
55 fd = eina_file_mkstemp(tmpn, &path);
56 if (fd < 0)
57 {
58 printf("Error Creating tmp file: %s\n", strerror(errno));
59 return;
60 }
61
62 f = fdopen(fd, "w");
63 if (!f)
64 {
65 printf("Cannot open %s for writing\n", tmpn);
66 return;
67 }
68
69 anim = eina_str_has_extension(import->file, "gif");
70 imgdir = ecore_file_dir_get(import->file);
71 if (!imgdir) ipart[0] = '\0';
72 else
73 {
74 snprintf(ipart, sizeof(ipart), "-id %s", e_util_filename_escape(imgdir));
75 free(imgdir);
76 }
77
78 img = evas_object_image_add(evas);
79 evas_object_image_file_set(img, import->file, NULL);
80 evas_object_image_size_get(img, &w, &h);
81 evas_object_del(img);
82
83 if (import->external)
84 { 45 {
85 const char *esc = e_util_filename_escape(import->file); 46 case IMPORT_STRETCH: fill = "stretch"; break;
86 fstrip = memcpy(fbuf, esc, strlen(esc) + 1); 47 case IMPORT_TILE: fill = "tile"; break;
87 snprintf(enc, sizeof(enc), "USER"); 48 case IMPORT_CENTER: fill = "center"; break;
49 case IMPORT_SCALE_ASPECT_IN: fill = "scale_in"; break;
50 case IMPORT_SCALE_ASPECT_OUT: fill = "scale_out"; break;
51 case IMPORT_PAN: fill = "pan"; break;
52 default: return; break;
88 } 53 }
54 s = e_util_filename_escape(import->file);
55 if (s) infile = strdup(s);
56 else return;
57 s = e_util_filename_escape(buf);
58 if (s) outfile = strdup(s);
89 else 59 else
90 { 60 {
91 const char *esc = e_util_filename_escape(file); 61 free(infile);
92 fstrip = memcpy(fbuf, esc, strlen(esc) + 1); 62 return;
93 if (import->quality == 100)
94 snprintf(enc, sizeof(enc), "COMP");
95 else
96 snprintf(enc, sizeof(enc), "LOSSY %i", import->quality);
97 }
98 switch (import->method)
99 {
100 case IMPORT_STRETCH:
101 fprintf(f,
102 "images { image: \"%s\" %s; }\n"
103 "collections {\n"
104 "group { name: \"e/desktop/background\";\n"
105 "%s"
106 "data { item: \"style\" \"0\"; }\n"
107 "parts {\n"
108 "part { name: \"bg\"; mouse_events: 0;\n"
109 "description { state: \"default\" 0.0;\n"
110 "image { normal: \"%s\"; scale_hint: STATIC; }\n"
111 "} } } } }\n"
112 , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", fstrip);
113 break;
114
115 case IMPORT_TILE:
116 fprintf(f,
117 "images { image: \"%s\" %s; }\n"
118 "collections {\n"
119 "group { name: \"e/desktop/background\";\n"
120 "data { item: \"style\" \"1\"; }\n"
121 "%s"
122 "parts {\n"
123 "part { name: \"bg\"; mouse_events: 0;\n"
124 "description { state: \"default\" 0.0;\n"
125 "image { normal: \"%s\"; }\n"
126 "fill { size {\n"
127 "relative: 0.0 0.0;\n"
128 "offset: %i %i;\n"
129 "} } } } } } }\n"
130 , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", fstrip, w, h);
131 break;
132
133 case IMPORT_CENTER:
134 fprintf(f,
135 "images { image: \"%s\" %s; }\n"
136 "collections {\n"
137 "group { name: \"e/desktop/background\";\n"
138 "data { item: \"style\" \"2\"; }\n"
139 "%s"
140 "parts {\n"
141 "part { name: \"col\"; type: RECT; mouse_events: 0;\n"
142 "description { state: \"default\" 0.0;\n"
143 "color: %i %i %i %i;\n"
144 "} }\n"
145 "part { name: \"bg\"; mouse_events: 0;\n"
146 "description { state: \"default\" 0.0;\n"
147 "min: %i %i; max: %i %i;\n"
148 "image { normal: \"%s\"; }\n"
149 "} } } } }\n"
150 , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", cr, cg, cb, ca, w, h, w, h, fstrip);
151 break;
152
153 case IMPORT_SCALE_ASPECT_IN:
154 locale = e_intl_language_get();
155 setlocale(LC_NUMERIC, "C");
156 fprintf(f,
157 "images { image: \"%s\" %s; }\n"
158 "collections {\n"
159 "group { name: \"e/desktop/background\";\n"
160 "data { item: \"style\" \"3\"; }\n"
161 "%s"
162 "parts {\n"
163 "part { name: \"col\"; type: RECT; mouse_events: 0;\n"
164 "description { state: \"default\" 0.0;\n"
165 "color: %i %i %i %i;\n"
166 "} }\n"
167 "part { name: \"bg\"; mouse_events: 0;\n"
168 "description { state: \"default\" 0.0;\n"
169 "aspect: %1.9f %1.9f; aspect_preference: BOTH;\n"
170 "image { normal: \"%s\"; scale_hint: STATIC; }\n"
171 "} } } } }\n"
172 , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n",
173 cr, cg, cb, ca, (double)w / (double)h, (double)w / (double)h, fstrip);
174 setlocale(LC_NUMERIC, locale);
175 break;
176
177 case IMPORT_SCALE_ASPECT_OUT:
178 locale = e_intl_language_get();
179 setlocale(LC_NUMERIC, "C");
180 fprintf(f,
181 "images { image: \"%s\" %s; }\n"
182 "collections {\n"
183 "group { name: \"e/desktop/background\";\n"
184 "data { item: \"style\" \"4\"; }\n"
185 "%s"
186 "parts {\n"
187 "part { name: \"bg\"; mouse_events: 0;\n"
188 "description { state: \"default\" 0.0;\n"
189 "aspect: %1.9f %1.9f; aspect_preference: NONE;\n"
190 "image { normal: \"%s\"; scale_hint: STATIC; }\n"
191 "} } } } }\n"
192 , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n",
193 (double)w / (double)h, (double)w / (double)h, fstrip);
194 setlocale(LC_NUMERIC, locale);
195 break;
196
197 case IMPORT_PAN:
198 locale = e_intl_language_get();
199 setlocale(LC_NUMERIC, "C");
200 fprintf(f,
201 "images { image: \"%s\" %s; }\n"
202 "collections {\n"
203 "group { name: \"e/desktop/background\";\n"
204 "data { item: \"style\" \"4\"; }\n"
205 "%s"
206 "script {\n"
207 "public cur_anim; public cur_x; public cur_y; public prev_x;\n"
208 "public prev_y; public total_x; public total_y; \n"
209 "public pan_bg(val, Float:v) {\n"
210 "new Float:x, Float:y, Float:px, Float: py;\n"
211
212 "px = get_float(prev_x); py = get_float(prev_y);\n"
213 "if (get_int(total_x) > 1) {\n"
214 "x = float(get_int(cur_x)) / (get_int(total_x) - 1);\n"
215 "x = px - (px - x) * v;\n"
216 "} else { x = 0.0; v = 1.0; }\n"
217 "if (get_int(total_y) > 1) {\n"
218 "y = float(get_int(cur_y)) / (get_int(total_y) - 1);\n"
219 "y = py - (py - y) * v;\n"
220 "} else { y = 0.0; v = 1.0; }\n"
221
222 "set_state_val(PART:\"bg\", STATE_ALIGNMENT, x, y);\n"
223
224 "if (v >= 1.0) {\n"
225 "set_int(cur_anim, 0); set_float(prev_x, x);\n"
226 "set_float(prev_y, y); return 0;\n"
227 "}\n"
228 "return 1;\n"
229 "}\n"
230 "public message(Msg_Type:type, id, ...) {\n"
231 "if ((type == MSG_FLOAT_SET) && (id == 0)) {\n"
232 "new ani;\n"
233
234 "get_state_val(PART:\"bg\", STATE_ALIGNMENT, prev_x, prev_y);\n"
235 "set_int(cur_x, round(getfarg(3))); set_int(total_x, round(getfarg(4)));\n"
236 "set_int(cur_y, round(getfarg(5))); set_int(total_y, round(getfarg(6)));\n"
237
238 "ani = get_int(cur_anim); if (ani > 0) cancel_anim(ani);\n"
239 "ani = anim(getfarg(2), \"pan_bg\", 0); set_int(cur_anim, ani);\n"
240 "} } }\n"
241 "parts {\n"
242 "part { name: \"bg\"; mouse_events: 0;\n"
243 "description { state: \"default\" 0.0;\n"
244 "aspect: %1.9f %1.9f; aspect_preference: NONE;\n"
245 "image { normal: \"%s\"; scale_hint: STATIC; }\n"
246 "} } }\n"
247 "programs { program {\n"
248 " name: \"init\";\n"
249 " signal: \"load\";\n"
250 " source: \"\";\n"
251 " script { custom_state(PART:\"bg\", \"default\", 0.0);\n"
252 " set_state(PART:\"bg\", \"custom\", 0.0);\n"
253 " set_float(prev_x, 0.0); set_float(prev_y, 0.0);\n"
254 "} } } } }\n"
255 , fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n",
256 (double)w / (double)h, (double)w / (double)h, fstrip);
257 setlocale(LC_NUMERIC, locale);
258 break;
259
260 default:
261 /* won't happen */
262 break;
263 } 63 }
264 64 snprintf(fbuf, sizeof(fbuf), "%s/edje_cc", e_prefix_bin_get());
265 fclose(f); 65 if (!ecore_file_can_exec(fbuf))
266 66 snprintf(fbuf, sizeof(fbuf), "edje_cc");
267 snprintf(cmd, sizeof(cmd), "%s/edje_cc -v %s %s %s", e_prefix_bin_get(), 67 snprintf(cmd, sizeof(cmd),
268 ipart, path, e_util_filename_escape(buf)); 68 "%s/enlightenment/utils/enlightenment_wallpaper_gen "
269 69 "%s %s %s %s %i %i %i %i",
270 import->tmpf = strdup(tmpn); 70 e_prefix_lib_get(),
71 fbuf, fill, infile, outfile, import->quality, cr, cg, cb);
72 free(infile);
73 free(outfile);
271 import->fdest = eina_stringshare_add(buf); 74 import->fdest = eina_stringshare_add(buf);
272 import->exe_handler = 75 import->exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
273 ecore_event_handler_add(ECORE_EXE_EVENT_DEL, 76 _import_cb_edje_cc_exit,
274 _import_cb_edje_cc_exit, import); 77 import);
275 import->exe = ecore_exe_run(cmd, import); 78 import->exe = ecore_exe_run(cmd, import);
276
277 eina_tmpstr_del(path);
278} 79}
279 80
280static Eina_Bool 81static Eina_Bool
@@ -298,6 +99,29 @@ _import_cb_edje_cc_exit(void *data, EINA_UNUSED int type, void *event)
298 99
299 if (r && import->ok) 100 if (r && import->ok)
300 { 101 {
102 char *p, *newfile = strdup(import->fdest);
103
104 if (!newfile)
105 {
106 e_object_del(E_OBJECT(import));
107 return ECORE_CALLBACK_DONE;
108 }
109 p = strrchr(newfile, '/');
110 if (!p)
111 {
112 e_object_del(E_OBJECT(import));
113 return ECORE_CALLBACK_DONE;
114 }
115 // strip out the .tmp. before the name
116 for (p = p + 1; ; p++)
117 {
118 *p = p[5];
119 if (*p == 0) break;
120 }
121 ecore_file_mv(import->fdest, newfile);
122 eina_stringshare_replace(&(import->fdest), newfile);
123 free(newfile);
124
301 e_object_ref(E_OBJECT(import)); 125 e_object_ref(E_OBJECT(import));
302 import->ok((void *)import->fdest, import); 126 import->ok((void *)import->fdest, import);
303 e_object_del(E_OBJECT(import)); 127 e_object_del(E_OBJECT(import));
@@ -409,9 +233,6 @@ _e_import_config_dialog_del(void *data)
409 233
410 if (import->exe_handler) ecore_event_handler_del(import->exe_handler); 234 if (import->exe_handler) ecore_event_handler_del(import->exe_handler);
411 import->exe_handler = NULL; 235 import->exe_handler = NULL;
412 if (import->tmpf && (unlink(import->tmpf) < 0))
413 ERR("Could not delete tmpfile '%s'", import->tmpf);
414 free(import->tmpf);
415 eina_stringshare_del(import->fdest); 236 eina_stringshare_del(import->fdest);
416 import->exe = NULL; 237 import->exe = NULL;
417 eina_stringshare_del(import->file); 238 eina_stringshare_del(import->file);
@@ -462,12 +283,10 @@ e_import_config_dialog_show(Evas_Object *parent, const char *path, Ecore_End_Cb
462 dia->data = import; 283 dia->data = import;
463 import->dia = dia; 284 import->dia = dia;
464 import->ok = ok, import->cancel = cancel; 285 import->ok = ok, import->cancel = cancel;
465 import->path = eina_stringshare_add(path);
466 e_object_del_attach_func_set(E_OBJECT(dia), _e_import_config_dia_del); 286 e_object_del_attach_func_set(E_OBJECT(dia), _e_import_config_dia_del);
467 evas_object_event_callback_add(dia->win, EVAS_CALLBACK_DEL, _e_import_config_dialog_win_del, dia); 287 evas_object_event_callback_add(dia->win, EVAS_CALLBACK_DEL, _e_import_config_dialog_win_del, dia);
468 288
469 import->method = IMPORT_SCALE_ASPECT_OUT; 289 import->method = IMPORT_SCALE_ASPECT_OUT;
470 import->external = 0;
471 import->quality = 90; 290 import->quality = 90;
472 import->file = eina_stringshare_add(path); 291 import->file = eina_stringshare_add(path);
473 292
@@ -522,11 +341,9 @@ e_import_config_dialog_show(Evas_Object *parent, const char *path, Ecore_End_Cb
522 ol = e_widget_list_add(evas, 0, 1); 341 ol = e_widget_list_add(evas, 0, 1);
523 342
524 of = e_widget_frametable_add(evas, _("File Quality"), 0); 343 of = e_widget_frametable_add(evas, _("File Quality"), 0);
525 ord = e_widget_check_add(evas, _("Use original file"), &(import->external));
526 e_widget_frametable_object_append(of, ord, 0, 0, 1, 1, 1, 0, 1, 0);
527 ord = e_widget_slider_add(evas, 1, 0, _("%3.0f%%"), 0.0, 100.0, 1.0, 0, 344 ord = e_widget_slider_add(evas, 1, 0, _("%3.0f%%"), 0.0, 100.0, 1.0, 0,
528 NULL, &(import->quality), 150); 345 NULL, &(import->quality), 150);
529 e_widget_frametable_object_append(of, ord, 0, 1, 1, 1, 1, 0, 1, 0); 346 e_widget_frametable_object_append(of, ord, 0, 0, 1, 1, 1, 0, 1, 0);
530 e_widget_list_object_append(ol, of, 1, 1, 0); 347 e_widget_list_object_append(ol, of, 1, 1, 0);
531 348
532 of = e_widget_framelist_add(evas, _("Fill Color"), 0); 349 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;
7#define E_IMPORT_CONFIG_DIALOG_TYPE 0xE0b01040 7#define E_IMPORT_CONFIG_DIALOG_TYPE 0xE0b01040
8struct _E_Import_Config_Dialog 8struct _E_Import_Config_Dialog
9{ 9{
10 E_Object e_obj_inherit; 10 E_Object e_obj_inherit;
11 Ecore_End_Cb ok; 11 Ecore_End_Cb ok;
12 Ecore_Cb cancel; 12 Ecore_Cb cancel;
13 13
14 const char *file; 14 const char *file;
15 int method; 15 int method;
16 int external; 16 int quality;
17 int quality;
18 E_Color color; 17 E_Color color;
19 18
20 Ecore_Exe *exe; 19 Ecore_Exe *exe;
21 Ecore_Event_Handler *exe_handler; 20 Ecore_Event_Handler *exe_handler;
22 const char *path; 21 const char *fdest;
23 char *tmpf;
24 const char *fdest;
25 22
26 E_Dialog *dia; 23 E_Dialog *dia;
27}; 24};
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 @@
1#include <Elementary.h>
2#include "config.h"
3
4// a set of commonly found resolution buckets to try size the image down
5// to to match width OR height so we can avoid decoding a larger image from
6// disk making startup time faster by picking the right res that's encoded
7// already in the file... the more resolutions we encode the bigger
8// the file so it's a tradeoff, thus commenting out a lot of the resolutions
9// because they are so close or can just miildly crop another res...
10// only encode resolutiosn less than the original image a well as throw in
11// the original as the highest res option
12// pick onne of each y resolution and scale accordingly so e.g. Nx480, Nx600,
13// Nx720, Nx788, Nx800, Nx900, ...
14static const int resolutions[] =
15{
16 // not bothering below 640x480
17// 640, 480,
18// 800, 480,
19 854, 480,
20// 768, 576,
21// 1024, 576,
22// 800, 600,
23 1024, 600,
24 1280, 720,
25// 1024, 768,
26// 1152, 768
27// 1280, 768
28 1366, 768,
29 1280, 800,
30// 1280, 854,
31// 1152, 864,
32// 1152, 900,
33// 1440, 900,
34 1600, 900,
35// 1280, 960,
36 1440, 960,
37// 1280, 1024,
38// 1400, 1050,
39// 1680, 1050,
40// 1440, 1080,
41// 1920, 1080,
42// 2048, 1080,
43// 2880, 1080,
44 3840, 1080,
45// 1600, 1200,
46 1920, 1200,
47// 1920, 1280,
48 2560, 1440,
49// 3840, 1440,
50// 5120, 1440,
51// 2048, 1536,
52 2560, 1600,
53// 2880, 1620,
54// 2880, 1800,
55 3200, 1800,
56// 2560, 2048,
57// 3840, 2160,
58 4096, 2160,
59// 5120, 2160,
60 5120, 2880,
61 6016, 3384,
62// 7680, 4320,
63 8192, 4320,
64
65// one day... we may have to add more resolutions here. when that day comes...
66// we'll do that. until then... I think 8k is "good enough"
67 0, 0 // sentinel
68};
69// when we have more res's above bump this to be that + 1 at a minimum
70#define MAX_RES_NUM 20
71
72#define ETC1 -1
73#define ETC2 -2
74
75static Evas_Object *win = NULL, *subwin = NULL, *image = NULL, *rend = NULL;
76
77typedef struct
78{
79 int from_w, from_h, to_w, to_h;
80 Eina_Bool last : 1;
81} Mip;
82
83static Mip *
84_resolutions_calc(int w, int h)
85{
86 int i, j = 0;
87 int nw, nh, pw = 0, ph = 0;
88 Mip *mips = calloc(1, sizeof(Mip) * MAX_RES_NUM);
89
90 if (!mips) return NULL;
91 for (i = 0; resolutions[i]; i += 2)
92 {
93 nh = resolutions[i + 1];
94 nw = (w * nh) / h;
95 if ((nh >= h) || (nw >= w))
96 {
97 mips[j].from_w = pw;
98 mips[j].from_h = ph;
99 mips[j].to_w = 1000000000;
100 mips[j].to_h = 1000000000;
101 mips[j].last = EINA_TRUE;
102 break;
103 }
104
105 mips[j].from_w = pw;
106 mips[j].from_h = ph;
107 mips[j].to_w = nw;
108 mips[j].to_h = nh;
109
110 j++;
111 pw = nw + 1;
112 ph = nh + 1;
113 }
114 return mips;
115}
116
117EAPI int
118elm_main(int argc, char **argv)
119{
120 const char *edje_cc, *mode, *file, *outfile;
121 int bg_r = 64;
122 int bg_g = 64;
123 int bg_b = 64;
124 char dir_buf[128], img_buf[256], edc_buf[256], cmd_buf[1024], qual_buf[64];
125 const char *dir, *quality_string = NULL, *img_name = NULL;
126 Mip *mips = NULL;
127 int i, imw, imh, w, h, quality;
128 int ret = 0, mips_num = 0;
129 Eina_Bool alpha;
130 FILE *f;
131
132 if (argc <= 1)
133 {
134 printf("USAGE: enlightenment_wallpaper_gen EDJE FILL INPUT OUT QUALITY [R G B]\n"
135 "\n"
136 " EDJE is edje_cc command to use (full path or in $PATH)\n"
137 " FILL is one of:\n"
138 " stretch\n"
139 " tile\n"
140 " center (requires R G B)\n"
141 " scale_in (requires R G B)\n"
142 " scale_out\n"
143 " pan\n"
144 " INPUT is some image file to put into the wallpaper edj\n"
145 " OUT is the paht/location of the wallpaper edj output\n"
146 " QUALITY is:\n"
147 " 0-100 (0-99 is lossy, 100 is lossless compression)\n"
148 " etc1\n"
149 " etc2\n"
150 " R, G, B are Red, Green and Blue values 0 to 255\n"
151 "\n"
152 " e.g.\n"
153 " enlightenment_wallpaper_gen edje_cc scale_out cat.jpg wallpaper.edj 80\n"
154 " enlightenment_wallpaper_gen edje_cc center mylogo.png wallpaper.edj 100 48 64 64\n"
155 " enlightenment_wallpaper_gen /usr/local/bin/edje_cc tile pattern.jpg wallpaper.edj 98\n"
156 " enlightenment_wallpaper_gen /opt/e/bin/edje_cc scale_out hugeimg.jpg wallpaper.edj etc1\n"
157 );
158 return 1;
159 }
160
161 elm_config_preferred_engine_set("buffer");
162 win = elm_win_add(NULL, "Wallpaper-Gen", ELM_WIN_BASIC);
163 elm_win_norender_push(win);
164 evas_object_show(win);
165
166 subwin = elm_win_add(win, "inlined", ELM_WIN_INLINED_IMAGE);
167 rend = elm_win_inlined_image_object_get(subwin);
168 elm_win_norender_push(subwin);
169 evas_object_show(subwin);
170
171 if (argc < 6) return 2;
172 edje_cc = argv[1];
173 mode = argv[2];
174 file = argv[3];
175 outfile = argv[4];
176 if (!strcmp(argv[5], "etc1")) quality = ETC1;
177 else if (!strcmp(argv[5], "etc2")) quality = ETC2;
178 else
179 {
180 quality = atoi(argv[5]);
181 if (quality < 0) quality = 0;
182 else if (quality > 100) quality = 100;
183 }
184
185 image = evas_object_image_filled_add(evas_object_evas_get(subwin));
186 evas_object_image_file_set(image, file, NULL);
187 evas_object_image_size_get(image, &w, &h);
188 if ((w <= 0) || (h <= 0)) return 3;
189 alpha = evas_object_image_alpha_get(image);
190 elm_win_alpha_set(subwin, alpha);
191 evas_object_show(image);
192
193 snprintf(dir_buf, sizeof(dir_buf), "/tmp/e_bg-XXXXXX");
194 dir = mkdtemp(dir_buf);
195 if (!dir) return 4;
196
197 if ((!strcmp(mode, "center")) ||
198 (!strcmp(mode, "scale_in")))
199 { // need backing rgb color here
200 if (argc < 9) return 5;
201 bg_r = atoi(argv[6]);
202 bg_g = atoi(argv[7]);
203 bg_b = atoi(argv[8]);
204 }
205 if ((!strcmp(mode, "stretch")) ||
206 (!strcmp(mode, "scale_in")) ||
207 (!strcmp(mode, "scale_out")) ||
208 (!strcmp(mode, "pan")))
209 { // need to produce multiple scaled versions
210 mips = _resolutions_calc(w, h);
211 if (!mips) return 6;
212 for (i = 0; mips[i].to_w; i++)
213 {
214 mips_num++;
215 if (mips[i].last)
216 {
217 imw = w;
218 imh = h;
219 }
220 else
221 {
222 imw = mips[i].to_w;
223 imh = mips[i].to_h;
224 }
225 evas_object_resize(subwin, imw, imh);
226 evas_object_resize(image, imw, imh);
227 elm_win_render(subwin);
228 if (mips[i].last)
229 snprintf(img_buf, sizeof(img_buf), "%s/img.png",
230 dir);
231 else
232 snprintf(img_buf, sizeof(img_buf), "%s/img-%ix%i.png",
233 dir, imw, imh);
234 if (!evas_object_image_save(rend, img_buf, NULL, "compress=0"))
235 {
236 ret = 7;
237 goto cleanup;
238 }
239 }
240 }
241 // no multiple resolutions -0 save out original
242 if (!mips)
243 {
244 evas_object_resize(subwin, w, h);
245 evas_object_resize(image, w, h);
246 elm_win_render(subwin);
247 snprintf(img_buf, sizeof(img_buf), "%s/img.png", dir);
248 if (!evas_object_image_save(rend, img_buf, NULL, "compress=0"))
249 {
250 ret = 8;
251 goto cleanup;
252 }
253 }
254 if ((quality == ETC1) && (alpha)) quality = ETC2; // etc1 -> etc2 if alpha
255 if (quality == 100) quality_string = "COMP";
256 else
257 {
258 if (quality == ETC1) quality_string = "LOSSY_ETC1";
259 else if (quality == ETC2) quality_string = "LOSSY_ETC2";
260 else
261 {
262 snprintf(qual_buf, sizeof(qual_buf), "LOSSY %i", quality);
263 quality_string = qual_buf;
264 }
265 }
266 // generate edc
267 snprintf(edc_buf, sizeof(edc_buf), "%s/bg.edc", dir);
268 f = fopen(edc_buf, "w");
269 if (!f) goto cleanup;
270 if ((mips) && (mips_num > 1))
271 {
272 fprintf(f,
273 "images {\n"
274 " set { name: \"img\";\n");
275 for (i = mips_num - 1; i >= 0; i--)
276 {
277 fprintf(f,
278 " image {\n");
279 if (mips[i].last)
280 {
281 imw = w;
282 imh = h;
283 fprintf(f,
284 " image: \"img.png\" %s;\n",
285 quality_string);
286 }
287 else
288 {
289 imw = mips[i].to_w;
290 imh = mips[i].to_h;
291 fprintf(f,
292 " image: \"img-%ix%i.png\" %s;\n",
293 imw, imh, quality_string);
294 }
295 fprintf(f,
296 " size: %i %i %i %i;\n"
297 " }\n",
298 mips[i].from_w, mips[i].from_h,
299 mips[i].to_w, mips[i].to_h);
300 }
301 fprintf(f,
302 " }\n"
303 "}\n");
304 img_name = "img";
305 }
306 else
307 {
308 fprintf(f, "images.image: \"img.png\" %s;\n", quality_string);
309 img_name = "img.png";
310 }
311 fprintf(f,
312 "collections {\n"
313 " group { name: \"e/desktop/background\";\n"
314 " data.item: \"noanimation\" \"1\";\n");
315 if (!strcmp(mode, "stretch"))
316 {
317 fprintf(f, " data { item: \"style\" \"0\"; }\n");
318 fprintf(f,
319 " parts {\n"
320 " part { name: \"bg\"; mouse_events: 0;\n"
321 " description { state: \"default\" 0;\n"
322 " image {\n"
323 " normal: \"%s\";\n"
324 " scale_hint: STATIC;\n"
325 " }\n"
326 " }\n"
327 " }\n"
328 " }\n"
329 , img_name);
330 }
331 else if (!strcmp(mode, "tile"))
332 {
333 fprintf(f, " data { item: \"style\" \"1\"; }\n");
334 fprintf(f,
335 " parts {\n"
336 " part { name: \"bg\"; mouse_events: 0;\n"
337 " description { state: \"default\" 0;\n"
338 " image {\n"
339 " normal: \"%s\";\n"
340 " }\n"
341 " fill.size.relative: 0 0;\n"
342 " fill.size.offset: %i %i;\n"
343 " }\n"
344 " }\n"
345 " }\n"
346 , img_name, w, h);
347 }
348 else if (!strcmp(mode, "center"))
349 {
350 fprintf(f, " data { item: \"style\" \"2\"; }\n");
351 fprintf(f,
352 " parts {\n"
353 " part { name: \"col\"; type: RECT; mouse_events: 0;\n"
354 " description { state: \"default\" 0;\n"
355 " color: %i %i %i 255;\n"
356 " }\n"
357 " }\n"
358 " part { name: \"bg\"; mouse_events: 0;\n"
359 " description { state: \"default\" 0;\n"
360 " image {\n"
361 " normal: \"%s\";\n"
362 " }\n"
363 " min: %i %i; max: %i %i;\n"
364 " }\n"
365 " }\n"
366 " }\n"
367 , bg_r, bg_g, bg_b, img_name, w, h, w, h);
368 }
369 else if (!strcmp(mode, "scale_in"))
370 {
371 fprintf(f, " data { item: \"style\" \"3\"; }\n");
372 fprintf(f,
373 " parts {\n"
374 " part { name: \"col\"; type: RECT; mouse_events: 0;\n"
375 " description { state: \"default\" 0;\n"
376 " color: %i %i %i 255;\n"
377 " }\n"
378 " }\n"
379 " part { name: \"bg\"; mouse_events: 0;\n"
380 " description { state: \"default\" 0;\n"
381 " image {\n"
382 " normal: \"%s\";\n"
383 " scale_hint: STATIC;\n"
384 " }\n"
385 " aspect: (%i/%i) (%i/%i); aspect_preference: BOTH;\n"
386 " }\n"
387 " }\n"
388 " }\n"
389 , bg_r, bg_g, bg_b, img_name, w, h, w, h);
390 }
391 else if (!strcmp(mode, "scale_out"))
392 {
393 fprintf(f, " data { item: \"style\" \"4\"; }\n");
394 fprintf(f,
395 " parts {\n"
396 " part { name: \"bg\"; mouse_events: 0;\n"
397 " description { state: \"default\" 0;\n"
398 " image {\n"
399 " normal: \"%s\";\n"
400 " scale_hint: STATIC;\n"
401 " }\n"
402 " aspect: (%i/%i) (%i/%i); aspect_preference: NONE;\n"
403 " }\n"
404 " }\n"
405 " }\n"
406 , img_name, w, h, w, h);
407 }
408 else if (!strcmp(mode, "pan"))
409 {
410 fprintf(f, " data { item: \"style\" \"5\"; }\n");
411 fprintf(f,
412 " script {\n"
413 " public cur_anim; public cur_x; public cur_y;\n"
414 " public prev_x; public prev_y;\n"
415 " public total_x; public total_y;\n"
416 " public pan_bg(val, Float:v) {\n"
417 " new Float:x, Float:y, Float:px, Float: py;\n"
418 " px = get_float(prev_x);\n"
419 " py = get_float(prev_y);\n"
420 " if (get_int(total_x) > 1) {\n"
421 " x = float(get_int(cur_x)) / (get_int(total_x) - 1);\n"
422 " x = px - (px - x) * v;\n"
423 " } else {\n"
424 " x = 0.0;\n"
425 " v = 1.0;\n"
426 " }\n"
427 " if (get_int(total_y) > 1) {\n"
428 " y = float(get_int(cur_y)) / (get_int(total_y) - 1);\n"
429 " y = py - (py - y) * v;\n"
430 " } else {\n"
431 " y = 0.0;\n"
432 " v = 1.0; }\n"
433 " set_state_val(PART:\"bg\", STATE_ALIGNMENT, x, y);\n"
434 " if (v >= 1.0) {\n"
435 " set_int(cur_anim, 0);\n"
436 " set_float(prev_x, x);\n"
437 " set_float(prev_y, y);\n"
438 " return 0;\n"
439 " }\n"
440 " return 1;\n"
441 " }\n"
442 " public message(Msg_Type:type, id, ...) {\n"
443 " if ((type == MSG_FLOAT_SET) && (id == 0)) {\n"
444 " new ani;\n"
445 " get_state_val(PART:\"bg\", STATE_ALIGNMENT, prev_x, prev_y);\n"
446 " set_int(cur_x, round(getfarg(3)));\n"
447 " set_int(total_x, round(getfarg(4)));\n"
448 " set_int(cur_y, round(getfarg(5)));\n"
449 " set_int(total_y, round(getfarg(6)));\n"
450 " ani = get_int(cur_anim);\n"
451 " if (ani > 0) cancel_anim(ani);\n"
452 " ani = anim(getfarg(2), \"pan_bg\", 0);\n"
453 " set_int(cur_anim, ani);\n"
454 " }\n"
455 " }\n"
456 " }\n"
457 " parts {\n"
458 " part { name: \"bg\"; mouse_events: 0;\n"
459 " description { state: \"default\" 0.0;\n"
460 " image {\n"
461 " normal: \"%s\";\n"
462 " scale_hint: STATIC;\n"
463 " }\n"
464 " aspect: (%i/%i) (%i/%i); aspect_preference: NONE;\n"
465 " }\n"
466 " }\n"
467 " program {\n"
468 " signal: \"load\"; source: \"\";\n"
469 " script {\n"
470 " custom_state(PART:\"bg\", \"default\", 0.0);\n"
471 " set_state(PART:\"bg\", \"custom\", 0.0);\n"
472 " set_float(prev_x, 0.0);\n"
473 " set_float(prev_y, 0.0);\n"
474 " }\n"
475 " }\n"
476 " }\n"
477 , img_name, w, h, w, h);
478 }
479 fprintf(f,
480 " }\n"
481 "}\n");
482 fclose(f);
483 free(mips);
484 if (snprintf(cmd_buf, sizeof(cmd_buf),
485 "%s -fastdecomp -id %s -fd %s -sd %s -vd %s -dd %s -md %s "
486 "%s/bg.edc %s",
487 edje_cc, dir, dir, dir, dir, dir, dir,
488 dir, outfile) >= (int)sizeof(cmd_buf))
489 {
490 ret = 9;
491 goto cleanup;
492 }
493 ret = system(cmd_buf);
494cleanup:
495 ecore_file_recursive_rm(dir);
496 evas_object_del(win);
497 return ret;
498}
499ELM_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',
513 install : true 513 install : true
514 ) 514 )
515 515
516executable('enlightenment_static_grabber', 516executable('enlightenment_wallpaper_gen',
517 [ 'e_static_grab.c' ], 517 [ 'e_wallpaper_gen_main.c' ],
518 include_directories: include_directories('../..'), 518 include_directories: include_directories('../..'),
519 dependencies : [ dep_eina, dep_eet ], 519 dependencies : [ dep_elementary ],
520 install_dir : dir_e_utils, 520 install_dir : dir_e_utils,
521 install : true 521 install : true
522 ) 522 )