package sun.awt.windows;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.peer.*;
import java.beans.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.List;
import java.util.logging.*;
import sun.awt.*;
import sun.java2d.pipe.Region;
public class WWindowPeer extends WPanelPeer implements WindowPeer {
private static final Logger log = Logger.getLogger("sun.awt.windows.WWindowPeer");
private static final Logger screenLog = Logger.getLogger("sun.awt.windows.screen.WWindowPeer");
private WWindowPeer modalBlocker = null;
private boolean isOpaque;
private TranslucentWindowPainter painter;
private final static StringBuffer ACTIVE_WINDOWS_KEY =
new StringBuffer("active_windows_list");
private static PropertyChangeListener activeWindowListener =
new ActiveWindowListener();
private static Set<AppContext> trackedAppContexts = new HashSet<AppContext>();
private static native void initIDs();
static {
initIDs();
}
protected void disposeImpl() {
AppContext appContext = SunToolkit.targetToAppContext(target);
synchronized (appContext) {
List<WWindowPeer> l = (List<WWindowPeer>)appContext.get(ACTIVE_WINDOWS_KEY);
if (l != null) {
l.remove(this);
}
}
GraphicsConfiguration gc = getGraphicsConfiguration();
((Win32GraphicsDevice)gc.getDevice()).removeDisplayChangedListener(this);
synchronized (getStateLock()) {
TranslucentWindowPainter currentPainter = painter;
if (currentPainter != null) {
currentPainter.flush();
}
}
super.disposeImpl();
}
public void toFront() {
updateFocusableWindowState();
_toFront();
}
native void _toFront();
public native void toBack();
public native void setAlwaysOnTopNative(boolean value);
public void setAlwaysOnTop(boolean value) {
if ((value && ((Window)target).isVisible()) || !value) {
setAlwaysOnTopNative(value);
}
}
public void updateAlwaysOnTopState() {
setAlwaysOnTop(((Window)target).isAlwaysOnTop());
}
public void updateFocusableWindowState() {
setFocusableWindow(((Window)target).isFocusableWindow());
}
native void setFocusableWindow(boolean value);
public void setTitle(String title) {
if (title == null) {
title = new String("");
}
_setTitle(title);
}
native void _setTitle(String title);
public void setResizable(boolean resizable) {
_setResizable(resizable);
}
public native void _setResizable(boolean resizable);
WWindowPeer(Window target) {
super(target);
}
void initialize() {
super.initialize();
updateInsets(insets_);
Font f = ((Window)target).getFont();
if (f == null) {
f = defaultFont;
((Window)target).setFont(f);
setFont(f);
}
GraphicsConfiguration gc = getGraphicsConfiguration();
((Win32GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
AppContext appContext = AppContext.getAppContext();
synchronized (appContext) {
if (!trackedAppContexts.contains(appContext)) {
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
kfm.addPropertyChangeListener("activeWindow", activeWindowListener);
trackedAppContexts.add(appContext);
}
}
updateIconImages();
Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
if (shape != null) {
applyShape(Region.getInstance(shape, null));
}
float opacity = AWTAccessor.getWindowAccessor().getOpacity((Window)target);
if (opacity < 1.0f) {
setOpacity(opacity);
}
synchronized (getStateLock()) {
this.isOpaque = true;
Color bgColor = ((Window)target).getBackground();
setOpaque((bgColor == null) || (bgColor.getAlpha() == 255));
}
}
native void createAwtWindow(WComponentPeer parent);
void create(WComponentPeer parent) {
createAwtWindow(parent);
}
protected void realShow() {
super.show();
}
public void show() {
updateFocusableWindowState();
boolean alwaysOnTop = ((Window)target).isAlwaysOnTop();
updateGC();
resetTargetGC();
realShow();
updateMinimumSize();
if (((Window)target).isAlwaysOnTopSupported() && alwaysOnTop) {
setAlwaysOnTop(alwaysOnTop);
}
synchronized (getStateLock()) {
if (!isOpaque) {
updateWindow(true);
}
}
}
native void updateInsets(Insets i);
static native int getSysMinWidth();
static native int getSysMinHeight();
static native int getSysIconWidth();
static native int getSysIconHeight();
static native int getSysSmIconWidth();
static native int getSysSmIconHeight();
native void setIconImagesData(int[] iconRaster, int w, int h,
int[] smallIconRaster, int smw, int smh);
synchronized native void reshapeFrame(int x, int y, int width, int height);
public boolean requestWindowFocus() {
return false;
}
public boolean focusAllowedFor() {
Window target = (Window)this.target;
if (!target.isVisible() ||
!target.isEnabled() ||
!target.isFocusable())
{
return false;
}
if (isModalBlocked()) {
return false;
}
return true;
}
public void updateMinimumSize() {
Dimension minimumSize = null;
if (((Component)target).isMinimumSizeSet()) {
minimumSize = ((Component)target).getMinimumSize();
}
if (minimumSize != null) {
int msw = getSysMinWidth();
int msh = getSysMinHeight();
int w = (minimumSize.width >= msw) ? minimumSize.width : msw;
int h = (minimumSize.height >= msh) ? minimumSize.height : msh;
setMinSize(w, h);
} else {
setMinSize(0, 0);
}
}
public void updateIconImages() {
java.util.List<Image> imageList = ((Window)target).getIconImages();
if (imageList == null || imageList.size() == 0) {
setIconImagesData(null, 0, 0, null, 0, 0);
} else {
int w = getSysIconWidth();
int h = getSysIconHeight();
int smw = getSysSmIconWidth();
int smh = getSysSmIconHeight();
DataBufferInt iconData = SunToolkit.getScaledIconData(imageList,
w, h);
DataBufferInt iconSmData = SunToolkit.getScaledIconData(imageList,
smw, smh);
if (iconData != null && iconSmData != null) {
setIconImagesData(iconData.getData(), w, h,
iconSmData.getData(), smw, smh);
} else {
setIconImagesData(null, 0, 0, null, 0, 0);
}
}
}
native void setMinSize(int width, int height);
public boolean isModalBlocked() {
return modalBlocker != null;
}
public void setModalBlocked(Dialog dialog, boolean blocked) {
synchronized (((Component)getTarget()).getTreeLock())
{
WWindowPeer blockerPeer = (WWindowPeer)dialog.getPeer();
if (blocked)
{
modalBlocker = blockerPeer;
if (blockerPeer instanceof WFileDialogPeer) {
((WFileDialogPeer)blockerPeer).blockWindow(this);
} else if (blockerPeer instanceof WPrintDialogPeer) {
((WPrintDialogPeer)blockerPeer).blockWindow(this);
} else {
modalDisable(dialog, blockerPeer.getHWnd());
}
} else {
modalBlocker = null;
if (blockerPeer instanceof WFileDialogPeer) {
((WFileDialogPeer)blockerPeer).unblockWindow(this);
} else if (blockerPeer instanceof WPrintDialogPeer) {
((WPrintDialogPeer)blockerPeer).unblockWindow(this);
} else {
modalEnable(dialog);
}
}
}
}
native void modalDisable(Dialog blocker, long blockerHWnd);
native void modalEnable(Dialog blocker);
public static long[] getActiveWindowHandles() {
AppContext appContext = AppContext.getAppContext();
if (appContext == null) return null;
synchronized (appContext) {
List<WWindowPeer> l = (List<WWindowPeer>)appContext.get(ACTIVE_WINDOWS_KEY);
if (l == null) {
return null;
}
long[] result = new long[l.size()];
for (int j = 0; j < l.size(); j++) {
result[j] = l.get(j).getHWnd();
}
return result;
}
}
void draggedToNewScreen() {
SunToolkit.executeOnEventHandlerThread((Component)target,new Runnable()
{
public void run() {
displayChanged();
}
});
}
void clearLocalGC() {}
public void updateGC() {
int scrn = getScreenImOn();
if (screenLog.isLoggable(Level.FINER)) {
log.log(Level.FINER, "Screen number: " + scrn);
}
Win32GraphicsDevice oldDev = (Win32GraphicsDevice)winGraphicsConfig
.getDevice();
Win32GraphicsDevice newDev;
GraphicsDevice devs[] = GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getScreenDevices();
if (scrn >= devs.length) {
newDev = (Win32GraphicsDevice)GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice();
} else {
newDev = (Win32GraphicsDevice)devs[scrn];
}
winGraphicsConfig = (Win32GraphicsConfig)newDev
.getDefaultConfiguration();
if (screenLog.isLoggable(Level.FINE)) {
if (winGraphicsConfig == null) {
screenLog.log(Level.FINE, "Assertion (winGraphicsConfig != null) failed");
}
}
if (oldDev != newDev) {
oldDev.removeDisplayChangedListener(this);
newDev.addDisplayChangedListener(this);
}
}
public void displayChanged() {
updateGC();
super.displayChanged();
}
private native int getScreenImOn();
public void grab() {
nativeGrab();
}
public void ungrab() {
nativeUngrab();
}
private native void nativeGrab();
private native void nativeUngrab();
private final boolean hasWarningWindow() {
return ((Window)target).getWarningString() != null;
}
boolean isTargetUndecorated() {
return true;
}
private volatile int sysX = 0;
private volatile int sysY = 0;
private volatile int sysW = 0;
private volatile int sysH = 0;
Rectangle constrainBounds(int x, int y, int width, int height) {
GraphicsConfiguration gc = this.winGraphicsConfig;
if (!hasWarningWindow() || gc == null) {
return new Rectangle(x, y, width, height);
}
int newX = x;
int newY = y;
int newW = width;
int newH = height;
Rectangle sB = gc.getBounds();
Insets sIn = Toolkit.getDefaultToolkit().getScreenInsets(gc);
int screenW = sB.width - sIn.left - sIn.right;
int screenH = sB.height - sIn.top - sIn.bottom;
if (!AWTAccessor.getComponentAccessor().isVisible_NoClientCode(
(Component)target) || isTargetUndecorated())
{
int screenX = sB.x + sIn.left;
int screenY = sB.y + sIn.top;
if (newW > screenW) {
newW = screenW;
}
if (newH > screenH) {
newH = screenH;
}
if (newX < screenX) {
newX = screenX;
} else if (newX + newW > screenX + screenW) {
newX = screenX + screenW - newW;
}
if (newY < screenY) {
newY = screenY;
} else if (newY + newH > screenY + screenH) {
newY = screenY + screenH - newH;
}
} else {
int maxW = Math.max(screenW, sysW);
int maxH = Math.max(screenH, sysH);
if (newW > maxW) {
newW = maxW;
}
if (newH > maxH) {
newH = maxH;
}
}
return new Rectangle(newX, newY, newW, newH);
}
public native void repositionSecurityWarning();
@Override
public void setBounds(int x, int y, int width, int height, int op) {
Rectangle newBounds = constrainBounds(x, y, width, height);
sysX = newBounds.x;
sysY = newBounds.y;
sysW = newBounds.width;
sysH = newBounds.height;
super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
}
@Override
public void print(Graphics g) {
Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
if (shape != null) {
g.setClip(shape);
}
super.print(g);
}
private void replaceSurfaceDataRecursively(Component c) {
if (c instanceof Container) {
for (Component child : ((Container)c).getComponents()) {
replaceSurfaceDataRecursively(child);
}
}
ComponentPeer cp = c.getPeer();
if (cp instanceof WComponentPeer) {
((WComponentPeer)cp).replaceSurfaceDataLater();
}
}
@Override
public Graphics getGraphics() {
synchronized (getStateLock()) {
if (!isOpaque) {
return painter.getBackBuffer(false).getGraphics();
}
}
return super.getGraphics();
}
@Override
public void setBackground(Color c) {
super.setBackground(c);
synchronized (getStateLock()) {
if (!isOpaque && ((Window)target).isVisible()) {
updateWindow(true);
}
}
}
private native void setOpacity(int iOpacity);
public void setOpacity(float opacity) {
if (!((SunToolkit)((Window)target).getToolkit()).
isWindowOpacitySupported())
{
return;
}
replaceSurfaceDataRecursively((Component)getTarget());
final int maxOpacity = 0xff;
int iOpacity = (int)(opacity * maxOpacity);
if (iOpacity < 0) {
iOpacity = 0;
}
if (iOpacity > maxOpacity) {
iOpacity = maxOpacity;
}
setOpacity(iOpacity);
synchronized (getStateLock()) {
if (!isOpaque && ((Window)target).isVisible()) {
updateWindow(true);
}
}
}
private native void setOpaqueImpl(boolean isOpaque);
public void setOpaque(boolean isOpaque) {
synchronized (getStateLock()) {
if (this.isOpaque == isOpaque) {
return;
}
}
Window target = (Window)getTarget();
SunToolkit sunToolkit = (SunToolkit)target.getToolkit();
if (!sunToolkit.isWindowTranslucencySupported() ||
!sunToolkit.isTranslucencyCapable(target.getGraphicsConfiguration()))
{
return;
}
boolean isVistaOS = Win32GraphicsEnvironment.isVistaOS();
if (!isVistaOS) {
replaceSurfaceDataRecursively(target);
}
synchronized (getStateLock()) {
this.isOpaque = isOpaque;
setOpaqueImpl(isOpaque);
if (isOpaque) {
TranslucentWindowPainter currentPainter = painter;
if (currentPainter != null) {
currentPainter.flush();
painter = null;
}
} else {
painter = TranslucentWindowPainter.createInstance(this);
}
}
if (isVistaOS) {
Shape shape = AWTAccessor.getWindowAccessor().getShape(target);
if (shape != null) {
AWTAccessor.getWindowAccessor().setShape(target, shape);
}
}
if (((Window)target).isVisible()) {
updateWindow(true);
}
}
public native void updateWindowImpl(int[] data, int width, int height);
public void updateWindow() {
updateWindow(false);
}
private void updateWindow(boolean repaint) {
Window w = (Window)target;
synchronized (getStateLock()) {
if (isOpaque || !w.isVisible() ||
(w.getWidth() <= 0) || (w.getHeight() <= 0))
{
return;
}
TranslucentWindowPainter currentPainter = painter;
if (currentPainter != null) {
currentPainter.updateWindow(repaint);
} else if (log.isLoggable(Level.FINER)) {
log.log(Level.FINER,
"Translucent window painter is null in updateWindow");
}
}
}
private static class ActiveWindowListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
Window w = (Window)e.getNewValue();
if (w == null) {
return;
}
AppContext appContext = SunToolkit.targetToAppContext(w);
synchronized (appContext) {
List<WWindowPeer> l = (List<WWindowPeer>)appContext.get(ACTIVE_WINDOWS_KEY);
if (l == null) {
l = new LinkedList<WWindowPeer>();
appContext.put(ACTIVE_WINDOWS_KEY, l);
}
WWindowPeer wp = (WWindowPeer)w.getPeer();
l.remove(wp);
l.add(wp);
}
}
}
}