8166772: Touch keyboard is not shown for text components on a screen touch
authoralitvinov
Wed, 11 Oct 2017 15:53:25 +0100
changeset 47384 3b244a98d5ab
parent 47383 74429839ae97
child 47385 8d56044a9850
8166772: Touch keyboard is not shown for text components on a screen touch Reviewed-by: serb, azvegint
src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifDesktopIconUI.java
src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifInternalFrameTitlePane.java
src/java.desktop/share/classes/java/awt/Component.java
src/java.desktop/share/classes/java/awt/Container.java
src/java.desktop/share/classes/java/awt/event/MouseEvent.java
src/java.desktop/share/classes/javax/swing/Autoscroller.java
src/java.desktop/share/classes/javax/swing/JList.java
src/java.desktop/share/classes/javax/swing/JTable.java
src/java.desktop/share/classes/javax/swing/JTree.java
src/java.desktop/share/classes/javax/swing/MenuSelectionManager.java
src/java.desktop/share/classes/javax/swing/SwingUtilities.java
src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboPopup.java
src/java.desktop/share/classes/javax/swing/table/JTableHeader.java
src/java.desktop/share/classes/sun/awt/AWTAccessor.java
src/java.desktop/share/classes/sun/awt/SunToolkit.java
src/java.desktop/share/classes/sun/swing/FilePane.java
src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java
src/java.desktop/windows/native/libawt/windows/awt.h
src/java.desktop/windows/native/libawt/windows/awt_Component.cpp
src/java.desktop/windows/native/libawt/windows/awt_Component.h
src/java.desktop/windows/native/libawt/windows/awt_MouseEvent.cpp
src/java.desktop/windows/native/libawt/windows/awt_MouseEvent.h
src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h
--- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifDesktopIconUI.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifDesktopIconUI.java	Wed Oct 11 15:53:25 2017 +0100
@@ -36,6 +36,8 @@
 import java.util.EventListener;
 import java.io.Serializable;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
 
 /**
  * Motif rendition of the component.
@@ -238,11 +240,15 @@
         }
         @SuppressWarnings("deprecation")
         void forwardEventToParent(MouseEvent e) {
-            getParent().dispatchEvent(new MouseEvent(
+            MouseEvent newEvent = new MouseEvent(
                 getParent(), e.getID(), e.getWhen(), e.getModifiers(),
                 e.getX(), e.getY(), e.getXOnScreen(),
                 e.getYOnScreen(), e.getClickCount(),
-                e.isPopupTrigger(), MouseEvent.NOBUTTON));
+                e.isPopupTrigger(), MouseEvent.NOBUTTON);
+            MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+            meAccessor.setCausedByTouchEvent(newEvent,
+                meAccessor.isCausedByTouchEvent(e));
+            getParent().dispatchEvent(newEvent);
         }
 
         @SuppressWarnings("deprecation")
@@ -331,10 +337,14 @@
         }
         @SuppressWarnings("deprecation")
         void forwardEventToParent(MouseEvent e) {
-            getParent().dispatchEvent(new MouseEvent(
+            MouseEvent newEvent = new MouseEvent(
                 getParent(), e.getID(), e.getWhen(), e.getModifiers(),
                 e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(),
-                e.getClickCount(), e.isPopupTrigger(), MouseEvent.NOBUTTON ));
+                e.getClickCount(), e.isPopupTrigger(), MouseEvent.NOBUTTON );
+            MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+            meAccessor.setCausedByTouchEvent(newEvent,
+                meAccessor.isCausedByTouchEvent(e));
+            getParent().dispatchEvent(newEvent);
         }
 
         @SuppressWarnings("deprecation")
--- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifInternalFrameTitlePane.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifInternalFrameTitlePane.java	Wed Oct 11 15:53:25 2017 +0100
@@ -37,6 +37,9 @@
 import java.beans.VetoableChangeListener;
 import java.beans.PropertyVetoException;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
+
 /**
  * Class that manages a Motif title bar
  *
@@ -363,11 +366,15 @@
         }
         @SuppressWarnings("deprecation")
         void forwardEventToParent(MouseEvent e) {
-            getParent().dispatchEvent(new MouseEvent(
+            MouseEvent newEvent = new MouseEvent(
                 getParent(), e.getID(), e.getWhen(), e.getModifiers(),
                 e.getX(), e.getY(),  e.getXOnScreen(),
                 e.getYOnScreen(), e.getClickCount(),
-                e.isPopupTrigger(),  MouseEvent.NOBUTTON));
+                e.isPopupTrigger(),  MouseEvent.NOBUTTON);
+            MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+            meAccessor.setCausedByTouchEvent(newEvent,
+                meAccessor.isCausedByTouchEvent(e));
+            getParent().dispatchEvent(newEvent);
         }
 
         public void paintComponent(Graphics g) {
--- a/src/java.desktop/share/classes/java/awt/Component.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/java/awt/Component.java	Wed Oct 11 15:53:25 2017 +0100
@@ -5022,6 +5022,12 @@
                 tpeer.handleEvent(e);
             }
         }
+
+        if (SunToolkit.isTouchKeyboardAutoShowEnabled() &&
+            (toolkit instanceof SunToolkit) &&
+            ((e instanceof MouseEvent) || (e instanceof FocusEvent))) {
+            ((SunToolkit)toolkit).showOrHideTouchKeyboard(this, e);
+        }
     } // dispatchEventImpl()
 
     /*
--- a/src/java.desktop/share/classes/java/awt/Container.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/java/awt/Container.java	Wed Oct 11 15:53:25 2017 +0100
@@ -55,6 +55,7 @@
 
 import sun.awt.AppContext;
 import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
 import sun.awt.PeerEvent;
 import sun.awt.SunToolkit;
 
@@ -4783,6 +4784,9 @@
                                srcEvent.getClickCount(),
                                srcEvent.isPopupTrigger(),
                                srcEvent.getButton());
+            MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+            meAccessor.setCausedByTouchEvent(me,
+                meAccessor.isCausedByTouchEvent(srcEvent));
             ((AWTEvent)srcEvent).copyPrivateDataInto(me);
             // translate coordinates to this native container
             final Point ptSrcOrigin = srcComponent.getLocationOnScreen();
@@ -4884,6 +4888,9 @@
                                             e.getClickCount(),
                                             e.isPopupTrigger(),
                                             e.getButton());
+                MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+                meAccessor.setCausedByTouchEvent(retargeted,
+                    meAccessor.isCausedByTouchEvent(e));
             }
 
             ((AWTEvent)e).copyPrivateDataInto(retargeted);
--- a/src/java.desktop/share/classes/java/awt/event/MouseEvent.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/java/awt/event/MouseEvent.java	Wed Oct 11 15:53:25 2017 +0100
@@ -33,6 +33,8 @@
 import java.io.ObjectInputStream;
 import java.awt.IllegalComponentStateException;
 import java.awt.MouseInfo;
+
+import sun.awt.AWTAccessor;
 import sun.awt.SunToolkit;
 
 /**
@@ -332,6 +334,11 @@
     int clickCount;
 
     /**
+     * Indicates whether the event is a result of a touch event.
+     */
+    private boolean causedByTouchEvent;
+
+    /**
      * Indicates which, if any, of the mouse buttons has changed state.
      *
      * The valid values are ranged from 0 to the value returned by the
@@ -399,6 +406,17 @@
             //whatever besides SunToolkit) could also operate.
             cachedNumberOfButtons = 3;
         }
+        AWTAccessor.setMouseEventAccessor(
+            new AWTAccessor.MouseEventAccessor() {
+                public boolean isCausedByTouchEvent(MouseEvent ev) {
+                    return ev.causedByTouchEvent;
+                }
+
+                public void setCausedByTouchEvent(MouseEvent ev,
+                    boolean causedByTouchEvent) {
+                    ev.causedByTouchEvent = causedByTouchEvent;
+                }
+            });
     }
 
     /**
--- a/src/java.desktop/share/classes/javax/swing/Autoscroller.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/javax/swing/Autoscroller.java	Wed Oct 11 15:53:25 2017 +0100
@@ -28,6 +28,9 @@
 import java.awt.*;
 import java.awt.event.*;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
+
 /**
  * Autoscroller is responsible for generating synthetic mouse dragged
  * events. It is the responsibility of the Component (or its MouseListeners)
@@ -97,6 +100,9 @@
                                e.getYOnScreen(),
                                e.getClickCount(), e.isPopupTrigger(),
                                MouseEvent.NOBUTTON);
+        MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+        meAccessor.setCausedByTouchEvent(event,
+            meAccessor.isCausedByTouchEvent(e));
 
         if (timer == null) {
             timer = new Timer(100, this);
@@ -175,6 +181,9 @@
                                       event.getClickCount(),
                                       event.isPopupTrigger(),
                                       MouseEvent.NOBUTTON);
+        MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+        meAccessor.setCausedByTouchEvent(e,
+            meAccessor.isCausedByTouchEvent(event));
         component.superProcessMouseMotionEvent(e);
     }
 
--- a/src/java.desktop/share/classes/javax/swing/JList.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/javax/swing/JList.java	Wed Oct 11 15:53:25 2017 +0100
@@ -48,6 +48,8 @@
 import java.io.IOException;
 import java.io.Serializable;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
 import sun.swing.SwingUtilities2;
 import sun.swing.SwingUtilities2.Section;
 import static sun.swing.SwingUtilities2.Section.*;
@@ -1552,6 +1554,10 @@
                                               event.getClickCount(),
                                               event.isPopupTrigger(),
                                               MouseEvent.NOBUTTON);
+                    MouseEventAccessor meAccessor =
+                        AWTAccessor.getMouseEventAccessor();
+                    meAccessor.setCausedByTouchEvent(newEvent,
+                        meAccessor.isCausedByTouchEvent(event));
 
                     String tip = ((JComponent)rComponent).getToolTipText(
                                               newEvent);
--- a/src/java.desktop/share/classes/javax/swing/JTable.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/javax/swing/JTable.java	Wed Oct 11 15:53:25 2017 +0100
@@ -56,6 +56,8 @@
 import javax.print.attribute.*;
 import javax.print.PrintService;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
 import sun.reflect.misc.ReflectUtil;
 
 import sun.swing.SwingUtilities2;
@@ -3420,6 +3422,9 @@
                                           event.getClickCount(),
                                           event.isPopupTrigger(),
                                           MouseEvent.NOBUTTON);
+                MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+                meAccessor.setCausedByTouchEvent(newEvent,
+                    meAccessor.isCausedByTouchEvent(event));
 
                 tip = ((JComponent)component).getToolTipText(newEvent);
             }
--- a/src/java.desktop/share/classes/javax/swing/JTree.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/javax/swing/JTree.java	Wed Oct 11 15:53:25 2017 +0100
@@ -39,6 +39,8 @@
 import javax.swing.text.Position;
 import javax.accessibility.*;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
 import sun.swing.SwingUtilities2;
 import sun.swing.SwingUtilities2.Section;
 import static sun.swing.SwingUtilities2.Section.*;
@@ -1578,6 +1580,10 @@
                                               event.getClickCount(),
                                               event.isPopupTrigger(),
                                               MouseEvent.NOBUTTON);
+                    MouseEventAccessor meAccessor =
+                        AWTAccessor.getMouseEventAccessor();
+                    meAccessor.setCausedByTouchEvent(newEvent,
+                        meAccessor.isCausedByTouchEvent(event));
 
                     tip = ((JComponent)rComponent).getToolTipText(newEvent);
                 }
--- a/src/java.desktop/share/classes/javax/swing/MenuSelectionManager.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/javax/swing/MenuSelectionManager.java	Wed Oct 11 15:53:25 2017 +0100
@@ -30,6 +30,8 @@
 import javax.swing.event.*;
 
 import sun.awt.AppContext;
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
 import sun.swing.SwingUtilities2;
 
 /**
@@ -308,6 +310,9 @@
                                                               event.getClickCount(),
                                                               event.isPopupTrigger(),
                                                               MouseEvent.NOBUTTON);
+                        MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+                        meAccessor.setCausedByTouchEvent(exitEvent,
+                            meAccessor.isCausedByTouchEvent(event));
                         currentSelection[currentSelection.length-1].
                             processMouseEvent(exitEvent, path, this);
 
@@ -320,6 +325,8 @@
                                                                event.getClickCount(),
                                                                event.isPopupTrigger(),
                                                                MouseEvent.NOBUTTON);
+                        meAccessor.setCausedByTouchEvent(enterEvent,
+                            meAccessor.isCausedByTouchEvent(event));
                         subElements[j].processMouseEvent(enterEvent, path, this);
                     }
                     MouseEvent mouseEvent = new MouseEvent(mc, event.getID(),event. getWhen(),
@@ -329,6 +336,9 @@
                                                            event.getClickCount(),
                                                            event.isPopupTrigger(),
                                                            MouseEvent.NOBUTTON);
+                    MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+                    meAccessor.setCausedByTouchEvent(mouseEvent,
+                        meAccessor.isCausedByTouchEvent(event));
                     subElements[j].processMouseEvent(mouseEvent, path, this);
                     success = true;
                     event.consume();
--- a/src/java.desktop/share/classes/javax/swing/SwingUtilities.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/javax/swing/SwingUtilities.java	Wed Oct 11 15:53:25 2017 +0100
@@ -44,6 +44,8 @@
 import sun.security.action.GetPropertyAction;
 
 import sun.awt.AppContext;
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
 
 /**
  * A collection of utility methods for Swing.
@@ -405,6 +407,9 @@
                                       sourceEvent.getClickCount(),
                                       sourceEvent.isPopupTrigger(),
                                       sourceEvent.getButton());
+            MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+            meAccessor.setCausedByTouchEvent(newEvent,
+                meAccessor.isCausedByTouchEvent(sourceEvent));
         }
         return newEvent;
     }
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboPopup.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboPopup.java	Wed Oct 11 15:53:25 2017 +0100
@@ -36,6 +36,8 @@
 import java.beans.PropertyChangeEvent;
 import java.io.Serializable;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
 
 /**
  * This is a basic implementation of the <code>ComboPopup</code> interface.
@@ -534,13 +536,18 @@
                     // Fix for 4234053. Filter out the Control Key from the list.
                     // ie., don't allow CTRL key deselection.
                     Toolkit toolkit = Toolkit.getDefaultToolkit();
-                    e = new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(),
+                    MouseEvent newEvent = new MouseEvent(
+                                       (Component)e.getSource(), e.getID(), e.getWhen(),
                                        e.getModifiers() ^ toolkit.getMenuShortcutKeyMask(),
                                        e.getX(), e.getY(),
                                        e.getXOnScreen(), e.getYOnScreen(),
                                        e.getClickCount(),
                                        e.isPopupTrigger(),
                                        MouseEvent.NOBUTTON);
+                    MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+                    meAccessor.setCausedByTouchEvent(newEvent,
+                        meAccessor.isCausedByTouchEvent(e));
+                    e = newEvent;
                 }
                 super.processMouseEvent(e);
             }
@@ -1251,6 +1258,9 @@
                                               e.getClickCount(),
                                               e.isPopupTrigger(),
                                               MouseEvent.NOBUTTON );
+        MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+        meAccessor.setCausedByTouchEvent(newEvent,
+            meAccessor.isCausedByTouchEvent(e));
         return newEvent;
     }
 
--- a/src/java.desktop/share/classes/javax/swing/table/JTableHeader.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/javax/swing/table/JTableHeader.java	Wed Oct 11 15:53:25 2017 +0100
@@ -42,6 +42,9 @@
 import java.io.ObjectOutputStream;
 import java.io.IOException;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
+
 /**
  * This is the object which manages the header of the <code>JTable</code>.
  * <p>
@@ -414,6 +417,9 @@
                                           p.x, p.y, event.getXOnScreen(), event.getYOnScreen(),
                                           event.getClickCount(),
                                           event.isPopupTrigger(), MouseEvent.NOBUTTON);
+                MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+                meAccessor.setCausedByTouchEvent(newEvent,
+                    meAccessor.isCausedByTouchEvent(event));
 
                 tip = ((JComponent)component).getToolTipText(newEvent);
             }
--- a/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Wed Oct 11 15:53:25 2017 +0100
@@ -38,6 +38,7 @@
 import java.awt.event.InputEvent;
 import java.awt.event.InvocationEvent;
 import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
 import java.awt.geom.Point2D;
 import java.awt.image.BufferStrategy;
 import java.awt.peer.ComponentPeer;
@@ -412,6 +413,21 @@
                 boolean canAccessSystemClipboard);
     }
 
+    /**
+     * An accessor for the MouseEvent class.
+     */
+    public interface MouseEventAccessor {
+        /**
+         * Indicates whether the event is a result of a touch event.
+         */
+        boolean isCausedByTouchEvent(MouseEvent ev);
+
+        /**
+         * Sets whether the event is a result of a touch event.
+         */
+        void setCausedByTouchEvent(MouseEvent ev, boolean causedByTouchEvent);
+    }
+
     /*
      * An accessor for the java.awt.Frame class.
      */
@@ -851,6 +867,7 @@
     private static WindowAccessor windowAccessor;
     private static AWTEventAccessor awtEventAccessor;
     private static InputEventAccessor inputEventAccessor;
+    private static MouseEventAccessor mouseEventAccessor;
     private static FrameAccessor frameAccessor;
     private static KeyboardFocusManagerAccessor kfmAccessor;
     private static MenuComponentAccessor menuComponentAccessor;
@@ -965,6 +982,23 @@
     }
 
     /*
+     * Set an accessor object for the java.awt.event.MouseEvent class.
+     */
+    public static void setMouseEventAccessor(MouseEventAccessor mea) {
+        mouseEventAccessor = mea;
+    }
+
+    /*
+     * Retrieve the accessor object for the java.awt.event.MouseEvent class.
+     */
+    public static MouseEventAccessor getMouseEventAccessor() {
+        if (mouseEventAccessor == null) {
+            unsafe.ensureClassInitialized(MouseEvent.class);
+        }
+        return mouseEventAccessor;
+    }
+
+    /*
      * Set an accessor object for the java.awt.Frame class.
      */
     public static void setFrameAccessor(FrameAccessor fa) {
--- a/src/java.desktop/share/classes/sun/awt/SunToolkit.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/sun/awt/SunToolkit.java	Wed Oct 11 15:53:25 2017 +0100
@@ -84,6 +84,9 @@
         if (AccessController.doPrivileged(new GetBooleanAction("sun.awt.nativedebug"))) {
             DebugSettings.init();
         }
+        touchKeyboardAutoShowIsEnabled = Boolean.valueOf(
+            GetPropertyAction.privilegedGetProperty(
+                "awt.touchKeyboardAutoShowIsEnabled", "true"));
     };
 
     /**
@@ -1614,6 +1617,13 @@
      */
     public abstract void ungrab(Window w);
 
+    public void showOrHideTouchKeyboard(Component comp, AWTEvent e) {}
+
+    private static boolean touchKeyboardAutoShowIsEnabled;
+
+    public static boolean isTouchKeyboardAutoShowEnabled() {
+        return touchKeyboardAutoShowIsEnabled;
+    }
 
     /**
      * Locates the splash screen library in a platform dependent way and closes
--- a/src/java.desktop/share/classes/sun/swing/FilePane.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/share/classes/sun/swing/FilePane.java	Wed Oct 11 15:53:25 2017 +0100
@@ -44,6 +44,8 @@
 import javax.swing.table.*;
 import javax.swing.text.*;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.MouseEventAccessor;
 import sun.awt.shell.*;
 
 /**
@@ -1858,13 +1860,17 @@
                     // Make a new event with the list as source, placing the
                     // click in the corresponding list cell.
                     Rectangle r = list.getCellBounds(index, index);
-                    evt = new MouseEvent(list, evt.getID(),
+                    MouseEvent newEvent = new MouseEvent(list, evt.getID(),
                                          evt.getWhen(), evt.getModifiers(),
                                          r.x + 1, r.y + r.height/2,
                                          evt.getXOnScreen(),
                                          evt.getYOnScreen(),
                                          evt.getClickCount(), evt.isPopupTrigger(),
                                          evt.getButton());
+                    MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
+                    meAccessor.setCausedByTouchEvent(newEvent,
+                        meAccessor.isCausedByTouchEvent(evt));
+                    evt = newEvent;
                 }
             } else {
                 return;
--- a/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Wed Oct 11 15:53:25 2017 +0100
@@ -31,12 +31,16 @@
 import java.awt.im.spi.InputMethodDescriptor;
 import java.awt.image.*;
 import java.awt.peer.*;
+import java.awt.event.FocusEvent;
 import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
 import java.awt.datatransfer.Clipboard;
+import java.awt.TextComponent;
 import java.awt.TrayIcon;
 import java.beans.PropertyChangeListener;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import javax.swing.text.JTextComponent;
 
 import sun.awt.AWTAccessor;
 import sun.awt.AppContext;
@@ -1084,6 +1088,61 @@
         }
     }
 
+    ///////////////////////////////////////////////////////////////////////////
+    // The following code is used for support of automatic showing of the touch
+    // keyboard for text components and is accessed only from EDT.
+    ///////////////////////////////////////////////////////////////////////////
+    private volatile Component compOnTouchDownEvent;
+    private volatile Component compOnMousePressedEvent;
+
+    @Override
+    public void showOrHideTouchKeyboard(Component comp, AWTEvent e) {
+        if ((comp == null) || (e == null) ||
+            (!(comp instanceof TextComponent) &&
+                !(comp instanceof JTextComponent))) {
+            return;
+        }
+
+        if ((e instanceof MouseEvent) && comp.isEnabled() &&
+            (((comp instanceof TextComponent) &&
+                    ((TextComponent)comp).isEditable()) ||
+                ((comp instanceof JTextComponent) &&
+                    ((JTextComponent)comp).isEditable()))) {
+            MouseEvent me = (MouseEvent)e;
+            if (me.getID() == MouseEvent.MOUSE_PRESSED) {
+                if (AWTAccessor.getMouseEventAccessor()
+                        .isCausedByTouchEvent(me)) {
+                    compOnTouchDownEvent = comp;
+                } else {
+                    compOnMousePressedEvent = comp;
+                }
+            } else if (me.getID() == MouseEvent.MOUSE_RELEASED) {
+                if (AWTAccessor.getMouseEventAccessor()
+                        .isCausedByTouchEvent(me)) {
+                    if (compOnTouchDownEvent == comp) {
+                        showTouchKeyboard(true);
+                    }
+                    compOnTouchDownEvent = null;
+                } else {
+                    if (compOnMousePressedEvent == comp) {
+                        showTouchKeyboard(false);
+                    }
+                    compOnMousePressedEvent = null;
+                }
+            }
+        } else if (e instanceof FocusEvent) {
+            if (e.getID() == FocusEvent.FOCUS_LOST) {
+                hideTouchKeyboard();
+            }
+        }
+    }
+
+    private native void showTouchKeyboard(boolean causedByTouchEvent);
+    private native void hideTouchKeyboard();
+    ///////////////////////////////////////////////////////////////////////////
+    // End of the touch keyboard related code.
+    ///////////////////////////////////////////////////////////////////////////
+
     @Override
     public native boolean syncNativeQueue(final long timeout);
 
--- a/src/java.desktop/windows/native/libawt/windows/awt.h	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/windows/native/libawt/windows/awt.h	Wed Oct 11 15:53:25 2017 +0100
@@ -163,6 +163,9 @@
 #define IS_WIN2000 (LOBYTE(LOWORD(::GetVersion())) >= 5)
 #define IS_WINXP ((IS_WIN2000 && HIBYTE(LOWORD(::GetVersion())) >= 1) || LOBYTE(LOWORD(::GetVersion())) > 5)
 #define IS_WINVISTA (LOBYTE(LOWORD(::GetVersion())) >= 6)
+#define IS_WIN8 (                                                              \
+    (IS_WINVISTA && (HIBYTE(LOWORD(::GetVersion())) >= 2)) ||                  \
+    (LOBYTE(LOWORD(::GetVersion())) > 6))
 
 #define IS_WINVER_ATLEAST(maj, min) \
                    ((maj) < LOBYTE(LOWORD(::GetVersion())) || \
--- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Wed Oct 11 15:53:25 2017 +0100
@@ -217,6 +217,10 @@
 AwtComponent::AwtComponent()
 {
     m_mouseButtonClickAllowed = 0;
+    m_touchDownOccurred = FALSE;
+    m_touchUpOccurred = FALSE;
+    m_touchDownPoint.x = m_touchDownPoint.y = 0;
+    m_touchUpPoint.x = m_touchUpPoint.y = 0;
     m_callbacksEnabled = FALSE;
     m_hwnd = NULL;
 
@@ -582,6 +586,11 @@
     /* Subclass the window now so that we can snoop on its messages */
     SubclassHWND();
 
+    AwtToolkit& tk = AwtToolkit::GetInstance();
+    if (tk.IsWin8OrLater() && tk.IsTouchKeyboardAutoShowEnabled()) {
+        tk.TIRegisterTouchWindow(GetHWnd(), TWF_WANTPALM);
+    }
+
     /*
       * Fix for 4046446.
       */
@@ -1713,6 +1722,9 @@
               break;
           }
           break;
+      case WM_TOUCH:
+          WmTouch(wParam, lParam);
+          break;
       case WM_SETCURSOR:
           mr = mrDoDefault;
           if (LOWORD(lParam) == HTCLIENT) {
@@ -2295,6 +2307,38 @@
     return mrDoDefault;
 }
 
+void AwtComponent::WmTouch(WPARAM wParam, LPARAM lParam) {
+    AwtToolkit& tk = AwtToolkit::GetInstance();
+    if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) {
+        return;
+    }
+
+    UINT inputsCount = LOWORD(wParam);
+    TOUCHINPUT* pInputs = new TOUCHINPUT[inputsCount];
+    if (pInputs != NULL) {
+        if (tk.TIGetTouchInputInfo((HTOUCHINPUT)lParam, inputsCount, pInputs,
+                sizeof(TOUCHINPUT)) != 0) {
+            for (UINT i = 0; i < inputsCount; i++) {
+                TOUCHINPUT ti = pInputs[i];
+                if (ti.dwFlags & TOUCHEVENTF_PRIMARY) {
+                    if (ti.dwFlags & TOUCHEVENTF_DOWN) {
+                        m_touchDownPoint.x = ti.x / 100;
+                        m_touchDownPoint.y = ti.y / 100;
+                        ::ScreenToClient(GetHWnd(), &m_touchDownPoint);
+                        m_touchDownOccurred = TRUE;
+                    } else if (ti.dwFlags & TOUCHEVENTF_UP) {
+                        m_touchUpPoint.x = ti.x / 100;
+                        m_touchUpPoint.y = ti.y / 100;
+                        ::ScreenToClient(GetHWnd(), &m_touchUpPoint);
+                        m_touchUpOccurred = TRUE;
+                    }
+                }
+            }
+        }
+        delete[] pInputs;
+    }
+}
+
 /* Double-click variables. */
 static jlong multiClickTime = ::GetDoubleClickTime();
 static int multiClickMaxX = ::GetSystemMetrics(SM_CXDOUBLECLK);
@@ -2337,6 +2381,14 @@
     m_mouseButtonClickAllowed |= GetButtonMK(button);
     lastTime = now;
 
+    BOOL causedByTouchEvent = FALSE;
+    if (m_touchDownOccurred &&
+        (abs(m_touchDownPoint.x - x) <= TOUCH_MOUSE_COORDS_DELTA) &&
+        (abs(m_touchDownPoint.y - y) <= TOUCH_MOUSE_COORDS_DELTA)) {
+        causedByTouchEvent = TRUE;
+        m_touchDownOccurred = FALSE;
+    }
+
     MSG msg;
     InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
 
@@ -2355,7 +2407,7 @@
 
     SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y,
                    GetJavaModifiers(), clickCount, JNI_FALSE,
-                   GetButton(button), &msg);
+                   GetButton(button), &msg, causedByTouchEvent);
     /*
      * NOTE: this call is intentionally placed after all other code,
      * since AwtComponent::WmMouseDown() assumes that the cached id of the
@@ -2377,13 +2429,21 @@
 
 MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button)
 {
+    BOOL causedByTouchEvent = FALSE;
+    if (m_touchUpOccurred &&
+        (abs(m_touchUpPoint.x - x) <= TOUCH_MOUSE_COORDS_DELTA) &&
+        (abs(m_touchUpPoint.y - y) <= TOUCH_MOUSE_COORDS_DELTA)) {
+        causedByTouchEvent = TRUE;
+        m_touchUpOccurred = FALSE;
+    }
+
     MSG msg;
     InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
 
     SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, ::JVM_CurrentTimeMillis(NULL, 0),
                    x, y, GetJavaModifiers(), clickCount,
                    (GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ?
-                    TRUE : FALSE), GetButton(button), &msg);
+                    TRUE : FALSE), GetButton(button), &msg, causedByTouchEvent);
     /*
      * If no movement, then report a click following the button release.
      * When WM_MOUSEUP comes to a window without previous WM_MOUSEDOWN,
@@ -4970,7 +5030,7 @@
 void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y,
                                   jint modifiers, jint clickCount,
                                   jboolean popupTrigger, jint button,
-                                  MSG *pMsg)
+                                  MSG *pMsg, BOOL causedByTouchEvent)
 {
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
     CriticalSection::Lock l(GetLock());
@@ -5020,6 +5080,10 @@
 
     DASSERT(mouseEvent != NULL);
     CHECK_NULL(mouseEvent);
+    if (causedByTouchEvent) {
+        env->SetBooleanField(mouseEvent, AwtMouseEvent::causedByTouchEventID,
+            JNI_TRUE);
+    }
     if (pMsg != 0) {
         AwtAWTEvent::saveMSG(env, pMsg, mouseEvent);
     }
--- a/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Wed Oct 11 15:53:25 2017 +0100
@@ -67,7 +67,10 @@
 const int ALL_MK_BUTTONS = MK_LBUTTON|MK_MBUTTON|MK_RBUTTON;
 const int X_BUTTONS = MK_XBUTTON1|MK_XBUTTON2;
 
-
+// The allowable difference between coordinates of the WM_TOUCH event and the
+// corresponding WM_LBUTTONDOWN/WM_LBUTTONUP event letting to associate these
+// events, when their coordinates are slightly different.
+const int TOUCH_MOUSE_COORDS_DELTA = 10;
 
 // Whether to check for embedded frame and adjust location
 #define CHECK_EMBEDDED 0
@@ -385,7 +388,7 @@
     void SendMouseEvent(jint id, jlong when, jint x, jint y,
                         jint modifiers, jint clickCount,
                         jboolean popupTrigger, jint button = 0,
-                        MSG *msg = NULL);
+                        MSG *msg = NULL, BOOL causedByTouchEvent = FALSE);
 
     /*
      * Allocate and initialize a new java.awt.event.MouseWheelEvent, and
@@ -528,6 +531,7 @@
     virtual MsgRouting WmNcMouseUp(WPARAM hitTest, int x, int y, int button);
     virtual MsgRouting WmWindowPosChanging(LPARAM windowPos);
     virtual MsgRouting WmWindowPosChanged(LPARAM windowPos);
+    virtual void WmTouch(WPARAM wParam, LPARAM lParam);
 
     // NB: 64-bit: vkey is wParam of the message, but other API's take
     // vkey parameters of type UINT, so we do the cast before dispatching.
@@ -764,6 +768,11 @@
     */
     UINT m_mouseButtonClickAllowed;
 
+    BOOL m_touchDownOccurred;
+    BOOL m_touchUpOccurred;
+    POINT m_touchDownPoint;
+    POINT m_touchUpPoint;
+
     BOOL m_bSubclassed;
     BOOL m_bPauseDestroy;
 
--- a/src/java.desktop/windows/native/libawt/windows/awt_MouseEvent.cpp	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/windows/native/libawt/windows/awt_MouseEvent.cpp	Wed Oct 11 15:53:25 2017 +0100
@@ -32,6 +32,7 @@
 
 jfieldID AwtMouseEvent::xID;
 jfieldID AwtMouseEvent::yID;
+jfieldID AwtMouseEvent::causedByTouchEventID;
 jfieldID AwtMouseEvent::buttonID;
 
 /************************************************************************
@@ -52,6 +53,11 @@
     DASSERT(AwtMouseEvent::yID != NULL);
     CHECK_NULL(AwtMouseEvent::yID);
 
+    AwtMouseEvent::causedByTouchEventID = env->GetFieldID(
+        cls, "causedByTouchEvent", "Z");
+    DASSERT(AwtMouseEvent::causedByTouchEventID != NULL);
+    CHECK_NULL(AwtMouseEvent::causedByTouchEventID);
+
     AwtMouseEvent::buttonID = env->GetFieldID(cls, "button", "I");
     DASSERT(AwtMouseEvent::buttonID != NULL);
     CHECK_NULL(AwtMouseEvent::buttonID);
--- a/src/java.desktop/windows/native/libawt/windows/awt_MouseEvent.h	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/windows/native/libawt/windows/awt_MouseEvent.h	Wed Oct 11 15:53:25 2017 +0100
@@ -39,6 +39,7 @@
     /* java.awt.MouseEvent field ids */
     static jfieldID xID;
     static jfieldID yID;
+    static jfieldID causedByTouchEventID;
     static jfieldID buttonID;
 
 };
--- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Wed Oct 11 15:53:25 2017 +0100
@@ -29,6 +29,8 @@
 #include <signal.h>
 #include <windowsx.h>
 #include <process.h>
+#include <shellapi.h>
+#include <shlwapi.h>
 
 #include "awt_DrawingSurface.h"
 #include "awt_AWTEvent.h"
@@ -305,6 +307,13 @@
     m_isDynamicLayoutSet = FALSE;
     m_areExtraMouseButtonsEnabled = TRUE;
 
+    m_isWin8OrLater = FALSE;
+    m_touchKbrdAutoShowIsEnabled = FALSE;
+    m_touchKbrdExeFilePath = NULL;
+    m_pRegisterTouchWindow = NULL;
+    m_pGetTouchInputInfo = NULL;
+    m_pCloseTouchInputHandle = NULL;
+
     m_verifyComponents = FALSE;
     m_breakOnError = FALSE;
 
@@ -359,6 +368,149 @@
     return hwnd;
 }
 
+void AwtToolkit::InitTouchKeyboardExeFilePath() {
+    enum RegistryView { WOW64_32BIT, WOW64_64BIT };
+    const TCHAR tabTipCoKeyName[] = _T("SOFTWARE\\Classes\\CLSID\\")
+        _T("{054AAE20-4BEA-4347-8A35-64A533254A9D}\\LocalServer32");
+    HKEY hTabTipCoKey = NULL;
+    RegistryView regViewWithTabTipCoKey = WOW64_32BIT;
+
+    if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, tabTipCoKeyName, 0,
+            KEY_READ | KEY_WOW64_32KEY, &hTabTipCoKey) != ERROR_SUCCESS) {
+        if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, tabTipCoKeyName, 0,
+                KEY_READ | KEY_WOW64_64KEY, &hTabTipCoKey) != ERROR_SUCCESS) {
+            return;
+        } else {
+            regViewWithTabTipCoKey = WOW64_64BIT;
+        }
+    }
+
+    DWORD keyValType = 0;
+    DWORD bytesCopied = 0;
+    if ((::RegQueryValueEx(hTabTipCoKey, NULL, NULL, &keyValType, NULL,
+            &bytesCopied) != ERROR_SUCCESS) ||
+        ((keyValType != REG_EXPAND_SZ) && (keyValType != REG_SZ))) {
+        if (hTabTipCoKey != NULL) {
+            ::RegCloseKey(hTabTipCoKey);
+        }
+        return;
+    }
+
+    // Increase the buffer size for 1 additional null-terminating character.
+    bytesCopied += sizeof(TCHAR);
+    TCHAR* tabTipFilePath = new TCHAR[bytesCopied / sizeof(TCHAR)];
+    ::memset(tabTipFilePath, 0, bytesCopied);
+
+    DWORD oldBytesCopied = bytesCopied;
+    if (::RegQueryValueEx(hTabTipCoKey, NULL, NULL, NULL,
+            (LPBYTE)tabTipFilePath, &bytesCopied) == ERROR_SUCCESS) {
+        const TCHAR searchedStr[] = _T("%CommonProgramFiles%");
+        const size_t searchedStrLen = ::_tcslen(searchedStr);
+        int searchedStrStartIndex = -1;
+
+        TCHAR* commonFilesDirPath = NULL;
+        DWORD commonFilesDirPathLen = 0;
+
+        // Check, if '%CommonProgramFiles%' string is present in the defined
+        // path of the touch keyboard executable.
+        TCHAR* const searchedStrStart = ::_tcsstr(tabTipFilePath, searchedStr);
+        if (searchedStrStart != NULL) {
+            searchedStrStartIndex = searchedStrStart - tabTipFilePath;
+
+            // Get value of 'CommonProgramFiles' environment variable, if the
+            // file path of the touch keyboard executable was found in 32-bit
+            // registry view, otherwise get value of 'CommonProgramW6432'.
+            const TCHAR envVar32BitName[] = _T("CommonProgramFiles");
+            const TCHAR envVar64BitName[] = _T("CommonProgramW6432");
+            const TCHAR* envVarName = (regViewWithTabTipCoKey == WOW64_32BIT ?
+                envVar32BitName : envVar64BitName);
+
+            DWORD charsStored = ::GetEnvironmentVariable(envVarName, NULL, 0);
+            if (charsStored > 0) {
+                commonFilesDirPath = new TCHAR[charsStored];
+                ::memset(commonFilesDirPath, 0, charsStored * sizeof(TCHAR));
+
+                DWORD oldCharsStored = charsStored;
+                if (((charsStored = ::GetEnvironmentVariable(envVarName,
+                        commonFilesDirPath, charsStored)) > 0) &&
+                    (charsStored <= oldCharsStored)) {
+                    commonFilesDirPathLen = charsStored;
+                } else {
+                    delete[] commonFilesDirPath;
+                    commonFilesDirPath = NULL;
+                }
+            }
+        }
+
+        // Calculate 'm_touchKbrdExeFilePath' length in characters including
+        // the null-terminating character.
+        DWORD exeFilePathLen = oldBytesCopied / sizeof(TCHAR);
+        if (commonFilesDirPathLen > 0) {
+            exeFilePathLen = exeFilePathLen - searchedStrLen +
+                commonFilesDirPathLen;
+        }
+
+        if (m_touchKbrdExeFilePath != NULL) {
+            delete[] m_touchKbrdExeFilePath;
+            m_touchKbrdExeFilePath = NULL;
+        }
+        m_touchKbrdExeFilePath = new TCHAR[exeFilePathLen];
+        ::memset(m_touchKbrdExeFilePath, 0, exeFilePathLen * sizeof(TCHAR));
+
+        if (commonFilesDirPathLen > 0) {
+            ::_tcsncpy_s(m_touchKbrdExeFilePath, exeFilePathLen, tabTipFilePath,
+                searchedStrStartIndex);
+            DWORD charsCopied = searchedStrStartIndex;
+
+            ::_tcsncpy_s(m_touchKbrdExeFilePath + charsCopied,
+                exeFilePathLen - charsCopied, commonFilesDirPath,
+                commonFilesDirPathLen);
+            charsCopied += commonFilesDirPathLen;
+
+            ::_tcsncpy_s(m_touchKbrdExeFilePath + charsCopied,
+                exeFilePathLen - charsCopied, searchedStrStart + searchedStrLen,
+                bytesCopied / sizeof(TCHAR) -
+                    (searchedStrStartIndex + searchedStrLen));
+        } else {
+            ::_tcsncpy_s(m_touchKbrdExeFilePath, exeFilePathLen, tabTipFilePath,
+                bytesCopied / sizeof(TCHAR));
+        }
+
+        // Remove leading and trailing quotation marks.
+        ::StrTrim(m_touchKbrdExeFilePath, _T("\""));
+
+        // Verify that a file with the path 'm_touchKbrdExeFilePath' exists.
+        DWORD fileAttrs = ::GetFileAttributes(m_touchKbrdExeFilePath);
+        DWORD err = ::GetLastError();
+        if ((fileAttrs == INVALID_FILE_ATTRIBUTES) ||
+            (fileAttrs & FILE_ATTRIBUTE_DIRECTORY)) {
+            delete[] m_touchKbrdExeFilePath;
+            m_touchKbrdExeFilePath = NULL;
+        }
+
+        if (commonFilesDirPath != NULL) {
+            delete[] commonFilesDirPath;
+        }
+    }
+
+    if (tabTipFilePath != NULL) {
+        delete[] tabTipFilePath;
+    }
+    if (hTabTipCoKey != NULL) {
+        ::RegCloseKey(hTabTipCoKey);
+    }
+}
+
+HWND AwtToolkit::GetTouchKeyboardWindow() {
+    const TCHAR wndClassName[] = _T("IPTip_Main_Window");
+    HWND hwnd = ::FindWindow(wndClassName, NULL);
+    if ((hwnd != NULL) && ::IsWindow(hwnd) && ::IsWindowEnabled(hwnd) &&
+        ::IsWindowVisible(hwnd)) {
+        return hwnd;
+    }
+    return NULL;
+}
+
 
 struct ToolkitThreadProc_Data {
     bool result;
@@ -517,6 +669,52 @@
 
     awt_dnd_initialize();
 
+    /*
+     * Initialization of the touch keyboard related variables.
+     */
+    tk.m_isWin8OrLater = IS_WIN8;
+
+    TRY;
+
+    JNIEnv* env = AwtToolkit::GetEnv();
+    jclass sunToolkitCls = env->FindClass("sun/awt/SunToolkit");
+    DASSERT(sunToolkitCls != 0);
+    CHECK_NULL_RETURN(sunToolkitCls, FALSE);
+
+    jmethodID isTouchKeyboardAutoShowEnabledMID = env->GetStaticMethodID(
+        sunToolkitCls, "isTouchKeyboardAutoShowEnabled", "()Z");
+    DASSERT(isTouchKeyboardAutoShowEnabledMID != 0);
+    CHECK_NULL_RETURN(isTouchKeyboardAutoShowEnabledMID, FALSE);
+
+    tk.m_touchKbrdAutoShowIsEnabled = env->CallStaticBooleanMethod(
+        sunToolkitCls, isTouchKeyboardAutoShowEnabledMID);
+
+    CATCH_BAD_ALLOC_RET(FALSE);
+
+    if (tk.m_isWin8OrLater && tk.m_touchKbrdAutoShowIsEnabled) {
+        tk.InitTouchKeyboardExeFilePath();
+        HMODULE hUser32Dll = ::LoadLibrary(_T("user32.dll"));
+        if (hUser32Dll != NULL) {
+            tk.m_pRegisterTouchWindow = (RegisterTouchWindowFunc)
+                ::GetProcAddress(hUser32Dll, "RegisterTouchWindow");
+            tk.m_pGetTouchInputInfo = (GetTouchInputInfoFunc)
+                ::GetProcAddress(hUser32Dll, "GetTouchInputInfo");
+            tk.m_pCloseTouchInputHandle = (CloseTouchInputHandleFunc)
+                ::GetProcAddress(hUser32Dll, "CloseTouchInputHandle");
+        }
+
+        if ((tk.m_pRegisterTouchWindow == NULL) ||
+            (tk.m_pGetTouchInputInfo == NULL) ||
+            (tk.m_pCloseTouchInputHandle == NULL)) {
+            tk.m_pRegisterTouchWindow = NULL;
+            tk.m_pGetTouchInputInfo = NULL;
+            tk.m_pCloseTouchInputHandle = NULL;
+        }
+    }
+    /*
+     * End of the touch keyboard related initialization code.
+     */
+
     return TRUE;
 }
 
@@ -541,6 +739,14 @@
     awt_dnd_uninitialize();
     awt_clipboard_uninitialize((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2));
 
+    if (tk.m_touchKbrdExeFilePath != NULL) {
+        delete[] tk.m_touchKbrdExeFilePath;
+        tk.m_touchKbrdExeFilePath = NULL;
+    }
+    tk.m_pRegisterTouchWindow = NULL;
+    tk.m_pGetTouchInputInfo = NULL;
+    tk.m_pCloseTouchInputHandle = NULL;
+
     if (tk.m_inputMethodHWnd != NULL) {
         ::SendMessage(tk.m_inputMethodHWnd, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0);
     }
@@ -2747,6 +2953,32 @@
     CATCH_BAD_ALLOC_RET(NULL);
 }
 
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WToolkit_showTouchKeyboard(JNIEnv *env, jobject self,
+    jboolean causedByTouchEvent)
+{
+    AwtToolkit& tk = AwtToolkit::GetInstance();
+    if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) {
+        return;
+    }
+
+    if (causedByTouchEvent ||
+        (tk.IsTouchKeyboardAutoShowSystemEnabled() &&
+            !tk.IsAnyKeyboardAttached())) {
+        tk.ShowTouchKeyboard();
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WToolkit_hideTouchKeyboard(JNIEnv *env, jobject self)
+{
+    AwtToolkit& tk = AwtToolkit::GetInstance();
+    if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) {
+        return;
+    }
+    tk.HideTouchKeyboard();
+}
+
 JNIEXPORT jboolean JNICALL
 Java_sun_awt_windows_WToolkit_syncNativeQueue(JNIEnv *env, jobject self, jlong timeout)
 {
@@ -2824,3 +3056,119 @@
 UINT AwtToolkit::GetNumberOfButtons() {
     return MOUSE_BUTTONS_WINDOWS_SUPPORTED;
 }
+
+bool AwtToolkit::IsWin8OrLater() {
+    return m_isWin8OrLater;
+}
+
+bool AwtToolkit::IsTouchKeyboardAutoShowEnabled() {
+    return m_touchKbrdAutoShowIsEnabled;
+}
+
+bool AwtToolkit::IsAnyKeyboardAttached() {
+    UINT numDevs = 0;
+    UINT numDevsRet = 0;
+    const UINT devListTypeSize = sizeof(RAWINPUTDEVICELIST);
+    if ((::GetRawInputDeviceList(NULL, &numDevs, devListTypeSize) != 0) ||
+        (numDevs == 0)) {
+        return false;
+    }
+
+    RAWINPUTDEVICELIST* pDevList = new RAWINPUTDEVICELIST[numDevs];
+    while (((numDevsRet = ::GetRawInputDeviceList(pDevList, &numDevs,
+            devListTypeSize)) == (UINT)-1) &&
+        (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+        if (pDevList != NULL) {
+            delete[] pDevList;
+        }
+        pDevList = new RAWINPUTDEVICELIST[numDevs];
+    }
+
+    bool keyboardIsAttached = false;
+    if (numDevsRet != (UINT)-1) {
+        for (UINT i = 0; i < numDevsRet; i++) {
+            if (pDevList[i].dwType == RIM_TYPEKEYBOARD) {
+                keyboardIsAttached = true;
+                break;
+            }
+        }
+    }
+
+    if (pDevList != NULL) {
+        delete[] pDevList;
+    }
+    return keyboardIsAttached;
+}
+
+bool AwtToolkit::IsTouchKeyboardAutoShowSystemEnabled() {
+    const TCHAR tabTipKeyName[] = _T("SOFTWARE\\Microsoft\\TabletTip\\1.7");
+    HKEY hTabTipKey = NULL;
+    if (::RegOpenKeyEx(HKEY_CURRENT_USER, tabTipKeyName, 0, KEY_READ,
+            &hTabTipKey) != ERROR_SUCCESS) {
+        return false;
+    }
+
+    const TCHAR enableAutoInvokeValName[] = _T("EnableDesktopModeAutoInvoke");
+    DWORD keyValType = 0;
+    bool autoShowIsEnabled = false;
+    if (::RegQueryValueEx(hTabTipKey, enableAutoInvokeValName, NULL,
+            &keyValType, NULL, NULL) == ERROR_SUCCESS) {
+        if (keyValType == REG_DWORD) {
+            DWORD enableAutoInvokeVal = 0;
+            DWORD bytesCopied = sizeof(DWORD);
+            if (::RegQueryValueEx(hTabTipKey, enableAutoInvokeValName, NULL,
+                    NULL, (LPBYTE)(DWORD*)&enableAutoInvokeVal,
+                    &bytesCopied) == ERROR_SUCCESS) {
+                autoShowIsEnabled = (enableAutoInvokeVal == 0 ? false : true);
+            }
+        }
+    }
+
+    if (hTabTipKey != NULL) {
+        ::RegCloseKey(hTabTipKey);
+    }
+    return autoShowIsEnabled;
+}
+
+void AwtToolkit::ShowTouchKeyboard() {
+    if (m_isWin8OrLater && m_touchKbrdAutoShowIsEnabled &&
+        (m_touchKbrdExeFilePath != NULL)) {
+        HINSTANCE retVal = ::ShellExecute(NULL, _T("open"),
+            m_touchKbrdExeFilePath, NULL, NULL, SW_SHOW);
+        if ((int)retVal <= 32) {
+            DTRACE_PRINTLN1("AwtToolkit::ShowTouchKeyboard: Failed"
+                ", retVal='%d'", (int)retVal);
+        }
+    }
+}
+
+void AwtToolkit::HideTouchKeyboard() {
+    if (m_isWin8OrLater && m_touchKbrdAutoShowIsEnabled) {
+        HWND hwnd = GetTouchKeyboardWindow();
+        if (hwnd != NULL) {
+            ::PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
+        }
+    }
+}
+
+BOOL AwtToolkit::TIRegisterTouchWindow(HWND hWnd, ULONG ulFlags) {
+    if (m_pRegisterTouchWindow == NULL) {
+        return FALSE;
+    }
+    return m_pRegisterTouchWindow(hWnd, ulFlags);
+}
+
+BOOL AwtToolkit::TIGetTouchInputInfo(HTOUCHINPUT hTouchInput,
+    UINT cInputs, PTOUCHINPUT pInputs, int cbSize) {
+    if (m_pGetTouchInputInfo == NULL) {
+        return FALSE;
+    }
+    return m_pGetTouchInputInfo(hTouchInput, cInputs, pInputs, cbSize);
+}
+
+BOOL AwtToolkit::TICloseTouchInputHandle(HTOUCHINPUT hTouchInput) {
+    if (m_pCloseTouchInputHandle == NULL) {
+        return FALSE;
+    }
+    return m_pCloseTouchInputHandle(hTouchInput);
+}
--- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h	Tue Oct 10 12:15:25 2017 -0700
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h	Wed Oct 11 15:53:25 2017 +0100
@@ -158,6 +158,48 @@
                 GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \
 }
 
+// Redefine WinAPI values related to touch input, if OS < Windows 7.
+#if (!defined(WINVER) || ((WINVER) < 0x0601))
+    /*
+     * RegisterTouchWindow flag values
+     */
+    #define TWF_FINETOUCH       (0x00000001)
+    #define TWF_WANTPALM        (0x00000002)
+
+    #define WM_TOUCH                        0x0240
+
+    /*
+     * Touch input handle
+     */
+    typedef HANDLE HTOUCHINPUT;
+
+    typedef struct tagTOUCHINPUT {
+        LONG x;
+        LONG y;
+        HANDLE hSource;
+        DWORD dwID;
+        DWORD dwFlags;
+        DWORD dwMask;
+        DWORD dwTime;
+        ULONG_PTR dwExtraInfo;
+        DWORD cxContact;
+        DWORD cyContact;
+    } TOUCHINPUT, *PTOUCHINPUT;
+    typedef TOUCHINPUT const * PCTOUCHINPUT;
+
+    /*
+     * Touch input flag values (TOUCHINPUT.dwFlags)
+     */
+    #define TOUCHEVENTF_MOVE            0x0001
+    #define TOUCHEVENTF_DOWN            0x0002
+    #define TOUCHEVENTF_UP              0x0004
+    #define TOUCHEVENTF_INRANGE         0x0008
+    #define TOUCHEVENTF_PRIMARY         0x0010
+    #define TOUCHEVENTF_NOCOALESCE      0x0020
+    #define TOUCHEVENTF_PEN             0x0040
+    #define TOUCHEVENTF_PALM            0x0080
+#endif
+
 /************************************************************************
  * AwtToolkit class
  */
@@ -196,6 +238,17 @@
     void setExtraMouseButtonsEnabled(BOOL enable);
     static UINT GetNumberOfButtons();
 
+    bool IsWin8OrLater();
+    bool IsTouchKeyboardAutoShowEnabled();
+    bool IsAnyKeyboardAttached();
+    bool IsTouchKeyboardAutoShowSystemEnabled();
+    void ShowTouchKeyboard();
+    void HideTouchKeyboard();
+    BOOL TIRegisterTouchWindow(HWND hWnd, ULONG ulFlags);
+    BOOL TIGetTouchInputInfo(HTOUCHINPUT hTouchInput,
+        UINT cInputs, PTOUCHINPUT pInputs, int cbSize);
+    BOOL TICloseTouchInputHandle(HTOUCHINPUT hTouchInput);
+
     INLINE BOOL localPump() { return m_localPump; }
     INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
     INLINE HWND GetHWnd() { return m_toolkitHWnd; }
@@ -393,6 +446,9 @@
 private:
     HWND CreateToolkitWnd(LPCTSTR name);
 
+    void InitTouchKeyboardExeFilePath();
+    HWND GetTouchKeyboardWindow();
+
     BOOL m_localPump;
     DWORD m_mainThreadId;
     HWND m_toolkitHWnd;
@@ -402,6 +458,18 @@
     BOOL m_isDisposed; // set to TRUE at end of Dispose
     BOOL m_areExtraMouseButtonsEnabled;
 
+    typedef BOOL (WINAPI *RegisterTouchWindowFunc)(HWND hWnd, ULONG ulFlags);
+    typedef BOOL (WINAPI *GetTouchInputInfoFunc)(HTOUCHINPUT hTouchInput,
+        UINT cInputs, PTOUCHINPUT pInputs, int cbSize);
+    typedef BOOL (WINAPI *CloseTouchInputHandleFunc)(HTOUCHINPUT hTouchInput);
+
+    BOOL m_isWin8OrLater;
+    BOOL m_touchKbrdAutoShowIsEnabled;
+    TCHAR* m_touchKbrdExeFilePath;
+    RegisterTouchWindowFunc m_pRegisterTouchWindow;
+    GetTouchInputInfoFunc m_pGetTouchInputInfo;
+    CloseTouchInputHandleFunc m_pCloseTouchInputHandle;
+
     BOOL m_vmSignalled; // set to TRUE if QUERYENDSESSION has successfully
                         // raised SIGTERM