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) \
80 maug_mlock( (win)->gui_h, (win)->gui_p ); \
81 maug_cleanup_if_null_lock( struct RETROGUI*, (win)->gui_p ); \
82 (win)->flags |= RETROWIN_FLAG_GUI_LOCKED; \
87#define retrowin_unlock_gui( win ) \
89 RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
90 RETROWIN_FLAG_GUI_LOCKED == (RETROWIN_FLAG_GUI_LOCKED & (win)->flags) \
94 maug_munlock( (win)->gui_h, (win)->gui_p ); \
95 (win)->flags &= ~RETROWIN_FLAG_GUI_LOCKED; \
105 retroflat_blit_t gui_bmp;
127void retrowin_free_win(
struct RETROWIN* win );
129ssize_t retrowin_get_by_idc(
size_t idc,
struct MDATA_VECTOR* win_stack );
141 size_t idc,
const char* font_filename,
142 size_t x,
size_t y,
size_t w,
size_t h, uint8_t flags );
158 RETROWIN_FLAG_INIT_GUI != (RETROWIN_FLAG_INIT_GUI & win->flags) ||
159 RETROWIN_FLAG_GUI_LOCKED == (RETROWIN_FLAG_GUI_LOCKED & win->flags) );
161 switch( RETROWIN_FLAG_BORDER_MASK & win->flags ) {
162 case RETROWIN_FLAG_BORDER_NONE:
164 win->gui_p->draw_bmp, RETROFLAT_COLOR_BLACK,
166 retroflat_2d_bitmap_w( win->gui_p->draw_bmp ),
167 retroflat_2d_bitmap_h( win->gui_p->draw_bmp ),
171 case RETROWIN_FLAG_BORDER_GRAY:
173 win->gui_p->draw_bmp,
174 2 < retroflat_screen_colors() ?
175 RETROFLAT_COLOR_GRAY : RETROFLAT_COLOR_WHITE, 0, 0,
176 retroflat_2d_bitmap_w( win->gui_p->draw_bmp ),
177 retroflat_2d_bitmap_h( win->gui_p->draw_bmp ),
182 win->gui_p->draw_bmp,
183 2 < retroflat_screen_colors() ?
185 retroflat_2d_bitmap_w( win->gui_p->draw_bmp ),
186 retroflat_2d_bitmap_h( win->gui_p->draw_bmp ),
188 if( 2 < retroflat_screen_colors() ) {
191 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
192 1, 1, retroflat_2d_bitmap_w( win->gui_p->draw_bmp ) - 2, 1, 0 );
194 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
195 1, 2, 1, retroflat_2d_bitmap_h( win->gui_p->draw_bmp ) - 3, 0 );
199 case RETROWIN_FLAG_BORDER_BLUE:
201 win->gui_p->draw_bmp,
202 2 < retroflat_screen_colors() ?
203 RETROFLAT_COLOR_BLUE : RETROFLAT_COLOR_BLACK, 0, 0,
204 retroflat_2d_bitmap_w( win->gui_p->draw_bmp ),
205 retroflat_2d_bitmap_h( win->gui_p->draw_bmp ),
210 win->gui_p->draw_bmp,
211 2 < retroflat_screen_colors() ?
213 retroflat_2d_bitmap_w( win->gui_p->draw_bmp ) - 4,
214 retroflat_2d_bitmap_h( win->gui_p->draw_bmp ) - 4,
217 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE, 1, 1,
218 retroflat_2d_bitmap_w( win->gui_p->draw_bmp ) - 2,
219 retroflat_2d_bitmap_h( win->gui_p->draw_bmp ) - 2,
222 win->gui_p->draw_bmp,
223 2 < retroflat_screen_colors() ?
225 retroflat_2d_bitmap_w( win->gui_p->draw_bmp ),
226 retroflat_2d_bitmap_h( win->gui_p->draw_bmp ),
240 RETROWIN_FLAG_INIT_GUI != (RETROWIN_FLAG_INIT_GUI & win->flags) ||
241 RETROWIN_FLAG_GUI_LOCKED == (RETROWIN_FLAG_GUI_LOCKED & win->flags) );
243 retroflat_2d_lock_bitmap( &(win->gui_bmp) );
246 win->gui_p->draw_bmp = &(win->gui_bmp);
248 debug_printf( RETROWIN_TRACE_LVL,
249 "redrawing window " SIZE_T_FMT
" (GUI %p)...", win->idc, win->gui_p );
251 _retrowin_draw_border( win );
259 retval = retrogui_redraw_ctls( win->gui_p );
260 win->gui_p->x = win->x;
261 win->gui_p->y = win->y;
262 maug_cleanup_if_not_ok();
264 retroflat_2d_release_bitmap( &(win->gui_bmp) );
278 if( 0 == mdata_vector_ct( win_stack ) ) {
282 assert( !mdata_vector_is_locked( win_stack ) );
283 mdata_vector_lock( win_stack );
285 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
286 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
287 assert( NULL != win );
289 if( !retrowin_win_is_active( win ) ) {
293 retrowin_lock_gui( win );
296 if( RETROGUI_FLAGS_DIRTY == (RETROGUI_FLAGS_DIRTY & win->gui_p->flags) ) {
297 debug_printf( RETROWIN_TRACE_LVL,
298 "redrawing window idx " SIZE_T_FMT
", IDC " SIZE_T_FMT,
302 retval = _retrowin_redraw_win( win );
303 maug_cleanup_if_not_ok();
309 retval = retroflat_2d_blit_win(
310 &(win->gui_bmp), win->gui_p->x, win->gui_p->y );
312 retrowin_unlock_gui( win );
317 mdata_vector_unlock( win_stack );
329 if( 0 == mdata_vector_ct( win_stack ) ) {
333 assert( !mdata_vector_is_locked( win_stack ) );
334 mdata_vector_lock( win_stack );
336 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
337 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
338 assert( NULL != win );
340 if( !retrowin_win_is_active( win ) ) {
344 retrowin_lock_gui( win );
346 debug_printf( RETROWIN_TRACE_LVL,
347 "refreshing window idx " SIZE_T_FMT
", IDC " SIZE_T_FMT,
350 win->gui_p->flags |= RETROGUI_FLAGS_DIRTY;
352 retrowin_unlock_gui( win );
357 mdata_vector_unlock( win_stack );
372 ssize_t win_idx = -1;
374 if( !mdata_vector_is_locked( win_stack ) ) {
375 mdata_vector_lock( win_stack );
379 win_idx = retrowin_get_by_idc( idc_active, win_stack );
382 error_printf(
"polling invalid window!" );
386 win = mdata_vector_get( win_stack, win_idx,
struct RETROWIN );
387 assert( NULL != win );
388 assert( idc_active == win->idc );
389 if( !retrowin_win_is_active( win ) ) {
391 error_printf(
"polling inactive window!" );
395 retrowin_lock_gui( win );
396 if( 0 != *p_input ) {
397 debug_printf( RETROWIN_TRACE_LVL,
398 "polling window idx " SIZE_T_FMT
", IDC " RETROGUI_IDC_FMT,
402 retrowin_unlock_gui( win );
406 if( MERROR_OK != retval ) {
407 error_printf(
"error polling windows!" );
408 idc_out = RETROGUI_IDC_NONE;
412 mdata_vector_unlock( win_stack );
424 ssize_t idx_out = -1;
428 ssize_t win_idx = -1;
430 if( !mdata_vector_is_locked( win_stack ) ) {
431 mdata_vector_lock( win_stack );
435 win_idx = retrowin_get_by_idc( idc_win, win_stack );
438 error_printf(
"polling invalid window!" );
442 win = mdata_vector_get( win_stack, win_idx,
struct RETROWIN );
443 assert( NULL != win );
444 assert( idc_win == win->idc );
445 if( !retrowin_win_is_active( win ) ) {
447 error_printf(
"polling inactive window!" );
451 retrowin_lock_gui( win );
452 idx_out = retrogui_get_ctl_sel_idx( win->gui_p, idc_ctl );
453 retrowin_unlock_gui( win );
457 if( MERROR_OK != retval ) {
458 error_printf(
"error getting window control selection index!" );
459 idx_out = merror_retval_to_sz( retval );
463 mdata_vector_unlock( win_stack );
471void retrowin_free_win(
struct RETROWIN* win ) {
474 if( RETROWIN_FLAG_INIT_BMP == (RETROWIN_FLAG_INIT_BMP & win->flags) ) {
475 retroflat_2d_destroy_bitmap( &(win->gui_bmp) );
476 retrowin_lock_gui( win );
477 win->gui_p->draw_bmp = NULL;
478 retrowin_unlock_gui( win );
483 retrowin_lock_gui( win )
484 retrogui_destroy( win->gui_p );
485 retrowin_unlock_gui( win )
486 maug_mfree( win->gui_h );
491 if( MERROR_OK != retval ) {
492 error_printf(
"error while locking self-managed GUI! not freed!" );
495 maug_mzero( win,
sizeof(
struct RETROWIN ) );
500ssize_t retrowin_get_by_idc(
size_t idc,
struct MDATA_VECTOR* win_stack ) {
501 ssize_t idx_out = -1;
507 if( 0 == mdata_vector_ct( win_stack ) ) {
511 if( !mdata_vector_is_locked( win_stack ) ) {
512 mdata_vector_lock( win_stack );
516 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
517 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
518 if( idc == win->idc ) {
527 mdata_vector_unlock( win_stack );
530 if( MERROR_OK != retval ) {
531 idx_out = merror_retval_to_sz( retval );
541 size_t idc,
const char* font_filename,
542 size_t x,
size_t y,
size_t w,
size_t h, uint8_t flags
546 ssize_t idx_out = -1;
548 idx_out = retrowin_get_by_idc( idc, win_stack );
550 error_printf(
"window IDC " SIZE_T_FMT
" already exists!", idc );
554 maug_mzero( &win,
sizeof(
struct RETROWIN ) );
562 win.gui_h = maug_malloc( 1,
sizeof(
struct RETROGUI ) );
563 maug_cleanup_if_null_alloc( MAUG_MHANDLE, win.gui_h );
568 retrowin_lock_gui( &win );
570 retval = retrogui_init( win.gui_p );
571 maug_cleanup_if_not_ok();
574 maug_cleanup_if_not_ok();
577 retval = retroflat_2d_create_bitmap( w, h, &(win.gui_bmp), 0 );
578 maug_cleanup_if_not_ok();
580 win.flags |= RETROWIN_FLAG_INIT_BMP;
594 debug_printf( RETROWIN_TRACE_LVL,
595 "pushing window IDC " SIZE_T_FMT
", GUI %p: " SIZE_T_FMT
"x" SIZE_T_FMT
596 " @ " SIZE_T_FMT
", " SIZE_T_FMT,
598 win.gui_p->w, win.gui_p->h, win.gui_p->x, win.gui_p->y );
600 retrowin_unlock_gui( &win );
602 idx_out = mdata_vector_append( win_stack, &win,
sizeof(
struct RETROWIN ) );
610 "non-square window created; some systems may have trouble!" );
618 retrowin_unlock_gui( &win );
634 debug_printf( RETROWIN_TRACE_LVL,
635 "attempting to destroy window: " SIZE_T_FMT, idc );
637 if( !mdata_vector_is_locked( win_stack ) ) {
638 mdata_vector_lock( win_stack );
642 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
643 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
644 assert( NULL != win );
645 if( idc != win->idc ) {
649 if( !retrowin_win_is_active( win ) ) {
650 debug_printf( RETROWIN_TRACE_LVL,
651 "window IDC " SIZE_T_FMT
" found, but not active! (flags: 0x%02x)",
656 debug_printf( RETROWIN_TRACE_LVL,
"freeing window: " SIZE_T_FMT,
659 retrowin_free_win( win );
669 mdata_vector_unlock( win_stack );
671 mdata_vector_remove( win_stack, i_free );
673 mdata_vector_lock( win_stack );
680 mdata_vector_unlock( win_stack );
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19
#define RETROFLAT_FLAGS_FILL
Flag for retroflat_rect() or retroflat_ellipse(), indicating drawn shape should be filled.
Definition retroflt.h:373
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 char *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:292
#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:95
MERROR_RETVAL retrowin_refresh_win_stack(struct MDATA_VECTOR *win_stack)
Force all windows on the stack to redraw.
ssize_t retrowin_push_win(struct RETROGUI *gui, struct MDATA_VECTOR *win_stack, size_t idc, const char *font_filename, size_t x, size_t y, size_t w, size_t h, uint8_t flags)
Create a new window on the given win_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.
MERROR_RETVAL retrowin_destroy_win(struct MDATA_VECTOR *win_stack, size_t idc)
Destroy the given window's resources and remove it from the window 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:93
Definition retrogui.h:430