2 * Copyright 2012 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.
19 #include <stdlib.h> /* free */
22 #include <sys/types.h>
26 #include <Ecore_Evas.h>
33 #include "slave_life.h"
34 #include "slave_rpc.h"
35 #include "client_life.h"
38 #include "buffer_handler.h"
39 #include "script_handler.h"
45 #define TYPE_TEXT "text"
46 #define TYPE_IMAGE "image"
47 #define TYPE_EDJE "script"
48 #define TYPE_SIGNAL "signal"
49 #define TYPE_INFO "info"
50 #define TYPE_DRAG "drag"
51 #define INFO_SIZE "size"
52 #define INFO_CATEGORY "category"
58 Eina_List *script_port_list;
59 enum buffer_type env_buf_type;
61 .script_port_list = NULL,
62 .env_buf_type = BUFFER_TYPE_FILE,
68 const char *(*magic_id)(void);
69 int (*update_text)(void *handle, Evas *e, const char *id, const char *part, const char *text);
70 int (*update_image)(void *handle, Evas *e, const char *id, const char *part, const char *path);
71 int (*update_script)(void *handle, Evas *e, const char *src_id, const char *target_id, const char *part, const char *path, const char *group);
72 int (*update_signal)(void *handle, Evas *e, const char *id, const char *part, const char *signal);
73 int (*update_drag)(void *handle, Evas *e, const char *id, const char *part, double x, double y);
74 int (*update_size)(void *handle, Evas *e, const char *id, int w, int h);
75 int (*update_category)(void *handle, Evas *e, const char *id, const char *category);
77 void *(*create)(const char *file, const char *group);
78 int (*destroy)(void *handle);
80 int (*load)(void *handle, Evas *e, int w, int h);
81 int (*unload)(void *handle, Evas *e);
113 struct inst_info *inst;
123 struct script_port *port;
127 static inline struct script_port *find_port(const char *magic_id)
130 struct script_port *item;
132 EINA_LIST_FOREACH(s_info.script_port_list, l, item) {
133 if (!strcmp(item->magic_id(), magic_id))
140 static void render_pre_cb(void *data, Evas *e, void *event_info)
142 struct inst_info *inst = data;
143 struct script_info *info;
145 if (instance_state(inst) != INST_ACTIVATED) {
146 DbgPrint("Render pre invoked but instance is not activated\n");
150 info = instance_lb_script(inst);
151 if (info && script_handler_evas(info) == e) {
155 info = instance_pd_script(inst);
156 if (info && script_handler_evas(info) == e) {
160 ErrPrint("Failed to do sync\n");
164 static void render_post_cb(void *data, Evas *e, void *event_info)
166 struct inst_info *inst;
167 struct script_info *info;
171 if (instance_state(inst) != INST_ACTIVATED) {
172 DbgPrint("Render post invoked but instance is not activated\n");
176 info = instance_lb_script(inst);
177 if (info && script_handler_evas(info) == e) {
178 fb_sync(script_handler_fb(info));
179 instance_lb_updated_by_instance(inst);
183 info = instance_pd_script(inst);
184 if (info && script_handler_evas(info) == e) {
185 fb_sync(script_handler_fb(info));
186 instance_pd_updated_by_instance(inst, NULL);
190 ErrPrint("Failed to sync\n");
198 int script_signal_emit(Evas *e, const char *part, const char *signal, double sx, double sy, double ex, double ey)
201 struct script_info *info;
204 ee = ecore_evas_ecore_evas_get(e);
206 ErrPrint("Evas has no Ecore_Evas\n");
210 info = ecore_evas_data_get(ee, "script,info");
212 ErrPrint("ecore_evas doesn't carry info data\n");
216 if (!signal || strlen(signal) == 0)
219 if (!part || strlen(part) == 0)
222 ret = instance_signal_emit(info->inst, signal, part, sx, sy, ex, ey, info->x, info->y, info->down);
226 HAPI int script_handler_load(struct script_info *info, int is_pd)
231 if (!info || !info->port) {
232 ErrPrint("Script handler is not created\n");
236 if (info->loaded > 0) {
241 ret = fb_create_buffer(info->fb);
245 info->ee = fb_canvas(info->fb);
247 ErrPrint("Failed to get canvas\n");
248 fb_destroy_buffer(info->fb);
252 ecore_evas_data_set(info->ee, "script,info", info);
254 e = script_handler_evas(info);
256 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_PRE, render_pre_cb, info->inst);
257 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, render_post_cb, info->inst);
258 if (info->port->load(info->port_data, e, info->w, info->h) < 0) {
259 ErrPrint("Failed to add new script object\n");
260 evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, render_post_cb);
261 evas_event_callback_del(e, EVAS_CALLBACK_RENDER_PRE, render_pre_cb);
262 fb_destroy_buffer(info->fb);
267 ErrPrint("Evas: (nil) %dx%d\n", info->w, info->h);
270 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
271 ecore_evas_resize(info->ee, info->w, info->h);
272 ecore_evas_show(info->ee);
273 ecore_evas_activate(info->ee);
277 script_signal_emit(e, util_uri_to_path(instance_id(info->inst)),
278 is_pd ? "pd,show" : "lb,show", 0.0f, 0.0f, 0.0f, 0.0f);
282 HAPI int script_handler_unload(struct script_info *info, int is_pd)
287 if (!info || !info->port)
291 if (info->loaded > 0)
294 if (info->loaded < 0) {
299 e = script_handler_evas(info);
301 script_signal_emit(e, util_uri_to_path(instance_id(info->inst)), is_pd ? "pd,hide" : "lb,hide", 0.0f, 0.0f, 0.0f, 0.0f);
302 if (info->port->unload(info->port_data, e) < 0)
303 ErrPrint("Failed to unload script object. but go ahead\n");
304 evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, render_post_cb);
305 evas_event_callback_del(e, EVAS_CALLBACK_RENDER_PRE, render_pre_cb);
307 ErrPrint("Evas(nil): Unload script\n");
310 ee = fb_canvas(info->fb);
312 ecore_evas_data_set(ee, "script,info", NULL);
314 fb_destroy_buffer(info->fb);
318 HAPI struct script_info *script_handler_create(struct inst_info *inst, const char *file, const char *group, int w, int h)
320 struct script_info *info;
322 DbgPrint("Create script: %s (%s)\n", file, group);
327 info = calloc(1, sizeof(*info));
329 ErrPrint("Heap: %s\n", strerror(errno));
333 info->fb = fb_create(inst, w, h, s_info.env_buf_type);
335 ErrPrint("Failed to create a FB (%dx%d)\n", w, h);
341 info->port = find_port(package_script(instance_package(inst)));
343 ErrPrint("Failed to find a proper port for [%s]%s\n",
344 instance_package(inst), package_script(instance_package(inst)));
345 fb_destroy(info->fb);
350 DbgPrint("Update info [%dx%d]\n", w, h);
354 info->port_data = info->port->create(file, group);
355 if (!info->port_data) {
356 ErrPrint("Failed to create a port (%s - %s)\n", file, group);
357 fb_destroy(info->fb);
365 HAPI int script_handler_destroy(struct script_info *info)
367 if (!info || !info->port) {
368 ErrPrint("port is not valid\n");
372 if (info->loaded != 0) {
373 ErrPrint("Script handler is not unloaded\n");
377 if (info->port->destroy(info->port_data) < 0)
378 ErrPrint("Failed to destroy port, but go ahead\n");
380 fb_destroy(info->fb);
385 HAPI int script_handler_is_loaded(struct script_info *info)
387 return info ? info->loaded > 0 : 0;
390 HAPI struct fb_info *script_handler_fb(struct script_info *info)
392 return info ? info->fb : NULL;
395 HAPI void *script_handler_evas(struct script_info *info)
403 return ecore_evas_get(info->ee);
406 static int update_script_text(struct inst_info *inst, struct block *block, int is_pd)
408 struct script_info *info;
411 if (!block || !block->part || !block->data) {
412 ErrPrint("Block or part or data is not valid\n");
416 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
418 ErrPrint("info is NIL\n");
423 ErrPrint("info->port is NIL\n");
427 e = script_handler_evas(info);
429 info->port->update_text(info->port_data, e, block->id, block->part, block->data);
431 ErrPrint("Evas(nil) id[%s] part[%s] data[%s]\n", block->id, block->part, block->data);
435 static int update_script_image(struct inst_info *inst, struct block *block, int is_pd)
437 struct script_info *info;
440 if (!block || !block->part) {
441 ErrPrint("Block or part is not valid\n");
445 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
447 ErrPrint("info is NIL\n");
452 ErrPrint("info->port is NIL\n");
456 e = script_handler_evas(info);
458 info->port->update_image(info->port_data, e, block->id, block->part, block->data);
460 ErrPrint("Evas: (nil) id[%s] part[%s] data[%s]\n", block->id, block->part, block->data);
464 static int update_script_script(struct inst_info *inst, struct block *block, int is_pd)
466 struct script_info *info;
469 if (!block || !block->part) {
470 ErrPrint("Block or part is NIL\n");
474 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
476 ErrPrint("info is NIL\n");
481 ErrPrint("info->port is NIL\n");
485 e = script_handler_evas(info);
487 info->port->update_script(info->port_data, e, block->id, block->target_id, block->part, block->data, block->group);
489 ErrPrint("Evas: (nil) id[%s] part[%s] data[%s] group[%s]\n",
490 block->id, block->part, block->data, block->group);
494 static int update_script_signal(struct inst_info *inst, struct block *block, int is_pd)
496 struct script_info *info;
500 ErrPrint("block is NIL\n");
504 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
506 ErrPrint("info is NIL\n");
511 ErrPrint("info->port is NIL\n");
515 e = script_handler_evas(info);
517 info->port->update_signal(info->port_data, e, block->id, block->part, block->data);
519 ErrPrint("Evas(nil) id[%s] part[%s] data[%s]\n", block->id, block->part, block->data);
523 static int update_script_drag(struct inst_info *inst, struct block *block, int is_pd)
525 struct script_info *info;
529 if (!block || !block->data || !block->part) {
530 ErrPrint("block or block->data or block->part is NIL\n");
534 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
536 ErrPrint("info is NIL\n");
540 if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) {
541 ErrPrint("Invalid format of data (DRAG data [%s])\n", block->data);
546 ErrPrint("info->port is NIL\n");
550 e = script_handler_evas(info);
552 info->port->update_drag(info->port_data, e, block->id, block->part, dx, dy);
554 ErrPrint("Evas(nil) id[%s] part[%s] %lfx%lf\n", block->id, block->part, dx, dy);
558 HAPI int script_handler_resize(struct script_info *info, int w, int h)
561 //|| (info->w == w && info->h == h)) {
562 ErrPrint("info[%p] resize is not changed\n", info);
566 fb_resize(script_handler_fb(info), w, h);
568 if (info->port->update_size) {
570 e = script_handler_evas(info);
572 info->port->update_size(info->port_data, e, NULL , w, h);
574 ErrPrint("Evas(nil) resize to %dx%d\n", w, h);
583 static int update_info(struct inst_info *inst, struct block *block, int is_pd)
585 struct script_info *info;
587 if (!block || !block->part || !block->data) {
588 ErrPrint("block or block->part or block->data is NIL\n");
592 info = is_pd ? instance_pd_script(inst) : instance_lb_script(inst);
594 ErrPrint("info is NIL\n");
599 ErrPrint("info->port is NIL\n");
603 if (!strcasecmp(block->part, INFO_SIZE)) {
606 if (sscanf(block->data, "%dx%d", &w, &h) != 2) {
607 ErrPrint("Invalid format for SIZE(%s)\n", block->data);
613 instance_set_pd_info(inst, w, h);
615 instance_set_lb_info(inst, w, h, NO_CHANGE, CONTENT_NO_CHANGE, TITLE_NO_CHANGE);
617 script_handler_resize(info, w, h);
620 e = script_handler_evas(info);
622 info->port->update_size(info->port_data, e, block->id, w, h);
624 ErrPrint("Evas(nil): id[%s] %dx%d\n", block->id, w, h);
626 } else if (!strcasecmp(block->part, INFO_CATEGORY)) {
628 e = script_handler_evas(info);
630 info->port->update_category(info->port_data, e, block->id, block->data);
632 ErrPrint("Evas(nil): id[%s] data[%s]\n", block->id, block->data);
638 HAPI int script_handler_parse_desc(const char *pkgname, const char *id, const char *descfile, int is_pd)
640 struct inst_info *inst;
659 const char *field_name[] = {
670 register int field_idx;
671 register int idx = 0;
676 int (*handler)(struct inst_info *inst, struct block *block, int is_pd);
680 .handler = update_script_text,
684 .handler = update_script_image,
688 .handler = update_script_script,
692 .handler = update_script_signal,
696 .handler = update_script_drag,
700 .handler = update_info,
709 inst = package_find_instance_by_id(pkgname, id);
711 ErrPrint("Instance is not exists\n");
715 fp = fopen(descfile, "rt");
717 ErrPrint("Error: %s [%s]\n", descfile, strerror(errno));
738 if (!isspace(ch) && ch != EOF) {
739 ErrPrint("%d: Syntax error: Desc is not started with '{' or space - (%c = 0x%x)\n", lineno, ch, ch);
750 ErrPrint("%d: Syntax error: New line must has to be started right after '{'\n", lineno);
754 block = calloc(1, sizeof(*block));
756 ErrPrint("Heap: %s\n", strerror(errno));
776 if (field_name[field_idx][idx] != '\0') {
777 ErrPrint("%d: Syntax error: Unrecognized field\n", lineno);
785 DbgFree(block->type);
794 DbgFree(block->part);
803 DbgFree(block->data);
812 DbgFree(block->file);
821 DbgFree(block->group);
823 block->group_len = 0;
837 state = VALUE_TARGET;
838 if (block->target_id) {
839 DbgFree(block->target_id);
840 block->target_id = NULL;
841 block->target_len = 0;
846 ErrPrint("%d: Syntax error: Unrecognized field\n", lineno);
856 if (field_name[field_idx][idx] != ch) {
862 ungetc(field_name[field_idx][idx], fp);
865 if (field_name[field_idx] == NULL) {
866 ErrPrint("%d: Syntax error: Unrecognized field\n", lineno);
878 if (idx == block->type_len) {
880 block->type_len += ADDEND;
881 tmp = realloc(block->type, block->type_len);
883 ErrPrint("Heap: %s\n", strerror(errno));
890 block->type[idx] = '\0';
897 block->type[idx] = ch;
902 if (idx == block->part_len) {
904 block->part_len += ADDEND;
905 tmp = realloc(block->part, block->part_len);
907 ErrPrint("Heap: %s\n", strerror(errno));
914 block->part[idx] = '\0';
921 block->part[idx] = ch;
926 if (idx == block->data_len) {
928 block->data_len += ADDEND;
929 tmp = realloc(block->data, block->data_len);
931 ErrPrint("Heap: %s\n", strerror(errno));
938 block->data[idx] = '\0';
945 block->data[idx] = ch;
950 if (idx == block->file_len) {
952 block->file_len += ADDEND;
953 tmp = realloc(block->file, block->file_len);
955 ErrPrint("Heap: %s\n", strerror(errno));
962 block->file[idx] = '\0';
969 block->file[idx] = ch;
974 if (idx == block->group_len) {
976 block->group_len += ADDEND;
977 tmp = realloc(block->group, block->group_len);
979 ErrPrint("Heap: %s\n", strerror(errno));
986 block->group[idx] = '\0';
993 block->group[idx] = ch;
997 if (idx == block->id_len) {
999 block->id_len += ADDEND;
1000 tmp = realloc(block->id, block->id_len);
1002 ErrPrint("Heap: %s\n", strerror(errno));
1009 block->id[idx] = '\0';
1016 block->id[idx] = ch;
1020 if (idx == block->target_len) {
1022 block->target_len += ADDEND;
1023 tmp = realloc(block->target_id, block->target_len);
1025 ErrPrint("Heap: %s\n", strerror(errno));
1028 block->target_id = tmp;
1032 block->target_id[idx] = '\0';
1039 block->target_id[idx] = ch;
1044 block->file = strdup(util_uri_to_path(id));
1046 ErrPrint("Heap: %s\n", strerror(errno));
1052 while (handlers[i].type) {
1053 if (!strcasecmp(handlers[i].type, block->type)) {
1054 handlers[i].handler(inst, block, is_pd);
1060 if (!handlers[i].type)
1061 ErrPrint("%d: Unknown block type: %s\n", lineno, block->type);
1063 DbgFree(block->file);
1064 DbgFree(block->type);
1065 DbgFree(block->part);
1066 DbgFree(block->data);
1067 DbgFree(block->group);
1069 DbgFree(block->target_id);
1081 if (state != UNKNOWN) {
1082 ErrPrint("%d: Unknown state\n", lineno);
1090 ErrPrint("Parse error at %d file %s\n", lineno, util_basename(descfile));
1092 DbgFree(block->file);
1093 DbgFree(block->type);
1094 DbgFree(block->part);
1095 DbgFree(block->data);
1096 DbgFree(block->group);
1098 DbgFree(block->target_id);
1105 HAPI int script_init(void)
1107 struct script_port *item;
1113 if (!strcasecmp(PROVIDER_METHOD, "shm"))
1114 s_info.env_buf_type = BUFFER_TYPE_SHM;
1115 else if (!strcasecmp(PROVIDER_METHOD, "pixmap"))
1116 s_info.env_buf_type = BUFFER_TYPE_PIXMAP;
1118 dir = opendir(SCRIPT_PORT_PATH);
1120 ErrPrint("Error: %s\n", strerror(errno));
1124 while ((ent = readdir(dir))) {
1125 if (ent->d_name[0] == '.')
1128 pathlen = strlen(ent->d_name) + strlen(SCRIPT_PORT_PATH) + 1;
1129 path = malloc(pathlen);
1131 ErrPrint("Heap: %s %d\n", strerror(errno), pathlen);
1136 snprintf(path, pathlen, "%s%s", SCRIPT_PORT_PATH, ent->d_name);
1138 item = malloc(sizeof(*item));
1140 ErrPrint("Heap: %s\n", strerror(errno));
1146 DbgPrint("Open SCRIPT PORT: %s\n", path);
1147 item->handle = dlopen(path, RTLD_LOCAL | RTLD_LAZY);
1149 if (!item->handle) {
1150 ErrPrint("Error: %s\n", dlerror());
1156 item->magic_id = dlsym(item->handle, "script_magic_id");
1157 if (!item->magic_id)
1160 DbgPrint("SCRIPT PORT magic id: %s\n", item->magic_id());
1162 item->update_text = dlsym(item->handle, "script_update_text");
1163 if (!item->update_text)
1166 item->update_image = dlsym(item->handle, "script_update_image");
1167 if (!item->update_image)
1170 item->update_script = dlsym(item->handle, "script_update_script");
1171 if (!item->update_script)
1174 item->update_signal = dlsym(item->handle, "script_update_signal");
1175 if (!item->update_signal)
1178 item->update_drag = dlsym(item->handle, "script_update_drag");
1179 if (!item->update_drag)
1182 item->update_size = dlsym(item->handle, "script_update_size");
1183 if (!item->update_size)
1186 item->update_category = dlsym(item->handle, "script_update_category");
1187 if (!item->update_category)
1190 item->create = dlsym(item->handle, "script_create");
1194 item->destroy = dlsym(item->handle, "script_destroy");
1198 item->load = dlsym(item->handle, "script_load");
1202 item->unload = dlsym(item->handle, "script_unload");
1206 item->init = dlsym(item->handle, "script_init");
1210 item->fini = dlsym(item->handle, "script_fini");
1214 if (item->init() < 0) {
1215 ErrPrint("Failed to initialize script engine\n");
1219 s_info.script_port_list = eina_list_append(s_info.script_port_list, item);
1226 ErrPrint("Error: %s\n", dlerror());
1227 dlclose(item->handle);
1233 HAPI int script_fini(void)
1235 struct script_port *item;
1237 * \TODO: Release all handles
1239 EINA_LIST_FREE(s_info.script_port_list, item) {
1241 dlclose(item->handle);
1248 HAPI int script_handler_update_pointer(struct script_info *info, double x, double y, int down)