changeset 6056:c37840998bfd

RT-35252 [Monocle] Synthesize mouse events on single-point touch screens
author Daniel Blaukopf <daniel.blaukopf@oracle.com>
date Fri, 10 Jan 2014 00:30:37 +0200
parents 3484840f5140
children 00c463f633fc
files buildSrc/armv6hf.gradle buildSrc/armv6sf.gradle buildSrc/x86egl.gradle modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleApplication.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/MouseInput.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/MouseInputSynthesizer.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/TouchInput.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/TouchState.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/AbsoluteInputCapabilities.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxInputDevice.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxMouseProcessor.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxSystem.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxTouchProcessor.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11InputDeviceRegistry.java modules/graphics/src/main/native-glass/monocle/linux/LinuxSystem.c
diffstat 15 files changed, 518 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/buildSrc/armv6hf.gradle	Thu Jan 09 22:31:59 2014 +0200
+++ b/buildSrc/armv6hf.gradle	Fri Jan 10 00:30:37 2014 +0200
@@ -348,8 +348,8 @@
 
 ARMV6HF.glass.monocle = [:]
 ARMV6HF.glass.monocle.nativeSource = [
-        file("modules/graphics/src/main/native-glass/monocle"),
-        file("modules/graphics/src/main/native-glass/monocle/linux") ]
+        file("modules/graphics/src/main/native-glass/monocle/linux"),
+        file("modules/graphics/src/main/native-glass/monocle/util") ]
 ARMV6HF.glass.monocle.compiler = compiler
 ARMV6HF.glass.monocle.ccFlags = monocleCFlags
 ARMV6HF.glass.monocle.linker = linker
--- a/buildSrc/armv6sf.gradle	Thu Jan 09 22:31:59 2014 +0200
+++ b/buildSrc/armv6sf.gradle	Fri Jan 10 00:30:37 2014 +0200
@@ -354,8 +354,8 @@
 
 ARMV6SF.glass.monocle = [:]
 ARMV6SF.glass.monocle.nativeSource = [
-        file("modules/graphics/src/main/native-glass/monocle"),
-        file("modules/graphics/src/main/native-glass/monocle/linux") ]
+        file("modules/graphics/src/main/native-glass/monocle/linux"),
+        file("modules/graphics/src/main/native-glass/monocle/util") ]
 ARMV6SF.glass.monocle.compiler = compiler
 ARMV6SF.glass.monocle.ccFlags = monocleCFlags
 ARMV6SF.glass.monocle.linker = linker
--- a/buildSrc/x86egl.gradle	Thu Jan 09 22:31:59 2014 +0200
+++ b/buildSrc/x86egl.gradle	Fri Jan 10 00:30:37 2014 +0200
@@ -279,8 +279,8 @@
 
 X86EGL.glass.monocle = [:]
 X86EGL.glass.monocle.nativeSource = [
-        file("modules/graphics/src/main/native-glass/monocle"),
-        file("modules/graphics/src/main/native-glass/monocle/linux") ]
+        file("modules/graphics/src/main/native-glass/monocle/linux"),
+        file("modules/graphics/src/main/native-glass/monocle/util") ]
 X86EGL.glass.monocle.compiler = compiler
 X86EGL.glass.monocle.ccFlags = monocleCFlags
 X86EGL.glass.monocle.linker = linker
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleApplication.java	Thu Jan 09 22:31:59 2014 +0200
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleApplication.java	Fri Jan 10 00:30:37 2014 +0200
@@ -267,7 +267,7 @@
                 MouseState mouseState = new MouseState();
                 mouseState.setX(ns.getWidth() / 2);
                 mouseState.setY(ns.getHeight() / 2);
-                MouseInput.getInstance().setState(mouseState);
+                MouseInput.getInstance().setState(mouseState, false);
             }
         } catch (Exception e) {
             e.printStackTrace();
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/MouseInput.java	Thu Jan 09 22:31:59 2014 +0200
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/MouseInput.java	Fri Jan 10 00:30:37 2014 +0200
@@ -50,7 +50,7 @@
         state.copyTo(result);
     }
 
-    public void setState(MouseState newState) {
+    public void setState(MouseState newState, boolean synthesized) {
         MonocleWindow oldWindow = state.getWindow(false);
         MonocleWindow window = newState.getWindow(true);
         MonocleView view = (window == null) ? null : (MonocleView) window.getView();
@@ -70,7 +70,7 @@
                 int oldRelY = oldY - oldWindow.getY();
                 oldView._notifyMouse(MouseEvent.EXIT, button,
                                   oldRelX, oldRelY, oldX, oldY,
-                                  modifiers, isPopupTrigger, false);
+                                  modifiers, isPopupTrigger, synthesized);
             }
         }
         int x = newState.getX();
@@ -98,7 +98,7 @@
             boolean isPopupTrigger = false; // TODO
             view._notifyMouse(MouseEvent.ENTER, button,
                               relX, relY, x, y,
-                              modifiers, isPopupTrigger, false);
+                              modifiers, isPopupTrigger, synthesized);
         }
         // send motion events
         if (oldWindow != window | newAbsoluteLocation) {
@@ -109,7 +109,7 @@
             boolean isPopupTrigger = false; // TODO
             view._notifyMouse(eventType, button,
                               relX, relY, x, y,
-                              modifiers, isPopupTrigger, false);
+                              modifiers, isPopupTrigger, synthesized);
         }
         // send press events
         newState.getButtonsPressed().difference(buttons, state.getButtonsPressed());
@@ -124,7 +124,7 @@
                 view._notifyMouse(MouseEvent.DOWN, button,
                                   relX, relY, x, y,
                                   pressState.getModifiers(), isPopupTrigger,
-                                  false);
+                                  synthesized);
             }
         }
         buttons.clear();
@@ -142,7 +142,7 @@
                 view._notifyMouse(MouseEvent.UP, button,
                                   relX, relY, x, y,
                                   releaseState.getModifiers(), isPopupTrigger,
-                                  false);
+                                  synthesized);
 
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/MouseInputSynthesizer.java	Fri Jan 10 00:30:37 2014 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.glass.ui.monocle.input;
+
+import com.sun.glass.events.MouseEvent;
+
+public class MouseInputSynthesizer {
+
+    private static MouseInputSynthesizer instance = new MouseInputSynthesizer();
+
+    private MouseState mouseState = new MouseState();
+
+    public static MouseInputSynthesizer getInstance() {
+        return instance;
+    }
+
+    public void setState(TouchState touchState) {
+        if (touchState.getPointCount() == 0) {
+            mouseState.releaseButton(MouseEvent.BUTTON_LEFT);
+        } else {
+            mouseState.pressButton(MouseEvent.BUTTON_LEFT);
+        }
+        if (touchState.getPointCount() == 1) {
+            // do not synthesize mouse drag events if more than one finger is
+            // down
+            TouchState.Point p = touchState.getPoint(0);
+            mouseState.setX(p.x);
+            mouseState.setY(p.y);
+        }
+        MouseInput.getInstance().setState(mouseState, true);
+    }
+
+}
\ No newline at end of file
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/TouchInput.java	Thu Jan 09 22:31:59 2014 +0200
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/TouchInput.java	Fri Jan 10 00:30:37 2014 +0200
@@ -43,8 +43,9 @@
     }
 
     public void setState(TouchState newState) {
-        System.out.println(newState);
+        // TODO: send touch events
         newState.copyTo(state);
+        MouseInputSynthesizer.getInstance().setState(newState);
     }
 
 }
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/TouchState.java	Thu Jan 09 22:31:59 2014 +0200
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/TouchState.java	Fri Jan 10 00:30:37 2014 +0200
@@ -31,8 +31,8 @@
 
     public static class Point {
         public int id;
-        public float x;
-        public float y;
+        public int x;
+        public int y;
         public void copyTo(Point target) {
             target.id = id;
             target.x = x;
@@ -50,6 +50,25 @@
         return points[index];
     }
 
+    /*
+     * If there is more than one point, returns the first point.
+     * If there used to be any points but now are not, reinstate what used to be
+     * the first point and return it.
+     * If there never where any points, create a new one and set it to be the first point.
+      */
+    public Point getPointZero() {
+        if (pointCount == 0 && points[0] == null) {
+            Point p = new Point();
+            addPoint(p);
+            return p;
+        } else if (pointCount == 0) {
+            pointCount ++;
+            return points[0];
+        } else {
+            return points[0];
+        }
+    }
+
     public int getPointCount() {
         return pointCount;
     }
@@ -97,13 +116,12 @@
     }
 
     public String toString() {
-        StringBuffer sb = new StringBuffer("TouchState[" + pointCount + ",");
+        StringBuffer sb = new StringBuffer("TouchState[" + pointCount);
         for (int i = 0; i < pointCount; i++) {
+            sb.append(",");
             sb.append(points[i]);
-            if (i < pointCount - 1) {
-                sb.append(",");
-            }
         }
+        sb.append("]");
         return sb.toString();
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/AbsoluteInputCapabilities.java	Fri Jan 10 00:30:37 2014 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.glass.ui.monocle.linux;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Describes the capabilities of Linux input devices with absolute
+ * coordinates. See /usr/include/linux/input.h */
+class AbsoluteInputCapabilities {
+
+    private int value;
+    private int minimum;
+    private int maximum;
+    private int fuzz;
+    private int flat;
+    private int resolution;
+
+    private AbsoluteInputCapabilities(LinuxSystem system,
+                                      LinuxSystem.InputAbsInfo info,
+                                      long fd, int axis) throws IOException {
+        system.ioctl(fd, system.EVIOCGABS(axis), info.p);
+        value = LinuxSystem.InputAbsInfo.getValue(info.p);
+        minimum = LinuxSystem.InputAbsInfo.getMinimum(info.p);
+        maximum = LinuxSystem.InputAbsInfo.getMaximum(info.p);
+        fuzz = LinuxSystem.InputAbsInfo.getFuzz(info.p);
+        flat = LinuxSystem.InputAbsInfo.getFlat(info.p);
+        resolution = LinuxSystem.InputAbsInfo.getResolution(info.p);
+    }
+
+    /** Reads capabilities from a device node.
+     *
+     * @return A Map of capabilities for each supported axis, or null if no
+     * capabilities are available.
+     * @throws IOException if an error occured when reading capabilities
+     * */
+    static Map<Integer, AbsoluteInputCapabilities> getCapabilities(
+            File devNode, BitSet axes) throws IOException {
+        if (axes == null || axes.isEmpty()) {
+            return null;
+        }
+        LinuxSystem system = LinuxSystem.getLinuxSystem();
+        LinuxSystem.InputAbsInfo info = new LinuxSystem.InputAbsInfo();
+        long fd = system.open(devNode.getPath(), LinuxSystem.O_RDONLY);
+        if (fd == -1) {
+            throw new IOException(system.strerror(system.errno()));
+        }
+        Map<Integer, AbsoluteInputCapabilities> caps =
+                new HashMap<Integer, AbsoluteInputCapabilities>();
+        for (int i = 0; (i = axes.nextSetBit(i)) != -1; i++) {
+            caps.put(i, new AbsoluteInputCapabilities(system, info, fd, i));
+        }
+        system.close(fd);
+        return caps;
+    }
+
+
+    public int getValue() {
+        return value;
+    }
+
+    public int getMinimum() {
+        return minimum;
+    }
+
+    public int getMaximum() {
+        return maximum;
+    }
+
+    public int getFuzz() {
+        return fuzz;
+    }
+
+    public int getFlat() {
+        return flat;
+    }
+
+    public int getResolution() {
+        return resolution;
+    }
+
+
+}
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxInputDevice.java	Thu Jan 09 22:31:59 2014 +0200
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxInputDevice.java	Fri Jan 10 00:30:37 2014 +0200
@@ -72,6 +72,7 @@
     private File devNode;
     private File sysPath;
     private Map<String, BitSet> capabilities;
+    private Map<Integer, AbsoluteInputCapabilities> absCaps;
     private Map<String, String> udevManifest;
     private ByteBuffer bb = ByteBuffer.allocate(EVENT_STRUCT_SIZE * EVENT_BUFFER_SIZE);
     private ByteBuffer event = ByteBuffer.allocate(EVENT_STRUCT_SIZE);
@@ -96,6 +97,8 @@
         this.sysPath = sysPath;
         this.udevManifest = udevManifest;
         this.capabilities = SysFS.readCapabilities(sysPath);
+        this.absCaps = AbsoluteInputCapabilities.getCapabilities(
+                devNode, capabilities.get("abs"));
         this.in = new FileInputStream(devNode).getChannel();
         this.executor = NativePlatformFactory.getNativePlatform().getExecutor();
     }
@@ -253,6 +256,10 @@
         return capabilities.get(type);
     }
 
+    AbsoluteInputCapabilities getAbsoluteInputCapabilities(int axis) {
+        return absCaps == null ? null : absCaps.get(axis);
+    }
+
     @Override
     public boolean isTouch() {
         return "1".equals(udevManifest.get("ID_INPUT_TOUCHSCREEN"))
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxMouseProcessor.java	Thu Jan 09 22:31:59 2014 +0200
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxMouseProcessor.java	Fri Jan 10 00:30:37 2014 +0200
@@ -58,7 +58,7 @@
                 case Input.EV_SYN:
                     switch (device.getEventCode()) {
                         case Input.SYN_REPORT:
-                            mouse.setState(state);
+                            mouse.setState(state, false);
                             break;
                         default: // ignore
                     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxSystem.java	Fri Jan 10 00:30:37 2014 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.glass.ui.monocle.linux;
+
+import com.sun.glass.ui.monocle.util.C;
+
+public class LinuxSystem {
+
+    private static LinuxSystem instance = new LinuxSystem();
+
+    public static LinuxSystem getLinuxSystem() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(new RuntimePermission("loadLibrary.*"));
+        }
+        return instance;
+    }
+
+    private LinuxSystem() {
+    }
+
+
+    // fcntl.h
+
+    static final int O_RDONLY = 0;
+
+    native long open(String path, int flags);
+
+    // unistd.h
+    native int close(long fd);
+
+    // input.h
+
+    static class InputAbsInfo extends C.Structure {
+        @Override
+        public native int sizeof();
+        static native int getValue(long p);
+        static native int getMinimum(long p);
+        static native int getMaximum(long p);
+        static native int getFuzz(long p);
+        static native int getFlat(long p);
+        static native int getResolution(long p);
+    }
+
+    native int EVIOCGABS(int type);
+
+    // fb.h
+
+    static final int FBIOGET_VSCREENINFO = 0x4600;
+
+    static class FbVarScreenInfo extends C.Structure {
+        @Override
+        public native int sizeof();
+        static native int getXRes(long p);
+        static native int getYRes(long p);
+    }
+
+    // ioctl.h
+
+    native int ioctl(long fd, int request, long data);
+
+    // errno.h
+    native int errno();
+
+    // string.h
+    native String strerror(int errnum);
+
+    // dlfcn.h
+    public native long dlopen(String filename, int flag);
+    public native String dlerror();
+    public native long dlsym(long handle, String symbol);
+    public native int dlclose(long handle);
+}
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxTouchProcessor.java	Thu Jan 09 22:31:59 2014 +0200
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxTouchProcessor.java	Fri Jan 10 00:30:37 2014 +0200
@@ -25,6 +25,7 @@
 
 package com.sun.glass.ui.monocle.linux;
 
+import com.sun.glass.ui.monocle.NativePlatformFactory;
 import com.sun.glass.ui.monocle.input.TouchInput;
 import com.sun.glass.ui.monocle.input.TouchState;
 
@@ -35,12 +36,64 @@
     @Override
     public void processEvents(LinuxInputDevice device) {
         TouchInput touch = TouchInput.getInstance();
-        touch.getState(state);
         while (device.hasNextEvent()) {
-            System.out.println(device.getEventDescription());
+            switch (device.getEventType()) {
+                case Input.EV_ABS: {
+                    int pixelValue = toPixelValue(device,
+                                                  device.getEventCode(),
+                                                  device.getEventValue());
+                    switch (device.getEventCode()) {
+                        case Input.ABS_X:
+                            state.getPointZero().x = pixelValue;
+                            break;
+                        case Input.ABS_Y:
+                            state.getPointZero().y = pixelValue;
+                            break;
+                    }
+                }
+                case Input.EV_SYN:
+                    switch (device.getEventCode()) {
+                        case Input.SYN_REPORT:
+                            touch.setState(state);
+                            state.clear();
+                            break;
+                        default: // ignore
+                    }
+                    break;
+            }
             device.nextEvent();
         }
+    }
 
+    private static int toPixelValue(LinuxInputDevice device, int axis, int value) {
+        switch (axis) {
+            case Input.ABS_X:
+            case Input.ABS_MT_POSITION_X:
+                return toPixelX(device, axis, value);
+            case Input.ABS_Y:
+            case Input.ABS_MT_POSITION_Y:
+                return toPixelY(device, axis, value);
+            default:
+                return value;
+        }
+    }
+
+    private static int toPixelX(LinuxInputDevice device, int axis, int value) {
+        AbsoluteInputCapabilities caps = device.getAbsoluteInputCapabilities(axis);
+        int minimum = caps.getMinimum();
+        int maximum = caps.getMaximum();
+        int screenWidth = NativePlatformFactory.getNativePlatform().getScreen().getWidth();
+        int pixel = ((value - minimum) * screenWidth) / (maximum - minimum);
+        return pixel;
+    }
+
+    private static int toPixelY(LinuxInputDevice device, int axis, int value) {
+        AbsoluteInputCapabilities caps = device.getAbsoluteInputCapabilities(axis);
+        int minimum = caps.getMinimum();
+        int maximum = caps.getMaximum();
+        int screenHeight = NativePlatformFactory.getNativePlatform().getScreen().getHeight();
+        int pixel = ((value - minimum) * screenHeight) / (maximum - minimum);
+        return pixel;
     }
 
 }
--- a/modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11InputDeviceRegistry.java	Thu Jan 09 22:31:59 2014 +0200
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11InputDeviceRegistry.java	Fri Jan 10 00:30:37 2014 +0200
@@ -131,7 +131,7 @@
             if (glassButton != MouseEvent.BUTTON_NONE) {
                 state.pressButton(glassButton);
             }
-            MouseInput.getInstance().setState(state);
+            MouseInput.getInstance().setState(state, false);
         }
     }
 
@@ -147,7 +147,7 @@
             if (glassButton != MouseEvent.BUTTON_NONE) {
                 state.releaseButton(glassButton);
             }
-            MouseInput.getInstance().setState(state);
+            MouseInput.getInstance().setState(state, false);
         }
     }
 
@@ -163,7 +163,7 @@
             MouseInput.getInstance().getState(state);
             state.setX(x);
             state.setY(y);
-            MouseInput.getInstance().setState(state);
+            MouseInput.getInstance().setState(state, false);
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/monocle/linux/LinuxSystem.c	Fri Jan 10 00:30:37 2014 +0200
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "com_sun_glass_ui_monocle_linux_LinuxSystem.h"
+#include "com_sun_glass_ui_monocle_linux_LinuxSystem_FbVarScreenInfo.h"
+#include "com_sun_glass_ui_monocle_linux_LinuxSystem_InputAbsInfo.h"
+#include "Monocle.h"
+
+#include <fcntl.h>
+#include <linux/fb.h>
+#include <linux/input.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <unistd.h>
+
+JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_open
+  (JNIEnv *env, jobject UNUSED(obj), jstring filenameS, jint flag) {
+    const char *filename = (*env)->GetStringUTFChars(env, filenameS, NULL);
+    int fd = open(filename, (int) flag);
+    (*env)->ReleaseStringUTFChars(env, filenameS, filename);
+    return (jlong) fd;
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_close
+  (JNIEnv *UNUSED(env), jobject UNUSED(obj), jlong fdL) {
+    return (jint) close((int) fdL);
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_EVIOCGABS
+  (JNIEnv *UNUSED(env), jobject UNUSED(obj), jint type) {
+    return (jint) EVIOCGABS((int) type);
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_ioctl
+  (JNIEnv *UNUSED(env), jobject UNUSED(obj), jlong fdL, jint request, jlong dataL) {
+    return ioctl((int) fdL, (int) request, asPtr(dataL));
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_errno
+  (JNIEnv *UNUSED(env), jobject UNUSED(obj)) {
+    return (jint) errno;
+}
+
+JNIEXPORT jstring JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_strerror
+  (JNIEnv *env, jobject UNUSED(obj), jint errnum) {
+    char *errChars = strerror(errnum);
+    return (*env)->NewStringUTF(env, errChars);
+}
+
+JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_dlopen
+  (JNIEnv *env, jobject UNUSED(obj), jstring filenameS, jint flag) {
+    const char *filename = (*env)->GetStringUTFChars(env, filenameS, NULL);
+    void *handle = dlopen(filename, (int) flag);
+    (*env)->ReleaseStringUTFChars(env, filenameS, filename);
+    return asJLong(handle);
+}
+
+JNIEXPORT jstring JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_dlerror
+  (JNIEnv *env, jobject UNUSED(obj)) {
+    char *errChars = dlerror();
+    return (*env)->NewStringUTF(env, errChars);
+}
+
+JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_dlsym
+  (JNIEnv *UNUSED(env), jobject UNUSED(obj), jlong handleL, jstring symbolS) {
+    const char *symbol = (*env)->GetStringUTFChars(env, symbolS, NULL);
+    void *handle = dlsym(asPtr(handleL), symbol);
+    (*env)->ReleaseStringUTFChars(env, symbolS, symbol);
+    return asJLong(handle);
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_dlclose
+  (JNIEnv *UNUSED(env), jobject UNUSED(obj), jlong handleL) {
+    return (jint) dlclose(asPtr(handleL));
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024FbVarScreenInfo_sizeof
+  (JNIEnv *UNUSED(env), jobject UNUSED(obj)) {
+    return (jint) sizeof(struct fb_var_screeninfo);
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024FbVarScreenInfo_getXRes
+  (JNIEnv *UNUSED(env), jclass UNUSED(cls), jlong p) {
+    return (jint) ((struct fb_var_screeninfo *) asPtr(p))->xres;
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024FbVarScreenInfo_getYRes
+  (JNIEnv *UNUSED(env), jclass UNUSED(cls), jlong p) {
+    return (jint) ((struct fb_var_screeninfo *) asPtr(p))->yres;
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024InputAbsInfo_sizeof
+  (JNIEnv *UNUSED(env), jobject UNUSED(obj)) {
+    return (jint) sizeof(struct input_absinfo);
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024InputAbsInfo_getValue
+  (JNIEnv *UNUSED(env), jclass UNUSED(cls), jlong p) {
+    return (jint) ((struct input_absinfo *) asPtr(p))->value;
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024InputAbsInfo_getMinimum
+  (JNIEnv *UNUSED(env), jclass UNUSED(cls), jlong p) {
+    return (jint) ((struct input_absinfo *) asPtr(p))->minimum;
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024InputAbsInfo_getMaximum
+  (JNIEnv *UNUSED(env), jclass UNUSED(cls), jlong p) {
+    return (jint) ((struct input_absinfo *) asPtr(p))->maximum;
+}
+
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024InputAbsInfo_getFuzz
+  (JNIEnv *UNUSED(env), jclass UNUSED(cls), jlong p) {
+    return (jint) ((struct input_absinfo *) asPtr(p))->fuzz;
+}
+
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024InputAbsInfo_getFlat
+  (JNIEnv *UNUSED(env), jclass UNUSED(cls), jlong p) {
+    return (jint) ((struct input_absinfo *) asPtr(p))->flat;
+}
+
+
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_monocle_linux_LinuxSystem_00024InputAbsInfo_getResolution
+  (JNIEnv *UNUSED(env), jclass UNUSED(cls), jlong p) {
+    return (jint) ((struct input_absinfo *) asPtr(p))->resolution;
+}