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> /* malloc */
20 #include <string.h> /* strdup */
22 #include <unistd.h> /* access */
24 #include <Ecore_Evas.h> /* binder.h */
27 #include <widget_errno.h>
28 #include <widget_service.h>
29 #include <widget_service_internal.h>
30 #include <widget_provider.h>
31 #include <widget_provider_buffer.h>
32 #include <widget_buffer.h>
33 #include <widget_util.h>
34 #include <widget_conf.h>
40 #include "widget_internal.h"
43 #define PUBLIC __attribute__((visibility("default")))
47 * This value is configurable value.
49 #define FRAME_WAIT_INTERVAL (1.0f/6.0f)
67 unsigned int last_idx;
69 struct dlist *block_list;
72 struct widget_buffer_data {
76 /* for Buffer event wrapper */
77 int (*handler)(widget_buffer_h , widget_buffer_event_data_t, void *);
85 Ecore_Timer *frame_wait_timer;
88 static inline int event_handler_wrapper(widget_buffer_h buffer, widget_buffer_event_data_t event_info, void *data)
92 struct widget_buffer_data *cbdata = data;
95 pkgname = widget_provider_buffer_pkgname(buffer);
97 ErrPrint("pkgname is not valid\n");
98 return WIDGET_ERROR_INVALID_PARAMETER;
101 id = widget_provider_buffer_id(buffer);
103 ErrPrint("id is not valid[%s]\n", pkgname);
104 return WIDGET_ERROR_INVALID_PARAMETER;
107 if (cbdata->handler) {
108 ret = cbdata->handler(buffer, event_info, cbdata->cbdata);
110 ret = WIDGET_ERROR_FAULT;
113 switch (event_info->type) {
114 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
115 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
116 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
117 case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE:
118 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP:
119 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN:
120 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
121 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
122 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
123 case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
124 case WIDGET_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
125 case WIDGET_BUFFER_EVENT_ACCESS_MOUSE:
126 case WIDGET_BUFFER_EVENT_ACCESS_BACK:
127 case WIDGET_BUFFER_EVENT_ACCESS_OVER:
128 case WIDGET_BUFFER_EVENT_ACCESS_READ:
129 case WIDGET_BUFFER_EVENT_ACCESS_ENABLE:
130 case WIDGET_BUFFER_EVENT_ACCESS_DISABLE:
131 DbgPrint("Accessibility event: %d\n", event_info->type);
133 (void)widget_provider_send_access_status(pkgname, id, WIDGET_ACCESS_STATUS_ERROR);
135 (void)widget_provider_send_access_status(pkgname, id, ret);
138 case WIDGET_BUFFER_EVENT_KEY_UP:
139 case WIDGET_BUFFER_EVENT_KEY_DOWN:
140 case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
141 case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
142 DbgPrint("Key event: %d\n", event_info->type);
144 (void)widget_provider_send_key_status(pkgname, id, WIDGET_KEY_STATUS_ERROR);
146 (void)widget_provider_send_key_status(pkgname, id, ret);
156 static inline int default_event_handler(widget_buffer_h buffer, widget_buffer_event_data_t event_info, void *data)
162 PUBLIC struct widget_desc *widget_desc_open(const char *filename, int for_pd)
164 struct widget_desc *handle;
167 handle = calloc(1, sizeof(*handle));
169 ErrPrint("Error: %d\n", errno);
175 len = strlen(filename) + strlen(".desc") + 1;
176 new_fname = malloc(len);
178 ErrPrint("Error: %d\n", errno);
182 snprintf(new_fname, len, "%s.desc", filename);
184 new_fname = strdup(filename);
186 ErrPrint("Error: %d\n", errno);
192 DbgPrint("Open a file %s with merge mode %s\n",
194 access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
196 handle->fp = fopen(new_fname, "at");
199 ErrPrint("Failed to open a file: %d\n", errno);
207 PUBLIC int widget_desc_close(struct widget_desc *handle)
214 return WIDGET_ERROR_INVALID_PARAMETER;
217 dlist_foreach_safe(handle->block_list, l, n, block) {
218 handle->block_list = dlist_remove(handle->block_list, l);
220 fprintf(handle->fp, "{\n");
222 fprintf(handle->fp, "type=%s\n", block->type);
226 fprintf(handle->fp, "part=%s\n", block->part);
230 fprintf(handle->fp, "data=%s\n", block->data);
234 fprintf(handle->fp, "option=%s\n", block->option);
238 fprintf(handle->fp, "id=%s\n", block->id);
241 if (block->target_id) {
242 fprintf(handle->fp, "target=%s\n", block->target_id);
244 fprintf(handle->fp, "}\n");
251 free(block->target_id);
255 if (fclose(handle->fp) != 0) {
256 ErrPrint("fclose: %d\n", errno);
259 return WIDGET_ERROR_NONE;
262 PUBLIC int widget_desc_set_category(struct widget_desc *handle, const char *id, const char *category)
266 if (!handle || !category) {
267 return WIDGET_ERROR_INVALID_PARAMETER;
270 block = calloc(1, sizeof(*block));
272 return WIDGET_ERROR_OUT_OF_MEMORY;
275 block->type = strdup(WIDGET_DESC_TYPE_INFO);
278 return WIDGET_ERROR_OUT_OF_MEMORY;
281 block->part = strdup("category");
285 return WIDGET_ERROR_OUT_OF_MEMORY;
288 block->data = strdup(category);
293 return WIDGET_ERROR_OUT_OF_MEMORY;
297 block->id = strdup(id);
303 return WIDGET_ERROR_OUT_OF_MEMORY;
307 block->idx = handle->last_idx++;
308 handle->block_list = dlist_append(handle->block_list, block);
312 PUBLIC int widget_desc_set_size(struct widget_desc *handle, const char *id, int w, int h)
318 return WIDGET_ERROR_INVALID_PARAMETER;
321 block = calloc(1, sizeof(*block));
323 return WIDGET_ERROR_OUT_OF_MEMORY;
326 block->type = strdup(WIDGET_DESC_TYPE_INFO);
329 return WIDGET_ERROR_OUT_OF_MEMORY;
332 block->part = strdup("size");
336 return WIDGET_ERROR_OUT_OF_MEMORY;
340 block->id = strdup(id);
345 return WIDGET_ERROR_OUT_OF_MEMORY;
349 snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
350 block->data = strdup(buffer);
356 return WIDGET_ERROR_OUT_OF_MEMORY;
359 block->idx = handle->last_idx++;
360 handle->block_list = dlist_append(handle->block_list, block);
364 PUBLIC int widget_desc_set_id(struct widget_desc *handle, int idx, const char *id)
369 dlist_foreach(handle->block_list, l, block) {
370 if (block->idx == idx) {
371 if (strcasecmp(block->type, WIDGET_DESC_TYPE_SCRIPT)) {
372 ErrPrint("Invalid block is used\n");
373 return WIDGET_ERROR_INVALID_PARAMETER;
376 free(block->target_id);
377 block->target_id = NULL;
379 if (!id || !strlen(id)) {
380 return WIDGET_ERROR_NONE;
383 block->target_id = strdup(id);
384 if (!block->target_id) {
385 ErrPrint("Heap: %d\n", errno);
386 return WIDGET_ERROR_OUT_OF_MEMORY;
389 return WIDGET_ERROR_NONE;
393 return WIDGET_ERROR_NOT_EXIST;
399 PUBLIC int widget_desc_add_block(struct widget_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option)
403 if (!handle || !type) {
404 return WIDGET_ERROR_INVALID_PARAMETER;
415 block = calloc(1, sizeof(*block));
417 ErrPrint("Heap: %d\n", errno);
418 return WIDGET_ERROR_OUT_OF_MEMORY;
421 block->type = strdup(type);
423 ErrPrint("Heap: %d\n", errno);
425 return WIDGET_ERROR_OUT_OF_MEMORY;
428 block->part = strdup(part);
430 ErrPrint("Heap: %d\n", errno);
433 return WIDGET_ERROR_OUT_OF_MEMORY;
436 block->data = strdup(data);
438 ErrPrint("Heap: %d\n", errno);
442 return WIDGET_ERROR_OUT_OF_MEMORY;
446 block->option = strdup(option);
447 if (!block->option) {
448 ErrPrint("Heap: %d\n", errno);
453 return WIDGET_ERROR_OUT_OF_MEMORY;
458 block->id = strdup(id);
460 ErrPrint("Heap: %d\n", errno);
466 return WIDGET_ERROR_OUT_OF_MEMORY;
470 block->idx = handle->last_idx++;
471 handle->block_list = dlist_append(handle->block_list, block);
475 PUBLIC int widget_desc_del_block(struct widget_desc *handle, int idx)
480 if (!handle || idx < 0) {
481 return WIDGET_ERROR_INVALID_PARAMETER;
484 dlist_foreach(handle->block_list, l, block) {
485 if (block->idx == idx) {
486 handle->block_list = dlist_remove(handle->block_list, l);
492 free(block->target_id);
494 return WIDGET_ERROR_NONE;
498 return WIDGET_ERROR_NOT_EXIST;
501 PUBLIC int widget_viewer_acquire_buffer(widget_buffer_h handle, int idx, int width, int height, int pixel_size)
505 if (!handle || width <= 0 || height <= 0 || pixel_size <= 0 || idx > WIDGET_CONF_EXTRA_BUFFER_COUNT) {
506 return WIDGET_ERROR_INVALID_PARAMETER;
513 /* To validate the buffer */
514 if (widget_provider_buffer_get_size(handle, &_width, &_height, &_pixel_size) < 0) {
515 ErrPrint("Failed to get buffer size\n");
518 if (_width != width || _height != height || pixel_size != _pixel_size) {
519 DbgPrint("Extra buffer's geometry is not matched with primary one\n");
522 ret = widget_provider_buffer_extra_acquire(handle, idx, width, height, pixel_size);
524 ret = widget_provider_buffer_acquire(handle, width, height, pixel_size);
530 PUBLIC widget_buffer_h widget_create_buffer(const char *filename, int is_gbar, int auto_align, int (*handler)(widget_buffer_h , widget_buffer_event_data_t, void *), void *data)
532 struct widget_buffer_data *user_data;
534 widget_buffer_h handle;
538 ErrPrint("Invalid argument: %p(%dx%d)\n", filename);
542 user_data = calloc(1, sizeof(*user_data));
544 ErrPrint("Heap: %d\n", errno);
548 user_data->is_gbar = is_gbar;
549 user_data->handler = handler ? handler : default_event_handler;
550 user_data->cbdata = data;
552 uri = util_id_to_uri(filename);
554 ErrPrint("Heap: %d\n", errno);
559 pkgname = binder_widget_find_pkgname(uri);
561 ErrPrint("Invalid Request\n");
567 handle = widget_provider_buffer_create((!!is_gbar) ? WIDGET_TYPE_GBAR : WIDGET_TYPE_WIDGET, pkgname, uri, auto_align, event_handler_wrapper, user_data);
574 (void)widget_provider_buffer_set_user_data(handle, user_data);
578 PUBLIC unsigned int widget_viewer_get_resource_id(widget_buffer_h handle, int idx)
582 if (!handle || idx > WIDGET_CONF_EXTRA_BUFFER_COUNT) {
583 return WIDGET_ERROR_INVALID_PARAMETER;
587 ret = widget_provider_buffer_extra_resource_id(handle, idx);
589 ret = widget_provider_buffer_resource_id(handle);
595 PUBLIC int widget_viewer_release_buffer(widget_buffer_h handle, int idx)
599 if (!handle || idx > WIDGET_CONF_EXTRA_BUFFER_COUNT) {
600 return WIDGET_ERROR_INVALID_PARAMETER;
604 ret = widget_provider_buffer_extra_release(handle, idx);
606 ret = widget_provider_buffer_release(handle);
609 DbgPrint("Release buffer: %d (%d)\n", idx, ret);
613 PUBLIC int widget_destroy_buffer(widget_buffer_h handle)
615 struct widget_buffer_data *user_data;
618 return WIDGET_ERROR_INVALID_PARAMETER;
621 user_data = widget_provider_buffer_user_data(handle);
623 if (user_data->frame_wait_timer) {
624 ecore_timer_del(user_data->frame_wait_timer);
625 user_data->frame_wait_timer = NULL;
627 free(user_data->content);
628 free(user_data->title);
629 free(user_data->icon);
630 free(user_data->name);
632 widget_provider_buffer_set_user_data(handle, NULL);
635 DbgPrint("Destroy buffer\n");
636 return widget_provider_buffer_destroy(handle);
639 PUBLIC void *widget_ref_buffer(widget_buffer_h handle)
641 struct widget_buffer_data *user_data;
650 user_data = widget_provider_buffer_user_data(handle);
655 if (user_data->accelerated) {
656 DbgPrint("H/W accelerated buffer is allocated\n");
660 ret = widget_provider_buffer_get_size(handle, &w, &h, &size);
662 data = widget_provider_buffer_ref(handle);
663 if (data && !ret && w > 0 && h > 0 && size > 0) {
664 memset(data, 0, w * h * size);
665 (void)widget_provider_buffer_sync(handle);
668 DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
672 PUBLIC int widget_unref_buffer(void *buffer)
675 return WIDGET_ERROR_INVALID_PARAMETER;
678 DbgPrint("Unref buffer\n");
679 return widget_provider_buffer_unref(buffer);
682 PUBLIC int widget_viewer_sync_buffer(widget_buffer_h handle)
684 struct widget_buffer_data *user_data;
693 return WIDGET_ERROR_INVALID_PARAMETER;
696 user_data = widget_provider_buffer_user_data(handle);
698 ErrPrint("Invalid buffer\n");
699 return WIDGET_ERROR_INVALID_PARAMETER;
702 if (user_data->accelerated) {
703 DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
704 return WIDGET_ERROR_NONE;
707 pkgname = widget_provider_buffer_pkgname(handle);
709 ErrPrint("Invalid buffer handler\n");
710 return WIDGET_ERROR_INVALID_PARAMETER;
713 id = widget_provider_buffer_id(handle);
715 ErrPrint("Invalid buffer handler\n");
716 return WIDGET_ERROR_INVALID_PARAMETER;
719 (void)widget_provider_buffer_sync(handle);
721 if (widget_provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
722 ErrPrint("Failed to get size (%s)\n", id);
727 * manipulate the damaged region, so send update event only for the damaged region.
728 * to make more efficient updates
730 ret = binder_widget_send_updated(pkgname, id, handle, WIDGET_PRIMARY_BUFFER, 0, 0, w, h, user_data->is_gbar, NULL);
732 ErrPrint("Failed to send%supdated (%s)\n", user_data->is_gbar ? " GBAR " : " ", id);
738 PUBLIC int widget_send_updated_by_idx(widget_buffer_h handle, int idx)
740 struct widget_buffer_data *user_data;
748 user_data = widget_provider_buffer_user_data(handle);
750 ErrPrint("Invalid buffer\n");
751 return WIDGET_ERROR_INVALID_PARAMETER;
754 pkgname = widget_provider_buffer_pkgname(handle);
756 ErrPrint("Invalid buffer handler\n");
757 return WIDGET_ERROR_INVALID_PARAMETER;
760 id = widget_provider_buffer_id(handle);
762 ErrPrint("Invalid buffer handler\n");
763 return WIDGET_ERROR_INVALID_PARAMETER;
766 if (widget_provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
767 ErrPrint("Failed to get size (%s)\n", id);
770 ret = binder_widget_send_updated(pkgname, id, handle, idx, 0, 0, w, h, user_data->is_gbar, NULL);
772 ErrPrint("Failed to send%supdated (%s) %d\n", user_data->is_gbar ? " GBAR " : " ", id, idx);
778 PUBLIC int widget_support_hw_buffer(widget_buffer_h handle)
781 return WIDGET_ERROR_INVALID_PARAMETER;
784 return widget_provider_buffer_is_support_hw(handle);
787 PUBLIC int widget_create_hw_buffer(widget_buffer_h handle)
789 struct widget_buffer_data *user_data;
793 return WIDGET_ERROR_INVALID_PARAMETER;
796 user_data = widget_provider_buffer_user_data(handle);
798 return WIDGET_ERROR_INVALID_PARAMETER;
801 if (user_data->accelerated) {
802 return WIDGET_ERROR_ALREADY_EXIST;
805 ret = widget_provider_buffer_create_hw(handle);
806 user_data->accelerated = (ret == 0);
810 PUBLIC int widget_destroy_hw_buffer(widget_buffer_h handle)
812 struct widget_buffer_data *user_data;
815 LOGD("handle is NULL\n");
816 return WIDGET_ERROR_INVALID_PARAMETER;
819 user_data = widget_provider_buffer_user_data(handle);
820 if (!user_data || !user_data->accelerated) {
821 LOGD("user_data is NULL\n");
822 return WIDGET_ERROR_INVALID_PARAMETER;
825 user_data->accelerated = 0;
827 return widget_provider_buffer_destroy_hw(handle);
830 PUBLIC void *widget_buffer_hw_buffer(widget_buffer_h handle)
832 struct widget_buffer_data *user_data;
838 user_data = widget_provider_buffer_user_data(handle);
839 if (!user_data || !user_data->accelerated) {
843 return widget_provider_buffer_hw_addr(handle);
846 PUBLIC int widget_buffer_pre_render(widget_buffer_h handle)
848 struct widget_buffer_data *user_data;
851 return WIDGET_ERROR_INVALID_PARAMETER;
854 user_data = widget_provider_buffer_user_data(handle);
856 return WIDGET_ERROR_INVALID_PARAMETER;
859 if (!user_data->accelerated) {
860 return WIDGET_ERROR_NONE;
865 * Do preprocessing for accessing the H/W render buffer
867 return widget_provider_buffer_pre_render(handle);
870 static Eina_Bool frame_wait_cb(void *data)
872 widget_buffer_h handle = data;
873 struct widget_buffer_data *user_data;
881 user_data = widget_provider_buffer_user_data(handle);
883 ErrPrint("Failed to get a user data\n");
884 return ECORE_CALLBACK_CANCEL;
887 pkgname = widget_provider_buffer_pkgname(handle);
888 id = widget_provider_buffer_id(handle);
890 if (!pkgname || !id) {
891 ErrPrint("Failed to get instance information (%s), (%s)\n", pkgname, id);
892 user_data->frame_wait_timer = NULL;
893 return ECORE_CALLBACK_CANCEL;
896 if (widget_provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
897 ErrPrint("Failed to get size (%s)\n", id);
900 pixel_size = sizeof(int);
903 DbgPrint("Frame skip waiting timer is fired (%s)\n", id);
907 * manipulate the damaged region, so send update event only for the damaged region.
908 * to make more efficient updates
910 ret = binder_widget_send_updated(pkgname, id, handle, WIDGET_PRIMARY_BUFFER, 0, 0, w, h, user_data->is_gbar, NULL);
912 ErrPrint("Failed to send%supdated (%s)\n", user_data->is_gbar ? " GBAR " : " ", id);
915 (void)widget_provider_buffer_clear_frame_skip(handle);
917 user_data->frame_wait_timer = NULL;
918 return ECORE_CALLBACK_CANCEL;
921 PUBLIC int widget_buffer_post_render(widget_buffer_h handle)
926 struct widget_buffer_data *user_data;
934 PERF_MARK("post_render");
935 return WIDGET_ERROR_INVALID_PARAMETER;
938 user_data = widget_provider_buffer_user_data(handle);
940 PERF_MARK("post_render");
941 return WIDGET_ERROR_INVALID_PARAMETER;
944 if (!user_data->accelerated) {
945 PERF_MARK("post_render");
946 return WIDGET_ERROR_NONE;
949 pkgname = widget_provider_buffer_pkgname(handle);
951 ErrPrint("Invalid buffer handle\n");
952 PERF_MARK("post_render");
953 return WIDGET_ERROR_INVALID_PARAMETER;
956 id = widget_provider_buffer_id(handle);
958 ErrPrint("Invalid buffer handler\n");
959 PERF_MARK("post_render");
960 return WIDGET_ERROR_INVALID_PARAMETER;
963 ret = widget_provider_buffer_post_render(handle);
965 ErrPrint("Failed to post render processing\n");
966 PERF_MARK("post_render");
970 if (widget_provider_buffer_frame_skip(handle) == 0) {
971 if (widget_provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
972 ErrPrint("Failed to get size (%s)\n", id);
977 * manipulate the damaged region, so send update event only for the damaged region.
978 * to make more efficient updates
980 ret = binder_widget_send_updated(pkgname, id, handle, WIDGET_PRIMARY_BUFFER, 0, 0, w, h, user_data->is_gbar, NULL);
982 ErrPrint("Failed to send%supdated (%s)\n", user_data->is_gbar ? " GBAR " : " ", id);
985 if (user_data->frame_wait_timer) {
986 ecore_timer_del(user_data->frame_wait_timer);
987 user_data->frame_wait_timer = NULL;
990 if (user_data->frame_wait_timer) {
991 ecore_timer_reset(user_data->frame_wait_timer);
993 user_data->frame_wait_timer = ecore_timer_add(FRAME_WAIT_INTERVAL, frame_wait_cb, handle);
994 if (!user_data->frame_wait_timer) {
995 ErrPrint("Failed to add waiting timer for next frame\n");
1000 PERF_MARK("post_render");
1004 PUBLIC int widget_buffer_stride(widget_buffer_h handle)
1007 return WIDGET_ERROR_INVALID_PARAMETER;
1010 return widget_provider_buffer_stride(handle);
1013 PUBLIC int widget_request_close_glance_bar(const char *pkgname, const char *id, int reason)
1016 int schema_len = strlen(FILE_SCHEMA);
1019 if (!pkgname || !id) {
1020 ErrPrint("Invalid parameters (%s) (%s)\n", pkgname, id);
1021 return WIDGET_ERROR_INVALID_PARAMETER;
1024 if (strncmp(id, FILE_SCHEMA, schema_len)) {
1025 uri = util_id_to_uri(id);
1027 ErrPrint("Heap: %d\n", errno);
1028 return WIDGET_ERROR_OUT_OF_MEMORY;
1033 ErrPrint("Heap: %d\n", errno);
1034 return WIDGET_ERROR_OUT_OF_MEMORY;
1038 ret = widget_provider_send_request_close_gbar(pkgname, uri, reason);
1043 PUBLIC int widget_freeze_scroller(const char *pkgname, const char *id)
1048 if (!pkgname || !id) {
1049 return WIDGET_ERROR_INVALID_PARAMETER;
1052 uri = util_id_to_uri(id);
1054 ErrPrint("Heap: %d\n", errno);
1055 return WIDGET_ERROR_OUT_OF_MEMORY;
1058 ret = widget_provider_send_hold_scroll(pkgname, uri, 1);
1063 PUBLIC int widget_thaw_scroller(const char *pkgname, const char *id)
1068 if (!pkgname || !id) {
1069 return WIDGET_ERROR_INVALID_PARAMETER;
1072 uri = util_id_to_uri(id);
1074 ErrPrint("Heap: %d\n", errno);
1075 return WIDGET_ERROR_OUT_OF_MEMORY;
1078 ret = widget_provider_send_hold_scroll(pkgname, uri, 0);
1083 PUBLIC int widget_set_extra_info(const char *id, const char *content, const char *title, const char *icon, const char *name)
1085 widget_buffer_h handle;
1086 const char *pkgname;
1089 uri = util_id_to_uri(id);
1091 ErrPrint("Heap: %d\n", errno);
1092 return WIDGET_ERROR_OUT_OF_MEMORY;
1095 pkgname = binder_widget_find_pkgname(uri);
1097 ErrPrint("Failed to find a package (%s)\n", uri);
1099 return WIDGET_ERROR_INVALID_PARAMETER;
1102 handle = widget_provider_buffer_find_buffer(WIDGET_TYPE_WIDGET, pkgname, uri);
1104 struct widget_buffer_data *user_data;
1106 user_data = widget_provider_buffer_user_data(handle);
1108 ErrPrint("User data is not available\n");
1110 return WIDGET_ERROR_FAULT;
1113 if (content && strlen(content)) {
1116 _content = strdup(content);
1118 if (user_data->content) {
1119 free(user_data->content);
1122 user_data->content = _content;
1124 ErrPrint("Heap: %d\n", errno);
1128 if (title && strlen(title)) {
1131 _title = strdup(title);
1133 if (user_data->title) {
1134 free(user_data->title);
1137 user_data->title = _title;
1139 ErrPrint("Heap: %d\n", errno);
1143 if (icon && strlen(icon)) {
1146 _icon = strdup(icon);
1148 if (user_data->icon) {
1149 free(user_data->icon);
1152 user_data->icon = _icon;
1154 ErrPrint("Heap: %d\n", errno);
1158 if (name && strlen(name)) {
1161 _name = strdup(name);
1163 if (user_data->name) {
1164 free(user_data->name);
1167 user_data->name = _name;
1169 ErrPrint("Heap: %d\n", errno);
1173 if (widget_provider_send_extra_info(pkgname, uri, -1.0f, user_data->content, user_data->title, user_data->icon, user_data->name) < 0) {
1174 ErrPrint("Failed to send extra info (%s)\n", id);
1178 return WIDGET_ERROR_NONE;
1182 return binder_widget_update_extra_info(id, content, title, icon, name);