diff --git a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlEventListener.java b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlEventListener.java new file mode 100644 index 0000000000..9943a3e048 --- /dev/null +++ b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlEventListener.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009-2026 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.input.lwjgl; + +import com.jme3.system.lwjgl.LwjglWindow; +import org.lwjgl.sdl.SDL_Event; + +/** + * Listen to raw SDL events. + * + * @author Ivan1pl + */ +public interface SdlEventListener { + + /** + * When registered by {@link LwjglWindow#registerSdlEventListener(SdlEventListener)}, + * it gets invoked on each polled SDL event before it is passed to jME inputs. + * + * @param event SDL event to handle + */ + void onSDLEvent(SDL_Event event); +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlJoystickInput.java b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlJoystickInput.java index d7a579b694..12bc98dd4b 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlJoystickInput.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlJoystickInput.java @@ -28,7 +28,7 @@ * * @author Riccardo Balbo */ -public class SdlJoystickInput implements JoyInput { +public class SdlJoystickInput implements JoyInput, SdlEventListener { private static final Logger LOGGER = Logger.getLogger(SdlJoystickInput.class.getName()); private final AppSettings settings; @@ -290,6 +290,7 @@ public boolean onPointerUp(int pointerId, float x, float y, long time) { return joystick != null && joystick.onPointerUp(pointerId, x, y, time); } + @Override public void onSDLEvent(SDL_Event evt) { int type = evt.type(); if (!(listener instanceof InputManager)) { diff --git a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlKeyInput.java b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlKeyInput.java index ccce791a98..ea4693a02d 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlKeyInput.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlKeyInput.java @@ -49,7 +49,7 @@ /** * SDL implementation of {@link KeyInput}. */ -public class SdlKeyInput implements KeyInput { +public class SdlKeyInput implements KeyInput, SdlEventListener { private static final Logger LOGGER = Logger.getLogger(SdlKeyInput.class.getName()); @@ -81,6 +81,7 @@ public void resetContext() { SDL_StartTextInput(context.getWindowHandle()); } + @Override public void onSDLEvent(SDL_Event event) { final int type = event.type(); if (type == SDL_EVENT_KEY_DOWN || type == SDL_EVENT_KEY_UP) { diff --git a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlMouseInput.java b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlMouseInput.java index e78c5e6eb5..9a1d3aa434 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlMouseInput.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlMouseInput.java @@ -65,7 +65,7 @@ /** * SDL implementation of {@link MouseInput}. */ -public class SdlMouseInput implements MouseInput { +public class SdlMouseInput implements MouseInput, SdlEventListener { private static final Logger LOGGER = Logger.getLogger(SdlMouseInput.class.getName()); private static final int WHEEL_SCALE = 120; @@ -127,6 +127,7 @@ public void resetContext() { setCursorVisible(cursorVisible); } + @Override public void onSDLEvent(SDL_Event event) { final int type = event.type(); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index 13144debbb..15dc574791 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -37,6 +37,7 @@ import com.jme3.input.KeyInput; import com.jme3.input.MouseInput; import com.jme3.input.TouchInput; +import com.jme3.input.lwjgl.SdlEventListener; import com.jme3.input.lwjgl.SdlJoystickInput; import com.jme3.input.lwjgl.SdlKeyInput; import com.jme3.input.lwjgl.SdlMouseInput; @@ -204,6 +205,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { private final JmeContext.Type type; private final SafeArrayList windowSizeListeners = new SafeArrayList<>(WindowSizeListener.class); + private final SafeArrayList sdlEventListeners = new SafeArrayList<>(SdlEventListener.class); private final AtomicBoolean windowCloseRequested = new AtomicBoolean(false); private Thread mainThread; @@ -255,6 +257,14 @@ public void removeWindowSizeListener(WindowSizeListener listener) { windowSizeListeners.remove(listener); } + public void registerSdlEventListener(SdlEventListener listener) { + sdlEventListeners.add(listener); + } + + public void removeSdlEventListener(SdlEventListener listener) { + sdlEventListeners.remove(listener); + } + private static void disableNvidiaThreadedOptimizations() { if (SDL_setenv_unsafe("__GL_THREADED_OPTIMIZATIONS", "0", 1) != 0) { throw new IllegalStateException("Unable to disable NVIDIA OpenGL threaded optimizations: " @@ -1111,14 +1121,21 @@ private void handleWindowEvent(SDL_Event event) { } private void dispatchSDLEvent(SDL_Event event) { - if (keyInput instanceof SdlKeyInput) { - ((SdlKeyInput) keyInput).onSDLEvent(event); + for (SdlEventListener listener : sdlEventListeners.getArray()) { + try { + listener.onSDLEvent(event); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Error handling SDL event", e); + } + } + if (keyInput instanceof SdlEventListener) { + ((SdlEventListener) keyInput).onSDLEvent(event); } - if (mouseInput instanceof SdlMouseInput) { - ((SdlMouseInput) mouseInput).onSDLEvent(event); + if (mouseInput instanceof SdlEventListener) { + ((SdlEventListener) mouseInput).onSDLEvent(event); } - if (joyInput instanceof SdlJoystickInput) { - ((SdlJoystickInput) joyInput).onSDLEvent(event); + if (joyInput instanceof SdlEventListener) { + ((SdlEventListener) joyInput).onSDLEvent(event); } }