From ec4721c5b81ca39355f660294bf45edc0a1584da Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 27 Mar 2019 18:53:27 +0100 Subject: Bug 1348: Fix X11 XI Multitouch I got access to a touchscreen laptop w/ Debian 9, hence I could fix and test the implementation. X11 DisplayDriver.java: - Store and pass through xi_opcode of XI extension, queried at initialization stage X11Window.c Fixes: - Initialize JavaWindow's xiTouchCoords[].id w/ -1, as required to track the pointer - Pass through xi_opcode as stored in X11 DisplayDriver X11Display.c Fixes: - sendTouchScreenEvent: Throw RuntimeException if 0 > actionId (Internal Error: based on xiTouchCoords[].id tracking) - DispatchMessages's windowPointer determination: -- Query potenial XI Event first: IF XI Event, must use XIDeviceEvent's event Window -- Only IF not an XI Event, we can use evt.xany.window as the event window - DispatchMessages's XI Event Handling: -- Always break deviceid search loop if id found, preserving index and time spend Works on my Debian 9 device, tested w/ com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT: - One pointer (finger) press, drag and release (click) - PinchToZoomGesture works - DoubleTabScrollGesture works +++ Potential Issues: JavaWindow's xiTouchCoords[].id accuracy is crucial to pointer tracking during XI_TouchBegin -> XI_TouchUpdate -> XI_TouchEnd. In the normal course of action: - XI_TouchBegin sets the id, assuming it is yet set - XI_TouchUpdate assumes it is set - XI_TouchEnd clears the id, assuming it is set This field in the JavaWindow array only gets reset to -1 once at native window creation. We may need to figure out when to reset this field to -1. If the XI_TouchEnd events would get lost for whatever reason, the above tracking state would be broken. --- src/newt/classes/jogamp/newt/WindowImpl.java | 2 +- .../classes/jogamp/newt/driver/x11/DisplayDriver.java | 10 ++++++---- src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java | 15 +++++++-------- 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src/newt/classes/jogamp') diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 0d395b970..5f03189ac 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -3545,7 +3545,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer final int pCount = pTypes.length; if( 0 > pActionIdx || pActionIdx >= pCount) { - throw new IllegalArgumentException("actionIdx out of bounds [0.."+(pCount-1)+"]"); + throw new IllegalArgumentException("actionIdx "+pActionIdx+" out of bounds [0.."+(pCount-1)+"]"); } if( 0 < pActionIdx ) { // swap values to make idx 0 the triggering pointer diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java index 81ccdbfcd..9d89ba085 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java @@ -110,7 +110,7 @@ public class DisplayDriver extends DisplayImpl { final long handle = _aDevice.getHandle(); if(0 != handle) { DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom /*, kbdHandle */, // XKB disabled for now - randr_event_base, randr_error_base); + randr_event_base, randr_error_base, xi_opcode); } } finally { _aDevice.unlock(); @@ -122,6 +122,7 @@ public class DisplayDriver extends DisplayImpl { // protected long getKbdHandle() { return kbdHandle; } // XKB disabled for now protected int getRandREventBase() { return randr_event_base; } protected int getRandRErrorBase() { return randr_error_base; } + protected int getXiOpcode() { return xi_opcode; } /** Returns null if !{@link #isNativeValid()}, otherwise the Boolean value of {@link X11GraphicsDevice#isXineramaEnabled()}. */ protected Boolean isXineramaEnabled() { return isNativeValid() ? Boolean.valueOf(((X11GraphicsDevice)aDevice).isXineramaEnabled()) : null; } @@ -145,12 +146,13 @@ public class DisplayDriver extends DisplayImpl { private native void CompleteDisplay0(long handle); private void displayCompleted(final long javaObjectAtom, final long windowDeleteAtom /*, long kbdHandle */, - final int randr_event_base, final int randr_error_base) { + final int randr_event_base, final int randr_error_base, final int xi_opcode) { this.javaObjectAtom=javaObjectAtom; this.windowDeleteAtom=windowDeleteAtom; // this.kbdHandle = kbdHandle; // XKB disabled for now this.randr_event_base = randr_event_base; this.randr_error_base = randr_error_base; + this.xi_opcode = xi_opcode; } private void sendRRScreenChangeNotify(final long event) { if( null != rAndR ) { @@ -163,7 +165,7 @@ public class DisplayDriver extends DisplayImpl { private native void DisplayRelease0(long handle, long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle */); // XKB disabled for now private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom /* , long kbdHandle */, // XKB disabled for now - final int randr_event_base, final int randr_error_base); + final int randr_event_base, final int randr_error_base, final int xi_opcode); private static long createPointerIcon(final long display, final Buffer pixels, final int width, final int height, final int hotX, final int hotY) { final boolean pixels_is_direct = Buffers.isDirect(pixels); @@ -185,7 +187,7 @@ public class DisplayDriver extends DisplayImpl { /** X11 Keyboard handle used on EDT */ // private long kbdHandle; // XKB disabled for now - private int randr_event_base, randr_error_base; + private int randr_event_base, randr_error_base, xi_opcode; private RandR rAndR; } diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index 468aca654..afd10f54b 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -127,7 +127,7 @@ public class WindowDriver extends WindowImpl { try { final long[] handles = CreateWindow(getParentWindowHandle(), edtDevice.getHandle(), screen.getIndex(), visualID, - display.getJavaObjectAtom(), display.getWindowDeleteAtom(), + display.getJavaObjectAtom(), display.getWindowDeleteAtom(), display.getXiOpcode(), getX(), getY(), getWidth(), getHeight(), flags, defaultIconDataSize, defaultIconData, DEBUG_IMPLEMENTATION); if (null == handles || 2 != handles.length || 0 == handles[0] || 0 == handles[1] ) { @@ -151,7 +151,7 @@ public class WindowDriver extends WindowImpl { edtDevice.lock(); try { CloseWindow0(edtDevice.getHandle(), javaWindowHandle /* , display.getKbdHandle() */, // XKB disabled for now - display.getRandREventBase(), display.getRandRErrorBase()); + display.getRandREventBase(), display.getRandRErrorBase(), display.getXiOpcode()); } catch (final Throwable t) { if(DEBUG_IMPLEMENTATION) { final Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); @@ -411,8 +411,7 @@ public class WindowDriver extends WindowImpl { final int[] pX, final int[] pY, final float[] pPressure, final float maxPressure) { final int pCount = pNames.length; final MouseEvent.PointerType[] pTypes = new MouseEvent.PointerType[pCount]; - for(int i=0; i