cbc9028833a6eabdcfa5fcb08275f79f2697604d
[apps/home/quickpanel.git] / daemon / quickpanel-ui.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 #include <stdio.h>
18 #include <signal.h>
19 #include <app.h>
20 #include <system_info.h>
21 #include <sys/utsname.h>
22 #include <X11/Xlib.h>
23 #include <utilX.h>
24 #include <Ecore_Input.h>
25 #include <vconf.h>
26 #include <unistd.h>
27 #include <privilege-control.h>
28 #include <bundle.h>
29 #include <notification.h>
30
31 #include "common.h"
32 #include "quickpanel-ui.h"
33 #include "modules.h"
34 #include "quickpanel_def.h"
35 #include "list_util.h"
36 #include "keyboard.h"
37 #include "vi_manager.h"
38
39 #define QP_WINDOW_PRIO 300
40 #define QP_ENABLE_HIDING_INDICATOR 1
41
42 static struct appdata *g_app_data = NULL;
43
44 /* binary information */
45 #define QP_EMUL_STR             "Emulator"
46
47 static Ecore_X_Atom E_ILLUME_ATOM_MV_QUICKPANEL_STATE;
48
49 static void _quickpanel_cache_flush(void *evas);
50 static void _quickpanel_init_size_genlist(void *data);
51 static void _quickpanel_ui_update_height(void *data);
52 #ifdef TBD_RSA
53 static void _quickpanel_ui_set_indicator_cover(void *data);
54 #endif
55 static void _quickpanel_move_data_to_service(const char *key, const char *val, void *data);
56
57 HAPI void *quickpanel_get_app_data(void)
58 {
59         return g_app_data;
60 }
61
62 HAPI int quickpanel_is_opened(void)
63 {
64         struct appdata *ad = quickpanel_get_app_data();
65         retif(ad == NULL, 0, "invalid data.");
66
67         return ad->is_opened;
68 }
69
70 HAPI int quickpanel_is_suspended(void)
71 {
72         struct appdata *ad = quickpanel_get_app_data();
73         retif(ad == NULL, 0, "invalid data.");
74
75         return ad->is_suspended;
76 }
77
78 HAPI int quickpanel_is_emul(void)
79 {
80         int is_emul = 0;
81         char *info = NULL;
82
83         if (system_info_get_value_string(SYSTEM_INFO_KEY_MODEL, &info) == 0) {
84                 if (info == NULL) return 0;
85                 if (!strncmp(QP_EMUL_STR, info, strlen(info))) {
86                         is_emul = 1;
87                 }
88         }
89
90         if (info != NULL) free(info);
91
92         return is_emul;
93 }
94
95 HAPI void quickpanel_initial_resize(Evas_Object *obj, int height)
96 {
97         struct appdata *ad = quickpanel_get_app_data();
98         retif(ad == NULL, , "invalid data.");
99
100         if (ad->angle == 90 || ad->angle == 270) {
101                 evas_object_resize(obj, ad->win_height, height * ad->scale);
102         } else  {
103                 evas_object_resize(obj, ad->win_width, height * ad->scale);
104         }
105 }
106
107 HAPI int quickpanel_launch_app(char *app_id, void *data)
108 {
109         int ret = SERVICE_ERROR_NONE;
110         service_h service = NULL;
111
112         retif(app_id == NULL && data == NULL, SERVICE_ERROR_INVALID_PARAMETER, "Invialid parameter!");
113
114         ret = service_create(&service);
115         if (ret != SERVICE_ERROR_NONE) {
116                 ERR("service_create() return error : %d", ret);
117                 return ret;
118         }
119         retif(service == NULL, SERVICE_ERROR_INVALID_PARAMETER, "fail to create service handle!");
120
121         if (app_id != NULL) {
122                 service_set_operation(service, SERVICE_OPERATION_DEFAULT);
123                 service_set_app_id(service, app_id);
124
125                 if (data != NULL) {
126                         bundle_iterate((bundle *)data, _quickpanel_move_data_to_service, service);
127                 }
128         } else {
129                 service_import_from_bundle(service, data);
130         }
131
132         ret = service_send_launch_request(service, NULL, NULL);
133         if (ret != SERVICE_ERROR_NONE) {
134                 ERR("service_send_launch_request() is failed : %d", ret);
135                 service_destroy(service);
136                 return ret;
137         }
138         service_destroy(service);
139         return ret;
140 }
141
142 HAPI void quickpanel_launch_app_inform_result(const char *pkgname, int retcode)
143 {
144         retif(retcode == SERVICE_ERROR_NONE, , "Invialid parameter!");
145         retif(pkgname == NULL && retcode != SERVICE_ERROR_APP_NOT_FOUND, , "Invialid parameter!");
146
147         const char *msg = NULL;
148
149         if (retcode == SERVICE_ERROR_APP_NOT_FOUND) {
150                 notification_status_message_post(_S("IDS_COM_BODY_NO_APPLICATIONS_CAN_PERFORM_THIS_ACTION"));
151         } else {
152                 Eina_Strbuf *strbuf = eina_strbuf_new();
153
154                 if (strbuf != NULL) {
155                         eina_strbuf_append_printf(strbuf, _S("IDS_IDLE_POP_UNABLE_TO_LAUNCH_PS"), pkgname);
156                         eina_strbuf_append_printf(strbuf, "(%d)", retcode);
157                         msg = eina_strbuf_string_get(strbuf);
158
159                         if (msg != NULL) {
160                                 notification_status_message_post(msg);
161                         }
162                         eina_strbuf_free(strbuf);
163                 }
164         }
165 }
166
167 #ifdef TBD
168 static Eina_Bool _anim_job_rotation(void *data) {
169         QP_VI *vi = data;
170         retif(vi == NULL, EINA_FALSE, "invalid parameter");
171
172         struct appdata *ad = vi->extra_data_1;
173         int new_angle =  vi->extra_flag_1;
174
175         if (ad != NULL) {
176                 elm_win_rotation_with_resize_set(ad->win,
177                                                  new_angle);
178
179                 ad->angle = new_angle;
180 #ifdef TBD_RSA
181                 _quickpanel_ui_set_indicator_cover(ad);
182 #endif
183         }
184
185         quickpanel_vi_done(vi);
186
187         return EINA_TRUE;
188 }
189
190 static Eina_Bool _anim_done_rotation(void *data) {
191         QP_VI *vi = data;
192         retif(vi == NULL, EINA_FALSE, "invalid parameter");
193
194         struct appdata *ad = vi->extra_data_1;
195         int new_angle =  vi->extra_flag_1;
196
197         if (ad != NULL) {
198                 elm_win_rotation_with_resize_set(ad->win, new_angle);
199
200                 ad->angle = new_angle;
201 #ifdef TBD_RSA
202                 _quickpanel_ui_set_indicator_cover(ad);
203 #endif
204
205                 refresh_modules(ad);
206
207                 _quickpanel_init_size_genlist(ad);
208                 _quickpanel_ui_update_height(ad);
209         }
210
211         return EINA_TRUE;
212 }
213 #endif
214
215 static void _quickpanel_move_data_to_service(const char *key, const char *val, void *data)
216 {
217         retif(data == NULL || key == NULL || val == NULL, , "Invialid parameter!");
218
219         service_h service = data;
220         service_add_extra_data(service, key, val);
221 }
222
223 static void atoms_init_quickpanel(void)
224 {
225         E_ILLUME_ATOM_MV_QUICKPANEL_STATE = ecore_x_atom_get("_E_MOVE_QUICKPANEL_STATE");
226 }
227
228 /******************************************************************************
229   *
230   * UI
231   *
232   ****************************************************************************/
233 static Eina_Bool _quickpanel_ui_refresh_cb(void *data)
234 {
235         struct appdata *ad = NULL;
236
237         retif(data == NULL, QP_FAIL, "Invalid parameter!");
238         ad = data;
239
240         INFO(" >>>>>>>>>>>>>>> Refresh QP modules!! <<<<<<<<<<<<<<<< ");
241         refresh_modules(data);
242
243         _quickpanel_init_size_genlist(ad);
244         _quickpanel_ui_update_height(ad);
245
246         return EINA_FALSE;
247 }
248
249 static void _quickpanel_cache_flush(void *evas)
250 {
251         int file_cache;
252         int collection_cache;
253         int image_cache;
254         int font_cache;
255
256         retif(evas == NULL, , "Evas is NULL\n");
257
258         file_cache = edje_file_cache_get();
259         collection_cache = edje_collection_cache_get();
260         image_cache = evas_image_cache_get(evas);
261         font_cache = evas_font_cache_get(evas);
262
263         edje_file_cache_set(file_cache);
264         edje_collection_cache_set(collection_cache);
265         evas_image_cache_set(evas, 0);
266         evas_font_cache_set(evas, 0);
267
268         evas_image_cache_flush(evas);
269         evas_render_idle_flush(evas);
270         evas_font_cache_flush(evas);
271
272         edje_file_cache_flush();
273         edje_collection_cache_flush();
274
275         edje_file_cache_set(file_cache);
276         edje_collection_cache_set(collection_cache);
277         evas_image_cache_set(evas, image_cache);
278         evas_font_cache_set(evas, font_cache);
279 }
280
281 static int _quickpanel_ui_rotation_get_angle(void *data)
282 {
283         struct appdata *ad = (struct appdata *)data;
284         Ecore_X_Window xwin, root;
285         int ret = 0, angle = 0, count = 0;
286         unsigned char *prop_data = NULL;
287
288         retif(data == NULL, -1, "Invalid parameter!");
289
290         xwin = elm_win_xwindow_get(ad->win);
291         root = ecore_x_window_root_get(xwin);
292
293         ret = ecore_x_window_prop_property_get(root,
294                                 ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE,
295                                 ECORE_X_ATOM_CARDINAL, 32,
296                                 &prop_data, &count);
297
298         if (ret && prop_data) {
299                 memcpy(&angle, prop_data, sizeof(int));
300
301                 if (prop_data)
302                         free(prop_data);
303
304                 return angle;
305         } else {
306                 ERR("Fail to get angle");
307                 if (prop_data)
308                         free(prop_data);
309
310                 return -1;
311         }
312 }
313
314 static void _quickpanel_ui_rotation(void *data, int new_angle)
315 {
316         struct appdata *ad = data;
317         retif(data == NULL, , "Invalid parameter!");
318
319         INFO("ROTATION: new:%d old:%d", new_angle, ad->angle);
320
321         if (new_angle == 0 || new_angle == 90 || new_angle == 180 || new_angle == 270) {
322                 if (new_angle != ad->angle) {
323                         ad->angle = new_angle;
324 #ifdef TBD_RSA
325                         _quickpanel_ui_set_indicator_cover(ad);
326 #endif
327                         refresh_modules(ad);
328                         _quickpanel_init_size_genlist(ad);
329                         _quickpanel_ui_update_height(ad);
330                 }
331         }
332 }
333
334 static Eina_Bool quickpanel_ui_client_message_cb(void *data, int type,
335                                                  void *event)
336 {
337         struct appdata *ad = data;
338         Ecore_X_Event_Client_Message *ev = event;
339
340         retif(data == NULL || event == NULL,
341                 ECORE_CALLBACK_RENEW, "Invalid parameter!");
342
343         if (ev->message_type == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE) {
344                 if (ev->data.l[0] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF) {
345                         ad->is_opened = 0;
346                         qp_closed_modules(data);
347                         quickpanel_player_stop();
348 #if QP_ENABLE_HIDING_INDICATOR
349                         elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_HIDE);
350 #endif
351                 }
352         } else if (ad->E_ILLUME_ATOM_MV_QUICKPANEL_STATE != NULL) {
353                 if (ev->message_type == *(ad->E_ILLUME_ATOM_MV_QUICKPANEL_STATE)) {
354                         if (ev->data.l[0] == 1) {
355                                 if (ad->is_opened == 0) {
356 #if QP_ENABLE_HIDING_INDICATOR
357                                         elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
358 #endif
359                                         INFO("quickpanel going to be opened");
360                                 }
361                         }
362                         if (ev->data.l[0] == 0) {
363                                 if (ad->is_opened == 0) {
364                                         INFO("quickpanel is closed");
365                                         ad->is_opened = 1;
366                                         qp_opened_modules(data);
367                                         quickpanel_player_stop();
368                                 }
369                         }
370                 }
371         }
372         return ECORE_CALLBACK_RENEW;
373 }
374
375 static void _quickpanel_signal_handler(int signum, siginfo_t *info, void *unused)
376 {
377         ERR("quickpanel going to be terminated");
378         app_efl_exit();
379 }
380
381 static Eina_Bool _quickpanel_ui_delayed_indicator_show_cb(void *data)
382 {
383         Evas_Object *win = data;
384         retif(win == NULL, EINA_FALSE, "Invalid parameter!");
385
386         elm_win_indicator_mode_set(win, ELM_WIN_INDICATOR_HIDE);
387
388         return EINA_FALSE;
389 }
390
391
392 static void _quickpanel_app_rotate_cb(void *data, Evas_Object *obj, void *event)
393 {
394         int angle = 0;
395         struct appdata *ad = data;
396         retif(ad == NULL, , "Invalid parameter!");
397
398         DBG("ROTATE:%d", angle);
399
400         angle = elm_win_rotation_get((Evas_Object *)obj);
401         _quickpanel_ui_rotation(ad, angle);
402 }
403
404 static Evas_Object *_quickpanel_ui_window_add(const char *name, int prio)
405 {
406         Evas_Object *eo = NULL;
407         Ecore_X_Window xwin;
408
409         eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
410
411         if (eo != NULL) {
412                 elm_win_alpha_set(eo, EINA_TRUE);
413 #if QP_ENABLE_HIDING_INDICATOR
414                 elm_win_indicator_mode_set(eo, ELM_WIN_INDICATOR_SHOW);
415                 ecore_idler_add(_quickpanel_ui_delayed_indicator_show_cb, eo);
416 #else
417                 elm_win_indicator_mode_set(eo, ELM_WIN_INDICATOR_SHOW);
418 #endif
419
420                 elm_win_title_set(eo, name);
421                 elm_win_borderless_set(eo, EINA_TRUE);
422                 elm_win_autodel_set(eo, EINA_TRUE);
423
424                 /* set this window as a quickpanel */
425                 elm_win_quickpanel_set(eo, 1);
426                 elm_win_quickpanel_priority_major_set(eo, prio);
427
428                 if (elm_win_wm_rotation_supported_get(eo))
429                 {
430                         int rots[4] = { 0, 90, 270 };
431                         elm_win_wm_rotation_available_rotations_set(eo, rots, 3);
432                 }
433
434                 /* icccm name class set */
435                 xwin = elm_win_xwindow_get(eo);
436                 ecore_x_icccm_name_class_set(xwin, "QUICKPANEL", "QUICKPANEL");
437
438                 unsigned int val = 1;
439                 ecore_x_window_prop_card32_set
440                         (xwin, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, &val, 1);
441
442                 evas_object_show(eo);
443         }
444
445         return eo;
446 }
447
448 #ifdef TBD
449 static void _quickpanel_add_debugging_bar(Evas_Object *list)
450 {
451         Eina_Bool ret = EINA_FALSE;
452         Evas_Object *bar = elm_layout_add(list);
453
454         ret = elm_layout_file_set(bar, DEFAULT_EDJ,
455                         "quickpanel/seperator/default");
456
457         if (ret != EINA_FALSE) {
458                 evas_object_size_hint_weight_set(bar, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
459                 evas_object_size_hint_align_set(bar, EVAS_HINT_FILL, EVAS_HINT_FILL);
460
461                 qp_item_data *qid
462                         = quickpanel_list_util_item_new(QP_ITEM_TYPE_BAR, NULL);
463                 quickpanel_list_util_item_set_tag(bar, qid);
464                 quickpanel_list_util_sort_insert(list, bar);
465                 evas_object_show(bar);
466         }
467 }
468 #endif
469
470 HAPI Evas_Object *quickpanel_ui_load_edj(Evas_Object * parent, const char *file,
471                                             const char *group, int is_just_load)
472 {
473         Eina_Bool r;
474         Evas_Object *eo = NULL;
475
476         retif(parent == NULL, NULL, "Invalid parameter!");
477
478         eo = elm_layout_add(parent);
479         retif(eo == NULL, NULL, "Failed to add layout object!");
480
481         r = elm_layout_file_set(eo, file, group);
482         retif(r != EINA_TRUE, NULL,
483                 "Failed to set edje object file[%s-%s]!", file, group);
484
485         evas_object_size_hint_weight_set(eo,
486                                          EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
487
488         if (is_just_load == 1) {
489                 elm_win_resize_object_add(parent, eo);
490         }
491         evas_object_show(eo);
492
493         return eo;
494 }
495
496 static int _quickpanel_ui_create_win(void *data)
497 {
498         struct appdata *ad = data;
499         int w = 0;
500         int h = 0;
501         int initial_angle = 0;
502
503         retif(data == NULL, QP_FAIL, "Invialid parameter!");
504
505         ad->win = _quickpanel_ui_window_add("Quickpanel Window",
506                                         QP_WINDOW_PRIO);
507         if (ad->win == NULL) {
508                 ERR("ui create : failed to create window.");
509                 return -1;
510         }
511
512         evas_object_smart_callback_add(ad->win, "wm,rotation,changed",
513                                         _quickpanel_app_rotate_cb, ad);
514
515 #ifdef QP_INDICATOR_WIDGET_ENABLE
516         ad->comformant = elm_conformant_add(ad->win);
517 #if QP_ENABLE_HIDING_INDICATOR
518         elm_object_style_set(ad->comformant, "without_resize");
519 #else
520         elm_object_style_set(ad->comformant, "nokeypad");
521 #endif
522
523         ad->ly = quickpanel_ui_load_edj(ad->comformant,
524                                 DEFAULT_EDJ, "quickpanel/gl_base", 0);
525         if (ad->ly == NULL)
526                 return -1;
527
528         evas_object_size_hint_weight_set(ad->comformant,
529                                          EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
530         elm_win_resize_object_add(ad->win, ad->comformant);
531         evas_object_show(ad->comformant);
532         elm_object_content_set(ad->comformant, ad->ly);
533
534 #else
535         ad->ly = quickpanel_ui_load_edj(ad->win,
536                                 DEFAULT_EDJ, "quickpanel/gl_base", 0);
537         if (ad->ly == NULL)
538                 return -1;
539 #endif
540
541         /* get noti evas */
542         ad->evas = evas_object_evas_get(ad->win);
543
544         Evas_Object *sc = elm_scroller_add(ad->ly);
545         retif(!sc, EINA_FALSE, "fail to add scroller");
546         elm_scroller_bounce_set(sc, EINA_TRUE, EINA_TRUE);
547         elm_scroller_policy_set(sc,
548                         ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
549         evas_object_size_hint_weight_set(sc,
550                         EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
551         evas_object_size_hint_fill_set(sc, EVAS_HINT_FILL, EVAS_HINT_FILL);
552         evas_object_show(sc);
553
554         Evas_Object *box = elm_box_add(sc);
555         if (!box) {
556                 ERR("fail to add box");
557                 evas_object_del(sc);
558                 return EINA_FALSE;
559         }
560         evas_object_size_hint_weight_set(box,
561                         EVAS_HINT_EXPAND, 0);
562         elm_box_horizontal_set(box, EINA_FALSE);
563         ad->list = box;
564         ad->scroller = sc;
565
566 #ifdef TBD
567         _quickpanel_add_debugging_bar(ad->list);
568 #endif
569
570         elm_object_content_set(sc, box);
571         elm_object_part_content_set(ad->ly, "qp.gl_base.gl.swallow", ad->scroller);
572         evas_object_show(ad->list);
573
574         ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
575         evas_object_resize(ad->win, w, h);
576
577         ad->win_width = w;
578         ad->win_height = h;
579
580         _quickpanel_init_size_genlist(ad);
581 #ifdef TBD_RSA
582         _quickpanel_ui_set_indicator_cover(ad);
583 #endif
584
585         initial_angle = _quickpanel_ui_rotation_get_angle(ad);
586         _quickpanel_ui_rotation(ad, initial_angle);
587         return 0;
588 }
589 #ifdef TBD_RSA
590 static void _quickpanel_ui_set_indicator_cover(void *data)
591 {
592         retif(data == NULL, , "data is NULL");
593         struct appdata *ad = data;
594
595         int x_2 = 0, y_2 = 0;
596         int angle = ad->angle;
597
598         int width = INDICATOR_COVER_W * ad->scale;
599         int height = INDICATOR_COVER_H * ad->scale;
600
601         switch (angle) {
602                 case 0:
603                         x_2 = ad->win_width - width;
604                         y_2 = 0;
605                         break;
606                 case 90:
607                         x_2 = ad->win_height - width;
608                         y_2 = 0;
609                         break;
610                 case 180:
611                         x_2 = ad->win_width - width;
612                         y_2 = 0;
613                         break;
614                 case 270:
615                         x_2 = ad->win_height - width;
616                         y_2 = 0;
617                         break;
618         }
619
620         if (ad->cover_indicator_right == NULL) {
621                 Evas_Object *bg = evas_object_rectangle_add(ad->evas);
622                 evas_object_color_set(bg, 52, 52, 50, 255); // opaque white background
623                 evas_object_repeat_events_set(bg, EINA_FALSE);
624                 evas_object_resize(bg, width, height); // covers full canvas
625                 evas_object_move(bg, x_2, y_2);
626                 evas_object_show(bg);
627                 ad->cover_indicator_right = bg;
628         } else {
629                 evas_object_move(ad->cover_indicator_right, x_2, y_2);
630         }
631 }
632 #endif
633
634 static void _quickpanel_ui_window_set_input_region(void *data, int contents_height)
635 {
636         struct appdata *ad = NULL;
637         Ecore_X_Window xwin;
638         Ecore_X_Atom atom_window_input_region = 0;
639         unsigned int window_input_region[4] = {0,};
640
641         retif(data == NULL,  , "Invialid parameter!");
642         ad = data;
643
644         xwin = elm_win_xwindow_get(ad->win);
645
646         INFO("angle:%d", ad->angle);
647         switch (ad->angle) {
648                 case 0:
649                         window_input_region[0] = 0; //X
650                         window_input_region[1] = contents_height; // Y
651                         window_input_region[2] = ad->win_width; // Width
652                         window_input_region[3] = ad->scale * QP_HANDLE_H; // height
653                         break;
654                 case 90:
655                         window_input_region[0] = contents_height; //X
656                         window_input_region[1] = 0; // Y
657                         window_input_region[2] = ad->scale * QP_HANDLE_H; // Width
658                         window_input_region[3] = ad->win_height; // height
659                         break;
660                 case 180:
661                         window_input_region[0] = 0; //X
662                         window_input_region[1] = ad->win_height - contents_height - ad->scale * QP_HANDLE_H; // Y
663                         window_input_region[2] = ad->win_width; // Width
664                         window_input_region[3] = ad->scale * QP_HANDLE_H; // height
665                         break;
666                 case 270:
667                         window_input_region[0] = ad->win_width - contents_height - ad->scale * QP_HANDLE_H ; //X
668                         window_input_region[1] = 0; // Y
669                         window_input_region[2] = ad->scale * QP_HANDLE_H; // Width
670                         window_input_region[3] = ad->win_height; // height
671                         break;
672         }
673
674         INFO("win_input_0:%d\nwin_input_1:%d\nwin_input_2:%d\nwin_input_3:%d\n"
675                         ,window_input_region[0]
676                         ,window_input_region[1]
677                         ,window_input_region[2]
678                     ,window_input_region[3]
679                         );
680
681         atom_window_input_region = ecore_x_atom_get(STR_ATOM_WINDOW_INPUT_REGION);
682         ecore_x_window_prop_card32_set(xwin, atom_window_input_region, window_input_region, 4);
683 }
684
685 static void _quickpanel_ui_window_set_content_region(void *data, int contents_height)
686 {
687         struct appdata *ad = NULL;
688         Ecore_X_Window xwin;
689         Ecore_X_Atom atom_window_contents_region = 0;
690         unsigned int window_contents_region[4] = {0,};
691
692         retif(data == NULL,  , "Invialid parameter!");
693         ad = data;
694
695         xwin = elm_win_xwindow_get(ad->win);
696
697         INFO("angle:%d", ad->angle);
698         switch (ad->angle) {
699                 case 0:
700                         window_contents_region[0] = 0; //X
701                         window_contents_region[1] = 0; // Y
702                         window_contents_region[2] = ad->win_width; // Width
703                         window_contents_region[3] = contents_height; // height
704                         break;
705                 case 90:
706                         window_contents_region[0] = 0; //X
707                         window_contents_region[1] = 0; // Y
708                         window_contents_region[2] = contents_height; // Width
709                         window_contents_region[3] = ad->win_height; // height
710                         break;
711                 case 180:
712                         window_contents_region[0] = 0; //X
713                         window_contents_region[1] = ad->win_height - contents_height; // Y
714                         window_contents_region[2] = ad->win_width; // Width
715                         window_contents_region[3] = contents_height; // height
716                         break;
717                 case 270:
718                         window_contents_region[0] = ad->win_width - contents_height ; //X
719                         window_contents_region[1] = 0; // Y
720                         window_contents_region[2] = contents_height; // Width
721                         window_contents_region[3] = ad->win_height; // height
722                         break;
723         }
724
725         DBG("win_contents_0:%d\nwin_contents_1:%d\nwin_contents_2:%d\nwin_contents_3:%d\n"
726                         ,window_contents_region[0]
727                         ,window_contents_region[1]
728                         ,window_contents_region[2]
729                     ,window_contents_region[3]
730                         );
731
732     atom_window_contents_region = ecore_x_atom_get(STR_ATOM_WINDOW_CONTENTS_REGION);
733     ecore_x_window_prop_card32_set(xwin, atom_window_contents_region, window_contents_region, 4);
734 }
735
736 static int _quickpanel_ui_delete_win(void *data)
737 {
738         struct appdata *ad = data;
739         retif(data == NULL, QP_FAIL, "Invialid parameter!");
740
741         if (ad->list != NULL) {
742                 evas_object_del(ad->list);
743                 ad->list = NULL;
744         }
745         if (ad->scroller != NULL) {
746                 evas_object_del(ad->scroller);
747                 ad->scroller = NULL;
748         }
749         if (ad->ly != NULL) {
750                 evas_object_del(ad->ly);
751                 ad->ly = NULL;
752         }
753         if (ad->win != NULL) {
754                 evas_object_del(ad->win);
755                 ad->win = NULL;
756         }
757
758         return QP_OK;
759 }
760
761 static void _quickpanel_ui_vconf_event_powerff_cb(keynode_t *node,
762                                                 void *data)
763 {
764         int val;
765         if (vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val) == 0 &&
766                         (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || val == VCONFKEY_SYSMAN_POWER_OFF_RESTART)) {
767                 app_efl_exit();
768         }
769 }
770
771 static void _quickpanel_ui_vconf_event_lcdoff_cb(keynode_t *node,
772                                                 void *data)
773 {
774         int ret = 0;
775         int pm_state = VCONFKEY_PM_STATE_NORMAL;
776
777         ret = vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
778
779         if (ret == 0 && pm_state == VCONFKEY_PM_STATE_LCDOFF) {
780                 quickpanel_close_quickpanel(false);
781         }
782 }
783
784 static void _quickpanel_ui_vconf_event_init(struct appdata *ad)
785 {
786         int ret = 0;
787
788         ret = vconf_notify_key_changed(VCONFKEY_PM_STATE,
789                         _quickpanel_ui_vconf_event_lcdoff_cb, ad);
790         if (ret != 0) {
791                 ERR("VCONFKEY_PM_STATE: %d", ret);
792         }
793
794         ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
795                         _quickpanel_ui_vconf_event_powerff_cb, ad);
796         if (ret != 0) {
797                 ERR("VCONFKEY_PM_STATE: %d", ret);
798         }
799 }
800
801 static void _quickpanel_ui_vconf_event_fini(struct appdata *ad)
802 {
803         int ret = 0;
804
805         ret = vconf_ignore_key_changed(VCONFKEY_PM_STATE,
806                         _quickpanel_ui_vconf_event_lcdoff_cb);
807         if (ret != 0) {
808                 ERR("VCONFKEY_PM_STATE: %d", ret);
809         }
810
811         ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
812                         _quickpanel_ui_vconf_event_powerff_cb);
813         if (ret != 0) {
814                 ERR("VCONFKEY_PM_STATE: %d", ret);
815         }
816 }
817
818 static void _quickpanel_ui_init_ecore_event(struct appdata *ad)
819 {
820         Ecore_Event_Handler *hdl = NULL;
821
822         /* Register window rotate event */
823         hdl = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
824                                 quickpanel_ui_client_message_cb, ad);
825         if (hdl == NULL)
826                 ERR("failed to add handler(ECORE_X_EVENT_CLIENT_MESSAGE)");
827
828         ad->hdl_client_message = hdl;
829 }
830
831 static void _quickpanel_ui_fini_ecore_event(struct appdata *ad)
832 {
833         if (ad->hdl_client_message != NULL) {
834                 ecore_event_handler_del(ad->hdl_client_message);
835                 ad->hdl_client_message = NULL;
836         }
837 }
838
839 static void _quickpanel_ui_setting_show(struct appdata *ad, int show)
840 {
841         if (!ad)
842                 return;
843
844         if (!ad->ly)
845                 return;
846 }
847
848 static void _quickpanel_ui_update_height(void *data)
849 {
850         int contents_height = 0;
851         int height_genlist = 0;
852
853         struct appdata *ad = NULL;
854
855         retif(data == NULL, , "data is NULL");
856         ad = data;
857
858         height_genlist = ad->gl_limit_height;
859         contents_height = ad->gl_distance_from_top + height_genlist + ad->gl_distance_to_bottom - ad->scale * QP_HANDLE_H;
860
861         _quickpanel_ui_window_set_input_region(ad, contents_height);
862         _quickpanel_ui_window_set_content_region(ad, contents_height);
863 }
864
865 static void _quickpanel_init_size_genlist(void *data)
866 {
867         struct appdata *ad = NULL;
868         int max_height_window = 0;
869         Evas_Coord genlist_y = 0;
870         Evas_Coord spn_height = 0;
871
872         retif(data == NULL, , "data is NULL");
873         ad = data;
874
875         if (ad->angle == 90 || ad->angle == 270 )
876                 max_height_window = ad->win_width;
877         else
878                 max_height_window = ad->win_height;
879
880         edje_object_part_geometry_get(_EDJ(ad->ly), "qp.gl_base.gl.swallow", NULL, &genlist_y, NULL, NULL);
881         edje_object_part_geometry_get(_EDJ(ad->ly), "qp.base.spn.swallow", NULL, NULL, NULL, &spn_height);
882
883         ad->gl_distance_from_top = genlist_y;
884         ad->gl_distance_to_bottom = spn_height + (1 * ad->scale) + (ad->scale*QP_HANDLE_H) ;
885         ad->gl_limit_height = max_height_window - ad->gl_distance_from_top - ad->gl_distance_to_bottom;
886 }
887
888 /*****************************************************************************
889   *
890   * App efl main interface
891   *
892   ****************************************************************************/
893 static bool quickpanel_app_create(void *data)
894 {
895         DBG("");
896
897         pid_t pid;
898         int r;
899
900         // signal handler
901         struct sigaction act;
902         act.sa_sigaction = _quickpanel_signal_handler;
903         act.sa_flags = SA_SIGINFO;
904
905         int ret = sigemptyset(&act.sa_mask);
906         if (ret < 0) {
907                 ERR("Failed to sigemptyset[%s]", strerror(errno));
908         }
909         ret = sigaddset(&act.sa_mask, SIGTERM);
910         if (ret < 0) {
911                 ERR("Failed to sigaddset[%s]", strerror(errno));
912         }
913         ret = sigaction(SIGTERM, &act, NULL);
914         if (ret < 0) {
915                 ERR("Failed to sigaction[%s]", strerror(errno));
916         }
917
918         pid = setsid();
919         if (pid < 0)
920                 WARN("Failed to set session id!");
921
922         r = nice(2);
923         if (r == -1)
924                 WARN("Failed to set nice value!");
925
926         return TRUE;
927 }
928
929 static void quickpanel_app_terminate(void *data)
930 {
931         DBG("");
932
933         struct appdata *ad = data;
934         retif(ad == NULL, , "invalid data.");
935
936         /* fini quickpanel modules */
937         fini_modules(ad);
938
939         _quickpanel_cache_flush(ad->evas);
940
941         feedback_deinitialize();
942
943         quickpanel_service_keyboard_fini(ad);
944
945         /* unregister system event callback */
946         _quickpanel_ui_vconf_event_fini(ad);
947
948         _quickpanel_ui_fini_ecore_event(ad);
949
950         if (ad->cover_indicator_right != NULL) {
951                 evas_object_del(ad->cover_indicator_right);
952                 ad->cover_indicator_right = NULL;
953         }
954         /* delete quickpanel window */
955         _quickpanel_ui_delete_win(ad);
956
957         INFO(" >>>>>>>>>>>>>>> QUICKPANEL IS TERMINATED!! <<<<<<<<<<<<<<<< ");
958 }
959
960 static void quickpanel_app_pause(void *data)
961 {
962         DBG("");
963
964         struct appdata *ad = data;
965         retif(ad == NULL,, "invalid data.");
966
967         suspend_modules(ad);
968         quickpanel_ui_del_current_popup();
969
970         ad->is_suspended = 1;
971
972         _quickpanel_cache_flush(ad->evas);
973 }
974
975 static void quickpanel_app_resume(void *data)
976 {
977         DBG("");
978
979         struct appdata *ad = data;
980         retif(ad == NULL,, "invalid data.");
981
982         ad->is_suspended = 0;
983
984         resume_modules(data);
985 }
986
987 static void quickpanel_app_service(service_h service, void *data)
988 {
989         struct appdata *ad = data;
990         int ret = 0;
991
992         retif(ad == NULL, , "Invialid parameter!");
993
994         INFO(" >>>>>>>>>>>>>>> QUICKPANEL IS STARTED!! <<<<<<<<<<<<<<<< ");
995
996         /* Check emulator */
997         ad->is_emul = quickpanel_is_emul();
998         INFO("quickpanel run in %s", ad->is_emul ? "Emul" : "Device");
999
1000         ad->scale = elm_config_scale_get();
1001         if (ad->scale < 0)
1002                 ad->scale = 1.0;
1003
1004         INFO("quickpanel scale %f", ad->scale);
1005
1006         ad->is_suspended = 1;
1007
1008         /* Get theme */
1009         elm_theme_extension_add(NULL, DEFAULT_THEME_EDJ);
1010
1011         /* create quickpanel window */
1012         ret = _quickpanel_ui_create_win(ad);
1013         retif(ret != QP_OK, , "Failed to create window!");
1014
1015         atoms_init_quickpanel();
1016
1017         ad->E_ILLUME_ATOM_MV_QUICKPANEL_STATE = &E_ILLUME_ATOM_MV_QUICKPANEL_STATE;
1018
1019         _quickpanel_ui_init_ecore_event(ad);
1020
1021         _quickpanel_ui_vconf_event_init(ad);
1022
1023         feedback_initialize();
1024
1025 #ifdef QP_SETTING_ENABLE
1026         _quickpanel_ui_setting_show(ad, 1);
1027 #else /* QP_SETTING_ENABLE */
1028         _quickpanel_ui_setting_show(ad, 0);
1029 #endif /* QP_SETTING_ENABLE */
1030
1031         /* init quickpanel modules */
1032         init_modules(ad);
1033
1034         quickpanel_service_keyboard_init(ad);
1035
1036         ecore_idler_add(_quickpanel_ui_refresh_cb, ad);
1037 }
1038
1039 static void quickpanel_app_language_changed_cb(void *data)
1040 {
1041         retif(data == NULL, , "Invalid parameter!");
1042
1043         INFO(" >>>>>>>>>>>>>>> LANGUAGE CHANGED!! <<<<<<<<<<<<<<<< ");
1044         lang_change_modules(data);
1045 }
1046
1047 static void quickpanel_app_region_format_changed_cb(void *data)
1048 {
1049         INFO(" >>>>>>>>>>>>>>> region_format CHANGED!! <<<<<<<<<<<<<<<< ");
1050         lang_change_modules(data);
1051 }
1052
1053 HAPI void quickpanel_open_quickpanel(void) {
1054         Ecore_X_Window xwin;
1055         Ecore_X_Window zone;
1056         struct appdata *ad = g_app_data;
1057
1058         DBG("");
1059
1060         retif(ad == NULL, , "Invalid parameter!");
1061         retif(ad->win == NULL, , "Invalid parameter!");
1062
1063         xwin = elm_win_xwindow_get(ad->win);
1064         if (xwin != 0) {
1065                 if ((zone = ecore_x_e_illume_zone_get(xwin)) != 0) {
1066                         if (ecore_x_e_illume_quickpanel_state_get(zone) == ECORE_X_ILLUME_QUICKPANEL_STATE_OFF) {
1067                                 ecore_x_e_illume_quickpanel_state_send(zone, ECORE_X_ILLUME_QUICKPANEL_STATE_ON);
1068                         }
1069                 } else {
1070                         ERR("failed to get zone");
1071                 }
1072         } else {
1073                 ERR("failed to get xwin");
1074         }
1075 }
1076
1077 HAPI void quickpanel_close_quickpanel(bool is_check_lock) {
1078         Ecore_X_Window xwin;
1079         Ecore_X_Window zone;
1080         int is_lock_launched = VCONFKEY_IDLE_UNLOCK;
1081         struct appdata *ad = g_app_data;
1082
1083         DBG("");
1084
1085         retif(ad == NULL, , "Invalid parameter!");
1086         retif(ad->win == NULL, , "Invalid parameter!");
1087
1088         if (is_check_lock == true) {
1089                 if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &is_lock_launched) == 0) {
1090                         if (is_lock_launched == VCONFKEY_IDLE_LOCK) {
1091                                 vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_UNLOCK);
1092                                 ERR("do unlock");
1093                         }
1094                 }
1095         }
1096
1097         xwin = elm_win_xwindow_get(ad->win);
1098         if (xwin != 0) {
1099                 if ((zone = ecore_x_e_illume_zone_get(xwin)) != 0) {
1100                         if (ecore_x_e_illume_quickpanel_state_get(zone) == ECORE_X_ILLUME_QUICKPANEL_STATE_ON) {
1101                                 ecore_x_e_illume_quickpanel_state_send(zone, ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
1102                         }
1103                 } else {
1104                         ERR("failed to get zone");
1105                 }
1106         } else {
1107                 ERR("failed to get xwin");
1108         }
1109 }
1110
1111 HAPI void quickpanel_toggle_openning_quickpanel(void) {
1112         Ecore_X_Window xwin;
1113         Ecore_X_Window zone;
1114         struct appdata *ad = g_app_data;
1115
1116         DBG("");
1117
1118         retif(ad == NULL, , "Invalid parameter!");
1119         retif(ad->win == NULL, , "Invalid parameter!");
1120
1121         xwin = elm_win_xwindow_get(ad->win);
1122         if (xwin != 0) {
1123                 if ((zone = ecore_x_e_illume_zone_get(xwin)) != 0) {
1124                         if (ecore_x_e_illume_quickpanel_state_get(zone) == ECORE_X_ILLUME_QUICKPANEL_STATE_ON) {
1125                                 ecore_x_e_illume_quickpanel_state_send(zone, ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
1126                         } else {
1127                                 ecore_x_e_illume_quickpanel_state_send(zone, ECORE_X_ILLUME_QUICKPANEL_STATE_ON);
1128                         }
1129                 } else {
1130                         ERR("failed to get zone");
1131                 }
1132         } else {
1133                 ERR("failed to get xwin");
1134         }
1135 }
1136
1137 int main(int argc, char *argv[])
1138 {
1139         int r = 0;
1140         struct appdata ad;
1141         app_event_callback_s app_callback = {0,};
1142
1143         r = control_privilege();
1144         if (r != 0) {
1145                 WARN("Failed to control privilege!");
1146         }
1147
1148         app_callback.create = quickpanel_app_create;
1149         app_callback.terminate = quickpanel_app_terminate;
1150         app_callback.pause = quickpanel_app_pause;
1151         app_callback.resume = quickpanel_app_resume;
1152         app_callback.service = quickpanel_app_service;
1153         app_callback.low_memory = NULL;
1154         app_callback.low_battery = NULL;
1155         app_callback.device_orientation = NULL;
1156         app_callback.language_changed = quickpanel_app_language_changed_cb;
1157         app_callback.region_format_changed = quickpanel_app_region_format_changed_cb;
1158
1159         memset(&ad, 0x0, sizeof(struct appdata));
1160
1161         g_app_data = &ad;
1162
1163         return app_efl_main(&argc, &argv, &app_callback, (void *)&ad);
1164 }