001: /*
002: * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.awt.X11;
027:
028: import java.awt.*;
029:
030: import java.util.LinkedList;
031: import java.util.Iterator;
032:
033: import java.util.logging.Level;
034: import java.util.logging.Logger;
035:
036: import sun.awt.EmbeddedFrame;
037: import sun.awt.SunToolkit;
038:
039: public class XEmbeddedFramePeer extends XFramePeer {
040:
041: private static final Logger xembedLog = Logger
042: .getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer");
043:
044: LinkedList<AWTKeyStroke> strokes;
045:
046: XEmbedClientHelper embedder; // Caution - can be null if XEmbed is not supported
047:
048: public XEmbeddedFramePeer(EmbeddedFrame target) {
049: // Don't specify PARENT_WINDOW param here. Instead we reparent
050: // this embedded frame peer to the proper parent window after
051: // an XEventDispatcher is registered to handle XEmbed events
052: super (new XCreateWindowParams(new Object[] { TARGET, target,
053: VISIBLE, Boolean.TRUE, EMBEDDED, Boolean.TRUE }));
054: }
055:
056: public void preInit(XCreateWindowParams params) {
057: super .preInit(params);
058: strokes = new LinkedList<AWTKeyStroke>();
059: if (supportsXEmbed()) {
060: embedder = new XEmbedClientHelper();
061: }
062: }
063:
064: void postInit(XCreateWindowParams params) {
065: super .postInit(params);
066: if (embedder != null) {
067: embedder.install(this );
068: } else if (getParentWindowHandle() != 0) {
069: XToolkit.awtLock();
070: try {
071: XlibWrapper.XReparentWindow(XToolkit.getDisplay(),
072: getWindow(), getParentWindowHandle(), 0, 0);
073: } finally {
074: XToolkit.awtUnlock();
075: }
076: }
077: }
078:
079: public void updateMinimumSize() {
080: }
081:
082: protected String getWMName() {
083: return "JavaEmbeddedFrame";
084: }
085:
086: final long getParentWindowHandle() {
087: return ((XEmbeddedFrame) target).handle;
088: }
089:
090: boolean supportsXEmbed() {
091: return ((EmbeddedFrame) target).supportsXEmbed();
092: }
093:
094: public boolean requestWindowFocus(long time, boolean timeProvided) {
095: // Should check for active state of host application
096: if (embedder != null && embedder.isActive()) {
097: xembedLog.fine("Requesting focus from embedding host");
098: return embedder.requestFocus();
099: } else {
100: xembedLog.fine("Requesting focus from X");
101: return super .requestWindowFocus(time, timeProvided);
102: }
103: }
104:
105: protected void requestInitialFocus() {
106: if (embedder != null && supportsXEmbed()) {
107: embedder.requestFocus();
108: } else {
109: super .requestInitialFocus();
110: }
111: }
112:
113: protected boolean isEventDisabled(XEvent e) {
114: if (embedder != null && embedder.isActive()) {
115: switch (e.get_type()) {
116: case FocusIn:
117: case FocusOut:
118: return true;
119: }
120: }
121: return super .isEventDisabled(e);
122: }
123:
124: public void handleConfigureNotifyEvent(XEvent xev) {
125: assert (SunToolkit.isAWTLockHeldByCurrentThread());
126: XConfigureEvent xe = xev.get_xconfigure();
127: if (xembedLog.isLoggable(Level.FINE)) {
128: xembedLog.fine(xe.toString());
129: }
130:
131: // fix for 5063031
132: // if we use super.handleConfigureNotifyEvent() we would get wrong
133: // size and position because embedded frame really is NOT a decorated one
134: checkIfOnNewScreen(toGlobal(new Rectangle(xe.get_x(), xe
135: .get_y(), xe.get_width(), xe.get_height())));
136:
137: Rectangle oldBounds = getBounds();
138:
139: synchronized (getStateLock()) {
140: x = xe.get_x();
141: y = xe.get_y();
142: width = xe.get_width();
143: height = xe.get_height();
144:
145: dimensions.setClientSize(width, height);
146: dimensions.setLocation(x, y);
147: }
148:
149: if (!getLocation().equals(oldBounds.getLocation())) {
150: handleMoved(dimensions);
151: }
152: reconfigureContentWindow(dimensions);
153: }
154:
155: protected void traverseOutForward() {
156: if (embedder != null && embedder.isActive()) {
157: if (embedder.isApplicationActive()) {
158: xembedLog.fine("Traversing out Forward");
159: embedder.traverseOutForward();
160: }
161: }
162: }
163:
164: protected void traverseOutBackward() {
165: if (embedder != null && embedder.isActive()) {
166: if (embedder.isApplicationActive()) {
167: xembedLog.fine("Traversing out Backward");
168: embedder.traverseOutBackward();
169: }
170: }
171: }
172:
173: // don't use getLocationOnScreen() inherited from XDecoratedPeer
174: public Point getLocationOnScreen() {
175: XToolkit.awtLock();
176: try {
177: return toGlobal(0, 0);
178: } finally {
179: XToolkit.awtUnlock();
180: }
181: }
182:
183: // don't use getBounds() inherited from XDecoratedPeer
184: public Rectangle getBounds() {
185: return new Rectangle(x, y, width, height);
186: }
187:
188: public void setBoundsPrivate(int x, int y, int width, int height) {
189: setBounds(x, y, width, height, SET_BOUNDS | NO_EMBEDDED_CHECK);
190: }
191:
192: public Rectangle getBoundsPrivate() {
193: int x = 0, y = 0;
194: int w = 0, h = 0;
195: XWindowAttributes attr = new XWindowAttributes();
196:
197: XToolkit.awtLock();
198: try {
199: XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
200: getWindow(), attr.pData);
201: x = attr.get_x();
202: y = attr.get_y();
203: w = attr.get_width();
204: h = attr.get_height();
205: } finally {
206: XToolkit.awtUnlock();
207: }
208: attr.dispose();
209:
210: return new Rectangle(x, y, w, h);
211: }
212:
213: void registerAccelerator(AWTKeyStroke stroke) {
214: if (stroke == null)
215: return;
216: strokes.add(stroke);
217: if (embedder != null && embedder.isActive()) {
218: embedder.registerAccelerator(stroke, strokes.size() - 1);
219: }
220: }
221:
222: void unregisterAccelerator(AWTKeyStroke stroke) {
223: if (stroke == null)
224: return;
225: if (embedder != null && embedder.isActive()) {
226: int index = strokes.indexOf(stroke);
227: embedder.unregisterAccelerator(index);
228: }
229: }
230:
231: void notifyStarted() {
232: // Register accelerators
233: if (embedder != null && embedder.isActive()) {
234: int i = 0;
235: Iterator<AWTKeyStroke> iter = strokes.iterator();
236: while (iter.hasNext()) {
237: embedder.registerAccelerator(iter.next(), i++);
238: }
239: }
240: // Now we know that the the embedder is an XEmbed server, so we
241: // reregister the drop target to enable XDnD protocol support via
242: // XEmbed.
243: updateDropTarget();
244: }
245:
246: long getFocusTargetWindow() {
247: return getWindow();
248: }
249:
250: boolean isXEmbedActive() {
251: return embedder != null && embedder.isActive();
252: }
253:
254: public int getAbsoluteX() {
255: Point absoluteLoc = XlibUtil.translateCoordinates(getWindow(),
256: XToolkit.getDefaultRootWindow(), new Point(0, 0));
257: return absoluteLoc.x;
258: }
259:
260: public int getAbsoluteY() {
261: Point absoluteLoc = XlibUtil.translateCoordinates(getWindow(),
262: XToolkit.getDefaultRootWindow(), new Point(0, 0));
263: return absoluteLoc.y;
264: }
265:
266: public int getWidth() {
267: return width;
268: }
269:
270: public int getHeight() {
271: return height;
272: }
273:
274: public Dimension getSize() {
275: return new Dimension(width, height);
276: }
277:
278: // override XWindowPeer's method to let the embedded frame to block
279: // the containing window
280: public void setModalBlocked(Dialog blocker, boolean blocked) {
281: super .setModalBlocked(blocker, blocked);
282:
283: EmbeddedFrame frame = (EmbeddedFrame) target;
284: frame.notifyModalBlocked(blocker, blocked);
285: }
286: }
|