Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/emulator-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ jobs:
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(sysctl -n hw.ncpu)
- name: Test
run: ctest --test-dir projects/CardputerZero-Emulator/build --output-on-failure
- name: Package
run: |
cd projects/CardputerZero-Emulator
Expand All @@ -46,7 +48,11 @@ jobs:
cp -r build/apps dist/CardputerZero-Emulator/
cp -r build/assets dist/CardputerZero-Emulator/
cp -r build/images dist/CardputerZero-Emulator/
cd dist && tar czf ../CardputerZero-Emulator-macOS.tar.gz CardputerZero-Emulator
cp -r build/APPLaunch dist/CardputerZero-Emulator/
cd dist/CardputerZero-Emulator
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy EMU_TEST_NAVIGATE_FRAME=10 EMU_TEST_QUIT_FRAME=20 ./cardputer-zero-emu
cd ..
tar czf ../CardputerZero-Emulator-macOS.tar.gz CardputerZero-Emulator
- uses: actions/upload-artifact@v4
with:
name: emulator-macos
Expand Down
14 changes: 14 additions & 0 deletions ext_components/cp0_lvgl/include/input_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define KEY_9 10
#define KEY_0 11
#define KEY_MINUS 12
#define KEY_EQUAL 13
#define KEY_BACKSPACE 14
#define KEY_TAB 15
#define KEY_Q 16
Expand All @@ -31,6 +32,8 @@
#define KEY_I 23
#define KEY_O 24
#define KEY_P 25
#define KEY_LEFTBRACE 26
#define KEY_RIGHTBRACE 27
#define KEY_ENTER 28
#define KEY_LEFTCTRL 29
#define KEY_A 30
Expand All @@ -42,7 +45,11 @@
#define KEY_J 36
#define KEY_K 37
#define KEY_L 38
#define KEY_SEMICOLON 39
#define KEY_APOSTROPHE 40
#define KEY_GRAVE 41
#define KEY_LEFTSHIFT 42
#define KEY_BACKSLASH 43
#define KEY_RIGHTSHIFT 54
#define KEY_Z 44
#define KEY_X 45
Expand All @@ -51,7 +58,9 @@
#define KEY_B 48
#define KEY_N 49
#define KEY_M 50
#define KEY_COMMA 51
#define KEY_DOT 52
#define KEY_SLASH 53
#define KEY_SPACE 57
#define KEY_LEFTALT 56
#define KEY_CAPSLOCK 58
Expand All @@ -68,6 +77,9 @@
#define KEY_F11 87
#define KEY_F12 88
#define KEY_KPENTER 96
#define KEY_RIGHTCTRL 97
#define KEY_SYSRQ 99
#define KEY_RIGHTALT 100
#define KEY_HOME 102
#define KEY_UP 103
#define KEY_PAGEUP 104
Expand All @@ -81,6 +93,8 @@
#define KEY_MUTE 113
#define KEY_VOLUMEDOWN 114
#define KEY_VOLUMEUP 115
#define KEY_LEFTMETA 125
#define KEY_RIGHTMETA 126
#define KEY_BRIGHTNESSDOWN 224
#define KEY_BRIGHTNESSUP 225
#define KEY_NEXT 407
Expand Down
52 changes: 50 additions & 2 deletions ext_components/cp0_lvgl/src/cp0_lvgl_app_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,38 @@
#include "cp0_runner_shutdown.hpp"
#include "hal_lvgl_bsp.h"

#include <chrono>
#include <cerrno>
#include <condition_variable>
#include <cstdio>
#include <mutex>
#if !defined(__APPLE__)
#include <semaphore.h>
#endif
#include <time.h>

namespace {

#if defined(__APPLE__)
std::condition_variable lvgl_wake;
size_t pending_wakes = 0;
#else
sem_t lvgl_sem;
#endif
std::mutex runner_mutex;
cp0::RunnerLifetime runner_lifetime;
bool semaphore_ready = false;

void post_lvgl_semaphore()
{
std::lock_guard<std::mutex> lock(runner_mutex);
if (semaphore_ready) sem_post(&lvgl_sem);
if (!semaphore_ready) return;
#if defined(__APPLE__)
++pending_wakes;
lvgl_wake.notify_one();
#else
sem_post(&lvgl_sem);
#endif
}

void resume_cb(void *)
Expand All @@ -40,6 +55,13 @@ void resume_cb(void *)

void wait_for_lvgl(uint32_t milliseconds)
{
#if defined(__APPLE__)
std::unique_lock<std::mutex> lock(runner_mutex);
lvgl_wake.wait_for(lock, std::chrono::milliseconds(milliseconds), [] {
return pending_wakes != 0 || !semaphore_ready;
});
if (pending_wakes != 0) --pending_wakes;
#else
struct timespec deadline;
#if defined(__linux__)
clock_gettime(CLOCK_MONOTONIC, &deadline);
Expand All @@ -58,6 +80,23 @@ void wait_for_lvgl(uint32_t milliseconds)
result = sem_timedwait(&lvgl_sem, &deadline);
#endif
} while (result != 0 && errno == EINTR);
#endif
}

void wait_for_lvgl()
{
#if defined(__APPLE__)
std::unique_lock<std::mutex> lock(runner_mutex);
lvgl_wake.wait(lock, [] {
return pending_wakes != 0 || !semaphore_ready;
});
if (pending_wakes != 0) --pending_wakes;
#else
int result;
do {
result = sem_wait(&lvgl_sem);
} while (result != 0 && errno == EINTR);
#endif
}

void stop_audio() noexcept
Expand Down Expand Up @@ -117,10 +156,14 @@ int cp0_lvgl_run(Cp0LvglRunOptions options)
std::fprintf(stderr, "cp0_lvgl: runner supports one run per process\n");
return 1;
}
#if defined(__APPLE__)
pending_wakes = 0;
#else
if (sem_init(&lvgl_sem, 0, 0) != 0) {
runner_lifetime.initialization_failed();
return 1;
}
#endif
semaphore_ready = true;
}

Expand All @@ -146,7 +189,12 @@ int cp0_lvgl_run(Cp0LvglRunOptions options)
deinit_input, deinit_wifi, stop_lora, deinit_battery, lv_deinit);
std::lock_guard<std::mutex> lock(runner_mutex);
semaphore_ready = false;
#if defined(__APPLE__)
pending_wakes = 0;
lvgl_wake.notify_all();
#else
sem_destroy(&lvgl_sem);
#endif
runner_lifetime.finish();
return teardown_failed;
};
Expand Down Expand Up @@ -182,7 +230,7 @@ int cp0_lvgl_run(Cp0LvglRunOptions options)
if (options.should_quit && options.should_quit())
break;
if (milliseconds == LV_NO_TIMER_READY)
sem_wait(&lvgl_sem);
wait_for_lvgl();
else
wait_for_lvgl(milliseconds);
}
Expand Down
15 changes: 15 additions & 0 deletions ext_components/cp0_lvgl/src/cp0_process_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,21 @@ Result run(std::vector<std::string> argv, const std::string *input, Output outpu
int count = 0;
getgrouplist(user_name.c_str(), gid, nullptr, &count);
if (count > 0) {
#if defined(__APPLE__)
std::vector<int> native_groups(count);
if (getgrouplist(user_name.c_str(), static_cast<int>(gid),
native_groups.data(), &count) < 0) {
result.exit_code = -EINVAL; return result;
}
native_groups.resize(count);
groups.assign(native_groups.begin(), native_groups.end());
#else
groups.resize(count);
if (getgrouplist(user_name.c_str(), gid, groups.data(), &count) < 0) {
result.exit_code = -EINVAL; return result;
}
groups.resize(count);
#endif
}
}
int in[2] = {-1, -1}, out[2] = {-1, -1};
Expand Down Expand Up @@ -212,7 +222,12 @@ Result run(std::vector<std::string> argv, const std::string *input, Output outpu
finish_input();
if (sigpipe_blocked) {
if (!sigpipe_was_pending && sigpending(&pending) == 0 && sigismember(&pending, SIGPIPE)) {
#if defined(__APPLE__)
int consumed_signal = 0;
sigwait(&set, &consumed_signal);
#else
timespec zero{0, 0}; sigtimedwait(&set, nullptr, &zero);
#endif
}
pthread_sigmask(SIG_SETMASK, &old, nullptr);
}
Expand Down
28 changes: 20 additions & 8 deletions ext_components/cp0_lvgl/src/cp0_pty_posix.inc
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,14 @@
#include <unordered_map>
#include <vector>

#if defined(__linux__) || defined(__APPLE__)
#define CP0_HAS_POSIX_PTY 1
#endif

#if defined(__linux__)
#include <pty.h>
#elif defined(__APPLE__)
#include <util.h>
#endif

namespace {
Expand All @@ -51,7 +57,7 @@ public:

pty_handle_t open(const char *cmd, const char *const *args, int cols, int rows)
{
#if defined(__linux__)
#if defined(CP0_HAS_POSIX_PTY)
if (!cmd || !cmd[0]) return NULL;

int master_fd = -1;
Expand Down Expand Up @@ -113,7 +119,7 @@ public:

int read(pty_handle_t pty, char *buf, size_t buf_size)
{
#if defined(__linux__)
#if defined(CP0_HAS_POSIX_PTY)
std::lock_guard<std::mutex> lock(handles_mutex_);
cp0_pty_handle *h = resolve(pty);
if (!h || !buf || buf_size == 0) return -1;
Expand All @@ -133,7 +139,7 @@ public:

int write(pty_handle_t pty, const char *buf, size_t len)
{
#if defined(__linux__)
#if defined(CP0_HAS_POSIX_PTY)
std::lock_guard<std::mutex> lock(handles_mutex_);
cp0_pty_handle *h = resolve(pty);
if (!h || !buf) return -1;
Expand All @@ -148,7 +154,7 @@ public:

int check_child(pty_handle_t pty, int *exit_status)
{
#if defined(__linux__)
#if defined(CP0_HAS_POSIX_PTY)
std::lock_guard<std::mutex> lock(handles_mutex_);
cp0_pty_handle *h = resolve(pty);
if (!h) return -1;
Expand All @@ -175,7 +181,7 @@ public:

int resize(pty_handle_t pty, int cols, int rows)
{
#if defined(__linux__)
#if defined(CP0_HAS_POSIX_PTY)
std::lock_guard<std::mutex> lock(handles_mutex_);
cp0_pty_handle *h = resolve(pty);
if (!h) return -1;
Expand All @@ -193,7 +199,7 @@ public:

bool close(pty_handle_t pty)
{
#if defined(__linux__)
#if defined(CP0_HAS_POSIX_PTY)
cp0_pty_handle *handle = nullptr;
{
std::lock_guard<std::mutex> lock(handles_mutex_);
Expand All @@ -212,7 +218,7 @@ public:

void shutdown() noexcept
{
#if defined(__linux__)
#if defined(CP0_HAS_POSIX_PTY)
std::unordered_map<uintptr_t, cp0_pty_handle *> handles;
try {
std::lock_guard<std::mutex> lock(handles_mutex_);
Expand Down Expand Up @@ -251,7 +257,7 @@ public:
private:
static void cleanup(cp0_pty_handle *handle) noexcept
{
#if defined(__linux__)
#if defined(CP0_HAS_POSIX_PTY)
if (!handle) return;
if (!handle->child_reaped) {
(void)kill(handle->child_pid, SIGKILL);
Expand Down Expand Up @@ -334,6 +340,8 @@ private:
(void)shell_result;
(void)chdir_result;
}
#else
(void)configured_user;
#endif
}

Expand Down Expand Up @@ -382,7 +390,9 @@ private:

std::unordered_map<uintptr_t, cp0_pty_handle *> handles_;
std::mutex handles_mutex_;
#if defined(CP0_HAS_POSIX_PTY)
bool accepting_ = true;
#endif
};

std::mutex g_pty_mutex;
Expand Down Expand Up @@ -425,3 +435,5 @@ extern "C" void deinit_pty(void) noexcept
} catch (...) {
}
}

#undef CP0_HAS_POSIX_PTY
2 changes: 1 addition & 1 deletion ext_components/cp0_lvgl/src/cp0_sudo_coordinator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ std::vector<Action> Coordinator::start_next_locked(int64_t now_ms)
return actions;
}

void Coordinator::terminal_locked(const std::shared_ptr<Request> &request,
void Coordinator::terminal_locked(std::shared_ptr<Request> request,
cp0_sudo_result_t result, int exit_code)
{
if (!request || request->state == State::TERMINAL) return;
Expand Down
2 changes: 1 addition & 1 deletion ext_components/cp0_lvgl/src/cp0_sudo_coordinator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class Coordinator {
std::vector<Action> start_next_locked(int64_t now_ms);
void expire_queued_locked(int64_t now_ms);
std::vector<Action> promote_reservations_locked(int64_t now_ms);
void terminal_locked(const std::shared_ptr<Request> &request,
void terminal_locked(std::shared_ptr<Request> request,
cp0_sudo_result_t result, int exit_code);
void remember_terminal_locked(uint64_t id);

Expand Down
2 changes: 1 addition & 1 deletion ext_components/cp0_lvgl/src/sdl/sdl_lvgl.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "hal_lvgl_bsp.h"
#include "lvgl/lvgl.h"

#include <linux/input.h>
#include "input_keys.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down
2 changes: 1 addition & 1 deletion ext_components/cp0_lvgl/src/sdl/sdl_lvgl_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "lvgl/src/drivers/sdl/lv_sdl_private.h"
#include "lvgl/src/drivers/sdl/lv_sdl_window.h"

#include <linux/input.h>
#include "input_keys.h"
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
Expand Down
Loading