Skip to content

Commit 3e913fb

Browse files
committed
OSD/OSK: quality of life improvements #435
* Android "back" button can exit from OSK, exit from menu and back in the menu system * "Zoomed" version of the current key hovered is displayed to be able to use OSK without an eagle-eyesight
1 parent 3822b44 commit 3e913fb

File tree

4 files changed

+83
-21
lines changed

4 files changed

+83
-21
lines changed

xemu/emutools.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,10 @@ int xemu_post_init (
13001300
#if defined(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK) && defined(XEMU_ARCH_MAC)
13011301
# warning "Activating workaround for lame newer Apple notebooks (no right click on touchpads)"
13021302
SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1"); // 1 = enable CTRL + click = right click (needed for modern Mac touchpads, it seems)
1303+
#endif
1304+
#if defined(SDL_HINT_ANDROID_TRAP_BACK_BUTTON) && defined(XEMU_ARCH_ANDROID)
1305+
# warning "BACK button trap has been activated."
1306+
SDL_SetHint(SDL_HINT_ANDROID_TRAP_BACK_BUTTON, "1");
13031307
#endif
13041308
/* end of SDL hints section */
13051309
if (sdl_default_win_x_pos == SDL_WINDOWPOS_UNDEFINED && sdl_default_win_y_pos == SDL_WINDOWPOS_UNDEFINED)

xemu/emutools_hid.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
2222
#endif
2323
#include "xemu/emutools_osk.h"
2424

25+
#if defined(XEMU_ARCH_ANDROID) && !defined(XEMU_OSK_SUPPORT)
26+
#error "Android builds needs XEMU_OSK_SUPPORT to be enabled."
27+
#endif
28+
2529

2630
/* Note: HID stands for "Human Input Devices" or something like that :)
2731
That is: keyboard, joystick, mouse.
@@ -589,6 +593,12 @@ int hid_handle_one_sdl_event ( SDL_Event *event )
589593
break;
590594
case SDL_KEYUP:
591595
case SDL_KEYDOWN:
596+
#ifdef XEMU_ARCH_ANDROID
597+
if (event->type == SDL_KEYDOWN && event->key.keysym.sym == SDLK_AC_BACK) { // Android "back" button
598+
osk_show(!osk_status());
599+
break;
600+
}
601+
#endif
592602
if (
593603
event->key.keysym.scancode != SDL_SCANCODE_UNKNOWN
594604
#ifdef CONFIG_KBD_SELECT_FOCUS

xemu/emutools_osk.c

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,24 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
2222
#include "xemu/emutools_osk.h"
2323
#include "xemu/emutools_hid.h"
2424

25+
// Do not change these, identifiers
2526
#define OSK_KEY_HIDE -100
2627
#define OSK_KEY_MENU -101
2728

28-
#define AUTO_RELEASE_MS 20
29+
// Release key after this amount of milliseconds (unless it's a toogle key)
30+
#define AUTO_RELEASE_MS 50
31+
// Zoom factor (>=1 integer) of the current key shown. Set to zero, to disable this feature
32+
#define ZOOM_FACTOR 3
2933

34+
// Colours (R,G,B,A) - 'A' being the alpha channel
3035
#define COLOUR_OUTLINE 0xFF, 0xFF, 0xFF, 0xFF
3136
#define COLOUR_TEXT 0xFF, 0xFF, 0xFF, 0xFF
3237
#define COLOUR_BG 0xFF, 0xFF, 0xFF, 0x80
3338
#define COLOUR_BGHOVER 0xFF, 0x00, 0x00, 0xFF
3439
#define COLOUR_BGPRESS 0x00, 0xFF, 0x00, 0xFF
3540
#define COLOUR_BGLOCKED 0x00, 0x00, 0xFF, 0xFF
3641

37-
#define RETURN_IF_NO_OSK() \
42+
#define RETURN_IF_NO_OSK() \
3843
if (!in_use || !tex) \
3944
return false;
4045

@@ -55,25 +60,38 @@ static int all_keys = 0;
5560
static int hovered = -1;
5661
static int last_pressed = -1;
5762
static Uint32 press_time;
63+
static struct { int x1, y1, x2, y2; } last_zoomed;
5864

5965

6066

61-
static void draw_text ( const char *s, int len, int xo, int yo, bool clear_too )
67+
static void draw_text ( const char *s, int len, int xo, int yo, int scale, bool clear_too )
6268
{
6369
while (len > 0) {
6470
const Uint8 *f = vga_font_8x8 + (*s) * 8;
65-
for (int y = yo; y < yo + 8; y++) {
66-
Uint32 *p = osk + y * size_x + xo;
67-
Uint8 c = *(f++);
68-
for (int x = 0; x < 8; x++, c <<= 1, p++)
69-
if (c & 0x80)
70-
*p = colour.text;
71-
else if (clear_too)
72-
*p = colour.bg;
73-
}
71+
for (int y = 0; y < 8; y++, f++)
72+
for (int ysc = 0; ysc < scale; ysc++) {
73+
Uint32 *p = osk + (y * scale + ysc + yo) * size_x + xo;
74+
Uint8 c = *f;
75+
for (int x = 0; x < 8; x++, c <<= 1)
76+
for (int xsc = 0; xsc < scale; xsc++, p++)
77+
if (c & 0x80)
78+
*p = colour.text;
79+
else if (clear_too)
80+
*p = colour.bg;
81+
}
7482
s++;
7583
len--;
76-
xo += 8;
84+
xo += 8 * scale;
85+
}
86+
}
87+
88+
89+
static void fill_rectangle ( const int x1, const int y1, const int x2, const int y2, const Uint32 sdl_colour )
90+
{
91+
for (int y = y1; y <= y2; y++) {
92+
Uint32 *p = osk + size_x * y + x1;
93+
for (int x = x1; x <= x2; x++)
94+
*p++ = sdl_colour;
7795
}
7896
}
7997

@@ -104,8 +122,26 @@ static void draw_key ( const int i, const bool active )
104122
s, l,
105123
(keys[i].x2 - keys[i].x1 - l * 8) / 2 + keys[i].x1,
106124
(keys[i].y2 - keys[i].y1 - 4 ) / 2 + keys[i].y1,
107-
false
125+
1, false
108126
);
127+
// Clearing/showing a "zoomed" version of the current key
128+
if (ZOOM_FACTOR > 0) {
129+
if (last_zoomed.x1 >= 0) {
130+
fill_rectangle(last_zoomed.x1, last_zoomed.y1, last_zoomed.x2, last_zoomed.y2, 0);
131+
last_zoomed.x1 = -1;
132+
}
133+
if (active) {
134+
// Also add 4 pix "border" (y will be 4 where text is positioned, etc)
135+
last_zoomed.x1 = (size_x - l * ZOOM_FACTOR * 8 - 2*4) / 2;
136+
last_zoomed.y1 = 0;
137+
last_zoomed.x2 = last_zoomed.x1 + l * ZOOM_FACTOR * 8 + 4;
138+
last_zoomed.y2 = ZOOM_FACTOR * 8 + 8;
139+
if (last_zoomed.x1 >= 0) {
140+
fill_rectangle(last_zoomed.x1, last_zoomed.y1, last_zoomed.x2, last_zoomed.y2, colour.bg);
141+
draw_text(s, l, last_zoomed.x1 + 4, last_zoomed.y1 + 4, ZOOM_FACTOR, false);
142+
}
143+
}
144+
}
109145
}
110146

111147

@@ -136,7 +172,7 @@ bool osk_mouse_movement_event ( const int x, const int y )
136172
#if 0
137173
char debug[100];
138174
sprintf(debug, "Mouse: %04d %04d", x, y);
139-
draw_text(debug, strlen(debug), 0, 40, true);
175+
draw_text(debug, strlen(debug), 0, 40, 2, true);
140176
#endif
141177
const int k = get_key_at_mouse(x, y);
142178
if (k != hovered) {
@@ -228,7 +264,7 @@ bool osk_render ( void )
228264
if (last_pressed >= 0 && SDL_GetTicks() - press_time >= AUTO_RELEASE_MS) {
229265
hid_sdl_synth_key_event(keys[last_pressed].p->key_id, 0);
230266
keys[last_pressed].pressed = false;
231-
//draw_key(last_pressed, false);
267+
draw_key(last_pressed, false); // so pressed key won't remain highlighted forever
232268
last_pressed = -1;
233269
}
234270
SDL_UpdateTexture(tex, NULL, osk, size_x * 4);
@@ -335,6 +371,7 @@ bool osk_init ( const struct osk_desc_st *desc, const int sx, const int sy, cons
335371
colour.bgpress = SDL_MapRGBA(sdl_pix_fmt, COLOUR_BGPRESS);
336372
colour.bglocked = SDL_MapRGBA(sdl_pix_fmt, COLOUR_BGLOCKED);
337373
calc_osk(desc);
374+
last_zoomed.x1 = -1;
338375
redraw_kbd();
339376
return true;
340377
error:

xemu/gui/gui_osd.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
2-
Copyright (C)2016-2022 LGB (Gábor Lénárt) <[email protected]>
2+
Copyright (C)2016-2022,2025 LGB (Gábor Lénárt) <[email protected]>
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -165,6 +165,11 @@ static int _osdgui_sdl_loop ( int need_rendering, SDL_Point *mousepos )
165165
case SDL_KEYUP:
166166
break;
167167
case SDL_KEYDOWN:
168+
#ifdef XEMU_ARCH_ANDROID
169+
if (event.key.keysym.sym == SDLK_AC_BACK) { // Android "BACK" button
170+
return OSDGUIKEY_LEFT; // means "back" in the menu structure
171+
}
172+
#endif
168173
for (int a = 0; scan2osdfunc[a].func >= 0; a++)
169174
if (scan2osdfunc[a].scan == event.key.keysym.scancode)
170175
return scan2osdfunc[a].func;
@@ -582,7 +587,8 @@ static void _osdgui_process_menu ( void )
582587
//space = 3;
583588
for (int need_rendering = 1;;) {
584589
int retev;
585-
const int options = (osdgui.menudepth ? OSDGUI_ITEMBROWSER_ALLOW_LEFT : 0) | OSDGUI_ITEMBROWSER_ALLOW_RIGHT | OSDGUI_ITEMBROWSER_ALLOW_F1;
590+
//const int options = (osdgui.menudepth ? OSDGUI_ITEMBROWSER_ALLOW_LEFT : 0) | OSDGUI_ITEMBROWSER_ALLOW_RIGHT | OSDGUI_ITEMBROWSER_ALLOW_F1;
591+
const int options = OSDGUI_ITEMBROWSER_ALLOW_LEFT | OSDGUI_ITEMBROWSER_ALLOW_RIGHT | OSDGUI_ITEMBROWSER_ALLOW_F1;
586592
int *selectedptr = &osdgui.menuselected[osdgui.menudepth];
587593
//static int _osdgui_do_browse_list_loop ( const char *textbuf[], const int all_items, const int page_items, int active_item, const int y, int need_rendering, int options, int *ev )
588594
*selectedptr = _osdgui_do_browse_list_loop(chooseptrs, attribs, items, space, *selectedptr, OSDGUI_MENU_Y, need_rendering, options, &retev);
@@ -604,9 +610,14 @@ static void _osdgui_process_menu ( void )
604610
return;
605611
}
606612
}
607-
if (retev == OSDGUIKEY_LEFT && osdgui.menudepth) { // previous menu
608-
osdgui.menudepth--;
609-
goto restart;
613+
if (retev == OSDGUIKEY_LEFT) { // previous menu
614+
if (osdgui.menudepth) {
615+
osdgui.menudepth--;
616+
goto restart;
617+
}
618+
#ifdef XEMU_ARCH_ANDROID
619+
retev = OSDGUIKEY_ESC; // trying to go to previous menu while in the main menu means leaving the menu
620+
#endif
610621
}
611622
if (retev == OSDGUIKEY_F1) { // go to main menu
612623
if (osdgui.menudepth) {

0 commit comments

Comments
 (0)