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 <dynamicbox_errno.h>
36 #include <dynamicbox_service.h>
37 #include <dynamicbox_conf.h>
39 #include "slave_life.h"
40 #include "slave_rpc.h"
41 #include "client_life.h"
44 #include "buffer_handler.h"
45 #include "script_handler.h"
50 #define INFO_SIZE "size"
51 #define INFO_CATEGORY "category"
53 static const char *type_list[] = {
66 static const char *field_list[] = {
80 Eina_List *script_port_list;
81 enum dynamicbox_fb_type env_buf_type;
83 .script_port_list = NULL,
84 .env_buf_type = DBOX_FB_TYPE_FILE,
90 const char *(*magic_id)(void);
91 int (*update_color)(void *handle, const char *id, const char *part, const char *rgba);
92 int (*update_text)(void *handle, const char *id, const char *part, const char *text);
93 int (*update_image)(void *handle, const char *id, const char *part, const char *path, const char *option);
94 int (*update_access)(void *handle, const char *id, const char *part, const char *text, const char *option);
95 int (*operate_access)(void *handle, const char *id, const char *part, const char *operation, const char *option);
96 int (*update_script)(void *handle, const char *src_id, const char *target_id, const char *part, const char *path, const char *option);
97 int (*update_signal)(void *handle, const char *id, const char *part, const char *signal);
98 int (*update_drag)(void *handle, const char *id, const char *part, double x, double y);
99 int (*update_size)(void *handle, const char *id, int w, int h);
100 int (*update_category)(void *handle, const char *id, const char *category);
101 int (*feed_event)(void *handle, int event_type, int x, int y, int down, unsigned int keycode, double timestamp);
103 void *(*create)(void *buffer_info, const char *file, const char *option);
104 int (*destroy)(void *handle);
106 int (*load)(void *handle, int (*render_pre)(void *buffer_info, void *data), int (*render_post)(void *buffer_info, void *data), void *data);
107 int (*unload)(void *handle);
109 int (*init)(double scale, int premultiplied);
137 enum block_type type;
145 /* Should be released */
147 const char *filename;
151 struct buffer_info *buffer_handle;
161 unsigned int keycode;
163 struct script_port *port;
166 Eina_List *cached_blocks;
169 static inline void consuming_parsed_block(struct inst_info *inst, int is_pd, struct block *block);
171 static int load_all_ports(void)
173 struct script_port *item;
179 dir = opendir(DYNAMICBOX_CONF_SCRIPT_PORT_PATH);
181 ErrPrint("Error: %s\n", strerror(errno));
182 return DBOX_STATUS_ERROR_IO_ERROR;
185 while ((ent = readdir(dir))) {
186 if (ent->d_name[0] == '.') {
190 pathlen = strlen(ent->d_name) + strlen(DYNAMICBOX_CONF_SCRIPT_PORT_PATH) + 1;
191 path = malloc(pathlen);
193 ErrPrint("Heap: %s %d\n", strerror(errno), pathlen);
194 if (closedir(dir) < 0) {
195 ErrPrint("closedir: %s\n", strerror(errno));
197 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
200 snprintf(path, pathlen, "%s%s", DYNAMICBOX_CONF_SCRIPT_PORT_PATH, ent->d_name);
202 item = malloc(sizeof(*item));
204 ErrPrint("Heap: %s\n", strerror(errno));
206 if (closedir(dir) < 0) {
207 ErrPrint("closedir: %s\n", strerror(errno));
209 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
212 DbgPrint("Open SCRIPT PORT: %s\n", path);
213 item->handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW | RTLD_DEEPBIND);
216 ErrPrint("Error: %s\n", dlerror());
218 if (closedir(dir) < 0) {
219 ErrPrint("closedir: %s\n", strerror(errno));
221 return DBOX_STATUS_ERROR_FAULT;
224 item->magic_id = dlsym(item->handle, "script_magic_id");
225 if (!item->magic_id) {
229 DbgPrint("SCRIPT PORT magic id: %s\n", item->magic_id());
231 item->update_color = dlsym(item->handle, "script_update_color");
232 if (!item->update_color) {
236 item->update_text = dlsym(item->handle, "script_update_text");
237 if (!item->update_text) {
241 item->update_image = dlsym(item->handle, "script_update_image");
242 if (!item->update_image) {
246 item->update_access = dlsym(item->handle, "script_update_access");
247 if (!item->update_access) {
251 item->operate_access = dlsym(item->handle, "script_operate_access");
252 if (!item->operate_access) {
256 item->update_script = dlsym(item->handle, "script_update_script");
257 if (!item->update_script) {
261 item->update_signal = dlsym(item->handle, "script_update_signal");
262 if (!item->update_signal) {
266 item->update_drag = dlsym(item->handle, "script_update_drag");
267 if (!item->update_drag) {
271 item->update_size = dlsym(item->handle, "script_update_size");
272 if (!item->update_size) {
276 item->update_category = dlsym(item->handle, "script_update_category");
277 if (!item->update_category) {
281 item->create = dlsym(item->handle, "script_create");
286 item->destroy = dlsym(item->handle, "script_destroy");
287 if (!item->destroy) {
291 item->load = dlsym(item->handle, "script_load");
296 item->unload = dlsym(item->handle, "script_unload");
301 item->init = dlsym(item->handle, "script_init");
306 item->fini = dlsym(item->handle, "script_fini");
311 item->feed_event = dlsym(item->handle, "script_feed_event");
312 if (!item->feed_event) {
316 if (item->init(DYNAMICBOX_CONF_SCALE_WIDTH_FACTOR, DYNAMICBOX_CONF_PREMULTIPLIED_COLOR) < 0) {
317 ErrPrint("Failed to initialize script engine\n");
321 s_info.script_port_list = eina_list_append(s_info.script_port_list, item);
324 if (closedir(dir) < 0) {
325 ErrPrint("closedir: %s\n", strerror(errno));
328 return DBOX_STATUS_ERROR_NONE;
331 ErrPrint("Error: %s\n", dlerror());
332 if (dlclose(item->handle) != 0) {
333 ErrPrint("dlclose: %s\n", strerror(errno));
336 if (closedir(dir) < 0) {
337 ErrPrint("closedir: %s\n", strerror(errno));
339 return DBOX_STATUS_ERROR_FAULT;
342 static inline struct script_port *find_port(const char *magic_id)
345 struct script_port *item;
347 if (!s_info.script_port_list) {
350 ret = load_all_ports();
352 ErrPrint("load_all_ports: %d\n", ret);
356 EINA_LIST_FOREACH(s_info.script_port_list, l, item) {
357 if (!strcmp(item->magic_id(), magic_id)) {
365 static inline void delete_block(struct block *block)
367 DbgFree(block->filebuf);
371 static int render_post_cb(void *_buffer_handle, void *data)
375 struct inst_info *inst;
376 struct buffer_info *buffer_handle = _buffer_handle;
377 struct script_info *info;
379 inst = buffer_handler_instance(buffer_handle);
384 if (instance_state(inst) != INST_ACTIVATED) {
385 ErrPrint("Render post invoked but instance is not activated\n");
387 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
390 info = instance_dbox_script(inst);
391 if (info && info == data) {
392 buffer_handler_flush(buffer_handle);
393 instance_dbox_updated_by_instance(inst, NULL, info->x, info->y, info->w, info->h);
394 PERF_MARK("lb,update");
395 return DBOX_STATUS_ERROR_NONE;
398 info = instance_gbar_script(inst);
399 if (info && info == data) {
400 buffer_handler_flush(buffer_handle);
401 instance_gbar_updated_by_instance(inst, NULL, info->x, info->y, info->w, info->h);
402 PERF_MARK("pd,update");
403 return DBOX_STATUS_ERROR_NONE;
407 ErrPrint("Failed to sync\n");
409 return DBOX_STATUS_ERROR_FAULT;
416 EAPI int script_signal_emit(void *buffer_handle, const char *part, const char *signal, double sx, double sy, double ex, double ey)
418 struct script_info *info;
419 struct inst_info *inst;
425 if (!buffer_handle) {
426 ErrPrint("Invalid handle\n");
427 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
430 info = buffer_handler_data(buffer_handle);
432 ErrPrint("Invalid handle\n");
433 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
436 inst = buffer_handler_instance(buffer_handle);
438 return DBOX_STATUS_ERROR_FAULT;
441 if (!signal || strlen(signal) == 0) {
445 if (!part || strlen(part) == 0) {
449 buffer_handler_get_size(buffer_handle, &w, &h);
451 fx = (double)info->x / (double)w;
452 fy = (double)info->y / (double)h;
454 return instance_signal_emit(inst, signal, part, sx, sy, ex, ey, fx, fy, info->down);
457 static inline void flushing_cached_block(struct script_info *info)
460 struct inst_info *inst;
463 inst = buffer_handler_instance(info->buffer_handle);
465 ErrPrint("Instance is not valid\n");
466 EINA_LIST_FREE(info->cached_blocks, block) {
472 is_pd = instance_gbar_script(inst) == info;
474 EINA_LIST_FREE(info->cached_blocks, block) {
475 consuming_parsed_block(inst, is_pd, block);
479 HAPI int script_handler_load(struct script_info *info, int is_pd)
481 struct inst_info *inst;
483 if (!info || !info->port) {
484 ErrPrint("Script handler is not created\n");
485 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
488 if (info->loaded > 0) {
490 return DBOX_STATUS_ERROR_NONE;
493 if (info->port->load(info->port_data, NULL, render_post_cb, info) < 0) {
494 ErrPrint("Unable to load the script\n");
495 return DBOX_STATUS_ERROR_FAULT;
499 flushing_cached_block(info);
501 inst = buffer_handler_instance(info->buffer_handle);
503 script_signal_emit(info->buffer_handle, instance_id(inst),
504 is_pd ? "gbar,show" : "dbox,show", 0.0f, 0.0f, 0.0f, 0.0f);
506 buffer_handler_flush(info->buffer_handle);
507 return DBOX_STATUS_ERROR_NONE;
510 HAPI int script_handler_unload(struct script_info *info, int is_pd)
512 struct inst_info *inst;
514 if (!info || !info->port) {
515 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
519 if (info->loaded > 0) {
520 return DBOX_STATUS_ERROR_BUSY;
523 if (info->loaded < 0) {
525 return DBOX_STATUS_ERROR_ALREADY;
528 inst = buffer_handler_instance(info->buffer_handle);
530 script_signal_emit(info->buffer_handle, instance_id(inst),
531 is_pd ? "gbar,hide" : "dbox,hide", 0.0f, 0.0f, 0.0f, 0.0f);
534 if (info->port->unload(info->port_data) < 0) {
535 ErrPrint("Failed to unload script object. but go ahead\n");
538 return DBOX_STATUS_ERROR_NONE;
541 HAPI struct script_info *script_handler_create(struct inst_info *inst, const char *file, const char *option, int w, int h)
543 struct script_info *info;
545 DbgPrint("Create script: %s (%s) %dx%d\n", file, option, w, h);
551 info = calloc(1, sizeof(*info));
553 ErrPrint("Heap: %s\n", strerror(errno));
557 info->buffer_handle = buffer_handler_create(inst, s_info.env_buf_type, w, h, DYNAMICBOX_CONF_DEFAULT_PIXELS);
558 if (!info->buffer_handle) {
559 /* buffer_handler_create will prints some log */
564 (void)buffer_handler_set_data(info->buffer_handle, info);
566 info->port = find_port(package_script(instance_package(inst)));
568 ErrPrint("Failed to find a proper port for [%s]%s\n",
569 instance_package(inst), package_script(instance_package(inst)));
570 buffer_handler_destroy(info->buffer_handle);
575 info->port_data = info->port->create(info->buffer_handle, file, option);
576 if (!info->port_data) {
577 ErrPrint("Failed to create a port (%s - %s)\n", file, option);
578 buffer_handler_destroy(info->buffer_handle);
586 HAPI int script_handler_destroy(struct script_info *info)
591 if (!info || !info->port) {
592 ErrPrint("port is not valid\n");
593 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
596 if (info->loaded != 0) {
597 ErrPrint("Script handler is not unloaded\n");
598 return DBOX_STATUS_ERROR_BUSY;
601 ret = info->port->destroy(info->port_data);
603 ErrPrint("Failed to destroy port, but go ahead: %d\n", ret);
606 (void)buffer_handler_destroy(info->buffer_handle);
608 EINA_LIST_FREE(info->cached_blocks, block) {
613 return DBOX_STATUS_ERROR_NONE;
616 HAPI int script_handler_is_loaded(struct script_info *info)
618 return info ? info->loaded > 0 : 0;
621 HAPI struct buffer_info *script_handler_buffer_info(struct script_info *info)
627 return info->buffer_handle;
630 static int update_script_color(struct inst_info *inst, struct block *block, int is_pd)
634 struct script_info *info;
637 if (!block || !block->part || !block->data) {
638 ErrPrint("Block or part or data is not valid\n");
640 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
643 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
645 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
647 return DBOX_STATUS_ERROR_FAULT;
651 ErrPrint("info->port is NIL (%d, %s)\n", is_pd, instance_id(inst));
653 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
656 ret = info->port->update_color(info->port_data, block->id, block->part, block->data);
661 static int update_script_text(struct inst_info *inst, struct block *block, int is_pd)
665 struct script_info *info;
668 if (!block || !block->part || !block->data) {
669 ErrPrint("Block or part or data is not valid\n");
671 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
674 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
676 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
678 return DBOX_STATUS_ERROR_FAULT;
682 ErrPrint("info->port is NIL\n");
684 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
687 DbgPrint("[%s] %s (%s)\n", block->id, block->part, block->data);
688 ret = info->port->update_text(info->port_data, block->id, block->part, block->data);
694 static int update_script_image(struct inst_info *inst, struct block *block, int is_pd)
698 struct script_info *info;
701 if (!block || !block->part) {
702 ErrPrint("Block or part is not valid\n");
704 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
707 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
709 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
711 return DBOX_STATUS_ERROR_FAULT;
715 ErrPrint("info->port is NIL\n");
717 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
720 DbgPrint("[%s] %s (%s)\n", block->id, block->part, block->data);
721 ret = info->port->update_image(info->port_data, block->id, block->part, block->data, block->option);
726 static int update_access(struct inst_info *inst, struct block *block, int is_pd)
730 struct script_info *info;
733 if (!block || !block->part) {
734 ErrPrint("Block or block->part is NIL\n");
736 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
739 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
741 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
743 return DBOX_STATUS_ERROR_FAULT;
747 ErrPrint("info->port is NIL\n");
749 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
752 ret = info->port->update_access(info->port_data, block->id, block->part, block->data, block->option);
757 static int operate_access(struct inst_info *inst, struct block *block, int is_pd)
761 struct script_info *info;
764 if (!block || !block->part) {
765 ErrPrint("Block or block->part is NIL\n");
766 PERF_MARK("operate_access");
767 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
770 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
772 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
773 PERF_MARK("operate_access");
774 return DBOX_STATUS_ERROR_FAULT;
778 ErrPrint("info->port is NIL\n");
779 PERF_MARK("operate_access");
780 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
783 ret = info->port->operate_access(info->port_data, block->id, block->part, block->data, block->option);
784 PERF_MARK("operate_access");
788 static int update_script_script(struct inst_info *inst, struct block *block, int is_pd)
792 struct script_info *info;
795 if (!block || !block->part) {
796 ErrPrint("Block or part is NIL\n");
798 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
801 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
803 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
805 return DBOX_STATUS_ERROR_FAULT;
809 ErrPrint("info->port is NIL\n");
811 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
814 ret = info->port->update_script(info->port_data, block->id, block->target, block->part, block->data, block->option);
819 static int update_script_signal(struct inst_info *inst, struct block *block, int is_pd)
823 struct script_info *info;
827 ErrPrint("block is NIL\n");
829 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
832 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
834 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
836 return DBOX_STATUS_ERROR_FAULT;
840 ErrPrint("info->port is NIL\n");
842 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
845 ret = info->port->update_signal(info->port_data, block->id, block->part, block->data);
850 static int update_script_drag(struct inst_info *inst, struct block *block, int is_pd)
854 struct script_info *info;
858 if (!block || !block->data || !block->part) {
859 ErrPrint("block or block->data or block->part is NIL\n");
861 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
864 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
866 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
868 return DBOX_STATUS_ERROR_FAULT;
871 if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) {
872 ErrPrint("Invalid format of data (DRAG data [%s])\n", block->data);
874 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
878 ErrPrint("info->port is NIL\n");
880 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
883 ret = info->port->update_drag(info->port_data, block->id, block->part, dx, dy);
888 static void update_size_for_script(struct script_info *info, struct inst_info *inst, int w, int h)
892 * After update the buffer size,
893 * If it required to be unload and load.
894 * New size of buffer will be allocated
896 buffer_handler_update_size(info->buffer_handle, w, h);
898 if (info->port->update_size) {
899 (void)info->port->update_size(info->port_data, NULL, w, h);
902 if (instance_dbox_script(inst) == info) {
903 instance_set_dbox_size(inst, w, h);
904 } else if (instance_gbar_script(inst) == info) {
905 instance_set_gbar_size(inst, w, h);
907 ErrPrint("Unknown script\n");
911 HAPI int script_handler_resize(struct script_info *info, int w, int h)
915 struct inst_info *inst;
918 ErrPrint("info[%p] resize is ignored\n", info);
920 return DBOX_STATUS_ERROR_NONE;
923 inst = buffer_handler_instance(info->buffer_handle);
925 ErrPrint("Instance is not valid\n");
927 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
930 update_size_for_script(info, inst, w, h);
933 return DBOX_STATUS_ERROR_NONE;
936 HAPI const char *script_handler_buffer_id(struct script_info *info)
938 if (!info || !info->buffer_handle) {
939 ErrPrint("Invalid info\n");
943 return buffer_handler_id(info->buffer_handle);
946 static int update_info(struct inst_info *inst, struct block *block, int is_pd)
950 struct script_info *info;
952 if (!block || !block->part || !block->data) {
953 ErrPrint("block or block->part or block->data is NIL\n");
955 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
958 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
960 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
962 return DBOX_STATUS_ERROR_FAULT;
966 ErrPrint("info->port is NIL\n");
968 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
971 if (!strcasecmp(block->part, INFO_SIZE)) {
974 if (sscanf(block->data, "%dx%d", &w, &h) != 2) {
975 ErrPrint("Invalid format for SIZE(%s)\n", block->data);
977 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
981 update_size_for_script(info, inst, w, h);
983 (void)info->port->update_size(info->port_data, block->id, w, h);
985 } else if (!strcasecmp(block->part, INFO_CATEGORY)) {
986 (void)info->port->update_category(info->port_data, block->id, block->data);
990 return DBOX_STATUS_ERROR_NONE;
993 static inline void consuming_parsed_block(struct inst_info *inst, int is_pd, struct block *block)
995 struct script_info *info;
996 typedef int (*update_function_t)(struct inst_info *inst, struct block *block, int is_pd);
997 update_function_t updators[] = {
1000 update_script_color,
1002 update_script_image,
1004 update_script_script,
1005 update_script_signal,
1010 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
1012 ErrPrint("info is NIL (%d, %s)\n", is_pd, instance_id(inst));
1016 if (script_handler_is_loaded(info)) {
1017 if (block->type >= 0 || block->type < TYPE_MAX) {
1018 (void)updators[block->type](inst, block, is_pd);
1020 ErrPrint("Block type[%d] is not valid\n", block->type);
1023 info->cached_blocks = eina_list_append(info->cached_blocks, block);
1024 DbgPrint("Block is cached (%p), %d, %s\n", block, eina_list_count(info->cached_blocks), instance_id(inst));
1029 delete_block(block);
1032 HAPI int script_init(void)
1034 if (!strcasecmp(DYNAMICBOX_CONF_PROVIDER_METHOD, "shm")) {
1035 s_info.env_buf_type = DBOX_FB_TYPE_SHM;
1036 } else if (!strcasecmp(DYNAMICBOX_CONF_PROVIDER_METHOD, "pixmap")) {
1037 s_info.env_buf_type = DBOX_FB_TYPE_PIXMAP;
1040 return DBOX_STATUS_ERROR_NONE;
1043 HAPI int script_fini(void)
1045 struct script_port *item;
1047 * \TODO: Release all handles
1049 EINA_LIST_FREE(s_info.script_port_list, item) {
1051 if (dlclose(item->handle) != 0) {
1052 ErrPrint("dlclose: %s\n", strerror(errno));
1060 HAPI int script_handler_update_pointer(struct script_info *info, int x, int y, int down)
1063 return DBOX_STATUS_ERROR_NONE;
1071 } else if (down == 1) {
1075 return DBOX_STATUS_ERROR_NONE;
1078 HAPI int script_handler_update_keycode(struct script_info *info, unsigned int keycode)
1081 return DBOX_STATUS_ERROR_NONE;
1084 info->keycode = keycode;
1086 return DBOX_STATUS_ERROR_NONE;
1089 HAPI int script_handler_feed_event(struct script_info *info, int event, double timestamp)
1094 ErrPrint("info->port is NIL\n");
1095 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1098 ret = info->port->feed_event(info->port_data, event, info->x, info->y, info->down, info->keycode, timestamp);
1102 static inline char *load_file(const char *filename)
1104 char *filebuf = NULL;
1108 size_t readsize = 0;
1110 fd = open(filename, O_RDONLY);
1112 ErrPrint("open: %s\n", strerror(errno));
1116 filesize = lseek(fd, 0L, SEEK_END);
1117 if (filesize == (off_t)-1) {
1118 ErrPrint("lseek: %s\n", strerror(errno));
1122 if (lseek(fd, 0L, SEEK_SET) < 0) {
1123 ErrPrint("lseek: %s\n", strerror(errno));
1127 filebuf = malloc(filesize + 1);
1129 ErrPrint("malloc: %s\n", strerror(errno));
1133 while (readsize < filesize) {
1134 ret = read(fd, filebuf + readsize, (size_t)filesize - readsize);
1136 if (errno == EINTR) {
1137 DbgPrint("Read is interrupted\n");
1141 ErrPrint("read: %s\n", strerror(errno));
1151 filebuf[readsize] = '\0';
1156 * Now, we are ready to parse the filebuf.
1160 if (close(fd) < 0) {
1161 ErrPrint("close: %s\n", strerror(errno));
1167 #if defined(_APPLY_SCRIPT_ASYNC_UPDATE)
1169 struct inst_info *inst;
1170 Eina_List *block_list;
1174 static Eina_Bool apply_changes_cb(void *_data)
1176 struct apply_data *data = _data;
1177 struct block *block;
1179 block = eina_list_nth(data->block_list, 0);
1180 data->block_list = eina_list_remove(data->block_list, block);
1181 consuming_parsed_block(data->inst, data->is_pd, block);
1183 if (!data->block_list) {
1185 return ECORE_CALLBACK_CANCEL;
1188 return ECORE_CALLBACK_RENEW;
1192 HAPI int script_handler_parse_desc(struct inst_info *inst, const char *filename, int is_pd)
1203 struct block *block = NULL;
1204 Eina_List *block_list = NULL;
1214 filebuf = load_file(filename);
1216 return DBOX_STATUS_ERROR_IO_ERROR;
1222 while (*fileptr && state != ERROR) {
1225 if (*fileptr == '{') {
1226 block = calloc(1, sizeof(*block));
1228 ErrPrint("calloc: %s\n", strerror(errno));
1237 if (isspace(*fileptr)) {
1241 } else if (*fileptr == '=') {
1245 } else if (ptr == NULL) {
1250 while (field_list[field_idx]) {
1251 if (field_list[field_idx][field_len] == *fileptr) {
1257 if (!field_list[field_idx]) {
1258 ErrPrint("Invalid field\n");
1265 if (field_list[field_idx][field_len] != *fileptr) {
1267 while (field_list[field_idx]) {
1268 if (!strncmp(field_list[field_idx], fileptr - field_len, field_len)) {
1275 if (!field_list[field_idx]) {
1277 ErrPrint("field is not valid\n");
1286 switch (field_idx) {
1289 if (isspace(*fileptr)) {
1293 if (*fileptr == '\0') {
1295 ErrPrint("Type is not valid\n");
1304 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1308 if (type_list[type_idx][type_len] != *fileptr) {
1310 while (type_list[type_idx]) {
1311 if (!strncmp(type_list[type_idx], fileptr - type_len, type_len)) {
1318 if (!type_list[type_idx]) {
1320 ErrPrint("type is not valid (%s)\n", fileptr - type_len);
1326 block->type = type_idx;
1338 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1353 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1368 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1373 block->option = ptr;
1383 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1398 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1403 block->target = ptr;
1413 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
1418 block->target = ptr;
1428 if (isspace(*fileptr)) {
1429 } else if (*fileptr == '}') {
1431 block->filename = filename;
1432 block_list = eina_list_append(block_list, block);
1447 if (state != BEGIN) {
1448 ErrPrint("State %d\n", state);
1453 EINA_LIST_FREE(block_list, block) {
1457 PERF_MARK("parser");
1458 return DBOX_STATUS_ERROR_FAULT;
1461 block = eina_list_data_get(eina_list_last(block_list));
1463 block->filebuf = filebuf;
1465 ErrPrint("Last block is not exists (There is no parsed block)\n");
1469 PERF_MARK("parser");
1471 #if defined(_APPLY_SCRIPT_ASYNC_UPDATE)
1472 struct apply_data *data;
1474 data = malloc(sizeof(*data));
1477 data->is_pd = is_pd;
1478 data->block_list = block_list;
1479 if (!ecore_timer_add(0.001f, apply_changes_cb, data)) {
1480 ErrPrint("Failed to add timer\n");
1482 EINA_LIST_FREE(block_list, block) {
1483 consuming_parsed_block(inst, is_pd, block);
1487 ErrPrint("Heap: %s\n", strerror(errno));
1488 EINA_LIST_FREE(block_list, block) {
1489 consuming_parsed_block(inst, is_pd, block);
1493 ErrPrint("Begin: Set content for EDJE object\n");
1494 EINA_LIST_FREE(block_list, block) {
1495 consuming_parsed_block(inst, is_pd, block);
1497 ErrPrint("End: Set content for EDJE object\n");
1500 * Doesn't need to force to render the contents.
1501 struct script_info *info;
1502 info = is_pd ? instance_gbar_script(inst) : instance_dbox_script(inst);
1503 if (info && info->ee) {
1504 ecore_evas_manual_render(info->ee);
1509 return DBOX_STATUS_ERROR_NONE;