2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <Elementary.h>
28 #include <Ecore_Evas.h>
35 #include <livebox-errno.h>
37 #include "script_port.h"
39 #define TEXT_CLASS "tizen"
40 #define BASE_WIDTH 720.0f
42 #define PUBLIC __attribute__((visibility("default")))
80 static inline double scale_get(void)
84 ecore_x_window_size_get(0, &width, &height);
85 return (double)width / BASE_WIDTH;
88 static inline Evas_Object *find_edje(struct info *handle, const char *id)
92 struct obj_info *obj_info;
94 EINA_LIST_FOREACH(handle->obj_list, l, edje) {
95 obj_info = evas_object_data_get(edje, "obj_info");
97 ErrPrint("Object info is not valid\n");
106 } else if (!obj_info->id) {
110 if (!strcmp(obj_info->id, id))
114 DbgPrint("EDJE[%s] is not found\n", id);
118 PUBLIC const char *script_magic_id(void)
123 PUBLIC int script_update_color(void *h, Evas *e, const char *id, const char *part, const char *rgba)
125 struct info *handle = h;
127 int r[3], g[3], b[3], a[3];
130 edje = find_edje(handle, id);
132 return LB_STATUS_ERROR_NOT_EXIST;
134 ret = sscanf(rgba, "%d %d %d %d %d %d %d %d %d %d %d %d",
135 r, g, b, a, /* OBJECT */
136 r + 1, g + 1, b + 1, a + 1, /* OUTLINE */
137 r + 2, g + 2, b + 2, a + 2); /* SHADOW */
139 DbgPrint("id[%s] part[%s] rgba[%s]\n", id, part, rgba);
140 return LB_STATUS_ERROR_INVALID;
143 ret = edje_object_color_class_set(elm_layout_edje_get(edje), part,
144 r[0], g[0], b[0], a[0], /* OBJECT */
145 r[1], g[1], b[1], a[1], /* OUTLINE */
146 r[2], g[2], b[2], a[2]); /* SHADOW */
148 DbgPrint("EDJE[%s] color class is %s changed", id, ret == EINA_TRUE ? "successfully" : "not");
149 return LB_STATUS_SUCCESS;
152 PUBLIC int script_update_text(void *h, Evas *e, const char *id, const char *part, const char *text)
154 struct info *handle = h;
157 edje = find_edje(handle, id);
159 return LB_STATUS_ERROR_NOT_EXIST;
161 elm_object_part_text_set(edje, part, text);
162 return LB_STATUS_SUCCESS;
165 static void parse_aspect(struct image_option *img_opt, const char *value, int len)
167 while (len > 0 && *value == ' ') {
175 img_opt->aspect = !strncasecmp(value, "true", 4);
176 DbgPrint("Parsed ASPECT: %d (%s)\n", img_opt->aspect, value);
179 static void parse_orient(struct image_option *img_opt, const char *value, int len)
181 while (len > 0 && *value == ' ') {
189 img_opt->orient = !strncasecmp(value, "true", 4);
190 DbgPrint("Parsed ORIENT: %d (%s)\n", img_opt->aspect, value);
193 static void parse_size(struct image_option *img_opt, const char *value, int len)
199 while (len > 0 && *value == ' ') {
204 buf = strndup(value, len);
206 ErrPrint("Heap: %s\n", strerror(errno));
210 if (sscanf(buf, "%dx%d", &width, &height) == 2) {
211 img_opt->width = width;
212 img_opt->height = height;
213 DbgPrint("Parsed size : %dx%d (%s)\n", width, height, buf);
215 DbgPrint("Invalid size tag[%s]\n", buf);
221 static void parse_fill(struct image_option *img_opt, const char *value, int len)
223 while (len > 0 && *value == ' ') {
228 if (!strncasecmp(value, "in-size", len))
229 img_opt->fill = FILL_IN_SIZE;
230 else if (!strncasecmp(value, "over-size", len))
231 img_opt->fill = FILL_OVER_SIZE;
233 img_opt->fill = FILL_DISABLE;
235 DbgPrint("Parsed FILL: %d (%s)\n", img_opt->fill, value);
238 static inline void parse_image_option(const char *option, struct image_option *img_opt)
245 void (*handler)(struct image_option *img_opt, const char *value, int len);
248 .cmd = "aspect", /* Keep the aspect ratio */
249 .handler = parse_aspect,
252 .cmd = "orient", /* Keep the orientation value: for the rotated images */
253 .handler = parse_orient,
256 .cmd = "fill", /* Fill the image to its container */
257 .handler = parse_fill, /* Value: in-size, over-size, disable(default) */
261 .handler = parse_size,
275 if (!option || !*option)
281 * GCC 4.7 warnings uninitialized idx and tag value.
282 * But it will be initialized by the state machine. :(
283 * Anyway, I just reset idx and tag for reducing the GCC4.7 complains.
290 for (ptr = option; state != STATE_END; ptr++) {
305 cmd = cmd_list[tag].cmd;
311 } else if (*ptr == '\0') {
316 if (cmd[idx] == '\0' && (*ptr == ' ' || *ptr == '\t' || *ptr == '=')) {
321 state = STATE_IGNORE;
324 } else if (*ptr == '\0') {
326 } else if (cmd[idx] == *ptr) {
332 if (tag == sizeof(cmd_list) / sizeof(cmd_list[0])) {
336 cmd = cmd_list[tag].cmd;
342 if (*ptr == ';' || *ptr == '\0') {
343 cmd_list[tag].handler(img_opt, value + 1, idx);
344 state = *ptr ? STATE_START : STATE_END;
352 else if (*ptr == '\0')
361 PUBLIC int script_update_image(void *_h, Evas *e, const char *id, const char *part, const char *path, const char *option)
363 struct info *handle = _h;
368 struct obj_info *obj_info;
370 struct image_option img_opt = {
373 .fill = FILL_DISABLE,
378 edje = find_edje(handle, id);
380 ErrPrint("No such object: %s\n", id);
381 return LB_STATUS_ERROR_NOT_EXIST;
384 obj_info = evas_object_data_get(edje, "obj_info");
386 ErrPrint("Object info is not available\n");
387 return LB_STATUS_ERROR_FAULT;
390 img = elm_object_part_content_unset(edje, part);
395 EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
396 if (child->obj != img)
399 obj_info->children = eina_list_remove(obj_info->children, child);
405 DbgPrint("delete object %s %p\n", part, img);
406 evas_object_del(img);
409 if (!path || !strlen(path) || access(path, R_OK) != 0) {
410 DbgPrint("SKIP - Path: [%s]\n", path);
411 return LB_STATUS_SUCCESS;
414 child = malloc(sizeof(*child));
416 ErrPrint("Heap: %s\n", strerror(errno));
417 return LB_STATUS_ERROR_MEMORY;
420 child->part = strdup(part);
422 ErrPrint("Heap: %s\n", strerror(errno));
424 return LB_STATUS_ERROR_MEMORY;
427 img = evas_object_image_add(e);
429 ErrPrint("Failed to add an image object\n");
432 return LB_STATUS_ERROR_FAULT;
435 evas_object_image_preload(img, EINA_FALSE);
436 parse_image_option(option, &img_opt);
437 evas_object_image_load_orientation_set(img, img_opt.orient);
439 evas_object_image_file_set(img, path, NULL);
440 err = evas_object_image_load_error_get(img);
441 if (err != EVAS_LOAD_ERROR_NONE) {
442 ErrPrint("Load error: %s\n", evas_load_error_str(err));
443 evas_object_del(img);
446 return LB_STATUS_ERROR_IO;
449 evas_object_image_size_get(img, &w, &h);
450 if (img_opt.aspect) {
451 if (img_opt.fill == FILL_OVER_SIZE) {
455 if (img_opt.width >= 0 && img_opt.height >= 0) {
456 part_w = img_opt.width * scale_get();
457 part_h = img_opt.height * scale_get();
461 edje_object_part_geometry_get(elm_layout_edje_get(edje), part, NULL, NULL, &part_w, &part_h);
463 DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h);
465 if (part_w > w || part_h > h) {
469 fw = (double)part_w / (double)w;
470 fh = (double)part_h / (double)h;
480 DbgPrint("Size: %dx%d\n", w, h);
482 evas_object_image_load_size_set(img, w, h);
483 evas_object_image_load_region_set(img, (w - part_w) / 2, (h - part_h) / 2, part_w, part_h);
484 evas_object_image_fill_set(img, 0, 0, part_w, part_h);
485 evas_object_image_reload(img);
487 evas_object_image_fill_set(img, 0, 0, w, h);
488 evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
489 evas_object_size_hint_aspect_set(img, EVAS_ASPECT_CONTROL_BOTH, w, h);
492 if (img_opt.width >= 0 && img_opt.height >= 0) {
495 DbgPrint("Using given image size: %dx%d\n", w, h);
498 evas_object_image_fill_set(img, 0, 0, w, h);
499 evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
500 evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
505 * object will be shown by below statement automatically
507 DbgPrint("%s part swallow image %p (%dx%d)\n", part, img, w, h);
509 elm_object_part_content_set(edje, part, img);
510 obj_info->children = eina_list_append(obj_info->children, child);
512 return LB_STATUS_SUCCESS;
515 static void script_signal_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
517 struct info *handle = data;
529 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
530 edje_object_part_geometry_get(elm_layout_edje_get(obj), source, &px, &py, &pw, &ph);
534 sx = (double)px / (double)w;
535 ex = (double)(px + pw) / (double)w;
540 sy = (double)py / (double)h;
541 ey = (double)(py + ph) / (double)h;
544 DbgPrint("Signal emit: source[%s], emission[%s]\n", source, emission);
545 script_signal_emit(handle->e, source, emission, sx, sy, ex, ey);
548 static void edje_del_cb(void *_info, Evas *e, Evas_Object *obj, void *event_info)
550 struct info *handle = _info;
551 struct obj_info *obj_info;
554 handle->obj_list = eina_list_remove(handle->obj_list, obj);
556 obj_info = evas_object_data_del(obj, "obj_info");
558 ErrPrint("Object info is not valid\n");
562 DbgPrint("delete object %s %p\n", obj_info->id, obj);
564 elm_object_signal_callback_del(obj, "*", "*", script_signal_cb);
566 EINA_LIST_FREE(obj_info->children, child) {
567 DbgPrint("delete object %s %p\n", child->part, child->obj);
569 evas_object_del(child->obj);
578 PUBLIC int script_update_script(void *h, Evas *e, const char *src_id, const char *target_id, const char *part, const char *path, const char *group)
580 struct info *handle = h;
583 struct obj_info *obj_info;
586 DbgPrint("src_id[%s] target_id[%s] part[%s] path[%s] group[%s]\n", src_id, target_id, part, path, group);
588 edje = find_edje(handle, src_id);
590 ErrPrint("Edje is not exists\n");
591 return LB_STATUS_ERROR_NOT_EXIST;
594 obj_info = evas_object_data_get(edje, "obj_info");
596 ErrPrint("Object info is not valid\n");
597 return LB_STATUS_ERROR_INVALID;
600 obj = elm_object_part_content_unset(edje, part);
605 EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
606 if (child->obj != obj)
609 obj_info->children = eina_list_remove(obj_info->children, child);
615 DbgPrint("delete object %s %p\n", part, obj);
616 evas_object_del(obj);
619 if (!path || !strlen(path) || access(path, R_OK) != 0) {
620 DbgPrint("SKIP - Path: [%s]\n", path);
621 return LB_STATUS_SUCCESS;
624 obj = elm_layout_add(edje);
626 ErrPrint("Failed to add a new edje object\n");
627 return LB_STATUS_ERROR_FAULT;
630 if (!elm_layout_file_set(obj, path, group)) {
634 err = edje_object_load_error_get(elm_layout_edje_get(obj));
635 errmsg = edje_load_error_str(err);
636 ErrPrint("Could not load %s from %s: %s\n", group, path, errmsg);
637 evas_object_del(obj);
638 return LB_STATUS_ERROR_IO;
641 evas_object_show(obj);
643 obj_info = calloc(1, sizeof(*obj_info));
645 ErrPrint("Failed to add a obj_info\n");
646 evas_object_del(obj);
647 return LB_STATUS_ERROR_MEMORY;
650 obj_info->id = strdup(target_id);
652 ErrPrint("Failed to add a obj_info\n");
654 evas_object_del(obj);
655 return LB_STATUS_ERROR_MEMORY;
658 child = malloc(sizeof(*child));
660 ErrPrint("Error: %s\n", strerror(errno));
663 evas_object_del(obj);
664 return LB_STATUS_ERROR_MEMORY;
667 child->part = strdup(part);
669 ErrPrint("Error: %s\n", strerror(errno));
673 evas_object_del(obj);
674 return LB_STATUS_ERROR_MEMORY;
679 evas_object_data_set(obj, "obj_info", obj_info);
680 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, edje_del_cb, handle);
681 elm_object_signal_callback_add(obj, "*", "*", script_signal_cb, handle);
682 handle->obj_list = eina_list_append(handle->obj_list, obj);
684 DbgPrint("%s part swallow edje %p\n", part, obj);
685 elm_object_part_content_set(edje, part, obj);
686 obj_info = evas_object_data_get(edje, "obj_info");
687 obj_info->children = eina_list_append(obj_info->children, child);
688 return LB_STATUS_SUCCESS;
691 PUBLIC int script_update_signal(void *h, Evas *e, const char *id, const char *part, const char *signal)
693 struct info *handle = h;
696 DbgPrint("id[%s], part[%s], signal[%s]\n", id, part, signal);
698 edje = find_edje(handle, id);
700 return LB_STATUS_ERROR_NOT_EXIST;
702 elm_object_signal_emit(edje, signal, part);
703 return LB_STATUS_SUCCESS;
706 PUBLIC int script_update_drag(void *h, Evas *e, const char *id, const char *part, double x, double y)
708 struct info *handle = h;
711 DbgPrint("id[%s], part[%s], %lfx%lf\n", id, part, x, y);
713 edje = find_edje(handle, id);
715 return LB_STATUS_ERROR_NOT_EXIST;
717 edje_object_part_drag_value_set(elm_layout_edje_get(edje), part, x, y);
718 return LB_STATUS_SUCCESS;
721 PUBLIC int script_update_size(void *han, Evas *e, const char *id, int w, int h)
723 struct info *handle = han;
726 edje = find_edje(handle, id);
728 return LB_STATUS_ERROR_NOT_EXIST;
735 DbgPrint("Resize object to %dx%d\n", w, h);
736 evas_object_resize(edje, w, h);
737 return LB_STATUS_SUCCESS;
740 PUBLIC int script_update_category(void *h, Evas *e, const char *id, const char *category)
742 struct info *handle = h;
744 DbgPrint("id[%s], category[%s]\n", id, category);
746 if (handle->category) {
747 free(handle->category);
748 handle->category = NULL;
752 return LB_STATUS_SUCCESS;
754 handle->category = strdup(category);
755 if (!handle->category) {
756 ErrPrint("Error: %s\n", strerror(errno));
757 return LB_STATUS_ERROR_MEMORY;
760 return LB_STATUS_SUCCESS;
763 PUBLIC void *script_create(const char *file, const char *group)
767 DbgPrint("file[%s], group[%s]\n", file, group);
769 handle = calloc(1, sizeof(*handle));
771 ErrPrint("Error: %s\n", strerror(errno));
775 handle->file = strdup(file);
777 ErrPrint("Error: %s\n", strerror(errno));
782 handle->group = strdup(group);
783 if (!handle->group) {
784 ErrPrint("Error: %s\n", strerror(errno));
793 PUBLIC int script_destroy(void *_handle)
800 edje = eina_list_nth(handle->obj_list, 0);
802 evas_object_del(edje);
804 free(handle->category);
808 return LB_STATUS_SUCCESS;
811 PUBLIC int script_load(void *_handle, Evas *e, int w, int h)
815 struct obj_info *obj_info;
819 obj_info = calloc(1, sizeof(*obj_info));
821 ErrPrint("Heap: %s\n", strerror(errno));
822 return LB_STATUS_ERROR_MEMORY;
825 obj_info->win = evas_object_rectangle_add(e);
826 if (!obj_info->win) {
828 return LB_STATUS_ERROR_FAULT;
831 edje = elm_layout_add(obj_info->win);
833 ErrPrint("Failed to create an edje object\n");
834 evas_object_del(obj_info->win);
836 return LB_STATUS_ERROR_FAULT;
839 DbgPrint("Load edje: %s - %s\n", handle->file, handle->group);
840 if (!elm_layout_file_set(edje, handle->file, handle->group)) {
844 err = edje_object_load_error_get(elm_layout_edje_get(edje));
845 errmsg = edje_load_error_str(err);
846 ErrPrint("Could not load %s from %s: %s\n", handle->group, handle->file, errmsg);
847 evas_object_del(edje);
848 evas_object_del(obj_info->win);
850 return LB_STATUS_ERROR_IO;
857 elm_object_signal_callback_add(edje, "*", "*", script_signal_cb, handle);
858 evas_object_event_callback_add(edje, EVAS_CALLBACK_DEL, edje_del_cb, handle);
859 evas_object_size_hint_weight_set(edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
860 evas_object_size_hint_fill_set(edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
861 evas_object_resize(edje, handle->w, handle->h);
862 evas_object_show(edje);
863 evas_object_data_set(edje, "obj_info", obj_info);
865 handle->obj_list = eina_list_append(handle->obj_list, edje);
866 return LB_STATUS_SUCCESS;
869 PUBLIC int script_unload(void *_handle, Evas *e)
876 DbgPrint("Unload edje: %s - %s\n", handle->file, handle->group);
877 edje = eina_list_nth(handle->obj_list, 0);
879 evas_object_del(edje);
881 return LB_STATUS_SUCCESS;
884 PUBLIC int script_init(void)
890 /* ecore is already initialized */
892 elm_config_scale_set(scale_get());
894 return LB_STATUS_SUCCESS;
897 PUBLIC int script_fini(void)
900 return LB_STATUS_SUCCESS;