mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-20 05:16:24 -04:00
Merge branch 'main' of ssh://github.com/TwilitRealm/dusklight into rando-mod
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user