1 /* 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.awt.X11; 27 28 import java.awt.*; 29 import java.util.HashMap; 30 import java.awt.event.KeyEvent; 31 import java.lang.reflect.*; 32 import sun.awt.AWTAccessor; 33 34 public class XEmbeddingContainer extends XEmbedHelper implements XEventDispatcher { 35 HashMap children = new HashMap(); 36 37 XEmbeddingContainer() { 38 } 39 40 XWindow embedder; 41 void install(XWindow embedder) { 42 this.embedder = embedder; 43 XToolkit.addEventDispatcher(embedder.getWindow(), this); 44 } 45 void deinstall() { 46 XToolkit.removeEventDispatcher(embedder.getWindow(), this); 47 } 48 49 void add(long child) { 50 if (checkXEmbed(child)) { 51 Component proxy = createChildProxy(child); 52 ((Container)embedder.getTarget()).add("Center", proxy); 53 if (proxy.getPeer() != null) { 54 children.put(Long.valueOf(child), proxy.getPeer()); 55 } 56 } 57 } 58 59 Component createChildProxy(long child) { 60 return new XEmbedChildProxy(this, child); 61 } 62 void notifyChildEmbedded(long child) { 63 sendMessage(child, XEMBED_EMBEDDED_NOTIFY, embedder.getWindow(), XEMBED_VERSION, 0); 64 } 65 66 void childResized(Component child) { 67 } 68 69 boolean checkXEmbed(long child) { 70 long data = unsafe.allocateMemory(8); 71 try { 72 if (XEmbedInfo.getAtomData(child, data, 2)) { 73 int protocol = unsafe.getInt(data); 74 int flags = unsafe.getInt(data); 75 return true; 76 } 77 } finally { 78 unsafe.freeMemory(data); 79 } 80 return false; 81 } 82 83 void detachChild(long child) { 84 // The embedder can unmap the client and reparent the client window 85 // to the root window. If the client receives an ReparentNotify 86 // event, it should check the parent field of the XReparentEvent 87 // structure. If this is the root window of the window's screen, then 88 // the protocol is finished and there is no further interaction. If 89 // it is a window other than the root window, then the protocol 90 // continues with the new parent acting as the embedder window. 91 XToolkit.awtLock(); 92 try { 93 XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), child); 94 XlibWrapper.XReparentWindow(XToolkit.getDisplay(), child, XToolkit.getDefaultRootWindow(), 0, 0); 95 } 96 finally { 97 XToolkit.awtUnlock(); 98 } 99 } 100 101 void focusGained(long child) { 102 sendMessage(child, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0); 103 } 104 void focusLost(long child) { 105 sendMessage(child, XEMBED_FOCUS_OUT); 106 } 107 108 XEmbedChildProxyPeer getChild(long child) { 109 return (XEmbedChildProxyPeer)children.get(Long.valueOf(child)); 110 } 111 public void handleClientMessage(XEvent xev) { 112 XClientMessageEvent msg = xev.get_xclient(); 113 if (msg.get_message_type() == XEmbed.getAtom()) { 114 switch ((int)msg.get_data(1)) { 115 case XEMBED_REQUEST_FOCUS: 116 long child = msg.get_data(2); // Unspecified 117 getChild(child).requestXEmbedFocus(); 118 break; 119 } 120 } 121 } 122 public void dispatchEvent(XEvent xev) { 123 switch(xev.get_type()) { 124 case XConstants.ClientMessage: 125 handleClientMessage(xev); 126 break; 127 } 128 } 129 130 void forwardKeyEvent(long child, KeyEvent e) { 131 byte[] bdata = AWTAccessor.getAWTEventAccessor().getBData(e); 132 long data = Native.toData(bdata); 133 if (data == 0) { 134 return; 135 } 136 XKeyEvent ke = new XKeyEvent(data); 137 ke.set_window(child); 138 XToolkit.awtLock(); 139 try { 140 XlibWrapper.XSendEvent(XToolkit.getDisplay(), child, false, XConstants.NoEventMask, data); 141 } 142 finally { 143 XToolkit.awtUnlock(); 144 } 145 XlibWrapper.unsafe.freeMemory(data); 146 } 147 }