19 #include <Ecore_Getopt.h>
20 #include <Ecore_Evas.h>
26 Eina_Bool list_groups;
29 unsigned char color[3];
40 static Eina_Bool _edje_load_or_show_error(Evas_Object *edje, const char *file, const char *group);
42 static Ecore_Evas *win;
45 _win_title_set(const char *group, const char *file)
48 snprintf(buf, sizeof(buf), "Edje_Player - %s of %s", group, file);
49 ecore_evas_title_set(win, buf);
53 _slave_mode_tok(char **p_arg)
58 if (!*p_arg) return NULL;
71 is_quoted = EINA_TRUE;
77 is_quoted = EINA_FALSE;
81 for (e = s; *e != '\0'; e++)
83 if ((!is_quoted) && (isspace(*e)))
85 else if ((is_quoted) && (*e == '"'))
89 if (*e == '\0') return NULL;
96 _slave_mode_signal(Evas_Object *edje, char *args)
98 char *emission, *source;
101 source = _slave_mode_tok(&emission);
102 _slave_mode_tok(&source);
104 if ((!emission) || (!source))
106 fputs("ERROR: Invalid command arguments.\n", stderr);
110 edje_object_signal_emit(edje, emission, source);
114 _slave_mode_info(Evas_Object *edje, char *args)
116 _slave_mode_tok(&args);
120 fputs("ERROR: Invalid command arguments.\n", stderr);
124 if (!edje_object_part_exists(edje, args))
126 printf("INFO: \"%s\" does not exist.\n", args);
130 Evas_Coord x, y, w, h;
131 edje_object_part_geometry_get(edje, args, &x, &y, &w, &h);
132 printf("INFO: \"%s\" %d,%d,%d,%d\n", args, x, y, w, h);
137 _slave_mode_quit(Evas_Object *edje __UNUSED__, char *args __UNUSED__)
140 ecore_main_loop_quit();
144 _slave_mode_help(Evas_Object *edje __UNUSED__, char *args __UNUSED__)
147 "One command per line, arguments separated by space. Strings may have "
148 "spaces if enclosed in quotes (\").\n"
150 "\t<command> [arguments]\n"
152 "Available commands:\n"
153 "\tsignal <emission> <source>\n"
154 "\t sends a signal to edje\n"
156 "\t Print part geometry: <x>,<y>,<w>,<h>\n"
158 "\t exit edje player.\n"
160 "\t shows this message.\n");
162 * Extension ideas (are they useful?):
163 * - message: send a message
164 * - data: show data value
165 * - color_class: set color class values (maybe also list?)
166 * - text_class: set text class values (maybe also list?)
167 * - play_set: change play state
168 * - animation_set: change animation state
175 void (*func)(Evas_Object *edje, char *args);
176 } _slave_mode_commands[] = {
177 {"signal", _slave_mode_signal},
178 {"info", _slave_mode_info},
179 {"quit", _slave_mode_quit},
180 {"help", _slave_mode_help},
185 _slave_mode(void *data, Ecore_Fd_Handler *fd_handler)
187 Evas_Object *edje = data;
189 const struct slave_cmd *itr;
192 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
194 fputs("ERROR: error on stdin! Exit.\n", stderr);
195 ecore_main_loop_quit();
196 return ECORE_CALLBACK_CANCEL;
198 if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
199 return ECORE_CALLBACK_RENEW;
201 if (!fgets(buf, sizeof(buf), stdin))
203 fputs("ERROR: end of stdin! Exit.\n", stderr);
204 ecore_main_loop_quit();
205 return ECORE_CALLBACK_CANCEL;
211 fputs("ERROR: no input! Try: help\n", stderr);
212 return ECORE_CALLBACK_RENEW;
214 if (buf[len - 1] == '\n')
220 p = strchr(buf, ' ');
233 char *q = p + strlen(p) - 1;
242 for (itr = _slave_mode_commands; itr->cmd; itr++)
244 if (strcmp(itr->cmd, buf) == 0)
251 return ECORE_CALLBACK_RENEW;
255 _print_signal(void *data __UNUSED__, Evas_Object *o __UNUSED__, const char *emission, const char *source)
257 printf("SIGNAL: \"%s\" \"%s\"\n", emission, source);
261 _print_message(void *data __UNUSED__, Evas_Object *edje __UNUSED__, Edje_Message_Type type, int id, void *msg)
268 case EDJE_MESSAGE_NONE:
271 case EDJE_MESSAGE_SIGNAL:
274 case EDJE_MESSAGE_STRING:
277 case EDJE_MESSAGE_INT:
280 case EDJE_MESSAGE_FLOAT:
283 case EDJE_MESSAGE_STRING_SET:
284 typestr = "STRING_SET";
286 case EDJE_MESSAGE_INT_SET:
289 case EDJE_MESSAGE_FLOAT_SET:
290 typestr = "FLOAT_SET";
292 case EDJE_MESSAGE_STRING_INT:
293 typestr = "STRING_INT";
295 case EDJE_MESSAGE_STRING_FLOAT:
296 typestr = "STRING_FLOAT";
298 case EDJE_MESSAGE_STRING_INT_SET:
301 case EDJE_MESSAGE_STRING_FLOAT_SET:
302 typestr = "FLOAT_SET";
305 snprintf(buf, sizeof(buf), "UNKNOWN(%d)", type);
309 printf("MESSAGE: type=%s, id=%d", typestr, id);
313 case EDJE_MESSAGE_NONE: break;
314 case EDJE_MESSAGE_SIGNAL: break;
315 case EDJE_MESSAGE_STRING:
317 Edje_Message_String *m = msg;
318 printf(" \"%s\"", m->str);
321 case EDJE_MESSAGE_INT:
323 Edje_Message_Int *m = msg;
324 printf(" %d", m->val);
327 case EDJE_MESSAGE_FLOAT:
329 Edje_Message_Float *m = msg;
330 printf(" %f", m->val);
333 case EDJE_MESSAGE_STRING_SET:
335 Edje_Message_String_Set *m = msg;
337 for (i = 0; i < m->count; i++)
338 printf(" \"%s\"", m->str[i]);
341 case EDJE_MESSAGE_INT_SET:
343 Edje_Message_Int_Set *m = msg;
345 for (i = 0; i < m->count; i++)
346 printf(" %d", m->val[i]);
349 case EDJE_MESSAGE_FLOAT_SET:
351 Edje_Message_Float_Set *m = msg;
353 for (i = 0; i < m->count; i++)
354 printf(" %f", m->val[i]);
357 case EDJE_MESSAGE_STRING_INT:
359 Edje_Message_String_Int *m = msg;
360 printf(" \"%s\" %d", m->str, m->val);
363 case EDJE_MESSAGE_STRING_FLOAT:
365 Edje_Message_String_Float *m = msg;
366 printf(" \"%s\" %f", m->str, m->val);
369 case EDJE_MESSAGE_STRING_INT_SET:
371 Edje_Message_String_Int_Set *m = msg;
373 printf(" \"%s\"", m->str);
374 for (i = 0; i < m->count; i++)
375 printf(" %d", m->val[i]);
378 case EDJE_MESSAGE_STRING_FLOAT_SET:
380 Edje_Message_String_Float_Set *m = msg;
382 printf(" \"%s\"", m->str);
383 for (i = 0; i < m->count; i++)
384 printf(" %f", m->val[i]);
395 _reset_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *stack, void *event_info __UNUSED__)
397 Evas_Coord minw, minh;
398 Evas_Object *edje = data;
400 edje_object_size_min_get(edje, &minw, &minh);
401 if ((minw <= 0) && (minh <= 0))
402 edje_object_size_min_calc(edje, &minw, &minh);
404 evas_object_size_hint_min_set(stack, minw, minh);
408 _key_down(void *data, Evas *e __UNUSED__, Evas_Object *stack __UNUSED__, void *event_info)
410 Evas_Event_Key_Down *ev = event_info;
411 struct opts *opts = data;
413 if ((!strcmp(ev->keyname, "equal")) ||
414 (!strcmp(ev->keyname, "plus")))
416 else if ((!strcmp(ev->keyname, "minus")) ||
417 (!strcmp(ev->keyname, "underscore")))
419 else if ((!strcmp(ev->keyname, "0")))
421 if (opts->scale < 0.1) opts->scale = 0.1;
422 else if (opts->scale > 10.0) opts->scale = 1.0;
423 edje_scale_set(opts->scale);
427 _create_stack(Evas *evas, const struct opts *opts)
429 Evas_Object *stack = evas_object_box_add(evas);
432 fputs("ERROR: could not create object stack (box).\n", stderr);
435 evas_object_box_layout_set(stack, evas_object_box_layout_stack, NULL, NULL);
436 evas_object_resize(stack, opts->size.w, opts->size.h);
437 evas_object_size_hint_weight_set(stack, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
438 evas_object_size_hint_align_set(stack, EVAS_HINT_FILL, EVAS_HINT_FILL);
439 evas_object_show(stack);
444 _create_bg(Evas *evas, const struct opts *opts)
446 const unsigned char *color = opts->color;
447 Evas_Object *bg = evas_object_rectangle_add(evas);
450 fputs("ERROR: could not create background.\n", stderr);
453 evas_object_resize(bg, opts->size.w, opts->size.h);
454 evas_object_color_set(bg, color[0], color[1], color[2], 255);
455 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
456 evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
457 evas_object_show(bg);
462 _edje_reload(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
466 edje_object_signal_callback_del(obj, "edje,change,file", "edje", _edje_reload);
468 edje_object_file_get(obj, &file, &group);
469 _edje_load_or_show_error(obj, file, group);
473 _edje_load_or_show_error(Evas_Object *edje, const char *file, const char *group)
478 if (edje_object_file_set(edje, file, group))
480 edje_object_signal_callback_add(edje, "edje,change,file", "edje", _edje_reload, NULL);;
481 evas_object_focus_set(edje, EINA_TRUE);
485 err = edje_object_load_error_get(edje);
486 errmsg = edje_load_error_str(err);
487 fprintf(stderr, "ERROR: could not load edje file '%s', group '%s': %s\n",
488 file, group, errmsg);
493 _create_edje(Evas *evas, const struct opts *opts)
495 Evas_Coord minw, minh, maxw, maxh;
496 Evas_Object *edje = edje_object_add(evas);
499 fputs("ERROR: could not create edje.\n", stderr);
505 if (!_edje_load_or_show_error(edje, opts->file, opts->group))
507 evas_object_del(edje);
510 if (!opts->title) _win_title_set(opts->group, opts->file);
514 if (edje_file_group_exists(opts->file, "main"))
516 if (!_edje_load_or_show_error(edje, opts->file, "main"))
518 evas_object_del(edje);
521 if (!opts->title) _win_title_set("main", opts->file);
525 Eina_List *groups = edje_file_collection_list(opts->file);
529 fprintf(stderr, "ERROR: file '%s' has no groups!\n",
531 evas_object_del(edje);
534 group = groups->data;
535 if (!_edje_load_or_show_error(edje, opts->file, group))
537 edje_file_collection_list_free(groups);
538 evas_object_del(edje);
541 if (!opts->title) _win_title_set(group, opts->file);
542 edje_file_collection_list_free(groups);
546 edje_object_size_max_get(edje, &maxw, &maxh);
547 edje_object_size_min_get(edje, &minw, &minh);
548 if ((minw <= 0) && (minh <= 0))
549 edje_object_size_min_calc(edje, &minw, &minh);
551 evas_object_size_hint_max_set(edje, maxw, maxh);
552 evas_object_size_hint_min_set(edje, minw, minh);
554 evas_object_size_hint_weight_set(edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
555 evas_object_size_hint_align_set(edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
556 evas_object_show(edje);
561 static unsigned char _parse_color(__UNUSED__ const Ecore_Getopt *parser, __UNUSED__ const Ecore_Getopt_Desc *desc, const char *str, __UNUSED__ void *data, Ecore_Getopt_Value *storage)
563 unsigned char *color = (unsigned char *)storage->ptrp;
565 if (sscanf(str, "%hhu,%hhu,%hhu", color, color + 1, color + 2) != 3)
567 fprintf(stderr, "ERROR: incorrect color value '%s'\n", str);
574 static void _cb_delete(__UNUSED__ Ecore_Evas *ee)
576 ecore_main_loop_quit();
579 const Ecore_Getopt optdesc = {
581 "%prog [options] <filename.edj>",
583 "(C) 2010 Enlightenment",
584 "BSD with advertisement clause",
585 "Simple application to view edje files.",
588 ECORE_GETOPT_STORE_STR
589 ('g', "group", "The edje group to view (defaults to 'main')."),
590 ECORE_GETOPT_STORE_TRUE
591 ('G', "list-groups", "The groups in the given file."),
592 ECORE_GETOPT_STORE_STR
593 ('e', "engine", "The Ecore-Evas engine to use (see --list-engines)"),
594 ECORE_GETOPT_CALLBACK_NOARGS
595 ('E', "list-engines", "list Ecore-Evas engines",
596 ecore_getopt_callback_ecore_evas_list_engines, NULL),
597 ECORE_GETOPT_CALLBACK_ARGS
598 ('Z', "size", "size to use in wxh form.", "WxH",
599 ecore_getopt_callback_size_parse, NULL),
600 ECORE_GETOPT_CALLBACK_ARGS
601 ('c', "bg-color", "Color of the background (if not shaped or alpha)",
602 "RRGGBB", _parse_color, NULL),
603 ECORE_GETOPT_STORE_TRUE
604 ('b', "borderless", "Display window without border."),
605 ECORE_GETOPT_STORE_TRUE
606 ('y', "sticky", "Display window sticky."),
607 ECORE_GETOPT_STORE_TRUE
608 ('s', "shaped", "Display window shaped."),
609 ECORE_GETOPT_STORE_TRUE
610 ('a', "alpha", "Display window with alpha channel "
611 "(needs composite manager!)"),
612 ECORE_GETOPT_STORE_STR
613 ('t', "title", "Define the window title string"),
614 ECORE_GETOPT_STORE_TRUE
615 ('p', "print", "Print signals and messages to stdout"),
616 ECORE_GETOPT_STORE_TRUE
617 ('S', "slave-mode", "Listen for commands on stdin"),
618 ECORE_GETOPT_STORE_DOUBLE
619 ('z', "scale", "Set scale factor"),
620 ECORE_GETOPT_LICENSE('L', "license"),
621 ECORE_GETOPT_COPYRIGHT('C', "copyright"),
622 ECORE_GETOPT_VERSION('V', "version"),
623 ECORE_GETOPT_HELP('h', "help"),
624 ECORE_GETOPT_SENTINEL
628 int main(int argc, char **argv)
631 Evas_Object *stack, *edje;
633 Eina_Bool quit_option = EINA_FALSE;
635 Ecore_Getopt_Value values[] = {
636 ECORE_GETOPT_VALUE_STR(opts.group),
637 ECORE_GETOPT_VALUE_BOOL(opts.list_groups),
638 ECORE_GETOPT_VALUE_STR(opts.engine),
639 ECORE_GETOPT_VALUE_BOOL(quit_option),
640 ECORE_GETOPT_VALUE_PTR_CAST(opts.size),
641 ECORE_GETOPT_VALUE_PTR_CAST(opts.color),
642 ECORE_GETOPT_VALUE_BOOL(opts.borderless),
643 ECORE_GETOPT_VALUE_BOOL(opts.sticky),
644 ECORE_GETOPT_VALUE_BOOL(opts.shaped),
645 ECORE_GETOPT_VALUE_BOOL(opts.alpha),
646 ECORE_GETOPT_VALUE_STR(opts.title),
647 ECORE_GETOPT_VALUE_BOOL(opts.print),
648 ECORE_GETOPT_VALUE_BOOL(opts.slave_mode),
649 ECORE_GETOPT_VALUE_DOUBLE(opts.scale),
650 ECORE_GETOPT_VALUE_BOOL(quit_option),
651 ECORE_GETOPT_VALUE_BOOL(quit_option),
652 ECORE_GETOPT_VALUE_BOOL(quit_option),
653 ECORE_GETOPT_VALUE_BOOL(quit_option),
654 ECORE_GETOPT_VALUE_NONE
657 memset(&opts, 0, sizeof(opts));
660 if (!ecore_evas_init())
663 goto shutdown_ecore_evas;
664 edje_frametime_set(1.0/60.0);
666 args = ecore_getopt_parse(&optdesc, values, argc, argv);
669 fputs("Could not parse arguments.\n", stderr);
672 else if (quit_option)
676 else if (args >= argc)
678 fputs("Missing edje file to load.\n", stderr);
682 ecore_app_args_set(argc, (const char **)argv);
683 edje_scale_set(opts.scale);
685 // check if the given edj file is there
686 if (access(argv[args], R_OK) == -1)
689 fprintf(stderr, "ERROR: file '%s' not accessible, error %d (%s).\n",
690 argv[args], e, strerror(e));
694 opts.file = argv[args];
695 if (opts.list_groups)
697 Eina_List *groups, *n;
699 groups = edje_file_collection_list(opts.file);
700 printf("%d groups in file '%s':\n", eina_list_count(groups), opts.file);
701 EINA_LIST_FOREACH(groups, n, group)
702 printf("\t'%s'\n", group);
703 edje_file_collection_list_free(groups);
707 if (opts.size.w <= 0) opts.size.w = 320;
708 if (opts.size.h <= 0) opts.size.h = 240;
709 win = ecore_evas_new(opts.engine, 0, 0, opts.size.w, opts.size.h, NULL);
713 "ERROR: could not create window of "
714 "size %dx%d using engine %s.\n",
715 opts.size.w, opts.size.h, opts.engine ? opts.engine : "(auto)");
719 ecore_evas_callback_delete_request_set(win, _cb_delete);
720 evas = ecore_evas_get(win);
721 stack = _create_stack(evas, &opts);
724 goto free_ecore_evas;
727 ecore_evas_object_associate(win, stack, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
730 ecore_evas_alpha_set(win, EINA_TRUE);
731 else if (opts.shaped)
732 ecore_evas_shaped_set(win, EINA_TRUE);
735 Evas_Object *bg = _create_bg(evas, &opts);
736 if (bg) evas_object_box_append(stack, bg);
739 edje = _create_edje(evas, &opts);
741 evas_object_box_append(stack, edje);
744 goto free_ecore_evas;
747 evas_object_focus_set(stack, EINA_TRUE);
748 evas_object_event_callback_add(stack, EVAS_CALLBACK_KEY_DOWN,
750 evas_object_event_callback_add(stack, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
751 _reset_size_hints, edje);
755 edje_object_signal_callback_add(edje, "*", "*", _print_signal, NULL);
756 edje_object_message_handler_set(edje, _print_message, NULL);
763 flags = fcntl(STDIN_FILENO, F_GETFL, 0);
765 if (fcntl(STDIN_FILENO, F_SETFL, flags) < 0)
767 fprintf(stderr, "ERROR: Could not set stdin to non-block: %s\n",
769 goto free_ecore_evas;
771 ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ | ECORE_FD_ERROR,
772 _slave_mode, edje, NULL, NULL);
774 /* TODO: port the code above to Windows */
775 fprintf (stderr, "ERROR: slave mode not working on Windows\n");
776 goto free_ecore_evas;
780 ecore_evas_borderless_set(win, opts.borderless);
781 ecore_evas_sticky_set(win, opts.sticky);
783 ecore_evas_title_set(win, opts.title);
785 ecore_evas_show(win);
786 ecore_main_loop_begin();
788 ecore_evas_free(win);
791 ecore_evas_shutdown();
796 ecore_evas_free(win);
800 ecore_evas_shutdown();