diff options
author | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:46:42 +0900 |
---|---|---|
committer | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:46:42 +0900 |
commit | 7596e199c101a324ac0bbab1be727962fe0ebf07 (patch) | |
tree | cc97cc634e3234446670bc6c7d455bd1be5dd806 /src | |
parent | c3875cbe2f8e945b837a76ac5f8e6d57bde940bb (diff) | |
download | ui-gadget-1-7596e199c101a324ac0bbab1be727962fe0ebf07.tar.gz ui-gadget-1-7596e199c101a324ac0bbab1be727962fe0ebf07.tar.bz2 ui-gadget-1-7596e199c101a324ac0bbab1be727962fe0ebf07.zip |
Tizen 2.1 base
Diffstat (limited to 'src')
-rwxr-xr-x | src/engine.c | 128 | ||||
-rwxr-xr-x | src/manager.c | 848 | ||||
-rw-r--r-- | src/module.c | 138 | ||||
-rwxr-xr-x | src/ug.c | 283 |
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; +} |