summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHyungKyu Song <hk76.song@samsung.com>2013-02-16 00:11:35 +0900
committerHyungKyu Song <hk76.song@samsung.com>2013-02-16 00:11:35 +0900
commitb32dea69029f492083f2b11f3a087300ddb2b9e0 (patch)
treecc97cc634e3234446670bc6c7d455bd1be5dd806 /src
parentc3875cbe2f8e945b837a76ac5f8e6d57bde940bb (diff)
downloadui-gadget-1-accepted/tizen_2.0/20130215.203947.tar.gz
ui-gadget-1-accepted/tizen_2.0/20130215.203947.tar.bz2
ui-gadget-1-accepted/tizen_2.0/20130215.203947.zip
Diffstat (limited to 'src')
-rwxr-xr-xsrc/engine.c128
-rwxr-xr-xsrc/manager.c848
-rw-r--r--src/module.c138
-rwxr-xr-xsrc/ug.c283
4 files changed, 1397 insertions, 0 deletions
diff --git a/src/engine.c b/src/engine.c
new file mode 100755
index 0000000..3dcdb11
--- /dev/null
+++ b/src/engine.c
@@ -0,0 +1,128 @@
+/*
+ * UI Gadget
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <linux/limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "ug-engine.h"
+#include "ug-dbg.h"
+
+#define UG_ENGINE_INIT_SYM "UG_ENGINE_INIT"
+#define UG_ENGINE_EXIT_SYM "UG_ENGINE_EXIT"
+
+enum ug_engine_type {
+ UG_ENGINE_EFL = 0x00,
+};
+
+static int file_exist(const char *filename)
+{
+ FILE *file;
+
+ file = fopen(filename, "r");
+ if (file)
+ {
+ fclose(file);
+ return 0;
+ }
+ return -1;
+}
+
+struct ug_engine *ug_engine_load()
+{
+ void *handle;
+ struct ug_engine *engine;
+ char engine_file[PATH_MAX];
+ enum ug_engine_type type = UG_ENGINE_EFL;
+ int (*engine_init)(struct ug_engine_ops *ops);
+
+ engine = calloc(1, sizeof(struct ug_engine));
+
+ if (!engine) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ if (type == UG_ENGINE_EFL) { /* UG_ENGINE_EFL is default*/
+ if (snprintf(engine_file, PATH_MAX, "/usr/lib/libui-gadget-1-efl-engine.so") < 0){
+ goto engine_free;
+ }
+ else if (file_exist(engine_file) < 0) {
+ goto engine_free;
+ }
+ }
+ else
+ goto engine_free;
+
+ handle = dlopen(engine_file, RTLD_LAZY);
+ if (!handle) {
+ _ERR("dlopen failed: %s", dlerror());
+ goto engine_free;
+ }
+
+ engine_init = dlsym(handle, UG_ENGINE_INIT_SYM);
+ if (!engine_init) {
+ _ERR("dlsym failed: %s", dlerror());
+ goto engine_dlclose;
+ }
+
+ if (engine_init(&engine->ops))
+ goto engine_dlclose;
+
+ engine->handle = handle;
+ return engine;
+
+engine_dlclose:
+ dlclose(handle);
+
+engine_free:
+ free(engine);
+ return NULL;
+}
+
+int ug_engine_unload(struct ug_engine *engine)
+{
+ void (*engine_exit)(struct ug_engine_ops *ops);
+
+ if (!engine) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (engine->handle) {
+ engine_exit = dlsym(engine->handle, UG_ENGINE_EXIT_SYM);
+ if (engine_exit)
+ engine_exit(&engine->ops);
+ else
+ _ERR("dlsym failed: %s", dlerror());
+
+ dlclose(engine->handle);
+ }
+
+ free(engine);
+ engine = NULL;
+ return 0;
+}
diff --git a/src/manager.c b/src/manager.c
new file mode 100755
index 0000000..36cccb5
--- /dev/null
+++ b/src/manager.c
@@ -0,0 +1,848 @@
+/*
+ * UI Gadget
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+#include <utilX.h>
+
+#include <Elementary.h>
+#include <Ecore.h>
+
+#include "ug.h"
+#include "ug-manager.h"
+#include "ug-engine.h"
+#include "ug-dbg.h"
+
+struct ug_manager {
+ ui_gadget_h root;
+ ui_gadget_h fv_top;
+ GSList *fv_list;
+
+ void *win;
+ Window win_id;
+ Display *disp;
+ void *conform;
+
+ enum ug_option base_opt;
+ enum ug_event last_rotate_evt;
+
+ int walking;
+
+ int is_initted:1;
+ int is_landscape:1;
+ int destroy_all:1;
+
+ struct ug_engine *engine;
+};
+
+static struct ug_manager ug_man;
+
+static inline void job_start(void);
+static inline void job_end(void);
+
+static int ug_relation_add(ui_gadget_h p, ui_gadget_h c)
+{
+ c->parent = p;
+ /* prepend element to avoid the inefficiency,
+ which is to traverse the entire list to find the end*/
+ p->children = g_slist_prepend(p->children, c);
+
+ return 0;
+}
+
+static int ug_relation_del(ui_gadget_h ug)
+{
+ ui_gadget_h p;
+
+ p = ug->parent;
+ if (!p) {
+ _ERR("ug_relation_del failed: no parent");
+ return -1;
+ }
+ p->children = g_slist_remove(p->children, ug);
+ if (ug->children)
+ g_slist_free(ug->children);
+ ug->parent = NULL;
+
+ return 0;
+}
+
+static int ug_fvlist_add(ui_gadget_h c)
+{
+ ug_man.fv_list = g_slist_prepend(ug_man.fv_list, c);
+ ug_man.fv_top = c;
+
+ return 0;
+}
+
+static int ug_fvlist_del(ui_gadget_h c)
+{
+ ui_gadget_h t;
+
+ ug_man.fv_list = g_slist_remove(ug_man.fv_list, c);
+
+ /* update fullview top ug*/
+ t = g_slist_nth_data(ug_man.fv_list, 0);
+ ug_man.fv_top = t;
+
+ return 0;
+}
+
+static void ugman_tree_dump(ui_gadget_h ug)
+{
+ static int i;
+ int lv;
+ const char *name;
+ GSList *child;
+ ui_gadget_h c;
+
+ if (!ug)
+ return;
+
+ name = ug->name;
+ if (ug == ug_man.root) {
+ i = 0;
+ _DBG("============== TREE_DUMP =============");
+ _DBG("ROOT: Manager");
+ name = "Manager";
+ }
+
+ child = ug->children;
+ if (!child)
+ return;
+
+ i++;
+ lv = i;
+
+ while (child) {
+ c = child->data;
+ _DBG("[%d] %s [%c] (%p) (PARENT: %s)",
+ lv,
+ c && c->name ? c->name : "NO CHILD INFO FIXIT!!!",
+ c && c->mode == UG_MODE_FULLVIEW ? 'F' : 'f', c, name);
+ ugman_tree_dump(c);
+ child = g_slist_next(child);
+ }
+}
+
+static int ugman_ug_find(ui_gadget_h p, ui_gadget_h ug)
+{
+ GSList *child = NULL;
+
+ if (!p || !ug)
+ return 0;
+ child = p->children;
+
+ while (child) {
+ if (child->data == ug)
+ return 1;
+ if (ugman_ug_find(child->data, ug))
+ return 1;
+ child = g_slist_next(child);
+ }
+
+ return 0;
+}
+
+static int ugman_ug_start(void *data)
+{
+ ui_gadget_h ug = data;
+ struct ug_module_ops *ops = NULL;
+
+ if (!ug || ug->state != UG_STATE_CREATED
+ || ug->state == UG_STATE_RUNNING)
+ return 0;
+
+ _DBG("ug=%p", ug);
+
+ ug->state = UG_STATE_RUNNING;
+
+ if (ug->module)
+ ops = &ug->module->ops;
+
+ if (ops && ops->start)
+ ops->start(ug, ug->service, ops->priv);
+
+ return 0;
+}
+
+static int ugman_ug_pause(void *data)
+{
+ ui_gadget_h ug = data;
+ struct ug_module_ops *ops = NULL;
+ GSList *child = NULL;
+
+ job_start();
+
+ if (!ug || ug->state != UG_STATE_RUNNING)
+ goto end;
+
+ ug->state = UG_STATE_STOPPED;
+
+ if (ug->children) {
+ child = ug->children;
+ while (child) {
+ ugman_ug_pause(child->data);
+ child = g_slist_next(child);
+ }
+ }
+
+ if (ug->module)
+ ops = &ug->module->ops;
+
+ if (ops && ops->pause)
+ ops->pause(ug, ug->service, ops->priv);
+
+ end:
+ job_end();
+ return 0;
+}
+
+static int ugman_ug_resume(void *data)
+{
+ ui_gadget_h ug = data;
+ struct ug_module_ops *ops = NULL;
+ GSList *child = NULL;
+
+ job_start();
+
+ if (!ug)
+ goto end;
+
+ switch (ug->state) {
+ case UG_STATE_CREATED:
+ ugman_ug_start(ug);
+ goto end;
+ case UG_STATE_STOPPED:
+ break;
+ default:
+ goto end;
+ }
+
+ ug->state = UG_STATE_RUNNING;
+
+ if (ug->children) {
+ child = ug->children;
+ while (child) {
+ ugman_ug_resume(child->data);
+ child = g_slist_next(child);
+ }
+ }
+
+ if (ug->module)
+ ops = &ug->module->ops;
+
+ if (ops && ops->resume)
+ ops->resume(ug, ug->service, ops->priv);
+
+ end:
+ job_end();
+ return 0;
+}
+
+static int ugman_indicator_overlap_update(enum ug_option opt)
+{
+ if (!ug_man.win) {
+ _ERR("indicator update failed: no window");
+ return -1;
+ }
+
+ if(GET_OPT_OVERLAP_VAL(opt)) {
+ _DBG("update overlap indicator / opt(%d)", opt);
+ elm_object_signal_emit(ug_man.conform, "elm,state,indicator,overlap", "");
+ } else {
+ _DBG("update no overlap indicator / opt(%d)", opt);
+ elm_object_signal_emit(ug_man.conform, "elm,state,indicator,nooverlap", "");
+ }
+
+ return 0;
+}
+
+static int ugman_indicator_update(enum ug_option opt, enum ug_event event)
+{
+ int enable;
+ int cur_state;
+
+ switch (GET_OPT_INDICATOR_VAL(opt)) {
+ case UG_OPT_INDICATOR_ENABLE:
+ if (event == UG_EVENT_NONE)
+ enable = 1;
+ else {
+ cur_state = utilx_get_indicator_state(ug_man.disp, ug_man.win_id);
+ enable = cur_state ? 1 : 0;
+ }
+ break;
+ case UG_OPT_INDICATOR_PORTRAIT_ONLY:
+ enable = ug_man.is_landscape ? 0 : 1;
+ break;
+ case UG_OPT_INDICATOR_LANDSCAPE_ONLY:
+ enable = ug_man.is_landscape ? 1 : 0;
+ break;
+ case UG_OPT_INDICATOR_DISABLE:
+ enable = 0;
+ break;
+ case UG_OPT_INDICATOR_MANUAL:
+ return 0;
+ default:
+ _ERR("update failed: Invalid opt(%d)", opt);
+ return -1;
+ }
+
+ utilx_enable_indicator(ug_man.disp, ug_man.win_id, enable);
+
+ return 0;
+}
+
+static int ugman_ug_getopt(ui_gadget_h ug)
+{
+ if (!ug)
+ return -1;
+
+ /* Indicator Option */
+ if (ug->mode == UG_MODE_FULLVIEW) {
+ ugman_indicator_overlap_update(ug->opt);
+ ugman_indicator_update(ug->opt, UG_EVENT_NONE);
+ }
+
+ return 0;
+}
+
+static int ugman_ug_event(ui_gadget_h ug, enum ug_event event)
+{
+ struct ug_module_ops *ops = NULL;
+ GSList *child = NULL;
+
+ if (!ug)
+ return 0;
+
+ if (ug->children) {
+ child = ug->children;
+ while (child) {
+ ugman_ug_event(child->data, event);
+ child = g_slist_next(child);
+ }
+ }
+
+ if (ug->module)
+ ops = &ug->module->ops;
+
+ if (ops && ops->event)
+ ops->event(ug, event, ug->service, ops->priv);
+
+ return 0;
+}
+
+static int ugman_ug_destroy(void *data)
+{
+ ui_gadget_h ug = data;
+ struct ug_module_ops *ops = NULL;
+ GSList *child, *trail;
+
+ job_start();
+
+ if (!ug)
+ goto end;
+
+ _DBG("ugman_ug_destroy start ug(%p)", ug);
+
+ switch (ug->state) {
+ case UG_STATE_CREATED:
+ case UG_STATE_RUNNING:
+ case UG_STATE_STOPPED:
+ case UG_STATE_DESTROYING:
+ break;
+ default:
+ goto end;
+ }
+
+ ug->state = UG_STATE_DESTROYED;
+
+ if (ug->module)
+ ops = &ug->module->ops;
+
+ if (ug->children) {
+ child = ug->children;
+ while (child) {
+ trail = g_slist_next(child);
+ ugman_ug_destroy(child->data);
+ child = trail;
+ }
+ }
+
+ if (ops && ops->destroy) {
+ _DBG("ug module destory cb call");
+ ops->destroy(ug, ug->service, ops->priv);
+ }
+
+ ug_relation_del(ug);
+
+ if (ug->mode == UG_MODE_FULLVIEW) {
+ if (ug_man.fv_top == ug) {
+ ug_fvlist_del(ug);
+ ugman_ug_getopt(ug_man.fv_top);
+ } else {
+ ug_fvlist_del(ug);
+ }
+ }
+
+ ug_free(ug);
+
+ if (ug_man.root == ug)
+ ug_man.root = NULL;
+
+ ugman_tree_dump(ug_man.root);
+ end:
+ job_end();
+
+ return 0;
+}
+
+static void ug_hide_end_cb(ui_gadget_h ug)
+{
+ ecore_idler_add(ugman_ug_destroy, ug);
+}
+
+static int ugman_ug_create(void *data)
+{
+ ui_gadget_h ug = data;
+ struct ug_module_ops *ops = NULL;
+ struct ug_cbs *cbs;
+ struct ug_engine_ops *eng_ops = NULL;
+
+ if (!ug || ug->state != UG_STATE_READY)
+ return -1;
+
+ ug->state = UG_STATE_CREATED;
+
+ if (ug->module)
+ ops = &ug->module->ops;
+
+ if (ug_man.engine)
+ eng_ops = &ug_man.engine->ops;
+
+ if (ops && ops->create) {
+ ug->layout = ops->create(ug, ug->mode, ug->service, ops->priv);
+ if (!ug->layout) {
+ ug_relation_del(ug);
+ return -1;
+ }
+ if (ug->mode == UG_MODE_FULLVIEW) {
+ if (eng_ops && eng_ops->create) {
+ //change start cb function call after transition,finished for fullview
+ ug_man.conform = eng_ops->create(ug_man.win, ug, ugman_ug_start);
+ }
+ }
+ cbs = &ug->cbs;
+
+ if (cbs && cbs->layout_cb)
+ cbs->layout_cb(ug, ug->mode, cbs->priv);
+
+ ugman_ug_getopt(ug);
+ }
+
+ ugman_ug_event(ug, ug_man.last_rotate_evt);
+
+ if(ug->mode == UG_MODE_FRAMEVIEW)
+ ugman_ug_start(ug);
+
+ ugman_tree_dump(ug_man.root);
+
+ return 0;
+}
+
+int ugman_ug_add(ui_gadget_h parent, ui_gadget_h ug)
+{
+ if (!ug_man.is_initted) {
+ _ERR("ugman_ug_add failed: manager is not initted");
+ return -1;
+ }
+
+ if (!ug_man.root) {
+ if (parent) {
+ _ERR("ugman_ug_add failed: parent has to be NULL w/o root");
+ errno = EINVAL;
+ return -1;
+ }
+
+ ug_man.root = ug_root_create();
+ if (!ug_man.root)
+ return -1;
+ ug_man.root->opt = ug_man.base_opt;
+ ug_man.root->layout = ug_man.win;
+ ug_fvlist_add(ug_man.root);
+ }
+
+ if (!parent)
+ parent = ug_man.root;
+
+ if (ug_relation_add(parent, ug))
+ return -1;
+
+ if (ugman_ug_create(ug) == -1)
+ return -1;
+
+ if (ug->mode == UG_MODE_FULLVIEW)
+ ug_fvlist_add(ug);
+
+ return 0;
+}
+
+ui_gadget_h ugman_ug_load(ui_gadget_h parent,
+ const char *name,
+ enum ug_mode mode,
+ service_h service, struct ug_cbs *cbs)
+{
+ int r;
+ ui_gadget_h ug;
+
+ ug = calloc(1, sizeof(struct ui_gadget_s));
+ if (!ug) {
+ _ERR("ug_create() failed: Memory allocation failed");
+ return NULL;
+ }
+
+ ug->module = ug_module_load(name);
+ if (!ug->module) {
+ _ERR("ug_create() failed: Module loading failed");
+ goto load_fail;
+ }
+
+ ug->name = strdup(name);
+
+ ug->mode = mode;
+ service_clone(&ug->service, service);
+ ug->opt = ug->module->ops.opt;
+ ug->state = UG_STATE_READY;
+ ug->children = NULL;
+
+ if (cbs)
+ memcpy(&ug->cbs, cbs, sizeof(struct ug_cbs));
+
+ r = ugman_ug_add(parent, ug);
+ if (r) {
+ _ERR("ug_create() failed: Tree update failed");
+ goto load_fail;
+ }
+
+ return ug;
+
+ load_fail:
+ ug_free(ug);
+ return NULL;
+}
+
+int ugman_ug_destroying(ui_gadget_h ug)
+{
+ struct ug_module_ops *ops = NULL;
+ GSList *child, *trail;
+
+ ug->destroy_me = 1;
+ ug->state = UG_STATE_DESTROYING;
+
+ if (ug->module)
+ ops = &ug->module->ops;
+
+ if (ug->children) {
+ child = ug->children;
+ while (child) {
+ trail = g_slist_next(child);
+ ugman_ug_destroying(child->data);
+ child = trail;
+ }
+ }
+
+ if (ops && ops->destroying)
+ ops->destroying(ug, ug->service, ops->priv);
+
+ return 0;
+}
+
+int ugman_ug_del(ui_gadget_h ug)
+{
+ struct ug_engine_ops *eng_ops = NULL;
+
+ if (!ug || !ugman_ug_exist(ug) || ug->state == UG_STATE_DESTROYED) {
+ _ERR("ugman_ug_del failed: Invalid ug");
+ errno = EINVAL;
+ return -1;
+ }
+
+ _DBG("ugman_ug_del start ug(%p)", ug);
+
+ if (ug->destroy_me) {
+ _ERR("ugman_ug_del failed: ug is alreay on destroying");
+ return -1;
+ }
+
+ if (!ug_man.is_initted) {
+ _ERR("ugman_ug_del failed: manager is not initted");
+ return -1;
+ }
+
+ if (!ug_man.root) {
+ _ERR("ugman_ug_del failed: no root");
+ return -1;
+ }
+
+ ugman_ug_destroying(ug);
+
+ /* pre call for indicator update time issue */
+ if (ug_man.fv_top == ug) {
+ ui_gadget_h t;
+ t = g_slist_nth_data(ug_man.fv_list, 1);
+ ugman_ug_getopt(t);
+ }
+
+ if (ug_man.engine)
+ eng_ops = &ug_man.engine->ops;
+
+ if (eng_ops && eng_ops->destroy)
+ if (ug->mode == UG_MODE_FULLVIEW)
+ eng_ops->destroy(ug, ug_man.fv_top, ug_hide_end_cb);
+ else {
+ eng_ops->destroy(ug, NULL, ug_hide_end_cb);
+ }
+ else
+ ecore_idler_add(ugman_ug_destroy, ug);
+
+ return 0;
+}
+
+int ugman_ug_del_all(void)
+{
+ /* Terminate */
+ if (!ug_man.is_initted) {
+ _ERR("ugman_ug_del_all failed: manager is not initted");
+ return -1;
+ }
+
+ if (!ug_man.root) {
+ _ERR("ugman_ug_del_all failed: no root");
+ return -1;
+ }
+
+ if (ug_man.walking > 0)
+ ug_man.destroy_all = 1;
+ else
+ ugman_ug_destroy(ug_man.root);
+
+ return 0;
+}
+
+int ugman_init(Display *disp, Window xid, void *win, enum ug_option opt)
+{
+ ug_man.is_initted = 1;
+ ug_man.win = win;
+ ug_man.disp = disp;
+ ug_man.win_id = xid;
+ ug_man.base_opt = opt;
+ ug_man.last_rotate_evt = UG_EVENT_ROTATE_PORTRAIT;
+ ug_man.engine = ug_engine_load();
+
+ return 0;
+}
+
+int ugman_resume(void)
+{
+ /* RESUME */
+ if (!ug_man.is_initted) {
+ _ERR("ugman_resume failed: manager is not initted");
+ return -1;
+ }
+
+ if (!ug_man.root) {
+ _ERR("ugman_resume failed: no root");
+ return -1;
+ }
+
+ ecore_idler_add(ugman_ug_resume, ug_man.root);
+
+ return 0;
+}
+
+int ugman_pause(void)
+{
+ /* PAUSE (Background) */
+ if (!ug_man.is_initted) {
+ _ERR("ugman_pause failed: manager is not initted");
+ return -1;
+ }
+
+ if (!ug_man.root) {
+ _ERR("ugman_pause failed: no root");
+ return -1;
+ }
+
+ ecore_idler_add(ugman_ug_pause, ug_man.root);
+
+ return 0;
+}
+
+static int ugman_send_event_pre(void *data)
+{
+ job_start();
+
+ ugman_ug_event(ug_man.root, (enum ug_event)data);
+
+ job_end();
+
+ return 0;
+}
+
+int ugman_send_event(enum ug_event event)
+{
+ int is_rotation = 1;
+
+ /* Propagate event */
+ if (!ug_man.is_initted) {
+ _ERR("ugman_send_event failed: manager is not initted");
+ return -1;
+ }
+
+ /* In case of rotation, indicator state has to be updated */
+ switch (event) {
+ case UG_EVENT_ROTATE_PORTRAIT:
+ case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN:
+ ug_man.last_rotate_evt = event;
+ ug_man.is_landscape = 0;
+ break;
+ case UG_EVENT_ROTATE_LANDSCAPE:
+ case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN:
+ ug_man.last_rotate_evt = event;
+ ug_man.is_landscape = 1;
+ break;
+ default:
+ is_rotation = 0;
+ }
+
+ if (!ug_man.root) {
+ _ERR("ugman_send_event failed: no root");
+ return -1;
+ }
+
+ ecore_idler_add(ugman_send_event_pre, (void *)event);
+
+ if (is_rotation && ug_man.fv_top)
+ ugman_indicator_update(ug_man.fv_top->opt, event);
+
+ return 0;
+}
+
+static int ugman_send_key_event_to_ug(ui_gadget_h ug,
+ enum ug_key_event event)
+{
+ struct ug_module_ops *ops = NULL;
+
+ if (!ug)
+ return -1;
+
+ if (ug->module) {
+ ops = &ug->module->ops;
+ } else {
+ return -1;
+ }
+
+ if (ops && ops->key_event) {
+ ops->key_event(ug, event, ug->service, ops->priv);
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+int ugman_send_key_event(enum ug_key_event event)
+{
+ if (!ug_man.is_initted) {
+ _ERR("ugman_send_key_event failed: manager is not initted");
+ return -1;
+ }
+
+ if (!ug_man.fv_top || !ugman_ug_exist(ug_man.fv_top)
+ || ug_man.fv_top->state == UG_STATE_DESTROYED) {
+ _ERR("ugman_send_key_event failed: full view top UG is invalid");
+ return -1;
+ }
+
+ return ugman_send_key_event_to_ug(ug_man.fv_top, event);
+}
+
+int ugman_send_message(ui_gadget_h ug, service_h msg)
+{
+ struct ug_module_ops *ops = NULL;
+ if (!ug || !ugman_ug_exist(ug) || ug->state == UG_STATE_DESTROYED) {
+ _ERR("ugman_send_message failed: Invalid ug");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (!msg) {
+ _ERR("ugman_send_message failed: Invalid msg");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (ug->module)
+ ops = &ug->module->ops;
+
+ if (ops && ops->message)
+ ops->message(ug, msg, ug->service, ops->priv);
+
+ return 0;
+}
+
+void *ugman_get_window(void)
+{
+ return ug_man.win;
+}
+
+void *ugman_get_conformant(void)
+{
+ return ug_man.conform;
+}
+
+
+static inline void job_start(void)
+{
+ ug_man.walking++;
+}
+
+static inline void job_end(void)
+{
+ ug_man.walking--;
+
+ if (!ug_man.walking && ug_man.destroy_all) {
+ ug_man.destroy_all = 0;
+ if (ug_man.root)
+ ugman_ug_destroy(ug_man.root);
+ }
+
+ if (ug_man.walking < 0)
+ ug_man.walking = 0;
+}
+
+int ugman_ug_exist(ui_gadget_h ug)
+{
+ return ugman_ug_find(ug_man.root, ug);
+}
diff --git a/src/module.c b/src/module.c
new file mode 100644
index 0000000..da518d3
--- /dev/null
+++ b/src/module.c
@@ -0,0 +1,138 @@
+/*
+ * UI Gadget
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <linux/limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <app_manager.h>
+
+#include "ug-module.h"
+#include "ug-dbg.h"
+
+#define UG_MODULE_INIT_SYM "UG_MODULE_INIT"
+#define UG_MODULE_EXIT_SYM "UG_MODULE_EXIT"
+
+static int file_exist(const char *filename)
+{
+ FILE *file;
+ if ((file = fopen(filename, "r"))) {
+ fclose(file);
+ return 1;
+ }
+
+ return 0;
+}
+
+struct ug_module *ug_module_load(const char *name)
+{
+ void *handle;
+ struct ug_module *module;
+ char ug_file[PATH_MAX];
+ char *pkg_name = NULL;
+
+ int (*module_init) (struct ug_module_ops *ops);
+
+ module = calloc(1, sizeof(struct ug_module));
+
+ if (!module) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ app_manager_get_package(getpid(), &pkg_name);
+
+ do {
+ if (pkg_name) {
+ snprintf(ug_file, PATH_MAX, "/usr/apps/%s/lib/libug-%s.so", pkg_name, name);
+ if (file_exist(ug_file))
+ break;
+ snprintf(ug_file, PATH_MAX, "/opt/apps/%s/lib/libug-%s.so", pkg_name, name);
+ if (file_exist(ug_file))
+ break;
+ }
+ snprintf(ug_file, PATH_MAX, "/usr/ug/lib/libug-%s.so", name);
+ if (file_exist(ug_file))
+ break;
+ snprintf(ug_file, PATH_MAX, "/opt/usr/ug/lib/libug-%s.so", name);
+ if (file_exist(ug_file))
+ break;
+ } while (0);
+
+ if(pkg_name) {
+ free(pkg_name);
+ pkg_name = NULL;
+ }
+
+ handle = dlopen(ug_file, RTLD_LAZY);
+ if (!handle) {
+ _ERR("dlopen failed: %s", dlerror());
+ goto module_free;
+ }
+
+ module_init = dlsym(handle, UG_MODULE_INIT_SYM);
+ if (!module_init) {
+ _ERR("dlsym failed: %s", dlerror());
+ goto module_dlclose;
+ }
+
+ if (module_init(&module->ops))
+ goto module_dlclose;
+
+ module->handle = handle;
+ return module;
+
+ module_dlclose:
+ dlclose(handle);
+
+ module_free:
+ free(module);
+ return NULL;
+}
+
+int ug_module_unload(struct ug_module *module)
+{
+ void (*module_exit) (struct ug_module_ops *ops);
+
+ if (!module) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (module->handle) {
+ module_exit = dlsym(module->handle, UG_MODULE_EXIT_SYM);
+ if (module_exit)
+ module_exit(&module->ops);
+ else
+ _ERR("dlsym failed: %s", dlerror());
+
+ dlclose(module->handle);
+ module->handle = NULL;
+ }
+
+ free(module);
+ return 0;
+}
diff --git a/src/ug.c b/src/ug.c
new file mode 100755
index 0000000..09f4679
--- /dev/null
+++ b/src/ug.c
@@ -0,0 +1,283 @@
+/*
+ * UI Gadget
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "ug.h"
+#include "ug-module.h"
+#include "ug-manager.h"
+#include "ug-dbg.h"
+
+#ifndef UG_API
+#define UG_API __attribute__ ((visibility("default")))
+#endif
+
+ui_gadget_h ug_root_create(void)
+{
+ ui_gadget_h ug;
+
+ ug = calloc(1, sizeof(struct ui_gadget_s));
+ if (!ug) {
+ _ERR("ug root create failed: Memory allocation failed");
+ return NULL;
+ }
+
+ ug->mode = UG_MODE_FULLVIEW;
+ ug->state = UG_STATE_RUNNING;
+ ug->children = NULL;
+
+ return ug;
+}
+
+int ug_free(ui_gadget_h ug)
+{
+ if (!ug) {
+ _ERR("ug free failed: Invalid ug");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (ug->module) {
+ ug_module_unload(ug->module);
+ }
+ if (ug->name) {
+ free((void *)ug->name);
+ ug->name = NULL;
+ }
+ if (ug->service) {
+ service_destroy(ug->service);
+ ug->service = NULL;
+ }
+ free(ug);
+ ug = NULL;
+ return 0;
+}
+
+UG_API ui_gadget_h ug_create(ui_gadget_h parent,
+ const char *name,
+ enum ug_mode mode,
+ service_h service, struct ug_cbs *cbs)
+{
+ if (!name) {
+ _ERR("ug_create() failed: Invalid name");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (mode < UG_MODE_FULLVIEW || mode >= UG_MODE_INVALID) {
+ _ERR("ug_create() failed: Invalid mode");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ return ugman_ug_load(parent, name, mode, service, cbs);
+}
+
+UG_API int ug_init(Display *disp, Window xid, void *win, enum ug_option opt)
+{
+ if (!win || !xid || !disp) {
+ _ERR("ug_init() failed: Invalid arguments");
+ return -1;
+ }
+
+ if (opt < UG_OPT_INDICATOR_ENABLE || opt >= UG_OPT_MAX) {
+ _ERR("ug_init() failed: Invalid option");
+ return -1;
+ }
+
+ return ugman_init(disp, xid, win, opt);
+}
+
+UG_API int ug_pause(void)
+{
+ return ugman_pause();
+}
+
+UG_API int ug_resume(void)
+{
+ return ugman_resume();
+}
+
+UG_API int ug_destroy(ui_gadget_h ug)
+{
+ return ugman_ug_del(ug);
+}
+
+UG_API int ug_destroy_all(void)
+{
+ return ugman_ug_del_all();
+}
+
+UG_API int ug_destroy_me(ui_gadget_h ug)
+{
+ if (!ug || !ugman_ug_exist(ug)) {
+ _ERR("ug_destroy_me() failed: Invalid ug");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (ug->state == UG_STATE_DESTROYING) {
+ _ERR("ug_destory_me() failed:ug is alreay on destroying");
+ return -1;
+ }
+
+ if (!ug->cbs.destroy_cb) {
+ _ERR("ug_destroy_me() failed: destroy callback does not "
+ "exist");
+ return -1;
+ }
+
+ ug->cbs.destroy_cb(ug, ug->cbs.priv);
+ return 0;
+}
+
+UG_API void *ug_get_layout(ui_gadget_h ug)
+{
+ if (!ug || !ugman_ug_exist(ug)) {
+ _ERR("ug_get_layout() failed: Invalid ug");
+ errno = EINVAL;
+ return NULL;
+ }
+ return ug->layout;
+}
+
+UG_API void *ug_get_parent_layout(ui_gadget_h ug)
+{
+ ui_gadget_h parent;
+ if (!ug || !ugman_ug_exist(ug)) {
+ _ERR("ug_get_parent_layout() failed: Invalid ug");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ parent = ug->parent;
+
+ if (parent)
+ return parent->layout;
+ return NULL;
+}
+
+UG_API enum ug_mode ug_get_mode(ui_gadget_h ug)
+{
+ if (!ug || !ugman_ug_exist(ug)) {
+ _ERR("ug_get_mode() failed: Invalid ug");
+ errno = EINVAL;
+ return UG_MODE_INVALID;
+ }
+
+ return ug->mode;
+}
+
+UG_API void *ug_get_window(void)
+{
+ return ugman_get_window();
+}
+
+UG_API void *ug_get_conformant(void)
+{
+ return ugman_get_conformant();
+}
+
+UG_API int ug_send_event(enum ug_event event)
+{
+ if (event <= UG_EVENT_NONE || event >= UG_EVENT_MAX) {
+ _ERR("ug_send_event() failed: Invalid event");
+ return -1;
+ }
+
+ return ugman_send_event(event);
+}
+
+UG_API int ug_send_key_event(enum ug_key_event event)
+{
+ if (event <= UG_KEY_EVENT_NONE || event >= UG_KEY_EVENT_MAX) {
+ _ERR("ug_send_key_event() failed: Invalid event");
+ return -1;
+ }
+
+ return ugman_send_key_event(event);
+}
+
+UG_API int ug_send_result(ui_gadget_h ug, service_h result)
+{
+ service_h result_dup = NULL;
+
+ if (!ug || !ugman_ug_exist(ug)) {
+ _ERR("ug_send_result() failed: Invalid ug");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (!ug->cbs.result_cb) {
+ _ERR("ug_send_result() failed: result callback does not exist");
+ return -1;
+ }
+
+ if (result) {
+ service_clone(&result_dup, result);
+ if (!result_dup) {
+ _ERR("ug_send_result() failed: service_destroy failed");
+ return -1;
+ }
+ }
+
+ ug->cbs.result_cb(ug, result_dup, ug->cbs.priv);
+
+ if (result_dup)
+ service_destroy(result_dup);
+
+ return 0;
+}
+
+UG_API int ug_send_message(ui_gadget_h ug, service_h msg)
+{
+ int r;
+
+ service_h msg_dup = NULL;
+ if (msg) {
+ service_clone(&msg_dup, msg);
+ if (!msg_dup) {
+ _ERR("ug_send_message() failed: service_destroy failed");
+ return -1;
+ }
+ }
+
+ r = ugman_send_message(ug, msg_dup);
+
+ if (msg_dup)
+ service_destroy(msg_dup);
+
+ return r;
+}
+
+UG_API int ug_disable_effect(ui_gadget_h ug)
+{
+ if (ug->layout_state != UG_LAYOUT_INIT) {
+ _ERR("ug_disable_effect() failed: ug has already been shown");
+ return -1;
+ }
+ ug->layout_state = UG_LAYOUT_NOEFFECT;
+
+ return 0;
+}