Simplify touchscreen scrollbar handling code
[Rockbox.git] / apps / main.c
blobecc80710a1a0b1a25ac4e39918a0c1138c4758fa
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 "ata.h"
24 #include "disk.h"
25 #include "fat.h"
26 #include "lcd.h"
27 #include "rtc.h"
28 #include "debug.h"
29 #include "led.h"
30 #include "kernel.h"
31 #include "button.h"
32 #include "tree.h"
33 #include "filetypes.h"
34 #include "panic.h"
35 #include "menu.h"
36 #include "system.h"
37 #include "usb.h"
38 #include "powermgmt.h"
39 #include "adc.h"
40 #include "i2c.h"
41 #ifndef DEBUG
42 #include "serial.h"
43 #endif
44 #include "audio.h"
45 #include "mp3_playback.h"
46 #include "thread.h"
47 #include "settings.h"
48 #include "backlight.h"
49 #include "status.h"
50 #include "debug_menu.h"
51 #include "version.h"
52 #include "sprintf.h"
53 #include "font.h"
54 #include "language.h"
55 #include "gwps.h"
56 #include "playlist.h"
57 #include "buffer.h"
58 #include "rolo.h"
59 #include "screens.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"
76 #if (CONFIG_CODEC == SWCODEC)
77 #include "playback.h"
78 #endif
79 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
80 #include "pcm_record.h"
81 #endif
83 #ifdef BUTTON_REC
84 #define SETTINGS_RESET BUTTON_REC
85 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
86 #define SETTINGS_RESET BUTTON_A
87 #endif
89 #if CONFIG_TUNER
90 #include "radio.h"
91 #endif
92 #ifdef HAVE_MMC
93 #include "ata_mmc.h"
94 #endif
96 #ifdef HAVE_REMOTE_LCD
97 #include "lcd-remote.h"
98 #endif
100 #if CONFIG_USBOTG == USBOTG_ISP1362
101 #include "isp1362.h"
102 #endif
104 #if CONFIG_USBOTG == USBOTG_M5636
105 #include "m5636.h"
106 #endif
108 #include "cuesheet.h"
110 #ifdef SIMULATOR
111 #include "system-sdl.h"
112 #endif
114 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
116 const char appsversion[]=APPSVERSION;
118 static void init(void);
120 #ifdef SIMULATOR
121 void app_main(void)
122 #else
123 static void app_main(void)
124 #endif
126 int i;
127 init();
128 FOR_NB_SCREENS(i)
130 screens[i].clear_display();
131 screens[i].update();
133 tree_gui_init();
134 #ifdef HAVE_TOUCHPAD
135 touchpad_set_mode(TOUCHPAD_BUTTON);
136 #endif
137 root_menu();
140 static int init_dircache(bool preinit)
142 #ifdef HAVE_DIRCACHE
143 int result = 0;
144 bool clear = false;
146 if (preinit)
147 dircache_init();
149 if (!global_settings.dircache)
150 return 0;
152 # ifdef HAVE_EEPROM_SETTINGS
153 if (firmware_settings.initialized && firmware_settings.disk_clean
154 && preinit)
156 result = dircache_load();
158 if (result < 0)
160 firmware_settings.disk_clean = false;
161 if (global_status.dircache_size <= 0)
163 /* This will be in default language, settings are not
164 applied yet. Not really any easy way to fix that. */
165 gui_syncsplash(0, str(LANG_SCANNING_DISK));
166 clear = true;
169 dircache_build(global_status.dircache_size);
172 else
173 # endif
175 if (preinit)
176 return -1;
178 if (!dircache_is_enabled()
179 && !dircache_is_initializing())
181 if (global_status.dircache_size <= 0)
183 gui_syncsplash(0, str(LANG_SCANNING_DISK));
184 clear = true;
186 result = dircache_build(global_status.dircache_size);
189 if (result < 0)
191 /* Initialization of dircache failed. Manual action is
192 * necessary to enable dircache again.
194 gui_syncsplash(0, "Dircache failed, disabled. Result: %d", result);
195 global_settings.dircache = false;
200 if (clear)
202 backlight_on();
203 show_logo();
204 global_status.dircache_size = dircache_get_cache_size();
205 status_save();
208 return result;
209 #else
210 (void)preinit;
211 return 0;
212 #endif
215 #ifdef HAVE_TAGCACHE
216 static void init_tagcache(void)
218 bool clear = false;
220 tagcache_init();
222 while (!tagcache_is_initialized())
224 #ifdef HAVE_LCD_CHARCELLS
225 char buf[32];
226 #endif
227 int ret = tagcache_get_commit_step();
229 if (ret > 0)
231 #if CONFIG_CODEC == SWCODEC
232 /* hwcodec can't use voice here, as the database commit
233 * uses the audio buffer. */
234 static long talked_tick = 0;
235 if(global_settings.talk_menu
236 && (talked_tick == 0
237 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
239 talked_tick = current_tick;
240 talk_id(LANG_TAGCACHE_INIT, false);
241 talk_number(ret, true);
242 talk_id(VOICE_OF, true);
243 talk_number(tagcache_get_max_commit_step(), true);
245 #endif
246 #ifdef HAVE_LCD_BITMAP
247 gui_syncsplash(0, "%s [%d/%d]",
248 str(LANG_TAGCACHE_INIT), ret,
249 tagcache_get_max_commit_step());
250 #else
251 lcd_double_height(false);
252 snprintf(buf, sizeof(buf), " DB [%d/%d]", ret,
253 tagcache_get_max_commit_step());
254 lcd_puts(0, 1, buf);
255 lcd_update();
256 #endif
257 clear = true;
259 sleep(HZ/4);
261 tagtree_init();
263 if (clear)
265 backlight_on();
266 show_logo();
269 #endif
271 #ifdef SIMULATOR
273 static void init(void)
275 kernel_init();
276 buffer_init();
277 enable_irq();
278 lcd_init();
279 #ifdef HAVE_REMOTE_LCD
280 lcd_remote_init();
281 #endif
282 font_init();
283 show_logo();
284 button_init();
285 backlight_init();
286 lang_init();
287 #ifdef DEBUG
288 debug_init();
289 #endif
290 /* Must be done before any code uses the multi-screen APi */
291 screen_access_init();
292 gui_syncstatusbar_init(&statusbars);
293 ata_init();
294 settings_reset();
295 settings_load(SETTINGS_ALL);
296 gui_sync_wps_init();
297 settings_apply(true);
298 init_dircache(true);
299 init_dircache(false);
300 #ifdef HAVE_TAGCACHE
301 init_tagcache();
302 #endif
303 sleep(HZ/2);
304 tree_mem_init();
305 filetype_init();
306 playlist_init();
308 #if CONFIG_CODEC != SWCODEC
309 mp3_init( global_settings.volume,
310 global_settings.bass,
311 global_settings.treble,
312 global_settings.balance,
313 global_settings.loudness,
314 global_settings.avc,
315 global_settings.channel_config,
316 global_settings.stereo_width,
317 global_settings.mdb_strength,
318 global_settings.mdb_harmonics,
319 global_settings.mdb_center,
320 global_settings.mdb_shape,
321 global_settings.mdb_enable,
322 global_settings.superbass);
324 /* audio_init must to know the size of voice buffer so init voice first */
325 talk_init();
326 #endif /* CONFIG_CODEC != SWCODEC */
328 scrobbler_init();
329 cuesheet_init();
331 audio_init();
332 button_clear_queue(); /* Empty the keyboard buffer */
335 #else
337 static void init(void)
339 int rc;
340 bool mounted = false;
341 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
342 /* if nobody initialized ATA before, I consider this a cold start */
343 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
344 #endif
346 system_init();
347 kernel_init();
349 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
350 set_cpu_frequency(CPUFREQ_NORMAL);
351 #ifdef CPU_COLDFIRE
352 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
353 #endif
354 cpu_boost(true);
355 #endif
357 buffer_init();
359 settings_reset();
361 i2c_init();
363 power_init();
365 enable_irq();
366 #ifdef CPU_ARM
367 enable_fiq();
368 #endif
369 lcd_init();
370 #ifdef HAVE_REMOTE_LCD
371 lcd_remote_init();
372 #endif
373 font_init();
375 show_logo();
376 lang_init();
378 #ifdef DEBUG
379 debug_init();
380 #else
381 #if !defined(HAVE_FMADC) && !defined(HAVE_MMC)
382 serial_setup();
383 #endif
384 #endif
386 #if CONFIG_RTC
387 rtc_init();
388 #endif
389 #ifdef HAVE_RTC_RAM
390 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
391 #endif
393 adc_init();
395 usb_init();
396 #if CONFIG_USBOTG == USBOTG_ISP1362
397 isp1362_init();
398 #elif CONFIG_USBOTG == USBOTG_M5636
399 m5636_init();
400 #endif
402 backlight_init();
404 button_init();
406 powermgmt_init();
408 #if CONFIG_TUNER
409 radio_init();
410 #endif
412 /* Must be done before any code uses the multi-screen APi */
413 screen_access_init();
414 gui_syncstatusbar_init(&statusbars);
416 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
417 if (coldstart && charger_inserted()
418 && !global_settings.car_adapter_mode
419 #ifdef ATA_POWER_PLAYERSTYLE
420 && !ide_powered() /* relies on probing result from bootloader */
421 #endif
424 rc = charging_screen(); /* display a "charging" screen */
425 if (rc == 1) /* charger removed */
426 power_off();
427 /* "On" pressed or USB connected: proceed */
428 show_logo(); /* again, to provide better visual feedback */
430 #endif
432 rc = ata_init();
433 if(rc)
435 #ifdef HAVE_LCD_BITMAP
436 char str[32];
437 lcd_clear_display();
438 snprintf(str, 31, "ATA error: %d", rc);
439 lcd_puts(0, 1, str);
440 lcd_puts(0, 3, "Press ON to debug");
441 lcd_update();
442 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
443 dbg_ports();
444 #endif
445 panicf("ata: %d", rc);
448 #ifdef HAVE_EEPROM_SETTINGS
449 eeprom_settings_init();
450 #endif
452 usb_start_monitoring();
453 #ifndef HAVE_USBSTACK
454 while (usb_detect() == USB_INSERTED)
456 #ifdef HAVE_EEPROM_SETTINGS
457 firmware_settings.disk_clean = false;
458 #endif
459 /* enter USB mode early, before trying to mount */
460 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
461 #ifdef HAVE_MMC
462 if (!mmc_touched() ||
463 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
464 #endif
466 usb_screen();
467 mounted = true; /* mounting done @ end of USB mode */
469 #ifdef HAVE_USB_POWER
470 if (usb_powered()) /* avoid deadlock */
471 break;
472 #endif
474 #endif
476 if (!mounted)
478 rc = disk_mount_all();
479 if (rc<=0)
481 lcd_clear_display();
482 lcd_puts(0, 0, "No partition");
483 lcd_puts(0, 1, "found.");
484 #ifdef HAVE_LCD_BITMAP
485 lcd_puts(0, 2, "Insert USB cable");
486 lcd_puts(0, 3, "and fix it.");
487 #endif
488 lcd_update();
490 while(button_get(true) != SYS_USB_CONNECTED) {};
491 usb_screen();
492 system_reboot();
496 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
497 (CONFIG_KEYPAD == IRIVER_H10_PAD)
498 #ifdef SETTINGS_RESET
499 /* Reset settings if holding the reset button. (Rec on Archos,
500 A on Gigabeat) */
501 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
502 #else
503 /* Reset settings if the hold button is turned on */
504 if (button_hold())
505 #endif
507 gui_syncsplash(HZ*2, str(LANG_RESET_DONE_CLEAR));
508 settings_reset();
510 else
511 #endif
512 settings_load(SETTINGS_ALL);
514 if (init_dircache(true) < 0)
516 #ifdef HAVE_TAGCACHE
517 remove(TAGCACHE_STATEFILE);
518 #endif
521 gui_sync_wps_init();
522 settings_apply(true);
523 init_dircache(false);
524 #ifdef HAVE_TAGCACHE
525 init_tagcache();
526 #endif
528 #ifdef HAVE_EEPROM_SETTINGS
529 if (firmware_settings.initialized)
531 /* In case we crash. */
532 firmware_settings.disk_clean = false;
533 eeprom_settings_store();
535 #endif
536 status_init();
537 playlist_init();
538 tree_mem_init();
539 filetype_init();
540 scrobbler_init();
541 cuesheet_init();
543 #if CONFIG_CODEC != SWCODEC
544 /* No buffer allocation (see buffer.c) may take place after the call to
545 audio_init() since the mpeg thread takes the rest of the buffer space */
546 mp3_init( global_settings.volume,
547 global_settings.bass,
548 global_settings.treble,
549 global_settings.balance,
550 global_settings.loudness,
551 global_settings.avc,
552 global_settings.channel_config,
553 global_settings.stereo_width,
554 global_settings.mdb_strength,
555 global_settings.mdb_harmonics,
556 global_settings.mdb_center,
557 global_settings.mdb_shape,
558 global_settings.mdb_enable,
559 global_settings.superbass);
561 /* audio_init must to know the size of voice buffer so init voice first */
562 talk_init();
563 #endif /* CONFIG_CODEC != SWCODEC */
565 audio_init();
567 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
568 pcm_rec_init();
569 #endif
571 /* runtime database has to be initialized after audio_init() */
572 cpu_boost(false);
574 #ifdef AUTOROCK
576 static const char filename[] = PLUGIN_APPS_DIR "/autostart.rock";
578 if(file_exists(filename)) /* no complaint if it doesn't exist */
580 plugin_load((char*)filename, NULL); /* start if it does */
583 #endif /* #ifdef AUTOROCK */
585 #if CONFIG_CHARGING
586 car_adapter_mode_init();
587 #endif
588 #ifdef HAVE_ACCESSORY_SUPPLY
589 accessory_supply_set(global_settings.accessory_supply);
590 #endif
593 #ifdef CPU_PP
594 void cop_main(void)
596 /* This is the entry point for the coprocessor
597 Anyone not running an upgraded bootloader will never reach this point,
598 so it should not be assumed that the coprocessor be usable even on
599 platforms which support it.
601 A kernel thread is initially setup on the coprocessor and immediately
602 destroyed for purposes of continuity. The cop sits idle until at least
603 one thread exists on it. */
605 /* 3G doesn't have Rolo or dual core support yet */
606 #if NUM_CORES > 1
607 system_init();
608 kernel_init();
609 /* This should never be reached */
610 #endif
611 while(1) {
612 sleep_core(COP);
615 #endif /* CPU_PP */
617 int main(void)
619 app_main();
621 while(1) {
622 #if (CONFIG_LED == LED_REAL)
623 led(true); sleep(HZ/10);
624 led(false); sleep(HZ/10);
625 #endif
627 return 0;
629 #endif