summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKyuho Jo <kyuho.jo@samsung.com>2015-02-12 22:01:19 +0900
committerKyuho Jo <kyuho.jo@samsung.com>2015-02-13 11:03:37 +0900
commit1b30d07bb82b2a7f8f4770eb4dc0b148391447af (patch)
treeee404fd690577bf9d10f192289116f09e9a0b742 /src
parent45c2785cf0c16c49a79a50c2d27d0a5707cf2ebf (diff)
downloadwidget-service-1b30d07bb82b2a7f8f4770eb4dc0b148391447af.tar.gz
widget-service-1b30d07bb82b2a7f8f4770eb4dc0b148391447af.tar.bz2
widget-service-1b30d07bb82b2a7f8f4770eb4dc0b148391447af.zip
Rename to widget
Change-Id: I46ba39326c98db73aab92be5767384937fd3db4c Signed-off-by: Kyuho Jo <kyuho.jo@samsung.com>
Diffstat (limited to 'src')
-rw-r--r--src/dlist.c189
-rwxr-xr-xsrc/util.c287
-rwxr-xr-xsrc/util_wayland.c237
-rwxr-xr-xsrc/util_x11.c355
-rwxr-xr-xsrc/widget_conf.c1819
-rwxr-xr-xsrc/widget_service.c3230
6 files changed, 6117 insertions, 0 deletions
diff --git a/src/dlist.c b/src/dlist.c
new file mode 100644
index 0000000..3ae571b
--- /dev/null
+++ b/src/dlist.c
@@ -0,0 +1,189 @@
+/*
+ * 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/src/util.c b/src/util.c
new file mode 100755
index 0000000..bec4eaf
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,287 @@
+/*
+ * 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 <sys/time.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/statvfs.h>
+#include <time.h>
+
+#include <sqlite3.h>
+#include <unicode/uloc.h>
+
+#include <dlog.h>
+
+#include "widget_errno.h"
+#include "util.h"
+#include "debug.h"
+
+int errno;
+#if defined(_USE_ECORE_TIME_GET)
+static struct info {
+ clockid_t type;
+} s_info = {
+ .type = CLOCK_MONOTONIC,
+};
+#endif
+
+double util_timestamp(void)
+{
+#if defined(_USE_ECORE_TIME_GET)
+ struct timespec ts;
+
+ do {
+ if (clock_gettime(s_info.type, &ts) == 0) {
+ return ts.tv_sec + ts.tv_nsec / 1000000000.0f;
+ }
+
+ ErrPrint("%d: %s\n", s_info.type, strerror(errno));
+ if (s_info.type == CLOCK_MONOTONIC) {
+ s_info.type = CLOCK_REALTIME;
+ } else if (s_info.type == CLOCK_REALTIME) {
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL) < 0) {
+ ErrPrint("gettimeofday: %s\n", strerror(errno));
+ break;
+ }
+
+ return tv.tv_sec + tv.tv_usec / 1000000.0f;
+ }
+ } while (1);
+
+ return 0.0f;
+#else
+ struct timeval tv;
+
+ if (gettimeofday(&tv, NULL) < 0) {
+ ErrPrint("gettimeofday: %s\n", strerror(errno));
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+
+ return tv.tv_sec + tv.tv_usec / 1000000.0f;
+#endif
+}
+
+const char *util_basename(const char *name)
+{
+ int length;
+ length = name ? strlen(name) : 0;
+ if (!length) {
+ return ".";
+ }
+
+ while (--length > 0 && name[length] != '/');
+
+ return length <= 0 ? name : (name + length + (name[length] == '/'));
+}
+
+unsigned long util_free_space(const char *path)
+{
+ struct statvfs st;
+ unsigned long space;
+
+ if (statvfs(path, &st) < 0) {
+ ErrPrint("statvfs: %s\n", strerror(errno));
+ return 0lu;
+ }
+
+ space = st.f_bsize * st.f_bfree;
+ /*!
+ * \note
+ * Must have to check the overflow
+ */
+ return space;
+}
+
+char *util_replace_string(const char *src, const char *pattern, const char *replace)
+{
+ int s_idx;
+ int p_idx;
+ int n_idx;
+ int t_idx;
+ int r_idx;
+ int idx;
+ char *result;
+ int len;
+ int rlen;
+ int matched;
+
+ if (!src || !pattern || !replace || !src[0] || !pattern[0]) {
+ ErrPrint("Invalid argument: %s %s %s\n", src, pattern, replace);
+ return NULL;
+ }
+
+ rlen = strlen(replace);
+ len = strlen(src);
+ result = malloc(len + 1);
+ if (!result) {
+ ErrPrint("Heap:%s\n", strerror(errno));
+ return NULL;
+ }
+
+ r_idx = 0;
+ idx = 0;
+ matched = 0;
+ for (s_idx = 0; src[s_idx]; s_idx++) {
+ if (idx == len) {
+ char *tmp;
+
+ len += (rlen > len ? rlen : len);
+ tmp = realloc(result, len + 1);
+ if (!tmp) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(result);
+ return NULL;
+ }
+ result = tmp;
+ }
+
+ if (src[s_idx] == pattern[0]) {
+ n_idx = -1;
+ t_idx = s_idx;
+ r_idx = idx;
+
+ if (r_idx == len) {
+ char *tmp;
+ len += (rlen > len ? rlen : len);
+ tmp = realloc(result, len + 1);
+ if (!tmp) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(result);
+ return NULL;
+ }
+ result = tmp;
+ }
+ result[r_idx++] = src[t_idx++];
+ p_idx = 1;
+ while (pattern[p_idx]) {
+ if (src[t_idx] == pattern[p_idx]) {
+ if (n_idx < 0) {
+ if (src[t_idx] == pattern[0]) {
+ n_idx = t_idx;
+ } else {
+ if (r_idx == len) {
+ char *tmp;
+ len += (rlen > len ? rlen : len);
+ tmp = realloc(result, len + 1);
+ if (!tmp) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(result);
+ return NULL;
+ }
+ result = tmp;
+ }
+ result[r_idx++] = src[t_idx];
+ }
+ }
+
+ p_idx++;
+ t_idx++;
+ continue;
+ }
+
+ if (n_idx < 0) {
+ s_idx = t_idx;
+ } else {
+ s_idx = n_idx;
+ }
+
+ break;
+ }
+
+ if (pattern[p_idx] == '\0') {
+ if (idx + rlen >= len) {
+ char *tmp;
+ len += (rlen > len ? rlen : len);
+ tmp = realloc(result, len + 1);
+ if (!tmp) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(result);
+ return NULL;
+ }
+ result = tmp;
+ matched++;
+ }
+ strcpy(result + idx, replace);
+ idx += strlen(replace);
+ s_idx = t_idx - 1;
+ } else {
+ idx = r_idx;
+ s_idx = (n_idx < 0 ? t_idx : n_idx) - 1;
+ }
+ } else {
+ result[idx++] = src[s_idx];
+ }
+ }
+
+ result[idx] = '\0';
+
+ if (!matched) {
+ free(result);
+ result = NULL;
+ }
+
+ return result;
+}
+
+const char *util_uri_to_path(const char *uri)
+{
+ int len;
+
+ len = strlen(SCHEMA_FILE);
+ if (strncasecmp(uri, SCHEMA_FILE, len)) {
+ return NULL;
+ }
+
+ return uri + len;
+}
+
+char *util_id_to_uri(const char *id)
+{
+ char *uri;
+
+ if (!id) {
+ uri = strdup("");
+ if (!uri) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+ } else if (strncmp(id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
+ int len;
+ len = strlen(SCHEMA_FILE) + strlen(id) + 2;
+ uri = malloc(len);
+ if (!uri) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ snprintf(uri, len, SCHEMA_FILE"%s", id);
+ } else {
+ uri = strdup(id);
+ if (!uri) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+ }
+
+ return uri;
+}
+
+/* End of a file */
diff --git a/src/util_wayland.c b/src/util_wayland.c
new file mode 100755
index 0000000..2ad812b
--- /dev/null
+++ b/src/util_wayland.c
@@ -0,0 +1,237 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <dlog.h>
+
+#include <sqlite3.h>
+#include <unicode/uloc.h>
+
+#include "widget_errno.h"
+#include "util.h"
+#include "widget_service.h"
+#include "debug.h"
+
+int errno;
+
+static int update_info(struct supported_size_list *SIZE_LIST, int width_type, int height_type, int width, int height)
+{
+ int idx;
+
+ if (width_type == 1 && height_type == 1) {
+ idx = 0;
+ } else if (width_type == 2 && height_type == 1) {
+ idx = 1;
+ } else if (width_type == 2 && height_type == 2) {
+ idx = 2;
+ } else if (width_type == 4 && height_type == 1) {
+ idx = 3;
+ } else if (width_type == 4 && height_type == 2) {
+ idx = 4;
+ } else if (width_type == 4 && height_type == 3) {
+ idx = 5;
+ } else if (width_type == 4 && height_type == 4) {
+ idx = 6;
+ } else if (width_type == 4 && height_type == 5) {
+ idx = 7;
+ } else if (width_type == 4 && height_type == 6) {
+ idx = 8;
+ } else if (width_type == 21 && height_type == 21) {
+ idx = 9;
+ } else if (width_type == 23 && height_type == 21) {
+ idx = 10;
+ } else if (width_type == 23 && height_type == 23) {
+ idx = 11;
+ } else if (width_type == 0 && height_type == 0) {
+ idx = 12;
+ } else {
+ ErrPrint("Unknown size type: %dx%d (%dx%d)\n", width_type, height_type, width, height);
+ return 0;
+ }
+
+ SIZE_LIST[idx].w = width;
+ SIZE_LIST[idx].h = height;
+ return 1;
+}
+
+static inline int update_from_file(struct service_info *info, struct supported_size_list *SIZE_LIST)
+{
+ FILE *fp;
+ int updated;
+ int width_type;
+ int height_type;
+ int width;
+ int height;
+ char buffer[MAX_COLUMN];
+ int ch;
+ int idx;
+ enum status {
+ START = 0x0,
+ TYPE = 0x01,
+ SIZE = 0x02,
+ COMMENT = 0x03,
+ ERROR = 0x04,
+ EOL = 0x05,
+ TYPE_END = 0x06,
+ SIZE_START = 0x07
+ } status;
+
+ fp = fopen(info->conf_file, "r");
+ if (!fp) {
+ ErrPrint("Open failed: %s\n", strerror(errno));
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ updated = 0;
+ status = START;
+ idx = 0;
+ do {
+ ch = fgetc(fp);
+
+ if (idx == MAX_COLUMN) {
+ ErrPrint("Buffer overflow. Too long line. LINE MUST BE SHOT THAN %d\n", MAX_COLUMN);
+ status = ERROR;
+ }
+
+ switch (status) {
+ case START:
+ if (isspace(ch) || ch == EOF) {
+ continue;
+ }
+
+ info->base_parse = 0;
+
+ if (ch == '#') {
+ status = COMMENT;
+ } else {
+ status = TYPE;
+ idx = 0;
+ ungetc(ch, fp);
+ }
+ break;
+ case TYPE:
+ if (isblank(ch)) {
+ buffer[idx] = '\0';
+ status = TYPE_END;
+ if (sscanf(buffer, "%dx%d", &width_type, &height_type) != 2) {
+ if (!strcasecmp(buffer, "base")) {
+ info->base_parse = 1;
+ } else {
+ ErrPrint("Invalid syntax: [%s]\n", buffer);
+ status = ERROR;
+ }
+ }
+ break;
+ } else if (ch == '=') {
+ buffer[idx] = '\0';
+ status = SIZE_START;
+ if (sscanf(buffer, "%dx%d", &width_type, &height_type) != 2) {
+ if (!strcasecmp(buffer, "base")) {
+ info->base_parse = 1;
+ } else {
+ ErrPrint("Invalid syntax: [%s]\n", buffer);
+ status = ERROR;
+ }
+ }
+ break;
+ } else if (ch == EOF) {
+ ErrPrint("Invalid Syntax\n");
+ status = ERROR;
+ continue;
+ }
+ buffer[idx++] = ch;
+ break;
+ case TYPE_END:
+ if (ch == '=') {
+ status = SIZE_START;
+ }
+ break;
+ case SIZE_START:
+ if (isspace(ch) || ch == EOF) {
+ continue;
+ }
+
+ status = SIZE;
+ idx = 0;
+ ungetc(ch, fp);
+ break;
+ case SIZE:
+ if (isspace(ch) || ch == EOF) {
+ buffer[idx] = '\0';
+ status = EOL;
+
+ if (sscanf(buffer, "%dx%d", &width, &height) != 2) {
+ ErrPrint("Invalid syntax: [%s]\n", buffer);
+ status = ERROR;
+ } else if (ch == EOF) {
+ if (info->base_parse) {
+ info->base_w = width;
+ info->base_h = height;
+ } else {
+ updated += update_info(SIZE_LIST, width_type, height_type, width, height);
+ }
+ }
+ break;
+ }
+ buffer[idx++] = ch;
+ break;
+ case EOL:
+ if (!info->base_parse) {
+ updated += update_info(SIZE_LIST, width_type, height_type, width, height);
+ } else {
+ info->base_w = width;
+ info->base_h = height;
+ }
+ status = START;
+ ungetc(ch, fp);
+ break;
+ case ERROR:
+ if (ch == '\n' || ch == '\r' || ch == '\f') {
+ status = START;
+ }
+ break;
+ case COMMENT:
+ if (ch == '\n' || ch == '\r' || ch == '\f') {
+ status = START;
+ }
+ break;
+ default:
+ ErrPrint("Unknown status. couldn't be reach to here\n");
+ break;
+ }
+ } while (!feof(fp));
+
+ if (fclose(fp) != 0) {
+ ErrPrint("fclose: %s\n", strerror(errno));
+ }
+
+ return WIDGET_NR_OF_SIZE_LIST - updated;
+}
+
+int util_update_resolution(struct service_info *info, struct supported_size_list *SIZE_LIST)
+{
+ unsigned int width;
+ unsigned int height;
+ unsigned int border;
+ unsigned int depth;
+ register int i;
+ static int res_resolved = 0;
+
+ if (res_resolved) {
+ return WIDGET_STATUS_ERROR_NONE;
+ }
+
+ if (update_from_file(info, SIZE_LIST) == 0) {
+ DbgPrint("Resolution info is all updated by file\n");
+ }
+
+ res_resolved = 1;
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+int util_screen_size_get(unsigned int *width, unsigned int *height)
+{
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+/* End of a file */
diff --git a/src/util_x11.c b/src/util_x11.c
new file mode 100755
index 0000000..2d1a30f
--- /dev/null
+++ b/src/util_x11.c
@@ -0,0 +1,355 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h> // access
+#include <stdlib.h> // free
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+
+#include <dlog.h>
+
+#include <sqlite3.h>
+#include <unicode/uloc.h>
+
+#include "widget_errno.h"
+#include "util.h"
+#include "widget_service.h"
+#include "debug.h"
+
+#define CONF_PATH_FORMAT "/usr/share/data-provider-master/%dx%d/resolution.ini"
+
+int errno;
+
+static struct {
+ unsigned int w;
+ unsigned int h;
+ int res_resolved;
+} s_info = {
+ .w = 0,
+ .h = 0,
+ .res_resolved = 0,
+};
+
+static int update_info(struct supported_size_list *SIZE_LIST, int width_type, int height_type, int width, int height)
+{
+ int idx;
+
+ if (width_type == 1 && height_type == 1) {
+ idx = 0;
+ } else if (width_type == 2 && height_type == 1) {
+ idx = 1;
+ } else if (width_type == 2 && height_type == 2) {
+ idx = 2;
+ } else if (width_type == 4 && height_type == 1) {
+ idx = 3;
+ } else if (width_type == 4 && height_type == 2) {
+ idx = 4;
+ } else if (width_type == 4 && height_type == 3) {
+ idx = 5;
+ } else if (width_type == 4 && height_type == 4) {
+ idx = 6;
+ } else if (width_type == 4 && height_type == 5) {
+ idx = 7;
+ } else if (width_type == 4 && height_type == 6) {
+ idx = 8;
+ } else if (width_type == 21 && height_type == 21) {
+ idx = 9;
+ } else if (width_type == 23 && height_type == 21) {
+ idx = 10;
+ } else if (width_type == 23 && height_type == 23) {
+ idx = 11;
+ } else if (width_type == 0 && height_type == 0) {
+ idx = 12;
+ } else {
+ ErrPrint("Unknown size type: %dx%d (%dx%d)\n", width_type, height_type, width, height);
+ return 0;
+ }
+
+ SIZE_LIST[idx].w = width;
+ SIZE_LIST[idx].h = height;
+ return 1;
+}
+
+static inline int update_from_file(struct service_info *info, struct supported_size_list *SIZE_LIST)
+{
+ FILE *fp;
+ int updated;
+ int width_type;
+ int height_type;
+ int width;
+ int height;
+ char buffer[MAX_COLUMN];
+ int ch;
+ int idx;
+ enum status {
+ START = 0x0,
+ TYPE = 0x01,
+ SIZE = 0x02,
+ COMMENT = 0x03,
+ ERROR = 0x04,
+ EOL = 0x05,
+ TYPE_END = 0x06,
+ SIZE_START = 0x07
+ } status;
+
+ fp = fopen(info->conf_file, "r");
+ if (!fp) {
+ ErrPrint("Open failed: %s\n", strerror(errno));
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ updated = 0;
+ status = START;
+ idx = 0;
+ do {
+ ch = fgetc(fp);
+
+ if (idx == MAX_COLUMN) {
+ ErrPrint("Buffer overflow. Too long line. LINE MUST BE SHOT THAN %d\n", MAX_COLUMN);
+ status = ERROR;
+ }
+
+ switch (status) {
+ case START:
+ if (isspace(ch) || ch == EOF) {
+ continue;
+ }
+
+ info->base_parse = 0;
+
+ if (ch == '#') {
+ status = COMMENT;
+ } else {
+ status = TYPE;
+ idx = 0;
+ ungetc(ch, fp);
+ }
+ break;
+ case TYPE:
+ if (isblank(ch)) {
+ buffer[idx] = '\0';
+ status = TYPE_END;
+ if (sscanf(buffer, "%dx%d", &width_type, &height_type) != 2) {
+ if (!strcasecmp(buffer, "base")) {
+ info->base_parse = 1;
+ } else {
+ ErrPrint("Invalid syntax: [%s]\n", buffer);
+ status = ERROR;
+ }
+ }
+ break;
+ } else if (ch == '=') {
+ buffer[idx] = '\0';
+ status = SIZE_START;
+ if (sscanf(buffer, "%dx%d", &width_type, &height_type) != 2) {
+ if (!strcasecmp(buffer, "base")) {
+ info->base_parse = 1;
+ } else {
+ ErrPrint("Invalid syntax: [%s]\n", buffer);
+ status = ERROR;
+ }
+ }
+ break;
+ } else if (ch == EOF) {
+ ErrPrint("Invalid Syntax\n");
+ status = ERROR;
+ continue;
+ }
+ buffer[idx++] = ch;
+ break;
+ case TYPE_END:
+ if (ch == '=') {
+ status = SIZE_START;
+ }
+ break;
+ case SIZE_START:
+ if (isspace(ch) || ch == EOF) {
+ continue;
+ }
+
+ status = SIZE;
+ idx = 0;
+ ungetc(ch, fp);
+ break;
+ case SIZE:
+ if (isspace(ch) || ch == EOF) {
+ buffer[idx] = '\0';
+ status = EOL;
+
+ if (sscanf(buffer, "%dx%d", &width, &height) != 2) {
+ if (!strncasecmp(buffer, "screen", strlen("screen"))) {
+ width = s_info.w;
+ height = s_info.h;
+ DbgPrint("Select screen size: %dx%d\n", width, height);
+ } else {
+ ErrPrint("Invalid syntax: [%s]\n", buffer);
+ status = ERROR;
+ }
+ }
+
+ if (status != ERROR && ch == EOF) {
+ if (info->base_parse) {
+ info->base_w = width;
+ info->base_h = height;
+ } else {
+ updated += update_info(SIZE_LIST, width_type, height_type, width, height);
+ }
+ }
+ break;
+ }
+ buffer[idx++] = ch;
+ break;
+ case EOL:
+ if (!info->base_parse) {
+ updated += update_info(SIZE_LIST, width_type, height_type, width, height);
+ } else {
+ info->base_w = width;
+ info->base_h = height;
+ }
+ status = START;
+ ungetc(ch, fp);
+ break;
+ case ERROR:
+ if (ch == '\n' || ch == '\r' || ch == '\f') {
+ status = START;
+ }
+ break;
+ case COMMENT:
+ if (ch == '\n' || ch == '\r' || ch == '\f') {
+ status = START;
+ }
+ break;
+ default:
+ ErrPrint("Unknown status. couldn't be reach to here\n");
+ break;
+ }
+ } while (!feof(fp));
+
+ if (fclose(fp) != 0) {
+ ErrPrint("fclose: %s\n", strerror(errno));
+ }
+
+ return WIDGET_NR_OF_SIZE_LIST - updated;
+}
+
+/*
+ * Find proper configuration and install(link) it to conf path.
+ */
+static char *conf_path(void)
+{
+ char *path;
+ int length;
+
+ length = strlen(CONF_PATH_FORMAT) + 12; // 12 == RESERVED SPACE
+ path = calloc(1, length);
+ if (!path) {
+ ErrPrint("calloc: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ if (s_info.w == 0 || s_info.h == 0) {
+ /* Try to update resolution first if it is not initialized */
+ util_screen_size_get(NULL, NULL);
+ }
+
+ snprintf(path, length, CONF_PATH_FORMAT, s_info.w, s_info.h);
+ DbgPrint("Selected conf file: %s\n", path);
+ if (access(path, F_OK) != 0) {
+ ErrPrint("Fallback to default, access: %s\n", strerror(errno));
+ strncpy(path, RESOLUTION_FILE, length);
+ if (access(path, F_OK) != 0) {
+ ErrPrint("Serious error - there is no conf file, use default setting: %s\n", strerror(errno));
+ free(path);
+ path = NULL;
+ }
+ }
+
+ return path;
+}
+
+int util_screen_size_get(unsigned int *width, unsigned int *height)
+{
+ Display *disp;
+ Window root;
+ Window dummy;
+ unsigned int border;
+ unsigned int depth;
+ int x;
+ int y;
+ int ret;
+ unsigned int _width;
+ unsigned int _height;
+
+ if (!width) {
+ width = &_width;
+ }
+
+ if (!height) {
+ height = &_height;
+ }
+
+ if (s_info.w != 0 && s_info.h != 0) {
+ DbgPrint("Already prepared (%dx%d)\n", s_info.w, s_info.h);
+ goto out;
+ }
+
+ disp = XOpenDisplay(NULL);
+ if (!disp) {
+ ErrPrint("Failed to open a display\n");
+ return WIDGET_STATUS_ERROR_FAULT;
+ }
+
+ root = XDefaultRootWindow(disp);
+ ret = XGetGeometry(disp, root, &dummy, &x, &y, &s_info.w, &s_info.h, &border, &depth);
+ XCloseDisplay(disp);
+ if (!ret) {
+ ErrPrint("Failed to get geometry\n");
+ return WIDGET_STATUS_ERROR_FAULT;
+ }
+
+out:
+ *width = s_info.w;
+ *height = s_info.h;
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+int util_update_resolution(struct service_info *info, struct supported_size_list *SIZE_LIST)
+{
+ if (s_info.res_resolved) {
+ return WIDGET_STATUS_ERROR_NONE;
+ }
+
+ if (!info->conf_file) {
+ info->conf_file = conf_path();
+ }
+
+ if (info->conf_file) {
+ register int i;
+ unsigned int width;
+ unsigned int height;
+
+ i = util_screen_size_get(&width, &height);
+ if (i != WIDGET_STATUS_ERROR_NONE) {
+ return i;
+ }
+
+ if (update_from_file(info, SIZE_LIST) == 0) {
+ DbgPrint("Resolution info is all updated by file\n");
+ }
+
+ if (width != info->base_w) {
+ for (i = 0; i < WIDGET_NR_OF_SIZE_LIST; i++) {
+ SIZE_LIST[i].w = (unsigned int)((double)SIZE_LIST[i].w * (double)width / (double)info->base_w);
+ SIZE_LIST[i].h = (unsigned int)((double)SIZE_LIST[i].h * (double)width / (double)info->base_w);
+ }
+ }
+ } else {
+ DbgPrint("Conf file is not loaded\n");
+ }
+
+ s_info.res_resolved = 1;
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+/* End of a file */
diff --git a/src/widget_conf.c b/src/widget_conf.c
new file mode 100755
index 0000000..04b2bc0
--- /dev/null
+++ b/src/widget_conf.c
@@ -0,0 +1,1819 @@
+/*
+ * 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 <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h> // access
+#include <sqlite3.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <dlog.h>
+#include <widget_errno.h>
+#include <unicode/uloc.h>
+
+#include "widget_conf.h"
+#include "util.h"
+#include "debug.h"
+
+#define BASE_SHARE_DIR "/opt/usr/share/live_magazine/"
+#define DEFAULT_INPUT_NODE "/dev/input/event2"
+#define DEV_PATH "/dev/input/"
+#define PROC_INPUT_DEVICES "/proc/bus/input/devices"
+#define MAX_LINE_BUFFER 256
+#define NODE_PREFIX "event"
+
+#define CR 13
+#define LF 10
+
+#define MAX_ABI 256
+#define MAX_PKGNAME 512
+
+static const char *CONF_DEFAULT_SERVICES = "[widget],[shortcut],[notification],[badge],[utility],[file]";
+static const char *CONF_DEFAULT_EMERGENCY_DISK = "source=tmpfs;type=tmpfs;option=size=6M";
+static const char *CONF_DEFAULT_PATH_CONF = "/opt/usr/live/%s/etc/%s.conf";
+static const char *CONF_DEFAULT_PATH_IMAGE = BASE_SHARE_DIR;
+static const char *CONF_DEFAULT_PATH_LOG = BASE_SHARE_DIR"log";
+static const char *CONF_DEFAULT_PATH_READER = BASE_SHARE_DIR"reader";
+static const char *CONF_DEFAULT_PATH_ALWAYS = BASE_SHARE_DIR"always";
+static const char *CONF_DEFAULT_PATH_SCRIPT = "/opt/usr/live/%s/res/script/%s.edj";
+static const char *CONF_DEFAULT_PATH_ROOT = "/opt/usr/live/";
+static const char *CONF_DEFAULT_PATH_SCRIPT_PORT = "/usr/share/data-provider-master/plugin-script/";
+static const char *CONF_DEFAULT_PATH_DB = "/opt/dbspace/.widget.db";
+static const char *CONF_DEFAULT_PATH_INPUT = DEFAULT_INPUT_NODE;
+static const char *CONF_DEFAULT_SCRIPT_TYPE = "edje";
+static const char *CONF_DEFAULT_ABI = "c";
+static const char *CONF_DEFAULT_GBAR_GROUP = "disclosure";
+static const char *CONF_DEFAULT_LAUNCH_BUNDLE_NAME = "name";
+static const char *CONF_DEFAULT_LAUNCH_BUNDLE_SECURED = "secured";
+static const char *CONF_DEFAULT_LAUNCH_BUNDLE_ABI = "abi";
+static const char *CONF_DEFAULT_LAUNCH_BUNDLE_HW_ACCELERATION = "hw-acceleration";
+static const char *CONF_DEFAULT_CONTENT = "default";
+static const char *CONF_DEFAULT_TITLE = "";
+static const char *CONF_DEFAULT_EMPTY_CONTENT = "";
+static const char *CONF_DEFAULT_EMPTY_TITLE = "";
+static const char *CONF_DEFAULT_REPLACE_TAG = "/APPID/";
+static const char *CONF_DEFAULT_PROVIDER_METHOD = "pixmap";
+static const char *CONF_DEFAULT_CATEGORY_LIST = "com.samsung.wmanager.WATCH_CLOCK";
+static const int CONF_DEFAULT_WIDTH = 0;
+static const int CONF_DEFAULT_HEIGHT = 0;
+static const int CONF_DEFAULT_BASE_WIDTH = 720;
+static const int CONF_DEFAULT_BASE_HEIGHT = 1280;
+static const double CONF_DEFAULT_MINIMUM_PERIOD = 1.0f;
+static const double CONF_DEFAULT_PERIOD = -1.0f;
+static const double CONF_DEFAULT_PACKET_TIME = 0.0001f;
+static const unsigned long CONF_DEFAULT_MINIMUM_SPACE = 5242880;
+static const double CONF_DEFAULT_SLAVE_TTL = 30.0f;
+static const double CONF_DEFAULT_SLAVE_ACTIVATE_TIME = 30.0f;
+static const double CONF_DEFAULT_SLAVE_RELAUNCH_TIME = 3.0f;
+static const int CONF_DEFAULT_SLAVE_RELAUNCH_COUNT = 3;
+static const int CONF_DEFAULT_MAX_LOG_LINE = 1000;
+static const int CONF_DEFAULT_MAX_LOG_FILE = 3;
+static const int CONF_DEFAULT_SQLITE_FLUSH_MAX = 1048576;
+static const double CONF_DEFAULT_PING_TIME = 240.0f;
+static const int CONF_DEFAULT_SLAVE_MAX_LOAD = 30;
+static const int CONF_DEFAULT_USE_SW_BACKEND = 0;
+static const int CONF_DEFAULT_DEBUG_MODE = 0;
+static const int CONF_DEFAULT_OVERWRITE_CONTENT = 0;
+static const int CONF_DEFAULT_COM_CORE_THREAD = 1;
+static const int CONF_DEFAULT_USE_XMONITOR = 0;
+static const int CONF_DEFAULT_PREMULTIPLIED = 1;
+static const double CONF_DEFAULT_SCALE_WIDTH_FACTOR = 1.0f;
+static const double CONF_DEFAULT_SCALE_HEIGHT_FACTOR = 1.0f;
+static const double CONF_DEFAULT_GBAR_REQUEST_TIMEOUT = 5.0f;
+static const int CONF_DEFAULT_PIXELS = sizeof(int);
+static const int CONF_DEFAULT_AUTO_ALIGN = 1;
+static const int CONF_DEFAULT_USE_EVENT_TIME = 1;
+static const int CONF_DEFAULT_CHECK_LCD = 1;
+static const int CONF_DEFAULT_EXTRA_BUFFER_COUNT = 1;
+static const int CONF_DEFAULT_USE_GETTIMEOFDAY = 0;
+static const int CONF_DEFAULT_SLAVE_EVENT_BOOST_ON = 0;
+static const int CONF_DEFAULT_SLAVE_EVENT_BOOST_OFF = 0;
+static const double CONF_DEFAULT_EVENT_FILTER = 0.5f;
+static const int CONF_DEFAULT_SLAVE_LIMIT_TO_TTL = 0;
+static const int CONF_DEFAULT_SLAVE_AUTO_CACHE_FLUSH = 0;
+
+#define CONF_PATH_FORMAT "/usr/share/data-provider-master/%dx%d/conf.ini"
+
+int errno;
+
+struct widget_conf {
+ unsigned int width;
+ unsigned int height;
+
+ unsigned int base_width;
+ unsigned int base_height;
+ double minimum_period;
+
+ struct {
+ char *script;
+ char *abi;
+ char *gbar_group;
+ double period;
+ int pixels;
+ } default_conf;
+
+ struct {
+ char *name;
+ char *secured;
+ char *abi;
+ char *hw_acceleration;
+ } launch_key;
+
+ double default_packet_time;
+
+ char *empty_content;
+ char *empty_title;
+
+ char *default_content;
+ char *default_title;
+
+ unsigned long minimum_space;
+
+ char *replace_tag;
+
+ double slave_ttl;
+ double slave_activate_time;
+ double slave_relaunch_time;
+ int slave_relaunch_count;
+
+ int max_log_line;
+ int max_log_file;
+
+ unsigned long sqlite_flush_max;
+
+ struct {
+ char *conf;
+ char *image;
+ char *script;
+ char *root;
+ char *script_port;
+ char *slave_log;
+ char *reader;
+ char *always;
+ char *db;
+ char *input;
+ } path;
+
+ int max_size_type;
+
+ int slave_max_load;
+
+ double ping_time;
+
+ char *vconf_sys_cluster;
+ int max_pended_ctx_events;
+
+ int use_sw_backend;
+ char *provider_method;
+ int debug_mode;
+ int overwrite_content;
+ int com_core_thread;
+ int use_xmonitor;
+ int premultiplied;
+
+ double scale_width_factor;
+ double scale_height_factor;
+
+ double gbar_request_timeout;
+
+ char *emergency_disk;
+ char *services;
+ int auto_align;
+ int use_event_time;
+ int check_lcd;
+ int extra_buffer_count;
+ int use_gettimeofday;
+ int slave_event_boost_on;
+ int slave_event_boost_off;
+ double event_filter;
+ int slave_limit_to_ttl;
+ int frame_skip;
+ int slave_auto_cache_flush;
+ char *category_list;
+};
+
+static struct widget_conf s_conf;
+
+static struct info {
+ int conf_loaded;
+} s_info = {
+ .conf_loaded = 0,
+};
+
+static void category_list_handler(char *buffer)
+{
+ s_conf.category_list = strdup(buffer);
+ if (!s_conf.category_list) {
+ ErrPrint("strdup: %s\n", strerror(errno));
+ s_conf.category_list = (char *)CONF_DEFAULT_CATEGORY_LIST;
+ }
+}
+
+static void slave_auto_cache_flush_handler(char *buffer)
+{
+ s_conf.slave_auto_cache_flush = !strcasecmp(buffer, "true");
+}
+
+static void frame_skip_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.frame_skip) != 1) {
+ ErrPrint("Unable to get frame skip: %d\n", s_conf.frame_skip);
+ }
+}
+
+static void slave_limit_to_ttl_handler(char *buffer)
+{
+ s_conf.slave_limit_to_ttl = !strcasecmp(buffer, "true");
+}
+
+static void event_filter_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &s_conf.event_filter) != 1) {
+ ErrPrint("Unable to get event filter: %lf\n", s_conf.event_filter);
+ }
+}
+
+static void slave_event_boost_on_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.slave_event_boost_on) != 1) {
+ ErrPrint("Unable to get boost on: %d\n", s_conf.slave_event_boost_on);
+ }
+}
+
+static void slave_event_boost_off_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.slave_event_boost_off) != 1) {
+ ErrPrint("Unable to get boost on: %d\n", s_conf.slave_event_boost_off);
+ }
+}
+
+static void extra_buffer_count_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.extra_buffer_count) != 1) {
+ ErrPrint("Extra buffer count is not valid: [%s], remained %d\n", buffer, s_conf.extra_buffer_count);
+ }
+}
+
+static void use_xmonitor(char *buffer)
+{
+ s_conf.use_xmonitor = !strcasecmp(buffer, "true");
+}
+
+static void emergency_disk_handler(char *buffer)
+{
+ s_conf.emergency_disk = strdup(buffer);
+ if (!s_conf.emergency_disk) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void check_lcd_handler(char *buffer)
+{
+ s_conf.check_lcd = !strcasecmp(buffer, "true");
+}
+
+static void use_gettimeofday_handler(char *buffer)
+{
+ s_conf.use_gettimeofday = !strcasecmp(buffer, "true");
+}
+
+static void use_event_time_handler(char *buffer)
+{
+ s_conf.use_event_time = !strcasecmp(buffer, "true");
+}
+
+static void auto_align_handler(char *buffer)
+{
+ s_conf.auto_align = !strcasecmp(buffer, "true");
+}
+
+static void services_handler(char *buffer)
+{
+ s_conf.services = strdup(buffer);
+ if (!s_conf.services) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void use_sw_backend_handler(char *buffer)
+{
+ s_conf.use_sw_backend = !strcasecmp(buffer, "true");
+}
+
+static void provider_method_handler(char *buffer)
+{
+ s_conf.provider_method = strdup(buffer);
+ if (!s_conf.provider_method) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void debug_mode_handler(char *buffer)
+{
+ s_conf.debug_mode = !strcasecmp(buffer, "true");
+}
+
+static void overwrite_content_handler(char *buffer)
+{
+ s_conf.overwrite_content = !strcasecmp(buffer, "true");
+}
+
+static void com_core_thread_handler(char *buffer)
+{
+ s_conf.com_core_thread = !strcasecmp(buffer, "true");
+}
+
+static void base_width_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.base_width) != 1) {
+ if (!strncasecmp(buffer, "screen", strlen("screen"))) {
+ s_conf.base_width = s_conf.width;
+ DbgPrint("Base width: %u (screen)\n", s_conf.base_width);
+ } else {
+ ErrPrint("Failed to parse the base_width\n");
+ }
+ }
+}
+
+static void base_height_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.base_height) != 1) {
+ if (!strncasecmp(buffer, "screen", strlen("screen"))) {
+ s_conf.base_height = s_conf.height;
+ DbgPrint("Base height: %u (screen)\n", s_conf.base_height);
+ } else {
+ ErrPrint("Failed to parse the base_height\n");
+ }
+ }
+}
+
+static void minimum_period_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &s_conf.minimum_period) != 1) {
+ ErrPrint("Failed to parse the minimum_period\n");
+ }
+ DbgPrint("Minimum period: %lf\n", s_conf.minimum_period);
+}
+
+static void pixels_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.default_conf.pixels) != 1) {
+ ErrPrint("Failed to parse the minimum_period\n");
+ }
+ DbgPrint("Default pixels: %lf\n", s_conf.default_conf.pixels);
+}
+
+static void script_handler(char *buffer)
+{
+ s_conf.default_conf.script = strdup(buffer);
+ if (!s_conf.default_conf.script) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void default_abi_handler(char *buffer)
+{
+ s_conf.default_conf.abi = strdup(buffer);
+ if (!s_conf.default_conf.abi) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void default_group_handler(char *buffer)
+{
+ s_conf.default_conf.gbar_group = strdup(buffer);
+ if (!s_conf.default_conf.gbar_group) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void default_period_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &s_conf.default_conf.period) != 1) {
+ ErrPrint("Failed to parse the default_period\n");
+ }
+ DbgPrint("Default Period: %lf\n", s_conf.default_conf.period);
+}
+
+static void default_packet_time_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &s_conf.default_packet_time) != 1) {
+ ErrPrint("Failed to parse the default_packet_time\n");
+ }
+ DbgPrint("Default packet time: %lf\n", s_conf.default_packet_time);
+}
+
+static void default_content_handler(char *buffer)
+{
+ s_conf.default_content = strdup(buffer);
+ if (!s_conf.default_content) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void default_title_handler(char *buffer)
+{
+ s_conf.default_title = strdup(buffer);
+ if (!s_conf.default_title) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void minimum_space_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lu", &s_conf.minimum_space) != 1) {
+ ErrPrint("Failed to parse the minimum_space\n");
+ }
+}
+
+static void replace_tag_handler(char *buffer)
+{
+ s_conf.replace_tag = strdup(buffer);
+ if (!s_conf.replace_tag) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void slave_ttl_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &s_conf.slave_ttl) != 1) {
+ ErrPrint("Failed to parse the slave_ttl\n");
+ }
+ DbgPrint("Slave TTL: %lf\n", s_conf.slave_ttl);
+}
+
+static void slave_activate_time_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &s_conf.slave_activate_time) != 1) {
+ ErrPrint("Failed to parse the slave_activate_time\n");
+ }
+ DbgPrint("Slave activate time: %lf\n", s_conf.slave_activate_time);
+}
+
+static void slave_relaunch_time_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &s_conf.slave_relaunch_time) != 1) {
+ ErrPrint("Failed to parse the slave_activate_time\n");
+ }
+ DbgPrint("Slave relaunch time: %lf\n", s_conf.slave_relaunch_time);
+}
+
+static void slave_relaunch_count_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.slave_relaunch_count) != 1) {
+ ErrPrint("Failed to parse the max_log_line\n");
+ }
+}
+
+static void max_log_line_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.max_log_line) != 1) {
+ ErrPrint("Failed to parse the max_log_line\n");
+ }
+}
+
+static void max_log_file_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.max_log_file) != 1) {
+ ErrPrint("Failed to parse the max_log_file\n");
+ }
+}
+
+static void sqlite_flush_max_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lu", &s_conf.sqlite_flush_max) != 1) {
+ ErrPrint("Failed to parse the sqlite_flush_max\n");
+ }
+}
+
+static void db_path_handler(char *buffer)
+{
+ s_conf.path.db = strdup(buffer);
+ if (!s_conf.path.db) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void reader_path_handler(char *buffer)
+{
+ s_conf.path.reader = strdup(buffer);
+ if (!s_conf.path.reader) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void always_path_handler(char *buffer)
+{
+ s_conf.path.always = strdup(buffer);
+ if (!s_conf.path.always) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void log_path_handler(char *buffer)
+{
+ s_conf.path.slave_log = strdup(buffer);
+ if (!s_conf.path.slave_log) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void script_port_path_handler(char *buffer)
+{
+ s_conf.path.script_port = strdup(buffer);
+ if (!s_conf.path.script_port) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static void share_path_handler(char *buffer)
+{
+ s_conf.path.image = strdup(buffer);
+ if (!s_conf.path.image) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+}
+
+static char *parse_handler(const char *buffer)
+{
+ const char *node_prefix = NODE_PREFIX;
+ int idx = 0;
+ const char *ptr;
+ int node_idx = 0;
+ char *node = NULL;
+
+ ptr = buffer;
+ while (*ptr) {
+ if (ptr[idx] == node_prefix[idx]) {
+ idx++;
+ } else if (idx > 0 && node_prefix[idx] == '\0') {
+ if (sscanf(ptr + idx, "%d", &node_idx) == 1) {
+ int node_len;
+ node_len = idx + strlen(DEV_PATH) + 10;
+ /* Gotcha */
+ node = malloc(node_len);
+ if (node) {
+ int len;
+
+ len = snprintf(node, node_len - 1, DEV_PATH "%s%d", node_prefix, node_idx);
+ if (len < 0) {
+ ErrPrint("snprintf: %s\n", strerror(errno));
+ free(node);
+ node = NULL;
+ } else {
+ node[len] = '\0';
+ DbgPrint("NODE FOUND: %s\n", node);
+ }
+ } else {
+ ErrPrint("malloc: %s\n", strerror(errno));
+ }
+
+ break;
+ } else {
+ DbgPrint("Invalid format: [%s] / [%s]\n", ptr, ptr + idx);
+ ptr++;
+ idx = 0;
+ }
+ } else {
+ ptr++;
+ idx = 0;
+ }
+ }
+
+ return node;
+}
+
+static char *find_input_device(const char *name)
+{
+ int fd;
+ char *node = NULL;
+ char ch;
+ int row;
+ int col;
+ int idx;
+ enum state {
+ STATE_BEGIN,
+ STATE_ID,
+ STATE_NAME,
+ STATE_PHYSICAL,
+ STATE_SYSFS,
+ STATE_UNIQ,
+ STATE_HANDLER,
+ STATE_BITMAPS,
+ STATE_ERROR,
+ } state;
+ char name_buffer[MAX_LINE_BUFFER] = { 0, };
+ char handler_buffer[MAX_LINE_BUFFER] = { 0, };
+
+ fd = open(PROC_INPUT_DEVICES, O_RDONLY);
+ if (fd < 0) {
+ ErrPrint("open: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ state = STATE_BEGIN;
+ row = 1;
+ col = 1;
+ idx = -1;
+ while (state != STATE_ERROR && node == NULL && read(fd, &ch, sizeof(ch)) == sizeof(ch)) {
+ if (ch == LF) {
+ row++;
+ col = 1;
+
+ switch (state) {
+ case STATE_NAME:
+ state = STATE_BEGIN;
+ if (idx > 0) {
+ /* Remove last double-quotes */
+ if (name_buffer[idx - 1] == '"') {
+ idx--;
+ }
+ name_buffer[idx] = '\0';
+ idx = -1;
+ DbgPrint("Name: [%s]\n", name_buffer);
+ }
+ break;
+ case STATE_HANDLER:
+ state = STATE_BEGIN;
+ if (idx > 0) {
+ handler_buffer[idx] = '\0';
+ idx = -1;
+ DbgPrint("Handler: [%s]\n", handler_buffer);
+ }
+ break;
+ case STATE_BEGIN:
+ DbgPrint("name: [%s], name_buffer[%s]\n", name, name_buffer);
+ if (!strcasecmp(name, name_buffer)) {
+ node = parse_handler(handler_buffer);
+ }
+ break;
+ default:
+ /* Ignore other attributes */
+ state = STATE_BEGIN;
+ idx = -1;
+ break;
+ }
+
+ continue;
+ }
+
+ col++;
+ switch (state) {
+ case STATE_BEGIN:
+ switch (ch) {
+ case 'I':
+ state = STATE_ID;
+ break;
+ case 'N':
+ state = STATE_NAME;
+ break;
+ case 'P':
+ state = STATE_PHYSICAL;
+ break;
+ case 'S':
+ state = STATE_SYSFS;
+ break;
+ case 'U':
+ state = STATE_UNIQ;
+ break;
+ case 'H':
+ state = STATE_HANDLER;
+ break;
+ case 'B':
+ state = STATE_BITMAPS;
+ break;
+ default:
+ state = STATE_ERROR;
+ break;
+ }
+ break;
+ case STATE_NAME:
+ if (ch == '=') {
+ idx = 0;
+ } else if (idx == MAX_LINE_BUFFER - 1) {
+ ErrPrint("Out of buffer\n");
+ } else if (idx == 0 && ch == '"') {
+ /* Ignore the first quotes */
+ } else if (idx >= 0) {
+ name_buffer[idx++] = ch;
+ }
+ break;
+ case STATE_HANDLER:
+ if (ch == '=') {
+ idx = 0;
+ } else if (idx == MAX_LINE_BUFFER - 1) {
+ ErrPrint("Out of buffer\n");
+ } else if (idx >= 0) {
+ handler_buffer[idx++] = ch;
+ }
+ break;
+ case STATE_ID:
+ case STATE_PHYSICAL:
+ case STATE_SYSFS:
+ case STATE_UNIQ:
+ case STATE_BITMAPS:
+ /* Ignore other attributes */
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (state == STATE_ERROR) {
+ ErrPrint("Invalid state: ROW[%d] COL[%d]\n", row, col);
+ }
+
+ if (close(fd) < 0) {
+ ErrPrint("close: %s\n", strerror(errno));
+ }
+
+ return node;
+}
+
+static void input_path_handler(char *buffer)
+{
+ if (buffer[0] == '/') {
+ DbgPrint("Specifying the input device\n");
+ s_conf.path.input = strdup(buffer);
+ if (!s_conf.path.input) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ } else {
+ DbgPrint("Find the input device\n");
+ s_conf.path.input = find_input_device(buffer);
+ if (s_conf.path.input == NULL) {
+ ErrPrint("Fallback to raw string\n");
+ s_conf.path.input = strdup(buffer);
+ if (!s_conf.path.input) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ }
+ }
+}
+
+static void ping_time_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &s_conf.ping_time) != 1) {
+ ErrPrint("Failed to parse the ping_time\n");
+ }
+ DbgPrint("Default ping time: %lf\n", s_conf.ping_time);
+}
+
+static void slave_max_loader(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.slave_max_load) != 1) {
+ ErrPrint("Failed to parse the slave_max_load\n");
+ }
+}
+
+static void premultiplied_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &s_conf.premultiplied) != 1) {
+ ErrPrint("Failed to parse the premultiplied color\n");
+ }
+
+ DbgPrint("Premultiplied: %d\n", s_conf.premultiplied);
+}
+
+static void gbar_request_timeout_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &s_conf.gbar_request_timeout) != 1) {
+ ErrPrint("Failed to parse the request_timeout\n");
+ }
+ DbgPrint("Default GBAR request timeout: %lf\n", s_conf.gbar_request_timeout);
+}
+
+EAPI void widget_conf_init(void)
+{
+ if (s_info.conf_loaded) {
+ DbgPrint("Already initialized.\n");
+ return;
+ }
+
+ s_conf.width = CONF_DEFAULT_WIDTH;
+ s_conf.height = CONF_DEFAULT_HEIGHT;
+ s_conf.base_width = CONF_DEFAULT_BASE_WIDTH;
+ s_conf.base_height = CONF_DEFAULT_BASE_HEIGHT;
+ s_conf.minimum_period = CONF_DEFAULT_MINIMUM_PERIOD;
+ s_conf.default_conf.period = CONF_DEFAULT_PERIOD;
+ s_conf.default_conf.pixels = CONF_DEFAULT_PIXELS;
+ s_conf.minimum_space = CONF_DEFAULT_MINIMUM_SPACE;
+ s_conf.default_packet_time = CONF_DEFAULT_PACKET_TIME;
+ s_conf.slave_ttl = CONF_DEFAULT_SLAVE_TTL;
+ s_conf.slave_activate_time = CONF_DEFAULT_SLAVE_ACTIVATE_TIME;
+ s_conf.slave_relaunch_time = CONF_DEFAULT_SLAVE_RELAUNCH_TIME;
+ s_conf.slave_relaunch_count = CONF_DEFAULT_SLAVE_RELAUNCH_COUNT;
+ s_conf.max_log_line = CONF_DEFAULT_MAX_LOG_LINE;
+ s_conf.max_log_file = CONF_DEFAULT_MAX_LOG_FILE;
+ s_conf.sqlite_flush_max = CONF_DEFAULT_SQLITE_FLUSH_MAX;
+ s_conf.ping_time = CONF_DEFAULT_PING_TIME;
+ s_conf.slave_max_load = CONF_DEFAULT_SLAVE_MAX_LOAD;
+ s_conf.use_sw_backend = CONF_DEFAULT_USE_SW_BACKEND;
+ s_conf.debug_mode = CONF_DEFAULT_DEBUG_MODE;
+ s_conf.overwrite_content = CONF_DEFAULT_OVERWRITE_CONTENT;
+ s_conf.com_core_thread = CONF_DEFAULT_COM_CORE_THREAD;
+ s_conf.use_xmonitor = CONF_DEFAULT_USE_XMONITOR;
+ s_conf.scale_width_factor = CONF_DEFAULT_SCALE_WIDTH_FACTOR;
+ s_conf.scale_height_factor = CONF_DEFAULT_SCALE_HEIGHT_FACTOR;
+ s_conf.gbar_request_timeout = CONF_DEFAULT_GBAR_REQUEST_TIMEOUT;
+ s_conf.premultiplied = CONF_DEFAULT_PREMULTIPLIED;
+ s_conf.default_conf.script = (char *)CONF_DEFAULT_SCRIPT_TYPE;
+ s_conf.default_conf.abi = (char *)CONF_DEFAULT_ABI;
+ s_conf.default_conf.gbar_group = (char *)CONF_DEFAULT_GBAR_GROUP;
+ s_conf.launch_key.name = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_NAME;
+ s_conf.launch_key.secured = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_SECURED;
+ s_conf.launch_key.abi = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_ABI;
+ s_conf.launch_key.hw_acceleration = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_HW_ACCELERATION;
+ s_conf.empty_content = (char *)CONF_DEFAULT_EMPTY_CONTENT;
+ s_conf.empty_title = (char *)CONF_DEFAULT_EMPTY_TITLE;
+ s_conf.default_content = (char *)CONF_DEFAULT_CONTENT;
+ s_conf.default_title = (char *)CONF_DEFAULT_TITLE;
+ s_conf.replace_tag = (char *)CONF_DEFAULT_REPLACE_TAG;
+ s_conf.path.conf = (char *)CONF_DEFAULT_PATH_CONF;
+ s_conf.path.image = (char *)CONF_DEFAULT_PATH_IMAGE;
+ s_conf.path.slave_log = (char *)CONF_DEFAULT_PATH_LOG;
+ s_conf.path.reader = (char *)CONF_DEFAULT_PATH_READER;
+ s_conf.path.always = (char *)CONF_DEFAULT_PATH_ALWAYS;
+ s_conf.path.script = (char *)CONF_DEFAULT_PATH_SCRIPT;
+ s_conf.path.root = (char *)CONF_DEFAULT_PATH_ROOT;
+ s_conf.path.script_port = (char *)CONF_DEFAULT_PATH_SCRIPT_PORT;
+ s_conf.path.db = (char *)CONF_DEFAULT_PATH_DB;
+ s_conf.path.input = (char *)CONF_DEFAULT_PATH_INPUT;
+ s_conf.provider_method = (char *)CONF_DEFAULT_PROVIDER_METHOD;
+ s_conf.emergency_disk = (char *)CONF_DEFAULT_EMERGENCY_DISK;
+ s_conf.services = (char *)CONF_DEFAULT_SERVICES;
+ s_conf.category_list = (char *)CONF_DEFAULT_CATEGORY_LIST;
+ s_conf.auto_align = CONF_DEFAULT_AUTO_ALIGN;
+ s_conf.use_event_time = CONF_DEFAULT_USE_EVENT_TIME;
+ s_conf.check_lcd = CONF_DEFAULT_CHECK_LCD;
+ s_conf.extra_buffer_count = CONF_DEFAULT_EXTRA_BUFFER_COUNT;
+ s_conf.use_gettimeofday = CONF_DEFAULT_USE_GETTIMEOFDAY;
+ s_conf.slave_event_boost_on = CONF_DEFAULT_SLAVE_EVENT_BOOST_ON;
+ s_conf.slave_event_boost_off = CONF_DEFAULT_SLAVE_EVENT_BOOST_OFF;
+ s_conf.event_filter = CONF_DEFAULT_EVENT_FILTER;
+ s_conf.slave_limit_to_ttl = CONF_DEFAULT_SLAVE_LIMIT_TO_TTL;
+ s_conf.slave_auto_cache_flush = CONF_DEFAULT_SLAVE_AUTO_CACHE_FLUSH;
+}
+
+/*
+ * Find proper configuration and install(link) it to conf path.
+ */
+static char *conf_path(void)
+{
+ char *path;
+ int length;
+
+ length = strlen(CONF_PATH_FORMAT) + 12; // 12 == RESERVED SPACE
+ path = calloc(1, length);
+ if (!path) {
+ ErrPrint("calloc: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ snprintf(path, length, CONF_PATH_FORMAT, s_conf.width, s_conf.height);
+ DbgPrint("Selected conf file: %s\n", path);
+ if (access(path, F_OK) != 0) {
+ ErrPrint("Fallback to default, access: %s\n", strerror(errno));
+ strncpy(path, DEFAULT_MASTER_CONF, length);
+ if (access(path, F_OK) != 0) {
+ ErrPrint("Serious error - there is no conf file, use default setting: %s\n", strerror(errno));
+ free(path);
+ path = NULL;
+ }
+ }
+
+ return path;
+}
+
+EAPI int widget_conf_load(void)
+{
+ char *conf_file;
+ FILE *fp;
+ int c;
+ enum state {
+ START,
+ SPACE,
+ TOKEN,
+ VALUE,
+ ERROR,
+ COMMENT,
+ END
+ } state;
+ int ch_idx;
+ int token_idx;
+ int buffer_idx;
+ int quote;
+ int linelen;
+ char buffer[256];
+ static const struct token_parser {
+ const char *name;
+ void (*handler)(char *buffer);
+ } token_handler[] = {
+ {
+ .name = "base_width",
+ .handler = base_width_handler,
+ },
+ {
+ .name = "base_height",
+ .handler = base_height_handler,
+ },
+ {
+ .name = "minimum_period",
+ .handler = minimum_period_handler,
+ },
+ {
+ .name = "script",
+ .handler = script_handler,
+ },
+ {
+ .name = "pixels",
+ .handler = pixels_handler,
+ },
+ {
+ .name = "default_abi",
+ .handler = default_abi_handler,
+ },
+ {
+ .name = "default_group",
+ .handler = default_group_handler,
+ },
+ {
+ .name = "default_period",
+ .handler = default_period_handler,
+ },
+ {
+ .name = "default_packet_time",
+ .handler = default_packet_time_handler,
+ },
+ {
+ .name = "default_content",
+ .handler = default_content_handler,
+ },
+ {
+ .name = "default_title",
+ .handler = default_title_handler,
+ },
+ {
+ .name = "minimum_space",
+ .handler = minimum_space_handler,
+ },
+ {
+ .name = "replace_tag",
+ .handler = replace_tag_handler,
+ },
+ {
+ .name = "slave_ttl",
+ .handler = slave_ttl_handler,
+ },
+ {
+ .name = "slave_activate_time",
+ .handler = slave_activate_time_handler,
+ },
+ {
+ .name = "slave_relaunch_time",
+ .handler = slave_relaunch_time_handler,
+ },
+ {
+ .name = "slave_relaunch_count",
+ .handler = slave_relaunch_count_handler,
+ },
+ {
+ .name = "max_log_line",
+ .handler = max_log_line_handler,
+ },
+ {
+ .name = "max_log_file",
+ .handler = max_log_file_handler,
+ },
+ {
+ .name = "sqilte_flush_max",
+ .handler = sqlite_flush_max_handler,
+ },
+ {
+ .name = "db_path",
+ .handler = db_path_handler,
+ },
+ {
+ .name = "log_path",
+ .handler = log_path_handler,
+ },
+ {
+ .name = "reader_path",
+ .handler = reader_path_handler,
+ },
+ {
+ .name = "always_path",
+ .handler = always_path_handler,
+ },
+ {
+ .name = "share_path",
+ .handler = share_path_handler,
+ },
+ {
+ .name = "script_port_path",
+ .handler = script_port_path_handler,
+ },
+ {
+ .name = "ping_interval",
+ .handler = ping_time_handler,
+ },
+ {
+ .name = "slave_max_load",
+ .handler = slave_max_loader,
+ },
+ {
+ .name = "use_sw_backend",
+ .handler = use_sw_backend_handler,
+ },
+ {
+ .name = "emergency_disk",
+ .handler = emergency_disk_handler,
+ },
+ {
+ .name = "services",
+ .handler = services_handler,
+ },
+ {
+ .name = "auto_align",
+ .handler = auto_align_handler,
+ },
+ {
+ .name = "use_event_time",
+ .handler = use_event_time_handler,
+ },
+ {
+ .name = "use_gettimeofday",
+ .handler = use_gettimeofday_handler,
+ },
+ {
+ .name = "check_lcd",
+ .handler = check_lcd_handler,
+ },
+ {
+ .name = "use_xmonitor",
+ .handler = use_xmonitor,
+ },
+ {
+ .name = "provider_method",
+ .handler = provider_method_handler,
+ },
+ {
+ .name = "debug_mode",
+ .handler = debug_mode_handler,
+ },
+ {
+ .name = "overwrite_content",
+ .handler = overwrite_content_handler,
+ },
+ {
+ .name = "com_core_thread",
+ .handler = com_core_thread_handler,
+ },
+ {
+ .name = "input",
+ .handler = input_path_handler,
+ },
+ {
+ .name = "gbar_request_timeout",
+ .handler = gbar_request_timeout_handler,
+ },
+ {
+ .name = "premultiplied",
+ .handler = premultiplied_handler,
+ },
+ {
+ .name = "extra_buffer_count",
+ .handler = extra_buffer_count_handler,
+ },
+ {
+ .name = "slave_event_boost_on",
+ .handler = slave_event_boost_on_handler,
+ },
+ {
+ .name = "slave_event_boost_off",
+ .handler = slave_event_boost_off_handler,
+ },
+ {
+ .name = "event_filter",
+ .handler = event_filter_handler,
+ },
+ {
+ .name = "slave_limit_to_ttl",
+ .handler = slave_limit_to_ttl_handler,
+ },
+ {
+ .name = "frame_skip",
+ .handler = frame_skip_handler,
+ },
+ {
+ .name = "slave_auto_cache_flush",
+ .handler = slave_auto_cache_flush_handler,
+ },
+ {
+ .name = "category_list",
+ .handler = category_list_handler,
+ },
+ {
+ .name = NULL,
+ .handler = NULL,
+ },
+ };
+
+ if (s_info.conf_loaded) {
+ ErrPrint("Already loaded\n");
+ return WIDGET_STATUS_ERROR_ALREADY;
+ }
+
+ util_screen_size_get(&s_conf.width, &s_conf.height);
+
+ conf_file = conf_path();
+ if (!conf_file) {
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ fp = fopen(conf_file, "rt");
+ free(conf_file);
+ if (!fp) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ state = START;
+ ch_idx = 0;
+ token_idx = -1;
+ buffer_idx = 0;
+ quote = 0;
+ linelen = 0;
+ do {
+ c = getc(fp);
+ if ((c == EOF) && (state == VALUE)) {
+ DbgPrint("[%s:%d] VALUE state EOF\n", __func__, __LINE__);
+ state = END;
+ }
+
+ switch (state) {
+ case COMMENT:
+ if (c == CR || c == LF || c == EOF) {
+ buffer[buffer_idx] = '\0';
+
+ state = START;
+ token_idx = -1;
+ ch_idx = 0;
+ buffer_idx = 0;
+ linelen = -1; /* Will be ZERO by follwing increment code */
+ quote = 0;
+ } else {
+ buffer[buffer_idx++] = c;
+ if (buffer_idx == (sizeof(buffer) - 1)) {
+ buffer[buffer_idx] = '\0';
+ buffer_idx = 0;
+ }
+ }
+ break;
+ case START:
+ if (linelen == 0 && c == '#') {
+ state = COMMENT;
+ } else if (isspace(c)) {
+ /* Ignore empty space */
+ } else {
+ state = TOKEN;
+ ungetc(c, fp);
+ }
+ break;
+ case SPACE:
+ if (c == '=') {
+ state = VALUE;
+ } else if (!isspace(c)) {
+ state = ERROR;
+ }
+ break;
+ case VALUE:
+ if (c == '"') {
+ if (quote == 1) {
+ buffer[buffer_idx] = '\0';
+ state = END;
+ } else if (buffer_idx != 0) {
+ buffer[buffer_idx++] = c;
+ if (buffer_idx >= sizeof(buffer)) {
+ state = ERROR;
+ }
+ } else {
+ quote = 1;
+ }
+ } else if (isspace(c)) {
+ if (buffer_idx == 0) {
+ /* Ignore */
+ } else if (quote == 1) {
+ buffer[buffer_idx++] = c;
+ if (buffer_idx >= sizeof(buffer)) {
+ state = ERROR;
+ }
+ } else {
+ buffer[buffer_idx] = '\0';
+ ungetc(c, fp);
+ state = END;
+ }
+ } else {
+ buffer[buffer_idx++] = c;
+ if (buffer_idx >= sizeof(buffer)) {
+ state = ERROR;
+ }
+ }
+ break;
+ case TOKEN:
+ if (c == '=') {
+ if (token_idx < 0) {
+ state = ERROR;
+ } else {
+ state = VALUE;
+ }
+ } else if (isspace(c)) {
+ if (token_idx < 0) {
+ break;
+ }
+
+ if (token_handler[token_idx].name[ch_idx] != '\0') {
+ state = ERROR;
+ } else {
+ state = SPACE;
+ }
+ } else {
+ if (token_idx < 0) {
+ /* Now start to find a token! */
+ token_idx = 0;
+ }
+
+ if (token_handler[token_idx].name[ch_idx] == c) {
+ ch_idx++;
+ } else {
+ ungetc(c, fp);
+ while (ch_idx-- > 0)
+ ungetc(token_handler[token_idx].name[ch_idx], fp);
+
+ token_idx++;
+
+ if (token_handler[token_idx].name == NULL) {
+ state = ERROR;
+ } else {
+ ch_idx = 0;
+ }
+ }
+ }
+ break;
+ case ERROR:
+ if (c == CR || c == LF || c == EOF) {
+ state = START;
+ token_idx = -1;
+ buffer_idx = 0;
+ ch_idx = 0;
+ linelen = -1;
+ quote = 0;
+ }
+ break;
+ case END:
+ if (c == LF || c == CR || c == EOF) {
+ state = START;
+
+ if (token_idx >= 0 && token_handler[token_idx].handler) {
+ buffer[buffer_idx] = '\0';
+ token_handler[token_idx].handler(buffer);
+ }
+
+ token_idx = -1;
+ ch_idx = 0;
+ buffer_idx = 0;
+ linelen = -1;
+ quote = 0;
+ /* Finish */
+ } else if (isspace(c)) {
+ /* ignore */
+ } else {
+ state = ERROR;
+ }
+ break;
+ default:
+ /* ?? */
+ break;
+ }
+
+ linelen++;
+ } while (c != EOF);
+
+ if (fclose(fp) != 0) {
+ ErrPrint("fclose: %s\n", strerror(errno));
+ }
+
+ s_conf.scale_width_factor = (double)s_conf.width / (double)WIDGET_CONF_BASE_W;
+ s_conf.scale_height_factor = (double)s_conf.height / (double)WIDGET_CONF_BASE_H;
+ s_info.conf_loaded = 1;
+
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+EAPI void widget_conf_reset(void)
+{
+ s_conf.width = CONF_DEFAULT_WIDTH;
+ s_conf.height = CONF_DEFAULT_HEIGHT;
+ s_conf.base_width = CONF_DEFAULT_BASE_WIDTH;
+ s_conf.base_height = CONF_DEFAULT_BASE_HEIGHT;
+ s_conf.minimum_period = CONF_DEFAULT_MINIMUM_PERIOD;
+ s_conf.default_conf.period = CONF_DEFAULT_PERIOD;
+ s_conf.minimum_space = CONF_DEFAULT_MINIMUM_SPACE;
+ s_conf.default_packet_time = CONF_DEFAULT_PACKET_TIME;
+ s_conf.slave_ttl = CONF_DEFAULT_SLAVE_TTL;
+ s_conf.slave_activate_time = CONF_DEFAULT_SLAVE_ACTIVATE_TIME;
+ s_conf.slave_relaunch_time = CONF_DEFAULT_SLAVE_RELAUNCH_TIME;
+ s_conf.slave_relaunch_count = CONF_DEFAULT_SLAVE_RELAUNCH_COUNT;
+ s_conf.max_log_line = CONF_DEFAULT_MAX_LOG_LINE;
+ s_conf.max_log_file = CONF_DEFAULT_MAX_LOG_FILE;
+ s_conf.sqlite_flush_max = CONF_DEFAULT_SQLITE_FLUSH_MAX;
+ s_conf.ping_time = CONF_DEFAULT_PING_TIME;
+ s_conf.slave_max_load = CONF_DEFAULT_SLAVE_MAX_LOAD;
+ s_conf.use_sw_backend = CONF_DEFAULT_USE_SW_BACKEND;
+ s_conf.debug_mode = CONF_DEFAULT_DEBUG_MODE;
+ s_conf.overwrite_content = CONF_DEFAULT_OVERWRITE_CONTENT;
+ s_conf.com_core_thread = CONF_DEFAULT_COM_CORE_THREAD;
+ s_conf.use_xmonitor = CONF_DEFAULT_USE_XMONITOR;
+ s_conf.scale_width_factor = CONF_DEFAULT_SCALE_WIDTH_FACTOR;
+ s_conf.scale_height_factor = CONF_DEFAULT_SCALE_HEIGHT_FACTOR;
+ s_conf.gbar_request_timeout = CONF_DEFAULT_GBAR_REQUEST_TIMEOUT;
+ s_conf.premultiplied = CONF_DEFAULT_PREMULTIPLIED;
+ s_conf.default_conf.pixels = CONF_DEFAULT_PIXELS;
+ s_conf.auto_align = CONF_DEFAULT_AUTO_ALIGN;
+ s_conf.use_event_time = CONF_DEFAULT_USE_EVENT_TIME;
+ s_conf.check_lcd = CONF_DEFAULT_CHECK_LCD;
+ s_conf.extra_buffer_count = CONF_DEFAULT_EXTRA_BUFFER_COUNT;
+ s_conf.use_gettimeofday = CONF_DEFAULT_USE_GETTIMEOFDAY;
+ s_conf.slave_event_boost_on = CONF_DEFAULT_SLAVE_EVENT_BOOST_ON;
+ s_conf.slave_event_boost_off = CONF_DEFAULT_SLAVE_EVENT_BOOST_OFF;
+ s_conf.event_filter = CONF_DEFAULT_EVENT_FILTER;
+ s_conf.slave_limit_to_ttl = CONF_DEFAULT_SLAVE_LIMIT_TO_TTL;
+ s_conf.slave_auto_cache_flush = CONF_DEFAULT_SLAVE_AUTO_CACHE_FLUSH;
+
+ if (s_conf.category_list != CONF_DEFAULT_CATEGORY_LIST) {
+ free(s_conf.category_list);
+ s_conf.category_list = (char *)CONF_DEFAULT_CATEGORY_LIST;
+ }
+
+ if (s_conf.default_conf.script != CONF_DEFAULT_SCRIPT_TYPE) {
+ free(s_conf.default_conf.script);
+ s_conf.default_conf.script = (char *)CONF_DEFAULT_SCRIPT_TYPE;
+ }
+
+ if (s_conf.default_conf.abi != CONF_DEFAULT_ABI) {
+ free(s_conf.default_conf.abi);
+ s_conf.default_conf.abi = (char *)CONF_DEFAULT_ABI;
+ }
+
+ if (s_conf.default_conf.gbar_group != CONF_DEFAULT_GBAR_GROUP) {
+ free(s_conf.default_conf.gbar_group);
+ s_conf.default_conf.gbar_group = (char *)CONF_DEFAULT_GBAR_GROUP;
+ }
+
+ if (s_conf.launch_key.name != CONF_DEFAULT_LAUNCH_BUNDLE_NAME) {
+ free(s_conf.launch_key.name);
+ s_conf.launch_key.name = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_NAME;
+ }
+
+ if (s_conf.launch_key.secured != CONF_DEFAULT_LAUNCH_BUNDLE_SECURED) {
+ free(s_conf.launch_key.secured);
+ s_conf.launch_key.secured = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_SECURED;
+ }
+
+ if (s_conf.launch_key.abi != CONF_DEFAULT_LAUNCH_BUNDLE_ABI) {
+ free(s_conf.launch_key.abi);
+ s_conf.launch_key.abi = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_ABI;
+ }
+
+ if (s_conf.launch_key.hw_acceleration != CONF_DEFAULT_LAUNCH_BUNDLE_HW_ACCELERATION) {
+ free(s_conf.launch_key.hw_acceleration);
+ s_conf.launch_key.hw_acceleration = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_HW_ACCELERATION;
+ }
+
+ if (s_conf.empty_content != CONF_DEFAULT_EMPTY_CONTENT) {
+ free(s_conf.empty_content);
+ s_conf.empty_content = (char *)CONF_DEFAULT_EMPTY_CONTENT;
+ }
+
+ if (s_conf.empty_title != CONF_DEFAULT_EMPTY_TITLE) {
+ free(s_conf.empty_title);
+ s_conf.empty_title = (char *)CONF_DEFAULT_EMPTY_TITLE;
+ }
+
+ if (s_conf.default_content != CONF_DEFAULT_CONTENT) {
+ free(s_conf.default_content);
+ s_conf.default_content = (char *)CONF_DEFAULT_CONTENT;
+ }
+
+ if (s_conf.default_title != CONF_DEFAULT_TITLE) {
+ free(s_conf.default_title);
+ s_conf.default_title = (char *)CONF_DEFAULT_TITLE;
+ }
+
+ if (s_conf.replace_tag != CONF_DEFAULT_REPLACE_TAG) {
+ free(s_conf.replace_tag);
+ s_conf.replace_tag = (char *)CONF_DEFAULT_REPLACE_TAG;
+ }
+
+ if (s_conf.path.conf != CONF_DEFAULT_PATH_CONF) {
+ free(s_conf.path.conf);
+ s_conf.path.conf = (char *)CONF_DEFAULT_PATH_CONF;
+ }
+
+ if (s_conf.path.image != CONF_DEFAULT_PATH_IMAGE) {
+ free(s_conf.path.image);
+ s_conf.path.image = (char *)CONF_DEFAULT_PATH_IMAGE;
+ }
+
+ if (s_conf.path.slave_log != CONF_DEFAULT_PATH_LOG) {
+ free(s_conf.path.slave_log);
+ s_conf.path.slave_log = (char *)CONF_DEFAULT_PATH_LOG;
+ }
+
+ if (s_conf.path.reader != CONF_DEFAULT_PATH_READER) {
+ free(s_conf.path.reader);
+ s_conf.path.reader = (char *)CONF_DEFAULT_PATH_READER;
+ }
+
+ if (s_conf.path.always != CONF_DEFAULT_PATH_ALWAYS) {
+ free(s_conf.path.always);
+ s_conf.path.always = (char *)CONF_DEFAULT_PATH_ALWAYS;
+ }
+
+ if (s_conf.path.script != CONF_DEFAULT_PATH_SCRIPT) {
+ free(s_conf.path.script);
+ s_conf.path.script = (char *)CONF_DEFAULT_PATH_SCRIPT;
+ }
+
+ if (s_conf.path.root != CONF_DEFAULT_PATH_ROOT) {
+ free(s_conf.path.root);
+ s_conf.path.root = (char *)CONF_DEFAULT_PATH_ROOT;
+ }
+
+ if (s_conf.path.script_port != CONF_DEFAULT_PATH_SCRIPT_PORT) {
+ free(s_conf.path.script_port);
+ s_conf.path.script_port = (char *)CONF_DEFAULT_PATH_SCRIPT_PORT;
+ }
+
+ if (s_conf.path.db != CONF_DEFAULT_PATH_DB) {
+ free(s_conf.path.db);
+ s_conf.path.db = (char *)CONF_DEFAULT_PATH_DB;
+ }
+
+ if (s_conf.path.input != CONF_DEFAULT_PATH_INPUT) {
+ free(s_conf.path.input);
+ s_conf.path.input = (char *)CONF_DEFAULT_PATH_INPUT;
+ }
+
+ if (s_conf.provider_method != CONF_DEFAULT_PROVIDER_METHOD) {
+ free(s_conf.provider_method);
+ s_conf.provider_method = (char *)CONF_DEFAULT_PROVIDER_METHOD;
+ }
+
+ if (s_conf.emergency_disk != CONF_DEFAULT_EMERGENCY_DISK) {
+ free(s_conf.emergency_disk);
+ s_conf.emergency_disk = (char *)CONF_DEFAULT_EMERGENCY_DISK;
+ }
+
+ if (s_conf.services != CONF_DEFAULT_SERVICES) {
+ free(s_conf.services);
+ s_conf.services = (char *)CONF_DEFAULT_SERVICES;
+ }
+
+ s_info.conf_loaded = 0;
+}
+
+EAPI const int const widget_conf_extra_buffer_count(void)
+{
+ return s_conf.extra_buffer_count;
+}
+
+EAPI const int const widget_conf_use_xmonitor(void)
+{
+ return s_conf.use_xmonitor;
+}
+
+EAPI const char * const widget_conf_emergency_disk(void)
+{
+ return s_conf.emergency_disk;
+}
+
+EAPI const int const widget_conf_check_lcd(void)
+{
+ return s_conf.check_lcd;
+}
+
+EAPI const int const widget_conf_use_event_time(void)
+{
+ return s_conf.use_event_time;
+}
+
+EAPI const int const widget_conf_auto_align(void)
+{
+ return s_conf.auto_align;
+}
+
+EAPI const char * const widget_conf_services(void)
+{
+ return s_conf.services;
+}
+
+EAPI const int const widget_conf_use_sw_backend(void)
+{
+ return s_conf.use_sw_backend;
+}
+
+EAPI const char * const widget_conf_provider_method(void)
+{
+ return s_conf.provider_method;
+}
+
+EAPI const int const widget_conf_debug_mode(void)
+{
+ return s_conf.debug_mode;
+}
+
+EAPI const int const widget_conf_overwrite_content(void)
+{
+ return s_conf.overwrite_content;
+}
+
+EAPI const int const widget_conf_com_core_thread(void)
+{
+ return s_conf.com_core_thread;
+}
+
+EAPI const unsigned int const widget_conf_base_width(void)
+{
+ return s_conf.base_width;
+}
+
+EAPI const unsigned int const widget_conf_base_height(void)
+{
+ return s_conf.base_height;
+}
+
+EAPI const double const widget_conf_minimum_period(void)
+{
+ return s_conf.minimum_period;
+}
+
+EAPI const int const widget_conf_default_pixels(void)
+{
+ return s_conf.default_conf.pixels;
+}
+
+EAPI const char * const widget_conf_default_script(void)
+{
+ return s_conf.default_conf.script;
+}
+
+EAPI const char * const widget_conf_default_abi(void)
+{
+ return s_conf.default_conf.abi;
+}
+
+EAPI const char * const widget_conf_default_gbar_group(void)
+{
+ return s_conf.default_conf.gbar_group;
+}
+
+EAPI const double const widget_conf_default_period(void)
+{
+ return s_conf.default_conf.period;
+}
+
+EAPI const double const widget_conf_default_packet_time(void)
+{
+ return s_conf.default_packet_time;
+}
+
+EAPI const char * const widget_conf_default_content(void)
+{
+ return s_conf.default_content;
+}
+
+EAPI const char * const widget_conf_default_title(void)
+{
+ return s_conf.default_title;
+}
+
+EAPI const unsigned long const widget_conf_minimum_space(void)
+{
+ return s_conf.minimum_space;
+}
+
+EAPI const char * const widget_conf_replace_tag(void)
+{
+ return s_conf.replace_tag;
+}
+
+EAPI const double const widget_conf_slave_ttl(void)
+{
+ return s_conf.slave_ttl;
+}
+
+EAPI const double const widget_conf_slave_activate_time(void)
+{
+ return s_conf.slave_activate_time;
+}
+
+EAPI const double const widget_conf_slave_relaunch_time(void)
+{
+ return s_conf.slave_relaunch_time;
+}
+
+EAPI const int const widget_conf_slave_relaunch_count(void)
+{
+ return s_conf.slave_relaunch_count;
+}
+
+EAPI const int const widget_conf_max_log_line(void)
+{
+ return s_conf.max_log_line;
+}
+
+EAPI const int const widget_conf_max_log_file(void)
+{
+ return s_conf.max_log_file;
+}
+
+EAPI const unsigned long const widget_conf_sqlite_flush_max(void)
+{
+ return s_conf.sqlite_flush_max;
+}
+
+EAPI const char * const widget_conf_db_path(void)
+{
+ return s_conf.path.db;
+}
+
+EAPI const char * const widget_conf_reader_path(void)
+{
+ return s_conf.path.reader;
+}
+
+EAPI const char * const widget_conf_always_path(void)
+{
+ return s_conf.path.always;
+}
+
+EAPI const char * const widget_conf_log_path(void)
+{
+ return s_conf.path.slave_log;
+}
+
+EAPI const char * const widget_conf_script_port(void)
+{
+ return s_conf.path.script_port;
+}
+
+EAPI const char * const widget_conf_script_path(void)
+{
+ return s_conf.path.script;
+}
+
+EAPI const char * const widget_conf_share_path(void)
+{
+ return s_conf.path.image;
+}
+
+EAPI const char * const widget_conf_input_path(void)
+{
+ return s_conf.path.input;
+}
+
+EAPI const double const widget_conf_ping_time(void)
+{
+ return s_conf.ping_time;
+}
+
+EAPI const int const widget_conf_slave_max_load(void)
+{
+ return s_conf.slave_max_load;
+}
+
+EAPI const int const widget_conf_premultiplied_alpha(void)
+{
+ return s_conf.premultiplied;
+}
+
+EAPI const double const widget_conf_gbar_request_timeout(void)
+{
+ return s_conf.gbar_request_timeout;
+}
+
+EAPI const double const widget_conf_scale_width_factor(void)
+{
+ return s_conf.scale_width_factor;
+}
+
+EAPI const double const widget_conf_scale_height_factor(void)
+{
+ return s_conf.scale_height_factor;
+}
+
+EAPI const char * const widget_conf_launch_key_name(void)
+{
+ return s_conf.launch_key.name;
+}
+
+EAPI const char * const widget_conf_launch_key_secured(void)
+{
+ return s_conf.launch_key.secured;
+}
+
+EAPI const char * const widget_conf_launch_key_abi(void)
+{
+ return s_conf.launch_key.abi;
+}
+
+EAPI const char * const widget_conf_launch_key_hw_acceleration(void)
+{
+ return s_conf.launch_key.hw_acceleration;
+}
+
+EAPI const char * const widget_conf_empty_content(void)
+{
+ return s_conf.empty_content;
+}
+
+EAPI const char * const widget_conf_empty_title(void)
+{
+ return s_conf.empty_title;
+}
+
+EAPI const char * const widget_conf_path(void)
+{
+ return s_conf.path.conf;
+}
+
+EAPI const char * const widget_conf_root_path(void)
+{
+ return s_conf.path.root;
+}
+
+EAPI const int const widget_conf_is_loaded(void)
+{
+ return s_info.conf_loaded;
+}
+
+EAPI const int const widget_conf_use_gettimeofday(void)
+{
+ return s_conf.use_gettimeofday;
+}
+
+EAPI const int const widget_conf_slave_event_boost_on(void)
+{
+ return s_conf.slave_event_boost_on;
+}
+
+EAPI const int const widget_conf_slave_event_boost_off(void)
+{
+ return s_conf.slave_event_boost_off;
+}
+
+EAPI const double const widget_conf_event_filter(void)
+{
+ return s_conf.event_filter;
+}
+
+EAPI const int const widget_conf_slave_limit_to_ttl(void)
+{
+ return s_conf.slave_limit_to_ttl;
+}
+
+EAPI const int const widget_conf_frame_skip(void)
+{
+ return s_conf.frame_skip;
+}
+
+EAPI const int const widget_conf_slave_auto_cache_flush(void)
+{
+ return s_conf.slave_auto_cache_flush;
+}
+
+EAPI const char * const widget_conf_category_list(void)
+{
+ return s_conf.category_list;
+}
+
+/* End of a file */
diff --git a/src/widget_service.c b/src/widget_service.c
new file mode 100755
index 0000000..a885164
--- /dev/null
+++ b/src/widget_service.c
@@ -0,0 +1,3230 @@
+/*
+ * 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 <errno.h>
+#include <stdlib.h> /* malloc */
+#include <string.h> /* strdup, strerror */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sqlite3.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+#include <com-core_packet.h>
+#include <packet.h>
+#include <dlog.h>
+#include <db-util.h>
+#include <package-manager.h>
+#include <pkgmgr-info.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <ail.h>
+#include <unicode/uloc.h>
+
+#include "widget_errno.h"
+#include "dlist.h"
+#include "util.h"
+#include "debug.h"
+#include "widget_service.h"
+#include "widget_cmd_list.h"
+#include "widget_buffer.h"
+
+#define WIDGET_ID_PREFIX "org.tizen."
+#define DEFAULT_TIMEOUT 2.0
+
+/* "/shared/res/" */
+#define RESOURCE_PATH "/"
+
+/* "/shared/libexec/" */
+#define LIBEXEC_PATH "/"
+
+static struct supported_size_list SIZE_LIST[WIDGET_NR_OF_SIZE_LIST] = {
+ { 175, 175 }, /*!< 1x1 */
+ { 354, 175 }, /*!< 2x1 */
+ { 354, 354 }, /*!< 2x2 */
+ { 712, 175 }, /*!< 4x1 */
+ { 712, 354 }, /*!< 4x2 */
+ { 712, 533 }, /*!< 4x3 */
+ { 712, 712 }, /*!< 4x4 */
+ { 712, 891 }, /*!< 4x5 */
+ { 712, 1070 }, /*!< 4x6 */
+ { 224, 215 }, /*!< 21x21 */
+ { 680, 215 }, /*!< 23x21 */
+ { 680, 653 }, /*!< 23x23 */
+ { 720, 1280 }, /*!< 0x0 */
+};
+
+struct widget_pkglist_handle {
+ enum pkglist_type {
+ PKGLIST_TYPE_WIDGET_LIST = 0x00beef00,
+ PKGLIST_TYPE_UNKNOWN = 0x00dead00
+ } type;
+ sqlite3 *handle;
+ sqlite3_stmt *stmt;
+};
+
+static struct service_info s_info = {
+ .handle = NULL,
+ .dbfile = DB_FILE,
+ .conf_file = NULL,
+ .init_count = 0,
+
+ .iso3lang = NULL,
+ .country = { 0, },
+ .syslang = NULL,
+ .country_len = 0,
+
+ .base_w = 720,
+ .base_h = 1280,
+
+ .base_parse = 0,
+
+ .last_status = WIDGET_STATUS_ERROR_NONE,
+};
+
+struct pkgmgr_cbdata {
+ const char *widgetid;
+ void (*cb)(const char *widgetid, const char *appid, void *data);
+ void *cbdata;
+};
+
+static sqlite3 *open_db(void)
+{
+ sqlite3 *handle;
+
+ if (!s_info.handle) {
+ int ret;
+
+ ret = db_util_open_with_options(s_info.dbfile, &handle, SQLITE_OPEN_READONLY, NULL);
+ if (ret != SQLITE_OK) {
+ switch (ret) {
+ case SQLITE_PERM:
+ widget_set_last_status(WIDGET_STATUS_ERROR_PERMISSION_DENIED);
+ break;
+ default:
+ widget_set_last_status(WIDGET_STATUS_ERROR_IO_ERROR);
+ break;
+ }
+
+ ErrPrint("Failed to open a DB\n");
+ return NULL;
+ }
+ } else {
+ handle = s_info.handle;
+ }
+
+ return handle;
+}
+
+static inline __attribute__((always_inline)) void close_db(sqlite3 *handle)
+{
+ if (!s_info.handle) {
+ db_util_close(handle);
+ }
+}
+
+static int convert_size_from_type(widget_size_type_e type, int *width, int *height)
+{
+ int idx;
+
+ switch (type) {
+ case WIDGET_SIZE_TYPE_1x1: /*!< 175x175 */
+ idx = 0;
+ break;
+ case WIDGET_SIZE_TYPE_2x1: /*!< 354x175 */
+ idx = 1;
+ break;
+ case WIDGET_SIZE_TYPE_2x2: /*!< 354x354 */
+ idx = 2;
+ break;
+ case WIDGET_SIZE_TYPE_4x1: /*!< 712x175 */
+ idx = 3;
+ break;
+ case WIDGET_SIZE_TYPE_4x2: /*!< 712x354 */
+ idx = 4;
+ break;
+ case WIDGET_SIZE_TYPE_4x3: /*!< 712x533 */
+ idx = 5;
+ break;
+ case WIDGET_SIZE_TYPE_4x4: /*!< 712x712 */
+ idx = 6;
+ break;
+ case WIDGET_SIZE_TYPE_4x5: /*!< 712x891 */
+ idx = 7;
+ break;
+ case WIDGET_SIZE_TYPE_4x6: /*!< 712x1070 */
+ idx = 8;
+ break;
+ case WIDGET_SIZE_TYPE_EASY_1x1: /*< 224x215 */
+ idx = 9;
+ break;
+ case WIDGET_SIZE_TYPE_EASY_3x1: /*!< 680x215 */
+ idx = 10;
+ break;
+ case WIDGET_SIZE_TYPE_EASY_3x3: /*!< 680x653 */
+ idx = 11;
+ break;
+ case WIDGET_SIZE_TYPE_0x0: /*!< 720x1280 */
+ idx = 12;
+ break;
+ default:
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (util_update_resolution(&s_info, SIZE_LIST) < 0) {
+ ErrPrint("Failed to update resolution\n");
+ }
+
+ *width = SIZE_LIST[idx].w;
+ *height = SIZE_LIST[idx].h;
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+static int pkgmgr_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
+{
+ struct pkgmgr_cbdata *cbdata = (struct pkgmgr_cbdata *)user_data;
+ char *appid;
+ int ret;
+
+ ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+ if (ret < 0) {
+ ErrPrint("Unable to get appid\n");
+ } else {
+ cbdata->cb(cbdata->widgetid, appid, cbdata->cbdata);
+ }
+
+ return 0;
+}
+
+static inline char *pkgmgr_get_mainapp(const char *pkgid)
+{
+ pkgmgrinfo_pkginfo_h handle;
+ char *ret = NULL;
+
+ if (pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle) != PMINFO_R_OK) {
+ ErrPrint("Unable to get mainapp: %s\n", pkgid);
+ return NULL;
+ }
+
+ if (pkgmgrinfo_pkginfo_get_mainappid(handle, &ret) == PMINFO_R_OK) {
+ ret = strdup(ret);
+ } else {
+ ErrPrint("Failed to get mainappid\n");
+ ret = NULL; /* I cannot believe the pkgmgrinfo_pkginfo_get_mainappid. it maybe able to touch my "ret" even though it fails */
+
+ }
+
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return ret;
+}
+
+static inline int pkgmgr_get_applist(const char *pkgid, const char *widgetid, void (*cb)(const char *widgetid, const char *appid, void *data), void *data)
+{
+ struct pkgmgr_cbdata cbdata;
+ pkgmgrinfo_pkginfo_h handle;
+ int ret;
+
+ ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
+ if (ret < 0) {
+ ErrPrint("Unable to get pkginfo: %s\n", pkgid);
+ return ret;
+ }
+
+ cbdata.widgetid = widgetid;
+ cbdata.cb = cb;
+ cbdata.cbdata = data;
+
+ ret = pkgmgrinfo_appinfo_get_list(handle, PM_UI_APP, pkgmgr_cb, &cbdata);
+ if (ret < 0) {
+ ErrPrint("Failed to get applist\n");
+ }
+
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return ret;
+}
+
+static char *cur_locale(void)
+{
+ char *language;
+ language = vconf_get_str(VCONFKEY_LANGSET);
+ if (language) {
+ char *ptr;
+
+ ptr = language;
+ while (*ptr) {
+ if (*ptr == '.') {
+ *ptr = '\0';
+ break;
+ }
+
+ if (*ptr == '_') {
+ *ptr = '-';
+ }
+
+ ptr++;
+ }
+ } else {
+ language = strdup("en-us");
+ if (!language) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ }
+
+ return language;
+}
+
+static char *get_default_name(const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ char *name = NULL;
+ int ret;
+
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT name FROM client WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ close_db(handle);
+ return NULL;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ const char *tmp;
+
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (tmp && strlen(tmp)) {
+ name = strdup(tmp);
+ if (!name) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ }
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return name;
+}
+
+static char *get_default_icon(const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ char *icon = NULL;
+ int ret;
+
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT icon FROM client WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ close_db(handle);
+ return NULL;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ const char *tmp;
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (tmp && strlen(tmp)) {
+ icon = strdup(tmp);
+ if (!icon) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ }
+ } else if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return icon;
+}
+
+static char *get_widget_pkgname_by_appid(const char *appid)
+{
+ sqlite3_stmt *stmt;
+ char *pkgid;
+ char *tmp;
+ sqlite3 *handle;
+ int ret;
+
+ if (!appid) {
+ return NULL;
+ }
+
+ pkgid = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT pkgid FROM pkgmap WHERE (appid = ? AND prime = 1) OR (uiapp = ? AND prime = 1) OR pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ close_db(handle);
+ return NULL;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, appid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 3, appid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ goto out;
+ }
+
+ if (sqlite3_step(stmt) != SQLITE_ROW) {
+ ErrPrint("Error: %s (has no record? - %s)\n", sqlite3_errmsg(handle), appid);
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ goto out;
+ }
+
+ tmp = (char *)sqlite3_column_text(stmt, 0);
+ if (tmp && strlen(tmp)) {
+ pkgid = strdup(tmp);
+ if (!pkgid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ }
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return pkgid;
+}
+
+static inline int update_lang_info(void)
+{
+ char *syslang;
+ UErrorCode err;
+
+ syslang = vconf_get_str(VCONFKEY_LANGSET);
+ if (!syslang) {
+ ErrPrint("Failed to get vconf-lang\n");
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ return -EFAULT;
+ }
+
+ if (s_info.syslang && !strcmp(s_info.syslang, syslang)) {
+ DbgPrint("Syslang is not changed: %s\n", syslang);
+ free(syslang);
+ return 0;
+ }
+
+ free(s_info.syslang);
+ s_info.syslang = syslang;
+
+ err = U_ZERO_ERROR;
+ uloc_setDefault((const char *)s_info.syslang, &err);
+ if (!U_SUCCESS(err)) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Failed to set default lang: %s\n", u_errorName(err));
+ free(s_info.syslang);
+ s_info.syslang = NULL;
+ return -EFAULT;
+ }
+
+ s_info.iso3lang = uloc_getISO3Language(uloc_getDefault());
+ if (!s_info.iso3lang || !strlen(s_info.iso3lang)) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Failed to get iso3lang\n");
+ free(s_info.syslang);
+ s_info.syslang = NULL;
+ return -EFAULT;
+ }
+
+ err = U_ZERO_ERROR;
+ s_info.country_len = uloc_getCountry(uloc_getDefault(), s_info.country, ULOC_COUNTRY_CAPACITY, &err);
+ if (!U_SUCCESS(err) || s_info.country_len <= 0) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Failed to get locale: %s, %s, %d (%s)\n", u_errorName(err), s_info.iso3lang, s_info.country_len, s_info.country);
+ free(s_info.syslang);
+ s_info.syslang = NULL;
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+EAPI int widget_service_change_period(const char *pkgname, const char *id, double period)
+{
+ struct packet *packet;
+ struct packet *result;
+ unsigned int cmd = CMD_SERVICE_CHANGE_PERIOD;
+ char *uri;
+ int ret;
+
+ if (!pkgname || !id || period < 0.0f) {
+ ErrPrint("Invalid argument\n");
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ uri = util_id_to_uri(id);
+ if (!uri) {
+ return WIDGET_STATUS_ERROR_OUT_OF_MEMORY;
+ }
+
+ packet = packet_create((const char *)&cmd, "ssd", pkgname, uri, period);
+ free(uri);
+ if (!packet) {
+ ErrPrint("Failed to create a packet for period changing\n");
+ return WIDGET_STATUS_ERROR_FAULT;
+ }
+
+ result = com_core_packet_oneshot_send(SERVICE_SOCKET, packet, DEFAULT_TIMEOUT);
+ packet_unref(packet);
+
+ if (result) {
+ if (packet_get(result, "i", &ret) != 1) {
+ ErrPrint("Failed to parse a result packet\n");
+ ret = WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+ packet_unref(result);
+ } else {
+ ErrPrint("Failed to get result packet\n");
+ ret = WIDGET_STATUS_ERROR_FAULT;
+ }
+
+ return ret;
+}
+
+EAPI int widget_service_get_instance_count(const char *pkgname, const char *cluster, const char *category)
+{
+ struct packet *packet;
+ struct packet *result;
+ unsigned int cmd = CMD_SERVICE_INST_CNT;
+ int ret;
+
+ if (!pkgname) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ packet = packet_create((const char *)&cmd, "sssd", pkgname, cluster, category, util_timestamp());
+ if (!packet) {
+ ErrPrint("Failed to create a packet for period changing\n");
+ return WIDGET_STATUS_ERROR_FAULT;
+ }
+
+ result = com_core_packet_oneshot_send(SERVICE_SOCKET, packet, DEFAULT_TIMEOUT);
+ packet_unref(packet);
+
+ if (result) {
+ if (packet_get(result, "i", &ret) != 1) {
+ ErrPrint("Failed to parse a result packet\n");
+ ret = WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+ packet_unref(result);
+ } else {
+ ErrPrint("Failed to get result packet\n");
+ ret = WIDGET_STATUS_ERROR_FAULT;
+ }
+
+ return ret;
+}
+
+EAPI int widget_service_trigger_update(const char *pkgname, const char *id, const char *cluster, const char *category, const char *content, int force)
+{
+ struct packet *packet;
+ struct packet *result;
+ unsigned int cmd = CMD_SERVICE_UPDATE;
+ char *uri;
+ int ret;
+
+ if (!pkgname) {
+ ErrPrint("Invalid argument\n");
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!force && access("/tmp/.live.paused", R_OK) == 0) {
+ DbgPrint("Provider is paused\n");
+ return WIDGET_STATUS_ERROR_CANCEL;
+ }
+
+ if (id) {
+ uri = util_id_to_uri(id);
+ if (!uri) {
+ return WIDGET_STATUS_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ uri = NULL;
+ }
+
+ if (!cluster) {
+ cluster = "user,created";
+ }
+
+ if (!category) {
+ category = "default";
+ }
+
+ packet = packet_create((const char *)&cmd, "sssssi", pkgname, uri, cluster, category, content, force);
+ /*!
+ * \note
+ * "free" function accepts NULL
+ */
+ free(uri);
+ if (!packet) {
+ ErrPrint("Failed to create a packet for service_update\n");
+ return WIDGET_STATUS_ERROR_FAULT;
+ }
+
+ result = com_core_packet_oneshot_send(SERVICE_SOCKET, packet, DEFAULT_TIMEOUT);
+ packet_unref(packet);
+
+ if (result) {
+ if (packet_get(result, "i", &ret) != 1) {
+ ErrPrint("Failed to parse a result packet\n");
+ ret = WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ packet_unref(result);
+ } else {
+ ErrPrint("Failed to get result packet\n");
+ ret = WIDGET_STATUS_ERROR_FAULT;
+ }
+
+ return ret;
+}
+
+EAPI widget_pkglist_h widget_service_pkglist_create(const char *pkgid, widget_pkglist_h handle)
+{
+ int ret;
+
+ if (handle) {
+ if (handle->type != PKGLIST_TYPE_WIDGET_LIST) {
+ ErrPrint("Invalid handle\n");
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ if (pkgid) {
+ ErrPrint("pkgid should be NULL\n");
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ sqlite3_reset(handle->stmt);
+ return handle;
+ }
+
+ handle = calloc(1, sizeof(*handle));
+ if (!handle) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ handle->type = PKGLIST_TYPE_WIDGET_LIST;
+
+ handle->handle = open_db();
+ if (!handle->handle) {
+ free(handle);
+ return NULL;
+ }
+
+ if (!pkgid) {
+ ret = sqlite3_prepare_v2(handle->handle, "SELECT appid, pkgid, prime FROM pkgmap", -1, &handle->stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle->handle));
+ close_db(handle->handle);
+ free(handle);
+ return NULL;
+ }
+ } else {
+ ret = sqlite3_prepare_v2(handle->handle, "SELECT appid, pkgid, prime FROM pkgmap WHERE appid = ?", -1, &handle->stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle->handle));
+ close_db(handle->handle);
+ free(handle);
+ return NULL;
+ }
+
+ ret = sqlite3_bind_text(handle->stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle->handle));
+ sqlite3_finalize(handle->stmt);
+ close_db(handle->handle);
+ free(handle);
+ return NULL;
+ }
+ }
+
+ return handle;
+}
+
+EAPI int widget_service_get_pkglist_item(widget_pkglist_h handle, char **appid, char **pkgname, int *is_prime)
+{
+ const char *tmp;
+ char *_appid = NULL;
+ char *_pkgname = NULL;
+
+ if (!handle || handle->type != PKGLIST_TYPE_WIDGET_LIST) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (sqlite3_step(handle->stmt) != SQLITE_ROW) {
+ return WIDGET_STATUS_ERROR_NOT_EXIST;
+ }
+
+ if (appid) {
+ tmp = (const char *)sqlite3_column_text(handle->stmt, 0);
+ if (tmp && strlen(tmp)) {
+ _appid = strdup(tmp);
+ if (!_appid) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return WIDGET_STATUS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ }
+
+ if (pkgname) {
+ tmp = (const char *)sqlite3_column_text(handle->stmt, 1);
+ if (tmp && strlen(tmp)) {
+ _pkgname = strdup(tmp);
+ if (!_pkgname) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(_appid);
+ return WIDGET_STATUS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ }
+
+ if (is_prime) {
+ *is_prime = sqlite3_column_int(handle->stmt, 2);
+ }
+
+ if (appid) {
+ *appid = _appid;
+ }
+
+ if (pkgname) {
+ *pkgname = _pkgname;
+ }
+
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+EAPI int widget_service_pkglist_destroy(widget_pkglist_h handle)
+{
+ if (!handle || handle->type != PKGLIST_TYPE_WIDGET_LIST) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ handle->type = PKGLIST_TYPE_UNKNOWN;
+ sqlite3_reset(handle->stmt);
+ sqlite3_finalize(handle->stmt);
+ close_db(handle->handle);
+ free(handle);
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+EAPI int widget_service_get_pkglist(int (*cb)(const char *appid, const char *pkgname, int is_prime, void *data), void *data)
+{
+ int ret;
+ sqlite3_stmt *stmt;
+ char *appid;
+ char *pkgid;
+ int is_prime;
+ sqlite3 *handle;
+
+ if (!cb) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT appid, pkgid, prime FROM pkgmap", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = 0;
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ appid = (char *)sqlite3_column_text(stmt, 0);
+ if (!appid || !strlen(appid)) {
+ ErrPrint("APPID is not valid\n");
+ continue;
+ }
+
+ pkgid = (char *)sqlite3_column_text(stmt, 1);
+ if (!pkgid || !strlen(pkgid)) {
+ ErrPrint("pkgid is not valid\n");
+ continue;
+ }
+
+ is_prime = sqlite3_column_int(stmt, 2);
+
+ ret++;
+
+ if (cb(appid, pkgid, is_prime, data) < 0) {
+ DbgPrint("Callback stopped package crawling\n");
+ break;
+ }
+ }
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+
+out:
+ close_db(handle);
+ return ret;
+}
+
+EAPI int widget_service_get_pkglist_by_pkgid(const char *pkgid, int (*cb)(const char *widgetid, int is_prime, void *data), void *data)
+{
+ int ret;
+ sqlite3_stmt *stmt;
+ const char *widgetid;
+ int is_prime;
+ sqlite3 *handle;
+
+ if (!cb || !pkgid) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT pkgid, prime FROM pkgmap WHERE appid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = 0;
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ widgetid = (const char *)sqlite3_column_text(stmt, 0);
+ if (!widgetid || !strlen(widgetid)) {
+ ErrPrint("WIDGETID is not valid\n");
+ continue;
+ }
+
+ is_prime = sqlite3_column_int(stmt, 1);
+
+ ret++;
+
+ if (cb(widgetid, is_prime, data) < 0) {
+ DbgPrint("Callback stopped package crawling\n");
+ break;
+ }
+ }
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+
+out:
+ close_db(handle);
+ return ret;
+}
+
+EAPI int widget_service_get_pkglist_by_category(const char *category, int (*cb)(const char *widgetid, void *data), void *data)
+{
+ int ret;
+ sqlite3_stmt *stmt;
+ const char *widgetid;
+ sqlite3 *handle;
+
+ if (!cb || !category) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT pkgid FROM pkgmap WHERE category = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, category, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = 0;
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ widgetid = (const char *)sqlite3_column_text(stmt, 0);
+ if (!widgetid || !strlen(widgetid)) {
+ ErrPrint("WIDGETID is not valid\n");
+ continue;
+ }
+
+ ret++;
+
+ if (cb(widgetid, data) < 0) {
+ DbgPrint("Callback stopped package crawling\n");
+ break;
+ }
+ }
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+
+out:
+ close_db(handle);
+ return ret;
+}
+
+EAPI int widget_service_get_applist(const char *widgetid, void (*cb)(const char *widgetid, const char *appid, void *data), void *data)
+{
+ sqlite3_stmt *stmt;
+ const char *tmp;
+ char *pkgid;
+ sqlite3 *handle;
+ int ret;
+
+ if (!widgetid || !cb) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT appid FROM pkgmap WHERE (pkgid = ?) or (appid = ?)", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, widgetid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, widgetid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (sqlite3_step(stmt) != SQLITE_ROW) {
+ ret = WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !strlen(tmp)) {
+ ErrPrint("Invalid package name (%s)\n", widgetid);
+ ret = WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ pkgid = strdup(tmp);
+ if (!pkgid) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ ret = WIDGET_STATUS_ERROR_OUT_OF_MEMORY;
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+
+ ret = pkgmgr_get_applist(pkgid, widgetid, cb, data);
+ free(pkgid);
+
+ switch (ret) {
+ case PMINFO_R_EINVAL:
+ ret = WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ break;
+ case PMINFO_R_OK:
+ ret = WIDGET_STATUS_ERROR_NONE;
+ break;
+ case PMINFO_R_ERROR:
+ default:
+ ret = WIDGET_STATUS_ERROR_FAULT;
+ break;
+ }
+
+out:
+ close_db(handle);
+ return ret;
+}
+
+EAPI char *widget_service_mainappid(const char *widgetid)
+{
+ sqlite3_stmt *stmt;
+ const char *tmp;
+ const char *pkgid;
+ sqlite3 *handle;
+ char *ret = NULL;
+
+ if (!widgetid) {
+ return NULL;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ if (sqlite3_prepare_v2(handle, "SELECT appid, uiapp FROM pkgmap WHERE (pkgid = ?) or (appid = ? and prime = 1)", -1, &stmt, NULL) != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ if (sqlite3_bind_text(stmt, 1, widgetid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ if (sqlite3_bind_text(stmt, 2, widgetid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ if (sqlite3_step(stmt) != SQLITE_ROW) {
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !strlen(tmp)) {
+ ErrPrint("Invalid package name (%s)\n", widgetid);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ pkgid = (const char *)sqlite3_column_text(stmt, 1);
+ if (!pkgid || !strlen(pkgid)) {
+ /*
+ * This record has no uiapp.
+ * Try to find the main ui-app id.
+ */
+ ret = pkgmgr_get_mainapp(tmp);
+ } else {
+ ret = strdup(pkgid);
+ if (!ret) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
+ }
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+
+out:
+ close_db(handle);
+ return ret;
+}
+
+EAPI int widget_service_get_supported_size_types(const char *pkgid, int *cnt, int *types)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int size;
+ int ret;
+
+ if (!types || !cnt || !pkgid) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT size_type FROM box_size WHERE pkgid = ? ORDER BY size_type ASC", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (*cnt > WIDGET_NR_OF_SIZE_LIST) {
+ *cnt = WIDGET_NR_OF_SIZE_LIST;
+ }
+
+ ret = 0;
+ while (sqlite3_step(stmt) == SQLITE_ROW && ret < *cnt) {
+ size = sqlite3_column_int(stmt, 0);
+ types[ret] = size;
+ ret++;
+ }
+
+ *cnt = ret;
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ ret = WIDGET_STATUS_ERROR_NONE;
+out:
+ close_db(handle);
+ return ret;
+}
+
+EAPI char *widget_service_content(const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ char *content = NULL;
+ int ret;
+
+ handle = open_db();
+ if (!handle) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT content FROM client WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ close_db(handle);
+ return NULL;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ const char *tmp;
+
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (tmp && strlen(tmp)) {
+ content = strdup(tmp);
+ if (!content) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ }
+ } else if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return content;
+}
+
+EAPI char *widget_service_setup_appid(const char *widgetid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+ char *appid;
+
+ if (!widgetid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT setup FROM client WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ close_db(handle);
+ return NULL;
+ }
+
+ appid = NULL;
+ ret = sqlite3_bind_text(stmt, 1, widgetid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ const char *tmp;
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !strlen(tmp)) {
+ goto out;
+ }
+
+ appid = strdup(tmp);
+ if (!appid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Error: %s\n", strerror(errno));
+ }
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return appid;
+}
+
+EAPI int widget_service_nodisplay(const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+
+ if (!pkgid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return 0;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT nodisplay FROM client WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ close_db(handle);
+ return 0;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = 0;
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ ret = !!sqlite3_column_int(stmt, 0);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ ret = 0;
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return ret;
+}
+
+EAPI int widget_service_need_frame(const char *pkgid, int size_type)
+{
+ char *widgetid;
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+
+ handle = open_db();
+ if (!handle) {
+ ErrPrint("Unable to open a DB\n");
+ return 0;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT need_frame FROM box_size WHERE pkgid = ? AND size_type = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ close_db(handle);
+ return 0;
+ }
+
+ /*!
+ */
+ widgetid = widget_service_widget_id(pkgid);
+ if (!widgetid) {
+ ErrPrint("Invalid appid (%s)\n", pkgid);
+ ret = 0;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, widgetid, -1, SQLITE_TRANSIENT);
+ free(widgetid);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = 0;
+ goto out;
+ }
+
+ ret = sqlite3_bind_int(stmt, 2, size_type);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = 0;
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ ret = !!sqlite3_column_int(stmt, 0);
+ } else {
+ ret = 0;
+ ErrPrint("There is no such result\n");
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ }
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return ret;
+}
+
+EAPI int widget_service_touch_effect(const char *pkgid, int size_type)
+{
+ char *widgetid;
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+
+ handle = open_db();
+ if (!handle) {
+ ErrPrint("Unable to open a DB\n");
+ return 1;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT touch_effect FROM box_size WHERE pkgid = ? AND size_type = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ close_db(handle);
+ return 1;
+ }
+
+ /**
+ * @note
+ * This function will validate the "pkgid"
+ * call the exported API in the exported API is not recomended
+ * but... I used.
+ */
+ widgetid = widget_service_widget_id(pkgid);
+ if (!widgetid) {
+ ErrPrint("Invalid appid (%s)\n", pkgid);
+ ret = 1;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, widgetid, -1, SQLITE_TRANSIENT);
+ free(widgetid);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = 1;
+ goto out;
+ }
+
+ ret = sqlite3_bind_int(stmt, 2, size_type);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = 1;
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ ret = !!sqlite3_column_int(stmt, 0);
+ } else {
+ ret = 1; /**< Default true: In this case the DB is corrupted. */
+ ErrPrint("There is no result\n");
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return ret;
+}
+
+EAPI int widget_service_mouse_event(const char *pkgid, int size_type)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ char *widgetid;
+ int ret;
+
+ handle = open_db();
+ if (!handle) {
+ return 0;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT mouse_event FROM box_size WHERE pkgid = ? AND size_type = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ close_db(handle);
+ return 0;
+ }
+
+ widgetid = widget_service_widget_id(pkgid);
+ if (!widgetid) {
+ ErrPrint("Failed to get widgetid: %s\n", pkgid);
+ ret = 0;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, widgetid, -1, SQLITE_TRANSIENT);
+ free(widgetid);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = 0;
+ goto out;
+ }
+
+ ret = sqlite3_bind_int(stmt, 2, size_type);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = 0;
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ ret = !!sqlite3_column_int(stmt, 0);
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ } else {
+ ret = 0; /**< Default is false, In this case the DB is corrupted */
+ ErrPrint("There is no result.\n");
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return ret;
+}
+
+static char *convert_to_abspath(const char *appid, const char *tmp, const char *mid_path, int *tmp_len)
+{
+ pkgmgrinfo_pkginfo_h handle;
+ const char *path;
+ int abspath_len;
+ char *abspath = NULL;
+ int ret;
+
+ if (!tmp || tmp[0] == '/' || !appid) {
+ return NULL;
+ }
+
+ ret = pkgmgrinfo_pkginfo_get_pkginfo(appid, &handle);
+ if (ret != PMINFO_R_OK) {
+ ErrPrint("Unable to get package info for %s\n", appid);
+ return NULL;
+ }
+
+ ret = pkgmgrinfo_pkginfo_get_root_path(handle, (char **)&path);
+ if (ret != PMINFO_R_OK) {
+ ErrPrint("Unable to get path for %s\n", appid);
+ goto out;
+ }
+
+ abspath_len = strlen(tmp) + strlen(path) + strlen(mid_path) + 1;
+ abspath = malloc(abspath_len);
+ if (!abspath) {
+ ErrPrint("malloc: %s\n", strerror(errno));
+ goto out;
+ }
+
+ if (snprintf(abspath, abspath_len, "%s%s%s", path, mid_path, tmp) < 0) {
+ ErrPrint("snprintf: %s\n", strerror(errno));
+ free(abspath);
+ abspath = NULL;
+ goto out;
+ }
+
+ if (tmp_len) {
+ *tmp_len = abspath_len;
+ }
+
+ DbgPrint("Converted path: %s (%d)\n", abspath, abspath_len);
+out:
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return abspath;
+}
+
+static char *get_appid(sqlite3 *handle, const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ int ret;
+ char *appid = NULL;
+
+ ret = sqlite3_prepare_v2(handle, "SELECT appid FROM pkgmap WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ return NULL;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ const char *tmp;
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (tmp && strlen(tmp)) {
+ appid = strdup(tmp);
+ if (!appid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+ } else if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ return appid;
+}
+
+EAPI char *widget_service_preview(const char *pkgid, int size_type)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+ char *preview = NULL;
+ const char *tmp;
+ char *appid;
+ int tmp_len;
+ int buf_len;
+ register int i;
+ int printed;
+ char *abspath;
+
+ handle = open_db();
+ if (!handle) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT preview FROM box_size WHERE pkgid = ? AND size_type = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s, %s\n", sqlite3_errmsg(handle), pkgid);
+ close_db(handle);
+ return NULL;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s, %s\n", sqlite3_errmsg(handle), pkgid);
+ goto out;
+ }
+
+ ret = sqlite3_bind_int(stmt, 2, size_type);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s, %s\n", sqlite3_errmsg(handle), pkgid);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+ ErrPrint("Error: %s, %s\n", sqlite3_errmsg(handle), pkgid);
+ goto out;
+ }
+
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !(tmp_len = strlen(tmp))) {
+ ErrPrint("Failed to get data (%s)\n", pkgid);
+ goto out;
+ }
+
+ appid = get_appid(handle, pkgid);
+ abspath = convert_to_abspath(appid, tmp, RESOURCE_PATH, &tmp_len);
+ free(appid);
+ if (!abspath) {
+ abspath = strdup(tmp);
+ if (!abspath) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("strdup: %s\n", strerror(errno));
+ goto out;
+ }
+ }
+
+ if (update_lang_info() != 0) {
+ preview = abspath;
+ if (!preview) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ goto out;
+ }
+
+ buf_len = tmp_len + strlen(s_info.iso3lang) + s_info.country_len + 3; /* '/' '-' '/' */
+ preview = malloc(buf_len + 1);
+ if (!preview) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(abspath);
+ goto out;
+ }
+
+ for (i = tmp_len; i >= 0 && abspath[i] != '/'; i--);
+ i++; /* Skip '/' */
+
+ strncpy(preview, abspath, i);
+ printed = snprintf(preview + i, buf_len - i, "%s-%s/%s", s_info.iso3lang, s_info.country, abspath + i);
+ if (preview[i + printed] != '\0') {
+ ErrPrint("Path is truncated\n");
+ preview[i + printed] = '\0';
+ }
+
+ if (access(preview, R_OK) != 0) {
+ DbgPrint("Access failed: %s, %s\n", preview, strerror(errno));
+ free(preview);
+
+ preview = abspath;
+ } else {
+ free(abspath);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return preview;
+}
+
+EAPI char *widget_service_i18n_icon(const char *pkgid, const char *lang)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ char *language;
+ char *icon = NULL;
+ char *appid;
+ int ret;
+ char *ret_icon;
+
+ if (!pkgid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ if (lang) {
+ language = strdup(lang);
+ if (!language) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+ } else {
+ language = cur_locale();
+ if (!language) {
+ return NULL;
+ }
+ }
+
+ handle = open_db();
+ if (!handle) {
+ free(language);
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT icon FROM i18n WHERE pkgid = ? AND lang = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ close_db(handle);
+ free(language);
+ return NULL;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, language, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ const char *tmp;
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !strlen(tmp)) {
+ icon = get_default_icon(pkgid);
+ } else {
+ icon = strdup(tmp);
+ if (!icon) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ }
+ } else {
+ icon = get_default_icon(pkgid);
+ }
+
+ appid = get_appid(handle, pkgid);
+ ret_icon = convert_to_abspath(appid, icon, RESOURCE_PATH, NULL);
+ free(appid);
+ if (ret_icon) {
+ free(icon);
+ icon = ret_icon;
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ free(language);
+ return icon;
+}
+
+EAPI char *widget_service_i18n_name(const char *pkgid, const char *lang)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ char *language;
+ char *name = NULL;
+ int ret;
+
+ if (!pkgid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ if (lang) {
+ language = strdup(lang);
+ if (!language) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Error: %s\n", strerror(errno));
+ return NULL;
+ }
+ } else {
+ language = cur_locale();
+ if (!language) {
+ return NULL;
+ }
+ }
+
+ handle = open_db();
+ if (!handle) {
+ free(language);
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT name FROM i18n WHERE pkgid = ? AND lang = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ close_db(handle);
+ free(language);
+ return NULL;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, language, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ const char *tmp;
+ tmp = (const char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !strlen(tmp)) {
+ name = get_default_name(pkgid);
+ } else {
+ name = strdup(tmp);
+ if (!name) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ }
+ } else {
+ name = get_default_name(pkgid);
+ }
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ free(language);
+ return name;
+}
+
+EAPI int widget_service_get_supported_sizes(const char *pkgid, int *cnt, int *w, int *h)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int size;
+ int ret;
+
+ if (!w || !h || !cnt || !pkgid) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT size_type FROM box_size WHERE pkgid = ? ORDER BY size_type ASC", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ ret = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (*cnt > WIDGET_NR_OF_SIZE_LIST) {
+ *cnt = WIDGET_NR_OF_SIZE_LIST;
+ }
+
+ ret = 0;
+ while (sqlite3_step(stmt) == SQLITE_ROW && ret < *cnt) {
+ size = sqlite3_column_int(stmt, 0);
+ ret += (convert_size_from_type((widget_size_type_e)size, w + ret, h + ret) == 0);
+ }
+
+ *cnt = ret;
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ ret = 0;
+out:
+ close_db(handle);
+ return ret;
+}
+
+EAPI char *widget_service_abi(const char *widgetid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+ char *abi;
+ char *tmp;
+
+ if (!widgetid) {
+ ErrPrint("Invalid argument\n");
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ abi = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT abi FROM provider WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, widgetid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+
+ ErrPrint("Error: %s (%d)\n", sqlite3_errmsg(handle), ret);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ tmp = (char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !strlen(tmp)) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ ErrPrint("Invalid abi: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ abi = strdup(tmp);
+ if (!abi) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("strdup: %s\n", strerror(errno));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ DbgPrint("abi: %s\n", abi);
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return abi;
+}
+
+EAPI char *widget_service_widget_id_by_libexec(const char *libexec)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+ char *pkgid;
+ char *tmp;
+ char *_libexec;
+ int len;
+
+ if (!libexec) {
+ ErrPrint("Invalid argument\n");
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ pkgid = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ len = strlen(libexec) + 3;
+
+ _libexec = malloc(len);
+ if (!_libexec) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ close_db(handle);
+ return NULL;
+ }
+
+ snprintf(_libexec, len - 1, "%%%s", libexec);
+
+ ret = sqlite3_prepare_v2(handle, "SELECT pkgid FROM provider WHERE libexec like ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, _libexec, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+ ErrPrint("No records (%s) for (%s)\n", sqlite3_errmsg(handle), libexec);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ tmp = (char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !strlen(tmp)) {
+ ErrPrint("Invalid pkgid: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ pkgid = strdup(tmp);
+ if (!pkgid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+
+ DbgPrint("pkgid: %s\n", pkgid);
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ free(_libexec);
+ return pkgid;
+}
+
+EAPI char *widget_service_libexec(const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+ char *libexec;
+ char *appid;
+ char *path;
+
+ if (!pkgid) {
+ ErrPrint("Invalid argument\n");
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ libexec = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.libexec FROM pkgmap, provider WHERE pkgmap.pkgid = ? AND provider.pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ appid = (char *)sqlite3_column_text(stmt, 0);
+ if (!appid || !strlen(appid)) {
+ ErrPrint("Invalid appid: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ path = (char *)sqlite3_column_text(stmt, 1);
+ if (!path || !strlen(path)) {
+ ErrPrint("Invalid libexec: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ libexec = convert_to_abspath(appid, path, LIBEXEC_PATH, NULL);
+ if (!libexec) {
+ libexec = strdup(path);
+ if (!libexec) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ }
+
+ DbgPrint("libexec: %s\n", libexec);
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return libexec;
+}
+
+EAPI char *widget_service_widget_id(const char *appid)
+{
+ char *widget_pkgname;
+ pkgmgrinfo_appinfo_h handle;
+ int ret;
+ char *new_appid;
+
+ if (!appid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ widget_pkgname = get_widget_pkgname_by_appid(appid);
+ if (widget_pkgname) {
+ return widget_pkgname;
+ }
+
+ /*!
+ * \note
+ * Try to get the package id using given appid
+ */
+ ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
+ if (ret != PKGMGR_R_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Failed to get appinfo\n");
+ return NULL;
+ }
+
+ ret = pkgmgrinfo_appinfo_get_pkgid(handle, &new_appid);
+ if (ret != PKGMGR_R_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ pkgmgrinfo_appinfo_destroy_appinfo(handle);
+ ErrPrint("Failed to get pkgname for (%s)\n", appid);
+ return NULL;
+ }
+
+ widget_pkgname = get_widget_pkgname_by_appid(new_appid);
+ pkgmgrinfo_appinfo_destroy_appinfo(handle);
+
+ if (!widget_pkgname) {
+ widget_pkgname = strdup(appid);
+ if (!widget_pkgname) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+
+ return widget_pkgname;
+}
+
+EAPI char *widget_service_package_id(const char *pkgname)
+{
+ sqlite3_stmt *stmt;
+ char *appid;
+ char *tmp;
+ sqlite3 *handle;
+ int is_prime __attribute__((__unused__));
+ int ret;
+
+ if (!pkgname) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ appid = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT appid, prime FROM pkgmap WHERE pkgid = ? OR appid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgname, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, pkgname, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ pkgmgrinfo_appinfo_h pkg_handle;
+ char *new_appid;
+
+ if (ret == SQLITE_DONE) {
+ ErrPrint("No records: %s\n", sqlite3_errmsg(handle));
+ } else {
+ ErrPrint("Failed to get record: %s\n", sqlite3_errmsg(handle));
+ }
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+
+ ret = pkgmgrinfo_appinfo_get_appinfo(pkgname, &pkg_handle);
+ if (ret != PKGMGR_R_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Failed to get appinfo: %s\n", pkgname);
+ goto out;
+ }
+
+ ret = pkgmgrinfo_appinfo_get_pkgid(pkg_handle, &new_appid);
+ if (ret != PKGMGR_R_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Failed to get pkgname for (%s)\n", appid);
+ pkgmgrinfo_appinfo_destroy_appinfo(pkg_handle);
+ goto out;
+ }
+
+ appid = strdup(new_appid);
+ if (!appid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+
+ pkgmgrinfo_appinfo_destroy_appinfo(pkg_handle);
+ goto out;
+ }
+
+ tmp = (char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !strlen(tmp)) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ ErrPrint("APPID is NIL\n");
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ appid = strdup(tmp);
+ if (!appid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ is_prime = sqlite3_column_int(stmt, 1);
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return appid;
+}
+
+EAPI char *widget_service_provider_name(const char *widgetid)
+{
+ char *ret;
+ int stage = 0;
+ int seq = 0;
+ int idx = 0;
+ char *str = WIDGET_ID_PREFIX;
+
+ if (!widgetid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ while (str[idx] && widgetid[idx] && widgetid[idx] == str[idx]) {
+ idx++;
+ if (seq < 2 && widgetid[idx] == '.') {
+ stage = idx;
+ seq++;
+ }
+ }
+
+ if (!str[idx] && widgetid[idx]) {
+ ret = strdup(widgetid);
+ /* Inhouse */
+ if (!ret) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ }
+ return ret;
+ } else if (seq < 2) {
+ while (seq < 2) {
+ if (widgetid[idx] == '.') {
+ seq++;
+ } else if (!widgetid[idx]) {
+ ErrPrint("Invalid widgetid: %s\n", widgetid);
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ idx++;
+ }
+
+ stage = idx;
+ } else {
+ stage++;
+ }
+
+ ret = strdup(widgetid + stage);
+ if (!ret) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Error: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ return ret;
+}
+
+EAPI int widget_service_is_enabled(const char *widgetid)
+{
+ return 1;
+ /*
+ ail_appinfo_h ai;
+ char *pkgname;
+ bool enabled;
+ int ret;
+
+ pkgname = widget_service_package_id(widgetid);
+ if (!pkgname)
+ return 0;
+
+ ret = ail_get_appinfo(pkgname, &ai);
+ if (ret != AIL_ERROR_OK) {
+ free(pkgname);
+ return 0;
+ }
+
+ if (ail_appinfo_get_bool(ai, AIL_PROP_X_SLP_ENABLED_BOOL, &enabled) != AIL_ERROR_OK)
+ enabled = false;
+
+ ail_destroy_appinfo(ai);
+ free(pkgname);
+ return enabled == true;
+ */
+}
+
+EAPI int widget_service_is_primary(const char *widgetid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret = 0;
+
+ if (!widgetid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return 0;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT prime FROM pkgmap WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ close_db(handle);
+ return 0;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, widgetid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_column_int(stmt, 0);
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+
+out:
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ close_db(handle);
+ return ret;
+}
+
+EAPI char *widget_service_category(const char *widgetid)
+{
+ sqlite3_stmt *stmt;
+ char *category = NULL;
+ char *tmp;
+ sqlite3 *handle;
+ int ret;
+
+ if (!widgetid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ category = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT category FROM pkgmap WHERE pkgid = ? OR appid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, widgetid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, widgetid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ ErrPrint("Has no record?: %s\n", sqlite3_errmsg(handle));
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Failed to retrieve record set: %s\n", sqlite3_errmsg(handle));
+ }
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ tmp = (char *)sqlite3_column_text(stmt, 0);
+ if (!tmp || !strlen(tmp)) {
+ ErrPrint("APPID is NIL\n");
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ category = strdup(tmp);
+ if (!category) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return category;
+}
+
+EAPI char *widget_service_widget_script_path(const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+ char *path;
+ char *appid;
+ char *widget_src;
+
+ if (!pkgid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ path = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.box_src FROM provider, pkgmap WHERE pkgmap.pkgid = ? AND provider.pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s, pkgid(%s), ret(%d)\n", sqlite3_errmsg(handle), pkgid, ret);
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s, pkgid(%s), ret(%d)\n", sqlite3_errmsg(handle), pkgid, ret);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s, pkgid(%s), ret(%d)\n", sqlite3_errmsg(handle), pkgid, ret);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+ ErrPrint("Error: %s, pkgid(%s), ret(%d)\n", sqlite3_errmsg(handle), pkgid, ret);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ appid = (char *)sqlite3_column_text(stmt, 0);
+ if (!appid || !strlen(appid)) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ ErrPrint("Invalid appid : %s, pkgid(%s)\n", sqlite3_errmsg(handle), pkgid);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ widget_src = (char *)sqlite3_column_text(stmt, 1);
+ if (!widget_src || !strlen(widget_src)) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ ErrPrint("No records for widget src : %s, pkgid(%s), appid(%s)\n", sqlite3_errmsg(handle), pkgid, appid);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ path = convert_to_abspath(appid, widget_src, RESOURCE_PATH, NULL);
+ if (!path) {
+ path = strdup(widget_src);
+ if (!path) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+
+ DbgPrint("WIDGET Src: %s\n", path);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return path;
+}
+
+EAPI char *widget_service_widget_script_group(const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+ char *group;
+ char *tmp;
+
+ if (!pkgid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ group = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT box_group FROM provider WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ tmp = (char *)sqlite3_column_text(stmt, 0);
+ if (tmp && strlen(tmp)) {
+ group = strdup(tmp);
+ if (!group) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ ErrPrint("Heap: %s\n", strerror(errno));
+ }
+ }
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return group;
+}
+
+EAPI char *widget_service_gbar_script_path(const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+ char *path;
+ char *gbar_src;
+ const char *appid;
+
+ if (!pkgid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ path = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.pd_src FROM provider, pkgmap WHERE provider.pkgid = ? AND pkgmap.pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s pkgid(%s) ret(%d)\n", sqlite3_errmsg(handle), pkgid, ret);
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s pkgid(%s) ret(%d)\n", sqlite3_errmsg(handle), pkgid, ret);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s pkgid(%s) ret(%d)\n", sqlite3_errmsg(handle), pkgid, ret);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ if (ret == SQLITE_DONE) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_NOT_EXIST);
+ } else {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ }
+ ErrPrint("Error: %s pkgid(%s) ret(%d)\n", sqlite3_errmsg(handle), pkgid, ret);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+
+ appid = (char *)sqlite3_column_text(stmt, 0);
+ if (!appid || !strlen(appid)) {
+ ErrPrint("Error: %s pkgid(%s)\n", sqlite3_errmsg(handle), pkgid);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ gbar_src = (char *)sqlite3_column_text(stmt, 1);
+ if (!gbar_src || !strlen(gbar_src)) {
+ ErrPrint("Error: %s pkgid(%s) appid(%s)\n", sqlite3_errmsg(handle), pkgid, appid);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ path = convert_to_abspath(appid, gbar_src, RESOURCE_PATH, NULL);
+ if (!path) {
+ path = strdup(gbar_src);
+ if (!path) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+
+ DbgPrint("GBAR Src: %s\n", path);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return path;
+}
+
+EAPI char *widget_service_gbar_script_group(const char *pkgid)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ int ret;
+ char *group;
+ char *tmp;
+
+ if (!pkgid) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ group = NULL;
+ handle = open_db();
+ if (!handle) {
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT pd_group FROM provider WHERE pkgid = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ goto out;
+ }
+
+ widget_set_last_status(WIDGET_STATUS_ERROR_NONE);
+ tmp = (char *)sqlite3_column_text(stmt, 0);
+ if (tmp && strlen(tmp)) {
+ group = strdup(tmp);
+ if (!group) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return group;
+}
+
+EAPI int widget_service_enumerate_cluster_list(int (*cb)(const char *cluster, void *data), void *data)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ const char *cluster;
+ int cnt;
+ int ret;
+
+ if (!cb) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ cnt = 0;
+ ret = sqlite3_prepare_v2(handle, "SELECT DISTINCT cluster FROM groupinfo", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ cnt = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ cluster = (const char *)sqlite3_column_text(stmt, 0);
+ if (!cluster || !strlen(cluster)) {
+ continue;
+ }
+
+ if (cb(cluster, data) < 0) {
+ break;
+ }
+
+ cnt++;
+ }
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return cnt;
+}
+
+EAPI int widget_service_enumerate_category_list(const char *cluster, int (*cb)(const char *cluster, const char *category, void *data), void *data)
+{
+ sqlite3_stmt *stmt;
+ sqlite3 *handle;
+ const char *category;
+ int cnt;
+ int ret;
+
+ if (!cluster || !cb) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = open_db();
+ if (!handle) {
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_prepare_v2(handle, "SELECT DISTINCT category FROM groupinfo WHERE cluster = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
+ cnt = WIDGET_STATUS_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ cnt = 0;
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ category = (const char *)sqlite3_column_text(stmt, 0);
+ if (!category || !strlen(category)) {
+ continue;
+ }
+
+ if (cb(cluster, category, data) < 0) {
+ break;
+ }
+
+ cnt++;
+ }
+
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+out:
+ close_db(handle);
+ return cnt;
+}
+
+EAPI int widget_service_init(void)
+{
+ if (s_info.handle) {
+ DbgPrint("Already initialized\n");
+ s_info.init_count++;
+ return WIDGET_STATUS_ERROR_NONE;
+ }
+
+ s_info.handle = open_db();
+ if (s_info.handle) {
+ s_info.init_count++;
+ return WIDGET_STATUS_ERROR_NONE;
+ }
+
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+}
+
+EAPI int widget_service_fini(void)
+{
+ if (!s_info.handle || s_info.init_count <= 0) {
+ ErrPrint("Service is not initialized\n");
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ s_info.init_count--;
+ if (s_info.init_count > 0) {
+ DbgPrint("Init count %d\n", s_info.init_count);
+ return WIDGET_STATUS_ERROR_NONE;
+ }
+
+ db_util_close(s_info.handle);
+ s_info.handle = NULL;
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+EAPI int widget_service_get_size(widget_size_type_e type, int *width, int *height)
+{
+ int _width;
+ int _height;
+
+ if (!width) {
+ width = &_width;
+ }
+
+ if (!height) {
+ height = &_height;
+ }
+
+ return convert_size_from_type(type, width, height);
+}
+
+EAPI widget_size_type_e widget_service_size_type(int width, int height)
+{
+ int idx;
+
+ if (util_update_resolution(&s_info, SIZE_LIST) < 0) {
+ ErrPrint("Failed to update the size list\n");
+ }
+
+ for (idx = 0; idx < WIDGET_NR_OF_SIZE_LIST; idx++) {
+ if (SIZE_LIST[idx].w == width && SIZE_LIST[idx].h == height) {
+ break;
+ }
+ }
+
+ switch (idx) {
+ case 0:
+ return WIDGET_SIZE_TYPE_1x1;
+ case 1:
+ return WIDGET_SIZE_TYPE_2x1;
+ case 2:
+ return WIDGET_SIZE_TYPE_2x2;
+ case 3:
+ return WIDGET_SIZE_TYPE_4x1;
+ case 4:
+ return WIDGET_SIZE_TYPE_4x2;
+ case 5:
+ return WIDGET_SIZE_TYPE_4x3;
+ case 6:
+ return WIDGET_SIZE_TYPE_4x4;
+ case 7:
+ return WIDGET_SIZE_TYPE_4x5;
+ case 8:
+ return WIDGET_SIZE_TYPE_4x6;
+ case 9:
+ return WIDGET_SIZE_TYPE_EASY_1x1;
+ case 10:
+ return WIDGET_SIZE_TYPE_EASY_3x1;
+ case 11:
+ return WIDGET_SIZE_TYPE_EASY_3x3;
+ case 12:
+ return WIDGET_SIZE_TYPE_0x0;
+ default:
+ break;
+ }
+
+ return WIDGET_SIZE_TYPE_UNKNOWN;
+}
+
+EAPI void widget_set_last_status(widget_status_e status)
+{
+ s_info.last_status = status;
+}
+
+EAPI widget_status_e widget_last_status(void)
+{
+ return s_info.last_status;
+}
+
+EAPI widget_lock_info_t widget_service_create_lock(const char *uri, widget_target_type_e type, widget_lock_type_e option)
+{
+ widget_lock_info_t info;
+ int len;
+ int flags;
+
+ info = malloc(sizeof(*info));
+ if (!info) {
+ ErrPrint("malloc: %s\n", strerror(errno));
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ return NULL;
+ }
+
+ len = strlen(uri);
+ info->filename = malloc(len + 20);
+ if (!info->filename) {
+ ErrPrint("malloc: %s\n", strerror(errno));
+ free(info);
+ widget_set_last_status(WIDGET_STATUS_ERROR_OUT_OF_MEMORY);
+ return NULL;
+ }
+
+ len = snprintf(info->filename, len + 20, "%s.%s.lck", util_uri_to_path(uri), type == WIDGET_TYPE_GBAR ? "gbar" : "widget");
+ if (len < 0) {
+ ErrPrint("snprintf: %s\n", strerror(errno));
+ free(info->filename);
+ free(info);
+ widget_set_last_status(WIDGET_STATUS_ERROR_FAULT);
+ return NULL;
+ }
+
+ if (option == WIDGET_LOCK_WRITE) {
+ flags = O_WRONLY | O_CREAT;
+ } else if (option == WIDGET_LOCK_READ) {
+ flags = O_RDONLY;
+ } else {
+ ErrPrint("Invalid paramter\n");
+ free(info->filename);
+ free(info);
+ widget_set_last_status(WIDGET_STATUS_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ info->type = option;
+
+ info->fd = open(info->filename, flags, 0644);
+ if (info->fd < 0) {
+ ErrPrint("open: %s\n", strerror(errno));
+ free(info->filename);
+ free(info);
+ widget_set_last_status(WIDGET_STATUS_ERROR_IO_ERROR);
+ return NULL;
+ }
+
+ return info;
+}
+
+EAPI int widget_service_destroy_lock(widget_lock_info_t info)
+{
+ if (!info || !info->filename || info->fd < 0) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (close(info->fd) < 0) {
+ ErrPrint("close: %s\n", strerror(errno));
+ return WIDGET_STATUS_ERROR_IO_ERROR;
+ }
+
+ if (unlink(info->filename) < 0) {
+ ErrPrint("unlink: %s\n", strerror(errno));
+ }
+
+ free(info->filename);
+ free(info);
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+EAPI int widget_service_acquire_lock(widget_lock_info_t info)
+{
+ struct flock flock;
+ int ret;
+
+ if (!info || info->fd < 0) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (info->type == WIDGET_LOCK_WRITE) {
+ flock.l_type = F_WRLCK;
+ } else if (info->type == WIDGET_LOCK_READ) {
+ flock.l_type = F_RDLCK;
+ }
+ flock.l_whence = SEEK_SET;
+ flock.l_start = 0;
+ flock.l_len = 0;
+ flock.l_pid = getpid();
+
+ do {
+ ret = fcntl(info->fd, F_SETLKW, &flock);
+ if (ret < 0) {
+ ret = errno;
+ ErrPrint("fcntl: %s\n", strerror(errno));
+ }
+ } while (ret == EINTR);
+
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+EAPI int widget_service_release_lock(widget_lock_info_t info)
+{
+ struct flock flock;
+ int ret;
+
+ if (info->fd < 0) {
+ return WIDGET_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ flock.l_type = F_UNLCK;
+ flock.l_whence = SEEK_SET;
+ flock.l_start = 0;
+ flock.l_len = 0;
+ flock.l_pid = getpid();
+
+ do {
+ ret = fcntl(info->fd, F_SETLKW, &flock);
+ if (ret < 0) {
+ ret = errno;
+ ErrPrint("fcntl: %s\n", strerror(errno));
+ }
+ } while (ret == EINTR);
+
+ return WIDGET_STATUS_ERROR_NONE;
+}
+
+/* End of a file */