2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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://floralicense.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>
32 #include <system_settings.h>
37 #include <livebox-errno.h>
38 #include <livebox-service.h>
40 #include "script_port.h"
42 #define TEXT_CLASS "tizen"
43 #define DEFAULT_FONT_SIZE -100
45 #define PUBLIC __attribute__((visibility("default")))
83 Eina_List *access_chain;
90 Eina_List *handle_list;
98 static inline Evas_Object *find_edje(struct info *handle, const char *id)
102 struct obj_info *obj_info;
104 EINA_LIST_FOREACH(handle->obj_list, l, edje) {
105 obj_info = evas_object_data_get(edje, "obj_info");
107 ErrPrint("Object info is not valid\n");
117 } else if (!obj_info->id) {
121 if (!strcmp(obj_info->id, id)) {
126 DbgPrint("EDJE[%s] is not found\n", id);
130 static inline void rebuild_focus_chain(Evas_Object *obj)
132 struct obj_info *obj_info;
136 obj_info = evas_object_data_get(obj, "obj_info");
138 ErrPrint("Object info is not available\n");
142 elm_object_focus_custom_chain_unset(obj);
144 EINA_LIST_FOREACH(obj_info->access_chain, l, ao) {
145 DbgPrint("Append %p\n", ao);
146 elm_object_focus_custom_chain_append(obj, ao, NULL);
150 PUBLIC const char *script_magic_id(void)
155 PUBLIC int script_update_color(void *h, Evas *e, const char *id, const char *part, const char *rgba)
157 struct info *handle = h;
159 int r[3], g[3], b[3], a[3];
162 edje = find_edje(handle, id);
164 return LB_STATUS_ERROR_NOT_EXIST;
167 ret = sscanf(rgba, "%d %d %d %d %d %d %d %d %d %d %d %d",
168 r, g, b, a, /* OBJECT */
169 r + 1, g + 1, b + 1, a + 1, /* OUTLINE */
170 r + 2, g + 2, b + 2, a + 2); /* SHADOW */
172 DbgPrint("id[%s] part[%s] rgba[%s]\n", id, part, rgba);
173 return LB_STATUS_ERROR_INVALID;
176 ret = edje_object_color_class_set(elm_layout_edje_get(edje), part,
177 r[0], g[0], b[0], a[0], /* OBJECT */
178 r[1], g[1], b[1], a[1], /* OUTLINE */
179 r[2], g[2], b[2], a[2]); /* SHADOW */
181 DbgPrint("EDJE[%s] color class is %s changed", id, ret == EINA_TRUE ? "successfully" : "not");
182 return LB_STATUS_SUCCESS;
185 static void activate_cb(void *data, Evas_Object *part_obj, Elm_Object_Item *item)
196 ao = evas_object_data_get(part_obj, "ao");
201 edje = evas_object_data_get(ao, "edje");
206 e = evas_object_evas_get(part_obj);
207 evas_object_geometry_get(part_obj, &x, &y, &w, &h);
211 #if defined(_USE_ECORE_TIME_GET)
212 timestamp = ecore_time_get();
215 if (gettimeofday(&tv, NULL) < 0) {
216 ErrPrint("Failed to get time\n");
219 timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f);
223 DbgPrint("Cursor is on %dx%d\n", x, y);
224 evas_event_feed_mouse_move(e, x, y, timestamp * 1000, NULL);
225 evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, (timestamp + 0.01f) * 1000, NULL);
226 evas_event_feed_mouse_move(e, x, y, (timestamp + 0.02f) * 1000, NULL);
227 evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, (timestamp + 0.03f) * 1000, NULL);
230 PUBLIC int script_update_text(void *h, Evas *e, const char *id, const char *part, const char *text)
232 struct obj_info *obj_info;
233 struct info *handle = h;
237 edje = find_edje(handle, id);
239 ErrPrint("Failed to find EDJE\n");
240 return LB_STATUS_ERROR_NOT_EXIST;
243 obj_info = evas_object_data_get(edje, "obj_info");
245 ErrPrint("Object info is not available\n");
246 return LB_STATUS_ERROR_FAULT;
249 elm_object_part_text_set(edje, part, text ? text : "");
251 to = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(edje), part);
256 ao = evas_object_data_get(to, "ao");
258 ao = elm_access_object_register(to, edje);
260 ErrPrint("Unable to add ao: %s\n", part);
263 obj_info->access_chain = eina_list_append(obj_info->access_chain, ao);
264 evas_object_data_set(to, "ao", ao);
265 evas_object_data_set(ao, "edje", edje);
266 elm_access_activate_cb_set(ao, activate_cb, NULL);
267 elm_object_focus_custom_chain_append(edje, ao, NULL);
270 if (!text || !strlen(text)) {
271 obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
272 evas_object_data_del(to, "ao");
273 evas_object_data_del(ao, "edje");
274 elm_access_object_unregister(ao);
275 DbgPrint("[%s] Remove access object\n", part);
277 rebuild_focus_chain(edje);
281 utf8 = elm_entry_markup_to_utf8(text);
282 if ((!utf8 || !strlen(utf8))) {
285 obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
286 evas_object_data_del(to, "ao");
287 evas_object_data_del(ao, "edje");
288 elm_access_object_unregister(ao);
289 DbgPrint("[%s] Remove access object\n", part);
291 rebuild_focus_chain(edje);
295 elm_access_info_set(ao, ELM_ACCESS_INFO, utf8);
298 ErrPrint("Unable to get text part[%s]\n", part);
302 return LB_STATUS_SUCCESS;
305 static void parse_aspect(struct image_option *img_opt, const char *value, int len)
307 while (len > 0 && *value == ' ') {
316 img_opt->aspect = !strncasecmp(value, "true", 4);
317 DbgPrint("Parsed ASPECT: %d (%s)\n", img_opt->aspect, value);
320 static void parse_orient(struct image_option *img_opt, const char *value, int len)
322 while (len > 0 && *value == ' ') {
331 img_opt->orient = !strncasecmp(value, "true", 4);
332 DbgPrint("Parsed ORIENT: %d (%s)\n", img_opt->orient, value);
335 static void parse_size(struct image_option *img_opt, const char *value, int len)
341 while (len > 0 && *value == ' ') {
346 buf = strndup(value, len);
348 ErrPrint("Heap: %s\n", strerror(errno));
352 if (sscanf(buf, "%dx%d", &width, &height) == 2) {
353 img_opt->width = width;
354 img_opt->height = height;
355 DbgPrint("Parsed size : %dx%d (%s)\n", width, height, buf);
357 DbgPrint("Invalid size tag[%s]\n", buf);
363 static void parse_fill(struct image_option *img_opt, const char *value, int len)
365 while (len > 0 && *value == ' ') {
370 if (!strncasecmp(value, "in-size", len)) {
371 img_opt->fill = FILL_IN_SIZE;
372 } else if (!strncasecmp(value, "over-size", len)) {
373 img_opt->fill = FILL_OVER_SIZE;
375 img_opt->fill = FILL_DISABLE;
378 DbgPrint("Parsed FILL: %d (%s)\n", img_opt->fill, value);
381 static inline void parse_image_option(const char *option, struct image_option *img_opt)
388 void (*handler)(struct image_option *img_opt, const char *value, int len);
391 .cmd = "aspect", /* Keep the aspect ratio */
392 .handler = parse_aspect,
395 .cmd = "orient", /* Keep the orientation value: for the rotated images */
396 .handler = parse_orient,
399 .cmd = "fill", /* Fill the image to its container */
400 .handler = parse_fill, /* Value: in-size, over-size, disable(default) */
404 .handler = parse_size,
418 if (!option || !*option) {
425 * GCC 4.7 warnings uninitialized idx and tag value.
426 * But it will be initialized by the state machine. :(
427 * Anyway, I just reset idx and tag for reducing the GCC4.7 complains.
434 for (ptr = option; state != STATE_END; ptr++) {
449 cmd = cmd_list[tag].cmd;
455 } else if (*ptr == '\0') {
460 if (cmd[idx] == '\0' && (*ptr == ' ' || *ptr == '\t' || *ptr == '=')) {
465 state = STATE_IGNORE;
468 } else if (*ptr == '\0') {
470 } else if (cmd[idx] == *ptr) {
476 if (tag == sizeof(cmd_list) / sizeof(cmd_list[0])) {
480 cmd = cmd_list[tag].cmd;
486 if (*ptr == ';' || *ptr == '\0') {
487 cmd_list[tag].handler(img_opt, value + 1, idx);
488 state = *ptr ? STATE_START : STATE_END;
496 } else if (*ptr == '\0') {
506 PUBLIC int script_update_access(void *_h, Evas *e, const char *id, const char *part, const char *text, const char *option)
508 struct info *handle = _h;
510 struct obj_info *obj_info;
513 edje = find_edje(handle, id);
515 ErrPrint("No such object: %s\n", id);
516 return LB_STATUS_ERROR_NOT_EXIST;
519 obj_info = evas_object_data_get(edje, "obj_info");
521 ErrPrint("Object info is not available\n");
522 return LB_STATUS_ERROR_FAULT;
525 to = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(edje), part);
529 ao = evas_object_data_get(to, "ao");
531 if (text && strlen(text)) {
532 elm_access_info_set(ao, ELM_ACCESS_INFO, text);
534 obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
535 evas_object_data_del(to, "ao");
536 evas_object_data_del(ao, "edje");
537 elm_access_object_unregister(ao);
538 DbgPrint("Successfully unregistered\n");
540 rebuild_focus_chain(edje);
542 } else if (text && strlen(text)) {
543 ao = elm_access_object_register(to, edje);
545 ErrPrint("Unable to register access object\n");
547 elm_access_info_set(ao, ELM_ACCESS_INFO, text);
548 obj_info->access_chain = eina_list_append(obj_info->access_chain, ao);
549 evas_object_data_set(to, "ao", ao);
550 elm_object_focus_custom_chain_append(edje, ao, NULL);
551 DbgPrint("[%s] Register access info: (%s)\n", part, text);
552 evas_object_data_set(ao, "edje", edje);
553 elm_access_activate_cb_set(ao, activate_cb, NULL);
557 ErrPrint("[%s] is not exists\n", part);
560 return LB_STATUS_SUCCESS;
563 PUBLIC int script_operate_access(void *_h, Evas *e, const char *id, const char *part, const char *operation, const char *option)
565 struct info *handle = _h;
567 struct obj_info *obj_info;
568 Elm_Access_Action_Info action_info;
571 if (!operation || !strlen(operation)) {
572 return LB_STATUS_ERROR_INVALID;
575 edje = find_edje(handle, id);
577 ErrPrint("No such object: %s\n", id);
578 return LB_STATUS_ERROR_NOT_EXIST;
581 obj_info = evas_object_data_get(edje, "obj_info");
583 ErrPrint("Object info is not available\n");
584 return LB_STATUS_ERROR_FAULT;
587 memset(&action_info, 0, sizeof(action_info));
589 /* OPERATION is defined in liblivebox package */
590 if (!strcasecmp(operation, "set,hl")) {
598 to = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(edje), part);
600 ErrPrint("Invalid part: %s\n", part);
604 evas_object_geometry_get(to, &x, &y, &w, &h);
606 action_info.x = x + w / 2;
607 action_info.y = x + h / 2;
608 } else if (option && sscanf(option, "%dx%d", &action_info.x, &action_info.y) == 2) {
610 ErrPrint("Insufficient info for HL\n");
614 DbgPrint("TXxTY: %dx%d\n", action_info.x, action_info.y);
615 ret = elm_access_action(edje, ELM_ACCESS_ACTION_HIGHLIGHT, &action_info);
616 if (ret == EINA_FALSE) {
617 ErrPrint("Action error\n");
619 } else if (!strcasecmp(operation, "unset,hl")) {
620 ret = elm_access_action(edje, ELM_ACCESS_ACTION_UNHIGHLIGHT, &action_info);
621 if (ret == EINA_FALSE) {
622 ErrPrint("Action error\n");
624 } else if (!strcasecmp(operation, "next,hl")) {
625 action_info.highlight_cycle = (!!option) && (!!strcasecmp(option, "no,cycle"));
627 ret = elm_access_action(edje, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, &action_info);
628 if (ret == EINA_FALSE) {
629 ErrPrint("Action error\n");
631 } else if (!strcasecmp(operation, "prev,hl")) {
632 action_info.highlight_cycle = EINA_TRUE;
633 ret = elm_access_action(edje, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, &action_info);
634 if (ret == EINA_FALSE) {
635 ErrPrint("Action error\n");
640 return LB_STATUS_SUCCESS;
643 PUBLIC int script_update_image(void *_h, Evas *e, const char *id, const char *part, const char *path, const char *option)
645 struct info *handle = _h;
650 struct obj_info *obj_info;
652 struct image_option img_opt = {
655 .fill = FILL_DISABLE,
660 edje = find_edje(handle, id);
662 ErrPrint("No such object: %s\n", id);
663 return LB_STATUS_ERROR_NOT_EXIST;
666 obj_info = evas_object_data_get(edje, "obj_info");
668 ErrPrint("Object info is not available\n");
669 return LB_STATUS_ERROR_FAULT;
672 img = elm_object_part_content_unset(edje, part);
678 EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
679 if (child->obj != img) {
683 obj_info->children = eina_list_remove(obj_info->children, child);
689 DbgPrint("delete object %s %p\n", part, img);
690 ao = evas_object_data_del(img, "ao");
692 obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
693 evas_object_data_del(ao, "edje");
694 elm_access_object_unregister(ao);
695 DbgPrint("Successfully unregistered\n");
697 evas_object_del(img);
699 rebuild_focus_chain(edje);
702 if (!path || !strlen(path) || access(path, R_OK) != 0) {
703 DbgPrint("SKIP - Path: [%s]\n", path);
704 return LB_STATUS_SUCCESS;
707 child = malloc(sizeof(*child));
709 ErrPrint("Heap: %s\n", strerror(errno));
710 return LB_STATUS_ERROR_MEMORY;
713 child->part = strdup(part);
715 ErrPrint("Heap: %s\n", strerror(errno));
717 return LB_STATUS_ERROR_MEMORY;
720 img = evas_object_image_add(e);
722 ErrPrint("Failed to add an image object\n");
725 return LB_STATUS_ERROR_FAULT;
728 evas_object_image_preload(img, EINA_FALSE);
729 parse_image_option(option, &img_opt);
730 evas_object_image_load_orientation_set(img, img_opt.orient);
732 evas_object_image_file_set(img, path, NULL);
733 err = evas_object_image_load_error_get(img);
734 if (err != EVAS_LOAD_ERROR_NONE) {
735 ErrPrint("Load error: %s\n", evas_load_error_str(err));
736 evas_object_del(img);
739 return LB_STATUS_ERROR_IO;
742 evas_object_image_size_get(img, &w, &h);
743 if (img_opt.aspect) {
744 if (img_opt.fill == FILL_OVER_SIZE) {
748 if (img_opt.width >= 0 && img_opt.height >= 0) {
749 part_w = img_opt.width * elm_config_scale_get();
750 part_h = img_opt.height * elm_config_scale_get();
754 edje_object_part_geometry_get(elm_layout_edje_get(edje), part, NULL, NULL, &part_w, &part_h);
756 DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h);
758 if (part_w > w || part_h > h) {
762 fw = (double)part_w / (double)w;
763 fh = (double)part_h / (double)h;
774 if (!part_w || !part_h || !w || !h) {
775 evas_object_del(img);
778 return LB_STATUS_ERROR_INVALID;
781 if (evas_object_image_region_support_get(img)) {
782 evas_object_image_load_region_set(img, (w - part_w) / 2, (h - part_h) / 2, part_w, part_h);
783 evas_object_image_load_size_set(img, part_w, part_h);
784 evas_object_image_filled_set(img, EINA_TRUE);
785 //evas_object_image_fill_set(img, 0, 0, part_w, part_h);
786 DbgPrint("Size: %dx%d (region: %dx%d - %dx%d)\n", w, h, (w - part_w) / 2, (h - part_h) / 2, part_w, part_h);
790 Evas_Object *src_img;
794 DbgPrint("Part loading is not supported\n");
795 ee = ecore_evas_buffer_new(part_w, part_h);
797 ErrPrint("Failed to create a EE\n");
798 evas_object_del(img);
801 return LB_STATUS_ERROR_FAULT;
804 ecore_evas_alpha_set(ee, EINA_TRUE);
806 e = ecore_evas_get(ee);
808 ErrPrint("Unable to get Evas\n");
811 evas_object_del(img);
814 return LB_STATUS_ERROR_FAULT;
817 src_img = evas_object_image_filled_add(e);
819 ErrPrint("Unable to add an image\n");
822 evas_object_del(img);
825 return LB_STATUS_ERROR_FAULT;
828 evas_object_image_alpha_set(src_img, EINA_TRUE);
829 evas_object_image_colorspace_set(src_img, EVAS_COLORSPACE_ARGB8888);
830 evas_object_image_smooth_scale_set(src_img, EINA_TRUE);
831 evas_object_image_load_orientation_set(src_img, img_opt.orient);
832 evas_object_image_file_set(src_img, path, NULL);
833 err = evas_object_image_load_error_get(src_img);
834 if (err != EVAS_LOAD_ERROR_NONE) {
835 ErrPrint("Load error: %s\n", evas_load_error_str(err));
836 evas_object_del(src_img);
839 evas_object_del(img);
842 return LB_STATUS_ERROR_IO;
844 evas_object_image_size_get(src_img, &rw, &rh);
845 evas_object_image_fill_set(src_img, 0, 0, rw, rh);
846 evas_object_resize(src_img, w, h);
847 evas_object_move(src_img, -(w - part_w) / 2, -(h - part_h) / 2);
848 evas_object_show(src_img);
850 data = ecore_evas_buffer_pixels_get(ee);
852 ErrPrint("Unable to get pixels\n");
853 evas_object_del(src_img);
856 evas_object_del(img);
859 return LB_STATUS_ERROR_IO;
862 e = evas_object_evas_get(img);
863 evas_object_del(img);
864 img = evas_object_image_filled_add(e);
866 evas_object_del(src_img);
871 return LB_STATUS_ERROR_MEMORY;
874 evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
875 evas_object_image_smooth_scale_set(img, EINA_TRUE);
876 evas_object_image_alpha_set(img, EINA_TRUE);
877 evas_object_image_data_set(img, NULL);
878 evas_object_image_size_set(img, part_w, part_h);
879 evas_object_resize(img, part_w, part_h);
880 evas_object_image_data_copy_set(img, (void *)data);
881 evas_object_image_fill_set(img, 0, 0, part_w, part_h);
882 evas_object_image_data_update_add(img, 0, 0, part_w, part_h);
884 evas_object_del(src_img);
887 } else if (img_opt.fill == FILL_IN_SIZE) {
891 if (img_opt.width >= 0 && img_opt.height >= 0) {
892 part_w = img_opt.width * elm_config_scale_get();
893 part_h = img_opt.height * elm_config_scale_get();
897 edje_object_part_geometry_get(elm_layout_edje_get(edje), part, NULL, NULL, &part_w, &part_h);
899 DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h);
901 if (part_w > w || part_h > h) {
905 fw = (double)part_w / (double)w;
906 fh = (double)part_h / (double)h;
916 DbgPrint("Size: %dx%d\n", w, h);
917 evas_object_image_fill_set(img, 0, 0, part_w, part_h);
918 evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
919 evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
921 evas_object_image_fill_set(img, 0, 0, w, h);
922 evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
923 evas_object_size_hint_aspect_set(img, EVAS_ASPECT_CONTROL_BOTH, w, h);
926 if (img_opt.width >= 0 && img_opt.height >= 0) {
929 DbgPrint("Using given image size: %dx%d\n", w, h);
932 evas_object_image_fill_set(img, 0, 0, w, h);
933 evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
934 evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
935 evas_object_image_filled_set(img, EINA_TRUE);
940 * object will be shown by below statement automatically
942 DbgPrint("%s part swallow image %p (%dx%d)\n", part, img, w, h);
944 elm_object_part_content_set(edje, part, img);
945 obj_info->children = eina_list_append(obj_info->children, child);
949 * This object is not registered as an access object.
950 * So the developer should add it to access list manually, using DESC_ACCESS block.
952 return LB_STATUS_SUCCESS;
955 static void script_signal_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
957 struct info *handle = data;
969 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
970 edje_object_part_geometry_get(elm_layout_edje_get(obj), source, &px, &py, &pw, &ph);
974 sx = (double)px / (double)w;
975 ex = (double)(px + pw) / (double)w;
980 sy = (double)py / (double)h;
981 ey = (double)(py + ph) / (double)h;
984 script_signal_emit(handle->e, source, emission, sx, sy, ex, ey);
987 static void edje_del_cb(void *_info, Evas *e, Evas_Object *obj, void *event_info)
989 struct info *handle = _info;
990 struct obj_info *obj_info;
991 struct obj_info *parent_obj_info;
995 handle->obj_list = eina_list_remove(handle->obj_list, obj);
997 obj_info = evas_object_data_del(obj, "obj_info");
999 ErrPrint("Object info is not valid\n");
1003 DbgPrint("delete object %s %p\n", obj_info->id, obj);
1004 parent_obj_info = evas_object_data_get(obj_info->parent, "obj_info");
1005 if (parent_obj_info) {
1009 EINA_LIST_FOREACH_SAFE(parent_obj_info->children, l, n, child) {
1010 if (child->obj != obj) {
1016 * If this code is executed,
1017 * The parent is not deleted by desc, this object is deleted by itself.
1018 * It is not possible, but we care it.
1020 DbgPrint("Parent's children is updated: %s\n", child->part);
1021 parent_obj_info->children = eina_list_remove(parent_obj_info->children, child);
1027 DbgPrint("Parent EDJE\n");
1030 elm_object_signal_callback_del(obj, "*", "*", script_signal_cb);
1032 elm_object_focus_custom_chain_unset(obj);
1034 EINA_LIST_FREE(obj_info->children, child) {
1035 DbgPrint("delete object %s %p\n", child->part, child->obj);
1038 ao = evas_object_data_del(child->obj, "ao");
1040 obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
1041 evas_object_data_del(ao, "edje");
1042 elm_access_object_unregister(ao);
1044 evas_object_del(child->obj);
1050 EINA_LIST_FREE(obj_info->access_chain, ao) {
1051 evas_object_data_del(ao, "edje");
1052 elm_access_object_unregister(ao);
1059 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
1061 Evas_Object *o, *ho;
1063 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
1064 if (!o) return NULL;
1066 ho = evas_object_data_get(o, "_elm_access_target");
1071 LB_ACCESS_HIGHLIGHT 0
1072 LB_ACCESS_HIGHLIGHT_NEXT 1
1073 LB_ACCESS_HIGHLIGHT_PREV 2
1074 LB_ACCESS_ACTIVATE 3
1078 PUBLIC int script_feed_event(void *h, Evas *e, int event_type, int x, int y, int down, double timestamp)
1080 struct info *handle = h;
1082 struct obj_info *obj_info;
1083 int ret = LB_STATUS_SUCCESS;
1085 edje = find_edje(handle, NULL); /*!< Get the base layout */
1087 ErrPrint("Base layout is not exist\n");
1088 return LB_STATUS_ERROR_NOT_EXIST;
1091 obj_info = evas_object_data_get(edje, "obj_info");
1093 ErrPrint("Object info is not valid\n");
1094 return LB_STATUS_ERROR_INVALID;
1097 if (event_type & LB_SCRIPT_ACCESS_EVENT) {
1098 Elm_Access_Action_Info info;
1099 Elm_Access_Action_Type action;
1101 memset(&info, 0, sizeof(info));
1103 if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT) == LB_SCRIPT_ACCESS_HIGHLIGHT) {
1104 action = ELM_ACCESS_ACTION_HIGHLIGHT;
1107 ret = elm_access_action(edje, action, &info);
1108 DbgPrint("ACCESS_HIGHLIGHT: %dx%d returns %d\n", x, y, ret);
1109 if (ret == EINA_TRUE) {
1110 if (!get_highlighted_object(edje)) {
1111 ErrPrint("Highlighted object is not found\n");
1112 ret = LB_ACCESS_STATUS_ERROR;
1114 DbgPrint("Highlighted object is found\n");
1115 ret = LB_ACCESS_STATUS_DONE;
1118 ErrPrint("Action error\n");
1119 ret = LB_ACCESS_STATUS_ERROR;
1121 } else if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT_NEXT) == LB_SCRIPT_ACCESS_HIGHLIGHT_NEXT) {
1122 action = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
1123 info.highlight_cycle = EINA_FALSE;
1124 ret = elm_access_action(edje, action, &info);
1125 DbgPrint("ACCESS_HIGHLIGHT_NEXT, returns %d\n", ret);
1126 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
1127 } else if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT_PREV) == LB_SCRIPT_ACCESS_HIGHLIGHT_PREV) {
1128 action = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
1129 info.highlight_cycle = EINA_FALSE;
1130 ret = elm_access_action(edje, action, &info);
1131 DbgPrint("ACCESS_HIGHLIGHT_PREV, returns %d\n", ret);
1132 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
1133 } else if ((event_type & LB_SCRIPT_ACCESS_ACTIVATE) == LB_SCRIPT_ACCESS_ACTIVATE) {
1134 action = ELM_ACCESS_ACTION_ACTIVATE;
1135 ret = elm_access_action(edje, action, &info);
1136 DbgPrint("ACCESS_ACTIVATE, returns %d\n", ret);
1137 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1138 } else if ((event_type & LB_SCRIPT_ACCESS_ACTION) == LB_SCRIPT_ACCESS_ACTION) {
1140 action = ELM_ACCESS_ACTION_UP;
1141 ret = elm_access_action(edje, action, &info);
1142 DbgPrint("ACCESS_ACTION(%d), returns %d\n", down, ret);
1143 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1144 } else if (down == 1) {
1145 action = ELM_ACCESS_ACTION_DOWN;
1146 ret = elm_access_action(edje, action, &info);
1147 DbgPrint("ACCESS_ACTION(%d), returns %d\n", down, ret);
1148 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1150 ErrPrint("Invalid access event\n");
1151 ret = LB_ACCESS_STATUS_ERROR;
1153 } else if ((event_type & LB_SCRIPT_ACCESS_SCROLL) == LB_SCRIPT_ACCESS_SCROLL) {
1154 action = ELM_ACCESS_ACTION_SCROLL;
1159 info.mouse_type = 0;
1160 ret = elm_access_action(edje, action, &info);
1161 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
1162 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1165 info.mouse_type = 1;
1166 ret = elm_access_action(edje, action, &info);
1167 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
1168 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1171 info.mouse_type = 2;
1172 ret = elm_access_action(edje, action, &info);
1173 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
1174 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1177 ret = LB_ACCESS_STATUS_ERROR;
1180 } else if ((event_type & LB_SCRIPT_ACCESS_UNHIGHLIGHT) == LB_SCRIPT_ACCESS_UNHIGHLIGHT) {
1181 action = ELM_ACCESS_ACTION_UNHIGHLIGHT;
1182 ret = elm_access_action(edje, action, &info);
1183 DbgPrint("ACCESS_UNHIGHLIGHT, returns %d\n", ret);
1184 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1186 DbgPrint("Invalid event\n");
1187 ret = LB_ACCESS_STATUS_ERROR;
1190 } else if (event_type & LB_SCRIPT_MOUSE_EVENT) {
1191 double cur_timestamp;
1193 #if defined(_USE_ECORE_TIME_GET)
1194 cur_timestamp = ecore_time_get();
1197 if (gettimeofday(&tv, NULL) < 0) {
1198 ErrPrint("Failed to get time\n");
1199 cur_timestamp = 0.0f;
1201 cur_timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f);
1204 if (cur_timestamp - timestamp > 0.1f && handle->is_mouse_down == 0) {
1205 DbgPrint("Discard lazy event : %lf\n", cur_timestamp - timestamp);
1206 return LB_STATUS_SUCCESS;
1209 switch (event_type) {
1210 case LB_SCRIPT_MOUSE_DOWN:
1211 if (handle->is_mouse_down == 0) {
1212 evas_event_feed_mouse_move(e, x, y, timestamp * 1000, NULL);
1213 evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, (timestamp + 0.01f) * 1000, NULL);
1214 handle->is_mouse_down = 1;
1217 case LB_SCRIPT_MOUSE_MOVE:
1218 evas_event_feed_mouse_move(e, x, y, timestamp * 1000, NULL);
1220 case LB_SCRIPT_MOUSE_UP:
1221 if (handle->is_mouse_down == 1) {
1222 evas_event_feed_mouse_move(e, x, y, timestamp * 1000, NULL);
1223 evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, (timestamp + 0.01f) * 1000, NULL);
1224 handle->is_mouse_down = 0;
1227 case LB_SCRIPT_MOUSE_IN:
1228 evas_event_feed_mouse_in(e, timestamp * 1000, NULL);
1230 case LB_SCRIPT_MOUSE_OUT:
1231 evas_event_feed_mouse_out(e, timestamp * 1000, NULL);
1234 return LB_STATUS_ERROR_INVALID;
1236 } else if (event_type & LB_SCRIPT_KEY_EVENT) {
1237 DbgPrint("Key event is not implemented\n");
1238 return LB_STATUS_ERROR_NOT_IMPLEMENTED;
1244 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)
1246 struct info *handle = h;
1249 struct obj_info *obj_info;
1250 struct child *child;
1251 char _target_id[32];
1253 edje = find_edje(handle, src_id);
1255 ErrPrint("Edje is not exists (%s)\n", src_id);
1256 return LB_STATUS_ERROR_NOT_EXIST;
1259 obj_info = evas_object_data_get(edje, "obj_info");
1261 ErrPrint("Object info is not valid\n");
1262 return LB_STATUS_ERROR_INVALID;
1265 obj = elm_object_part_content_unset(edje, part);
1270 EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
1271 if (child->obj != obj) {
1275 obj_info->children = eina_list_remove(obj_info->children, child);
1282 DbgPrint("delete object %s %p\n", part, obj);
1285 * This will call the edje_del_cb.
1286 * It will delete all access objects
1288 evas_object_del(obj);
1291 if (!path || !strlen(path) || access(path, R_OK) != 0) {
1292 DbgPrint("SKIP - Path: [%s]\n", path);
1293 return LB_STATUS_SUCCESS;
1297 if (find_edje(handle, part)) {
1301 #if defined(_USE_ECORE_TIME_GET)
1302 timestamp = ecore_time_get();
1305 if (gettimeofday(&tv, NULL) < 0) {
1306 static int local_idx = 0;
1307 timestamp = (double)(local_idx++);
1309 timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f);
1313 snprintf(_target_id, sizeof(_target_id), "%lf", timestamp);
1314 } while (find_edje(handle, _target_id));
1316 target_id = _target_id;
1321 DbgPrint("Anonymouse target id: %s\n", target_id);
1324 obj = elm_layout_add(edje);
1326 ErrPrint("Failed to add a new edje object\n");
1327 return LB_STATUS_ERROR_FAULT;
1330 edje_object_scale_set(elm_layout_edje_get(obj), elm_config_scale_get());
1332 if (!elm_layout_file_set(obj, path, group)) {
1334 err = edje_object_load_error_get(elm_layout_edje_get(obj));
1335 ErrPrint("Could not load %s from %s: %s\n", group, path, edje_load_error_str(err));
1336 evas_object_del(obj);
1337 return LB_STATUS_ERROR_IO;
1340 evas_object_show(obj);
1342 obj_info = calloc(1, sizeof(*obj_info));
1344 ErrPrint("Failed to add a obj_info\n");
1345 evas_object_del(obj);
1346 return LB_STATUS_ERROR_MEMORY;
1349 obj_info->id = strdup(target_id);
1350 if (!obj_info->id) {
1351 ErrPrint("Failed to add a obj_info\n");
1353 evas_object_del(obj);
1354 return LB_STATUS_ERROR_MEMORY;
1357 obj_info->parent = edje;
1359 child = malloc(sizeof(*child));
1361 ErrPrint("Error: %s\n", strerror(errno));
1364 evas_object_del(obj);
1365 return LB_STATUS_ERROR_MEMORY;
1368 child->part = strdup(part);
1370 ErrPrint("Error: %s\n", strerror(errno));
1374 evas_object_del(obj);
1375 return LB_STATUS_ERROR_MEMORY;
1380 evas_object_data_set(obj, "obj_info", obj_info);
1381 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, edje_del_cb, handle);
1382 elm_object_signal_callback_add(obj, "*", "*", script_signal_cb, handle);
1383 handle->obj_list = eina_list_append(handle->obj_list, obj);
1385 DbgPrint("%s part swallow edje %p\n", part, obj);
1386 elm_object_part_content_set(edje, part, obj);
1388 obj_info = evas_object_data_get(edje, "obj_info");
1389 obj_info->children = eina_list_append(obj_info->children, child);
1390 return LB_STATUS_SUCCESS;
1393 PUBLIC int script_update_signal(void *h, Evas *e, const char *id, const char *part, const char *signal)
1395 struct info *handle = h;
1398 edje = find_edje(handle, id);
1400 return LB_STATUS_ERROR_NOT_EXIST;
1403 elm_object_signal_emit(edje, signal, part);
1404 return LB_STATUS_SUCCESS;
1407 PUBLIC int script_update_drag(void *h, Evas *e, const char *id, const char *part, double x, double y)
1409 struct info *handle = h;
1412 edje = find_edje(handle, id);
1414 return LB_STATUS_ERROR_NOT_EXIST;
1417 edje_object_part_drag_value_set(elm_layout_edje_get(edje), part, x, y);
1418 return LB_STATUS_SUCCESS;
1421 PUBLIC int script_update_size(void *han, Evas *e, const char *id, int w, int h)
1423 struct info *handle = han;
1426 edje = find_edje(handle, id);
1428 return LB_STATUS_ERROR_NOT_EXIST;
1436 DbgPrint("Resize object to %dx%d\n", w, h);
1437 evas_object_resize(edje, w, h);
1438 return LB_STATUS_SUCCESS;
1441 PUBLIC int script_update_category(void *h, Evas *e, const char *id, const char *category)
1443 struct info *handle = h;
1445 if (handle->category) {
1446 free(handle->category);
1447 handle->category = NULL;
1451 return LB_STATUS_SUCCESS;
1454 handle->category = strdup(category);
1455 if (!handle->category) {
1456 ErrPrint("Error: %s\n", strerror(errno));
1457 return LB_STATUS_ERROR_MEMORY;
1460 return LB_STATUS_SUCCESS;
1463 PUBLIC void *script_create(const char *file, const char *group)
1465 struct info *handle;
1467 handle = calloc(1, sizeof(*handle));
1469 ErrPrint("Error: %s\n", strerror(errno));
1473 handle->file = strdup(file);
1474 if (!handle->file) {
1475 ErrPrint("Error: %s\n", strerror(errno));
1480 handle->group = strdup(group);
1481 if (!handle->group) {
1482 ErrPrint("Error: %s\n", strerror(errno));
1488 s_info.handle_list = eina_list_append(s_info.handle_list, handle);
1493 PUBLIC int script_destroy(void *_handle)
1495 struct info *handle;
1500 if (!eina_list_data_find(s_info.handle_list, handle)) {
1501 DbgPrint("Not found (already deleted?)\n");
1502 return LB_STATUS_ERROR_NOT_EXIST;
1505 s_info.handle_list = eina_list_remove(s_info.handle_list, handle);
1507 edje = eina_list_nth(handle->obj_list, 0);
1509 evas_object_del(edje);
1512 free(handle->category);
1514 free(handle->group);
1516 return LB_STATUS_SUCCESS;
1519 PUBLIC int script_load(void *_handle, Evas *e, int w, int h)
1521 struct info *handle;
1523 struct obj_info *obj_info;
1527 obj_info = calloc(1, sizeof(*obj_info));
1529 ErrPrint("Heap: %s\n", strerror(errno));
1530 return LB_STATUS_ERROR_MEMORY;
1533 obj_info->parent = evas_object_rectangle_add(e);
1534 if (!obj_info->parent) {
1535 ErrPrint("Unable to create a parent box\n");
1537 return LB_STATUS_ERROR_FAULT;
1540 edje = elm_layout_add(obj_info->parent);
1542 ErrPrint("Failed to create an edje object\n");
1543 evas_object_del(obj_info->parent);
1545 return LB_STATUS_ERROR_FAULT;
1548 edje_object_scale_set(elm_layout_edje_get(edje), elm_config_scale_get());
1550 if (!elm_layout_file_set(edje, handle->file, handle->group)) {
1553 err = edje_object_load_error_get(elm_layout_edje_get(edje));
1554 ErrPrint("Could not load %s from %s: %s\n", handle->group, handle->file, edje_load_error_str(err));
1555 evas_object_del(edje);
1556 evas_object_del(obj_info->parent);
1558 return LB_STATUS_ERROR_IO;
1565 elm_object_signal_callback_add(edje, "*", "*", script_signal_cb, handle);
1566 evas_object_event_callback_add(edje, EVAS_CALLBACK_DEL, edje_del_cb, handle);
1567 evas_object_size_hint_weight_set(edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1568 evas_object_size_hint_fill_set(edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
1569 evas_object_resize(edje, handle->w, handle->h);
1570 evas_object_show(edje);
1571 evas_object_data_set(edje, "obj_info", obj_info);
1573 handle->obj_list = eina_list_append(handle->obj_list, edje);
1574 return LB_STATUS_SUCCESS;
1577 PUBLIC int script_unload(void *_handle, Evas *e)
1579 struct info *handle;
1581 Evas_Object *parent = NULL;
1585 edje = eina_list_nth(handle->obj_list, 0);
1587 struct obj_info *obj_info;
1589 obj_info = evas_object_data_get(edje, "obj_info");
1591 parent = obj_info->parent;
1593 evas_object_del(edje);
1597 DbgPrint("Delete parent box\n");
1598 evas_object_del(parent);
1602 return LB_STATUS_SUCCESS;
1605 static void access_cb(keynode_t *node, void *user_data)
1610 if (vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &state) != 0) {
1611 ErrPrint("Idle lock state is not valid\n");
1612 state = 0; /* DISABLED */
1615 state = vconf_keynode_get_bool(node);
1618 DbgPrint("ELM CONFIG ACCESS: %d\n", state);
1619 elm_config_access_set(state);
1622 static void update_font_cb(void *data)
1624 elm_config_font_overlay_set(TEXT_CLASS, s_info.font_name, DEFAULT_FONT_SIZE);
1625 DbgPrint("Update text class %s (%s, %d)\n", TEXT_CLASS, s_info.font_name, DEFAULT_FONT_SIZE);
1628 static void font_changed_cb(keynode_t *node, void *user_data)
1632 if (s_info.font_name) {
1633 font_name = vconf_get_str("db/setting/accessibility/font_name");
1635 ErrPrint("Invalid font name (NULL)\n");
1639 if (!strcmp(s_info.font_name, font_name)) {
1640 DbgPrint("Font is not changed (Old: %s(%p) <> New: %s(%p))\n", s_info.font_name, s_info.font_name, font_name, font_name);
1645 DbgPrint("Release old font name: %s(%p)\n", s_info.font_name, s_info.font_name);
1646 free(s_info.font_name);
1651 * Get the first font name using system_settings API.
1654 ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_FONT_TYPE, &font_name);
1655 if (ret != SYSTEM_SETTINGS_ERROR_NONE || !font_name) {
1656 ErrPrint("System setting get: %d, font_name[%p]\n", ret, font_name);
1661 s_info.font_name = font_name;
1662 DbgPrint("Font name is changed to %s(%p)\n", s_info.font_name, s_info.font_name);
1666 * Try to update all liveboxes
1668 update_font_cb(NULL);
1671 static inline int convert_font_size(int size)
1674 case SYSTEM_SETTINGS_FONT_SIZE_SMALL:
1677 case SYSTEM_SETTINGS_FONT_SIZE_NORMAL:
1680 case SYSTEM_SETTINGS_FONT_SIZE_LARGE:
1683 case SYSTEM_SETTINGS_FONT_SIZE_HUGE:
1686 case SYSTEM_SETTINGS_FONT_SIZE_GIANT:
1694 DbgPrint("Return size: %d\n", size);
1698 static void font_size_cb(system_settings_key_e key, void *user_data)
1702 if (system_settings_get_value_int(SYSTEM_SETTINGS_KEY_FONT_SIZE, &size) != SYSTEM_SETTINGS_ERROR_NONE) {
1706 size = convert_font_size(size);
1708 if (size == s_info.font_size) {
1709 DbgPrint("Font size is not changed\n");
1713 s_info.font_size = size;
1714 DbgPrint("Font size is changed to %d, but don't update the font info\n", size);
1717 PUBLIC int script_init(double scale)
1725 /* ecore is already initialized */
1727 elm_config_scale_set(scale);
1728 DbgPrint("Scale is updated: %lf\n", scale);
1730 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, access_cb, NULL);
1731 DbgPrint("TTS changed: %d\n", ret);
1733 ret = vconf_notify_key_changed("db/setting/accessibility/font_name", font_changed_cb, NULL);
1734 DbgPrint("System font is changed: %d\n", ret);
1736 ret = system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE, font_size_cb, NULL);
1737 DbgPrint("System font size is changed: %d\n", ret);
1739 access_cb(NULL, NULL);
1740 font_changed_cb(NULL, NULL);
1741 font_size_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE, NULL);
1742 return LB_STATUS_SUCCESS;
1745 PUBLIC int script_fini(void)
1750 struct info *handle;
1752 EINA_LIST_FOREACH_SAFE(s_info.handle_list, l, n, handle) {
1753 script_destroy(handle);
1756 ret = system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE);
1757 DbgPrint("Unset font size change event callback: %d\n", ret);
1759 ret = vconf_ignore_key_changed("db/setting/accessibility/font_name", font_changed_cb);
1760 DbgPrint("Unset font name change event callback: %d\n", ret);
1762 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, access_cb);
1763 DbgPrint("Unset tts: %d\n", ret);
1767 free(s_info.font_name);
1768 s_info.font_name = NULL;
1769 return LB_STATUS_SUCCESS;