2 * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
4 * This program is licensed under the terms and conditions of the
5 * Apache License, version 2.0. The full text of the Apache License is at
6 * http://www.apache.org/licenses/LICENSE-2.0
10 * @brief statusbar application
19 #include <libwebsockets.h>
22 #include <Ecore_Wayland.h>
23 #include <Ecore_Evas.h>
24 #include <Elementary.h>
27 #include "ico_uxf_conf.h"
29 #include "home_screen.h"
30 #include "home_screen_res.h"
31 #include "home_screen_conf.h"
33 /*============================================================================*/
34 /* Define data types */
35 /*============================================================================*/
36 #define ICO_SB_TIME_AM (10) /* f_name in sb_time_data */
37 #define ICO_SB_TIME_PM (11) /* f_name in sb_time_data */
38 #define ICO_SB_TIME_IMG_PARTS (12) /* total counts of sb_time_data */
39 #define ICO_SB_TIMEOUT (0.2)
41 #define ICO_SB_WS_TIMEOUT (0.05)
42 #define ICO_SB_WS_ADDRESS "127.0.0.1"
43 #define ICO_SB_WS_PROTOCOL_NAME ICO_HS_PROTOCOL_SB
44 #define ICO_SB_BUF_SIZE (1024)
45 #define ICO_SB_VERTICAL (1)
46 #define ICO_SB_HORIZONTAL (2)
48 #define ICO_SB_POS_Y (0)
49 #define ICO_SB_POS_COLON_X (689)
50 #define ICO_SB_POS_COLON_Y (30)
51 #define ICO_SB_POS_AMPM_X (582)
52 #define ICO_SB_POS_AMPM_Y (27)
53 #define ICO_SB_POS_HOUR1_X (640)
54 #define ICO_SB_POS_HOUR1_Y (18)
55 #define ICO_SB_POS_HOUR2_X (662)
56 #define ICO_SB_POS_HOUR2_Y (18)
57 #define ICO_SB_POS_MIN1_X (703)
58 #define ICO_SB_POS_MIN1_Y (18)
59 #define ICO_SB_POS_MIN2_X (725)
60 #define ICO_SB_POS_MIN2_Y (18)
62 #define ICO_SB_SIZE_COLON_W (6)
63 #define ICO_SB_SIZE_COLON_H (17)
64 #define ICO_SB_SIZE_NUM_W (20)
65 #define ICO_SB_SIZE_NUM_H (30)
66 #define ICO_SB_SIZE_AMPM_W (47)
67 #define ICO_SB_SIZE_AMPM_H (27)
69 /*============================================================================*/
70 /* static(internal) functions prototype */
71 /*============================================================================*/
72 static void sb_on_destroy(Ecore_Evas *ee);
73 static int sb_callback_http(struct libwebsocket_context *context,
74 struct libwebsocket *wsi,
75 enum libwebsocket_callback_reasons reason, void *user, void *in,
77 static int sb_callback_statusbar(struct libwebsocket_context *context,
78 struct libwebsocket *wsi,
79 enum libwebsocket_callback_reasons reason, void *user,
80 void *in, size_t len);
81 static void sb_create_ws_context(void);
82 static void sb_time_hour(struct tm *t_st);
83 static void sb_time_min(struct tm *t_st);
84 static Eina_Bool sb_time_show(void* thread_data);
85 static void sb_touch_up_escathion(void *data, Evas_Object *obj, void *event_info);
86 static void sb_clock_display_fixation(Evas *canvas);
88 /*============================================================================*/
90 /*============================================================================*/
91 static int sb_ws_port = ICO_HS_WS_PORT;
92 static int sb_ws_connected = 0;
93 static struct libwebsocket_context *sb_ws_context;
94 static struct libwebsocket *sb_wsi_mirror;
96 static int sb_width = 0;
97 static char sb_respath[ICO_SB_BUF_SIZE];
98 static struct tm sb_st_buf;
99 static Evas_Object *sb_ampm;
100 static Evas_Object *sb_hour1;
101 static Evas_Object *sb_hour2;
102 static Evas_Object *sb_min1;
103 static Evas_Object *sb_min2;
105 struct _sb_time_data {
107 Evas_Object *time_img;
110 struct _sb_time_data sb_time_data[ICO_SB_TIME_IMG_PARTS] = {
111 {fname_num0, }, {fname_num1, },
112 {fname_num2, }, {fname_num3, },
113 {fname_num4, }, {fname_num5, },
114 {fname_num6, }, {fname_num7, },
115 {fname_num8, }, {fname_num9, },
116 {fname_am, }, {fname_pm, }
119 static struct libwebsocket_protocols ws_protocols[] = {
126 "statusbar-protocol",
127 sb_callback_statusbar,
138 /*============================================================================*/
140 /*============================================================================*/
141 /*--------------------------------------------------------------------------*/
143 * @brief sb_on_destroy
144 * callback function called by EFL when ecore destroyed.
145 * exit ecore main loop.
147 * @param[in] ee ecore evas object
150 /*--------------------------------------------------------------------------*/
152 sb_on_destroy(Ecore_Evas *ee)
154 /* Quits the main loop */
155 ecore_main_loop_quit();
158 /*--------------------------------------------------------------------------*/
160 * @brief sb_callback_http
161 * Connection status is notified from libwebsockets.
163 * @param[in] context libwebsockets context
164 * @param[in] wsi libwebsockets management table
165 * @param[in] reason event type
166 * @param[in] user intact
167 * @param[in] in receive message
168 * @param[in] len message size[BYTE]
173 /*--------------------------------------------------------------------------*/
175 sb_callback_http(struct libwebsocket_context *context, struct libwebsocket *wsi,
176 enum libwebsocket_callback_reasons reason, void *user, void *in,
179 uifw_trace("sb_callback_http %p", context);
180 uifw_trace("SB-REASON %d", reason);
184 /*--------------------------------------------------------------------------*/
186 * @brief sb_callback_statusbar
187 * this callback function is notified from libwebsockets
190 * @param[in] context libwebsockets context
191 * @param[in] wsi libwebsockets management table
192 * @param[in] reason event type
193 * @param[in] user intact
194 * @param[in] in receive message
195 * @param[in] len message size[BYTE]
200 /*--------------------------------------------------------------------------*/
202 sb_callback_statusbar(struct libwebsocket_context *context,
203 struct libwebsocket *wsi,
204 enum libwebsocket_callback_reasons reason, void *user,
205 void *in, size_t len)
208 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512
209 + LWS_SEND_BUFFER_POST_PADDING];
210 unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
212 uifw_trace("sb_callback_statusbar %p", context);
215 case LWS_CALLBACK_CLIENT_ESTABLISHED:
216 uifw_trace("SB-ESTABLISHED %x", wsi);
218 n = sprintf((char *)p, "%s", "ANS HELLO");
220 case LWS_CALLBACK_CLIENT_RECEIVE:
221 uifw_trace("SB-RECEIVE[%d] %s", len, in);
223 n = sprintf((char *)p, "ANS %s OK", (char *)in);
225 case LWS_CALLBACK_CLOSED:
226 uifw_trace("SB-CLOSE");
227 sb_wsi_mirror = NULL;
230 uifw_trace("SB-REASON %d", reason);
235 n = libwebsocket_write(wsi, p, n, LWS_WRITE_TEXT);
241 /*--------------------------------------------------------------------------*/
243 * @brief sb_create_ws_context
244 * connect to the homescreen using websocket.
249 /*--------------------------------------------------------------------------*/
251 sb_create_ws_context(void)
254 = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL,
256 libwebsocket_internal_extensions,
257 NULL, NULL, -1, -1, 0);
258 uifw_trace("sb_create_ws_context ctx = %p", sb_ws_context);
261 if (sb_ws_context == NULL) {
262 uifw_trace("libwebsocket_create_context failed.");
266 = libwebsocket_client_connect(sb_ws_context, ICO_SB_WS_ADDRESS,
268 ICO_SB_WS_ADDRESS, NULL,
269 ICO_SB_WS_PROTOCOL_NAME, -1);
270 uifw_trace("sb_create_ws_context wsi = %p", sb_wsi_mirror);
271 if (sb_wsi_mirror != NULL) {
277 /*--------------------------------------------------------------------------*/
279 * @brief sb_ecore_event
280 * timer handler called by Ecore.
282 * @param[in] data user data
283 * @return call back setting
284 * @retval ECORE_CALLBACK_RENEW set callback
286 /*--------------------------------------------------------------------------*/
288 sb_ecore_event(void *data)
290 if (sb_ws_connected) {
291 libwebsocket_service(sb_ws_context, 0);
294 if (sb_ws_context != NULL) {
295 libwebsocket_context_destroy(sb_ws_context);
298 = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL,
300 libwebsocket_internal_extensions,
301 NULL, NULL, -1, -1, 0);
302 if (sb_ws_context == NULL) {
303 uifw_trace("libwebsocket_create_context failed.");
307 = libwebsocket_client_connect(sb_ws_context,
310 ICO_SB_WS_ADDRESS, NULL,
311 ICO_SB_WS_PROTOCOL_NAME, -1);
312 if (sb_wsi_mirror != NULL) {
317 return ECORE_CALLBACK_RENEW;
320 /*--------------------------------------------------------------------------*/
322 * @brief sb_time_hour
323 * show the clock's hour image on statubar
325 * @param[in] tm time data
328 /*--------------------------------------------------------------------------*/
330 sb_time_hour(struct tm *t_st)
332 char file[ICO_SB_BUF_SIZE];
333 if (t_st->tm_hour < 12) {
334 sprintf(file, "%s%s", sb_respath, sb_time_data[ICO_SB_TIME_AM].f_name);
335 evas_object_image_file_set(sb_ampm, file, NULL);
336 sprintf(file, "%s%s", sb_respath,
337 sb_time_data[t_st->tm_hour / 10].f_name);
338 evas_object_image_file_set(sb_hour1, file, NULL);
339 sprintf(file, "%s%s", sb_respath,
340 sb_time_data[t_st->tm_hour % 10].f_name);
341 evas_object_image_file_set(sb_hour2, file, NULL);
344 sprintf(file, "%s%s", sb_respath, sb_time_data[ICO_SB_TIME_PM].f_name);
345 evas_object_image_file_set(sb_ampm, file, NULL);
346 sprintf(file, "%s%s", sb_respath, sb_time_data[(t_st->tm_hour - 12)
348 evas_object_image_file_set(sb_hour1, file, NULL);
349 sprintf(file, "%s%s", sb_respath, sb_time_data[(t_st->tm_hour - 12)
351 evas_object_image_file_set(sb_hour2, file, NULL);
354 /*Makes the given Evas object visible*/
355 evas_object_show(sb_ampm);
356 evas_object_show(sb_hour1);
357 evas_object_show(sb_hour2);
360 /*--------------------------------------------------------------------------*/
362 * @brief sb_time_hour
363 * show the clock's minite image on statubar
365 * @param[in] tm time data
368 /*--------------------------------------------------------------------------*/
370 sb_time_min(struct tm *t_st)
372 char file[ICO_SB_BUF_SIZE];
373 sprintf(file, "%s%s", sb_respath, sb_time_data[t_st->tm_min / 10].f_name);
374 evas_object_image_file_set(sb_min1, file, NULL);
375 sprintf(file, "%s%s", sb_respath, sb_time_data[t_st->tm_min % 10].f_name);
376 evas_object_image_file_set(sb_min2, file, NULL);
378 /*Makes the given Evas object visible*/
379 evas_object_show(sb_min1);
380 evas_object_show(sb_min2);
383 /*--------------------------------------------------------------------------*/
385 * @brief sb_time_show
386 * callback function called by Ecore.
387 * get time data, and show the clock's image on statubar.
389 * @param[in] thread_data user data
390 * @return call back setting
391 * @retval ECORE_CALLBACK_RENEW set callback
393 /*--------------------------------------------------------------------------*/
395 sb_time_show(void *thread_data)
398 struct tm *t_st, *old_t_st;
400 old_t_st = &sb_st_buf;
404 t_st = localtime(&timer);
406 if (old_t_st->tm_hour != t_st->tm_hour) {
410 if (old_t_st->tm_min != t_st->tm_min) {
414 memcpy(old_t_st, t_st, sizeof(struct tm));
416 return ECORE_CALLBACK_RENEW;
419 /*--------------------------------------------------------------------------*/
421 * @brief sb_touch_up_escathion
422 * processing when change button touch up.
424 * @param[in] data user data
425 * @param[in] obj evas object of the button
426 * @param[in] event_info evas event infomation
429 /*--------------------------------------------------------------------------*/
431 sb_touch_up_escathion(void *data, Evas_Object *obj, void *event_info)
434 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512
435 + LWS_SEND_BUFFER_POST_PADDING];
436 unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
438 if (sb_wsi_mirror != NULL) {
439 n = sprintf((char *)p, "%s", "CLICK ESCUTCHEON 1");
440 libwebsocket_write(sb_wsi_mirror, p, n,
441 LWS_WRITE_CLIENT_IGNORE_XOR_MASK | LWS_WRITE_TEXT);
442 uifw_trace("SB: CLICK ESCUTCHEON 1");
445 /* operation sound */
446 hs_snd_play(hs_snd_get_filename(ICO_HS_SND_TYPE_DEFAULT));
449 /*--------------------------------------------------------------------------*/
451 * @brief sb_clock_display_fixation
452 * set up fixed images on status bar
454 * @param[in] canvas evas to draw
457 /*--------------------------------------------------------------------------*/
459 sb_clock_display_fixation(Evas *canvas)
461 Evas_Object *title, *colon;
464 char file[ICO_SB_BUF_SIZE];
466 moveH = sb_width - ICO_HS_SIZE_LAYOUT_WIDTH;
467 escPosX = sb_width / 2 - ICO_HS_SIZE_SB_HEIGHT / 2;
469 /* show escutcheon */
470 Evas_Object *icon, *btn;
471 title = evas_object_rectangle_add(canvas);
472 evas_object_move(title, escPosX, ICO_SB_POS_Y);
473 evas_object_resize(title, ICO_HS_SIZE_SB_HEIGHT, ICO_HS_SIZE_SB_HEIGHT);
474 evas_object_show(title);
476 icon = elm_icon_add(title);
477 elm_icon_standard_set(icon, "refresh");
479 btn = elm_button_add(title);
480 elm_object_part_content_set(btn, "icon", icon);
481 evas_object_move(btn, escPosX, ICO_SB_POS_Y);
482 evas_object_resize(btn, ICO_HS_SIZE_SB_HEIGHT, ICO_HS_SIZE_SB_HEIGHT);
483 evas_object_smart_callback_add(btn, "clicked", sb_touch_up_escathion, NULL );
484 evas_object_show(btn);
486 /* show clock's colon */
487 /*Creates a new image object*/
488 colon = evas_object_image_filled_add(canvas);
489 /*Set the image file */
490 sprintf(file, "%s%s", sb_respath, fname_colon);
491 evas_object_image_file_set(colon, file, NULL);
492 /*This function will make layout change*/
493 evas_object_move(colon, moveH + ICO_SB_POS_COLON_X, ICO_SB_POS_COLON_Y);
494 /*This function will make size change of a picture*/
495 evas_object_resize(colon, ICO_SB_SIZE_COLON_W, ICO_SB_SIZE_COLON_H);
496 /*Makes the given Evas object visible*/
497 evas_object_show(colon);
500 /*--------------------------------------------------------------------------*/
502 * @brief status bar application
505 * @param main() finction's standard parameter (argc,argv)
510 /*--------------------------------------------------------------------------*/
512 main(int argc, char *argv[])
518 char file[ICO_SB_BUF_SIZE];
521 int orientation = ICO_SB_HORIZONTAL;
524 static Ecore_Evas *ee;
527 hs_get_image_path(sb_respath, ICO_SB_BUF_SIZE);
530 if (getenv("PKG_NAME")) {
531 ico_uxf_log_open(getenv("PKG_NAME"));
534 ico_uxf_log_open(ICO_HS_APPID_DEFAULT_SB);
539 for (ii = 1; ii < argc; ii++) {
540 if (argv[ii][0] != '-')
542 if (strncasecmp(argv[ii], "-orientaion=", strlen("-orientaion=")) == 0) {
543 if (strcmp(&argv[ii][strlen("-orientaion=")], "vertical") == 0) {
544 orientation = ICO_SB_VERTICAL;
546 else if (strcmp(&argv[ii][strlen("-orientaion=")], "horizontal")
548 orientation = ICO_SB_HORIZONTAL;
553 /* load configuration */
554 ret = initHomeScreenConfig(ICO_STATUSBAR_CONFIG_FILE);
555 if (ret == ICO_HS_OK) {
556 sb_ws_port = hs_conf_get_integer(ICO_HS_CONFIG_STATUBAR,
557 ICO_HS_CONFIG_WS_PORT,
559 orientation = hs_conf_get_integer(ICO_HS_CONFIG_STATUBAR,
560 ICO_HS_CONFIG_ORIENTAION,
565 /* Initialize a new system of Ecore_Evas */
568 /* Generate Ecore_Evas */
569 ee = ecore_evas_new(NULL, 0, 0, 1, 1, "frame=0");
573 ecore_main_loop_iterate();
574 ecore_wl_screen_size_get(&width, &height);
576 if (orientation == ICO_SB_VERTICAL) {
577 sb_width = width > height ? height : width;
578 moveH = sb_width - ICO_HS_SIZE_LAYOUT_WIDTH;
581 sb_width = width < height ? height : width;
582 moveH = sb_width - ICO_HS_SIZE_LAYOUT_WIDTH;
585 /* Set the window size of the maximum and minimum */
586 ecore_evas_size_min_set(ee, sb_width, ICO_HS_SIZE_SB_HEIGHT);
587 ecore_evas_size_max_set(ee, sb_width, ICO_HS_SIZE_SB_HEIGHT);
589 /* Set a callback for Ecore_Evas delete request events */
590 ecore_evas_callback_delete_request_set(ee, sb_on_destroy);
592 /* Set the title of an Ecore_Evas window */
593 /* ecore_evas_title_set(ee, "Ecore_Evas buffer (image) example"); */
595 ecore_evas_move(ee, 0, 0);
596 ecore_evas_resize(ee, sb_width, ICO_HS_SIZE_SB_HEIGHT);
599 /* Wrapper of Evas */
600 canvas = ecore_evas_get(ee);
603 bg = evas_object_rectangle_add(canvas);
604 evas_object_color_set(bg, 0, 0, 0, 255);
605 evas_object_move(bg, 0, 0);
606 evas_object_resize(bg, sb_width, ICO_HS_SIZE_SB_HEIGHT);
607 evas_object_show(bg);
609 /* Call the function */
610 elm_init(argc, argv);
611 sb_clock_display_fixation(canvas);
614 sb_ampm = evas_object_image_filled_add(canvas);
615 sb_hour1 = evas_object_image_filled_add(canvas);
616 sb_hour2 = evas_object_image_filled_add(canvas);
617 sb_min1 = evas_object_image_filled_add(canvas);
618 sb_min2 = evas_object_image_filled_add(canvas);
620 /* This function will make layout change */
621 evas_object_move(sb_ampm, moveH + ICO_SB_POS_AMPM_X, ICO_SB_POS_AMPM_Y);
622 evas_object_move(sb_hour1, moveH + ICO_SB_POS_HOUR1_X, ICO_SB_POS_HOUR1_Y);
623 evas_object_move(sb_hour2, moveH + ICO_SB_POS_HOUR2_X, ICO_SB_POS_HOUR2_Y);
625 /* This function will make size change of picture */
626 evas_object_resize(sb_ampm, ICO_SB_SIZE_AMPM_W, ICO_SB_SIZE_AMPM_H);
627 evas_object_resize(sb_hour1, ICO_SB_SIZE_NUM_W, ICO_SB_SIZE_NUM_H);
628 evas_object_resize(sb_hour2, ICO_SB_SIZE_NUM_W, ICO_SB_SIZE_NUM_H);
630 /* Makes the given Evas object visible */
631 evas_object_show(sb_ampm);
632 evas_object_show(sb_hour1);
633 evas_object_show(sb_hour2);
635 /* Change default layout of Evas object */
636 evas_object_move(sb_min1, moveH + ICO_SB_POS_MIN1_X, ICO_SB_POS_MIN1_Y);
637 evas_object_move(sb_min2, moveH + ICO_SB_POS_MIN2_X, ICO_SB_POS_MIN2_Y);
639 /* Change default size of Evas object */
640 evas_object_resize(sb_min1, ICO_SB_SIZE_NUM_W, ICO_SB_SIZE_NUM_H);
641 evas_object_resize(sb_min2, ICO_SB_SIZE_NUM_W, ICO_SB_SIZE_NUM_H);
643 /* Makes the given Evas object visible */
644 evas_object_show(sb_min1);
645 evas_object_show(sb_min2);
648 t_st = localtime(&timer);
652 /* Set the image file */
653 for (ii = 0; ii < ICO_SB_TIME_IMG_PARTS; ii++) {
654 sb_time_data[ii].time_img = evas_object_image_filled_add(canvas);
655 sprintf(file, "%s%s", sb_respath, sb_time_data[ii].f_name);
656 evas_object_image_file_set(sb_time_data[ii].time_img, file, NULL);
658 ecore_timer_add(ICO_SB_TIMEOUT, sb_time_show, NULL);
660 /* Init websockets */
661 sb_create_ws_context();
662 ecore_timer_add(ICO_SB_WS_TIMEOUT, sb_ecore_event, NULL);
664 /* Runs the application main loop */
665 ecore_main_loop_begin();
666 /* Free an Ecore_Evas */
668 /* Shut down the Ecore_Evas system */
669 ecore_evas_shutdown();
673 uifw_warn("status_bar: error use ecore")
674 ecore_evas_shutdown();