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