diff options
-rwxr-xr-x | examples/ui.c | 6 | ||||
-rw-r--r-- | index.htm | 73 | ||||
-rwxr-xr-x | reduced_system_layer.c | 86 |
3 files changed, 122 insertions, 43 deletions
diff --git a/examples/ui.c b/examples/ui.c index d595617..79bdd70 100755 --- a/examples/ui.c +++ b/examples/ui.c @@ -87,7 +87,7 @@ void update_and_render_frame(void) { for (i64 i = 0; i < platform.input_size; ++i) if (platform.input[i].ctrl) switch (platform.input[i].key) { - case 'v': { + case KEY_V: { if (selection != 0) { i64 i0 = selection < 0 ? cursor + selection : cursor; i64 i1 = selection < 0 ? cursor : cursor + selection; @@ -112,7 +112,7 @@ void update_and_render_frame(void) { } } break; - case 'x': { + case KEY_X: { i64 len = 0; static c8 buf[1024]; @@ -131,7 +131,7 @@ void update_and_render_frame(void) { text_len -= i1 - i0; } break; - case 'c': { + case KEY_C: { i64 len = 0; static c8 buf[1024]; @@ -10,8 +10,8 @@ <canvas style="margin: 0; width: 100%; height: 100%;" id="frame" oncontextmenu="event.preventDefault()"></canvas> <script type="worklet"> registerProcessor( - 'Sound_Node', - class Sound_Ring extends AudioWorkletProcessor { + "Sound_Node", + class Sound_Node extends AudioWorkletProcessor { constructor(options) { super(); @@ -33,7 +33,7 @@ fd_seek : () => { throw new Error("Unexpected fd_seek call"); }, }, env : { - p_clipboard_write : (size, text) => { + p_clipboard_write_impl : (size, text) => { let text_buffer = new ArrayBuffer(size); new Uint8Array(text_buffer).set(new Uint8Array(this.memory_buffer, text, size)); @@ -116,7 +116,7 @@ if (this.program === undefined) return; - this.program.exports.js_keydown(ev.key, ev.mod); + this.program.exports.js_keydown(ev.key, ev.mod, ev.ch); }, keyup : (ev) => { @@ -125,6 +125,18 @@ this.program.exports.js_keyup(ev.key, ev.mod); }, + + paste : (ev) => { + if (this.program === undefined) + return; + + let address = this.program.exports.js_clipboard_buffer(ev.bytes.length); + let len = this.program.exports.js_clipboard_size(); + + new Uint8Array(this.memory_buffer, address, len).set(ev.bytes.subarray(0, len)); + + this.program.exports.js_keydown(ev.key, ev.mod, ev.ch); + }, }; this.port.onmessage = (ev) => { @@ -162,6 +174,8 @@ ); </script> <script type="text/javascript"> + const KEY_PASTE = 118; + let key_map = { "Backspace" : 8, "Tab" : 9, @@ -229,7 +243,7 @@ "KeyS" : 115, "KeyT" : 116, "KeyU" : 117, - "KeyV" : 118, + "KeyV" : KEY_PASTE, "KeyW" : 119, "KeyX" : 120, "KeyY" : 121, @@ -276,6 +290,12 @@ return mod; }; + function char_from_event(ev) { + if (ev.key.length != 1) + return 0; + return ev.key.charCodeAt(0); + } + async function run(attrs) { let sound_sample_rate = 44100; // TODO let sound_num_channels = 2; // TODO @@ -293,6 +313,9 @@ let sound_context; let sound_node; + let paste_mod = 0; + let paste_ch = 0; + canvas = attrs.canvas; context = canvas.getContext("2d"); @@ -378,7 +401,6 @@ frame : (ev) => { pixels_buffer = ev.pixels_buffer; - let pixels = new Uint8Array(pixels_buffer); } }; @@ -428,23 +450,26 @@ }); window.addEventListener("keydown", (ev) => { - ev.preventDefault(); if (!sound_ready) return; if (ev.repeat) return; - let mod = mod_from_event(ev); let key = key_from_code(ev.code); if (key == 0) return; + let mod = mod_from_event(ev); + let ch = char_from_event(ev); - console.log(ev); - - sound_node.port.postMessage({ - id : "keydown", - mod : mod, - key : key, - }); + if (ev.ctrlKey && key == KEY_PASTE) { + paste_mod = mod; + paste_ch = ch; + } else + sound_node.port.postMessage({ + id : "keydown", + mod : mod, + key : key, + ch : ch, + }); }); window.addEventListener("keyup", (ev) => { @@ -453,15 +478,29 @@ return; if (ev.repeat) return; - let mod = mod_from_event(ev); let key = key_from_code(ev.code); if (key == 0) return; + let mod = mod_from_event(ev); sound_node.port.postMessage({ id : "keyup", - mod : mod, key : key, + mod : mod, + }); + }); + + window.addEventListener("paste", (ev) => { + ev.preventDefault(); + if (!sound_ready) + return; + + sound_node.port.postMessage({ + id : "paste", + bytes : new TextEncoder("utf-8").encode(ev.clipboardData.getData("text")), + mod : paste_mod, + key : KEY_PASTE, + ch : paste_ch, }); }); } diff --git a/reduced_system_layer.c b/reduced_system_layer.c index 30fb48b..87778cd 100755 --- a/reduced_system_layer.c +++ b/reduced_system_layer.c @@ -1565,16 +1565,17 @@ void p_clipboard_write(i64 size, c8 *data) { #ifdef __wasm__ -static u32 _buffer[MAX_NUM_PIXELS] = {0}; -static Input_Key _input[MAX_INPUT_SIZE] = {0}; -static i32 _num_events = 0; -static i32 _input_size = 0; -static b8 _key_pressed[MAX_NUM_KEYS] = {0}; -static b8 _wait_events = 0; -i64 _sound_position = 0; -i64 _sound_read = 0; -f32 _sound_ring[MAX_NUM_AUDIO_FRAMES] = {0}; -f32 _sound_buffer[MAX_NUM_AUDIO_FRAMES] = {0}; +static u32 _buffer[MAX_NUM_PIXELS] = {0}; +static Input_Key _input[MAX_INPUT_SIZE] = {0}; +static c8 _clipboard_buffer[MAX_CLIPBOARD_SIZE] = {0}; +static i32 _num_events = 0; +static i32 _input_size = 0; +static b8 _key_pressed[MAX_NUM_KEYS] = {0}; +static b8 _wait_events = 0; +i64 _sound_position = 0; +i64 _sound_read = 0; +f32 _sound_ring[MAX_NUM_AUDIO_FRAMES] = {0}; +f32 _sound_buffer[MAX_NUM_AUDIO_FRAMES] = {0}; i32 p_time_impl(void); @@ -1588,11 +1589,12 @@ void p_sleep_for(i64 duration) { void p_init(void) { ++_num_events; - platform.pixels = _buffer; - platform.input = _input; - platform.done = 1; - _sound_position = AUDIO_AVAIL_MIN % MAX_NUM_AUDIO_FRAMES; - _sound_read = 0; + platform.pixels = _buffer; + platform.input = _input; + platform.clipboard = _clipboard_buffer; + platform.done = 1; + _sound_position = AUDIO_AVAIL_MIN % MAX_NUM_AUDIO_FRAMES; + _sound_read = 0; } i32 p_handle_events(void) { @@ -1615,6 +1617,21 @@ i32 p_wait_events(void) { void p_render_frame(void) { } +void p_clipboard_write_impl(i32 size, c8 *data); + +void p_clipboard_write(i64 size, c8 *data) { + if (size < 0 || data == NULL) + return; + if (size > MAX_CLIPBOARD_SIZE) + size = MAX_CLIPBOARD_SIZE; + + platform.clipboard_size = size; + for (i64 i = 0; i < size; ++i) + platform.clipboard[i] = data[i]; + + p_clipboard_write_impl((i32) size, data); +} + void p_handle_audio(i64 samples_elapsed) { if (samples_elapsed <= 0) return; @@ -1722,22 +1739,32 @@ __attribute__((export_name("js_mouseup"))) void js_mouseup(u32 buttons) { if (!(buttons & 4)) platform.key_down[BUTTON_MIDDLE] = 0; } -__attribute__((export_name("js_keydown"))) void js_keydown(u32 key, u32 mod) { - // TODO +__attribute__((export_name("js_keydown"))) void js_keydown(u32 key, u32 mod, u32 ch) { ++_num_events; - _key_pressed[key] = 1; - platform.key_down[key] = 1; + _key_pressed[key] = 1; + platform.key_down[key] = 1; + platform.key_down[MOD_CTRL] = (mod & 1) ? 1 : 0; + platform.key_down[MOD_SHIFT] = (mod & 2) ? 1 : 0; + platform.key_down[MOD_ALT] = (mod & 4) ? 1 : 0; + platform.key_down[MOD_META] = (mod & 8) ? 1 : 0; if (platform.input_size < MAX_INPUT_SIZE) platform.input[_input_size++] = (Input_Key) { - .key = key, - .c = key, + .ctrl = (mod & 1) ? 1 : 0, + .shift = (mod & 2) ? 1 : 0, + .alt = (mod & 4) ? 1 : 0, + .meta = (mod & 8) ? 1 : 0, + .key = key, + .c = ch, }; } __attribute__((export_name("js_keyup"))) void js_keyup(u32 key, u32 mod) { - // TODO ++_num_events; - platform.key_down[key] = 0; + platform.key_down[key] = 0; + platform.key_down[MOD_CTRL] = (mod & 1) ? 1 : 0; + platform.key_down[MOD_SHIFT] = (mod & 2) ? 1 : 0; + platform.key_down[MOD_ALT] = (mod & 4) ? 1 : 0; + platform.key_down[MOD_META] = (mod & 8) ? 1 : 0; } __attribute__((export_name("js_sample_rate"))) f64 js_sample_rate(void) { @@ -1756,6 +1783,19 @@ __attribute__((export_name("js_sound_buffer"))) void *js_sound_buffer(void) { return _sound_buffer; } +__attribute__((export_name("js_clipboard_size"))) i32 js_clipboard_size(void) { + return platform.clipboard_size; +} + +__attribute__((export_name("js_clipboard_buffer"))) void *js_clipboard_buffer(i32 len) { + if (len < 0) + len = 0; + if (len > MAX_CLIPBOARD_SIZE) + len = MAX_CLIPBOARD_SIZE; + platform.clipboard_size = len; + return platform.clipboard; +} + #endif // __wasm__ // ================================================================ |