From f84af439535640e1072b6cd670aa44cbe91ef052 Mon Sep 17 00:00:00 2001
From: Xerxes Rånby <xerxes@gudinna.com>
Date: Wed, 22 Jul 2015 02:08:41 +0200
Subject: Bug 1178: Implement X11UnderlayTracker
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

driver/x11/X11UnderlayTracker
Using NEWT to initialize an X11 window for use by Raspberry Pi users
to handle mouse and keyboard input when using the bcm.vc.iv driver inside xorg.

newt/driver/bcm/vc/iv/WindowDriver
Try use X11UnderlayTracker as input for bcm.vc.iv
If X11 fail to initialize then
track using the /dev/event files directly
using the LinuxMouseTracker.

Input source is switched inside bcm/vc/iv/WindowDriver
by using the new
newt/driver/KeyTracker
newt/driver/MouseTracker
interfaces.

Signed-off-by: Xerxes Rånby <xerxes@gudinna.com>
---
 .../classes/jogamp/newt/driver/KeyTracker.java     |  35 +++
 .../classes/jogamp/newt/driver/MouseTracker.java   |  39 +++
 .../jogamp/newt/driver/bcm/vc/iv/WindowDriver.java |  50 +++-
 .../newt/driver/linux/LinuxEventDeviceTracker.java |   3 +-
 .../newt/driver/linux/LinuxMouseTracker.java       |   3 +-
 .../jogamp/newt/driver/x11/X11UnderlayTracker.java | 328 +++++++++++++++++++++
 6 files changed, 446 insertions(+), 12 deletions(-)
 create mode 100644 src/newt/classes/jogamp/newt/driver/KeyTracker.java
 create mode 100644 src/newt/classes/jogamp/newt/driver/MouseTracker.java
 create mode 100644 src/newt/classes/jogamp/newt/driver/x11/X11UnderlayTracker.java

diff --git a/src/newt/classes/jogamp/newt/driver/KeyTracker.java b/src/newt/classes/jogamp/newt/driver/KeyTracker.java
new file mode 100644
index 000000000..ab91d48aa
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/KeyTracker.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright 2015 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.newt.driver;
+
+import com.jogamp.newt.event.WindowListener;
+
+public interface KeyTracker extends WindowListener{
+
+}
diff --git a/src/newt/classes/jogamp/newt/driver/MouseTracker.java b/src/newt/classes/jogamp/newt/driver/MouseTracker.java
new file mode 100644
index 000000000..3a0cb2db4
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/MouseTracker.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2015 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.newt.driver;
+
+import com.jogamp.newt.event.WindowListener;
+
+public interface MouseTracker extends WindowListener {
+
+	int getLastY();
+
+	int getLastX();
+
+}
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 93c28d370..02076348b 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
@@ -34,6 +34,7 @@ import com.jogamp.nativewindow.Capabilities;
 import com.jogamp.nativewindow.DefaultGraphicsScreen;
 import com.jogamp.nativewindow.GraphicsConfigurationFactory;
 import com.jogamp.nativewindow.NativeWindowException;
+
 import com.jogamp.nativewindow.VisualIDHolder;
 import com.jogamp.nativewindow.util.Insets;
 import com.jogamp.nativewindow.util.Point;
@@ -41,12 +42,16 @@ import com.jogamp.nativewindow.util.Rectangle;
 import com.jogamp.nativewindow.util.RectangleImmutable;
 import com.jogamp.common.util.IntBitfield;
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
 import com.jogamp.newt.event.MouseEvent;
 
 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.LinuxMouseTracker;
+import jogamp.newt.driver.x11.X11UnderlayTracker;
 import jogamp.opengl.egl.EGLDisplayUtil;
 
 public class WindowDriver extends WindowImpl {
@@ -57,8 +62,26 @@ public class WindowDriver extends WindowImpl {
     }
 
     public WindowDriver() {
-        linuxMouseTracker = LinuxMouseTracker.getSingleton();
-        linuxEventDeviceTracker = LinuxEventDeviceTracker.getSingleton();
+        
+    	/* Try use X11 as input for bcm.vc.iv
+    	 * if X11 fail to initialize then
+    	 * track using the /dev/event files directly
+    	 * using the LinuxMouseTracker
+    	 */
+        try{
+            x11UnderlayTracker = X11UnderlayTracker.getSingleton();
+
+            mouseTracker = x11UnderlayTracker;
+            keyTracker = x11UnderlayTracker;
+        } catch(ExceptionInInitializerError e){
+            linuxMouseTracker = LinuxMouseTracker.getSingleton();
+            linuxEventDeviceTracker = LinuxEventDeviceTracker.getSingleton();
+
+            mouseTracker = linuxMouseTracker;
+            keyTracker = linuxEventDeviceTracker;
+        }
+        
+        
         layer = -1;
         nativeWindowHandle = 0;
         windowHandleClose = 0;
@@ -192,8 +215,10 @@ public class WindowDriver extends WindowImpl {
         }
         windowHandleClose = nativeWindowHandle;
 
-        addWindowListener(linuxEventDeviceTracker);
-        addWindowListener(linuxMouseTracker);
+        addWindowListener(keyTracker);
+        addWindowListener(mouseTracker);
+
+        
         focusChanged(false, true);
     }
 
@@ -202,8 +227,8 @@ public class WindowDriver extends WindowImpl {
         final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
         final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getGraphicsConfiguration().getScreen().getDevice();
 
-        removeWindowListener(linuxMouseTracker);
-        removeWindowListener(linuxEventDeviceTracker);
+        removeWindowListener(mouseTracker);
+        removeWindowListener(keyTracker);
 
         if(0!=windowHandleClose) {
             CloseWindow0(display.getBCMHandle(), windowHandleClose);
@@ -229,6 +254,7 @@ public class WindowDriver extends WindowImpl {
         final RectangleImmutable rect = clampRect((ScreenDriver) getScreen(), new Rectangle(x, y, width, height), false);
         // reconfigure0 will issue position/size changed events if required
         reconfigure0(nativeWindowHandle, rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), flags);
+        
         return true;
     }
 
@@ -255,21 +281,25 @@ public class WindowDriver extends WindowImpl {
     @Override
     protected void setPointerIconImpl(final PointerIconImpl pi) {
         final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
-        display.setPointerIconActive(null != pi ? pi.validatedHandle() : 0, linuxMouseTracker.getLastX(), linuxMouseTracker.getLastY());
+        display.setPointerIconActive(null != pi ? pi.validatedHandle() : 0, mouseTracker.getLastX(), mouseTracker.getLastY());
     }
 
     @Override
     protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
         final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
-        display.setActivePointerIconVisible(pointerVisible, linuxMouseTracker.getLastX(), linuxMouseTracker.getLastY());
+        display.setActivePointerIconVisible(pointerVisible, mouseTracker.getLastX(), mouseTracker.getLastY());
         return true;
     }
 
     //----------------------------------------------------------------------
     // Internals only
     //
-    private final LinuxMouseTracker linuxMouseTracker;
-    private final LinuxEventDeviceTracker linuxEventDeviceTracker;
+    private LinuxMouseTracker linuxMouseTracker;
+    private LinuxEventDeviceTracker linuxEventDeviceTracker;
+    private X11UnderlayTracker x11UnderlayTracker;
+    
+    private MouseTracker mouseTracker;
+    private KeyTracker keyTracker;
 
     protected static native boolean initIDs();
     private        native long CreateWindow0(long bcmDisplay, int layer, int x, int y, int width, int height, boolean opaque, int alphaBits);
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
index 49a815cb6..bc0bfaa16 100644
--- a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
@@ -40,6 +40,7 @@ import java.lang.Thread;
 import java.nio.ByteBuffer;
 
 import jogamp.newt.WindowImpl;
+import jogamp.newt.driver.KeyTracker;
 
 import com.jogamp.common.nio.StructAccessor;
 import com.jogamp.newt.Window;
@@ -55,7 +56,7 @@ import com.jogamp.newt.event.KeyEvent;
  * within it's own polling thread.
  */
 
-public class LinuxEventDeviceTracker implements WindowListener {
+public class LinuxEventDeviceTracker implements WindowListener, KeyTracker {
 
     private static final LinuxEventDeviceTracker ledt;
 
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
index 1d9377563..f40728da0 100644
--- a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
@@ -35,6 +35,7 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import jogamp.newt.WindowImpl;
+import jogamp.newt.driver.MouseTracker;
 
 import com.jogamp.newt.Screen;
 import com.jogamp.newt.Window;
@@ -48,7 +49,7 @@ import com.jogamp.newt.event.WindowUpdateEvent;
  * just reading <code>/dev/input/mice</code>
  * within it's own polling thread.
  */
-public class LinuxMouseTracker implements WindowListener {
+public class LinuxMouseTracker implements WindowListener, MouseTracker {
 
     private static final LinuxMouseTracker lmt;
 
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11UnderlayTracker.java b/src/newt/classes/jogamp/newt/driver/x11/X11UnderlayTracker.java
new file mode 100644
index 000000000..d0c5ed2c0
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11UnderlayTracker.java
@@ -0,0 +1,328 @@
+/**
+ * Copyright 2015 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.newt.driver.x11;
+
+import jogamp.nativewindow.x11.X11Util;
+import jogamp.newt.WindowImpl;
+import jogamp.newt.driver.MouseTracker;
+import jogamp.newt.driver.KeyTracker;
+
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.nativewindow.Capabilities;
+import com.jogamp.nativewindow.GraphicsConfigurationFactory;
+import com.jogamp.nativewindow.NativeWindowFactory;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowListener;
+import com.jogamp.newt.event.WindowUpdateEvent;
+
+/**
+ * UnderlayTracker can be used as input for
+ * WM that only provide undecorated overlays.
+ * 
+ * The UnderlayTracker enable move and resize
+ * manipulation of the overlays.
+ * 
+ * A NEWT window may use the UnderlayTracker by calling
+ * <code>addWindowListener(X11UnderlayTracker.getSingleton())</code>
+ */
+public class X11UnderlayTracker implements WindowListener, KeyListener, MouseListener, MouseTracker, KeyTracker {
+
+    private static final X11UnderlayTracker tracker;
+    private static Window window;
+    private volatile WindowImpl focusedWindow = null;
+	private volatile MouseEvent lastMouse;
+
+    static {
+    	tracker = new X11UnderlayTracker();
+    }
+
+    public static X11UnderlayTracker getSingleton() {
+        return tracker;
+    }
+    
+    private X11UnderlayTracker() {
+    	
+    	/* 
+    	 * X11UnderlayTracker is intended to be used on systems where
+    	 * X11 is not the default WM.
+    	 * We must explicitly initialize all X11 dependencies
+    	 * to make sure they are available.
+    	 */
+    	X11Util.initSingleton();
+    	GraphicsConfigurationFactory.initSingleton();
+    	try {
+             ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory",
+                                             "registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());
+        } catch (final Exception e) {
+                throw new RuntimeException(e);
+        }
+    	
+    	/*
+    	 * Initialize the X11 window.
+    	 */
+    	Capabilities caps = new Capabilities();
+        final Display display = NewtFactory.createDisplay(NativeWindowFactory.TYPE_X11, null, false);
+        final Screen screen  = NewtFactory.createScreen(display, 0);
+             	
+    	window = WindowImpl.create(null, 0, screen, caps);
+        //window.setSize(200, 140);
+        //window.setPosition(300, 400);
+        window.setVisible(false, true);
+        
+    	window.addKeyListener(this);
+        window.addMouseListener(this);
+        window.addWindowListener(this);
+    }
+
+
+
+    @Override
+    public void windowResized(final WindowEvent e) {
+    	final Object s = e.getSource();
+    	
+    	if(s instanceof WindowImpl) {
+    		if(window == s) {
+    			if(focusedWindow!=null){
+    				focusedWindow.setSize(window.getSurfaceWidth(),window.getSurfaceHeight());
+    				// workaround bvm.vc.iv possition gets moved during setSize
+    				focusedWindow.setPosition(window.getX(),window.getY());
+    			}
+    		} else {
+    			// FIXME null check here used as a workaround to prevent event avalance
+    			// fixing it will allow the user to resize the NEWT window using code
+    			// after it has gained focus.
+    			if(focusedWindow==null){
+    				WindowImpl sourceWindow = (WindowImpl) s;
+    				window.setSize(sourceWindow.getSurfaceWidth(),sourceWindow.getSurfaceHeight());
+    			}
+    		}
+        }
+    }
+
+    @Override
+    public void windowMoved(final WindowEvent e) {
+    	final Object s = e.getSource();
+    	if(s instanceof WindowImpl) {
+    		if(window == s) {
+    			if(focusedWindow!=null){
+    				//focusedWindow.setSize(window.getSurfaceWidth(),window.getSurfaceHeight());
+    				focusedWindow.setPosition(window.getX(), window.getY());
+    			}
+    		} else {
+    			// FIXME null check here used as a workaround to prevent event avalance
+    			// fixing it will allow the user to move the NEWT window using code
+    			// after it has gained focus.
+    			if(focusedWindow==null){
+    				WindowImpl sourceWindow = (WindowImpl) s;
+    				window.setPosition(sourceWindow.getX(), sourceWindow.getY());
+    			}
+    		}
+        }
+    }
+
+    @Override
+    public void windowDestroyNotify(final WindowEvent e) {
+        final Object s = e.getSource();
+        
+        if(window == s) {
+    		if(focusedWindow!=null){
+    			focusedWindow.destroy();
+    			focusedWindow = null;
+    		}
+    	} else {
+    		if(focusedWindow == s) {
+    			focusedWindow = null;
+    			window.setVisible(false, false);
+    			window.destroy();
+    		}
+    	}
+    }
+
+    @Override
+    public void windowDestroyed(final WindowEvent e) { }
+
+    @Override
+    public void windowGainedFocus(final WindowEvent e) {
+        final Object s = e.getSource();
+        if(s instanceof WindowImpl) {
+        	if(window == s) {
+        		// do nothing
+        	} else {
+        		if(focusedWindow==null) {
+        			// hack that initially make the tracking window the same size as the overlay
+        			WindowImpl sourceWindow = (WindowImpl) s;
+            		window.setSize(sourceWindow.getSurfaceWidth(),sourceWindow.getSurfaceHeight());
+            		window.setPosition(sourceWindow.getX(), sourceWindow.getY());
+        		}
+        		focusedWindow = (WindowImpl) s;
+        	}
+        }
+    }
+
+    @Override
+    public void windowLostFocus(final WindowEvent e) {
+        final Object s = e.getSource();
+    	if(window == s) {
+    		// do nothing
+    	} else {
+    		if(focusedWindow == s) {
+    			focusedWindow = null;
+    		}
+    	}
+    }
+
+    @Override
+    public void windowRepaint(final WindowUpdateEvent e) { }
+    
+    public static void main(String[] args) throws InterruptedException{
+    	X11UnderlayTracker.getSingleton();
+        
+    	Thread.sleep(25000);
+    }
+
+	@Override
+	public void mouseClicked(MouseEvent e) {
+		lastMouse = e;
+		if(focusedWindow != null){
+			//e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_CLICKED, 0, e.getX(), e.getY(), (short)0, 0 );
+		}
+	}
+
+	@Override
+	public void mouseEntered(MouseEvent e) {
+		lastMouse = e;
+		if(focusedWindow != null){
+			//e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_ENTERED, 0, e.getX(), e.getY(), (short)0, 0 );
+		}
+	}
+
+	@Override
+	public void mouseExited(MouseEvent e) {
+		lastMouse = e;
+		if(focusedWindow != null){
+			//e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_EXITED, 0, e.getX(), e.getY(), (short)0, 0 );
+		}
+	}
+
+	@Override
+	public void mousePressed(MouseEvent e) {
+		lastMouse = e;
+		if(focusedWindow != null){
+            //e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_PRESSED, 0, e.getX(), e.getY(), (short)0, 0 );
+		}
+	}
+
+	@Override
+	public void mouseReleased(MouseEvent e) {
+		lastMouse = e;
+		if(focusedWindow != null){
+			//e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_RELEASED, 0, e.getX(), e.getY(), (short)0, 0 );
+		}
+	}
+
+	@Override
+	public void mouseMoved(MouseEvent e) {
+		lastMouse = e;
+		if(focusedWindow != null){
+			//e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_MOVED, 0, e.getX(), e.getY(), (short)0, 0 );
+		}
+	}
+
+	@Override
+	public void mouseDragged(MouseEvent e) {
+		lastMouse = e;
+		if(focusedWindow != null){
+			//e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_DRAGGED, 0, e.getX(), e.getY(), (short)0, 0 );
+		}
+	}
+
+	@Override
+	public void mouseWheelMoved(MouseEvent e) {
+		lastMouse = e;
+		if(focusedWindow != null){
+			//e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_WHEEL_MOVED, 0, e.getX(), e.getY(), (short)0, 0 );
+		}
+	}
+
+	@Override
+	public void keyPressed(KeyEvent e) {
+		if(focusedWindow != null){
+			//e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendKeyEvent(e.getEventType(), e.getModifiers(), e.getKeyCode(), e.getKeyCode(), (char)e.getKeySymbol());
+		}
+	}
+
+	@Override
+	public void keyReleased(KeyEvent e) {
+		if(focusedWindow != null){
+			//e.setConsumed(false);
+			//focusedWindow.consumeEvent(e);
+			focusedWindow.sendKeyEvent(e.getEventType(), e.getModifiers(), e.getKeyCode(), e.getKeyCode(), (char)e.getKeySymbol());
+		}
+	}
+
+	@Override
+	public int getLastY() {
+        if(lastMouse!=null)
+            return lastMouse.getY();
+		return 0;
+	}
+
+	@Override
+	public int getLastX() {
+        if(lastMouse!=null)
+            return lastMouse.getX();	
+		return 0;
+	}
+}
-- 
cgit v1.2.3