diff options
Diffstat (limited to 'apps/plugins/lib')
-rw-r--r-- | apps/plugins/lib/SOURCES | 1 | ||||
-rw-r--r-- | apps/plugins/lib/osd.c | 470 | ||||
-rw-r--r-- | apps/plugins/lib/osd.h | 94 |
3 files changed, 565 insertions, 0 deletions
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index 4b33901088..d49605f1ad 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES | |||
@@ -52,6 +52,7 @@ pluginlib_jpeg_load.c | |||
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | checkbox.c | 54 | checkbox.c |
55 | osd.c | ||
55 | picture.c | 56 | picture.c |
56 | xlcd_core.c | 57 | xlcd_core.c |
57 | xlcd_draw.c | 58 | xlcd_draw.c |
diff --git a/apps/plugins/lib/osd.c b/apps/plugins/lib/osd.c new file mode 100644 index 0000000000..ff0533a898 --- /dev/null +++ b/apps/plugins/lib/osd.c | |||
@@ -0,0 +1,470 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Floating on-screen display | ||
11 | * | ||
12 | * Copyright (C) 2012 Michael Sevakis | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
20 | * KIND, either express or implied. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | #include "plugin.h" | ||
24 | #include "osd.h" | ||
25 | |||
26 | #if 1 | ||
27 | #undef DEBUGF | ||
28 | #define DEBUGF(...) | ||
29 | #endif | ||
30 | |||
31 | /* At this time: assumes use of the default viewport for normal drawing */ | ||
32 | |||
33 | /* If multiple OSD's are wanted, could convert to caller-allocated */ | ||
34 | static struct osd | ||
35 | { | ||
36 | enum osd_status | ||
37 | { | ||
38 | OSD_DISABLED = 0, /* Disabled entirely */ | ||
39 | OSD_HIDDEN, /* Hidden from view */ | ||
40 | OSD_VISIBLE, /* Visible on screen */ | ||
41 | OSD_ERASED, /* Erased in preparation for regular drawing */ | ||
42 | } status; /* View status */ | ||
43 | struct viewport vp; /* Clipping viewport */ | ||
44 | struct bitmap lcd_bitmap; /* The main LCD fb bitmap */ | ||
45 | struct bitmap back_bitmap; /* The OSD backbuffer fb bitmap */ | ||
46 | int maxwidth; /* How wide may it be at most? */ | ||
47 | int maxheight; /* How high may it be at most? */ | ||
48 | long timeout; /* Current popup stay duration */ | ||
49 | long hide_tick; /* Tick when it should be hidden */ | ||
50 | osd_draw_cb_fn_t draw_cb; /* Draw update callback */ | ||
51 | } osd; | ||
52 | |||
53 | /* Framebuffer allocation macros */ | ||
54 | #if LCD_DEPTH == 1 | ||
55 | # if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
56 | # define LCD_WIDTH2BYTES(w) (((w)+7)/8) | ||
57 | # define LCD_BYTES2WIDTH(b) ((b)*8) | ||
58 | # elif LCD_PIXELFORMAT == VERTICAL_PACKING | ||
59 | # define LCD_HEIGHT2BYTES(h) (((h)+7)/8) | ||
60 | # define LCD_BYTES2HEIGHT(b) ((b)*8) | ||
61 | # else | ||
62 | # error Unknown 1-bit format; please define macros | ||
63 | # endif /* LCD_PIXELFORMAT */ | ||
64 | #elif LCD_DEPTH == 2 | ||
65 | # if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
66 | # define LCD_WIDTH2BYTES(w) (((w)+3)/4) | ||
67 | # define LCD_BYTES2WIDTH(b) ((b)*4) | ||
68 | # elif LCD_PIXELFORMAT == VERTICAL_PACKING | ||
69 | # define LCD_HEIGHT2BYTES(h) (((h)+3)/4) | ||
70 | # define LCD_BYTES2HEIGHT(b) ((b)*4) | ||
71 | # elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED | ||
72 | # define LCD_WIDTH2BYTES(w) ((w)*2) | ||
73 | # define LCD_BYTES2WIDTH(b) ((b)/2) | ||
74 | # define LCD_HEIGHT2BYTES(h) (((h)+7)/8*2) | ||
75 | # define LCD_BYTES2HEIGHT(b) ((b)/2*8) | ||
76 | # else | ||
77 | # error Unknown 2-bit format; please define macros | ||
78 | # endif /* LCD_PIXELFORMAT */ | ||
79 | #elif LCD_DEPTH == 16 | ||
80 | # define LCD_WIDTH2BYTES(w) ((w)*2) | ||
81 | # define LCD_BYTES2WIDTH(b) ((b)/2) | ||
82 | #else | ||
83 | # error Unknown LCD depth; please define macros | ||
84 | #endif /* LCD_DEPTH */ | ||
85 | /* Set defaults if not defined different yet. */ | ||
86 | #ifndef LCD_WIDTH2BYTES | ||
87 | # define LCD_WIDTH2BYTES(w) (w) | ||
88 | #endif | ||
89 | #ifndef LCD_BYTES2WIDTH | ||
90 | # define LCD_BYTES2WIDTH(b) (b) | ||
91 | #endif | ||
92 | #ifndef LCD_HEIGHT2BYTES | ||
93 | # define LCD_HEIGHT2BYTES(h) (h) | ||
94 | #endif | ||
95 | #ifndef LCD_BYTES2HEIGHT | ||
96 | # define LCD_BYTES2HEIGHT(b) (b) | ||
97 | #endif | ||
98 | |||
99 | /* Create a bitmap framebuffer from a buffer */ | ||
100 | static fb_data * buf_to_fb_bitmap(void *buf, size_t bufsize, | ||
101 | int *width, int *height) | ||
102 | { | ||
103 | /* Used as dest, the LCD functions cannot deal with alternate | ||
104 | strides as of now - the stride guides the calulations. If | ||
105 | that is no longer the case, then width or height can be | ||
106 | used instead (and less memory needed for a small surface!). | ||
107 | */ | ||
108 | DEBUGF("buf: %p bufsize: %lu\n", buf, (unsigned long)bufsize); | ||
109 | |||
110 | #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE | ||
111 | int h = LCD_BYTES2HEIGHT(LCD_HEIGHT2BYTES(LCD_HEIGHT)); | ||
112 | int w = bufsize / LCD_HEIGHT2BYTES(h); | ||
113 | |||
114 | if (w == 0) | ||
115 | { | ||
116 | DEBUGF("OSD: not enough buffer\n"); | ||
117 | return NULL; /* not enough buffer */ | ||
118 | } | ||
119 | #else | ||
120 | int w = LCD_BYTES2WIDTH(LCD_WIDTH2BYTES(LCD_WIDTH)); | ||
121 | int h = bufsize / LCD_WIDTH2BYTES(w); | ||
122 | |||
123 | if (h == 0) | ||
124 | { | ||
125 | DEBUGF("OSD: not enough buffer\n"); | ||
126 | return NULL; /* not enough buffer */ | ||
127 | } | ||
128 | #endif | ||
129 | |||
130 | DEBUGF("fbw:%d fbh:%d\n", w, h); | ||
131 | |||
132 | *width = w; | ||
133 | *height = h; | ||
134 | |||
135 | return (fb_data *)buf; | ||
136 | } | ||
137 | |||
138 | static inline void osd_set_vp_pos(int x, int y, int width, int height) | ||
139 | { | ||
140 | osd.vp.x = x; | ||
141 | osd.vp.y = y; | ||
142 | osd.vp.width = width; | ||
143 | osd.vp.height = height; | ||
144 | } | ||
145 | |||
146 | /* Sync the backbuffer to the on-screen image */ | ||
147 | static void osd_lcd_update_back_buffer(void) | ||
148 | { | ||
149 | rb->lcd_set_framebuffer((fb_data *)osd.back_bitmap.data); | ||
150 | rb->lcd_bmp_part(&osd.lcd_bitmap, osd.vp.x, osd.vp.y, | ||
151 | 0, 0, osd.vp.width, osd.vp.height); | ||
152 | /* Assume it was on default framebuffer for now */ | ||
153 | rb->lcd_set_framebuffer(NULL); | ||
154 | } | ||
155 | |||
156 | /* Erase the OSD to restore the framebuffer */ | ||
157 | static void osd_lcd_erase(void) | ||
158 | { | ||
159 | rb->lcd_bmp_part(&osd.back_bitmap, 0, 0, osd.vp.x, osd.vp.y, | ||
160 | osd.vp.width, osd.vp.height); | ||
161 | } | ||
162 | |||
163 | /* Draw the OSD image portion using the callback */ | ||
164 | static void osd_lcd_draw_rect(int x, int y, int width, int height) | ||
165 | { | ||
166 | rb->lcd_set_viewport(&osd.vp); | ||
167 | osd.draw_cb(x, y, width, height); | ||
168 | rb->lcd_set_viewport(NULL); | ||
169 | } | ||
170 | |||
171 | /* Draw the OSD image using the callback */ | ||
172 | static void osd_lcd_draw(void) | ||
173 | { | ||
174 | osd_lcd_draw_rect(0, 0, osd.vp.width, osd.vp.height); | ||
175 | } | ||
176 | |||
177 | |||
178 | /** Public APIs **/ | ||
179 | |||
180 | /* Initialized the OSD and set its backbuffer */ | ||
181 | bool osd_init(void *backbuf, size_t backbuf_size, | ||
182 | osd_draw_cb_fn_t draw_cb) | ||
183 | { | ||
184 | osd_show(OSD_HIDE); | ||
185 | |||
186 | osd.status = OSD_DISABLED; /* Disabled unless all is okay */ | ||
187 | osd_set_vp_pos(0, 0, 0, 0); | ||
188 | osd.maxwidth = osd.maxheight = 0; | ||
189 | osd.timeout = 0; | ||
190 | |||
191 | if (!draw_cb) | ||
192 | return false; | ||
193 | |||
194 | if (!backbuf) | ||
195 | return false; | ||
196 | |||
197 | ALIGN_BUFFER(backbuf, backbuf_size, FB_DATA_SZ); | ||
198 | |||
199 | if (!backbuf_size) | ||
200 | return false; | ||
201 | |||
202 | rb->viewport_set_fullscreen(&osd.vp, SCREEN_MAIN); | ||
203 | |||
204 | fb_data *backfb = buf_to_fb_bitmap(backbuf, backbuf_size, | ||
205 | &osd.maxwidth, &osd.maxheight); | ||
206 | |||
207 | if (!backfb) | ||
208 | return false; | ||
209 | |||
210 | osd.draw_cb = draw_cb; | ||
211 | |||
212 | /* LCD framebuffer bitmap */ | ||
213 | osd.lcd_bitmap.width = LCD_BYTES2WIDTH(LCD_WIDTH2BYTES(LCD_WIDTH)); | ||
214 | osd.lcd_bitmap.height = LCD_BYTES2HEIGHT(LCD_HEIGHT2BYTES(LCD_HEIGHT)); | ||
215 | #if LCD_DEPTH > 1 | ||
216 | osd.lcd_bitmap.format = FORMAT_NATIVE; | ||
217 | osd.lcd_bitmap.maskdata = NULL; | ||
218 | #endif | ||
219 | #ifdef HAVE_LCD_COLOR | ||
220 | osd.lcd_bitmap.alpha_offset = 0; | ||
221 | #endif | ||
222 | osd.lcd_bitmap.data = (void *)rb->lcd_framebuffer; | ||
223 | |||
224 | /* Backbuffer bitmap */ | ||
225 | osd.back_bitmap.width = osd.maxwidth; | ||
226 | osd.back_bitmap.height = osd.maxheight; | ||
227 | #if LCD_DEPTH > 1 | ||
228 | osd.back_bitmap.format = FORMAT_NATIVE; | ||
229 | osd.back_bitmap.maskdata = NULL; | ||
230 | #endif | ||
231 | #ifdef HAVE_LCD_COLOR | ||
232 | osd.back_bitmap.alpha_offset = 0; | ||
233 | #endif | ||
234 | osd.back_bitmap.data = (void *)backfb; | ||
235 | |||
236 | DEBUGF("FB:%p BB:%p\n", osd.lcd_bitmap.data, osd.back_bitmap.data); | ||
237 | |||
238 | /* Set the default position to the whole thing */ | ||
239 | osd_set_vp_pos(0, 0, osd.maxwidth, osd.maxheight); | ||
240 | |||
241 | osd.status = OSD_HIDDEN; /* Ready when you are */ | ||
242 | return true; | ||
243 | } | ||
244 | |||
245 | /* Show/Hide the OSD on screen */ | ||
246 | bool osd_show(unsigned flags) | ||
247 | { | ||
248 | if (flags & OSD_SHOW) | ||
249 | { | ||
250 | switch (osd.status) | ||
251 | { | ||
252 | case OSD_DISABLED: | ||
253 | break; /* No change */ | ||
254 | |||
255 | case OSD_HIDDEN: | ||
256 | osd_lcd_update_back_buffer(); | ||
257 | osd.status = OSD_VISIBLE; | ||
258 | osd_update(); | ||
259 | osd.hide_tick = *rb->current_tick + osd.timeout; | ||
260 | break; | ||
261 | |||
262 | case OSD_VISIBLE: | ||
263 | if (flags & OSD_UPDATENOW) | ||
264 | osd_update(); | ||
265 | /* Fall-through */ | ||
266 | case OSD_ERASED: | ||
267 | osd.hide_tick = *rb->current_tick + osd.timeout; | ||
268 | return true; | ||
269 | } | ||
270 | } | ||
271 | else | ||
272 | { | ||
273 | switch (osd.status) | ||
274 | { | ||
275 | case OSD_DISABLED: | ||
276 | case OSD_HIDDEN: | ||
277 | break; | ||
278 | |||
279 | case OSD_VISIBLE: | ||
280 | osd_lcd_erase(); | ||
281 | rb->lcd_update_rect(osd.vp.x, osd.vp.y, osd.vp.width, | ||
282 | osd.vp.height); | ||
283 | /* Fall-through */ | ||
284 | case OSD_ERASED: | ||
285 | osd.status = OSD_HIDDEN; | ||
286 | return true; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | return false; | ||
291 | } | ||
292 | |||
293 | /* Redraw the entire OSD */ | ||
294 | bool osd_update(void) | ||
295 | { | ||
296 | if (osd.status != OSD_VISIBLE) | ||
297 | return false; | ||
298 | |||
299 | osd_lcd_draw(); | ||
300 | |||
301 | rb->lcd_update_rect(osd.vp.x, osd.vp.y, osd.vp.width, | ||
302 | osd.vp.height); | ||
303 | |||
304 | return true; | ||
305 | } | ||
306 | |||
307 | /* Redraw part of the OSD (viewport-relative coordinates) */ | ||
308 | bool osd_update_rect(int x, int y, int width, int height) | ||
309 | { | ||
310 | if (osd.status != OSD_VISIBLE) | ||
311 | return false; | ||
312 | |||
313 | osd_lcd_draw_rect(x, y, width, height); | ||
314 | |||
315 | if (x + width > osd.vp.width) | ||
316 | width = osd.vp.width - x; | ||
317 | |||
318 | if (x < 0) | ||
319 | { | ||
320 | width += x; | ||
321 | x = 0; | ||
322 | } | ||
323 | |||
324 | if (width <= 0) | ||
325 | return false; | ||
326 | |||
327 | if (y + height > osd.vp.height) | ||
328 | height = osd.vp.height - y; | ||
329 | |||
330 | if (y < 0) | ||
331 | { | ||
332 | height += y; | ||
333 | y = 0; | ||
334 | } | ||
335 | |||
336 | if (height <= 0) | ||
337 | return false; | ||
338 | |||
339 | rb->lcd_update_rect(osd.vp.x + x, osd.vp.y + y, width, height); | ||
340 | |||
341 | return true; | ||
342 | } | ||
343 | |||
344 | /* Set a new screen location and size (screen coordinates) */ | ||
345 | bool osd_update_pos(int x, int y, int width, int height) | ||
346 | { | ||
347 | if (osd.status == OSD_DISABLED) | ||
348 | return false; | ||
349 | |||
350 | if (width < 0) | ||
351 | width = 0; | ||
352 | else if (width > osd.maxwidth) | ||
353 | width = osd.maxwidth; | ||
354 | |||
355 | if (height < 0) | ||
356 | height = 0; | ||
357 | else if (height > osd.maxheight) | ||
358 | height = osd.maxheight; | ||
359 | |||
360 | if (x == osd.vp.x && y == osd.vp.y && | ||
361 | width == osd.vp.width && height == osd.vp.height) | ||
362 | return false; /* No change */ | ||
363 | |||
364 | if (osd.status != OSD_VISIBLE) | ||
365 | { | ||
366 | /* Not visible - just update pos */ | ||
367 | osd_set_vp_pos(x, y, width, height); | ||
368 | return false; | ||
369 | } | ||
370 | |||
371 | /* Visible area has changed */ | ||
372 | osd_lcd_erase(); | ||
373 | |||
374 | /* Update the smallest rectangle that encloses both the old and new | ||
375 | regions to make the change free of flicker (they may overlap) */ | ||
376 | int xu = MIN(osd.vp.x, x); | ||
377 | int yu = MIN(osd.vp.y, y); | ||
378 | int wu = MAX(osd.vp.x + osd.vp.width, x + width) - xu; | ||
379 | int hu = MAX(osd.vp.y + osd.vp.height, y + height) - yu; | ||
380 | |||
381 | osd_set_vp_pos(x, y, width, height); | ||
382 | osd_lcd_update_back_buffer(); | ||
383 | osd_lcd_draw(); | ||
384 | |||
385 | rb->lcd_update_rect(xu, yu, wu, hu); | ||
386 | return true; | ||
387 | } | ||
388 | |||
389 | /* Call periodically to have the OSD timeout and hide itself */ | ||
390 | void osd_monitor_timeout(void) | ||
391 | { | ||
392 | if (osd.status <= OSD_HIDDEN) | ||
393 | return; /* Already hidden/disabled */ | ||
394 | |||
395 | if (osd.timeout > 0 && TIME_AFTER(*rb->current_tick, osd.hide_tick)) | ||
396 | osd_show(OSD_HIDE); | ||
397 | } | ||
398 | |||
399 | /* Set the OSD timeout value. <= 0 = never timeout */ | ||
400 | void osd_set_timeout(long timeout) | ||
401 | { | ||
402 | if (osd.status == OSD_DISABLED) | ||
403 | return; | ||
404 | |||
405 | osd.timeout = timeout; | ||
406 | osd_monitor_timeout(); | ||
407 | } | ||
408 | |||
409 | /* Use the OSD viewport context */ | ||
410 | struct viewport * osd_get_viewport(void) | ||
411 | { | ||
412 | return &osd.vp; | ||
413 | } | ||
414 | |||
415 | /* Get the maximum dimensions calculated by osd_init() */ | ||
416 | void osd_get_max_dims(int *maxwidth, int *maxheight) | ||
417 | { | ||
418 | if (maxwidth) | ||
419 | *maxwidth = osd.maxwidth; | ||
420 | |||
421 | if (maxheight) | ||
422 | *maxheight = osd.maxheight; | ||
423 | } | ||
424 | |||
425 | /* Is the OSD enabled? */ | ||
426 | bool osd_enabled(void) | ||
427 | { | ||
428 | return osd.status != OSD_DISABLED; | ||
429 | } | ||
430 | |||
431 | |||
432 | /** LCD update substitutes **/ | ||
433 | |||
434 | /* Prepare LCD framebuffer for regular drawing */ | ||
435 | void osd_lcd_update_prepare(void) | ||
436 | { | ||
437 | if (osd.status == OSD_VISIBLE) | ||
438 | { | ||
439 | osd.status = OSD_ERASED; | ||
440 | osd_lcd_erase(); | ||
441 | } | ||
442 | } | ||
443 | |||
444 | /* Update the whole screen */ | ||
445 | void osd_lcd_update(void) | ||
446 | { | ||
447 | if (osd.status == OSD_ERASED) | ||
448 | { | ||
449 | /* Save the screen image underneath and restore the OSD image */ | ||
450 | osd.status = OSD_VISIBLE; | ||
451 | osd_lcd_update_back_buffer(); | ||
452 | osd_lcd_draw(); | ||
453 | } | ||
454 | |||
455 | rb->lcd_update(); | ||
456 | } | ||
457 | |||
458 | /* Update a part of the screen */ | ||
459 | void osd_lcd_update_rect(int x, int y, int width, int height) | ||
460 | { | ||
461 | if (osd.status == OSD_ERASED) | ||
462 | { | ||
463 | /* Save the screen image underneath and restore the OSD image */ | ||
464 | osd.status = OSD_VISIBLE; | ||
465 | osd_lcd_update_back_buffer(); | ||
466 | osd_lcd_draw(); | ||
467 | } | ||
468 | |||
469 | rb->lcd_update_rect(x, y, width, height); | ||
470 | } | ||
diff --git a/apps/plugins/lib/osd.h b/apps/plugins/lib/osd.h new file mode 100644 index 0000000000..89441ae273 --- /dev/null +++ b/apps/plugins/lib/osd.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Floating on-screen display | ||
11 | * | ||
12 | * Copyright (C) 2012 Michael Sevakis | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
20 | * KIND, either express or implied. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | #ifndef OSD_H | ||
24 | #define OSD_H | ||
25 | |||
26 | /* At this time: assumes use of the default viewport for normal drawing */ | ||
27 | |||
28 | /* Callback implemented by user. Paramters are OSD vp-relative coordinates */ | ||
29 | typedef void (* osd_draw_cb_fn_t)(int x, int y, int width, int height); | ||
30 | |||
31 | /* Initialize the OSD, set its backbuffer, update callback and enable it if | ||
32 | * the call succeeded. */ | ||
33 | bool osd_init(void *backbuf, size_t backbuf_size, | ||
34 | osd_draw_cb_fn_t draw_cb); | ||
35 | |||
36 | enum | ||
37 | { | ||
38 | OSD_HIDE = 0x0, /* Hide from view */ | ||
39 | OSD_SHOW = 0x1, /* Bring into view, updating if needed */ | ||
40 | OSD_UPDATENOW = 0x2, /* Force update even if nothing changed */ | ||
41 | }; | ||
42 | |||
43 | /* Show/Hide the OSD on screen returning previous status */ | ||
44 | bool osd_show(unsigned flags); | ||
45 | |||
46 | /* Redraw the entire OSD returning true if screen update occurred */ | ||
47 | bool osd_update(void); | ||
48 | |||
49 | /* Redraw part of the OSD (OSD viewport-relative coordinates) returning true | ||
50 | if any screen update occurred */ | ||
51 | bool osd_update_rect(int x, int y, int width, int height); | ||
52 | |||
53 | /* Set a new screen location and size (screen coordinates) */ | ||
54 | bool osd_update_pos(int x, int y, int width, int height); | ||
55 | |||
56 | /* Call periodically to have the OSD timeout and hide itself */ | ||
57 | void osd_monitor_timeout(void); | ||
58 | |||
59 | /* Set the OSD timeout value. 'timeout' <= 0 == never timeout */ | ||
60 | void osd_set_timeout(long timeout); | ||
61 | |||
62 | /* Use the OSD viewport context */ | ||
63 | struct viewport * osd_get_viewport(void); | ||
64 | |||
65 | /* Get the maximum buffer dimensions calculated by osd_init() */ | ||
66 | void osd_get_max_dims(int *maxwidth, int *maxheight); | ||
67 | |||
68 | /* Is the OSD enabled? */ | ||
69 | bool osd_enabled(void); | ||
70 | |||
71 | /** Functions that must be used in lieu of regular LCD functions for this | ||
72 | ** to work. | ||
73 | ** | ||
74 | ** To be efficient, as much drawing as possible should be combined between | ||
75 | ** *prepare and *update. | ||
76 | ** | ||
77 | ** osd_lcd_update_prepare(); | ||
78 | ** <draw stuff using lcd_* routines> | ||
79 | ** osd_lcd_update[_rect](); | ||
80 | ** | ||
81 | ** TODO: Make it work seamlessly with greylib and regular LCD functions. | ||
82 | **/ | ||
83 | |||
84 | /* Prepare LCD frambuffer for regular drawing - call before any other LCD | ||
85 | function */ | ||
86 | void osd_lcd_update_prepare(void); | ||
87 | |||
88 | /* Update the whole screen and restore OSD if it is visible */ | ||
89 | void osd_lcd_update(void); | ||
90 | |||
91 | /* Update a part of the screen and restore OSD if it is visible */ | ||
92 | void osd_lcd_update_rect(int x, int y, int width, int height); | ||
93 | |||
94 | #endif /* OSD_H */ | ||