4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
30 #include "ug-manager.h"
31 #include "ug-engine.h"
43 enum ug_option base_opt;
44 enum ug_event last_rotate_evt;
52 struct ug_engine *engine;
55 static struct ug_manager ug_man;
57 static inline void job_start(void);
58 static inline void job_end(void);
60 static int ug_relation_add(ui_gadget_h p, ui_gadget_h c)
63 /* prepend element to avoid the inefficiency,
64 which is to traverse the entire list to find the end*/
65 p->children = g_slist_prepend(p->children, c);
70 static int ug_relation_del(ui_gadget_h ug)
76 _ERR("ug_relation_del failed: no parent\n");
79 p->children = g_slist_remove(p->children, ug);
81 g_slist_free(ug->children);
87 static int ug_fvlist_add(ui_gadget_h c)
89 ug_man.fv_list = g_slist_prepend(ug_man.fv_list, c);
95 static int ug_fvlist_del(ui_gadget_h c)
99 ug_man.fv_list = g_slist_remove(ug_man.fv_list, c);
101 /* update fullview top ug*/
102 t = g_slist_nth_data(ug_man.fv_list, 0);
108 static void ugman_tree_dump(ui_gadget_h ug)
120 if (ug == ug_man.root) {
122 _DBG("\n============== TREE_DUMP =============\n");
123 _DBG("ROOT: Manager\n");
127 child = ug->children;
136 _DBG("[%d] %s [%c] (%p) (PARENT: %s)\n",
138 c && c->name ? c->name : "NO CHILD INFO FIXIT!!!",
139 c && c->mode == UG_MODE_FULLVIEW ? 'F' : 'f', c, name);
141 child = g_slist_next(child);
145 static int ugman_ug_find(ui_gadget_h p, ui_gadget_h ug)
147 GSList *child = NULL;
154 if (child->data == ug)
156 if (ugman_ug_find(child->data, ug))
158 child = g_slist_next(child);
164 static int ugman_ug_start(void *data)
166 ui_gadget_h ug = data;
167 struct ug_module_ops *ops = NULL;
169 if (!ug || ug->state != UG_STATE_CREATED
170 || ug->state == UG_STATE_RUNNING)
173 ug->state = UG_STATE_RUNNING;
176 ops = &ug->module->ops;
178 if (ops && ops->start)
179 ops->start(ug, ug->service, ops->priv);
184 static int ugman_ug_pause(void *data)
186 ui_gadget_h ug = data;
187 struct ug_module_ops *ops = NULL;
188 GSList *child = NULL;
192 if (!ug || ug->state != UG_STATE_RUNNING)
195 ug->state = UG_STATE_STOPPED;
198 child = ug->children;
200 ugman_ug_pause(child->data);
201 child = g_slist_next(child);
206 ops = &ug->module->ops;
208 if (ops && ops->pause)
209 ops->pause(ug, ug->service, ops->priv);
216 static int ugman_ug_resume(void *data)
218 ui_gadget_h ug = data;
219 struct ug_module_ops *ops = NULL;
220 GSList *child = NULL;
228 case UG_STATE_CREATED:
231 case UG_STATE_STOPPED:
237 ug->state = UG_STATE_RUNNING;
240 child = ug->children;
242 ugman_ug_resume(child->data);
243 child = g_slist_next(child);
248 ops = &ug->module->ops;
250 if (ops && ops->resume)
251 ops->resume(ug, ug->service, ops->priv);
258 static int ugman_indicator_update(enum ug_option opt, enum ug_event event)
264 _ERR("ugman_indicator_update failed: no window\n");
268 switch (UG_OPT_INDICATOR(opt)) {
269 case UG_OPT_INDICATOR_ENABLE:
270 if (event == UG_EVENT_NONE)
273 cur_state = utilx_get_indicator_state(ug_man.disp, ug_man.win_id);
274 enable = cur_state ? 1 : 0;
277 case UG_OPT_INDICATOR_PORTRAIT_ONLY:
278 enable = ug_man.is_landscape ? 0 : 1;
280 case UG_OPT_INDICATOR_LANDSCAPE_ONLY:
281 enable = ug_man.is_landscape ? 1 : 0;
283 case UG_OPT_INDICATOR_DISABLE:
287 _ERR("ugman_indicator_update failed: Invalid opt\n");
291 utilx_enable_indicator(ug_man.disp, ug_man.win_id, enable);
296 static int ugman_ug_getopt(ui_gadget_h ug)
300 /* Indicator Option */
301 if (ug->mode == UG_MODE_FULLVIEW)
302 ugman_indicator_update(UG_OPT_INDICATOR(ug->opt), UG_EVENT_NONE);
307 static int ugman_ug_event(ui_gadget_h ug, enum ug_event event)
309 struct ug_module_ops *ops = NULL;
310 GSList *child = NULL;
316 child = ug->children;
318 ugman_ug_event(child->data, event);
319 child = g_slist_next(child);
324 ops = &ug->module->ops;
326 if (ops && ops->event)
327 ops->event(ug, event, ug->service, ops->priv);
332 static int ugman_ug_destroy(void *data)
334 ui_gadget_h ug = data;
335 struct ug_module_ops *ops = NULL;
336 GSList *child, *trail;
344 case UG_STATE_CREATED:
345 case UG_STATE_RUNNING:
346 case UG_STATE_STOPPED:
347 case UG_STATE_DESTROYING:
353 ug->state = UG_STATE_DESTROYED;
356 ops = &ug->module->ops;
359 child = ug->children;
361 trail = g_slist_next(child);
362 ugman_ug_destroy(child->data);
367 if (ops && ops->destroy)
368 ops->destroy(ug, ug->service, ops->priv);
372 if (ug->mode == UG_MODE_FULLVIEW) {
373 if (ug_man.fv_top == ug) {
375 ugman_ug_getopt(ug_man.fv_top);
383 if (ug_man.root == ug)
386 ugman_tree_dump(ug_man.root);
393 static void ug_hide_end_cb(ui_gadget_h ug)
395 g_idle_add(ugman_ug_destroy, ug);
398 static int ugman_ug_create(void *data)
400 ui_gadget_h ug = data;
401 struct ug_module_ops *ops = NULL;
403 struct ug_engine_ops *eng_ops = NULL;
405 if (!ug || ug->state != UG_STATE_READY)
408 ug->state = UG_STATE_CREATED;
411 ops = &ug->module->ops;
414 eng_ops = &ug_man.engine->ops;
416 if (ops && ops->create) {
417 ug->layout = ops->create(ug, ug->mode, ug->service, ops->priv);
422 if (ug->mode == UG_MODE_FULLVIEW) {
423 if (eng_ops && eng_ops->create)
424 ug->effect_layout = eng_ops->create(ug_man.win, ug, ug_hide_end_cb);
428 if (cbs && cbs->layout_cb)
429 cbs->layout_cb(ug, ug->mode, cbs->priv);
434 ugman_ug_event(ug, ug_man.last_rotate_evt);
436 ugman_tree_dump(ug_man.root);
441 int ugman_ug_add(ui_gadget_h parent, ui_gadget_h ug)
443 if (!ug_man.is_initted) {
444 _ERR("ugman_ug_add failed: manager is not initted\n");
450 _ERR("ugman_ug_add failed: parent has to be NULL w/o root\n");
455 ug_man.root = ug_root_create();
458 ug_man.root->opt = ug_man.base_opt;
459 ug_man.root->layout = ug_man.win;
460 ug_fvlist_add(ug_man.root);
464 parent = ug_man.root;
466 if (ug_relation_add(parent, ug))
469 if (ugman_ug_create(ug) == -1)
472 if (ug->mode == UG_MODE_FULLVIEW)
478 ui_gadget_h ugman_ug_load(ui_gadget_h parent,
481 service_h service, struct ug_cbs *cbs)
486 ug = calloc(1, sizeof(struct ui_gadget_s));
488 _ERR("ug_create() failed: Memory allocation failed\n");
492 ug->module = ug_module_load(name);
494 _ERR("ug_create() failed: Module loading failed\n");
498 ug->name = strdup(name);
501 service_clone(&ug->service, service);
502 ug->opt = ug->module->ops.opt;
503 ug->state = UG_STATE_READY;
507 memcpy(&ug->cbs, cbs, sizeof(struct ug_cbs));
509 r = ugman_ug_add(parent, ug);
511 _ERR("ug_create() failed: Tree update failed\n");
522 int ugman_ug_destroying(ui_gadget_h ug)
524 struct ug_module_ops *ops = NULL;
525 GSList *child, *trail;
528 ug->state = UG_STATE_DESTROYING;
531 ops = &ug->module->ops;
534 child = ug->children;
536 trail = g_slist_next(child);
537 ugman_ug_destroying(child->data);
542 if (ops && ops->destroying)
543 ops->destroying(ug, ug->service, ops->priv);
548 int ugman_ug_del(ui_gadget_h ug)
550 struct ug_engine_ops *eng_ops = NULL;
552 if (!ug || !ugman_ug_exist(ug) || ug->state == UG_STATE_DESTROYED) {
553 _ERR("ugman_ug_del failed: Invalid ug\n");
558 if (ug->destroy_me) {
559 _ERR("ugman_ug_del failed: ug is alreay on destroying\n");
563 if (!ug_man.is_initted) {
564 _ERR("ugman_ug_del failed: manager is not initted\n");
569 _ERR("ugman_ug_del failed: no root\n");
573 ugman_ug_destroying(ug);
576 eng_ops = &ug_man.engine->ops;
578 if (eng_ops && eng_ops->destroy)
579 if (ug->mode == UG_MODE_FULLVIEW)
580 eng_ops->destroy(ug, ug_man.fv_top);
582 eng_ops->destroy(ug, NULL);
583 g_idle_add(ugman_ug_destroy, ug);
586 g_idle_add(ugman_ug_destroy, ug);
591 int ugman_ug_del_all(void)
594 if (!ug_man.is_initted) {
595 _ERR("ugman_ug_del_all failed: manager is not initted\n");
600 _ERR("ugman_ug_del_all failed: no root\n");
604 if (ug_man.walking > 0)
605 ug_man.destroy_all = 1;
607 ugman_ug_destroy(ug_man.root);
612 int ugman_init(Display *disp, Window xid, void *win, enum ug_option opt)
614 ug_man.is_initted = 1;
618 ug_man.base_opt = opt;
619 ug_man.last_rotate_evt = UG_EVENT_ROTATE_PORTRAIT;
620 ug_man.engine = ug_engine_load();
625 int ugman_resume(void)
628 if (!ug_man.is_initted) {
629 _ERR("ugman_resume failed: manager is not initted\n");
634 _ERR("ugman_resume failed: no root\n");
638 g_idle_add(ugman_ug_resume, ug_man.root);
643 int ugman_pause(void)
645 /* PAUSE (Background) */
646 if (!ug_man.is_initted) {
647 _ERR("ugman_pause failed: manager is not initted\n");
652 _ERR("ugman_pause failed: no root\n");
656 g_idle_add(ugman_ug_pause, ug_man.root);
661 static int ugman_send_event_pre(void *data)
665 ugman_ug_event(ug_man.root, (enum ug_event)data);
672 int ugman_send_event(enum ug_event event)
676 /* Propagate event */
677 if (!ug_man.is_initted) {
678 _ERR("ugman_send_event failed: manager is not initted\n");
682 /* In case of rotation, indicator state has to be updated */
684 case UG_EVENT_ROTATE_PORTRAIT:
685 case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN:
686 ug_man.last_rotate_evt = event;
687 ug_man.is_landscape = 0;
689 case UG_EVENT_ROTATE_LANDSCAPE:
690 case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN:
691 ug_man.last_rotate_evt = event;
692 ug_man.is_landscape = 1;
699 _ERR("ugman_send_event failed: no root\n");
703 g_idle_add(ugman_send_event_pre, (void *)event);
705 if (is_rotation && ug_man.fv_top)
706 ugman_indicator_update(UG_OPT_INDICATOR(ug_man.fv_top->opt), event);
711 static int ugman_send_key_event_to_ug(ui_gadget_h ug,
712 enum ug_key_event event)
714 struct ug_module_ops *ops = NULL;
720 ops = &ug->module->ops;
725 if (ops && ops->key_event) {
726 ops->key_event(ug, event, ug->service, ops->priv);
734 int ugman_send_key_event(enum ug_key_event event)
736 if (!ug_man.is_initted) {
737 _ERR("ugman_send_key_event failed: manager is not initted\n");
741 if (!ug_man.fv_top || !ugman_ug_exist(ug_man.fv_top)
742 || ug_man.fv_top->state == UG_STATE_DESTROYED) {
743 _ERR("ugman_send_key_event failed: full view top UG is invalid\n");
747 return ugman_send_key_event_to_ug(ug_man.fv_top, event);
750 int ugman_send_message(ui_gadget_h ug, service_h msg)
752 struct ug_module_ops *ops = NULL;
753 if (!ug || !ugman_ug_exist(ug) || ug->state == UG_STATE_DESTROYED) {
754 _ERR("ugman_send_message failed: Invalid ug\n");
760 _ERR("ugman_send_message failed: Invalid msg\n");
766 ops = &ug->module->ops;
768 if (ops && ops->message)
769 ops->message(ug, msg, ug->service, ops->priv);
774 void *ugman_get_window(void)
779 static inline void job_start(void)
784 static inline void job_end(void)
788 if (!ug_man.walking && ug_man.destroy_all) {
789 ug_man.destroy_all = 0;
791 ugman_ug_destroy(ug_man.root);
794 if (ug_man.walking < 0)
798 int ugman_ug_exist(ui_gadget_h ug)
800 return ugman_ug_find(ug_man.root, ug);