Refactor SDL/FreeRTOS implementation to support macOS simulator properly (#653)
- Run SDL from main() and place FreeRTOS in separate thread. This fixes macOS support. - Updated GitHub Actions to publish macOS simulator build for testing, updated amd64 to x86_64 for consistent naming.
This commit is contained in:
committed by
Adolfo Reyna
parent
89e8baf517
commit
72089f74f3
@@ -7,11 +7,16 @@
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t KEY_QUEUE_CAPACITY = 32;
|
||||
|
||||
// Written by sdl_input_pump() on the real main thread, read by sdl_input_get_pointer_state()/
|
||||
// sdl_input_pop_key()/sdl_input_has_queued_key() on the lvgl task.
|
||||
std::mutex state_mutex;
|
||||
|
||||
SdlPointerState pointer_state = { 0, 0, false };
|
||||
|
||||
} // namespace
|
||||
@@ -26,6 +31,7 @@ uint32_t touch_override_until_tick = 0;
|
||||
#define SIM_TOUCH_HOLD_MS 1500
|
||||
|
||||
extern "C" void sdl_input_set_touch_override(int32_t x, int32_t y, bool pressed) {
|
||||
std::lock_guard<std::mutex> lock(state_mutex);
|
||||
touch_override.x = x;
|
||||
touch_override.y = y;
|
||||
touch_override.pressed = pressed;
|
||||
@@ -36,6 +42,7 @@ extern "C" void sdl_input_set_touch_override(int32_t x, int32_t y, bool pressed)
|
||||
}
|
||||
|
||||
extern "C" void sdl_input_clear_touch_override(void) {
|
||||
std::lock_guard<std::mutex> lock(state_mutex);
|
||||
touch_override_active = false;
|
||||
touch_override.pressed = false;
|
||||
}
|
||||
@@ -101,58 +108,73 @@ uint32_t keycode_to_key(SDL_Keycode sdl_key, bool shift) {
|
||||
} // namespace
|
||||
|
||||
void sdl_input_pump() {
|
||||
if (!text_input_started) {
|
||||
SDL_StartTextInput();
|
||||
text_input_started = true;
|
||||
// exit() must run with state_mutex unlocked: it never returns, so a lock_guard held across it
|
||||
// would never release the mutex, hanging any other thread that later calls into this file's
|
||||
// other functions (all of which lock state_mutex) while exit() tears the process down.
|
||||
bool quit_requested = false;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(state_mutex);
|
||||
|
||||
if (!text_input_started) {
|
||||
SDL_StartTextInput();
|
||||
text_input_started = true;
|
||||
}
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_MOUSEMOTION:
|
||||
set_pointer_position(event.motion.x, event.motion.y);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if (event.button.button == SDL_BUTTON_LEFT) {
|
||||
// event.button.x/y can be stale immediately after a window resize (an
|
||||
// SDL/X11 event-queue quirk - confirmed by comparing against a live
|
||||
// SDL_GetWindowSize() at the same instant). SDL_GetMouseState() queries the
|
||||
// OS for the current pointer position directly, sidestepping that entirely.
|
||||
int live_x, live_y;
|
||||
SDL_GetMouseState(&live_x, &live_y);
|
||||
set_pointer_position(live_x, live_y);
|
||||
pointer_state.pressed = true;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if (event.button.button == SDL_BUTTON_LEFT) {
|
||||
pointer_state.pressed = false;
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
push_key(keycode_to_key(event.key.keysym.sym, (event.key.keysym.mod & KMOD_SHIFT) != 0));
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
// ASCII only (first byte of event.text.text) - sufficient for a simulator keyboard.
|
||||
push_key(static_cast<uint8_t>(event.text.text[0]));
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
// Resizing doesn't change what LVGL last rendered, only how large it should
|
||||
// appear - re-present the existing frame at the new scale immediately, rather
|
||||
// than leaving stale-looking content on screen until the next LVGL-driven flush.
|
||||
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
sdl_display_present_now();
|
||||
}
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
quit_requested = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_MOUSEMOTION:
|
||||
set_pointer_position(event.motion.x, event.motion.y);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if (event.button.button == SDL_BUTTON_LEFT) {
|
||||
// event.button.x/y can be stale immediately after a window resize (an
|
||||
// SDL/X11 event-queue quirk - confirmed by comparing against a live
|
||||
// SDL_GetWindowSize() at the same instant). SDL_GetMouseState() queries the
|
||||
// OS for the current pointer position directly, sidestepping that entirely.
|
||||
int live_x, live_y;
|
||||
SDL_GetMouseState(&live_x, &live_y);
|
||||
set_pointer_position(live_x, live_y);
|
||||
pointer_state.pressed = true;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if (event.button.button == SDL_BUTTON_LEFT) {
|
||||
pointer_state.pressed = false;
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
push_key(keycode_to_key(event.key.keysym.sym, (event.key.keysym.mod & KMOD_SHIFT) != 0));
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
// ASCII only (first byte of event.text.text) - sufficient for a simulator keyboard.
|
||||
push_key(static_cast<uint8_t>(event.text.text[0]));
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
// Resizing doesn't change what LVGL last rendered, only how large it should
|
||||
// appear - re-present the existing frame at the new scale immediately, rather
|
||||
// than leaving stale-looking content on screen until the next LVGL-driven flush.
|
||||
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
sdl_display_present_now();
|
||||
}
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
exit(0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (quit_requested) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void sdl_input_get_pointer_state(SdlPointerState* out_state) {
|
||||
std::lock_guard<std::mutex> lock(state_mutex);
|
||||
if (touch_override_active) {
|
||||
// Auto-release: viewer sends press only; LVGL needs press then release
|
||||
// to register a click. Hold long enough for several indev polls.
|
||||
@@ -168,6 +190,7 @@ void sdl_input_get_pointer_state(SdlPointerState* out_state) {
|
||||
}
|
||||
|
||||
bool sdl_input_pop_key(uint32_t* out_key) {
|
||||
std::lock_guard<std::mutex> lock(state_mutex);
|
||||
if (key_queue_count == 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -178,5 +201,6 @@ bool sdl_input_pop_key(uint32_t* out_key) {
|
||||
}
|
||||
|
||||
bool sdl_input_has_queued_key() {
|
||||
std::lock_guard<std::mutex> lock(state_mutex);
|
||||
return key_queue_count > 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user