Merge branch 'master' into tizen_2.0
[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 Evas *menu_screen_get_evas(void)
68 {
69         return menu_screen_info.evas;
70 }
71
72
73
74 int menu_screen_get_root_width(void)
75 {
76         return menu_screen_info.root_width;
77 }
78
79
80
81 int menu_screen_get_root_height(void)
82 {
83         return menu_screen_info.root_height;
84 }
85
86
87
88 Evas_Object *menu_screen_get_win(void)
89 {
90         return menu_screen_info.win;
91 }
92
93
94
95 Elm_Theme *menu_screen_get_theme(void)
96 {
97         return menu_screen_info.theme;
98 }
99
100
101
102 bool menu_screen_get_done(void)
103 {
104         return menu_screen_info.is_done;
105 }
106
107
108
109 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_data_set(menu_screen_get_win(), "bg", bg);
226         }
227
228         if (trigger == 0) {
229                 key = "/";
230                 trigger = 1;
231         } else {
232                 key = NULL;
233                 trigger = 0;
234         }
235
236         evas_object_image_file_set(bg, buf, key);
237         evas_object_image_size_get(bg, &w, &h);
238         evas_object_image_filled_set(bg, 1);
239
240         wf = (double) width / (double) w;
241         hf = (double) height / (double) h;
242
243         f = wf < hf ? hf : wf;
244
245         w = (int) ((double) f * (double) w);
246         h = (int) ((double) f * (double) h);
247
248         evas_object_image_load_size_set(bg, w, h);
249         evas_object_image_fill_set(bg, 0, 0, w, h);
250         evas_object_move(bg, (width - w) / 2, (height - h) / 2);
251         evas_object_resize(bg, w, h);
252         evas_object_show(bg);
253
254         free(buf);
255 }
256
257
258
259
260 static void _destroy_bg()
261 {
262         Evas_Object *rect;
263         Evas_Object *bg;
264
265         rect = evas_object_data_del(menu_screen_get_win(), "rect");
266         evas_object_del(rect);
267
268         bg = evas_object_data_del(menu_screen_get_win(), "bg");
269         evas_object_del(bg);
270 }
271
272
273
274 static void _change_bg_cb(keynode_t *node, void *data)
275 {
276         _D("Background image is changed.");
277         _create_bg();
278 }
279
280
281
282 static void _init_theme(void)
283 {
284         menu_screen_info.theme = elm_theme_new();
285         elm_theme_ref_set(menu_screen_info.theme, NULL);
286         elm_theme_extension_add(menu_screen_info.theme, EDJEDIR"/index.edj");
287 }
288
289
290
291 static void _fini_theme(void)
292 {
293         elm_theme_extension_del(menu_screen_info.theme, EDJEDIR"/index.edj");
294         elm_theme_free(menu_screen_info.theme);
295         menu_screen_info.theme = NULL;
296
297 }
298
299
300
301 Evas_Object *_create_conformant(Evas_Object *win)
302 {
303         Evas_Object *conformant;
304
305         conformant = elm_conformant_add(win);
306         retv_if(NULL == conformant, NULL);
307
308         evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
309         evas_object_data_set(conformant, "win", win);
310         evas_object_show(conformant);
311
312         elm_win_resize_object_add(win, conformant);
313         elm_win_conformant_set(win, EINA_TRUE);
314
315         return conformant;
316 }
317
318
319
320 void _destroy_conformant(Evas_Object *conformant)
321 {
322         evas_object_data_del(conformant, "win");
323         evas_object_del(conformant);
324 }
325
326
327
328 static bool _create_cb(void *data)
329 {
330         Evas_Object *conformant;
331         Evas_Object *layout;
332
333         _get_window_size();
334         _init_theme();
335         retv_if(MENU_SCREEN_ERROR_FAIL == _create_canvas(PACKAGE, PACKAGE), false);
336         elm_win_indicator_mode_set(menu_screen_info.win, ELM_WIN_INDICATOR_SHOW);
337
338         if (vconf_notify_key_changed(VCONFKEY_BGSET, _change_bg_cb, NULL) < 0) {
339                 _E("Failed to register a vconf cb for %s\n", VCONFKEY_BGSET);
340         }
341         _create_bg();
342
343         conformant = _create_conformant(menu_screen_info.win);
344         retv_if(NULL == conformant, false);
345         evas_object_data_set(menu_screen_info.win, "conformant", conformant);
346
347         layout = layout_create(conformant, LAYOUT_EDJE_PORTRAIT,
348                                 LAYOUT_GROUP_NAME, MENU_SCREEN_ROTATE_PORTRAIT);
349         if (NULL == layout) {
350                 _E("Failed to load an edje object");
351                 evas_object_del(menu_screen_info.win);
352                 return false;
353         }
354         evas_object_data_set(menu_screen_info.win, "layout", layout);
355
356         elm_object_content_set(conformant, layout);
357         mouse_register();
358         aul_listen_app_dead_signal(_dead_cb, NULL);
359
360         return true;
361 }
362
363
364
365 static void _terminate_cb(void *data)
366 {
367         Evas_Object *conformant;
368         Evas_Object *layout;
369
370         if (vconf_ignore_key_changed(VCONFKEY_BGSET, _change_bg_cb) < 0) {
371                 _E("Failed to remove bgset %s\n", VCONFKEY_BGSET);
372         }
373
374         evas_object_hide(menu_screen_info.win);
375
376         mouse_unregister();
377
378         layout = evas_object_data_del(menu_screen_info.win, "layout");
379         if (layout) layout_destroy(layout);
380
381         conformant = evas_object_data_del(menu_screen_info.win, "conformant");
382         if (conformant) _destroy_conformant(conformant);
383
384         _destroy_bg();
385         _destroy_canvas();
386         _fini_theme();
387         evas_object_del(menu_screen_info.win);
388 }
389
390
391
392 static void _pause_cb(void *data)
393 {
394         _D("Pause start");
395
396         if (vconf_set_int(VCONFKEY_IDLE_SCREEN_TOP, VCONFKEY_IDLE_SCREEN_TOP_FALSE) < 0) {
397                 _E("Failed to set %s to 0", VCONFKEY_IDLE_SCREEN_TOP);
398         }
399
400         menu_screen_info.state = APP_STATE_PAUSE;
401 }
402
403
404
405 static void _resume_cb(void *data)
406 {
407         _D("START RESUME");
408
409         if (vconf_set_int(VCONFKEY_IDLE_SCREEN_TOP, VCONFKEY_IDLE_SCREEN_TOP_TRUE) < 0) {
410                 _E("Failed to set %s to 1", VCONFKEY_IDLE_SCREEN_TOP);
411         }
412
413         utilx_hide_fake_effect(
414                 ecore_x_display_get(),
415                 ecore_x_window_root_get(ecore_evas_window_get(menu_screen_info.ee))
416         );
417
418         menu_screen_info.state = APP_STATE_RESUME;
419 }
420
421
422
423 static void _service_cb(service_h service, void *data)
424 {
425         _D("START RESET : %d", menu_screen_info.state);
426
427         if (vconf_set_int(VCONFKEY_IDLE_SCREEN_TOP, VCONFKEY_IDLE_SCREEN_TOP_TRUE) < 0) {
428                 _E("Failed to set %s to 1", VCONFKEY_IDLE_SCREEN_TOP);
429         }
430
431         utilx_hide_fake_effect(
432                 ecore_x_display_get(),
433                 ecore_x_window_root_get(ecore_evas_window_get(menu_screen_info.ee))
434         );
435 }
436
437
438
439 static void _language_changed_cb(void *data)
440 {
441         register unsigned int i;
442         register unsigned int j;
443         unsigned int count;
444         Evas_Object *layout;
445         Evas_Object *all_apps;
446         Evas_Object *scroller;
447         Evas_Object *page;
448         Evas_Object *item;
449         unsigned int page_max_app;
450
451         _D("Language is changed");
452
453         if (false == menu_screen_info.is_done) {
454                 elm_exit();
455         }
456
457         layout = evas_object_data_get(menu_screen_info.win, "layout");
458         ret_if(NULL == layout);
459         all_apps = evas_object_data_get(layout, "all_apps");
460         ret_if(NULL == all_apps);
461         scroller = elm_object_part_content_get(all_apps, "content");
462         ret_if(NULL == scroller);
463
464         count = page_scroller_count_page(scroller);
465         page_max_app = (unsigned int) evas_object_data_get(scroller, "page_max_app");
466         for (i = 0; i < count; i ++) {
467                 page = page_scroller_get_page_at(scroller, i);
468                 if (!page) continue;
469                 if (mapbuf_is_enabled(page)) {
470                         mapbuf_disable(page, 1);
471                 }
472
473                 for (j = 0; j < page_max_app; j ++) {
474                         ail_appinfo_h ai;
475                         char *name;
476
477                         item = page_get_item_at(page, j);
478                         if (!item) continue;
479
480                         if (ail_get_appinfo(item_get_package(item), &ai) < 0) continue;
481                         if (ail_appinfo_get_str(ai, AIL_PROP_NAME_STR, &name) < 0) {
482                                 ail_destroy_appinfo(ai);
483                                 continue;
484                         }
485
486                         if (!name) {
487                                 _D("Failed to get name for %s", item_get_package(item));
488                                 ail_destroy_appinfo(ai);
489                                 continue;
490                         }
491
492                         item_set_name(item, name, 0);
493                         ail_destroy_appinfo(ai);
494                 }
495
496                 mapbuf_enable(page, 1);
497         }
498 }
499
500
501
502 static void _init(app_event_callback_s *event_callback)
503 {
504         event_callback->create = _create_cb;
505         event_callback->terminate = _terminate_cb;
506         event_callback->pause = _pause_cb;
507         event_callback->resume = _resume_cb;
508         event_callback->service = _service_cb;
509         event_callback->low_memory = NULL;
510         event_callback->low_battery = NULL;
511         event_callback->device_orientation = NULL;
512         event_callback->language_changed = _language_changed_cb;
513         event_callback->region_format_changed = NULL;
514 }
515
516
517
518 static void _fini(void)
519 {
520 }
521
522
523
524 int main(int argc, char *argv[])
525 {
526         char *buf;
527         app_event_callback_s event_callback;
528
529         buf = vconf_get_str(MENU_SCREEN_ENGINE);
530         if (buf) {
531                 _D("ELM_ENGINE is set as [%s]\n", buf);
532                 setenv("ELM_ENGINE", buf, 1);
533                 free(buf);
534         } else {
535                 _D("ELM_ENGINE is set as [%s]", "gl");
536                 setenv("ELM_ENGINE", "gl", 1);
537         }
538
539         _init(&event_callback);
540         app_efl_main(&argc, &argv, &event_callback, NULL);
541         _fini();
542
543         return EXIT_SUCCESS;
544 }
545
546
547
548
549
550 // End of a file