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