blob: 53cfd87774ae31c93c20443c1dcec49004608a4e [file] [log] [blame]
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000010 * Copyright (C) 2007 Jonathan Gordon
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +000011 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000021#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include "inttypes.h"
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +000025#include "config.h"
26#include "icon.h"
27#include "screen_access.h"
28#include "icons.h"
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000029#include "settings.h"
30#include "bmp.h"
31#include "filetypes.h"
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +000032
Björn Stenbergac488f82008-11-03 14:37:50 +000033#include "bitmaps/default_icons.h"
Magnus Holmgren392a4ef2007-04-18 17:49:32 +000034#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
Björn Stenbergac488f82008-11-03 14:37:50 +000035#include "bitmaps/remote_default_icons.h"
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000036#endif
37
Jonathan Gordone9610dc2007-04-17 08:37:01 +000038/* These are just the file names, the full path is snprint'ed when used */
Jens Arnoldf87eaf32007-04-17 00:29:04 +000039#define DEFAULT_VIEWER_BMP "viewers"
40#define DEFAULT_REMOTE_VIEWER_BMP "remote_viewers"
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000041
Karl Kurbjunf4511082009-08-18 00:53:27 +000042/* These can be defined in config-<target>.h, if it is not provide defaults */
43#if !defined(MAX_ICON_HEIGHT)
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000044#define MAX_ICON_HEIGHT 24
Karl Kurbjunf4511082009-08-18 00:53:27 +000045#endif
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000046
Karl Kurbjunf4511082009-08-18 00:53:27 +000047#if !defined(MAX_ICON_WIDTH)
48#define MAX_ICON_WIDTH 24
49#endif
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000050
51/* We dont actually do anything with these pointers,
52 but they need to be grouped like this to save code
53 so storing them as void* is ok. (stops compile warning) */
54static const void * inbuilt_icons[NB_SCREENS] = {
55 (void*)default_icons
Magnus Holmgren392a4ef2007-04-18 17:49:32 +000056#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000057 , (void*)remote_default_icons
58#endif
59};
60
61static const int default_width[NB_SCREENS] = {
62 BMPWIDTH_default_icons
Magnus Holmgren392a4ef2007-04-18 17:49:32 +000063#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000064 , BMPWIDTH_remote_default_icons
65#endif
66};
67
68/* height of whole file */
69static const int default_height[NB_SCREENS] = {
70 BMPHEIGHT_default_icons
Magnus Holmgren392a4ef2007-04-18 17:49:32 +000071#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000072 , BMPHEIGHT_remote_default_icons
73#endif
74};
75
76#define IMG_BUFSIZE (MAX_ICON_HEIGHT * MAX_ICON_WIDTH * \
77 Icon_Last_Themeable *LCD_DEPTH/8)
Jonathan Gordona9c1df42007-04-16 14:33:29 +000078static unsigned char icon_buffer[NB_SCREENS][IMG_BUFSIZE];
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000079static bool custom_icons_loaded[NB_SCREENS] = {false};
80static struct bitmap user_iconset[NB_SCREENS];
81
Jonathan Gordona9c1df42007-04-16 14:33:29 +000082static unsigned char viewer_icon_buffer[NB_SCREENS][IMG_BUFSIZE];
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +000083static bool viewer_icons_loaded[NB_SCREENS] = {false};
84static struct bitmap viewer_iconset[NB_SCREENS];
85
86
87#define ICON_HEIGHT(screen) (!custom_icons_loaded[screen]? \
88 default_height[screen] : \
89 user_iconset[screen].height) \
90 / Icon_Last_Themeable
91
92#define ICON_WIDTH(screen) (!custom_icons_loaded[screen]? \
93 default_width[screen] : \
94 user_iconset[screen].width)
95
96/* x,y in letters, not pixles */
97void screen_put_icon(struct screen * display,
98 int x, int y, enum themable_icons icon)
99{
100 screen_put_icon_with_offset(display, x, y, 0, 0, icon);
101}
102
103void screen_put_icon_with_offset(struct screen * display,
104 int x, int y, int off_x, int off_y,
105 enum themable_icons icon)
106{
107 int xpos, ypos;
108 int width, height;
109 int screen = display->screen_type;
110 display->getstringsize((unsigned char *)"M", &width, &height);
111 xpos = x*ICON_WIDTH(screen) + off_x;
Jonathan Gordonbdbdb972008-06-23 13:20:35 +0000112 ypos = y*height + off_y;
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000113
114 if ( height > ICON_HEIGHT(screen) )/* center the cursor */
115 ypos += (height - ICON_HEIGHT(screen)) / 2;
116 screen_put_iconxy(display, xpos, ypos, icon);
117}
118
119/* x,y in pixels */
Jens Arnold539c5132007-04-16 23:55:19 +0000120void screen_put_iconxy(struct screen * display,
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000121 int xpos, int ypos, enum themable_icons icon)
122{
Jens Arnold539c5132007-04-16 23:55:19 +0000123 const void *data;
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000124 int screen = display->screen_type;
Magnus Holmgren62994d42007-04-16 19:17:37 +0000125 int width = ICON_WIDTH(screen);
126 int height = ICON_HEIGHT(screen);
Karl Kurbjun7bb7c5f2009-08-29 19:31:29 +0000127 int stride;
Jens Arnold539c5132007-04-16 23:55:19 +0000128 screen_bitmap_part_func *draw_func = NULL;
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000129
130 if (icon == Icon_NOICON)
131 {
Magnus Holmgren62994d42007-04-16 19:17:37 +0000132 screen_clear_area(display, xpos, ypos, width, height);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000133 return;
134 }
135 else if (icon >= Icon_Last_Themeable)
136 {
137 icon -= Icon_Last_Themeable;
Jonathan Gordonb6658bb2007-04-16 12:50:01 +0000138 if (!viewer_icons_loaded[screen] ||
Jonathan Gordon9d3694c2007-04-22 08:50:24 +0000139 (global_status.viewer_icon_count*height
140 > viewer_iconset[screen].height) ||
Magnus Holmgren62994d42007-04-16 19:17:37 +0000141 (icon * height > viewer_iconset[screen].height))
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000142 {
Jonathan Gordon9d3694c2007-04-22 08:50:24 +0000143 screen_put_iconxy(display, xpos, ypos, Icon_Questionmark);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000144 return;
145 }
Karl Kurbjun7bb7c5f2009-08-29 19:31:29 +0000146 data = viewer_iconset[screen].data;
Karl Kurbjun25123572009-09-04 00:46:24 +0000147 stride = STRIDE( display->screen_type, viewer_iconset[screen].width,
Karl Kurbjun7bb7c5f2009-08-29 19:31:29 +0000148 viewer_iconset[screen].height);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000149 }
150 else if (custom_icons_loaded[screen])
151 {
Karl Kurbjun7bb7c5f2009-08-29 19:31:29 +0000152 data = user_iconset[screen].data;
Karl Kurbjun25123572009-09-04 00:46:24 +0000153 stride = STRIDE( display->screen_type, user_iconset[screen].width,
Karl Kurbjun7bb7c5f2009-08-29 19:31:29 +0000154 user_iconset[screen].height);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000155 }
156 else
157 {
Karl Kurbjun7bb7c5f2009-08-29 19:31:29 +0000158 data = inbuilt_icons[screen];
Karl Kurbjun25123572009-09-04 00:46:24 +0000159 stride = STRIDE( display->screen_type, BMPWIDTH_default_icons,
160 BMPHEIGHT_default_icons);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000161 }
162 /* add some left padding to the icons if they are on the edge */
163 if (xpos == 0)
164 xpos++;
165
Jens Arnoldded87cf2007-04-17 00:08:58 +0000166#if (LCD_DEPTH == 16) || defined(LCD_REMOTE_DEPTH) && (LCD_REMOTE_DEPTH == 16)
Jens Arnold539c5132007-04-16 23:55:19 +0000167 if (display->depth == 16)
Karl Kurbjun7bb7c5f2009-08-29 19:31:29 +0000168 draw_func = display->transparent_bitmap_part;
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000169 else
170#endif
Karl Kurbjun7bb7c5f2009-08-29 19:31:29 +0000171 draw_func = display->bitmap_part;
Jens Arnold539c5132007-04-16 23:55:19 +0000172
Karl Kurbjun7bb7c5f2009-08-29 19:31:29 +0000173 draw_func(data, 0, height * icon, stride, xpos, ypos, width, height);
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000174}
175
Kevin Ferrare8517ed82005-11-16 02:12:25 +0000176void screen_put_cursorxy(struct screen * display, int x, int y, bool on)
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000177{
178#ifdef HAVE_LCD_BITMAP
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000179 screen_put_icon(display, x, y, on?Icon_Cursor:0);
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000180#else
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000181 screen_put_icon(display, x, y, on?CURSOR_CHAR:-1);
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000182#endif
Kevin Ferrare8517ed82005-11-16 02:12:25 +0000183
Linus Nielsen Feltzing7da94772005-10-28 00:00:00 +0000184}
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000185enum Iconset {
186 Iconset_Mainscreen,
187 Iconset_Mainscreen_viewers,
Magnus Holmgren392a4ef2007-04-18 17:49:32 +0000188#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000189 Iconset_Remotescreen,
190 Iconset_Remotescreen_viewers,
191#endif
192};
193
Magnus Holmgren62994d42007-04-16 19:17:37 +0000194static void load_icons(const char* filename, enum Iconset iconset,
195 bool allow_disable)
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000196{
197 int size_read;
198 bool *loaded_ok = NULL;
199 struct bitmap *bmp = NULL;
Jens Arnold79a8b412007-04-17 01:03:25 +0000200 int bmpformat = (FORMAT_NATIVE|FORMAT_DITHER);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000201
202 switch (iconset)
203 {
204 case Iconset_Mainscreen:
205 loaded_ok = &custom_icons_loaded[SCREEN_MAIN];
206 bmp = &user_iconset[SCREEN_MAIN];
207 bmp->data = icon_buffer[SCREEN_MAIN];
208 break;
209 case Iconset_Mainscreen_viewers:
210 loaded_ok = &viewer_icons_loaded[SCREEN_MAIN];
211 bmp = &viewer_iconset[SCREEN_MAIN];
212 bmp->data = viewer_icon_buffer[SCREEN_MAIN];
213 break;
Magnus Holmgren392a4ef2007-04-18 17:49:32 +0000214#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000215 case Iconset_Remotescreen:
Jonathan Gordonccaf24a2007-04-16 11:01:41 +0000216 loaded_ok = &custom_icons_loaded[SCREEN_REMOTE];
217 bmp = &user_iconset[SCREEN_REMOTE];
218 bmp->data = icon_buffer[SCREEN_REMOTE];
Jens Arnold79a8b412007-04-17 01:03:25 +0000219 bmpformat |= FORMAT_REMOTE;
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000220 break;
221 case Iconset_Remotescreen_viewers:
222 loaded_ok = &viewer_icons_loaded[SCREEN_REMOTE];
223 bmp = &viewer_iconset[SCREEN_REMOTE];
224 bmp->data = viewer_icon_buffer[SCREEN_REMOTE];
Jens Arnold79a8b412007-04-17 01:03:25 +0000225 bmpformat |= FORMAT_REMOTE;
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000226 break;
227#endif
228 }
229
230 *loaded_ok = false;
Jonathan Gordon754d9192007-04-17 06:37:22 +0000231 if (!allow_disable || (filename[0] && filename[0] != '-'))
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000232 {
Magnus Holmgren62994d42007-04-16 19:17:37 +0000233 char path[MAX_PATH];
234
235 snprintf(path, sizeof(path), "%s/%s.bmp", ICON_DIR, filename);
Andrew Mahone90586202008-12-26 07:05:13 +0000236 size_read = read_bmp_file(path, bmp, IMG_BUFSIZE, bmpformat, NULL);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000237 if (size_read > 0)
238 {
239 *loaded_ok = true;
240 }
241 }
242}
243
244
245void icons_init(void)
246{
Magnus Holmgren62994d42007-04-16 19:17:37 +0000247 load_icons(global_settings.icon_file, Iconset_Mainscreen, true);
248
249 if (*global_settings.viewers_icon_file)
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000250 {
Magnus Holmgren62994d42007-04-16 19:17:37 +0000251 load_icons(global_settings.viewers_icon_file,
252 Iconset_Mainscreen_viewers, true);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000253 read_viewer_theme_file();
254 }
255 else
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000256 {
Magnus Holmgren62994d42007-04-16 19:17:37 +0000257 load_icons(DEFAULT_VIEWER_BMP, Iconset_Mainscreen_viewers, false);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000258 }
Magnus Holmgren62994d42007-04-16 19:17:37 +0000259
Magnus Holmgren392a4ef2007-04-18 17:49:32 +0000260#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
Magnus Holmgren62994d42007-04-16 19:17:37 +0000261 load_icons(global_settings.remote_icon_file,
262 Iconset_Remotescreen, true);
263
264 if (*global_settings.remote_viewers_icon_file)
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000265 {
Magnus Holmgren62994d42007-04-16 19:17:37 +0000266 load_icons(global_settings.remote_viewers_icon_file,
267 Iconset_Remotescreen_viewers, true);
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000268 }
269 else
Magnus Holmgren62994d42007-04-16 19:17:37 +0000270 {
271 load_icons(DEFAULT_REMOTE_VIEWER_BMP,
272 Iconset_Remotescreen_viewers, false);
273 }
Jonathan Gordon6a5cc0b2007-04-16 09:14:36 +0000274#endif
275}
276
277int get_icon_width(enum screen_type screen_type)
278{
279 return ICON_WIDTH(screen_type);
280}