c277ae3ace04eb26ef32d05294d646f597486cdf
[apps/core/preloaded/quickpanel.git] / daemon / quickpanel-ui.c
1 /*
2  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18
19 #include <stdio.h>
20 #include <signal.h>
21 #include <sys/utsname.h>
22 #include <Elementary.h>
23 #include <Ecore_Input.h>
24 #include <unistd.h>
25 #include <malloc.h>
26
27 #include <app.h>
28 #include <vconf.h>
29 #include <E_DBus.h>
30 #include <tapi_common.h>
31 #include <ITapiSim.h>
32 #include <tzsh_quickpanel_service.h>
33 #include <notification.h>
34 #include <sound_manager.h>
35 #include <media.h>
36 #include <system_settings.h>
37
38 #if defined(WINSYS_X11)
39 #include <X11/Xlib.h>
40 #include <utilX.h>
41 #include <Ecore_X.h>
42 #endif
43 #include <privilege-control.h>
44
45 /* quickpanel basics */
46 #include "common.h"
47 #include "common_uic.h"
48 #include "quickpanel-ui.h"
49 #include "modules.h"
50 #include "quickpanel_def.h"
51 #include "list_util.h"
52 #include "noti_node.h"
53 #include "vi_manager.h"
54 #include "pager.h"
55 #include "page_base.h"
56 #ifdef QP_ENABLE_PAGE_EDIT
57 #include "page_edit.h"
58 #else
59 #include "page_setting_all.h"
60 #endif
61
62 #include "sim_controller.h"
63 #include "noti.h"
64
65 /* services */
66 #include "keyboard.h"
67 #include "keyboard_x.h"
68 #include "uninstall.h"
69 #ifdef QP_REMINDER_ENABLE
70 #include "reminder.h"
71 #endif
72 #ifdef QP_EMERGENCY_MODE_ENABLE
73 #include "emergency_mode.h"
74 #endif
75 #include "minictrl.h"
76 #include "util-time.h"
77
78 #define QP_WINDOW_PRIO 300
79
80 static struct appdata *g_app_data = NULL;
81
82 #if defined(WINSYS_X11)
83 static Ecore_X_Atom E_ILLUME_ATOM_MV_QUICKPANEL_STATE;
84 #endif
85
86 static void _ui_rotate(void *data, int new_angle);
87 static void _ui_geometry_info_set(void *data);
88 static void _ui_handler_info_set(void *data);
89 static void _ui_efl_cache_flush(void *evas);
90
91 HAPI void *quickpanel_get_app_data(void)
92 {
93         return g_app_data;
94 }
95
96 /******************************************************************************
97  *
98  * UI
99  *
100  ****************************************************************************/
101 static void _ui_efl_cache_flush(void *evas)
102 {
103         int file_cache;
104         int collection_cache;
105         int image_cache;
106         int font_cache;
107
108         retif(evas == NULL, , "Evas is NULL\n");
109         file_cache = edje_file_cache_get();
110         collection_cache = edje_collection_cache_get();
111         image_cache = evas_image_cache_get(evas);
112         font_cache = evas_font_cache_get(evas);
113
114         edje_file_cache_set(file_cache);
115         edje_collection_cache_set(collection_cache);
116         evas_image_cache_set(evas, 0);
117         evas_font_cache_set(evas, 0);
118
119         evas_image_cache_flush(evas);
120         evas_render_idle_flush(evas);
121         evas_font_cache_flush(evas);
122
123         edje_file_cache_flush();
124         edje_collection_cache_flush();
125
126         edje_file_cache_set(file_cache);
127         edje_collection_cache_set(collection_cache);
128         evas_image_cache_set(evas, image_cache);
129         evas_font_cache_set(evas, font_cache);
130
131         elm_cache_all_flush();
132         malloc_trim(0);
133 }
134
135 static void _ui_handler_input_region_set(void *data, int contents_height)
136 {
137         struct appdata *ad = NULL;
138 #if defined(WINSYS_X11)
139         Ecore_X_Window xwin;
140         Ecore_X_Atom atom_window_input_region = 0;
141 #endif
142         unsigned int window_input_region[4] = {0,};
143
144         retif(data == NULL,  , "Invialid parameter!");
145         ad = data;
146         
147 #if defined(WINSYS_X11)
148         xwin = elm_win_xwindow_get(ad->win);
149 #endif
150
151         switch (ad->angle) {
152         case 0:
153                 window_input_region[0] = 0; //X
154                 window_input_region[1] = contents_height; // Y
155                 window_input_region[2] = ad->win_width; // Width
156                 window_input_region[3] = ELM_SCALE_SIZE(QP_HANDLE_H); // height
157                 break;
158         case 90:
159                 window_input_region[0] = contents_height; //X
160                 window_input_region[1] = 0; // Y
161                 window_input_region[2] = ELM_SCALE_SIZE(QP_HANDLE_H); // Width
162                 window_input_region[3] = ad->win_height; // height
163                 break;
164         case 180:
165                 window_input_region[0] = 0; //X
166                 window_input_region[1] = ad->win_height - contents_height - ELM_SCALE_SIZE(QP_HANDLE_H); // Y
167                 window_input_region[2] = ad->win_width; // Width
168                 window_input_region[3] = ELM_SCALE_SIZE(QP_HANDLE_H); // height
169                 break;
170         case 270:
171                 window_input_region[0] = ad->win_width - contents_height - ELM_SCALE_SIZE(QP_HANDLE_H); //X
172                 window_input_region[1] = 0; // Y
173                 window_input_region[2] = ELM_SCALE_SIZE(QP_HANDLE_H); // Width
174                 window_input_region[3] = ad->win_height; // height
175                 break;
176         }
177
178         INFO("win_input_0:%d\nwin_input_1:%d\nwin_input_2:%d\nwin_input_3:%d\n"
179                         ,window_input_region[0]
180                         ,window_input_region[1]
181                         ,window_input_region[2]
182                         ,window_input_region[3]
183                 );
184
185 #if 0//defined(WINSYS_X11)
186         atom_window_input_region = ecore_x_atom_get(STR_ATOM_WINDOW_INPUT_REGION);
187
188         ecore_x_window_prop_card32_set(xwin, atom_window_input_region, window_input_region, 4);
189 #endif
190 }
191
192 static void _ui_handler_content_region_set(void *data, int contents_height)
193 {
194         struct appdata *ad = NULL;
195
196 #if defined(WINSYS_X11)
197         Ecore_X_Window xwin;
198         Ecore_X_Atom atom_window_contents_region = 0;
199 #endif
200         unsigned int window_contents_region[4] = {0,};
201
202         retif(data == NULL,  , "Invialid parameter!");
203         ad = data;
204
205 #if defined(WINSYS_X11)
206         xwin = elm_win_xwindow_get(ad->win);
207 #endif
208
209         switch (ad->angle) {
210         case 0:
211                 window_contents_region[0] = 0; //X
212                 window_contents_region[1] = 0; // Y
213                 window_contents_region[2] = ad->win_width; // Width
214                 window_contents_region[3] = contents_height; // height
215                 break;
216         case 90:
217                 window_contents_region[0] = 0; //X
218                 window_contents_region[1] = 0; // Y
219                 window_contents_region[2] = contents_height; // Width
220                 window_contents_region[3] = ad->win_height; // height
221                 break;
222         case 180:
223                 window_contents_region[0] = 0; //X
224                 window_contents_region[1] = ad->win_height - contents_height; // Y
225                 window_contents_region[2] = ad->win_width; // Width
226                 window_contents_region[3] = contents_height; // height
227                 break;
228         case 270:
229                 window_contents_region[0] = ad->win_width - contents_height ; //X
230                 window_contents_region[1] = 0; // Y
231                 window_contents_region[2] = contents_height; // Width
232                 window_contents_region[3] = ad->win_height; // height
233                 break;
234         }
235
236         DBG("win_contents_0:%d\nwin_contents_1:%d\nwin_contents_2:%d\nwin_contents_3:%d\n"
237                         ,window_contents_region[0]
238                         ,window_contents_region[1]
239                         ,window_contents_region[2]
240                         ,window_contents_region[3]
241            );
242
243 #if 0//defined(WINSYS_X11)
244         atom_window_contents_region = ecore_x_atom_get(STR_ATOM_WINDOW_CONTENTS_REGION);
245         ecore_x_window_prop_card32_set(xwin, atom_window_contents_region, window_contents_region, 4);
246 #endif
247 }
248
249 static void _ui_handler_info_set(void *data)
250 {
251         int contents_height = 0;
252         struct appdata *ad = NULL;
253
254         retif(data == NULL, , "data is NULL");
255         ad = data;
256
257         contents_height = ad->gl_distance_from_top + ad->gl_limit_height;
258
259         _ui_handler_input_region_set(ad, contents_height);
260         _ui_handler_content_region_set(ad, contents_height);
261 }
262
263 static void _ui_geometry_info_set(void *data)
264 {
265         struct appdata *ad = NULL;
266         int max_height_window = 0;
267         Evas_Coord genlist_y = 0;
268
269         retif(data == NULL, , "data is NULL");
270         ad = data;
271
272         if (ad->angle == 90 || ad->angle == 270 ) {
273                 max_height_window = ad->win_width;
274         } else {
275                 max_height_window = ad->win_height;
276         }
277
278         edje_object_part_geometry_get(_EDJ(ad->ly), "qp.base.list.swallow", NULL, &genlist_y, NULL, NULL);
279
280         ad->gl_distance_from_top = genlist_y;
281         ad->gl_distance_to_bottom = ELM_SCALE_SIZE(QP_HANDLE_H);
282         ad->gl_limit_height = max_height_window - ad->gl_distance_from_top - ad->gl_distance_to_bottom;
283 }
284
285 /*****************************************************************************
286  *
287  * ui rotation functions
288  *
289  ****************************************************************************/
290 static void _ui_rotation_wm_cb(void *data, Evas_Object *obj, void *event)
291 {
292         int angle = 0;
293         struct appdata *ad = data;
294         retif(ad == NULL, , "Invalid parameter!");
295
296         angle = elm_win_rotation_get((Evas_Object *)obj);
297
298         DBG("ROTATE:%d", angle);
299
300         quickpanel_minictrl_rotation_report(angle);
301
302         _ui_rotate(ad, angle);
303 }
304
305 static int _ui_rotation_angle_get(void *data)
306 {
307         struct appdata *ad = (struct appdata *)data;
308         retif(ad == NULL, 0, "Invalid parameter!");
309         retif(ad->win == NULL, 0, "Invalid parameter!");
310
311         return elm_win_rotation_get(ad->win);
312 }
313
314 static void _ui_handler_enable_set(Eina_Bool is_enable)
315 {
316         const char *signal = NULL;
317         struct appdata *ad = quickpanel_get_app_data();
318         retif(ad == NULL, , "invalid data.");
319         retif(ad->view_root == NULL, , "data is NULL");
320
321         if (is_enable == EINA_TRUE) {
322                 signal = "mouse,down,1";
323         } else {
324                 signal = "mouse,up,1";
325         }
326
327         elm_object_signal_emit(ad->view_root, signal, "qp.handler.bg");
328 }
329
330 static void _ui_rotation_handler(struct appdata *ad, int angle)
331 {
332         const char *signal = NULL;
333
334         retif(ad == NULL, , "data is NULL");
335         retif(ad->view_root == NULL, , "data is NULL");
336
337
338         if (angle == 90 || angle == 270) {
339                 signal = "quickpanel.landscape";
340         } else {
341                 signal = "quickpanel.portrait";
342         }
343
344         elm_object_signal_emit(ad->view_root, signal, "quickpanel.prog");
345 }
346
347 static void _ui_rotate(void *data, int new_angle)
348 {
349         struct appdata *ad = data;
350         retif(data == NULL, , "Invalid parameter!");
351
352         DBG("ROTATION: new:%d old:%d", new_angle, ad->angle);
353
354         if (new_angle == 0 || new_angle == 90 || new_angle == 180 || new_angle == 270) {
355                 if (new_angle != ad->angle) {
356                         ad->angle = new_angle;
357                         quickpanel_modules_refresh(ad);
358                         _ui_geometry_info_set(ad);
359                         _ui_handler_info_set(ad);
360                         _ui_rotation_handler(ad, ad->angle);
361                 }
362         }
363 }
364 #if 1
365 static int _tzsh_set(Evas_Object *win)
366 {
367         tzsh_h tzsh = NULL;
368         tzsh_quickpanel_service_h quickpanel_service = NULL;
369         tzsh_window tz_win;
370
371         retif(!win, QP_FAIL, "Invialid parameter!");
372
373         tzsh = tzsh_create(TZSH_TOOLKIT_TYPE_EFL);
374         retif(!tzsh, QP_FAIL, "tzsh_create ERROR!");
375
376         struct appdata *ad = quickpanel_get_app_data();
377
378         ad->tzsh = tzsh;
379
380         tz_win = elm_win_window_id_get(win);
381         if (!tz_win) {
382                 tzsh_destroy(tzsh);
383                 return QP_FAIL;
384         }
385
386         quickpanel_service = tzsh_quickpanel_service_create(tzsh, tz_win);
387         if (!quickpanel_service) {
388                 tzsh_destroy(tzsh);
389                 return QP_FAIL;
390         }
391         ad->quickpanel_service = quickpanel_service;
392
393         return QP_OK;
394 }
395
396 static void _tzsh_unset(void)
397 {
398         struct appdata *ad = quickpanel_get_app_data();
399
400         if (ad->quickpanel_service) {
401                 tzsh_quickpanel_service_destroy(ad->quickpanel_service);
402                 ad->quickpanel_service = NULL;
403         }
404
405         if (ad->tzsh) {
406                 tzsh_destroy(ad->tzsh);
407                 ad->tzsh = NULL;
408         }
409 }
410 #endif
411
412 /*****************************************************************************
413  *
414  * ui creation/deletion functions
415  *
416  ****************************************************************************/
417 static Evas_Object *_ui_window_add(const char *name, int prio)
418 {
419         Evas_Object *eo = NULL;
420
421         eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
422
423         if (eo != NULL) {
424                 elm_win_alpha_set(eo, EINA_TRUE);
425                 elm_win_indicator_mode_set(eo, ELM_WIN_INDICATOR_HIDE);
426
427                 elm_win_title_set(eo, name);
428                 elm_win_borderless_set(eo, EINA_TRUE);
429                 elm_win_autodel_set(eo, EINA_TRUE);
430
431                 /* set this window as a quickpanel */
432                 elm_win_quickpanel_set(eo, 1);
433                 elm_win_quickpanel_priority_major_set(eo, prio);
434
435                 if (elm_win_wm_rotation_supported_get(eo)) {
436                         int rots[4] = { 0, 90, 180, 270 };
437                         elm_win_wm_rotation_available_rotations_set(eo, rots, 4);
438                 }
439
440                 if( QP_OK != _tzsh_set(eo)) {
441                         ERR("Failed to set tzsh");
442                 }
443
444                 evas_object_show(eo);
445         }
446
447         return eo;
448 }
449
450 static int _ui_gui_create(void *data)
451 {
452         struct appdata *ad = data;
453         int w = 0, h = 0;
454         int initial_angle = 0;
455         Evas_Object *page_base = NULL;
456
457         retif(data == NULL, QP_FAIL, "Invialid parameter!");
458
459         ad->win = _ui_window_add("Quickpanel Window",
460                         QP_WINDOW_PRIO);
461         retif(ad->win == NULL, QP_FAIL, "Failed to create main window");
462         //build error
463         //elm_win_focus_allow_set(ad->win, EINA_TRUE);
464
465         evas_object_smart_callback_add(ad->win, "wm,rotation,changed",
466                         _ui_rotation_wm_cb, ad);
467
468         ad->background = elm_bg_add(ad->win);
469         if (ad->background  != NULL) {
470                 evas_object_size_hint_weight_set(ad->background,
471                                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
472                 elm_win_resize_object_add(ad->win, ad->background);
473                 evas_object_show(ad->background);
474         } else {
475                 ERR("failed to create background");
476         }
477
478         ad->view_root = quickpanel_uic_load_edj(ad->background,
479                         DEFAULT_EDJ, "quickpanel/root", 0);
480         retif(ad->view_root == NULL, QP_FAIL, "Failed to create main page");
481
482         Evas_Object *pager_scroller = quickpanel_pager_new(ad->view_root, NULL);
483         Evas_Object *pager_box = quickpanel_pager_view_get("BOX");
484
485         page_base = quickpanel_page_base_create(pager_box, NULL);
486         retif(page_base == NULL, QP_FAIL, "Failed to create main page");
487         ad->ly = quickpanel_page_base_view_get("LAYOUT");
488         retif(ad->ly == NULL, QP_FAIL, "Failed to create main page");
489
490         elm_box_pack_end(pager_box, page_base);
491         elm_win_resize_object_add(ad->win, ad->view_root);
492         elm_object_part_content_set(ad->view_root, "qp.root.swallow", pager_scroller);
493
494         /* get noti evas */
495         ad->evas = evas_object_evas_get(ad->win);
496         ad->list = quickpanel_page_base_view_get("BOX");
497         ad->scroller = quickpanel_page_base_view_get("SCROLLER");
498
499         //ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
500         elm_win_screen_size_get(ad->win, NULL, NULL, &w, &h);
501         evas_object_resize(ad->win, w, h);
502
503         ad->win_width = w;
504         ad->win_height = h;
505
506         _ui_geometry_info_set(ad);
507
508         initial_angle = _ui_rotation_angle_get(ad);
509         _ui_rotate(ad, initial_angle);
510
511         quickpanel_pager_page_set(PAGE_IDX_MAIN, 1);
512
513         sim_controller_init(ad->ly);
514
515         quickpanel_noti_init_noti_section();
516
517         return 0;
518 }
519
520 static int _ui_gui_destroy(void *data)
521 {
522         struct appdata *ad = data;
523         retif(data == NULL, QP_FAIL, "Invialid parameter!");
524
525         if (ad->list != NULL) {
526                 evas_object_del(ad->list);
527                 ad->list = NULL;
528         }
529         if (ad->scroller != NULL) {
530                 evas_object_del(ad->scroller);
531                 ad->scroller = NULL;
532         }
533         if (ad->ly != NULL) {
534                 evas_object_del(ad->ly);
535                 ad->ly = NULL;
536         }
537         if (ad->win != NULL) {
538                 evas_object_del(ad->win);
539                 ad->win = NULL;
540         }
541
542         _tzsh_unset();
543
544         return QP_OK;
545 }
546
547 static void _ui_setting_visibility_set(struct appdata *ad, int show)
548 {
549         retif(ad == NULL, , "data is NULL");
550         retif(ad->ly == NULL, , "data is NULL");
551
552         elm_object_signal_emit(ad->ly, "quickpanel.setting.show",
553                         "quickpanel.prog");
554 }
555
556 /*****************************************************************************
557  *
558  * event handler initialization functions
559  *
560  ****************************************************************************/
561 static void _vconf_event_powerff_cb(keynode_t *node,
562                 void *data)
563 {
564         int val;
565         if (vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val) == 0 &&
566                         (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || val == VCONFKEY_SYSMAN_POWER_OFF_RESTART)) {
567                 ui_app_exit();
568         }
569 }
570
571 static void _vconf_event_lcdoff_cb(keynode_t *node,
572                 void *data)
573 {
574         int ret = 0;
575         int pm_state = VCONFKEY_PM_STATE_NORMAL;
576
577         ret = vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
578
579         if (ret == 0 && pm_state == VCONFKEY_PM_STATE_LCDOFF) {
580                 quickpanel_uic_close_quickpanel(false, 0);
581         }
582 }
583
584 #if defined(WINSYS_X11)
585 static Eina_Bool _ecore_event_client_message_cb(void *data, int type,
586                 void *event)
587 {
588         struct appdata *ad = data;
589
590         Ecore_X_Event_Client_Message *ev = event;
591
592         retif(data == NULL || event == NULL,
593                         ECORE_CALLBACK_RENEW, "Invalid parameter!");
594
595         if (ev->message_type == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE) {
596                 if (ev->data.l[0] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF) {
597                         SERR("quickpanel is closed");
598                         ad->is_opened = 0;
599                         quickpanel_util_time_timer_enable_set(0);
600                         quickpanel_keyboard_closing_fini(ad);
601                         quickpanel_keyboard_x_closing_fini(ad);
602                         quickpanel_modules_closed(data);
603                         quickpanel_media_player_stop();
604                 }
605         } else if (ev->message_type == E_ILLUME_ATOM_MV_QUICKPANEL_STATE) {
606                 if (ev->data.l[0] == 1) {
607                         // pressed
608                         if (ad->is_opened == 0) {
609                                 quickpanel_util_time_timer_enable_set(1);
610                                 quickpanel_keyboard_openning_init(ad);
611                                 quickpanel_keyboard_x_openning_init(ad);
612                                 if (quickpanel_uic_opened_reason_get() != OPENED_BY_CMD_SHOW_SETTINGS) {
613                                         quickpanel_pager_page_set(PAGE_IDX_MAIN, 0);
614                                 }
615                         }
616                         _ui_handler_enable_set(EINA_TRUE);
617                 }
618                 if (ev->data.l[0] == 0) {
619                         // released
620                         if (ad->is_opened == 0) {
621                                 SERR("quickpanel is opened");
622                                 ad->is_opened = 1;
623                                 quickpanel_modules_opened(data);
624                                 quickpanel_media_player_stop();
625                                 quickpanel_uic_opened_reason_set(OPENED_NO_REASON);
626                         }
627                         _ui_handler_enable_set(EINA_FALSE);
628                 }
629         }
630         return ECORE_CALLBACK_RENEW;
631 }
632 #endif
633
634 static void _vconf_init(struct appdata *ad)
635 {
636         int ret = 0;
637
638         ret = vconf_notify_key_changed(VCONFKEY_PM_STATE,
639                         _vconf_event_lcdoff_cb, ad);
640         if (ret != 0) {
641                 ERR("VCONFKEY_PM_STATE: %d", ret);
642         }
643
644         ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
645                         _vconf_event_powerff_cb, ad);
646         if (ret != 0) {
647                 ERR("VCONFKEY_PM_STATE: %d", ret);
648         }
649 }
650
651 static void _vconf_fini(struct appdata *ad)
652 {
653         int ret = 0;
654
655         ret = vconf_ignore_key_changed(VCONFKEY_PM_STATE,
656                         _vconf_event_lcdoff_cb);
657         if (ret != 0) {
658                 ERR("VCONFKEY_PM_STATE: %d", ret);
659         }
660
661         ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
662                         _vconf_event_powerff_cb);
663         if (ret != 0) {
664                 ERR("VCONFKEY_PM_STATE: %d", ret);
665         }
666 }
667
668 static void _edbus_init(struct appdata *ad)
669 {
670         e_dbus_init();
671         ad->dbus_connection = e_dbus_bus_get(DBUS_BUS_SYSTEM);
672         if (ad->dbus_connection == NULL) {
673                 ERR("noti register : failed to get dbus bus");
674         }
675 }
676
677 static void _edbus_fini(struct appdata *ad)
678 {
679         if (ad->dbus_connection != NULL) {
680                 e_dbus_connection_close(ad->dbus_connection);
681                 ad->dbus_connection = NULL;
682                 e_dbus_shutdown();
683         }
684 }
685
686 static void _ecore_event_init(struct appdata *ad)
687 {
688 #if defined(WINSYS_X11)
689
690         Ecore_Event_Handler *hdl = NULL;
691
692         /* Register window rotate event */
693         hdl = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
694                         _ecore_event_client_message_cb, ad);
695         if (hdl == NULL) {
696                 ERR("failed to add handler(ECORE_X_EVENT_CLIENT_MESSAGE)");
697         }
698
699         ad->hdl_client_message = hdl;
700 #endif
701 }
702
703 static void _ecore_event_fini(struct appdata *ad)
704 {
705         if (ad->hdl_client_message != NULL) {
706                 ecore_event_handler_del(ad->hdl_client_message);
707                 ad->hdl_client_message = NULL;
708         }
709 }
710
711 static void _x_atom_init(void)
712 {
713 #if defined(WINSYS_X11)
714         E_ILLUME_ATOM_MV_QUICKPANEL_STATE = ecore_x_atom_get("_E_MOVE_QUICKPANEL_STATE");
715 #endif
716 }
717 /*****************************************************************************
718  *
719  * App efl main interface
720  *
721  ****************************************************************************/
722 static void _sigaction_terminate_handler(int signum, siginfo_t *info, void *unused)
723 {
724         ERR("quickpanel going to be terminated");
725         ui_app_exit();
726 }
727
728 static void _service_request_process(app_control_h service, void *data)
729 {
730         char *value = NULL;
731         retif(service == NULL, , "Invialid parameter!");
732
733         if (!app_control_get_extra_data(service, "HIDE_LAUNCH", &value))
734         {
735                 if (value != NULL) {
736                         ERR("HIDE_LAUNCH: %s", value);
737                         if (!strcmp(value, "1")) {
738                                 quickpanel_uic_close_quickpanel(false, 0);
739                         } else {
740                                 quickpanel_uic_open_quickpanel(OPENED_BY_CMD_HIDE_LAUNCH);
741                         }
742
743                         free(value);
744                 }
745         } else if (!app_control_get_extra_data(service, "SHOW_SETTINGS", &value)) {
746                 if (value != NULL) {
747                         ERR("SHOW_SETTINGS: %s", value);
748                         if (!strcmp(value, "1")) {
749                                 quickpanel_pager_page_set(PAGE_IDX_EDITING, 0);
750                                 quickpanel_uic_open_quickpanel(OPENED_BY_CMD_SHOW_SETTINGS);
751                         }
752
753                         free(value);
754                 }
755         }
756 #ifdef QP_EMERGENCY_MODE_ENABLE
757         else if (!app_control_get_extra_data(service, "EMERGENCY_MODE_LAUNCH", &value)) {
758                 if (value != NULL) {
759                         ERR("EMERGENCY_MODE_LAUNCH: %s", value);
760                         if (!strcmp(value, "1")) {
761                                 if (quickpanel_emergency_mode_syspopup_launch() == QP_FAIL) {
762                                         ERR("failed to launch emergency mode syspopup");
763                                 } else {
764                                         quickpanel_uic_close_quickpanel(true, 0);
765                                 }
766                         }
767
768                         free(value);
769                 }
770         }
771 #endif
772 }
773
774 static Eina_Bool _appcore_cache_flush_timer_cb(void *data)
775 {
776         if (!quickpanel_uic_is_suspended()) {
777                 return ECORE_CALLBACK_CANCEL;
778         }
779
780         return ECORE_CALLBACK_CANCEL;
781 }
782
783 static Eina_Bool _ui_refresh_idler_cb(void *data)
784 {
785         DBG("");
786         struct appdata *ad = data;
787         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
788
789         quickpanel_modules_refresh(ad);
790         _ui_geometry_info_set(ad);
791         _ui_handler_info_set(ad);
792
793         /*      Cache memory is cleared when the application paused (every time, after 5 seconds (in appcore)),
794          *      but after running in a minimized mode application have status AS_RUNNING.
795          *      Application have status AS_PAUSED only after change of visibility to hidden condition by user (on hiding window)
796          *      Cleaning must be performed only once after application loading in hidden condition
797          *      (and stay in a hidden condition at time of cleaning).
798          */
799         ecore_timer_add(10, _appcore_cache_flush_timer_cb, NULL);
800
801         return EINA_FALSE;
802 }
803
804 static void _quickpanel_initialize(void *data)
805 {
806         int ret = 0;
807         struct appdata *ad = data;
808         retif(ad == NULL, , "Invialid parameter!");
809
810         INFO(">> Creating Quickpanel");
811         /* Check emulator */
812         ad->is_emul = quickpanel_uic_is_emul();
813         INFO("quickpanel run in %s", ad->is_emul ? "Emul" : "Device");
814
815         int w, h;
816         elm_win_screen_size_get(ad->win, NULL, NULL, &w, &h);
817         ad->scale = elm_config_scale_get();
818         if (ad->scale < 0) {
819                 ad->scale = 1.0;
820         }
821
822         INFO("quickpanel scale %f", ad->scale);
823
824         ad->is_suspended = 1;
825
826         /* Get theme */
827         elm_theme_extension_add(NULL, DEFAULT_THEME_EDJ);
828         /* create quickpanel window */
829         ret = _ui_gui_create(ad);
830         retif(ret != QP_OK, , "Failed to create window!");
831
832         quickpanel_media_init();
833
834         _x_atom_init();
835         _ecore_event_init(ad);
836         _vconf_init(ad);
837         _edbus_init(ad);
838
839         quickpanel_uninstall_init(ad);
840 #ifdef QP_EMERGENCY_MODE_ENABLE
841         quickpanel_emergency_mode_init(ad);
842 #endif
843         quickpanel_keyboard_init(ad);
844 #if defined(WINSYS_X11)
845         quickpanel_keyboard_x_init(ad);
846 #endif
847 #ifdef QP_REMINDER_ENABLE
848         quickpanel_reminder_init(ad);
849 #endif
850
851 #ifdef QP_SETTING_ENABLE
852         _ui_setting_visibility_set(ad, 1);
853 #else /* QP_SETTING_ENABLE */
854         _ui_setting_visibility_set(ad, 0);
855 #endif /* QP_SETTING_ENABLE */
856
857         /* init quickpanel modules */
858         quickpanel_modules_init(ad);
859         ecore_idler_add(_ui_refresh_idler_cb, ad);
860 }
861
862 static bool _app_create_cb(void *data)
863 {
864         ERR("");
865 #if defined(WINSYS_X11)
866         elm_config_engine_set("opengl_x11");
867 #endif
868         elm_app_base_scale_set(1.8);
869
870         pid_t pid;
871         int r;
872
873         // signal handler
874         struct sigaction act;
875         act.sa_sigaction = _sigaction_terminate_handler;
876         act.sa_flags = SA_SIGINFO;
877
878         int ret = sigemptyset(&act.sa_mask);
879         if (ret < 0) {
880                 ERR("Failed to sigemptyset[%s]", strerror(errno));
881         }
882         ret = sigaddset(&act.sa_mask, SIGTERM);
883         if (ret < 0) {
884                 ERR("Failed to sigaddset[%s]", strerror(errno));
885         }
886         ret = sigaction(SIGTERM, &act, NULL);
887         if (ret < 0) {
888                 ERR("Failed to sigaction[%s]", strerror(errno));
889         }
890
891         pid = setsid();
892         if (pid < 0) {
893                 WARN("Failed to set session id!");
894         }
895
896         r = nice(2);
897         if (r == -1) {
898                 WARN("Failed to set nice value!");
899         }
900
901         return TRUE;
902 }
903
904 static void _app_service_cb(app_control_h service, void *data)
905 {
906         struct appdata *ad = data;
907         retif(ad == NULL, , "Invialid parameter!");
908
909         if (ad->win == NULL && ad->ly == NULL) {
910                 _quickpanel_initialize(data);
911         } else {
912                 _service_request_process(service, data);
913         }
914 }
915
916 static void _app_terminate_cb(void *data)
917 {
918         ERR("");
919
920         struct appdata *ad = data;
921         retif(ad == NULL, , "invalid data.");
922
923         quickpanel_media_fini();
924
925         /* fini quickpanel modules */
926         quickpanel_modules_fini(ad);
927         _edbus_fini(ad);
928         _vconf_fini(ad);
929         _ecore_event_fini(ad);
930
931         quickpanel_keyboard_fini(ad);
932 #if defined(WINSYS_X11)
933         quickpanel_keyboard_x_fini(ad);
934 #endif
935         quickpanel_uninstall_fini(ad);
936 #ifdef QP_REMINDER_ENABLE
937         quickpanel_reminder_fini(ad);
938 #endif
939 #ifdef QP_EMERGENCY_MODE_ENABLE
940         quickpanel_emergency_mode_fini(ad);
941 #endif
942
943         /* delete quickpanel window */
944         _ui_gui_destroy(ad);
945
946         INFO("Quickpanel is terminated");
947 }
948
949 static void _app_resume_cb(void *data)
950 {
951         DBG("");
952         struct appdata *ad = data;
953         retif(ad == NULL,, "invalid data.");
954
955         ad->is_suspended = 0;
956         _ui_handler_enable_set(EINA_FALSE);
957
958         quickpanel_modules_resume(data);
959
960         sim_controller_resume();
961 }
962
963 static void _app_pause_cb(void *data)
964 {
965         DBG("");
966         struct appdata *ad = data;
967         retif(ad == NULL,, "invalid data.");
968
969
970         quickpanel_modules_suspend(ad);
971
972         ad->is_suspended = 1;
973
974         if (ad->evas != NULL) {
975                 _ui_efl_cache_flush(ad->evas);
976                 evas_event_feed_mouse_cancel(ad->evas, ecore_time_get(), NULL);
977         }
978 }
979
980 static void _app_language_changed_cb(app_event_info_h event_info, void *data)
981 {
982         DBG("");
983         quickpanel_modules_lang_change(data);
984
985         sim_controller_on_language_change();
986 }
987
988 static void _app_region_format_changed_cb(app_event_info_h event_info, void *data)
989 {
990         DBG("");
991         quickpanel_modules_lang_change(data);
992 }
993
994 int main(int argc, char *argv[])
995 {
996         INFO("BUILD START: %s %s", __DATE__, __TIME__);
997         ERR("BUILD START: %s %s", __DATE__, __TIME__);
998
999         int ret = 0;
1000         struct appdata ad;
1001         ui_app_lifecycle_callback_s event_callback = {0,};
1002         app_event_handler_h handlers[5] = {NULL, };
1003
1004         ERR("quickpanel is forked");
1005
1006 #if defined(WINSYS_X11)
1007         ret = perm_app_set_privilege("org.tizen.", NULL, NULL);
1008         if (ret != 0) {
1009                 WARN("Failed to control privilege!");
1010         }
1011 #endif
1012
1013         event_callback.create = _app_create_cb;
1014         event_callback.terminate = _app_terminate_cb;
1015         event_callback.pause = _app_pause_cb;
1016         event_callback.resume = _app_resume_cb;
1017         event_callback.app_control = _app_service_cb;
1018
1019 //      ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, NULL, NULL);
1020 //      ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, NULL, NULL);
1021 //      ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, NULL, NULL);
1022         ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, _app_language_changed_cb, &ad);
1023         ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, _app_region_format_changed_cb, &ad);
1024
1025         memset(&ad, 0x0, sizeof(struct appdata));
1026
1027         g_app_data = &ad;
1028
1029         ret = ui_app_main(argc, argv, &event_callback, (void *)&ad);
1030         if (ret != APP_ERROR_NONE) {
1031                 ERR("ui_app_main() is failed. err = %d", ret);
1032         }
1033
1034         return ret;
1035
1036 }