summaryrefslogtreecommitdiff
path: root/apps/gui
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui')
-rw-r--r--apps/gui/buttonbar.c126
-rw-r--r--apps/gui/buttonbar.h81
-rw-r--r--apps/gui/icon.c49
-rw-r--r--apps/gui/icon.h51
-rw-r--r--apps/gui/list.c499
-rw-r--r--apps/gui/list.h232
-rw-r--r--apps/gui/scrollbar.c106
-rw-r--r--apps/gui/scrollbar.h49
-rw-r--r--apps/gui/splash.c216
-rw-r--r--apps/gui/splash.h39
-rw-r--r--apps/gui/statusbar.c508
-rw-r--r--apps/gui/statusbar.h107
12 files changed, 2063 insertions, 0 deletions
diff --git a/apps/gui/buttonbar.c b/apps/gui/buttonbar.c
new file mode 100644
index 0000000..be87b1b
--- /dev/null
+++ b/apps/gui/buttonbar.c
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) Linus Nielsen Feltzing (2002), Kévin FERRARE (2005)
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "buttonbar.h"
+
+#ifdef HAS_BUTTONBAR
+
+#include "lcd.h"
+#include "font.h"
+#include "string.h"
+#include "settings.h"
+
+void gui_buttonbar_init(struct gui_buttonbar * buttonbar)
+{
+ gui_buttonbar_unset(buttonbar);
+}
+
+void gui_buttonbar_set_display(struct gui_buttonbar * buttonbar,
+ struct screen * display)
+{
+ buttonbar->display = display;
+}
+
+void gui_buttonbar_draw_button(struct gui_buttonbar * buttonbar, int num)
+{
+ int xpos, ypos, button_width, text_width;
+ int fw, fh;
+ struct screen * display = buttonbar->display;
+
+ display->setfont(FONT_SYSFIXED);
+ display->getstringsize("M", &fw, &fh);
+
+ button_width = display->width/BUTTONBAR_MAX_BUTTONS;
+ xpos = num * button_width;
+ ypos = display->height - fh;
+
+ if(buttonbar->caption[num][0] != 0)
+ {
+ /* center the text */
+ text_width = fw * strlen(buttonbar->caption[num]);
+ display->putsxy(xpos + (button_width - text_width)/2,
+ ypos, buttonbar->caption[num]);
+ }
+
+ display->set_drawmode(DRMODE_COMPLEMENT);
+ display->fillrect(xpos, ypos, button_width - 1, fh);
+ display->set_drawmode(DRMODE_SOLID);
+ display->setfont(FONT_UI);
+}
+
+void gui_buttonbar_set(struct gui_buttonbar * buttonbar,
+ const char *caption1,
+ const char *caption2,
+ const char *caption3)
+{
+ gui_buttonbar_unset(buttonbar);
+ if(caption1)
+ {
+ strncpy(buttonbar->caption[0], caption1, 7);
+ buttonbar->caption[0][7] = 0;
+ }
+ if(caption2)
+ {
+ strncpy(buttonbar->caption[1], caption2, 7);
+ buttonbar->caption[1][7] = 0;
+ }
+ if(caption3)
+ {
+ strncpy(buttonbar->caption[2], caption3, 7);
+ buttonbar->caption[2][7] = 0;
+ }
+}
+
+void gui_buttonbar_unset(struct gui_buttonbar * buttonbar)
+{
+ int i;
+ for(i = 0;i < BUTTONBAR_MAX_BUTTONS;++i)
+ buttonbar->caption[i][0] = 0;
+}
+
+void gui_buttonbar_draw(struct gui_buttonbar * buttonbar)
+{
+ struct screen * display = buttonbar->display;
+ int i;
+
+ display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ display->fillrect(0, display->height - BUTTONBAR_HEIGHT,
+ display->width, BUTTONBAR_HEIGHT);
+ display->set_drawmode(DRMODE_SOLID);
+
+ for(i = 0;i < BUTTONBAR_MAX_BUTTONS;++i)
+ gui_buttonbar_draw_button(buttonbar, i);
+ display->update_rect(0, display->height - BUTTONBAR_HEIGHT,
+ display->width, BUTTONBAR_HEIGHT);
+}
+
+bool gui_buttonbar_isset(struct gui_buttonbar * buttonbar)
+{
+ /* If all buttons are unset, the button bar is considered disabled */
+ if(!global_settings.buttonbar)
+ return(false);
+ int i;
+ for(i = 0;i < BUTTONBAR_MAX_BUTTONS;++i)
+ if(buttonbar->caption[i] != 0)
+ return true;
+ return false;
+}
+
+#endif /* HAS_BUTTONBAR */
diff --git a/apps/gui/buttonbar.h b/apps/gui/buttonbar.h
new file mode 100644
index 0000000..ee7b8d0
--- /dev/null
+++ b/apps/gui/buttonbar.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Kévin FERRARE
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef _GUI_BUTTONBAR_H_
+#define _GUI_BUTTONBAR_H_
+#include "config.h"
+#include "button.h"
+#if CONFIG_KEYPAD == RECORDER_PAD
+
+#define HAS_BUTTONBAR
+#define BUTTONBAR_HEIGHT 8
+#define BUTTONBAR_MAX_BUTTONS 3
+#define BUTTONBAR_CAPTION_LENGTH 8
+#include "screen_access.h"
+
+struct gui_buttonbar
+{
+ char caption[BUTTONBAR_MAX_BUTTONS][BUTTONBAR_CAPTION_LENGTH];
+ struct screen * display;
+};
+
+/*
+ * Initializes the buttonbar
+ * - buttonbar : the buttonbar
+ */
+extern void gui_buttonbar_init(struct gui_buttonbar * buttonbar);
+
+/*
+ * Attach the buttonbar to a screen
+ * - buttonbar : the buttonbar
+ * - display : the display to attach the buttonbar
+ */
+extern void gui_buttonbar_set_display(struct gui_buttonbar * buttonbar,
+ struct screen * display);
+
+/*
+ * Set the caption of the items of the buttonbar
+ * - buttonbar : the buttonbar
+ * - caption1,2,3 : the first, second and thirds items of the bar
+ */
+extern void gui_buttonbar_set(struct gui_buttonbar * buttonbar,
+ const char *caption1,
+ const char *caption2,
+ const char *caption3);
+
+/*
+ * Disable the buttonbar
+ * - buttonbar : the buttonbar
+ */
+extern void gui_buttonbar_unset(struct gui_buttonbar * buttonbar);
+
+/*
+ * Draw the buttonbar on it's attached screen
+ * - buttonbar : the buttonbar
+ */
+extern void gui_buttonbar_draw(struct gui_buttonbar * buttonbar);
+
+/*
+ * Returns true if the buttonbar has something to display, false otherwise
+ * - buttonbar : the buttonbar
+ */
+extern bool gui_buttonbar_isset(struct gui_buttonbar * buttonbar);
+
+#endif /* CONFIG_KEYPAD == RECORDER_PAD */
+#endif /* _GUI_BUTTONBAR_H_ */
diff --git a/apps/gui/icon.c b/apps/gui/icon.c
new file mode 100644
index 0000000..4d174d3
--- /dev/null
+++ b/apps/gui/icon.c
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) Robert E. Hak(2002), Kévin FERRARE (2005)
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "icon.h"
+#include "screen_access.h"
+#include "icons.h"
+
+/* Count in letter positions, NOT pixels */
+void screen_put_iconxy(struct screen * display, int x, int y, ICON icon)
+{
+#ifdef HAVE_LCD_BITMAP
+ if(icon==0)/* Don't display invalid icons */
+ return;
+ int xpos, ypos;
+ xpos = x*CURSOR_WIDTH;
+ ypos = y*display->char_height + display->getymargin();
+ if ( display->char_height > CURSOR_HEIGHT )/* center the cursor */
+ ypos += (display->char_height - CURSOR_HEIGHT) / 2;
+ display->mono_bitmap(icon, xpos, ypos, CURSOR_WIDTH, CURSOR_HEIGHT);
+#else
+ display->putc(x, y, icon);
+#endif
+}
+
+void screen_put_cursorxy(struct screen * display, int x, int y)
+{
+#ifdef HAVE_LCD_BITMAP
+ screen_put_iconxy(display, x, y, bitmap_icons_6x8[Icon_Cursor]);
+#else
+ screen_put_iconxy(display, x, y, CURSOR_CHAR);
+#endif
+}
diff --git a/apps/gui/icon.h b/apps/gui/icon.h
new file mode 100644
index 0000000..46faf09
--- /dev/null
+++ b/apps/gui/icon.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Kévin FERRARE
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef _GUI_ICON_H_
+#define _GUI_ICON_H_
+#include "lcd.h"
+#include "screen_access.h"
+/* Defines a type for the icons since it's not the same thing on
+ * char-based displays and bitmap displays */
+#ifdef HAVE_LCD_BITMAP
+ #define ICON const unsigned char *
+#else
+ #define ICON unsigned short
+#endif
+
+#define CURSOR_CHAR 0x92
+#define CURSOR_WIDTH 6
+#define CURSOR_HEIGHT 8
+/*
+ * Draws a cursor at a given position
+ * - screen : the screen where we put the cursor
+ * - x, y : the position, in character, not in pixel !!
+ */
+extern void screen_put_cursorxy(struct screen * screen, int x, int y);
+
+/*
+ * Put an icon on a screen at a given position
+ * (the position is given in characters)
+ * - screen : the screen where we put our icon
+ * - x, y : the position, in character, not in pixel !!
+ * - icon : the icon to put
+ */
+extern void screen_put_iconxy(struct screen * screen, int x, int y, ICON icon);
+
+#endif /*_GUI_ICON_H_*/
diff --git a/apps/gui/list.c b/apps/gui/list.c
new file mode 100644
index 0000000..bb3eb7c
--- /dev/null
+++ b/apps/gui/list.c
@@ -0,0 +1,499 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Kévin FERRARE
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "lcd.h"
+#include "font.h"
+#include "button.h"
+#include "sprintf.h"
+#include "settings.h"
+#include "kernel.h"
+
+#include "screen_access.h"
+#include "list.h"
+#include "scrollbar.h"
+#include "statusbar.h"
+
+#ifdef HAVE_LCD_CHARCELLS
+#define SCROLL_LIMIT 1
+#else
+#define SCROLL_LIMIT 2
+#endif
+
+
+
+void gui_list_init(struct gui_list * gui_list,
+ void (*callback_get_item_icon)(int selected_item, ICON * icon),
+ char * (*callback_get_item_name)(int selected_item, char *buffer))
+{
+ gui_list->callback_get_item_icon = callback_get_item_icon;
+ gui_list->callback_get_item_name = callback_get_item_name;
+ gui_list->display = NULL;
+ gui_list_set_nb_items(gui_list, 0);
+ gui_list->selected_item = 0;
+ gui_list->start_item = 0;
+}
+
+void gui_list_set_nb_items(struct gui_list * gui_list, int nb_items)
+{
+ gui_list->nb_items = nb_items;
+}
+
+void gui_list_set_display(struct gui_list * gui_list, struct screen * display)
+{
+ if(gui_list->display != 0) /* we switched from a previous display */
+ gui_list->display->stop_scroll();
+ gui_list->display = display;
+#ifdef HAVE_LCD_CHARCELLS
+ display->double_height(false);
+#endif
+ gui_list_put_selection_in_screen(gui_list, false);
+}
+
+void gui_list_put_selection_in_screen(struct gui_list * gui_list,
+ bool put_from_end)
+{
+ struct screen * display = gui_list->display;
+ if(put_from_end)
+ {
+ int list_end = gui_list->selected_item + SCROLL_LIMIT - 1;
+ if(list_end > gui_list->nb_items)
+ list_end = gui_list->nb_items;
+ gui_list->start_item = list_end - display->nb_lines;
+ }
+ else
+ {
+ int list_start = gui_list->selected_item - SCROLL_LIMIT + 1;
+ if(list_start + display->nb_lines > gui_list->nb_items)
+ list_start = gui_list->nb_items - display->nb_lines;
+ gui_list->start_item = list_start;
+ }
+ if(gui_list->start_item < 0)
+ gui_list->start_item = 0;
+}
+
+void gui_list_get_selected_item_name(struct gui_list * gui_list, char *buffer)
+{
+ gui_list->callback_get_item_name(gui_list->selected_item, buffer);
+}
+
+int gui_list_get_selected_item_position(struct gui_list * gui_list)
+{
+ return gui_list->selected_item;
+}
+
+void gui_list_draw(struct gui_list * gui_list)
+{
+ struct screen * display=gui_list->display;
+ int cursor_pos = 0;
+ int icon_pos = 1;
+ int text_pos;
+ bool draw_icons = (gui_list->callback_get_item_icon != NULL &&
+ global_settings.show_icons) ;
+ bool draw_cursor;
+ int i;
+
+ /* Adjust the position of icon, cursor, text */
+#ifdef HAVE_LCD_BITMAP
+ bool draw_scrollbar = (global_settings.scrollbar &&
+ display->nb_lines < gui_list->nb_items);
+
+ int list_y_start = screen_get_text_y_start(gui_list->display);
+ int list_y_end = screen_get_text_y_end(gui_list->display);
+
+ draw_cursor = !global_settings.invert_cursor;
+ text_pos = 0; /* here it's in pixels */
+ if(draw_scrollbar)
+ {
+ ++cursor_pos;
+ ++icon_pos;
+ text_pos += SCROLLBAR_WIDTH;
+ }
+ if(!draw_cursor)
+ {
+ --icon_pos;
+ }
+ else
+ text_pos += CURSOR_WIDTH;
+
+ if(draw_icons)
+ text_pos += 8;
+#else
+ draw_cursor = true;
+ if(draw_icons)
+ text_pos = 2; /* here it's in chars */
+ else
+ text_pos = 1;
+#endif
+ /* The drawing part */
+#ifdef HAVE_LCD_BITMAP
+ /* clear the drawing area */
+ display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ display->fillrect(0, list_y_start,
+ display->width, list_y_end - list_y_start);
+ display->set_drawmode(DRMODE_SOLID);
+
+ /* FIXME: should not be handled here, but rather in the
+ * code that changes fonts */
+ screen_update_nblines(display);
+
+ display->stop_scroll();
+ display->setmargins(text_pos, list_y_start);
+#else
+ display->clear_display();
+#endif
+
+ for(i = 0;i < display->nb_lines;++i)
+ {
+ char entry_buffer[MAX_PATH];
+ char * entry_name;
+ int current_item = gui_list->start_item + i;
+
+ /* When there are less items to display than the
+ * current available space on the screen, we stop*/
+ if(current_item >= gui_list->nb_items)
+ break;
+ entry_name = gui_list->callback_get_item_name(current_item,
+ entry_buffer);
+ if(current_item == gui_list->selected_item)
+ {
+ /* The selected item must be displayed scrolling */
+#ifdef HAVE_LCD_BITMAP
+ if (global_settings.invert_cursor)/* Display inverted-line-style*/
+ display->puts_scroll_style(0, i, entry_name, STYLE_INVERT);
+ else
+ display->puts_scroll(0, i, entry_name);
+#else
+ display->puts_scroll(text_pos, i, entry_name);
+#endif
+
+ if(draw_cursor)
+ screen_put_cursorxy(display, cursor_pos, i);
+ }
+ else
+ {/* normal item */
+#ifdef HAVE_LCD_BITMAP
+ display->puts(0, i, entry_name);
+#else
+ display->puts(text_pos, i, entry_name);
+#endif
+ }
+ /* Icons display */
+ if(draw_icons)
+ {
+ ICON icon;
+ gui_list->callback_get_item_icon(current_item, &icon);
+ screen_put_iconxy(display, icon_pos, i, icon);
+ }
+ }
+#ifdef HAVE_LCD_BITMAP
+ /* Draw the scrollbar if needed*/
+ if(draw_scrollbar)
+ {
+ int scrollbar_y_end = display->char_height *
+ display->nb_lines + list_y_start;
+ gui_scrollbar_draw(display, 0, list_y_start, SCROLLBAR_WIDTH-1,
+ scrollbar_y_end - list_y_start, gui_list->nb_items,
+ gui_list->start_item,
+ gui_list->start_item + display->nb_lines, VERTICAL);
+ }
+ display->update_rect(0, list_y_start, display->width,
+ list_y_end - list_y_start);
+#else
+#ifdef SIMULATOR
+ display->update();
+#endif
+#endif
+}
+
+void gui_list_select_item(struct gui_list * gui_list, int item_number)
+{
+ if( item_number > gui_list->nb_items-1 || item_number < 0 )
+ return;
+ gui_list->selected_item = item_number;
+ gui_list_put_selection_in_screen(gui_list, false);
+}
+
+void gui_list_select_next(struct gui_list * gui_list)
+{
+ int item_pos;
+ int end_item;
+ int nb_lines = gui_list->display->nb_lines;
+
+ ++gui_list->selected_item;
+
+ if( gui_list->selected_item >= gui_list->nb_items )
+ {
+ /* we have already reached the bottom of the list */
+ gui_list->selected_item = 0;
+ gui_list->start_item = 0;
+ }
+ else
+ {
+ item_pos = gui_list->selected_item - gui_list->start_item;
+ end_item = gui_list->start_item + nb_lines;
+ /* we start scrolling vertically when reaching the line
+ * (nb_lines-SCROLL_LIMIT)
+ * and when we are not in the last part of the list*/
+ if( item_pos > nb_lines-SCROLL_LIMIT && end_item < gui_list->nb_items )
+ ++gui_list->start_item;
+ }
+}
+
+void gui_list_select_previous(struct gui_list * gui_list)
+{
+ int item_pos;
+ int nb_lines = gui_list->display->nb_lines;
+
+ --gui_list->selected_item;
+ if( gui_list->selected_item < 0 )
+ {
+ /* we have aleady reached the top of the list */
+ int start;
+ gui_list->selected_item = gui_list->nb_items-1;
+ start = gui_list->nb_items-nb_lines;
+ if( start < 0 )
+ gui_list->start_item = 0;
+ else
+ gui_list->start_item = start;
+ }
+ else
+ {
+ item_pos = gui_list->selected_item - gui_list->start_item;
+ if( item_pos < SCROLL_LIMIT-1 && gui_list->start_item > 0 )
+ --gui_list->start_item;
+ }
+}
+
+void gui_list_select_next_page(struct gui_list * gui_list, int nb_lines)
+{
+ if(gui_list->selected_item == gui_list->nb_items-1)
+ gui_list->selected_item = 0;
+ else
+ {
+ gui_list->selected_item += nb_lines;
+ if(gui_list->selected_item > gui_list->nb_items-1)
+ gui_list->selected_item = gui_list->nb_items-1;
+ }
+ gui_list_put_selection_in_screen(gui_list, true);
+}
+
+void gui_list_select_previous_page(struct gui_list * gui_list, int nb_lines)
+{
+ if(gui_list->selected_item == 0)
+ gui_list->selected_item = gui_list->nb_items - 1;
+ else
+ {
+ gui_list->selected_item -= nb_lines;
+ if(gui_list->selected_item < 0)
+ gui_list->selected_item = 0;
+ }
+ gui_list_put_selection_in_screen(gui_list, false);
+}
+
+void gui_list_add_item(struct gui_list * gui_list)
+{
+ ++gui_list->nb_items;
+ /* if only one item in the list, select it */
+ if(gui_list->nb_items == 1)
+ gui_list->selected_item = 0;
+}
+
+void gui_list_del_item(struct gui_list * gui_list)
+{
+ int nb_lines = gui_list->display->nb_lines;
+
+ if(gui_list->nb_items > 0)
+ {
+ int dist_selected_from_end = gui_list->nb_items
+ - gui_list->selected_item - 1;
+ int dist_start_from_end = gui_list->nb_items
+ - gui_list->start_item - 1;
+ if(dist_selected_from_end == 0)
+ {
+ /* Oops we are removing the selected item,
+ select the previous one */
+ --gui_list->selected_item;
+ }
+ --gui_list->nb_items;
+
+ /* scroll the list if needed */
+ if( (dist_start_from_end < nb_lines) && (gui_list->start_item != 0) )
+ --gui_list->start_item;
+ }
+}
+
+/*
+ * Synchronized lists stuffs
+ */
+void gui_synclist_init(
+ struct gui_synclist * lists,
+ void (*callback_get_item_icon)(int selected_item, ICON * icon),
+ char * (*callback_get_item_name)(int selected_item, char *buffer)
+ )
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ {
+ gui_list_init(&(lists->gui_list[i]), callback_get_item_icon,
+ callback_get_item_name);
+ gui_list_set_display(&(lists->gui_list[i]), &(screens[i]));
+ }
+}
+
+void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ {
+ gui_list_set_nb_items(&(lists->gui_list[i]), nb_items);
+ }
+}
+
+void gui_synclist_get_selected_item_name(struct gui_synclist * lists,
+ char *buffer)
+{
+ gui_list_get_selected_item_name(&(lists->gui_list[0]), buffer);
+}
+
+int gui_synclist_get_selected_item_position(struct gui_synclist * lists)
+{
+ return gui_list_get_selected_item_position(&(lists->gui_list[0]));
+}
+
+void gui_synclist_draw(struct gui_synclist * lists)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ gui_list_draw(&(lists->gui_list[i]));
+}
+
+void gui_synclist_select_item(struct gui_synclist * lists, int item_number)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ gui_list_select_item(&(lists->gui_list[i]), item_number);
+}
+
+void gui_synclist_select_next(struct gui_synclist * lists)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ gui_list_select_next(&(lists->gui_list[i]));
+}
+
+void gui_synclist_select_previous(struct gui_synclist * lists)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ gui_list_select_previous(&(lists->gui_list[i]));
+}
+
+void gui_synclist_select_next_page(struct gui_synclist * lists,
+ enum screen_type screen)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ gui_list_select_next_page(&(lists->gui_list[i]),
+ screens[screen].nb_lines);
+}
+
+void gui_synclist_select_previous_page(struct gui_synclist * lists,
+ enum screen_type screen)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ gui_list_select_previous_page(&(lists->gui_list[i]),
+ screens[screen].nb_lines);
+}
+
+void gui_synclist_add_item(struct gui_synclist * lists)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ gui_list_add_item(&(lists->gui_list[i]));
+}
+
+void gui_synclist_del_item(struct gui_synclist * lists)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;i++)
+ gui_list_del_item(&(lists->gui_list[i]));
+}
+
+bool gui_synclist_do_button(struct gui_synclist * lists, unsigned button)
+{
+ switch(button)
+ {
+ case LIST_PREV:
+ case LIST_PREV | BUTTON_REPEAT:
+#ifdef LIST_RC_PREV
+ case LIST_RC_PREV:
+ case LIST_RC_PREV | BUTTON_REPEAT:
+#endif
+ gui_synclist_select_previous(lists);
+ gui_synclist_draw(lists);
+ return true;
+
+ case LIST_NEXT:
+ case LIST_NEXT | BUTTON_REPEAT:
+#ifdef LIST_RC_NEXT
+ case LIST_RC_NEXT:
+ case LIST_RC_NEXT | BUTTON_REPEAT:
+#endif
+ gui_synclist_select_next(lists);
+ gui_synclist_draw(lists);
+ return true;
+/* for pgup / pgdown, we are obliged to have a different behaviour depending on the screen
+ * for which the user pressed the key since for example, remote and main screen doesn't
+ * have the same number of lines*/
+#ifdef LIST_PGUP
+ case LIST_PGUP:
+ case LIST_PGUP | BUTTON_REPEAT:
+ gui_synclist_select_previous_page(lists, SCREEN_MAIN);
+ gui_synclist_draw(lists);
+ return true;
+#endif
+
+#ifdef LIST_RC_PGUP
+ case LIST_RC_PGUP:
+ case LIST_RC_PGUP | BUTTON_REPEAT:
+ gui_synclist_select_previous_page(lists, SCREEN_REMOTE);
+ gui_synclist_draw(lists);
+ return true;
+#endif
+
+#ifdef LIST_PGDN
+ case LIST_PGDN:
+ case LIST_PGDN | BUTTON_REPEAT:
+ gui_synclist_select_next_page(lists, SCREEN_MAIN);
+ gui_synclist_draw(lists);
+ return true;
+#endif
+
+#ifdef LIST_RC_PGDN
+ case LIST_RC_PGDN:
+ case LIST_RC_PGDN | BUTTON_REPEAT:
+ gui_synclist_select_next_page(lists, SCREEN_REMOTE);
+ gui_synclist_draw(lists);
+ return true;
+#endif
+ }
+ return false;
+}
diff --git a/apps/gui/list.h b/apps/gui/list.h
new file mode 100644
index 0000000..fd553f3
--- /dev/null
+++ b/apps/gui/list.h
@@ -0,0 +1,232 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Kévin FERRARE
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef _GUI_LIST_H_
+#define _GUI_LIST_H_
+
+#include "config.h"
+#include "icon.h"
+#include "screen_access.h"
+
+#define SCROLLBAR_WIDTH 6
+
+/* Key assignement */
+#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
+ (CONFIG_KEYPAD == IRIVER_H300_PAD)
+#define LIST_NEXT BUTTON_DOWN
+#define LIST_PREV BUTTON_UP
+#define LIST_PGUP (BUTTON_ON | BUTTON_UP)
+#define LIST_PGDN (BUTTON_ON | BUTTON_DOWN)
+#define LIST_RC_NEXT BUTTON_RC_FF
+#define LIST_RC_PREV BUTTON_RC_REW
+#define LIST_RC_PGUP BUTTON_RC_SOURCE
+#define LIST_RC_PGDN BUTTON_RC_BITRATE
+
+#elif CONFIG_KEYPAD == RECORDER_PAD
+#define LIST_NEXT BUTTON_DOWN
+#define LIST_PREV BUTTON_UP
+#define LIST_PGUP (BUTTON_ON | BUTTON_UP)
+#define LIST_PGDN (BUTTON_ON | BUTTON_DOWN)
+#define LIST_RC_NEXT BUTTON_RC_RIGHT
+#define LIST_RC_PREV BUTTON_RC_LEFT
+
+#elif CONFIG_KEYPAD == PLAYER_PAD
+#define LIST_NEXT BUTTON_RIGHT
+#define LIST_PREV BUTTON_LEFT
+#define LIST_RC_NEXT BUTTON_RC_RIGHT
+#define LIST_RC_PREV BUTTON_RC_LEFT
+
+#elif CONFIG_KEYPAD == ONDIO_PAD
+#define LIST_NEXT BUTTON_DOWN
+#define LIST_PREV BUTTON_UP
+
+#elif CONFIG_KEYPAD == GMINI100_PAD
+#define LIST_NEXT BUTTON_DOWN
+#define LIST_PREV BUTTON_UP
+#define LIST_PGUP (BUTTON_ON | BUTTON_UP)
+#define LIST_PGDN (BUTTON_ON | BUTTON_DOWN)
+#endif
+
+
+struct gui_list
+{
+ int nb_items;
+ int selected_item;
+ int start_item; /* the item that is displayed at the top of the screen */
+
+ void (*callback_get_item_icon)(int selected_item, ICON * icon);
+ char * (*callback_get_item_name)(int selected_item, char *buffer);
+
+ struct screen * display;
+ int line_scroll_limit;
+};
+
+/*
+ * Initializes a scrolling list
+ * - gui_list : the list structure to initialize
+ * - callback_get_item_icon : pointer to a function that associates an icon
+ * to a given item number
+ * - callback_get_item_name : pointer to a function that associates a label
+ * to a given item number
+ */
+extern void gui_list_init(struct gui_list * gui_list,
+ void (*callback_get_item_icon)(int selected_item, ICON * icon),
+ char * (*callback_get_item_name)(int selected_item, char *buffer)
+ );
+
+/*
+ * Sets the numburs of items the list can currently display
+ * note that the list's context like the currently pointed item is resetted
+ * - gui_list : the list structure to initialize
+ * - nb_items : the numbers of items you want
+ */
+extern void gui_list_set_nb_items(struct gui_list * gui_list, int nb_items);
+
+/*
+ * Puts the selection in the screen
+ * - gui_list : the list structure
+ * - put_from_end : if true, selection will be put as close from
+ * the end of the list as possible, else, it's
+ * from the beginning
+ */
+extern void gui_list_put_selection_in_screen(struct gui_list * gui_list,
+ bool put_from_end);
+
+/*
+ * Attach the scrolling list to a screen
+ * (The previous screen attachement is lost)
+ * - gui_list : the list structure
+ * - display : the screen to attach
+ */
+extern void gui_list_set_display(struct gui_list * gui_list,
+ struct screen * display);
+
+/*
+ * Gives the name of the selected object
+ * - gui_list : the list structure
+ * - buffer : a buffer which is filled with the name
+ */
+extern void gui_list_get_selected_item_name(struct gui_list * gui_list,
+ char *buffer);
+
+/*
+ * Gives the position of the selected item
+ * - gui_list : the list structure
+ * Returns the position
+ */
+extern int gui_list_get_selected_item_position(struct gui_list * gui_list);
+
+/*
+ * Selects an item in the list
+ * - gui_list : the list structure
+ * - item_number : the number of the item which will be selected
+ */
+extern void gui_list_select_item(struct gui_list * gui_list, int item_number);
+
+/*
+ * Draws the list on the attached screen
+ * - gui_list : the list structure
+ */
+extern void gui_list_draw(struct gui_list * gui_list);
+
+/*
+ * Selects the next item in the list
+ * (Item 0 gets selected if the end of the list is reached)
+ * - gui_list : the list structure
+ */
+extern void gui_list_select_next(struct gui_list * gui_list);
+
+/*
+ * Selects the previous item in the list
+ * (Last item in the list gets selected if the list beginning is reached)
+ * - gui_list : the list structure
+ */
+extern void gui_list_select_previous(struct gui_list * gui_list);
+
+/*
+ * Go to next page if any, else selects the last item in the list
+ * - gui_list : the list structure
+ * - nb_lines : the number of lines to try to move the cursor
+ */
+extern void gui_list_select_next_page(struct gui_list * gui_list,
+ int nb_lines);
+
+/*
+ * Go to previous page if any, else selects the first item in the list
+ * - gui_list : the list structure
+ * - nb_lines : the number of lines to try to move the cursor
+ */
+extern void gui_list_select_previous_page(struct gui_list * gui_list,
+ int nb_lines);
+
+/*
+ * Adds an item to the list (the callback will be asked for one more item)
+ * - gui_list : the list structure
+ */
+extern void gui_list_add_item(struct gui_list * gui_list);
+
+/*
+ * Removes an item to the list (the callback will be asked for one less item)
+ * - gui_list : the list structure
+ */
+extern void gui_list_del_item(struct gui_list * gui_list);
+
+
+/*
+ * This part handles as many lists as there are connected screens
+ * (the api is similar to the ones above)
+ * The lists on the screens are synchronized ;
+ * theirs items and selected items are the same, but of course,
+ * they can be displayed on screens with different sizes
+ * The final aim is to let the programmer handle many lists in one
+ * function call and make its code independant from the number of screens
+ */
+struct gui_synclist
+{
+ struct gui_list gui_list[NB_SCREENS];
+};
+
+extern void gui_synclist_init(struct gui_synclist * lists,
+ void (*callback_get_item_icon)(int selected_item, ICON * icon),
+ char * (*callback_get_item_name)(int selected_item, char *buffer)
+ );
+extern void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items);
+extern void gui_synclist_get_selected_item_name(struct gui_synclist * lists,
+ char *buffer);
+extern int gui_synclist_get_selected_item_position(struct gui_synclist * lists);
+extern void gui_synclist_draw(struct gui_synclist * lists);
+extern void gui_synclist_select_item(struct gui_synclist * lists,
+ int item_number);
+extern void gui_synclist_select_next(struct gui_synclist * lists);
+extern void gui_synclist_select_previous(struct gui_synclist * lists);
+extern void gui_synclist_select_next_page(struct gui_synclist * lists,
+ enum screen_type screen);
+extern void gui_synclist_select_previous_page(struct gui_synclist * lists,
+ enum screen_type screen);
+extern void gui_synclist_add_item(struct gui_synclist * lists);
+extern void gui_synclist_del_item(struct gui_synclist * lists);
+/*
+ * Do the action implied by the given button,
+ * returns true if something has been done, false otherwise
+ * - lists : the synchronized lists
+ * - button : the keycode of a pressed button
+ */
+extern bool gui_synclist_do_button(struct gui_synclist * lists, unsigned button);
+
+#endif /* _GUI_LIST_H_ */
diff --git a/apps/gui/scrollbar.c b/apps/gui/scrollbar.c
new file mode 100644
index 0000000..9d5717f
--- /dev/null
+++ b/apps/gui/scrollbar.c
@@ -0,0 +1,106 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) Markus Braun (2002), Kévin FERRARE (2005)
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "lcd.h"
+#ifdef HAVE_LCD_BITMAP
+#include "limits.h"
+#include "scrollbar.h"
+#include "screen_access.h"
+
+void gui_scrollbar_draw(struct screen * screen, int x, int y,
+ int width, int height, int items,
+ int min_shown, int max_shown,
+ enum orientation orientation)
+{
+ int min;
+ int max;
+ int inner_len;
+ int start;
+ int size;
+
+ /* draw box */
+ screen->drawrect(x, y, width, height);
+
+ screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+
+ /* clear edge pixels */
+ screen->drawpixel(x, y);
+ screen->drawpixel((x + width - 1), y);
+ screen->drawpixel(x, (y + height - 1));
+ screen->drawpixel((x + width - 1), (y + height - 1));
+
+ /* clear pixels in progress bar */
+ screen->fillrect(x + 1, y + 1, width - 2, height - 2);
+
+ /* min should be min */
+ if(min_shown < max_shown) {
+ min = min_shown;
+ max = max_shown;
+ }
+ else {
+ min = max_shown;
+ max = min_shown;
+ }
+
+ /* limit min and max */
+ if(min < 0)
+ min = 0;
+ if(min > items)
+ min = items;
+
+ if(max < 0)
+ max = 0;
+ if(max > items)
+ max = items;
+
+ if (orientation == VERTICAL)
+ inner_len = height - 2;
+ else
+ inner_len = width - 2;
+
+ /* avoid overflows */
+ while (items > (INT_MAX / inner_len)) {
+ items >>= 1;
+ min >>= 1;
+ max >>= 1;
+ }
+
+ /* calc start and end of the knob */
+ if (items > 0 && items > (max - min)) {
+ size = inner_len * (max - min) / items;
+ if (size == 0) { /* width of knob is null */
+ size = 1;
+ start = (inner_len - 1) * min / items;
+ } else {
+ start = (inner_len - size) * min / (items - (max - min));
+ }
+ } else { /* if null draw full bar */
+ size = inner_len;
+ start = 0;
+ }
+
+ screen->set_drawmode(DRMODE_SOLID);
+
+ if(orientation == VERTICAL)
+ screen->fillrect(x + 1, y + start + 1, width - 2, size);
+ else
+ screen->fillrect(x + start + 1, y + 1, size, height - 2);
+}
+#endif /* HAVE_LCD_BITMAP */
diff --git a/apps/gui/scrollbar.h b/apps/gui/scrollbar.h
new file mode 100644
index 0000000..51c0835
--- /dev/null
+++ b/apps/gui/scrollbar.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 Kévin FERRARE
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef _GUI_SCROLLBAR_H_
+#define _GUI_SCROLLBAR_H_
+#include <lcd.h>
+#ifdef HAVE_LCD_BITMAP
+
+struct screen;
+
+enum orientation {
+ VERTICAL,
+ HORIZONTAL
+};
+
+/*
+ * Draws a scrollbar on the given screen
+ * - screen : the screen to put the scrollbar on
+ * - x : x start position of the scrollbar
+ * - y : y start position of the scrollbar
+ * - width : you won't guess =(^o^)=
+ * - height : I won't tell you either !
+ * - items : total number of items on the screen
+ * - min_shown : index of the starting item on the screen
+ * - max_shown : index of the last item on the screen
+ * - orientation : either VERTICAL or HORIZONTAL
+ */
+extern void gui_scrollbar_draw(struct screen * screen, int x, int y,
+ int width, int height, int items,
+ int min_shown, int max_shown,
+ enum orientation orientation);
+#endif /* HAVE_LCD_BITMAP */
+#endif /* _GUI_SCROLLBAR_H_ */
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
new file mode 100644
index 0000000..a3cbb19
--- /dev/null
+++ b/apps/gui/splash.c
@@ -0,0 +1,216 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) Daniel Stenberg (2002), Kévin FERRARE (2005)
+ *
+ * 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.
+ *
+ ****************************************************************************/
+#include "stdarg.h"
+#include "string.h"
+#include "stdio.h"
+#include "kernel.h"
+#include "screen_access.h"
+
+
+#ifdef HAVE_LCD_BITMAP
+
+#define SPACE 3 /* pixels between words */
+#define MAXLETTERS 128 /* 16*8 */
+#define MAXLINES 10
+
+#else
+
+#define SPACE 1 /* one letter space */
+#define MAXLETTERS 22 /* 11 * 2 */
+#define MAXLINES 2
+
+#endif
+
+
+void internal_splash(struct screen * screen,
+ bool center, const char *fmt, va_list ap)
+{
+ char *next;
+ char *store=NULL;
+ int x=0;
+ int y=0;
+ int w, h;
+ unsigned char splash_buf[MAXLETTERS];
+ unsigned char widths[MAXLINES];
+ int line=0;
+ bool first=true;
+#ifdef HAVE_LCD_BITMAP
+ int maxw=0;
+#endif
+
+#ifdef HAVE_LCD_CHARCELLS
+ screen->double_height (false);
+#endif
+ vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap );
+
+ if(center) {
+ /* first a pass to measure sizes */
+ next = strtok_r(splash_buf, " ", &store);
+ while (next) {
+#ifdef HAVE_LCD_BITMAP
+ screen->getstringsize(next, &w, &h);
+#else
+ w = strlen(next);
+ h = 1; /* store height in characters */
+#endif
+ if(!first) {
+ if(x+w> screen->width) {
+ /* Too wide, wrap */
+ y+=h;
+ line++;
+ if((y > (screen->height-h)) || (line > screen->nb_lines))
+ /* STOP */
+ break;
+ x=0;
+ first=true;
+ }
+ }
+ else
+ first = false;
+
+ /* think of it as if the text was written here at position x,y
+ being w pixels/chars wide and h high */
+
+ x += w+SPACE;
+ widths[line]=x-SPACE; /* don't count the trailing space */
+#ifdef HAVE_LCD_BITMAP
+ /* store the widest line */
+ if(widths[line]>maxw)
+ maxw = widths[line];
+#endif
+ next = strtok_r(NULL, " ", &store);
+ }
+
+#ifdef HAVE_LCD_BITMAP
+ /* Start displaying the message at position y. The reason for the
+ added h here is that it isn't added until the end of lines in the
+ loop above and we always break the loop in the middle of a line. */
+ y = (screen->height - (y+h) )/2;
+#else
+ y = 0; /* vertical center on 2 lines would be silly */
+#endif
+ first=true;
+
+ /* Now recreate the string again since the strtok_r() above has ruined
+ the one we already have! Here's room for improvements! */
+ vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap );
+ }
+ va_end( ap );
+
+ if(center)
+ {
+ x = (screen->width-widths[0])/2;
+ if(x < 0)
+ x = 0;
+ }
+
+#ifdef HAVE_LCD_BITMAP
+ /* If we center the display, then just clear the box we need and put
+ a nice little frame and put the text in there! */
+ if(center && (y > 2)) {
+ int xx = (screen->width-maxw)/2 - 2;
+ /* The new graphics routines handle clipping, so no need to check */
+#if LCD_DEPTH > 1
+#ifdef HAVE_LCD_COLOR
+ screen->set_background((struct rgb){LCD_MAX_RED-1, LCD_MAX_GREEN-1,
+ LCD_MAX_BLUE-1});
+#else
+ if(screen->depth>1)
+ screen->set_background(LCD_MAX_LEVEL-1);
+#endif
+#endif
+ screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ screen->fillrect(xx, y-2, maxw+4, screen->height-y*2+4);
+ screen->set_drawmode(DRMODE_SOLID);
+ screen->drawrect(xx, y-2, maxw+4, screen->height-y*2+4);
+ }
+ else
+#endif
+ screen->clear_display();
+ line=0;
+ next = strtok_r(splash_buf, " ", &store);
+ while (next) {
+#ifdef HAVE_LCD_BITMAP
+ screen->getstringsize(next, &w, &h);
+#else
+ w = strlen(next);
+ h = 1;
+#endif
+ if(!first) {
+ if(x+w> screen->width) {
+ /* too wide */
+ y+=h;
+ line++; /* goto next line */
+ first=true;
+ if(y > (screen->height-h))
+ /* STOP */
+ break;
+ if(center) {
+ x = (screen->width-widths[line])/2;
+ if(x < 0)
+ x = 0;
+ }
+ else
+ x=0;
+ }
+ }
+ else
+ first=false;
+#ifdef HAVE_LCD_BITMAP
+ screen->putsxy(x, y, next);
+#else
+ screen->puts(x, y, next);
+#endif
+ x += w+SPACE; /* pixels space! */
+ next = strtok_r(NULL, " ", &store);
+ }
+
+#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1)
+ if(screen->depth > 1)
+ screen->set_background(LCD_WHITE);
+#endif
+#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
+ screen->update();
+#endif
+}
+
+void gui_splash(struct screen * screen, int ticks,
+ bool center, const char *fmt, ...)
+{
+ va_list ap;
+ va_start( ap, fmt );
+ internal_splash(screen, center, fmt, ap);
+ va_end( ap );
+
+ if(ticks)
+ sleep(ticks);
+}
+
+void gui_syncsplash(int ticks, bool center, const char *fmt, ...)
+{
+ va_list ap;
+ int i;
+ va_start( ap, fmt );
+ for(i=0;i<NB_SCREENS;++i)
+ internal_splash(&(screens[i]), center, fmt, ap);
+ va_end( ap );
+
+ if(ticks)
+ sleep(ticks);
+}
diff --git a/apps/gui/splash.h b/apps/gui/splash.h
new file mode 100644
index 0000000..b0d55db
--- /dev/null
+++ b/apps/gui/splash.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Kévin FERRARE
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/*
+ * Puts a splash message on the given screen for a given period
+ * - screen : the screen to put the splash on
+ * - ticks : how long the splash is displayed (in rb ticks)
+ * - center : FALSE means left-justified, TRUE means
+ * horizontal and vertical center
+ * - fmt : what to say *printf style
+ */
+extern void gui_splash(struct screen * screen, int ticks,
+ bool center, const char *fmt, ...);
+
+/*
+ * Puts a splash message on all the screens for a given period
+ * - ticks : how long the splash is displayed (in rb ticks)
+ * - center : FALSE means left-justified, TRUE means
+ * horizontal and vertical center
+ * - fmt : what to say *printf style
+ */
+extern void gui_syncsplash(int ticks, bool center,
+ const char *fmt, ...);
diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c
new file mode 100644
index 0000000..5ddc194
--- /dev/null
+++ b/apps/gui/statusbar.c
@@ -0,0 +1,508 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) Robert E. Hak (2002), Linus Nielsen Feltzing (2002), Kévin FERRARE (2005)
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "screen_access.h"
+#include "lcd.h"
+#include "font.h"
+#include "kernel.h"
+#include "string.h" /* for memcmp oO*/
+#include "sprintf.h"
+#include "sound.h"
+#include "power.h"
+#include "settings.h"
+#include "icons.h"
+#include "powermgmt.h"
+#include "button.h"
+
+#include "status.h" /* needed for battery_state global var */
+#include "wps.h" /* for keys_locked */
+#include "statusbar.h"
+
+
+/* FIXME: should be removed from icon.h to avoid redefinition,
+ but still needed for compatibility with old system */
+#define STATUSBAR_X_POS 0
+#define STATUSBAR_Y_POS 0 /* MUST be a multiple of 8 */
+#define STATUSBAR_HEIGHT 8
+#define STATUSBAR_BATTERY_X_POS 0
+#define STATUSBAR_BATTERY_WIDTH 18
+#define STATUSBAR_PLUG_X_POS STATUSBAR_X_POS + \
+ STATUSBAR_BATTERY_WIDTH +2
+#define STATUSBAR_PLUG_WIDTH 7
+#define STATUSBAR_VOLUME_X_POS STATUSBAR_X_POS + \
+ STATUSBAR_BATTERY_WIDTH + \
+ STATUSBAR_PLUG_WIDTH +2+2
+#define STATUSBAR_VOLUME_WIDTH 16
+#define STATUSBAR_PLAY_STATE_X_POS STATUSBAR_X_POS + \
+ STATUSBAR_BATTERY_WIDTH + \
+ STATUSBAR_PLUG_WIDTH + \
+ STATUSBAR_VOLUME_WIDTH+2+2+2
+#define STATUSBAR_PLAY_STATE_WIDTH 7
+#define STATUSBAR_PLAY_MODE_X_POS STATUSBAR_X_POS + \
+ STATUSBAR_BATTERY_WIDTH + \
+ STATUSBAR_PLUG_WIDTH + \
+ STATUSBAR_VOLUME_WIDTH + \
+ STATUSBAR_PLAY_STATE_WIDTH + \
+ 2+2+2+2
+#define STATUSBAR_PLAY_MODE_WIDTH 7
+#define STATUSBAR_SHUFFLE_X_POS STATUSBAR_X_POS + \
+ STATUSBAR_BATTERY_WIDTH + \
+ STATUSBAR_PLUG_WIDTH + \
+ STATUSBAR_VOLUME_WIDTH + \
+ STATUSBAR_PLAY_STATE_WIDTH + \
+ STATUSBAR_PLAY_MODE_WIDTH + \
+ 2+2+2+2+2
+#define STATUSBAR_SHUFFLE_WIDTH 7
+#define STATUSBAR_LOCK_X_POS STATUSBAR_X_POS + \
+ STATUSBAR_BATTERY_WIDTH + \
+ STATUSBAR_PLUG_WIDTH + \
+ STATUSBAR_VOLUME_WIDTH + \
+ STATUSBAR_PLAY_STATE_WIDTH + \
+ STATUSBAR_PLAY_MODE_WIDTH + \
+ STATUSBAR_SHUFFLE_WIDTH + \
+ 2+2+2+2+2+2
+#define STATUSBAR_LOCK_WIDTH 5
+#define STATUSBAR_DISK_WIDTH 12
+#define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \
+ STATUSBAR_DISK_WIDTH
+#define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width-1
+
+void gui_statusbar_init(struct gui_statusbar * bar)
+{
+ bar->last_volume = -1; /* -1 means "first update ever" */
+ bar->battery_icon_switch_tick = 0;
+#ifdef HAVE_USB_POWER
+ bar->battery_charge_step = 0;
+#endif
+}
+
+void gui_statusbar_set_screen(struct gui_statusbar * bar,
+ struct screen * display)
+{
+ bar->display = display;
+ gui_statusbar_draw(bar, false);
+}
+
+void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw)
+{
+#ifdef HAVE_LCD_BITMAP
+ if(!global_settings.statusbar)
+ return;
+#endif
+
+ struct screen * display = bar->display;
+
+#ifdef HAVE_LCD_BITMAP
+ struct tm* tm; /* For Time */
+#else
+ (void)force_redraw; /* players always "redraw" */
+#endif
+
+ bar->info.volume = sound_val2phys(SOUND_VOLUME, global_settings.volume);
+ bar->info.inserted = charger_inserted();
+ bar->info.battlevel = battery_level();
+ bar->info.battery_safe = battery_level_safe();
+
+#ifdef HAVE_LCD_BITMAP
+ tm = get_time();
+ bar->info.hour = tm->tm_hour;
+ bar->info.minute = tm->tm_min;
+ bar->info.shuffle = global_settings.playlist_shuffle;
+#if CONFIG_KEYPAD == IRIVER_H100_PAD
+ bar->info.keylock = button_hold();
+#else
+ bar->info.keylock = keys_locked;
+#endif
+ bar->info.repeat = global_settings.repeat_mode;
+ bar->info.playmode = current_playmode();
+#if CONFIG_LED == LED_VIRTUAL
+ bar->info.led = led_read(HZ/2); /* delay should match polling interval */
+#endif
+#ifdef HAVE_USB_POWER
+ bar->info.usb_power = usb_powered();
+#endif
+
+ /* only redraw if forced to, or info has changed */
+ if (force_redraw ||
+ bar->info.inserted ||
+ !bar->info.battery_safe ||
+ bar->info.redraw_volume ||
+ memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info)))
+ {
+ display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ display->fillrect(0,0,display->width,8);
+ display->set_drawmode(DRMODE_SOLID);
+
+#else
+
+ /* players always "redraw" */
+ {
+#endif
+
+#ifdef HAVE_CHARGING
+ if (bar->info.inserted) {
+ battery_state = true;
+#if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200
+ /* zero battery run time if charging */
+ if (charge_state > 0) {
+ global_settings.runtime = 0;
+ lasttime = current_tick;
+ }
+
+ /* animate battery if charging */
+ if ((charge_state == 1) ||
+ (charge_state == 2)) {
+#else
+ global_settings.runtime = 0;
+ lasttime = current_tick;
+ {
+#endif
+ /* animate in three steps (34% per step for a better look) */
+ bar->info.battlevel = bar->battery_charge_step * 34;
+ if (bar->info.battlevel > 100)
+ bar->info.battlevel = 100;
+ if(TIME_AFTER(current_tick, bar->battery_icon_switch_tick)) {
+ bar->battery_charge_step=(bar->battery_charge_step+1)%4;
+ bar->battery_icon_switch_tick = current_tick + HZ;
+ }
+ }
+ }
+ else
+#endif /* HAVE_CHARGING */
+ {
+ if (bar->info.battery_safe)
+ battery_state = true;
+ else {
+ /* blink battery if level is low */
+ if(TIME_AFTER(current_tick, bar->battery_icon_switch_tick) &&
+ (bar->info.battlevel > -1)) {
+ bar->battery_icon_switch_tick = current_tick+HZ;
+ battery_state = !battery_state;
+ }
+ }
+ }
+#ifdef HAVE_LCD_BITMAP
+ if (battery_state)
+ gui_statusbar_icon_battery(display, bar->info.battlevel);
+ /* draw power plug if charging */
+ if (bar->info.inserted)
+ display->mono_bitmap(bitmap_icons_7x8[Icon_Plug],
+ STATUSBAR_PLUG_X_POS,
+ STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
+ STATUSBAR_HEIGHT);
+#ifdef HAVE_USB_POWER
+ else if (bar->info.usb_power)
+ display->mono_bitmap(bitmap_icons_7x8[Icon_USBPlug],
+ STATUSBAR_PLUG_X_POS,
+ STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
+ STATUSBAR_HEIGHT);
+#endif
+
+ bar->info.redraw_volume = gui_statusbar_icon_volume(bar,
+ bar->info.volume);
+ gui_statusbar_icon_play_state(display, current_playmode() +
+ Icon_Play);
+ switch (bar->info.repeat) {
+#ifdef AB_REPEAT_ENABLE
+ case REPEAT_AB:
+ gui_statusbar_icon_play_mode(display, Icon_RepeatAB);
+ break;
+#endif
+
+ case REPEAT_ONE:
+ gui_statusbar_icon_play_mode(display, Icon_RepeatOne);
+ break;
+
+ case REPEAT_ALL:
+ case REPEAT_SHUFFLE:
+ gui_statusbar_icon_play_mode(display, Icon_Repeat);
+ break;
+ }
+ if (bar->info.shuffle)
+ gui_statusbar_icon_shuffle(display);
+ if (bar->info.keylock)
+ gui_statusbar_icon_lock(display);
+#ifdef HAVE_RTC
+ gui_statusbar_time(display, bar->info.hour, bar->info.minute);
+#endif
+#if CONFIG_LED == LED_VIRTUAL
+ if (bar->info.led)
+ statusbar_led();
+#endif
+ display->update_rect(0, 0, display->width, STATUSBAR_HEIGHT);
+ bar->lastinfo = bar->info;
+#endif
+ }
+
+
+#ifndef HAVE_LCD_BITMAP
+ if (bar->info.battlevel > -1)
+ display->icon(ICON_BATTERY, battery_state);
+ display->icon(ICON_BATTERY_1, bar->info.battlevel > 25);
+ display->icon(ICON_BATTERY_2, bar->info.battlevel > 50);
+ display->icon(ICON_BATTERY_3, bar->info.battlevel > 75);
+
+ display->icon(ICON_VOLUME, true);
+ display->icon(ICON_VOLUME_1, bar->info.volume > 10);
+ display->icon(ICON_VOLUME_2, bar->info.volume > 30);
+ display->icon(ICON_VOLUME_3, bar->info.volume > 50);
+ display->icon(ICON_VOLUME_4, bar->info.volume > 70);
+ display->icon(ICON_VOLUME_5, bar->info.volume > 90);
+
+ display->icon(ICON_PLAY, current_playmode() == STATUS_PLAY);
+ display->icon(ICON_PAUSE, current_playmode() == STATUS_PAUSE);
+
+ display->icon(ICON_REPEAT, global_settings.repeat_mode != REPEAT_OFF);
+ display->icon(ICON_1, global_settings.repeat_mode == REPEAT_ONE);
+
+ display->icon(ICON_RECORD, record);
+ display->icon(ICON_AUDIO, audio);
+ display->icon(ICON_PARAM, param);
+ display->icon(ICON_USB, usb);
+#endif
+}
+
+#ifdef HAVE_LCD_BITMAP
+/* from icon.c */
+/*
+ * Print battery icon to status bar
+ */
+void gui_statusbar_icon_battery(struct screen * display, int percent)
+{
+ int fill;
+ char buffer[5];
+ unsigned int width, height;
+
+ /* fill battery */
+ fill = percent;
+ if (fill < 0)
+ fill = 0;
+ if (fill > 100)
+ fill = 100;
+
+#if defined(HAVE_CHARGE_CTRL) && !defined(SIMULATOR) /* Rec v1 target only */
+ /* show graphical animation when charging instead of numbers */
+ if ((global_settings.battery_display) &&
+ (charge_state != 1) &&
+ (percent > -1)) {
+#else /* all others */
+ if (global_settings.battery_display && (percent > -1)) {
+#endif
+ /* Numeric display */
+ display->setfont(FONT_SYSFIXED);
+ snprintf(buffer, sizeof(buffer), "%3d", fill);
+ display->getstringsize(buffer, &width, &height);
+ if (height <= STATUSBAR_HEIGHT)
+ display->putsxy(STATUSBAR_BATTERY_X_POS
+ + STATUSBAR_BATTERY_WIDTH / 2
+ - width/2, STATUSBAR_Y_POS, buffer);
+ display->setfont(FONT_UI);
+
+ }
+ else {
+ /* draw battery */
+ display->drawrect(STATUSBAR_BATTERY_X_POS, STATUSBAR_Y_POS, 17, 7);
+ display->vline(STATUSBAR_BATTERY_X_POS + 17, STATUSBAR_Y_POS + 2,
+ STATUSBAR_Y_POS + 4);
+
+ fill = fill * 15 / 100;
+ display->fillrect(STATUSBAR_BATTERY_X_POS + 1, STATUSBAR_Y_POS + 1,
+ fill, 5);
+ }
+
+ if (percent == -1) {
+ display->setfont(FONT_SYSFIXED);
+ display->putsxy(STATUSBAR_BATTERY_X_POS + STATUSBAR_BATTERY_WIDTH / 2
+ - 4, STATUSBAR_Y_POS, "?");
+ display->setfont(FONT_UI);
+ }
+}
+
+/*
+ * Print volume gauge to status bar
+ */
+bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int percent)
+{
+ int i;
+ int volume;
+ int vol;
+ char buffer[4];
+ unsigned int width, height;
+ bool needs_redraw = false;
+ int type = global_settings.volume_type;
+ struct screen * display=bar->display;
+
+ volume = percent;
+ if (volume < 0)
+ volume = 0;
+ if (volume > 100)
+ volume = 100;
+
+ if (volume == 0) {
+ display->mono_bitmap(bitmap_icons_7x8[Icon_Mute],
+ STATUSBAR_VOLUME_X_POS + STATUSBAR_VOLUME_WIDTH / 2 - 4,
+ STATUSBAR_Y_POS, 7, STATUSBAR_HEIGHT);
+ }
+ else {
+ /* We want to redraw the icon later on */
+ if (bar->last_volume != volume && bar->last_volume >= 0) {
+ bar->volume_icon_switch_tick = current_tick + HZ;
+ }
+
+ /* If the timeout hasn't yet been reached, we show it numerically
+ and tell the caller that we want to be called again */
+ if (TIME_BEFORE(current_tick,bar->volume_icon_switch_tick)) {
+ type = 1;
+ needs_redraw = true;
+ }
+
+ /* display volume level numerical? */
+ if (type)
+ {
+ display->setfont(FONT_SYSFIXED);
+ snprintf(buffer, sizeof(buffer), "%2d", percent);
+ display->getstringsize(buffer, &width, &height);
+ if (height <= STATUSBAR_HEIGHT)
+ {
+ display->putsxy(STATUSBAR_VOLUME_X_POS
+ + STATUSBAR_VOLUME_WIDTH / 2
+ - width/2, STATUSBAR_Y_POS, buffer);
+ }
+ display->setfont(FONT_UI);
+ } else {
+ /* display volume bar */
+ vol = volume * 14 / 100;
+ for(i=0; i < vol; i++) {
+ display->vline(STATUSBAR_VOLUME_X_POS + i,
+ STATUSBAR_Y_POS + 6 - i / 2,
+ STATUSBAR_Y_POS + 6);
+ }
+ }
+ }
+ bar->last_volume = volume;
+
+ return needs_redraw;
+}
+
+/*
+ * Print play state to status bar
+ */
+void gui_statusbar_icon_play_state(struct screen * display, int state)
+{
+ display->mono_bitmap(bitmap_icons_7x8[state], STATUSBAR_PLAY_STATE_X_POS,
+ STATUSBAR_Y_POS, STATUSBAR_PLAY_STATE_WIDTH,
+ STATUSBAR_HEIGHT);
+}
+
+/*
+ * Print play mode to status bar
+ */
+void gui_statusbar_icon_play_mode(struct screen * display, int mode)
+{
+ display->mono_bitmap(bitmap_icons_7x8[mode], STATUSBAR_PLAY_MODE_X_POS,
+ STATUSBAR_Y_POS, STATUSBAR_PLAY_MODE_WIDTH,
+ STATUSBAR_HEIGHT);
+}
+
+/*
+ * Print shuffle mode to status bar
+ */
+void gui_statusbar_icon_shuffle(struct screen * display)
+{
+ display->mono_bitmap(bitmap_icons_7x8[Icon_Shuffle],
+ STATUSBAR_SHUFFLE_X_POS, STATUSBAR_Y_POS,
+ STATUSBAR_SHUFFLE_WIDTH, STATUSBAR_HEIGHT);
+}
+
+/*
+ * Print lock when keys are locked
+ */
+void gui_statusbar_icon_lock(struct screen * display)
+{
+ display->mono_bitmap(bitmap_icons_5x8[Icon_Lock], STATUSBAR_LOCK_X_POS,
+ STATUSBAR_Y_POS, 5, 8);
+}
+
+#if CONFIG_LED == LED_VIRTUAL
+/*
+ * no real LED: disk activity in status bar
+ */
+void gui_statusbar_led(struct screen * display)
+{
+ display->mono_bitmap(bitmap_icon_disk, STATUSBAR_DISK_X_POS,
+ STATUSBAR_Y_POS, STATUSBAR_DISK_WIDTH(screen->width),
+ STATUSBAR_HEIGHT);
+}
+#endif
+
+
+#ifdef HAVE_RTC
+/*
+ * Print time to status bar
+ */
+void gui_statusbar_time(struct screen * display, int hour, int minute)
+{
+ unsigned char buffer[6];
+ unsigned int width, height;
+ if ( hour >= 0 &&
+ hour <= 23 &&
+ minute >= 0 &&
+ minute <= 59 ) {
+ if ( global_settings.timeformat ) { /* 12 hour clock */
+ hour %= 12;
+ if ( hour == 0 ) {
+ hour += 12;
+ }
+ }
+ snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute);
+ }
+ else {
+ strncpy(buffer, "--:--", sizeof buffer);
+ }
+ display->setfont(FONT_SYSFIXED);
+ display->getstringsize(buffer, &width, &height);
+ if (height <= STATUSBAR_HEIGHT) {
+ display->putsxy(STATUSBAR_TIME_X_END(display->width) - width,
+ STATUSBAR_Y_POS, buffer);
+ }
+ display->setfont(FONT_UI);
+
+}
+#endif
+
+#endif /* HAVE_LCD_BITMAP */
+
+void gui_syncstatusbar_init(struct gui_syncstatusbar * bars)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;++i) {
+ gui_statusbar_init( &(bars->statusbars[i]) );
+ gui_statusbar_set_screen( &(bars->statusbars[i]), &(screens[i]) );
+ }
+}
+
+void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars,
+ bool force_redraw)
+{
+ int i;
+ for(i = 0;i < NB_SCREENS;++i) {
+ gui_statusbar_draw( &(bars->statusbars[i]), force_redraw );
+ }
+}
diff --git a/apps/gui/statusbar.h b/apps/gui/statusbar.h
new file mode 100644
index 0000000..434d679
--- /dev/null
+++ b/apps/gui/statusbar.h
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Kévin FERRARE
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef _GUI_STATUSBAR_H_
+#define _GUI_STATUSBAR_H_
+
+#include "config.h"
+#include "status.h"
+
+struct status_info {
+ int battlevel;
+ int volume;
+ int hour;
+ int minute;
+ int playmode;
+ int repeat;
+ bool inserted;
+ bool shuffle;
+ bool keylock;
+ bool battery_safe;
+ bool redraw_volume; /* true if the volume gauge needs updating */
+#if CONFIG_LED == LED_VIRTUAL
+ bool led; /* disk LED simulation in the status bar */
+#endif
+#ifdef HAVE_USB_POWER
+ bool usb_power;
+#endif
+};
+
+struct gui_statusbar
+{
+ /* Volume icon stuffs */
+ long volume_icon_switch_tick;
+ int last_volume;
+
+ long battery_icon_switch_tick;
+
+#ifdef HAVE_CHARGING
+ int battery_charge_step;
+#endif
+
+ struct status_info info;
+ struct status_info lastinfo;
+
+ struct screen * display;
+};
+
+/*
+ * Initializes a status bar
+ * - bar : the bar to initialize
+ */
+extern void gui_statusbar_init(struct gui_statusbar * bar);
+
+/*
+ * Attach the status bar to a screen
+ * (The previous screen attachement is lost)
+ * - bar : the statusbar structure
+ * - display : the screen to attach
+ */
+extern void gui_statusbar_set_screen(struct gui_statusbar * bar, struct screen * display);
+
+/*
+ * Draws the status bar on the attached screen
+ * - bar : the statusbar structure
+ */
+extern void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw);
+
+void gui_statusbar_icon_battery(struct screen * display, int percent);
+bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int percent);
+void gui_statusbar_icon_play_state(struct screen * display, int state);
+void gui_statusbar_icon_play_mode(struct screen * display, int mode);
+void gui_statusbar_icon_shuffle(struct screen * display);
+void gui_statusbar_icon_lock(struct screen * display);
+#if CONFIG_LED == LED_VIRTUAL
+void gui_statusbar_led(struct screen * display);
+#endif
+
+#ifdef HAVE_RTC
+void gui_statusbar_time(struct screen * display, int hour, int minute);
+#endif
+
+
+struct gui_syncstatusbar
+{
+ struct gui_statusbar statusbars[NB_SCREENS];
+};
+
+extern void gui_syncstatusbar_init(struct gui_syncstatusbar * bars);
+extern void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars, bool force_redraw);
+
+#endif /*_GUI_STATUSBAR_H_*/