Update shortcut service library.
authorSung-jae Park <nicesj.park@samsung.com>
Tue, 7 May 2013 08:19:33 +0000 (17:19 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Wed, 8 May 2013 03:58:28 +0000 (12:58 +0900)
Icon service API is implemented.
Default layout & group should be "" (zero length string)
The icon provider will choose the default layout and group when it get zero length string.

Change-Id: Icff92720c7581be51cea492cfe4851fefff38571

lib/CMakeLists.txt
lib/include/dlist.h [new file with mode: 0644]
lib/include/shortcut.h
lib/include/shortcut_internal.h [new file with mode: 0644]
lib/src/dlist.c [new file with mode: 0644]
lib/src/icon.c [new file with mode: 0644]
lib/src/main.c
packaging/libshortcut.spec

index 0e27e2d..f088671 100644 (file)
@@ -32,6 +32,8 @@ ADD_DEFINITIONS("-DLOG_TAG=\"SHORTCUT\"")
 
 ADD_LIBRARY(${PROJECT_NAME} SHARED 
        src/main.c
+       src/icon.c
+       src/dlist.c
 )
 
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${svc_pkgs_LDFLAGS})
diff --git a/lib/include/dlist.h b/lib/include/dlist.h
new file mode 100644 (file)
index 0000000..cd1a421
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define dlist_remove_data(list, data) do { \
+       struct dlist *l; \
+       l = dlist_find_data(list, data); \
+       list = dlist_remove(list, l); \
+} while (0)
+
+#define dlist_foreach(list, l, data) \
+       for ((l) = (list); (l) && ((data) = dlist_data(l)); (l) = dlist_next(l))
+
+#define dlist_foreach_safe(list, l, n, data) \
+       for ((l) = (list), (n) = dlist_next(l); \
+               (l) && ((data) = dlist_data(l)); \
+               (l) = (n), (n) = dlist_next(l))
+
+struct dlist;
+
+extern struct dlist *dlist_append(struct dlist *list, void *data);
+extern struct dlist *dlist_prepend(struct dlist *list, void *data);
+extern struct dlist *dlist_remove(struct dlist *list, struct dlist *l);
+extern struct dlist *dlist_find_data(struct dlist *list, void *data);
+extern void *dlist_data(struct dlist *l);
+extern struct dlist *dlist_next(struct dlist *l);
+extern struct dlist *dlist_prev(struct dlist *l);
+extern int dlist_count(struct dlist *l);
+extern struct dlist *dlist_nth(struct dlist *l, int nth);
+
+/* End of a file */
index 1be88ff..6e0496a 100644 (file)
@@ -268,6 +268,57 @@ extern int add_to_home_remove_shortcut(const char *appid, const char *name, cons
 
 extern int add_to_home_remove_livebox(const char *appid, const char *name, result_cb_t result_cb, void *data);
 
+
+
+/*!
+ * \note
+ * Example)
+ *
+ * // Initialize the service request
+ * int ret;
+ *
+ * ret = shortcut_icon_init(init_cb, NULL);
+ * if (ret < 0) {
+ *    ...
+ * }
+ *
+ * // After the init_cb is called, you can use below functions.
+ * struct shortcut_icon *handle;
+ *
+ * // Create request for creating shortcut icon.
+ * handle = shortcut_icon_create(LIVEBOX_TYPE_1x1, "/opt/usr/apps/org.tizen.cluster-home/data/shortcut/app1.png", NULL, NULL);
+ * if (!handle) {
+ *    ...
+ * }
+ * 
+ * // Send the request to the shortcut service
+ * ret = shortcut_icon_request_and_destroy(handle, result_cb, NULL);
+ * if (ret < 0) {
+ *    ...
+ * }
+ *
+ * // Don't finalize the icon service if you don't get result callbacks of all requests
+ * ret = shortcut_icon_fini();
+ * if (ret < 0) {
+ *    ...
+ * }
+ *
+ */
+
+struct shortcut_icon;
+#define DEFAULT_ICON_PART              "icon"
+#define DEFAULT_NAME_PART              "name"
+#define SHORTCUT_ICON_TYPE_IMAGE       "image"
+#define SHORTCUT_ICON_TYPE_TEXT                "text"
+#define SHORTCUT_ICON_TYPE_SCRIPT      "script"
+extern int shortcut_icon_service_init(int (*initialized_cb)(int status, void *data), void *data);
+extern int shortcut_icon_service_fini(void);
+
+extern struct shortcut_icon *shortcut_icon_request_create(int size_type, const char *output, const char *layout, const char *group);
+extern int shortcut_icon_request_set_info(struct shortcut_icon *handle, const char *id, const char *type, const char *part, const char *data, const char *option, const char *subid);
+extern int shortcut_icon_request_send_and_destroy(struct shortcut_icon *handle, result_cb_t result_cb, void *data);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/include/shortcut_internal.h b/lib/include/shortcut_internal.h
new file mode 100644 (file)
index 0000000..5009ba2
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+#if !defined(FLOG)
+#define DbgPrint(format, arg...)       LOGD("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...)       LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#else
+extern FILE *__file_log_fp;
+#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
+
+#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
+#endif
+
+#define EAPI __attribute__((visibility("default")))
+
+#if !defined(VCONFKEY_MASTER_STARTED)
+#define VCONFKEY_MASTER_STARTED        "memory/data-provider-master/started"
+#endif
+
+#define DEFAULT_ICON_LAYOUT ""
+#define DEFAULT_ICON_GROUP ""
+
+/* End of a file */
diff --git a/lib/src/dlist.c b/lib/src/dlist.c
new file mode 100644 (file)
index 0000000..fa3082a
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "dlist.h"
+
+/*!
+ * \brief
+ * This dlist is called Modified Doubly Linked List.
+ *
+ * Noramlly, The dobule linked list contains address of previous and next element.
+ * This dlist also contains them, but the tail element only contains prev address.
+ *
+ * The head element's prev pointer indicates the last element.
+ * But the last element's next pointer indicates NIL.
+ *
+ * So we can find the last element while crawling this DList
+ * But we have to remember the address of the head element.
+ */
+
+struct dlist {
+       struct dlist *next;
+       struct dlist *prev;
+       void *data;
+};
+
+struct dlist *dlist_append(struct dlist *list, void *data)
+{
+       struct dlist *item;
+
+       item = malloc(sizeof(*item));
+       if (!item)
+               return NULL;
+
+       item->next = NULL;
+       item->data = data;
+
+       if (!list) {
+               item->prev = item;
+
+               list = item;
+       } else {
+               item->prev = list->prev;
+               item->prev->next = item;
+               list->prev = item;
+       }
+
+       assert(!list->prev->next && "item NEXT");
+
+       return list;
+}
+
+struct dlist *dlist_prepend(struct dlist *list, void *data)
+{
+       struct dlist *item;
+
+       item = malloc(sizeof(*item));
+       if (!item)
+               return NULL;
+
+       item->data = data;
+
+       if (!list) {
+               item->prev = item;
+               item->next = NULL;
+       } else {
+               if (list->prev->next)
+                       list->prev->next = item;
+
+               item->prev = list->prev;
+               item->next = list;
+
+               list->prev = item;
+
+       }
+
+       return item;
+}
+
+struct dlist *dlist_remove(struct dlist *list, struct dlist *l)
+{
+       if (!list || !l)
+               return NULL;
+
+       if (l == list)
+               list = l->next;
+       else
+               l->prev->next = l->next;
+
+       if (l->next)
+               l->next->prev = l->prev;
+       /*!
+        * \note
+        * If the removed entry 'l' has no next element, it is the last element.
+        * In this case, check the existence of the list first,
+        * and if the list is not empty, update the 'prev' of the list (which is a head element of the list) 
+        *
+        * If we didn't care about this, the head element(list) can indicates the invalid element.
+        */
+       else if (list)
+               list->prev = l->prev;
+
+       free(l);
+       return list;
+}
+
+struct dlist *dlist_find_data(struct dlist *list, void *data)
+{
+       struct dlist *l;
+       void *_data;
+
+       dlist_foreach(list, l, _data) {
+               if (data == _data)
+                       return l;
+       }
+
+       return NULL;
+}
+
+void *dlist_data(struct dlist *l)
+{
+       return l ? l->data : NULL;
+}
+
+struct dlist *dlist_next(struct dlist *l)
+{
+       return l ? l->next : NULL;
+}
+
+struct dlist *dlist_prev(struct dlist *l)
+{
+       return l ? l->prev : NULL;
+}
+
+int dlist_count(struct dlist *l)
+{
+       register int i;
+       struct dlist *n;
+       void *data;
+
+       i = 0;
+       dlist_foreach(l, n, data) {
+               i++;
+       }
+
+       return i;
+}
+
+struct dlist *dlist_nth(struct dlist *l, int nth)
+{
+       register int i;
+       struct dlist *n;
+
+       i = 0;
+       for (n = l; n; n = n->next) {
+               if (i == nth)
+                       return n;
+               i++;
+       }
+
+       return NULL;
+}
+
+/* End of a file */
diff --git a/lib/src/icon.c b/lib/src/icon.c
new file mode 100644 (file)
index 0000000..6327544
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <libgen.h>
+
+#include <dlog.h>
+#include <glib.h>
+#include <db-util.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include <packet.h>
+#include <com-core.h>
+#include <com-core_packet.h>
+
+#include "shortcut_internal.h"
+#include "shortcut.h"
+#include "dlist.h"
+
+
+
+static struct info {
+       int fd;
+       int (*init_cb)(int status, void *data);
+       void *cbdata;
+       int initialized;
+
+       const char *utility_socket;
+
+       struct dlist *pending_list;
+} s_info = {
+       .fd = -1,
+       .init_cb = NULL,
+       .cbdata = NULL,
+       .initialized = 0,
+
+       .utility_socket = "/tmp/.utility.service",
+       .pending_list = NULL,
+};
+
+
+
+struct request_item {
+       result_cb_t result_cb;
+       void *data;
+};
+
+
+
+struct pending_item {
+       struct request_item *item;
+       struct packet *packet;
+};
+
+
+
+struct block {
+       unsigned int idx;
+
+       char *type;
+       char *part;
+       char *data;
+       char *option;
+       char *id;
+       char *file;
+       char *target_id;
+};
+
+
+
+struct shortcut_icon {
+       struct shortcut_desc *desc;
+       char *layout;
+       char *output;
+       char *descfile;
+       char *group;
+       int size_type;
+};
+
+
+
+struct shortcut_desc {
+       FILE *fp;
+       int for_pd;
+       char *filename;
+
+       unsigned int last_idx;
+
+       struct dlist *block_list;
+};
+
+
+
+static int disconnected_cb(int handle, void *data)
+{
+       if (s_info.fd != handle)
+               return 0;
+
+       ErrPrint("Disconnected\n");
+       s_info.fd = -1;
+       s_info.init_cb = NULL;
+       s_info.cbdata = NULL;
+       s_info.initialized = 0;
+       return 0;
+}
+
+
+
+static inline struct shortcut_desc *shortcut_icon_desc_open(const char *filename)
+{
+       struct shortcut_desc *handle;
+
+       handle = calloc(1, sizeof(*handle));
+       if (!handle) {
+               ErrPrint("Error: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       handle->filename = strdup(filename);
+       if (!handle->filename) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(handle);
+               return NULL;
+       }
+
+       handle->fp = fopen(handle->filename, "w+");
+       if (!handle->fp) {
+               ErrPrint("Failed to open a file: %s\n", strerror(errno));
+               free(handle->filename);
+               free(handle);
+               return NULL;
+       }
+
+       return handle;
+}
+
+
+
+static inline int shortcut_icon_desc_close(struct shortcut_desc *handle)
+{
+       struct dlist *l;
+       struct dlist *n;
+       struct block *block;
+
+       if (!handle)
+               return -EINVAL;
+
+       DbgPrint("Close and flush\n");
+       dlist_foreach_safe(handle->block_list, l, n, block) {
+               handle->block_list = dlist_remove(handle->block_list, l);
+
+               DbgPrint("{\n");
+               fprintf(handle->fp, "{\n");
+               if (block->type) {
+                       fprintf(handle->fp, "type=%s\n", block->type);
+                       DbgPrint("type=%s\n", block->type);
+               }
+
+               if (block->part) {
+                       fprintf(handle->fp, "part=%s\n", block->part);
+                       DbgPrint("part=%s\n", block->part);
+               }
+
+               if (block->data) {
+                       fprintf(handle->fp, "data=%s\n", block->data);
+                       DbgPrint("data=%s\n", block->data);
+               }
+
+               if (block->option) {
+                       fprintf(handle->fp, "option=%s\n", block->option);
+                       DbgPrint("option=%s\n", block->option);
+               }
+
+               if (block->id) {
+                       fprintf(handle->fp, "id=%s\n", block->id);
+                       DbgPrint("id=%s\n", block->id);
+               }
+
+               if (block->target_id) {
+                       fprintf(handle->fp, "target=%s\n", block->target_id);
+                       DbgPrint("target=%s\n", block->target_id);
+               }
+
+               fprintf(handle->fp, "}\n");
+               DbgPrint("}\n");
+
+               free(block->type);
+               free(block->part);
+               free(block->data);
+               free(block->option);
+               free(block->id);
+               free(block->target_id);
+               free(block);
+       }
+
+       fclose(handle->fp);
+       free(handle->filename);
+       free(handle);
+       return 0;
+}
+
+
+
+static inline int shortcut_icon_desc_set_id(struct shortcut_desc *handle, int idx, const char *id)
+{
+       struct dlist *l;
+       struct block *block;
+
+       dlist_foreach(handle->block_list, l, block) {
+               if (block->idx == idx) {
+                       if (strcasecmp(block->type, SHORTCUT_ICON_TYPE_SCRIPT)) {
+                               ErrPrint("Invalid block is used\n");
+                               return SHORTCUT_ERROR_INVALID;
+                       }
+
+                       free(block->target_id);
+                       block->target_id = NULL;
+
+                       if (!id || !strlen(id))
+                               return SHORTCUT_SUCCESS;
+
+                       block->target_id = strdup(id);
+                       if (!block->target_id) {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                               return SHORTCUT_ERROR_MEMORY;
+                       }
+
+                       return SHORTCUT_SUCCESS;
+               }
+       }
+
+       return SHORTCUT_ERROR_INVALID;
+}
+/*!
+ * \return idx
+ */
+
+
+
+static inline int shortcut_icon_desc_add_block(struct shortcut_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option)
+{
+       struct block *block;
+
+       if (!handle || !type)
+               return SHORTCUT_ERROR_INVALID;
+
+       if (!part)
+               part = "";
+
+       if (!data)
+               data = "";
+
+       block = calloc(1, sizeof(*block));
+       if (!block) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return SHORTCUT_ERROR_MEMORY;
+       }
+
+       block->type = strdup(type);
+       if (!block->type) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(block);
+               return SHORTCUT_ERROR_MEMORY;
+       }
+
+       block->part = strdup(part);
+       if (!block->part) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(block->type);
+               free(block);
+               return SHORTCUT_ERROR_MEMORY;
+       }
+
+       block->data = strdup(data);
+       if (!block->data) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(block->type);
+               free(block->part);
+               free(block);
+               return SHORTCUT_ERROR_MEMORY;
+       }
+
+       if (option) {
+               block->option = strdup(option);
+               if (!block->option) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       free(block->data);
+                       free(block->type);
+                       free(block->part);
+                       free(block);
+                       return SHORTCUT_ERROR_MEMORY;
+               }
+       }
+
+       if (id) {
+               block->id = strdup(id);
+               if (!block->id) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       free(block->option);
+                       free(block->data);
+                       free(block->type);
+                       free(block->part);
+                       free(block);
+                       return SHORTCUT_ERROR_MEMORY;
+               }
+       }
+
+       block->idx = handle->last_idx++;
+       handle->block_list = dlist_append(handle->block_list, block);
+       return block->idx;
+}
+
+
+
+static int icon_request_cb(pid_t pid, int handle, const struct packet *packet, void *data)
+{
+       struct request_item *item = data;
+       int ret;
+
+       if (!packet) {
+               ret = -EFAULT;
+               DbgPrint("Disconnected?\n");
+       } else {
+               if (packet_get(packet, "i", &ret) != 1) {
+                       DbgPrint("Invalid packet\n");
+                       ret = -EINVAL;
+               }
+       }
+
+       if (item->result_cb)
+               item->result_cb(ret, pid, item->data);
+
+       free(item);
+       return 0;
+}
+
+
+
+static inline int make_connection(void)
+{
+       int ret;
+       static struct method service_table[] = {
+               {
+                       .cmd = NULL,
+                       .handler = NULL,
+               },
+       };
+
+       s_info.fd = com_core_packet_client_init(s_info.utility_socket, 0, service_table);
+       if (s_info.fd < 0) {
+               ret = SHORTCUT_ERROR_COMM;
+
+               if (s_info.init_cb)
+                       s_info.init_cb(ret, s_info.cbdata);
+       } else {
+               struct dlist *l;
+               struct dlist *n;
+               struct pending_item *pend;
+
+               if (s_info.init_cb)
+                       s_info.init_cb(SHORTCUT_SUCCESS, s_info.cbdata);
+
+               dlist_foreach_safe(s_info.pending_list, l, n, pend) {
+                       s_info.pending_list = dlist_remove(s_info.pending_list, l);
+
+                       ret = com_core_packet_async_send(s_info.fd, pend->packet, 0.0f, icon_request_cb, pend->item);
+                       packet_destroy(pend->packet);
+                       if (ret < 0) {
+                               ErrPrint("ret: %d\n", ret);
+                               if (pend->item->result_cb)
+                                       pend->item->result_cb(ret, getpid(), pend->item->data);
+                               free(pend->item);
+                       }
+
+                       free(pend);
+               }
+
+               ret = SHORTCUT_SUCCESS;
+       }
+
+       return ret;
+}
+
+
+
+static void master_started_cb(keynode_t *node, void *user_data)
+{
+       int state = 0;
+
+       if (vconf_get_bool(VCONFKEY_MASTER_STARTED, &state) < 0)
+               ErrPrint("Unable to get \"%s\"\n", VCONFKEY_MASTER_STARTED);
+
+       if (state == 1 && make_connection() == SHORTCUT_SUCCESS) {
+               int ret;
+               ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb);
+               DbgPrint("Ignore VCONF [%d]\n", ret);
+       }
+}
+
+
+
+EAPI int shortcut_icon_service_init(int (*init_cb)(int status, void *data), void *data)
+{
+       int ret;
+
+       if (s_info.fd >= 0)
+               return -EALREADY;
+
+       if (s_info.initialized) {
+               s_info.initialized = 1;
+               com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
+       }
+
+       s_info.init_cb = init_cb;
+       s_info.cbdata = data;
+
+       ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL);
+       if (ret < 0)
+               ErrPrint("Failed to add vconf for service state [%d]\n", ret);
+       else
+               DbgPrint("vconf is registered\n");
+
+       master_started_cb(NULL, NULL);
+       return 0;
+}
+
+
+
+EAPI int shortcut_icon_service_fini(void)
+{
+       if (s_info.initialized) {
+               com_core_del_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
+               s_info.initialized = 0;
+       }
+
+       if (s_info.fd < 0)
+               return -EINVAL;
+
+       com_core_packet_client_fini(s_info.fd);
+       s_info.init_cb = NULL;
+       s_info.cbdata = NULL;
+       s_info.fd = -1;
+       return 0;
+}
+
+
+
+EAPI struct shortcut_icon *shortcut_icon_request_create(int size_type, const char *output, const char *layout, const char *group)
+{
+       struct shortcut_icon *handle;
+       int len;
+
+       if (!layout) {
+               DbgPrint("Using default icon layout\n");
+               layout = DEFAULT_ICON_LAYOUT;
+       }
+
+       if (!group) {
+               DbgPrint("Using default icon group\n");
+               group = DEFAULT_ICON_GROUP;
+       }
+
+       handle = malloc(sizeof(*handle));
+       if (!handle) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       len = strlen(output) + strlen(".desc") + 1;
+       handle->descfile = malloc(len);
+       if (!handle->descfile) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(handle);
+               return NULL;
+       }
+
+       handle->layout = strdup(layout);
+       if (!handle->layout) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(handle->descfile);
+               free(handle);
+               return NULL;
+       }
+
+       handle->group = strdup(group);
+       if (!handle->group) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(handle->descfile);
+               free(handle->layout);
+               free(handle);
+               return NULL;
+       }
+
+       handle->output = strdup(output);
+       if (!handle->output) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(handle->group);
+               free(handle->layout);
+               free(handle->descfile);
+               free(handle);
+               return NULL;
+       }
+
+       snprintf(handle->descfile, len, "%s.desc", output);
+
+       handle->desc = shortcut_icon_desc_open(handle->descfile);
+       if (!handle->desc) {
+               ErrPrint("Uanble to open desc\n");
+               free(handle->output);
+               free(handle->group);
+               free(handle->layout);
+               free(handle->descfile);
+               free(handle);
+               return NULL;
+       }
+
+       handle->size_type = size_type;
+       return handle;
+}
+
+
+
+EAPI int shortcut_icon_request_set_info(struct shortcut_icon *handle, const char *id, const char *type, const char *part, const char *data, const char *option, const char *subid)
+{
+       int idx;
+
+       idx = shortcut_icon_desc_add_block(handle->desc, id, type, part, data, option);
+       if (subid && idx >= 0)
+               shortcut_icon_desc_set_id(handle->desc, idx, subid);
+
+       return idx;
+}
+
+
+
+EAPI int shortcut_icon_request_send_and_destroy(struct shortcut_icon *handle, result_cb_t result_cb, void *data)
+{
+       int ret;
+       struct packet *packet;
+       struct request_item *item;
+
+       DbgPrint("Request and Destroy\n");
+       shortcut_icon_desc_close(handle->desc);
+
+       item = malloc(sizeof(*item));
+       if (!item) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               ret = -ENOMEM;
+       } else {
+               item->result_cb = result_cb;
+               item->data = data;
+
+               packet = packet_create("icon_create", "sssis", handle->layout, handle->group, handle->descfile, handle->size_type, handle->output);
+               if (!packet) {
+                       ErrPrint("Failed to create a packet\n");
+                       free(item);
+                       ret = -EFAULT;
+                       goto out;
+               }
+
+               if (s_info.fd >= 0 && !s_info.pending_list) {
+                       ret = com_core_packet_async_send(s_info.fd, packet, 0.0f, icon_request_cb, item);
+                       packet_destroy(packet);
+                       if (ret < 0) {
+                               ErrPrint("ret: %d\n", ret);
+                               free(item);
+                       }
+                       DbgPrint("Request is sent\n");
+               } else {
+                       struct pending_item *pend;
+
+                       pend = malloc(sizeof(*pend));
+                       if (!pend) {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                               ret = -ENOMEM;
+                               packet_destroy(packet);
+                               free(item);
+                               goto out;
+                       }
+
+                       pend->packet = packet;
+                       pend->item = item;
+
+                       s_info.pending_list = dlist_append(s_info.pending_list, pend);
+                       DbgPrint("Request is pended\n");
+
+                       ret = 0;
+               }
+       }
+
+out:
+       free(handle->output);
+       free(handle->layout);
+       free(handle->group);
+       free(handle->descfile);
+       free(handle);
+       return ret;
+}
+
+
+/* End of a file */
index 2410fb2..0a27aa3 100644 (file)
 #include <com-core_packet.h>
 
 #include "shortcut.h"
-
-#if !defined(FLOG)
-#define DbgPrint(format, arg...)       LOGD("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
-#define ErrPrint(format, arg...)       LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
-#else
-extern FILE *__file_log_fp;
-#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
-
-#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
-#endif
-
-#define EAPI __attribute__((visibility("default")))
-
-#if !defined(VCONFKEY_MASTER_STARTED)
-#define VCONFKEY_MASTER_STARTED        "memory/data-provider-master/started"
-#endif
+#include "shortcut_internal.h"
 
 int errno;
 
index 66205dc..39ab350 100644 (file)
@@ -1,6 +1,6 @@
 Name: libshortcut
 Summary: Shortcut add feature supporting library
-Version: 0.5.1
+Version: 0.6.0
 Release: 0
 Group: HomeTF/Framework
 License: Apache License