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 #define LOG_TAG "ICON_PROVIDER"
26 #include <Elementary.h>
29 #include <glib-object.h>
40 #include <livebox-service.h>
41 #include <livebox-errno.h>
44 #include <system_settings.h>
48 #include <com-core_packet.h>
55 #define UTILITY_ADDR "/tmp/.utility.service"
56 #define DEFAULT_ICON_LAYOUT "/usr/apps/org.tizen.data-provider-slave/res/edje/icon.edj"
57 #define DEFAULT_ICON_GROUP "default"
59 #define TEXT_CLASS "tizen"
60 #define DEFAULT_FONT_SIZE -100
62 int script_handler_parse_desc(Evas_Object *edje, const char *descfile);
65 Ecore_Timer *ttl_timer;
67 const char *socket_file;
72 .socket_file = UTILITY_ADDR,
76 #define TTL 30.0f /* Can alive only 30 seconds from the last event */
77 #define QUALITY_N_COMPRESS "quality=100 compress=1"
80 * Defined for liblivebox
82 const char *livebox_find_pkgname(const char *filename)
87 int livebox_request_update_by_id(const char *filename)
89 return LB_STATUS_ERROR_NOT_EXIST;
92 int livebox_trigger_update_monitor(const char *id, int is_pd)
94 return LB_STATUS_ERROR_INVALID;
97 static inline Evas *create_virtual_canvas(int w, int h)
99 Ecore_Evas *internal_ee;
102 // Create virtual canvas
103 internal_ee = ecore_evas_buffer_new(w, h);
105 ErrPrint("Failed to create a new canvas buffer\n");
109 ecore_evas_alpha_set(internal_ee, EINA_TRUE);
110 ecore_evas_manual_render_set(internal_ee, EINA_TRUE);
112 // Get the "Evas" object from a virtual canvas
113 internal_e = ecore_evas_get(internal_ee);
115 ecore_evas_free(internal_ee);
116 ErrPrint("Faield to get Evas object\n");
120 ecore_evas_resize(internal_ee, w, h);
121 ecore_evas_show(internal_ee);
126 static inline int flush_data_to_file(Evas *e, char *data, const char *filename, int w, int h)
130 output = evas_object_image_add(e);
132 ErrPrint("Failed to create an image object\n");
136 evas_object_image_data_set(output, NULL);
137 evas_object_image_colorspace_set(output, EVAS_COLORSPACE_ARGB8888);
138 evas_object_image_alpha_set(output, EINA_TRUE);
139 evas_object_image_size_set(output, w, h);
140 evas_object_image_smooth_scale_set(output, EINA_TRUE);
141 evas_object_image_data_set(output, data);
142 evas_object_image_data_update_add(output, 0, 0, w, h);
144 if (evas_object_image_save(output, filename, NULL, QUALITY_N_COMPRESS) == EINA_FALSE) {
145 evas_object_del(output);
146 ErrPrint("Faield to save a captured image (%s)\n", filename);
150 evas_object_del(output);
152 if (access(filename, F_OK) != 0) {
153 ErrPrint("File %s is not found\n", filename);
160 static inline int flush_to_file(Evas *e, const char *filename, int w, int h)
163 Ecore_Evas *internal_ee;
165 internal_ee = ecore_evas_ecore_evas_get(e);
167 ErrPrint("Failed to get ecore evas\n");
171 ecore_evas_manual_render(internal_ee);
173 // Get a pointer of a buffer of the virtual canvas
174 data = (void *)ecore_evas_buffer_pixels_get(internal_ee);
176 ErrPrint("Failed to get pixel data\n");
180 return flush_data_to_file(e, data, filename, w, h);
183 static inline int destroy_virtual_canvas(Evas *e)
187 ee = ecore_evas_ecore_evas_get(e);
189 ErrPrint("Failed to ecore evas object\n");
197 static int disconnected_cb(int handle, void *data)
199 s_info.client_fd = -1;
204 static inline int convert_shortcut_type_to_lb_type(int shortcut_type, char **str)
212 switch (shortcut_type) {
213 case LIVEBOX_TYPE_1x1:
215 return LB_SIZE_TYPE_1x1;
216 case LIVEBOX_TYPE_2x1:
218 return LB_SIZE_TYPE_2x1;
219 case LIVEBOX_TYPE_2x2:
221 return LB_SIZE_TYPE_2x2;
222 case LIVEBOX_TYPE_4x1:
224 return LB_SIZE_TYPE_4x1;
225 case LIVEBOX_TYPE_4x2:
227 return LB_SIZE_TYPE_4x2;
228 case LIVEBOX_TYPE_4x3:
230 return LB_SIZE_TYPE_4x3;
231 case LIVEBOX_TYPE_4x4:
233 return LB_SIZE_TYPE_4x4;
234 case LIVEBOX_TYPE_4x5:
236 return LB_SIZE_TYPE_4x5;
237 case LIVEBOX_TYPE_4x6:
239 return LB_SIZE_TYPE_4x6;
240 case LIVEBOX_TYPE_EASY_1x1:
242 return LB_SIZE_TYPE_EASY_1x1;
243 case LIVEBOX_TYPE_EASY_3x1:
245 return LB_SIZE_TYPE_EASY_3x1;
246 case LIVEBOX_TYPE_EASY_3x3:
248 return LB_SIZE_TYPE_EASY_3x3;
251 return LB_SIZE_TYPE_UNKNOWN;
255 static struct packet *icon_create(pid_t pid, int handle, const struct packet *packet)
258 const char *edje_path;
260 const char *desc_file;
271 if (s_info.ttl_timer) {
272 ecore_timer_reset(s_info.ttl_timer);
275 ret = packet_get(packet, "sssis", &edje_path, &group, &desc_file, &size_type, &output);
277 ErrPrint("Invalid parameters");
282 if (!edje_path || !strlen(edje_path)) {
283 edje_path = DEFAULT_ICON_LAYOUT;
286 size_type = convert_shortcut_type_to_lb_type(size_type, &size_str);
287 if (!group || !strlen(group)) {
288 snprintf(_group, sizeof(_group), DEFAULT_ICON_GROUP",%s", size_str);
291 DbgPrint("Selected layout: %s(%s)\n", edje_path, group);
293 ret = livebox_service_get_size(size_type, &w, &h);
294 if (ret != LB_STATUS_SUCCESS) {
295 ErrPrint("Unable to get size(%d): %d\n", size_type, ret);
299 e = create_virtual_canvas(w, h);
301 ErrPrint("Unable to create a canvas: %dx%d\n", w, h);
302 ret = LB_STATUS_ERROR_FAULT;
306 parent = evas_object_rectangle_add(e);
308 ErrPrint("Unable to create a parent\n");
309 destroy_virtual_canvas(e);
310 ret = LB_STATUS_ERROR_FAULT;
314 evas_object_resize(parent, w, h);
315 evas_object_color_set(parent, 0, 0, 0, 0);
316 evas_object_show(parent);
318 edje = elm_layout_add(parent);
320 ErrPrint("Unable to add an edje object\n");
321 evas_object_del(parent);
322 destroy_virtual_canvas(e);
326 if (elm_layout_file_set(edje, edje_path, group) == EINA_FALSE) {
328 err = edje_object_load_error_get(elm_layout_edje_get(edje));
329 ErrPrint("Uanble to load an edje %s(%s) - %s\n", edje_path, group, edje_load_error_str(err));
330 evas_object_del(edje);
331 evas_object_del(parent);
332 destroy_virtual_canvas(e);
336 evas_object_resize(edje, w, h);
337 evas_object_show(edje);
339 if (script_handler_parse_desc(edje, desc_file) != LB_STATUS_SUCCESS) {
340 ErrPrint("Unable to parse the %s\n", desc_file);
343 flush_to_file(e, output, w, h);
344 evas_object_del(edje);
345 evas_object_del(parent);
346 destroy_virtual_canvas(e);
350 /* Desc file should be deleted if it fails to create an icon image */
351 if (unlink(desc_file) < 0) {
352 ErrPrint("unlink(%s): %s\n", desc_file, strerror(errno));
356 return packet_create_reply(packet, "i", ret);
359 static inline int client_init(void)
362 struct packet *packet;
363 static struct method service_table[] = {
365 .cmd = "icon_create",
366 .handler = icon_create,
374 com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
376 s_info.client_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
377 if (s_info.client_fd < 0) {
378 ErrPrint("Failed to make a connection to the master\n");
382 packet = packet_create_noack("service_register", "");
384 ErrPrint("Failed to build a packet\n");
388 ret = com_core_packet_send_only(s_info.client_fd, packet);
389 DbgPrint("Service register sent: %d\n", ret);
390 packet_destroy(packet);
392 com_core_packet_client_fini(s_info.client_fd);
393 s_info.client_fd = -1;
399 DbgPrint("Server FD: %d\n", s_info.client_fd);
403 static Eina_Bool life_timer_cb(void *data)
407 DbgPrint("Life timer expired\n");
409 s_info.ttl_timer = NULL;
411 return ECORE_CALLBACK_CANCEL;
414 static inline void client_fini(void)
416 if (s_info.client_fd < 0) {
417 DbgPrint("Client is not initiated\n");
421 com_core_packet_client_fini(s_info.client_fd);
422 s_info.client_fd = -1;
425 static void update_font_cb(void *data)
430 list = edje_text_class_list();
431 DbgPrint("List: %p\n", list);
433 EINA_LIST_FREE(list, text) {
434 if (!strncasecmp(text, TEXT_CLASS, strlen(TEXT_CLASS))) {
435 DbgPrint("Update text class %s (%s, %d)\n", text, s_info.font_name, DEFAULT_FONT_SIZE);
436 edje_text_class_del(text);
437 edje_text_class_set(text, s_info.font_name, DEFAULT_FONT_SIZE);
439 DbgPrint("Skip text class %s\n", text);
443 DbgPrint("New (%s, %d)\n", s_info.font_name, DEFAULT_FONT_SIZE);
444 edje_text_class_set(TEXT_CLASS, s_info.font_name, DEFAULT_FONT_SIZE);
448 static void font_changed_cb(keynode_t *node, void *user_data)
452 if (s_info.font_name) {
453 font_name = vconf_get_str("db/setting/accessibility/font_name");
455 ErrPrint("Invalid font name (NULL)\n");
459 if (!strcmp(s_info.font_name, font_name)) {
460 DbgPrint("Font is not changed (Old: %s(%p) <> New: %s(%p))\n", s_info.font_name, s_info.font_name, font_name, font_name);
465 DbgPrint("Release old font name: %s(%p)\n", s_info.font_name, s_info.font_name);
466 free(s_info.font_name);
471 ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_FONT_TYPE, &font_name);
472 if (ret != SYSTEM_SETTINGS_ERROR_NONE || !font_name) {
473 ErrPrint("system settings: %d, font_name[%p]\n", ret, font_name);
478 s_info.font_name = font_name;
479 DbgPrint("Font name is changed to %s(%p)\n", s_info.font_name, s_info.font_name);
481 update_font_cb(NULL);
484 static bool app_create(void *data)
488 if (client_init() < 0) {
489 ErrPrint("Unable to initiate the client\n");
494 * Send a request to reigister as a service.
496 s_info.ttl_timer = ecore_timer_add(TTL, life_timer_cb, NULL);
497 if (!s_info.ttl_timer) {
498 ErrPrint("Unable to register a life timer\n");
501 ret = vconf_notify_key_changed("db/setting/accessibility/font_name", font_changed_cb, NULL);
502 DbgPrint("System font is changed: %d\n", ret);
504 font_changed_cb(NULL, NULL);
508 static void app_terminate(void *data)
512 ret = vconf_ignore_key_changed("db/setting/accessibility/font_name", font_changed_cb);
513 DbgPrint("Remove font change callback: %d\n", ret);
515 if (s_info.ttl_timer) {
516 ecore_timer_del(s_info.ttl_timer);
517 s_info.ttl_timer = NULL;
522 free(s_info.font_name);
523 s_info.font_name = NULL;
527 static void app_pause(void *data)
529 /* Will not be called */
533 static void app_resume(void *data)
535 /* Will not be called */
539 static void app_service(service_h service, void *data)
543 int main(int argc, char *argv[])
546 app_event_callback_s event_callback;
548 event_callback.create = app_create;
549 event_callback.terminate = app_terminate;
550 event_callback.pause = app_pause;
551 event_callback.resume = app_resume;
552 event_callback.service = app_service;
553 event_callback.low_memory = NULL;
554 event_callback.low_battery = NULL;
555 event_callback.device_orientation = NULL;
556 event_callback.language_changed = NULL;
557 event_callback.region_format_changed = NULL;
559 ret = app_efl_main(&argc, &argv, &event_callback, NULL);