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