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