/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2007 Jonathan Gordon * * 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 #include #include #include "inttypes.h" #include "config.h" #include "icon.h" #include "screen_access.h" #include "icons.h" #include "settings.h" #include "bmp.h" #include "filetypes.h" /* Quick and Dirty hack untill lcd bitmap drawing is fixed */ #ifdef HAVE_REMOTE_LCD #include "lcd-remote.h" #endif #include #ifdef HAVE_REMOTE_LCD #include #endif #define DEFAULT_VIEWER_BMP "/viewers.bmp" #define DEFAULT_REMOTE_VIEWER_BMP "/remote_viewers.bmp" /* These should probably be moved to config-.h */ #define MAX_ICON_HEIGHT 24 #define MAX_ICON_WIDTH 24 /* We dont actually do anything with these pointers, but they need to be grouped like this to save code so storing them as void* is ok. (stops compile warning) */ static const void * inbuilt_icons[NB_SCREENS] = { (void*)default_icons #ifdef HAVE_REMOTE_LCD , (void*)remote_default_icons #endif }; static const int default_width[NB_SCREENS] = { BMPWIDTH_default_icons #ifdef HAVE_REMOTE_LCD , BMPWIDTH_remote_default_icons #endif }; /* height of whole file */ static const int default_height[NB_SCREENS] = { BMPHEIGHT_default_icons #ifdef HAVE_REMOTE_LCD , BMPHEIGHT_remote_default_icons #endif }; #define IMG_BUFSIZE (MAX_ICON_HEIGHT * MAX_ICON_WIDTH * \ Icon_Last_Themeable *LCD_DEPTH/8) static unsigned char icon_buffer[NB_SCREENS][IMG_BUFSIZE]; static bool custom_icons_loaded[NB_SCREENS] = {false}; static struct bitmap user_iconset[NB_SCREENS]; static unsigned char viewer_icon_buffer[NB_SCREENS][IMG_BUFSIZE]; static bool viewer_icons_loaded[NB_SCREENS] = {false}; static struct bitmap viewer_iconset[NB_SCREENS]; #define ICON_HEIGHT(screen) (!custom_icons_loaded[screen]? \ default_height[screen] : \ user_iconset[screen].height) \ / Icon_Last_Themeable #define ICON_WIDTH(screen) (!custom_icons_loaded[screen]? \ default_width[screen] : \ user_iconset[screen].width) /* x,y in letters, not pixles */ void screen_put_icon(struct screen * display, int x, int y, enum themable_icons icon) { screen_put_icon_with_offset(display, x, y, 0, 0, icon); } void screen_put_icon_with_offset(struct screen * display, int x, int y, int off_x, int off_y, enum themable_icons icon) { int xpos, ypos; int width, height; int screen = display->screen_type; display->getstringsize((unsigned char *)"M", &width, &height); xpos = x*ICON_WIDTH(screen) + off_x; ypos = y*height + display->getymargin() + off_y; if ( height > ICON_HEIGHT(screen) )/* center the cursor */ ypos += (height - ICON_HEIGHT(screen)) / 2; screen_put_iconxy(display, xpos, ypos, icon); } /* x,y in pixels */ typedef void (*lcd_draw_func)(const fb_data *src, int src_x, int src_y, int stride, int x, int y, int width, int height); void screen_put_iconxy(struct screen * display, int xpos, int ypos, enum themable_icons icon) { fb_data *data; int screen = display->screen_type; int width = ICON_WIDTH(screen); int height = ICON_HEIGHT(screen); lcd_draw_func draw_func = NULL; if (icon == Icon_NOICON) { screen_clear_area(display, xpos, ypos, width, height); return; } else if (icon >= Icon_Last_Themeable) { icon -= Icon_Last_Themeable; if (!viewer_icons_loaded[screen] || (icon * height > viewer_iconset[screen].height)) { #ifdef HAVE_REMOTE_LCD if (screen == SCREEN_REMOTE) { screen_put_iconxy(display, xpos, ypos, Icon_Questionmark); return; } #endif screen_clear_area(display, xpos, ypos, width, height); return; } data = (fb_data *)viewer_iconset[screen].data; } else if (custom_icons_loaded[screen]) { data = (fb_data *)user_iconset[screen].data; } else { data = (fb_data *)inbuilt_icons[screen]; } /* add some left padding to the icons if they are on the edge */ if (xpos == 0) xpos++; #ifdef HAVE_REMOTE_LCD if (display->screen_type == SCREEN_REMOTE) { /* Quick and Dirty hack untill lcd bitmap drawing is fixed */ draw_func = (lcd_draw_func)lcd_remote_bitmap_part; } else #endif #if LCD_DEPTH == 16 draw_func = display->transparent_bitmap_part; #else /* LCD_DEPTH < 16 */ draw_func = display->bitmap_part; #endif /* LCD_DEPTH == 16 */ draw_func( (const fb_data *)data, 0, height * icon, width, xpos, ypos, width, height); } void screen_put_cursorxy(struct screen * display, int x, int y, bool on) { #ifdef HAVE_LCD_BITMAP screen_put_icon(display, x, y, on?Icon_Cursor:0); #else screen_put_icon(display, x, y, on?CURSOR_CHAR:-1); #endif } enum Iconset { Iconset_Mainscreen, Iconset_Mainscreen_viewers, #ifdef HAVE_REMOTE_LCD Iconset_Remotescreen, Iconset_Remotescreen_viewers, #endif }; static void load_icons(const char* filename, enum Iconset iconset, bool allow_disable) { int size_read; bool *loaded_ok = NULL; struct bitmap *bmp = NULL; if (!(*filename)) { return; } switch (iconset) { case Iconset_Mainscreen: loaded_ok = &custom_icons_loaded[SCREEN_MAIN]; bmp = &user_iconset[SCREEN_MAIN]; bmp->data = icon_buffer[SCREEN_MAIN]; break; case Iconset_Mainscreen_viewers: loaded_ok = &viewer_icons_loaded[SCREEN_MAIN]; bmp = &viewer_iconset[SCREEN_MAIN]; bmp->data = viewer_icon_buffer[SCREEN_MAIN]; break; #ifdef HAVE_REMOTE_LCD case Iconset_Remotescreen: loaded_ok = &custom_icons_loaded[SCREEN_REMOTE]; bmp = &user_iconset[SCREEN_REMOTE]; bmp->data = icon_buffer[SCREEN_REMOTE]; break; case Iconset_Remotescreen_viewers: loaded_ok = &viewer_icons_loaded[SCREEN_REMOTE]; bmp = &viewer_iconset[SCREEN_REMOTE]; bmp->data = viewer_icon_buffer[SCREEN_REMOTE]; break; #endif } *loaded_ok = false; if (!allow_disable || *filename != '-') { char path[MAX_PATH]; snprintf(path, sizeof(path), "%s/%s.bmp", ICON_DIR, filename); size_read = read_bmp_file(path, bmp, IMG_BUFSIZE, FORMAT_NATIVE | FORMAT_DITHER); if (size_read > 0) { *loaded_ok = true; } } } void icons_init(void) { load_icons(global_settings.icon_file, Iconset_Mainscreen, true); if (*global_settings.viewers_icon_file) { load_icons(global_settings.viewers_icon_file, Iconset_Mainscreen_viewers, true); read_viewer_theme_file(); } else { load_icons(DEFAULT_VIEWER_BMP, Iconset_Mainscreen_viewers, false); } #ifdef HAVE_REMOTE_LCD load_icons(global_settings.remote_icon_file, Iconset_Remotescreen, true); if (*global_settings.remote_viewers_icon_file) { load_icons(global_settings.remote_viewers_icon_file, Iconset_Remotescreen_viewers, true); } else { load_icons(DEFAULT_REMOTE_VIEWER_BMP, Iconset_Remotescreen_viewers, false); } #endif } int get_icon_width(enum screen_type screen_type) { return ICON_WIDTH(screen_type); }