changeset 6047:0d5bcb3c0951

RT-33250: Adding Monocle, a new embedded Glass port with minimal native code Reviewed-by: ddhill
author Daniel Blaukopf <daniel.blaukopf@oracle.com>
date Wed, 08 Jan 2014 19:38:13 +0200
parents 6958ed0ddda5
children 56e532279c86
files buildSrc/armv6hf.gradle buildSrc/armv6sf.gradle buildSrc/x86egl.gradle modules/graphics/src/main/java/com/sun/glass/ui/monocle/EGL.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleApplication.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleClipboardDelegate.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleCursor.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleDnDClipboard.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonoclePixels.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonoclePlatformFactory.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleSystemClipboard.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleTimer.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleView.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleWindow.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleWindowManager.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativeCursor.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativePlatform.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativePlatformFactory.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativeScreen.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/NullCursor.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/headless/HeadlessPlatform.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/headless/HeadlessPlatformFactory.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/headless/HeadlessScreen.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/InputDevice.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/InputDeviceRegistry.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/MouseState.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/FBDevScreen.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/GetEvent.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/Input.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/KeyBits.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/LinuxInputDeviceRegistry.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxInputProcessor.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/LinuxPlatform.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxPlatformFactory.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxTouchProcessor.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/SysFS.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/Udev.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/UdevListener.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/omap/OMAPCursor.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/omap/OMAPPlatform.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/omap/OMAPPlatformFactory.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/omapx11/OMAPX11Platform.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/omapx11/OMAPX11PlatformFactory.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/util/C.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/util/IntSet.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11InputDeviceRegistry.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11Platform.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11PlatformFactory.java modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11Screen.java modules/graphics/src/main/native-glass/monocle/Monocle.h modules/graphics/src/main/native-glass/monocle/linux/Udev.c modules/graphics/src/main/native-glass/monocle/util/C.c modules/graphics/src/main/native-glass/monocle/x11/X11.c
diffstat 59 files changed, 6662 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/buildSrc/armv6hf.gradle	Tue Jan 07 10:52:41 2014 +0200
+++ b/buildSrc/armv6hf.gradle	Wed Jan 08 19:38:13 2014 +0200
@@ -235,6 +235,19 @@
 fb.com.sun.javafx.isEmbedded=true
 fb.glass.restrictWindowToScreen=true
 fb.com.sun.javafx.scene.control.skin.FXVK.cache=true
+monocle.glass.platform=Monocle
+monocle.prism.order=es2,sw
+monocle.prism.eglfb=true
+monocle.prism.lcdtext=false
+monocle.prism.maxvram=128m
+monocle.prism.targetvram=112m
+monocle.use.egl=true
+monocle.use.gles2=true
+monocle.embedded=eglfb
+monocle.com.sun.javafx.isEmbedded=true
+monocle.doNativeComposite=true
+monocle.com.sun.javafx.scene.control.skin.FXVK.cache=true
+monocle.prism.glDepthSize=0
 eglx11.glass.platform=Lens
 eglx11.glass.lens=eglx11
 eglx11.prism.order=es2
--- a/buildSrc/armv6sf.gradle	Tue Jan 07 10:52:41 2014 +0200
+++ b/buildSrc/armv6sf.gradle	Wed Jan 08 19:38:13 2014 +0200
@@ -241,6 +241,19 @@
 fb.com.sun.javafx.isEmbedded=true
 fb.glass.restrictWindowToScreen=true
 fb.com.sun.javafx.scene.control.skin.FXVK.cache=true
+monocle.glass.platform=Monocle
+monocle.prism.order=es2,sw
+monocle.prism.eglfb=true
+monocle.prism.lcdtext=false
+monocle.prism.maxvram=128m
+monocle.prism.targetvram=112m
+monocle.use.egl=true
+monocle.use.gles2=true
+monocle.embedded=eglfb
+monocle.com.sun.javafx.isEmbedded=true
+monocle.doNativeComposite=true
+monocle.com.sun.javafx.scene.control.skin.FXVK.cache=true
+monocle.prism.glDepthSize=0
 eglx11.glass.platform=Lens
 eglx11.glass.lens=eglx11
 eglx11.prism.order=es2
--- a/buildSrc/x86egl.gradle	Tue Jan 07 10:52:41 2014 +0200
+++ b/buildSrc/x86egl.gradle	Wed Jan 08 19:38:13 2014 +0200
@@ -167,6 +167,19 @@
 fb.com.sun.javafx.isEmbedded=true
 fb.glass.restrictWindowToScreen=true
 fb.com.sun.javafx.scene.control.skin.FXVK.cache=true
+monocle.glass.platform=Monocle
+monocle.prism.order=es2,sw
+monocle.prism.eglfb=true
+monocle.prism.lcdtext=false
+monocle.prism.maxvram=128m
+monocle.prism.targetvram=112m
+monocle.use.egl=true
+monocle.use.gles2=true
+monocle.embedded=eglfb
+monocle.com.sun.javafx.isEmbedded=true
+monocle.doNativeComposite=true
+monocle.com.sun.javafx.scene.control.skin.FXVK.cache=true
+monocle.prism.glDepthSize=0
 eglx11.glass.platform=Lens
 eglx11.glass.lens=eglx11
 eglx11.prism.order=es2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/EGL.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2014, 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;
+
+import java.lang.reflect.Field;
+import java.util.Formatter;
+
+/** Java wrapper for the EGL API */
+public class EGL {
+
+    public static final long EGL_DEFAULT_DISPLAY = 0l;
+    public static final long EGL_NO_CONTEXT = 0l;
+    public static final long EGL_NO_DISPLAY = 0l;
+    public static final long EGL_NO_SURFACE = 0l;
+    public static final int EGL_DONT_CARE = -1;
+    public static final int EGL_SUCCESS = 0x3000;
+    public static final int EGL_NOT_INITIALIZED = 0x3001;
+    public static final int EGL_BAD_ACCESS = 0x3002;
+    public static final int EGL_BAD_ALLOC = 0x3003;
+    public static final int EGL_BAD_ATTRIBUTE = 0x3004;
+    public static final int EGL_BAD_CONFIG = 0x3005;
+    public static final int EGL_BAD_CONTEXT = 0x3006;
+    public static final int EGL_BAD_CURRENT_SURFACE = 0x3007;
+    public static final int EGL_BAD_DISPLAY = 0x3008;
+    public static final int EGL_BAD_MATCH = 0x3009;
+    public static final int EGL_BAD_NATIVE_PIXMAP = 0x300A;
+    public static final int EGL_BAD_NATIVE_WINDOW = 0x300B;
+    public static final int EGL_BAD_PARAMETER = 0x300C;
+    public static final int EGL_BAD_SURFACE = 0x300D;
+    public static final int EGL_CONTEXT_LOST = 0x300E;
+    public static final int EGL_BUFFER_SIZE = 0x3020;
+    public static final int EGL_ALPHA_SIZE = 0x3021;
+    public static final int EGL_BLUE_SIZE = 0x3022;
+    public static final int EGL_GREEN_SIZE = 0x3023;
+    public static final int EGL_RED_SIZE = 0x3024;
+    public static final int EGL_DEPTH_SIZE = 0x3025;
+    public static final int EGL_STENCIL_SIZE = 0x3026;
+    public static final int EGL_CONFIG_CAVEAT = 0x3027;
+    public static final int EGL_CONFIG_ID = 0x3028;
+    public static final int EGL_LEVEL = 0x3029;
+    public static final int EGL_MAX_PBUFFER_HEIGHT = 0x302A;
+    public static final int EGL_MAX_PBUFFER_PIXELS = 0x302B;
+    public static final int EGL_MAX_PBUFFER_WIDTH = 0x302C;
+    public static final int EGL_NATIVE_RENDERABLE = 0x302D;
+    public static final int EGL_NATIVE_VISUAL_ID = 0x302E;
+    public static final int EGL_NATIVE_VISUAL_TYPE = 0x302F;
+    public static final int EGL_SAMPLES = 0x3031;
+    public static final int EGL_SAMPLE_BUFFERS = 0x3032;
+    public static final int EGL_SURFACE_TYPE = 0x3033;
+    public static final int EGL_TRANSPARENT_TYPE = 0x3034;
+    public static final int EGL_TRANSPARENT_BLUE_VALUE = 0x3035;
+    public static final int EGL_TRANSPARENT_GREEN_VALUE = 0x3036;
+    public static final int EGL_TRANSPARENT_RED_VALUE = 0x3037;
+    public static final int EGL_NONE = 0x3038;
+    public static final int EGL_BIND_TO_TEXTURE_RGB = 0x3039;
+    public static final int EGL_BIND_TO_TEXTURE_RGBA = 0x303A;
+    public static final int EGL_MIN_SWAP_INTERVAL = 0x303B;
+    public static final int EGL_MAX_SWAP_INTERVAL = 0x303C;
+    public static final int EGL_LUMINANCE_SIZE = 0x303D;
+    public static final int EGL_ALPHA_MASK_SIZE = 0x303E;
+    public static final int EGL_COLOR_BUFFER_TYPE = 0x303F;
+    public static final int EGL_RENDERABLE_TYPE = 0x3040;
+    public static final int EGL_MATCH_NATIVE_PIXMAP = 0x3041;
+    public static final int EGL_CONFORMANT = 0x3042;
+    public static final int EGL_SLOW_CONFIG = 0x3050;
+    public static final int EGL_NON_CONFORMANT_CONFIG = 0x3051;
+    public static final int EGL_TRANSPARENT_RGB = 0x3052;
+    public static final int EGL_RGB_BUFFER = 0x308E;
+    public static final int EGL_LUMINANCE_BUFFER = 0x308F;
+    public static final int EGL_NO_TEXTURE = 0x305C;
+    public static final int EGL_TEXTURE_RGB = 0x305D;
+    public static final int EGL_TEXTURE_RGBA = 0x305E;
+    public static final int EGL_TEXTURE_2D = 0x305F;
+    public static final int EGL_PBUFFER_BIT = 0x0001;
+    public static final int EGL_PIXMAP_BIT = 0x0002;
+    public static final int EGL_WINDOW_BIT = 0x0004;
+    public static final int EGL_VG_COLORSPACE_LINEAR_BIT = 0x0020;
+    public static final int EGL_VG_ALPHA_FORMAT_PRE_BIT = 0x0040;
+    public static final int EGL_MULTISAMPLE_RESOLVE_BOX_BIT = 0x0200;
+    public static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
+    public static final int EGL_OPENGL_ES_BIT = 0x0001;
+    public static final int EGL_OPENVG_BIT = 0x0002;
+    public static final int EGL_OPENGL_ES = 2;
+    public static final int EGL_OPENGL_BIT = 0x0008;
+    public static final int EGL_VENDOR = 0x3053;
+    public static final int EGL_VERSION = 0x3054;
+    public static final int EGL_EXTENSIONS = 0x3055;
+    public static final int EGL_CLIENT_APIS = 0x308D;
+    public static final int EGL_HEIGHT = 0x3056;
+    public static final int EGL_WIDTH = 0x3057;
+    public static final int EGL_LARGEST_PBUFFER = 0x3058;
+    public static final int EGL_TEXTURE_FORMAT = 0x3080;
+    public static final int EGL_TEXTURE_TARGET = 0x3081;
+    public static final int EGL_MIPMAP_TEXTURE = 0x3082;
+    public static final int EGL_MIPMAP_LEVEL = 0x3083;
+    public static final int EGL_RENDER_BUFFER = 0x3086;
+    public static final int EGL_VG_COLORSPACE = 0x3087;
+    public static final int EGL_VG_ALPHA_FORMAT = 0x3088;
+    public static final int EGL_HORIZONTAL_RESOLUTION = 0x3090;
+    public static final int EGL_VERTICAL_RESOLUTION = 0x3091;
+    public static final int EGL_PIXEL_ASPECT_RATIO = 0x3092;
+    public static final int EGL_SWAP_BEHAVIOR = 0x3093;
+    public static final int EGL_MULTISAMPLE_RESOLVE = 0x3099;
+    public static final int EGL_BACK_BUFFER = 0x3084;
+    public static final int EGL_SINGLE_BUFFER = 0x3085;
+    public static final int EGL_VG_COLORSPACE_sRGB = 0x3089;
+    public static final int EGL_VG_COLORSPACE_LINEAR = 0x308A;
+    public static final int EGL_VG_ALPHA_FORMAT_NONPRE = 0x308B;
+    public static final int EGL_VG_ALPHA_FORMAT_PRE = 0x308C;
+    public static final int EGL_DISPLAY_SCALING = 10000;
+    public static final int EGL_UNKNOWN = -1;
+    public static final int EGL_BUFFER_PRESERVED = 0x3094;
+    public static final int EGL_BUFFER_DESTROYED = 0x3095;
+    public static final int EGL_OPENVG_IMAGE = 0x3096;
+    public static final int EGL_CONTEXT_CLIENT_TYPE = 0x3097;
+    public static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+    public static final int EGL_MULTISAMPLE_RESOLVE_DEFAULT = 0x309A;
+    public static final int EGL_MULTISAMPLE_RESOLVE_BOX = 0x309B;
+    public static final int EGL_OPENGL_ES_API = 0x30A0;
+    public static final int EGL_OPENVG_API = 0x30A1;
+    public static final int EGL_OPENGL_API = 0x30A2;
+    public static final int EGL_DRAW = 0x3059;
+    public static final int EGL_READ = 0x305A;
+    public static final int EGL_CORE_NATIVE_ENGINE = 0x305B;
+
+    public static native void loadFunctions(long dlHandle);
+
+    public static native boolean eglBindAPI(int api);
+
+    public static native boolean eglChooseConfig(
+            long eglDisplay,
+            long eglAttrs,
+            long[] eglConfigs,
+            int[] configCount);
+
+    public static native long eglContextFromConfig(long eglDisplay, long eglConfig);
+
+    public static native long eglCreateContext(
+            long eglDisplay,
+            long eglConfig,
+            long shareContext,
+            int[] attribs);
+
+    public static native long eglCreateWindowSurface(
+            long eglDisplay,
+            long eglConfig,
+            long nativeWindow,
+            int[] attribs);
+
+    public static native boolean eglDestroyContext(long eglDisplay, long eglContext);
+
+    public static native boolean eglGetConfigAttrib(
+            long eglDisplay,
+            long eglConfig,
+            int attrib,
+            int[] value);
+
+    public static native long eglGetDisplay(long nativeDisplay);
+
+    public static native int eglGetError();
+
+    public static native boolean eglInitialize(long eglDisplay, int[] major,
+                                        int[] minor);
+
+    public static native boolean eglMakeCurrent(
+            long eglDisplay,
+            long eglDrawSurface,
+            long eglReadSurface,
+            long eglContext);
+
+    public static native String eglQueryString(long eglDisplay, int name);
+
+    public static native String eglQueryVersion(long eglDisplay, int versionType);
+
+    public static native boolean eglSwapBuffers(long eglDisplay, long eglSurface);
+
+    /** Convert an EGL error code such as EGL_BAD_CONTEXT to a string
+     * representation.
+     * @param errorCode the EGL error code
+     * @return the constant name of the error code. If errorCode cannot be
+     * matched to an EGL error, a string representation of the error code's
+     * value is returned.
+     */
+    public static String eglErrorToString(int errorCode) {
+        if (errorCode >= 0x3000 && errorCode < 0x3020) {
+            for (Field field : EGL.class.getFields()) {
+                try {
+                    if (field.getName().startsWith("EGL_")
+                            && field.getType() == Integer.TYPE
+                            && field.getInt(null) == errorCode) {
+                        return field.getName();
+                    }
+                } catch (IllegalAccessException e) {
+                }
+            }
+        }
+        return new Formatter()
+                .format("0x%04x", errorCode & 0xffff)
+                .out()
+                .toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleApplication.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2010, 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;
+
+import com.sun.glass.ui.Application;
+import com.sun.glass.ui.CommonDialogs.ExtensionFilter;
+import com.sun.glass.ui.CommonDialogs.FileChooserResult;
+import com.sun.glass.ui.Cursor;
+import com.sun.glass.ui.Pixels;
+import com.sun.glass.ui.Robot;
+import com.sun.glass.ui.Screen;
+import com.sun.glass.ui.Size;
+import com.sun.glass.ui.Timer;
+import com.sun.glass.ui.View;
+import com.sun.glass.ui.Window;
+import com.sun.glass.ui.monocle.input.InputDevice;
+import javafx.collections.SetChangeListener;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+
+final class MonocleApplication extends Application {
+
+    private final NativePlatform platform =
+            NativePlatformFactory.getNativePlatform();
+    private final ExecutorService executor = platform.getExecutor();
+
+    /** Bit to indicate that a device has touch support */
+    private static final int DEVICE_TOUCH = 0;
+    /** Bit to indicate that a device has multitouch support */
+    private static final int DEVICE_MULTITOUCH = 1;
+    /** Bit to indicate that a device has relative motion pointer support */
+    private static final int DEVICE_POINTER = 2;
+    /** Bit to indicate that a device has arrow keys and a select key */
+    private static final int DEVICE_5WAY = 3;
+    /** Bit to indicate that a device has a full PC keyboard */
+    private static final int DEVICE_PC_KEYBOARD = 4;
+    /** Largest bit used in device capability bitmasks */
+    private static final int DEVICE_MAX = 4;
+    /** A running count of the numbers of devices with each device capability */
+    private int[] deviceFlags = new int[DEVICE_MAX + 1];
+
+    MonocleApplication() {
+        platform.getInputDeviceRegistry().getInputDevices().addListener(
+                new SetChangeListener<InputDevice>() {
+            @Override
+            public void onChanged(
+                    Change<? extends InputDevice> change) {
+                if (change.wasAdded()) {
+                    InputDevice device = change.getElementAdded();
+                    if (device.isTouch()) {
+                        deviceFlags[DEVICE_TOUCH] ++;
+                    }
+                    if (device.isMultiTouch()) {
+                        deviceFlags[DEVICE_MULTITOUCH] ++;
+                    }
+                    if (device.isRelative()) {
+                        deviceFlags[DEVICE_POINTER] ++;
+                    }
+                    if (device.isFullKeyboard()) {
+                        deviceFlags[DEVICE_PC_KEYBOARD] ++;
+                    }
+                    if (device.is5Way()) {
+                        deviceFlags[DEVICE_5WAY] ++;
+                    }
+                } else if (change.wasRemoved()) {
+                    InputDevice device = change.getElementRemoved();
+                    if (device.isTouch()) {
+                        deviceFlags[DEVICE_TOUCH] --;
+                    }
+                    if (device.isMultiTouch()) {
+                        deviceFlags[DEVICE_MULTITOUCH] --;
+                    }
+                    if (device.isRelative()) {
+                        deviceFlags[DEVICE_POINTER] --;
+                    }
+                    if (device.isFullKeyboard()) {
+                        deviceFlags[DEVICE_PC_KEYBOARD] --;
+                    }
+                    if (device.is5Way()) {
+                        deviceFlags[DEVICE_5WAY] --;
+                    }
+                }
+            }
+        });
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+            @Override public void run() {
+                platform.shutdown();
+            }
+        });
+    }
+
+    @Override
+    protected void runLoop(Runnable launchable) {
+        Application.setEventThread(platform.getExecutorThread());
+        executor.submit(launchable);
+    }
+
+    @Override
+    protected void _invokeAndWait(Runnable runnable) {
+        try {
+            executor.submit(new Callable<Void>() {
+                public Void call() {
+                    runnable.run();
+                    return null;
+                }
+            }).get();
+        } catch (InterruptedException e) {
+            // we are shutting down
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    protected void _invokeLater(Runnable runnable) {
+        executor.submit(runnable);
+    }
+
+    @Override
+    protected Object _enterNestedEventLoop() {
+        Thread.dumpStack();
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void _leaveNestedEventLoop(Object retValue) {
+        Thread.dumpStack();
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Window createWindow(Window owner, Screen screen, int styleMask) {
+        return new MonocleWindow(owner, screen, styleMask);
+    }
+
+    @Override
+    public Window createWindow(long parent) {
+        return new MonocleWindow(parent);
+    }
+
+    @Override
+    public View createView() {
+        return new MonocleView();
+    }
+
+    @Override
+    public Cursor createCursor(int type) {
+        return new MonocleCursor(type);
+    }
+
+    @Override
+    public Cursor createCursor(int x, int y, Pixels pixels) {
+        return new MonocleCursor(x, y, pixels);
+    }
+
+    @Override
+    protected void staticCursor_setVisible(boolean visible) {
+        NativeCursor cursor = NativePlatformFactory.getNativePlatform().getCursor();
+        cursor.setVisibility(visible);
+    }
+
+    @Override
+    protected Size staticCursor_getBestSize(int width, int height) {
+        NativeCursor cursor = NativePlatformFactory.getNativePlatform().getCursor();
+        return cursor.getBestSize();
+    }
+
+    @Override
+    public Pixels createPixels(int width, int height, ByteBuffer data) {
+        return new MonoclePixels(width, height, data);
+    }
+
+    @Override
+    public Pixels createPixels(int width, int height, IntBuffer data) {
+        return new MonoclePixels(width, height, data);
+    }
+
+    @Override
+    public Pixels createPixels(int width, int height, IntBuffer data,
+                               float scale) {
+        return new MonoclePixels(width, height, data, scale);
+    }
+
+    @Override
+    protected int staticPixels_getNativeFormat() {
+        return platform.getScreen().getNativeFormat();
+    }
+
+    @Override
+    public Robot createRobot() {
+        Thread.dumpStack();
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected double staticScreen_getVideoRefreshPeriod() {
+        return 0.0;
+    }
+
+    @Override
+    protected Screen[] staticScreen_getScreens() {
+        Screen screen = null;
+        try {
+            NativeScreen ns = platform.getScreen();
+            Constructor c = AccessController.doPrivileged(
+                    new PrivilegedAction<Constructor>() {
+                        @Override
+                        public Constructor run() {
+                            try {
+                                Constructor c = Screen.class.getDeclaredConstructor(
+                                        Long.TYPE,
+                                        Integer.TYPE,
+                                        Integer.TYPE, Integer.TYPE,
+                                        Integer.TYPE, Integer.TYPE,
+                                        Integer.TYPE, Integer.TYPE,
+                                        Integer.TYPE, Integer.TYPE,
+                                        Integer.TYPE, Integer.TYPE, Float.TYPE);
+                                c.setAccessible(true);
+                                return c;
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                                return null;
+                            }
+                        }
+                    });
+            if (c != null) {
+                screen = (Screen) c.newInstance(
+                        1l, // dummy native pointer;
+                        ns.getDepth(),
+                        0, 0, ns.getWidth(), ns.getHeight(),
+                        0, 0, ns.getWidth(), ns.getHeight(),
+                        ns.getDPI(), ns.getDPI(),
+                        1.0f);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } catch (UnsatisfiedLinkError e) {
+            e.printStackTrace();
+        }
+        return new Screen[] { screen };
+    }
+
+    @Override
+    public Timer createTimer(Runnable runnable) {
+        return new MonocleTimer(runnable);
+    }
+
+    @Override
+    protected int staticTimer_getMinPeriod() {
+        return MonocleTimer.getMinPeriod_impl();
+    }
+
+    @Override
+    protected int staticTimer_getMaxPeriod() {
+        return MonocleTimer.getMaxPeriod_impl();
+    }
+
+    public boolean hasWindowManager() {
+        return false;
+    }
+
+    @Override
+    protected FileChooserResult staticCommonDialogs_showFileChooser(
+            Window owner, String folder, String filename, String title,
+            int type, boolean multipleMode,
+            ExtensionFilter[] extensionFilters,
+            int defaultFilterIndex) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected File staticCommonDialogs_showFolderChooser(Window owner,
+                                                         String folder,
+                                                         String title) {
+        Thread.dumpStack();
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected long staticView_getMultiClickTime() {
+        return MonocleView._getMultiClickTime();
+    }
+
+    @Override
+    protected int staticView_getMultiClickMaxX() {
+        return MonocleView._getMultiClickMaxX();
+    }
+
+    @Override
+    protected int staticView_getMultiClickMaxY() {
+        return MonocleView._getMultiClickMaxY();
+    }
+
+    @Override
+    protected boolean _supportsTransparentWindows() {
+        return true;
+    }
+
+    @Override
+    protected boolean _supportsUnifiedWindows() {
+        return false;
+    }
+
+    @Override
+    public boolean hasTwoLevelFocus() {
+        return deviceFlags[DEVICE_PC_KEYBOARD] == 0 && deviceFlags[DEVICE_5WAY] > 0;
+    }
+
+    @Override
+    public boolean hasVirtualKeyboard() {
+        return deviceFlags[DEVICE_PC_KEYBOARD] == 0 && deviceFlags[DEVICE_TOUCH] > 0;
+    }
+
+    @Override
+    public boolean hasTouch() {
+        return deviceFlags[DEVICE_TOUCH] > 0;
+    }
+
+    @Override
+    public boolean hasMultiTouch() {
+        return deviceFlags[DEVICE_MULTITOUCH] > 0;
+    }
+
+    @Override
+    public boolean hasPointer() {
+        return deviceFlags[DEVICE_POINTER] > 0;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleClipboardDelegate.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, 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;
+
+import com.sun.glass.ui.Clipboard;
+import com.sun.glass.ui.delegate.ClipboardDelegate;
+
+final class MonocleClipboardDelegate implements ClipboardDelegate {
+
+    @Override
+    public Clipboard createClipboard(String clipboardName) {
+        // Currently only DnD clipboards are supported.
+        // System clipboards will probably will not be supported as embedded
+        // platforms do not support this functionality
+        // We might support Selection clipboard in the future, but other systems
+        // do not seem to use it at this point
+        if (Clipboard.DND.equals(clipboardName)) {
+            return new MonocleDnDClipboard();
+        } else if (Clipboard.SYSTEM.equals(clipboardName)) {
+            return new MonocleSystemClipboard();
+        } else {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleCursor.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+package com.sun.glass.ui.monocle;
+
+import com.sun.glass.ui.Application;
+import com.sun.glass.ui.Cursor;
+import com.sun.glass.ui.Pixels;
+
+final class MonocleCursor extends Cursor {
+    byte[] image;
+    int hotspotX;
+    int hotspotY;
+
+    protected MonocleCursor(int type) {
+        super(type);
+        image = getImage(type);
+        hotspotX = 0;
+        hotspotY = 0;
+    }
+
+    protected MonocleCursor(int x, int y, Pixels pixels) {
+        super(x, y, pixels);
+    }
+
+    void applyCursor() {
+        int type = getType();
+        if (type == CURSOR_NONE) {
+            // CURSOR_NONE is mapped to setVisible(false) and will be registered
+            // in MonocleApplication as a preference to not show the cursor.
+            ((MonocleApplication) Application.GetApplication())
+                    .staticCursor_setVisible(false);
+        } else {
+            NativeCursor cursor = NativePlatformFactory.getNativePlatform().getCursor();
+            cursor.setImage(image);
+            ((MonocleApplication) Application.GetApplication())
+                    .staticCursor_setVisible(true);
+        }
+    }
+
+    @Override
+    protected long _createCursor(int x, int y, Pixels pixels) {
+        hotspotX = x;
+        hotspotY = y;
+        image = pixels.asByteBuffer().array();
+        return 1l;
+    }
+
+    private static byte[] getImage(int cursorType) {
+        // TODO: use the correct cursor image and load it more efficiently
+        // TODO: this way of storing the cursor doesn't even work because it
+        // mixes up UTF-16 and UTF-8 encodings
+        String s =
+            "\0\0\0\324\0\0\0\25\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0"
+            + "\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\0\0\0\324\0\0\0\25\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+            + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377"
+            + "\314\314\314\377\0\0\0\324\0\0\0\25\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\0\0\0\0\0"
+            + "\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\377\377\314\314\314\377"
+            + "\0\0\0\324\0\0\0\25\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0"
+            + "\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377\314\314\314\377\0\0\0\324"
+            + "\0\0\0\25\377\377\377\0\377\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0"
+            + "\377\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\314\314\314\377\0\0\0\324\0\0\0\25"
+            + "\377\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
+            + "\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\314\314\314\377\0\0\0\324\0\0\0\25"
+            + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\377\377"
+            + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\314\314\314\377\0\0\0\324\0\0\0\25\0\0\0\0"
+            + "\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377"
+            + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\314\314\314\377\0\0\0\324\0\0\0\25\0\0\0\0"
+            + "\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\377\377\376\376\376\377"
+            + "\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\323\0\0\0\25\0\0\0\0\377\377\377\0"
+            + "\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\377\377\311\311\311\377\237\237\237\377\376\376\376\377"
+            + "\52\52\52\377\0\0\0\100\377\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0"
+            + "\377\377\377\0\0\0\0\377\321\321\321\377\0\0\0\324\0\0\0\346\352\352\352\377\315\315\315\377\0\0\0\260"
+            + "\377\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
+            + "\0\0\0\377\1\1\1\342\0\0\0\34\0\0\0\201\266\266\266\377\366\366\366\377\25\25\25\376\0\0\0\52\0\0\0\0"
+            + "\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\352\0\0\0\44\0\0\0\0"
+            + "\0\0\0\34\20\20\20\373\364\364\364\377\301\301\301\377\0\0\0\232\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0"
+            + "\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\62\0\0\0\0\0\0\0\0\377\377\377\0\0\0\0\257\312\312\312\377"
+            + "\305\305\305\377\0\0\0\366\0\0\0\20\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0"
+            + "\377\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\110\1\1\1\377\0\0\0\266\0\0\0\72\0\0\0\0\0\0\0\0"
+            + "\0\0\0\0\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0";
+        return s.getBytes();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleDnDClipboard.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+package com.sun.glass.ui.monocle;
+
+import com.sun.glass.ui.Clipboard;
+import com.sun.glass.ui.SystemClipboard;
+
+import java.util.HashMap;
+
+final class MonocleDnDClipboard extends SystemClipboard {
+
+    public MonocleDnDClipboard() {
+        super(Clipboard.DND);
+    }
+
+    /**
+     * Should be called when drag operation completed by the 'system'
+     *
+     * @param action mask of actions from Clipboard
+     */
+    public void actionPerformed(int action) {
+        super.actionPerformed(action);
+    }
+
+    protected  boolean isOwner() {
+        return true;
+    }
+    /**
+     * Here the magic happens.
+     * When this method is called all input events should be grabbed and
+     * appropriate drag notifications should be sent instead of regular input
+     * events
+     */
+    protected  void pushToSystem(HashMap<String, Object> cacheData, int supportedActions) {
+        // TODO: implement drag and nested loops in MonocleApplication
+        // MonocleApplication app = (MonocleApplication)Application.GetApplication();
+        // app.notifyDragStart();
+        // app.enterDnDEventLoop();
+        // The loop is exited in LensApplication.LensDragEvent.dispatch()
+        actionPerformed(Clipboard.ACTION_COPY_OR_MOVE);
+    }
+
+    protected void pushTargetActionToSystem(int actionDone) {
+    }
+
+    protected  Object popFromSystem(String mimeType) {
+        return null;
+    }
+    protected  int supportedSourceActionsFromSystem() {
+        return Clipboard.ACTION_COPY_OR_MOVE;
+    }
+
+    protected  String[] mimesFromSystem() {
+        return new String[0];
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonoclePixels.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+package com.sun.glass.ui.monocle;
+
+import com.sun.glass.ui.Pixels;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+final class MonoclePixels extends Pixels {
+
+    protected MonoclePixels(int width, int height, ByteBuffer data) {
+        super(width, height, data);
+    }
+
+    protected MonoclePixels(int width, int height, IntBuffer data) {
+        super(width, height, data);
+    }
+
+    protected MonoclePixels(int width, int height, IntBuffer data, float scale) {
+        super(width, height, data, scale);
+    }
+
+
+    private void _copyPixels(Buffer dst, Buffer src, int size) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override protected void _fillDirectByteBuffer(ByteBuffer bb) {
+        if (this.bytes != null) {
+            this.bytes.rewind();
+            if (this.bytes.isDirect()) {
+                _copyPixels(bb, this.bytes, getWidth() * getHeight());
+            } else {
+                bb.put(this.bytes);
+            }
+            this.bytes.rewind();
+        } else {
+            this.ints.rewind();
+            if (this.ints.isDirect()) {
+                _copyPixels(bb, this.ints, getWidth() * getHeight());
+            } else {
+                for (int i = 0; i < this.ints.capacity(); i++) {
+                    int data = this.ints.get();
+                    bb.put((byte)((data) & 0xff));
+                    bb.put((byte)((data >> 8) & 0xff));
+                    bb.put((byte)((data >> 16) & 0xff));
+                    bb.put((byte)((data >> 24) & 0xff));
+                }
+            }
+            this.ints.rewind();
+        }
+        bb.rewind();
+    }
+
+    @Override protected void _attachInt(long nativeWindowPointer, int w, int h,
+                                        IntBuffer ints, int[] array, int offset) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override protected void _attachByte(long ptr, int w, int h, ByteBuffer bytes,
+                                         byte[] array, int offset) {
+
+        throw new UnsupportedOperationException("not implemented");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonoclePlatformFactory.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010, 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;
+
+import com.sun.glass.ui.Application;
+import com.sun.glass.ui.Menu;
+import com.sun.glass.ui.MenuBar;
+import com.sun.glass.ui.MenuItem;
+import com.sun.glass.ui.PlatformFactory;
+import com.sun.glass.ui.Window;
+import com.sun.glass.ui.accessible.AccessibleBaseProvider;
+import com.sun.glass.ui.accessible.AccessibleRoot;
+import com.sun.glass.ui.delegate.ClipboardDelegate;
+import com.sun.glass.ui.delegate.MenuBarDelegate;
+import com.sun.glass.ui.delegate.MenuDelegate;
+import com.sun.glass.ui.delegate.MenuItemDelegate;
+
+public class MonoclePlatformFactory extends PlatformFactory {
+
+    @Override
+    public Application createApplication() {
+        return new MonocleApplication();
+    }
+
+    @Override
+    public AccessibleRoot createAccessibleRoot(Object node, Window window) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public AccessibleBaseProvider createAccessibleProvider(Object node) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public MenuBarDelegate createMenuBarDelegate(MenuBar menubar) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public MenuDelegate createMenuDelegate(Menu menu) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public MenuItemDelegate createMenuItemDelegate(MenuItem menuItem) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ClipboardDelegate createClipboardDelegate() {
+        return new MonocleClipboardDelegate();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleSystemClipboard.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package com.sun.glass.ui.monocle;
+
+import com.sun.glass.ui.Clipboard;
+import com.sun.glass.ui.SystemClipboard;
+
+import java.util.HashMap;
+
+/** There is no system clipboard on embedded Linux systems using a
+ * framebuffer. For X11 and Android a different implementation will
+ * be needed. */
+final class MonocleSystemClipboard extends SystemClipboard {
+
+    public MonocleSystemClipboard() {
+        super(Clipboard.SYSTEM);
+    }
+
+    protected boolean isOwner() {
+        return true;
+    }
+
+    protected void pushToSystem(HashMap<String, Object> cacheData,
+                                int supportedActions) {
+    }
+
+    protected void pushTargetActionToSystem(int actionDone) {
+    }
+    protected Object popFromSystem(String mimeType) {
+        return null;
+    }
+
+    protected int supportedSourceActionsFromSystem() {
+        return Clipboard.ACTION_NONE;
+    }
+
+    protected String[] mimesFromSystem() {
+        return new String[0];
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleTimer.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, 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;
+
+import com.sun.glass.ui.Timer;
+
+/**
+ * Monocle implementation class for Timer.
+ */
+final class MonocleTimer extends Timer {
+    static java.util.Timer timer;
+    private java.util.TimerTask task;
+
+    protected MonocleTimer(final Runnable runnable) {
+        super(runnable);
+    }
+
+    static int getMinPeriod_impl() {
+        return 0;
+    }
+
+    static int getMaxPeriod_impl() {
+        return 1000000;
+    }
+
+    @Override protected long _start(final Runnable runnable, int period) {
+        if (timer == null) {
+            timer = new java.util.Timer(true);
+        }
+
+        task = new java.util.TimerTask() {
+
+            @Override
+            public void run() {
+                runnable.run();
+            }
+        };
+
+        timer.schedule(task, 0, (long)period);
+        return 1; // need something non-zero to denote success.
+    }
+
+    @Override protected long _start(Runnable runnable) {
+        throw new RuntimeException("vsync timer not supported");
+    }
+
+    @Override protected void _stop(long timer) {
+        if (task != null) {
+            task.cancel();
+            task = null;
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleView.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,210 @@
+/*
+ * 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.
+ */
+
+package com.sun.glass.ui.monocle;
+
+import com.sun.glass.events.ViewEvent;
+import com.sun.glass.ui.Pixels;
+import com.sun.glass.ui.View;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.util.Map;
+
+public final class MonocleView extends View {
+
+    MonocleView() {
+    }
+
+    // Constants
+    private static long multiClickTime =  500;
+    private static int multiClickMaxX = 20;
+    private static int multiClickMaxY = 20;
+
+    // view variables
+    private int x;
+    private int y;
+
+    protected static long _getMultiClickTime() {
+        return multiClickTime;
+    }
+
+    protected static int _getMultiClickMaxX() {
+        return multiClickMaxX;
+    }
+
+    protected static int _getMultiClickMaxY() {
+        return multiClickMaxY;
+    }
+
+    @Override
+    protected void _enableInputMethodEvents(long ptr, boolean enable) {
+    }
+
+    @Override
+    protected long _getNativeView(long ptr) {
+        return ptr;
+    }
+
+    @Override
+    protected int _getX(long ptr) {
+        return x;
+    }
+
+    @Override
+    protected int _getY(long ptr) {
+        return y;
+    }
+
+
+
+    @Override
+    protected void _scheduleRepaint(long ptr) {
+    }
+
+
+
+    @Override protected void _uploadPixels(long nativeViewPtr, Pixels pixels) {
+        if (getWindow() != null) {
+            NativeScreen screen =
+                    NativePlatformFactory.getNativePlatform().getScreen();
+            screen.uploadPixels(pixels.asByteBuffer(), // TODO: asByteBuffer is inefficient
+                                x, y,
+                                pixels.getWidth(), pixels.getHeight());
+        }
+    }
+
+    /**
+     * Events
+     */
+
+    public void _notifyMove(int x, int y) {
+        this.x = x;
+        this.y = y;
+        notifyView(ViewEvent.MOVE);
+    }
+
+    public void _notifyKey(int type, int keyCode, char[] keyChars,
+                              int modifiers) {
+        notifyKey(type, keyCode, keyChars, modifiers);
+    }
+
+    public void _notifyMouse(int type, int button,
+                                int x, int y, int xAbs, int yAbs, int modifiers,
+                                boolean isPopupTrigger, boolean isSynthesized) {
+        notifyMouse(type, button, x, y, xAbs, yAbs, modifiers, isPopupTrigger,
+                    isSynthesized);
+    }
+
+    public void _notifyScroll(int x, int y, int xAbs, int yAbs,
+                                 double deltaX, double deltaY, int modifiers,
+                                 int lines, int chars,
+                                 int defaultLines, int defaultChars,
+                                 double xMultiplier, double yMultiplier) {
+        notifyScroll(x, y, xAbs, yAbs, deltaX, deltaY,
+                     modifiers, lines, chars,
+                     defaultLines, defaultChars, xMultiplier, yMultiplier);
+    }
+
+    protected void _notifyRepaint(int x, int y, int width, int height) {
+        notifyRepaint(x, y, width, height);
+    }
+
+    protected void _notifyResize(int width, int height) {
+        notifyResize(width, height);
+    }
+
+    protected void _notifyViewEvent(int viewEvent) {
+        notifyView(viewEvent);
+    }
+
+    //DnD
+    protected void _notifyDragEnter(int x, int y, int absx, int absy, int recommendedDropAction) {
+        notifyDragEnter(x, y, absx, absy, recommendedDropAction);
+    }
+    protected void _notifyDragLeave() {
+        notifyDragLeave();
+    }
+    protected void _notifyDragDrop(int x, int y, int absx, int absy, int recommendedDropAction) {
+        notifyDragDrop(x, y, absx, absy, recommendedDropAction);
+    }
+    protected void _notifyDragOver(int x, int y, int absx, int absy, int recommendedDropAction) {
+        notifyDragOver(x, y, absx, absy, recommendedDropAction);
+    }
+
+    //Menu event - i.e context menu hint (usually mouse right click) 
+    protected void _notifyMenu(int x, int y, int xAbs, int yAbs, boolean isKeyboardTrigger) {
+        notifyMenu(x, y, xAbs, yAbs, isKeyboardTrigger);
+    }
+
+    @Override
+    protected long _create(Map caps) {
+        return 1l;
+    }
+
+    @Override
+    protected void _setParent(long ptr, long parentPtr) {
+    }
+
+    @Override
+    protected boolean _close(long ptr) {
+        return true;
+    }
+
+    @Override
+    protected boolean _enterFullscreen(long ptr, boolean animate,
+                                       boolean keepRatio,
+                                       boolean hideCursor) {
+        return true;
+    }
+
+    @Override
+    protected void _exitFullscreen(long ptr, boolean animate) {
+    }
+
+    @Override
+    public String toString() {
+        return "MonocleView["
+                + x + "," + y
+                + "+" + getWidth() + "x" + getHeight()
+                + "]";
+    }
+
+    /**
+    * Assuming this is used to lock the surface for painting
+    */
+    @Override
+    protected void _begin(long ptr) {
+    }
+
+    /**
+     * Assuming this is used to unlock the surface after painting is
+     * done
+     */
+    @Override
+    protected  void _end(long ptr) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleWindow.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,394 @@
+/*
+ * 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.
+ */
+
+package com.sun.glass.ui.monocle;
+
+import com.sun.glass.events.WindowEvent;
+import com.sun.glass.ui.Cursor;
+import com.sun.glass.ui.Pixels;
+import com.sun.glass.ui.Screen;
+import com.sun.glass.ui.View;
+import com.sun.glass.ui.Window;
+
+public final class MonocleWindow extends Window {
+
+    private int id;
+
+    protected MonocleWindow(Window owner, Screen screen, int styleMask) {
+        super(owner, screen, styleMask);
+    }
+
+    protected MonocleWindow(long parent) {
+        super(parent);
+    }
+
+    @Override
+    protected void _toFront(long ptr) {
+        MonocleWindowManager.getInstance().toFront(this);
+    }
+
+    @Override
+    protected void _toBack(long ptr) {
+        MonocleWindowManager.getInstance().toBack(this);
+
+    }
+
+    /**
+     *
+     * w/h is the total window width/height including all its
+     * decorations (e.g. title bar). cw/ch is the "client", or
+     * interior width/height. Negative values for w/h/cw/ch are
+     * treated as "not set". For example: setBounds(x, y, xSet,
+     * ySet, 800, 600, -1, -1) will make the window 800x600 pixels.
+     * The client area available for drawing will be smaller, e.g.
+     * 792x580 - it depends on the window decorations on different
+     * platforms. setBounds(x, y, xSet, ySet, -1, -1, 800, 600) will
+     * make the window client size to be 800x600 pixels. The area
+     * for drawing (FX scene size) will be exactly 800x600, but the
+     * total window size including decorations will be slightly
+     * bigger. For undecorated windows w/h and cw/ch are obviously
+     * the same.
+     *
+     * As this is a void function the native code should trigger an
+     * event to notify the system on actual change
+     *
+     */
+    @Override
+    protected void _setBounds(long nativeWindowPointer,
+                              int x, int y, boolean xSet, boolean ySet,
+                              int w, int h, int cw, int ch,
+                              float xGravity, float yGravity) {
+
+        //calculated window dimensions
+        int width;
+        int height;
+
+        //is new window size is the content size or the window size
+        //this required for platforms that support decorations.
+        //if isContentSize == true - width & height are
+        //the window size w/o decorations
+        boolean isContentSize = false;
+
+        //if true window position is also need to be update, else x&y are
+        //to be ignored
+        boolean  needToUpdatePosition = xSet || ySet;
+
+        //if false, only move window
+        boolean needResize = false;
+
+        if (!xSet && !ySet && w < 0 && h < 0 && cw < 0 && ch < 0) {
+            //nothing to do, return
+            return;
+        }
+
+        if (needToUpdatePosition) {
+            if (!xSet) {
+                //no explicit request to change x, get default
+                x = getX();
+            }
+
+            if (!ySet) {
+                //no explicit request to change y, get default
+                y = getY();
+            }
+        }
+
+        if (w > 0) {
+            //window width surpass window content width (cw)
+            width = w;
+            needResize = true;
+        } else if (cw > 0) {
+            //content width changed
+            width = cw;
+            isContentSize = true;
+            needResize = true;
+        } else {
+            //no explicit request to change width, get default
+            width = getWidth();
+        }
+
+        if (h > 0) {
+            //window height surpass window content height(ch)
+            height = h;
+            needResize = true;
+        } else if (cw > 0) {
+            //content height changed
+            height = ch;
+            isContentSize = true;
+            needResize = true;
+        } else {
+            //no explicit request to change height, get default
+            height = getHeight();
+        }
+
+
+        //perform actions
+        boolean windowHasBeenUpdated = false;
+        needResize |= isContentSize;
+
+        //handle resize if needed
+        if (needResize &&
+            (getWidth() != width || getHeight() != height)) {
+
+            notifyResize(WindowEvent.RESIZE, width, height);
+
+            windowHasBeenUpdated = true;
+
+        }
+
+        //handle move if needed
+        if (needToUpdatePosition && 
+            (getX() != x || getY() != y)) {
+            notifyMove(x, y);       
+
+            windowHasBeenUpdated = true;
+
+            //TODO: do we need repaints?
+            //lens_wm_repaint(env, window);
+        }
+
+    }
+
+    //creates the native window
+    @Override
+    protected long _createWindow(long NativeWindow, long NativeScreen,
+                                 int mask) {
+        id = MonocleWindowManager.getInstance().addWindow(this);
+        return id;
+    }
+
+    @Override
+    protected long _createChildWindow(long parent) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected boolean _close(long nativeWindowPointer) {
+        return MonocleWindowManager.getInstance().closeWindow(this);
+    }
+
+    @Override
+    protected boolean _setView(long nativeWindowPointer, View view) {
+        boolean result = true;
+        if (view != null) {
+            // the system assumes a resize notification to set the View
+            // sizes and to get the Scene to layout correctly.
+            ((MonocleView)view)._notifyResize(getWidth(), getHeight());
+        }
+        return result;
+    }
+
+    /**
+     * Returns the handle used to create a rendering context in Prism
+     */
+    @Override
+    public long getNativeWindow() {
+        return NativePlatformFactory.getNativePlatform().getScreen().getNativeHandle();
+    }
+
+    @Override
+    protected boolean _setMenubar(long ptr, long menubarPtr) {
+        return true;
+    }
+
+    @Override
+    protected boolean _minimize(long nativeWindowPointer, boolean minimize) {
+        return MonocleWindowManager.getInstance().minimizeWindow(this);
+    }
+
+    @Override
+    protected boolean _maximize(long nativeWindowPointer, boolean maximize,
+                                boolean wasMaximized) {
+        return MonocleWindowManager.getInstance().maximizeWindow(this);
+    }
+
+    private float cachedAlpha = 1;
+    @Override
+    protected boolean _setVisible(long ptr, boolean visible) {
+        if (visible) {
+            setAlpha(cachedAlpha);
+        } else {
+            cachedAlpha = getAlpha();
+            setAlpha(0);
+        }
+
+        return true;
+    }
+
+    @Override
+    protected boolean _setResizable(long ptr, boolean resizable){
+        return true;
+    }
+
+    @Override
+    protected boolean _requestFocus(long ptr, int event) {
+        return MonocleWindowManager.getInstance().requestFocus(this);
+    }
+
+    @Override
+    protected void _setFocusable(long ptr, boolean isFocusable){}
+
+    @Override
+    protected boolean _setTitle(long ptr, String title) {
+        return true;
+    }
+
+    @Override
+    protected void _setLevel(long ptr, int level) {}
+
+    @Override
+    protected void _setAlpha(long ptr, float alpha) {}
+
+    @Override
+    protected boolean _setBackground(long ptr, float r, float g, float b) {
+        return true;
+    }
+
+    @Override
+    protected void _setEnabled(long ptr, boolean enabled){}
+
+    @Override
+    protected boolean _setMinimumSize(long ptr, int width, int height) {
+        return true;
+    }
+
+    @Override
+    protected boolean _setMaximumSize(long ptr, int width, int height) {
+        return true;
+    }
+
+    @Override
+    protected void _setIcon(long ptr, Pixels pixels){}
+
+    @Override
+    protected boolean _grabFocus(long ptr) {
+        return MonocleWindowManager.getInstance().grabFocus(this);
+    }
+
+    @Override
+    protected void _ungrabFocus(long ptr) {
+        MonocleWindowManager.getInstance().ungrabFocus(this);
+    }
+
+    /**
+     * The functions below are used when the platform support modality natively.
+     * Currently only GTK is using it. This functionality is disabled by
+     * default. In order to enable it this class need to override Window::
+     * supportsPlatformModality() to return true.
+     *
+     */
+    @Override
+    protected void _enterModal(long ptr) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void _enterModalWithWindow(long dialog, long window) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void _exitModal(long ptr) {
+        throw new UnsupportedOperationException();
+    }
+
+    //**************************************************************
+    // wrappers so Application run loop can get where it needs to go
+    protected void _notifyClose() {
+        //This event is called by MonocleWindowManager when a window needs to be
+        //closed, so this is a synthetic way to emulate platform window manager
+        //window close event
+        notifyClose();
+        close();
+    }
+
+    protected void _notifyDestroy() {
+        notifyDestroy();
+    }
+
+    protected void _notifyFocus(int event) {
+        notifyFocus(event);
+    }
+
+    protected void _notifyMove(final int x, final int y) {
+        notifyMove(x, y);
+        // Note! we don't notify the view of a move
+        // as the view is only supposed to have decoration
+        // offsets for X and Y. If we have those, call
+        // view._notifyMove(x,y) directly with the offsets
+    }
+
+    protected void _notifyResize(final int type, final int width,
+                                 final int height) {
+        notifyResize(type, width, height);
+        MonocleView view = (MonocleView) getView();
+        if (view != null) {
+            view._notifyResize(width, height);
+        }
+    }
+
+    protected void _notifyExpose(final int x, final int y, final int width,
+                                 final int height) {
+        MonocleView view = (MonocleView) getView();
+        if (view != null) {
+            view._notifyRepaint(x, y, width, height);
+        }
+    }
+
+    protected void _notifyFocusUngrab() {
+        notifyFocusUngrab();
+    }
+
+    protected void _notifyFocusDisabled() {
+        notifyFocusDisabled();
+    }
+
+    //**************************************************************
+
+    @Override protected void _setCursor(long ptr, Cursor cursor) {
+        ((MonocleCursor) cursor).applyCursor();
+    }
+
+    @Override protected int _getEmbeddedX(long ptr) {
+        return 0;
+    }
+    @Override protected int _getEmbeddedY(long ptr) {
+        return 0;
+    }
+
+    @Override
+    protected void _requestInput(long ptr, String text, int type, double width, double height,
+                                 double Mxx, double Mxy, double Mxz, double Mxt,
+                                 double Myx, double Myy, double Myz, double Myt,
+                                 double Mzx, double Mzy, double Mzz, double Mzt) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    protected void _releaseInput(long ptr) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/MonocleWindowManager.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+package com.sun.glass.ui.monocle;
+
+import com.sun.glass.events.WindowEvent;
+
+import java.util.Arrays;
+
+public final class MonocleWindowManager {
+
+    static private MonocleWindowManager instance = new MonocleWindowManager();
+
+    private MonocleWindow[] windows = new MonocleWindow[0];
+    private int nextID = 1;
+
+    private MonocleWindow focusedWindow = null;
+
+    private MonocleWindowManager() {
+        //singleton
+    }
+
+    public static MonocleWindowManager getInstance() {
+        return instance;
+    }
+
+    private int getWindowIndex(MonocleWindow window) {
+        for (int i = 0; i < windows.length; i++) {
+            // Any two MonocleWindow objects represent different windows, so
+            // equality can be determined by reference comparison.
+            if (windows[i] == window) {
+                return i;
+            }
+        }
+        return -1;
+    }
+    public void toBack(MonocleWindow window) {
+        int index = getWindowIndex(window);
+        if (index != 0 && index != -1) {
+            System.arraycopy(windows, 0, windows, 1, index);
+            windows[0] = window;
+        }
+    }
+
+    public void toFront(MonocleWindow window) {
+        int index = getWindowIndex(window);
+        if (index != windows.length - 1 && index != -1) {
+            System.arraycopy(windows, index + 1, windows, index,
+                             windows.length - index - 1);
+            windows[windows.length - 1] = window;
+        }
+    }
+
+    public int addWindow(MonocleWindow window) {
+        int index = getWindowIndex(window);
+        if (index == -1) {
+            windows = Arrays.copyOf(windows, windows.length + 1);
+            windows[windows.length - 1] = window;
+        }
+        return nextID++;
+
+    }
+
+    public boolean closeWindow(MonocleWindow window) {
+        int index = getWindowIndex(window);
+        if (index != -1) {
+            System.arraycopy(windows, index + 1, windows, index,
+                             windows.length - index - 1);
+            windows = Arrays.copyOf(windows, windows.length - 1);
+        }
+        return true;
+
+    }
+
+    public boolean minimizeWindow(MonocleWindow window) {
+        return true;
+    }
+
+    public boolean maximizeWindow(MonocleWindow window) {
+        return true;
+    }
+
+    public boolean requestFocus(MonocleWindow window) {
+        int index = getWindowIndex(window);
+        if (index != -1) {
+            focusedWindow = window;
+            window._notifyFocus(WindowEvent.FOCUS_GAINED);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean grabFocus(MonocleWindow window) {
+        return true;
+    }
+
+    public void ungrabFocus(MonocleWindow window) {
+
+    }
+
+    public MonocleWindow getWindowForLocation(int x, int y) {
+        for (int i = 0; i < windows.length; i++) {
+            MonocleWindow w = windows[i];
+            if (x >= w.getX() && y >= w.getY()
+                   && x < w.getX() + w.getWidth()
+                   && y < w.getY() + w.getHeight()) {
+                return w;
+            }
+        }
+        return null;
+    }
+    
+    public MonocleWindow getFocusedWindow() {
+        return focusedWindow;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativeCursor.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import com.sun.glass.ui.Size;
+
+public interface NativeCursor {
+
+    public Size getBestSize();
+    public void setVisibility(boolean visibility);
+    public void setImage(byte[] cursorImage);
+    public void setLocation(int x, int y);
+    public void setHotSpot(int hotspotX, int hotspotY);
+    public void shutdown();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativePlatform.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2010, 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;
+
+import com.sun.glass.ui.monocle.input.InputDeviceRegistry;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+public abstract class NativePlatform {
+
+    private static InputDeviceRegistry inputDeviceRegistry;
+    protected final ExecutorService executor;
+    private Thread executorThread;
+    private NativeCursor cursor;
+    private NativeScreen screen;
+
+    protected NativePlatform() {
+        this.executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
+            @Override
+            public Thread newThread(Runnable r) {
+                executorThread = new Thread(r, "Monocle Application Thread");
+                return executorThread;
+            }
+        });
+        // Get the event thread started so that its thread exists when we ask
+        // for it in getExecutorThread(). This causes newThread() to run
+        // immediately, in the current thread. So once submit() returns,
+        // executorThread has been initialized.
+        executor.submit(new Runnable() {
+            public void run() {
+            }
+        });
+        assert(executorThread != null);
+    }
+
+    protected void shutdown() {
+        executor.shutdown();
+        if (cursor != null) {
+            cursor.shutdown();
+        }
+        if (screen != null) {
+            screen.shutdown();
+        }
+    }
+
+    public ExecutorService getExecutor() {
+        return executor;
+    }
+
+    public Thread getExecutorThread() {
+        return executorThread;
+    }
+
+    public synchronized InputDeviceRegistry getInputDeviceRegistry() {
+        if (inputDeviceRegistry == null) {
+            inputDeviceRegistry = createInputDeviceRegistry();
+        }
+        return inputDeviceRegistry;
+    }
+
+    protected abstract InputDeviceRegistry createInputDeviceRegistry();
+
+    protected abstract NativeCursor createCursor();
+
+    public synchronized NativeCursor getCursor() {
+        if (cursor == null) {
+            cursor = createCursor();
+        }
+        return cursor;
+    }
+
+    protected abstract NativeScreen createScreen();
+
+    public synchronized NativeScreen getScreen() {
+        if (screen == null) {
+            screen = createScreen();
+        }
+        return screen;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativePlatformFactory.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Locale;
+
+public abstract class NativePlatformFactory {
+
+    protected abstract boolean matches();
+
+    protected abstract NativePlatform createNativePlatform();
+
+    private static NativePlatform platform;
+    public static synchronized NativePlatform getNativePlatform() {
+        if (platform == null) {
+            String platformFactoryProperty =
+                    AccessController.doPrivileged(new PrivilegedAction<String>() {
+                @Override
+                public String run() {
+                    return System.getProperty("monocle.platform", "OMAP,Linux");
+                }
+            });
+            String[] platformFactories = platformFactoryProperty.split(",");
+            for (int i = 0; i < platformFactories.length; i++) {
+                String factoryName = platformFactories[i].trim();
+                String factoryClassName;
+                if (factoryName.contains(".")) {
+                    factoryClassName = factoryName;
+                } else {
+                    factoryClassName = "com.sun.glass.ui.monocle."
+                        + factoryName.toLowerCase(Locale.ROOT)
+                        + "." + factoryName + "PlatformFactory";
+                }
+                try {
+                    NativePlatformFactory npf = (NativePlatformFactory)
+                            Class.forName(factoryClassName)
+                            .newInstance();
+                    if (npf.matches()) {
+                        platform = npf.createNativePlatform();
+                        return platform;
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+            throw new UnsupportedOperationException(
+                    "Cannot load a native platform from: '"
+                    + platformFactoryProperty + "'");
+        }
+        return platform;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/NativeScreen.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+import java.nio.ByteBuffer;
+
+public interface NativeScreen {
+
+    public int getDepth();
+    public int getNativeFormat();
+    public int getWidth();
+    public int getHeight();
+    public int getDPI();
+    public long getNativeHandle();
+    public void shutdown();
+
+    public void uploadPixels(ByteBuffer b,
+                             int x, int y, int width, int height);
+
+    public void swapBuffers();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/NullCursor.java	Wed Jan 08 19:38:13 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;
+
+import com.sun.glass.ui.Size;
+
+public class NullCursor implements NativeCursor {
+
+    @Override
+    public Size getBestSize() {
+        return new Size(16, 16);
+    }
+
+    @Override
+    public void setVisibility(boolean visibility) {
+    }
+
+    @Override
+    public void setImage(byte[] cursorImage) {
+    }
+
+    @Override
+    public void setLocation(int x, int y) {
+    }
+
+    @Override
+    public void setHotSpot(int hotspotX, int hotspotY) {
+    }
+
+    @Override
+    public void shutdown() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/headless/HeadlessPlatform.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,49 @@
+package com.sun.glass.ui.monocle.headless;/*
+ * 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.
+ */
+
+import com.sun.glass.ui.monocle.NativeCursor;
+import com.sun.glass.ui.monocle.NativePlatform;
+import com.sun.glass.ui.monocle.NativeScreen;
+import com.sun.glass.ui.monocle.NullCursor;
+import com.sun.glass.ui.monocle.input.InputDeviceRegistry;
+
+public class HeadlessPlatform extends NativePlatform {
+
+    @Override
+    protected InputDeviceRegistry createInputDeviceRegistry() {
+        return new InputDeviceRegistry();
+    }
+
+    @Override
+    protected NativeCursor createCursor() {
+        return new NullCursor();
+    }
+
+    @Override
+    protected NativeScreen createScreen() {
+        return new HeadlessScreen();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/headless/HeadlessPlatformFactory.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.headless;
+
+import com.sun.glass.ui.monocle.NativePlatform;
+import com.sun.glass.ui.monocle.NativePlatformFactory;
+import com.sun.glass.ui.monocle.x11.X11Platform;
+
+public class HeadlessPlatformFactory extends NativePlatformFactory {
+
+    @Override
+    protected boolean matches() {
+        return true;
+    }
+
+    @Override
+    protected NativePlatform createNativePlatform() {
+        return new HeadlessPlatform();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/headless/HeadlessScreen.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010, 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.headless;
+
+import com.sun.glass.ui.Pixels;
+import com.sun.glass.ui.monocle.NativeScreen;
+
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class HeadlessScreen implements NativeScreen {
+
+    private int depth = 32;
+    private int width = 1280;
+    private int height = 800;
+
+    public HeadlessScreen() {
+        String geometry = AccessController.doPrivileged(new PrivilegedAction<String>() {
+            @Override
+            public String run() {
+                return System.getProperty("headless.geometry");
+            }
+        });
+        if (geometry != null && geometry.indexOf('x') > 0) {
+            try {
+                int i = geometry.indexOf("x");
+                width = Integer.parseInt(geometry.substring(0, i));
+                height = Integer.parseInt(geometry.substring(i + 1));
+            } catch (NumberFormatException e) {
+                System.err.println("Cannot parse geometry string: '"
+                        + geometry + "'");
+            }
+        }
+    }
+
+    @Override
+    public int getDepth() {
+        return 32;
+    }
+
+    @Override
+    public int getNativeFormat() {
+        return Pixels.Format.BYTE_BGRA_PRE;
+    }
+
+    @Override
+    public int getWidth() {
+        return width;
+    }
+
+    @Override
+    public int getHeight() {
+        return height;
+    }
+
+    @Override
+    public long getNativeHandle() {
+        return 1l;
+    }
+
+    @Override
+    public int getDPI() {
+        return 96;
+    }
+
+    @Override
+    public void shutdown() {
+    }
+
+    @Override
+    public void uploadPixels(ByteBuffer b, int x, int y, int width, int height) {
+    }
+
+    @Override
+    public void swapBuffers() {
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/InputDevice.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+public interface InputDevice {
+
+    public boolean isTouch();
+    public boolean isMultiTouch();
+    public boolean isRelative();
+    public boolean is5Way();
+    public boolean isFullKeyboard();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/InputDeviceRegistry.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,39 @@
+/*
+ * 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 javafx.collections.FXCollections;
+import javafx.collections.ObservableSet;
+
+public class InputDeviceRegistry {
+    protected ObservableSet<InputDevice> devices =
+            FXCollections.observableSet();
+
+    public ObservableSet<InputDevice> getInputDevices() {
+        return FXCollections.unmodifiableObservableSet(devices);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/MouseInput.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,147 @@
+/*
+ * 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;
+import com.sun.glass.ui.monocle.MonocleView;
+import com.sun.glass.ui.monocle.MonocleWindow;
+import com.sun.glass.ui.monocle.NativePlatformFactory;
+import com.sun.glass.ui.monocle.util.IntSet;
+
+/**
+ * Processes mouse input events based on changes to mouse state. Not
+ * thread-safe.
+ */
+public class MouseInput {
+    private static MouseInput instance = new MouseInput();
+
+    private MouseState state = new MouseState();
+    private IntSet buttons = new IntSet();
+
+    public static MouseInput getInstance() {
+        return instance;
+    }
+
+    public void getState(MouseState result) {
+        state.copyTo(result);
+    }
+
+    public void setState(MouseState newState) {
+        MonocleWindow oldWindow = state.getWindow();
+        MonocleWindow window = newState.getWindow();
+        MonocleView view = (window == null) ? null : (MonocleView) window.getView();
+        boolean moved = false;
+        // send exit event
+        if (oldWindow != window && oldWindow != null) {
+            MonocleView oldView = (MonocleView) oldWindow.getView();
+            moved = true;
+            if (oldView != null) {
+                // send exit event
+                int modifiers = state.getModifiers(); // TODO: include key modifiers
+                int button = state.getButton();
+                boolean isPopupTrigger = false; // TODO
+                int oldX = state.getX();
+                int oldY = state.getY();
+                int oldRelX = oldX - oldWindow.getX();
+                int oldRelY = oldY - oldWindow.getY();
+                oldView._notifyMouse(MouseEvent.EXIT, button,
+                                  oldRelX, oldRelY, oldX, oldY,
+                                  modifiers, isPopupTrigger, false);
+            }
+        }
+        int x = newState.getX();
+        int y = newState.getY();
+        boolean newAbsoluteLocation = state.getX() != x || state.getY() != y;
+        if (newAbsoluteLocation) {
+            NativePlatformFactory.getNativePlatform()
+                    .getCursor().setLocation(x, y);
+        }
+        if (view == null) {
+            newState.copyTo(state);
+            return;
+        }
+        int relX = x - window.getX();
+        int relY = y - window.getY();
+        // send enter event
+        if (oldWindow != window && view != null) {
+            int modifiers = state.getModifiers(); // TODO: include key modifiers
+            int button = state.getButton();
+            boolean isPopupTrigger = false; // TODO
+            view._notifyMouse(MouseEvent.ENTER, button,
+                              relX, relY, x, y,
+                              modifiers, isPopupTrigger, false);
+        }
+        // send motion events
+        if (oldWindow != window | newAbsoluteLocation) {
+            boolean isDrag = !state.getButtonsPressed().isEmpty();
+            int eventType = isDrag ? MouseEvent.DRAG : MouseEvent.MOVE;
+            int modifiers = state.getModifiers(); // TODO: include key modifiers
+            int button = state.getButton();
+            boolean isPopupTrigger = false; // TODO
+            view._notifyMouse(eventType, button,
+                              relX, relY, x, y,
+                              modifiers, isPopupTrigger, false);
+        }
+        // send press events
+        newState.getButtonsPressed().difference(buttons, state.getButtonsPressed());
+        if (!buttons.isEmpty()) {
+            MouseState pressState = new MouseState();
+            state.copyTo(pressState);
+            for (int i = 0; i < buttons.size(); i++) {
+                int button = buttons.get(i);
+                pressState.pressButton(button);
+                // send press event
+                boolean isPopupTrigger = false; // TODO
+                view._notifyMouse(MouseEvent.DOWN, button,
+                                  relX, relY, x, y,
+                                  pressState.getModifiers(), isPopupTrigger,
+                                  false);
+            }
+        }
+        buttons.clear();
+        // send release events
+        state.getButtonsPressed().difference(buttons,
+                                             newState.getButtonsPressed());
+        if (!buttons.isEmpty()) {
+            MouseState releaseState = new MouseState();
+            state.copyTo(releaseState);
+            for (int i = 0; i < buttons.size(); i++) {
+                int button = buttons.get(i);
+                releaseState.releaseButton(button);
+                // send release event
+                boolean isPopupTrigger = false; // TODO
+                view._notifyMouse(MouseEvent.UP, button,
+                                  relX, relY, x, y,
+                                  releaseState.getModifiers(), isPopupTrigger,
+                                  false);
+
+            }
+        }
+        buttons.clear();
+        newState.copyTo(state);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/MouseState.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,116 @@
+/*
+ * 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.KeyEvent;
+import com.sun.glass.events.MouseEvent;
+import com.sun.glass.ui.monocle.MonocleWindow;
+import com.sun.glass.ui.monocle.MonocleWindowManager;
+import com.sun.glass.ui.monocle.util.IntSet;
+
+public class MouseState {
+
+    private int x;
+    private int y;
+    private MonocleWindow window;
+
+    private IntSet buttonsPressed = new IntSet();
+
+    public int getX() {
+        return x;
+    }
+
+    public void setX(int x) {
+        this.x = x;
+    }
+
+    public int getY() {
+        return y;
+    }
+
+    public void setY(int y) {
+        this.y = y;
+    }
+
+    public void pressButton(int button) {
+        buttonsPressed.addInt(button);
+    }
+
+    public void releaseButton(int button) {
+        buttonsPressed.removeInt(button);
+    }
+
+    /** Returns the Glass window on which this event state is located . */
+    MonocleWindow getWindow() {
+        if (window == null) {
+            window = (MonocleWindow)
+                    MonocleWindowManager.getInstance().getWindowForLocation(x, y);
+        }
+        return window;
+    }
+
+    /** Returns the Glass button ID used for this state. */
+    int getButton() {
+        return buttonsPressed.isEmpty()
+               ? MouseEvent.BUTTON_NONE
+               : buttonsPressed.get(0);
+    }
+
+    /** Returns the Glass event modifiers for this state */
+    int getModifiers() {
+        int modifiers = KeyEvent.MODIFIER_NONE;
+        for (int i = 0; i < buttonsPressed.size(); i++) {
+            switch(buttonsPressed.get(i)) {
+                case MouseEvent.BUTTON_LEFT:
+                    modifiers |= KeyEvent.MODIFIER_BUTTON_PRIMARY;
+                    break;
+                case MouseEvent.BUTTON_OTHER:
+                    modifiers |= KeyEvent.MODIFIER_BUTTON_MIDDLE;
+                    break;
+                case MouseEvent.BUTTON_RIGHT:
+                    modifiers |= KeyEvent.MODIFIER_BUTTON_SECONDARY;
+                    break;
+            }
+        }
+        return modifiers;
+    }
+
+    void copyTo(MouseState target) {
+        target.x = x;
+        target.y = y;
+        buttonsPressed.copyTo(target.buttonsPressed);
+    }
+
+    IntSet getButtonsPressed() {
+        return buttonsPressed;
+    }
+
+    public String toString() {
+        return "MouseState[x="
+                + x + ",y=" + y
+                + ",buttonsPressed=" + buttonsPressed + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/TouchInput.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+/**
+ * Processes touch input events based on changes to touch state. Not
+ * thread-safe.
+ */
+public class TouchInput {
+    private static TouchInput instance = new TouchInput();
+
+    private TouchState state = new TouchState();
+
+    public static TouchInput getInstance() {
+        return instance;
+    }
+
+    public void getState(TouchState result) {
+        state.copyTo(result);
+    }
+
+    public void setState(TouchState newState) {
+        System.out.println(newState);
+        newState.copyTo(state);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/input/TouchState.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,110 @@
+/*
+ * 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 java.util.Arrays;
+
+public class TouchState {
+
+    public static class Point {
+        public int id;
+        public float x;
+        public float y;
+        public void copyTo(Point target) {
+            target.id = id;
+            target.x = x;
+            target.y = y;
+        }
+        public String toString() {
+            return "TouchState.Point[id=" + id + ",x=" + x + ",y="  + y + "]";
+        }
+    }
+
+    private Point[] points = new Point[1];
+    private int pointCount = 0;
+
+    public Point getPoint(int index) {
+        return points[index];
+    }
+
+    public int getPointCount() {
+        return pointCount;
+    }
+
+    public void clear() {
+        pointCount = 0;
+    }
+
+    public void addPoint(Point p) {
+        if (points.length == pointCount) {
+            points = Arrays.copyOf(points, points.length * 2);
+        }
+        if (points[pointCount] == null) {
+            points[pointCount] = new Point();
+        }
+        p.copyTo(points[pointCount]);
+        pointCount ++;
+    }
+
+    public void removePointForID(int id) {
+        for (int i = 0; i < pointCount; i++) {
+            if (points[i].id == id) {
+                if (i < pointCount - 1) {
+                    System.arraycopy(points, i + 1, points, i, pointCount - i - 1);
+                }
+                pointCount --;
+            }
+        }
+    }
+
+    public void setPoint(int index, Point p) {
+        if (index >= pointCount) {
+            throw new IndexOutOfBoundsException();
+        }
+        p.copyTo(points[index]);
+    }
+
+    void copyTo(TouchState target) {
+        if (target.points.length < points.length) {
+            target.points = Arrays.copyOf(points, points.length);
+        } else {
+            System.arraycopy(points, 0, target.points, 0, points.length);
+        }
+        target.pointCount = pointCount;
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer("TouchState[" + pointCount + ",");
+        for (int i = 0; i < pointCount; i++) {
+            sb.append(points[i]);
+            if (i < pointCount - 1) {
+                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/FBDevScreen.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2010, 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.Pixels;
+import com.sun.glass.ui.monocle.NativeScreen;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+
+public class FBDevScreen implements NativeScreen {
+
+    private int depth;
+    private int nativeFormat;
+    private int width;
+    private int height;
+    private long nativeHandle;
+    private FileChannel fbdev;
+    private boolean isShutdown;
+
+    public FBDevScreen() {
+        try {
+            depth = SysFS.readInt("/sys/class/graphics/fb0/bits_per_pixel");
+            int[] vsize = SysFS.readInts("/sys/class/graphics/fb0/virtual_size", 2);
+            width = vsize[0];
+            height = vsize[1];
+            nativeHandle = 1l;
+            nativeFormat = Pixels.Format.BYTE_BGRA_PRE;
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw (IllegalStateException)
+                    new IllegalStateException().initCause(e);
+        }
+    }
+
+    @Override
+    public int getDepth() {
+        return depth;
+    }
+
+    @Override
+    public int getNativeFormat() {
+        return nativeFormat;
+    }
+
+    @Override
+    public int getWidth() {
+        return width;
+    }
+
+    @Override
+    public int getHeight() {
+        return height;
+    }
+
+    @Override
+    public long getNativeHandle() {
+        return nativeHandle;
+    }
+
+    @Override
+    public int getDPI() {
+        return 96; // no way to read DPI from sysfs and ioctl returns junk values
+    }
+
+    private void openFBDev() throws IOException {
+        Path fbdevPath = FileSystems.getDefault().getPath("/dev/fb0");
+        fbdev = FileChannel.open(fbdevPath, StandardOpenOption.WRITE);
+    }
+
+    private void clearFBDev() {
+        ByteBuffer b = ByteBuffer.allocate(width * depth >> 3);
+        try {
+            for (int i = 0; i < height; i++) {
+                b.position(0);
+                b.limit(b.capacity());
+                fbdev.position(i * width * depth >> 3);
+                fbdev.write(b);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public synchronized void shutdown() {
+        try {
+            if (fbdev == null) {
+                openFBDev();
+            }
+            if (fbdev != null) {
+                clearFBDev();
+                fbdev.close();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            fbdev = null;
+            isShutdown = true;
+        }
+    }
+
+    @Override
+    public synchronized void uploadPixels(ByteBuffer b,
+                             int pX, int pY, int pWidth, int pHeight) {
+        if (isShutdown) {
+            return;
+        }
+        // TODO: Handle 16-bit screens and window composition
+        try {
+            if (fbdev == null) {
+                openFBDev();
+                clearFBDev();
+            }
+            if (width == pWidth) {
+                b.limit(pWidth * 4 * pHeight);
+                fbdev.position((pY * width + pX) * (depth >> 3));
+                fbdev.write(b);
+            } else {
+                for (int i = 0; i < pHeight; i++) {
+                    int position = i * pWidth * (depth >> 3);
+                    b.position(position);
+                    b.limit(position + pWidth * 4);
+                    fbdev.position(((i + pY) * width + pX) * (depth >> 3));
+                    fbdev.write(b);
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void swapBuffers() {
+        // TODO: We could double-buffer here if the virtual screen size is at
+        // least twice the visible size
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/GetEvent.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2010, 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.NativePlatform;
+import com.sun.glass.ui.monocle.NativePlatformFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+/** A test entry point for Monacle to show what events are read from input
+ * devices.
+ */
+public class GetEvent {
+
+    private static Set<File> devices = new HashSet<>();
+
+    private static UdevListener udevListener = new UdevListener() {
+        @Override
+        public void udevEvent(String action, Map<String, String> event) {
+            String subsystem = event.get("SUBSYSTEM");
+            String devPath = event.get("DEVPATH");
+            if (subsystem != null && subsystem.equals("input")
+                    && devPath != null) {
+
+                // show the udev event properties
+                System.out.format("%1$ts.%1$tL Received UEVENT:\n",
+                        new Date());
+                List<String> keys = new ArrayList<>(event.keySet());
+                Collections.sort(keys);
+                for (String key: keys) {
+                    System.out.format("  %s='%s'\n", key, event.get(key));
+                }
+
+                // process the event
+                try {
+                    File sysPath = new File("/sys", devPath);
+                    String devNode = event.get("DEVNAME");
+                    if (devNode == null) {
+                        return;
+                    }
+                    if (action.equals("add")
+                            || (action.equals("change")
+                                && !devices.contains(sysPath))) {
+                        LinuxInputDevice device = new LinuxInputDevice(
+                                new File(devNode), sysPath, event);
+                        device.setInputProcessor(new LinuxInputProcessor.Logger());
+                        Thread thread = new Thread(device);
+                        thread.setName(devNode.toString());
+                        thread.setDaemon(true);
+                        thread.start();
+                        System.out.println("Added device " + devNode);
+                        System.out.println("  touch=" + device.isTouch());
+                        System.out.println("  multiTouch=" + device.isMultiTouch());
+                        System.out.println("  relative=" + device.isRelative());
+                        System.out.println("  5-way=" + device.is5Way());
+                        System.out.println("  fullKeyboard=" + device.isFullKeyboard());
+                        devices.add(sysPath);
+                    } else if (action.equals("remove")) {
+                        devices.remove(devPath);
+                    }
+                } catch (IOException | RuntimeException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    };
+
+    public static void main(String[] argv) throws Exception {
+        NativePlatform platform = NativePlatformFactory.getNativePlatform();
+        Udev.getInstance().addListener(udevListener);
+        // Request updates for existing devices
+        SysFS.triggerUdevNotification("input");
+        // Make sure the executor is started. Otherwise we will exit at the
+        // end of this method, since all other threads are daemons.
+        platform.getExecutor().submit(new Callable<Void>() {
+            public Void call() {
+                return null;
+            }
+        }).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/Input.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 2010, 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.lang.reflect.Field;
+import java.util.Formatter;
+
+/** Constants from /usr/include/linux/input.h */
+public class Input {
+
+    public static final short INPUT_PROP_POINTER = 0x00;
+    public static final short INPUT_PROP_DIRECT = 0x01;
+    public static final short INPUT_PROP_BUTTONPAD = 0x02;
+    public static final short INPUT_PROP_SEMI_MT = 0x03;
+    public static final short INPUT_PROP_MAX = 0x1f;
+    public static final short INPUT_PROP_CNT = INPUT_PROP_MAX + 1;
+
+    public static final short EV_SYN = 0x00;
+    public static final short EV_KEY = 0x01;
+    public static final short EV_REL = 0x02;
+    public static final short EV_ABS = 0x03;
+    public static final short EV_MSC = 0x04;
+    public static final short EV_SW = 0x05;
+    public static final short EV_LED = 0x11;
+    public static final short EV_SND = 0x12;
+    public static final short EV_REP = 0x14;
+    public static final short EV_FF = 0x15;
+    public static final short EV_PWR = 0x16;
+    public static final short EV_FF_STATUS = 0x17;
+    public static final short EV_MAX = 0x1f;
+    public static final short EV_CNT = EV_MAX + 1;
+
+    public static final short SYN_REPORT = 0;
+    public static final short SYN_CONFIG = 1;
+    public static final short SYN_MT_REPORT = 2;
+    public static final short SYN_DROPPED = 3;
+
+    public static final short KEY_RESERVED = 0;
+    public static final short KEY_ESC = 1;
+    public static final short KEY_1 = 2;
+    public static final short KEY_2 = 3;
+    public static final short KEY_3 = 4;
+    public static final short KEY_4 = 5;
+    public static final short KEY_5 = 6;
+    public static final short KEY_6 = 7;
+    public static final short KEY_7 = 8;
+    public static final short KEY_8 = 9;
+    public static final short KEY_9 = 10;
+    public static final short KEY_0 = 11;
+    public static final short KEY_MINUS = 12;
+    public static final short KEY_EQUAL = 13;
+    public static final short KEY_BACKSPACE = 14;
+    public static final short KEY_TAB = 15;
+    public static final short KEY_Q = 16;
+    public static final short KEY_W = 17;
+    public static final short KEY_E = 18;
+    public static final short KEY_R = 19;
+    public static final short KEY_T = 20;
+    public static final short KEY_Y = 21;
+    public static final short KEY_U = 22;
+    public static final short KEY_I = 23;
+    public static final short KEY_O = 24;
+    public static final short KEY_P = 25;
+    public static final short KEY_LEFTBRACE = 26;
+    public static final short KEY_RIGHTBRACE = 27;
+    public static final short KEY_ENTER = 28;
+    public static final short KEY_LEFTCTRL = 29;
+    public static final short KEY_A = 30;
+    public static final short KEY_S = 31;
+    public static final short KEY_D = 32;
+    public static final short KEY_F = 33;
+    public static final short KEY_G = 34;
+    public static final short KEY_H = 35;
+    public static final short KEY_J = 36;
+    public static final short KEY_K = 37;
+    public static final short KEY_L = 38;
+    public static final short KEY_SEMICOLON = 39;
+    public static final short KEY_APOSTROPHE = 40;
+    public static final short KEY_GRAVE = 41;
+    public static final short KEY_LEFTSHIFT = 42;
+    public static final short KEY_BACKSLASH = 43;
+    public static final short KEY_Z = 44;
+    public static final short KEY_X = 45;
+    public static final short KEY_C = 46;
+    public static final short KEY_V = 47;
+    public static final short KEY_B = 48;
+    public static final short KEY_N = 49;
+    public static final short KEY_M = 50;
+    public static final short KEY_COMMA = 51;
+    public static final short KEY_DOT = 52;
+    public static final short KEY_SLASH = 53;
+    public static final short KEY_RIGHTSHIFT = 54;
+    public static final short KEY_KPASTERISK = 55;
+    public static final short KEY_LEFTALT = 56;
+    public static final short KEY_SPACE = 57;
+    public static final short KEY_CAPSLOCK = 58;
+    public static final short KEY_F1 = 59;
+    public static final short KEY_F2 = 60;
+    public static final short KEY_F3 = 61;
+    public static final short KEY_F4 = 62;
+    public static final short KEY_F5 = 63;
+    public static final short KEY_F6 = 64;
+    public static final short KEY_F7 = 65;
+    public static final short KEY_F8 = 66;
+    public static final short KEY_F9 = 67;
+    public static final short KEY_F10 = 68;
+    public static final short KEY_NUMLOCK = 69;
+    public static final short KEY_SCROLLLOCK = 70;
+    public static final short KEY_KP7 = 71;
+    public static final short KEY_KP8 = 72;
+    public static final short KEY_KP9 = 73;
+    public static final short KEY_KPMINUS = 74;
+    public static final short KEY_KP4 = 75;
+    public static final short KEY_KP5 = 76;
+    public static final short KEY_KP6 = 77;
+    public static final short KEY_KPPLUS = 78;
+    public static final short KEY_KP1 = 79;
+    public static final short KEY_KP2 = 80;
+    public static final short KEY_KP3 = 81;
+    public static final short KEY_KP0 = 82;
+    public static final short KEY_KPDOT = 83;
+    public static final short KEY_ZENKAKUHANKAKU = 85;
+    public static final short KEY_102ND = 86;
+    public static final short KEY_F11 = 87;
+    public static final short KEY_F12 = 88;
+    public static final short KEY_RO = 89;
+    public static final short KEY_KATAKANA = 90;
+    public static final short KEY_HIRAGANA = 91;
+    public static final short KEY_HENKAN = 92;
+    public static final short KEY_KATAKANAHIRAGANA = 93;
+    public static final short KEY_MUHENKAN = 94;
+    public static final short KEY_KPJPCOMMA = 95;
+    public static final short KEY_KPENTER = 96;
+    public static final short KEY_RIGHTCTRL = 97;
+    public static final short KEY_KPSLASH = 98;
+    public static final short KEY_SYSRQ = 99;
+    public static final short KEY_RIGHTALT = 100;
+    public static final short KEY_LINEFEED = 101;
+    public static final short KEY_HOME = 102;
+    public static final short KEY_UP = 103;
+    public static final short KEY_PAGEUP = 104;
+    public static final short KEY_LEFT = 105;
+    public static final short KEY_RIGHT = 106;
+    public static final short KEY_END = 107;
+    public static final short KEY_DOWN = 108;
+    public static final short KEY_PAGEDOWN = 109;
+    public static final short KEY_INSERT = 110;
+    public static final short KEY_DELETE = 111;
+    public static final short KEY_MACRO = 112;
+    public static final short KEY_MUTE = 113;
+    public static final short KEY_VOLUMEDOWN = 114;
+    public static final short KEY_VOLUMEUP = 115;
+    public static final short KEY_POWER = 116;
+    public static final short KEY_KPEQUAL = 117;
+    public static final short KEY_KPPLUSMINUS = 118;
+    public static final short KEY_PAUSE = 119;
+    public static final short KEY_SCALE = 120;
+    public static final short KEY_KPCOMMA = 121;
+    public static final short KEY_HANGEUL = 122;
+    public static final short KEY_HANGUEL = KEY_HANGEUL;
+    public static final short KEY_HANJA = 123;
+    public static final short KEY_YEN = 124;
+    public static final short KEY_LEFTMETA = 125;
+    public static final short KEY_RIGHTMETA = 126;
+    public static final short KEY_COMPOSE = 127;
+    public static final short KEY_STOP = 128;
+    public static final short KEY_AGAIN = 129;
+    public static final short KEY_PROPS = 130;
+    public static final short KEY_UNDO = 131;
+    public static final short KEY_FRONT = 132;
+    public static final short KEY_COPY = 133;
+    public static final short KEY_OPEN = 134;
+    public static final short KEY_PASTE = 135;
+    public static final short KEY_FIND = 136;
+    public static final short KEY_CUT = 137;
+    public static final short KEY_HELP = 138;
+    public static final short KEY_MENU = 139;
+    public static final short KEY_CALC = 140;
+    public static final short KEY_SETUP = 141;
+    public static final short KEY_SLEEP = 142;
+    public static final short KEY_WAKEUP = 143;
+    public static final short KEY_FILE = 144;
+    public static final short KEY_SENDFILE = 145;
+    public static final short KEY_DELETEFILE = 146;
+    public static final short KEY_XFER = 147;
+    public static final short KEY_PROG1 = 148;
+    public static final short KEY_PROG2 = 149;
+    public static final short KEY_WWW = 150;
+    public static final short KEY_MSDOS = 151;
+    public static final short KEY_COFFEE = 152;
+    public static final short KEY_SCREENLOCK = KEY_COFFEE;
+    public static final short KEY_DIRECTION = 153;
+    public static final short KEY_CYCLEWINDOWS = 154;
+    public static final short KEY_MAIL = 155;
+    public static final short KEY_BOOKMARKS = 156;
+    public static final short KEY_COMPUTER = 157;
+    public static final short KEY_BACK = 158;
+    public static final short KEY_FORWARD = 159;
+    public static final short KEY_CLOSECD = 160;
+    public static final short KEY_EJECTCD = 161;
+    public static final short KEY_EJECTCLOSECD = 162;
+    public static final short KEY_NEXTSONG = 163;
+    public static final short KEY_PLAYPAUSE = 164;
+    public static final short KEY_PREVIOUSSONG = 165;
+    public static final short KEY_STOPCD = 166;
+    public static final short KEY_RECORD = 167;
+    public static final short KEY_REWIND = 168;
+    public static final short KEY_PHONE = 169;
+    public static final short KEY_ISO = 170;
+    public static final short KEY_CONFIG = 171;
+    public static final short KEY_HOMEPAGE = 172;
+    public static final short KEY_REFRESH = 173;
+    public static final short KEY_EXIT = 174;
+    public static final short KEY_MOVE = 175;
+    public static final short KEY_EDIT = 176;
+    public static final short KEY_SCROLLUP = 177;
+    public static final short KEY_SCROLLDOWN = 178;
+    public static final short KEY_KPLEFTPAREN = 179;
+    public static final short KEY_KPRIGHTPAREN = 180;
+    public static final short KEY_NEW = 181;
+    public static final short KEY_REDO = 182;
+    public static final short KEY_F13 = 183;
+    public static final short KEY_F14 = 184;
+    public static final short KEY_F15 = 185;
+    public static final short KEY_F16 = 186;
+    public static final short KEY_F17 = 187;
+    public static final short KEY_F18 = 188;
+    public static final short KEY_F19 = 189;
+    public static final short KEY_F20 = 190;
+    public static final short KEY_F21 = 191;
+    public static final short KEY_F22 = 192;
+    public static final short KEY_F23 = 193;
+    public static final short KEY_F24 = 194;
+    public static final short KEY_PLAYCD = 200;
+    public static final short KEY_PAUSECD = 201;
+    public static final short KEY_PROG3 = 202;
+    public static final short KEY_PROG4 = 203;
+    public static final short KEY_DASHBOARD = 204;
+    public static final short KEY_SUSPEND = 205;
+    public static final short KEY_CLOSE = 206;
+    public static final short KEY_PLAY = 207;
+    public static final short KEY_FASTFORWARD = 208;
+    public static final short KEY_BASSBOOST = 209;
+    public static final short KEY_PRINT = 210;
+    public static final short KEY_HP = 211;
+    public static final short KEY_CAMERA = 212;
+    public static final short KEY_SOUND = 213;
+    public static final short KEY_QUESTION = 214;
+    public static final short KEY_EMAIL = 215;
+    public static final short KEY_CHAT = 216;
+    public static final short KEY_SEARCH = 217;
+    public static final short KEY_CONNECT = 218;
+    public static final short KEY_FINANCE = 219;
+    public static final short KEY_SPORT = 220;
+    public static final short KEY_SHOP = 221;
+    public static final short KEY_ALTERASE = 222;
+    public static final short KEY_CANCEL = 223;
+    public static final short KEY_BRIGHTNESSDOWN = 224;
+    public static final short KEY_BRIGHTNESSUP = 225;
+    public static final short KEY_MEDIA = 226;
+    public static final short KEY_SWITCHVIDEOMODE = 227;
+    public static final short KEY_KBDILLUMTOGGLE = 228;
+    public static final short KEY_KBDILLUMDOWN = 229;
+    public static final short KEY_KBDILLUMUP = 230;
+    public static final short KEY_SEND = 231;
+    public static final short KEY_REPLY = 232;
+    public static final short KEY_FORWARDMAIL = 233;
+    public static final short KEY_SAVE = 234;
+    public static final short KEY_DOCUMENTS = 235;
+    public static final short KEY_BATTERY = 236;
+    public static final short KEY_BLUETOOTH = 237;
+    public static final short KEY_WLAN = 238;
+    public static final short KEY_UWB = 239;
+    public static final short KEY_UNKNOWN = 240;
+    public static final short KEY_VIDEO_NEXT = 241;
+    public static final short KEY_VIDEO_PREV = 242;
+    public static final short KEY_BRIGHTNESS_CYCLE = 243;
+    public static final short KEY_BRIGHTNESS_ZERO = 244;
+    public static final short KEY_DISPLAY_OFF = 245;
+    public static final short KEY_WIMAX = 246;
+    public static final short KEY_RFKILL = 247;
+    public static final short KEY_MICMUTE = 248;
+
+    public static final short BTN_MISC = 0x100;
+    public static final short BTN_0 = 0x100;
+    public static final short BTN_1 = 0x101;
+    public static final short BTN_2 = 0x102;
+    public static final short BTN_3 = 0x103;
+    public static final short BTN_4 = 0x104;
+    public static final short BTN_5 = 0x105;
+    public static final short BTN_6 = 0x106;
+    public static final short BTN_7 = 0x107;
+    public static final short BTN_8 = 0x108;
+    public static final short BTN_9 = 0x109;
+    public static final short BTN_MOUSE = 0x110;
+    public static final short BTN_LEFT = 0x110;
+    public static final short BTN_RIGHT = 0x111;
+    public static final short BTN_MIDDLE = 0x112;
+    public static final short BTN_SIDE = 0x113;
+    public static final short BTN_EXTRA = 0x114;
+    public static final short BTN_FORWARD = 0x115;
+    public static final short BTN_BACK = 0x116;
+    public static final short BTN_TASK = 0x117;
+    public static final short BTN_JOYSTICK = 0x120;
+    public static final short BTN_TRIGGER = 0x120;
+    public static final short BTN_THUMB = 0x121;
+    public static final short BTN_THUMB2 = 0x122;
+    public static final short BTN_TOP = 0x123;
+    public static final short BTN_TOP2 = 0x124;
+    public static final short BTN_PINKIE = 0x125;
+    public static final short BTN_BASE = 0x126;
+    public static final short BTN_BASE2 = 0x127;
+    public static final short BTN_BASE3 = 0x128;
+    public static final short BTN_BASE4 = 0x129;
+    public static final short BTN_BASE5 = 0x12a;
+    public static final short BTN_BASE6 = 0x12b;
+    public static final short BTN_DEAD = 0x12f;
+    public static final short BTN_GAMEPAD = 0x130;
+    public static final short BTN_A = 0x130;
+    public static final short BTN_B = 0x131;
+    public static final short BTN_C = 0x132;
+    public static final short BTN_X = 0x133;
+    public static final short BTN_Y = 0x134;
+    public static final short BTN_Z = 0x135;
+    public static final short BTN_TL = 0x136;
+    public static final short BTN_TR = 0x137;
+    public static final short BTN_TL2 = 0x138;
+    public static final short BTN_TR2 = 0x139;
+    public static final short BTN_SELECT = 0x13a;
+    public static final short BTN_START = 0x13b;
+    public static final short BTN_MODE = 0x13c;
+    public static final short BTN_THUMBL = 0x13d;
+    public static final short BTN_THUMBR = 0x13e;
+    public static final short BTN_DIGI = 0x140;
+    public static final short BTN_TOOL_PEN = 0x140;
+    public static final short BTN_TOOL_RUBBER = 0x141;
+    public static final short BTN_TOOL_BRUSH = 0x142;
+    public static final short BTN_TOOL_PENCIL = 0x143;
+    public static final short BTN_TOOL_AIRBRUSH = 0x144;
+    public static final short BTN_TOOL_FINGER = 0x145;
+    public static final short BTN_TOOL_MOUSE = 0x146;
+    public static final short BTN_TOOL_LENS = 0x147;
+    public static final short BTN_TOOL_QUINTTAP = 0x148;
+    public static final short BTN_TOUCH = 0x14a;
+    public static final short BTN_STYLUS = 0x14b;
+    public static final short BTN_STYLUS2 = 0x14c;
+    public static final short BTN_TOOL_DOUBLETAP = 0x14d;
+    public static final short BTN_TOOL_TRIPLETAP = 0x14e;
+    public static final short BTN_TOOL_QUADTAP = 0x14f;
+    public static final short BTN_WHEEL = 0x150;
+    public static final short BTN_GEAR_DOWN = 0x150;
+    public static final short BTN_GEAR_UP = 0x151;
+    public static final short KEY_OK = 0x160;
+    public static final short KEY_SELECT = 0x161;
+    public static final short KEY_GOTO = 0x162;
+    public static final short KEY_CLEAR = 0x163;
+    public static final short KEY_POWER2 = 0x164;
+    public static final short KEY_OPTION = 0x165;
+    public static final short KEY_INFO = 0x166;
+    public static final short KEY_TIME = 0x167;
+    public static final short KEY_VENDOR = 0x168;
+    public static final short KEY_ARCHIVE = 0x169;
+    public static final short KEY_PROGRAM = 0x16a;
+    public static final short KEY_CHANNEL = 0x16b;
+    public static final short KEY_FAVORITES = 0x16c;
+    public static final short KEY_EPG = 0x16d;
+    public static final short KEY_PVR = 0x16e;
+    public static final short KEY_MHP = 0x16f;
+    public static final short KEY_LANGUAGE = 0x170;
+    public static final short KEY_TITLE = 0x171;
+    public static final short KEY_SUBTITLE = 0x172;
+    public static final short KEY_ANGLE = 0x173;
+    public static final short KEY_ZOOM = 0x174;
+    public static final short KEY_MODE = 0x175;
+    public static final short KEY_KEYBOARD = 0x176;
+    public static final short KEY_SCREEN = 0x177;
+    public static final short KEY_PC = 0x178;
+    public static final short KEY_TV = 0x179;
+    public static final short KEY_TV2 = 0x17a;
+    public static final short KEY_VCR = 0x17b;
+    public static final short KEY_VCR2 = 0x17c;
+    public static final short KEY_SAT = 0x17d;
+    public static final short KEY_SAT2 = 0x17e;
+    public static final short KEY_CD = 0x17f;
+    public static final short KEY_TAPE = 0x180;
+    public static final short KEY_RADIO = 0x181;
+    public static final short KEY_TUNER = 0x182;
+    public static final short KEY_PLAYER = 0x183;
+    public static final short KEY_TEXT = 0x184;
+    public static final short KEY_DVD = 0x185;
+    public static final short KEY_AUX = 0x186;
+    public static final short KEY_MP3 = 0x187;
+    public static final short KEY_AUDIO = 0x188;
+    public static final short KEY_VIDEO = 0x189;
+    public static final short KEY_DIRECTORY = 0x18a;
+    public static final short KEY_LIST = 0x18b;
+    public static final short KEY_MEMO = 0x18c;
+    public static final short KEY_CALENDAR = 0x18d;
+    public static final short KEY_RED = 0x18e;
+    public static final short KEY_GREEN = 0x18f;
+    public static final short KEY_YELLOW = 0x190;
+    public static final short KEY_BLUE = 0x191;
+    public static final short KEY_CHANNELUP = 0x192;
+    public static final short KEY_CHANNELDOWN = 0x193;
+    public static final short KEY_FIRST = 0x194;
+    public static final short KEY_LAST = 0x195;
+    public static final short KEY_AB = 0x196;
+    public static final short KEY_NEXT = 0x197;
+    public static final short KEY_RESTART = 0x198;
+    public static final short KEY_SLOW = 0x199;
+    public static final short KEY_SHUFFLE = 0x19a;
+    public static final short KEY_BREAK = 0x19b;
+    public static final short KEY_PREVIOUS = 0x19c;
+    public static final short KEY_DIGITS = 0x19d;
+    public static final short KEY_TEEN = 0x19e;
+    public static final short KEY_TWEN = 0x19f;
+    public static final short KEY_VIDEOPHONE = 0x1a0;
+    public static final short KEY_GAMES = 0x1a1;
+    public static final short KEY_ZOOMIN = 0x1a2;
+    public static final short KEY_ZOOMOUT = 0x1a3;
+    public static final short KEY_ZOOMRESET = 0x1a4;
+    public static final short KEY_WORDPROCESSOR = 0x1a5;
+    public static final short KEY_EDITOR = 0x1a6;
+    public static final short KEY_SPREADSHEET = 0x1a7;
+    public static final short KEY_GRAPHICSEDITOR = 0x1a8;
+    public static final short KEY_PRESENTATION = 0x1a9;
+    public static final short KEY_DATABASE = 0x1aa;
+    public static final short KEY_NEWS = 0x1ab;
+    public static final short KEY_VOICEMAIL = 0x1ac;
+    public static final short KEY_ADDRESSBOOK = 0x1ad;
+    public static final short KEY_MESSENGER = 0x1ae;
+    public static final short KEY_DISPLAYTOGGLE = 0x1af;
+    public static final short KEY_SPELLCHECK = 0x1b0;
+    public static final short KEY_LOGOFF = 0x1b1;
+    public static final short KEY_DOLLAR = 0x1b2;
+    public static final short KEY_EURO = 0x1b3;
+    public static final short KEY_FRAMEBACK = 0x1b4;
+    public static final short KEY_FRAMEFORWARD = 0x1b5;
+    public static final short KEY_CONTEXT_MENU = 0x1b6;
+    public static final short KEY_MEDIA_REPEAT = 0x1b7;
+    public static final short KEY_10CHANNELSUP = 0x1b8;
+    public static final short KEY_10CHANNELSDOWN = 0x1b9;
+    public static final short KEY_IMAGES = 0x1ba;
+    public static final short KEY_DEL_EOL = 0x1c0;
+    public static final short KEY_DEL_EOS = 0x1c1;
+    public static final short KEY_INS_LINE = 0x1c2;
+    public static final short KEY_DEL_LINE = 0x1c3;
+    public static final short KEY_FN = 0x1d0;
+    public static final short KEY_FN_ESC = 0x1d1;
+    public static final short KEY_FN_F1 = 0x1d2;
+    public static final short KEY_FN_F2 = 0x1d3;
+    public static final short KEY_FN_F3 = 0x1d4;
+    public static final short KEY_FN_F4 = 0x1d5;
+    public static final short KEY_FN_F5 = 0x1d6;
+    public static final short KEY_FN_F6 = 0x1d7;
+    public static final short KEY_FN_F7 = 0x1d8;
+    public static final short KEY_FN_F8 = 0x1d9;
+    public static final short KEY_FN_F9 = 0x1da;
+    public static final short KEY_FN_F10 = 0x1db;
+    public static final short KEY_FN_F11 = 0x1dc;
+    public static final short KEY_FN_F12 = 0x1dd;
+    public static final short KEY_FN_1 = 0x1de;
+    public static final short KEY_FN_2 = 0x1df;
+    public static final short KEY_FN_D = 0x1e0;
+    public static final short KEY_FN_E = 0x1e1;
+    public static final short KEY_FN_F = 0x1e2;
+    public static final short KEY_FN_S = 0x1e3;
+    public static final short KEY_FN_B = 0x1e4;
+    public static final short KEY_BRL_DOT1 = 0x1f1;
+    public static final short KEY_BRL_DOT2 = 0x1f2;
+    public static final short KEY_BRL_DOT3 = 0x1f3;
+    public static final short KEY_BRL_DOT4 = 0x1f4;
+    public static final short KEY_BRL_DOT5 = 0x1f5;
+    public static final short KEY_BRL_DOT6 = 0x1f6;
+    public static final short KEY_BRL_DOT7 = 0x1f7;
+    public static final short KEY_BRL_DOT8 = 0x1f8;
+    public static final short KEY_BRL_DOT9 = 0x1f9;
+    public static final short KEY_BRL_DOT10 = 0x1fa;
+    public static final short KEY_NUMERIC_0 = 0x200;
+    public static final short KEY_NUMERIC_1 = 0x201;
+    public static final short KEY_NUMERIC_2 = 0x202;
+    public static final short KEY_NUMERIC_3 = 0x203;
+    public static final short KEY_NUMERIC_4 = 0x204;
+    public static final short KEY_NUMERIC_5 = 0x205;
+    public static final short KEY_NUMERIC_6 = 0x206;
+    public static final short KEY_NUMERIC_7 = 0x207;
+    public static final short KEY_NUMERIC_8 = 0x208;
+    public static final short KEY_NUMERIC_9 = 0x209;
+    public static final short KEY_NUMERIC_STAR = 0x20a;
+    public static final short KEY_NUMERIC_POUND = 0x20b;
+    public static final short KEY_CAMERA_FOCUS = 0x210;
+    public static final short KEY_WPS_BUTTON = 0x211;
+    public static final short KEY_TOUCHPAD_TOGGLE = 0x212;
+    public static final short KEY_TOUCHPAD_ON = 0x213;
+    public static final short KEY_TOUCHPAD_OFF = 0x214;
+    public static final short KEY_CAMERA_ZOOMIN = 0x215;
+    public static final short KEY_CAMERA_ZOOMOUT = 0x216;
+    public static final short KEY_CAMERA_UP = 0x217;
+    public static final short KEY_CAMERA_DOWN = 0x218;
+    public static final short KEY_CAMERA_LEFT = 0x219;
+    public static final short KEY_CAMERA_RIGHT = 0x21a;
+    public static final short BTN_TRIGGER_HAPPY = 0x2c0;
+    public static final short BTN_TRIGGER_HAPPY1 = 0x2c0;
+    public static final short BTN_TRIGGER_HAPPY2 = 0x2c1;
+    public static final short BTN_TRIGGER_HAPPY3 = 0x2c2;
+    public static final short BTN_TRIGGER_HAPPY4 = 0x2c3;
+    public static final short BTN_TRIGGER_HAPPY5 = 0x2c4;
+    public static final short BTN_TRIGGER_HAPPY6 = 0x2c5;
+    public static final short BTN_TRIGGER_HAPPY7 = 0x2c6;
+    public static final short BTN_TRIGGER_HAPPY8 = 0x2c7;
+    public static final short BTN_TRIGGER_HAPPY9 = 0x2c8;
+    public static final short BTN_TRIGGER_HAPPY10 = 0x2c9;
+    public static final short BTN_TRIGGER_HAPPY11 = 0x2ca;
+    public static final short BTN_TRIGGER_HAPPY12 = 0x2cb;
+    public static final short BTN_TRIGGER_HAPPY13 = 0x2cc;
+    public static final short BTN_TRIGGER_HAPPY14 = 0x2cd;
+    public static final short BTN_TRIGGER_HAPPY15 = 0x2ce;
+    public static final short BTN_TRIGGER_HAPPY16 = 0x2cf;
+    public static final short BTN_TRIGGER_HAPPY17 = 0x2d0;
+    public static final short BTN_TRIGGER_HAPPY18 = 0x2d1;
+    public static final short BTN_TRIGGER_HAPPY19 = 0x2d2;
+    public static final short BTN_TRIGGER_HAPPY20 = 0x2d3;
+    public static final short BTN_TRIGGER_HAPPY21 = 0x2d4;
+    public static final short BTN_TRIGGER_HAPPY22 = 0x2d5;
+    public static final short BTN_TRIGGER_HAPPY23 = 0x2d6;
+    public static final short BTN_TRIGGER_HAPPY24 = 0x2d7;
+    public static final short BTN_TRIGGER_HAPPY25 = 0x2d8;
+    public static final short BTN_TRIGGER_HAPPY26 = 0x2d9;
+    public static final short BTN_TRIGGER_HAPPY27 = 0x2da;
+    public static final short BTN_TRIGGER_HAPPY28 = 0x2db;
+    public static final short BTN_TRIGGER_HAPPY29 = 0x2dc;
+    public static final short BTN_TRIGGER_HAPPY30 = 0x2dd;
+    public static final short BTN_TRIGGER_HAPPY31 = 0x2de;
+    public static final short BTN_TRIGGER_HAPPY32 = 0x2df;
+    public static final short BTN_TRIGGER_HAPPY33 = 0x2e0;
+    public static final short BTN_TRIGGER_HAPPY34 = 0x2e1;
+    public static final short BTN_TRIGGER_HAPPY35 = 0x2e2;
+    public static final short BTN_TRIGGER_HAPPY36 = 0x2e3;
+    public static final short BTN_TRIGGER_HAPPY37 = 0x2e4;
+    public static final short BTN_TRIGGER_HAPPY38 = 0x2e5;
+    public static final short BTN_TRIGGER_HAPPY39 = 0x2e6;
+    public static final short BTN_TRIGGER_HAPPY40 = 0x2e7;
+
+    public static final short KEY_MIN_INTERESTING = KEY_MUTE;
+    public static final short KEY_MAX = 0x2ff;
+    public static final short KEY_CNT = KEY_MAX + 1;
+
+    public static final short REL_X = 0x00;
+    public static final short REL_Y = 0x01;
+    public static final short REL_Z = 0x02;
+    public static final short REL_RX = 0x03;
+    public static final short REL_RY = 0x04;
+    public static final short REL_RZ = 0x05;
+    public static final short REL_HWHEEL = 0x06;
+    public static final short REL_DIAL = 0x07;
+    public static final short REL_WHEEL = 0x08;
+    public static final short REL_MISC = 0x09;
+    public static final short REL_MAX = 0x0f;
+    public static final short REL_CNT = REL_MAX + 1;
+
+    public static final short ABS_X = 0x00;
+    public static final short ABS_Y = 0x01;
+    public static final short ABS_Z = 0x02;
+    public static final short ABS_RX = 0x03;
+    public static final short ABS_RY = 0x04;
+    public static final short ABS_RZ = 0x05;
+    public static final short ABS_THROTTLE = 0x06;
+    public static final short ABS_RUDDER = 0x07;
+    public static final short ABS_WHEEL = 0x08;
+    public static final short ABS_GAS = 0x09;
+    public static final short ABS_BRAKE = 0x0a;
+    public static final short ABS_HAT0X = 0x10;
+    public static final short ABS_HAT0Y = 0x11;
+    public static final short ABS_HAT1X = 0x12;
+    public static final short ABS_HAT1Y = 0x13;
+    public static final short ABS_HAT2X = 0x14;
+    public static final short ABS_HAT2Y = 0x15;
+    public static final short ABS_HAT3X = 0x16;
+    public static final short ABS_HAT3Y = 0x17;
+    public static final short ABS_PRESSURE = 0x18;
+    public static final short ABS_DISTANCE = 0x19;
+    public static final short ABS_TILT_X = 0x1a;
+    public static final short ABS_TILT_Y = 0x1b;
+    public static final short ABS_TOOL_WIDTH = 0x1c;
+    public static final short ABS_VOLUME = 0x20;
+    public static final short ABS_MISC = 0x28;
+    public static final short ABS_MT_SLOT = 0x2f;
+    public static final short ABS_MT_TOUCH_MAJOR = 0x30;
+    public static final short ABS_MT_TOUCH_MINOR = 0x31;
+    public static final short ABS_MT_WIDTH_MAJOR = 0x32;
+    public static final short ABS_MT_WIDTH_MINOR = 0x33;
+    public static final short ABS_MT_ORIENTATION = 0x34;
+    public static final short ABS_MT_POSITION_X = 0x35;
+    public static final short ABS_MT_POSITION_Y = 0x36;
+    public static final short ABS_MT_TOOL_TYPE = 0x37;
+    public static final short ABS_MT_BLOB_ID = 0x38;
+    public static final short ABS_MT_TRACKING_ID = 0x39;
+    public static final short ABS_MT_PRESSURE = 0x3a;
+    public static final short ABS_MT_DISTANCE = 0x3b;
+    public static final short ABS_MAX = 0x3f;
+    public static final short ABS_CNT = ABS_MAX + 1;
+
+    public static final short SW_LID = 0x00;
+    public static final short SW_TABLET_MODE = 0x01;
+    public static final short SW_HEADPHONE_INSERT = 0x02;
+    public static final short SW_RFKILL_ALL = 0x03;
+    public static final short SW_RADIO = SW_RFKILL_ALL;
+    public static final short SW_MICROPHONE_INSERT = 0x04;
+    public static final short SW_DOCK = 0x05;
+    public static final short SW_LINEOUT_INSERT = 0x06;
+    public static final short SW_JACK_PHYSICAL_INSERT = 0x07;
+    public static final short SW_VIDEOOUT_INSERT = 0x08;
+    public static final short SW_CAMERA_LENS_COVER = 0x09;
+    public static final short SW_KEYPAD_SLIDE = 0x0a;
+    public static final short SW_FRONT_PROXIMITY = 0x0b;
+    public static final short SW_ROTATE_LOCK = 0x0c;
+    public static final short SW_LINEIN_INSERT = 0x0d;
+    public static final short SW_MAX = 0x0f;
+    public static final short SW_CNT = SW_MAX + 1;
+
+    public static final short MSC_SERIAL = 0x00;
+    public static final short MSC_PULSELED = 0x01;
+    public static final short MSC_GESTURE = 0x02;
+    public static final short MSC_RAW = 0x03;
+    public static final short MSC_SCAN = 0x04;
+    public static final short MSC_MAX = 0x07;
+    public static final short MSC_CNT = MSC_MAX + 1;
+
+    public static final short LED_NUML = 0x00;
+    public static final short LED_CAPSL = 0x01;
+    public static final short LED_SCROLLL = 0x02;
+    public static final short LED_COMPOSE = 0x03;
+    public static final short LED_KANA = 0x04;
+    public static final short LED_SLEEP = 0x05;
+    public static final short LED_SUSPEND = 0x06;
+    public static final short LED_MUTE = 0x07;
+    public static final short LED_MISC = 0x08;
+    public static final short LED_MAIL = 0x09;
+    public static final short LED_CHARGING = 0x0a;
+    public static final short LED_MAX = 0x0f;
+    public static final short LED_CNT = LED_MAX + 1;
+
+    public static final short REP_DELAY = 0x00;
+    public static final short REP_PERIOD = 0x01;
+    public static final short REP_MAX = 0x01;
+    public static final short REP_CNT = REP_MAX + 1;
+
+    public static final short SND_CLICK = 0x00;
+    public static final short SND_BELL = 0x01;
+    public static final short SND_TONE = 0x02;
+    public static final short SND_MAX = 0x07;
+    public static final short SND_CNT = SND_MAX + 1;
+
+    public static final short ID_BUS = 0;
+    public static final short ID_VENDOR = 1;
+    public static final short ID_PRODUCT = 2;
+    public static final short ID_VERSION = 3;
+    public static final short BUS_PCI = 0x01;
+    public static final short BUS_ISAPNP = 0x02;
+    public static final short BUS_USB = 0x03;
+    public static final short BUS_HIL = 0x04;
+    public static final short BUS_BLUETOOTH = 0x05;
+    public static final short BUS_VIRTUAL = 0x06;
+    public static final short BUS_ISA = 0x10;
+    public static final short BUS_I8042 = 0x11;
+    public static final short BUS_XTKBD = 0x12;
+    public static final short BUS_RS232 = 0x13;
+    public static final short BUS_GAMEPORT = 0x14;
+    public static final short BUS_PARPORT = 0x15;
+    public static final short BUS_AMIGA = 0x16;
+    public static final short BUS_ADB = 0x17;
+    public static final short BUS_I2C = 0x18;
+    public static final short BUS_HOST = 0x19;
+    public static final short BUS_GSC = 0x1A;
+    public static final short BUS_ATARI = 0x1B;
+    public static final short BUS_SPI = 0x1C;
+
+    public static final short MT_TOOL_FINGER = 0;
+    public static final short MT_TOOL_PEN = 1;
+    public static final short MT_TOOL_MAX = 1;
+
+    public static final short FF_STATUS_STOPPED = 0x00;
+    public static final short FF_STATUS_PLAYING = 0x01;
+    public static final short FF_STATUS_MAX = 0x01;
+
+    public static final short FF_RUMBLE = 0x50;
+    public static final short FF_PERIODIC = 0x51;
+    public static final short FF_CONSTANT = 0x52;
+    public static final short FF_SPRING = 0x53;
+    public static final short FF_FRICTION = 0x54;
+    public static final short FF_DAMPER = 0x55;
+    public static final short FF_INERTIA = 0x56;
+    public static final short FF_RAMP = 0x57;
+    public static final short FF_EFFECT_MIN = FF_RUMBLE;
+    public static final short FF_EFFECT_MAX = FF_RAMP;
+
+    public static final short FF_SQUARE = 0x58;
+    public static final short FF_TRIANGLE = 0x59;
+    public static final short FF_SINE = 0x5a;
+    public static final short FF_SAW_UP = 0x5b;
+    public static final short FF_SAW_DOWN = 0x5c;
+    public static final short FF_CUSTOM = 0x5d;
+    public static final short FF_WAVEFORM_MIN = FF_SQUARE;
+    public static final short FF_WAVEFORM_MAX = FF_CUSTOM;
+
+    public static final short FF_GAIN = 0x60;
+    public static final short FF_AUTOCENTER = 0x61;
+    public static final short FF_MAX = 0x7f;
+    public static final short FF_CNT = FF_MAX + 1;
+
+    /**
+     * Convert an event type to its equivalent string. This method is
+     * inefficient and is for debugging use only.
+     */
+    public static String typeToString(short type) {
+        for (Field field : Input.class.getFields()) {
+            try {
+                if (field.getName().startsWith("EV_")
+                        && field.getType() == Short.TYPE
+                        && field.getShort(null) == type) {
+                    return field.getName();
+                }
+            } catch (IllegalAccessException e) {
+            }
+        }
+        return new Formatter().format("0x%04x", type & 0xffff).out().toString();
+    }
+
+    /**
+     * Convert an event code to its equivalent string, given its type string.
+     * The type string is needed because event codes are context sensitive. For
+     * example, the code 1 is "SYN_CONFIG" for an EV_SYN event but "KEY_ESC" for
+     * an EV_KEY event.  This method is inefficient and is for debugging use
+     * only.
+     */
+    public static String codeToString(String type, short code) {
+        int i = type.indexOf("_");
+        if (i >= 0) {
+            String prefix = type.substring(i + 1);
+            String altPrefix = prefix.equals("KEY") ? "BTN" : prefix;
+            for (Field field : Input.class.getFields()) {
+                String name = field.getName();
+                try {
+                    if ((name.startsWith(prefix) || name.startsWith(altPrefix))
+                            && field.getType() == Short.TYPE
+                            && field.getShort(null) == code) {
+                        return field.getName();
+                    }
+                } catch (IllegalAccessException e) {
+                }
+            }
+        }
+        return new Formatter().format("0x%04x", code & 0xffff).out().toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/KeyBits.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+/**
+ * KeyBits defines sets of keys that are used to identify classes of key input
+ * devices
+ */
+public class KeyBits extends Input {
+
+    static final short KEYBITS_ARROWS[] = {
+        KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT
+    };
+
+    static final short KEYBITS_SELECT[] = {
+        KEY_ENTER, KEY_SELECT
+    };
+
+    /** Keybits for PC keyboard */
+    static final short KEYBITS_PC[] = {
+        KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
+        KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
+        KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z,
+        KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0,
+        KEY_LEFTSHIFT, KEY_TAB
+    };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxInputDevice.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2010, 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.NativePlatformFactory;
+import com.sun.glass.ui.monocle.input.InputDevice;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.ReadableByteChannel;
+import java.util.BitSet;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * A LinuxInputDevice listens for events on a Linux
+ * input device node, typically one of the files in /dev/input. When events are
+ * waiting to be processed on the device it notifies its listener on a thread
+ * provided by its executor object. The executor should be a single-threaded
+ * ExecutorService that runs all tasks on the JavaFX application thread.
+ * <p>
+ * Event lines are accumulated in a buffer until an event "EV_SYN EV_SYN_REPORT
+ * 0" is received. At this point the listener is notified. The listener can then
+ * use the methods getEventType(), getEventCode() and getEventValue() to obtain
+ * the details of the current event line to process. nextEvent() and
+ * hasNextEvent() are used to iterate over pending events.
+ * <p>
+ * To save on RAM and GC, event lines are not objects.
+ */
+public class LinuxInputDevice implements Runnable, InputDevice {
+    private static final int EVENT_STRUCT_SIZE = 16;
+    private static final int EVENT_STRUCT_TYPE_INDEX = 8;
+    private static final int EVENT_STRUCT_CODE_INDEX = 10;
+    private static final int EVENT_STRUCT_VALUE_INDEX = 12;
+    /**
+     * EVENT_BUFFER_SIZE controls the maximum number of event lines that can be
+     * processed per device in one pulse. This value must be greater than the
+     * number of lines in the largest event including the terminating EV_SYN
+     * SYN_REPORT. However it sould not be too large or a flood of events will
+     * prevent rendering from happening until the buffer is full.
+     */
+    private static final int EVENT_BUFFER_SIZE = 100;
+
+    private LinuxInputProcessor inputProcessor;
+    private ReadableByteChannel in;
+    private File devNode;
+    private File sysPath;
+    private Map<String, BitSet> capabilities;
+    private Map<String, String> udevManifest;
+    private ByteBuffer bb = ByteBuffer.allocate(EVENT_STRUCT_SIZE * EVENT_BUFFER_SIZE);
+    private ByteBuffer event = ByteBuffer.allocate(EVENT_STRUCT_SIZE);
+    private ExecutorService executor;
+    private EventProcessor processor = new EventProcessor();
+    private int positionOfLastSync;
+    private int currentPosition;
+
+    /**
+     * Create a new com.sun.glass.ui.monocle.input.LinuxInputDevice on the given
+     * input node.
+     *
+     * @param devNode The node on which to listen for input
+     * @param sysPath The sysfs path describing the device
+     * @throws IOException
+     */
+    public LinuxInputDevice(
+            File devNode,
+            File sysPath,
+            Map<String, String> udevManifest) throws IOException {
+        this.devNode = devNode;
+        this.sysPath = sysPath;
+        this.udevManifest = udevManifest;
+        this.capabilities = SysFS.readCapabilities(sysPath);
+        this.in = new FileInputStream(devNode).getChannel();
+        this.executor = NativePlatformFactory.getNativePlatform().getExecutor();
+    }
+
+    public void setInputProcessor(LinuxInputProcessor inputProcessor) {
+        this.inputProcessor = inputProcessor;
+    }
+
+    @Override
+    public void run() {
+        if (inputProcessor == null) {
+            System.err.println("Error: no input processor set on " + devNode);
+            return;
+        }
+        bb.order(ByteOrder.nativeOrder());
+        while (true) {
+            try {
+                in.read(event);
+                if (event.position() == event.limit()) {
+                    event.flip();
+                    boolean isSync = event.getInt(EVENT_STRUCT_TYPE_INDEX) == 0
+                            && event.getInt(EVENT_STRUCT_CODE_INDEX) == 0;
+                    synchronized (bb) {
+                        while (bb.limit() - bb.position() < event.limit()) {
+                            // Block if bb is full. This should be the
+                            // only time this thread waits for anything
+                            // except for more event lines.
+                            bb.wait();
+                        }
+                        if (isSync) {
+                            positionOfLastSync = bb.position();
+                        }
+                        bb.put(event);
+                        if (isSync && !processor.scheduled) {
+                            executor.submit(processor);
+                            processor.scheduled = true;
+                        }
+                    }
+                    event.rewind();
+                }
+            } catch (IOException | InterruptedException e) {
+                // the device is disconnected
+                return;
+            }
+        }
+    }
+
+    /**
+     * The EventProcessor is used to notify listeners of pending events. It runs
+     * on the executor thread.
+     */
+    class EventProcessor implements Runnable {
+        boolean scheduled;
+
+        public void run() {
+            synchronized (bb) {
+                processor.scheduled = false;
+                currentPosition = 0;
+            }
+            // Do not lock bb while process events. We still want to be
+            // able to add incoming events to it.
+            inputProcessor.processEvents(LinuxInputDevice.this);
+            synchronized (bb) {
+                positionOfLastSync -= currentPosition;
+                int newLimit = bb.position();
+                bb.position(currentPosition);
+                bb.limit(newLimit);
+                bb.compact();
+                bb.notifyAll();
+            }
+        }
+    }
+
+    /**
+     * Returns the type of the current event line. Call from the application
+     * thread.
+     *
+     * @return the type of the current event line
+     */
+    public short getEventType() {
+        synchronized (bb) {
+            return bb.getShort(currentPosition + EVENT_STRUCT_TYPE_INDEX);
+        }
+    }
+
+    /**
+     * Returns the code of the current event line.  Call from the application
+     * thread.
+     *
+     * @return the code of the event line
+     */
+    public short getEventCode() {
+        synchronized (bb) {
+            return bb.getShort(currentPosition + EVENT_STRUCT_CODE_INDEX);
+        }
+    }
+
+    /**
+     * Returns the value of the current event line.  Call from the application
+     * thread.
+     *
+     * @return the value of the current event line
+     */
+    public int getEventValue() {
+        synchronized (bb) {
+            return bb.getInt(currentPosition + EVENT_STRUCT_VALUE_INDEX);
+        }
+    }
+
+    /**
+     * Returns a string describing the current event. Call from the application
+     * thread.
+     *
+     * @return a string describing the event
+     */
+    public String getEventDescription() {
+        short type = getEventType();
+        short code = getEventCode();
+        int value = getEventValue();
+        String typeStr = Input.typeToString(type);
+        return typeStr + " " + Input.codeToString(typeStr, code) + " " + value;
+    }
+
+    /**
+     * Advances to the next event line.  Call from the application thread.
+     */
+    public void nextEvent() {
+        synchronized (bb) {
+            if (currentPosition > positionOfLastSync) {
+                throw new IllegalStateException("Cannot advance past the last" +
+                        " EV_SYN EV_SYN_REPORT 0");
+            }
+            currentPosition += EVENT_STRUCT_SIZE;
+        }
+    }
+
+    /**
+     * Returns true iff another event line is available AND it is part of a
+     * complete event. Call from the application thread.
+     */
+    public boolean hasNextEvent() {
+        synchronized (bb) {
+            return currentPosition <= positionOfLastSync;
+        }
+    }
+
+    /**
+     * @return a string describing this input device
+     */
+    public String toString() {
+        return devNode.toString();
+    }
+
+    BitSet getCapability(String type) {
+        return capabilities.get(type);
+    }
+
+    @Override
+    public boolean isTouch() {
+        return "1".equals(udevManifest.get("ID_INPUT_TOUCHSCREEN"))
+                || "1".equals(udevManifest.get("ID_INPUT_TABLET"));
+    }
+
+    @Override
+    public boolean isMultiTouch() {
+        if (isTouch()) {
+            BitSet abs = capabilities.get("abs");
+            if (abs == null) {
+                return false;
+            }
+            return abs.get(Input.ABS_MT_SLOT)
+                    || (abs.get(Input.ABS_MT_POSITION_X)
+                        && abs.get(Input.ABS_MT_POSITION_Y));
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean isRelative() {
+        return "1".equals(udevManifest.get("ID_INPUT_MOUSE"));
+    }
+
+    @Override
+    public boolean is5Way() {
+        BitSet key = capabilities.get("key");
+        if (key == null) {
+            return false;
+        }
+        // Make sure we have all arrow keys
+        for (int i = 0; i < KeyBits.KEYBITS_ARROWS.length; i++) {
+            if (!key.get(KeyBits.KEYBITS_ARROWS[i])) {
+                return false;
+            }
+        }
+        // and at least one select key
+        for (int i = 0; i < KeyBits.KEYBITS_SELECT.length; i++) {
+            if (key.get(KeyBits.KEYBITS_SELECT[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isFullKeyboard() {
+        BitSet key = capabilities.get("key");
+        if (key == null) {
+            return false;
+        }
+        // Make sure we have all alphanumeric keys
+        for (int i = 0; i < KeyBits.KEYBITS_PC.length; i++) {
+            if (!key.get(KeyBits.KEYBITS_PC[i])) {
+                return false;
+            }
+        }
+        // ...and the 5-way keys
+        return is5Way();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxInputDeviceRegistry.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,113 @@
+/*
+ * 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.input.InputDeviceRegistry;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
+
+class LinuxInputDeviceRegistry extends InputDeviceRegistry {
+
+    LinuxInputDeviceRegistry() {
+        Map<File, LinuxInputDevice> deviceMap = new HashMap<>();
+        UdevListener udevListener = new UdevListener() {
+            @Override
+            public void udevEvent(String action, Map<String, String> event) {
+                String subsystem = event.get("SUBSYSTEM");
+                String devPath = event.get("DEVPATH");
+                String devName = event.get("DEVNAME");
+                if (subsystem != null && subsystem.equals("input")
+                        && devPath != null && devName != null) {
+                    try {
+                        File sysPath = new File("/sys", devPath);
+                        if (action.equals("add")
+                                || (action.equals("change")
+                                && !deviceMap.containsKey(sysPath))) {
+                            File devNode = new File(devName);
+                            LinuxInputDevice device = createDevice(
+                                    devNode, sysPath, event);
+                            if (device != null) {
+                                deviceMap.put(sysPath, device);
+                                devices.add(device);
+                            }
+                        } else if (action.equals("remove")) {
+                            LinuxInputDevice device = deviceMap.get(devPath);
+                            deviceMap.remove(devPath);
+                            if (device != null) {
+                                devices.remove(device);
+                            }
+                        }
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        };
+        Udev.getInstance().addListener(udevListener);
+        // Request updates for existing devices
+        SysFS.triggerUdevNotification("input");
+    }
+
+    private LinuxInputDevice createDevice(File devNode,
+                                          File sysPath,
+                                          Map<String, String> udevManifest)
+            throws IOException {
+        LinuxInputDevice device = new LinuxInputDevice(
+                devNode, sysPath, udevManifest);
+        LinuxInputProcessor processor = createInputProcessor(device);
+        if (processor == null) {
+            return null;
+        } else {
+            device.setInputProcessor(createInputProcessor(device));
+            Thread thread = new Thread(device);
+            thread.setName("Linux input: " + devNode.toString());
+            thread.setDaemon(true);
+            thread.start();
+            return device;
+        }
+    }
+
+    private LinuxInputProcessor createInputProcessor(LinuxInputDevice device) {
+        if (device.isTouch()) {
+            return new LinuxTouchProcessor();
+        } else if (device.isRelative()) {
+            return new LinuxMouseProcessor();
+        } else {
+            BitSet keyCaps = device.getCapability("key");
+            if (keyCaps != null && !keyCaps.isEmpty()) {
+                System.err.println("TODO: implement LinuxKeyboardProcessor");
+                return new LinuxInputProcessor.Logger();
+            } else {
+                return null;
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxInputProcessor.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 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;
+
+/**
+ * A com.sun.glass.ui.monocle.input.LinuxInputProcessor is registered with a
+ * com.sun.glass.ui.monocle.input.LinuxInputDevice when the device
+ * is created. The listener is then notified when events are waiting to be
+ * processed on the device.
+ */
+public interface LinuxInputProcessor {
+    /**
+     * Called when events are waiting on the input device to be processed.
+     * Called on the executor provided to the input device.
+     *
+     * @param device The device on which events are pending
+     */
+    public void processEvents(LinuxInputDevice device);
+
+    static class Logger implements LinuxInputProcessor {
+        @Override
+        public void processEvents(LinuxInputDevice device) {
+            while (device.hasNextEvent()) {
+                System.out.format("%1$ts.%1$tL %2$s: %3$s\n",
+                                  new java.util.Date(),
+                                  device, device.getEventDescription());
+                device.nextEvent();
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxMouseProcessor.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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.events.MouseEvent;
+import com.sun.glass.ui.monocle.input.MouseInput;
+import com.sun.glass.ui.monocle.input.MouseState;
+
+public class LinuxMouseProcessor implements LinuxInputProcessor {
+
+    private MouseState state = new MouseState();
+
+    @Override
+    public void processEvents(LinuxInputDevice device) {
+        MouseInput mouse = MouseInput.getInstance();
+        mouse.getState(state);
+        while (device.hasNextEvent()) {
+            switch (device.getEventType()) {
+                case Input.EV_REL:
+                    switch (device.getEventCode()) {
+                        case Input.REL_X:
+                            int x = state.getX();
+                            x += device.getEventValue();
+                            state.setX(x);
+                            break;
+                        case Input.REL_Y:
+                            int y = state.getY();
+                            y += device.getEventValue();
+                            state.setY(y);
+                            break;
+                        default:
+                            // Ignore other axes
+                    }
+                    break;
+                case Input.EV_SYN:
+                    switch (device.getEventCode()) {
+                        case Input.SYN_REPORT:
+                            mouse.setState(state);
+                            break;
+                        default: // ignore
+                    }
+                    break;
+                case Input.EV_KEY: {
+                    int button = mouseButtonForKeyCode(device.getEventCode());
+                    if (button >= 0) {
+                        if (device.getEventValue() == 0) {
+                            state.releaseButton(button);
+                        } else {
+                            state.pressButton(button);
+                        }
+                    }
+                    break;
+                }
+                default:
+                    // Ignore other events
+            }
+            device.nextEvent();
+        }
+
+    }
+
+    private static int mouseButtonForKeyCode(int keyCode) {
+        switch (keyCode) {
+            case Input.BTN_MOUSE:
+                return MouseEvent.BUTTON_LEFT;
+            case Input.BTN_MIDDLE:
+                return MouseEvent.BUTTON_OTHER;
+            case Input.BTN_RIGHT:
+                return MouseEvent.BUTTON_RIGHT;
+            default:
+                return -1;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxPlatform.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,31 @@
+package com.sun.glass.ui.monocle.linux;
+
+import com.sun.glass.ui.monocle.NativeCursor;
+import com.sun.glass.ui.monocle.NativePlatform;
+import com.sun.glass.ui.monocle.NativeScreen;
+import com.sun.glass.ui.monocle.NullCursor;
+import com.sun.glass.ui.monocle.input.InputDeviceRegistry;
+import com.sun.glass.utils.NativeLibLoader;
+
+/** LinuxPlatform matches any Linux system */
+public class LinuxPlatform extends NativePlatform {
+
+    public LinuxPlatform() {
+        NativeLibLoader.loadLibrary("glass_monocle");
+    }
+
+    @Override
+    protected InputDeviceRegistry createInputDeviceRegistry() {
+        return new LinuxInputDeviceRegistry();
+    }
+
+    @Override
+    protected NativeCursor createCursor() {
+        return new NullCursor();
+    }
+
+    @Override
+    protected NativeScreen createScreen() {
+        return new FBDevScreen();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxPlatformFactory.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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.NativePlatform;
+import com.sun.glass.ui.monocle.NativePlatformFactory;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class LinuxPlatformFactory extends NativePlatformFactory {
+
+    @Override
+    protected boolean matches() {
+        String os = AccessController.doPrivileged(
+                new PrivilegedAction<String>() {
+                    @Override
+                    public String run() {
+                        return System.getProperty("os.name");
+                    }
+                });
+        return os != null && os.equals("Linux");
+    }
+
+    @Override
+    protected NativePlatform createNativePlatform() {
+        return new LinuxPlatform();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/LinuxTouchProcessor.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,46 @@
+/*
+ * 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.input.TouchInput;
+import com.sun.glass.ui.monocle.input.TouchState;
+
+public class LinuxTouchProcessor implements LinuxInputProcessor {
+
+    private TouchState state = new TouchState();
+
+    @Override
+    public void processEvents(LinuxInputDevice device) {
+        TouchInput touch = TouchInput.getInstance();
+        touch.getState(state);
+        while (device.hasNextEvent()) {
+            System.out.println(device.getEventDescription());
+            device.nextEvent();
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/SysFS.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,154 @@
+/*
+ * 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.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SysFS {
+
+    /** Read input device capability data from sysfs */
+    static Map<String, BitSet> readCapabilities(File sysPath) {
+        Map<String, BitSet> capsMap = new HashMap<String, BitSet>();
+        File[] capsFiles = new File(sysPath, "device/capabilities").listFiles();
+        if (capsFiles == null) {
+            return capsMap;
+        }
+        for (int i = 0; i < capsFiles.length; i++) {
+            try {
+                BufferedReader r = new BufferedReader(new FileReader(capsFiles[i]));
+                String s = r.readLine();
+                r.close();
+                if (s == null) {
+                    continue;
+                }
+                String[] elements = s.split(" ");
+                if (elements == null) {
+                    continue;
+                }
+                byte[] b = new byte[elements.length * 4];
+                ByteBuffer bb = ByteBuffer.wrap(b);
+                bb.order(ByteOrder.LITTLE_ENDIAN);
+                IntBuffer ib = bb.asIntBuffer();
+                for (int j = elements.length - 1; j >= 0; j--) {
+                    ib.put(Integer.parseUnsignedInt(elements[j], 16));
+                }
+                capsMap.put(capsFiles[i].getName(), BitSet.valueOf(b));
+            } catch (IOException | RuntimeException e) {
+                e.printStackTrace();
+            }
+        }
+        return capsMap;
+    }
+
+    /** Fires udev notification events for devices of the given type */
+    public static void triggerUdevNotification(String sysClass) {
+        File[] devices = new File("/sys/class/" + sysClass).listFiles();
+        byte[] action = "change".getBytes();
+        for (File device: devices) {
+            File uevent = new File(device, "uevent");
+            if (uevent.exists()) {
+                try {
+                    write(uevent.getAbsolutePath(), action);
+                } catch (IOException e) {
+                    System.err.println("Udev: Failed to write to " + uevent);
+                    System.err.println("      Check that you have permission to access input devices");
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public static void write(String location, byte[] value) throws IOException {
+        FileOutputStream out = new FileOutputStream(location);
+        try {
+            out.write(value);
+        } finally {
+            out.close();
+        }
+    }
+
+    public static void write(String location, String value) throws IOException {
+        write(location, value.getBytes());
+    }
+
+    /** Read a comma-separated list of integer values from a file */
+    public static int[] readInts(String location, int expectedLength) throws IOException {
+        BufferedReader r = new BufferedReader(new FileReader(location));
+        String s = r.readLine();
+        r.close();
+        if (s != null && s.length() > 0) {
+            String[] elements = s.split(",");
+            try {
+                if (expectedLength == 0 || elements.length == expectedLength) {
+                    int[] xs = new int[elements.length];
+                    for (int i = 0; i < xs.length; i++) {
+                        xs[i] = Integer.parseInt(elements[i]);
+                    }
+                    return xs;
+                }
+            } catch (NumberFormatException e) {
+                // fall through to throw an IOException
+            }
+        }
+        if (expectedLength != 0) {
+            throw new IOException("Expected to find " + expectedLength
+                    + " integers in " + location + " but found '"
+                    + s + "'");
+        } else {
+            return new int[0];
+        }
+    }
+
+    /**
+     * Read a single integer value from a file
+     */
+    public static int readInt(String location) throws IOException {
+        BufferedReader r = new BufferedReader(new FileReader(location));
+        String s = r.readLine();
+        r.close();
+        try {
+            if (s != null && s.length() > 0) {
+                return Integer.parseInt(s);
+            } else {
+                throw new IOException(location + " does not contain an integer");
+            }
+        } catch (NumberFormatException e) {
+            throw new IOException(
+                    location + " does not contain an integer ('" + s + "'");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/Udev.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2010, 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.NativePlatformFactory;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Udev connects to the udev system to get updates on sysfs devices that
+ * are connected, disconnected and modified.
+ */
+public class Udev implements Runnable {
+    private static Udev instance;
+
+    private long fd;
+    private ByteBuffer buffer;
+    private Thread thread;
+    private UdevListener[] listeners;
+
+    /** Gets the singleton Udev object */
+    public static synchronized Udev getInstance() {
+        if (instance == null) {
+            try {
+                instance = new Udev();
+            } catch (IOException e) {
+                System.err.println("Udev: failed to open connection");
+                e.printStackTrace();
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * Creates a new Udev object
+     */
+    private Udev() throws IOException {
+        // Open a connection to the udev monitor
+        fd = _open();
+        buffer = ByteBuffer.allocateDirect(4096);
+        buffer.order(ByteOrder.nativeOrder());
+        thread = new Thread(this, "udev monitor");
+        thread.setDaemon(true);
+        thread.start();
+    }
+
+    public synchronized void addListener(UdevListener listener) {
+        if (listeners == null) {
+            listeners = new UdevListener[] { listener };
+        } else {
+            listeners = Arrays.copyOf(listeners, listeners.length + 1);
+            listeners[listeners.length - 1] = listener;
+        }
+    }
+
+    private native long _open() throws IOException;
+    private native int _readEvent(long fd, ByteBuffer buffer) throws
+            IOException;
+    private native void _close(long fd);
+    private native int _getPropertiesOffset(ByteBuffer buffer);
+    private native int _getPropertiesLength(ByteBuffer buffer);
+
+    @Override
+    public void run() {
+        try {
+            ExecutorService executor =
+                    NativePlatformFactory.getNativePlatform().getExecutor();
+            while (true) {
+                Map<String, String> event = readEvent();
+                executor.submit(new Runnable() {
+                    public void run() {
+                        String action = event.get("ACTION");
+                        if (action != null) {
+                            UdevListener[] uls;
+                            synchronized (this) {
+                                uls = listeners;
+                            }
+                            if (uls != null) {
+                                for (int i = 0; i < uls.length; i++) {
+                                    try {
+                                        uls[i].udevEvent(action, event);
+                                    } catch (RuntimeException e) {
+                                        System.err.println("Exception in udev listener:");
+                                        e.printStackTrace();
+                                    } catch (Error e) {
+                                        System.err.println("Error in udev listener, closing udev");
+                                        e.printStackTrace();
+                                        close();
+                                        return;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                });
+            }
+        } catch (IOException e) {
+            if (!thread.isInterrupted()) {
+                System.err.println("Exception in udev thread:");
+                e.printStackTrace();
+                close();
+            }
+        }
+    }
+
+    /** Reads data from the udev monitor. Blocks until data is available */
+    private Map<String, String> readEvent() throws IOException {
+        Map<String, String> map = new HashMap<>();
+        ByteBuffer b;
+        synchronized (this) {
+            b = buffer;
+            if (b == null) {
+                return map;
+            }
+        }
+        int length = _readEvent(fd, b);
+        synchronized (this) {
+            if (buffer == null) {
+                return map;
+            }
+            int propertiesOffset = _getPropertiesOffset(buffer);
+            int propertiesLength = _getPropertiesLength(buffer);
+            int propertiesEnd = propertiesOffset + propertiesLength;
+            if (length < propertiesEnd) {
+                throw new IOException("Mismatched property segment length");
+            }
+            buffer.position(propertiesOffset);
+            // Data read from the udev monitor is in the form of a list of
+            // lines separated by null bytes.
+            // Each line defines a key/value pair, with the
+            // format: <key>=<value><null terminator>
+            StringBuffer key = new StringBuffer();
+            StringBuffer value = new StringBuffer();
+            nextKey: while (buffer.position() < propertiesEnd) {
+                key.setLength(0);
+                value.setLength(0);
+                boolean readKey = false;
+                while (buffer.position() < length && !readKey) {
+                    char ch = (char) buffer.get();
+                    switch (ch) {
+                        case '\000': // no value on this line
+                            map.put(key.toString(), "");
+                            continue nextKey;
+                        case '=':
+                            readKey = true;
+                            break;
+                        default:
+                            key.append(ch);
+                    }
+                }
+                while (buffer.position() < propertiesEnd) {
+                    char ch = (char) buffer.get();
+                    switch (ch) {
+                        case '\000':
+                            map.put(key.toString(), value.toString());
+                            continue nextKey;
+                        default:
+                            value.append(ch);
+                    }
+                }
+            }
+            buffer.clear();
+        }
+        return map;
+    }
+
+    /** Closes the udev monitor connection */
+    public synchronized void close() {
+        thread.interrupt();
+        _close(fd);
+        fd = 0l;
+        buffer = null;
+        thread = null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/linux/UdevListener.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010, 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.util.Map;
+
+/**
+ * A UdevListener is registered with a Udev when the Udev
+ * is created. The listener is then called on the event thread when udev
+ * events are avaialable.
+ */
+public interface UdevListener {
+
+    /**
+     * Called when a udev event is available.
+     * Called on the executor provided to the Udev.
+     *
+     * @param action The udev action, usually "add", "remove", "change",
+     *               "online" or "offline.
+     * @param event a map of key/value pairs describing the event. These are
+     *              the key/value pairs received from udev.
+     */
+    public void udevEvent(String action, Map<String, String> event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/omap/OMAPCursor.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,100 @@
+/*
+ * 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.omap;
+
+import com.sun.glass.ui.Size;
+import com.sun.glass.ui.monocle.NativeCursor;
+import com.sun.glass.ui.monocle.linux.SysFS;
+
+import java.io.IOException;
+
+/** Cursor using a framebuffer overlay on OMAP3.
+ * TODO: Can we mmap the image and location files?
+ */
+public class OMAPCursor implements NativeCursor {
+
+    private int hotspotX;
+    private int hotspotY;
+
+    public OMAPCursor() {
+        try {
+            SysFS.write("/sys/class/graphics/fb1/virtual_size", "16,16");
+            SysFS.write("/sys/devices/platform/omapdss/overlay1/output_size", "16,16");
+        } catch (IOException e) {
+            System.err.println("Failed to initialize OMAP cursor");
+        }
+    }
+
+    @Override
+    public Size getBestSize() {
+        return new Size(16, 16);
+    }
+
+    @Override
+    public void setVisibility(boolean visibility) {
+        try {
+            SysFS.write("/sys/devices/platform/omapdss/overlay1/enabled",
+                        visibility ? "1" : "0");
+        } catch (IOException e) {
+            System.err.format("Failed to %s OMAP cursor\n",
+                              (visibility ? "enable" : "disable"));
+        }
+    }
+
+    @Override
+    public void setImage(byte[] cursorImage) {
+        try {
+            SysFS.write("/dev/fb1", cursorImage);
+        } catch (IOException e) {
+            System.err.println("Failed to write OMAP cursor image");
+        }
+    }
+
+    @Override
+    public void setLocation(int x, int y) {
+        try {
+            SysFS.write("/sys/devices/platform/omapdss/overlay1/position",
+                        (x - hotspotX) + "," + (y - hotspotY));
+        } catch (IOException e) {
+            System.err.println("Failed to set OMAP cursor position");
+        }
+    }
+
+    @Override
+    public void setHotSpot(int hotspotX, int hotspotY) {
+        this.hotspotX = hotspotX;
+        this.hotspotY = hotspotY;
+    }
+
+    @Override
+    public void shutdown() {
+        try {
+            SysFS.write("/sys/devices/platform/omapdss/overlay1/enabled", "0");
+        } catch (IOException e) {
+            System.err.println("Failed to shut down OMAP cursor");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/omap/OMAPPlatform.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,36 @@
+package com.sun.glass.ui.monocle.omap;/*
+ * 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.
+ */
+
+import com.sun.glass.ui.monocle.NativeCursor;
+import com.sun.glass.ui.monocle.linux.LinuxPlatform;
+
+public class OMAPPlatform extends LinuxPlatform {
+
+    @Override
+    protected NativeCursor createCursor() {
+        return new OMAPCursor();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/omap/OMAPPlatformFactory.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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.omap;
+
+import com.sun.glass.ui.monocle.NativePlatform;
+import com.sun.glass.ui.monocle.NativePlatformFactory;
+
+import java.io.File;
+
+public class OMAPPlatformFactory extends NativePlatformFactory {
+
+    @Override
+    protected boolean matches() {
+        return new File("/sys/devices/omapdss").exists();
+    }
+
+    @Override
+    protected NativePlatform createNativePlatform() {
+        return new OMAPPlatform();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/omapx11/OMAPX11Platform.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,37 @@
+package com.sun.glass.ui.monocle.omapx11;/*
+ * 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.
+ */
+
+import com.sun.glass.ui.monocle.NativeScreen;
+import com.sun.glass.ui.monocle.omap.OMAPPlatform;
+import com.sun.glass.ui.monocle.x11.X11Screen;
+
+public class OMAPX11Platform extends OMAPPlatform {
+
+    @Override
+    protected NativeScreen createScreen() {
+        return new X11Screen(false);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/omapx11/OMAPX11PlatformFactory.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,38 @@
+/*
+ * 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.omapx11;
+
+import com.sun.glass.ui.monocle.NativePlatform;
+import com.sun.glass.ui.monocle.omap.OMAPPlatformFactory;
+
+public class OMAPX11PlatformFactory extends OMAPPlatformFactory {
+
+    @Override
+    protected NativePlatform createNativePlatform() {
+        return new OMAPX11Platform();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/util/C.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.util;
+
+import java.nio.ByteBuffer;
+
+public class C {
+
+    public static abstract class Structure {
+        public final ByteBuffer b;
+        public final long p;
+        protected Structure() {
+            b = ByteBuffer.allocateDirect(sizeof());
+            p = GetDirectBufferAddress(b);
+        }
+        protected Structure(long ptr) {
+            b = NewDirectByteBuffer(ptr, sizeof());
+            p = ptr;
+        }
+        public abstract int sizeof();
+    }
+
+    private static native ByteBuffer NewDirectByteBuffer(long ptr, int size);
+    private static native long GetDirectBufferAddress(ByteBuffer b);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/util/IntSet.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,166 @@
+/*
+ * 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.util;
+
+import java.util.Arrays;
+
+/**
+ * Mutable sorted set of int values, optimized for a small number of values. Not
+ * thread-safe.
+ */
+public class IntSet {
+    private int[] elements = new int[4];
+    private int size = 0;
+
+    public void addInt(int value) {
+        int i = getIndex(value);
+        if (i < 0) {
+            int insertionPoint = -1 - i;
+            if (size == elements.length) {
+                elements = Arrays.copyOf(elements, size * 2);
+            }
+            if (insertionPoint != size) {
+            } else {
+                System.arraycopy(elements, insertionPoint,
+                                 elements, insertionPoint + 1,
+                                 size - insertionPoint);
+            }
+            elements[insertionPoint] = value;
+            size ++;
+        }
+    }
+
+    public void removeInt(int value) {
+        int i = getIndex(value);
+        if (i >= 0) {
+            if (i < size - 1) {
+                System.arraycopy(elements, i + 1, elements, i, size - i - 1);
+            }
+            size --;
+        }
+    }
+
+    public boolean containsInt(int value) {
+        return getIndex(value) >= 0;
+    }
+
+    private int getIndex(int value) {
+        for (int i = 0; i < size; i++) {
+            if (elements[i] == value) {
+                return i;
+            } else if (elements[i] > value) {
+                return -i - 1;
+            }
+        }
+        return -1;
+    }
+
+    public int get(int index) {
+        return elements[index];
+    }
+
+    /** Adds to the set "dest" values that are not in the set "compared". */
+    public void difference(IntSet dest, IntSet compared) {
+        int i = 0;
+        int j = 0;
+        while (i < size && j < compared.size) {
+            int a = elements[i];
+            int b = elements[j];
+            if (a < b) {
+                // our set has a value that is not in "compared"
+                dest.addInt(a);
+                i ++;
+            } else if (a > b) {
+                // "compared" has a value that is not in our set.
+                j ++;
+            } else {
+                // the sets match at this index.
+                i ++;
+                j ++;
+            }
+        }
+        // anything left in our set is part of the delta and belongs in "dest".
+        while (i < size) {
+            dest.addInt(elements[i]);
+            i ++;
+        }
+    }
+
+    public void clear() {
+        size = 0;
+    }
+
+    public int size() {
+        return size;
+    }
+
+    public boolean isEmpty() {
+        return size == 0;
+    }
+
+    /** Copies the contents of this set to the target set. */
+    public void copyTo(IntSet target) {
+        if (target.elements.length > size) {
+            target.elements = Arrays.copyOf(elements, elements.length);
+        } else {
+            System.arraycopy(elements, 0, target.elements, 0, size);
+        }
+        target.size = size;
+    }
+
+    public boolean equals(IntSet set) {
+        if (set.size == size) {
+            for (int i = 0; i < size; i++) {
+                if (set.elements[i] != elements[i]) {
+                    return false;
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean equals(Object o) {
+        if (o instanceof IntSet) {
+            return equals((IntSet) o);
+        } else {
+            return false;
+        }
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer("IntSet[");
+        for (int i = 0; i < size; i++) {
+            sb.append(elements[i]);
+            if (i < size - 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/x11/X.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,114 @@
+/*
+ * 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.x11;
+
+import com.sun.glass.ui.monocle.util.C;
+import com.sun.glass.utils.NativeLibLoader;
+
+public class X {
+
+    static {
+        NativeLibLoader.loadLibrary("glass_monocle_x11");
+    }
+
+    static final long None = 0l;
+    static final int CopyFromParent = 0;
+    static final int InputOutput = 1;
+
+    static final long ButtonPressMask = 1l << 2;
+    static final long ButtonReleaseMask = 1l << 3;
+    static final long PointerMotionMask = 1l << 6;
+
+    static final long CWEventMask = 1l << 11;
+    static final long CWCursorMask = 1l << 14;
+
+    static final int ButtonPress = 4;
+    static final int ButtonRelease = 5;
+    static final int MotionNotify = 6;
+
+    static final int Button1 = 1;
+    static final int Button2 = 2;
+    static final int Button3 = 3;
+    static final int Button4 = 4;
+    static final int Button5 = 5;
+
+    static class XSetWindowAttributes extends C.Structure {
+        @Override
+        public native int sizeof();
+        static native void setEventMask(long p, long mask);
+        static native void setCursor(long p, long cursor);
+    }
+
+    static class XEvent extends C.Structure {
+        XEvent(long p) {
+            super(p);
+        }
+        XEvent() {
+            super();
+        }
+        @Override
+        public native int sizeof();
+        static native int getType(long p);
+        static native long getWindow(long p);
+    }
+
+    static class XButtonEvent extends XEvent {
+        XButtonEvent(XEvent event) {
+            super(event.p);
+        }
+        static native int getButton(long p);
+    }
+
+    static class XMotionEvent extends XEvent {
+        XMotionEvent(XEvent event) {
+            super(event.p);
+        }
+        static native int getX(long p);
+        static native int getY(long p);
+    }
+
+    static native long XOpenDisplay(String displayName);
+    static native long DefaultScreenOfDisplay(long display);
+    static native long RootWindowOfScreen(long screen);
+    static native int WidthOfScreen(long screen);
+    static native int HeightOfScreen(long screen);
+    static native long XCreateWindow(
+            long display, long parent,
+            int x, int y, int width, int height,
+            int borderWidth, int depth, int windowClass,
+            long visual, long valueMask,
+            long attributes);
+    static native void XMapWindow(long display, long window);
+    static native void XStoreName(long display, long window, String name);
+    static native void XSync(long display, boolean flush);
+    static native void XGetGeometry(long display, long window,
+                                    long[] root,
+                                    int[] x, int[] y,
+                                    int[] width, int[] height,
+                                    int[] borderWidth, int[] depth);
+    static native void XNextEvent(long display, long xevent);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11InputDeviceRegistry.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,179 @@
+/*
+ * 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.x11;
+
+import com.sun.glass.events.MouseEvent;
+import com.sun.glass.ui.monocle.NativePlatform;
+import com.sun.glass.ui.monocle.NativePlatformFactory;
+import com.sun.glass.ui.monocle.input.InputDevice;
+import com.sun.glass.ui.monocle.input.InputDeviceRegistry;
+import com.sun.glass.ui.monocle.input.MouseInput;
+import com.sun.glass.ui.monocle.input.MouseState;
+
+import java.util.concurrent.ExecutorService;
+
+class X11InputDeviceRegistry extends InputDeviceRegistry {
+
+    private MouseState state;
+
+    X11InputDeviceRegistry() {
+        InputDevice device = new InputDevice() {
+            @Override
+            public boolean isTouch() {
+                return false;
+            }
+
+            @Override
+            public boolean isMultiTouch() {
+                return false;
+            }
+
+            @Override
+            public boolean isRelative() {
+                return true;
+            }
+
+            @Override
+            public boolean is5Way() {
+                return false;
+            }
+
+            @Override
+            public boolean isFullKeyboard() {
+                return false;
+            }
+        };
+        Thread x11InputThread = new Thread(new Runnable() {
+            public void run() {
+                NativePlatform platform =
+                        NativePlatformFactory.getNativePlatform();
+                X11Screen screen = (X11Screen) platform.getScreen();
+                long display = screen.getDisplay();
+                long window = screen.getNativeHandle();
+                ExecutorService executor = platform.getExecutor();
+                executor.submit(new Runnable() {
+                    public void run() {
+                        devices.add(device);
+                    }
+                });
+                state = new MouseState();
+                X.XEvent event = new X.XEvent();
+                while (true) {
+                    X.XNextEvent(display, event.p);
+                    if (X.XEvent.getWindow(event.p) != window) {
+                        continue;
+                    }
+                    processXEvent(event, executor);
+                }
+            }
+        });
+        x11InputThread.setName("X11 Input");
+        x11InputThread.setDaemon(true);
+        x11InputThread.start();
+    }
+
+    private void processXEvent(X.XEvent event, ExecutorService executor) {
+        switch (X.XEvent.getType(event.p)) {
+            case X.ButtonPress: {
+                X.XButtonEvent buttonEvent = new X.XButtonEvent(event);
+                int button = X.XButtonEvent.getButton(buttonEvent.p);
+                executor.submit(new ButtonPressProcessor(button));
+                break;
+            }
+            case X.ButtonRelease: {
+                X.XButtonEvent buttonEvent = new X.XButtonEvent(event);
+                int button = X.XButtonEvent.getButton(buttonEvent.p);
+                executor.submit(new ButtonReleaseProcessor(button));
+                break;
+            }
+            case X.MotionNotify: {
+                X.XMotionEvent motionEvent = new X.XMotionEvent(event);
+                int x = X.XMotionEvent.getX(motionEvent.p);
+                int y = X.XMotionEvent.getY(motionEvent.p);
+                executor.submit(new MotionProcessor(x, y));
+                break;
+            }
+        }
+    }
+
+    private class ButtonPressProcessor implements Runnable {
+        private int button;
+        ButtonPressProcessor(int button) {
+            this.button = button;
+        }
+        @Override
+        public void run() {
+            MouseInput.getInstance().getState(state);
+            int glassButton = buttonToGlassButton(button);
+            if (glassButton != MouseEvent.BUTTON_NONE) {
+                state.pressButton(glassButton);
+            }
+            MouseInput.getInstance().setState(state);
+        }
+    }
+
+    private class ButtonReleaseProcessor implements Runnable {
+        private int button;
+        ButtonReleaseProcessor(int button) {
+            this.button = button;
+        }
+        @Override
+        public void run() {
+            MouseInput.getInstance().getState(state);
+            int glassButton = buttonToGlassButton(button);
+            if (glassButton != MouseEvent.BUTTON_NONE) {
+                state.releaseButton(glassButton);
+            }
+            MouseInput.getInstance().setState(state);
+        }
+    }
+
+    private class MotionProcessor implements Runnable {
+        private int x;
+        private int y;
+        MotionProcessor(int x, int y) {
+            this.x = x;
+            this.y = y;
+        }
+        @Override
+        public void run() {
+            MouseInput.getInstance().getState(state);
+            state.setX(x);
+            state.setY(y);
+            MouseInput.getInstance().setState(state);
+        }
+    }
+
+    private static int buttonToGlassButton(int button) {
+        switch (button) {
+            case X.Button1: return MouseEvent.BUTTON_LEFT;
+            case X.Button2: return MouseEvent.BUTTON_OTHER;
+            case X.Button3: return MouseEvent.BUTTON_RIGHT;
+            default: return MouseEvent.BUTTON_NONE;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11Platform.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,49 @@
+package com.sun.glass.ui.monocle.x11;/*
+ * 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.
+ */
+
+import com.sun.glass.ui.monocle.NativeCursor;
+import com.sun.glass.ui.monocle.NativePlatform;
+import com.sun.glass.ui.monocle.NativeScreen;
+import com.sun.glass.ui.monocle.NullCursor;
+import com.sun.glass.ui.monocle.input.InputDeviceRegistry;
+
+public class X11Platform extends NativePlatform {
+
+    @Override
+    protected InputDeviceRegistry createInputDeviceRegistry() {
+        return new X11InputDeviceRegistry();
+    }
+
+    @Override
+    protected NativeCursor createCursor() {
+        return new NullCursor();
+    }
+
+    @Override
+    protected NativeScreen createScreen() {
+        return new X11Screen(true);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11PlatformFactory.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,43 @@
+/*
+ * 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.x11;
+
+import com.sun.glass.ui.monocle.NativePlatform;
+import com.sun.glass.ui.monocle.NativePlatformFactory;
+
+public class X11PlatformFactory extends NativePlatformFactory {
+
+    @Override
+    protected boolean matches() {
+        return true;
+    }
+
+    @Override
+    protected NativePlatform createNativePlatform() {
+        return new X11Platform();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/monocle/x11/X11Screen.java	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2010, 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.x11;
+
+import com.sun.glass.ui.Pixels;
+import com.sun.glass.ui.monocle.NativeScreen;
+
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class X11Screen implements NativeScreen {
+
+    private int depth;
+    private int nativeFormat;
+    private int width;
+    private int height;
+    private long nativeHandle;
+    private long display;
+
+    public X11Screen(boolean showCursor) {
+        display = X.XOpenDisplay(null);
+        if (display == 0l) {
+            throw new NullPointerException("Cannot open X11 display");
+        }
+        long screen = X.DefaultScreenOfDisplay(display);
+        X.XSetWindowAttributes attrs = new X.XSetWindowAttributes();
+        attrs.setEventMask(attrs.p,
+                           X.ButtonPressMask | X.ButtonReleaseMask
+                                   | X.PointerMotionMask);
+        long cwMask = X.CWEventMask;
+        if (!showCursor) {
+            cwMask |= X.CWCursorMask;
+            attrs.setCursor(attrs.p, X.None);
+        }
+        int x = 0;
+        int y = 0;
+        int w = X.WidthOfScreen(screen);
+        int h = X.HeightOfScreen(screen);
+        String geometry = AccessController.doPrivileged(new PrivilegedAction<String>() {
+            @Override
+            public String run() {
+                return System.getProperty("x11.geometry");
+            }
+        });
+        if (geometry != null) {
+            try {
+                String size;
+                if (geometry.contains(",")) {
+                    // use the first two numbers for x and y
+                    String location;
+                    int i = geometry.indexOf("+");
+                    if (i >= 0) {
+                        location = geometry.substring(0, i);
+                        size = geometry.substring(i + 1);
+                    } else {
+                        location = geometry;
+                        size = "";
+                    }
+                    i = location.indexOf(",");
+                    x = Integer.parseInt(location.substring(0, i));
+                    y = Integer.parseInt(location.substring(i + 1));
+                } else {
+                    size = geometry;
+                }
+                if (size.length() > 0) {
+                    int i = size.indexOf("x");
+                    w = Integer.parseInt(size.substring(0, i));
+                    h = Integer.parseInt(size.substring(i + 1));
+                }
+            } catch (NumberFormatException e) {
+                System.err.println("Cannot parse geometry string: '"
+                        + geometry + "'");
+            }
+        }
+        long window = X.XCreateWindow(
+                display,
+                X.RootWindowOfScreen(screen),
+                x, y, w, h,
+                0, // border width
+                X.CopyFromParent, // depth
+                X.InputOutput, // class
+                X.CopyFromParent, // visual
+                cwMask,
+                attrs.p);
+        X.XMapWindow(display, window);
+        X.XStoreName(display, window, "JavaFX EGL/framebuffer container");
+        X.XSync(display, false);
+        int[] widthA = new int[1];
+        int[] heightA = new int[1];
+        int[] depthA = new int[1];
+        X.XGetGeometry(display, window, null, null, null, widthA, heightA, null, depthA);
+        width = widthA[0];
+        height = heightA[0];
+        depth = depthA[0];
+        nativeFormat = Pixels.Format.BYTE_BGRA_PRE;
+        nativeHandle = window;
+    }
+
+    @Override
+    public int getDepth() {
+        return depth;
+    }
+
+    @Override
+    public int getNativeFormat() {
+        return nativeFormat;
+    }
+
+    @Override
+    public int getWidth() {
+        return width;
+    }
+
+    @Override
+    public int getHeight() {
+        return height;
+    }
+
+    @Override
+    public long getNativeHandle() {
+        return nativeHandle;
+    }
+
+    @Override
+    public int getDPI() {
+        return 96;
+    }
+
+    @Override
+    public void shutdown() {
+    }
+
+    long getDisplay() {
+        return display;
+    }
+
+    @Override
+    public void uploadPixels(ByteBuffer b, int x, int y, int width, int height) {
+        // TODO: upload pixels to X11 window
+    }
+
+    @Override
+    public void swapBuffers() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/monocle/Monocle.h	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#ifdef __GNUC__
+#define UNUSED(x) x __attribute__((unused))
+#else
+#define UNUSED(x) x
+#endif
+
+#define asPtr(x) ((void *) (unsigned long) (x))
+#define asJLong(x) ((jlong) (unsigned long) (x))
+
+void monocle_returnInt(JNIEnv *env, jintArray buffer, jint value);
+
+void monocle_returnLong(JNIEnv *env, jlongArray buffer, jlong value);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/monocle/linux/Udev.c	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,188 @@
+/*
+ * 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_Udev.h"
+#include "Monocle.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <linux/un.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+
+/** The udev event header structures are defined here so that we can extract
+ * elements from them. There are multiple versions of the header; we determine
+ * at run-time which is being used. */
+typedef struct {
+    char prefix[8];
+    unsigned int magic;
+    unsigned int _;
+    unsigned int propertiesOffset;
+    unsigned int propertiesLength;
+} udev_event_header_A;
+
+typedef struct {
+	char prefix[16];
+	unsigned int magic;
+	unsigned short propertiesOffset;
+	unsigned short propertiesLength;
+} udev_event_header_B;
+
+#define UDEV_MONITOR_MAGIC_A htonl(0xfeedcafe)
+#define UDEV_MONITOR_MAGIC_B htonl(0xcafe1dea)
+
+typedef enum {
+    EVENT_FORMAT_UNKNOWN, EVENT_FORMAT_A, EVENT_FORMAT_B, EVENT_FORMAT_INVALID
+} EventFormat;
+
+static EventFormat getEventFormat(void *event) {
+    static EventFormat eventFormat = EVENT_FORMAT_UNKNOWN;
+    if (eventFormat == EVENT_FORMAT_UNKNOWN) {
+        udev_event_header_A *a = (udev_event_header_A *) event;
+        if (a->magic == UDEV_MONITOR_MAGIC_A) {
+            eventFormat = EVENT_FORMAT_A;
+            return eventFormat;
+        }
+        udev_event_header_B *b = (udev_event_header_B *) event;
+        if (b->magic == UDEV_MONITOR_MAGIC_B) {
+            eventFormat = EVENT_FORMAT_B;
+            return eventFormat;
+        }
+        eventFormat = EVENT_FORMAT_INVALID;
+        uint32_t *u = (uint32_t *) event;
+        fprintf(stderr, "Cannot identify udev event format:\n");
+        fprintf(stderr, "00 %08x %08x %08x %08x\n", u[0], u[1], u[2], u[3]);
+        fprintf(stderr, "10 %08x %08x %08x %08x\n", u[4], u[5], u[6], u[7]);
+        fprintf(stderr, "20 %08x %08x %08x %08x\n", u[8], u[9], u[10], u[11]);
+    }
+    return eventFormat;
+}
+
+static void monocle_IOException(JNIEnv *env, const char *msg) {
+    char msgBuffer[1024];
+    snprintf(msgBuffer, sizeof(msgBuffer),
+            "%s (errno=%i, %s)", msg, errno, strerror(errno));
+    jclass cls = (*env)->FindClass(env, "java/io/IOException");
+    if (cls) {
+        (*env)->ThrowNew(env, cls, msgBuffer);
+    } else {
+        fprintf(stderr, "IOException: %s", msgBuffer);
+        exit(1);
+    }
+}
+
+static void monocle_close(JNIEnv UNUSED(*env), int fd) {
+    if (fd > 0) {
+        close(fd);
+    }
+}
+
+ JNIEXPORT jlong JNICALL
+ Java_com_sun_glass_ui_monocle_linux_Udev__1open
+ (JNIEnv *env, jobject UNUSED(jUdev)) {
+    int fd;
+    struct sockaddr_nl addrS;
+    int bufferSize = 16384;
+    memset(&addrS, 0, sizeof(addrS));
+    addrS.nl_family = AF_NETLINK;
+    addrS.nl_pid = getpid();
+    addrS.nl_groups = 2;
+    fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+    if (fd == -1) {
+        monocle_IOException(env, "Cannot create netlink socket");
+        return 0;
+    }
+    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
+    if (bind(fd, (struct sockaddr *) &addrS, sizeof(addrS))) {
+        monocle_close(env, fd);
+        monocle_IOException(env, "Cannot bind netlink socket");
+        return 0l;
+     }
+
+     return (jlong) fd;
+ }
+
+JNIEXPORT jint JNICALL
+Java_com_sun_glass_ui_monocle_linux_Udev__1readEvent
+(JNIEnv *env, jobject UNUSED(jUdev), jlong fdL, jobject bufferObj) {
+    int fd = (int) fdL;
+    char *buffer = (char *) (*env)->GetDirectBufferAddress(env, bufferObj);
+    size_t bufferCapacity = (*env)->GetDirectBufferCapacity(env, bufferObj);
+    if (fd <= 0) {
+        monocle_IOException(env, "Invalid socket descriptor");
+    }
+    if (buffer == NULL) {
+        monocle_IOException(env, "Invalid buffer");
+    }
+    jint length = (jint) recv(fd, buffer, bufferCapacity, 0);
+    if (length <= 0) {
+        monocle_IOException(env, "Error receiving event");
+        return 0;
+    }
+    return length;
+}
+
+JNIEXPORT void JNICALL
+Java_com_sun_glass_ui_monocle_linux_Udev__1close
+(JNIEnv *env, jobject UNUSED(jUdev), jlong fdL) {
+    monocle_close(env, (int) fdL);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_sun_glass_ui_monocle_linux_Udev__1getPropertiesOffset
+(JNIEnv *env, jobject UNUSED(jUdev), jobject bufferObj) {
+    void *buffer = (*env)->GetDirectBufferAddress(env, bufferObj);
+    switch (getEventFormat(buffer)) {
+        case EVENT_FORMAT_A:
+            return (jint) ((udev_event_header_A *) buffer)->propertiesOffset;
+            break;
+        case EVENT_FORMAT_B:
+            return (jint) ((udev_event_header_B *) buffer)->propertiesOffset;
+            break;
+        default:
+            return -1;
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_com_sun_glass_ui_monocle_linux_Udev__1getPropertiesLength
+(JNIEnv *env, jobject UNUSED(jUdev), jobject bufferObj) {
+    void *buffer = (*env)->GetDirectBufferAddress(env, bufferObj);
+    switch (getEventFormat(buffer)) {
+        case EVENT_FORMAT_A:
+            return (jint) ((udev_event_header_A *) buffer)->propertiesLength;
+            break;
+        case EVENT_FORMAT_B:
+            return (jint) ((udev_event_header_B *) buffer)->propertiesLength;
+            break;
+        default:
+            return -1;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/monocle/util/C.c	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * 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_util_C.h"
+#include "monocle.h"
+
+JNIEXPORT jobject JNICALL
+ Java_com_sun_glass_ui_monocle_util_C_NewDirectByteBuffer
+    (JNIEnv *env, jclass UNUSED(cClass), jlong ptr, jint size) {
+    return (*env)->NewDirectByteBuffer(env,
+            (void *) (unsigned long) ptr, (jlong) size);
+}
+
+JNIEXPORT jlong JNICALL
+ Java_com_sun_glass_ui_monocle_util_C_GetDirectBufferAddress
+    (JNIEnv *env, jclass UNUSED(cClass), jobject byteBuffer) {
+    return byteBuffer
+            ? asJLong((*env)->GetDirectBufferAddress(env, byteBuffer))
+            : (jlong) 0l;
+}
+
+void monocle_returnInt(JNIEnv *env, jintArray buffer, jint value) {
+    if (buffer && (*env)->GetArrayLength(env, buffer) > 0) {
+        (*env)->SetIntArrayRegion(env, buffer, 0, 1, &value);
+    }
+}
+
+void monocle_returnLong(JNIEnv *env, jlongArray buffer, jlong value) {
+    if (buffer && (*env)->GetArrayLength(env, buffer) > 0) {
+        (*env)->SetLongArrayRegion(env, buffer, 0, 1, &value);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/monocle/x11/X11.c	Wed Jan 08 19:38:13 2014 +0200
@@ -0,0 +1,199 @@
+/*
+ * 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_x11_X.h"
+#include <X11/Xlib.h>
+#include "monocle.h"
+
+JNIEXPORT jlong JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_XOpenDisplay
+ (JNIEnv *env, jclass UNUSED(xClass), jstring displayName) {
+    const char *s = NULL;
+    if (displayName) {
+        s = (*env)->GetStringUTFChars(env, displayName, NULL);
+    }
+    Display *display = XOpenDisplay(s);
+    if (displayName) {
+        (*env)->ReleaseStringUTFChars(env, displayName, s);
+    }
+    return asJLong(display);
+}
+
+JNIEXPORT jlong JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_DefaultScreenOfDisplay
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass), jlong display) {
+    Screen *screen = DefaultScreenOfDisplay((Display *) asPtr(display));
+    return asJLong(screen);
+}
+
+JNIEXPORT jlong JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_RootWindowOfScreen
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass), jlong screen) {
+    return asJLong(RootWindowOfScreen((Screen *) asPtr(screen)));
+}
+
+JNIEXPORT jint JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_WidthOfScreen
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass), jlong screen) {
+    return (jint) WidthOfScreen((Screen *) asPtr(screen));
+}
+
+JNIEXPORT jint JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_HeightOfScreen
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass), jlong screen) {
+    return (jint) HeightOfScreen((Screen *) asPtr(screen));
+}
+
+JNIEXPORT jlong JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_XCreateWindow
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass),
+        jlong display, jlong parent,
+        jint x, jint y, jint width, jint height,
+        jint borderWidth, jint depth, jint windowClass,
+        jlong visual, jlong valueMask, jlong attributes) {
+    return asJLong(XCreateWindow(
+            (Display *) asPtr(display), (Window) parent,
+            (int) x, (int) y, (int) width, (int) height,
+            (int) borderWidth, (int) depth, (int) windowClass,
+            (Visual *) asPtr(visual), (long) valueMask,
+            (XSetWindowAttributes *) asPtr(attributes)));
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_XMapWindow
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass), jlong display, jlong window) {
+    XMapWindow((Display *) asPtr(display), (Window) window);
+}
+
+JNIEXPORT jint JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_00024XSetWindowAttributes_sizeof
+ (JNIEnv *UNUSED(env), jobject UNUSED(obj)) {
+    return (jint) sizeof(XSetWindowAttributes);
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_00024XSetWindowAttributes_setEventMask
+ (JNIEnv *UNUSED(env), jclass UNUSED(attrClass), jlong attrsL, jlong mask) {
+    XSetWindowAttributes *attrs = (XSetWindowAttributes *) asPtr(attrsL);
+    attrs->event_mask = (unsigned long) mask;
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_00024XSetWindowAttributes_setCursor
+ (JNIEnv *UNUSED(env), jclass UNUSED(attrClass), jlong attrsL, jlong cursor) {
+    XSetWindowAttributes *attrs = (XSetWindowAttributes *) asPtr(attrsL);
+    attrs->cursor = (Cursor) cursor;
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_XStoreName
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass), jlong display, jlong window,
+        jstring nameString) {
+    const char *name = NULL;
+    if (nameString) {
+        name = (*env)->GetStringUTFChars(env, nameString, NULL);
+    }
+    XStoreName((Display *) asPtr(display), (Window) window, name);
+    if (nameString) {
+        (*env)->ReleaseStringUTFChars(env, nameString, name);
+    }
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_XSync
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass), jlong display, jboolean flush) {
+    XSync((Display *) asPtr(display), flush ? True : False);
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_XGetGeometry
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass),
+        jlong display, jlong window,
+        jlongArray rootBuffer,
+        jintArray xBuffer, jintArray yBuffer,
+        jintArray widthBuffer, jintArray heightBuffer,
+        jintArray borderWidthBuffer, jintArray depthBuffer) {
+    Window root;
+    int x, y;
+    unsigned int width, height, borderWidth, depth;
+    XGetGeometry((Display *) asPtr(display), (Window) window,
+            &root, &x, &y, &width, &height, &borderWidth, &depth);
+    monocle_returnLong(env, rootBuffer, root);
+    monocle_returnInt(env, xBuffer, x);
+    monocle_returnInt(env, yBuffer, y);
+    monocle_returnInt(env, widthBuffer, width);
+    monocle_returnInt(env, heightBuffer, height);
+    monocle_returnInt(env, borderWidthBuffer, borderWidth);
+    monocle_returnInt(env, depthBuffer, depth);
+}
+
+JNIEXPORT jint JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_00024XEvent_sizeof
+ (JNIEnv *UNUSED(env), jobject UNUSED(obj)) {
+    return (jint) sizeof(XEvent);
+}
+
+JNIEXPORT void JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_XNextEvent
+ (JNIEnv *UNUSED(env), jclass UNUSED(xClass),
+        jlong display, jlong eventL) {
+    XNextEvent((Display *) asPtr(display),
+               (XEvent *) asPtr(eventL));
+}
+
+JNIEXPORT jlong JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_00024XEvent_getWindow
+ (JNIEnv *UNUSED(env), jclass UNUSED(eClass), jlong eventL) {
+    XEvent *event = (XEvent *) asPtr(eventL);
+    return (jlong) event->xany.window;
+}
+
+JNIEXPORT jint JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_00024XEvent_getType
+ (JNIEnv *UNUSED(env), jclass UNUSED(eClass), jlong eventL) {
+    XEvent *event = (XEvent *) asPtr(eventL);
+    return (jint) event->type;
+}
+
+JNIEXPORT jint JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_00024XButtonEvent_getButton
+ (JNIEnv *UNUSED(env), jclass UNUSED(eClass), jlong eventL) {
+    XButtonEvent *event = (XButtonEvent *) asPtr(eventL);
+    return (jint) event->button;
+}
+
+JNIEXPORT jint JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_00024XMotionEvent_getX
+ (JNIEnv *UNUSED(env), jclass UNUSED(eClass), jlong eventL) {
+    XMotionEvent *event = (XMotionEvent *) asPtr(eventL);
+    return (jint) event->x;
+}
+
+JNIEXPORT jint JNICALL
+ Java_com_sun_glass_ui_monocle_x11_X_00024XMotionEvent_getY
+ (JNIEnv *UNUSED(env), jclass UNUSED(eClass), jlong eventL) {
+    XMotionEvent *event = (XMotionEvent *) asPtr(eventL);
+    return (jint) event->y;
+}