1 /*
2 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package sun.awt.X11;
26
27 import java.awt.Component;
28 import java.awt.Rectangle;
29 import java.awt.Insets;
30
31 import java.awt.event.ComponentEvent;
32
33 import sun.util.logging.PlatformLogger;
34
35 import sun.awt.AWTAccessor;
36
37 /**
38 * This class implements window which serves as content window for decorated frames.
39 * Its purpose to provide correct events dispatching for the complex
40 * constructs such as decorated frames.
41 *
42 * It should always be located at (- left inset, - top inset) in the associated
43 * decorated window. So coordinates in it would be the same as java coordinates.
44 */
45 public final class XContentWindow extends XWindow {
46 private static PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XContentWindow");
47
48 static XContentWindow createContent(XDecoratedPeer parentFrame) {
49 final WindowDimensions dims = parentFrame.getDimensions();
50 Rectangle rec = dims.getBounds();
51 // Fix for - set the location of the content window to the (-left inset, -top inset)
52 Insets ins = dims.getInsets();
53 if (ins != null) {
54 rec.x = -ins.left;
55 rec.y = -ins.top;
56 } else {
57 rec.x = 0;
58 rec.y = 0;
59 }
60 final XContentWindow cw = new XContentWindow(parentFrame, rec);
61 cw.xSetVisible(true);
62 return cw;
63 }
64
65 private final XDecoratedPeer parentFrame;
66
67 // A list of expose events that come when the parentFrame is iconified
68 private final java.util.List<SavedExposeEvent> iconifiedExposeEvents =
69 new java.util.ArrayList<SavedExposeEvent>();
70
71 private XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
72 super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds);
73 this.parentFrame = parentFrame;
74 }
75
76 void preInit(XCreateWindowParams params) {
77 super.preInit(params);
78 params.putIfNull(BIT_GRAVITY, Integer.valueOf(XConstants.NorthWestGravity));
79 Long eventMask = (Long)params.get(EVENT_MASK);
80 if (eventMask != null) {
81 eventMask = eventMask & ~(XConstants.StructureNotifyMask);
82 params.put(EVENT_MASK, eventMask);
83 }
84 }
85
86 protected String getWMName() {
87 return "Content window";
88 }
89 protected boolean isEventDisabled(XEvent e) {
90 switch (e.get_type()) {
91 // Override parentFrame to receive MouseEnter/Exit
92 case XConstants.EnterNotify:
93 case XConstants.LeaveNotify:
94 return false;
95 // We handle ConfigureNotify specifically in XDecoratedPeer
96 case XConstants.ConfigureNotify:
97 return true;
98 // We don't want SHOWN/HIDDEN on content window since it will duplicate XDecoratedPeer
99 case XConstants.MapNotify:
100 case XConstants.UnmapNotify:
101 return true;
102 default:
103 return super.isEventDisabled(e) || parentFrame.isEventDisabled(e);
104 }
105 }
106
107 // Coordinates are that of the shell
108 void setContentBounds(WindowDimensions dims) {
109 XToolkit.awtLock();
110 try {
111 // Bounds of content window are of the same size as bounds of Java window and with
112 // location as -(insets)
113 Rectangle newBounds = dims.getBounds();
114 Insets in = dims.getInsets();
115 if (in != null) {
116 newBounds.setLocation(-in.left, -in.top);
117 }
118 if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
119 insLog.fine("Setting content bounds {0}, old bounds {1}",
120 newBounds, getBounds());
121 }
122 // Fix for 5023533:
123 // Change in the size of the content window means, well, change of the size
124 // Change in the location of the content window means change in insets
125 boolean needHandleResize = !(newBounds.equals(getBounds()));
126 reshape(newBounds);
127 if (needHandleResize) {
128 insLog.fine("Sending RESIZED");
129 handleResize(newBounds);
130 }
131 } finally {
132 XToolkit.awtUnlock();
133 }
134 validateSurface();
135 }
136
137 // NOTE: This method may be called by privileged threads.
138 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
139 public void handleResize(Rectangle bounds) {
140 AWTAccessor.getComponentAccessor().setSize((Component)target, bounds.width, bounds.height);
141 postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED));
142 }
143
144
145 public void handleExposeEvent(Component target, int x, int y, int w, int h) {
146 // TODO: ?
147 // get rid of 'istanceof' by subclassing:
148 // XContentWindow -> XFrameContentWindow
149
150 // Expose event(s) that result from deiconification
151 // come before a deicinofication notification.
152 // We reorder these events by saving all expose events
153 // that come when the frame is iconified. Then we
154 // actually handle saved expose events on deiconification.
155
156 if (parentFrame instanceof XFramePeer &&
157 (((XFramePeer)parentFrame).getState() & java.awt.Frame.ICONIFIED) != 0) {
158 // Save expose events if the frame is iconified
159 // in order to handle them on deiconification.
160 iconifiedExposeEvents.add(new SavedExposeEvent(target, x, y, w, h));
161 } else {
162 // Normal case: [it is not a frame or] the frame is not iconified.
163 super.handleExposeEvent(target, x, y, w, h);
164 }
165 }
166
167 void purgeIconifiedExposeEvents() {
168 for (SavedExposeEvent evt : iconifiedExposeEvents) {
169 super.handleExposeEvent(evt.target, evt.x, evt.y, evt.w, evt.h);
170 }
171 iconifiedExposeEvents.clear();
172 }
173
174 private static class SavedExposeEvent {
175 Component target;
176 int x, y, w, h;
177 SavedExposeEvent(Component target, int x, int y, int w, int h) {
178 this.target = target;
179 this.x = x;
180 this.y = y;
181 this.w = w;
182 this.h = h;
183 }
184 }
185
186 public String toString() {
187 return getClass().getName() + "[" + getBounds() + "]";
188 }
189 }
--- EOF ---