49#ifndef RETROWIN_TRACE_LVL
50# define RETROWIN_TRACE_LVL 0
58#define RETROWIN_FLAG_INIT_GUI 0x10
60#define RETROWIN_FLAG_INIT_BMP 0x20
62#define RETROWIN_FLAG_GUI_LOCKED 0x04
64#define RETROWIN_FLAG_BORDER_NONE 0x00
65#define RETROWIN_FLAG_BORDER_GRAY 0x01
66#define RETROWIN_FLAG_BORDER_BLUE 0x02
68#define retrowin_win_is_active( win ) \
69 (RETROWIN_FLAG_INIT_BMP == (RETROWIN_FLAG_INIT_BMP & (win)->flags))
71#define RETROWIN_FLAG_BORDER_MASK 0x03
73#define retrowin_lock_gui( win ) \
75 RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
76 RETROWIN_FLAG_GUI_LOCKED != (RETROWIN_FLAG_GUI_LOCKED & (win)->flags) \
78 maug_mlock( (win)->gui_h, (win)->gui_p ); \
79 maug_cleanup_if_null_lock( struct RETROGUI*, (win)->gui_p ); \
80 (win)->flags |= RETROWIN_FLAG_GUI_LOCKED; \
83#define retrowin_unlock_gui( win ) \
85 RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
86 RETROWIN_FLAG_GUI_LOCKED == (RETROWIN_FLAG_GUI_LOCKED & (win)->flags) \
88 maug_munlock( (win)->gui_h, (win)->gui_p ); \
89 (win)->flags &= ~RETROWIN_FLAG_GUI_LOCKED; \
92#define retrowin_gui_is_locked( win ) \
93 (RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
94 RETROWIN_FLAG_GUI_LOCKED == (RETROWIN_FLAG_GUI_LOCKED & (win)->flags))
103#ifndef RETROWIN_NO_BITMAP
104 retroflat_blit_t gui_bmp;
141void retrowin_free_win(
struct RETROWIN* win );
145ssize_t retrowin_get_by_idc(
176 uint8_t autolock_gui = 0;
178#if RETROWIN_TRACE_LVL > 0
179 debug_printf( RETROWIN_TRACE_LVL,
"drawing window border..." );
182 if( !retrowin_gui_is_locked( win ) ) {
183 retrowin_lock_gui( win );
187 switch( RETROWIN_FLAG_BORDER_MASK & win->flags ) {
188 case RETROWIN_FLAG_BORDER_NONE:
190 win->gui_p->draw_bmp, RETROFLAT_COLOR_BLACK,
198 case RETROWIN_FLAG_BORDER_GRAY:
200 win->gui_p->draw_bmp,
201 2 < retroflat_screen_colors() ?
202 RETROFLAT_COLOR_GRAY : RETROFLAT_COLOR_WHITE,
211 win->gui_p->draw_bmp,
212 2 < retroflat_screen_colors() ?
219 if( 2 < retroflat_screen_colors() ) {
222 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
225 win->gui_p->x + win->gui_p->w - 2,
229 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
233 win->gui_p->y + win->gui_p->h - 3,
238 case RETROWIN_FLAG_BORDER_BLUE:
240 win->gui_p->draw_bmp,
241 2 < retroflat_screen_colors() ?
242 RETROFLAT_COLOR_BLUE : RETROFLAT_COLOR_BLACK,
251 win->gui_p->draw_bmp,
252 2 < retroflat_screen_colors() ?
260 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
267 win->gui_p->draw_bmp,
268 2 < retroflat_screen_colors() ?
278#if RETROWIN_TRACE_LVL > 0
279 debug_printf( RETROWIN_TRACE_LVL,
"drawing window border complete!" );
285 retrowin_unlock_gui( win );
295 uint8_t autolock_gui = 0;
297 if( !retrowin_gui_is_locked( win ) ) {
298 retrowin_lock_gui( win );
304#ifdef RETROWIN_NO_BITMAP
305 win->gui_p->draw_bmp = NULL;
307 retroflat_2d_lock_bitmap( &(win->gui_bmp) );
308 win->gui_p->draw_bmp = &(win->gui_bmp);
311#if RETROWIN_TRACE_LVL > 0
312 debug_printf( RETROWIN_TRACE_LVL,
313 "redrawing window IDC " RETROGUI_IDC_FMT
" at "
314 PXXY_FMT
", " PXXY_FMT
"...",
315 win->idc, win->gui_p->x, win->gui_p->y );
318#ifndef RETROWIN_NO_BITMAP
326 retval = _retrowin_draw_border( win );
327 if( MERROR_OK == retval ) {
328 retval = retrogui_redraw_ctls( win->gui_p );
330#ifndef RETROWIN_NO_BITMAP
331 win->gui_p->x = win->x;
332 win->gui_p->y = win->y;
334 retroflat_2d_release_bitmap( &(win->gui_bmp) );
337 maug_cleanup_if_not_ok();
339#if RETROWIN_TRACE_LVL > 0
340 debug_printf( RETROWIN_TRACE_LVL,
341 "redraw of window IDC " RETROGUI_IDC_FMT
" at "
342 PXXY_FMT
", " PXXY_FMT
" complete!",
343 win->idc, win->gui_p->x, win->gui_p->y );
349 retrowin_unlock_gui( win );
361 uint8_t autolock_stack = 0;
363 if( 0 == mdata_vector_ct( win_stack ) ) {
367 if( !mdata_vector_is_locked( win_stack ) ) {
368 mdata_vector_lock( win_stack );
372 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
373 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
374 assert( NULL != win );
376 if( !retrowin_win_is_active( win ) ) {
380 retrowin_lock_gui( win );
382#ifndef RETROWIN_NO_BITMAP
384 RETROGUI_FLAGS_DIRTY == (RETROGUI_FLAGS_DIRTY & win->gui_p->flags)
387#if RETROWIN_TRACE_LVL > 0
388 debug_printf( RETROWIN_TRACE_LVL,
389 "redrawing window idx " SIZE_T_FMT
" with IDC " RETROGUI_IDC_FMT,
394 retval = _retrowin_redraw_win( win );
395 maug_cleanup_if_not_ok();
396#ifndef RETROWIN_NO_BITMAP
400#ifndef RETROWIN_NO_BITMAP
404 retval = retroflat_2d_blit_win(
405 &(win->gui_bmp), win->gui_p->x, win->gui_p->y );
408 retrowin_unlock_gui( win );
410#if RETROWIN_TRACE_LVL > 0
411 debug_printf( RETROWIN_TRACE_LVL,
412 "redraw of window idx " SIZE_T_FMT
" with IDC " RETROGUI_IDC_FMT
418#if RETROWIN_TRACE_LVL > 0
419 debug_printf( RETROWIN_TRACE_LVL,
"redraw of all windows complete!" );
424 if( autolock_stack ) {
425 mdata_vector_unlock( win_stack );
437 uint8_t autolock_stack = 0;
439 if( 0 == mdata_vector_ct( win_stack ) ) {
443 if( !mdata_vector_is_locked( win_stack ) ) {
444 mdata_vector_lock( win_stack );
448 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
449 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
450 assert( NULL != win );
452 if( !retrowin_win_is_active( win ) ) {
456 retrowin_lock_gui( win );
458#if RETROWIN_TRACE_LVL > 0
459 debug_printf( RETROWIN_TRACE_LVL,
460 "refreshing window idx " SIZE_T_FMT
" with IDC " RETROGUI_IDC_FMT,
464 win->gui_p->flags |= RETROGUI_FLAGS_DIRTY;
466 retrowin_unlock_gui( win );
471 if( autolock_stack ) {
472 mdata_vector_unlock( win_stack );
488 ssize_t win_idx = -1;
490 if( !mdata_vector_is_locked( win_stack ) ) {
491 mdata_vector_lock( win_stack );
495 win_idx = retrowin_get_by_idc( idc_active, win_stack );
498 error_printf(
"polling missing window!" );
503 win = mdata_vector_get( win_stack, win_idx,
struct RETROWIN );
504 assert( NULL != win );
505 assert( idc_active == win->idc );
506 if( !retrowin_win_is_active( win ) ) {
508 error_printf(
"polling uninitialized window!" );
513 retrowin_lock_gui( win );
514 if( 0 != *p_input ) {
515#if RETROWIN_TRACE_LVL > 0
516 debug_printf( RETROWIN_TRACE_LVL,
517 "polling window idx " SIZE_T_FMT
" with IDC " RETROGUI_IDC_FMT,
522 retrowin_unlock_gui( win );
526 if( MERROR_OK != retval ) {
527 error_printf(
"error polling windows!" );
528 idc_out = merror_retval_to_sz( retval );
532 mdata_vector_unlock( win_stack );
544 ssize_t idx_out = -1;
548 ssize_t win_idx = -1;
550 if( !mdata_vector_is_locked( win_stack ) ) {
551 mdata_vector_lock( win_stack );
555 win_idx = retrowin_get_by_idc( idc_win, win_stack );
558 error_printf(
"polling invalid window!" );
562 win = mdata_vector_get( win_stack, win_idx,
struct RETROWIN );
563 assert( NULL != win );
564 assert( idc_win == win->idc );
565 if( !retrowin_win_is_active( win ) ) {
567 error_printf(
"polling inactive window!" );
571 retrowin_lock_gui( win );
572 idx_out = retrogui_get_ctl_sel_idx( win->gui_p, idc_ctl );
573 retrowin_unlock_gui( win );
577 if( MERROR_OK != retval ) {
578 error_printf(
"error getting window control selection index!" );
579 idx_out = merror_retval_to_sz( retval );
583 mdata_vector_unlock( win_stack );
591void retrowin_free_win(
struct RETROWIN* win ) {
594 if( RETROWIN_FLAG_INIT_BMP == (RETROWIN_FLAG_INIT_BMP & win->flags) ) {
595#ifndef RETROWIN_NO_BITMAP
596 retroflat_2d_destroy_bitmap( &(win->gui_bmp) );
598 retrowin_lock_gui( win );
599 win->gui_p->draw_bmp = NULL;
600 retrowin_unlock_gui( win );
605 retrowin_lock_gui( win )
606 retrogui_destroy( win->gui_p );
607 retrowin_unlock_gui( win )
608 maug_mfree( win->gui_h );
613 if( MERROR_OK != retval ) {
614 error_printf(
"error while locking self-managed GUI! not freed!" );
617 maug_mzero( win,
sizeof(
struct RETROWIN ) );
626 if( 0 < mdata_vector_ct( win_stack ) ) {
627 mdata_vector_lock( win_stack );
628 while( 0 < mdata_vector_ct( win_stack ) ) {
629 win = mdata_vector_get( win_stack, 0,
struct RETROWIN );
630 assert( NULL != win );
631 retrowin_free_win( win );
632 mdata_vector_unlock( win_stack );
633 mdata_vector_remove( win_stack, 0 );
634 mdata_vector_lock( win_stack );
636 mdata_vector_unlock( win_stack );
638 mdata_vector_free( win_stack );
647ssize_t retrowin_get_by_idc(
650 ssize_t idx_out = -1;
656 if( 0 == mdata_vector_ct( win_stack ) ) {
660 if( !mdata_vector_is_locked( win_stack ) ) {
661 mdata_vector_lock( win_stack );
665 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
666 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
667 if( idc == win->idc ) {
676 mdata_vector_unlock( win_stack );
679 if( MERROR_OK != retval ) {
680 idx_out = merror_retval_to_sz( retval );
696 ssize_t idx_out = -1;
698 if( RETROGUI_IDC_NONE >= idc ) {
699 error_printf(
"invalid IDC: %d", idc );
706 retroflat_screen_w() < x + w || retroflat_screen_h() < y + h
708 error_printf(
"attempting to create window with IDC " RETROGUI_IDC_FMT
709 " offscreen at %d, %d (%d x %d)", idc, x, y, w, h );
714 idx_out = retrowin_get_by_idc( idc, win_stack );
717 "window with IDC " RETROGUI_IDC_FMT
" already exists!", idc );
722 maug_mzero( &win,
sizeof(
struct RETROWIN ) );
729#if RETROWIN_TRACE_LVL > 0
730 debug_printf( RETROWIN_TRACE_LVL,
731 "creating self-owned GUI for window with IDC " RETROGUI_IDC_FMT
": "
732 PXXY_FMT
"x" PXXY_FMT
" @ " PXXY_FMT
", " PXXY_FMT,
737 maug_malloc_test( win.gui_h, 1,
sizeof(
struct RETROGUI ) );
741 debug_printf( RETROWIN_TRACE_LVL,
"x0" );
744 retrowin_lock_gui( &win );
746 debug_printf( RETROWIN_TRACE_LVL,
"x1" );
748 retval = retrogui_init( win.gui_p );
749 maug_cleanup_if_not_ok();
751 debug_printf( RETROWIN_TRACE_LVL,
"x2" );
754 maug_cleanup_if_not_ok();
756 debug_printf( RETROWIN_TRACE_LVL,
"x3" );
759#ifndef RETROWIN_NO_BITMAP
760 retval = retroflat_2d_create_bitmap(
761 w, h, &(win.gui_bmp),
763 maug_cleanup_if_not_ok_msg(
"error creating window bitmap!" );
766 win.flags |= RETROWIN_FLAG_INIT_BMP;
780#if RETROWIN_TRACE_LVL > 0
781 debug_printf( RETROWIN_TRACE_LVL,
782 "pushing window with IDC " RETROGUI_IDC_FMT
": "
783 PXXY_FMT
"x" PXXY_FMT
" @ " PXXY_FMT
", " PXXY_FMT,
784 win.idc, win.gui_p->w, win.gui_p->h, win.gui_p->x, win.gui_p->y );
787 retrowin_unlock_gui( &win );
789 idx_out = mdata_vector_append( win_stack, &win,
sizeof(
struct RETROWIN ) );
797 "non-square window created; some systems may have trouble!" );
805 retrowin_unlock_gui( &win );
821#if RETROWIN_TRACE_LVL > 0
822 debug_printf( RETROWIN_TRACE_LVL,
823 "attempting to destroy window with IDC " RETROGUI_IDC_FMT, idc );
826 if( !mdata_vector_is_locked( win_stack ) ) {
827 mdata_vector_lock( win_stack );
831 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
832 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
833 assert( NULL != win );
834 if( idc != win->idc ) {
838 if( !retrowin_win_is_active( win ) ) {
839#if RETROWIN_TRACE_LVL > 0
840 debug_printf( RETROWIN_TRACE_LVL,
841 "window with IDC " RETROGUI_IDC_FMT
842 " found, but not active! (flags: 0x%02x)",
848#if RETROWIN_TRACE_LVL > 0
849 debug_printf( RETROWIN_TRACE_LVL,
850 "freeing window with IDC " RETROGUI_IDC_FMT, win->idc );
853 retrowin_free_win( win );
863 mdata_vector_unlock( win_stack );
865 mdata_vector_remove( win_stack, i_free );
867 mdata_vector_lock( win_stack );
874 mdata_vector_unlock( win_stack );
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:28
char maug_path[MAUG_PATH_SZ_MAX]
Path/name used to load an asset from disk or access other files.
Definition mfile.h:138
#define RETROFLAT_BITMAP_FLAG_OPAQUE
Flag for retroflat_create_bitmap() or retroflat_load_bitmap() to create or load a bitmap without tran...
Definition retroflt.h:575
#define RETROFLAT_DRAW_FLAG_FILL
Flag for retroflat_rect() or retroflat_ellipse(), indicating drawn shape should be filled.
Definition retroflt.h:376
int16_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition retroflt.h:925
retrogui_idc_t retrogui_poll_ctls(struct RETROGUI *gui, RETROFLAT_IN_KEY *p_input, struct RETROFLAT_INPUT *input_evt)
Poll for the last clicked control and maintain listboxes and menus.
MERROR_RETVAL retrogui_set_font(struct RETROGUI *gui, const maug_path font_path)
Load the RetroFont API for the given RETROGUI to draw its controls with. Use RetroGXCache API if avai...
int16_t retrogui_idc_t
Unique identifying constant number for controls.
Definition retrogui.h:330
#define RETROGUI_COLOR_BORDER
RetroGUI will try to use this color on non-monochrome systems instead of black to draw things like bo...
Definition retrogui.h:93
retrogui_idc_t retrowin_poll_win_stack(struct MDATA_VECTOR *win_stack, retrogui_idc_t idc_active, RETROFLAT_IN_KEY *p_input, struct RETROFLAT_INPUT *input_evt)
Given the outputs of the input poller, check the controls on the active window to see if the inputs t...
MERROR_RETVAL retrowin_refresh_win_stack(struct MDATA_VECTOR *win_stack)
Force all windows on the stack to redraw.
MERROR_RETVAL retrowin_destroy_win(struct MDATA_VECTOR *win_stack, retrogui_idc_t idc)
Destroy the given window's resources and remove it from the window stack.
ssize_t retrowin_get_win_stack_sel_idx(struct MDATA_VECTOR *win_stack, retrogui_idc_t idc_win, retrogui_idc_t idc_ctl)
Get the selected index of the given control in the given window from the window stack.
ssize_t retrowin_push_win(struct RETROGUI *gui, struct MDATA_VECTOR *win_stack, retrogui_idc_t idc, const maug_path font_filename, retroflat_pxxy_t x, retroflat_pxxy_t y, retroflat_pxxy_t w, retroflat_pxxy_t h, uint8_t flags)
Create a new window on the given win_stack.
#define RETROWIN_FLAG_INIT_GUI
Flag for RETROWIN::flags indicating RETROWIN::gui_p should be locked from RETROWIN::gui_h before use.
Definition retrowin.h:58
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:108
Definition retrogui.h:468