Merge branch 'main' of ssh://github.com/TwilitRealm/dusklight into rando-mod

This commit is contained in:
TakaRikka
2026-08-19 19:37:57 -07:00
3 changed files with 110 additions and 1 deletions
+5 -1
View File
@@ -9,7 +9,7 @@
#define UI_SERVICE_ID "dev.twilitrealm.dusklight.ui"
#define UI_SERVICE_MAJOR 1u
#define UI_SERVICE_MINOR 1u
#define UI_SERVICE_MINOR 2u
/*
* UI primitives: a panel inside the host Mods window, mod-owned windows, dialogs, toasts,
@@ -291,6 +291,10 @@ typedef struct UiService {
/* Enqueue a toast notification. */
ModResult (*push_toast)(ModContext* ctx, const UiToastDesc* desc);
/* Minor version 2 */
ModResult (*get_clipboard_text)(ModContext* ctx, char* buffer, size_t bufferSize, size_t* outLength);
ModResult (*set_clipboard_text)(ModContext* ctx, const char* text);
} UiService;
MOD_DECLARE_SERVICE(UiService, svc_ui, UI_SERVICE_ID, UI_SERVICE_MAJOR, UI_SERVICE_MINOR);
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include <mods/svc/ui.h>
#include <string>
#include <utility>
namespace mods::ui {
inline ModResult get_clipboard_text(std::string& outText) {
outText.clear();
size_t textLength = 0;
auto result = svc_ui->get_clipboard_text(mod_ctx, nullptr, 0, &textLength);
if (result != MOD_OK) {
return result;
}
for (int attempt = 0; attempt < 3; ++attempt) {
std::string buffer(textLength + 1, '\0');
size_t actualLength = 0;
result = svc_ui->get_clipboard_text(
mod_ctx, buffer.data(), buffer.size(), &actualLength);
if (result == MOD_OK) {
buffer.resize(actualLength);
outText = std::move(buffer);
return MOD_OK;
}
// Retry if the clipboard grew between the two calls.
if (result != MOD_INVALID_ARGUMENT || actualLength <= textLength) {
return result;
}
textLength = actualLength;
}
return MOD_ERROR;
}
inline ModResult set_clipboard_text(const std::string& text) {
return svc_ui->set_clipboard_text(mod_ctx, text.c_str());
}
} // namespace mods::ui
+58
View File
@@ -29,6 +29,8 @@
#include <utility>
#include <vector>
#include "SDL3/SDL_clipboard.h"
namespace dusk::mods::svc::ui_impl {
namespace {
@@ -1037,6 +1039,43 @@ void ui_remove_mod(LoadedMod& mod) {
}
}
ModResult ui_get_clipboard_text(LoadedMod& mod, char* buffer, size_t bufferSize, size_t* outLength) {
if (outLength != nullptr) {
*outLength = 0;
}
std::string text;
if (SDL_HasClipboardText()) {
char* textPtr = SDL_GetClipboardText();
text = textPtr != nullptr ? textPtr : "";
SDL_free(textPtr);
if (text.empty()) {
return MOD_ERROR;
}
}
if (outLength != nullptr) {
*outLength = text.size();
}
if (buffer == nullptr) {
return MOD_OK;
}
if (bufferSize < text.size() + 1) {
return MOD_INVALID_ARGUMENT;
}
memcpy(buffer, text.c_str(), text.size() + 1);
return MOD_OK;
}
ModResult ui_set_clipboard_text(LoadedMod& mod, const char* text) {
if (!SDL_SetClipboardText(text)) {
return MOD_ERROR;
}
return MOD_OK;
}
} // namespace dusk::mods::svc::ui_impl
namespace dusk::mods::svc {
@@ -1368,6 +1407,23 @@ ModResult ui_dialog_add_action(
return ui_impl::ui_dialog_add_action(*mod, dialog, *action);
}
ModResult ui_get_clipboard_text(ModContext* ctx, char* buffer, size_t bufferSize, size_t* outLength) {
auto* mod = mod_from_context(ctx);
if (mod == nullptr || (buffer == nullptr && bufferSize != 0)) {
return MOD_INVALID_ARGUMENT;
}
return ui_impl::ui_get_clipboard_text(*mod, buffer, bufferSize, outLength);
}
ModResult ui_set_clipboard_text(ModContext* ctx, const char* text) {
auto* mod = mod_from_context(ctx);
if (mod == nullptr || text == nullptr) {
return MOD_INVALID_ARGUMENT;
}
return ui_impl::ui_set_clipboard_text(*mod, text);
}
constexpr UiService s_uiService{
.header = SERVICE_HEADER(UiService, UI_SERVICE_MAJOR, UI_SERVICE_MINOR),
.register_mods_panel = ui_register_mods_panel,
@@ -1394,6 +1450,8 @@ constexpr UiService s_uiService{
.register_menu_tab = ui_register_menu_tab,
.unregister_menu_tab = ui_unregister_menu_tab,
.push_toast = ui_push_toast,
.get_clipboard_text = ui_get_clipboard_text,
.set_clipboard_text = ui_set_clipboard_text,
};
} // namespace