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