A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 253 lines 7.6 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2007 Jonathan Gordon 11 * 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. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24#include "inttypes.h" 25#include "config.h" 26#include "core_alloc.h" 27#include "icon.h" 28#include "screen_access.h" 29#include "icons.h" 30#include "settings.h" 31#include "rbpaths.h" 32#include "bmp.h" 33#include "filetypes.h" 34#include "language.h" 35#include "misc.h" 36 37#include "bitmaps/default_icons.h" 38#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) 39#include "bitmaps/remote_default_icons.h" 40#endif 41 42/* We dont actually do anything with these pointers, 43 but they need to be grouped like this to save code 44 so storing them as void* is ok. (stops compile warning) */ 45static const struct bitmap *inbuilt_iconset[NB_SCREENS] = 46{ 47 &bm_default_icons, 48#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) 49 &bm_remote_default_icons, 50#endif 51}; 52 53enum Iconset { 54 Iconset_user, 55 Iconset_viewers, 56 Iconset_Count 57}; 58 59static struct iconset { 60 struct bitmap bmp; 61 bool loaded; 62 int handle; 63} iconsets[Iconset_Count][NB_SCREENS]; 64 65#define ICON_HEIGHT(screen) (!iconsets[Iconset_user][screen].loaded ? \ 66 (*(inbuilt_iconset[screen])) : iconsets[Iconset_user][screen].bmp).height \ 67 / Icon_Last_Themeable 68 69#define ICON_WIDTH(screen) (!iconsets[Iconset_user][screen].loaded ? \ 70 (*(inbuilt_iconset[screen])) : iconsets[Iconset_user][screen].bmp).width 71 72/* x,y in letters, not pixles */ 73void screen_put_icon(struct screen * display, 74 int x, int y, enum themable_icons icon) 75{ 76 screen_put_icon_with_offset(display, x, y, 0, 0, icon); 77} 78 79void screen_put_icon_with_offset(struct screen * display, 80 int x, int y, int off_x, int off_y, 81 enum themable_icons icon) 82{ 83 const int screen = display->screen_type; 84 const int icon_width = ICON_WIDTH(screen); 85 const int icon_height = ICON_HEIGHT(screen); 86 int xpos, ypos; 87 int width, height; 88 display->getstringsize((unsigned char *)"M", &width, &height); 89 xpos = x*icon_width + off_x; 90 ypos = y*height + off_y; 91 92 if ( height > icon_height )/* center the cursor */ 93 ypos += (height - icon_height) / 2; 94 screen_put_iconxy(display, xpos, ypos, icon); 95} 96 97/* x,y in pixels */ 98void screen_put_iconxy(struct screen * display, 99 int xpos, int ypos, enum themable_icons icon) 100{ 101 const int screen = display->screen_type; 102 const int width = ICON_WIDTH(screen); 103 const int height = ICON_HEIGHT(screen); 104 const int is_rtl = lang_is_rtl(); 105 const struct bitmap *iconset; 106 107 if (icon <= Icon_NOICON) 108 { 109 if (is_rtl) 110 xpos = display->getwidth() - xpos - width; 111 screen_clear_area(display, xpos, ypos, width, height); 112 return; 113 } 114 else if (icon >= Icon_Last_Themeable) 115 { 116 iconset = &iconsets[Iconset_viewers][screen].bmp; 117 icon -= Icon_Last_Themeable; 118 if (!iconsets[Iconset_viewers][screen].loaded || 119 (global_status.viewer_icon_count * height > iconset->height) || 120 (icon * height + height > iconset->height)) 121 { 122 screen_put_iconxy(display, xpos, ypos, Icon_Questionmark); 123 return; 124 } 125 } 126 else if (iconsets[Iconset_user][screen].loaded) 127 { 128 iconset = &iconsets[Iconset_user][screen].bmp; 129 } 130 else 131 { 132 iconset = inbuilt_iconset[screen]; 133 } 134 135 if (is_rtl) 136 xpos = display->getwidth() - xpos - width; 137 138 139 display->bmp_part(iconset, 0, height * icon, xpos, ypos, width, height); 140} 141 142void screen_put_cursorxy(struct screen * display, int x, int y, bool on) 143{ 144 screen_put_icon(display, x, y, on?Icon_Cursor:0); 145} 146 147static int buflib_move_callback(int handle, void* current, void* new) 148{ 149 (void)handle; 150 (void)new; 151 int i; 152 FOR_NB_SCREENS(j) 153 { 154 for (i=0; i<Iconset_Count; i++) 155 { 156 struct iconset *set = &iconsets[i][j]; 157 if (set->bmp.data == current) 158 { 159 set->bmp.data = new; 160 return BUFLIB_CB_OK; 161 } 162 } 163 } 164 return BUFLIB_CB_OK; 165} 166 167static void load_icons(const char* filename, enum Iconset iconset, 168 enum screen_type screen) 169{ 170 static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL}; 171 const int bmpformat = (FORMAT_ANY|FORMAT_DITHER|FORMAT_TRANSPARENT); 172 struct iconset *ic = &iconsets[iconset][screen]; 173 ssize_t buf_reqd; 174 175 ic->loaded = false; 176 ic->handle = CLB_ALOC_ERR; 177 if (filename[0] && filename[0] != '-') 178 { 179 char fname[MAX_PATH]; 180 snprintf(fname, sizeof(fname), ICON_DIR "/%s.bmp", filename); 181 ic->handle = core_load_bmp(fname, &ic->bmp, bmpformat, &buf_reqd, &buflib_ops); 182 if (ic->handle != CLB_ALOC_ERR) 183 { 184 ic->bmp.data = core_get_data(ic->handle); 185 ic->loaded = true; 186 } 187 } 188} 189 190void icons_init(void) 191{ 192 int i; 193 FOR_NB_SCREENS(j) 194 { 195 for (i=0; i<Iconset_Count; i++) 196 { 197 struct iconset* set = &iconsets[i][j]; 198 if (set->loaded && set->handle > 0) 199 { 200 set->handle = core_free(set->handle); 201 set->loaded = false; 202 } 203 } 204 } 205 206 if (global_settings.show_icons) 207 { 208 load_icons(global_settings.icon_file, Iconset_user, SCREEN_MAIN); 209 210 if (global_settings.viewers_icon_file[0] != '-' && 211 global_settings.viewers_icon_file[0] != '\0') 212 { 213 load_icons(global_settings.viewers_icon_file, 214 Iconset_viewers, SCREEN_MAIN); 215 read_viewer_theme_file(); 216 } 217#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) 218 load_icons(global_settings.remote_icon_file, 219 Iconset_user, SCREEN_REMOTE); 220 221 if (global_settings.remote_viewers_icon_file[0] != '-' && 222 global_settings.remote_viewers_icon_file[0] != '\0') 223 { 224 load_icons(global_settings.remote_viewers_icon_file, 225 Iconset_viewers, SCREEN_REMOTE); 226 } 227#endif 228 } 229} 230 231int get_icon_width(enum screen_type screen_type) 232{ 233 return ICON_WIDTH(screen_type); 234} 235 236int get_icon_height(enum screen_type screen_type) 237{ 238 return ICON_HEIGHT(screen_type); 239} 240 241#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) 242int get_icon_format(enum screen_type screen) 243{ 244 const struct bitmap *iconset; 245 246 if (iconsets[Iconset_user][screen].loaded) 247 iconset = &iconsets[Iconset_user][screen].bmp; 248 else 249 iconset = inbuilt_iconset[screen]; 250 251 return iconset->format; 252} 253#endif