skin tags: fix the id3 track/disc numbers in conditionals
[maemo-rb.git] / apps / gui / icon.c
blobf37cee969cf0d6e694c8e487de6ddd27711959d8
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 Jonathan Gordon
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
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 "bmp.h"
32 #include "filetypes.h"
33 #include "language.h"
35 #include "bitmaps/default_icons.h"
36 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
37 #include "bitmaps/remote_default_icons.h"
38 #endif
40 /* These are just the file names, the full path is snprint'ed when used */
41 #define DEFAULT_VIEWER_BMP "viewers"
42 #define DEFAULT_REMOTE_VIEWER_BMP "remote_viewers"
44 /* We dont actually do anything with these pointers,
45 but they need to be grouped like this to save code
46 so storing them as void* is ok. (stops compile warning) */
47 static const struct bitmap *inbuilt_iconset[NB_SCREENS] =
49 &bm_default_icons,
50 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
51 &bm_remote_default_icons,
52 #endif
55 enum Iconset {
56 Iconset_user,
57 Iconset_viewers,
58 Iconset_Count
61 static struct iconset {
62 struct bitmap bmp;
63 bool loaded;
64 int handle;
65 int handle_locked;
66 } iconsets[Iconset_Count][NB_SCREENS];
68 #define ICON_HEIGHT(screen) (!iconsets[Iconset_user][screen].loaded ? \
69 (*(inbuilt_iconset[screen])) : iconsets[Iconset_user][screen].bmp).height \
70 / Icon_Last_Themeable
72 #define ICON_WIDTH(screen) (!iconsets[Iconset_user][screen].loaded ? \
73 (*(inbuilt_iconset[screen])) : iconsets[Iconset_user][screen].bmp).width
75 /* x,y in letters, not pixles */
76 void screen_put_icon(struct screen * display,
77 int x, int y, enum themable_icons icon)
79 screen_put_icon_with_offset(display, x, y, 0, 0, icon);
82 void screen_put_icon_with_offset(struct screen * display,
83 int x, int y, int off_x, int off_y,
84 enum themable_icons icon)
86 const int screen = display->screen_type;
87 const int icon_width = ICON_WIDTH(screen);
88 const int icon_height = ICON_HEIGHT(screen);
89 int xpos, ypos;
90 int width, height;
91 display->getstringsize((unsigned char *)"M", &width, &height);
92 xpos = x*icon_width + off_x;
93 ypos = y*height + off_y;
95 if ( height > icon_height )/* center the cursor */
96 ypos += (height - icon_height) / 2;
97 screen_put_iconxy(display, xpos, ypos, icon);
100 /* x,y in pixels */
101 void screen_put_iconxy(struct screen * display,
102 int xpos, int ypos, enum themable_icons icon)
104 const int screen = display->screen_type;
105 const int width = ICON_WIDTH(screen);
106 const int height = ICON_HEIGHT(screen);
107 const int is_rtl = lang_is_rtl();
108 const struct bitmap *iconset;
110 if (icon == Icon_NOICON)
112 if (is_rtl)
113 xpos = display->getwidth() - xpos - width;
114 screen_clear_area(display, xpos, ypos, width, height);
115 return;
117 else if (icon >= Icon_Last_Themeable)
119 iconset = &iconsets[Iconset_viewers][screen].bmp;
120 icon -= Icon_Last_Themeable;
121 if (!iconsets[Iconset_viewers][screen].loaded ||
122 (global_status.viewer_icon_count * height > iconset->height) ||
123 (icon * height + height > iconset->height))
125 screen_put_iconxy(display, xpos, ypos, Icon_Questionmark);
126 return;
129 else if (iconsets[Iconset_user][screen].loaded)
131 iconset = &iconsets[Iconset_user][screen].bmp;
133 else
135 iconset = inbuilt_iconset[screen];
137 /* add some left padding to the icons if they are on the edge */
138 if (xpos == 0)
139 xpos++;
141 if (is_rtl)
142 xpos = display->getwidth() - xpos - width;
145 display->bmp_part(iconset, 0, height * icon, xpos, ypos, width, height);
148 void screen_put_cursorxy(struct screen * display, int x, int y, bool on)
150 #ifdef HAVE_LCD_BITMAP
151 screen_put_icon(display, x, y, on?Icon_Cursor:0);
152 #else
153 screen_put_icon(display, x, y, on?CURSOR_CHAR:-1);
154 #endif
157 static int buflib_move_callback(int handle, void* current, void* new)
159 (void)handle;
160 (void)new;
161 int i;
162 FOR_NB_SCREENS(j)
164 for (i=0; i<Iconset_Count; i++)
166 struct iconset *set = &iconsets[i][j];
167 if (set->bmp.data == current)
169 if (set->handle_locked > 0)
170 return BUFLIB_CB_CANNOT_MOVE;
171 set->bmp.data = new;
172 return BUFLIB_CB_OK;
176 return BUFLIB_CB_OK;
178 static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL};
180 static void load_icons(const char* filename, enum Iconset iconset,
181 enum screen_type screen)
183 int size_read;
184 int bmpformat = (FORMAT_NATIVE|FORMAT_DITHER|FORMAT_TRANSPARENT);
185 struct iconset *ic = &iconsets[iconset][screen];
186 int fd;
188 ic->loaded = false;
189 if (filename[0] && filename[0] != '-')
191 char path[MAX_PATH];
193 snprintf(path, sizeof(path), ICON_DIR "/%s.bmp", filename);
194 fd = open(path, O_RDONLY);
195 if (fd < 0)
196 return;
197 size_t buf_size = read_bmp_fd(fd, &ic->bmp, 0,
198 bmpformat|FORMAT_RETURN_SIZE, NULL);
199 ic->handle = core_alloc_ex(filename, buf_size, &buflib_ops);
200 if (ic->handle <= 0)
202 close(fd);
203 return;
205 lseek(fd, 0, SEEK_SET);
206 ic->bmp.data = core_get_data(ic->handle);
208 ic->handle_locked = 1;
209 size_read = read_bmp_fd(fd, &ic->bmp, buf_size, bmpformat, NULL);
210 close(fd);
211 ic->handle_locked = 0;
213 /* free unused alpha channel, if any */
214 core_shrink(ic->handle, ic->bmp.data, size_read);
216 if (size_read <= 0)
217 ic->handle = core_free(ic->handle);
218 else
219 ic->loaded = true;
223 void icons_init(void)
225 int i;
226 FOR_NB_SCREENS(j)
228 for (i=0; i<Iconset_Count; i++)
230 struct iconset* set = &iconsets[i][j];
231 if (set->loaded && set->handle > 0)
233 set->handle = core_free(set->handle);
234 set->loaded = false;
239 if (global_settings.show_icons)
241 load_icons(global_settings.icon_file, Iconset_user, SCREEN_MAIN);
243 if (global_settings.viewers_icon_file[0] &&
244 global_settings.viewers_icon_file[0] != '-')
246 load_icons(global_settings.viewers_icon_file,
247 Iconset_viewers, SCREEN_MAIN);
248 read_viewer_theme_file();
250 else
252 load_icons(DEFAULT_VIEWER_BMP, Iconset_viewers, SCREEN_MAIN);
255 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
256 load_icons(global_settings.remote_icon_file,
257 Iconset_user, SCREEN_REMOTE);
259 if (global_settings.remote_viewers_icon_file[0] &&
260 global_settings.remote_viewers_icon_file[0] != '-')
262 load_icons(global_settings.remote_viewers_icon_file,
263 Iconset_viewers, SCREEN_REMOTE);
265 else
267 load_icons(DEFAULT_REMOTE_VIEWER_BMP,
268 Iconset_viewers, SCREEN_REMOTE);
270 #endif
274 int get_icon_width(enum screen_type screen_type)
276 return ICON_WIDTH(screen_type);
279 int get_icon_height(enum screen_type screen_type)
281 return ICON_HEIGHT(screen_type);