/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2010 Jonathan Gordon * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "config.h" #include #include #include "core_alloc.h" #include "string-extra.h" #include "settings.h" #include "wps_internals.h" #include "skin_engine.h" #if !defined(__PCTOOL__) && defined(HAVE_BACKDROP_IMAGE) #define NB_BDROPS SKINNABLE_SCREENS_COUNT*NB_SCREENS static struct skin_backdrop { char name[MAX_PATH]; char *buffer; enum screen_type screen; bool loaded; int buflib_handle; int ref_count; } backdrops[NB_BDROPS]; #define NB_BDROPS SKINNABLE_SCREENS_COUNT*NB_SCREENS static int handle_being_loaded; static int current_lcd_backdrop[NB_SCREENS]; bool skin_backdrop_get_debug(int index, char **path, int *ref_count, size_t *size) { if (index + 1 >= NB_BDROPS) return false; *path = backdrops[index].name; *ref_count = backdrops[index].ref_count; #if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) enum screen_type screen = backdrops[index].screen; if (screen == SCREEN_REMOTE) *size = REMOTE_LCD_BACKDROP_BYTES; else #endif *size = LCD_BACKDROP_BYTES; return true; } static int buflib_move_callback(int handle, void* current, void* new) { if (handle == handle_being_loaded) return BUFLIB_CB_CANNOT_MOVE; for (int i=0; i= 0) { strlcpy(backdrops[free].name, filename, MAX_PATH); backdrops[free].buffer = NULL; backdrops[free].screen = screen; backdrops[free].ref_count = 1; return free; } else if (i < NB_BDROPS) return i; return -1; } bool skin_backdrops_preload(void) { bool retval = true; int i; char *filename; for (i=0; i 1) if (screen == SCREEN_REMOTE) buf_size = REMOTE_LCD_BACKDROP_BYTES; else #endif buf_size = LCD_BACKDROP_BYTES; filename = backdrops[i].name; if (screen == SCREEN_MAIN && global_settings.backdrop_file[0] && global_settings.backdrop_file[0] != '-' && filename[0] == '-') { filename = global_settings.backdrop_file; } if (*filename && *filename != '-') { backdrops[i].buflib_handle = core_alloc_ex(filename, buf_size, &buflib_ops); if (backdrops[i].buflib_handle > 0) { backdrops[i].buffer = core_get_data(backdrops[i].buflib_handle); if (strcmp(filename, BACKDROP_BUFFERNAME)) { handle_being_loaded = backdrops[i].buflib_handle; backdrops[i].loaded = screens[screen].backdrop_load(filename, backdrops[i].buffer); if (!backdrops[i].loaded) { core_free(backdrops[i].buflib_handle); backdrops[i].buflib_handle = -1; retval = false; } handle_being_loaded = -1; } else backdrops[i].loaded = true; } else retval = false; } if (backdrops[i].name[0] == '-' && backdrops[i].loaded) backdrops[i].name[2] = '.'; } } return retval; } void skin_backdrop_set_buffer(int backdrop_id, struct skin_viewport *svp) { if (UNLIKELY(!svp)) return; else if (backdrop_id < 0) { #if 1 /* ensure the current vp has been removed so it has to be reselected */ screens[SCREEN_MAIN].set_viewport_ex(NULL, 0); # if defined(HAVE_REMOTE_LCD) screens[SCREEN_REMOTE].set_viewport_ex(NULL, 0); # endif #endif /* WARNING: vp-> buffer is invaid till viewport is set to a screen */ svp->vp.buffer = NULL; /*Default*/ return; } enum screen_type screen = backdrops[backdrop_id].screen; svp->framebuf.ch_ptr = backdrops[backdrop_id].buffer; #if defined(HAVE_REMOTE_LCD) if (screen == SCREEN_REMOTE) svp->framebuf.elems = REMOTE_LCD_BACKDROP_BYTES / sizeof(fb_remote_data); else #endif { svp->framebuf.elems = LCD_BACKDROP_BYTES / sizeof(fb_data); } svp->framebuf.stride = 0; /* default stride */ svp->framebuf.get_address_fn = NULL; /*Default iterator*/ screens[screen].viewport_set_buffer(&svp->vp, &svp->framebuf); } void skin_backdrop_show(int backdrop_id) { if (backdrop_id < 0) { screens[0].backdrop_show(NULL); current_lcd_backdrop[0] = -1; return; } enum screen_type screen = backdrops[backdrop_id].screen; if ((backdrops[backdrop_id].loaded == false) || (backdrops[backdrop_id].name[0] == '-' && backdrops[backdrop_id].name[2] == '\0')) { screens[screen].backdrop_show(NULL); current_lcd_backdrop[screen] = -1; } else if (backdrops[backdrop_id].buffer) { screens[screen].backdrop_show(backdrops[backdrop_id].buffer); current_lcd_backdrop[screen] = backdrop_id; } } void skin_backdrop_unload(int backdrop_id) { backdrops[backdrop_id].ref_count--; if (backdrops[backdrop_id].ref_count <= 0) { if (backdrops[backdrop_id].buflib_handle > 0) core_free(backdrops[backdrop_id].buflib_handle); backdrops[backdrop_id].buffer = NULL; backdrops[backdrop_id].buflib_handle = -1; backdrops[backdrop_id].loaded = false; backdrops[backdrop_id].name[0] = '\0'; backdrops[backdrop_id].ref_count = 0; } } void skin_backdrop_load_setting(void) { int i; for(i=0;i 1 else if (backdrops[i].name[0] == '-') { backdrops[i].name[2] = '\0'; return; } #endif } } #elif defined(__PCTOOL__) int skin_backdrop_assign(char* backdrop, char *bmpdir, enum screen_type screen) { (void)backdrop; (void)bmpdir; (void)screen; return 0; } void skin_backdrop_unload(int backdrop_id) { (void)backdrop_id; } #else void skin_backdrop_init(void) { } #endif