summaryrefslogtreecommitdiffstats
path: root/platform/web/js/libs
diff options
context:
space:
mode:
Diffstat (limited to 'platform/web/js/libs')
-rw-r--r--platform/web/js/libs/library_godot_input.js135
-rw-r--r--platform/web/js/libs/library_godot_webgl2.externs.js16
-rw-r--r--platform/web/js/libs/library_godot_webgl2.js17
3 files changed, 167 insertions, 1 deletions
diff --git a/platform/web/js/libs/library_godot_input.js b/platform/web/js/libs/library_godot_input.js
index eaff40f89c..1292c468f5 100644
--- a/platform/web/js/libs/library_godot_input.js
+++ b/platform/web/js/libs/library_godot_input.js
@@ -29,6 +29,110 @@
/**************************************************************************/
/*
+ * IME API helper.
+ */
+
+const GodotIME = {
+ $GodotIME__deps: ['$GodotRuntime', '$GodotEventListeners'],
+ $GodotIME__postset: 'GodotOS.atexit(function(resolve, reject) { GodotIME.clear(); resolve(); });',
+ $GodotIME: {
+ ime: null,
+ active: false,
+
+ getModifiers: function (evt) {
+ return (evt.shiftKey + 0) + ((evt.altKey + 0) << 1) + ((evt.ctrlKey + 0) << 2) + ((evt.metaKey + 0) << 3);
+ },
+
+ ime_active: function (active) {
+ function focus_timer() {
+ GodotIME.active = true;
+ GodotIME.ime.focus();
+ }
+
+ if (GodotIME.ime) {
+ if (active) {
+ GodotIME.ime.style.display = 'block';
+ setInterval(focus_timer, 100);
+ } else {
+ GodotIME.ime.style.display = 'none';
+ GodotConfig.canvas.focus();
+ GodotIME.active = false;
+ }
+ }
+ },
+
+ ime_position: function (x, y) {
+ if (GodotIME.ime) {
+ GodotIME.ime.style.left = `${x}px`;
+ GodotIME.ime.style.top = `${y}px`;
+ }
+ },
+
+ init: function (ime_cb, key_cb, code, key) {
+ function key_event_cb(pressed, evt) {
+ const modifiers = GodotIME.getModifiers(evt);
+ GodotRuntime.stringToHeap(evt.code, code, 32);
+ GodotRuntime.stringToHeap(evt.key, key, 32);
+ key_cb(pressed, evt.repeat, modifiers);
+ evt.preventDefault();
+ }
+ function ime_event_cb(event) {
+ if (GodotIME.ime) {
+ if (event.type === 'compositionstart') {
+ ime_cb(0, null);
+ GodotIME.ime.innerHTML = '';
+ } else if (event.type === 'compositionupdate') {
+ const ptr = GodotRuntime.allocString(event.data);
+ ime_cb(1, ptr);
+ GodotRuntime.free(ptr);
+ } else if (event.type === 'compositionend') {
+ const ptr = GodotRuntime.allocString(event.data);
+ ime_cb(2, ptr);
+ GodotRuntime.free(ptr);
+ GodotIME.ime.innerHTML = '';
+ }
+ }
+ }
+
+ const ime = document.createElement('div');
+ ime.className = 'ime';
+ ime.style.background = 'none';
+ ime.style.opacity = 0.0;
+ ime.style.position = 'fixed';
+ ime.style.left = '0px';
+ ime.style.top = '0px';
+ ime.style.width = '2px';
+ ime.style.height = '2px';
+ ime.style.display = 'none';
+ ime.contentEditable = 'true';
+
+ GodotEventListeners.add(ime, 'compositionstart', ime_event_cb, false);
+ GodotEventListeners.add(ime, 'compositionupdate', ime_event_cb, false);
+ GodotEventListeners.add(ime, 'compositionend', ime_event_cb, false);
+ GodotEventListeners.add(ime, 'keydown', key_event_cb.bind(null, 1), false);
+ GodotEventListeners.add(ime, 'keyup', key_event_cb.bind(null, 0), false);
+
+ ime.onblur = function () {
+ this.style.display = 'none';
+ GodotConfig.canvas.focus();
+ GodotIME.active = false;
+ };
+
+ GodotConfig.canvas.parentElement.appendChild(ime);
+ GodotIME.ime = ime;
+ },
+
+ clear: function () {
+ if (GodotIME.ime) {
+ GodotIME.ime.remove();
+ GodotIME.ime = null;
+ }
+ },
+ },
+};
+mergeInto(LibraryManager.library, GodotIME);
+
+/*
* Gamepad API helper.
*/
const GodotInputGamepads = {
@@ -338,7 +442,7 @@ mergeInto(LibraryManager.library, GodotInputDragDrop);
* Godot exposed input functions.
*/
const GodotInput = {
- $GodotInput__deps: ['$GodotRuntime', '$GodotConfig', '$GodotEventListeners', '$GodotInputGamepads', '$GodotInputDragDrop'],
+ $GodotInput__deps: ['$GodotRuntime', '$GodotConfig', '$GodotEventListeners', '$GodotInputGamepads', '$GodotInputDragDrop', '$GodotIME'],
$GodotInput: {
getModifiers: function (evt) {
return (evt.shiftKey + 0) + ((evt.altKey + 0) << 1) + ((evt.ctrlKey + 0) << 2) + ((evt.metaKey + 0) << 3);
@@ -462,6 +566,35 @@ const GodotInput = {
},
/*
+ * IME API
+ */
+ godot_js_set_ime_active__proxy: 'sync',
+ godot_js_set_ime_active__sig: 'vi',
+ godot_js_set_ime_active: function (p_active) {
+ GodotIME.ime_active(p_active);
+ },
+
+ godot_js_set_ime_position__proxy: 'sync',
+ godot_js_set_ime_position__sig: 'vii',
+ godot_js_set_ime_position: function (p_x, p_y) {
+ GodotIME.ime_position(p_x, p_y);
+ },
+
+ godot_js_set_ime_cb__proxy: 'sync',
+ godot_js_set_ime_cb__sig: 'viiii',
+ godot_js_set_ime_cb: function (p_ime_cb, p_key_cb, code, key) {
+ const ime_cb = GodotRuntime.get_func(p_ime_cb);
+ const key_cb = GodotRuntime.get_func(p_key_cb);
+ GodotIME.init(ime_cb, key_cb, code, key);
+ },
+
+ godot_js_is_ime_focused__proxy: 'sync',
+ godot_js_is_ime_focused__sig: 'i',
+ godot_js_is_ime_focused: function () {
+ return GodotIME.active;
+ },
+
+ /*
* Gamepad API
*/
godot_js_input_gamepad_cb__proxy: 'sync',
diff --git a/platform/web/js/libs/library_godot_webgl2.externs.js b/platform/web/js/libs/library_godot_webgl2.externs.js
index 18d8d0815a..99190ab009 100644
--- a/platform/web/js/libs/library_godot_webgl2.externs.js
+++ b/platform/web/js/libs/library_godot_webgl2.externs.js
@@ -34,3 +34,19 @@ OVR_multiview2.prototype.FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR;
* @return {void}
*/
OVR_multiview2.prototype.framebufferTextureMultiviewOVR = function(target, attachment, texture, level, baseViewIndex, numViews) {};
+
+/**
+ * @constructor OCULUS_multiview
+ */
+function OCULUS_multiview() {}
+
+/**
+ * @param {number} target
+ * @param {number} attachment
+ * @param {WebGLTexture} texture
+ * @param {number} level
+ * @param {number} baseViewIndex
+ * @param {number} numViews
+ * @return {void}
+ */
+OCULUS_multiview.prototype.framebufferTextureMultisampleMultiviewOVR = function(target, attachment, texture, level, samples, baseViewIndex, numViews) {};
diff --git a/platform/web/js/libs/library_godot_webgl2.js b/platform/web/js/libs/library_godot_webgl2.js
index dbaec9f01b..005b4b7917 100644
--- a/platform/web/js/libs/library_godot_webgl2.js
+++ b/platform/web/js/libs/library_godot_webgl2.js
@@ -61,6 +61,23 @@ const GodotWebGL2 = {
const /** OVR_multiview2 */ ext = context.multiviewExt;
ext.framebufferTextureMultiviewOVR(target, attachment, GL.textures[texture], level, base_view_index, num_views);
},
+
+ godot_webgl2_glFramebufferTextureMultisampleMultiviewOVR__deps: ['emscripten_webgl_get_current_context'],
+ godot_webgl2_glFramebufferTextureMultisampleMultiviewOVR__proxy: 'sync',
+ godot_webgl2_glFramebufferTextureMultisampleMultiviewOVR__sig: 'viiiiiii',
+ godot_webgl2_glFramebufferTextureMultisampleMultiviewOVR: function (target, attachment, texture, level, samples, base_view_index, num_views) {
+ const context = GL.currentContext;
+ if (typeof context.oculusMultiviewExt === 'undefined') {
+ const /** OCULUS_multiview */ ext = context.GLctx.getExtension('OCULUS_multiview');
+ if (!ext) {
+ GodotRuntime.error('Trying to call glFramebufferTextureMultisampleMultiviewOVR() without the OCULUS_multiview extension');
+ return;
+ }
+ context.oculusMultiviewExt = ext;
+ }
+ const /** OCULUS_multiview */ ext = context.oculusMultiviewExt;
+ ext.framebufferTextureMultisampleMultiviewOVR(target, attachment, GL.textures[texture], level, samples, base_view_index, num_views);
+ },
};
autoAddDeps(GodotWebGL2, '$GodotWebGL2');