@@ -44,6 +44,30 @@ static SDL_Surface * gui_render_menu_legend_surface(struct gui_context * context
4444 return icon_circled_text (context -> fonts .small , context -> colors .legend .foreground , context -> colors .legend .background , gettext ("Menu" ), 0 , (localization_font_height () + SCREEN_MARGIN ) * context -> surfaces .scale_factor , (SCREEN_MARGIN >> 1 ) * context -> surfaces .scale_factor , icon_load ("hamburger.svg" , DEFAULT_BAR_ICON_HEIGHT * context -> surfaces .scale_factor , DEFAULT_BAR_ICON_HEIGHT * context -> surfaces .scale_factor , & context -> colors .legend .foreground ), 1 );
4545}
4646
47+ /**
48+ * @brief Renders the osk key surface.
49+ */
50+ static SDL_Surface * gui_render_osk_key (struct gui_context * context , const char * key , int index )
51+ {
52+ SDL_Surface * text_surface = TTF_RenderUTF8_Blended (context -> fonts .small , gettext (key ), SDL_ToSDLColor (context -> colors .osk .foreground ));
53+ SDL_Surface * surface = context -> surfaces .overlays .osk .surface ;
54+
55+ // Render the description text onto the surface
56+ SDL_Rect text_position ;
57+ int x = surface -> w / OSK_COLS ;
58+ int y = surface -> h / OSK_ROWS ;
59+
60+ text_position .x = x * (index % OSK_COLS ) + ((x - text_surface -> w ) >> 1 );
61+ text_position .y = y * (index / OSK_COLS | 0 ) + ((y - text_surface -> h ) >> 1 );
62+ text_position .w = text_surface -> w ;
63+ text_position .h = text_surface -> h ;
64+
65+ SDL_BlitSurfaceAlpha (text_surface , NULL , surface , & text_position );
66+
67+ // Free the description text surface
68+ SDL_FreeSurface (text_surface );
69+ }
70+
4771/**
4872 * @brief Triggers the invalidate callback.
4973 */
@@ -412,7 +436,7 @@ struct gui_context * gui_create_context(int argc, char * argv[])
412436 }
413437
414438 // Create a 32bpp double-buffered screen surface
415- context -> surfaces .screen = SDL_SetVideoMode (info -> current_w , info -> current_h , 32 , SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN );
439+ context -> surfaces .screen = SDL_SetVideoMode (SCALING_REFERENCE_WIDTH , SCALING_REFERENCE_HEIGHT , 32 , SDL_HWSURFACE | SDL_DOUBLEBUF );
416440
417441 // If 32bpp isn't available...
418442 if (context -> surfaces .screen == NULL )
@@ -463,6 +487,14 @@ struct gui_context * gui_create_context(int argc, char * argv[])
463487 GET_RGB_COMPONENTS (context -> colors .notch .foreground , r , g , b );
464488 context -> colors .notch .foreground = SDL_MapRGB (context -> surfaces .screen -> format , r , g , b );
465489
490+ // Set the osk background color
491+ GET_RGB_COMPONENTS (context -> colors .osk .background , r , g , b );
492+ context -> colors .osk .background = SDL_MapRGB (context -> surfaces .screen -> format , r , g , b );
493+
494+ // Set the osk foreground color
495+ GET_RGB_COMPONENTS (context -> colors .osk .foreground , r , g , b );
496+ context -> colors .osk .foreground = SDL_MapRGB (context -> surfaces .screen -> format , r , g , b );
497+
466498 // Calculate the scale factor
467499 context -> surfaces .scale_factor = SCALE_FACTOR_HEIGHT (context -> surfaces .screen -> h , SCALING_REFERENCE_HEIGHT );
468500
@@ -556,6 +588,16 @@ struct gui_context * gui_create_context(int argc, char * argv[])
556588 goto free_menu_action_surface ;
557589 }
558590
591+ // Render the osk overlay
592+ context -> surfaces .overlays .osk .surface = icon_rounded_rectangle (context -> surfaces .screen -> w , context -> surfaces .screen -> h >> 1 , 1 , & context -> colors .notch .background );
593+
594+ // We failed to render the osk overlay
595+ if (context -> surfaces .overlays .osk .surface == NULL )
596+ {
597+ // No use continuing if we're missing overlays
598+ goto free_notch_overlay_surface ;
599+ }
600+
559601 // Calculate the garlic icon position
560602 context -> surfaces .bars .top .logo .position .x = SCREEN_MARGIN * context -> surfaces .scale_factor ;
561603 context -> surfaces .bars .top .logo .position .y = SCREEN_MARGIN * context -> surfaces .scale_factor ;
@@ -586,12 +628,23 @@ struct gui_context * gui_create_context(int argc, char * argv[])
586628 context -> surfaces .overlays .notch .position .w = context -> surfaces .overlays .notch .surface -> w ;
587629 context -> surfaces .overlays .notch .position .h = context -> surfaces .overlays .notch .surface -> h ;
588630
631+ // Calculate the osk overlay position
632+ context -> surfaces .overlays .osk .position .x = 0 ;
633+ context -> surfaces .overlays .osk .position .y = context -> surfaces .screen -> h - context -> surfaces .overlays .osk .surface -> h ;
634+ context -> surfaces .overlays .osk .position .w = context -> surfaces .overlays .osk .surface -> w ;
635+ context -> surfaces .overlays .osk .position .h = context -> surfaces .overlays .osk .surface -> h ;
636+
637+ for (int i = 0 , n = OSK_COLS * OSK_ROWS ; i < n ; i ++ )
638+ {
639+ gui_render_osk_key (context , lowercase_grid [i ], i );
640+ }
641+
589642#ifndef __MACOSX__
590643 // We couldn't enumerate the joysticks
591644 if (SDL_NumJoysticks () <= 0 )
592645 {
593646 // No use going further if we have no way of controlling the UI
594- goto free_notch_overlay_surface ;
647+ goto free_osk_overlay_surface ;
595648 }
596649
597650 // Open the internal joystick
@@ -692,6 +745,10 @@ struct gui_context * gui_create_context(int argc, char * argv[])
692745 SDL_JoystickClose (context -> inputs .internal .joystick );
693746#endif
694747
748+ free_osk_overlay_surface :
749+ // Free the osk overlay
750+ SDL_FreeSurface (context -> surfaces .overlays .osk .surface );
751+
695752free_notch_overlay_surface :
696753 // Free the notch overlay
697754 SDL_FreeSurface (context -> surfaces .overlays .notch .surface );
@@ -1512,8 +1569,15 @@ void gui_update(struct gui_context * context)
15121569 active_context_menu = active_context_menu -> parent ;
15131570 }
15141571
1572+ // We're currently inside an OSK
1573+ if (context -> osk_active )
1574+ {
1575+ // Deactivate the OSK
1576+ context -> osk_active = 0 ;
1577+ }
1578+
15151579 // We're currently inside a context menu
1516- if (active_context_menu != NULL )
1580+ else if (active_context_menu != NULL )
15171581 {
15181582 // Get the context menu
15191583 struct gui_node * context_menu = context -> menu .active ;
@@ -1820,6 +1884,13 @@ void gui_render(struct gui_context * context)
18201884 SDL_BlitSurface (context -> surfaces .bars .bottom .actions .menu .surface , NULL , context -> surfaces .screen , & context -> surfaces .bars .bottom .actions .menu .position );
18211885 }
18221886
1887+ // We need to render the osk
1888+ if (context -> osk_active )
1889+ {
1890+ // Render the osk
1891+ SDL_BlitSurface (context -> surfaces .overlays .osk .surface , NULL , context -> surfaces .screen , & context -> surfaces .overlays .osk .position );
1892+ }
1893+
18231894 // Flip the front and back buffer
18241895 SDL_Flip (context -> surfaces .screen );
18251896}
@@ -1844,6 +1915,8 @@ void gui_read_configuration(struct gui_context * context)
18441915 context -> colors .icon .foreground = 0x000000 ;
18451916 context -> colors .notch .background = 0x000000 ;
18461917 context -> colors .notch .foreground = 0xffffff ;
1918+ context -> colors .osk .background = 0x000000 ;
1919+ context -> colors .osk .foreground = 0xffffff ;
18471920
18481921 // We managed to load the XML document
18491922 if (document != NULL )
@@ -1957,6 +2030,12 @@ void gui_read_configuration(struct gui_context * context)
19572030 // Get the notch foreground color
19582031 context -> colors .notch .foreground = io_get_skin_color (document , "Notch" , "Foreground" , 0xffffff );
19592032
2033+ // Get the osk background color
2034+ context -> colors .osk .background = io_get_skin_color (document , "Keyboard" , "Background" , 0x000000 );
2035+
2036+ // Get the osk foreground color
2037+ context -> colors .osk .foreground = io_get_skin_color (document , "Keyboard" , "Foreground" , 0xffffff );
2038+
19602039 // Free the XML document
19612040 xmlFreeDoc (document );
19622041 }
0 commit comments