diff --git a/platform/javascript/js/libs/library_pandemonium_display.js b/platform/javascript/js/libs/library_pandemonium_display.js index 86bae03b1..d4ee425c7 100644 --- a/platform/javascript/js/libs/library_pandemonium_display.js +++ b/platform/javascript/js/libs/library_pandemonium_display.js @@ -30,101 +30,101 @@ const PandemoniumDisplayVK = { - $PandemoniumDisplayVK__deps: ['$PandemoniumRuntime', '$PandemoniumConfig', '$PandemoniumEventListeners'], - $PandemoniumDisplayVK__postset: 'PandemoniumOS.atexit(function(resolve, reject) { PandemoniumDisplayVK.clear(); resolve(); });', - $PandemoniumDisplayVK: { - textinput: null, - textarea: null, + $PandemoniumDisplayVK__deps: ['$PandemoniumRuntime', '$PandemoniumConfig', '$PandemoniumEventListeners'], + $PandemoniumDisplayVK__postset: 'PandemoniumOS.atexit(function(resolve, reject) { PandemoniumDisplayVK.clear(); resolve(); });', + $PandemoniumDisplayVK: { + textinput: null, + textarea: null, - available: function() { - return PandemoniumConfig.virtual_keyboard && 'ontouchstart' in window; - }, - - init: function(input_cb) { - function create(what) { - const elem = document.createElement(what); - elem.style.display = 'none'; - elem.style.position = 'absolute'; - elem.style.zIndex = '-1'; - elem.style.background = 'transparent'; - elem.style.padding = '0px'; - elem.style.margin = '0px'; - elem.style.overflow = 'hidden'; - elem.style.width = '0px'; - elem.style.height = '0px'; - elem.style.border = '0px'; - elem.style.outline = 'none'; - elem.readonly = true; - elem.disabled = true; - PandemoniumEventListeners.add(elem, 'input', function(evt) { - const c_str = PandemoniumRuntime.allocString(elem.value); - input_cb(c_str, elem.selectionEnd); - PandemoniumRuntime.free(c_str); - }, false); - PandemoniumEventListeners.add(elem, 'blur', function(evt) { - elem.style.display = 'none'; - elem.readonly = true; - elem.disabled = true; - }, false); - PandemoniumConfig.canvas.insertAdjacentElement('beforebegin', elem); - return elem; - } - PandemoniumDisplayVK.textinput = create('input'); - PandemoniumDisplayVK.textarea = create('textarea'); - PandemoniumDisplayVK.updateSize(); - }, - show: function(text, multiline, start, end) { - if (!PandemoniumDisplayVK.textinput || !PandemoniumDisplayVK.textarea) { - return; - } - if (PandemoniumDisplayVK.textinput.style.display !== '' || PandemoniumDisplayVK.textarea.style.display !== '') { - PandemoniumDisplayVK.hide(); - } - PandemoniumDisplayVK.updateSize(); - const elem = multiline ? PandemoniumDisplayVK.textarea : PandemoniumDisplayVK.textinput; - elem.readonly = false; - elem.disabled = false; - elem.value = text; - elem.style.display = 'block'; - elem.focus(); - elem.setSelectionRange(start, end); - }, - hide: function() { - if (!PandemoniumDisplayVK.textinput || !PandemoniumDisplayVK.textarea) { - return; - } - [PandemoniumDisplayVK.textinput, PandemoniumDisplayVK.textarea].forEach(function(elem) { - elem.blur(); - elem.style.display = 'none'; - elem.value = ''; - }); - }, - updateSize: function() { - if (!PandemoniumDisplayVK.textinput || !PandemoniumDisplayVK.textarea) { - return; - } - const rect = PandemoniumConfig.canvas.getBoundingClientRect(); - - function update(elem) { - elem.style.left = `${rect.left}px`; - elem.style.top = `${rect.top}px`; - elem.style.width = `${rect.width}px`; - elem.style.height = `${rect.height}px`; - } - update(PandemoniumDisplayVK.textinput); - update(PandemoniumDisplayVK.textarea); - }, - clear: function() { - if (PandemoniumDisplayVK.textinput) { - PandemoniumDisplayVK.textinput.remove(); - PandemoniumDisplayVK.textinput = null; - } - if (PandemoniumDisplayVK.textarea) { - PandemoniumDisplayVK.textarea.remove(); - PandemoniumDisplayVK.textarea = null; - } - }, + available: function() { + return PandemoniumConfig.virtual_keyboard && 'ontouchstart' in window; }, + + init: function(input_cb) { + function create(what) { + const elem = document.createElement(what); + elem.style.display = 'none'; + elem.style.position = 'absolute'; + elem.style.zIndex = '-1'; + elem.style.background = 'transparent'; + elem.style.padding = '0px'; + elem.style.margin = '0px'; + elem.style.overflow = 'hidden'; + elem.style.width = '0px'; + elem.style.height = '0px'; + elem.style.border = '0px'; + elem.style.outline = 'none'; + elem.readonly = true; + elem.disabled = true; + PandemoniumEventListeners.add(elem, 'input', function(evt) { + const c_str = PandemoniumRuntime.allocString(elem.value); + input_cb(c_str, elem.selectionEnd); + PandemoniumRuntime.free(c_str); + }, false); + PandemoniumEventListeners.add(elem, 'blur', function(evt) { + elem.style.display = 'none'; + elem.readonly = true; + elem.disabled = true; + }, false); + PandemoniumConfig.canvas.insertAdjacentElement('beforebegin', elem); + return elem; + } + PandemoniumDisplayVK.textinput = create('input'); + PandemoniumDisplayVK.textarea = create('textarea'); + PandemoniumDisplayVK.updateSize(); + }, + show: function(text, multiline, start, end) { + if (!PandemoniumDisplayVK.textinput || !PandemoniumDisplayVK.textarea) { + return; + } + if (PandemoniumDisplayVK.textinput.style.display !== '' || PandemoniumDisplayVK.textarea.style.display !== '') { + PandemoniumDisplayVK.hide(); + } + PandemoniumDisplayVK.updateSize(); + const elem = multiline ? PandemoniumDisplayVK.textarea : PandemoniumDisplayVK.textinput; + elem.readonly = false; + elem.disabled = false; + elem.value = text; + elem.style.display = 'block'; + elem.focus(); + elem.setSelectionRange(start, end); + }, + hide: function() { + if (!PandemoniumDisplayVK.textinput || !PandemoniumDisplayVK.textarea) { + return; + } + [PandemoniumDisplayVK.textinput, PandemoniumDisplayVK.textarea].forEach(function(elem) { + elem.blur(); + elem.style.display = 'none'; + elem.value = ''; + }); + }, + updateSize: function() { + if (!PandemoniumDisplayVK.textinput || !PandemoniumDisplayVK.textarea) { + return; + } + const rect = PandemoniumConfig.canvas.getBoundingClientRect(); + + function update(elem) { + elem.style.left = `${rect.left}px`; + elem.style.top = `${rect.top}px`; + elem.style.width = `${rect.width}px`; + elem.style.height = `${rect.height}px`; + } + update(PandemoniumDisplayVK.textinput); + update(PandemoniumDisplayVK.textarea); + }, + clear: function() { + if (PandemoniumDisplayVK.textinput) { + PandemoniumDisplayVK.textinput.remove(); + PandemoniumDisplayVK.textinput = null; + } + if (PandemoniumDisplayVK.textarea) { + PandemoniumDisplayVK.textarea.remove(); + PandemoniumDisplayVK.textarea = null; + } + }, + }, }; mergeInto(LibraryManager.library, PandemoniumDisplayVK); @@ -133,159 +133,159 @@ mergeInto(LibraryManager.library, PandemoniumDisplayVK); * Keeps track of cursor status and custom shapes. */ const PandemoniumDisplayCursor = { - $PandemoniumDisplayCursor__deps: ['$PandemoniumOS', '$PandemoniumConfig'], - $PandemoniumDisplayCursor__postset: 'PandemoniumOS.atexit(function(resolve, reject) { PandemoniumDisplayCursor.clear(); resolve(); });', - $PandemoniumDisplayCursor: { - shape: 'auto', - visible: true, - cursors: {}, - set_style: function(style) { - PandemoniumConfig.canvas.style.cursor = style; - }, - set_shape: function(shape) { - PandemoniumDisplayCursor.shape = shape; - let css = shape; - if (shape in PandemoniumDisplayCursor.cursors) { - const c = PandemoniumDisplayCursor.cursors[shape]; - css = `url("${c.url}") ${c.x} ${c.y}, auto`; - } - if (PandemoniumDisplayCursor.visible) { - PandemoniumDisplayCursor.set_style(css); - } - }, - clear: function() { - PandemoniumDisplayCursor.set_style(''); - PandemoniumDisplayCursor.shape = 'auto'; - PandemoniumDisplayCursor.visible = true; - Object.keys(PandemoniumDisplayCursor.cursors).forEach(function(key) { - URL.revokeObjectURL(PandemoniumDisplayCursor.cursors[key]); - delete PandemoniumDisplayCursor.cursors[key]; - }); - }, - lockPointer: function() { - const canvas = PandemoniumConfig.canvas; - if (canvas.requestPointerLock) { - canvas.requestPointerLock(); - } - }, - releasePointer: function() { - if (document.exitPointerLock) { - document.exitPointerLock(); - } - }, - isPointerLocked: function() { - return document.pointerLockElement === PandemoniumConfig.canvas; - }, + $PandemoniumDisplayCursor__deps: ['$PandemoniumOS', '$PandemoniumConfig'], + $PandemoniumDisplayCursor__postset: 'PandemoniumOS.atexit(function(resolve, reject) { PandemoniumDisplayCursor.clear(); resolve(); });', + $PandemoniumDisplayCursor: { + shape: 'auto', + visible: true, + cursors: {}, + set_style: function(style) { + PandemoniumConfig.canvas.style.cursor = style; }, + set_shape: function(shape) { + PandemoniumDisplayCursor.shape = shape; + let css = shape; + if (shape in PandemoniumDisplayCursor.cursors) { + const c = PandemoniumDisplayCursor.cursors[shape]; + css = `url("${c.url}") ${c.x} ${c.y}, auto`; + } + if (PandemoniumDisplayCursor.visible) { + PandemoniumDisplayCursor.set_style(css); + } + }, + clear: function() { + PandemoniumDisplayCursor.set_style(''); + PandemoniumDisplayCursor.shape = 'auto'; + PandemoniumDisplayCursor.visible = true; + Object.keys(PandemoniumDisplayCursor.cursors).forEach(function(key) { + URL.revokeObjectURL(PandemoniumDisplayCursor.cursors[key]); + delete PandemoniumDisplayCursor.cursors[key]; + }); + }, + lockPointer: function() { + const canvas = PandemoniumConfig.canvas; + if (canvas.requestPointerLock) { + canvas.requestPointerLock(); + } + }, + releasePointer: function() { + if (document.exitPointerLock) { + document.exitPointerLock(); + } + }, + isPointerLocked: function() { + return document.pointerLockElement === PandemoniumConfig.canvas; + }, + }, }; mergeInto(LibraryManager.library, PandemoniumDisplayCursor); const PandemoniumDisplayScreen = { - $PandemoniumDisplayScreen__deps: ['$PandemoniumConfig', '$PandemoniumOS', '$GL', 'emscripten_webgl_get_current_context'], - $PandemoniumDisplayScreen: { - desired_size: [0, 0], - hidpi: true, - getPixelRatio: function() { - return PandemoniumDisplayScreen.hidpi ? window.devicePixelRatio || 1 : 1; - }, - isFullscreen: function() { - const elem = document.fullscreenElement || document.mozFullscreenElement || - document.webkitFullscreenElement || document.msFullscreenElement; - if (elem) { - return elem === PandemoniumConfig.canvas; - } - // But maybe knowing the element is not supported. - return document.fullscreen || document.mozFullScreen || - document.webkitIsFullscreen; - }, - hasFullscreen: function() { - return document.fullscreenEnabled || document.mozFullScreenEnabled || - document.webkitFullscreenEnabled; - }, - requestFullscreen: function() { - if (!PandemoniumDisplayScreen.hasFullscreen()) { - return 1; - } - const canvas = PandemoniumConfig.canvas; - try { - const promise = (canvas.requestFullscreen || canvas.msRequestFullscreen || - canvas.mozRequestFullScreen || canvas.mozRequestFullscreen || - canvas.webkitRequestFullscreen - ).call(canvas); - // Some browsers (Safari) return undefined. - // For the standard ones, we need to catch it. - if (promise) { - promise.catch(function() { - // nothing to do. - }); - } - } catch (e) { - return 1; - } - return 0; - }, - exitFullscreen: function() { - if (!PandemoniumDisplayScreen.isFullscreen()) { - return 0; - } - try { - const promise = document.exitFullscreen(); - if (promise) { - promise.catch(function() { - // nothing to do. - }); - } - } catch (e) { - return 1; - } - return 0; - }, - _updateGL: function() { - const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef - const gl = GL.getContext(gl_context_handle); - if (gl) { - GL.resizeOffscreenFramebuffer(gl); - } - }, - updateSize: function() { - const isFullscreen = PandemoniumDisplayScreen.isFullscreen(); - const wantsFullWindow = PandemoniumConfig.canvas_resize_policy === 2; - const noResize = PandemoniumConfig.canvas_resize_policy === 0; - const wwidth = PandemoniumDisplayScreen.desired_size[0]; - const wheight = PandemoniumDisplayScreen.desired_size[1]; - const canvas = PandemoniumConfig.canvas; - let width = wwidth; - let height = wheight; - if (noResize) { - // Don't resize canvas, just update GL if needed. - if (canvas.width !== width || canvas.height !== height) { - PandemoniumDisplayScreen.desired_size = [canvas.width, canvas.height]; - PandemoniumDisplayScreen._updateGL(); - return 1; - } - return 0; - } - const scale = PandemoniumDisplayScreen.getPixelRatio(); - if (isFullscreen || wantsFullWindow) { - // We need to match screen size. - width = window.innerWidth * scale; - height = window.innerHeight * scale; - } - const csw = `${width / scale}px`; - const csh = `${height / scale}px`; - if (canvas.style.width !== csw || canvas.style.height !== csh || canvas.width !== width || canvas.height !== height) { - // Size doesn't match. - // Resize canvas, set correct CSS pixel size, update GL. - canvas.width = width; - canvas.height = height; - canvas.style.width = csw; - canvas.style.height = csh; - PandemoniumDisplayScreen._updateGL(); - return 1; - } - return 0; - }, + $PandemoniumDisplayScreen__deps: ['$PandemoniumConfig', '$PandemoniumOS', '$GL', 'emscripten_webgl_get_current_context'], + $PandemoniumDisplayScreen: { + desired_size: [0, 0], + hidpi: true, + getPixelRatio: function() { + return PandemoniumDisplayScreen.hidpi ? window.devicePixelRatio || 1 : 1; }, + isFullscreen: function() { + const elem = document.fullscreenElement || document.mozFullscreenElement || + document.webkitFullscreenElement || document.msFullscreenElement; + if (elem) { + return elem === PandemoniumConfig.canvas; + } + // But maybe knowing the element is not supported. + return document.fullscreen || document.mozFullScreen || + document.webkitIsFullscreen; + }, + hasFullscreen: function() { + return document.fullscreenEnabled || document.mozFullScreenEnabled || + document.webkitFullscreenEnabled; + }, + requestFullscreen: function() { + if (!PandemoniumDisplayScreen.hasFullscreen()) { + return 1; + } + const canvas = PandemoniumConfig.canvas; + try { + const promise = (canvas.requestFullscreen || canvas.msRequestFullscreen || + canvas.mozRequestFullScreen || canvas.mozRequestFullscreen || + canvas.webkitRequestFullscreen + ).call(canvas); + // Some browsers (Safari) return undefined. + // For the standard ones, we need to catch it. + if (promise) { + promise.catch(function() { + // nothing to do. + }); + } + } catch (e) { + return 1; + } + return 0; + }, + exitFullscreen: function() { + if (!PandemoniumDisplayScreen.isFullscreen()) { + return 0; + } + try { + const promise = document.exitFullscreen(); + if (promise) { + promise.catch(function() { + // nothing to do. + }); + } + } catch (e) { + return 1; + } + return 0; + }, + _updateGL: function() { + const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef + const gl = GL.getContext(gl_context_handle); + if (gl) { + GL.resizeOffscreenFramebuffer(gl); + } + }, + updateSize: function() { + const isFullscreen = PandemoniumDisplayScreen.isFullscreen(); + const wantsFullWindow = PandemoniumConfig.canvas_resize_policy === 2; + const noResize = PandemoniumConfig.canvas_resize_policy === 0; + const wwidth = PandemoniumDisplayScreen.desired_size[0]; + const wheight = PandemoniumDisplayScreen.desired_size[1]; + const canvas = PandemoniumConfig.canvas; + let width = wwidth; + let height = wheight; + if (noResize) { + // Don't resize canvas, just update GL if needed. + if (canvas.width !== width || canvas.height !== height) { + PandemoniumDisplayScreen.desired_size = [canvas.width, canvas.height]; + PandemoniumDisplayScreen._updateGL(); + return 1; + } + return 0; + } + const scale = PandemoniumDisplayScreen.getPixelRatio(); + if (isFullscreen || wantsFullWindow) { + // We need to match screen size. + width = window.innerWidth * scale; + height = window.innerHeight * scale; + } + const csw = `${width / scale}px`; + const csh = `${height / scale}px`; + if (canvas.style.width !== csw || canvas.style.height !== csh || canvas.width !== width || canvas.height !== height) { + // Size doesn't match. + // Resize canvas, set correct CSS pixel size, update GL. + canvas.width = width; + canvas.height = height; + canvas.style.width = csw; + canvas.style.height = csh; + PandemoniumDisplayScreen._updateGL(); + return 1; + } + return 0; + }, + }, }; mergeInto(LibraryManager.library, PandemoniumDisplayScreen); @@ -295,365 +295,366 @@ mergeInto(LibraryManager.library, PandemoniumDisplayScreen); * Exposes all the functions needed by DisplayServer implementation. */ const PandemoniumDisplay = { - $PandemoniumDisplay__deps: ['$PandemoniumConfig', '$PandemoniumRuntime', '$PandemoniumDisplayCursor', '$PandemoniumEventListeners', '$PandemoniumDisplayScreen', '$PandemoniumDisplayVK'], - $PandemoniumDisplay: { - window_icon: '', - findDPI: function() { - function testDPI(dpi) { - return window.matchMedia(`(max-resolution: ${dpi}dpi)`).matches; - } + $PandemoniumDisplay__deps: ['$PandemoniumConfig', '$PandemoniumRuntime', '$PandemoniumDisplayCursor', '$PandemoniumEventListeners', '$PandemoniumDisplayScreen', '$PandemoniumDisplayVK'], + $PandemoniumDisplay: { + window_icon: '', + findDPI: function() { + function testDPI(dpi) { + return window.matchMedia(`(max-resolution: ${dpi}dpi)`).matches; + } - function bisect(low, high, func) { - const mid = parseInt(((high - low) / 2) + low, 10); - if (high - low <= 1) { - return func(high) ? high : low; - } - if (func(mid)) { - return bisect(low, mid, func); - } - return bisect(mid, high, func); - } - try { - const dpi = bisect(0, 800, testDPI); - return dpi >= 96 ? dpi : 96; - } catch (e) { - return 96; - } - }, - }, - - // This is implemented as "glGetBufferSubData" in new emscripten versions. - // Since we have to support older (pre 2.0.17) emscripten versions, we add this wrapper function instead. - pandemonium_js_display_glGetBufferSubData__sig: 'viiii', - pandemonium_js_display_glGetBufferSubData__deps: ['$GL', 'emscripten_webgl_get_current_context'], - pandemonium_js_display_glGetBufferSubData: function(target, offset, size, data) { - const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef - const gl = GL.getContext(gl_context_handle); - if (gl) { - gl.GLctx['getBufferSubData'](target, offset, HEAPU8, data, size); + function bisect(low, high, func) { + const mid = parseInt(((high - low) / 2) + low, 10); + if (high - low <= 1) { + return func(high) ? high : low; } - }, - - pandemonium_js_display_is_swap_ok_cancel__sig: 'i', - pandemonium_js_display_is_swap_ok_cancel: function() { - const win = (['Windows', 'Win64', 'Win32', 'WinCE']); - const plat = navigator.platform || ''; - if (win.indexOf(plat) !== -1) { - return 1; + if (func(mid)) { + return bisect(low, mid, func); } - return 0; + return bisect(mid, high, func); + } + try { + const dpi = bisect(0, 800, testDPI); + return dpi >= 96 ? dpi : 96; + } catch (e) { + return 96; + } }, + }, - pandemonium_js_display_alert__sig: 'vi', - pandemonium_js_display_alert: function(p_text) { - window.alert(PandemoniumRuntime.parseString(p_text)); // eslint-disable-line no-alert - }, + // This is implemented as "glGetBufferSubData" in new emscripten versions. + // Since we have to support older (pre 2.0.17) emscripten versions, we add this wrapper function instead. + pandemonium_js_display_glGetBufferSubData__sig: 'viiii', + pandemonium_js_display_glGetBufferSubData__deps: ['$GL', 'emscripten_webgl_get_current_context'], + pandemonium_js_display_glGetBufferSubData: function(target, offset, size, data) { + const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef + const gl = GL.getContext(gl_context_handle); + if (gl) { + gl.GLctx['getBufferSubData'](target, offset, HEAPU8, data, size); + } + }, - pandemonium_js_display_screen_dpi_get__sig: 'i', - pandemonium_js_display_screen_dpi_get: function() { - return PandemoniumDisplay.findDPI(); - }, + pandemonium_js_display_is_swap_ok_cancel__sig: 'i', + pandemonium_js_display_is_swap_ok_cancel: function() { + const win = (['Windows', 'Win64', 'Win32', 'WinCE']); + const plat = navigator.platform || ''; + if (win.indexOf(plat) !== -1) { + return 1; + } + return 0; + }, - pandemonium_js_display_pixel_ratio_get__sig: 'f', - pandemonium_js_display_pixel_ratio_get: function() { - return PandemoniumDisplayScreen.getPixelRatio(); - }, + pandemonium_js_display_alert__sig: 'vi', + pandemonium_js_display_alert: function(p_text) { + window.alert(PandemoniumRuntime.parseString(p_text)); // eslint-disable-line no-alert + }, - pandemonium_js_display_fullscreen_request__sig: 'i', - pandemonium_js_display_fullscreen_request: function() { - return PandemoniumDisplayScreen.requestFullscreen(); - }, + pandemonium_js_display_screen_dpi_get__sig: 'i', + pandemonium_js_display_screen_dpi_get: function() { + return PandemoniumDisplay.findDPI(); + }, - pandemonium_js_display_fullscreen_exit__sig: 'i', - pandemonium_js_display_fullscreen_exit: function() { - return PandemoniumDisplayScreen.exitFullscreen(); - }, + pandemonium_js_display_pixel_ratio_get__sig: 'f', + pandemonium_js_display_pixel_ratio_get: function() { + return PandemoniumDisplayScreen.getPixelRatio(); + }, - pandemonium_js_display_desired_size_set__sig: 'vii', - pandemonium_js_display_desired_size_set: function(width, height) { - PandemoniumDisplayScreen.desired_size = [width, height]; - PandemoniumDisplayScreen.updateSize(); - }, + pandemonium_js_display_fullscreen_request__sig: 'i', + pandemonium_js_display_fullscreen_request: function() { + return PandemoniumDisplayScreen.requestFullscreen(); + }, - pandemonium_js_display_size_update__sig: 'i', - pandemonium_js_display_size_update: function() { - const updated = PandemoniumDisplayScreen.updateSize(); - if (updated) { - PandemoniumDisplayVK.updateSize(); - } - return updated; - }, + pandemonium_js_display_fullscreen_exit__sig: 'i', + pandemonium_js_display_fullscreen_exit: function() { + return PandemoniumDisplayScreen.exitFullscreen(); + }, - pandemonium_js_display_screen_size_get__sig: 'vii', - pandemonium_js_display_screen_size_get: function(width, height) { - const scale = PandemoniumDisplayScreen.getPixelRatio(); - PandemoniumRuntime.setHeapValue(width, window.screen.width * scale, 'i32'); - PandemoniumRuntime.setHeapValue(height, window.screen.height * scale, 'i32'); - }, + pandemonium_js_display_desired_size_set__sig: 'vii', + pandemonium_js_display_desired_size_set: function(width, height) { + PandemoniumDisplayScreen.desired_size = [width, height]; + PandemoniumDisplayScreen.updateSize(); + }, - pandemonium_js_display_window_size_get: function(p_width, p_height) { - PandemoniumRuntime.setHeapValue(p_width, PandemoniumConfig.canvas.width, 'i32'); - PandemoniumRuntime.setHeapValue(p_height, PandemoniumConfig.canvas.height, 'i32'); - }, + pandemonium_js_display_size_update__sig: 'i', + pandemonium_js_display_size_update: function() { + const updated = PandemoniumDisplayScreen.updateSize(); + if (updated) { + PandemoniumDisplayVK.updateSize(); + } + return updated; + }, - pandemonium_js_display_has_webgl__sig: 'ii', - pandemonium_js_display_has_webgl: function(p_version) { - if (p_version !== 1 && p_version !== 2) { - return false; - } - try { - return !!document.createElement('canvas').getContext(p_version === 2 ? 'webgl2' : 'webgl'); - } catch (e) { - /* Not available */ - } - return false; - }, + pandemonium_js_display_screen_size_get__sig: 'vii', + pandemonium_js_display_screen_size_get: function(width, height) { + const scale = PandemoniumDisplayScreen.getPixelRatio(); + PandemoniumRuntime.setHeapValue(width, window.screen.width * scale, 'i32'); + PandemoniumRuntime.setHeapValue(height, window.screen.height * scale, 'i32'); + }, - /* - * Canvas - */ - pandemonium_js_display_canvas_focus__sig: 'v', - pandemonium_js_display_canvas_focus: function() { - PandemoniumConfig.canvas.focus(); - }, + pandemonium_js_display_window_size_get__sig: 'vii', + pandemonium_js_display_window_size_get: function(p_width, p_height) { + PandemoniumRuntime.setHeapValue(p_width, PandemoniumConfig.canvas.width, 'i32'); + PandemoniumRuntime.setHeapValue(p_height, PandemoniumConfig.canvas.height, 'i32'); + }, - pandemonium_js_display_canvas_is_focused__sig: 'i', - pandemonium_js_display_canvas_is_focused: function() { - return document.activeElement === PandemoniumConfig.canvas; - }, + pandemonium_js_display_has_webgl__sig: 'ii', + pandemonium_js_display_has_webgl: function(p_version) { + if (p_version !== 1 && p_version !== 2) { + return false; + } + try { + return !!document.createElement('canvas').getContext(p_version === 2 ? 'webgl2' : 'webgl'); + } catch (e) { + /* Not available */ + } + return false; + }, - /* - * Touchscreen - */ - pandemonium_js_display_touchscreen_is_available__sig: 'i', - pandemonium_js_display_touchscreen_is_available: function() { - return 'ontouchstart' in window; - }, + /* + * Canvas + */ + pandemonium_js_display_canvas_focus__sig: 'v', + pandemonium_js_display_canvas_focus: function() { + PandemoniumConfig.canvas.focus(); + }, - /* - * Clipboard - */ - pandemonium_js_display_clipboard_set__sig: 'ii', - pandemonium_js_display_clipboard_set: function(p_text) { - const text = PandemoniumRuntime.parseString(p_text); - if (!navigator.clipboard || !navigator.clipboard.writeText) { - return 1; - } - navigator.clipboard.writeText(text).catch(function(e) { - // Setting OS clipboard is only possible from an input callback. - PandemoniumRuntime.error('Setting OS clipboard is only possible from an input callback for the HTML5 plafrom. Exception:', e); - }); - return 0; - }, + pandemonium_js_display_canvas_is_focused__sig: 'i', + pandemonium_js_display_canvas_is_focused: function() { + return document.activeElement === PandemoniumConfig.canvas; + }, - pandemonium_js_display_clipboard_get__sig: 'ii', - pandemonium_js_display_clipboard_get: function(callback) { - const func = PandemoniumRuntime.get_func(callback); - try { - navigator.clipboard.readText().then(function(result) { - const ptr = PandemoniumRuntime.allocString(result); - func(ptr); - PandemoniumRuntime.free(ptr); - }).catch(function(e) { - // Fail graciously. - }); - } catch (e) { - // Fail graciously. - } - }, + /* + * Touchscreen + */ + pandemonium_js_display_touchscreen_is_available__sig: 'i', + pandemonium_js_display_touchscreen_is_available: function() { + return 'ontouchstart' in window; + }, - /* - * Window - */ - pandemonium_js_display_window_title_set__sig: 'vi', - pandemonium_js_display_window_title_set: function(p_data) { - document.title = PandemoniumRuntime.parseString(p_data); - }, + /* + * Clipboard + */ + pandemonium_js_display_clipboard_set__sig: 'ii', + pandemonium_js_display_clipboard_set: function(p_text) { + const text = PandemoniumRuntime.parseString(p_text); + if (!navigator.clipboard || !navigator.clipboard.writeText) { + return 1; + } + navigator.clipboard.writeText(text).catch(function(e) { + // Setting OS clipboard is only possible from an input callback. + PandemoniumRuntime.error('Setting OS clipboard is only possible from an input callback for the HTML5 plafrom. Exception:', e); + }); + return 0; + }, - pandemonium_js_display_window_icon_set__sig: 'vii', - pandemonium_js_display_window_icon_set: function(p_ptr, p_len) { - let link = document.getElementById('-gd-engine-icon'); - if (link === null) { - link = document.createElement('link'); - link.rel = 'icon'; - link.id = '-gd-engine-icon'; - document.head.appendChild(link); - } - const old_icon = PandemoniumDisplay.window_icon; - const png = new Blob([PandemoniumRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { - type: 'image/png' - }); - PandemoniumDisplay.window_icon = URL.createObjectURL(png); - link.href = PandemoniumDisplay.window_icon; - if (old_icon) { - URL.revokeObjectURL(old_icon); - } - }, + pandemonium_js_display_clipboard_get__sig: 'ii', + pandemonium_js_display_clipboard_get: function(callback) { + const func = PandemoniumRuntime.get_func(callback); + try { + navigator.clipboard.readText().then(function(result) { + const ptr = PandemoniumRuntime.allocString(result); + func(ptr); + PandemoniumRuntime.free(ptr); + }).catch(function(e) { + // Fail graciously. + }); + } catch (e) { + // Fail graciously. + } + }, - /* - * Cursor - */ - pandemonium_js_display_cursor_set_visible__sig: 'vi', - pandemonium_js_display_cursor_set_visible: function(p_visible) { - const visible = p_visible !== 0; - if (visible === PandemoniumDisplayCursor.visible) { - return; - } - PandemoniumDisplayCursor.visible = visible; - if (visible) { - PandemoniumDisplayCursor.set_shape(PandemoniumDisplayCursor.shape); - } else { - PandemoniumDisplayCursor.set_style('none'); - } - }, + /* + * Window + */ + pandemonium_js_display_window_title_set__sig: 'vi', + pandemonium_js_display_window_title_set: function(p_data) { + document.title = PandemoniumRuntime.parseString(p_data); + }, - pandemonium_js_display_cursor_is_hidden__sig: 'i', - pandemonium_js_display_cursor_is_hidden: function() { - return !PandemoniumDisplayCursor.visible; - }, + pandemonium_js_display_window_icon_set__sig: 'vii', + pandemonium_js_display_window_icon_set: function(p_ptr, p_len) { + let link = document.getElementById('-gd-engine-icon'); + if (link === null) { + link = document.createElement('link'); + link.rel = 'icon'; + link.id = '-gd-engine-icon'; + document.head.appendChild(link); + } + const old_icon = PandemoniumDisplay.window_icon; + const png = new Blob([PandemoniumRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { + type: 'image/png' + }); + PandemoniumDisplay.window_icon = URL.createObjectURL(png); + link.href = PandemoniumDisplay.window_icon; + if (old_icon) { + URL.revokeObjectURL(old_icon); + } + }, - pandemonium_js_display_cursor_set_shape__sig: 'vi', - pandemonium_js_display_cursor_set_shape: function(p_string) { - PandemoniumDisplayCursor.set_shape(PandemoniumRuntime.parseString(p_string)); - }, + /* + * Cursor + */ + pandemonium_js_display_cursor_set_visible__sig: 'vi', + pandemonium_js_display_cursor_set_visible: function(p_visible) { + const visible = p_visible !== 0; + if (visible === PandemoniumDisplayCursor.visible) { + return; + } + PandemoniumDisplayCursor.visible = visible; + if (visible) { + PandemoniumDisplayCursor.set_shape(PandemoniumDisplayCursor.shape); + } else { + PandemoniumDisplayCursor.set_style('none'); + } + }, - pandemonium_js_display_cursor_set_custom_shape__sig: 'viiiii', - pandemonium_js_display_cursor_set_custom_shape: function(p_shape, p_ptr, p_len, p_hotspot_x, p_hotspot_y) { - const shape = PandemoniumRuntime.parseString(p_shape); - const old_shape = PandemoniumDisplayCursor.cursors[shape]; - if (p_len > 0) { - const png = new Blob([PandemoniumRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { - type: 'image/png' - }); - const url = URL.createObjectURL(png); - PandemoniumDisplayCursor.cursors[shape] = { - url: url, - x: p_hotspot_x, - y: p_hotspot_y, - }; - } else { - delete PandemoniumDisplayCursor.cursors[shape]; - } - if (shape === PandemoniumDisplayCursor.shape) { - PandemoniumDisplayCursor.set_shape(PandemoniumDisplayCursor.shape); - } - if (old_shape) { - URL.revokeObjectURL(old_shape.url); - } - }, + pandemonium_js_display_cursor_is_hidden__sig: 'i', + pandemonium_js_display_cursor_is_hidden: function() { + return !PandemoniumDisplayCursor.visible; + }, - pandemonium_js_display_cursor_lock_set__sig: 'vi', - pandemonium_js_display_cursor_lock_set: function(p_lock) { - if (p_lock) { - PandemoniumDisplayCursor.lockPointer(); - } else { - PandemoniumDisplayCursor.releasePointer(); - } - }, + pandemonium_js_display_cursor_set_shape__sig: 'vi', + pandemonium_js_display_cursor_set_shape: function(p_string) { + PandemoniumDisplayCursor.set_shape(PandemoniumRuntime.parseString(p_string)); + }, - pandemonium_js_display_cursor_is_locked__sig: 'i', - pandemonium_js_display_cursor_is_locked: function() { - return PandemoniumDisplayCursor.isPointerLocked() ? 1 : 0; - }, + pandemonium_js_display_cursor_set_custom_shape__sig: 'viiiii', + pandemonium_js_display_cursor_set_custom_shape: function(p_shape, p_ptr, p_len, p_hotspot_x, p_hotspot_y) { + const shape = PandemoniumRuntime.parseString(p_shape); + const old_shape = PandemoniumDisplayCursor.cursors[shape]; + if (p_len > 0) { + const png = new Blob([PandemoniumRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { + type: 'image/png' + }); + const url = URL.createObjectURL(png); + PandemoniumDisplayCursor.cursors[shape] = { + url: url, + x: p_hotspot_x, + y: p_hotspot_y, + }; + } else { + delete PandemoniumDisplayCursor.cursors[shape]; + } + if (shape === PandemoniumDisplayCursor.shape) { + PandemoniumDisplayCursor.set_shape(PandemoniumDisplayCursor.shape); + } + if (old_shape) { + URL.revokeObjectURL(old_shape.url); + } + }, - /* - * Listeners - */ - pandemonium_js_display_fullscreen_cb__sig: 'vi', - pandemonium_js_display_fullscreen_cb: function(callback) { - const canvas = PandemoniumConfig.canvas; - const func = PandemoniumRuntime.get_func(callback); + pandemonium_js_display_cursor_lock_set__sig: 'vi', + pandemonium_js_display_cursor_lock_set: function(p_lock) { + if (p_lock) { + PandemoniumDisplayCursor.lockPointer(); + } else { + PandemoniumDisplayCursor.releasePointer(); + } + }, - function change_cb(evt) { - if (evt.target === canvas) { - func(PandemoniumDisplayScreen.isFullscreen()); - } - } - PandemoniumEventListeners.add(document, 'fullscreenchange', change_cb, false); - PandemoniumEventListeners.add(document, 'mozfullscreenchange', change_cb, false); - PandemoniumEventListeners.add(document, 'webkitfullscreenchange', change_cb, false); - }, + pandemonium_js_display_cursor_is_locked__sig: 'i', + pandemonium_js_display_cursor_is_locked: function() { + return PandemoniumDisplayCursor.isPointerLocked() ? 1 : 0; + }, - pandemonium_js_display_window_blur_cb__sig: 'vi', - pandemonium_js_display_window_blur_cb: function(callback) { - const func = PandemoniumRuntime.get_func(callback); - PandemoniumEventListeners.add(window, 'blur', function() { - func(); - }, false); - }, + /* + * Listeners + */ + pandemonium_js_display_fullscreen_cb__sig: 'vi', + pandemonium_js_display_fullscreen_cb: function(callback) { + const canvas = PandemoniumConfig.canvas; + const func = PandemoniumRuntime.get_func(callback); - pandemonium_js_display_notification_cb__sig: 'viiiii', - pandemonium_js_display_notification_cb: function(callback, p_enter, p_exit, p_in, p_out) { - const canvas = PandemoniumConfig.canvas; - const func = PandemoniumRuntime.get_func(callback); - const notif = [p_enter, p_exit, p_in, p_out]; - ['mouseover', 'mouseleave', 'focus', 'blur'].forEach(function(evt_name, idx) { - PandemoniumEventListeners.add(canvas, evt_name, function() { - func(notif[idx]); - }, true); - }); - }, + function change_cb(evt) { + if (evt.target === canvas) { + func(PandemoniumDisplayScreen.isFullscreen()); + } + } + PandemoniumEventListeners.add(document, 'fullscreenchange', change_cb, false); + PandemoniumEventListeners.add(document, 'mozfullscreenchange', change_cb, false); + PandemoniumEventListeners.add(document, 'webkitfullscreenchange', change_cb, false); + }, - pandemonium_js_display_setup_canvas__sig: 'viiii', - pandemonium_js_display_setup_canvas: function(p_width, p_height, p_fullscreen, p_hidpi) { - const canvas = PandemoniumConfig.canvas; - PandemoniumEventListeners.add(canvas, 'contextmenu', function(ev) { - ev.preventDefault(); - }, false); - PandemoniumEventListeners.add(canvas, 'webglcontextlost', function(ev) { - alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert - ev.preventDefault(); - }, false); - PandemoniumDisplayScreen.hidpi = !!p_hidpi; - switch (PandemoniumConfig.canvas_resize_policy) { - case 0: // None - PandemoniumDisplayScreen.desired_size = [canvas.width, canvas.height]; - break; - case 1: // Project - PandemoniumDisplayScreen.desired_size = [p_width, p_height]; - break; - default: // Full window - // Ensure we display in the right place, the size will be handled by updateSize - canvas.style.position = 'absolute'; - canvas.style.top = 0; - canvas.style.left = 0; - break; - } - PandemoniumDisplayScreen.updateSize(); - if (p_fullscreen) { - PandemoniumDisplayScreen.requestFullscreen(); - } - }, + pandemonium_js_display_window_blur_cb__sig: 'vi', + pandemonium_js_display_window_blur_cb: function(callback) { + const func = PandemoniumRuntime.get_func(callback); + PandemoniumEventListeners.add(window, 'blur', function() { + func(); + }, false); + }, - /* - * Virtual Keyboard - */ - pandemonium_js_display_vk_show__sig: 'viiii', - pandemonium_js_display_vk_show: function(p_text, p_multiline, p_start, p_end) { - const text = PandemoniumRuntime.parseString(p_text); - const start = p_start > 0 ? p_start : 0; - const end = p_end > 0 ? p_end : start; - PandemoniumDisplayVK.show(text, p_multiline, start, end); - }, + pandemonium_js_display_notification_cb__sig: 'viiiii', + pandemonium_js_display_notification_cb: function(callback, p_enter, p_exit, p_in, p_out) { + const canvas = PandemoniumConfig.canvas; + const func = PandemoniumRuntime.get_func(callback); + const notif = [p_enter, p_exit, p_in, p_out]; + ['mouseover', 'mouseleave', 'focus', 'blur'].forEach(function(evt_name, idx) { + PandemoniumEventListeners.add(canvas, evt_name, function() { + func(notif[idx]); + }, true); + }); + }, - pandemonium_js_display_vk_hide__sig: 'v', - pandemonium_js_display_vk_hide: function() { - PandemoniumDisplayVK.hide(); - }, + pandemonium_js_display_setup_canvas__sig: 'viiii', + pandemonium_js_display_setup_canvas: function(p_width, p_height, p_fullscreen, p_hidpi) { + const canvas = PandemoniumConfig.canvas; + PandemoniumEventListeners.add(canvas, 'contextmenu', function(ev) { + ev.preventDefault(); + }, false); + PandemoniumEventListeners.add(canvas, 'webglcontextlost', function(ev) { + alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert + ev.preventDefault(); + }, false); + PandemoniumDisplayScreen.hidpi = !!p_hidpi; + switch (PandemoniumConfig.canvas_resize_policy) { + case 0: // None + PandemoniumDisplayScreen.desired_size = [canvas.width, canvas.height]; + break; + case 1: // Project + PandemoniumDisplayScreen.desired_size = [p_width, p_height]; + break; + default: // Full window + // Ensure we display in the right place, the size will be handled by updateSize + canvas.style.position = 'absolute'; + canvas.style.top = 0; + canvas.style.left = 0; + break; + } + PandemoniumDisplayScreen.updateSize(); + if (p_fullscreen) { + PandemoniumDisplayScreen.requestFullscreen(); + } + }, - pandemonium_js_display_vk_available__sig: 'i', - pandemonium_js_display_vk_available: function() { - return PandemoniumDisplayVK.available(); - }, + /* + * Virtual Keyboard + */ + pandemonium_js_display_vk_show__sig: 'viiii', + pandemonium_js_display_vk_show: function(p_text, p_multiline, p_start, p_end) { + const text = PandemoniumRuntime.parseString(p_text); + const start = p_start > 0 ? p_start : 0; + const end = p_end > 0 ? p_end : start; + PandemoniumDisplayVK.show(text, p_multiline, start, end); + }, - pandemonium_js_display_vk_cb__sig: 'vi', - pandemonium_js_display_vk_cb: function(p_input_cb) { - const input_cb = PandemoniumRuntime.get_func(p_input_cb); - if (PandemoniumDisplayVK.available()) { - PandemoniumDisplayVK.init(input_cb); - } - }, + pandemonium_js_display_vk_hide__sig: 'v', + pandemonium_js_display_vk_hide: function() { + PandemoniumDisplayVK.hide(); + }, + + pandemonium_js_display_vk_available__sig: 'i', + pandemonium_js_display_vk_available: function() { + return PandemoniumDisplayVK.available(); + }, + + pandemonium_js_display_vk_cb__sig: 'vi', + pandemonium_js_display_vk_cb: function(p_input_cb) { + const input_cb = PandemoniumRuntime.get_func(p_input_cb); + if (PandemoniumDisplayVK.available()) { + PandemoniumDisplayVK.init(input_cb); + } + }, }; autoAddDeps(PandemoniumDisplay, '$PandemoniumDisplay'); -mergeInto(LibraryManager.library, PandemoniumDisplay); \ No newline at end of file +mergeInto(LibraryManager.library, PandemoniumDisplay);