From 63152283ee4e37a90c92150c4ddd574a3e3ee564 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 17 Aug 2022 13:13:13 +0200 Subject: [PATCH] Add webapp This allows running di-edid-decode from a web browser. The C code is compiled to Web Assembly via Emscripten. The HTML shell is based on [1]. [1]: https://github.com/emscripten-core/emscripten/blob/main/src/shell_minimal.html Signed-off-by: Simon Ser --- di-edid-decode/meson.build | 8 ++++ di-edid-decode/web/README.md | 11 ++++++ di-edid-decode/web/index.html | 32 ++++++++++++++++ di-edid-decode/web/main.js | 70 +++++++++++++++++++++++++++++++++++ di-edid-decode/web/style.css | 7 ++++ di-edid-decode/web/wasm.txt | 15 ++++++++ 6 files changed, 143 insertions(+) create mode 100644 di-edid-decode/web/README.md create mode 100644 di-edid-decode/web/index.html create mode 100644 di-edid-decode/web/main.js create mode 100644 di-edid-decode/web/style.css create mode 100644 di-edid-decode/web/wasm.txt diff --git a/di-edid-decode/meson.build b/di-edid-decode/meson.build index 6c3e1a1..9aac5ff 100644 --- a/di-edid-decode/meson.build +++ b/di-edid-decode/meson.build @@ -9,3 +9,11 @@ di_edid_decode = executable( dependencies: [di_dep, math], install: true, ) + +if target_machine.system() == 'emscripten' + fs = import('fs') + + foreach filename : ['index.html', 'main.js', 'style.css'] + fs.copyfile('web' / filename) + endforeach +endif diff --git a/di-edid-decode/web/README.md b/di-edid-decode/web/README.md new file mode 100644 index 0000000..be69050 --- /dev/null +++ b/di-edid-decode/web/README.md @@ -0,0 +1,11 @@ +# Webapp + +To build `di-edid-decode` as a webapp, install Emscripten and run: + + meson setup build-wasm/ --cross-file di-edid-decode/web/wasm.txt + ninja -C build-wasm/ + +Then start a web server serving static files in `build-wasm/di-edid-decode/`, +for instance: + + python -m http.server --directory build-wasm/di-edid-decode/ diff --git a/di-edid-decode/web/index.html b/di-edid-decode/web/index.html new file mode 100644 index 0000000..b6e2ea4 --- /dev/null +++ b/di-edid-decode/web/index.html @@ -0,0 +1,32 @@ + + + + + libdisplay-info + + + + +

libdisplay-info

+ +

+ This webapp parses EDID files via + libdisplay-info. +

+ + + +

Loading...

+ +
+

Select an EDID file:

+ +

+		
+ + + + + diff --git a/di-edid-decode/web/main.js b/di-edid-decode/web/main.js new file mode 100644 index 0000000..58a9262 --- /dev/null +++ b/di-edid-decode/web/main.js @@ -0,0 +1,70 @@ +let appElt = document.getElementById('app'); +let statusElt = document.getElementById('status'); +let fileInput = document.getElementById('file-input'); +let outputElt = document.getElementById('output'); + +function handleFileChange() { + if (fileInput.files.length === 0) { + return; + } + let file = fileInput.files[0]; + let reader = new FileReader(); + reader.addEventListener('load', () => { + let filename = 'edid'; + FS.writeFile(filename, new Uint8Array(reader.result)); + + outputElt.innerHTML = ''; + + let argv = ['di-edid-decode', filename]; + + let ptrSize = 4; + let cArgv = Module._malloc(argv.length * ptrSize); + for (let i = 0; i < argv.length; i++) { + let str = argv[i]; + let cStr = Module._malloc(str.length + 1); + Module.stringToUTF8(str, cStr, str.length + 1); + Module.setValue(cArgv + i * ptrSize, cStr, '*'); + } + + let ret = Module._main(argv.length, cArgv); + console.log('di-edid-decode exited with code ' + ret); + + for (let i = 0; i < argv.length; i++) { + let cStr = Module.getValue(cArgv + i * ptrSize, '*'); + Module._free(cStr); + } + Module._free(cArgv); + }); + reader.readAsArrayBuffer(file); +} + +fileInput.addEventListener('change', handleFileChange); + +window.Module = { + noInitialRun: true, + setStatus: (text) => { + console.log(text || 'Done'); + statusElt.innerText = text; + statusElt.style.display = text ? 'block' : 'none'; + }, + print: (text) => { + outputElt.appendChild(document.createTextNode(text + '\n')); + }, + printErr: (text) => { + let elt = document.createElement('span'); + elt.className = 'error'; + elt.innerText = text + '\n'; + outputElt.appendChild(elt); + }, + onRuntimeInitialized: () => { + app.style.display = 'block'; + handleFileChange(); + }, + onAbort: (text) => { + Module.setStatus('Abort: ' + text); + }, +}; + +window.addEventListener('error', (event) => { + Module.setStatus('Error: ' + event.message); +}); diff --git a/di-edid-decode/web/style.css b/di-edid-decode/web/style.css new file mode 100644 index 0000000..ff39b3a --- /dev/null +++ b/di-edid-decode/web/style.css @@ -0,0 +1,7 @@ +#app { + display: none; +} + +.error { + color: red; +} diff --git a/di-edid-decode/web/wasm.txt b/di-edid-decode/web/wasm.txt new file mode 100644 index 0000000..4f535f9 --- /dev/null +++ b/di-edid-decode/web/wasm.txt @@ -0,0 +1,15 @@ +[binaries] +c = '/usr/lib/emscripten/emcc' +cpp = '/usr/lib/emscripten/em++' +ar = '/usr/lib/emscripten/emar' +strip = '/usr/lib/emscripten/emstrip' + +[built-in options] +default_library = 'static' +c_link_args = ['-sEXPORTED_FUNCTIONS=_main,_malloc,_free', '-sEXPORTED_RUNTIME_METHODS=getValue,setValue,stringToUTF8'] + +[host_machine] +system = 'emscripten' +cpu_family = 'wasm32' +cpu = 'wasm32' +endian = 'little'