2002-11-22 13:00:10 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright (C) 2002 by Daniel Stenberg
|
|
|
|
*
|
|
|
|
* All files in this archive are subject to the GNU General Public License.
|
|
|
|
* See the file COPYING in the source tree root for full license agreement.
|
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
2004-09-19 21:58:37 +00:00
|
|
|
#include <stdlib.h>
|
2004-07-05 11:15:50 +00:00
|
|
|
#include <ctype.h>
|
2004-07-24 21:26:41 +00:00
|
|
|
#include "lang.h"
|
2003-04-14 15:58:51 +00:00
|
|
|
#include "string.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "file.h"
|
|
|
|
#include "lcd.h"
|
2002-11-22 13:00:10 +00:00
|
|
|
#include "sprintf.h"
|
2003-05-04 02:04:31 +00:00
|
|
|
#include "errno.h"
|
|
|
|
#include "system.h"
|
2004-06-30 13:31:14 +00:00
|
|
|
#include "timefuncs.h"
|
2004-07-24 21:26:41 +00:00
|
|
|
#include "screens.h"
|
|
|
|
#include "mpeg.h"
|
|
|
|
#include "mp3_playback.h"
|
|
|
|
#include "settings.h"
|
|
|
|
#include "ata.h"
|
|
|
|
#include "kernel.h"
|
|
|
|
#include "power.h"
|
2004-10-13 09:08:32 +00:00
|
|
|
#include "backlight.h"
|
2004-10-12 00:02:51 +00:00
|
|
|
#ifdef HAVE_MMC
|
|
|
|
#include "ata_mmc.h"
|
|
|
|
#endif
|
2003-05-04 02:04:31 +00:00
|
|
|
|
2002-11-22 13:00:10 +00:00
|
|
|
#define ONE_KILOBYTE 1024
|
|
|
|
#define ONE_MEGABYTE (1024*1024)
|
|
|
|
|
|
|
|
/* The point of this function would be to return a string of the input data,
|
|
|
|
but never longer than 5 columns. Add suffix k and M when suitable...
|
|
|
|
Make sure to have space for 6 bytes in the buffer. 5 letters plus the
|
|
|
|
terminating zero byte. */
|
|
|
|
char *num2max5(unsigned int bytes, char *max5)
|
|
|
|
{
|
|
|
|
if(bytes < 100000) {
|
|
|
|
snprintf(max5, 6, "%5d", bytes);
|
|
|
|
return max5;
|
|
|
|
}
|
|
|
|
if(bytes < (9999*ONE_KILOBYTE)) {
|
|
|
|
snprintf(max5, 6, "%4dk", bytes/ONE_KILOBYTE);
|
|
|
|
return max5;
|
|
|
|
}
|
|
|
|
if(bytes < (100*ONE_MEGABYTE)) {
|
|
|
|
/* 'XX.XM' is good as long as we're less than 100 megs */
|
2002-12-12 02:25:30 +00:00
|
|
|
snprintf(max5, 6, "%2d.%0dM",
|
2002-11-22 13:00:10 +00:00
|
|
|
bytes/ONE_MEGABYTE,
|
|
|
|
(bytes%ONE_MEGABYTE)/(ONE_MEGABYTE/10) );
|
|
|
|
return max5;
|
|
|
|
}
|
|
|
|
snprintf(max5, 6, "%4dM", bytes/ONE_MEGABYTE);
|
|
|
|
return max5;
|
|
|
|
}
|
|
|
|
|
2003-05-04 02:04:31 +00:00
|
|
|
/* Read (up to) a line of text from fd into buffer and return number of bytes
|
|
|
|
* read (which may be larger than the number of bytes stored in buffer). If
|
|
|
|
* an error occurs, -1 is returned (and buffer contains whatever could be
|
|
|
|
* read). A line is terminated by a LF char. Neither LF nor CR chars are
|
|
|
|
* stored in buffer.
|
|
|
|
*/
|
|
|
|
int read_line(int fd, char* buffer, int buffer_size)
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
int num_read = 0;
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
|
|
|
while (count < buffer_size)
|
|
|
|
{
|
|
|
|
unsigned char c;
|
|
|
|
|
|
|
|
if (1 != read(fd, &c, 1))
|
|
|
|
break;
|
|
|
|
|
|
|
|
num_read++;
|
|
|
|
|
|
|
|
if ( c == '\n' )
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ( c == '\r' )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
buffer[count++] = c;
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer[MIN(count, buffer_size - 1)] = 0;
|
|
|
|
|
|
|
|
return errno ? -1 : num_read;
|
|
|
|
}
|
|
|
|
|
2002-11-22 13:00:10 +00:00
|
|
|
#ifdef TEST_MAX5
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
char buffer[32];
|
|
|
|
if(argc>1) {
|
|
|
|
printf("%d => %s\n",
|
|
|
|
atoi(argv[1]),
|
|
|
|
num2max5(atoi(argv[1]), buffer));
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2003-04-14 15:58:51 +00:00
|
|
|
|
2004-06-30 13:31:14 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
2003-12-23 23:41:45 +00:00
|
|
|
extern unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH];
|
2004-08-01 21:50:57 +00:00
|
|
|
static const unsigned char bmpheader[] =
|
2003-04-14 15:58:51 +00:00
|
|
|
{
|
|
|
|
0x42, 0x4d, 0x3e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00,
|
|
|
|
0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x40, 0x00,
|
|
|
|
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
|
|
|
|
0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
2004-07-07 07:47:32 +00:00
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xee, 0x90, 0x00, 0x00, 0x00,
|
2003-04-14 15:58:51 +00:00
|
|
|
0x00, 0x00
|
|
|
|
};
|
|
|
|
|
|
|
|
void screen_dump(void)
|
|
|
|
{
|
2004-09-03 22:24:29 +00:00
|
|
|
int fh;
|
|
|
|
int bx, by, ix, iy;
|
|
|
|
int src_byte, src_mask, dst_mask;
|
2003-04-14 15:58:51 +00:00
|
|
|
char filename[MAX_PATH];
|
2004-09-03 22:24:29 +00:00
|
|
|
static unsigned char line_block[8][16];
|
2004-06-30 13:31:14 +00:00
|
|
|
struct tm *tm = get_time();
|
2003-04-14 15:58:51 +00:00
|
|
|
|
2004-06-30 13:31:14 +00:00
|
|
|
snprintf(filename, MAX_PATH, "/dump %04d-%02d-%02d %02d-%02d-%02d.bmp",
|
|
|
|
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
|
|
|
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
2004-09-03 22:24:29 +00:00
|
|
|
|
|
|
|
fh = creat(filename, O_WRONLY);
|
|
|
|
if (fh < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
write(fh, bmpheader, sizeof(bmpheader));
|
|
|
|
|
|
|
|
/* BMP image goes bottom up */
|
|
|
|
for (by = LCD_HEIGHT/8 - 1; by >= 0; by--)
|
2003-04-14 15:58:51 +00:00
|
|
|
{
|
2004-09-03 22:24:29 +00:00
|
|
|
memset(&line_block[0][0], 0, 8*16);
|
|
|
|
|
|
|
|
for (bx = 0; bx < LCD_WIDTH/8; bx++)
|
2003-04-14 15:58:51 +00:00
|
|
|
{
|
2004-09-03 22:24:29 +00:00
|
|
|
dst_mask = 0x01;
|
|
|
|
for (ix = 7; ix >= 0; ix--)
|
|
|
|
{
|
|
|
|
src_byte = lcd_framebuffer[by][8*bx+ix];
|
|
|
|
src_mask = 0x01;
|
|
|
|
for (iy = 7; iy >= 0; iy--)
|
|
|
|
{
|
|
|
|
if (src_byte & src_mask)
|
|
|
|
line_block[iy][bx] |= dst_mask;
|
|
|
|
src_mask <<= 1;
|
|
|
|
}
|
|
|
|
dst_mask <<= 1;
|
|
|
|
}
|
2003-04-14 15:58:51 +00:00
|
|
|
}
|
|
|
|
|
2004-09-03 22:24:29 +00:00
|
|
|
write(fh, &line_block[0][0], 8*16);
|
2003-04-14 15:58:51 +00:00
|
|
|
}
|
2004-09-03 22:24:29 +00:00
|
|
|
close(fh);
|
2003-04-14 15:58:51 +00:00
|
|
|
}
|
|
|
|
#endif
|
2004-07-05 11:15:50 +00:00
|
|
|
|
2004-09-03 22:24:29 +00:00
|
|
|
/* parse a line from a configuration file. the line format is:
|
2004-07-05 11:15:50 +00:00
|
|
|
|
|
|
|
name: value
|
|
|
|
|
|
|
|
Any whitespace before setting name or value (after ':') is ignored.
|
|
|
|
A # as first non-whitespace character discards the whole line.
|
|
|
|
Function sets pointers to null-terminated setting name and value.
|
|
|
|
Returns false if no valid config entry was found.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool settings_parseline(char* line, char** name, char** value)
|
|
|
|
{
|
|
|
|
char* ptr;
|
|
|
|
|
|
|
|
while ( isspace(*line) )
|
|
|
|
line++;
|
|
|
|
|
|
|
|
if ( *line == '#' )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
ptr = strchr(line, ':');
|
|
|
|
if ( !ptr )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
*name = line;
|
|
|
|
*ptr = 0;
|
|
|
|
ptr++;
|
|
|
|
while (isspace(*ptr))
|
|
|
|
ptr++;
|
|
|
|
*value = ptr;
|
|
|
|
return true;
|
|
|
|
}
|
2004-07-24 21:26:41 +00:00
|
|
|
|
|
|
|
bool clean_shutdown(void)
|
|
|
|
{
|
2004-09-19 21:58:37 +00:00
|
|
|
#ifdef SIMULATOR
|
|
|
|
exit(0);
|
|
|
|
#else
|
2004-07-24 21:26:41 +00:00
|
|
|
if(!charger_inserted())
|
|
|
|
{
|
2004-07-26 07:37:26 +00:00
|
|
|
lcd_clear_display();
|
|
|
|
splash(0, true, str(LANG_SHUTTINGDOWN));
|
|
|
|
mpeg_stop();
|
2004-10-23 23:12:48 +00:00
|
|
|
ata_flush();
|
|
|
|
ata_spindown(1);
|
|
|
|
while(ata_disk_is_active())
|
|
|
|
sleep(HZ/10);
|
|
|
|
|
2004-07-26 07:37:26 +00:00
|
|
|
mp3_shutdown();
|
2004-10-13 09:08:32 +00:00
|
|
|
#if CONFIG_KEYPAD == ONDIO_PAD
|
|
|
|
backlight_off();
|
|
|
|
sleep(1);
|
|
|
|
lcd_set_contrast(0);
|
|
|
|
#endif
|
2004-07-24 21:26:41 +00:00
|
|
|
power_off();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
2004-07-26 16:06:59 +00:00
|
|
|
|
2004-10-12 22:45:01 +00:00
|
|
|
int default_event_handler_ex(int event, void (*callback)(void *), void *parameter)
|
2004-07-26 16:06:59 +00:00
|
|
|
{
|
2004-07-26 23:31:40 +00:00
|
|
|
switch(event)
|
2004-07-26 16:06:59 +00:00
|
|
|
{
|
|
|
|
case SYS_USB_CONNECTED:
|
2004-10-12 22:45:01 +00:00
|
|
|
if (callback != NULL)
|
|
|
|
callback(parameter);
|
2004-10-12 00:02:51 +00:00
|
|
|
#ifdef HAVE_MMC
|
|
|
|
if (!mmc_detect() || (mmc_remove_request() == SYS_MMC_EXTRACTED))
|
|
|
|
#endif
|
|
|
|
usb_screen();
|
2004-07-26 16:06:59 +00:00
|
|
|
return SYS_USB_CONNECTED;
|
2004-10-12 11:00:19 +00:00
|
|
|
case SYS_POWEROFF:
|
2004-10-12 22:45:01 +00:00
|
|
|
if (callback != NULL)
|
|
|
|
callback(parameter);
|
2004-10-12 11:00:19 +00:00
|
|
|
if (!clean_shutdown())
|
|
|
|
return SYS_POWEROFF;
|
|
|
|
break;
|
2004-07-26 16:06:59 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2004-10-12 22:45:01 +00:00
|
|
|
|
|
|
|
int default_event_handler(int event)
|
|
|
|
{
|
|
|
|
return default_event_handler_ex(event, NULL, NULL);
|
|
|
|
}
|
|
|
|
|