From a5567da82cdb140dd581891fdc0268a65a66d598 Mon Sep 17 00:00:00 2001 From: Ilia Demianenko Date: Mon, 11 Sep 2023 01:59:23 -0700 Subject: [PATCH] Clipboard handling --- samples/ui/src/main.c | 5 +- scripts/bindgen.py | 1 - src/app/app.h | 3 ++ src/app/osx_app.m | 1 + src/runtime.c | 52 +++++++++++++++++---- src/runtime.h | 3 ++ src/runtime_clipboard.c | 96 ++++++++++++++++++++++++++++++++++++++ src/runtime_clipboard.h | 31 ++++++++++++ src/runtime_io.c | 3 +- src/runtime_memory.c | 6 +-- src/runtime_memory.h | 4 +- src/ui/input_state.c | 27 ++++++++++- src/ui/input_state.h | 12 ++++- src/ui/ui.c | 35 +++++++++++--- src/ui/ui.h | 4 ++ src/wasmbind/core_api.json | 18 +++++++ 16 files changed, 273 insertions(+), 28 deletions(-) create mode 100644 src/runtime_clipboard.c create mode 100644 src/runtime_clipboard.h diff --git a/samples/ui/src/main.c b/samples/ui/src/main.c index 6b94054..616e934 100644 --- a/samples/ui/src/main.c +++ b/samples/ui/src/main.c @@ -333,7 +333,10 @@ ORCA_EXPORT void oc_on_frame_refresh(void) OC_UI_STYLE_LAYOUT_SPACING); oc_ui_container("buttons", 0) { - oc_ui_button("Button A"); + if(oc_ui_button("Break the law").clicked) + { + oc_clipboard_set_string((oc_str8)OC_STR8_LIT("Check out my cool website")); + } oc_ui_button("Button B"); oc_ui_button("Button C"); oc_ui_button("Button D"); diff --git a/scripts/bindgen.py b/scripts/bindgen.py index 1eccf22..913cb30 100755 --- a/scripts/bindgen.py +++ b/scripts/bindgen.py @@ -133,7 +133,6 @@ def bindgen(apiName, spec, **kwargs): s += '\t\tOC_ASSERT((char*)__retPtr + sizeof(' + retTypeCName + ') <= ((char*)_mem + m3_GetMemorySize(runtime)), "return pointer is out of bounds");\n' s += '\t}\n' - for argIndex, arg in enumerate(decl['args']): argName = arg['name'] diff --git a/src/app/app.h b/src/app/app.h index 474fc98..55ff91f 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -58,6 +58,7 @@ typedef enum OC_EVENT_MOUSE_WHEEL, OC_EVENT_MOUSE_ENTER, OC_EVENT_MOUSE_LEAVE, + OC_EVENT_CLIPBOARD_PASTE, OC_EVENT_WINDOW_RESIZE, OC_EVENT_WINDOW_MOVE, OC_EVENT_WINDOW_FOCUS, @@ -479,6 +480,8 @@ void oc_window_set_size(oc_vec2 size); void ORCA_IMPORT(oc_request_quit)(void); oc_key_code ORCA_IMPORT(oc_scancode_to_keycode)(oc_scan_code scanCode); +void oc_clipboard_set_string(oc_str8 string); + #endif // !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) #ifdef __cplusplus diff --git a/src/app/osx_app.m b/src/app/osx_app.m index d53595d..3018776 100644 --- a/src/app/osx_app.m +++ b/src/app/osx_app.m @@ -1243,6 +1243,7 @@ void oc_clipboard_set_string(oc_str8 string) NSString* nsString = [[NSString alloc] initWithBytes:string.ptr length:string.len encoding:NSUTF8StringEncoding]; NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [pb clearContents]; [pb writeObjects:[[NSArray alloc] initWithObjects:nsString, nil]]; } } diff --git a/src/runtime.c b/src/runtime.c index d04e1f4..d9e6f4d 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -14,6 +14,7 @@ #include "orca.h" #include "runtime.h" +#include "runtime_clipboard.c" #include "runtime_io.c" #include "runtime_memory.c" @@ -117,6 +118,16 @@ void oc_bridge_window_set_size(oc_vec2 size) oc_window_set_content_size(__orcaApp.window, size); } +oc_wasm_str8 oc_bridge_clipboard_get_string(oc_wasm_addr wasmArena) +{ + return oc_runtime_clipboard_get_string(&__orcaApp.clipboard, wasmArena); +} + +void oc_bridge_clipboard_set_string(oc_wasm_str8 value) +{ + oc_runtime_clipboard_set_string(&__orcaApp.clipboard, value); +} + void oc_bridge_log(oc_log_level level, int fileLen, char* file, @@ -553,7 +564,6 @@ i32 orca_runloop(void* user) oc_event* event = 0; while((event = oc_next_event(oc_scratch())) != 0) { - if(app->debugOverlay.show) { oc_ui_process_event(event); @@ -561,19 +571,41 @@ i32 orca_runloop(void* user) if(exports[OC_EXPORT_RAW_EVENT]) { -#ifndef M3_BIG_ENDIAN - oc_event* eventPtr = (oc_event*)oc_wasm_address_to_ptr(app->env.rawEventOffset, sizeof(oc_event)); - memcpy(eventPtr, event, sizeof(*event)); - - const void* args[1] = { &app->env.rawEventOffset }; - M3Result res = m3_Call(exports[OC_EXPORT_RAW_EVENT], 1, args); - if(res) + oc_arena_scope scratch = oc_scratch_begin(); + oc_event* clipboardEvent = oc_runtime_clipboard_process_event_begin(&__orcaApp.clipboard, scratch.arena, event); + oc_event* events[2]; + u64 eventsCount; + if(clipboardEvent != 0) { - ORCA_WASM3_ABORT(app->env.m3Runtime, res, "Runtime error"); + events[0] = clipboardEvent; + events[1] = event; + eventsCount = 2; } + else + { + events[0] = event; + eventsCount = 1; + } + + for(int i = 0; i < eventsCount; i++) + { +#ifndef M3_BIG_ENDIAN + oc_event* eventPtr = (oc_event*)oc_wasm_address_to_ptr(app->env.rawEventOffset, sizeof(oc_event)); + memcpy(eventPtr, events[i], sizeof(*events[i])); + + const void* args[1] = { &app->env.rawEventOffset }; + M3Result res = m3_Call(exports[OC_EXPORT_RAW_EVENT], 1, args); + if(res) + { + ORCA_WASM3_ABORT(app->env.m3Runtime, res, "Runtime error"); + } #else - oc_log_error("oc_on_raw_event() is not supported on big endian platforms"); + oc_log_error("oc_on_raw_event() is not supported on big endian platforms"); #endif + } + + oc_runtime_clipboard_process_event_end(&__orcaApp.clipboard); + oc_scratch_end(scratch); } switch(event->type) diff --git a/src/runtime.h b/src/runtime.h index b5513d0..46b20d5 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -9,6 +9,8 @@ #define __RUNTIME_H_ #include "platform/platform_io_internal.h" +#include "runtime_memory.h" +#include "runtime_clipboard.h" #include "m3_compile.h" #include "m3_env.h" @@ -121,6 +123,7 @@ typedef struct oc_runtime oc_wasm_env env; + oc_runtime_clipboard clipboard; } oc_runtime; oc_runtime* oc_runtime_get(void); diff --git a/src/runtime_clipboard.c b/src/runtime_clipboard.c new file mode 100644 index 0000000..6a31ccf --- /dev/null +++ b/src/runtime_clipboard.c @@ -0,0 +1,96 @@ +/************************************************************************* +* +* Orca +* Copyright 2023 Martin Fouilleul and the Orca project contributors +* See LICENSE.txt for licensing information +* +**************************************************************************/ + +#include "runtime_clipboard.h" + +#if OC_PLATFORM_WINDOWS || OC_PLATFORM_MACOS + +oc_wasm_str8 oc_runtime_clipboard_get_string(oc_runtime_clipboard* clipboard, oc_wasm_addr wasmArena) +{ + oc_wasm_str8 result = { 0 }; + if(clipboard->isGetAllowed) + { + oc_arena_scope scratch = oc_scratch_begin(); + oc_str8 value = oc_clipboard_get_string(scratch.arena); + oc_wasm_addr valueAddr = oc_wasm_arena_push(wasmArena, value.len); + char* valuePtr = (char*)oc_wasm_address_to_ptr(valueAddr, value.len); + memcpy(valuePtr, value.ptr, value.len); + oc_scratch_end(scratch); + result = (oc_wasm_str8){ .ptr = valueAddr, + .len = value.len }; + } + else + { + oc_log_warning("Clipboard contents can only be get from within the paste event handler\n"); + } + return (result); +} + +static f64 OC_CLIPBOARD_SET_TIMEOUT = 1; + +void oc_runtime_clipboard_set_string(oc_runtime_clipboard* clipboard, oc_wasm_str8 value) +{ + f64 time = oc_clock_time(OC_CLOCK_MONOTONIC); + if(time < clipboard->setAllowedUntil) + { + oc_str8 nativeValue = oc_wasm_str8_to_native(value); + oc_clipboard_set_string(nativeValue); + } + else + { + oc_log_warning("Clipboard contents can only be set within %f second(s) of a paste shortcut press\n", OC_CLIPBOARD_SET_TIMEOUT); + } +} + +oc_event* oc_runtime_clipboard_process_event_begin(oc_runtime_clipboard* clipboard, oc_arena* arena, oc_event* origEvent) +{ + oc_event* resultEvent = 0; + if(origEvent->type == OC_EVENT_KEYBOARD_KEY) + { + bool isPressedOrRepeated = origEvent->key.action == OC_KEY_PRESS || origEvent->key.action == OC_KEY_REPEAT; + oc_keymod_flags rawMods = origEvent->key.mods & ~OC_KEYMOD_MAIN_MODIFIER; + #if OC_PLATFORM_WINDOWS + bool cutOrCopied = isPressedOrRepeated + && ((origEvent->key.keyCode == OC_KEY_X && rawMods == OC_KEYMOD_CTRL) + || (origEvent->key.keyCode == OC_KEY_DELETE && rawMods == OC_KEYMOD_SHIFT) + || (origEvent->key.keyCode == OC_KEY_C && rawMods == OC_KEYMOD_CTRL) + || (origEvent->key.keyCode == OC_KEY_INSERT && rawMods == OC_KEYMOD_CTRL)); + bool pasted = isPressedOrRepeated + && ((origEvent->key.keyCode == OC_KEY_V && rawMods == OC_KEYMOD_CTRL) + || (origEvent->key.keyCode == OC_KEY_INSERT && rawMods == OC_KEYMOD_SHIFT)); + #elif OC_PLATFORM_MACOS + bool cutOrCopied = isPressedOrRepeated + && ((origEvent->key.keyCode == OC_KEY_X && rawMods == OC_KEYMOD_CMD) + || (origEvent->key.keyCode == OC_KEY_C && rawMods == OC_KEYMOD_CMD)); + bool pasted = isPressedOrRepeated + && origEvent->key.keyCode == OC_KEY_V && rawMods == OC_KEYMOD_CMD; + #endif + if(cutOrCopied) + { + clipboard->setAllowedUntil = oc_clock_time(OC_CLOCK_MONOTONIC) + OC_CLIPBOARD_SET_TIMEOUT; + } + + if(pasted) + { + clipboard->isGetAllowed = true; + resultEvent = oc_arena_push_type(arena, oc_event); + *resultEvent = (oc_event){ .window = origEvent->window, + .type = OC_EVENT_CLIPBOARD_PASTE }; + } + } + return (resultEvent); +} + +void oc_runtime_clipboard_process_event_end(oc_runtime_clipboard* clipboard) +{ + clipboard->isGetAllowed = false; +} + +#else + #error Default clipboard handling is not supported on this platform" +#endif diff --git a/src/runtime_clipboard.h b/src/runtime_clipboard.h new file mode 100644 index 0000000..b3ce651 --- /dev/null +++ b/src/runtime_clipboard.h @@ -0,0 +1,31 @@ +/************************************************************************* +* +* Orca +* Copyright 2023 Martin Fouilleul and the Orca project contributors +* See LICENSE.txt for licensing information +* +**************************************************************************/ + +#ifndef __RUNTIME_CLIPBOARD_H_ +#define __RUNTIME_CLIPBOARD_H_ + +#include "runtime_memory.h" + +typedef struct oc_runtime_clipboard +{ + bool isGetAllowed; + f64 setAllowedUntil; +} oc_runtime_clipboard; + +#if OC_PLATFORM_WINDOWS || OC_PLATFORM_MACOS + +oc_wasm_str8 oc_runtime_clipboard_get_string(oc_runtime_clipboard* clipboard, oc_wasm_addr wasmArena); +void oc_runtime_clipboard_set_string(oc_runtime_clipboard* clipboard, oc_wasm_str8 value); +oc_event* oc_runtime_clipboard_process_event_begin(oc_runtime_clipboard* clipboard, oc_arena* arena, oc_event* origEvent); +void oc_runtime_clipboard_process_event_end(oc_runtime_clipboard* clipboard); + +#else + #error Default clipboard handling is not supported on this platform" +#endif + +#endif //__RUNTIME_CLIPBOARD_H_ \ No newline at end of file diff --git a/src/runtime_io.c b/src/runtime_io.c index c12900f..cac93bd 100644 --- a/src/runtime_io.c +++ b/src/runtime_io.c @@ -134,7 +134,8 @@ oc_wasm_file_open_with_dialog_result oc_file_open_with_dialog_bridge(oc_wasm_add oc_list_for(&nativeResult.selection, elt, oc_file_open_with_dialog_elt, listElt) { - oc_wasm_file_open_with_dialog_elt* wasmElt = oc_wasm_arena_push(wasmArena, sizeof(oc_wasm_file_open_with_dialog_elt)); + oc_wasm_addr wasmEltAddr = oc_wasm_arena_push(wasmArena, sizeof(oc_wasm_file_open_with_dialog_elt)); + oc_wasm_file_open_with_dialog_elt* wasmElt = oc_wasm_address_to_ptr(wasmEltAddr, sizeof(oc_wasm_file_open_with_dialog_elt)); wasmElt->file = elt->file; oc_wasm_list_push_back(&result.selection, &wasmElt->listElt); diff --git a/src/runtime_memory.c b/src/runtime_memory.c index a7ea9b8..09da969 100644 --- a/src/runtime_memory.c +++ b/src/runtime_memory.c @@ -127,7 +127,7 @@ void oc_wasm_list_push_back(oc_wasm_list* list, oc_wasm_list_elt* elt) // Wasm arenas helpers //------------------------------------------------------------------------------------ -void* oc_wasm_arena_push(oc_wasm_addr arena, u64 size) +oc_wasm_addr oc_wasm_arena_push(oc_wasm_addr arena, u64 size) { oc_wasm_env* env = oc_runtime_get_env(); @@ -146,6 +146,6 @@ void* oc_wasm_arena_push(oc_wasm_addr arena, u64 size) { ORCA_WASM3_ABORT(env->m3Runtime, res, "Runtime error"); } - void* ptr = oc_wasm_address_to_ptr(retValues[0], size); - return (ptr); + + return (retValues[0]); } diff --git a/src/runtime_memory.h b/src/runtime_memory.h index e571c8f..ee63ee1 100644 --- a/src/runtime_memory.h +++ b/src/runtime_memory.h @@ -8,8 +8,6 @@ #ifndef __RUNTIME_MEMORY_H_ #define __RUNTIME_MEMORY_H_ -#include "runtime.h" - typedef u32 oc_wasm_addr; typedef u32 oc_wasm_size; @@ -96,6 +94,6 @@ typedef struct oc_wasm_str8_list // Wasm arenas helpers //------------------------------------------------------------------------------------ -void* oc_wasm_arena_push(oc_wasm_addr arena, u64 size); +oc_wasm_addr oc_wasm_arena_push(oc_wasm_addr arena, u64 size); #endif //__RUNTIME_MEMORY_H_ diff --git a/src/ui/input_state.c b/src/ui/input_state.c index 1d01643..32f6654 100644 --- a/src/ui/input_state.c +++ b/src/ui/input_state.c @@ -63,6 +63,12 @@ static void oc_update_key_mods(oc_input_state* state, oc_keymod_flags mods) state->keyboard.mods = mods; } +static void oc_update_clipboard_paste(oc_input_state* state, oc_arena* arena) +{ + state->clipboard.lastUpdate = state->frameCounter; + state->clipboard.pastedText = oc_clipboard_get_string(arena); +} + static void oc_update_mouse_move(oc_input_state* state, f32 x, f32 y, f32 deltaX, f32 deltaY) { u64 frameCounter = state->frameCounter; @@ -134,7 +140,7 @@ void oc_input_next_frame(oc_input_state* state) state->frameCounter++; } -void oc_input_process_event(oc_input_state* state, oc_event* event) +void oc_input_process_event(oc_input_state* state, oc_arena* arena, oc_event* event) { switch(event->type) { @@ -154,6 +160,10 @@ void oc_input_process_event(oc_input_state* state, oc_event* event) oc_update_key_mods(state, event->key.mods); break; + case OC_EVENT_CLIPBOARD_PASTE: + oc_update_clipboard_paste(state, arena); + break; + case OC_EVENT_MOUSE_MOVE: oc_update_mouse_move(state, event->mouse.x, event->mouse.y, event->mouse.deltaX, event->mouse.deltaY); break; @@ -413,3 +423,18 @@ oc_str8 oc_input_text_utf8(oc_input_state* input, oc_arena* arena) } return (res); } + +bool oc_clipboard_pasted(oc_input_state* input) +{ + return input->clipboard.lastUpdate == input->frameCounter; +} + +oc_str8 oc_clipboard_pasted_text(oc_input_state* input) +{ + oc_str8 res = { 0 }; + if(input->clipboard.lastUpdate == input->frameCounter) + { + res = input->clipboard.pastedText; + } + return (res); +} diff --git a/src/ui/input_state.h b/src/ui/input_state.h index f5de33a..2e034b1 100644 --- a/src/ui/input_state.h +++ b/src/ui/input_state.h @@ -67,15 +67,22 @@ typedef struct oc_text_state oc_str32 codePoints; } oc_text_state; +typedef struct oc_clipboard_state +{ + u64 lastUpdate; + oc_str8 pastedText; +} oc_clipboard_state; + typedef struct oc_input_state { u64 frameCounter; oc_keyboard_state keyboard; oc_mouse_state mouse; oc_text_state text; + oc_clipboard_state clipboard; } oc_input_state; -ORCA_API void oc_input_process_event(oc_input_state* state, oc_event* event); +ORCA_API void oc_input_process_event(oc_input_state* state, oc_arena* arena, oc_event* event); ORCA_API void oc_input_next_frame(oc_input_state* state); ORCA_API bool oc_key_down(oc_input_state* state, oc_key_code key); @@ -101,6 +108,9 @@ ORCA_API oc_vec2 oc_mouse_wheel(oc_input_state* state); ORCA_API oc_str32 oc_input_text_utf32(oc_input_state* state, oc_arena* arena); ORCA_API oc_str8 oc_input_text_utf8(oc_input_state* state, oc_arena* arena); +ORCA_API bool oc_clipboard_pasted(oc_input_state* state); +ORCA_API oc_str8 oc_clipboard_pasted_text(oc_input_state* state); + ORCA_API oc_keymod_flags oc_key_mods(oc_input_state* state); #endif //__INPUT_STATE_H_ diff --git a/src/ui/ui.c b/src/ui/ui.c index a0138ca..9e5302a 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -7,6 +7,7 @@ **************************************************************************/ #include "ui.h" #include "math.h" +#include "app/app.h" #include "platform/platform.h" #include "platform/platform_clock.h" #include "platform/platform_debug.h" @@ -329,7 +330,7 @@ void oc_ui_style_box_after(oc_ui_box* box, oc_ui_pattern pattern, oc_ui_style* s void oc_ui_process_event(oc_event* event) { oc_ui_context* ui = oc_ui_get_context(); - oc_input_process_event(&ui->input, event); + oc_input_process_event(&ui->input, &ui->frameArena, event); } oc_vec2 oc_ui_mouse_position(void) @@ -590,6 +591,8 @@ oc_ui_sig oc_ui_box_sig(oc_ui_box* box) sig.dragging = box->dragging; } + + sig.pasted = oc_clipboard_pasted(input); } return (sig); } @@ -1438,8 +1441,6 @@ void oc_ui_begin_frame(oc_vec2 size, oc_ui_style* defaultStyle, oc_ui_style_mask { oc_ui_context* ui = oc_ui_get_context(); - oc_arena_clear(&ui->frameArena); - ui->frameCounter++; f64 time = oc_clock_time(OC_CLOCK_MONOTONIC); ui->lastFrameDuration = time - ui->frameTime; @@ -1515,6 +1516,7 @@ void oc_ui_end_frame(void) } } + oc_arena_clear(&ui->frameArena); oc_input_next_frame(&ui->input); } @@ -2699,7 +2701,6 @@ oc_str32 oc_ui_edit_delete_selection(oc_ui_context* ui, oc_str32 codepoints) void oc_ui_edit_copy_selection_to_clipboard(oc_ui_context* ui, oc_str32 codepoints) { -#if !OC_PLATFORM_ORCA if(ui->editCursor == ui->editMark) { return; @@ -2709,15 +2710,13 @@ void oc_ui_edit_copy_selection_to_clipboard(oc_ui_context* ui, oc_str32 codepoin oc_str32 selection = oc_str32_slice(codepoints, start, end); oc_str8 string = oc_utf8_push_from_codepoints(&ui->frameArena, selection); - oc_clipboard_clear(); oc_clipboard_set_string(string); -#endif } oc_str32 oc_ui_edit_replace_selection_with_clipboard(oc_ui_context* ui, oc_str32 codepoints) { #if OC_PLATFORM_ORCA - oc_str32 result = { 0 }; + oc_str32 result = codepoints; #else oc_str8 string = oc_clipboard_get_string(&ui->frameArena); oc_str32 input = oc_utf8_push_to_codepoints(&ui->frameArena, string); @@ -3095,17 +3094,32 @@ const oc_ui_edit_command OC_UI_EDIT_COMMANDS_WINDOWS[] = { .mods = OC_KEYMOD_CTRL, .operation = OC_UI_EDIT_CUT, .move = OC_UI_EDIT_MOVE_NONE }, + { + .key = OC_KEY_DELETE, + .mods = OC_KEYMOD_SHIFT, + .operation = OC_UI_EDIT_CUT, + .move = OC_UI_EDIT_MOVE_NONE }, //NOTE(martin): copy { .key = OC_KEY_C, .mods = OC_KEYMOD_CTRL, .operation = OC_UI_EDIT_COPY, .move = OC_UI_EDIT_MOVE_NONE }, + { + .key = OC_KEY_INSERT, + .mods = OC_KEYMOD_CTRL, + .operation = OC_UI_EDIT_COPY, + .move = OC_UI_EDIT_MOVE_NONE }, //NOTE(martin): paste { .key = OC_KEY_V, .mods = OC_KEYMOD_CTRL, .operation = OC_UI_EDIT_PASTE, + .move = OC_UI_EDIT_MOVE_NONE }, + { + .key = OC_KEY_INSERT, + .mods = OC_KEYMOD_SHIFT, + .operation = OC_UI_EDIT_PASTE, .move = OC_UI_EDIT_MOVE_NONE } }; @@ -3696,6 +3710,13 @@ oc_ui_text_box_result oc_ui_text_box(const char* name, oc_arena* arena, oc_str8 } } + if(sig.pasted) + { + oc_str8 pastedText = oc_clipboard_pasted_text(&ui->input); + oc_str32 input = oc_utf8_push_to_codepoints(&ui->frameArena, pastedText); + codepoints = oc_ui_edit_replace_selection_with_codepoints(ui, codepoints, input); + } + //NOTE(martin): check changed/accepted if(oldCodepoints.ptr != codepoints.ptr) { diff --git a/src/ui/ui.h b/src/ui/ui.h index 3cb423a..259ada1 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -456,6 +456,8 @@ typedef struct oc_ui_sig bool dragging; bool hovering; + bool pasted; + } oc_ui_sig; typedef void (*oc_ui_box_draw_proc)(oc_ui_box* box, void* data); @@ -620,6 +622,8 @@ typedef struct oc_ui_context oc_ui_edit_move editSelectionMode; i32 editWordSelectionInitialCursor; i32 editWordSelectionInitialMark; + + bool clipboardRegistered; oc_ui_theme* theme; } oc_ui_context; diff --git a/src/wasmbind/core_api.json b/src/wasmbind/core_api.json index e6acbd5..a8ae953 100644 --- a/src/wasmbind/core_api.json +++ b/src/wasmbind/core_api.json @@ -106,5 +106,23 @@ { "name": "scanCode", "type": {"name": "oc_scan_code", "tag": "i"}} ] +}, +{ + "name": "oc_clipboard_get_string", + "cname": "oc_bridge_clipboard_get_string", + "ret": { "name": "oc_str8", "cname": "oc_wasm_str8", "tag": "S"}, + "args": [ + {"name": "arena", + "type": {"name": "oc_arena*", "cname": "i32", "tag": "i"}} + ] +}, +{ + "name": "oc_clipboard_set_string", + "cname": "oc_bridge_clipboard_set_string", + "ret": {"name": "void", "tag": "v"}, + "args": [ + { "name": "value", + "type": {"name": "oc_str8", "cname": "oc_wasm_str8", "tag": "S"}} + ] } ]