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