mirror of
https://gitlab.freedesktop.org/emersion/libdisplay-info.git
synced 2024-12-24 21:58:59 +01:00
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 <contact@emersion.fr>
This commit is contained in:
parent
ebee35935d
commit
63152283ee
6 changed files with 143 additions and 0 deletions
|
@ -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
|
||||
|
|
11
di-edid-decode/web/README.md
Normal file
11
di-edid-decode/web/README.md
Normal file
|
@ -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/
|
32
di-edid-decode/web/index.html
Normal file
32
di-edid-decode/web/index.html
Normal file
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>libdisplay-info</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>libdisplay-info</h1>
|
||||
|
||||
<p>
|
||||
This webapp parses EDID files via
|
||||
<a href="https://gitlab.freedesktop.org/emersion/libdisplay-info">libdisplay-info</a>.
|
||||
</p>
|
||||
|
||||
<noscript>
|
||||
<p>JavaScript is required.</p>
|
||||
</noscript>
|
||||
|
||||
<p id="status">Loading...</p>
|
||||
|
||||
<div id="app">
|
||||
<p>Select an EDID file:</p>
|
||||
<input type="file" id="file-input">
|
||||
<pre id="output"></pre>
|
||||
</div>
|
||||
|
||||
<script src="main.js"></script>
|
||||
<script src="di-edid-decode.js" async></script>
|
||||
</body>
|
||||
</html>
|
70
di-edid-decode/web/main.js
Normal file
70
di-edid-decode/web/main.js
Normal file
|
@ -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);
|
||||
});
|
7
di-edid-decode/web/style.css
Normal file
7
di-edid-decode/web/style.css
Normal file
|
@ -0,0 +1,7 @@
|
|||
#app {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
}
|
15
di-edid-decode/web/wasm.txt
Normal file
15
di-edid-decode/web/wasm.txt
Normal file
|
@ -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'
|
Loading…
Reference in a new issue