jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedChildProxyPeer.java
changeset 25859 3317bb8137f4
parent 23010 6dadb192ad81
child 28231 b608ffcaed74
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedChildProxyPeer.java	Sun Aug 17 15:54:13 2014 +0100
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2003, 2012, 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 sun.awt.X11;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
+import java.awt.peer.*;
+import sun.java2d.pipe.Region;
+import sun.awt.*;
+
+public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
+    XEmbeddingContainer container;
+    XEmbedChildProxy proxy;
+    long handle;
+    XEmbedChildProxyPeer(XEmbedChildProxy proxy) {
+        this.container = proxy.getEmbeddingContainer();
+        this.handle = proxy.getHandle();
+        this.proxy = proxy;
+        initDispatching();
+    }
+
+    void initDispatching() {
+        XToolkit.awtLock();
+        try {
+            XToolkit.addEventDispatcher(handle, this);
+            XlibWrapper.XSelectInput(XToolkit.getDisplay(), handle,
+                    XConstants.StructureNotifyMask | XConstants.PropertyChangeMask);
+        }
+        finally {
+            XToolkit.awtUnlock();
+        }
+        container.notifyChildEmbedded(handle);
+    }
+    public boolean isObscured() { return false; }
+    public boolean canDetermineObscurity() { return false; }
+    public void                 setVisible(boolean b) {
+        if (!b) {
+            XToolkit.awtLock();
+            try {
+                XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), handle);
+            }
+            finally {
+                XToolkit.awtUnlock();
+            }
+        } else {
+            XToolkit.awtLock();
+            try {
+                XlibWrapper.XMapWindow(XToolkit.getDisplay(), handle);
+            }
+            finally {
+                XToolkit.awtUnlock();
+            }
+        }
+    }
+    public void setEnabled(boolean b) {}
+    public void paint(Graphics g) {}
+    public void repaint(long tm, int x, int y, int width, int height) {}
+    public void print(Graphics g) {}
+    public void setBounds(int x, int y, int width, int height, int op) {
+        // Unimplemeneted: Check for min/max hints for non-resizable
+        XToolkit.awtLock();
+        try {
+            XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), handle, x, y, width, height);
+        }
+        finally {
+            XToolkit.awtUnlock();
+        }
+    }
+    public void handleEvent(AWTEvent e) {
+        switch (e.getID()) {
+          case FocusEvent.FOCUS_GAINED:
+              XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(proxy);
+              container.focusGained(handle);
+              break;
+          case FocusEvent.FOCUS_LOST:
+              XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
+              container.focusLost(handle);
+              break;
+          case KeyEvent.KEY_PRESSED:
+          case KeyEvent.KEY_RELEASED:
+              if (!((InputEvent)e).isConsumed()) {
+                  container.forwardKeyEvent(handle, (KeyEvent)e);
+              }
+              break;
+        }
+    }
+    public void                coalescePaintEvent(PaintEvent e) {}
+    public Point                getLocationOnScreen() {
+        XWindowAttributes attr = new XWindowAttributes();
+        XToolkit.awtLock();
+        try{
+            XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(), handle, attr.pData);
+            return new Point(attr.get_x(), attr.get_y());
+        } finally {
+            XToolkit.awtUnlock();
+            attr.dispose();
+        }
+    }
+    public Dimension            getPreferredSize() {
+        XToolkit.awtLock();
+        long p_hints = XlibWrapper.XAllocSizeHints();
+        try {
+            XSizeHints hints = new XSizeHints(p_hints);
+            XlibWrapper.XGetWMNormalHints(XToolkit.getDisplay(), handle, p_hints, XlibWrapper.larg1);
+            Dimension res = new Dimension(hints.get_width(), hints.get_height());
+            return res;
+        } finally {
+            XlibWrapper.XFree(p_hints);
+            XToolkit.awtUnlock();
+        }
+    }
+    public Dimension            getMinimumSize() {
+        XToolkit.awtLock();
+        long p_hints = XlibWrapper.XAllocSizeHints();
+        try {
+            XSizeHints hints = new XSizeHints(p_hints);
+            XlibWrapper.XGetWMNormalHints(XToolkit.getDisplay(), handle, p_hints, XlibWrapper.larg1);
+            Dimension res = new Dimension(hints.get_min_width(), hints.get_min_height());
+            return res;
+        } finally {
+            XlibWrapper.XFree(p_hints);
+            XToolkit.awtUnlock();
+        }
+    }
+    public ColorModel           getColorModel() { return null; }
+    public Toolkit              getToolkit() { return Toolkit.getDefaultToolkit(); }
+
+    public Graphics             getGraphics() { return null; }
+    public FontMetrics          getFontMetrics(Font font) { return null; }
+    public void         dispose() {
+        container.detachChild(handle);
+    }
+    public void         setForeground(Color c) {}
+    public void         setBackground(Color c) {}
+    public void         setFont(Font f) {}
+    public void                 updateCursorImmediately() {}
+
+    void postEvent(AWTEvent event) {
+        XToolkit.postEvent(XToolkit.targetToAppContext(proxy), event);
+    }
+
+    boolean simulateMotifRequestFocus(Component lightweightChild, boolean temporary,
+                                      boolean focusedWindowChangeAllowed, long time)
+    {
+        if (lightweightChild == null) {
+            lightweightChild = (Component)proxy;
+        }
+        Component currentOwner = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
+        if (currentOwner != null && currentOwner.getPeer() == null) {
+            currentOwner = null;
+        }
+        FocusEvent  fg = new FocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED, false, currentOwner );
+        FocusEvent fl = null;
+        if (currentOwner != null) {
+            fl = new FocusEvent(currentOwner, FocusEvent.FOCUS_LOST, false, lightweightChild);
+        }
+
+        // TODO: do we need to wrap in sequenced?
+        if (fl != null) {
+            postEvent(XComponentPeer.wrapInSequenced(fl));
+        }
+        postEvent(XComponentPeer.wrapInSequenced(fg));
+        // End of Motif compatibility code
+        return true;
+    }
+
+    public boolean requestFocus(Component lightweightChild,
+                                boolean temporary,
+                                boolean focusedWindowChangeAllowed,
+                                long time,
+                                CausedFocusEvent.Cause cause)
+    {
+        int result = XKeyboardFocusManagerPeer
+            .shouldNativelyFocusHeavyweight(proxy, lightweightChild,
+                                            temporary, false, time, cause);
+
+        switch (result) {
+          case XKeyboardFocusManagerPeer.SNFH_FAILURE:
+              return false;
+          case XKeyboardFocusManagerPeer.SNFH_SUCCESS_PROCEED:
+              // Currently we just generate focus events like we deal with lightweight instead of calling
+              // XSetInputFocus on native window
+
+              /**
+               * The problems with requests in non-focused window arise because shouldNativelyFocusHeavyweight
+               * checks that native window is focused while appropriate WINDOW_GAINED_FOCUS has not yet
+               * been processed - it is in EventQueue. Thus, SNFH allows native request and stores request record
+               * in requests list - and it breaks our requests sequence as first record on WGF should be the last focus
+               * owner which had focus before WLF. So, we should not add request record for such requests
+               * but store this component in mostRecent - and return true as before for compatibility.
+               */
+              Container parent = proxy.getParent();
+              // Search for parent window
+              while (parent != null && !(parent instanceof Window)) {
+                  parent = parent.getParent();
+              }
+              if (parent != null) {
+                  Window parentWindow = (Window)parent;
+                  // and check that it is focused
+                  if (!parentWindow.isFocused() &&
+                      XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == parentWindow) {
+                      // if it is not - skip requesting focus on Solaris
+                      // but return true for compatibility.
+                      return true;
+                  }
+              }
+
+              // NOTE: We simulate heavyweight behavior of Motif - component receives focus right
+              // after request, not after event. Normally, we should better listen for event
+              // by listeners.
+
+              // TODO: consider replacing with XKeyboardFocusManagerPeer.deliverFocus
+              return simulateMotifRequestFocus(lightweightChild, temporary, focusedWindowChangeAllowed, time);
+              // Motif compatibility code
+          case XKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
+              // Either lightweight or excessive requiest - all events are generated.
+              return true;
+        }
+        return false;
+    }
+    public boolean              isFocusable() {
+        return true;
+    }
+
+    public Image                createImage(ImageProducer producer) { return null; }
+    public Image                createImage(int width, int height) { return null; }
+    public VolatileImage        createVolatileImage(int width, int height) { return null; }
+    public boolean              prepareImage(Image img, int w, int h, ImageObserver o) { return false; }
+    public int                  checkImage(Image img, int w, int h, ImageObserver o) { return 0; }
+    public GraphicsConfiguration getGraphicsConfiguration() { return null; }
+    public boolean     handlesWheelScrolling() { return true; }
+    public void createBuffers(int numBuffers, BufferCapabilities caps)
+      throws AWTException { }
+    public Image getBackBuffer() { return null; }
+    public void flip(int x1, int y1, int x2, int y2, BufferCapabilities.FlipContents flipAction) {  }
+    public void destroyBuffers() { }
+
+    /**
+     * Used by lightweight implementations to tell a ComponentPeer to layout
+     * its sub-elements.  For instance, a lightweight Checkbox needs to layout
+     * the box, as well as the text label.
+     */
+    public void        layout() {}
+
+    /**
+     * DEPRECATED:  Replaced by getPreferredSize().
+     */
+    public Dimension            preferredSize() {
+        return getPreferredSize();
+    }
+
+    /**
+     * DEPRECATED:  Replaced by getMinimumSize().
+     */
+    public Dimension            minimumSize() {
+        return getMinimumSize();
+    }
+
+    /**
+     * DEPRECATED:  Replaced by setVisible(boolean).
+     */
+    public void         show() {
+        setVisible(true);
+    }
+
+    /**
+     * DEPRECATED:  Replaced by setVisible(boolean).
+     */
+    public void         hide() {
+        setVisible(false);
+    }
+
+    /**
+     * DEPRECATED:  Replaced by setEnabled(boolean).
+     */
+    public void         enable() {}
+
+    /**
+     * DEPRECATED:  Replaced by setEnabled(boolean).
+     */
+    public void         disable() {}
+
+    /**
+     * DEPRECATED:  Replaced by setBounds(int, int, int, int).
+     */
+    public void reshape(int x, int y, int width, int height) {
+        setBounds(x, y, width, height, SET_BOUNDS);
+    }
+
+    Window getTopLevel(Component comp) {
+        while (comp != null && !(comp instanceof Window)) {
+            comp = comp.getParent();
+        }
+        return (Window)comp;
+    }
+
+    void childResized() {
+        XToolkit.postEvent(XToolkit.targetToAppContext(proxy), new ComponentEvent(proxy, ComponentEvent.COMPONENT_RESIZED));
+        container.childResized(proxy);
+//         XToolkit.postEvent(XToolkit.targetToAppContext(proxy), new InvocationEvent(proxy, new Runnable() {
+//                 public void run() {
+//                     getTopLevel(proxy).invalidate();
+//                     getTopLevel(proxy).pack();
+//                 }
+//             }));
+    }
+    void handlePropertyNotify(XEvent xev) {
+        XPropertyEvent ev = xev.get_xproperty();
+        if (ev.get_atom() == XAtom.XA_WM_NORMAL_HINTS) {
+            childResized();
+        }
+    }
+    void handleConfigureNotify(XEvent xev) {
+        childResized();
+    }
+    public void dispatchEvent(XEvent xev) {
+        int type = xev.get_type();
+        switch (type) {
+          case XConstants.PropertyNotify:
+              handlePropertyNotify(xev);
+              break;
+          case XConstants.ConfigureNotify:
+              handleConfigureNotify(xev);
+              break;
+        }
+    }
+
+    void requestXEmbedFocus() {
+        postEvent(new InvocationEvent(proxy, new Runnable() {
+                public void run() {
+                    proxy.requestFocusInWindow();
+                }
+            }));
+    }
+
+    public void reparent(ContainerPeer newNativeParent) {
+    }
+    public boolean isReparentSupported() {
+        return false;
+    }
+    public Rectangle getBounds() {
+        XWindowAttributes attrs = new XWindowAttributes();
+        XToolkit.awtLock();
+        try {
+            XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(), handle, attrs.pData);
+            return new Rectangle(attrs.get_x(), attrs.get_y(), attrs.get_width(), attrs.get_height());
+        } finally {
+            XToolkit.awtUnlock();
+            attrs.dispose();
+        }
+    }
+    public void setBoundsOperation(int operation) {
+    }
+
+    public void applyShape(Region shape) {
+    }
+
+    public void setZOrder(ComponentPeer above) {
+    }
+
+    public boolean updateGraphicsData(GraphicsConfiguration gc) {
+        return false;
+    }
+}