diff options
author | Sven Gothel <[email protected]> | 2014-01-09 18:44:35 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-01-09 18:44:35 +0100 |
commit | bf0e93260dbd6cb8b6ee0cd10d81341906e62da9 (patch) | |
tree | bfba843071f6976247ef6f19595bfbdc4377fde4 /src/newt/classes | |
parent | 2b899a55e365aa03aeb234187600526777c1a9ac (diff) |
Bug 676 - Add support for native Mouse Pointer rendering (Rasp.-Pi.)
- Utilizing layer element 2000 for PointerIcon
- Using NEWT PointerIcon code
- Using MouseListener to update PointerIcon position
- FIXME: Check whether we shall intercept sendMouseEvent directly (lag)
Misc:
- Properly open, assign and close the BCM display handle
- Properly destroy the window (BCM element)
- Prepare for multiple windows, set position and size
Diffstat (limited to 'src/newt/classes')
4 files changed, 201 insertions, 22 deletions
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java index d8d93f123..3d563d88f 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java @@ -28,15 +28,28 @@ package jogamp.newt.driver.bcm.vc.iv; +import java.net.URLConnection; +import java.nio.Buffer; +import java.nio.ByteBuffer; + import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.util.PixelFormat; + +import com.jogamp.common.nio.Buffers; +import com.jogamp.common.util.IOUtil; +import com.jogamp.opengl.util.PNGPixelRect; import jogamp.newt.DisplayImpl; import jogamp.newt.NEWTJNILibLoader; +import jogamp.newt.PointerIconImpl; +import jogamp.newt.driver.linux.LinuxMouseTracker; import jogamp.opengl.egl.EGL; import jogamp.opengl.egl.EGLDisplayUtil; public class DisplayDriver extends DisplayImpl { + static final PNGPixelRect defaultPointerIconImage; + static { NEWTJNILibLoader.loadNEWT(); @@ -49,6 +62,18 @@ public class DisplayDriver extends DisplayImpl { if (!WindowDriver.initIDs()) { throw new NativeWindowException("Failed to initialize bcm.vc.iv Window jmethodIDs"); } + + PNGPixelRect image = null; + if( DisplayImpl.isPNGUtilAvailable() ) { + final IOUtil.ClassResources res = new IOUtil.ClassResources(DisplayDriver.class, new String[] { "newt/data/pointer-grey-alpha-16x24.png" } ); + try { + final URLConnection urlConn = res.resolve(0); + image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */); + } catch (Exception e) { + e.printStackTrace(); + } + } + defaultPointerIconImage = image; } public static void initSingleton() { @@ -57,25 +82,127 @@ public class DisplayDriver extends DisplayImpl { public DisplayDriver() { + bcmHandle = 0; + activePointerIcon = 0; + activePointerIconVisible = false; } @Override protected void createNativeImpl() { // FIXME: map name to EGL_*_DISPLAY + bcmHandle = OpenBCMDisplay0(); aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + + defaultPointerIcon = (PointerIconImpl) createPointerIcon(defaultPointerIconImage, 0, 0); + if( DEBUG_POINTER_ICON ) { + System.err.println("Display.PointerIcon.createDefault: "+defaultPointerIcon); + } + if( null != defaultPointerIcon ) { + final LinuxMouseTracker lmt = LinuxMouseTracker.getSingleton(); + setPointerIconActive(defaultPointerIcon.getHandle(), lmt.getLastX(), lmt.getLastY()); + } } + private PointerIconImpl defaultPointerIcon = null; @Override protected void closeNativeImpl(AbstractGraphicsDevice aDevice) { aDevice.close(); + CloseBCMDisplay0(bcmHandle); + bcmHandle = 0; } + /* pp */ final long getBCMHandle() { return bcmHandle; } + @Override protected void dispatchMessagesNative() { - DispatchMessages(); + DispatchMessages0(); + } + + // @Override + // public final PixelFormat getNativePointerIconPixelFormat() { return PixelFormat.BGRA8888; } + + @Override + protected final long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) { + return CreatePointerIcon(bcmHandle, pixels, width, height, hotX, hotY); + } + + @Override + protected final void destroyPointerIconImpl(final long displayHandle, long piHandle) { + DestroyPointerIcon0(piHandle); + } + + /* pp */ void setPointerIconActive(long piHandle, final int x, final int y) { + synchronized(pointerIconSync) { + if( DEBUG_POINTER_ICON ) { + System.err.println("Display.PointerIcon.set.0: active ["+toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"] -> "+toHexString(piHandle)); + } + if( 0 != activePointerIcon && activePointerIconVisible ) { + SetPointerIcon0(bcmHandle, activePointerIcon, false, x, y); + } + if( 0 == piHandle && null != defaultPointerIcon ) { + piHandle = defaultPointerIcon.getHandle(); + } + if( 0 != piHandle ) { + SetPointerIcon0(bcmHandle, piHandle, true, x, y); + activePointerIconVisible = true; + } else { + activePointerIconVisible = false; + } + activePointerIcon = piHandle; + if( DEBUG_POINTER_ICON ) { + System.err.println("Display.PointerIcon.set.X: active ["+toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"]"); + } + } + } + /* pp */ void setActivePointerIconVisible(final boolean visible, final int x, final int y) { + synchronized(pointerIconSync) { + if( DEBUG_POINTER_ICON ) { + System.err.println("Display.PointerIcon.visible: active ["+toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"] -> visible "+visible); + } + if( activePointerIconVisible != visible ) { + if( 0 != activePointerIcon ) { + SetPointerIcon0(bcmHandle, activePointerIcon, visible, x, y); + } + activePointerIconVisible = visible; + } + } + } + /* pp */ void moveActivePointerIcon(final int x, final int y) { + synchronized(pointerIconSync) { + if( DEBUG_POINTER_ICON ) { + System.err.println("Display.PointerIcon.move: active ["+toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"], "+x+"/"+y); + } + if( 0 != activePointerIcon && activePointerIconVisible ) { + MovePointerIcon0(activePointerIcon, x, y); + } + } } + //---------------------------------------------------------------------- + // Internals only + // + protected static native boolean initIDs(); - private native void DispatchMessages(); + private static native long OpenBCMDisplay0(); + private static native void CloseBCMDisplay0(long handle); + + private static long CreatePointerIcon(long bcmHandle, Buffer pixels, int width, int height, int hotX, int hotY) { + final boolean pixels_is_direct = Buffers.isDirect(pixels); + return CreatePointerIcon0(pixels_is_direct ? pixels : Buffers.getArray(pixels), + pixels_is_direct ? Buffers.getDirectBufferByteOffset(pixels) : Buffers.getIndirectBufferByteOffset(pixels), + pixels_is_direct, + width, height, hotX, hotY); + } + private static native long CreatePointerIcon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, int hotX, int hotY); + private static native void DestroyPointerIcon0(long handle); + private static native void SetPointerIcon0(long bcmHandle, long handle, boolean enable, int x, int y); + private static native void MovePointerIcon0(long handle, int x, int y); + + private static native void DispatchMessages0(); + + private long bcmHandle; + private long activePointerIcon; + private boolean activePointerIconVisible; + private final Object pointerIconSync = new Object(); } diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java index 4d4977776..5109d0fbb 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java @@ -39,7 +39,10 @@ import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; import com.jogamp.nativewindow.egl.EGLGraphicsDevice; +import com.jogamp.newt.event.MouseListener; +import com.jogamp.newt.event.MouseAdapter; +import jogamp.newt.PointerIconImpl; import jogamp.newt.WindowImpl; import jogamp.newt.driver.linux.LinuxEventDeviceTracker; import jogamp.newt.driver.linux.LinuxMouseTracker; @@ -53,6 +56,8 @@ public class WindowDriver extends WindowImpl { } public WindowDriver() { + linuxMouseTracker = LinuxMouseTracker.getSingleton(); + linuxEventDeviceTracker = LinuxEventDeviceTracker.getSingleton(); } @Override @@ -60,9 +65,12 @@ public class WindowDriver extends WindowImpl { if(0!=getParentWindowHandle()) { throw new RuntimeException("Window parenting not supported (yet)"); } + final ScreenDriver screen = (ScreenDriver) getScreen(); + final DisplayDriver display = (DisplayDriver) screen.getDisplay(); + // Create own screen/device resource instance allowing independent ownership, // while still utilizing shared EGL resources. - final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen(); + final AbstractGraphicsScreen aScreen = screen.getGraphicsScreen(); final EGLGraphicsDevice aDevice = (EGLGraphicsDevice) aScreen.getDevice(); final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(aDevice.getNativeDisplayID(), aDevice.getConnection(), aDevice.getUnitID()); final DefaultGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aScreen.getIndex()); @@ -78,7 +86,8 @@ public class WindowDriver extends WindowImpl { chosenCaps.setBackgroundOpaque(capsRequested.isBackgroundOpaque()); } setGraphicsConfiguration(cfg); - nativeWindowHandle = CreateWindow(getWidth(), getHeight(), chosenCaps.isBackgroundOpaque(), chosenCaps.getAlphaBits()); + nativeWindowHandle = CreateWindow0(display.getBCMHandle(), getX(), getY(), getWidth(), getHeight(), + chosenCaps.isBackgroundOpaque(), chosenCaps.getAlphaBits()); if (nativeWindowHandle == 0) { throw new NativeWindowException("Error creating egl window: "+cfg); } @@ -88,21 +97,37 @@ public class WindowDriver extends WindowImpl { throw new NativeWindowException("Error native Window Handle is null"); } windowHandleClose = nativeWindowHandle; - addWindowListener(LinuxMouseTracker.getSingleton()); - addWindowListener(LinuxEventDeviceTracker.getSingleton()); + + addWindowListener(linuxEventDeviceTracker); + addWindowListener(linuxMouseTracker); + addMouseListener(mousePointerTracker); focusChanged(false, true); } + final MouseListener mousePointerTracker = new MouseAdapter() { + @Override + public void mouseMoved(com.jogamp.newt.event.MouseEvent e) { + final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); + display.moveActivePointerIcon(e.getX(), e.getY()); + } + + @Override + public void mouseDragged(com.jogamp.newt.event.MouseEvent e) { + final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); + display.moveActivePointerIcon(e.getX(), e.getY()); + } + }; @Override protected void closeNativeImpl() { + final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getGraphicsConfiguration().getScreen().getDevice(); - removeWindowListener(LinuxMouseTracker.getSingleton()); - removeWindowListener(LinuxEventDeviceTracker.getSingleton()); + removeMouseListener(mousePointerTracker); + removeWindowListener(linuxMouseTracker); + removeWindowListener(linuxEventDeviceTracker); if(0!=windowHandleClose) { - CloseWindow(windowHandleClose, windowUserData); - windowUserData=0; + CloseWindow0(display.getBCMHandle(), windowHandleClose); } eglDevice.close(); @@ -157,23 +182,44 @@ public class WindowDriver extends WindowImpl { // nop .. } + /** + @Override + public final void sendMouseEvent(final short eventType, final int modifiers, + final int x, final int y, final short button, final float rotation) { + if( MouseEvent.MOUSE_MOVED == eventType ) { + final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); + display.moveActivePointerIcon(x, y); + } + super.sendMouseEvent(eventType, modifiers, x, y, button, rotation); + } */ + + @Override + protected void setPointerIconImpl(final PointerIconImpl pi) { + final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); + display.setPointerIconActive(null != pi ? pi.validatedHandle() : 0, linuxMouseTracker.getLastX(), linuxMouseTracker.getLastY()); + } + + @Override + protected boolean setPointerVisibleImpl(final boolean pointerVisible) { + final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); + display.setActivePointerIconVisible(pointerVisible, linuxMouseTracker.getLastX(), linuxMouseTracker.getLastY()); + return true; + } + //---------------------------------------------------------------------- // Internals only // + private final LinuxMouseTracker linuxMouseTracker; + private final LinuxEventDeviceTracker linuxEventDeviceTracker; protected static native boolean initIDs(); - private native long CreateWindow(int width, int height, boolean opaque, int alphaBits); - private native long RealizeWindow(long eglWindowHandle); - private native int CloseWindow(long eglWindowHandle, long userData); + private native long CreateWindow0(long bcmDisplay, int x, int y, int width, int height, boolean opaque, int alphaBits); + private native void CloseWindow0(long bcmDisplay, long eglWindowHandle); private native void setVisible0(long eglWindowHandle, boolean visible); + private native void setPos0(long eglWindowHandle, int x, int y); private native void setSize0(long eglWindowHandle, int width, int height); private native void setFullScreen0(long eglWindowHandle, boolean fullscreen); - private void windowCreated(long userData) { - windowUserData=userData; - } - private long nativeWindowHandle; private long windowHandleClose; - private long windowUserData; } diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java index 1e314b7f4..9d7b8931b 100644 --- a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java +++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java @@ -68,9 +68,14 @@ public class LinuxMouseTracker implements WindowListener { private short buttonDown = 0; private int old_x = 0; private int old_y = 0; + private volatile int lastFocusedX = 0; + private volatile int lastFocusedY = 0; private short old_buttonDown = 0; private WindowImpl focusedWindow = null; - private MouseDevicePoller mouseDevicePoller = new MouseDevicePoller(); + private final MouseDevicePoller mouseDevicePoller = new MouseDevicePoller(); + + public final int getLastX() { return lastFocusedX; } + public final int getLastY() { return lastFocusedY; } @Override public void windowResized(WindowEvent e) { } @@ -179,10 +184,11 @@ public class LinuxMouseTracker implements WindowListener { if( y >= focusedWindow.getScreen().getHeight() ) { y = focusedWindow.getScreen().getHeight() - 1; } - int wx = x - focusedWindow.getX(), wy = y - focusedWindow.getY(); - + final int wx = x - focusedWindow.getX(), wy = y - focusedWindow.getY(); if(old_x != x || old_y != y) { // mouse moved + lastFocusedX = wx; + lastFocusedY = wy; focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_MOVED, 0, wx, wy, (short)0, 0 ); } diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java index 4d1388eec..391b8b19d 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java @@ -165,7 +165,7 @@ public class DisplayDriver extends DisplayImpl { } private static native long createPointerIcon0(long display, Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, int hotX, int hotY); - static native void destroyPointerIcon0(long display, long handle); + private static native void destroyPointerIcon0(long display, long handle); /** X11 Window delete atom marker used on EDT */ private long windowDeleteAtom; |