Merge branch 'master' into sdk
[apps/native/menu-screen.git] / src / menu_screen.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://www.tizenopensource.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
18
19 #include <Elementary.h>
20 #include <Ecore_X.h>
21 #include <ail.h>
22 #include <app.h>
23 #include <stdbool.h>
24 #include <vconf.h>
25 #include <utilX.h>
26 #include <aul.h>
27
28 #include "conf.h"
29 #include "item.h"
30 #include "layout.h"
31 #include "mapbuf.h"
32 #include "menu_screen.h"
33 #include "mouse.h"
34 #include "page.h"
35 #include "page_scroller.h"
36 #include "util.h"
37
38 #define MENU_SCREEN_ENGINE "file/private/org.tizen.menu-screen/engine"
39
40 #define LAYOUT_EDJE_PORTRAIT EDJEDIR"/layout_portrait.edj"
41 #define LAYOUT_GROUP_NAME "layout"
42
43
44
45 // Define prototype of the "hidden API of AUL"
46 extern int aul_listen_app_dead_signal(int (*func)(int signal, void *data), void *data);
47 static struct {
48         int state;
49         int root_width;
50         int root_height;
51         Evas *evas;
52         Ecore_Evas *ee;
53         Evas_Object *win;
54         Elm_Theme *theme;
55         bool is_done;
56 } menu_screen_info = {
57         .state = APP_STATE_PAUSE,
58         .evas = NULL,
59         .ee = NULL,
60         .win = NULL,
61         .theme = NULL,
62         .is_done = false,
63 };
64
65
66
67 HAPI Evas *menu_screen_get_evas(void)
68 {
69         return menu_screen_info.evas;
70 }
71
72
73
74 HAPI int menu_screen_get_root_width(void)
75 {
76         return menu_screen_info.root_width;
77 }
78
79
80
81 HAPI int menu_screen_get_root_height(void)
82 {
83         return menu_screen_info.root_height;
84 }
85
86
87
88 HAPI Evas_Object *menu_screen_get_win(void)
89 {
90         return menu_screen_info.win;
91 }
92
93
94
95 HAPI Elm_Theme *menu_screen_get_theme(void)
96 {
97         return menu_screen_info.theme;
98 }
99
100
101
102 HAPI bool menu_screen_get_done(void)
103 {
104         return menu_screen_info.is_done;
105 }
106
107
108
109 HAPI void menu_screen_set_done(bool is_done)
110 {
111         menu_screen_info.is_done = is_done;
112 }
113
114
115
116 static menu_screen_error_e _create_canvas(char *name, char *title)
117 {
118         Ecore_X_Atom ATOM_WM_WINDOW_ROLE;
119
120         menu_screen_info.win = elm_win_add(NULL, name, ELM_WIN_BASIC);
121         retv_if(NULL == menu_screen_info.win, MENU_SCREEN_ERROR_FAIL);
122
123         if (title) {
124                 elm_win_title_set(menu_screen_info.win, title);
125         }
126         elm_win_borderless_set(menu_screen_info.win, EINA_TRUE);
127
128         ecore_x_icccm_name_class_set(elm_win_xwindow_get(menu_screen_info.win), "MENU_SCREEN", "MENU_SCREEN");
129         ATOM_WM_WINDOW_ROLE = ecore_x_atom_get("WM_WINDOW_ROLE");
130         if (ATOM_WM_WINDOW_ROLE) {
131                 ecore_x_window_prop_string_set(elm_win_xwindow_get(menu_screen_info.win), ATOM_WM_WINDOW_ROLE, "MENU_SCREEN");
132         } else {
133                 _D("Failed to set the window role as MENU_SCREEN");
134         }
135
136         menu_screen_info.evas = evas_object_evas_get(menu_screen_info.win);
137         if (!menu_screen_info.evas) {
138                 _E("[%s] Failed to get the evas object", __func__);
139         }
140
141         menu_screen_info.ee = ecore_evas_ecore_evas_get(menu_screen_info.evas);
142         if (!menu_screen_info.ee) {
143                 _E("[%s] Failed to get ecore_evas object", __func__);
144         }
145
146         evas_object_size_hint_min_set(menu_screen_info.win, menu_screen_info.root_width, menu_screen_info.root_height);
147         evas_object_size_hint_max_set(menu_screen_info.win, menu_screen_info.root_width, menu_screen_info.root_height);
148         evas_object_resize(menu_screen_info.win, menu_screen_info.root_width, menu_screen_info.root_height);
149         evas_object_show(menu_screen_info.win);
150
151         return MENU_SCREEN_ERROR_OK;
152 }
153
154
155
156 static void _destroy_canvas(void)
157 {
158         evas_object_del(menu_screen_info.win);
159 }
160
161
162
163 static int _dead_cb(int pid, void *data)
164 {
165         utilx_hide_fake_effect(
166                 ecore_x_display_get(),
167                 ecore_x_window_root_get(ecore_evas_window_get(menu_screen_info.ee))
168         );
169
170         return EXIT_SUCCESS;
171 }
172
173
174
175 static void _get_window_size(void)
176 {
177         Ecore_X_Window focus_win;
178         Ecore_X_Window root_win;
179
180         focus_win = ecore_x_window_focus_get();
181         root_win = ecore_x_window_root_get(focus_win);
182         ecore_x_window_size_get(root_win, &menu_screen_info.root_width, &menu_screen_info.root_height);
183
184         _D("width:%d, height:%d", menu_screen_info.root_width, menu_screen_info.root_height);
185 }
186
187
188
189 static void _create_bg(void)
190 {
191         char *buf;
192         Evas_Coord w;
193         Evas_Coord h;
194         Evas_Object *bg;
195         double f, wf, hf;
196         static int trigger = 0;
197         const char *key;
198         int width;
199         int height;
200
201         buf = vconf_get_str(VCONFKEY_BGSET);
202         ret_if(NULL == buf);
203
204         width = menu_screen_get_root_width();
205         height = menu_screen_get_root_height();
206
207         bg = evas_object_data_get(menu_screen_get_win(), "bg");
208         if (NULL == bg) {
209                 Evas_Object *rect;
210
211                 rect = evas_object_rectangle_add(menu_screen_get_evas());
212                 ret_if(NULL == rect);
213                 evas_object_data_set(menu_screen_get_win(), "rect", rect);
214                 evas_object_color_set(rect, 0, 0, 0, 255);
215                 evas_object_size_hint_min_set(rect, width, height);
216                 evas_object_size_hint_max_set(rect, width, height);
217                 evas_object_resize(rect, width, height);
218                 evas_object_show(rect);
219
220                 bg = evas_object_image_add(menu_screen_get_evas());
221                 if (NULL == bg) {
222                         free(buf);
223                         return;
224                 }
225                 evas_object_image_load_orientation_set(bg, EINA_TRUE);
226                 evas_object_data_set(menu_screen_get_win(), "bg", bg);
227         }
228
229         if (trigger == 0) {
230                 key = "/";
231                 trigger = 1;
232         } else {
233                 key = NULL;
234                 trigger = 0;
235         }
236
237         evas_object_image_file_set(bg, buf, key);
238         evas_object_image_size_get(bg, &w, &h);
239         evas_object_image_filled_set(bg, 1);
240
241         wf = (double) width / (double) w;
242         hf = (double) height / (double) h;
243
244         f = wf < hf ? hf : wf;
245
246         w = (int) ((double) f * (double) w);
247         h = (int) ((double) f * (double) h);
248
249         evas_object_image_load_size_set(bg, w, h);
250         evas_object_image_fill_set(bg, 0, 0, w, h);
251         evas_object_move(bg, (width - w) / 2, (height - h) / 2);
252         evas_object_resize(bg, w, h);
253         evas_object_show(bg);
254
255         free(buf);
256 }
257
258
259
260
261 static void _destroy_bg()
262 {
263         Evas_Object *rect;
264         Evas_Object *bg;
265
266         rect = evas_object_data_del(menu_screen_get_win(), "rect");
267         evas_object_del(rect);
268
269         bg = evas_object_data_del(menu_screen_get_win(), "bg");
270         evas_object_del(bg);
271 }
272
273
274
275 static void _change_bg_cb(keynode_t *node, void *data)
276 {
277         _D("Background image is changed.");
278         _create_bg();
279 }
280
281
282
283 static void _init_theme(void)
284 {
285         menu_screen_info.theme = elm_theme_new();
286         elm_theme_ref_set(menu_screen_info.theme, NULL);
287         elm_theme_extension_add(menu_screen_info.theme, EDJEDIR"/index.edj");
288 }
289
290
291
292 static void _fini_theme(void)
293 {
294         elm_theme_extension_del(menu_screen_info.theme, EDJEDIR"/index.edj");
295         elm_theme_free(menu_screen_info.theme);
296         menu_screen_info.theme = NULL;
297
298 }
299
300
301
302 static Evas_Object *_create_conformant(Evas_Object *win)
303 {
304         Evas_Object *conformant;
305
306         conformant = elm_conformant_add(win);
307         retv_if(NULL == conformant, NULL);
308
309         elm_object_style_set(conformant, "nokeypad");
310         evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
311         evas_object_data_set(conformant, "win", win);
312         evas_object_show(conformant);
313
314         elm_win_resize_object_add(win, conformant);
315         elm_win_conformant_set(win, EINA_TRUE);
316
317         return conformant;
318 }
319
320
321
322 static void _destroy_conformant(Evas_Object *conformant)
323 {
324         evas_object_data_del(conformant, "win");
325         evas_object_del(conformant);
326 }
327
328
329
330 static bool _create_cb(void *data)
331 {
332         Evas_Object *conformant;
333         Evas_Object *layout;
334
335         _get_window_size();
336         _init_theme();
337         retv_if(MENU_SCREEN_ERROR_FAIL == _create_canvas(PACKAGE, PACKAGE), false);
338         elm_win_indicator_mode_set(menu_screen_info.win, ELM_WIN_INDICATOR_SHOW);
339
340         if (vconf_notify_key_changed(VCONFKEY_BGSET, _change_bg_cb, NULL) < 0) {
341                 _E("Failed to register a vconf cb for %s\n", VCONFKEY_BGSET);
342         }
343         _create_bg();
344
345         conformant = _create_conformant(menu_screen_info.win);
346         retv_if(NULL == conformant, false);
347         evas_object_data_set(menu_screen_info.win, "conformant", conformant);
348
349         layout = layout_create(conformant, LAYOUT_EDJE_PORTRAIT,
350                                 LAYOUT_GROUP_NAME, MENU_SCREEN_ROTATE_PORTRAIT);
351         if (NULL == layout) {
352                 _E("Failed to load an edje object");
353                 evas_object_del(menu_screen_info.win);
354                 return false;
355         }
356         evas_object_data_set(menu_screen_info.win, "layout", layout);
357
358         elm_object_content_set(conformant, layout);
359         mouse_register();
360         aul_listen_app_dead_signal(_dead_cb, NULL);
361
362         return true;
363 }
364
365
366
367 static void _terminate_cb(void *data)
368 {
369         Evas_Object *conformant;
370         Evas_Object *layout;
371
372         if (vconf_ignore_key_changed(VCONFKEY_BGSET, _change_bg_cb) < 0) {
373                 _E("Failed to remove bgset %s\n", VCONFKEY_BGSET);
374         }
375
376         evas_object_hide(menu_screen_info.win);
377
378         mouse_unregister();
379
380         layout = evas_object_data_del(menu_screen_info.win, "layout");
381         if (layout) layout_destroy(layout);
382
383         conformant = evas_object_data_del(menu_screen_info.win, "conformant");
384         if (conformant) _destroy_conformant(conformant);
385
386         _destroy_bg();
387         _destroy_canvas();
388         _fini_theme();
389         evas_object_del(menu_screen_info.win);
390 }
391
392
393
394 static void _pause_cb(void *data)
395 {
396         _D("Pause start");
397
398         if (vconf_set_int(VCONFKEY_IDLE_SCREEN_TOP, VCONFKEY_IDLE_SCREEN_TOP_FALSE) < 0) {
399                 _E("Failed to set %s to 0", VCONFKEY_IDLE_SCREEN_TOP);
400         }
401
402         menu_screen_info.state = APP_STATE_PAUSE;
403 }
404
405
406
407 static void _resume_cb(void *data)
408 {
409         _D("START RESUME");
410
411         if (vconf_set_int(VCONFKEY_IDLE_SCREEN_TOP, VCONFKEY_IDLE_SCREEN_TOP_TRUE) < 0) {
412                 _E("Failed to set %s to 1", VCONFKEY_IDLE_SCREEN_TOP);
413         }
414
415         utilx_hide_fake_effect(
416                 ecore_x_display_get(),
417                 ecore_x_window_root_get(ecore_evas_window_get(menu_screen_info.ee))
418         );
419
420         menu_screen_info.state = APP_STATE_RESUME;
421 }
422
423
424
425 static void _service_cb(service_h service, void *data)
426 {
427         _D("START RESET : %d", menu_screen_info.state);
428
429         if (vconf_set_int(VCONFKEY_IDLE_SCREEN_TOP, VCONFKEY_IDLE_SCREEN_TOP_TRUE) < 0) {
430                 _E("Failed to set %s to 1", VCONFKEY_IDLE_SCREEN_TOP);
431         }
432
433         utilx_hide_fake_effect(
434                 ecore_x_display_get(),
435                 ecore_x_window_root_get(ecore_evas_window_get(menu_screen_info.ee))
436         );
437 }
438
439
440
441 static void _language_changed_cb(void *data)
442 {
443         register unsigned int i;
444         register unsigned int j;
445         unsigned int count;
446         Evas_Object *layout;
447         Evas_Object *all_apps;
448         Evas_Object *scroller;
449         Evas_Object *page;
450         Evas_Object *item;
451         unsigned int page_max_app;
452
453         _D("Language is changed");
454
455         if (false == menu_screen_info.is_done) {
456                 elm_exit();
457         }
458
459         layout = evas_object_data_get(menu_screen_info.win, "layout");
460         ret_if(NULL == layout);
461         all_apps = evas_object_data_get(layout, "all_apps");
462         ret_if(NULL == all_apps);
463         scroller = elm_object_part_content_get(all_apps, "content");
464         ret_if(NULL == scroller);
465
466         count = page_scroller_count_page(scroller);
467         page_max_app = (unsigned int) evas_object_data_get(scroller, "page_max_app");
468         for (i = 0; i < count; i ++) {
469                 page = page_scroller_get_page_at(scroller, i);
470                 if (!page) continue;
471                 if (mapbuf_is_enabled(page)) {
472                         mapbuf_disable(page, 1);
473                 }
474
475                 for (j = 0; j < page_max_app; j ++) {
476                         ail_appinfo_h ai;
477                         char *name;
478
479                         item = page_get_item_at(page, j);
480                         if (!item) continue;
481
482                         if (ail_get_appinfo(item_get_package(item), &ai) < 0) continue;
483                         if (ail_appinfo_get_str(ai, AIL_PROP_NAME_STR, &name) < 0) {
484                                 ail_destroy_appinfo(ai);
485                                 continue;
486                         }
487
488                         if (!name) {
489                                 _D("Failed to get name for %s", item_get_package(item));
490                                 ail_destroy_appinfo(ai);
491                                 continue;
492                         }
493
494                         item_set_name(item, name, 0);
495                         ail_destroy_appinfo(ai);
496                 }
497
498                 mapbuf_enable(page, 1);
499         }
500 }
501
502
503
504 static void _init(app_event_callback_s *event_callback)
505 {
506         event_callback->create = _create_cb;
507         event_callback->terminate = _terminate_cb;
508         event_callback->pause = _pause_cb;
509         event_callback->resume = _resume_cb;
510         event_callback->service = _service_cb;
511         event_callback->low_memory = NULL;
512         event_callback->low_battery = NULL;
513         event_callback->device_orientation = NULL;
514         event_callback->language_changed = _language_changed_cb;
515         event_callback->region_format_changed = NULL;
516 }
517
518
519
520 static void _fini(void)
521 {
522 }
523
524
525
526 int main(int argc, char *argv[])
527 {
528         char *buf;
529         app_event_callback_s event_callback;
530
531         buf = vconf_get_str(MENU_SCREEN_ENGINE);
532         if (buf) {
533                 _D("ELM_ENGINE is set as [%s]\n", buf);
534                 setenv("ELM_ENGINE", buf, 1);
535                 free(buf);
536         } else {
537                 _D("ELM_ENGINE is set as [%s]", "gl");
538                 setenv("ELM_ENGINE", "gl", 1);
539         }
540
541         _init(&event_callback);
542         app_efl_main(&argc, &argv, &event_callback, NULL);
543         _fini();
544
545         return EXIT_SUCCESS;
546 }
547
548
549
550
551
552 // End of a file