Fix the build errors
[maemo-rb.git] / apps / main.c
bloba6178829b8cbfb44a7ccbd3abec72862a5acd181
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Björn Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "config.h"
23 #include "gcc_extensions.h"
24 #include "storage.h"
25 #include "disk.h"
26 #include "fat.h"
27 #include "lcd.h"
28 #include "rtc.h"
29 #include "debug.h"
30 #include "led.h"
31 #include "kernel.h"
32 #include "button.h"
33 #include "tree.h"
34 #include "filetypes.h"
35 #include "panic.h"
36 #include "menu.h"
37 #include "system.h"
38 #include "usb.h"
39 #include "powermgmt.h"
40 #include "adc.h"
41 #include "i2c.h"
42 #ifndef DEBUG
43 #include "serial.h"
44 #endif
45 #include "audio.h"
46 #include "mp3_playback.h"
47 #include "thread.h"
48 #include "settings.h"
49 #include "backlight.h"
50 #include "status.h"
51 #include "debug_menu.h"
52 #include "font.h"
53 #include "language.h"
54 #include "wps.h"
55 #include "playlist.h"
56 #include "core_alloc.h"
57 #include "rolo.h"
58 #include "screens.h"
59 #include "usb_screen.h"
60 #include "power.h"
61 #include "talk.h"
62 #include "plugin.h"
63 #include "misc.h"
64 #include "dircache.h"
65 #ifdef HAVE_TAGCACHE
66 #include "tagcache.h"
67 #include "tagtree.h"
68 #endif
69 #include "lang.h"
70 #include "string.h"
71 #include "splash.h"
72 #include "eeprom_settings.h"
73 #include "scrobbler.h"
74 #include "icon.h"
75 #include "viewport.h"
76 #include "skin_engine/skin_engine.h"
77 #include "statusbar-skinned.h"
78 #include "bootchart.h"
79 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
80 #include "notification.h"
81 #endif
83 #ifdef IPOD_ACCESSORY_PROTOCOL
84 #include "iap.h"
85 #endif
87 #if (CONFIG_CODEC == SWCODEC)
88 #include "playback.h"
89 #include "tdspeed.h"
90 #endif
91 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
92 #include "pcm_record.h"
93 #endif
95 #ifdef BUTTON_REC
96 #define SETTINGS_RESET BUTTON_REC
97 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
98 #define SETTINGS_RESET BUTTON_A
99 #endif
101 #if CONFIG_TUNER
102 #include "radio.h"
103 #endif
104 #if (CONFIG_STORAGE & STORAGE_MMC)
105 #include "ata_mmc.h"
106 #endif
108 #ifdef HAVE_REMOTE_LCD
109 #include "lcd-remote.h"
110 #endif
112 #if CONFIG_USBOTG == USBOTG_ISP1362
113 #include "isp1362.h"
114 #endif
116 #if CONFIG_USBOTG == USBOTG_M5636
117 #include "m5636.h"
118 #endif
120 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
121 #define MAIN_NORETURN_ATTR NORETURN_ATTR
122 #else
123 /* gcc adds an implicit 'return 0;' at the end of main(), causing a warning
124 * with noreturn attribute */
125 #define MAIN_NORETURN_ATTR
126 #endif
128 #if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA))
129 #include "sim_tasks.h"
130 #include "system-sdl.h"
131 #define HAVE_ARGV_MAIN
132 /* Don't use SDL_main on windows -> no more stdio redirection */
133 #if defined(WIN32)
134 #undef main
135 #endif
136 #endif
138 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
140 static void init(void);
141 /* main(), and various functions called by main() and init() may be
142 * be INIT_ATTR. These functions must not be called after the final call
143 * to root_menu() at the end of main()
144 * see definition of INIT_ATTR in config.h */
145 #ifdef HAVE_ARGV_MAIN
146 int main(int argc, char *argv[]) INIT_ATTR MAIN_NORETURN_ATTR ;
147 int main(int argc, char *argv[])
149 sys_handle_argv(argc, argv);
150 #else
151 int main(void) INIT_ATTR MAIN_NORETURN_ATTR;
152 int main(void)
154 #endif
155 int i;
156 CHART(">init");
157 init();
158 CHART("<init");
159 FOR_NB_SCREENS(i)
161 screens[i].clear_display();
162 screens[i].update();
164 #ifdef HAVE_LCD_BITMAP
165 list_init();
166 #endif
167 tree_gui_init();
168 /* Keep the order of this 3
169 * Must be done before any code uses the multi-screen API */
170 #ifdef HAVE_USBSTACK
171 /* All threads should be created and public queues registered by now */
172 usb_start_monitoring();
173 #endif
175 #ifdef AUTOROCK
177 char filename[MAX_PATH];
178 const char *file =
179 #ifdef APPLICATION
180 ROCKBOX_DIR
181 #else
182 PLUGIN_APPS_DIR
183 #endif
184 "/autostart.rock";
185 if(file_exists(file)) /* no complaint if it doesn't exist */
187 plugin_load(file, NULL); /* start if it does */
190 #endif /* #ifdef AUTOROCK */
192 global_status.last_volume_change = 0;
193 /* no calls INIT_ATTR functions after this point anymore!
194 * see definition of INIT_ATTR in config.h */
195 CHART(">root_menu");
196 root_menu();
199 static int init_dircache(bool preinit) INIT_ATTR;
200 static int init_dircache(bool preinit)
202 #ifdef HAVE_DIRCACHE
203 int result = 0;
204 bool clear = false;
206 if (preinit)
207 dircache_init();
209 if (!global_settings.dircache)
210 return 0;
212 # ifdef HAVE_EEPROM_SETTINGS
213 if (firmware_settings.initialized && firmware_settings.disk_clean
214 && preinit)
216 result = dircache_load();
218 if (result < 0)
220 firmware_settings.disk_clean = false;
221 if (global_status.dircache_size <= 0)
223 /* This will be in default language, settings are not
224 applied yet. Not really any easy way to fix that. */
225 splash(0, str(LANG_SCANNING_DISK));
226 clear = true;
229 dircache_build(global_status.dircache_size);
232 else
233 # endif
235 if (preinit)
236 return -1;
238 if (!dircache_is_enabled()
239 && !dircache_is_initializing())
241 if (global_status.dircache_size <= 0)
243 splash(0, str(LANG_SCANNING_DISK));
244 clear = true;
246 result = dircache_build(global_status.dircache_size);
249 if (result < 0)
251 /* Initialization of dircache failed. Manual action is
252 * necessary to enable dircache again.
254 splashf(0, "Dircache failed, disabled. Result: %d", result);
255 global_settings.dircache = false;
259 if (clear)
261 backlight_on();
262 show_logo();
263 global_status.dircache_size = dircache_get_cache_size();
264 status_save();
267 return result;
268 #else
269 (void)preinit;
270 return 0;
271 #endif
274 #ifdef HAVE_TAGCACHE
275 static void init_tagcache(void) INIT_ATTR;
276 static void init_tagcache(void)
278 bool clear = false;
279 #if CONFIG_CODEC == SWCODEC
280 long talked_tick = 0;
281 #endif
282 tagcache_init();
284 while (!tagcache_is_initialized())
286 int ret = tagcache_get_commit_step();
288 if (ret > 0)
290 #if CONFIG_CODEC == SWCODEC
291 /* hwcodec can't use voice here, as the database commit
292 * uses the audio buffer. */
293 if(global_settings.talk_menu
294 && (talked_tick == 0
295 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
297 talked_tick = current_tick;
298 talk_id(LANG_TAGCACHE_INIT, false);
299 talk_number(ret, true);
300 talk_id(VOICE_OF, true);
301 talk_number(tagcache_get_max_commit_step(), true);
303 #endif
304 #ifdef HAVE_LCD_BITMAP
305 if (lang_is_rtl())
307 splashf(0, "[%d/%d] %s", ret, tagcache_get_max_commit_step(),
308 str(LANG_TAGCACHE_INIT));
310 else
312 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT), ret,
313 tagcache_get_max_commit_step());
315 #else
316 lcd_double_height(false);
317 lcd_putsf(0, 1, " DB [%d/%d]", ret,
318 tagcache_get_max_commit_step());
319 lcd_update();
320 #endif
321 clear = true;
323 sleep(HZ/4);
325 tagtree_init();
327 if (clear)
329 backlight_on();
330 show_logo();
333 #endif
335 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
337 static void init(void)
339 #ifdef HAVE_LCD_BITMAP
340 int i;
341 #endif
342 system_init();
343 core_allocator_init();
344 kernel_init();
345 #ifdef APPLICATION
346 paths_init();
347 #endif
348 enable_irq();
349 lcd_init();
350 #ifdef HAVE_REMOTE_LCD
351 lcd_remote_init();
352 #endif
353 #ifdef HAVE_LCD_BITMAP
354 FOR_NB_SCREENS(i)
355 global_status.font_id[i] = FONT_SYSFIXED;
356 font_init();
357 #endif
358 show_logo();
359 button_init();
360 powermgmt_init();
361 backlight_init();
362 #if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA))
363 sim_tasks_init();
364 #endif
365 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
366 notification_init();
367 #endif
368 lang_init(core_language_builtin, language_strings,
369 LANG_LAST_INDEX_IN_ARRAY);
370 #ifdef DEBUG
371 debug_init();
372 #endif
373 /* Keep the order of this 3 (viewportmanager handles statusbars)
374 * Must be done before any code uses the multi-screen API */
375 gui_syncstatusbar_init(&statusbars);
376 gui_sync_skin_init();
377 sb_skin_init();
378 viewportmanager_init();
380 storage_init();
381 settings_reset();
382 settings_load(SETTINGS_ALL);
383 settings_apply(true);
384 init_dircache(true);
385 init_dircache(false);
386 #ifdef HAVE_TAGCACHE
387 init_tagcache();
388 #endif
389 sleep(HZ/2);
390 tree_mem_init();
391 filetype_init();
392 playlist_init();
393 theme_init_buffer();
395 #if CONFIG_CODEC != SWCODEC
396 mp3_init( global_settings.volume,
397 global_settings.bass,
398 global_settings.treble,
399 global_settings.balance,
400 global_settings.loudness,
401 global_settings.avc,
402 global_settings.channel_config,
403 global_settings.stereo_width,
404 global_settings.mdb_strength,
405 global_settings.mdb_harmonics,
406 global_settings.mdb_center,
407 global_settings.mdb_shape,
408 global_settings.mdb_enable,
409 global_settings.superbass);
410 #endif /* CONFIG_CODEC != SWCODEC */
412 scrobbler_init();
414 audio_init();
416 settings_apply_skins();
419 #else
421 static void init(void) INIT_ATTR;
422 static void init(void)
424 int rc;
425 bool mounted = false;
426 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
427 /* if nobody initialized ATA before, I consider this a cold start */
428 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
429 #endif
431 system_init();
432 core_allocator_init();
433 kernel_init();
435 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
436 set_cpu_frequency(CPUFREQ_NORMAL);
437 #ifdef CPU_COLDFIRE
438 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
439 #endif
440 cpu_boost(true);
441 #endif
444 settings_reset();
446 i2c_init();
448 power_init();
450 enable_irq();
451 #ifdef CPU_ARM
452 enable_fiq();
453 #endif
454 /* current_tick should be ticking by now */
455 CHART("ticking");
457 lcd_init();
458 #ifdef HAVE_REMOTE_LCD
459 lcd_remote_init();
460 #endif
461 #ifdef HAVE_LCD_BITMAP
462 FOR_NB_SCREENS(rc)
463 global_status.font_id[rc] = FONT_SYSFIXED;
464 font_init();
465 #endif
467 CHART(">show_logo");
468 show_logo();
469 CHART("<show_logo");
470 lang_init(core_language_builtin, language_strings,
471 LANG_LAST_INDEX_IN_ARRAY);
473 #ifdef DEBUG
474 debug_init();
475 #else
476 #ifdef HAVE_SERIAL
477 serial_setup();
478 #endif
479 #endif
481 #if CONFIG_RTC
482 rtc_init();
483 #endif
484 #ifdef HAVE_RTC_RAM
485 CHART(">settings_load(RTC)");
486 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
487 CHART("<settings_load(RTC)");
488 #endif
490 adc_init();
492 usb_init();
493 #if CONFIG_USBOTG == USBOTG_ISP1362
494 isp1362_init();
495 #elif CONFIG_USBOTG == USBOTG_M5636
496 m5636_init();
497 #endif
499 backlight_init();
501 button_init();
503 powermgmt_init();
505 #if CONFIG_TUNER
506 radio_init();
507 #endif
509 /* Keep the order of this 3 (viewportmanager handles statusbars)
510 * Must be done before any code uses the multi-screen API */
511 CHART(">gui_syncstatusbar_init");
512 gui_syncstatusbar_init(&statusbars);
513 CHART("<gui_syncstatusbar_init");
514 CHART(">sb_skin_init");
515 sb_skin_init();
516 CHART("<sb_skin_init");
517 CHART(">gui_sync_wps_init");
518 gui_sync_skin_init();
519 CHART("<gui_sync_wps_init");
520 CHART(">viewportmanager_init");
521 viewportmanager_init();
522 CHART("<viewportmanager_init");
524 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
525 /* charger_inserted() can't be used here because power_thread()
526 hasn't checked power_input_status() yet */
527 if (coldstart && (power_input_status() & POWER_INPUT_MAIN_CHARGER)
528 && !global_settings.car_adapter_mode
529 #ifdef ATA_POWER_PLAYERSTYLE
530 && !ide_powered() /* relies on probing result from bootloader */
531 #endif
534 rc = charging_screen(); /* display a "charging" screen */
535 if (rc == 1) /* charger removed */
536 power_off();
537 /* "On" pressed or USB connected: proceed */
538 show_logo(); /* again, to provide better visual feedback */
540 #endif
543 disk_init_subsystem();
544 CHART(">storage_init");
545 rc = storage_init();
546 CHART("<storage_init");
547 if(rc)
549 #ifdef HAVE_LCD_BITMAP
550 lcd_clear_display();
551 lcd_putsf(0, 1, "ATA error: %d", rc);
552 lcd_puts(0, 3, "Press ON to debug");
553 lcd_update();
554 while(!(button_get(true) & BUTTON_REL)); /* DO NOT CHANGE TO ACTION SYSTEM */
555 dbg_ports();
556 #endif
557 panicf("ata: %d", rc);
560 #ifdef HAVE_EEPROM_SETTINGS
561 CHART(">eeprom_settings_init");
562 eeprom_settings_init();
563 CHART("<eeprom_settings_init");
564 #endif
566 #ifndef HAVE_USBSTACK
567 usb_start_monitoring();
568 while (usb_detect() == USB_INSERTED)
570 #ifdef HAVE_EEPROM_SETTINGS
571 firmware_settings.disk_clean = false;
572 #endif
573 /* enter USB mode early, before trying to mount */
574 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
575 #if (CONFIG_STORAGE & STORAGE_MMC)
576 if (!mmc_touched() ||
577 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
578 #endif
580 gui_usb_screen_run(true);
581 mounted = true; /* mounting done @ end of USB mode */
583 #ifdef HAVE_USB_POWER
584 if (usb_powered()) /* avoid deadlock */
585 break;
586 #endif
588 #endif
590 if (!mounted)
592 CHART(">disk_mount_all");
593 rc = disk_mount_all();
594 CHART("<disk_mount_all");
595 if (rc<=0)
597 lcd_clear_display();
598 lcd_puts(0, 0, "No partition");
599 lcd_puts(0, 1, "found.");
600 #ifdef HAVE_LCD_BITMAP
601 lcd_puts(0, 2, "Insert USB cable");
602 lcd_puts(0, 3, "and fix it.");
603 #endif
604 lcd_update();
606 while(button_get(true) != SYS_USB_CONNECTED) {};
607 gui_usb_screen_run(true);
608 system_reboot();
612 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
613 (CONFIG_KEYPAD == IRIVER_H10_PAD)
614 #ifdef SETTINGS_RESET
615 /* Reset settings if holding the reset button. (Rec on Archos,
616 A on Gigabeat) */
617 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
618 #else
619 /* Reset settings if the hold button is turned on */
620 if (button_hold())
621 #endif
623 splash(HZ*2, str(LANG_RESET_DONE_CLEAR));
624 settings_reset();
626 else
627 #endif
629 CHART(">settings_load(ALL)");
630 settings_load(SETTINGS_ALL);
631 CHART("<settings_load(ALL)");
634 CHART(">init_dircache(true)");
635 rc = init_dircache(true);
636 CHART("<init_dircache(true)");
637 if (rc < 0)
639 #ifdef HAVE_TAGCACHE
640 remove(TAGCACHE_STATEFILE);
641 #endif
644 CHART(">settings_apply(true)");
645 settings_apply(true);
646 CHART("<settings_apply(true)");
647 CHART(">init_dircache(false)");
648 init_dircache(false);
649 CHART("<init_dircache(false)");
650 #ifdef HAVE_TAGCACHE
651 CHART(">init_tagcache");
652 init_tagcache();
653 CHART("<init_tagcache");
654 #endif
656 #ifdef HAVE_EEPROM_SETTINGS
657 if (firmware_settings.initialized)
659 /* In case we crash. */
660 firmware_settings.disk_clean = false;
661 CHART(">eeprom_settings_store");
662 eeprom_settings_store();
663 CHART("<eeprom_settings_store");
665 #endif
666 playlist_init();
667 tree_mem_init();
668 filetype_init();
669 scrobbler_init();
670 theme_init_buffer();
672 #if CONFIG_CODEC != SWCODEC
673 /* No buffer allocation (see buffer.c) may take place after the call to
674 audio_init() since the mpeg thread takes the rest of the buffer space */
675 mp3_init( global_settings.volume,
676 global_settings.bass,
677 global_settings.treble,
678 global_settings.balance,
679 global_settings.loudness,
680 global_settings.avc,
681 global_settings.channel_config,
682 global_settings.stereo_width,
683 global_settings.mdb_strength,
684 global_settings.mdb_harmonics,
685 global_settings.mdb_center,
686 global_settings.mdb_shape,
687 global_settings.mdb_enable,
688 global_settings.superbass);
689 #endif /* CONFIG_CODEC != SWCODEC */
691 CHART(">audio_init");
692 audio_init();
693 CHART("<audio_init");
695 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
696 pcm_rec_init();
697 #endif
699 /* runtime database has to be initialized after audio_init() */
700 cpu_boost(false);
702 #if CONFIG_CHARGING
703 car_adapter_mode_init();
704 #endif
705 #ifdef IPOD_ACCESSORY_PROTOCOL
706 iap_setup(global_settings.serial_bitrate);
707 #endif
708 #ifdef HAVE_ACCESSORY_SUPPLY
709 accessory_supply_set(global_settings.accessory_supply);
710 #endif
711 #ifdef HAVE_LINEOUT_POWEROFF
712 lineout_set(global_settings.lineout_active);
713 #endif
714 #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
715 CHART("<check_bootfile(false)");
716 check_bootfile(false); /* remember write time and filesize */
717 CHART(">check_bootfile(false)");
718 #endif
719 CHART("<settings_apply_skins");
720 settings_apply_skins();
721 CHART(">settings_apply_skins");
724 #ifdef CPU_PP
725 void cop_main(void) MAIN_NORETURN_ATTR;
726 void cop_main(void)
728 /* This is the entry point for the coprocessor
729 Anyone not running an upgraded bootloader will never reach this point,
730 so it should not be assumed that the coprocessor be usable even on
731 platforms which support it.
733 A kernel thread is initially setup on the coprocessor and immediately
734 destroyed for purposes of continuity. The cop sits idle until at least
735 one thread exists on it. */
737 #if NUM_CORES > 1
738 system_init();
739 kernel_init();
740 /* This should never be reached */
741 #endif
742 while(1) {
743 sleep_core(COP);
746 #endif /* CPU_PP */
748 #endif /* SIMULATOR */