001: /*
002: * Copyright 2003-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: import java.awt.event.*;
030: import java.awt.image.ColorModel;
031: import java.awt.image.ImageObserver;
032: import java.awt.image.ImageProducer;
033: import java.awt.image.VolatileImage;
034: import java.awt.peer.*;
035: import sun.awt.*;
036: import sun.awt.motif.MToolkit;
037: import sun.awt.motif.X11FontMetrics;
038:
039: public class XEmbedChildProxyPeer implements ComponentPeer,
040: XEventDispatcher {
041: XEmbeddingContainer container;
042: XEmbedChildProxy proxy;
043: long handle;
044:
045: XEmbedChildProxyPeer(XEmbedChildProxy proxy) {
046: this .container = proxy.getEmbeddingContainer();
047: this .handle = proxy.getHandle();
048: this .proxy = proxy;
049: initDispatching();
050: }
051:
052: void initDispatching() {
053: XToolkit.awtLock();
054: try {
055: XToolkit.addEventDispatcher(handle, this );
056: XlibWrapper.XSelectInput(XToolkit.getDisplay(), handle,
057: XlibWrapper.StructureNotifyMask
058: | XlibWrapper.PropertyChangeMask);
059: } finally {
060: XToolkit.awtUnlock();
061: }
062: container.notifyChildEmbedded(handle);
063: }
064:
065: public boolean isObscured() {
066: return false;
067: }
068:
069: public boolean canDetermineObscurity() {
070: return false;
071: }
072:
073: public void setVisible(boolean b) {
074: if (!b) {
075: XToolkit.awtLock();
076: try {
077: XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), handle);
078: } finally {
079: XToolkit.awtUnlock();
080: }
081: } else {
082: XToolkit.awtLock();
083: try {
084: XlibWrapper.XMapWindow(XToolkit.getDisplay(), handle);
085: } finally {
086: XToolkit.awtUnlock();
087: }
088: }
089: }
090:
091: public void setEnabled(boolean b) {
092: }
093:
094: public void paint(Graphics g) {
095: }
096:
097: public void repaint(long tm, int x, int y, int width, int height) {
098: }
099:
100: public void print(Graphics g) {
101: }
102:
103: public void setBounds(int x, int y, int width, int height, int op) {
104: // Unimplemeneted: Check for min/max hints for non-resizable
105: XToolkit.awtLock();
106: try {
107: XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(),
108: handle, x, y, width, height);
109: } finally {
110: XToolkit.awtUnlock();
111: }
112: }
113:
114: public void handleEvent(AWTEvent e) {
115: switch (e.getID()) {
116: case FocusEvent.FOCUS_GAINED:
117: XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(proxy);
118: container.focusGained(handle);
119: break;
120: case FocusEvent.FOCUS_LOST:
121: XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
122: container.focusLost(handle);
123: break;
124: case KeyEvent.KEY_PRESSED:
125: case KeyEvent.KEY_RELEASED:
126: if (!((InputEvent) e).isConsumed()) {
127: container.forwardKeyEvent(handle, (KeyEvent) e);
128: }
129: break;
130: }
131: }
132:
133: public void coalescePaintEvent(PaintEvent e) {
134: }
135:
136: public Point getLocationOnScreen() {
137: XWindowAttributes attr = new XWindowAttributes();
138: XToolkit.awtLock();
139: try {
140: XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
141: handle, attr.pData);
142: return new Point(attr.get_x(), attr.get_y());
143: } finally {
144: XToolkit.awtUnlock();
145: attr.dispose();
146: }
147: }
148:
149: public Dimension getPreferredSize() {
150: XToolkit.awtLock();
151: long p_hints = XlibWrapper.XAllocSizeHints();
152: try {
153: XSizeHints hints = new XSizeHints(p_hints);
154: XlibWrapper.XGetWMNormalHints(XToolkit.getDisplay(),
155: handle, p_hints, XlibWrapper.larg1);
156: Dimension res = new Dimension(hints.get_width(), hints
157: .get_height());
158: return res;
159: } finally {
160: XlibWrapper.XFree(p_hints);
161: XToolkit.awtUnlock();
162: }
163: }
164:
165: public Dimension getMinimumSize() {
166: XToolkit.awtLock();
167: long p_hints = XlibWrapper.XAllocSizeHints();
168: try {
169: XSizeHints hints = new XSizeHints(p_hints);
170: XlibWrapper.XGetWMNormalHints(XToolkit.getDisplay(),
171: handle, p_hints, XlibWrapper.larg1);
172: Dimension res = new Dimension(hints.get_min_width(), hints
173: .get_min_height());
174: return res;
175: } finally {
176: XlibWrapper.XFree(p_hints);
177: XToolkit.awtUnlock();
178: }
179: }
180:
181: public ColorModel getColorModel() {
182: return null;
183: }
184:
185: public Toolkit getToolkit() {
186: return Toolkit.getDefaultToolkit();
187: }
188:
189: public Graphics getGraphics() {
190: return null;
191: }
192:
193: public FontMetrics getFontMetrics(Font font) {
194: return null;
195: }
196:
197: public void dispose() {
198: container.detachChild(handle);
199: }
200:
201: public void setForeground(Color c) {
202: }
203:
204: public void setBackground(Color c) {
205: }
206:
207: public void setFont(Font f) {
208: }
209:
210: public void updateCursorImmediately() {
211: }
212:
213: void postEvent(AWTEvent event) {
214: XToolkit.postEvent(XToolkit.targetToAppContext(proxy), event);
215: }
216:
217: boolean simulateMotifRequestFocus(Component lightweightChild,
218: boolean temporary, boolean focusedWindowChangeAllowed,
219: long time) {
220: if (lightweightChild == null) {
221: lightweightChild = (Component) proxy;
222: }
223: Component currentOwner = XKeyboardFocusManagerPeer
224: .getCurrentNativeFocusOwner();
225: if (currentOwner != null && currentOwner.getPeer() == null) {
226: currentOwner = null;
227: }
228: FocusEvent fg = new FocusEvent(lightweightChild,
229: FocusEvent.FOCUS_GAINED, false, currentOwner);
230: FocusEvent fl = null;
231: if (currentOwner != null) {
232: fl = new FocusEvent(currentOwner, FocusEvent.FOCUS_LOST,
233: false, lightweightChild);
234: }
235:
236: if (fl != null) {
237: postEvent(XComponentPeer.wrapInSequenced(fl));
238: }
239: postEvent(XComponentPeer.wrapInSequenced(fg));
240: // End of Motif compatibility code
241: return true;
242: }
243:
244: public boolean requestFocus(Component lightweightChild,
245: boolean temporary, boolean focusedWindowChangeAllowed,
246: long time, CausedFocusEvent.Cause cause) {
247: int result = XKeyboardFocusManagerPeer
248: .shouldNativelyFocusHeavyweight(proxy,
249: lightweightChild, temporary, false, time, cause);
250:
251: switch (result) {
252: case XComponentPeer.SNFH_FAILURE:
253: return false;
254: case XComponentPeer.SNFH_SUCCESS_PROCEED:
255: // Currently we just generate focus events like we deal with lightweight instead of calling
256: // XSetInputFocus on native window
257:
258: /**
259: * The problems with requests in non-focused window arise because shouldNativelyFocusHeavyweight
260: * checks that native window is focused while appropriate WINDOW_GAINED_FOCUS has not yet
261: * been processed - it is in EventQueue. Thus, SNFH allows native request and stores request record
262: * in requests list - and it breaks our requests sequence as first record on WGF should be the last focus
263: * owner which had focus before WLF. So, we should not add request record for such requests
264: * but store this component in mostRecent - and return true as before for compatibility.
265: */
266: Container parent = proxy.getParent();
267: // Search for parent window
268: while (parent != null && !(parent instanceof Window)) {
269: parent = parent.getParent();
270: }
271: if (parent != null) {
272: Window parentWindow = (Window) parent;
273: // and check that it is focused
274: if (!parentWindow.isFocused()
275: && XKeyboardFocusManagerPeer
276: .getCurrentNativeFocusedWindow() == parentWindow) {
277: // if it is not - skip requesting focus on Solaris
278: // but return true for compatibility.
279: return true;
280: }
281: }
282:
283: // NOTE: We simulate heavyweight behavior of Motif - component receives focus right
284: // after request, not after event. Normally, we should better listen for event
285: // by listeners.
286: return simulateMotifRequestFocus(lightweightChild,
287: temporary, focusedWindowChangeAllowed, time);
288: // Motif compatibility code
289: case XComponentPeer.SNFH_SUCCESS_HANDLED:
290: // Either lightweight or excessive requiest - all events are generated.
291: return true;
292: }
293: return false;
294: }
295:
296: public boolean isFocusable() {
297: return true;
298: }
299:
300: public Image createImage(ImageProducer producer) {
301: return null;
302: }
303:
304: public Image createImage(int width, int height) {
305: return null;
306: }
307:
308: public VolatileImage createVolatileImage(int width, int height) {
309: return null;
310: }
311:
312: public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
313: return false;
314: }
315:
316: public int checkImage(Image img, int w, int h, ImageObserver o) {
317: return 0;
318: }
319:
320: public GraphicsConfiguration getGraphicsConfiguration() {
321: return null;
322: }
323:
324: public boolean handlesWheelScrolling() {
325: return true;
326: }
327:
328: public void createBuffers(int numBuffers, BufferCapabilities caps)
329: throws AWTException {
330: }
331:
332: public Image getBackBuffer() {
333: return null;
334: }
335:
336: public void flip(BufferCapabilities.FlipContents flipAction) {
337: }
338:
339: public void destroyBuffers() {
340: }
341:
342: /**
343: * Used by lightweight implementations to tell a ComponentPeer to layout
344: * its sub-elements. For instance, a lightweight Checkbox needs to layout
345: * the box, as well as the text label.
346: */
347: public void layout() {
348: }
349:
350: /**
351: * DEPRECATED: Replaced by getPreferredSize().
352: */
353: public Dimension preferredSize() {
354: return getPreferredSize();
355: }
356:
357: /**
358: * DEPRECATED: Replaced by getMinimumSize().
359: */
360: public Dimension minimumSize() {
361: return getMinimumSize();
362: }
363:
364: /**
365: * DEPRECATED: Replaced by setVisible(boolean).
366: */
367: public void show() {
368: setVisible(true);
369: }
370:
371: /**
372: * DEPRECATED: Replaced by setVisible(boolean).
373: */
374: public void hide() {
375: setVisible(false);
376: }
377:
378: /**
379: * DEPRECATED: Replaced by setEnabled(boolean).
380: */
381: public void enable() {
382: }
383:
384: /**
385: * DEPRECATED: Replaced by setEnabled(boolean).
386: */
387: public void disable() {
388: }
389:
390: /**
391: * DEPRECATED: Replaced by setBounds(int, int, int, int).
392: */
393: public void reshape(int x, int y, int width, int height) {
394: setBounds(x, y, width, height, SET_BOUNDS);
395: }
396:
397: Window getTopLevel(Component comp) {
398: while (comp != null && !(comp instanceof Window)) {
399: comp = comp.getParent();
400: }
401: return (Window) comp;
402: }
403:
404: void childResized() {
405: XToolkit.postEvent(XToolkit.targetToAppContext(proxy),
406: new ComponentEvent(proxy,
407: ComponentEvent.COMPONENT_RESIZED));
408: container.childResized(proxy);
409: // XToolkit.postEvent(XToolkit.targetToAppContext(proxy), new InvocationEvent(proxy, new Runnable() {
410: // public void run() {
411: // getTopLevel(proxy).invalidate();
412: // getTopLevel(proxy).pack();
413: // }
414: // }));
415: }
416:
417: void handlePropertyNotify(XEvent xev) {
418: XPropertyEvent ev = xev.get_xproperty();
419: if (ev.get_atom() == XAtom.XA_WM_NORMAL_HINTS) {
420: childResized();
421: }
422: }
423:
424: void handleConfigureNotify(XEvent xev) {
425: childResized();
426: }
427:
428: public void dispatchEvent(XEvent xev) {
429: int type = xev.get_type();
430: switch (type) {
431: case XlibWrapper.PropertyNotify:
432: handlePropertyNotify(xev);
433: break;
434: case XlibWrapper.ConfigureNotify:
435: handleConfigureNotify(xev);
436: break;
437: }
438: }
439:
440: void requestXEmbedFocus() {
441: postEvent(new InvocationEvent(proxy, new Runnable() {
442: public void run() {
443: proxy.requestFocusInWindow();
444: }
445: }));
446: }
447:
448: public void reparent(ContainerPeer newNativeParent) {
449: }
450:
451: public boolean isReparentSupported() {
452: return false;
453: }
454:
455: public Rectangle getBounds() {
456: XWindowAttributes attrs = new XWindowAttributes();
457: XToolkit.awtLock();
458: try {
459: XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
460: handle, attrs.pData);
461: return new Rectangle(attrs.get_x(), attrs.get_y(), attrs
462: .get_width(), attrs.get_height());
463: } finally {
464: XToolkit.awtUnlock();
465: attrs.dispose();
466: }
467: }
468:
469: public void setBoundsOperation(int operation) {
470: }
471: }
|