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.
19 #include <stdlib.h> /* free */
22 #include <sys/types.h>
26 #include <sys/types.h>
35 #include <livebox-errno.h>
37 #include "slave_life.h"
38 #include "slave_rpc.h"
39 #include "client_life.h"
42 #include "buffer_handler.h"
43 #include "script_handler.h"
48 #define INFO_SIZE "size"
49 #define INFO_CATEGORY "category"
51 static const char *type_list[] = {
64 static const char *field_list[] = {
78 Eina_List *script_port_list;
79 enum buffer_type env_buf_type;
81 .script_port_list = NULL,
82 .env_buf_type = BUFFER_TYPE_FILE,
88 const char *(*magic_id)(void);
89 int (*update_color)(void *handle, const char *id, const char *part, const char *rgba);
90 int (*update_text)(void *handle, const char *id, const char *part, const char *text);
91 int (*update_image)(void *handle, const char *id, const char *part, const char *path, const char *option);
92 int (*update_access)(void *handle, const char *id, const char *part, const char *text, const char *option);
93 int (*operate_access)(void *handle, const char *id, const char *part, const char *operation, const char *option);
94 int (*update_script)(void *handle, const char *src_id, const char *target_id, const char *part, const char *path, const char *option);
95 int (*update_signal)(void *handle, const char *id, const char *part, const char *signal);
96 int (*update_drag)(void *handle, const char *id, const char *part, double x, double y);
97 int (*update_size)(void *handle, const char *id, int w, int h);
98 int (*update_category)(void *handle, const char *id, const char *category);
99 int (*feed_event)(void *handle, int event_type, int x, int y, int down, unsigned int keycode, double timestamp);
101 void *(*create)(void *buffer_info, const char *file, const char *option);
102 int (*destroy)(void *handle);
104 int (*load)(void *handle, int (*render_pre)(void *buffer_info, void *data), int (*render_post)(void *buffer_info, void *data), void *data);
105 int (*unload)(void *handle);
107 int (*init)(double scale, int premultiplied);
135 enum block_type type;
143 /* Should be released */
145 const char *filename;
149 struct buffer_info *buffer_handle;
159 unsigned int keycode;
161 struct script_port *port;
164 Eina_List *cached_blocks;
167 static inline void consuming_parsed_block(struct inst_info *inst, int is_pd, struct block *block);
169 static int load_all_ports(void)
171 struct script_port *item;
177 dir = opendir(SCRIPT_PORT_PATH);
179 ErrPrint("Error: %s\n", strerror(errno));
180 return LB_STATUS_ERROR_IO;
183 while ((ent = readdir(dir))) {
184 if (ent->d_name[0] == '.') {
188 pathlen = strlen(ent->d_name) + strlen(SCRIPT_PORT_PATH) + 1;
189 path = malloc(pathlen);
191 ErrPrint("Heap: %s %d\n", strerror(errno), pathlen);
192 if (closedir(dir) < 0) {
193 ErrPrint("closedir: %s\n", strerror(errno));
195 return LB_STATUS_ERROR_MEMORY;
198 snprintf(path, pathlen, "%s%s", SCRIPT_PORT_PATH, ent->d_name);
200 item = malloc(sizeof(*item));
202 ErrPrint("Heap: %s\n", strerror(errno));
204 if (closedir(dir) < 0) {
205 ErrPrint("closedir: %s\n", strerror(errno));
207 return LB_STATUS_ERROR_MEMORY;
210 DbgPrint("Open SCRIPT PORT: %s\n", path);
211 item->handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW | RTLD_DEEPBIND);
214 ErrPrint("Error: %s\n", dlerror());
216 if (closedir(dir) < 0) {
217 ErrPrint("closedir: %s\n", strerror(errno));
219 return LB_STATUS_ERROR_FAULT;
222 item->magic_id = dlsym(item->handle, "script_magic_id");
223 if (!item->magic_id) {
227 DbgPrint("SCRIPT PORT magic id: %s\n", item->magic_id());
229 item->update_color = dlsym(item->handle, "script_update_color");
230 if (!item->update_color) {
234 item->update_text = dlsym(item->handle, "script_update_text");
235 if (!item->update_text) {
239 item->update_image = dlsym(item->handle, "script_update_image");
240 if (!item->update_image) {
244 item->update_access = dlsym(item->handle, "script_update_access");
245 if (!item->update_access) {
249 item->operate_access = dlsym(item->handle, "script_operate_access");
250 if (!item->operate_access) {
254 item->update_script = dlsym(item->handle, "script_update_script");
255 if (!item->update_script) {
259 item->update_signal = dlsym(item->handle, "script_update_signal");
260 if (!item->update_signal) {
264 item->update_drag = dlsym(item->handle, "script_update_drag");
265 if (!item->update_drag) {
269 item->update_size = dlsym(item->handle, "script_update_size");
270 if (!item->update_size) {
274 item->update_category = dlsym(item->handle, "script_update_category");
275 if (!item->update_category) {
279 item->create = dlsym(item->handle, "script_create");
284 item->destroy = dlsym(item->handle, "script_destroy");
285 if (!item->destroy) {
289 item->load = dlsym(item->handle, "script_load");
294 item->unload = dlsym(item->handle, "script_unload");
299 item->init = dlsym(item->handle, "script_init");
304 item->fini = dlsym(item->handle, "script_fini");
309 item->feed_event = dlsym(item->handle, "script_feed_event");
310 if (!item->feed_event) {
314 if (item->init(SCALE_WIDTH_FACTOR, PREMULTIPLIED_COLOR) < 0) {
315 ErrPrint("Failed to initialize script engine\n");
319 s_info.script_port_list = eina_list_append(s_info.script_port_list, item);
322 if (closedir(dir) < 0) {
323 ErrPrint("closedir: %s\n", strerror(errno));
326 return LB_STATUS_SUCCESS;
329 ErrPrint("Error: %s\n", dlerror());
330 if (dlclose(item->handle) != 0) {
331 ErrPrint("dlclose: %s\n", strerror(errno));
334 if (closedir(dir) < 0) {
335 ErrPrint("closedir: %s\n", strerror(errno));
337 return LB_STATUS_ERROR_FAULT;
340 static inline struct script_port *find_port(const char *magic_id)
343 struct script_port *item;
345 if (!s_info.script_port_list) {
348 ret = load_all_ports();
350 ErrPrint("load_all_ports: %d\n", ret);
354 EINA_LIST_FOREACH(s_info.script_port_list, l, item) {
355 if (!strcmp(item->magic_id(), magic_id)) {
363 static inline void delete_block(struct block *block)
365 DbgFree(block->filebuf);
369 static int render_post_cb(void *_buffer_handle, void *data)
373 struct inst_info *inst;
374 struct buffer_info *buffer_handle = _buffer_handle;
375 struct script_info *info;
377 inst = buffer_handler_instance(buffer_handle);
382 if (instance_state(inst) != INST_ACTIVATED) {
383 ErrPrint("Render post invoked but instance is not activated\n");
385 return LB_STATUS_ERROR_INVALID;
388 info = instance_lb_script(inst);
389 if (info && info == data) {
390 buffer_handler_flush(buffer_handle);
391 instance_lb_updated_by_instance(inst, NULL);
392 PERF_MARK("lb,update");
393 return LB_STATUS_SUCCESS;
396 info = instance_pd_script(inst);
397 if (info && info == data) {
398 buffer_handler_flush(buffer_handle);
399 instance_pd_updated_by_instance(inst, NULL);
400 PERF_MARK("pd,update");
401 return LB_STATUS_SUCCESS;
405 ErrPrint("Failed to sync\n");
407 return LB_STATUS_ERROR_FAULT;
414 EAPI int script_signal_emit(void *buffer_handle, const char *part, const char *signal, double sx, double sy, double ex, double ey)
416 struct script_info *info;
417 struct inst_info *inst;
423 if (!buffer_handle) {
424 ErrPrint("Invalid handle\n");
425 return LB_STATUS_ERROR_INVALID;
428 info = buffer_handler_data(buffer_handle);
430 ErrPrint("Invalid handle\n");
431 return LB_STATUS_ERROR_INVALID;
434 inst = buffer_handler_instance(buffer_handle);
436 return LB_STATUS_ERROR_FAULT;
439 if (!signal || strlen(signal) == 0) {
443 if (!part || strlen(part) == 0) {
447 buffer_handler_get_size(buffer_handle, &w, &h);
449 fx = (double)info->x / (double)w;
450 fy = (double)info->y / (double)h;
452 return instance_signal_emit(inst, signal, part, sx, sy, ex, ey, fx, fy, info->down);
455 static inline void flushing_cached_block(struct script_info *info)
458 struct inst_info *inst;
461 inst = buffer_handler_instance(info->buffer_handle);
463 ErrPrint("Instance is not valid\n");
464 EINA_LIST_FREE(info->cached_blocks, block) {
470 is_pd = instance_pd_script(inst) == info;
472 EINA_LIST_FREE(info->cached_blocks, block) {
473 consuming_parsed_block(inst, is_pd, block);
477 HAPI int script_handler_load(struct script_info *info, int is_pd)
479 struct inst_info *inst;
481 if (!info || !info->port) {
482 ErrPrint("Script handler is not created\n");
483 return LB_STATUS_ERROR_INVALID;
486 if (info->loaded > 0) {
488 return LB_STATUS_SUCCESS;
491 if (info->port->load(info->port_data, NULL, render_post_cb, info) < 0) {
492 ErrPrint("Unable to load the script\n");
493 return LB_STATUS_ERROR_FAULT;
497 flushing_cached_block(info);
499 inst = buffer_handler_instance(info->buffer_handle);
501 script_signal_emit(info->buffer_handle, instance_id(inst),
502 is_pd ? "pd,show" : "lb,show", 0.0f, 0.0f, 0.0f, 0.0f);
504 buffer_handler_flush(info->buffer_handle);
505 return LB_STATUS_SUCCESS;
508 HAPI int script_handler_unload(struct script_info *info, int is_pd)
510 struct inst_info *inst;
512 if (!info || !info->port) {
513 return LB_STATUS_ERROR_INVALID;
517 if (info->loaded > 0) {
518 return LB_STATUS_ERROR_BUSY;
521 if (info->loaded < 0) {
523 return LB_STATUS_ERROR_ALREADY;
526 inst = buffer_handler_instance(info->buffer_handle);
528 script_signal_emit(info->buffer_handle, instance_id(inst),
529 is_pd ? "pd,hide" : "lb,hide", 0.0f, 0.0f, 0.0f, 0.0f);
532 if (info->port->unload(info->port_data) < 0) {
533 ErrPrint("Failed to unload script object. but go ahead\n");
536 return LB_STATUS_SUCCESS;
539 HAPI struct script_info *script_handler_create(struct inst_info *inst, const char *file, const char *option, int w, int h)
541 struct script_info *info;
543 DbgPrint("Create script: %s (%s) %dx%d\n", file, option, w, h);
549 info = calloc(1, sizeof(*info));
551 ErrPrint("Heap: %s\n", strerror(errno));
555 info->buffer_handle = buffer_handler_create(inst, s_info.env_buf_type, w, h, DEFAULT_PIXELS);
556 if (!info->buffer_handle) {
557 /* buffer_handler_create will prints some log */
562 (void)buffer_handler_set_data(info->buffer_handle, info);
564 info->port = find_port(package_script(instance_package(inst)));
566 ErrPrint("Failed to find a proper port for [%s]%s\n",
567 instance_package(inst), package_script(instance_package(inst)));
568 buffer_handler_destroy(info->buffer_handle);
573 info->port_data = info->port->create(info->buffer_handle, file, option);
574 if (!info->port_data) {
575 ErrPrint("Failed to create a port (%s - %s)\n", file, option);
576 buffer_handler_destroy(info->buffer_handle);
584 HAPI int script_handler_destroy(struct script_info *info)
589 if (!info || !info->port) {
590 ErrPrint("port is not valid\n");
591 return LB_STATUS_ERROR_INVALID;
594 if (info->loaded != 0) {
595 ErrPrint("Script handler is not unloaded\n");
596 return LB_STATUS_ERROR_BUSY;
599 ret = info->port->destroy(info->port_data);
601 ErrPrint("Failed to destroy port, but go ahead: %d\n", ret);
604 (void)buffer_handler_destroy(info->buffer_handle);
606 EINA_LIST_FREE(info->cached_blocks, block) {
611 return LB_STATUS_SUCCESS;
614 HAPI int script_handler_is_loaded(struct script_info *info)
616 return info ? info->loaded > 0 : 0;
619 HAPI struct buffer_info *script_handler_buffer_info(struct script_info *info)
625 return info->buffer_handle;
628 static int update_script_color(struct inst_info *inst, struct block *block, int is_pd)
632 struct script_info *info;
635 if (!block || !block->part || !block->data) {
636 ErrPrint("Block or part or data is not valid\n");
638 return LB_STATUS_ERROR_INVALID;
641 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
643 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
645 return LB_STATUS_ERROR_FAULT;
649 ErrPrint("info->port is NIL (%d, %s)\n", is_pd, instance_id(inst));
651 return LB_STATUS_ERROR_INVALID;
654 ret = info->port->update_color(info->port_data, block->id, block->part, block->data);
659 static int update_script_text(struct inst_info *inst, struct block *block, int is_pd)
663 struct script_info *info;
666 if (!block || !block->part || !block->data) {
667 ErrPrint("Block or part or data is not valid\n");
669 return LB_STATUS_ERROR_INVALID;
672 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
674 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
676 return LB_STATUS_ERROR_FAULT;
680 ErrPrint("info->port is NIL\n");
682 return LB_STATUS_ERROR_INVALID;
685 DbgPrint("[%s] %s (%s)\n", block->id, block->part, block->data);
686 ret = info->port->update_text(info->port_data, block->id, block->part, block->data);
692 static int update_script_image(struct inst_info *inst, struct block *block, int is_pd)
696 struct script_info *info;
699 if (!block || !block->part) {
700 ErrPrint("Block or part is not valid\n");
702 return LB_STATUS_ERROR_INVALID;
705 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
707 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
709 return LB_STATUS_ERROR_FAULT;
713 ErrPrint("info->port is NIL\n");
715 return LB_STATUS_ERROR_INVALID;
718 DbgPrint("[%s] %s (%s)\n", block->id, block->part, block->data);
719 ret = info->port->update_image(info->port_data, block->id, block->part, block->data, block->option);
724 static int update_access(struct inst_info *inst, struct block *block, int is_pd)
728 struct script_info *info;
731 if (!block || !block->part) {
732 ErrPrint("Block or block->part is NIL\n");
734 return LB_STATUS_ERROR_INVALID;
737 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
739 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
741 return LB_STATUS_ERROR_FAULT;
745 ErrPrint("info->port is NIL\n");
747 return LB_STATUS_ERROR_INVALID;
750 ret = info->port->update_access(info->port_data, block->id, block->part, block->data, block->option);
755 static int operate_access(struct inst_info *inst, struct block *block, int is_pd)
759 struct script_info *info;
762 if (!block || !block->part) {
763 ErrPrint("Block or block->part is NIL\n");
764 PERF_MARK("operate_access");
765 return LB_STATUS_ERROR_INVALID;
768 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
770 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
771 PERF_MARK("operate_access");
772 return LB_STATUS_ERROR_FAULT;
776 ErrPrint("info->port is NIL\n");
777 PERF_MARK("operate_access");
778 return LB_STATUS_ERROR_INVALID;
781 ret = info->port->operate_access(info->port_data, block->id, block->part, block->data, block->option);
782 PERF_MARK("operate_access");
786 static int update_script_script(struct inst_info *inst, struct block *block, int is_pd)
790 struct script_info *info;
793 if (!block || !block->part) {
794 ErrPrint("Block or part is NIL\n");
796 return LB_STATUS_ERROR_INVALID;
799 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
801 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
803 return LB_STATUS_ERROR_FAULT;
807 ErrPrint("info->port is NIL\n");
809 return LB_STATUS_ERROR_INVALID;
812 ret = info->port->update_script(info->port_data, block->id, block->target, block->part, block->data, block->option);
817 static int update_script_signal(struct inst_info *inst, struct block *block, int is_pd)
821 struct script_info *info;
825 ErrPrint("block is NIL\n");
827 return LB_STATUS_ERROR_INVALID;
830 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
832 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
834 return LB_STATUS_ERROR_FAULT;
838 ErrPrint("info->port is NIL\n");
840 return LB_STATUS_ERROR_INVALID;
843 ret = info->port->update_signal(info->port_data, block->id, block->part, block->data);
848 static int update_script_drag(struct inst_info *inst, struct block *block, int is_pd)
852 struct script_info *info;
856 if (!block || !block->data || !block->part) {
857 ErrPrint("block or block->data or block->part is NIL\n");
859 return LB_STATUS_ERROR_INVALID;
862 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
864 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
866 return LB_STATUS_ERROR_FAULT;
869 if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) {
870 ErrPrint("Invalid format of data (DRAG data [%s])\n", block->data);
872 return LB_STATUS_ERROR_INVALID;
876 ErrPrint("info->port is NIL\n");
878 return LB_STATUS_ERROR_INVALID;
881 ret = info->port->update_drag(info->port_data, block->id, block->part, dx, dy);
886 static void update_size_for_script(struct script_info *info, struct inst_info *inst, int w, int h)
890 * After update the buffer size,
891 * If it required to be unload and load.
892 * New size of buffer will be allocated
894 buffer_handler_update_size(info->buffer_handle, w, h);
896 if (info->port->update_size) {
897 (void)info->port->update_size(info->port_data, NULL, w, h);
900 if (instance_lb_script(inst) == info) {
901 instance_set_lb_size(inst, w, h);
902 } else if (instance_pd_script(inst) == info) {
903 instance_set_pd_size(inst, w, h);
905 ErrPrint("Unknown script\n");
909 HAPI int script_handler_resize(struct script_info *info, int w, int h)
913 struct inst_info *inst;
916 ErrPrint("info[%p] resize is ignored\n", info);
918 return LB_STATUS_SUCCESS;
921 inst = buffer_handler_instance(info->buffer_handle);
923 ErrPrint("Instance is not valid\n");
925 return LB_STATUS_ERROR_INVALID;
928 update_size_for_script(info, inst, w, h);
931 return LB_STATUS_SUCCESS;
934 HAPI const char *script_handler_buffer_id(struct script_info *info)
936 if (!info || !info->buffer_handle) {
937 ErrPrint("Invalid info\n");
941 return buffer_handler_id(info->buffer_handle);
944 static int update_info(struct inst_info *inst, struct block *block, int is_pd)
948 struct script_info *info;
950 if (!block || !block->part || !block->data) {
951 ErrPrint("block or block->part or block->data is NIL\n");
953 return LB_STATUS_ERROR_INVALID;
956 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
958 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
960 return LB_STATUS_ERROR_FAULT;
964 ErrPrint("info->port is NIL\n");
966 return LB_STATUS_ERROR_INVALID;
969 if (!strcasecmp(block->part, INFO_SIZE)) {
972 if (sscanf(block->data, "%dx%d", &w, &h) != 2) {
973 ErrPrint("Invalid format for SIZE(%s)\n", block->data);
975 return LB_STATUS_ERROR_INVALID;
979 update_size_for_script(info, inst, w, h);
981 (void)info->port->update_size(info->port_data, block->id, w, h);
983 } else if (!strcasecmp(block->part, INFO_CATEGORY)) {
984 (void)info->port->update_category(info->port_data, block->id, block->data);
988 return LB_STATUS_SUCCESS;
991 static inline void consuming_parsed_block(struct inst_info *inst, int is_pd, struct block *block)
993 struct script_info *info;
994 typedef int (*update_function_t)(struct inst_info *inst, struct block *block, int is_pd);
995 update_function_t updators[] = {
1000 update_script_image,
1002 update_script_script,
1003 update_script_signal,
1008 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
1010 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
1014 if (script_handler_is_loaded(info)) {
1015 if (block->type >= 0 || block->type < TYPE_MAX) {
1016 (void)updators[block->type](inst, block, is_pd);
1018 ErrPrint("Block type[%d] is not valid\n", block->type);
1021 info->cached_blocks = eina_list_append(info->cached_blocks, block);
1022 DbgPrint("Block is cached (%p), %d, %s\n", block, eina_list_count(info->cached_blocks), instance_id(inst));
1027 delete_block(block);
1030 HAPI int script_init(void)
1032 if (!strcasecmp(PROVIDER_METHOD, "shm")) {
1033 s_info.env_buf_type = BUFFER_TYPE_SHM;
1034 } else if (!strcasecmp(PROVIDER_METHOD, "pixmap")) {
1035 s_info.env_buf_type = BUFFER_TYPE_PIXMAP;
1038 return LB_STATUS_SUCCESS;
1041 HAPI int script_fini(void)
1043 struct script_port *item;
1045 * \TODO: Release all handles
1047 EINA_LIST_FREE(s_info.script_port_list, item) {
1049 if (dlclose(item->handle) != 0) {
1050 ErrPrint("dlclose: %s\n", strerror(errno));
1058 HAPI int script_handler_update_pointer(struct script_info *info, int x, int y, int down)
1061 return LB_STATUS_SUCCESS;
1069 } else if (down == 1) {
1073 return LB_STATUS_SUCCESS;
1076 HAPI int script_handler_update_keycode(struct script_info *info, unsigned int keycode)
1079 return LB_STATUS_SUCCESS;
1082 info->keycode = keycode;
1084 return LB_STATUS_SUCCESS;
1087 HAPI int script_handler_feed_event(struct script_info *info, int event, double timestamp)
1092 ErrPrint("info->port is NIL\n");
1093 return LB_STATUS_ERROR_INVALID;
1096 ret = info->port->feed_event(info->port_data, event, info->x, info->y, info->down, info->keycode, timestamp);
1100 static inline char *load_file(const char *filename)
1102 char *filebuf = NULL;
1106 size_t readsize = 0;
1108 fd = open(filename, O_RDONLY);
1110 ErrPrint("open: %s\n", strerror(errno));
1114 filesize = lseek(fd, 0L, SEEK_END);
1115 if (filesize == (off_t)-1) {
1116 ErrPrint("lseek: %s\n", strerror(errno));
1120 if (lseek(fd, 0L, SEEK_SET) < 0) {
1121 ErrPrint("lseek: %s\n", strerror(errno));
1125 filebuf = malloc(filesize + 1);
1127 ErrPrint("malloc: %s\n", strerror(errno));
1131 while (readsize < filesize) {
1132 ret = read(fd, filebuf + readsize, (size_t)filesize - readsize);
1134 if (errno == EINTR) {
1135 DbgPrint("Read is interrupted\n");
1139 ErrPrint("read: %s\n", strerror(errno));
1149 filebuf[readsize] = '\0';
1154 * Now, we are ready to parse the filebuf.
1158 if (close(fd) < 0) {
1159 ErrPrint("close: %s\n", strerror(errno));
1165 #if defined(_APPLY_SCRIPT_ASYNC_UPDATE)
1167 struct inst_info *inst;
1168 Eina_List *block_list;
1172 static Eina_Bool apply_changes_cb(void *_data)
1174 struct apply_data *data = _data;
1175 struct block *block;
1177 block = eina_list_nth(data->block_list, 0);
1178 data->block_list = eina_list_remove(data->block_list, block);
1179 consuming_parsed_block(data->inst, data->is_pd, block);
1181 if (!data->block_list) {
1183 return ECORE_CALLBACK_CANCEL;
1186 return ECORE_CALLBACK_RENEW;
1191 HAPI int script_handler_parse_desc(struct inst_info *inst, const char *filename, int is_pd)
1202 struct block *block = NULL;
1203 Eina_List *block_list = NULL;
1213 filebuf = load_file(filename);
1215 return LB_STATUS_ERROR_IO;
1221 while (*fileptr && state != ERROR) {
1224 if (*fileptr == '{') {
1225 block = calloc(1, sizeof(*block));
1227 ErrPrint("calloc: %s\n", strerror(errno));
1236 if (isspace(*fileptr)) {
1240 } else if (*fileptr == '=') {
1244 } else if (ptr == NULL) {
1249 while (field_list[field_idx]) {
1250 if (field_list[field_idx][field_len] == *fileptr) {
1256 if (!field_list[field_idx]) {
1257 ErrPrint("Invalid field\n");
1264 if (field_list[field_idx][field_len] != *fileptr) {
1266 while (field_list[field_idx]) {
1267 if (!strncmp(field_list[field_idx], fileptr - field_len, field_len)) {
1274 if (!field_list[field_idx]) {
1276 ErrPrint("field is not valid\n");
1285 switch (field_idx) {
1288 if (isspace(*fileptr)) {
1292 if (*fileptr == '\0') {
1294 ErrPrint("Type is not valid\n");
1303 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1307 if (type_list[type_idx][type_len] != *fileptr) {
1309 while (type_list[type_idx]) {
1310 if (!strncmp(type_list[type_idx], fileptr - type_len, type_len)) {
1317 if (!type_list[type_idx]) {
1319 ErrPrint("type is not valid (%s)\n", fileptr - type_len);
1325 block->type = type_idx;
1337 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1352 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1367 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1372 block->option = ptr;
1382 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1397 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1402 block->target = ptr;
1412 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1417 block->target = ptr;
1427 if (isspace(*fileptr)) {
1428 } else if (*fileptr == '}') {
1430 block->filename = filename;
1431 block_list = eina_list_append(block_list, block);
1446 if (state != BEGIN) {
1447 ErrPrint("State %d\n", state);
1452 EINA_LIST_FREE(block_list, block) {
1456 PERF_MARK("parser");
1457 return LB_STATUS_ERROR_FAULT;
1460 block = eina_list_data_get(eina_list_last(block_list));
1462 block->filebuf = filebuf;
1464 ErrPrint("Last block is not exists (There is no parsed block)\n");
1468 PERF_MARK("parser");
1470 #if defined(_APPLY_SCRIPT_ASYNC_UPDATE)
1471 struct apply_data *data;
1473 data = malloc(sizeof(*data));
1476 data->is_pd = is_pd;
1477 data->block_list = block_list;
1478 if (!ecore_timer_add(0.001f, apply_changes_cb, data)) {
1479 ErrPrint("Failed to add timer\n");
1481 EINA_LIST_FREE(block_list, block) {
1482 consuming_parsed_block(inst, is_pd, block);
1486 ErrPrint("Heap: %s\n", strerror(errno));
1487 EINA_LIST_FREE(block_list, block) {
1488 consuming_parsed_block(inst, is_pd, block);
1492 ErrPrint("Begin: Set content for EDJE object\n");
1493 EINA_LIST_FREE(block_list, block) {
1494 consuming_parsed_block(inst, is_pd, block);
1496 ErrPrint("End: Set content for EDJE object\n");
1499 * Doesn't need to force to render the contents.
1500 struct script_info *info;
1501 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
1502 if (info && info->ee) {
1503 ecore_evas_manual_render(info->ee);
1508 return LB_STATUS_SUCCESS;