summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/elementary/meson.build1
-rw-r--r--src/bin/elementary/test.c4
-rw-r--r--src/bin/elementary/test_fileselector_button.c1
-rw-r--r--src/bin/elementary/test_label.c17
-rw-r--r--src/bin/elementary/test_map.c1228
-rw-r--r--src/generic/evas/pdf/main.cpp4
-rw-r--r--src/generic/evas/rsvg/main.c30
-rw-r--r--src/generic/evas/rsvg/meson.build5
-rw-r--r--src/lib/ecore_x/Ecore_X.h1
-rw-r--r--src/lib/ecore_x/ecore_x_randr.c35
-rw-r--r--src/lib/edje/edje_calc.c2
-rw-r--r--src/lib/edje/edje_embryo.c2
-rw-r--r--src/lib/edje/edje_lua2.c2
-rw-r--r--src/lib/edje/edje_private.h1
-rw-r--r--src/lib/edje/edje_util.c80
-rw-r--r--src/lib/eina/eina_debug_chunk.c22
-rw-r--r--src/lib/eina/eina_evlog.c22
-rw-r--r--src/lib/eina/eina_safepointer.c36
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_calc.c2
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_root_focus.c1
-rw-r--r--src/lib/elementary/efl_ui_widget.c16
-rw-r--r--src/lib/elementary/elm_code_syntax.c15
-rw-r--r--src/lib/elementary/elm_config.c276
-rw-r--r--src/lib/elementary/elm_map.c5529
-rw-r--r--src/lib/elementary/elm_map_common.h440
-rw-r--r--src/lib/elementary/elm_map_eo.legacy.h470
-rw-r--r--src/lib/elementary/elm_map_legacy.h130
-rw-r--r--src/lib/emotion/emotion_smart.c7
-rw-r--r--src/lib/eo/eo.c49
-rw-r--r--src/lib/eo/eo_add_fallback.c38
-rw-r--r--src/lib/eo/eo_ptr_indirection.x59
-rw-r--r--src/lib/evas/canvas/efl_canvas_proxy.c20
-rw-r--r--src/lib/evas/canvas/evas_map.c10
-rw-r--r--src/lib/evas/canvas/evas_object_textblock.c16
-rw-r--r--src/lib/evas/canvas/evas_textblock_legacy.h7
-rw-r--r--src/lib/evas/common/evas_image_main.c12
-rw-r--r--src/lib/evas/include/evas_private.h1
-rw-r--r--src/lib/evil/evil_main.c16
-rw-r--r--src/lib/evil/meson.build3
-rw-r--r--src/modules/emotion/gstreamer1/emotion_gstreamer.c18
-rw-r--r--src/modules/emotion/gstreamer1/emotion_gstreamer.h1
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h2
-rw-r--r--src/modules/evas/engines/gl_x11/evas_engine.c10
-rw-r--r--src/modules/evas/engines/gl_x11/evas_x_main.c1
-rw-r--r--src/modules/evas/engines/software_generic/evas_native_common.h1
-rw-r--r--src/tests/eina/eina_test_simple_xml_parser.c2
46 files changed, 1030 insertions, 7615 deletions
diff --git a/src/bin/elementary/meson.build b/src/bin/elementary/meson.build
index 1d7aa75057..5254eb69ba 100644
--- a/src/bin/elementary/meson.build
+++ b/src/bin/elementary/meson.build
@@ -86,7 +86,6 @@ elementary_test_src = [
86 'test_launcher.c', 86 'test_launcher.c',
87 'test_layout.c', 87 'test_layout.c',
88 'test_list.c', 88 'test_list.c',
89 'test_map.c',
90 'test_main_menu.c', 89 'test_main_menu.c',
91 'test_menu.c', 90 'test_menu.c',
92 'test_multi.c', 91 'test_multi.c',
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index d0d374ece4..a317875263 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -228,7 +228,6 @@ void test_calendar(void *data, Evas_Object *obj, void *event_info);
228void test_calendar2(void *data, Evas_Object *obj, void *event_info); 228void test_calendar2(void *data, Evas_Object *obj, void *event_info);
229void test_calendar3(void *data, Evas_Object *obj, void *event_info); 229void test_calendar3(void *data, Evas_Object *obj, void *event_info);
230void test_efl_ui_calendar(void *data, Evas_Object *obj, void *event_info); 230void test_efl_ui_calendar(void *data, Evas_Object *obj, void *event_info);
231void test_map(void *data, Evas_Object *obj, void *event_info);
232void test_weather(void *data, Evas_Object *obj, void *event_info); 231void test_weather(void *data, Evas_Object *obj, void *event_info);
233void test_flip(void *data, Evas_Object *obj, void *event_info); 232void test_flip(void *data, Evas_Object *obj, void *event_info);
234void test_flip2(void *data, Evas_Object *obj, void *event_info); 233void test_flip2(void *data, Evas_Object *obj, void *event_info);
@@ -1256,9 +1255,6 @@ add_tests:
1256 ADD_TEST(NULL, "Naviframe", "Naviframe: Complex", test_naviframe_complex); 1255 ADD_TEST(NULL, "Naviframe", "Naviframe: Complex", test_naviframe_complex);
1257 1256
1258 //------------------------------// 1257 //------------------------------//
1259 ADD_TEST(NULL, "Geographic", "Map", test_map);
1260
1261 //------------------------------//
1262 ADD_TEST(NULL, "Dividers", "Panel", test_panel); 1258 ADD_TEST(NULL, "Dividers", "Panel", test_panel);
1263 ADD_TEST(NULL, "Dividers", "Panel Scrollable", test_panel2); 1259 ADD_TEST(NULL, "Dividers", "Panel Scrollable", test_panel2);
1264 ADD_TEST(NULL, "Dividers", "Panes", test_panes); 1260 ADD_TEST(NULL, "Dividers", "Panes", test_panes);
diff --git a/src/bin/elementary/test_fileselector_button.c b/src/bin/elementary/test_fileselector_button.c
index 2ee1a3338c..e3410bf92b 100644
--- a/src/bin/elementary/test_fileselector_button.c
+++ b/src/bin/elementary/test_fileselector_button.c
@@ -195,6 +195,7 @@ test_fileselector_button(void *data EINA_UNUSED,
195 elm_object_text_set(fs_bt, "Select a file"); 195 elm_object_text_set(fs_bt, "Select a file");
196 elm_object_part_content_set(fs_bt, "icon", ic); 196 elm_object_part_content_set(fs_bt, "icon", ic);
197 elm_fileselector_path_set(fs_bt, "/tmp/test_fs_bt"); 197 elm_fileselector_path_set(fs_bt, "/tmp/test_fs_bt");
198 evas_object_show(ic);
198 199
199 elm_box_pack_end(vbox, fs_bt); 200 elm_box_pack_end(vbox, fs_bt);
200 evas_object_show(fs_bt); 201 evas_object_show(fs_bt);
diff --git a/src/bin/elementary/test_label.c b/src/bin/elementary/test_label.c
index de7c2bcf32..a7f0d62da0 100644
--- a/src/bin/elementary/test_label.c
+++ b/src/bin/elementary/test_label.c
@@ -320,7 +320,8 @@ enum BUTTON{
320 BUTTON_ARRAY = 4, 320 BUTTON_ARRAY = 4,
321 BUTTON_CONTENT = 5, 321 BUTTON_CONTENT = 5,
322 BUTTON_STYLE = 6, 322 BUTTON_STYLE = 6,
323 BUTTON_ALL = BUTTON_STYLE+1, 323 BUTTON_SIZE = 7,
324 BUTTON_ALL = BUTTON_SIZE+1,
324}; 325};
325 326
326char* BUTTON_STR[BUTTON_ALL] ={ 327char* BUTTON_STR[BUTTON_ALL] ={
@@ -331,6 +332,7 @@ char* BUTTON_STR[BUTTON_ALL] ={
331 "ARRAY", 332 "ARRAY",
332 "CONTENT", 333 "CONTENT",
333 "STYLE", 334 "STYLE",
335 "Get Size",
334}; 336};
335 337
336char *contents[] = { 338char *contents[] = {
@@ -430,6 +432,8 @@ char * get_fit_status(Eo * textblock)
430 static char status[0xFFF]; 432 static char status[0xFFF];
431 unsigned int options,min,max,step,size_array[256]; 433 unsigned int options,min,max,step,size_array[256];
432 size_t size_array_len; 434 size_t size_array_len;
435 int current_fitting_fontsize = 0;
436 current_fitting_fontsize = evas_textblock_fit_font_size_get(textblock);
433 evas_textblock_fit_options_get(textblock,&options); 437 evas_textblock_fit_options_get(textblock,&options);
434 evas_textblock_fit_size_range_get(textblock,&min,&max); 438 evas_textblock_fit_size_range_get(textblock,&min,&max);
435 evas_textblock_fit_step_size_get(textblock,&step); 439 evas_textblock_fit_step_size_get(textblock,&step);
@@ -464,8 +468,15 @@ char * get_fit_status(Eo * textblock)
464 sprintf(status + strlen(status)," ]"); 468 sprintf(status + strlen(status)," ]");
465 469
466 sprintf(status + strlen(status),"<br>"); 470 sprintf(status + strlen(status),"<br>");
467 sprintf(status + strlen(status),"%s",styles_names[app->i_style]); 471 sprintf(status + strlen(status),"%s<br>",styles_names[app->i_style]);
468 472 if (current_fitting_fontsize == -1)
473 {
474 sprintf(status + strlen(status),"Current Font Size = No Fitting");
475 }
476 else
477 {
478 sprintf(status + strlen(status),"Current Font Size = %d", current_fitting_fontsize);
479 }
469 480
470 481
471 return status; 482 return status;
diff --git a/src/bin/elementary/test_map.c b/src/bin/elementary/test_map.c
deleted file mode 100644
index b87f3d6521..0000000000
--- a/src/bin/elementary/test_map.c
+++ /dev/null
@@ -1,1228 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4#include <Elementary.h>
5
6#define SOURCE_MAX 10
7#define MARKER_MAX 1000
8#define NAME_ENTRY_TEXT "Enter freeform address"
9
10typedef struct Overlay_Data
11{
12 char file[PATH_MAX];
13} Overlay_Data;
14
15typedef struct Map_Source
16{
17 Evas_Object *map;
18 Elm_Map_Source_Type type;
19 char *source_name;
20} Map_Source;
21
22
23static Elm_Map_Overlay *route_start, *route_end, *route_clas;
24static Elm_Map_Overlay *bubble_img;
25static Elm_Map_Overlay *bubble_parking;
26static Elm_Map_Overlay *route_ovl;
27static Elm_Map_Overlay *line_start, *line_end, *line;
28static Elm_Map_Overlay *poly;
29static Elm_Map_Overlay *circle;
30static Elm_Map_Overlay *scale;
31static Eina_List *poly_points;
32
33static Evas_Object *menu, *fs_win;
34static Elm_Map_Route *route;
35static Elm_Map_Name *name;
36static Evas_Object *track;
37static Evas_Coord down_x, down_y;
38static Evas_Coord old_x, old_y, old_d;
39static Map_Source ts[SOURCE_MAX];
40static Map_Source rs[SOURCE_MAX];
41static Map_Source ns[SOURCE_MAX];
42
43static void
44#ifdef ELM_EMAP
45my_map_gpx_fileselector_done(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
46#else
47my_map_gpx_fileselector_done(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
48#endif
49{
50 const char *selected = event_info;
51
52 if (selected)
53 {
54 printf("Selected file: %s\n", selected);
55#ifdef ELM_EMAP
56 EMap_Route *emap = emap_route_gpx_new(selected);
57 track = elm_map_track_add(data, emap);
58#else
59 printf("libEMap is required !\n");
60#endif
61 }
62 evas_object_del(fs_win);
63}
64
65static Evas_Object *
66_route_icon_get(Evas_Object *obj)
67{
68 Evas_Object *icon = elm_icon_add(obj);
69 elm_image_file_set(icon, PACKAGE_DATA_DIR"/images/bubble.png", NULL);
70 evas_object_show(icon);
71
72 return icon;
73}
74
75static Evas_Object *
76_box_get(Evas_Object *obj, Overlay_Data *data, Elm_Map_Overlay *ovl)
77{
78 Evas_Object *bx, *img, *label;
79 double lon, lat;
80 char buf[256];
81 bx = elm_box_add(obj);
82 evas_object_show(bx);
83
84 img = evas_object_image_add(evas_object_evas_get(obj));
85 evas_object_image_file_set(img, data->file, NULL);
86 evas_object_image_filled_set(img, EINA_TRUE);
87 evas_object_size_hint_min_set(img, 64, 64);
88 evas_object_show(img);
89 elm_box_pack_end(bx, img);
90
91 label = elm_label_add(bx);
92 elm_map_overlay_region_get(ovl, &lon, &lat);
93 snprintf(buf, sizeof(buf), "%0.4lf %0.4lf", lon, lat);
94 elm_object_text_set(label, buf);
95 evas_object_show(label);
96 elm_box_pack_end(bx, label);
97 return bx;
98}
99
100static void
101_overlays_show(void *data, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
102{
103 Eina_List *members = elm_map_overlay_group_members_get(data);
104 elm_map_overlays_show(members);
105}
106
107static Evas_Object *
108_btn_get(Evas_Object *obj, Elm_Map_Overlay *ovl)
109{
110 Evas_Object *btn;
111
112 btn = elm_button_add(obj);
113 elm_object_text_set(btn, "Show");
114 evas_object_smart_callback_add(btn, "clicked", _overlays_show, ovl);
115 evas_object_show(btn);
116
117 return btn;
118}
119
120static Evas_Object *
121_label_get(Evas_Object *obj)
122{
123 Evas_Object *label;
124 label = elm_label_add(obj);
125 elm_object_text_set(label, "Here is a parking lot.");
126 evas_object_show(label);
127 return label;
128}
129
130static Evas_Object *
131_icon_get(Evas_Object *obj, Overlay_Data *data)
132{
133 Evas_Object *icon = elm_icon_add(obj);
134 elm_image_file_set(icon, data->file, NULL);
135 evas_object_show(icon);
136
137 return icon;
138}
139
140static void
141_overlay_hide(void *data, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
142{
143 elm_map_overlay_hide_set(data, EINA_TRUE);
144}
145
146static void
147_overlay_pause(void *data, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
148{
149 elm_map_overlay_paused_set(data, EINA_TRUE);
150}
151
152static void
153_overlay_unpause(void *data, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
154{
155 elm_map_overlay_paused_set(data, EINA_FALSE);
156}
157
158static void
159_overlay_show(void *data, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
160{
161 elm_map_overlay_show(data);
162}
163
164static Evas_Object *
165_btn_box_get(Evas_Object *obj, Elm_Map_Overlay *ovl)
166{
167 Evas_Object *bx, *btn, *btn2, *btn3, *btn4;
168 bx = elm_box_add(obj);
169 elm_box_horizontal_set(bx, EINA_TRUE);
170 evas_object_show(bx);
171
172 btn = elm_button_add(bx);
173 elm_object_text_set(btn, "Hide");
174 evas_object_smart_callback_add(btn, "clicked", _overlay_hide, ovl);
175 evas_object_show(btn);
176 elm_box_pack_end(bx, btn);
177
178 btn2 = elm_button_add(bx);
179 elm_object_text_set(btn2, "Pause");
180 evas_object_smart_callback_add(btn2, "clicked", _overlay_pause, ovl);
181 evas_object_show(btn2);
182 elm_box_pack_end(bx, btn2);
183
184 btn3 = elm_button_add(bx);
185 elm_object_text_set(btn3, "Unpause");
186 evas_object_smart_callback_add(btn3, "clicked", _overlay_unpause, ovl);
187 evas_object_show(btn3);
188 elm_box_pack_end(bx, btn3);
189
190 btn4 = elm_button_add(bx);
191 elm_object_text_set(btn4, "Show");
192 evas_object_smart_callback_add(btn4, "clicked", _overlay_show, ovl);
193 evas_object_show(btn4);
194 elm_box_pack_end(bx, btn4);
195
196 return bx;
197}
198
199static void
200_bubble_parking_follow(Evas_Object *map)
201{
202 double lon, lat;
203 Evas_Coord x, y;
204
205 if (bubble_parking)
206 {
207 Elm_Map_Overlay *ovl = elm_map_overlay_data_get(bubble_parking);
208 elm_map_overlay_region_get(ovl, &lon, &lat);
209 elm_map_region_to_canvas_convert(map, lon, lat, &x, &y);
210 elm_map_canvas_to_region_convert(map, x+40, y+50, &lon, &lat);
211 elm_map_overlay_region_set(bubble_parking, lon, lat);
212 }
213}
214
215static void
216_overlays_num_check(Evas_Object *obj)
217{
218 Evas_Coord x, y, w, h;
219 double lon, lat, max_lon, max_lat, min_lon, min_lat;
220 Eina_List *overlays, *l;
221 Elm_Map_Overlay *ovl;
222 int cnt = 0;
223 int cnt_visible = 0;
224
225 overlays = elm_map_overlays_get(obj);
226 evas_object_geometry_get(obj, &x, &y, &w, &h);
227 elm_map_canvas_to_region_convert(obj, x, y, &min_lon, &max_lat);
228 elm_map_canvas_to_region_convert(obj, x + w, y + h, &max_lon, &min_lat);
229
230 EINA_LIST_FOREACH(overlays, l, ovl)
231 {
232 if (elm_map_overlay_type_get(ovl) == ELM_MAP_OVERLAY_TYPE_CLASS)
233 continue;
234 elm_map_overlay_region_get(ovl, &lon, &lat);
235 if ((min_lon <= lon) && (lon <= max_lon) &&
236 (min_lat <= lat) && (lat <= max_lat))
237 {
238 if (elm_map_overlay_visible_get(ovl)) cnt_visible++;
239 cnt++;
240 }
241 }
242 printf("Number of (visible/total) overlays in viewport: %d/%d\n",
243 cnt_visible, cnt);
244}
245
246static void
247_map_clicked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
248{
249 printf("clicked\n");
250}
251
252static void
253_map_clicked_double(void *data EINA_UNUSED, Evas_Object *obj, void *event_info)
254{
255 printf("clicked,double\n");
256 double lon, lat;
257 Evas_Event_Mouse_Down *ev = event_info;
258 if (!ev) return;
259 if (elm_map_zoom_get(obj) < 5) return;
260
261 elm_map_canvas_to_region_convert(obj, ev->canvas.x, ev->canvas.y, &lon, &lat);
262 printf("x:%d, y:%d, lon:%lf, lat:%lf\n", ev->canvas.x, ev->canvas.y, lon, lat);
263
264 if (!route_clas)
265 {
266 route_clas = elm_map_overlay_class_add(obj);
267 elm_map_overlay_icon_set(route_clas, _route_icon_get(obj));
268 elm_map_overlay_displayed_zoom_min_set(route_clas, 5);
269 }
270
271 if (route_start && route_end)
272 {
273 elm_map_overlay_del(route_start);
274 elm_map_overlay_del(route_end);
275 elm_map_route_del(route);
276 route_start = NULL;
277 route_end = NULL;
278 route = NULL;
279 }
280
281 if (!route_start) route_start = elm_map_overlay_add(obj, lon, lat);
282 else route_end = elm_map_overlay_add(obj, lon, lat);
283
284 if (route_start && route_end)
285 {
286 double start_lon, start_lat, end_lon, end_lat;
287 elm_map_overlay_class_append(route_clas, route_start);
288 elm_map_overlay_class_append(route_clas, route_end);
289 elm_map_overlay_region_get(route_start, &start_lon, &start_lat);
290 elm_map_overlay_region_get(route_end, &end_lon, &end_lat);
291 route = elm_map_route_add(obj, ELM_MAP_ROUTE_TYPE_MOTOCAR,
292 ELM_MAP_ROUTE_METHOD_FASTEST,
293 start_lon, start_lat, end_lon, end_lat,
294 NULL, NULL);
295 }
296}
297
298static void
299_map_press(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
300{
301 printf("press\n");
302}
303
304static void
305_map_longpressed(void *data EINA_UNUSED, Evas_Object *obj, void *event_info)
306{
307 if (!event_info) return;
308 double lon, lat;
309 Evas_Event_Mouse_Down *ev = event_info;
310 elm_map_canvas_to_region_convert(obj, ev->canvas.x, ev->canvas.y, &lon, &lat);
311 printf("longpressed, x:%d, y:%d, lon:%lf, lat:%lf\n", ev->canvas.x, ev->canvas.y, lon, lat);
312
313 if (elm_map_zoom_get(obj) < 8) return;
314 if (name) elm_map_name_del(name);
315 name = elm_map_name_add(obj, NULL, lon, lat, NULL, NULL);
316}
317
318static void
319_map_scroll(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
320{
321 double lon, lat;
322 elm_map_region_get(obj, &lon, &lat);
323 printf("scroll, longitude: %f latitude: %f\n", lon, lat);
324 _bubble_parking_follow(obj);
325}
326
327static void
328_map_drag_start(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
329{
330 printf("scroll,drag,start\n");
331 evas_object_smart_callback_del(data, "longpressed", _map_longpressed);
332}
333
334static void
335_map_drag_stop(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
336{
337 printf("scroll,drag,stop\n");
338 evas_object_smart_callback_add(data, "longpressed", _map_longpressed, data);
339 _overlays_num_check(obj);
340}
341
342static void
343_map_anim_start(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
344{
345 printf("scroll,anim,start\n");
346}
347
348static void
349_map_anim_stop(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
350{
351 printf("scroll,anim,stop\n");
352}
353
354static void
355_map_zoom_start(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
356{
357 printf("zoom,start\n");
358}
359
360static void
361_map_zoom_stop(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
362{
363 printf("zoom,stop\n");
364 _overlays_num_check(obj);
365}
366
367static void
368_map_zoom_change(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
369{
370 printf("zoom,change\n");
371 _bubble_parking_follow(obj);
372}
373
374static void
375_map_loaded(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
376{
377 printf("loaded\n");
378}
379
380static void
381_map_tile_load(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
382{
383 printf("tile,load\n");
384}
385
386static void
387_map_tile_loaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
388{
389 int try_num, finish_num;
390 elm_map_tile_load_status_get(data, &try_num, &finish_num);
391 printf("tile,loaded: %d / %d\n", finish_num, try_num);
392}
393
394static void
395_map_tile_loaded_fail(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
396{
397 int try_num, finish_num;
398 elm_map_tile_load_status_get(data, &try_num, &finish_num);
399 printf("tile,loaded,fail: %d / %d\n", finish_num, try_num);
400}
401
402static void
403_map_route_load(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
404{
405 printf("route,load\n");
406}
407
408static void
409_map_route_loaded(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
410{
411 printf("route,loaded\n");
412 double d;
413 const char *w, *n;
414
415 d = elm_map_route_distance_get(route);
416 printf("route distance = %lf km\n", d);
417
418 w = elm_map_route_waypoint_get(route);
419 if (w) printf("[waypoints]\n%s\n", w);
420
421 n = elm_map_route_node_get(route);
422 if (n) printf("[nodes]\n%s\n", n);
423
424 if (route_ovl) elm_map_overlay_del(route_ovl);
425 route_ovl = elm_map_overlay_route_add(obj, route);
426}
427
428static void
429_map_route_loaded_fail(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
430{
431 printf("route,loaded,fail\n");
432}
433
434static void
435_map_name_load(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
436{
437 printf("name,load\n");
438}
439
440static void
441_map_name_loaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
442{
443 printf("name,loaded\n");
444 if (!name) return;
445 double lon, lat;
446 const char *addr = elm_map_name_address_get(name);
447 elm_map_name_region_get(name, &lon, &lat);
448 if (addr)
449 {
450 printf("name of [lon = %lf, lat = %lf] is %s\n", lon, lat, addr);
451 if (EINA_DBL_NONZERO(lon) && EINA_DBL_NONZERO(lat))
452 {
453 Eina_Bool b = elm_map_paused_get(data);
454 elm_map_paused_set(data, EINA_TRUE);
455 elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
456 elm_map_zoom_set(data, elm_map_zoom_max_get(data));
457 elm_map_region_show(data, lon, lat);
458 elm_map_paused_set(data, b);
459 }
460 }
461
462 elm_map_name_del(name);
463 name = NULL;
464}
465
466static void
467_map_name_loaded_fail(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
468{
469 printf("name,loaded,fail\n");
470}
471
472static void
473_src_set(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
474{
475 Map_Source *s = data;
476
477 if (!s) return;
478 elm_map_source_set(s->map, s->type, s->source_name);
479}
480
481static void
482_show_urmatt(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
483{
484 elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
485 if (elm_map_zoom_get(data) < 12) elm_map_zoom_set(data, 12);
486 elm_map_region_show(data,7.325201, 48.526813);
487}
488
489static void
490_bring_seoul(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
491{
492 elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
493 if (elm_map_zoom_get(data) < 12) elm_map_zoom_set(data, 12);
494 elm_map_region_bring_in(data, 126.977969, 37.566535);
495}
496
497static void
498_bring_zoom_suwon(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
499{
500 elm_map_region_zoom_bring_in(data, 16, 126.977969, 37.566535);
501}
502
503static void
504_paused_set(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
505{
506 elm_map_paused_set(data, EINA_TRUE);
507}
508
509static void
510_paused_unset(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
511{
512 elm_map_paused_set(data, EINA_FALSE);
513}
514
515static void
516_zoom_in(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
517{
518 int zoom;
519
520 zoom = elm_map_zoom_get(data) + 1;
521 elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
522 elm_map_zoom_set(data, zoom);
523}
524
525static void
526_zoom_out(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
527{
528 int zoom;
529
530 zoom = elm_map_zoom_get(data) - 1;
531 elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
532 elm_map_zoom_set(data, zoom);
533}
534
535static void
536_zoom_fit(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
537{
538 elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FIT);
539}
540
541static void
542_zoom_fill(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
543{
544 elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FILL);
545}
546
547static void
548_zoom_manual(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
549{
550 elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
551}
552
553static void
554_track_add(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
555{
556 Evas_Object *fs, *vbox, *hbox, *sep;
557 const char *path = NULL;
558
559 fs_win = elm_win_util_standard_add("fileselector", "File Selector");
560 elm_win_autodel_set(fs_win, EINA_TRUE);
561
562 vbox = elm_box_add(fs_win);
563 evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
564 elm_win_resize_object_add(fs_win, vbox);
565 evas_object_show(vbox);
566
567 fs = elm_fileselector_add(fs_win);
568 elm_fileselector_is_save_set(fs, EINA_TRUE);
569 elm_fileselector_expandable_set(fs, EINA_FALSE);
570 path = eina_environment_home_get();
571 //if "HOME" is not available, set current dir. path
572 if (!path)
573 path = ".";
574 elm_fileselector_path_set(fs, path);
575 evas_object_size_hint_weight_set(fs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
576 evas_object_size_hint_align_set(fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
577 elm_box_pack_end(vbox, fs);
578 evas_object_show(fs);
579
580 evas_object_smart_callback_add(fs, "done", my_map_gpx_fileselector_done, data);
581
582 sep = elm_separator_add(fs_win);
583 elm_separator_horizontal_set(sep, EINA_TRUE);
584 elm_box_pack_end(vbox, sep);
585 evas_object_show(sep);
586
587 hbox = elm_box_add(fs_win);
588 elm_box_horizontal_set(hbox, EINA_TRUE);
589 elm_box_pack_end(vbox, hbox);
590 evas_object_show(hbox);
591
592 evas_object_resize(fs_win, 240, 350);
593 evas_object_show(fs_win);
594}
595
596
597static void
598_track_remove(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
599{
600 elm_map_track_remove(data, track);
601}
602
603static void
604_rotate_cw(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
605{
606 double d;
607 Evas_Coord x, y, w, h;
608 float half_w, half_h;
609 evas_object_geometry_get(data, &x, &y, &w, &h);
610 half_w = (float)w * 0.5;
611 half_h = (float)h * 0.5;
612
613 elm_map_rotate_get(data, &d, NULL, NULL);
614 d += 15.0;
615 elm_map_rotate_set(data, d, x + half_w, y + half_h);
616}
617
618static void
619_rotate_ccw(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
620{
621 double d;
622 Evas_Coord x, y, w, h;
623 float half_w, half_h;
624 evas_object_geometry_get(data, &x, &y, &w, &h);
625 half_w = (float)w * 0.5;
626 half_h = (float)h * 0.5;
627
628 elm_map_rotate_get(data, &d, NULL, NULL);
629 d -= 15.0;
630 elm_map_rotate_set(data, d, x + half_w, y + half_h);
631}
632
633static void
634_rotate_reset(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
635{
636 Evas_Coord x, y, w, h;
637 float half_w, half_h;
638 evas_object_geometry_get(data, &x, &y, &w, &h);
639 half_w = (float)w * 0.5;
640 half_h = (float)h * 0.5;
641
642 elm_map_rotate_set(data, 0.0, x + half_w, y + half_h);
643}
644
645static void
646_wheel_disable(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
647{
648 elm_map_wheel_disabled_set(data, EINA_TRUE);
649}
650
651static void
652_wheel_enable(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
653{
654 elm_map_wheel_disabled_set(data, EINA_FALSE);
655}
656
657static void
658_zoom_min_set(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
659{
660 elm_map_zoom_min_set(data, 1);
661}
662
663static void
664_zoom_max_set(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
665{
666 elm_map_zoom_max_set(data, 10);
667}
668
669static void
670_line_add(void *data, Evas_Object *obj EINA_UNUSED, void *ei EINA_UNUSED)
671{
672 double lon, lat;
673
674 elm_map_canvas_to_region_convert(data, down_x, down_y, &lon, &lat);
675 printf("line marker: %d %d %lf %lf\n", down_x, down_y, lon, lat);
676 if (line_start && line_end)
677 {
678 elm_map_overlay_del(line_start);
679 elm_map_overlay_del(line_end);
680 elm_map_overlay_del(line);
681 line_start = NULL;
682 line_end = NULL;
683 line = NULL;
684 }
685 if (!line_start) line_start = elm_map_overlay_add(data, lon, lat);
686 else if (!line_end) line_end = elm_map_overlay_add(data, lon, lat);
687
688 if (line_start && line_end)
689 {
690 double flon, flat, tlon, tlat;
691 elm_map_overlay_region_get(line_start, &flon, &flat);
692 elm_map_overlay_region_get(line_end, &tlon, &tlat);
693 line = elm_map_overlay_line_add(data, flon, flat, tlon, tlat);
694 printf("line add: (%lf, %lf) --> (%lf, %lf)\n", flon, flat, tlon, tlat);
695 }
696}
697
698static void
699_poly_add(void *data, Evas_Object *obj EINA_UNUSED, void *ei EINA_UNUSED)
700{
701 double lon, lat;
702
703 elm_map_canvas_to_region_convert(data, down_x, down_y, &lon, &lat);
704 printf("%d %d %lf %lf\n", down_x, down_y, lon, lat);
705
706 if (!poly) poly = elm_map_overlay_polygon_add(data);
707 poly_points = eina_list_append(poly_points,
708 elm_map_overlay_add(data, lon, lat));
709 elm_map_overlay_polygon_region_add(poly, lon, lat);
710}
711
712static void
713_poly_clear(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ei EINA_UNUSED)
714{
715 Elm_Map_Overlay *ovl;
716 if (poly) elm_map_overlay_del(poly);
717 EINA_LIST_FREE(poly_points, ovl) elm_map_overlay_del(ovl);
718 poly = NULL;
719 poly_points = NULL;
720}
721
722static void
723_circle_add(void *data, Evas_Object *obj EINA_UNUSED, void *ei EINA_UNUSED)
724{
725 double radius = 100;
726 double lon, lat;
727
728 if (circle) elm_map_overlay_del(circle);
729 elm_map_canvas_to_region_convert(data, down_x, down_y, &lon, &lat);
730 circle = elm_map_overlay_circle_add(data, lon, lat, radius);
731}
732
733static void
734_scale_add(void *data, Evas_Object *obj EINA_UNUSED, void *ei EINA_UNUSED)
735{
736 if (scale) elm_map_overlay_del(scale);
737 scale = elm_map_overlay_scale_add(data, down_x, down_y);
738}
739
740static void
741_submenu_src_add(void *data, Elm_Object_Item *parent)
742{
743 int idx;
744 const char **tile_srcs;
745 const char **route_srcs;
746 const char **name_srcs;
747
748 if ((!data) || (!parent)) return;
749
750 tile_srcs = elm_map_sources_get(data, ELM_MAP_SOURCE_TYPE_TILE);
751 route_srcs = elm_map_sources_get(data, ELM_MAP_SOURCE_TYPE_ROUTE);
752 name_srcs = elm_map_sources_get(data, ELM_MAP_SOURCE_TYPE_NAME);
753
754 for (idx = 0; tile_srcs[idx]; idx++)
755 {
756 if (idx >= SOURCE_MAX) break;
757 ts[idx].map = data;
758 ts[idx].type = ELM_MAP_SOURCE_TYPE_TILE;
759 ts[idx].source_name = strdup(tile_srcs[idx]);
760 elm_menu_item_add(menu, parent, "", tile_srcs[idx], _src_set, &ts[idx]);
761 }
762 for (idx = 0; route_srcs[idx]; idx++)
763 {
764 if (idx >= SOURCE_MAX) break;
765 rs[idx].map = data;
766 rs[idx].type = ELM_MAP_SOURCE_TYPE_ROUTE;
767 rs[idx].source_name = strdup(route_srcs[idx]);
768 elm_menu_item_add(menu, parent, "", route_srcs[idx], _src_set, &rs[idx]);
769 }
770 for (idx = 0; name_srcs[idx]; idx++)
771 {
772 if (idx >= SOURCE_MAX) break;
773 ns[idx].map = data;
774 ns[idx].type = ELM_MAP_SOURCE_TYPE_NAME;
775 ns[idx].source_name = strdup(name_srcs[idx]);
776 elm_menu_item_add(menu, parent, "", name_srcs[idx], _src_set, &ns[idx]);
777 }
778}
779
780static void
781_submenu_move_add(void *data, Elm_Object_Item *parent)
782{
783 if ((!data) || (!parent)) return;
784 elm_menu_item_add(menu, parent, NULL, "Show Urmatt", _show_urmatt, data);
785 elm_menu_item_add(menu, parent, NULL, "Bring Seoul", _bring_seoul, data);
786 elm_menu_item_add(menu, parent, NULL, "Zoom & Bring Suwon", _bring_zoom_suwon, data);
787
788}
789
790static void
791_submenu_zoom_add(void *data, Elm_Object_Item *parent)
792{
793 if ((!data) || (!parent)) return;
794 elm_menu_item_add(menu, parent, NULL, "Zoom +", _zoom_in, data);
795 elm_menu_item_add(menu, parent, NULL, "Zoom -", _zoom_out, data);
796 elm_menu_item_add(menu, parent, NULL, "Zoom Fit", _zoom_fit, data);
797 elm_menu_item_add(menu, parent, NULL, "Zoom Fill", _zoom_fill, data);
798 elm_menu_item_add(menu, parent, NULL, "Zoom Manual", _zoom_manual, data);
799 elm_menu_item_add(menu, parent, NULL, "Zoom Min to 1", _zoom_min_set, data);
800 elm_menu_item_add(menu, parent, NULL, "Zoom Max to 10", _zoom_max_set, data);
801}
802
803static void
804_submenu_prop_add(void *data, Elm_Object_Item *parent)
805{
806 if ((!data) || (!parent)) return;
807 elm_menu_item_add(menu, parent, NULL, "Paused Set", _paused_set, data);
808 elm_menu_item_add(menu, parent, NULL, "Paused Unset", _paused_unset, data);
809 elm_menu_item_add(menu, parent, NULL, "Rotate CW", _rotate_cw, data);
810 elm_menu_item_add(menu, parent, NULL, "Rotate CCW", _rotate_ccw, data);
811 elm_menu_item_add(menu, parent, NULL, "Reset Rotate", _rotate_reset, data);
812 elm_menu_item_add(menu, parent, NULL, "Disable Wheel", _wheel_disable, data);
813 elm_menu_item_add(menu, parent, NULL, "Enable Wheel", _wheel_enable, data);
814}
815
816static void
817_submenu_track_add(void *data, Elm_Object_Item *parent)
818{
819 if ((!data) || (!parent)) return;
820 elm_menu_item_add(menu, parent, NULL, "Add Track", _track_add, data);
821 elm_menu_item_add(menu, parent, NULL, "Remove Track", _track_remove, data);
822}
823
824static void
825_submenu_ovl_add(void *data, Elm_Object_Item *parent)
826{
827 if ((!data) || (!parent)) return;
828 elm_menu_item_add(menu, parent, NULL, "Add line", _line_add, data);
829 elm_menu_item_add(menu, parent, NULL, "Add polygon", _poly_add, data);
830 elm_menu_item_add(menu, parent, NULL, "Clear polygon", _poly_clear, data);
831 elm_menu_item_add(menu, parent, NULL, "Add circle", _circle_add, data);
832 elm_menu_item_add(menu, parent, NULL, "Add scale", _scale_add, data);
833}
834
835static void
836_submenu_info_add(Evas_Object *map, Elm_Object_Item *parent)
837{
838 if (!map || !parent) return;
839 char buf[PATH_MAX] = { 0 };
840 double lon = 0.0, lat = 0.0;
841
842 elm_map_canvas_to_region_convert(map,
843 down_x, down_y,
844 &lon, &lat);
845
846 snprintf(buf, PATH_MAX, "Longitude : %f", lon);
847 elm_menu_item_add(menu, parent, NULL, buf, NULL, NULL);
848
849 snprintf(buf, PATH_MAX, "Latitude : %f", lat);
850 elm_menu_item_add(menu, parent, NULL, buf, NULL, NULL);
851}
852
853static void
854_map_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event_info)
855{
856 Evas_Event_Mouse_Down *ev = event_info;
857 Elm_Object_Item *menu_it;
858 static Elm_Object_Item *info_it = NULL;
859
860 if (!ev) return;
861
862 if (ev->button == 2)
863 {
864 old_x = ev->canvas.x;
865 old_y = ev->canvas.y;
866 old_d = 0.0;
867 }
868 else if (ev->button == 3)
869 {
870 down_x = ev->canvas.x;
871 down_y = ev->canvas.y;
872 if (!menu)
873 {
874 menu = elm_menu_add(obj);
875 elm_menu_parent_set(menu, obj);
876 menu_it = elm_menu_item_add(menu, NULL, "", "Source", NULL, NULL);
877 _submenu_src_add(data, menu_it);
878 menu_it = elm_menu_item_add(menu, NULL, "", "Move", NULL, NULL);
879 _submenu_move_add(data, menu_it);
880 menu_it = elm_menu_item_add(menu, NULL, "", "Zoom", NULL, NULL);
881 _submenu_zoom_add(data, menu_it);
882 menu_it = elm_menu_item_add(menu, NULL, "", "Prop", NULL, NULL);
883 _submenu_prop_add(data, menu_it);
884 menu_it = elm_menu_item_add(menu, NULL, "", "Track", NULL, NULL);
885 _submenu_track_add(data, menu_it);
886 menu_it = elm_menu_item_add(menu, NULL, "", "Overlay", NULL, NULL);
887 _submenu_ovl_add(data, menu_it);
888
889 info_it = elm_menu_item_add(menu, NULL, "", "Info", NULL, NULL);
890 }
891
892 elm_menu_item_subitems_clear(info_it);
893 _submenu_info_add(obj, info_it);
894
895 elm_menu_move(menu, ev->canvas.x, ev->canvas.y);
896 evas_object_show(menu);
897 }
898}
899
900static void
901_map_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
902{
903 Evas_Event_Mouse_Move *move = event_info;
904 Evas_Coord x, y, w, h;
905 float half_w, half_h;
906 int d, d_diff;
907 double cur_d;
908 if (!move) return;
909
910 if (move->buttons == 2)
911 {
912 evas_object_geometry_get(data, &x, &y, &w, &h);
913 half_w = (float)w * 0.5;
914 half_h = (float)h * 0.5;
915 elm_map_rotate_get(data, &cur_d, NULL, NULL);
916
917 d = move->cur.canvas.x - old_x;
918 if (!old_d) old_d = d;
919 else
920 {
921 d_diff = old_d - d;
922 if (d_diff > 0)
923 {
924 old_d --;
925 cur_d += 1.0;
926 }
927 else if (d_diff < 0)
928 {
929 old_d ++;
930 cur_d -= 1.0;
931 }
932 old_d = d;
933 elm_map_rotate_set(data, cur_d, x + half_w, y + half_h);
934 }
935 }
936}
937
938static void
939_map_mouse_up(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
940{
941 Evas_Event_Mouse_Up *up = event_info;
942 if (!up) return;
943
944 if (up->button == 2)
945 {
946 old_x = 0;
947 old_y = 0;
948 }
949}
950
951static void
952_overlay_cb(void *data EINA_UNUSED, Evas_Object *map, void *ev)
953{
954 printf("Overlay clicked: ");
955 Elm_Map_Overlay *overlay = ev;
956 Overlay_Data *od;
957 Elm_Map_Overlay_Type type = elm_map_overlay_type_get(overlay);
958
959 if (type != ELM_MAP_OVERLAY_TYPE_GROUP &&
960 type != ELM_MAP_OVERLAY_TYPE_DEFAULT) return;
961
962 if (!bubble_img) bubble_img = elm_map_overlay_bubble_add(map);
963 elm_map_overlay_bubble_follow(bubble_img, overlay);
964 elm_map_overlay_bubble_content_clear(bubble_img);
965
966 if (type == ELM_MAP_OVERLAY_TYPE_GROUP)
967 {
968 Eina_List *l;
969 Elm_Map_Overlay *memb;
970 Eina_List *members = elm_map_overlay_group_members_get(overlay);
971 printf("Group Members Num: %d\n", eina_list_count(members));
972 EINA_LIST_FOREACH(members, l, memb)
973 {
974 od = elm_map_overlay_data_get(memb);
975 if (od)
976 elm_map_overlay_bubble_content_append(bubble_img,
977 _box_get(map, od, memb));
978 }
979 elm_map_overlay_bubble_content_append(bubble_img,
980 _btn_get(map, overlay));
981 }
982 else
983 {
984 od = elm_map_overlay_data_get(overlay);
985 if (od)
986 elm_map_overlay_bubble_content_append(bubble_img,
987 _box_get(map, od, overlay));
988 elm_map_overlay_bubble_content_append(bubble_img,
989 _btn_box_get(map, overlay));
990 }
991}
992
993static void
994_parking_cb(void *data EINA_UNUSED, Evas_Object *map, Elm_Map_Overlay *ovl)
995{
996 double lon, lat;
997 Evas_Coord x, y;
998 elm_map_overlay_region_get(ovl, &lon, &lat);
999 elm_map_region_to_canvas_convert(map, lon, lat, &x, &y);
1000 printf("Parking clicked: %lf %lf %d %d\n", lon, lat, x, y);
1001
1002 elm_map_canvas_to_region_convert(map, x+40, y+50, &lon, &lat);
1003 if (!bubble_parking)
1004 {
1005 Evas_Object *bubble, *label;
1006 bubble = elm_bubble_add(map);
1007 elm_bubble_pos_set(bubble, ELM_BUBBLE_POS_TOP_LEFT);
1008 elm_object_text_set(bubble, "Overlay object");
1009 elm_object_part_text_set(bubble, "info", "Bubble is overlayed");
1010
1011 label = elm_label_add(bubble);
1012 elm_object_text_set(label, "Parking Here !!");
1013 evas_object_show(label);
1014 elm_object_content_set(bubble, label);
1015
1016 evas_object_resize(bubble, 125, 50);
1017 evas_object_show(bubble);
1018
1019 bubble_parking = elm_map_overlay_add(map, lon, lat);
1020 elm_map_overlay_content_set(bubble_parking, bubble);
1021 }
1022 else elm_map_overlay_region_set(bubble_parking, lon, lat);
1023 elm_map_overlay_data_set(bubble_parking, ovl);
1024}
1025
1026static void
1027_del_map(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ei EINA_UNUSED)
1028{
1029 if (route_start) elm_map_overlay_del(route_start);
1030 if (route_end) elm_map_overlay_del(route_end);
1031 if (route_clas) elm_map_overlay_del(route_clas);
1032 if (bubble_img) elm_map_overlay_del(bubble_img);
1033 if (bubble_parking) elm_map_overlay_del(bubble_parking);
1034 if (route_ovl) elm_map_overlay_del(route_ovl);
1035 route_start = NULL;
1036 route_end = NULL;
1037 route_clas = NULL;
1038 bubble_img = NULL;
1039 bubble_parking = NULL;
1040 route_ovl = NULL;
1041
1042 if (route) elm_map_route_del(route);
1043 if (name) elm_map_name_del(name);
1044 if (menu) evas_object_del(menu);
1045 route = NULL;
1046 name = NULL;
1047 menu = NULL;
1048}
1049
1050void
1051test_map(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1052{
1053 Evas_Object *win, *map;
1054 int idx = 0;
1055 const char **tile_srcs;
1056 const char **route_srcs;
1057 const char **name_srcs;
1058 Overlay_Data data1;
1059 Overlay_Data data2;
1060 Overlay_Data data3;
1061 Overlay_Data data4;
1062 Overlay_Data data5;
1063 Overlay_Data data6;
1064 Overlay_Data data7;
1065 Overlay_Data data8;
1066 Overlay_Data data9;
1067 Overlay_Data data10;
1068 Overlay_Data data11;
1069 Overlay_Data parking;
1070 Overlay_Data icon_data;
1071
1072 snprintf(data1.file, PATH_MAX, "%s/images/logo.png", elm_app_data_dir_get());
1073 snprintf(data2.file, PATH_MAX, "%s/images/logo_small.png", elm_app_data_dir_get());
1074 snprintf(data3.file, PATH_MAX, "%s/images/panel_01.png", elm_app_data_dir_get());
1075 snprintf(data4.file, PATH_MAX, "%s/images/plant_01.png", elm_app_data_dir_get());
1076 snprintf(data5.file, PATH_MAX, "%s/images/rock_01.png", elm_app_data_dir_get());
1077 snprintf(data6.file, PATH_MAX, "%s/images/rock_02.png", elm_app_data_dir_get());
1078 snprintf(data7.file, PATH_MAX, "%s/images/sky_01.png", elm_app_data_dir_get());
1079 snprintf(data8.file, PATH_MAX, "%s/images/sky_02.png", elm_app_data_dir_get());
1080 snprintf(data9.file, PATH_MAX, "%s/images/sky_03.png", elm_app_data_dir_get());
1081 snprintf(data10.file, PATH_MAX, "%s/images/sky_03.png", elm_app_data_dir_get());
1082 snprintf(data11.file, PATH_MAX, "%s/images/wood_01.png", elm_app_data_dir_get());
1083 snprintf(parking.file, PATH_MAX, "%s/images/parking.png", elm_app_data_dir_get());
1084 snprintf(icon_data.file, PATH_MAX, "%s/images/icon_14.png", elm_app_data_dir_get());
1085
1086 win = elm_win_util_standard_add("map", "Map");
1087 elm_win_autodel_set(win, EINA_TRUE);
1088
1089 map = elm_map_add(win);
1090 if (map)
1091 {
1092 Elm_Map_Overlay *ovl_1, *ovl_2, *ovl_3, *ovl_4, *ovl_5, *ovl_6;
1093 Elm_Map_Overlay *ovl_7, *ovl_8, *ovl_9, *ovl_10, *ovl_11;
1094 Elm_Map_Overlay *parking1, *parking2, *parking3, *parking4, *parking5;
1095 Elm_Map_Overlay *grp1, *grp2, *grp_parking;
1096
1097 evas_object_event_callback_add(map, EVAS_CALLBACK_DEL, _del_map, NULL);
1098
1099 tile_srcs = elm_map_sources_get(map, ELM_MAP_SOURCE_TYPE_TILE);
1100 route_srcs = elm_map_sources_get(map, ELM_MAP_SOURCE_TYPE_ROUTE);
1101 name_srcs = elm_map_sources_get(map, ELM_MAP_SOURCE_TYPE_NAME);
1102
1103 if (!tile_srcs) return;
1104 printf("Tile sources [ ");
1105 for (idx = 0; tile_srcs[idx] ; idx++) printf("%s, ", tile_srcs[idx]);
1106 printf("]\n");
1107 if (!route_srcs) return;
1108 printf("Route sources [ ");
1109 for (idx = 0; route_srcs[idx] ; idx++) printf("%s, ", route_srcs[idx]);
1110 printf("]\n");
1111 if (!name_srcs) return;
1112 printf("Name sources [ ");
1113 for (idx = 0; name_srcs[idx] ; idx++) printf("%s, ", name_srcs[idx]);
1114 printf("]\n");
1115
1116 evas_object_size_hint_weight_set(map, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1117 elm_win_resize_object_add(win, map);
1118 evas_object_data_set(map, "window", win);
1119
1120 evas_object_event_callback_add(map, EVAS_CALLBACK_MOUSE_DOWN,
1121 _map_mouse_down, map);
1122 evas_object_event_callback_add(map, EVAS_CALLBACK_MOUSE_MOVE,
1123 _map_mouse_move, map);
1124 evas_object_event_callback_add(map, EVAS_CALLBACK_MOUSE_UP,
1125 _map_mouse_up, map);
1126
1127 evas_object_smart_callback_add(map, "clicked", _map_clicked, map);
1128 evas_object_smart_callback_add(map, "clicked,double", _map_clicked_double, map);
1129 evas_object_smart_callback_add(map, "press", _map_press, map);
1130 evas_object_smart_callback_add(map, "longpressed", _map_longpressed, map);
1131 evas_object_smart_callback_add(map, "scroll", _map_scroll, map);
1132 evas_object_smart_callback_add(map, "scroll,drag,start", _map_drag_start, map);
1133 evas_object_smart_callback_add(map, "scroll,drag,stop", _map_drag_stop, map);
1134 evas_object_smart_callback_add(map, "scroll,anim,start", _map_anim_start, map);
1135 evas_object_smart_callback_add(map, "scroll,anim,stop", _map_anim_stop, map);
1136 evas_object_smart_callback_add(map, "zoom,start", _map_zoom_start, map);
1137 evas_object_smart_callback_add(map, "zoom,stop", _map_zoom_stop, map);
1138 evas_object_smart_callback_add(map, "zoom,change", _map_zoom_change, map);
1139 evas_object_smart_callback_add(map, "loaded", _map_loaded, map);
1140 evas_object_smart_callback_add(map, "tile,load", _map_tile_load, map);
1141 evas_object_smart_callback_add(map, "tile,loaded", _map_tile_loaded, map);
1142 evas_object_smart_callback_add(map, "tile,loaded,fail", _map_tile_loaded_fail, map);
1143 evas_object_smart_callback_add(map, "route,load", _map_route_load, map);
1144 evas_object_smart_callback_add(map, "route,loaded", _map_route_loaded, map);
1145 evas_object_smart_callback_add(map, "route,loaded,fail", _map_route_loaded_fail, map);
1146 evas_object_smart_callback_add(map, "name,load", _map_name_load, map);
1147 evas_object_smart_callback_add(map, "name,loaded", _map_name_loaded, map);
1148 evas_object_smart_callback_add(map, "name,loaded,fail", _map_name_loaded_fail, map);
1149 evas_object_smart_callback_add(map, "overlay,clicked", _overlay_cb, map);
1150
1151 // Create Overlays
1152 ovl_1 = elm_map_overlay_add(map, 2.352, 48.857);
1153 elm_map_overlay_color_set(ovl_1, 0x00, 0xfa, 0x9a, 0xff);
1154 elm_map_overlay_displayed_zoom_min_set(ovl_1, 5);
1155 ovl_2 = elm_map_overlay_add(map, 3, 48.857);
1156 elm_map_overlay_color_set(ovl_2, 0xff, 0xd7, 0x00, 0xff);
1157 elm_map_overlay_displayed_zoom_min_set(ovl_2, 4);
1158 ovl_3 = elm_map_overlay_add(map, 2.352, 49);
1159 elm_map_overlay_displayed_zoom_min_set(ovl_3, 3);
1160 ovl_4 = elm_map_overlay_add(map, 7.31451, 48.857127);
1161 ovl_5 = elm_map_overlay_add(map, 7.314704, 48.857119);
1162 ovl_6 = elm_map_overlay_add(map, 7.31432, 48.856785);
1163 ovl_7 = elm_map_overlay_add(map, 7.3148, 48.85725);
1164 ovl_8 = elm_map_overlay_add(map, 7.316445, 48.8572210000694);
1165 ovl_9 = elm_map_overlay_add(map, 7.316527000125, 48.85609);
1166 ovl_10 = elm_map_overlay_add(map, 7.3165409990833, 48.856078);
1167 ovl_11 = elm_map_overlay_add(map, 7.319812, 48.856561);
1168 elm_map_overlay_data_set(ovl_1, &data1);
1169 elm_map_overlay_data_set(ovl_2, &data2);
1170 elm_map_overlay_data_set(ovl_3, &data3);
1171 elm_map_overlay_data_set(ovl_4, &data4);
1172 elm_map_overlay_data_set(ovl_5, &data5);
1173 elm_map_overlay_data_set(ovl_6, &data6);
1174 elm_map_overlay_data_set(ovl_7, &data7);
1175 elm_map_overlay_data_set(ovl_8, &data8);
1176 elm_map_overlay_data_set(ovl_9, &data9);
1177 elm_map_overlay_data_set(ovl_10, &data10);
1178 elm_map_overlay_data_set(ovl_11, &data11);
1179
1180 // Append overlays to groups
1181 grp1 = elm_map_overlay_class_add(map);
1182 elm_map_overlay_class_zoom_max_set(grp1, 6);
1183 elm_map_overlay_class_append(grp1, ovl_1);
1184 elm_map_overlay_class_append(grp1, ovl_2);
1185 elm_map_overlay_class_append(grp1, ovl_3);
1186 elm_map_overlay_class_append(grp1, ovl_4);
1187 elm_map_overlay_class_append(grp1, ovl_5);
1188 elm_map_overlay_class_append(grp1, ovl_6);
1189
1190 // Append overlays to groups
1191 grp2 = elm_map_overlay_class_add(map);
1192 elm_map_overlay_displayed_zoom_min_set(grp2, 9);
1193 elm_map_overlay_class_append(grp2, ovl_7);
1194 elm_map_overlay_class_append(grp2, ovl_8);
1195 elm_map_overlay_class_append(grp2, ovl_9);
1196 elm_map_overlay_class_append(grp2, ovl_10);
1197 elm_map_overlay_class_append(grp2, ovl_11);
1198
1199 // Create overlays
1200 parking1 = elm_map_overlay_add(map, 127.04871, 37.25730);
1201 parking2 = elm_map_overlay_add(map, 127.05578, 37.25545);
1202 parking3 = elm_map_overlay_add(map, 127.05515, 37.25439);
1203 parking4 = elm_map_overlay_add(map, 127.05328, 37.25721);
1204 elm_map_overlay_icon_set(parking4, _icon_get(map, &icon_data));
1205 parking5 = elm_map_overlay_add(map, 127.05431, 37.25873);
1206 elm_map_overlay_content_set(parking5, _label_get(map));
1207 elm_map_overlay_get_cb_set(parking1, _parking_cb, NULL);
1208 elm_map_overlay_get_cb_set(parking2, _parking_cb, NULL);
1209 elm_map_overlay_get_cb_set(parking3, _parking_cb, NULL);
1210 elm_map_overlay_get_cb_set(parking4, _parking_cb, NULL);
1211 elm_map_overlay_get_cb_set(parking5, _parking_cb, NULL);
1212
1213 // Append overlays to groups
1214 grp_parking = elm_map_overlay_class_add(map);
1215 elm_map_overlay_icon_set(grp_parking, _icon_get(map, &parking));
1216 elm_map_overlay_get_cb_set(grp_parking, _parking_cb, NULL);
1217 elm_map_overlay_class_append(grp_parking, parking1);
1218 elm_map_overlay_class_append(grp_parking, parking2);
1219 elm_map_overlay_class_append(grp_parking, parking3);
1220 elm_map_overlay_class_append(grp_parking, parking4);
1221 elm_map_overlay_class_append(grp_parking, parking5);
1222
1223 evas_object_show(map);
1224 }
1225
1226 evas_object_resize(win, 800, 800);
1227 evas_object_show(win);
1228}
diff --git a/src/generic/evas/pdf/main.cpp b/src/generic/evas/pdf/main.cpp
index 5c70bfef21..253b3f3ebf 100644
--- a/src/generic/evas/pdf/main.cpp
+++ b/src/generic/evas/pdf/main.cpp
@@ -283,7 +283,7 @@ main(int argc, char **argv)
283 // This is a funny hack to call an external tool to generate a pdf that will then be processed by poppler 283 // This is a funny hack to call an external tool to generate a pdf that will then be processed by poppler
284 extension = strrchr(file, '.'); 284 extension = strrchr(file, '.');
285 dir = dirname(argv[0]); 285 dir = dirname(argv[0]);
286 if (extension && dir && strcmp(extension, ".pdf")) 286 if (extension && dir && (!(!strcasecmp(extension, ".pdf"))))
287 { 287 {
288#ifndef _WIN32 288#ifndef _WIN32
289 signal(SIGSEGV, _crash); 289 signal(SIGSEGV, _crash);
@@ -348,8 +348,8 @@ main(int argc, char **argv)
348 D("poppler_file_init\n"); 348 D("poppler_file_init\n");
349 if (!poppler_init(file, page_num, size_w, size_h)) 349 if (!poppler_init(file, page_num, size_w, size_h))
350 { 350 {
351 goto cleanup;
352 ret = 1; 351 ret = 1;
352 goto cleanup;
353 } 353 }
354 D("poppler_file_init done\n"); 354 D("poppler_file_init done\n");
355 355
diff --git a/src/generic/evas/rsvg/main.c b/src/generic/evas/rsvg/main.c
index 1eaf2a32c7..e6389b7afc 100644
--- a/src/generic/evas/rsvg/main.c
+++ b/src/generic/evas/rsvg/main.c
@@ -23,7 +23,8 @@ static int width = 0;
23static int height = 0; 23static int height = 0;
24static RsvgDimensionData dim; 24static RsvgDimensionData dim;
25 25
26static inline Eina_Bool evas_image_load_file_is_svg(const char *file) 26static inline Eina_Bool
27evas_image_load_file_is_svg(const char *file)
27{ 28{
28 int i, len = strlen(file); 29 int i, len = strlen(file);
29 Eina_Bool is_gz = EINA_FALSE; 30 Eina_Bool is_gz = EINA_FALSE;
@@ -97,9 +98,18 @@ static int
97read_svg_header(int scale_down, double dpi, int size_w, int size_h) 98read_svg_header(int scale_down, double dpi, int size_w, int size_h)
98{ 99{
99 rsvg_handle_set_dpi(rsvg, 75.0); 100 rsvg_handle_set_dpi(rsvg, 75.0);
101
102#ifndef HAVE_SVG_2_51
100 rsvg_handle_get_dimensions(rsvg, &dim); 103 rsvg_handle_get_dimensions(rsvg, &dim);
101 width = dim.width; 104 width = dim.width;
102 height = dim.height; 105 height = dim.height;
106#else
107 double owidth, oheight;
108
109 rsvg_handle_get_intrinsic_size_in_pixels(rsvg, &owidth, &oheight);
110 width = ceil(owidth);
111 height = ceil(oheight);
112#endif
103 113
104 if ((width < 1) || (height < 1)) return 0; 114 if ((width < 1) || (height < 1)) return 0;
105 115
@@ -151,14 +161,29 @@ read_svg_data(void)
151 if (!cr) return 0; 161 if (!cr) return 0;
152 162
153 cairo_scale(cr, (double) width / dim.em, (double) height / dim.ex); 163 cairo_scale(cr, (double) width / dim.em, (double) height / dim.ex);
164
165#ifndef HAVE_SVG_2_51
154 rsvg_handle_render_cairo(rsvg, cr); 166 rsvg_handle_render_cairo(rsvg, cr);
167#else
168 RsvgRectangle vp =
169 {
170 .x = 0,
171 .y = 0,
172 .width = width,
173 .height = height,
174 };
175
176 rsvg_handle_render_document(rsvg, cr, &vp, NULL);
177#endif
178
155 cairo_surface_destroy(surface); 179 cairo_surface_destroy(surface);
156 cairo_destroy(cr); 180 cairo_destroy(cr);
157 181
158 return 1; 182 return 1;
159} 183}
160 184
161int main(int argc, char **argv) 185int
186main(int argc, char **argv)
162{ 187{
163 char *file; 188 char *file;
164 int i; 189 int i;
@@ -236,6 +261,5 @@ int main(int argc, char **argv)
236 _svg_shutdown(); 261 _svg_shutdown();
237 fflush(stdout); 262 fflush(stdout);
238 return 0; 263 return 0;
239
240} 264}
241 265
diff --git a/src/generic/evas/rsvg/meson.build b/src/generic/evas/rsvg/meson.build
index a0c5ea12ce..64ae1a2edd 100644
--- a/src/generic/evas/rsvg/meson.build
+++ b/src/generic/evas/rsvg/meson.build
@@ -8,5 +8,10 @@ if rsvg.version() >= '2.36.0'
8 config_h.set('HAVE_SVG_2_36', '1') 8 config_h.set('HAVE_SVG_2_36', '1')
9endif 9endif
10 10
11# Needed for rsvg_handle_get_intrinsic_size_in_pixels
12if rsvg.version() >= '2.51.0'
13 config_h.set('HAVE_SVG_2_51', '1')
14endif
15
11generic_deps = [rsvg] 16generic_deps = [rsvg]
12generic_support = ['svg', 'svgz', 'svg.gz'] 17generic_support = ['svg', 'svgz', 'svg.gz']
diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h
index 8eb235b5fb..9dced7f381 100644
--- a/src/lib/ecore_x/Ecore_X.h
+++ b/src/lib/ecore_x/Ecore_X.h
@@ -2166,6 +2166,7 @@ EAPI void ecore_x_randr_events_select(Ecore
2166EAPI void ecore_x_randr_screen_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm); 2166EAPI void ecore_x_randr_screen_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm);
2167EAPI void ecore_x_randr_screen_size_range_get(Ecore_X_Window root, int *wmin, int *hmin, int *wmax, int *hmax); 2167EAPI void ecore_x_randr_screen_size_range_get(Ecore_X_Window root, int *wmin, int *hmin, int *wmax, int *hmax);
2168EAPI void ecore_x_randr_screen_reset(Ecore_X_Window root); 2168EAPI void ecore_x_randr_screen_reset(Ecore_X_Window root);
2169EAPI void ecore_x_randr_screen_refresh(Ecore_X_Window root); /**< @since 1.26 */
2169EAPI Eina_Bool ecore_x_randr_screen_current_size_set(Ecore_X_Window root, int w, int h, int w_mm, int h_mm); 2170EAPI Eina_Bool ecore_x_randr_screen_current_size_set(Ecore_X_Window root, int w, int h, int w_mm, int h_mm);
2170EAPI Ecore_X_Randr_Mode_Info **ecore_x_randr_modes_info_get(Ecore_X_Window root, int *num); 2171EAPI Ecore_X_Randr_Mode_Info **ecore_x_randr_modes_info_get(Ecore_X_Window root, int *num);
2171EAPI Ecore_X_Randr_Mode ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info); 2172EAPI Ecore_X_Randr_Mode ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info);
diff --git a/src/lib/ecore_x/ecore_x_randr.c b/src/lib/ecore_x/ecore_x_randr.c
index faab344eb5..bd1ef23427 100644
--- a/src/lib/ecore_x/ecore_x_randr.c
+++ b/src/lib/ecore_x/ecore_x_randr.c
@@ -44,7 +44,14 @@ typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio_Preferred
44 44
45static int _randr_major, _randr_minor, _randr_version; 45static int _randr_major, _randr_minor, _randr_version;
46 46
47XRRScreenResources *(*_ecore_x_randr_screen_resources_get)(Display *disp, Window win); 47static XRRScreenResources *
48_ecore_x_randr_screen_resources_get_dummy(Display *disp EINA_UNUSED, Window win EINA_UNUSED)
49{
50 return NULL;
51}
52
53XRRScreenResources *(*_ecore_x_randr_screen_resources_get)(Display *disp, Window win) = _ecore_x_randr_screen_resources_get_dummy;
54XRRScreenResources *(*_ecore_x_randr_screen_resources_get_slow)(Display *disp, Window win) = _ecore_x_randr_screen_resources_get_dummy;
48 55
49#endif 56#endif
50 57
@@ -63,9 +70,15 @@ _ecore_x_randr_init(void)
63 _randr_version = (_randr_major << 16) | _randr_minor; 70 _randr_version = (_randr_major << 16) | _randr_minor;
64 71
65 if (_randr_version >= RANDR_VERSION_1_3) 72 if (_randr_version >= RANDR_VERSION_1_3)
66 _ecore_x_randr_screen_resources_get = XRRGetScreenResourcesCurrent; 73 {
74 _ecore_x_randr_screen_resources_get = XRRGetScreenResourcesCurrent;
75 _ecore_x_randr_screen_resources_get_slow = XRRGetScreenResources;
76 }
67 else if (_randr_version == RANDR_VERSION_1_2) 77 else if (_randr_version == RANDR_VERSION_1_2)
68 _ecore_x_randr_screen_resources_get = XRRGetScreenResources; 78 {
79 _ecore_x_randr_screen_resources_get = XRRGetScreenResources;
80 _ecore_x_randr_screen_resources_get_slow = XRRGetScreenResources;
81 }
69 82
70 _randr_avail = EINA_TRUE; 83 _randr_avail = EINA_TRUE;
71 84
@@ -539,6 +552,22 @@ ecore_x_randr_screen_size_range_get(Ecore_X_Window root, int *wmin, int *hmin, i
539} 552}
540 553
541/** 554/**
555 * @brief forces a hardware monitor info etc. refresh on the server side
556 * @param root the window's screen which will be reset.
557 */
558EAPI void
559ecore_x_randr_screen_refresh(Ecore_X_Window root)
560{
561 XRRScreenResources *res = NULL;
562
563 if (_randr_version < RANDR_VERSION_1_2) return;
564 if ((res = _ecore_x_randr_screen_resources_get_slow(_ecore_x_disp, root)))
565 {
566 XRRFreeScreenResources(res);
567 }
568}
569
570/**
542 * @brief removes unused screen space. The most upper left CRTC is set to 0x0 571 * @brief removes unused screen space. The most upper left CRTC is set to 0x0
543 * and all other CRTCs dx,dy respectively. 572 * and all other CRTCs dx,dy respectively.
544 * @param root the window's screen which will be reset. 573 * @param root the window's screen which will be reset.
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c
index 221e7b645d..7d66345955 100644
--- a/src/lib/edje/edje_calc.c
+++ b/src/lib/edje/edje_calc.c
@@ -2560,7 +2560,7 @@ _edje_part_recalc_single_filter(Edje *ed,
2560 if (r && (r[1] == ')') && (r[2] == '\0')) 2560 if (r && (r[1] == ')') && (r[2] == '\0'))
2561 { 2561 {
2562 *r = '\0'; 2562 *r = '\0';
2563 cc = _edje_color_class_find(ed, ccname); 2563 cc = _edje_color_class_recursive_find(ed, ccname);
2564 if (cc) 2564 if (cc)
2565 { 2565 {
2566 static const char fmt[] = 2566 static const char fmt[] =
diff --git a/src/lib/edje/edje_embryo.c b/src/lib/edje/edje_embryo.c
index bb3828ab3d..0b3c3b0dc7 100644
--- a/src/lib/edje/edje_embryo.c
+++ b/src/lib/edje/edje_embryo.c
@@ -1619,7 +1619,7 @@ _edje_embryo_fn_get_color_class(Embryo_Program *ep, Embryo_Cell *params)
1619 ed = embryo_program_data_get(ep); 1619 ed = embryo_program_data_get(ep);
1620 GETSTR(class, params[1]); 1620 GETSTR(class, params[1]);
1621 if (!class) return 0; 1621 if (!class) return 0;
1622 c_class = _edje_color_class_find(ed, class); 1622 c_class = _edje_color_class_recursive_find(ed, class);
1623 if (!c_class) return 0; 1623 if (!c_class) return 0;
1624 SETINT(c_class->r, params[2]); 1624 SETINT(c_class->r, params[2]);
1625 SETINT(c_class->g, params[3]); 1625 SETINT(c_class->g, params[3]);
diff --git a/src/lib/edje/edje_lua2.c b/src/lib/edje/edje_lua2.c
index 6032528815..28e6667fda 100644
--- a/src/lib/edje/edje_lua2.c
+++ b/src/lib/edje/edje_lua2.c
@@ -1458,7 +1458,7 @@ _elua_color_class(lua_State *L) // Stack usage [-(10|14), +(11|15), ?]
1458 edje_color_class_set(class, r, g, b, a, r, g, b, a, r, g, b, a); 1458 edje_color_class_set(class, r, g, b, a, r, g, b, a, r, g, b, a);
1459 } 1459 }
1460 1460
1461 c_class = _edje_color_class_find(ed, class); 1461 c_class = _edje_color_class_recursive_find(ed, class);
1462 if (!c_class) return 0; 1462 if (!c_class) return 0;
1463 1463
1464 _elua_ret(L, "%r %g %b %a", c_class->r, c_class->g, c_class->b, c_class->a); 1464 _elua_ret(L, "%r %g %b %a", c_class->r, c_class->g, c_class->b, c_class->a);
diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h
index c0e3f6c247..1d289123a7 100644
--- a/src/lib/edje/edje_private.h
+++ b/src/lib/edje/edje_private.h
@@ -2538,7 +2538,6 @@ _edje_part_recalc_single_textblock(FLOAT_T sc,
2538 2538
2539Edje_Real_Part *_edje_real_part_get(const Edje *ed, const char *part); 2539Edje_Real_Part *_edje_real_part_get(const Edje *ed, const char *part);
2540Edje_Real_Part *_edje_real_part_recursive_get(Edje **ed, const char *part); 2540Edje_Real_Part *_edje_real_part_recursive_get(Edje **ed, const char *part);
2541Edje_Color_Class *_edje_color_class_find(const Edje *ed, const char *color_class);
2542// The color_class has to be a pointer to an Eet owned string. 2541// The color_class has to be a pointer to an Eet owned string.
2543Edje_Color_Class *_edje_color_class_recursive_find(const Edje *ed, const char *color_class); 2542Edje_Color_Class *_edje_color_class_recursive_find(const Edje *ed, const char *color_class);
2544void _edje_color_class_on_del(Edje *ed, Edje_Part *ep); 2543void _edje_color_class_on_del(Edje *ed, Edje_Part *ep);
diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c
index 625898947d..82f245f356 100644
--- a/src/lib/edje/edje_util.c
+++ b/src/lib/edje/edje_util.c
@@ -840,7 +840,7 @@ _edje_color_class_active_iterator_next(Eina_Iterator *it, void **data)
840 It is being assumed that the color key are the same for all object here. 840 It is being assumed that the color key are the same for all object here.
841 This can some times not be the case, but for now we should be fine. 841 This can some times not be the case, but for now we should be fine.
842 */ 842 */
843 cc = _edje_color_class_find(ed, tuple->key); 843 cc = _edje_color_class_recursive_find(ed, tuple->key);
844 if (!cc) return EINA_FALSE; 844 if (!cc) return EINA_FALSE;
845 et->cc = *cc; 845 et->cc = *cc;
846 846
@@ -972,7 +972,7 @@ _efl_canvas_layout_efl_gfx_color_class_color_class_get(const Eo *obj EINA_UNUSED
972 if (!color_class) 972 if (!color_class)
973 cc = NULL; 973 cc = NULL;
974 else 974 else
975 cc = _edje_color_class_find(ed, color_class); 975 cc = _edje_color_class_recursive_find(ed, color_class);
976 976
977 return _edje_color_class_get_internal(cc, layer, r, g, b, a); 977 return _edje_color_class_get_internal(cc, layer, r, g, b, a);
978} 978}
@@ -986,7 +986,7 @@ edje_object_color_class_description_get(const Evas_Object *obj, const char *colo
986EOLIAN const char * 986EOLIAN const char *
987_efl_canvas_layout_efl_gfx_color_class_color_class_description_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *color_class) 987_efl_canvas_layout_efl_gfx_color_class_color_class_description_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *color_class)
988{ 988{
989 Edje_Color_Class *cc = _edje_color_class_find(ed, color_class); 989 Edje_Color_Class *cc = _edje_color_class_recursive_find(ed, color_class);
990 return cc ? cc->desc : NULL; 990 return cc ? cc->desc : NULL;
991} 991}
992 992
@@ -5812,7 +5812,6 @@ _edje_real_part_get(const Edje *ed, const char *part)
5812void * 5812void *
5813_edje_hash_find_helper(const Eina_Hash *hash, const char *key) 5813_edje_hash_find_helper(const Eina_Hash *hash, const char *key)
5814{ 5814{
5815 static const char *remember_key = NULL;
5816 void *data; 5815 void *data;
5817 int i, j; 5816 int i, j;
5818 char **tokens; 5817 char **tokens;
@@ -5822,20 +5821,6 @@ _edje_hash_find_helper(const Eina_Hash *hash, const char *key)
5822 if (data) 5821 if (data)
5823 return data; 5822 return data;
5824 5823
5825 // We only receive pointer from Eet files as key, we can
5826 // assume them constant over the life time of the program.
5827 if (remember_key == key)
5828 return NULL;
5829
5830 // It is usually faster to walk the string once to check
5831 // if there will be any tokens to process, that to allocate
5832 // an array, copy one token, and then just free it.
5833 if (strchr(key, '/') == NULL)
5834 {
5835 remember_key = key;
5836 return NULL;
5837 }
5838
5839 tokens = eina_str_split_full(key, "/", 0, &tokens_count); 5824 tokens = eina_str_split_full(key, "/", 0, &tokens_count);
5840 if ((tokens) && (tokens_count > 1)) 5825 if ((tokens) && (tokens_count > 1))
5841 { 5826 {
@@ -5843,15 +5828,15 @@ _edje_hash_find_helper(const Eina_Hash *hash, const char *key)
5843 5828
5844 buf = eina_strbuf_new(); 5829 buf = eina_strbuf_new();
5845 5830
5846 for (i = tokens_count - 2; i >= 0; i--) 5831 for (i = tokens_count - 1; i >= 0; i--)
5847 { 5832 {
5848 for (j = 0; j < i; j++) 5833 for (j = 0; j < i; j++)
5849 { 5834 {
5850 eina_strbuf_append(buf, tokens[j]); 5835 eina_strbuf_append(buf, tokens[j]);
5851 eina_strbuf_append(buf, "/"); 5836 eina_strbuf_append(buf, "/");
5852 } 5837 }
5853 eina_strbuf_append(buf, tokens[tokens_count - 1]); 5838 if (i == 0) eina_strbuf_append(buf, "/");
5854 5839 eina_strbuf_append(buf, tokens[i]);
5855 data = eina_hash_find(hash, eina_strbuf_string_get(buf)); 5840 data = eina_hash_find(hash, eina_strbuf_string_get(buf));
5856 if (data) break; 5841 if (data) break;
5857 5842
@@ -5860,10 +5845,6 @@ _edje_hash_find_helper(const Eina_Hash *hash, const char *key)
5860 5845
5861 eina_strbuf_free(buf); 5846 eina_strbuf_free(buf);
5862 } 5847 }
5863 else
5864 {
5865 remember_key = key;
5866 }
5867 5848
5868 if (tokens) 5849 if (tokens)
5869 { 5850 {
@@ -5874,55 +5855,6 @@ _edje_hash_find_helper(const Eina_Hash *hash, const char *key)
5874} 5855}
5875 5856
5876Edje_Color_Class * 5857Edje_Color_Class *
5877_edje_color_class_find(const Edje *ed, const char *color_class)
5878{
5879 Edje_Color_Class *cc = NULL;
5880
5881 if ((!ed) || (!color_class)) return NULL;
5882
5883 /* first look through the object scope */
5884 cc = eina_hash_find(ed->color_classes, color_class);
5885 if (cc) return cc;
5886
5887 /* next look through the global scope */
5888 cc = eina_hash_find(_edje_color_class_hash, color_class);
5889 if (cc) return cc;
5890
5891 /* finally, look through the file scope */
5892 if (ed->file)
5893 cc = eina_hash_find(ed->file->color_hash, color_class);
5894 if (cc) return cc;
5895
5896 // fall back to parent class. expecting classes like:
5897 // /bg <- fallback for /bg/*
5898 // /bg/normal <- fallback for /bg/normal/*
5899 // /bg/normal/button <- mid grey
5900 // etc.
5901 if (color_class[0] == '/')
5902 {
5903 size_t len = strlen(color_class);
5904 char *color_class_parent = alloca(len + 1);
5905 const char *src = color_class;
5906 char *last_slash = NULL, *dst = color_class_parent;
5907
5908 for (;; src++, dst++)
5909 {
5910 *dst = *src;
5911 if (*dst == '/') last_slash = dst;
5912 if (*dst == 0) break;
5913 }
5914 if (last_slash)
5915 {
5916 if (last_slash == color_class_parent)
5917 return NULL;
5918 *last_slash = 0;
5919 }
5920 return _edje_color_class_find(ed, color_class_parent);
5921 }
5922 return NULL;
5923}
5924
5925Edje_Color_Class *
5926_edje_color_class_recursive_find_helper(const Edje *ed, Eina_Hash *hash, const char *color_class) 5858_edje_color_class_recursive_find_helper(const Edje *ed, Eina_Hash *hash, const char *color_class)
5927{ 5859{
5928 Edje_Color_Class *cc = NULL; 5860 Edje_Color_Class *cc = NULL;
diff --git a/src/lib/eina/eina_debug_chunk.c b/src/lib/eina/eina_debug_chunk.c
index 1c6c028647..58b6e9bf7c 100644
--- a/src/lib/eina/eina_debug_chunk.c
+++ b/src/lib/eina/eina_debug_chunk.c
@@ -54,6 +54,8 @@ static int chunk2_num = 0;
54static int chunk3_size = 0; 54static int chunk3_size = 0;
55static int chunk3_num = 0; 55static int chunk3_num = 0;
56 56
57static int no_anon = -1;
58
57// get a new chunk of "anonymous mmaped memory" 59// get a new chunk of "anonymous mmaped memory"
58static void * 60static void *
59_eina_debug_chunk_need(int size) 61_eina_debug_chunk_need(int size)
@@ -65,9 +67,18 @@ _eina_debug_chunk_need(int size)
65 else 67 else
66#endif 68#endif
67 { 69 {
68 ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, 70 if (no_anon == -1)
69 MAP_PRIVATE | MAP_ANON, -1, 0); 71 {
70 if (ptr == MAP_FAILED) return NULL; 72 if (getenv("EFL_NO_MMAP_ANON")) no_anon = 1;
73 else no_anon = 0;
74 }
75 if (no_anon == 1) ptr = malloc(size);
76 else
77 {
78 ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
79 MAP_PRIVATE | MAP_ANON, -1, 0);
80 if (ptr == MAP_FAILED) return NULL;
81 }
71 } 82 }
72 return ptr; 83 return ptr;
73} 84}
@@ -80,7 +91,10 @@ _eina_debug_chunk_noneed(void *ptr, int size)
80 if (RUNNING_ON_VALGRIND) free(ptr); 91 if (RUNNING_ON_VALGRIND) free(ptr);
81 else 92 else
82#endif 93#endif
83 munmap(ptr, size); 94 {
95 if (no_anon == 1) free(ptr);
96 else munmap(ptr, size);
97 }
84} 98}
85 99
86// push a new bit of mem on our growing stack of mem - given our workload, 100// push a new bit of mem on our growing stack of mem - given our workload,
diff --git a/src/lib/eina/eina_evlog.c b/src/lib/eina/eina_evlog.c
index c0fe64fe22..b9081876ce 100644
--- a/src/lib/eina/eina_evlog.c
+++ b/src/lib/eina/eina_evlog.c
@@ -94,6 +94,8 @@ get_time(void)
94#endif 94#endif
95} 95}
96 96
97static int no_anon = -1;
98
97static void 99static void
98alloc_buf(Eina_Evlog_Buf *b, unsigned int size) 100alloc_buf(Eina_Evlog_Buf *b, unsigned int size)
99{ 101{
@@ -106,9 +108,18 @@ alloc_buf(Eina_Evlog_Buf *b, unsigned int size)
106 else 108 else
107# endif 109# endif
108 { 110 {
109 b->buf = mmap(NULL, size, PROT_READ | PROT_WRITE, 111 if (no_anon == -1)
110 MAP_PRIVATE | MAP_ANON, -1, 0); 112 {
111 if (b->buf == MAP_FAILED) b->buf = NULL; 113 if (getenv("EFL_NO_MMAP_ANON")) no_anon = 1;
114 else no_anon = 0;
115 }
116 if (no_anon == 1) b->buf = malloc(size);
117 else
118 {
119 b->buf = mmap(NULL, size, PROT_READ | PROT_WRITE,
120 MAP_PRIVATE | MAP_ANON, -1, 0);
121 if (b->buf == MAP_FAILED) b->buf = NULL;
122 }
112 } 123 }
113#else 124#else
114 b->buf = malloc(size); 125 b->buf = malloc(size);
@@ -125,7 +136,10 @@ free_buf(Eina_Evlog_Buf *b)
125 if (RUNNING_ON_VALGRIND) free(b->buf); 136 if (RUNNING_ON_VALGRIND) free(b->buf);
126 else 137 else
127# endif 138# endif
128 munmap(b->buf, b->size); 139 {
140 if (no_anon == 1) free(b->buf);
141 else munmap(b->buf, b->size);
142 }
129#else 143#else
130 free(b->buf); 144 free(b->buf);
131#endif 145#endif
diff --git a/src/lib/eina/eina_safepointer.c b/src/lib/eina/eina_safepointer.c
index fc88b6c63e..dd832b68d6 100644
--- a/src/lib/eina/eina_safepointer.c
+++ b/src/lib/eina/eina_safepointer.c
@@ -72,6 +72,8 @@ static Eina_Spinlock sl;
72#define MEM_PAGE_SIZE 4096 72#define MEM_PAGE_SIZE 4096
73#define SAFEPOINTER_MAGIC 0x7DEADC03 73#define SAFEPOINTER_MAGIC 0x7DEADC03
74 74
75static int no_anon = -1;
76
75static void * 77static void *
76_eina_safepointer_calloc(int number, size_t size) 78_eina_safepointer_calloc(int number, size_t size)
77{ 79{
@@ -89,12 +91,21 @@ _eina_safepointer_calloc(int number, size_t size)
89 (size % MEM_PAGE_SIZE ? 1 : 0)) 91 (size % MEM_PAGE_SIZE ? 1 : 0))
90 * MEM_PAGE_SIZE; 92 * MEM_PAGE_SIZE;
91 93
92 header = mmap(NULL, newsize, PROT_READ | PROT_WRITE, 94 if (no_anon == -1)
93 MAP_PRIVATE | MAP_ANON, -1, 0);
94 if (header == MAP_FAILED)
95 { 95 {
96 ERR("mmap of Eina_Safepointer table region failed."); 96 if (getenv("EFL_NO_MMAP_ANON")) no_anon = 1;
97 return NULL; 97 else no_anon = 0;
98 }
99 if (no_anon == 1) header = calloc(number, size);
100 else
101 {
102 header = mmap(NULL, newsize, PROT_READ | PROT_WRITE,
103 MAP_PRIVATE | MAP_ANON, -1, 0);
104 if (header == MAP_FAILED)
105 {
106 ERR("mmap of Eina_Safepointer table region failed.");
107 return NULL;
108 }
98 } 109 }
99 110
100 header->size = newsize; 111 header->size = newsize;
@@ -120,12 +131,15 @@ _eina_safepointer_free(void *pointer)
120 131
121 if (!pointer) return; 132 if (!pointer) return;
122 133
123 header = (Eina_Memory_Header*)(pointer) - 1; 134 if (no_anon == 1) free((void *)((uintptr_t) pointer & ~0x3));
124 if (!EINA_MAGIC_CHECK(header, SAFEPOINTER_MAGIC)) 135 else
125 EINA_MAGIC_FAIL(header, SAFEPOINTER_MAGIC); 136 {
126 137 header = (Eina_Memory_Header*)(pointer) - 1;
127 EINA_MAGIC_SET(header, 0); 138 if (!EINA_MAGIC_CHECK(header, SAFEPOINTER_MAGIC))
128 munmap(header, header->size); 139 EINA_MAGIC_FAIL(header, SAFEPOINTER_MAGIC);
140 EINA_MAGIC_SET(header, 0);
141 munmap(header, header->size);
142 }
129 } 143 }
130#else 144#else
131 free((void *)((uintptr_t) pointer & ~0x3)); 145 free((void *)((uintptr_t) pointer & ~0x3));
diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c
index 5b7589d95f..ec8f1a1adb 100644
--- a/src/lib/elementary/efl_ui_focus_manager_calc.c
+++ b/src/lib/elementary/efl_ui_focus_manager_calc.c
@@ -645,7 +645,7 @@ _efl_ui_focus_manager_calc_update_parent(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manag
645 Node *node; 645 Node *node;
646 Node *parent; 646 Node *parent;
647 647
648 EINA_SAFETY_ON_NULL_RETURN_VAL(parent_obj, EINA_FALSE); 648 if (!parent_obj) return EINA_FALSE;
649 EINA_SAFETY_ON_NULL_RETURN_VAL(child, EINA_FALSE); 649 EINA_SAFETY_ON_NULL_RETURN_VAL(child, EINA_FALSE);
650 650
651 node = node_get(obj, pd, child); 651 node = node_get(obj, pd, child);
diff --git a/src/lib/elementary/efl_ui_focus_manager_root_focus.c b/src/lib/elementary/efl_ui_focus_manager_root_focus.c
index 29507001fb..70c0aee2c3 100644
--- a/src/lib/elementary/efl_ui_focus_manager_root_focus.c
+++ b/src/lib/elementary/efl_ui_focus_manager_root_focus.c
@@ -95,6 +95,7 @@ _efl_ui_focus_manager_root_focus_efl_ui_focus_manager_calc_register(Eo *obj, Efl
95EOLIAN static Eina_Bool 95EOLIAN static Eina_Bool
96_efl_ui_focus_manager_root_focus_efl_ui_focus_manager_calc_register_logical(Eo *obj, Efl_Ui_Focus_Manager_Root_Focus_Data *pd, Efl_Ui_Focus_Object *child, Efl_Ui_Focus_Object *parent, Efl_Ui_Focus_Manager *redirect) 96_efl_ui_focus_manager_root_focus_efl_ui_focus_manager_calc_register_logical(Eo *obj, Efl_Ui_Focus_Manager_Root_Focus_Data *pd, Efl_Ui_Focus_Object *child, Efl_Ui_Focus_Object *parent, Efl_Ui_Focus_Manager *redirect)
97{ 97{
98 if (!parent) return EINA_FALSE;
98 if (efl_ui_focus_manager_calc_register_logical(efl_super(obj, MY_CLASS), child, parent, redirect)) 99 if (efl_ui_focus_manager_calc_register_logical(efl_super(obj, MY_CLASS), child, parent, redirect))
99 { 100 {
100 if (redirect && pd->rect_registered) 101 if (redirect && pd->rect_registered)
diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c
index 26c4887684..8ad78e28c2 100644
--- a/src/lib/elementary/efl_ui_widget.c
+++ b/src/lib/elementary/efl_ui_widget.c
@@ -441,16 +441,16 @@ _logical_parent_eval(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd, Eina_Bool s
441 if (should) 441 if (should)
442 { 442 {
443 provider = efl_provider_find(obj, EFL_UI_FOCUS_PARENT_PROVIDER_INTERFACE); 443 provider = efl_provider_find(obj, EFL_UI_FOCUS_PARENT_PROVIDER_INTERFACE);
444 EINA_SAFETY_ON_NULL_RETURN_VAL(provider, NULL); 444 if (provider)
445 parent = efl_ui_focus_parent_provider_find_logical_parent(provider, obj); 445 {
446 EINA_SAFETY_ON_NULL_RETURN_VAL(provider, NULL);
447 parent = efl_ui_focus_parent_provider_find_logical_parent(provider, obj);
448 }
449 else parent = NULL;
446 } 450 }
447 else 451 else parent = NULL;
448 parent = NULL;
449 }
450 else
451 {
452 parent = efl_ui_widget_parent_get(obj);
453 } 452 }
453 else parent = efl_ui_widget_parent_get(obj);
454 454
455 455
456 if (pd->logical.parent != parent) 456 if (pd->logical.parent != parent)
diff --git a/src/lib/elementary/elm_code_syntax.c b/src/lib/elementary/elm_code_syntax.c
index dbdf7d32f7..59784ffa5c 100644
--- a/src/lib/elementary/elm_code_syntax.c
+++ b/src/lib/elementary/elm_code_syntax.c
@@ -156,6 +156,19 @@ static Elm_Code_Syntax _elm_code_syntax_csharp =
156 "orderby","select","where","unmanaged","var", NULL } 156 "orderby","select","where","unmanaged","var", NULL }
157}; 157};
158 158
159static Elm_Code_Syntax _elm_code_syntax_shell =
160{
161 "{}()[]:;%^/*+&|~!=<->,.",
162 "",
163 NULL,
164 "#",
165 NULL,
166 NULL,
167 _elm_code_syntax_scope_change_braces,
168 { "if", "then", "else", "elif", "fi", "case", "esac", "for", "select", "while", "until", "do" \
169 "done", "in", "function", "time", "coproc", NULL }
170};
171
159EAPI Elm_Code_Syntax * 172EAPI Elm_Code_Syntax *
160elm_code_syntax_for_mime_get(const char *mime) 173elm_code_syntax_for_mime_get(const char *mime)
161{ 174{
@@ -175,6 +188,8 @@ elm_code_syntax_for_mime_get(const char *mime)
175 return &_elm_code_syntax_go; 188 return &_elm_code_syntax_go;
176 if (!strcmp("text/x-csharp", mime)) 189 if (!strcmp("text/x-csharp", mime))
177 return &_elm_code_syntax_csharp; 190 return &_elm_code_syntax_csharp;
191 if (!strcmp("application/x-shellscript", mime))
192 return &_elm_code_syntax_shell;
178 193
179 return NULL; 194 return NULL;
180} 195}
diff --git a/src/lib/elementary/elm_config.c b/src/lib/elementary/elm_config.c
index ef6581a7ce..9b570822d8 100644
--- a/src/lib/elementary/elm_config.c
+++ b/src/lib/elementary/elm_config.c
@@ -108,6 +108,274 @@ static void _color_overlays_cancel(void);
108#define ELM_CONFIG_LIST(edd, type, member, eddtype) \ 108#define ELM_CONFIG_LIST(edd, type, member, eddtype) \
109 EET_DATA_DESCRIPTOR_ADD_LIST(edd, type, #member, member, eddtype) 109 EET_DATA_DESCRIPTOR_ADD_LIST(edd, type, #member, member, eddtype)
110 110
111#ifdef _WIN32
112
113# include <windows.h>
114# include <shtypes.h>
115
116# define ELM_CONFIG_WIN32_CLASS "Elm_Config_Win32_Class"
117
118/* Default message procedure for the window - mandatory */
119static LRESULT CALLBACK
120_elm_config_win32_proc(HWND window,
121 UINT message,
122 WPARAM window_param,
123 LPARAM data_param)
124{
125
126 switch (message)
127 {
128 default:
129 return DefWindowProc(window, message, window_param, data_param);
130 }
131}
132
133/* Create a hidden window and retrieve the monitor from it */
134static HMONITOR
135_elm_config_win32_monitor_get(void)
136{
137 HINSTANCE instance;
138 WNDCLASS wc;
139 HWND win;
140 HMONITOR mon;
141 DWORD style;
142
143 instance = GetModuleHandle(NULL);
144 if (!instance)
145 return NULL;
146
147 memset (&wc, 0, sizeof (WNDCLASS));
148 wc.style = 0;
149 wc.lpfnWndProc = _elm_config_win32_proc;
150 wc.cbClsExtra = 0;
151 wc.cbWndExtra = 0;
152 wc.hInstance = instance;
153 wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
154 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
155 wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
156 wc.lpszMenuName = NULL;
157 wc.lpszClassName = ELM_CONFIG_WIN32_CLASS;
158
159 if(!RegisterClass(&wc))
160 {
161 FreeLibrary(instance);
162 return NULL;
163 }
164
165 style = WS_POPUP & ~(WS_CAPTION | WS_THICKFRAME);
166 win = CreateWindow(ELM_CONFIG_WIN32_CLASS, "",
167 style,
168 0, 0, 800, 600,
169 NULL, NULL,
170 instance, NULL);
171 if (!win)
172 {
173 UnregisterClass(ELM_CONFIG_WIN32_CLASS, instance);
174 FreeLibrary(instance);
175 return NULL;
176 }
177
178 mon = MonitorFromWindow(win, MONITOR_DEFAULTTONEAREST);
179
180 DestroyWindow(win);
181 UnregisterClass(ELM_CONFIG_WIN32_CLASS, instance);
182 FreeLibrary(instance);
183
184 return mon;
185}
186
187static void
188_elm_config_win32_awareness(void)
189{
190 HMODULE mod;
191
192 /*
193 * Several API can make an application DPI aware :
194 * SetProcessDpiAwarenessContext() (Windows 10 version 1607)
195 * SetProcessDpiAwareness() (Windows 8.1)
196 * SetProcessDpiAware() (Windows Vista)
197 *
198 * We check these functions in that order:
199 */
200
201 /* Windows 10 */
202 typedef BOOL (*SetProcessDpiAwarenessContext_t)(void *);
203 SetProcessDpiAwarenessContext_t SetProcessDpiAwarenessContext_;
204
205 /* Windows 8.1 */
206 typedef enum PROCESS_DPI_AWARENESS_
207 {
208 PROCESS_DPI_UNAWARE_,
209 PROCESS_SYSTEM_DPI_AWARE_,
210 PROCESS_PER_MONITOR_DPI_AWARE_
211 } PROCESS_DPI_AWARENESS_;
212 typedef HRESULT (*SetProcessDpiAwareness_t)(PROCESS_DPI_AWARENESS_);
213 SetProcessDpiAwareness_t SetProcessDpiAwareness_;
214
215 /* Windows Vista */
216 typedef BOOL (*SetProcessDpiAware_t)(void);
217 SetProcessDpiAware_t SetProcessDpiAware_;
218
219 mod = LoadLibrary("user32.dll");
220 if (!mod)
221 goto win8;
222
223 SetProcessDpiAwarenessContext_ = (SetProcessDpiAwarenessContext_t)GetProcAddress(mod, "SetProcessDpiAwarenessContext");
224
225 FreeLibrary(mod);
226
227 if (!SetProcessDpiAwarenessContext_)
228 goto win8;
229
230 if (!SetProcessDpiAwarenessContext_((void *)-2))
231 goto win8;
232
233 return;
234
235 win8:
236
237 mod = LoadLibrary("shcore.dll");
238 if (!mod)
239 goto vista;
240
241 SetProcessDpiAwareness_ = (SetProcessDpiAwareness_t)GetProcAddress(mod, "SetProcessDpiAwareness");
242
243 FreeLibrary(mod);
244
245 if (!SetProcessDpiAwareness_)
246 goto vista;
247
248 if (!SetProcessDpiAwareness_(PROCESS_SYSTEM_DPI_AWARE_))
249 goto vista;
250
251 return;
252
253 vista:
254
255 mod = LoadLibrary("user32.dll");
256 if (!mod)
257 return;
258
259 SetProcessDpiAware_ = (SetProcessDpiAware_t)GetProcAddress(mod, "SetProcessDPIAware");
260
261 FreeLibrary(mod);
262
263 if (!SetProcessDpiAware_)
264 return;
265
266 SetProcessDpiAware_();
267}
268
269static void
270_elm_config_win32_dpi_awareness_set(Elm_Config *cfg)
271{
272 typedef HRESULT (*GetScaleFactorForMonitor_t)(HMONITOR, DEVICE_SCALE_FACTOR *);
273 typedef enum
274 {
275 DEVICE_PRIMARY_,
276 DEBICE_IMMERSIVE_
277 } DISPLAY_DEVICE_TYPE_;
278
279 typedef DEVICE_SCALE_FACTOR (*GetScaleFactorForDevice_t)(DISPLAY_DEVICE_TYPE_ deviceType);
280
281 HMODULE mod;
282 HMONITOR mon;
283 DEVICE_SCALE_FACTOR scale;
284 HRESULT res;
285 HDC dc;
286 int ppi;
287
288 GetScaleFactorForMonitor_t GetScaleFactorForMonitor_;
289 GetScaleFactorForDevice_t GetScaleFactorForDevice_;
290
291 /*
292 * First, get the scale factor. We try in that order :
293 * - GetScaleFactorForMonitor() (appeared in Windows 8.1)
294 * - GetScaleFactorForDevice() (appeared in Windows 8)
295 *
296 * We need to get the functions from shcore.dll, so we
297 * load that DLL first. If not, we will use the GDI functions
298 */
299
300 mod = LoadLibrary("shcore.dll");
301 if (!mod)
302 goto gdi;
303
304 /*
305 * First, try GetScaleFactorForMonitor().
306 * It needs a monitor. We can retrieve a monitor from a hidden window.
307 */
308
309 mon = _elm_config_win32_monitor_get();
310 if (!mon)
311 {
312 /* Try GetScaleFactorForDevice() */
313 FreeLibrary(mod);
314 goto _next;
315 }
316
317 GetScaleFactorForMonitor_ = (GetScaleFactorForMonitor_t)GetProcAddress(mod, "GetScaleFactorForMonitor");
318 if (!GetScaleFactorForMonitor_)
319 {
320 /* Try GetScaleFactorForDevice() */
321 FreeLibrary(mod);
322 goto _next;
323 }
324
325 res = GetScaleFactorForMonitor_(mon, &scale);
326
327 FreeLibrary(mod);
328
329 if ((res != S_OK) || (scale == DEVICE_SCALE_FACTOR_INVALID))
330 {
331 /* Try GetScaleFactorForDevice() */
332 goto _next;
333 }
334
335 cfg->scale = (double)scale / 100.0;
336 _elm_config_win32_awareness();
337
338 return;
339
340 _next:
341
342 GetScaleFactorForDevice_ = (GetScaleFactorForDevice_t)GetProcAddress(mod, "GetScaleFactorForDevice");
343
344 FreeLibrary(mod);
345
346 if (!GetScaleFactorForDevice_)
347 {
348 /* Try GDI */
349 goto gdi;
350 }
351
352 scale = GetScaleFactorForDevice_(DEVICE_PRIMARY_);
353 if (scale == DEVICE_SCALE_FACTOR_INVALID)
354 {
355 /* Try GDI */
356 goto gdi;
357 }
358
359 cfg->scale = (double)scale / 100.0;
360 _elm_config_win32_awareness();
361
362 return;
363
364 gdi:
365 dc = GetDC(NULL);
366 if (dc)
367 {
368 ppi = GetDeviceCaps(dc, LOGPIXELSY);
369 cfg->scale = (double)ppi / 96.0;
370 ReleaseDC(NULL, dc);
371 _elm_config_win32_awareness();
372 }
373
374 return;
375}
376
377#endif
378
111static void 379static void
112_elm_font_overlays_del_free(void) 380_elm_font_overlays_del_free(void)
113{ 381{
@@ -834,7 +1102,7 @@ _palette_apply(const char *name)
834 l = edje_color_class_list(); 1102 l = edje_color_class_list();
835 EINA_LIST_FREE(l, s) 1103 EINA_LIST_FREE(l, s)
836 { 1104 {
837 if ((s) && (s[0] == '/')) edje_color_class_del(s); 1105 if ((s) && ((s[0] == '/') || s[0] == ':')) edje_color_class_del(s);
838 free(s); 1106 free(s);
839 } 1107 }
840 pal = _palette_find(name); 1108 pal = _palette_find(name);
@@ -1883,6 +2151,9 @@ _config_load(void)
1883 { 2151 {
1884 if (_elm_config->config_version < ELM_CONFIG_VERSION) 2152 if (_elm_config->config_version < ELM_CONFIG_VERSION)
1885 _config_update(); 2153 _config_update();
2154#ifdef _WIN32
2155 _elm_config_win32_dpi_awareness_set(_elm_config);
2156#endif
1886 _env_get(); 2157 _env_get();
1887 _palette_apply(_elm_config->palette); 2158 _palette_apply(_elm_config->palette);
1888 return; 2159 return;
@@ -1897,6 +2168,9 @@ _config_load(void)
1897 if (_elm_config) 2168 if (_elm_config)
1898 { 2169 {
1899 _palette_apply(_elm_config->palette); 2170 _palette_apply(_elm_config->palette);
2171#ifdef _WIN32
2172 _elm_config_win32_dpi_awareness_set(_elm_config);
2173#endif
1900 _env_get(); 2174 _env_get();
1901 return; 2175 return;
1902 } 2176 }
diff --git a/src/lib/elementary/elm_map.c b/src/lib/elementary/elm_map.c
index 6d287fef5e..afe8757867 100644
--- a/src/lib/elementary/elm_map.c
+++ b/src/lib/elementary/elm_map.c
@@ -57,265 +57,13 @@
57#define NOMINATIM_ATTR_ADDRESS "display_name" 57#define NOMINATIM_ATTR_ADDRESS "display_name"
58 58
59static Eina_Bool _key_action_move(Evas_Object *obj, const char *params); 59static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
60static Eina_Bool _key_action_zoom(Evas_Object *obj, const char *params);
61static Eina_Bool _zoom_animator_set(Elm_Map_Data *sd, void *callback);
62 60
63static const Elm_Action key_actions[] = { 61static const Elm_Action key_actions[] = {
64 {"move", _key_action_move}, 62 {"move", _key_action_move},
65 {"zoom", _key_action_zoom}, 63 {"zoom", _key_action_move},
66 {NULL, NULL} 64 {NULL, NULL}
67}; 65};
68 66
69static char *
70_mapnik_url_cb(const Evas_Object *obj EINA_UNUSED,
71 int x,
72 int y,
73 int zoom)
74{
75 char buf[PATH_MAX];
76
77 // ((x+y+zoom)%3)+'a' is requesting map images from distributed
78 // tile servers (eg., a, b, c)
79 snprintf(buf, sizeof(buf), "http://%c.tile.openstreetmap.org/%d/%d/%d.png",
80 ((x + y + zoom) % 3) + 'a', zoom, x, y);
81 return strdup(buf);
82}
83
84static char *
85_osmarender_url_cb(const Evas_Object *obj EINA_UNUSED,
86 int x,
87 int y,
88 int zoom)
89{
90 char buf[PATH_MAX];
91
92 snprintf(buf, sizeof(buf),
93 "http://%c.tah.openstreetmap.org/Tiles/tile/%d/%d/%d.png",
94 ((x + y + zoom) % 3) + 'a', zoom, x, y);
95
96 return strdup(buf);
97}
98
99static char *
100_cyclemap_url_cb(const Evas_Object *obj EINA_UNUSED,
101 int x,
102 int y,
103 int zoom)
104{
105 char buf[PATH_MAX];
106
107 snprintf(buf, sizeof(buf),
108 "http://%c.tile.opencyclemap.org/cycle/%d/%d/%d.png",
109 ((x + y + zoom) % 3) + 'a', zoom, x, y);
110
111 return strdup(buf);
112}
113
114static char *
115_mapquest_url_cb(const Evas_Object *obj EINA_UNUSED,
116 int x,
117 int y,
118 int zoom)
119{
120 char buf[PATH_MAX];
121
122 snprintf(buf, sizeof(buf),
123 "http://otile%d.mqcdn.com/tiles/1.0.0/osm/%d/%d/%d.png",
124 ((x + y + zoom) % 4) + 1, zoom, x, y);
125
126 return strdup(buf);
127}
128
129static char *
130_mapquest_aerial_url_cb(const Evas_Object *obj EINA_UNUSED,
131 int x,
132 int y,
133 int zoom)
134{
135 char buf[PATH_MAX];
136
137 snprintf(buf, sizeof(buf), "http://oatile%d.mqcdn.com/naip/%d/%d/%d.png",
138 ((x + y + zoom) % 4) + 1, zoom, x, y);
139
140 return strdup(buf);
141}
142
143static char *
144_yours_url_cb(const Evas_Object *obj EINA_UNUSED,
145 const char *type_name,
146 int method,
147 double flon,
148 double flat,
149 double tlon,
150 double tlat)
151{
152 char buf[PATH_MAX];
153
154 snprintf
155 (buf, sizeof(buf),
156 "%s?flat=%lf&flon=%lf&tlat=%lf&tlon=%lf&v=%s&fast=%d&instructions=1",
157 ROUTE_YOURS_URL, flat, flon, tlat, tlon, type_name, method);
158
159 return strdup(buf);
160}
161
162// TODO: fix monav api
163/*
164 static char *
165 _monav_url_cb(const Evas_Object *obj EINA_UNUSED,
166 char *type_name,
167 int method,
168 double flon,
169 double flat,
170 double tlon,
171 double tlat)
172 {
173 char buf[PATH_MAX];
174
175 snprintf(buf, sizeof(buf),
176 "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
177 ROUTE_MONAV_URL, flat, flon, tlat, tlon, type_name, method);
178
179 return strdup(buf);
180 }
181
182 //TODO: fix ors api
183
184 static char *
185 _ors_url_cb(const Evas_Object *obj EINA_UNUSED,
186 char *type_name,
187 int method,
188 double flon,
189 double flat,
190 double tlon,
191 double tlat)
192 {
193 char buf[PATH_MAX];
194
195 snprintf(buf, sizeof(buf),
196 "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
197 ROUTE_ORS_URL, flat, flon, tlat, tlon, type_name, method);
198
199 return strdup(buf);
200 }
201 */
202
203static char *
204_nominatim_url_cb(const Evas_Object *obj,
205 int method,
206 const char *name,
207 double lon,
208 double lat)
209{
210 char **str;
211 char buf[PATH_MAX + 256];
212 unsigned int ele, idx;
213 char search_url[PATH_MAX];
214
215 ELM_MAP_DATA_GET(obj, sd);
216
217 if (method == ELM_MAP_NAME_METHOD_SEARCH)
218 {
219 search_url[0] = '\0';
220 str = eina_str_split_full(name, " ", 0, &ele);
221 for (idx = 0; idx < ele; idx++)
222 {
223 eina_strlcat(search_url, str[idx], sizeof(search_url));
224 if (!(idx == (ele - 1)))
225 eina_strlcat(search_url, "+", sizeof(search_url));
226 }
227 snprintf(buf, sizeof(buf),
228 "%s/search?q=%s&format=xml&polygon=0&addressdetails=0",
229 NAME_NOMINATIM_URL, search_url);
230
231 if (str)
232 {
233 free(str[0]);
234 free(str);
235 }
236 }
237 else if (method == ELM_MAP_NAME_METHOD_REVERSE)
238 snprintf(buf, sizeof(buf),
239 "%s/reverse?format=xml&lat=%lf&lon=%lf&zoom=%d&addressdetails=0",
240 NAME_NOMINATIM_URL, lat, lon, (int)sd->zoom);
241 else strcpy(buf, "");
242
243 return strdup(buf);
244}
245
246// Refer : http://wiki.openstreetmap.org/wiki/FAQ
247// meters per pixel when latitude is 0 (equator)
248// meters per pixel = _osm_scale_meter[zoom] * cos (latitude)
249static const double _osm_scale_meter[] =
250{
251 78206, 39135.758482, 19567.879241, 9783.939621, 4891.969810,
252 2445.984905, 1222.992453, 611.496226, 305.748113, 152.874057, 76.437028,
253 38.218514, 19.109257, 9.554629, 4.777314, 2.388657, 1.194329, 0.597164,
254 0.29858
255};
256
257static double
258_scale_cb(const Evas_Object *obj EINA_UNUSED,
259 double lon EINA_UNUSED,
260 double lat,
261 int zoom)
262{
263 if ((zoom < 0) ||
264 (zoom >= (int)(sizeof(_osm_scale_meter) / sizeof(_osm_scale_meter[0])))
265 )
266 return 0;
267 return _osm_scale_meter[zoom] * cos(lat * ELM_PI / 180.0);
268}
269
270static Evas_Object *
271_osm_copyright_cb(Evas_Object *obj)
272{
273 Evas_Object *label;
274
275 label = elm_label_add(obj);
276 elm_object_text_set(label, "<color=#000000FF><backing=on><backing_color=#FCFCFBFF><shadow_color=#00000000>"
277 "openstreetmap.org opendatacommons.org creativecommons.org"
278 "</shadow_color></backing_color></backing></color>");
279
280 return label;
281}
282
283static const Source_Tile src_tiles[] =
284{
285 {"Mapnik", 0, 18, _mapnik_url_cb, NULL, NULL, _scale_cb, _osm_copyright_cb},
286 {"Osmarender", 0, 17, _osmarender_url_cb, NULL, NULL, _scale_cb, _osm_copyright_cb},
287 {"CycleMap", 0, 16, _cyclemap_url_cb, NULL, NULL, _scale_cb, _osm_copyright_cb},
288 {"MapQuest", 0, 18, _mapquest_url_cb, NULL, NULL, _scale_cb, _osm_copyright_cb},
289 {"MapQuest Open Aerial", 0, 11, _mapquest_aerial_url_cb, NULL, NULL,
290 _scale_cb, _osm_copyright_cb}
291};
292
293static void _kml_parse(Elm_Map_Route *r);
294// FIXME: Fix more open sources
295static const Source_Route src_routes[] =
296{
297 {"Yours", _yours_url_cb, _kml_parse} // http://www.yournavigation.org/
298 //{"Monav", _monav_url_cb, _kml_parse},
299 //{"ORS", _ors_url_cb, _kml_parse)}, // http://www.openrouteservice.org
300};
301
302// Scale in meters
303static const double _scale_tb[] =
304{
305 10000000, 5000000, 2000000, 1000000, 500000, 200000, 100000, 50000,
306 20000, 10000, 5000, 2000, 1000, 500, 500, 200, 100, 50, 20, 10, 5, 2, 1
307};
308
309static void _name_parse(Elm_Map_Name *n);
310static void _name_list_parse(Elm_Map_Name_List *nl);
311// FIXME: Add more open sources
312static const Source_Name src_names[] =
313{
314 {"Nominatim", _nominatim_url_cb, _name_parse, _name_list_parse}
315};
316
317static int id_num = 1;
318
319static const char SIG_CLICKED[] = "clicked"; 67static const char SIG_CLICKED[] = "clicked";
320static const char SIG_CLICKED_DOUBLE[] = "clicked,double"; 68static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
321static const char SIG_PRESS[] = "press"; 69static const char SIG_PRESS[] = "press";
@@ -367,3506 +115,6 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
367 {NULL, NULL} 115 {NULL, NULL}
368}; 116};
369 117
370static void
371_edj_overlay_size_get(Elm_Map_Data *sd,
372 Evas_Coord *w,
373 Evas_Coord *h)
374{
375 Evas_Object *edj;
376 const char *s;
377
378 EINA_SAFETY_ON_NULL_RETURN(w);
379 EINA_SAFETY_ON_NULL_RETURN(h);
380
381 edj = edje_object_add(evas_object_evas_get(sd->obj));
382 elm_widget_theme_object_set
383 (sd->obj, edj, "map/marker", "radio",
384 elm_widget_style_get(sd->obj));
385
386 s = edje_object_data_get(edj, "size_w");
387 if (s) *w = atoi(s);
388 else *w = 0;
389
390 s = edje_object_data_get(edj, "size_h");
391 if (s) *h = atoi(s);
392 else *h = 0;
393
394 evas_object_del(edj);
395}
396
397static void
398_rotate_do(Evas_Coord x,
399 Evas_Coord y,
400 Evas_Coord cx,
401 Evas_Coord cy,
402 double degree,
403 Evas_Coord *xx,
404 Evas_Coord *yy)
405{
406 double r = (degree * M_PI) / 180.0;
407
408 if (xx) *xx = ((x - cx) * cos(r)) + ((y - cy) * cos(r + M_PI_2)) + cx;
409 if (yy) *yy = ((x - cx) * sin(r)) + ((y - cy) * sin(r + M_PI_2)) + cy;
410}
411
412static void
413_obj_rotate(Elm_Map_Data *sd,
414 Evas_Object *obj)
415{
416 Evas_Coord w, h, ow, oh;
417
418 evas_map_util_points_populate_from_object(sd->map, obj);
419
420 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
421 evas_object_image_size_get(obj, &w, &h);
422 if ((w > ow) || (h > oh))
423 {
424 evas_map_point_image_uv_set(sd->map, 0, 0, 0);
425 evas_map_point_image_uv_set(sd->map, 1, w, 0);
426 evas_map_point_image_uv_set(sd->map, 2, w, h);
427 evas_map_point_image_uv_set(sd->map, 3, 0, h);
428 }
429 evas_map_util_rotate(sd->map, sd->rotate.d, sd->rotate.cx, sd->rotate.cy);
430
431 evas_object_map_set(obj, sd->map);
432 evas_object_map_enable_set(obj, EINA_TRUE);
433}
434
435static void
436_obj_place(Evas_Object *obj,
437 Evas_Coord x,
438 Evas_Coord y,
439 Evas_Coord w,
440 Evas_Coord h)
441{
442 EINA_SAFETY_ON_NULL_RETURN(obj);
443
444 evas_object_geometry_set(obj, x, y, w, h);
445 evas_object_show(obj);
446}
447
448static void
449_coord_to_region_convert(Elm_Map_Data *sd,
450 Evas_Coord x,
451 Evas_Coord y,
452 Evas_Coord size,
453 double *lon,
454 double *lat)
455{
456 int zoom;
457
458 EINA_SAFETY_ON_NULL_RETURN(sd);
459
460 zoom = floor(log((double)size / sd->size.tile) / log(2));
461 if ((sd->src_tile) && (sd->src_tile->coord_to_geo))
462 {
463 if (sd->src_tile->coord_to_geo
464 (sd->obj, zoom, x, y, size, lon, lat))
465 return;
466 }
467
468 if (lon) *lon = (x / (double)size * 360.0) - 180;
469 if (lat)
470 {
471 double n = ELM_PI - (2.0 * ELM_PI * y / size);
472 *lat = 180.0 / ELM_PI *atan(0.5 * (exp(n) - exp(-n)));
473 }
474}
475
476static void
477_region_to_coord_convert(Elm_Map_Data *sd,
478 double lon,
479 double lat,
480 Evas_Coord size,
481 Evas_Coord *x,
482 Evas_Coord *y)
483{
484 int zoom;
485
486 EINA_SAFETY_ON_NULL_RETURN(sd);
487
488 zoom = floor(log((double)size / 256) / log(2));
489 if ((sd->src_tile) && (sd->src_tile->geo_to_coord))
490 {
491 if (sd->src_tile->geo_to_coord
492 (sd->obj, zoom, lon, lat, size, x, y)) return;
493 }
494
495 if (x) *x = floor((lon + 180.0) / 360.0 * size);
496 if (y)
497 *y = floor((1.0 - log(tan(lat * ELM_PI / 180.0) +
498 (1.0 / cos(lat * ELM_PI / 180.0)))
499 / ELM_PI) / 2.0 * size);
500}
501
502static void
503_viewport_coord_get(Elm_Map_Data *sd,
504 Evas_Coord *vx,
505 Evas_Coord *vy,
506 Evas_Coord *vw,
507 Evas_Coord *vh)
508{
509 Evas_Coord x = 0, y = 0, w = 0, h = 0;
510
511 EINA_SAFETY_ON_NULL_RETURN(sd);
512
513 elm_interface_scrollable_content_pos_get(sd->obj, &x, &y);
514 elm_interface_scrollable_content_viewport_geometry_get
515 (sd->obj, NULL, NULL, &w, &h);
516
517 if (w > sd->size.w) x -= ((w - sd->size.w) / 2);
518 if (h > sd->size.h) y -= ((h - sd->size.h) / 2);
519 if (vx) *vx = x;
520 if (vy) *vy = y;
521 if (vw) *vw = w;
522 if (vh) *vh = h;
523}
524
525// Map coordinates to canvas geometry without rotate
526static void
527_coord_to_canvas_no_rotation(Elm_Map_Data *sd,
528 Evas_Coord x,
529 Evas_Coord y,
530 Evas_Coord *xx,
531 Evas_Coord *yy)
532{
533 Evas_Coord vx = 0, vy = 0, sx = 0, sy = 0;
534
535 _viewport_coord_get(sd, &vx, &vy, NULL, NULL);
536 evas_object_geometry_get(sd->pan_obj, &sx, &sy, NULL, NULL);
537 if (xx) *xx = x - vx + sx;
538 if (yy) *yy = y - vy + sy;
539}
540
541// Map coordinates to canvas geometry
542static void
543_coord_to_canvas(Elm_Map_Data *sd,
544 Evas_Coord x,
545 Evas_Coord y,
546 Evas_Coord *xx,
547 Evas_Coord *yy)
548{
549 _coord_to_canvas_no_rotation(sd, x, y, &x, &y);
550 _rotate_do(x, y, sd->rotate.cx, sd->rotate.cy, sd->rotate.d, &x, &y);
551 if (xx) *xx = x;
552 if (yy) *yy = y;
553}
554
555// Canvas geometry to map coordinates
556static void
557_canvas_to_coord(Elm_Map_Data *sd,
558 Evas_Coord x,
559 Evas_Coord y,
560 Evas_Coord *xx,
561 Evas_Coord *yy)
562{
563 Evas_Coord vx = 0, vy = 0, sx = 0, sy = 0;
564
565 _viewport_coord_get(sd, &vx, &vy, NULL, NULL);
566 evas_object_geometry_get(sd->pan_obj, &sx, &sy, NULL, NULL);
567 _rotate_do(x - sx + vx, y - sy + vy, sd->rotate.cx - sx + vx,
568 sd->rotate.cy - sy + vy, -sd->rotate.d, &x, &y);
569 if (xx) *xx = x;
570 if (yy) *yy = y;
571}
572
573static void
574_grid_item_coord_get(Grid_Item *gi,
575 int *x,
576 int *y,
577 int *w,
578 int *h)
579{
580 EINA_SAFETY_ON_NULL_RETURN(gi);
581
582 if (x) *x = gi->x * gi->wsd->size.tile;
583 if (y) *y = gi->y * gi->wsd->size.tile;
584 if (w) *w = gi->wsd->size.tile;
585 if (h) *h = gi->wsd->size.tile;
586}
587
588static Eina_Bool
589_grid_item_in_viewport(Grid_Item *gi)
590{
591 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
592 Evas_Coord x = 0, y = 0, w = 0, h = 0;
593
594 EINA_SAFETY_ON_NULL_RETURN_VAL(gi, EINA_FALSE);
595
596 _viewport_coord_get(gi->wsd, &vx, &vy, &vw, &vh);
597 _grid_item_coord_get(gi, &x, &y, &w, &h);
598
599 return ELM_RECTS_INTERSECT(x, y, w, h, vx, vy, vw, vh);
600}
601
602static Eina_Bool
603_loaded_timeout_cb(void *data)
604{
605 ELM_MAP_DATA_GET(data, sd);
606
607 EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
608
609 sd->loaded_timer = NULL;
610 if (!(sd->download_num) && !(sd->download_idler))
611 efl_event_callback_legacy_call
612 (sd->obj, ELM_MAP_EVENT_LOADED, NULL);
613 return ECORE_CALLBACK_CANCEL;
614}
615
616static void
617_grid_item_update(Grid_Item *gi)
618{
619 Evas_Load_Error err;
620
621 EINA_SAFETY_ON_NULL_RETURN(gi);
622
623 evas_object_image_file_set(gi->img, gi->file, NULL);
624 if (!gi->wsd->zoom_timer && !gi->wsd->scr_timer)
625 evas_object_image_smooth_scale_set(gi->img, EINA_TRUE);
626 else evas_object_image_smooth_scale_set(gi->img, EINA_FALSE);
627
628 err = evas_object_image_load_error_get(gi->img);
629 if (err != EVAS_LOAD_ERROR_NONE)
630 {
631 ERR("Image loading error (%s): %s", gi->file, evas_load_error_str(err));
632 ecore_file_remove(gi->file);
633 gi->file_have = EINA_FALSE;
634 }
635 else
636 {
637 Evas_Coord x, y, w, h;
638
639 _grid_item_coord_get(gi, &x, &y, &w, &h);
640 _coord_to_canvas_no_rotation(gi->wsd, x, y, &x, &y);
641 _obj_place(gi->img, x, y, w, h);
642 _obj_rotate(gi->wsd, gi->img);
643 gi->file_have = EINA_TRUE;
644 }
645
646 ecore_timer_del(gi->wsd->loaded_timer);
647 gi->wsd->loaded_timer = ecore_timer_add(0.25, _loaded_timeout_cb, gi->wsd->obj);
648}
649
650static void
651_grid_item_load(Grid_Item *gi)
652{
653 EINA_SAFETY_ON_NULL_RETURN(gi);
654
655 if (gi->file_have) _grid_item_update(gi);
656 else if (!gi->job)
657 {
658 gi->wsd->download_list = eina_list_remove(gi->wsd->download_list, gi);
659 gi->wsd->download_list = eina_list_append(gi->wsd->download_list, gi);
660 }
661}
662
663static void
664_grid_item_unload(Grid_Item *gi)
665{
666 EINA_SAFETY_ON_NULL_RETURN(gi);
667
668 if (gi->file_have)
669 {
670 evas_object_hide(gi->img);
671 evas_object_image_file_set(gi->img, NULL, NULL);
672 }
673 else if (gi->job)
674 {
675 ecore_file_download_abort(gi->job);
676 ecore_file_remove(gi->file);
677 gi->job = NULL;
678 gi->wsd->try_num--;
679 }
680 else gi->wsd->download_list = eina_list_remove(gi->wsd->download_list, gi);
681}
682
683static Grid_Item *
684_grid_item_create(Grid *g,
685 Evas_Coord x,
686 Evas_Coord y)
687{
688 char buf[PATH_MAX];
689 char buf2[PATH_MAX + 128];
690 Grid_Item *gi;
691 char *url;
692
693 EINA_SAFETY_ON_NULL_RETURN_VAL(g, NULL);
694
695 gi = ELM_NEW(Grid_Item);
696 gi->wsd = g->wsd;
697 gi->g = g;
698 gi->x = x;
699 gi->y = y;
700
701 gi->file_have = EINA_FALSE;
702 gi->job = NULL;
703
704 gi->img = evas_object_image_add
705 (evas_object_evas_get((g->wsd)->obj));
706 evas_object_image_smooth_scale_set(gi->img, EINA_FALSE);
707 evas_object_image_scale_hint_set(gi->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
708 evas_object_image_filled_set(gi->img, EINA_TRUE);
709 evas_object_smart_member_add(gi->img, g->wsd->pan_obj);
710 evas_object_pass_events_set(gi->img, EINA_TRUE);
711 evas_object_stack_below(gi->img, g->wsd->sep_maps_overlays);
712
713 snprintf(buf, sizeof(buf), "%s" CACHE_TILE_ROOT, efreet_cache_home_get(),
714 g->wsd->id, g->zoom, x);
715
716 snprintf(buf2, sizeof(buf2), CACHE_TILE_PATH, buf, y);
717 if (!ecore_file_exists(buf)) ecore_file_mkpath(buf);
718
719 eina_stringshare_replace(&gi->file, buf2);
720 url = g->wsd->src_tile->url_cb((g->wsd)->obj, x, y, g->zoom);
721 if ((!url) || (!strlen(url)))
722 {
723 eina_stringshare_replace(&gi->url, NULL);
724 ERR("Getting source url failed: %s", gi->file);
725 }
726 else eina_stringshare_replace(&gi->url, url);
727
728 free(url);
729 eina_matrixsparse_data_idx_set(g->grid, y, x, gi);
730
731 return gi;
732}
733
734static void
735_grid_item_free(Grid_Item *gi)
736{
737 EINA_SAFETY_ON_NULL_RETURN(gi);
738
739 _grid_item_unload(gi);
740 if (gi->g && gi->g->grid)
741 eina_matrixsparse_data_idx_set(gi->g->grid, gi->y, gi->x, NULL);
742 eina_stringshare_del(gi->url);
743 if (gi->file_have) ecore_file_remove(gi->file);
744 eina_stringshare_del(gi->file);
745 evas_object_del(gi->img);
746
747 free(gi);
748}
749
750static void
751_downloaded_cb(void *data,
752 const char *file EINA_UNUSED,
753 int status)
754{
755 Grid_Item *gi = data;
756
757 if (status == 200)
758 {
759 DBG("Download success from %s to %s", gi->url, gi->file);
760
761 _grid_item_update(gi);
762 gi->wsd->finish_num++;
763 efl_event_callback_legacy_call
764 ((gi->wsd)->obj, ELM_MAP_EVENT_TILE_LOADED, NULL);
765 }
766 else
767 {
768 WRN("Download failed from %s to %s (%d) ", gi->url, gi->file, status);
769
770 ecore_file_remove(gi->file);
771 gi->file_have = EINA_FALSE;
772 efl_event_callback_legacy_call
773 ((gi->wsd)->obj, ELM_MAP_EVENT_TILE_LOADED_FAIL, NULL);
774 }
775
776 ELM_WIDGET_DATA_GET_OR_RETURN(gi->wsd->obj, wd);
777 gi->job = NULL;
778 gi->wsd->download_num--;
779 if (!gi->wsd->download_num)
780 edje_object_signal_emit(wd->resize_obj,
781 "elm,state,busy,stop", "elm");
782}
783
784static Eina_Bool
785_download_job(void *data)
786{
787 Evas_Object *obj = data;
788 ELM_MAP_DATA_GET(obj, sd);
789 Eina_List *l, *ll;
790 Grid_Item *gi;
791 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, ECORE_CALLBACK_CANCEL);
792
793 if (!eina_list_count(sd->download_list))
794 {
795 sd->download_idler = NULL;
796 return ECORE_CALLBACK_CANCEL;
797 }
798
799 EINA_LIST_REVERSE_FOREACH_SAFE(sd->download_list, l, ll, gi)
800 {
801 Eina_Bool ret, file_exists;
802
803 if ((gi->g->zoom != sd->zoom) || !(_grid_item_in_viewport(gi)))
804 {
805 sd->download_list = eina_list_remove(sd->download_list, gi);
806 continue;
807 }
808 if (sd->download_num >= MAX_CONCURRENT_DOWNLOAD)
809 return ECORE_CALLBACK_RENEW;
810
811 file_exists = ecore_file_exists(gi->file);
812 if (!file_exists)
813 {
814 /* Check here if we can download into this directory even if this one
815 disappear due to some user black magic */
816 char *dir_path;
817 dir_path = ecore_file_dir_get(gi->file);
818 if (!ecore_file_exists(dir_path)) ecore_file_mkpath(dir_path);
819 free(dir_path);
820 ret = ecore_file_download_full
821 (gi->url, gi->file, _downloaded_cb, NULL, gi, &(gi->job), sd->ua);
822
823 if ((!ret) || (!gi->job))
824 {
825 ERR("Can't start to download from %s to %s", gi->url, gi->file);
826 continue;
827 }
828 sd->try_num++;
829 sd->download_num++;
830 }
831 sd->download_list = eina_list_remove(sd->download_list, gi);
832 efl_event_callback_legacy_call
833 (obj, ELM_MAP_EVENT_TILE_LOAD, NULL);
834 if (sd->download_num == 1)
835 edje_object_signal_emit(wd->resize_obj,
836 "elm,state,busy,start", "elm");
837 if (file_exists)
838 {
839 /* It seem the file already exists, try to load it and let
840 _grid_item_update do his job. If this file isn't a image the func
841 will invalidate it and try to redownload it. */
842 _grid_item_update(gi);
843 gi->wsd->finish_num++;
844 efl_event_callback_legacy_call
845 ((gi->wsd)->obj, ELM_MAP_EVENT_TILE_LOADED, NULL);
846 }
847 }
848
849 return ECORE_CALLBACK_RENEW;
850}
851
852static void
853_grid_viewport_get(Grid *g,
854 int *x,
855 int *y,
856 int *w,
857 int *h)
858{
859 int xx, yy, ww, hh;
860 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
861
862 EINA_SAFETY_ON_NULL_RETURN(g);
863
864 _viewport_coord_get(g->wsd, &vx, &vy, &vw, &vh);
865 if (vx < 0) vx = 0;
866 if (vy < 0) vy = 0;
867
868 xx = (vx / g->wsd->size.tile) - 1;
869 if (xx < 0) xx = 0;
870
871 yy = (vy / g->wsd->size.tile) - 1;
872 if (yy < 0) yy = 0;
873
874 ww = (vw / g->wsd->size.tile) + 3;
875 if (xx + ww >= g->tw) ww = g->tw - xx;
876
877 hh = (vh / g->wsd->size.tile) + 3;
878 if (yy + hh >= g->th) hh = g->th - yy;
879
880 if (x) *x = xx;
881 if (y) *y = yy;
882 if (w) *w = ww;
883 if (h) *h = hh;
884}
885
886static void
887_grid_unload(Grid *g)
888{
889 Eina_Matrixsparse_Cell *cell;
890 Eina_Iterator *it;
891 Grid_Item *gi;
892
893 EINA_SAFETY_ON_NULL_RETURN(g);
894
895 it = eina_matrixsparse_iterator_new(g->grid);
896 EINA_ITERATOR_FOREACH(it, cell)
897 {
898 gi = eina_matrixsparse_cell_data_get(cell);
899 _grid_item_unload(gi);
900 }
901 eina_iterator_free(it);
902}
903
904static void
905_grid_load(Grid *g)
906{
907 Eina_Matrixsparse_Cell *cell;
908 int x, y, xx, yy, ww, hh;
909 Eina_Iterator *it;
910 Grid_Item *gi;
911
912 EINA_SAFETY_ON_NULL_RETURN(g);
913
914 it = eina_matrixsparse_iterator_new(g->grid);
915 EINA_ITERATOR_FOREACH(it, cell)
916 {
917 gi = eina_matrixsparse_cell_data_get(cell);
918 if (!_grid_item_in_viewport(gi)) _grid_item_unload(gi);
919 }
920 eina_iterator_free(it);
921
922 _grid_viewport_get(g, &xx, &yy, &ww, &hh);
923 for (y = yy; y < yy + hh; y++)
924 {
925 for (x = xx; x < xx + ww; x++)
926 {
927 gi = eina_matrixsparse_data_idx_get(g->grid, y, x);
928 if (!gi) gi = _grid_item_create(g, x, y);
929 _grid_item_load(gi);
930 }
931 }
932}
933
934static void
935_grid_place(Elm_Map_Data *sd)
936{
937 Eina_List *l;
938 Grid *g;
939
940 EINA_SAFETY_ON_NULL_RETURN(sd);
941
942 EINA_LIST_FOREACH(sd->grids, l, g)
943 {
944 if (sd->zoom == g->zoom) _grid_load(g);
945 else _grid_unload(g);
946 }
947 if (!sd->download_idler)
948 sd->download_idler = ecore_idler_add(_download_job, sd->obj);
949}
950
951static void
952_grid_all_create(Elm_Map_Data *sd)
953{
954 int zoom;
955
956 EINA_SAFETY_ON_NULL_RETURN(sd->src_tile);
957
958 for (zoom = sd->src_tile->zoom_min; zoom <= sd->src_tile->zoom_max; zoom++)
959 {
960 Grid *g;
961 int tnum;
962
963 g = ELM_NEW(Grid);
964 g->wsd = sd;
965 g->zoom = zoom;
966 tnum = pow(2.0, g->zoom);
967 g->tw = tnum;
968 g->th = tnum;
969 g->grid = eina_matrixsparse_new(g->th, g->tw, NULL, NULL);
970 sd->grids = eina_list_append(sd->grids, g);
971 }
972}
973
974static void
975_grid_all_clear(Elm_Map_Data *sd)
976{
977 Grid *g;
978
979 EINA_SAFETY_ON_NULL_RETURN(sd);
980
981 EINA_LIST_FREE(sd->grids, g)
982 {
983 Eina_Matrixsparse_Cell *cell;
984 Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
985
986 EINA_ITERATOR_FOREACH(it, cell)
987 {
988 Grid_Item *gi;
989
990 gi = eina_matrixsparse_cell_data_get(cell);
991 if (gi) _grid_item_free(gi);
992 }
993 eina_iterator_free(it);
994
995 eina_matrixsparse_free(g->grid);
996 free(g);
997 }
998}
999
1000static void
1001_track_place(Elm_Map_Data *sd)
1002{
1003#ifdef ELM_EMAP
1004 Eina_List *l;
1005 Evas_Coord size;
1006 Evas_Object *route;
1007 Evas_Coord px, py, ow, oh;
1008 int xmin, xmax, ymin, ymax;
1009
1010 px = sd->pan_x;
1011 py = sd->pan_y;
1012 _viewport_coord_get(sd, NULL, NULL, &ow, &oh);
1013
1014 size = sd->size.w;
1015
1016 EINA_LIST_FOREACH(sd->track, l, route)
1017 {
1018 double lon_min, lon_max;
1019 double lat_min, lat_max;
1020
1021 elm_route_longitude_min_max_get(route, &lon_min, &lon_max);
1022 elm_route_latitude_min_max_get(route, &lat_min, &lat_max);
1023 _region_to_coord_convert(sd, lon_min, lat_max, size, &xmin, &ymin);
1024 _region_to_coord_convert(sd, lon_max, lat_min, size, &xmax, &ymax);
1025
1026 if ( !(xmin < px && xmax < px) && !(xmin > px + ow && xmax > px + ow))
1027 {
1028 if ((ymin < py && ymax < py) ||
1029 (ymin > py + oh && ymax > py + oh))
1030 {
1031 //display the route
1032 evas_object_geometry_set(route, xmin - px, ymin - py,
1033 xmax - xmin, ymax - ymin);
1034 evas_object_raise(route);
1035 _obj_rotate(sd, route);
1036 evas_object_show(route);
1037
1038 continue;
1039 }
1040 }
1041 //the route is not display
1042 evas_object_hide(route);
1043 }
1044#else
1045 (void)sd;
1046#endif
1047}
1048
1049static void
1050_calc_job(Elm_Map_Data *sd)
1051{
1052 if (sd->calc_job.zoom_mode_set)
1053 {
1054 sd->calc_job.zoom_mode_set(sd, sd->calc_job.zoom);
1055 sd->calc_job.zoom_mode_set = NULL;
1056 }
1057 if (!sd->zoom_animator)
1058 {
1059 if (sd->calc_job.region_show_bring_in)
1060 {
1061 sd->calc_job.region_show_bring_in
1062 (sd, sd->calc_job.lon, sd->calc_job.lat, sd->calc_job.bring_in);
1063 sd->calc_job.region_show_bring_in = NULL;
1064 }
1065 if (sd->calc_job.overlays_show)
1066 {
1067 sd->calc_job.overlays_show(sd, sd->calc_job.overlays);
1068 sd->calc_job.overlays_show = NULL;
1069 }
1070 }
1071}
1072
1073static void
1074_smooth_update(Elm_Map_Data *sd)
1075{
1076 Eina_List *l;
1077 Grid *g;
1078
1079 EINA_LIST_FOREACH(sd->grids, l, g)
1080 {
1081 Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
1082 Eina_Matrixsparse_Cell *cell;
1083
1084 EINA_ITERATOR_FOREACH(it, cell)
1085 {
1086 Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
1087 if (_grid_item_in_viewport(gi))
1088 evas_object_image_smooth_scale_set(gi->img, EINA_TRUE);
1089 }
1090 eina_iterator_free(it);
1091 }
1092}
1093
1094static Eina_Bool
1095_zoom_timeout_cb(void *data)
1096{
1097 ELM_MAP_DATA_GET(data, sd);
1098
1099 _smooth_update(sd);
1100 sd->zoom_timer = NULL;
1101 efl_event_callback_legacy_call
1102 (sd->obj, EFL_UI_EVENT_ZOOM_STOP, NULL);
1103
1104 return ECORE_CALLBACK_CANCEL;
1105}
1106
1107static void
1108_zoom_do(Elm_Map_Data *sd,
1109 double zoom)
1110{
1111 Evas_Coord vx, vy, vw, vh;
1112 Evas_Coord ow, oh;
1113
1114 if (zoom > sd->src_tile->zoom_max) zoom = sd->src_tile->zoom_max;
1115 else if (zoom < sd->src_tile->zoom_min)
1116 zoom = sd->src_tile->zoom_min;
1117 if (zoom > sd->zoom_max) zoom = sd->zoom_max;
1118 else if (zoom < sd->zoom_min)
1119 zoom = sd->zoom_min;
1120
1121 sd->zoom = ROUND(zoom);
1122 sd->zoom_detail = zoom;
1123 ow = sd->size.w;
1124 oh = sd->size.h;
1125 sd->size.tile = pow(2.0, (zoom - sd->zoom)) * sd->tsize;
1126 sd->size.w = pow(2.0, sd->zoom) * sd->size.tile;
1127 sd->size.h = sd->size.w;
1128
1129 // Fix to zooming with (viewport center vx, vy) as the center to prevent
1130 // from zooming with (0,0) as the center. (scroller default behavior)
1131 _viewport_coord_get(sd, &vx, &vy, &vw, &vh);
1132 if ((vw > 0) && (vh > 0) && (ow > 0) && (oh > 0))
1133 {
1134 Evas_Coord x, y;
1135 double sx, sy;
1136
1137 if (vw > ow) sx = 0.5;
1138 else sx = (vx + ((double)vw / 2)) / ow;
1139 if (vh > oh) sy = 0.5;
1140 else sy = (vy + ((double)vh / 2)) / oh;
1141
1142 if (sx > 1.0) sx = 1.0;
1143 if (sy > 1.0) sy = 1.0;
1144
1145 x = ceil((sx * sd->size.w) - ((double)vw / 2));
1146 y = ceil((sy * sd->size.h) - ((double)vh / 2));
1147 if (x < 0) x = 0;
1148 else if (x > (sd->size.w - vw))
1149 x = sd->size.w - vw;
1150 if (y < 0) y = 0;
1151 else if (y > (sd->size.h - vh))
1152 y = sd->size.h - vh;
1153 elm_interface_scrollable_content_region_show
1154 (sd->obj, x, y, vw, vh);
1155 }
1156
1157 if (sd->zoom_timer)
1158 {
1159 ecore_timer_del(sd->zoom_timer);
1160 sd->zoom_timer = NULL;
1161 }
1162 else
1163 efl_event_callback_legacy_call
1164 (sd->obj, EFL_UI_EVENT_ZOOM_START, NULL);
1165
1166 sd->zoom_timer = ecore_timer_add(0.25, _zoom_timeout_cb, sd->obj);
1167 efl_event_callback_legacy_call
1168 (sd->obj, EFL_UI_EVENT_ZOOM_CHANGE, NULL);
1169
1170 efl_event_callback_legacy_call
1171 (sd->pan_obj, ELM_PAN_EVENT_CHANGED, NULL);
1172 evas_object_smart_changed(sd->pan_obj);
1173}
1174
1175static void
1176_zoom_anim_cb(void *data, const Efl_Event *event EINA_UNUSED)
1177{
1178 ELM_MAP_DATA_GET(data, sd);
1179
1180 if (sd->ani.zoom_cnt <= 0)
1181 {
1182 _zoom_animator_set(sd, NULL);
1183 evas_object_smart_changed(sd->pan_obj);
1184 _calc_job(sd);
1185 }
1186 else
1187 {
1188 sd->ani.zoom += sd->ani.zoom_diff;
1189 sd->ani.zoom_cnt--;
1190 _zoom_do(sd, sd->ani.zoom);
1191 }
1192}
1193
1194static void
1195_zoom_bring_anim_cb(void *data, const Efl_Event *event EINA_UNUSED)
1196{
1197 ELM_MAP_DATA_GET(data, sd);
1198
1199 if ((sd->ani.zoom_cnt <= 0) && (sd->ani.region_cnt <= 0))
1200 {
1201 _zoom_animator_set(sd, NULL);
1202 evas_object_smart_changed(sd->pan_obj);
1203 _calc_job(sd);
1204 }
1205 else
1206 {
1207 Evas_Coord x, y, w, h;
1208 if (sd->ani.zoom_cnt > 0)
1209 {
1210 sd->ani.zoom += sd->ani.zoom_diff;
1211 _zoom_do(sd, sd->ani.zoom);
1212 sd->ani.zoom_cnt--;
1213 }
1214 if (sd->ani.region_cnt > 0)
1215 {
1216 sd->ani.lon += sd->ani.lon_diff;
1217 sd->ani.lat += sd->ani.lat_diff;
1218
1219 _region_to_coord_convert
1220 (sd, sd->ani.lon, sd->ani.lat, sd->size.w, &x, &y);
1221 _viewport_coord_get(sd, NULL, NULL, &w, &h);
1222 x = x - (w / 2);
1223 y = y - (h / 2);
1224 elm_interface_scrollable_content_region_show(sd->obj, x, y, w, h);
1225 sd->ani.region_cnt--;
1226 }
1227 }
1228}
1229
1230static Eina_Bool
1231_zoom_animator_set(Elm_Map_Data *sd,
1232 void *callback)
1233{
1234 Eina_Bool r = EINA_FALSE;
1235
1236 sd->zoom_animator = !!callback;
1237 r = efl_event_callback_del(sd->obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _zoom_anim_cb, sd->obj);
1238 r |= efl_event_callback_del(sd->obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _zoom_bring_anim_cb, sd->obj);
1239 if (callback) efl_event_callback_add(sd->obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, callback, sd->obj);
1240
1241 return r;
1242}
1243
1244static void
1245_zoom_with_animation(Elm_Map_Data *sd,
1246 double zoom,
1247 int cnt)
1248{
1249 if (cnt == 0) return;
1250
1251 sd->ani.zoom_cnt = cnt;
1252 sd->ani.zoom = sd->zoom;
1253 sd->ani.zoom_diff = (double)(zoom - sd->zoom) / cnt;
1254 _zoom_animator_set(sd, _zoom_anim_cb);
1255}
1256
1257static void
1258_zoom_bring_with_animation(Elm_Map_Data *sd,
1259 double zoom,
1260 double lon,
1261 double lat,
1262 int zoom_cnt,
1263 int region_cnt)
1264{
1265 double tlon, tlat;
1266 Evas_Coord vx, vy, vw, vh;
1267 if ((zoom_cnt == 0) || (region_cnt == 0)) return;
1268
1269 sd->ani.zoom_cnt = zoom_cnt;
1270 sd->ani.zoom = sd->zoom;
1271 sd->ani.zoom_diff = (double)(zoom - sd->zoom) / zoom_cnt;
1272
1273 sd->ani.region_cnt = region_cnt;
1274 _viewport_coord_get(sd, &vx, &vy, &vw, &vh);
1275 _coord_to_region_convert
1276 (sd, vx + vw / 2, vy + vh / 2, sd->size.w, &tlon, &tlat);
1277 sd->ani.lon = tlon;
1278 sd->ani.lat = tlat;
1279 sd->ani.lon_diff = (lon - tlon) / region_cnt;
1280 sd->ani.lat_diff = (lat - tlat) / region_cnt;
1281
1282 _zoom_animator_set(sd, _zoom_bring_anim_cb);
1283}
1284
1285static void
1286_sizing_eval(Evas_Object *obj)
1287{
1288 Evas_Coord maxw = -1, maxh = -1;
1289
1290 evas_object_size_hint_max_get(obj, &maxw, &maxh);
1291 evas_object_size_hint_max_set(obj, maxw, maxh);
1292}
1293
1294static void
1295_changed_size_hints_cb(void *data,
1296 Evas *e EINA_UNUSED,
1297 Evas_Object *obj EINA_UNUSED,
1298 void *event_info EINA_UNUSED)
1299{
1300 _sizing_eval(data);
1301}
1302
1303static Eina_Bool
1304_scr_timeout_cb(void *data)
1305{
1306 ELM_MAP_DATA_GET(data, sd);
1307
1308 _smooth_update(sd);
1309 sd->scr_timer = NULL;
1310 evas_object_smart_callback_call(sd->obj, "scroll,drag,stop", NULL);
1311
1312 return ECORE_CALLBACK_CANCEL;
1313}
1314
1315static void
1316_scroll_cb(Evas_Object *obj,
1317 void *data EINA_UNUSED)
1318{
1319 ELM_MAP_DATA_GET(obj, sd);
1320
1321 if (sd->scr_timer) ecore_timer_del(sd->scr_timer);
1322 else
1323 evas_object_smart_callback_call(sd->obj, "scroll,drag,start", NULL);
1324 ELM_SAFE_FREE(sd->long_timer, ecore_timer_del);
1325 sd->scr_timer = ecore_timer_add(0.25, _scr_timeout_cb, obj);
1326 evas_object_smart_callback_call(sd->obj, "scroll", NULL);
1327}
1328
1329static void
1330_scroll_animate_start_cb(Evas_Object *obj,
1331 void *data EINA_UNUSED)
1332{
1333 ELM_MAP_DATA_GET(obj, sd);
1334
1335 evas_object_smart_callback_call(sd->obj, "scroll,anim,start", NULL);
1336}
1337
1338static void
1339_scroll_animate_stop_cb(Evas_Object *obj,
1340 void *data EINA_UNUSED)
1341{
1342 ELM_MAP_DATA_GET(obj, sd);
1343
1344 evas_object_smart_callback_call(sd->obj, "scroll,anim,stop", NULL);
1345}
1346
1347static Eina_Bool
1348_long_press_cb(void *data)
1349{
1350 ELM_MAP_DATA_GET(data, sd);
1351
1352 sd->long_timer = NULL;
1353
1354 evas_object_smart_callback_call(sd->obj, "longpressed", &sd->ev);
1355
1356 return ECORE_CALLBACK_CANCEL;
1357}
1358
1359static void
1360_mouse_down_cb(void *data,
1361 Evas *evas EINA_UNUSED,
1362 Evas_Object *obj EINA_UNUSED,
1363 void *event_info)
1364{
1365 ELM_MAP_DATA_GET(data, sd);
1366 Evas_Event_Mouse_Down *ev = event_info;
1367
1368 if (ev->button != 1) return;
1369 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
1370 else sd->on_hold = EINA_FALSE;
1371
1372 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1373 evas_object_smart_callback_call
1374 (sd->obj, "clicked,double", ev);
1375 else
1376 efl_event_callback_legacy_call
1377 (sd->obj, ELM_MAP_EVENT_PRESS, ev);
1378
1379 ecore_timer_del(sd->long_timer);
1380 sd->ev = *ev;
1381 sd->long_timer =
1382 ecore_timer_add(_elm_config->longpress_timeout, _long_press_cb, data);
1383}
1384
1385static void
1386_mouse_up_cb(void *data,
1387 Evas *evas EINA_UNUSED,
1388 Evas_Object *obj EINA_UNUSED,
1389 void *event_info)
1390{
1391 ELM_MAP_DATA_GET(data, sd);
1392 Evas_Event_Mouse_Up *ev = event_info;
1393
1394 EINA_SAFETY_ON_NULL_RETURN(ev);
1395
1396 if (ev->button != 1) return;
1397
1398 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
1399 else sd->on_hold = EINA_FALSE;
1400
1401 ELM_SAFE_FREE(sd->long_timer, ecore_timer_del);
1402
1403 if (!sd->on_hold)
1404
1405 evas_object_smart_callback_call
1406 (sd->obj, "clicked", ev);
1407 sd->on_hold = EINA_FALSE;
1408}
1409
1410static void
1411_mouse_wheel_cb(void *data,
1412 Evas *e EINA_UNUSED,
1413 Evas_Object *obj EINA_UNUSED,
1414 void *event_info)
1415{
1416 ELM_MAP_DATA_GET(data, sd);
1417
1418 if (!sd->paused)
1419 {
1420 Evas_Event_Mouse_Wheel *ev = event_info;
1421
1422 _zoom_do(sd, sd->zoom_detail - ((double)ev->z / 10));
1423 }
1424}
1425
1426static void
1427_region_max_min_get(Eina_List *overlays,
1428 double *max_longitude,
1429 double *min_longitude,
1430 double *max_latitude,
1431 double *min_latitude)
1432{
1433 double max_lon = -180, min_lon = 180;
1434 double max_lat = -90, min_lat = 90;
1435 Elm_Map_Overlay *overlay;
1436 Eina_List *l;
1437
1438 EINA_LIST_FOREACH(overlays, l, overlay)
1439 {
1440 double lon, lat;
1441
1442 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
1443 {
1444 Overlay_Default *ovl = overlay->ovl;
1445
1446 lon = ovl->lon;
1447 lat = ovl->lat;
1448 }
1449 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
1450 {
1451 // FIXME: class center coord is alright??
1452 Overlay_Class *ovl = overlay->ovl;
1453 double max_lo, min_lo, max_la, min_la;
1454
1455 _region_max_min_get
1456 (ovl->members, &max_lo, &min_lo, &max_la, &min_la);
1457 lon = (max_lo + min_lo) / 2;
1458 lat = (max_la + min_la) / 2;
1459 }
1460 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
1461 {
1462 Overlay_Bubble *ovl = overlay->ovl;
1463
1464 lon = ovl->lon;
1465 lat = ovl->lat;
1466 }
1467 else
1468 {
1469 WRN("Not supported overlay type: %d", overlay->type);
1470 continue;
1471 }
1472 if (lon > max_lon) max_lon = lon;
1473 if (lon < min_lon) min_lon = lon;
1474 if (lat > max_lat) max_lat = lat;
1475 if (lat < min_lat) min_lat = lat;
1476 }
1477
1478 if (max_longitude) *max_longitude = max_lon;
1479 if (min_longitude) *min_longitude = min_lon;
1480 if (max_latitude) *max_latitude = max_lat;
1481 if (min_latitude) *min_latitude = min_lat;
1482}
1483
1484static Evas_Object *
1485_icon_dup(Evas_Object *icon,
1486 Evas_Object *parent)
1487{
1488 Evas_Object *dupp;
1489 Evas_Coord w, h;
1490
1491 if (!icon || !parent) return NULL;
1492 dupp = evas_object_image_filled_add(evas_object_evas_get(parent));
1493 evas_object_image_source_set(dupp, icon);
1494 // Set size as origin' size for proxy
1495 evas_object_geometry_get(icon, NULL, NULL, &w, &h);
1496 if (w <= 0 || h <= 0)
1497 {
1498 evas_object_size_hint_combined_min_get(icon, &w, &h);
1499 evas_object_size_hint_min_set(dupp, w, h);
1500 }
1501 else evas_object_resize(dupp, w, h);
1502 // Original should have size for proxy
1503 evas_object_resize(icon, w, h);
1504
1505 return dupp;
1506}
1507
1508static void
1509_overlay_clicked_cb(void *data,
1510 Evas *e EINA_UNUSED,
1511 Evas_Object *obj EINA_UNUSED,
1512 void *ev EINA_UNUSED)
1513{
1514 Elm_Map_Overlay *overlay = data;
1515
1516 EINA_SAFETY_ON_NULL_RETURN(data);
1517
1518 efl_event_callback_legacy_call
1519 ((overlay->wsd)->obj, ELM_MAP_EVENT_OVERLAY_CLICKED, overlay);
1520 if (overlay->cb)
1521 overlay->cb(overlay->cb_data, (overlay->wsd)->obj, overlay);
1522}
1523
1524static void
1525_overlay_default_hide(Overlay_Default *ovl)
1526{
1527 EINA_SAFETY_ON_NULL_RETURN(ovl);
1528
1529 if (ovl->content) evas_object_hide(ovl->content);
1530 if (ovl->icon) evas_object_hide(ovl->icon);
1531 if (ovl->clas_content) evas_object_hide(ovl->clas_content);
1532 if (ovl->clas_icon) evas_object_hide(ovl->clas_icon);
1533 if (ovl->layout) evas_object_hide(ovl->layout);
1534}
1535
1536static void
1537_overlay_default_show(Overlay_Default *ovl)
1538{
1539 Evas_Object *disp;
1540 Evas_Coord x, y, w, h;
1541
1542 EINA_SAFETY_ON_NULL_RETURN(ovl);
1543
1544 evas_object_hide(ovl->layout);
1545 if (ovl->content)
1546 {
1547 disp = ovl->content;
1548 evas_object_geometry_get(disp, NULL, NULL, &w, &h);
1549 if (w <= 0 || h <= 0) evas_object_size_hint_combined_min_get(disp, &w, &h);
1550 ovl->w = w;
1551 ovl->h = h;
1552 }
1553 else if (!(ovl->icon) && ovl->clas_content)
1554 {
1555 disp = ovl->clas_content;
1556
1557 evas_object_geometry_get(disp, NULL, NULL, &w, &h);
1558 if (w <= 0 || h <= 0) evas_object_size_hint_combined_min_get(disp, &w, &h);
1559 }
1560 else
1561 {
1562 if (ovl->icon) evas_object_show(ovl->icon);
1563 else if (ovl->clas_icon)
1564 evas_object_show(ovl->clas_icon);
1565 disp = ovl->layout;
1566 w = ovl->w;
1567 h = ovl->h;
1568 }
1569 _coord_to_canvas(ovl->wsd, ovl->x, ovl->y, &x, &y);
1570 _obj_place(disp, x - (w / 2), y - (h / 2), w, h);
1571}
1572
1573static void
1574_overlay_default_coord_get(Overlay_Default *ovl,
1575 Evas_Coord *x,
1576 Evas_Coord *y,
1577 Evas_Coord *w,
1578 Evas_Coord *h)
1579{
1580 EINA_SAFETY_ON_NULL_RETURN(ovl);
1581
1582 if (x) *x = ovl->x;
1583 if (y) *y = ovl->y;
1584 if (w) *w = ovl->w;
1585 if (h) *h = ovl->h;
1586}
1587
1588static void
1589_overlay_default_coord_set(Overlay_Default *ovl,
1590 Evas_Coord x,
1591 Evas_Coord y)
1592{
1593 EINA_SAFETY_ON_NULL_RETURN(ovl);
1594
1595 ovl->x = x;
1596 ovl->y = y;
1597}
1598
1599static void
1600_overlay_default_coord_update(Overlay_Default *ovl)
1601{
1602 EINA_SAFETY_ON_NULL_RETURN(ovl);
1603
1604 _region_to_coord_convert
1605 (ovl->wsd, ovl->lon, ovl->lat, ovl->wsd->size.w, &ovl->x, &ovl->y);
1606}
1607
1608static void
1609_overlay_default_layout_text_update(Overlay_Default *ovl,
1610 const char *text)
1611{
1612 if (!ovl->content && !ovl->icon && !ovl->clas_content && !ovl->clas_icon)
1613 elm_layout_text_set(ovl->layout, "elm.text", text);
1614}
1615
1616static void
1617_overlay_default_content_update(Overlay_Default *ovl,
1618 Evas_Object *content,
1619 Elm_Map_Overlay *overlay)
1620{
1621 EINA_SAFETY_ON_NULL_RETURN(ovl);
1622
1623 if (ovl->content == content) return;
1624 evas_object_del(ovl->content);
1625 ovl->content = content;
1626 evas_object_smart_member_add(ovl->content, ovl->wsd->pan_obj);
1627 evas_object_stack_above(ovl->content, ovl->wsd->sep_maps_overlays);
1628
1629 if (ovl->content)
1630 evas_object_event_callback_add(ovl->content, EVAS_CALLBACK_MOUSE_DOWN,
1631 _overlay_clicked_cb, overlay);
1632}
1633
1634static void
1635_overlay_default_layout_update(Overlay_Default *ovl)
1636{
1637 EINA_SAFETY_ON_NULL_RETURN(ovl);
1638
1639 if (ovl->icon)
1640 {
1641 evas_object_color_set(ovl->layout, 255, 255, 255, 255);
1642 if (!elm_layout_theme_set
1643 (ovl->layout, "map/marker", "empty",
1644 elm_widget_style_get((ovl->wsd)->obj)))
1645 CRI("Failed to set layout!");
1646
1647 elm_object_part_content_set(ovl->layout, "elm.icon", ovl->icon);
1648 }
1649 else if (!ovl->icon && ovl->clas_icon)
1650 {
1651 evas_object_color_set(ovl->layout, 255, 255, 255, 255);
1652 if (!elm_layout_theme_set
1653 (ovl->layout, "map/marker", "empty",
1654 elm_widget_style_get((ovl->wsd)->obj)))
1655 CRI("Failed to set layout!");
1656
1657 elm_object_part_content_set(ovl->layout, "elm.icon", ovl->clas_icon);
1658 }
1659 else
1660 {
1661 evas_object_color_set
1662 (ovl->layout, ovl->c.r, ovl->c.g, ovl->c.b, ovl->c.a);
1663 if (!elm_layout_theme_set
1664 (ovl->layout, "map/marker", "radio",
1665 elm_widget_style_get((ovl->wsd)->obj)))
1666 CRI("Failed to set layout!");
1667 }
1668}
1669
1670static void
1671_overlay_default_class_content_update(Overlay_Default *ovl,
1672 Evas_Object *content)
1673{
1674 EINA_SAFETY_ON_NULL_RETURN(ovl);
1675
1676 evas_object_del(ovl->clas_content);
1677 ovl->clas_content = _icon_dup(content, ovl->layout);
1678 _overlay_default_layout_update(ovl);