Prepare new maemo release
[maemo-rb.git] / apps / plugins / lib / osd.c
blob598a76759c85701b0905d52438bd60f085a31d83
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Floating on-screen display
12 * Copyright (C) 2012 Michael Sevakis
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.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
23 #include "plugin.h"
24 #include "grey.h"
25 #include "osd.h"
27 #if 1
28 #undef DEBUGF
29 #define DEBUGF(...)
30 #endif
32 #if defined(SIMULATOR) && LCD_DEPTH < 4
33 /* Sim isn't using --ffunction-sections thus greylib references will happen
34 here even if not using this with greylib on a grayscale display, which
35 demands that a struct _grey_info exist. */
36 #ifndef _WIN32
37 __attribute__((weak))
38 #endif /* _WIN32 */
39 struct _grey_info _grey_info;
40 #endif /* defined(SIMULATOR) && LCD_DEPTH < 4 */
42 /* At this time: assumes use of the default viewport for normal drawing */
44 /* If multiple OSD's are wanted, could convert to caller-allocated */
45 struct osd
47 enum osd_status
49 OSD_DISABLED = 0, /* Disabled entirely */
50 OSD_HIDDEN, /* Hidden from view */
51 OSD_VISIBLE, /* Visible on screen */
52 OSD_ERASED, /* Erased in preparation for regular drawing */
53 } status; /* View status */
54 struct viewport vp; /* Clipping viewport */
55 int lcd_bitmap_stride; /* Stride of LCD bitmap */
56 void *lcd_bitmap_data; /* Backbuffer framebuffer data */
57 int back_bitmap_stride; /* Stride of backbuffer bitmap */
58 void *back_bitmap_data; /* LCD framebuffer data */
59 int maxwidth; /* How wide may it be at most? */
60 int maxheight; /* How high may it be at most? */
61 long timeout; /* Current popup stay duration */
62 long hide_tick; /* Tick when it should be hidden */
63 osd_draw_cb_fn_t draw_cb; /* Draw update callback */
64 /* Functions to factilitate interface compatibility of OSD types */
65 void * (*init_buffers)(struct osd *osd, unsigned flags, void *buf,
66 size_t *bufsize);
67 void (*set_viewport_pos)(struct viewport *vp, int x, int y, int width,
68 int height);
69 void (*lcd_update)(void);
70 void (*lcd_update_rect)(int x, int y, int width, int height);
71 void (*lcd_set_viewport)(struct viewport *vp);
72 void (*lcd_set_framebuffer)(void *buf);
73 void (*lcd_framebuffer_set_pos)(int x, int y, int width, int height);
74 void (*lcd_bitmap_part)(const void *src, int src_x, int src_y,
75 int stride, int x, int y, int width, int height);
78 static struct osd native_osd;
79 #if LCD_DEPTH < 4
80 static struct osd grey_osd;
81 #endif
83 /* Framebuffer allocation macros */
84 #if LCD_DEPTH == 1
85 # if LCD_PIXELFORMAT == HORIZONTAL_PACKING
86 # define _OSD_WIDTH2BYTES(w) (((w)+7)/8)
87 # define _OSD_BYTES2WIDTH(b) ((b)*8)
88 # elif LCD_PIXELFORMAT == VERTICAL_PACKING
89 # define _OSD_HEIGHT2BYTES(h) (((h)+7)/8)
90 # define _OSD_BYTES2HEIGHT(b) ((b)*8)
91 # else
92 # error Unknown 1-bit format; please define macros
93 # endif /* LCD_PIXELFORMAT */
94 #elif LCD_DEPTH == 2
95 # if LCD_PIXELFORMAT == HORIZONTAL_PACKING
96 # define _OSD_WIDTH2BYTES(w) (((w)+3)/4)
97 # define _OSD_BYTES2WIDTH(b) ((b)*4)
98 # elif LCD_PIXELFORMAT == VERTICAL_PACKING
99 # define _OSD_HEIGHT2BYTES(h) (((h)+3)/4)
100 # define _OSD_BYTES2HEIGHT(b) ((b)*4)
101 # elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
102 # define _OSD_HEIGHT2BYTES(h) (((h)+7)/8*2)
103 # define _OSD_BYTES2HEIGHT(b) ((b)/2*8)
104 # else
105 # error Unknown 2-bit format; please define macros
106 # endif /* LCD_PIXELFORMAT */
107 #elif LCD_DEPTH == 16
108 # if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
109 # define _OSD_HEIGHT2BYTES(h) ((h)*2)
110 # define _OSD_BYTES2HEIGHT(b) ((b)/2)
111 # else /* !defined(LCD_STRIDEFORMAT) || LCD_STRIDEFORMAT != VERTICAL_STRIDE */
112 # define _OSD_WIDTH2BYTES(w) ((w)*2)
113 # define _OSD_BYTES2WIDTH(b) ((b)/2)
114 # endif /* end stride type selection */
115 #else /* other LCD depth */
116 # error Unknown LCD depth; please define macros
117 #endif /* LCD_DEPTH */
118 /* Set defaults if not defined differently */
119 #ifndef _OSD_WIDTH2BYTES
120 # define _OSD_WIDTH2BYTES(w) (w)
121 #endif
122 #ifndef _OSD_BYTES2WIDTH
123 # define _OSD_BYTES2WIDTH(b) (b)
124 #endif
125 #ifndef _OSD_HEIGHT2BYTES
126 # define _OSD_HEIGHT2BYTES(h) (h)
127 #endif
128 #ifndef _OSD_BYTES2HEIGHT
129 # define _OSD_BYTES2HEIGHT(b) (b)
130 #endif
131 #ifndef _OSD_BUFSIZE
132 # define _OSD_BUFSIZE(w, h) (_OSD_WIDTH2BYTES(w)*_OSD_HEIGHT2BYTES(h))
133 #endif
135 static void _osd_destroy(struct osd *osd);
136 static bool _osd_show(struct osd *osd, unsigned flags);
139 /** Native LCD routines **/
141 /* Create a bitmap framebuffer from a buffer */
142 static void * _osd_lcd_init_buffers(struct osd *osd, unsigned flags,
143 void *buf, size_t *bufsize)
145 /* Used as dest, the LCD functions cannot deal with alternate
146 strides as of now - the stride guides the calulations. If
147 that is no longer the case, then width or height can be
148 used instead (and less memory needed for a small surface!).
149 IOW: crappiness means one dimension is non-negotiable.
151 DEBUGF("OSD: in(buf=%p bufsize=%lu)\n", buf,
152 (unsigned long)*bufsize);
154 rb->viewport_set_fullscreen(&osd->vp, SCREEN_MAIN);
156 #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
157 int colbytes = _OSD_HEIGHT2BYTES(LCD_HEIGHT);
158 int bytecols = *bufsize / colbytes;
159 int w = _OSD_BYTES2WIDTH(bytecols);
160 int h = _OSD_BYTES2HEIGHT(colbytes);
162 if (flags & OSD_INIT_MAJOR_HEIGHT)
164 if (w == 0 || ((flags & OSD_INIT_MINOR_MIN) && w < osd->maxwidth))
166 DEBUGF("OSD: not enough buffer\n");
167 return NULL; /* not enough buffer */
170 if ((flags & OSD_INIT_MINOR_MAX) && w > osd->maxwidth)
171 w = osd->maxwidth;
173 else /* OSD_INIT_MAJOR_WIDTH implied */
175 if (w == 0 || w < osd->maxwidth)
177 DEBUGF("OSD: not enough buffer\n");
178 return NULL; /* not enough buffer */
180 else if (w > osd->maxwidth)
182 w = osd->maxwidth;
186 w = _OSD_BYTES2WIDTH(_OSD_WIDTH2BYTES(w));
187 osd->lcd_bitmap_stride = _OSD_BYTES2HEIGHT(_OSD_HEIGHT2BYTES(LCD_HEIGHT));
188 osd->back_bitmap_stride = h;
189 #else /* !defined(LCD_STRIDEFORMAT) || LCD_STRIDEFORMAT != VERTICAL_STRIDE */
190 int rowbytes = _OSD_WIDTH2BYTES(LCD_WIDTH);
191 int byterows = *bufsize / rowbytes;
192 int w = _OSD_BYTES2WIDTH(rowbytes);
193 int h = _OSD_BYTES2HEIGHT(byterows);
195 if (flags & OSD_INIT_MAJOR_HEIGHT)
197 if (h == 0 || h < osd->maxheight)
199 DEBUGF("OSD: not enough buffer\n");
200 return NULL;
202 else if (h > osd->maxheight)
204 h = osd->maxheight;
207 else /* OSD_INIT_MAJOR_WIDTH implied */
209 if (h == 0 || ((flags & OSD_INIT_MINOR_MIN) && h < osd->maxheight))
211 DEBUGF("OSD: not enough buffer\n");
212 return NULL;
215 if ((flags & OSD_INIT_MINOR_MAX) && h > osd->maxheight)
216 h = osd->maxheight;
219 h = _OSD_BYTES2HEIGHT(_OSD_HEIGHT2BYTES(h));
220 osd->lcd_bitmap_stride = _OSD_BYTES2WIDTH(_OSD_WIDTH2BYTES(LCD_WIDTH));
221 osd->back_bitmap_stride = w;
222 #endif /* end stride type selection */
224 osd->lcd_bitmap_data = (void *)rb->lcd_framebuffer;
225 osd->back_bitmap_data = buf;
227 osd->maxwidth = w;
228 osd->maxheight = h;
229 *bufsize = _OSD_BUFSIZE(w, h);
231 DEBUGF("OSD: addr(fb=%p bb=%p)\n", osd->lcd_bitmap_data,
232 osd->back_bitmap_data);
233 DEBUGF("OSD: w=%d h=%d bufsz=%lu\n", w, h, (unsigned long)*bufsize);
235 return buf;
238 /* Set viewport coordinates */
239 static void _osd_lcd_viewport_set_pos(
240 struct viewport *vp, int x, int y, int width, int height)
242 vp->x = x;
243 vp->y = y;
244 vp->width = width;
245 vp->height = height;
249 #if LCD_DEPTH < 4
250 /** Greylib LCD routines **/
252 /* Create a greylib bitmap framebuffer from a buffer */
253 static void * _osd_grey_init_buffers(struct osd *osd, unsigned flags,
254 void *buf, size_t *bufsize)
256 int w, h;
258 DEBUGF("OSD (grey): in(buf=%p bufsize=%lu)\n", buf,
259 (unsigned long)*bufsize);
261 grey_viewport_set_fullscreen(&osd->vp, SCREEN_MAIN);
263 if (flags & OSD_INIT_MAJOR_HEIGHT)
265 h = osd->maxheight;
266 w = *bufsize / h;
268 if (w == 0 || ((flags & OSD_INIT_MINOR_MIN) && w < osd->maxwidth))
270 DEBUGF("OSD (grey): Not enough buffer\n");
271 return NULL;
274 if ((flags & OSD_INIT_MINOR_MAX) && w > osd->maxwidth)
275 w = osd->maxwidth;
277 else /* OSD_INIT_MAJOR_WIDTH implied */
279 w = osd->maxwidth;
280 h = *bufsize / w;
282 if (h == 0 || ((flags & OSD_INIT_MINOR_MIN) && h < osd->maxheight))
284 DEBUGF("OSD (grey): Not enough buffer\n");
285 return NULL;
288 if ((flags & OSD_INIT_MINOR_MAX) && h > osd->maxheight)
289 h = osd->maxheight;
292 /* Have to peek into _grey_info a bit */
293 osd->lcd_bitmap_stride = _grey_info.width;
294 osd->lcd_bitmap_data = _grey_info.buffer;
295 osd->back_bitmap_stride = w;
296 osd->back_bitmap_data = buf;
298 osd->maxwidth = w;
299 osd->maxheight = h;
300 *bufsize = w * h;
302 DEBUGF("OSD (grey): addr(fb=%p bb=%p)\n", osd->lcd_bitmap_data,
303 osd->back_bitmap_data);
304 DEBUGF("OSD (grey): w=%d h=%d bufsz=%lu\n", w, h, (unsigned long)*bufsize);
306 return buf;
308 #endif /* LCD_DEPTH < 4*/
311 /** Common LCD routines **/
313 /* Draw the OSD image portion using the callback */
314 static void _osd_draw_osd_rect(struct osd *osd, int x, int y,
315 int width, int height)
317 osd->lcd_set_viewport(&osd->vp);
318 osd->draw_cb(x, y, width, height);
319 osd->lcd_set_viewport(NULL);
322 /* Draw the OSD image using the callback */
323 static void _osd_draw_osd(struct osd *osd)
325 _osd_draw_osd_rect(osd, 0, 0, osd->vp.width, osd->vp.height);
328 static void _osd_update_viewport(struct osd *osd)
330 osd->lcd_update_rect(osd->vp.x, osd->vp.y, osd->vp.width,
331 osd->vp.height);
334 /* Sync the backbuffer to the framebuffer image */
335 static void _osd_update_back_buffer(struct osd *osd)
337 /* Assume it's starting with default viewport for now */
338 osd->lcd_set_framebuffer(osd->back_bitmap_data);
339 #if LCD_DEPTH < 4
340 if (osd->lcd_framebuffer_set_pos)
341 osd->lcd_framebuffer_set_pos(0, 0, osd->maxwidth, osd->maxheight);
342 #endif /* LCD_DEPTH < 4 */
343 osd->lcd_bitmap_part(osd->lcd_bitmap_data, osd->vp.x, osd->vp.y,
344 osd->lcd_bitmap_stride, 0, 0, osd->vp.width,
345 osd->vp.height);
346 /* Assume it was on default framebuffer for now */
347 osd->lcd_set_framebuffer(NULL);
350 /* Erase the OSD to restore the framebuffer image */
351 static void _osd_erase_osd(struct osd *osd)
353 osd->lcd_bitmap_part(osd->back_bitmap_data, 0, 0, osd->back_bitmap_stride,
354 osd->vp.x, osd->vp.y, osd->vp.width, osd->vp.height);
357 /* Initialized the OSD and set its backbuffer */
358 static bool _osd_init(struct osd *osd, unsigned flags, void *backbuf,
359 size_t backbuf_size, osd_draw_cb_fn_t draw_cb,
360 int *width, int *height, size_t *bufused)
362 _osd_destroy(osd);
364 if (!draw_cb)
365 return false;
367 if (!backbuf)
368 return false;
370 void *backbuf_orig = backbuf; /* Save in case of ptr advance */
371 ALIGN_BUFFER(backbuf, backbuf_size, MAX(FB_DATA_SZ, 4));
373 if (!backbuf_size)
374 return false;
376 if (flags & OSD_INIT_MAJOR_HEIGHT)
378 if (!height || *height <= 0)
379 return false;
381 if ((flags & (OSD_INIT_MINOR_MIN | OSD_INIT_MINOR_MAX)) &&
382 (!width || *width <= 0))
384 return false;
387 else
389 if (!width || *width <= 0)
390 return false;
392 if ((flags & (OSD_INIT_MINOR_MIN | OSD_INIT_MINOR_MAX)) &&
393 (!height || *height <= 0))
395 return false;
399 /* Store requested sizes in max(width|height) */
400 if (width)
401 osd->maxwidth = *width;
402 else
403 osd->maxwidth = LCD_WIDTH;
405 if (height)
406 osd->maxheight = *height;
407 else
408 osd->maxheight = LCD_HEIGHT;
410 if (!osd->init_buffers(osd, flags, backbuf, &backbuf_size))
412 osd->maxwidth = osd->maxheight = 0;
413 return false;
416 osd->draw_cb = draw_cb;
418 if (bufused)
419 *bufused = backbuf_size + (backbuf_orig - backbuf);
421 if (width)
422 *width = osd->maxwidth;
424 if (height)
425 *height = osd->maxheight;
427 /* Set the default position to the whole thing */
428 osd->set_viewport_pos(&osd->vp, 0, 0, osd->maxwidth, osd->maxheight);
430 osd->status = OSD_HIDDEN; /* Ready when you are */
432 return true;
435 static void _osd_destroy(struct osd *osd)
437 _osd_show(osd, OSD_HIDE);
439 /* Set to essential defaults */
440 osd->status = OSD_DISABLED;
441 osd->set_viewport_pos(&osd->vp, 0, 0, 0, 0);
442 osd->maxwidth = osd->maxheight = 0;
443 osd->timeout = 0;
446 /* Redraw the entire OSD */
447 static bool _osd_update(struct osd *osd)
449 if (osd->status != OSD_VISIBLE)
450 return false;
452 _osd_draw_osd(osd);
453 _osd_update_viewport(osd);
454 return true;
457 /* Show/Hide the OSD on screen */
458 static bool _osd_show(struct osd *osd, unsigned flags)
460 if (flags & OSD_SHOW)
462 switch (osd->status)
464 case OSD_DISABLED:
465 break; /* No change */
467 case OSD_HIDDEN:
468 _osd_update_back_buffer(osd);
469 osd->status = OSD_VISIBLE;
470 _osd_update(osd);
471 osd->hide_tick = *rb->current_tick + osd->timeout;
472 break;
474 case OSD_VISIBLE:
475 if (flags & OSD_UPDATENOW)
476 _osd_update(osd);
477 /* Fall-through */
478 case OSD_ERASED:
479 osd->hide_tick = *rb->current_tick + osd->timeout;
480 return true;
483 else
485 switch (osd->status)
487 case OSD_DISABLED:
488 case OSD_HIDDEN:
489 break;
491 case OSD_VISIBLE:
492 _osd_erase_osd(osd);
493 _osd_update_viewport(osd);
494 /* Fall-through */
495 case OSD_ERASED:
496 osd->status = OSD_HIDDEN;
497 return true;
501 return false;
504 /* Redraw part of the OSD (viewport-relative coordinates) */
505 static bool _osd_update_rect(struct osd *osd, int x, int y, int width,
506 int height)
508 if (osd->status != OSD_VISIBLE)
509 return false;
511 _osd_draw_osd_rect(osd, x, y, width, height);
513 int vp_x = osd->vp.x;
514 int vp_w = osd->vp.width;
516 if (x + width > vp_w)
517 width = vp_w - x;
519 if (x < 0)
521 width += x;
522 x = 0;
525 if (width <= 0)
526 return false;
528 int vp_y = osd->vp.y;
529 int vp_h = osd->vp.height;
531 if (y + height > vp_h)
532 height = vp_h - y;
534 if (y < 0)
536 height += y;
537 y = 0;
540 if (height <= 0)
541 return false;
543 osd->lcd_update_rect(vp_x + x, vp_y + y, width, height);
545 return true;
548 /* Set a new screen location and size (screen coordinates) */
549 static bool _osd_update_pos(struct osd *osd, int x, int y, int width,
550 int height)
552 if (osd->status == OSD_DISABLED)
553 return false;
555 if (width < 0)
556 width = 0;
557 else if (width > osd->maxwidth)
558 width = osd->maxwidth;
560 if (height < 0)
561 height = 0;
562 else if (height > osd->maxheight)
563 height = osd->maxheight;
565 int vp_x = osd->vp.x;
566 int vp_y = osd->vp.y;
567 int vp_w = osd->vp.width;
568 int vp_h = osd->vp.height;
570 if (x == vp_x && y == vp_y && width == vp_w && height == vp_h)
571 return false; /* No change */
573 if (osd->status != OSD_VISIBLE)
575 /* Not visible - just update pos */
576 osd->set_viewport_pos(&osd->vp, x, y, width, height);
577 return false;
580 /* Visible area has changed */
581 _osd_erase_osd(osd);
583 /* Update the smallest rectangle that encloses both the old and new
584 regions to make the change free of flicker (they may overlap) */
585 int xu = MIN(vp_x, x);
586 int yu = MIN(vp_y, y);
587 int wu = MAX(vp_x + vp_w, x + width) - xu;
588 int hu = MAX(vp_y + vp_h, y + height) - yu;
590 osd->set_viewport_pos(&osd->vp, x, y, width, height);
591 _osd_update_back_buffer(osd);
592 _osd_draw_osd(osd);
593 osd->lcd_update_rect(xu, yu, wu, hu);
595 return true;
598 /* Call periodically to have the OSD timeout and hide itself */
599 static void _osd_monitor_timeout(struct osd *osd)
601 if (osd->status <= OSD_HIDDEN)
602 return; /* Already hidden/disabled */
604 if (osd->timeout > 0 && TIME_AFTER(*rb->current_tick, osd->hide_tick))
605 _osd_show(osd, OSD_HIDE);
608 /* Set the OSD timeout value. <= 0 = never timeout */
609 static void _osd_set_timeout(struct osd *osd, long timeout)
611 if (osd->status == OSD_DISABLED)
612 return;
614 osd->timeout = timeout;
615 _osd_monitor_timeout(osd);
618 /* Use the OSD viewport context */
619 static inline struct viewport * _osd_get_viewport(struct osd *osd)
621 return &osd->vp;
624 /* Get the maximum dimensions calculated by osd_init() */
625 static void _osd_get_max_dims(struct osd *osd,
626 int *maxwidth, int *maxheight)
628 if (maxwidth)
629 *maxwidth = osd->maxwidth;
631 if (maxheight)
632 *maxheight = osd->maxheight;
635 /* Is the OSD enabled? */
636 static inline bool _osd_enabled(struct osd *osd)
638 return osd->status != OSD_DISABLED;
642 /** LCD update substitutes **/
644 /* Prepare LCD framebuffer for regular drawing */
645 static inline void _osd_lcd_update_prepare(struct osd *osd)
647 if (osd->status == OSD_VISIBLE)
649 osd->status = OSD_ERASED;
650 _osd_erase_osd(osd);
654 /* Update the whole screen */
655 static inline void _osd_lcd_update(struct osd *osd)
657 if (osd->status == OSD_ERASED)
659 /* Save the screen image underneath and restore the OSD image */
660 osd->status = OSD_VISIBLE;
661 _osd_update_back_buffer(osd);
662 _osd_draw_osd(osd);
665 osd->lcd_update();
668 /* Update a part of the screen */
669 static void _osd_lcd_update_rect(struct osd *osd,
670 int x, int y, int width, int height)
672 if (osd->status == OSD_ERASED)
674 /* Save the screen image underneath and restore the OSD image */
675 osd->status = OSD_VISIBLE;
676 _osd_update_back_buffer(osd);
677 _osd_draw_osd(osd);
680 osd->lcd_update_rect(x, y, width, height);
683 /* Native LCD, public */
684 bool osd_init(unsigned flags, void *backbuf, size_t backbuf_size,
685 osd_draw_cb_fn_t draw_cb, int *width, int *height,
686 size_t *bufused)
688 native_osd.init_buffers = _osd_lcd_init_buffers;
689 native_osd.set_viewport_pos = _osd_lcd_viewport_set_pos;
690 native_osd.lcd_update = rb->lcd_update;
691 native_osd.lcd_update_rect = rb->lcd_update_rect;
692 native_osd.lcd_set_viewport = rb->lcd_set_viewport;
693 native_osd.lcd_set_framebuffer = (void *)rb->lcd_set_framebuffer;
694 #if LCD_DEPTH < 4
695 native_osd.lcd_framebuffer_set_pos = NULL;
696 #endif /* LCD_DEPTH < 4 */
697 native_osd.lcd_bitmap_part = (void *)rb->lcd_bitmap_part;
699 return _osd_init(&native_osd, flags, backbuf, backbuf_size, draw_cb,
700 width, height, bufused);
703 void osd_destroy(void)
705 return _osd_destroy(&native_osd);
708 bool osd_show(unsigned flags)
710 return _osd_show(&native_osd, flags);
713 bool osd_update(void)
715 return _osd_update(&native_osd);
718 bool osd_update_rect(int x, int y, int width, int height)
720 return _osd_update_rect(&native_osd, x, y, width, height);
723 bool osd_update_pos(int x, int y, int width, int height)
725 return _osd_update_pos(&native_osd, x, y, width, height);
728 void osd_monitor_timeout(void)
730 _osd_monitor_timeout(&native_osd);
733 void osd_set_timeout(long timeout)
735 _osd_set_timeout(&native_osd, timeout);
738 struct viewport * osd_get_viewport(void)
740 return _osd_get_viewport(&native_osd);
743 void osd_get_max_dims(int *maxwidth, int *maxheight)
745 _osd_get_max_dims(&native_osd, maxwidth, maxheight);
748 bool osd_enabled(void)
750 return _osd_enabled(&native_osd);
753 void osd_lcd_update_prepare(void)
755 _osd_lcd_update_prepare(&native_osd);
759 void osd_lcd_update(void)
761 _osd_lcd_update(&native_osd);
764 void osd_lcd_update_rect(int x, int y, int width, int height)
766 _osd_lcd_update_rect(&native_osd, x, y, width, height);
769 #if LCD_DEPTH < 4
770 /* Greylib LCD, public */
771 bool osd_grey_init(unsigned flags, void *backbuf, size_t backbuf_size,
772 osd_draw_cb_fn_t draw_cb, int *width, int *height,
773 size_t *bufused)
775 grey_osd.init_buffers = _osd_grey_init_buffers;
776 grey_osd.set_viewport_pos = grey_viewport_set_pos;
777 grey_osd.lcd_update = grey_update;
778 grey_osd.lcd_update_rect = grey_update_rect;
779 grey_osd.lcd_set_viewport = grey_set_viewport;
780 grey_osd.lcd_set_framebuffer = (void *)grey_set_framebuffer;
781 grey_osd.lcd_framebuffer_set_pos = grey_framebuffer_set_pos;
782 grey_osd.lcd_bitmap_part = (void *)grey_gray_bitmap_part;
784 return _osd_init(&grey_osd, flags, backbuf, backbuf_size, draw_cb,
785 width, height, bufused);
788 void osd_grey_destroy(void)
790 return _osd_destroy(&grey_osd);
793 bool osd_grey_show(unsigned flags)
795 return _osd_show(&grey_osd, flags);
798 bool osd_grey_update(void)
800 return _osd_update(&grey_osd);
803 bool osd_grey_update_rect(int x, int y, int width, int height)
805 return _osd_update_rect(&grey_osd, x, y, width, height);
808 bool osd_grey_update_pos(int x, int y, int width, int height)
810 return _osd_update_pos(&grey_osd, x, y, width, height);
813 void osd_grey_monitor_timeout(void)
815 _osd_monitor_timeout(&grey_osd);
818 void osd_grey_set_timeout(long timeout)
820 _osd_set_timeout(&grey_osd, timeout);
823 struct viewport * osd_grey_get_viewport(void)
825 return _osd_get_viewport(&grey_osd);
828 void osd_grey_get_max_dims(int *maxwidth, int *maxheight)
830 _osd_get_max_dims(&grey_osd, maxwidth, maxheight);
833 bool osd_grey_enabled(void)
835 return _osd_enabled(&grey_osd);
838 void osd_grey_lcd_update_prepare(void)
840 _osd_lcd_update_prepare(&grey_osd);
843 void osd_grey_lcd_update(void)
845 _osd_lcd_update(&grey_osd);
848 void osd_grey_lcd_update_rect(int x, int y, int width, int height)
850 _osd_lcd_update_rect(&grey_osd, x, y, width, height);
852 #endif /* LCD_DEPTH < 4 */