diff options
-rw-r--r-- | apps/gui/icon.c | 162 | ||||
-rw-r--r-- | firmware/export/config/mrobe500.h | 3 |
2 files changed, 86 insertions, 79 deletions
diff --git a/apps/gui/icon.c b/apps/gui/icon.c index 87ea0718fb..284e1979a0 100644 --- a/apps/gui/icon.c +++ b/apps/gui/icon.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <string.h> | 23 | #include <string.h> |
24 | #include "inttypes.h" | 24 | #include "inttypes.h" |
25 | #include "config.h" | 25 | #include "config.h" |
26 | #include "core_alloc.h" | ||
26 | #include "icon.h" | 27 | #include "icon.h" |
27 | #include "screen_access.h" | 28 | #include "screen_access.h" |
28 | #include "icons.h" | 29 | #include "icons.h" |
@@ -40,15 +41,6 @@ | |||
40 | #define DEFAULT_VIEWER_BMP "viewers" | 41 | #define DEFAULT_VIEWER_BMP "viewers" |
41 | #define DEFAULT_REMOTE_VIEWER_BMP "remote_viewers" | 42 | #define DEFAULT_REMOTE_VIEWER_BMP "remote_viewers" |
42 | 43 | ||
43 | /* These can be defined in config-<target>.h, if it is not provide defaults */ | ||
44 | #if !defined(MAX_ICON_HEIGHT) | ||
45 | #define MAX_ICON_HEIGHT 24 | ||
46 | #endif | ||
47 | |||
48 | #if !defined(MAX_ICON_WIDTH) | ||
49 | #define MAX_ICON_WIDTH 24 | ||
50 | #endif | ||
51 | |||
52 | /* We dont actually do anything with these pointers, | 44 | /* We dont actually do anything with these pointers, |
53 | but they need to be grouped like this to save code | 45 | but they need to be grouped like this to save code |
54 | so storing them as void* is ok. (stops compile warning) */ | 46 | so storing them as void* is ok. (stops compile warning) */ |
@@ -68,23 +60,25 @@ static const struct bitmap inbuilt_iconset[NB_SCREENS] = | |||
68 | #endif | 60 | #endif |
69 | }; | 61 | }; |
70 | 62 | ||
71 | #define IMG_BUFSIZE (MAX_ICON_HEIGHT * MAX_ICON_WIDTH * \ | 63 | enum Iconset { |
72 | Icon_Last_Themeable *LCD_DEPTH/8) | 64 | Iconset_user, |
73 | static unsigned char icon_buffer[NB_SCREENS][IMG_BUFSIZE]; | 65 | Iconset_viewers, |
74 | static bool custom_icons_loaded[NB_SCREENS] = {false}; | 66 | Iconset_Count |
75 | static struct bitmap user_iconset[NB_SCREENS]; | 67 | }; |
76 | |||
77 | static unsigned char viewer_icon_buffer[NB_SCREENS][IMG_BUFSIZE]; | ||
78 | static bool viewer_icons_loaded[NB_SCREENS] = {false}; | ||
79 | static struct bitmap viewer_iconset[NB_SCREENS]; | ||
80 | 68 | ||
69 | struct iconset { | ||
70 | struct bitmap bmp; | ||
71 | bool loaded; | ||
72 | int handle; | ||
73 | int handle_locked; | ||
74 | } iconsets[Iconset_Count][NB_SCREENS]; | ||
81 | 75 | ||
82 | #define ICON_HEIGHT(screen) (!custom_icons_loaded[screen]? \ | 76 | #define ICON_HEIGHT(screen) (!iconsets[Iconset_user][screen].loaded ? \ |
83 | inbuilt_iconset : user_iconset)[screen].height \ | 77 | inbuilt_iconset[screen] : iconsets[Iconset_user][screen].bmp).height \ |
84 | / Icon_Last_Themeable | 78 | / Icon_Last_Themeable |
85 | 79 | ||
86 | #define ICON_WIDTH(screen) (!custom_icons_loaded[screen]? \ | 80 | #define ICON_WIDTH(screen) (!iconsets[Iconset_user][screen].loaded ? \ |
87 | inbuilt_iconset : user_iconset)[screen].width | 81 | inbuilt_iconset[screen] : iconsets[Iconset_user][screen].bmp).width |
88 | 82 | ||
89 | /* x,y in letters, not pixles */ | 83 | /* x,y in letters, not pixles */ |
90 | void screen_put_icon(struct screen * display, | 84 | void screen_put_icon(struct screen * display, |
@@ -133,9 +127,9 @@ void screen_put_iconxy(struct screen * display, | |||
133 | } | 127 | } |
134 | else if (icon >= Icon_Last_Themeable) | 128 | else if (icon >= Icon_Last_Themeable) |
135 | { | 129 | { |
136 | iconset = &viewer_iconset[screen]; | 130 | iconset = &iconsets[Iconset_viewers][screen].bmp; |
137 | icon -= Icon_Last_Themeable; | 131 | icon -= Icon_Last_Themeable; |
138 | if (!viewer_icons_loaded[screen] || | 132 | if (!iconsets[Iconset_viewers][screen].loaded || |
139 | (global_status.viewer_icon_count * height > iconset->height) || | 133 | (global_status.viewer_icon_count * height > iconset->height) || |
140 | (icon * height + height > iconset->height)) | 134 | (icon * height + height > iconset->height)) |
141 | { | 135 | { |
@@ -143,9 +137,9 @@ void screen_put_iconxy(struct screen * display, | |||
143 | return; | 137 | return; |
144 | } | 138 | } |
145 | } | 139 | } |
146 | else if (custom_icons_loaded[screen]) | 140 | else if (iconsets[Iconset_user][screen].loaded) |
147 | { | 141 | { |
148 | iconset = &user_iconset[screen]; | 142 | iconset = &iconsets[Iconset_user][screen].bmp; |
149 | } | 143 | } |
150 | else | 144 | else |
151 | { | 145 | { |
@@ -180,95 +174,111 @@ void screen_put_cursorxy(struct screen * display, int x, int y, bool on) | |||
180 | #endif | 174 | #endif |
181 | } | 175 | } |
182 | 176 | ||
183 | enum Iconset { | 177 | static int buflib_move_callback(int handle, void* current, void* new) |
184 | Iconset_Mainscreen, | 178 | { |
185 | Iconset_Mainscreen_viewers, | 179 | (void)current; |
186 | #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) | 180 | (void)new; |
187 | Iconset_Remotescreen, | 181 | int i; |
188 | Iconset_Remotescreen_viewers, | 182 | FOR_NB_SCREENS(j) |
189 | #endif | 183 | { |
190 | }; | 184 | for (i=0; i<Iconset_Count; i++) |
185 | { | ||
186 | if (iconsets[i][j].handle == handle) | ||
187 | { | ||
188 | if (iconsets[i][j].handle_locked > 0) | ||
189 | return BUFLIB_CB_CANNOT_MOVE; | ||
190 | ptrdiff_t diff = new - current; | ||
191 | iconsets[i][j].bmp.data += diff; | ||
192 | return BUFLIB_CB_OK; | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | return BUFLIB_CB_OK; | ||
197 | } | ||
198 | static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL}; | ||
191 | 199 | ||
192 | static void load_icons(const char* filename, enum Iconset iconset) | 200 | static void load_icons(const char* filename, enum Iconset iconset, |
201 | enum screen_type screen) | ||
193 | { | 202 | { |
194 | int size_read; | 203 | int size_read; |
195 | bool *loaded_ok = NULL; | ||
196 | struct bitmap *bmp = NULL; | ||
197 | int bmpformat = (FORMAT_NATIVE|FORMAT_DITHER); | 204 | int bmpformat = (FORMAT_NATIVE|FORMAT_DITHER); |
205 | struct iconset *ic = &iconsets[iconset][screen]; | ||
206 | int fd; | ||
198 | 207 | ||
199 | switch (iconset) | 208 | ic->loaded = false; |
200 | { | ||
201 | case Iconset_Mainscreen: | ||
202 | loaded_ok = &custom_icons_loaded[SCREEN_MAIN]; | ||
203 | bmp = &user_iconset[SCREEN_MAIN]; | ||
204 | bmp->data = icon_buffer[SCREEN_MAIN]; | ||
205 | break; | ||
206 | case Iconset_Mainscreen_viewers: | ||
207 | loaded_ok = &viewer_icons_loaded[SCREEN_MAIN]; | ||
208 | bmp = &viewer_iconset[SCREEN_MAIN]; | ||
209 | bmp->data = viewer_icon_buffer[SCREEN_MAIN]; | ||
210 | break; | ||
211 | #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) | ||
212 | case Iconset_Remotescreen: | ||
213 | loaded_ok = &custom_icons_loaded[SCREEN_REMOTE]; | ||
214 | bmp = &user_iconset[SCREEN_REMOTE]; | ||
215 | bmp->data = icon_buffer[SCREEN_REMOTE]; | ||
216 | bmpformat |= FORMAT_REMOTE; | ||
217 | break; | ||
218 | case Iconset_Remotescreen_viewers: | ||
219 | loaded_ok = &viewer_icons_loaded[SCREEN_REMOTE]; | ||
220 | bmp = &viewer_iconset[SCREEN_REMOTE]; | ||
221 | bmp->data = viewer_icon_buffer[SCREEN_REMOTE]; | ||
222 | bmpformat |= FORMAT_REMOTE; | ||
223 | break; | ||
224 | #endif | ||
225 | } | ||
226 | |||
227 | *loaded_ok = false; | ||
228 | if (filename[0] && filename[0] != '-') | 209 | if (filename[0] && filename[0] != '-') |
229 | { | 210 | { |
230 | char path[MAX_PATH]; | 211 | char path[MAX_PATH]; |
231 | 212 | ||
232 | snprintf(path, sizeof(path), ICON_DIR "/%s.bmp", filename); | 213 | snprintf(path, sizeof(path), ICON_DIR "/%s.bmp", filename); |
233 | size_read = read_bmp_file(path, bmp, IMG_BUFSIZE, bmpformat, NULL); | 214 | fd = open(path, O_RDONLY); |
234 | if (size_read > 0) | 215 | if (fd < 0) |
216 | return; | ||
217 | size_t buf_size = read_bmp_fd(fd, &ic->bmp, 0, | ||
218 | bmpformat|FORMAT_RETURN_SIZE, NULL); | ||
219 | ic->handle = core_alloc_ex(filename, buf_size, &buflib_ops); | ||
220 | if (ic->handle < 0) | ||
221 | { | ||
222 | close(fd); | ||
223 | return; | ||
224 | } | ||
225 | lseek(fd, 0, SEEK_SET); | ||
226 | ic->handle_locked = 1; | ||
227 | ic->bmp.data = core_get_data(ic->handle); | ||
228 | |||
229 | size_read = read_bmp_fd(fd, &ic->bmp, buf_size, bmpformat, NULL); | ||
230 | if (size_read <= 0) | ||
235 | { | 231 | { |
236 | *loaded_ok = true; | 232 | core_free(ic->handle); |
233 | return; | ||
237 | } | 234 | } |
235 | ic->handle_locked = 0; | ||
236 | ic->loaded = true; | ||
238 | } | 237 | } |
239 | } | 238 | } |
240 | 239 | ||
241 | |||
242 | void icons_init(void) | 240 | void icons_init(void) |
243 | { | 241 | { |
244 | load_icons(global_settings.icon_file, Iconset_Mainscreen); | 242 | int i; |
243 | FOR_NB_SCREENS(j) | ||
244 | { | ||
245 | for (i=0; i<Iconset_Count; i++) | ||
246 | { | ||
247 | if (iconsets[i][j].loaded && iconsets[i][j].handle > 0) | ||
248 | { | ||
249 | core_free(iconsets[i][j].handle); | ||
250 | iconsets[i][j].loaded = false; | ||
251 | } | ||
252 | } | ||
253 | } | ||
254 | load_icons(global_settings.icon_file, Iconset_user, SCREEN_MAIN); | ||
245 | 255 | ||
246 | if (global_settings.viewers_icon_file[0] && | 256 | if (global_settings.viewers_icon_file[0] && |
247 | global_settings.viewers_icon_file[0] != '-') | 257 | global_settings.viewers_icon_file[0] != '-') |
248 | { | 258 | { |
249 | load_icons(global_settings.viewers_icon_file, | 259 | load_icons(global_settings.viewers_icon_file, |
250 | Iconset_Mainscreen_viewers); | 260 | Iconset_viewers, SCREEN_MAIN); |
251 | read_viewer_theme_file(); | 261 | read_viewer_theme_file(); |
252 | } | 262 | } |
253 | else | 263 | else |
254 | { | 264 | { |
255 | load_icons(DEFAULT_VIEWER_BMP, Iconset_Mainscreen_viewers); | 265 | load_icons(DEFAULT_VIEWER_BMP, Iconset_viewers, SCREEN_MAIN); |
256 | } | 266 | } |
257 | 267 | ||
258 | #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) | 268 | #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) |
259 | load_icons(global_settings.remote_icon_file, | 269 | load_icons(global_settings.remote_icon_file, |
260 | Iconset_Remotescreen); | 270 | Iconset_user, SCREEN_REMOTE); |
261 | 271 | ||
262 | if (global_settings.remote_viewers_icon_file[0] && | 272 | if (global_settings.remote_viewers_icon_file[0] && |
263 | global_settings.remote_viewers_icon_file[0] != '-') | 273 | global_settings.remote_viewers_icon_file[0] != '-') |
264 | { | 274 | { |
265 | load_icons(global_settings.remote_viewers_icon_file, | 275 | load_icons(global_settings.remote_viewers_icon_file, |
266 | Iconset_Remotescreen_viewers); | 276 | Iconset_viewers, SCREEN_REMOTE); |
267 | } | 277 | } |
268 | else | 278 | else |
269 | { | 279 | { |
270 | load_icons(DEFAULT_REMOTE_VIEWER_BMP, | 280 | load_icons(DEFAULT_REMOTE_VIEWER_BMP, |
271 | Iconset_Remotescreen_viewers); | 281 | Iconset_viewers, SCREEN_REMOTE); |
272 | } | 282 | } |
273 | #endif | 283 | #endif |
274 | } | 284 | } |
diff --git a/firmware/export/config/mrobe500.h b/firmware/export/config/mrobe500.h index b8f2c62cf1..590f8a95f9 100644 --- a/firmware/export/config/mrobe500.h +++ b/firmware/export/config/mrobe500.h | |||
@@ -112,9 +112,6 @@ | |||
112 | #define LCD_DEPTH 16 /* 65k colours */ | 112 | #define LCD_DEPTH 16 /* 65k colours */ |
113 | #define LCD_PIXELFORMAT RGB565 /* rgb565 */ | 113 | #define LCD_PIXELFORMAT RGB565 /* rgb565 */ |
114 | 114 | ||
115 | #define MAX_ICON_HEIGHT 35 | ||
116 | #define MAX_ICON_WIDTH 35 | ||
117 | |||
118 | /* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE | 115 | /* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE |
119 | should be defined as well. */ | 116 | should be defined as well. */ |
120 | #define HAVE_LCD_SLEEP | 117 | #define HAVE_LCD_SLEEP |