blob: d33e545e27920c3b9f2e50971da9f1afd9e5e16c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.awt.X11;
27
28import java.awt.*;
29
30import java.util.LinkedList;
31import java.util.Iterator;
32
33import java.util.logging.Level;
34import java.util.logging.Logger;
35
36import sun.awt.EmbeddedFrame;
37import sun.awt.SunToolkit;
38
39public class XEmbeddedFramePeer extends XFramePeer {
40
41 private static final Logger xembedLog = Logger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer");
42
43 LinkedList<AWTKeyStroke> strokes;
44
45 XEmbedClientHelper embedder; // Caution - can be null if XEmbed is not supported
46 public XEmbeddedFramePeer(EmbeddedFrame target) {
47 // Don't specify PARENT_WINDOW param here. Instead we reparent
48 // this embedded frame peer to the proper parent window after
49 // an XEventDispatcher is registered to handle XEmbed events
50 super(new XCreateWindowParams(new Object[] {
51 TARGET, target,
52 VISIBLE, Boolean.TRUE,
53 EMBEDDED, Boolean.TRUE}));
54 }
55
56 public void preInit(XCreateWindowParams params) {
57 super.preInit(params);
58 strokes = new LinkedList<AWTKeyStroke>();
59 if (supportsXEmbed()) {
60 embedder = new XEmbedClientHelper();
61 }
62 }
63 void postInit(XCreateWindowParams params) {
64 super.postInit(params);
65 if (embedder != null) {
66 embedder.install(this);
67 } else if (getParentWindowHandle() != 0) {
68 XToolkit.awtLock();
69 try {
70 XlibWrapper.XReparentWindow(XToolkit.getDisplay(),
71 getWindow(),
72 getParentWindowHandle(),
73 0, 0);
74 } finally {
75 XToolkit.awtUnlock();
76 }
77 }
78 }
79
80 public void updateMinimumSize() {
81 }
82
83 protected String getWMName() {
84 return "JavaEmbeddedFrame";
85 }
86
87 final long getParentWindowHandle() {
88 return ((XEmbeddedFrame)target).handle;
89 }
90
91 boolean supportsXEmbed() {
92 return ((EmbeddedFrame)target).supportsXEmbed();
93 }
94
95 public boolean requestWindowFocus(long time, boolean timeProvided) {
96 // Should check for active state of host application
97 if (embedder != null && embedder.isActive()) {
98 xembedLog.fine("Requesting focus from embedding host");
99 return embedder.requestFocus();
100 } else {
101 xembedLog.fine("Requesting focus from X");
102 return super.requestWindowFocus(time, timeProvided);
103 }
104 }
105
106 protected void requestInitialFocus() {
107 if (embedder != null && supportsXEmbed()) {
108 embedder.requestFocus();
109 } else {
110 super.requestInitialFocus();
111 }
112 }
113
114 protected boolean isEventDisabled(XEvent e) {
115 if (embedder != null && embedder.isActive()) {
116 switch (e.get_type()) {
117 case FocusIn:
118 case FocusOut:
119 return true;
120 }
121 }
122 return super.isEventDisabled(e);
123 }
124
125 public void handleConfigureNotifyEvent(XEvent xev)
126 {
127 assert (SunToolkit.isAWTLockHeldByCurrentThread());
128 XConfigureEvent xe = xev.get_xconfigure();
129 if (xembedLog.isLoggable(Level.FINE)) {
130 xembedLog.fine(xe.toString());
131 }
132
133 // fix for 5063031
134 // if we use super.handleConfigureNotifyEvent() we would get wrong
135 // size and position because embedded frame really is NOT a decorated one
136 checkIfOnNewScreen(toGlobal(new Rectangle(xe.get_x(),
137 xe.get_y(),
138 xe.get_width(),
139 xe.get_height())));
140
141 Rectangle oldBounds = getBounds();
142
143 synchronized (getStateLock()) {
144 x = xe.get_x();
145 y = xe.get_y();
146 width = xe.get_width();
147 height = xe.get_height();
148
149 dimensions.setClientSize(width, height);
150 dimensions.setLocation(x, y);
151 }
152
153 if (!getLocation().equals(oldBounds.getLocation())) {
154 handleMoved(dimensions);
155 }
156 reconfigureContentWindow(dimensions);
157 }
158
159 protected void traverseOutForward() {
160 if (embedder != null && embedder.isActive()) {
161 if (embedder.isApplicationActive()) {
162 xembedLog.fine("Traversing out Forward");
163 embedder.traverseOutForward();
164 }
165 }
166 }
167
168 protected void traverseOutBackward() {
169 if (embedder != null && embedder.isActive()) {
170 if (embedder.isApplicationActive()) {
171 xembedLog.fine("Traversing out Backward");
172 embedder.traverseOutBackward();
173 }
174 }
175 }
176
177 // don't use getLocationOnScreen() inherited from XDecoratedPeer
178 public Point getLocationOnScreen() {
179 XToolkit.awtLock();
180 try {
181 return toGlobal(0, 0);
182 } finally {
183 XToolkit.awtUnlock();
184 }
185 }
186
187 // don't use getBounds() inherited from XDecoratedPeer
188 public Rectangle getBounds() {
189 return new Rectangle(x, y, width, height);
190 }
191
192 public void setBoundsPrivate(int x, int y, int width, int height) {
193 setBounds(x, y, width, height, SET_BOUNDS | NO_EMBEDDED_CHECK);
194 }
195
196 public Rectangle getBoundsPrivate() {
197 int x = 0, y = 0;
198 int w = 0, h = 0;
199 XWindowAttributes attr = new XWindowAttributes();
200
201 XToolkit.awtLock();
202 try {
203 XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
204 getWindow(), attr.pData);
205 x = attr.get_x();
206 y = attr.get_y();
207 w = attr.get_width();
208 h = attr.get_height();
209 } finally {
210 XToolkit.awtUnlock();
211 }
212 attr.dispose();
213
214 return new Rectangle(x, y, w, h);
215 }
216 void registerAccelerator(AWTKeyStroke stroke) {
217 if (stroke == null) return;
218 strokes.add(stroke);
219 if (embedder != null && embedder.isActive()) {
220 embedder.registerAccelerator(stroke, strokes.size()-1);
221 }
222 }
223
224 void unregisterAccelerator(AWTKeyStroke stroke) {
225 if (stroke == null) return;
226 if (embedder != null && embedder.isActive()) {
227 int index = strokes.indexOf(stroke);
228 embedder.unregisterAccelerator(index);
229 }
230 }
231
232 void notifyStarted() {
233 // Register accelerators
234 if (embedder != null && embedder.isActive()) {
235 int i = 0;
236 Iterator<AWTKeyStroke> iter = strokes.iterator();
237 while (iter.hasNext()) {
238 embedder.registerAccelerator(iter.next(), i++);
239 }
240 }
241 // Now we know that the the embedder is an XEmbed server, so we
242 // reregister the drop target to enable XDnD protocol support via
243 // XEmbed.
244 updateDropTarget();
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 {
256 Point absoluteLoc = XlibUtil.translateCoordinates(getWindow(),
257 XToolkit.getDefaultRootWindow(),
258 new Point(0, 0));
259 return absoluteLoc.x;
260 }
261
262 public int getAbsoluteY()
263 {
264 Point absoluteLoc = XlibUtil.translateCoordinates(getWindow(),
265 XToolkit.getDefaultRootWindow(),
266 new Point(0, 0));
267 return absoluteLoc.y;
268 }
269
270 public int getWidth() {
271 return width;
272 }
273 public int getHeight() {
274 return height;
275 }
276
277 public Dimension getSize() {
278 return new Dimension(width, height);
279 }
280
281 // override XWindowPeer's method to let the embedded frame to block
282 // the containing window
283 public void setModalBlocked(Dialog blocker, boolean blocked) {
284 super.setModalBlocked(blocker, blocked);
285
286 EmbeddedFrame frame = (EmbeddedFrame)target;
287 frame.notifyModalBlocked(blocker, blocked);
288 }
289}