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