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