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