/*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.X11;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.Insets;
import java.awt.event.ComponentEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import sun.awt.ComponentAccessor;
This class implements window which serves as content window for decorated frames.
Its purpose to provide correct events dispatching for the complex
constructs such as decorated frames.
/**
* This class implements window which serves as content window for decorated frames.
* Its purpose to provide correct events dispatching for the complex
* constructs such as decorated frames.
*/
public class XContentWindow extends XWindow implements XConstants {
private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow");
XDecoratedPeer parentFrame;
// A list of expose events that come when the parentFrame is iconified
private java.util.List<SavedExposeEvent> iconifiedExposeEvents = new java.util.ArrayList<SavedExposeEvent>();
XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds);
this.parentFrame = parentFrame;
}
void preInit(XCreateWindowParams params) {
super.preInit(params);
params.putIfNull(BIT_GRAVITY, Integer.valueOf(NorthWestGravity));
Long eventMask = (Long)params.get(EVENT_MASK);
if (eventMask != null) {
eventMask = eventMask & ~(StructureNotifyMask);
params.put(EVENT_MASK, eventMask);
}
}
void initialize() {
xSetVisible(true);
}
protected String getWMName() {
return "Content window";
}
protected boolean isEventDisabled(XEvent e) {
switch (e.get_type()) {
// Override parentFrame to receive MouseEnter/Exit
case EnterNotify:
case LeaveNotify:
return false;
// We handle ConfigureNotify specifically in XDecoratedPeer
case ConfigureNotify:
return true;
// We don't want SHOWN/HIDDEN on content window since it will duplicate XDecoratedPeer
case MapNotify:
case UnmapNotify:
return true;
default:
return super.isEventDisabled(e) || parentFrame.isEventDisabled(e);
}
}
// Coordinates are that of the shell
void setContentBounds(WindowDimensions dims) {
XToolkit.awtLock();
try {
// Bounds of content window are of the same size as bounds of Java window and with
// location as -(insets)
Rectangle newBounds = dims.getBounds();
Insets in = dims.getInsets();
if (in != null) {
newBounds.setLocation(-in.left, -in.top);
}
if (insLog.isLoggable(Level.FINE)) {
insLog.log(Level.FINE, "Setting content bounds {0}, old bounds {1}",
new Object[] {String.valueOf(newBounds), String.valueOf(getBounds())});
}
// Fix for 5023533:
// Change in the size of the content window means, well, change of the size
// Change in the location of the content window means change in insets
boolean needHandleResize = !(newBounds.equals(getBounds()));
reshape(newBounds);
if (needHandleResize) {
if (insLog.isLoggable(Level.FINE)) {
insLog.fine("Sending RESIZED");
}
handleResize(newBounds);
}
} finally {
XToolkit.awtUnlock();
}
validateSurface();
}
// NOTE: This method may be called by privileged threads.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
public void handleResize(Rectangle bounds) {
ComponentAccessor.setWidth((Component)target, bounds.width);
ComponentAccessor.setHeight((Component)target, bounds.height);
postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED));
}
public void postPaintEvent(Component target, int x, int y, int w, int h) {
// TODO: ?
// get rid of 'istanceof' by subclassing:
// XContentWindow -> XFrameContentWindow
// Expose event(s) that result from deiconification
// come before a deicinofication notification.
// We reorder these events by saving all expose events
// that come when the frame is iconified. Then we
// actually handle saved expose events on deiconification.
if (parentFrame instanceof XFramePeer &&
(((XFramePeer)parentFrame).getState() & java.awt.Frame.ICONIFIED) != 0) {
// Save expose events if the frame is iconified
// in order to handle them on deiconification.
iconifiedExposeEvents.add(new SavedExposeEvent(target, x, y, w, h));
} else {
// Normal case: [it is not a frame or] the frame is not iconified.
super.postPaintEvent(target, x, y, w, h);
}
}
void purgeIconifiedExposeEvents() {
for (SavedExposeEvent evt : iconifiedExposeEvents) {
super.postPaintEvent(evt.target, evt.x, evt.y, evt.w, evt.h);
}
iconifiedExposeEvents.clear();
}
private static class SavedExposeEvent {
Component target;
int x, y, w, h;
SavedExposeEvent(Component target, int x, int y, int w, int h) {
this.target = target;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
}
public String toString() {
return getClass().getName() + "[" + getBounds() + "]";
}
}