2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
29 #include "ug-manager.h"
30 #include "ug-engine.h"
34 struct ui_gadget *root;
35 struct ui_gadget *fv_top;
42 enum ug_option base_opt;
43 enum ug_event last_rotate_evt;
51 struct ug_engine *engine;
54 static struct ug_manager ug_man;
56 static inline void job_start(void);
57 static inline void job_end(void);
59 static int ug_relation_add(struct ui_gadget *p, struct ui_gadget *c)
62 /* prepend element to avoid the inefficiency,
63 which is to traverse the entire list to find the end*/
64 p->children = g_slist_prepend(p->children, c);
69 static int ug_relation_del(struct ui_gadget *ug)
75 _ERR("ug_relation_del failed: no parent\n");
78 p->children = g_slist_remove(p->children, ug);
80 g_slist_free(ug->children);
86 static int ug_fvlist_add(struct ui_gadget *c)
88 ug_man.fv_list = g_slist_prepend(ug_man.fv_list, c);
94 static int ug_fvlist_del(struct ui_gadget *c)
98 ug_man.fv_list = g_slist_remove(ug_man.fv_list, c);
100 /* update fullview top ug*/
101 t = g_slist_nth_data(ug_man.fv_list, 0);
107 static void ugman_tree_dump(struct ui_gadget *ug)
119 if (ug == ug_man.root) {
121 _DBG("\n============== TREE_DUMP =============\n");
122 _DBG("ROOT: Manager\n");
126 child = ug->children;
135 _DBG("[%d] %s [%c] (%p) (PARENT: %s)\n",
137 c && c->name ? c->name : "NO CHILD INFO FIXIT!!!",
138 c && c->mode == UG_MODE_FULLVIEW ? 'F' : 'f', c, name);
140 child = g_slist_next(child);
144 static int ugman_ug_find(struct ui_gadget *p, struct ui_gadget *ug)
146 GSList *child = NULL;
153 if (child->data == ug)
155 if (ugman_ug_find(child->data, ug))
157 child = g_slist_next(child);
163 static int ugman_ug_start(void *data)
165 struct ui_gadget *ug = data;
166 struct ug_module_ops *ops = NULL;
168 if (!ug || ug->state != UG_STATE_CREATED
169 || ug->state == UG_STATE_RUNNING)
172 ug->state = UG_STATE_RUNNING;
175 ops = &ug->module->ops;
177 if (ops && ops->start)
178 ops->start(ug, ug->data, ops->priv);
183 static int ugman_ug_pause(void *data)
185 struct ui_gadget *ug = data;
186 struct ug_module_ops *ops = NULL;
187 GSList *child = NULL;
191 if (!ug || ug->state != UG_STATE_RUNNING)
194 ug->state = UG_STATE_STOPPED;
197 child = ug->children;
199 ugman_ug_pause(child->data);
200 child = g_slist_next(child);
205 ops = &ug->module->ops;
207 if (ops && ops->pause)
208 ops->pause(ug, ug->data, ops->priv);
215 static int ugman_ug_resume(void *data)
217 struct ui_gadget *ug = data;
218 struct ug_module_ops *ops = NULL;
219 GSList *child = NULL;
227 case UG_STATE_CREATED:
230 case UG_STATE_STOPPED:
236 ug->state = UG_STATE_RUNNING;
239 child = ug->children;
241 ugman_ug_resume(child->data);
242 child = g_slist_next(child);
247 ops = &ug->module->ops;
249 if (ops && ops->resume)
250 ops->resume(ug, ug->data, ops->priv);
257 static int ugman_indicator_update(enum ug_option opt, enum ug_event event)
263 _ERR("ugman_indicator_update failed: no window\n");
267 switch (UG_OPT_INDICATOR(opt)) {
268 case UG_OPT_INDICATOR_ENABLE:
269 if (event == UG_EVENT_NONE)
272 cur_state = utilx_get_indicator_state(ug_man.disp, ug_man.win_id);
273 enable = cur_state ? 1 : 0;
276 case UG_OPT_INDICATOR_PORTRAIT_ONLY:
277 enable = ug_man.is_landscape ? 0 : 1;
279 case UG_OPT_INDICATOR_LANDSCAPE_ONLY:
280 enable = ug_man.is_landscape ? 1 : 0;
282 case UG_OPT_INDICATOR_DISABLE:
286 _ERR("ugman_indicator_update failed: Invalid opt\n");
290 utilx_enable_indicator(ug_man.disp, ug_man.win_id, enable);
295 static int ugman_ug_getopt(struct ui_gadget *ug)
299 /* Indicator Option */
300 if (ug->mode == UG_MODE_FULLVIEW)
301 ugman_indicator_update(UG_OPT_INDICATOR(ug->opt), UG_EVENT_NONE);
306 static int ugman_ug_event(struct ui_gadget *ug, enum ug_event event)
308 struct ug_module_ops *ops = NULL;
309 GSList *child = NULL;
315 child = ug->children;
317 ugman_ug_event(child->data, event);
318 child = g_slist_next(child);
323 ops = &ug->module->ops;
325 if (ops && ops->event)
326 ops->event(ug, event, ug->data, ops->priv);
331 static int ugman_ug_destroy(void *data)
333 struct ui_gadget *ug = data;
334 struct ug_module_ops *ops = NULL;
335 GSList *child, *trail;
343 case UG_STATE_CREATED:
344 case UG_STATE_RUNNING:
345 case UG_STATE_STOPPED:
346 case UG_STATE_DESTROYING:
352 ug->state = UG_STATE_DESTROYED;
355 ops = &ug->module->ops;
358 child = ug->children;
360 trail = g_slist_next(child);
361 ugman_ug_destroy(child->data);
366 if (ops && ops->destroy)
367 ops->destroy(ug, ug->data, ops->priv);
371 if (ug->mode == UG_MODE_FULLVIEW) {
372 if (ug_man.fv_top == ug) {
374 ugman_ug_getopt(ug_man.fv_top);
382 if (ug_man.root == ug)
385 ugman_tree_dump(ug_man.root);
392 static void ug_hide_end_cb(struct ui_gadget *ug)
394 g_idle_add(ugman_ug_destroy, ug);
397 static int ugman_ug_create(void *data)
399 struct ui_gadget *ug = data;
400 struct ug_module_ops *ops = NULL;
402 struct ug_engine_ops *eng_ops = NULL;
404 if (!ug || ug->state != UG_STATE_READY)
407 ug->state = UG_STATE_CREATED;
410 ops = &ug->module->ops;
413 eng_ops = &ug_man.engine->ops;
415 if (ops && ops->create) {
416 ug->layout = ops->create(ug, ug->mode, ug->data, 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(struct ui_gadget *parent, struct ui_gadget *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 struct ui_gadget *ugman_ug_load(struct ui_gadget *parent,
481 bundle *data, struct ug_cbs *cbs)
484 struct ui_gadget *ug;
486 ug = calloc(1, sizeof(struct ui_gadget));
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 ug->data = bundle_dup(data);
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(struct ui_gadget *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->data, ops->priv);
548 int ugman_ug_del(struct ui_gadget *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);
575 if (ug->mode == UG_MODE_FULLVIEW) {
577 eng_ops = &ug_man.engine->ops;
579 if (eng_ops && eng_ops->destroy) {
580 eng_ops->destroy(ug, ug_man.fv_top);
583 g_idle_add(ugman_ug_destroy, ug);
587 g_idle_add(ugman_ug_destroy, ug);
593 int ugman_ug_del_all(void)
596 if (!ug_man.is_initted) {
597 _ERR("ugman_ug_del_all failed: manager is not initted\n");
602 _ERR("ugman_ug_del_all failed: no root\n");
606 if (ug_man.walking > 0)
607 ug_man.destroy_all = 1;
609 ugman_ug_destroy(ug_man.root);
614 int ugman_init(Display *disp, Window xid, void *win, enum ug_option opt)
616 ug_man.is_initted = 1;
620 ug_man.base_opt = opt;
621 ug_man.last_rotate_evt = UG_EVENT_ROTATE_PORTRAIT;
622 ug_man.engine = ug_engine_load();
627 int ugman_resume(void)
630 if (!ug_man.is_initted) {
631 _ERR("ugman_resume failed: manager is not initted\n");
636 _ERR("ugman_resume failed: no root\n");
640 g_idle_add(ugman_ug_resume, ug_man.root);
645 int ugman_pause(void)
647 /* PAUSE (Background) */
648 if (!ug_man.is_initted) {
649 _ERR("ugman_pause failed: manager is not initted\n");
654 _ERR("ugman_pause failed: no root\n");
658 g_idle_add(ugman_ug_pause, ug_man.root);
663 static int ugman_send_event_pre(void *data)
667 ugman_ug_event(ug_man.root, (enum ug_event)data);
674 int ugman_send_event(enum ug_event event)
678 /* Propagate event */
679 if (!ug_man.is_initted) {
680 _ERR("ugman_send_event failed: manager is not initted\n");
684 /* In case of rotation, indicator state has to be updated */
686 case UG_EVENT_ROTATE_PORTRAIT:
687 case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN:
688 ug_man.last_rotate_evt = event;
689 ug_man.is_landscape = 0;
691 case UG_EVENT_ROTATE_LANDSCAPE:
692 case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN:
693 ug_man.last_rotate_evt = event;
694 ug_man.is_landscape = 1;
701 _ERR("ugman_send_event failed: no root\n");
705 g_idle_add(ugman_send_event_pre, (void *)event);
707 if (is_rotation && ug_man.fv_top)
708 ugman_indicator_update(UG_OPT_INDICATOR(ug_man.fv_top->opt), event);
713 static int ugman_send_key_event_to_ug(struct ui_gadget *ug,
714 enum ug_key_event event)
716 struct ug_module_ops *ops = NULL;
722 ops = &ug->module->ops;
727 if (ops && ops->key_event) {
728 ops->key_event(ug, event, ug->data, ops->priv);
736 int ugman_send_key_event(enum ug_key_event event)
738 if (!ug_man.is_initted) {
739 _ERR("ugman_send_key_event failed: manager is not initted\n");
743 if (!ug_man.fv_top || !ugman_ug_exist(ug_man.fv_top)
744 || ug_man.fv_top->state == UG_STATE_DESTROYED) {
745 _ERR("ugman_send_key_event failed: full view top UG is invalid\n");
749 return ugman_send_key_event_to_ug(ug_man.fv_top, event);
752 int ugman_send_message(struct ui_gadget *ug, bundle *msg)
754 struct ug_module_ops *ops = NULL;
755 if (!ug || !ugman_ug_exist(ug) || ug->state == UG_STATE_DESTROYED) {
756 _ERR("ugman_send_message failed: Invalid ug\n");
762 _ERR("ugman_send_message failed: Invalid msg\n");
768 ops = &ug->module->ops;
770 if (ops && ops->message)
771 ops->message(ug, msg, ug->data, ops->priv);
776 void *ugman_get_window(void)
781 static inline void job_start(void)
786 static inline void job_end(void)
790 if (!ug_man.walking && ug_man.destroy_all) {
791 ug_man.destroy_all = 0;
793 ugman_ug_destroy(ug_man.root);
796 if (ug_man.walking < 0)
800 int ugman_ug_exist(struct ui_gadget *ug)
802 return ugman_ug_find(ug_man.root, ug);