diff options
author | Sven Gothel <[email protected]> | 2019-11-29 07:32:52 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2019-11-29 07:32:52 +0100 |
commit | 381858b82c5197193ba2f490a8282149536a54f7 (patch) | |
tree | 4e416ce275283f84c051afb6d2b76496e09f137e /src/newt/classes | |
parent | bdbdcdc800294db3a84926b79503fc2e0e919128 (diff) |
Bug 1156: DRM/GBM: Add full PointerIcon (Cursor) Support
DRM allows 64x64 pixel cursor images, using GBM_FORMAT_ARGB888 only.
Notable: GBM_FORMAT_ARGB888 == PixelFormat.BGRA8888
Having fixed mouse and keyboard input with previous commit,
the demo com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT
shows via key press
- i -> pointer visible/invisible
- c -> pointer icon change
Diffstat (limited to 'src/newt/classes')
4 files changed, 201 insertions, 39 deletions
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 42ddb8e7f..31b1d7087 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 @@ -48,7 +48,7 @@ import jogamp.newt.PointerIconImpl; import jogamp.newt.WindowImpl; import jogamp.newt.driver.KeyTracker; import jogamp.newt.driver.MouseTracker; -import jogamp.newt.driver.linux.LinuxEventDeviceTracker; +import jogamp.newt.driver.linux.LinuxKeyEventTracker; import jogamp.newt.driver.linux.LinuxMouseTracker; import jogamp.newt.driver.x11.X11UnderlayTracker; import jogamp.opengl.egl.EGLDisplayUtil; @@ -73,11 +73,8 @@ public class WindowDriver extends WindowImpl { mouseTracker = x11UnderlayTracker; keyTracker = x11UnderlayTracker; } catch(final ExceptionInInitializerError e) { - linuxMouseTracker = LinuxMouseTracker.getSingleton(); - linuxEventDeviceTracker = LinuxEventDeviceTracker.getSingleton(); - - mouseTracker = linuxMouseTracker; - keyTracker = linuxEventDeviceTracker; + mouseTracker = LinuxMouseTracker.getSingleton(); + keyTracker = LinuxKeyEventTracker.getSingleton(); } layer = -1; @@ -301,8 +298,6 @@ public class WindowDriver extends WindowImpl { //---------------------------------------------------------------------- // Internals only // - private LinuxMouseTracker linuxMouseTracker; - private LinuxEventDeviceTracker linuxEventDeviceTracker; private X11UnderlayTracker x11UnderlayTracker; private MouseTracker mouseTracker; diff --git a/src/newt/classes/jogamp/newt/driver/egl/gbm/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/egl/gbm/DisplayDriver.java index 847532bb4..edc5fb532 100644 --- a/src/newt/classes/jogamp/newt/driver/egl/gbm/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/egl/gbm/DisplayDriver.java @@ -27,18 +27,27 @@ */ package jogamp.newt.driver.egl.gbm; +import java.net.URLConnection; +import java.nio.Buffer; +import java.nio.ByteBuffer; + +import com.jogamp.common.nio.Buffers; +import com.jogamp.common.util.IOUtil; import com.jogamp.nativewindow.AbstractGraphicsDevice; import com.jogamp.nativewindow.NativeWindowException; +import com.jogamp.nativewindow.util.PixelFormat; +import com.jogamp.newt.Display; import com.jogamp.opengl.GLProfile; +import com.jogamp.opengl.util.PNGPixelRect; import jogamp.nativewindow.drm.DRMLib; import jogamp.nativewindow.drm.DRMUtil; import jogamp.newt.DisplayImpl; import jogamp.newt.NEWTJNILibLoader; +import jogamp.newt.PointerIconImpl; import jogamp.opengl.egl.EGLDisplayUtil; public class DisplayDriver extends DisplayImpl { - static { NEWTJNILibLoader.loadNEWT(); GLProfile.initSingleton(); @@ -52,6 +61,20 @@ public class DisplayDriver extends DisplayImpl { if (!WindowDriver.initIDs()) { throw new NativeWindowException("Failed to initialize egl.gbm Window jmethodIDs"); } + + PNGPixelRect image = null; + if( DisplayImpl.isPNGUtilAvailable() ) { + final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "newt/data/pointer-grey-alpha-16x24.png" }, DisplayDriver.class.getClassLoader(), null); + try { + final URLConnection urlConn = res.resolve(0); + if( null != urlConn ) { + image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */); + } + } catch (final Exception e) { + e.printStackTrace(); + } + } + defaultPointerIconImage = image; } public static void initSingleton() { @@ -71,6 +94,15 @@ public class DisplayDriver extends DisplayImpl { gbmHandle = DRMLib.gbm_create_device(drmFd); aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(gbmHandle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); aDevice.open(); + + if( null != defaultPointerIconImage ) { + defaultPointerIcon = (PointerIconImpl) createPointerIcon(defaultPointerIconImage, 0, 0); + } else { + defaultPointerIcon = null; + } + if( DEBUG_POINTER_ICON ) { + System.err.println("Display.PointerIcon.createDefault: "+defaultPointerIcon); + } } @Override @@ -87,6 +119,19 @@ public class DisplayDriver extends DisplayImpl { DispatchMessages0(); } + @Override + public final PixelFormat getNativePointerIconPixelFormat() { return PixelFormat.BGRA8888; } + + @Override + protected final long createPointerIconImpl(final PixelFormat pixelformat, final int width, final int height, final ByteBuffer pixels, final int hotX, final int hotY) { + return CreatePointerIcon(gbmHandle, pixels, width, height, hotX, hotY); + } + + @Override + protected final void destroyPointerIconImpl(final long displayHandle, final long piHandle) { + DestroyPointerIcon0(piHandle); + } + //---------------------------------------------------------------------- // Internals only // @@ -94,5 +139,27 @@ public class DisplayDriver extends DisplayImpl { private static native void DispatchMessages0(); + private static long CreatePointerIcon(final long gbmDevice, final Buffer pixels, final int width, final int height, final int hotX, final int hotY) { + if( 0 >= width || width > 64 || 0 >= height || height > 64 ) { + throw new IllegalArgumentException("implementation only supports BGRA icons of size [1x1] -> [64x64]"); + } + final boolean pixels_is_direct = Buffers.isDirect(pixels); + return CreatePointerIcon0(gbmDevice, + 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(long gbmDevice, Object pixels, int pixels_byte_offset, boolean pixels_is_direct, + int width, int height, int hotX, int hotY); + private static native void DestroyPointerIcon0(long piHandle); + /* pp */ static native boolean SetPointerIcon0(int drmFd, int crtc_id, long piHandle, boolean enable, int x, int y); + /* pp */ static native boolean MovePointerIcon0(int drmFd, int crtc_id, int x, int y); + + /* pp */ static final boolean DEBUG_POINTER_ICON = Display.DEBUG_POINTER_ICON; + /* pp */ PointerIconImpl defaultPointerIcon = null; + private long gbmHandle; + private static final PNGPixelRect defaultPointerIconImage; } diff --git a/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java index 7d6c2b41c..77ec3ce1a 100644 --- a/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java @@ -29,13 +29,19 @@ package jogamp.newt.driver.egl.gbm; import com.jogamp.nativewindow.DefaultGraphicsScreen; import com.jogamp.nativewindow.util.Rectangle; +import com.jogamp.newt.Display; import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.MonitorMode; import jogamp.nativewindow.drm.DRMUtil; import jogamp.nativewindow.drm.DrmMode; +import jogamp.nativewindow.drm.drmModeConnector; +import jogamp.nativewindow.drm.drmModeEncoder; +import jogamp.nativewindow.drm.drmModeModeInfo; import jogamp.newt.MonitorModeProps; +import jogamp.newt.PointerIconImpl; import jogamp.newt.ScreenImpl; +import jogamp.newt.driver.linux.LinuxMouseTracker; public class ScreenDriver extends ScreenImpl { static { @@ -52,10 +58,12 @@ public class ScreenDriver extends ScreenImpl { if( DEBUG ) { drmMode.print(System.err); } + defaultPointerIcon = ((DisplayDriver)display).defaultPointerIcon; } @Override protected void closeNativeImpl() { + defaultPointerIcon = null; drmMode.destroy(); drmMode = null; } @@ -75,13 +83,17 @@ public class ScreenDriver extends ScreenImpl { // FIXME add multi-monitor multi-mode support final int scridx = 0; // getIndex(); + final drmModeConnector[] connectors = drmMode.getConnectors(); + final drmModeEncoder[] encoder = drmMode.getEncoder(); + final drmModeModeInfo[] mode = drmMode.getModes(); + int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ]; int i = 0; props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL; - props[i++] = drmMode.getModes()[scridx].getHdisplay(); - props[i++] = drmMode.getModes()[scridx].getVdisplay(); + props[i++] = mode[scridx].getHdisplay(); + props[i++] = mode[scridx].getVdisplay(); props[i++] = ScreenImpl.default_sm_bpp; // FIXME - props[i++] = drmMode.getModes()[scridx].getVrefresh() * 100; + props[i++] = mode[scridx].getVrefresh() * 100; props[i++] = 0; // flags props[i++] = 0; // mode_idx props[i++] = 0; // rotation @@ -90,20 +102,26 @@ public class ScreenDriver extends ScreenImpl { props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES]; i = 0; props[i++] = props.length; - props[i++] = 0; // crt_idx + props[i++] = encoder[scridx].getCrtc_id(); // crt_id props[i++] = 0; // is-clone props[i++] = 1; // is-primary - props[i++] = drmMode.getConnectors()[scridx].getMmWidth(); - props[i++] = drmMode.getConnectors()[scridx].getMmHeight(); + props[i++] = connectors[scridx].getMmWidth(); + props[i++] = connectors[scridx].getMmHeight(); props[i++] = 0; // rotated viewport x pixel-units props[i++] = 0; // rotated viewport y pixel-units - props[i++] = drmMode.getModes()[scridx].getHdisplay(); // rotated viewport width pixel-units - props[i++] = drmMode.getModes()[scridx].getVdisplay(); // rotated viewport height pixel-units + props[i++] = mode[scridx].getHdisplay(); // rotated viewport width pixel-units + props[i++] = mode[scridx].getVdisplay(); // rotated viewport height pixel-units props[i++] = 0; // rotated viewport x window-units props[i++] = 0; // rotated viewport y window-units - props[i++] = drmMode.getModes()[scridx].getHdisplay(); // rotated viewport width window-units - props[i++] = drmMode.getModes()[scridx].getVdisplay(); // rotated viewport height window-units + props[i++] = mode[scridx].getHdisplay(); // rotated viewport width window-units + props[i++] = mode[scridx].getVdisplay(); // rotated viewport height window-units MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, cache.monitorModes, props, 0, null); + + crtc_ids = new int[] { encoder[scridx].getCrtc_id() }; + if( null != defaultPointerIcon ) { + final LinuxMouseTracker lmt = LinuxMouseTracker.getSingleton(); + setPointerIconActive(defaultPointerIcon.getHandle(), lmt.getLastX(), lmt.getLastY()); + } } @Override @@ -126,8 +144,67 @@ public class ScreenDriver extends ScreenImpl { viewportInWindowUnits.set(viewport); } + /* pp */ void setPointerIconActive(long piHandle, final int x, final int y) { + synchronized(pointerIconSync) { + if( DisplayDriver.DEBUG_POINTER_ICON ) { + System.err.println("Screen.PointerIcon.set.0: "+Thread.currentThread().getName()); + System.err.println("Screen.PointerIcon.set.0: crtc id "+Display.toHexString(crtc_ids[0])+", active ["+Display.toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"] -> "+Display.toHexString(piHandle)); + } + if( 0 != activePointerIcon && activePointerIconVisible ) { + System.err.println("Screen.PointerIcon.set.1"); + DisplayDriver.SetPointerIcon0(DRMUtil.getDrmFd(), crtc_ids[0], activePointerIcon, false, x, y); + } + if( 0 == piHandle && null != defaultPointerIcon ) { + System.err.println("Screen.PointerIcon.set.2"); + piHandle = ((DisplayDriver)display).defaultPointerIcon.getHandle(); + } + if( 0 != piHandle ) { + System.err.println("Screen.PointerIcon.set.3"); + DisplayDriver.SetPointerIcon0(DRMUtil.getDrmFd(), crtc_ids[0], piHandle, true, x, y); + activePointerIconVisible = true; + } else { + System.err.println("Screen.PointerIcon.set.4"); + activePointerIconVisible = false; + } + activePointerIcon = piHandle; + if( DisplayDriver.DEBUG_POINTER_ICON ) { + System.err.println("Screen.PointerIcon.set.X: active ["+Display.toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"]"); + } + } + } + /* pp */ void setActivePointerIconVisible(final boolean visible, final int x, final int y) { + synchronized(pointerIconSync) { + if( DisplayDriver.DEBUG_POINTER_ICON ) { + System.err.println("Screen.PointerIcon.visible: crtc id "+Display.toHexString(crtc_ids[0])+", active ["+Display.toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"] -> visible "+visible); + } + if( activePointerIconVisible != visible ) { + if( 0 != activePointerIcon ) { + DisplayDriver.SetPointerIcon0(DRMUtil.getDrmFd(), crtc_ids[0], activePointerIcon, visible, x, y); + } + activePointerIconVisible = visible; + } + } + } + /* pp */ void moveActivePointerIcon(final int x, final int y) { + synchronized(pointerIconSync) { + if( DisplayDriver.DEBUG_POINTER_ICON ) { + System.err.println("Screen.PointerIcon.move: crtc id "+Display.toHexString(crtc_ids[0])+", active ["+Display.toHexString(activePointerIcon)+", visible "+activePointerIconVisible+"], "+x+"/"+y); + } + if( 0 != activePointerIcon && activePointerIconVisible ) { + DisplayDriver.MovePointerIcon0(DRMUtil.getDrmFd(), crtc_ids[0], x, y); + } + } + } + + /* pp */ DrmMode drmMode; protected static native boolean initIDs(); protected native void initNative(long drmHandle); + protected int[] crtc_ids; + + private long activePointerIcon; + private boolean activePointerIconVisible; + private final Object pointerIconSync = new Object(); + private PointerIconImpl defaultPointerIcon = null; } diff --git a/src/newt/classes/jogamp/newt/driver/egl/gbm/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/egl/gbm/WindowDriver.java index 7253fac52..de09ba6e3 100644 --- a/src/newt/classes/jogamp/newt/driver/egl/gbm/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/egl/gbm/WindowDriver.java @@ -28,17 +28,15 @@ package jogamp.newt.driver.egl.gbm; import java.nio.ByteBuffer; -import java.nio.IntBuffer; import com.jogamp.common.nio.Buffers; -import com.jogamp.nativewindow.AbstractGraphicsDevice; import com.jogamp.nativewindow.AbstractGraphicsScreen; import com.jogamp.nativewindow.NativeWindowException; -import com.jogamp.nativewindow.egl.EGLGraphicsDevice; import com.jogamp.nativewindow.util.Point; import com.jogamp.nativewindow.util.Rectangle; import com.jogamp.nativewindow.util.RectangleImmutable; import com.jogamp.newt.Display; +import com.jogamp.newt.event.MouseEvent; import com.jogamp.opengl.GLCapabilitiesChooser; import com.jogamp.opengl.GLCapabilitiesImmutable; import com.jogamp.opengl.GLException; @@ -48,8 +46,11 @@ import jogamp.nativewindow.drm.DRMLib; import jogamp.nativewindow.drm.DRMUtil; import jogamp.nativewindow.drm.DrmMode; import jogamp.nativewindow.drm.drmModeModeInfo; +import jogamp.newt.PointerIconImpl; import jogamp.newt.WindowImpl; -import jogamp.newt.driver.linux.LinuxEventDeviceTracker; +import jogamp.newt.driver.KeyTracker; +import jogamp.newt.driver.MouseTracker; +import jogamp.newt.driver.linux.LinuxKeyEventTracker; import jogamp.newt.driver.linux.LinuxMouseTracker; import jogamp.opengl.egl.EGLGraphicsConfiguration; import jogamp.opengl.egl.EGLGraphicsConfigurationFactory; @@ -62,8 +63,8 @@ public class WindowDriver extends WindowImpl { } public WindowDriver() { - linuxMouseTracker = null; // LinuxMouseTracker.getSingleton(); - linuxEventDeviceTracker = null; // LinuxEventDeviceTracker.getSingleton(); + mouseTracker = LinuxMouseTracker.getSingleton(); + keyTracker = LinuxKeyEventTracker.getSingleton(); windowHandleClose = 0; } @@ -236,11 +237,11 @@ public class WindowDriver extends WindowImpl { lastBO = 0; - if( null != linuxEventDeviceTracker ) { - addWindowListener(linuxEventDeviceTracker); + if( null != keyTracker ) { + addWindowListener(keyTracker); } - if( null != linuxMouseTracker ) { - addWindowListener(linuxMouseTracker); + if( null != mouseTracker ) { + addWindowListener(mouseTracker); } visibleChanged(true); focusChanged(false, true); @@ -250,11 +251,11 @@ public class WindowDriver extends WindowImpl { protected void closeNativeImpl() { final Display display = getScreen().getDisplay(); - if( null != linuxMouseTracker ) { - removeWindowListener(linuxMouseTracker); + if( null != mouseTracker ) { + removeWindowListener(mouseTracker); } - if( null != linuxEventDeviceTracker ) { - removeWindowListener(linuxEventDeviceTracker); + if( null != keyTracker ) { + removeWindowListener(keyTracker); } lastBO = 0; @@ -307,7 +308,7 @@ public class WindowDriver extends WindowImpl { @Override protected final int getSupportedReconfigMaskImpl() { - return minimumReconfigStateMask + return minimumReconfigStateMask | // | STATE_MASK_UNDECORATED // | STATE_MASK_ALWAYSONTOP // | STATE_MASK_ALWAYSONBOTTOM @@ -315,9 +316,8 @@ public class WindowDriver extends WindowImpl { // | STATE_MASK_RESIZABLE // | STATE_MASK_MAXIMIZED_VERT // | STATE_MASK_MAXIMIZED_HORZ - // | STATE_MASK_POINTERVISIBLE - // | STATE_MASK_POINTERCONFINED - ; + STATE_MASK_POINTERVISIBLE | + STATE_MASK_POINTERCONFINED; } @Override @@ -334,11 +334,34 @@ public class WindowDriver extends WindowImpl { return new Point(x,y); } + @Override + protected final void doMouseEvent(final boolean enqueue, final boolean wait, final short eventType, final int modifiers, + final int x, final int y, final short button, final float[] rotationXYZ, final float rotationScale) { + if( MouseEvent.EVENT_MOUSE_MOVED == eventType || MouseEvent.EVENT_MOUSE_DRAGGED == eventType ) { + final ScreenDriver screen = (ScreenDriver) getScreen(); + screen.moveActivePointerIcon(getX() + x, getY() + y); + } + super.doMouseEvent(enqueue, wait, eventType, modifiers, x, y, button, rotationXYZ, rotationScale); + } + + @Override + protected void setPointerIconImpl(final PointerIconImpl pi) { + final ScreenDriver screen = (ScreenDriver) getScreen(); + screen.setPointerIconActive(null != pi ? pi.validatedHandle() : 0, mouseTracker.getLastX(), mouseTracker.getLastY()); + } + + @Override + protected boolean setPointerVisibleImpl(final boolean pointerVisible) { + final ScreenDriver screen = (ScreenDriver) getScreen(); + screen.setActivePointerIconVisible(pointerVisible, mouseTracker.getLastX(), mouseTracker.getLastY()); + return true; + } + //---------------------------------------------------------------------- // Internals only // - private final LinuxMouseTracker linuxMouseTracker; - private final LinuxEventDeviceTracker linuxEventDeviceTracker; + private final MouseTracker mouseTracker; + private final KeyTracker keyTracker; private long windowHandleClose; private long eglSurface; private long lastBO; |