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: package sun.awt.X11;
026:
027: import java.awt.Component;
028: import java.awt.Rectangle;
029: import java.awt.Insets;
030:
031: import java.awt.event.ComponentEvent;
032:
033: import java.util.logging.Level;
034: import java.util.logging.Logger;
035:
036: import sun.awt.ComponentAccessor;
037:
038: /**
039: * This class implements window which serves as content window for decorated frames.
040: * Its purpose to provide correct events dispatching for the complex
041: * constructs such as decorated frames.
042: */
043: public class XContentWindow extends XWindow implements XConstants {
044: private static Logger insLog = Logger
045: .getLogger("sun.awt.X11.insets.XContentWindow");
046:
047: XDecoratedPeer parentFrame;
048:
049: // A list of expose events that come when the parentFrame is iconified
050: private java.util.List<SavedExposeEvent> iconifiedExposeEvents = new java.util.ArrayList<SavedExposeEvent>();
051:
052: XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
053: super ((Component) parentFrame.getTarget(), parentFrame
054: .getShell(), bounds);
055: this .parentFrame = parentFrame;
056: }
057:
058: void preInit(XCreateWindowParams params) {
059: super .preInit(params);
060: params
061: .putIfNull(BIT_GRAVITY, Integer
062: .valueOf(NorthWestGravity));
063: Long eventMask = (Long) params.get(EVENT_MASK);
064: if (eventMask != null) {
065: eventMask = eventMask & ~(StructureNotifyMask);
066: params.put(EVENT_MASK, eventMask);
067: }
068: }
069:
070: void initialize() {
071: xSetVisible(true);
072: }
073:
074: protected String getWMName() {
075: return "Content window";
076: }
077:
078: protected boolean isEventDisabled(XEvent e) {
079: switch (e.get_type()) {
080: // Override parentFrame to receive MouseEnter/Exit
081: case EnterNotify:
082: case LeaveNotify:
083: return false;
084: // We handle ConfigureNotify specifically in XDecoratedPeer
085: case ConfigureNotify:
086: return true;
087: // We don't want SHOWN/HIDDEN on content window since it will duplicate XDecoratedPeer
088: case MapNotify:
089: case UnmapNotify:
090: return true;
091: default:
092: return super .isEventDisabled(e)
093: || parentFrame.isEventDisabled(e);
094: }
095: }
096:
097: // Coordinates are that of the shell
098: void setContentBounds(WindowDimensions dims) {
099: XToolkit.awtLock();
100: try {
101: // Bounds of content window are of the same size as bounds of Java window and with
102: // location as -(insets)
103: Rectangle newBounds = dims.getBounds();
104: Insets in = dims.getInsets();
105: if (in != null) {
106: newBounds.setLocation(-in.left, -in.top);
107: }
108: if (insLog.isLoggable(Level.FINE))
109: insLog.log(Level.FINE,
110: "Setting content bounds {0}, old bounds {1}",
111: new Object[] { newBounds, getBounds() });
112: // Fix for 5023533:
113: // Change in the size of the content window means, well, change of the size
114: // Change in the location of the content window means change in insets
115: boolean needHandleResize = !(newBounds.equals(getBounds()));
116: reshape(newBounds);
117: if (needHandleResize) {
118: insLog.fine("Sending RESIZED");
119: handleResize(newBounds);
120: }
121: } finally {
122: XToolkit.awtUnlock();
123: }
124: validateSurface();
125: }
126:
127: // NOTE: This method may be called by privileged threads.
128: // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
129: public void handleResize(Rectangle bounds) {
130: ComponentAccessor.setWidth((Component) target, bounds.width);
131: ComponentAccessor.setHeight((Component) target, bounds.height);
132: postEvent(new ComponentEvent(target,
133: ComponentEvent.COMPONENT_RESIZED));
134: }
135:
136: public void handleExposeEvent(Component target, int x, int y,
137: int w, int h) {
138: // TODO: ?
139: // get rid of 'istanceof' by subclassing:
140: // XContentWindow -> XFrameContentWindow
141:
142: // Expose event(s) that result from deiconification
143: // come before a deicinofication notification.
144: // We reorder these events by saving all expose events
145: // that come when the frame is iconified. Then we
146: // actually handle saved expose events on deiconification.
147:
148: if (parentFrame instanceof XFramePeer
149: && (((XFramePeer) parentFrame).getState() & java.awt.Frame.ICONIFIED) != 0) {
150: // Save expose events if the frame is iconified
151: // in order to handle them on deiconification.
152: iconifiedExposeEvents.add(new SavedExposeEvent(target, x,
153: y, w, h));
154: } else {
155: // Normal case: [it is not a frame or] the frame is not iconified.
156: super .handleExposeEvent(target, x, y, w, h);
157: }
158: }
159:
160: void purgeIconifiedExposeEvents() {
161: for (SavedExposeEvent evt : iconifiedExposeEvents) {
162: super .handleExposeEvent(evt.target, evt.x, evt.y, evt.w,
163: evt.h);
164: }
165: iconifiedExposeEvents.clear();
166: }
167:
168: private static class SavedExposeEvent {
169: Component target;
170: int x, y, w, h;
171:
172: SavedExposeEvent(Component target, int x, int y, int w, int h) {
173: this .target = target;
174: this .x = x;
175: this .y = y;
176: this .w = w;
177: this .h = h;
178: }
179: }
180:
181: public String toString() {
182: return getClass().getName() + "[" + getBounds() + "]";
183: }
184: }
|