提交 5c6bc751 编写于 作者: A art

6633275: Need to support shaped/translucent windows

Summary: forward-port from 6u14, no public API is introduced
Reviewed-by: anthony, dcherepanov
上级 272e7290
# #
# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. # Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -104,7 +104,8 @@ FILES_c = \ ...@@ -104,7 +104,8 @@ FILES_c = \
OGLVertexCache.c \ OGLVertexCache.c \
WGLGraphicsConfig.c \ WGLGraphicsConfig.c \
WGLSurfaceData.c \ WGLSurfaceData.c \
AccelGlyphCache.c AccelGlyphCache.c \
rect.c
FILES_cpp = \ FILES_cpp = \
CmdIDList.cpp \ CmdIDList.cpp \
......
# #
# Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. # Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -219,6 +219,7 @@ vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/image/cvutils ...@@ -219,6 +219,7 @@ vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/image/cvutils
vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/shell vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/shell
vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/medialib vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/medialib
vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/debug vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/debug
vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/utility
vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/../java2d vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/../java2d
vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/../java2d/loops vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/../java2d/loops
vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/../java2d/pipe vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/../java2d/pipe
......
此差异已折叠。
...@@ -291,6 +291,7 @@ SUNWprivate_1.1 { ...@@ -291,6 +291,7 @@ SUNWprivate_1.1 {
Java_sun_awt_X11GraphicsConfig_createBackBuffer; Java_sun_awt_X11GraphicsConfig_createBackBuffer;
Java_sun_awt_X11GraphicsConfig_destroyBackBuffer; Java_sun_awt_X11GraphicsConfig_destroyBackBuffer;
Java_sun_awt_X11GraphicsConfig_swapBuffers; Java_sun_awt_X11GraphicsConfig_swapBuffers;
Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable;
Java_sun_awt_X11GraphicsDevice_isDBESupported; Java_sun_awt_X11GraphicsDevice_isDBESupported;
Java_sun_awt_X11GraphicsDevice_getDisplay; Java_sun_awt_X11GraphicsDevice_getDisplay;
Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals; Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals;
......
...@@ -407,6 +407,7 @@ SUNWprivate_1.1 { ...@@ -407,6 +407,7 @@ SUNWprivate_1.1 {
Java_sun_awt_X11GraphicsConfig_getNumColors; Java_sun_awt_X11GraphicsConfig_getNumColors;
Java_sun_awt_X11GraphicsConfig_getXResolution; Java_sun_awt_X11GraphicsConfig_getXResolution;
Java_sun_awt_X11GraphicsConfig_getYResolution; Java_sun_awt_X11GraphicsConfig_getYResolution;
Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable;
Java_sun_awt_X11GraphicsDevice_isDBESupported; Java_sun_awt_X11GraphicsDevice_isDBESupported;
Java_sun_awt_X11GraphicsDevice_getDisplay; Java_sun_awt_X11GraphicsDevice_getDisplay;
Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals; Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals;
......
...@@ -217,6 +217,7 @@ SUNWprivate_1.1 { ...@@ -217,6 +217,7 @@ SUNWprivate_1.1 {
Java_sun_awt_X11GraphicsConfig_createBackBuffer; Java_sun_awt_X11GraphicsConfig_createBackBuffer;
Java_sun_awt_X11GraphicsConfig_destroyBackBuffer; Java_sun_awt_X11GraphicsConfig_destroyBackBuffer;
Java_sun_awt_X11GraphicsConfig_swapBuffers; Java_sun_awt_X11GraphicsConfig_swapBuffers;
Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable;
Java_java_awt_Insets_initIDs; Java_java_awt_Insets_initIDs;
Java_java_awt_KeyboardFocusManager_initIDs; Java_java_awt_KeyboardFocusManager_initIDs;
Java_java_awt_Font_initIDs; Java_java_awt_Font_initIDs;
......
/* /*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,17 +26,37 @@ ...@@ -26,17 +26,37 @@
package com.sun.awt; package com.sun.awt;
import java.awt.*; import java.awt.*;
import sun.awt.AWTAccessor;
import sun.awt.AWTAccessor;
import sun.awt.SunToolkit;
/** /**
* A collection of utility methods for AWT. * A collection of utility methods for AWT.
* *
* The functionality provided by the static methods of the class includes: * The functionality provided by the static methods of the class includes:
* <ul> * <ul>
* <li>Setting shapes on top-level windows
* <li>Setting a constant alpha value for each pixel of a top-level window
* <li>Making a window non-opaque, after that it paints only explicitly
* painted pixels on the screen, with arbitrary alpha values for every pixel.
* <li>Setting a 'mixing-cutout' shape for a component. * <li>Setting a 'mixing-cutout' shape for a component.
* </ul> * </ul>
* <p> * <p>
* A "top-level window" is an instance of the {@code Window} class (or its
* descendant, such as {@code JFrame}).
* <p>
* Some of the mentioned features may not be supported by the native platform.
* To determine whether a particular feature is supported, the user must use
* the {@code isTranslucencySupported()} method of the class passing a desired
* translucency kind (a member of the {@code Translucency} enum) as an
* argument.
* <p>
* The per-pixel alpha feature also requires the user to create her/his
* windows using a translucency-capable graphics configuration.
* The {@code isTranslucencyCapable()} method must
* be used to verify whether any given GraphicsConfiguration supports
* the trasnlcency effects.
* <p>
* <b>WARNING</b>: This class is an implementation detail and only meant * <b>WARNING</b>: This class is an implementation detail and only meant
* for limited use outside of the core platform. This API may change * for limited use outside of the core platform. This API may change
* drastically between update release, and it may even be * drastically between update release, and it may even be
...@@ -50,6 +70,344 @@ public final class AWTUtilities { ...@@ -50,6 +70,344 @@ public final class AWTUtilities {
private AWTUtilities() { private AWTUtilities() {
} }
/** Kinds of translucency supported by the underlying system.
* @see #isTranslucencySupported
*/
public static enum Translucency {
/**
* Represents support in the underlying system for windows each pixel
* of which is guaranteed to be either completely opaque, with
* an alpha value of 1.0, or completely transparent, with an alpha
* value of 0.0.
*/
PERPIXEL_TRANSPARENT,
/**
* Represents support in the underlying system for windows all of
* the pixels of which have the same alpha value between or including
* 0.0 and 1.0.
*/
TRANSLUCENT,
/**
* Represents support in the underlying system for windows that
* contain or might contain pixels with arbitrary alpha values
* between and including 0.0 and 1.0.
*/
PERPIXEL_TRANSLUCENT;
}
/**
* Returns whether the given level of translucency is supported by
* the underlying system.
*
* Note that this method may sometimes return the value
* indicating that the particular level is supported, but
* the native windowing system may still not support the
* given level of translucency (due to the bugs in
* the windowing system).
*
* @param translucencyKind a kind of translucency support
* (either PERPIXEL_TRANSPARENT,
* TRANSLUCENT, or PERPIXEL_TRANSLUCENT)
* @return whether the given translucency kind is supported
*/
public static boolean isTranslucencySupported(Translucency translucencyKind) {
switch (translucencyKind) {
case PERPIXEL_TRANSPARENT:
return isWindowShapingSupported();
case TRANSLUCENT:
return isWindowOpacitySupported();
case PERPIXEL_TRANSLUCENT:
return isWindowTranslucencySupported();
}
return false;
}
/**
* Returns whether the windowing system supports changing the opacity
* value of top-level windows.
* Note that this method may sometimes return true, but the native
* windowing system may still not support the concept of
* translucency (due to the bugs in the windowing system).
*/
private static boolean isWindowOpacitySupported() {
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isWindowOpacitySupported();
}
/**
* Set the opacity of the window. The opacity is at the range [0..1].
* Note that setting the opacity level of 0 may or may not disable
* the mouse event handling on this window. This is
* a platform-dependent behavior.
*
* In order for this method to enable the translucency effect,
* the isTranslucencySupported() method should indicate that the
* TRANSLUCENT level of translucency is supported.
*
* <p>Also note that the window must not be in the full-screen mode
* when setting the opacity value &lt; 1.0f. Otherwise
* the IllegalArgumentException is thrown.
*
* @param window the window to set the opacity level to
* @param opacity the opacity level to set to the window
* @throws NullPointerException if the window argument is null
* @throws IllegalArgumentException if the opacity is out of
* the range [0..1]
* @throws IllegalArgumentException if the window is in full screen mode,
* and the opacity is less than 1.0f
* @throws UnsupportedOperationException if the TRANSLUCENT translucency
* kind is not supported
*/
public static void setWindowOpacity(Window window, float opacity) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
AWTAccessor.getWindowAccessor().setOpacity(window, opacity);
}
/**
* Get the opacity of the window. If the opacity has not
* yet being set, this method returns 1.0.
*
* @param window the window to get the opacity level from
* @throws NullPointerException if the window argument is null
*/
public static float getWindowOpacity(Window window) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
return AWTAccessor.getWindowAccessor().getOpacity(window);
}
/**
* Returns whether the windowing system supports changing the shape
* of top-level windows.
* Note that this method may sometimes return true, but the native
* windowing system may still not support the concept of
* shaping (due to the bugs in the windowing system).
*/
public static boolean isWindowShapingSupported() {
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isWindowShapingSupported();
}
/**
* Returns an object that implements the Shape interface and represents
* the shape previously set with the call to the setWindowShape() method.
* If no shape has been set yet, or the shape has been reset to null,
* this method returns null.
*
* @param window the window to get the shape from
* @return the current shape of the window
* @throws NullPointerException if the window argument is null
*/
public static Shape getWindowShape(Window window) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
return AWTAccessor.getWindowAccessor().getShape(window);
}
/**
* Sets a shape for the given window.
* If the shape argument is null, this methods restores
* the default shape making the window rectangular.
* <p>Note that in order to set a shape, the window must be undecorated.
* If the window is decorated, this method ignores the {@code shape}
* argument and resets the shape to null.
* <p>Also note that the window must not be in the full-screen mode
* when setting a non-null shape. Otherwise the IllegalArgumentException
* is thrown.
* <p>Depending on the platform, the method may return without
* effecting the shape of the window if the window has a non-null warning
* string ({@link Window#getWarningString()}). In this case the passed
* shape object is ignored.
*
* @param window the window to set the shape to
* @param shape the shape to set to the window
* @throws NullPointerException if the window argument is null
* @throws IllegalArgumentException if the window is in full screen mode,
* and the shape is not null
* @throws UnsupportedOperationException if the PERPIXEL_TRANSPARENT
* translucency kind is not supported
*/
public static void setWindowShape(Window window, Shape shape) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
AWTAccessor.getWindowAccessor().setShape(window, shape);
}
private static boolean isWindowTranslucencySupported() {
/*
* Per-pixel alpha is supported if all the conditions are TRUE:
* 1. The toolkit is a sort of SunToolkit
* 2. The toolkit supports translucency in general
* (isWindowTranslucencySupported())
* 3. There's at least one translucency-capable
* GraphicsConfiguration
*/
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
if (!((SunToolkit)curToolkit).isWindowTranslucencySupported()) {
return false;
}
GraphicsEnvironment env =
GraphicsEnvironment.getLocalGraphicsEnvironment();
// If the default GC supports translucency return true.
// It is important to optimize the verification this way,
// see CR 6661196 for more details.
if (isTranslucencyCapable(env.getDefaultScreenDevice()
.getDefaultConfiguration()))
{
return true;
}
// ... otherwise iterate through all the GCs.
GraphicsDevice[] devices = env.getScreenDevices();
for (int i = 0; i < devices.length; i++) {
GraphicsConfiguration[] configs = devices[i].getConfigurations();
for (int j = 0; j < configs.length; j++) {
if (isTranslucencyCapable(configs[j])) {
return true;
}
}
}
return false;
}
/**
* Enables the per-pixel alpha support for the given window.
* Once the window becomes non-opaque (the isOpaque is set to false),
* the drawing sub-system is starting to respect the alpha value of each
* separate pixel. If a pixel gets painted with alpha color component
* equal to zero, it becomes visually transparent, if the alpha of the
* pixel is equal to 255, the pixel is fully opaque. Interim values
* of the alpha color component make the pixel semi-transparent (i.e.
* translucent).
* <p>Note that in order for the window to support the per-pixel alpha
* mode, the window must be created using the GraphicsConfiguration
* for which the {@link #isTranslucencyCapable}
* method returns true.
* <p>Also note that some native systems enable the per-pixel translucency
* mode for any window created using the translucency-compatible
* graphics configuration. However, it is highly recommended to always
* invoke the setWindowOpaque() method for these windows, at least for
* the sake of cross-platform compatibility reasons.
* <p>Also note that the window must not be in the full-screen mode
* when making it non-opaque. Otherwise the IllegalArgumentException
* is thrown.
* <p>If the window is a {@code Frame} or a {@code Dialog}, the window must
* be undecorated prior to enabling the per-pixel translucency effect (see
* {@link Frame#setUndecorated()} and/or {@link Dialog#setUndecorated()}).
* If the window becomes decorated through a subsequent call to the
* corresponding {@code setUndecorated()} method, the per-pixel
* translucency effect will be disabled and the opaque property reset to
* {@code true}.
* <p>Depending on the platform, the method may return without
* effecting the opaque property of the window if the window has a non-null
* warning string ({@link Window#getWarningString()}). In this case
* the passed 'isOpaque' value is ignored.
*
* @param window the window to set the shape to
* @param isOpaque whether the window must be opaque (true),
* or translucent (false)
* @throws NullPointerException if the window argument is null
* @throws IllegalArgumentException if the window uses
* a GraphicsConfiguration for which the
* {@code isTranslucencyCapable()}
* method returns false
* @throws IllegalArgumentException if the window is in full screen mode,
* and the isOpaque is false
* @throws IllegalArgumentException if the window is decorated and the
* isOpaque argument is {@code false}.
* @throws UnsupportedOperationException if the PERPIXEL_TRANSLUCENT
* translucency kind is not supported
*/
public static void setWindowOpaque(Window window, boolean isOpaque) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
if (!isOpaque && !isTranslucencySupported(Translucency.PERPIXEL_TRANSLUCENT)) {
throw new UnsupportedOperationException(
"The PERPIXEL_TRANSLUCENT translucency kind is not supported");
}
AWTAccessor.getWindowAccessor().setOpaque(window, isOpaque);
}
/**
* Returns whether the window is opaque or translucent.
*
* @param window the window to set the shape to
* @return whether the window is currently opaque (true)
* or translucent (false)
* @throws NullPointerException if the window argument is null
*/
public static boolean isWindowOpaque(Window window) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
return AWTAccessor.getWindowAccessor().isOpaque(window);
}
/**
* Verifies whether a given GraphicsConfiguration supports
* the PERPIXEL_TRANSLUCENT kind of translucency.
* All windows that are intended to be used with the {@link #setWindowOpaque}
* method must be created using a GraphicsConfiguration for which this method
* returns true.
* <p>Note that some native systems enable the per-pixel translucency
* mode for any window created using a translucency-capable
* graphics configuration. However, it is highly recommended to always
* invoke the setWindowOpaque() method for these windows, at least
* for the sake of cross-platform compatibility reasons.
*
* @param gc GraphicsConfiguration
* @throws NullPointerException if the gc argument is null
* @return whether the given GraphicsConfiguration supports
* the translucency effects.
*/
public static boolean isTranslucencyCapable(GraphicsConfiguration gc) {
if (gc == null) {
throw new NullPointerException("The gc argument should not be null");
}
/*
return gc.isTranslucencyCapable();
*/
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isTranslucencyCapable(gc);
}
/** /**
* Sets a 'mixing-cutout' shape for the given component. * Sets a 'mixing-cutout' shape for the given component.
* *
......
/* /*
* Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -799,8 +799,24 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -799,8 +799,24 @@ public abstract class Component implements ImageObserver, MenuContainer,
} }
} }
// Whether this Component has had the background erase flag
// specified via SunToolkit.disableBackgroundErase(). This is
// needed in order to make this function work on X11 platforms,
// where currently there is no chance to interpose on the creation
// of the peer and therefore the call to XSetBackground.
transient boolean backgroundEraseDisabled;
static { static {
AWTAccessor.setComponentAccessor(new AWTAccessor.ComponentAccessor() { AWTAccessor.setComponentAccessor(new AWTAccessor.ComponentAccessor() {
public void setBackgroundEraseDisabled(Component comp, boolean disabled) {
comp.backgroundEraseDisabled = disabled;
}
public boolean getBackgroundEraseDisabled(Component comp) {
return comp.backgroundEraseDisabled;
}
public Rectangle getBounds(Component comp) {
return new Rectangle(comp.x, comp.y, comp.width, comp.height);
}
public void setMixingCutoutShape(Component comp, Shape shape) { public void setMixingCutoutShape(Component comp, Shape shape) {
Region region = shape == null ? null : Region region = shape == null ? null :
Region.getInstance(shape, null); Region.getInstance(shape, null);
...@@ -7456,7 +7472,7 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -7456,7 +7472,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
// sometimes most recent focus owner may be null, but focus owner is not // sometimes most recent focus owner may be null, but focus owner is not
// e.g. we reset most recent focus owner if user removes focus owner // e.g. we reset most recent focus owner if user removes focus owner
focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (focusOwner != null && getContainingWindow(focusOwner) != window) { if (focusOwner != null && focusOwner.getContainingWindow() != window) {
focusOwner = null; focusOwner = null;
} }
} }
...@@ -8689,30 +8705,8 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -8689,30 +8705,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
* null, if component is not a part of window hierarchy * null, if component is not a part of window hierarchy
*/ */
Window getContainingWindow() { Window getContainingWindow() {
return getContainingWindow(this); return SunToolkit.getContainingWindow(this);
} }
/**
* Returns the <code>Window</code> ancestor of the component <code>comp</code>.
* @return Window ancestor of the component or component by itself if it is Window;
* null, if component is not a part of window hierarchy
*/
static Window getContainingWindow(Component comp) {
while (comp != null && !(comp instanceof Window)) {
comp = comp.getParent();
}
return (Window)comp;
}
/** /**
* Initialize JNI field and method IDs * Initialize JNI field and method IDs
...@@ -9827,4 +9821,29 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -9827,4 +9821,29 @@ public abstract class Component implements ImageObserver, MenuContainer,
} }
// ****************** END OF MIXING CODE ******************************** // ****************** END OF MIXING CODE ********************************
private static boolean doesClassImplement(Class cls, String interfaceName) {
if (cls == null) return false;
for (Class c : cls.getInterfaces()) {
if (c.getName().equals(interfaceName)) {
return true;
}
}
return doesClassImplement(cls.getSuperclass(), interfaceName);
}
/**
* Checks that the given object implements the given interface.
* @param obj Object to be checked
* @param interfaceName The name of the interface. Must be fully-qualified interface name.
* @return true, if this object implements the given interface,
* false, otherwise, or if obj or interfaceName is null
*/
static boolean doesImplement(Object obj, String interfaceName) {
if (obj == null) return false;
if (interfaceName == null) return false;
return doesClassImplement(obj.getClass(), interfaceName);
}
} }
/* /*
* Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -167,6 +167,9 @@ public class Container extends Component { ...@@ -167,6 +167,9 @@ public class Container extends Component {
transient int listeningBoundsChildren; transient int listeningBoundsChildren;
transient int descendantsCount; transient int descendantsCount;
/* Non-opaque window support -- see Window.setLayersOpaque */
transient Color preserveBackgroundColor = null;
/** /**
* JDK 1.1 serialVersionUID * JDK 1.1 serialVersionUID
*/ */
......
...@@ -479,7 +479,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { ...@@ -479,7 +479,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
// that a Component outside of the focused Window receives a // that a Component outside of the focused Window receives a
// FOCUS_GAINED event. We synthesize a WINDOW_GAINED_FOCUS // FOCUS_GAINED event. We synthesize a WINDOW_GAINED_FOCUS
// event in that case. // event in that case.
final Window newFocusedWindow = Component.getContainingWindow(newFocusOwner); final Window newFocusedWindow = SunToolkit.getContainingWindow(newFocusOwner);
final Window currentFocusedWindow = getGlobalFocusedWindow(); final Window currentFocusedWindow = getGlobalFocusedWindow();
if (newFocusedWindow != null && if (newFocusedWindow != null &&
newFocusedWindow != currentFocusedWindow) newFocusedWindow != currentFocusedWindow)
......
/* /*
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -434,4 +434,20 @@ public abstract class GraphicsConfiguration { ...@@ -434,4 +434,20 @@ public abstract class GraphicsConfiguration {
} }
return defaultImageCaps; return defaultImageCaps;
} }
/**
* Returns whether this GraphicsConfiguration supports
* the {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
* PERPIXEL_TRANSLUCENT} kind of translucency.
*
* @param gc GraphicsConfiguration
* @throws NullPointerException if the gc argument is null
* @return whether the given GraphicsConfiguration supports
* the translucency effects.
* @see Window#setBackground(Color)
*/
/*public */boolean isTranslucencyCapable() {
// Overridden in subclasses
return false;
} }
}
/* /*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,7 +27,10 @@ ...@@ -27,7 +27,10 @@
package java.awt; package java.awt;
import java.awt.image.ColorModel; import java.awt.image.ColorModel;
import sun.awt.AWTAccessor;
import sun.awt.AppContext; import sun.awt.AppContext;
import sun.awt.SunToolkit;
/** /**
* The <code>GraphicsDevice</code> class describes the graphics devices * The <code>GraphicsDevice</code> class describes the graphics devices
...@@ -109,6 +112,31 @@ public abstract class GraphicsDevice { ...@@ -109,6 +112,31 @@ public abstract class GraphicsDevice {
*/ */
public final static int TYPE_IMAGE_BUFFER = 2; public final static int TYPE_IMAGE_BUFFER = 2;
/** Kinds of translucency supported by the underlying system.
* @see #isTranslucencySupported
*/
/*public */static enum WindowTranslucency {
/**
* Represents support in the underlying system for windows each pixel
* of which is guaranteed to be either completely opaque, with
* an alpha value of 1.0, or completely transparent, with an alpha
* value of 0.0.
*/
PERPIXEL_TRANSPARENT,
/**
* Represents support in the underlying system for windows all of
* the pixels of which have the same alpha value between or including
* 0.0 and 1.0.
*/
TRANSLUCENT,
/**
* Represents support in the underlying system for windows that
* contain or might contain pixels with arbitrary alpha values
* between and including 0.0 and 1.0.
*/
PERPIXEL_TRANSLUCENT;
}
/** /**
* Returns the type of this <code>GraphicsDevice</code>. * Returns the type of this <code>GraphicsDevice</code>.
* @return the type of this <code>GraphicsDevice</code>, which can * @return the type of this <code>GraphicsDevice</code>, which can
...@@ -235,6 +263,21 @@ public abstract class GraphicsDevice { ...@@ -235,6 +263,21 @@ public abstract class GraphicsDevice {
* @since 1.4 * @since 1.4
*/ */
public void setFullScreenWindow(Window w) { public void setFullScreenWindow(Window w) {
if (w != null) {
//XXX: The actions should be documented in some non-update release.
/*
if (w.getShape() != null) {
w.setShape(w, null);
}
if (!w.isOpaque()) {
w.setOpaque(false);
}
if (w.getOpacity() < 1.0f) {
w.setOpacity(1.0f);
}
*/
}
if (fullScreenWindow != null && windowedModeBounds != null) { if (fullScreenWindow != null && windowedModeBounds != null) {
// if the window went into fs mode before it was realized it may // if the window went into fs mode before it was realized it may
// have (0,0) dimensions // have (0,0) dimensions
...@@ -424,4 +467,94 @@ public abstract class GraphicsDevice { ...@@ -424,4 +467,94 @@ public abstract class GraphicsDevice {
public int getAvailableAcceleratedMemory() { public int getAvailableAcceleratedMemory() {
return -1; return -1;
} }
/**
* Returns whether the given level of translucency is supported
* this graphics device.
*
* @param translucencyKind a kind of translucency support
* @return whether the given translucency kind is supported
*/
/*public */boolean isWindowTranslucencySupported(WindowTranslucency translucencyKind) {
switch (translucencyKind) {
case PERPIXEL_TRANSPARENT:
return isWindowShapingSupported();
case TRANSLUCENT:
return isWindowOpacitySupported();
case PERPIXEL_TRANSLUCENT:
return isWindowPerpixelTranslucencySupported();
}
return false;
}
/**
* Returns whether the windowing system supports changing the shape
* of top-level windows.
* Note that this method may sometimes return true, but the native
* windowing system may still not support the concept of
* shaping (due to the bugs in the windowing system).
*/
static boolean isWindowShapingSupported() {
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isWindowShapingSupported();
}
/**
* Returns whether the windowing system supports changing the opacity
* value of top-level windows.
* Note that this method may sometimes return true, but the native
* windowing system may still not support the concept of
* translucency (due to the bugs in the windowing system).
*/
static boolean isWindowOpacitySupported() {
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isWindowOpacitySupported();
}
boolean isWindowPerpixelTranslucencySupported() {
/*
* Per-pixel alpha is supported if all the conditions are TRUE:
* 1. The toolkit is a sort of SunToolkit
* 2. The toolkit supports translucency in general
* (isWindowTranslucencySupported())
* 3. There's at least one translucency-capable
* GraphicsConfiguration
*/
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
if (!((SunToolkit)curToolkit).isWindowTranslucencySupported()) {
return false;
}
// TODO: cache translucency capable GC
return getTranslucencyCapableGC() != null;
}
GraphicsConfiguration getTranslucencyCapableGC() {
// If the default GC supports translucency return true.
// It is important to optimize the verification this way,
// see CR 6661196 for more details.
GraphicsConfiguration defaultGC = getDefaultConfiguration();
if (defaultGC.isTranslucencyCapable()) {
return defaultGC;
}
// ... otherwise iterate through all the GCs.
GraphicsConfiguration[] configs = getConfigurations();
for (int j = 0; j < configs.length; j++) {
if (configs[j].isTranslucencyCapable()) {
return configs[j];
}
}
return null;
}
} }
...@@ -2208,7 +2208,7 @@ public abstract class KeyboardFocusManager ...@@ -2208,7 +2208,7 @@ public abstract class KeyboardFocusManager
boolean temporary, boolean focusedWindowChangeAllowed, boolean temporary, boolean focusedWindowChangeAllowed,
long time) long time)
{ {
Window parentWindow = Component.getContainingWindow(heavyweight); Window parentWindow = SunToolkit.getContainingWindow(heavyweight);
if (parentWindow == null || !parentWindow.syncLWRequests) { if (parentWindow == null || !parentWindow.syncLWRequests) {
return false; return false;
} }
...@@ -2542,7 +2542,7 @@ public abstract class KeyboardFocusManager ...@@ -2542,7 +2542,7 @@ public abstract class KeyboardFocusManager
(HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER); (HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER);
Component activeWindow = ((hwFocusRequest != null) Component activeWindow = ((hwFocusRequest != null)
? Component.getContainingWindow(hwFocusRequest.heavyweight) ? SunToolkit.getContainingWindow(hwFocusRequest.heavyweight)
: nativeFocusedWindow); : nativeFocusedWindow);
while (activeWindow != null && while (activeWindow != null &&
!((activeWindow instanceof Frame) || !((activeWindow instanceof Frame) ||
...@@ -3013,8 +3013,8 @@ public abstract class KeyboardFocusManager ...@@ -3013,8 +3013,8 @@ public abstract class KeyboardFocusManager
} }
private static boolean focusedWindowChanged(Component to, Component from) { private static boolean focusedWindowChanged(Component to, Component from) {
Window wto = Component.getContainingWindow(to); Window wto = SunToolkit.getContainingWindow(to);
Window wfrom = Component.getContainingWindow(from); Window wfrom = SunToolkit.getContainingWindow(from);
if (wto == null && wfrom == null) { if (wto == null && wfrom == null) {
return true; return true;
} }
...@@ -3028,8 +3028,8 @@ public abstract class KeyboardFocusManager ...@@ -3028,8 +3028,8 @@ public abstract class KeyboardFocusManager
} }
private static boolean isTemporary(Component to, Component from) { private static boolean isTemporary(Component to, Component from) {
Window wto = Component.getContainingWindow(to); Window wto = SunToolkit.getContainingWindow(to);
Window wfrom = Component.getContainingWindow(from); Window wfrom = SunToolkit.getContainingWindow(from);
if (wto == null && wfrom == null) { if (wto == null && wfrom == null) {
return false; return false;
} }
......
/* /*
* Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,7 @@ package java.awt; ...@@ -27,6 +27,7 @@ package java.awt;
import java.awt.event.*; import java.awt.event.*;
import java.awt.im.InputContext; import java.awt.im.InputContext;
import java.awt.image.BufferStrategy; import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.peer.ComponentPeer; import java.awt.peer.ComponentPeer;
import java.awt.peer.WindowPeer; import java.awt.peer.WindowPeer;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
...@@ -49,6 +50,7 @@ import java.util.logging.Level; ...@@ -49,6 +50,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import javax.accessibility.*; import javax.accessibility.*;
import sun.awt.AWTAccessor;
import sun.awt.AppContext; import sun.awt.AppContext;
import sun.awt.CausedFocusEvent; import sun.awt.CausedFocusEvent;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
...@@ -291,6 +293,25 @@ public class Window extends Container implements Accessible { ...@@ -291,6 +293,25 @@ public class Window extends Container implements Accessible {
*/ */
transient boolean isInShow = false; transient boolean isInShow = false;
/*
* Opacity level of the window
*
* @see #setOpacity(float)
* @see #getOpacity()
* @since 1.7
*/
private float opacity = 1.0f;
/*
* The shape assigned to this window. This field is set to null if
* no shape is set (rectangular window).
*
* @see #getShape()
* @see #setShape(Shape)
* @since 1.7
*/
private Shape shape = null;
private static final String base = "win"; private static final String base = "win";
private static int nameCounter = 0; private static int nameCounter = 0;
...@@ -666,9 +687,9 @@ public class Window extends Container implements Accessible { ...@@ -666,9 +687,9 @@ public class Window extends Container implements Accessible {
} }
if (peer == null) { if (peer == null) {
peer = getToolkit().createWindow(this); peer = getToolkit().createWindow(this);
} synchronized (allWindows) {
synchronized (allWindows) { allWindows.add(this);
allWindows.add(this); }
} }
super.addNotify(); super.addNotify();
} }
...@@ -2849,6 +2870,8 @@ public class Window extends Container implements Accessible { ...@@ -2849,6 +2870,8 @@ public class Window extends Container implements Accessible {
if(aot) { if(aot) {
setAlwaysOnTop(aot); // since 1.5; subject to permission check setAlwaysOnTop(aot); // since 1.5; subject to permission check
} }
shape = (Shape)f.get("shape", null);
opacity = (Float)f.get("opacity", 1.0f);
deserializeResources(s); deserializeResources(s);
} }
...@@ -3016,7 +3039,7 @@ public class Window extends Container implements Accessible { ...@@ -3016,7 +3039,7 @@ public class Window extends Container implements Accessible {
Dimension windowSize = getSize(); Dimension windowSize = getSize();
// search a top-level of c // search a top-level of c
Window componentWindow = Component.getContainingWindow(c); Window componentWindow = SunToolkit.getContainingWindow(c);
if ((c == null) || (componentWindow == null)) { if ((c == null) || (componentWindow == null)) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gc = ge.getDefaultScreenDevice().getDefaultConfiguration(); gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
...@@ -3304,6 +3327,225 @@ public class Window extends Container implements Accessible { ...@@ -3304,6 +3327,225 @@ public class Window extends Container implements Accessible {
} }
// ******************** SHAPES & TRANSPARENCY CODE ********************
/**
* JavaDoc
*/
/*public */float getOpacity() {
synchronized (getTreeLock()) {
return opacity;
}
}
/**
* JavaDoc
*/
/*public */void setOpacity(float opacity) {
synchronized (getTreeLock()) {
if (opacity < 0.0f || opacity > 1.0f) {
throw new IllegalArgumentException(
"The value of opacity should be in the range [0.0f .. 1.0f].");
}
GraphicsConfiguration gc = getGraphicsConfiguration();
GraphicsDevice gd = gc.getDevice();
if (!gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT)) {
throw new UnsupportedOperationException(
"TRANSLUCENT translucency is not supported.");
}
if ((gc.getDevice().getFullScreenWindow() == this) && (opacity < 1.0f)) {
throw new IllegalArgumentException(
"Setting opacity for full-screen window is not supported.");
}
this.opacity = opacity;
WindowPeer peer = (WindowPeer)getPeer();
if (peer != null) {
peer.setOpacity(opacity);
}
}
}
/**
* JavaDoc
*/
/*public */Shape getShape() {
synchronized (getTreeLock()) {
return shape;
}
}
/**
* JavaDoc
*
* @param window the window to set the shape to
* @param shape the shape to set to the window
* @throws IllegalArgumentException if the window is in full screen mode,
* and the shape is not null
*/
/*public */void setShape(Shape shape) {
synchronized (getTreeLock()) {
GraphicsConfiguration gc = getGraphicsConfiguration();
GraphicsDevice gd = gc.getDevice();
if (!gd.isWindowTranslucencySupported(
GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT))
{
throw new UnsupportedOperationException(
"PERPIXEL_TRANSPARENT translucency is not supported.");
}
if ((gc.getDevice().getFullScreenWindow() == this) && (shape != null)) {
throw new IllegalArgumentException(
"Setting shape for full-screen window is not supported.");
}
this.shape = shape;
WindowPeer peer = (WindowPeer)getPeer();
if (peer != null) {
peer.applyShape(shape == null ? null : Region.getInstance(shape, null));
}
}
}
/**
* JavaDoc
*/
/*
@Override
public void setBackground(Color bgColor) {
int alpha = bgColor.getAlpha();
if (alpha < 255) { // non-opaque window
GraphicsConfiguration gc = getGraphicsConfiguration();
GraphicsDevice gd = gc.getDevice();
if (gc.getDevice().getFullScreenWindow() == this) {
throw new IllegalArgumentException(
"Making full-screen window non opaque is not supported.");
}
if (!gc.isTranslucencyCapable()) {
GraphicsConfiguration capableGC = gd.getTranslucencyCapableGC();
if (capableGC == null) {
throw new IllegalArgumentException(
"PERPIXEL_TRANSLUCENT translucency is not supported");
}
// TODO: change GC
}
setLayersOpaque(this, false);
}
super.setBackground(bgColor);
WindowPeer peer = (WindowPeer)getPeer();
if (peer != null) {
peer.setOpaque(alpha == 255);
}
}
*/
private transient boolean opaque = true;
void setOpaque(boolean opaque) {
synchronized (getTreeLock()) {
GraphicsConfiguration gc = getGraphicsConfiguration();
if (!opaque && !com.sun.awt.AWTUtilities.isTranslucencyCapable(gc)) {
throw new IllegalArgumentException(
"The window must use a translucency-compatible graphics configuration");
}
if (!com.sun.awt.AWTUtilities.isTranslucencySupported(
com.sun.awt.AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT))
{
throw new UnsupportedOperationException(
"PERPIXEL_TRANSLUCENT translucency is not supported.");
}
if ((gc.getDevice().getFullScreenWindow() == this) && !opaque) {
throw new IllegalArgumentException(
"Making full-screen window non opaque is not supported.");
}
setLayersOpaque(this, opaque);
this.opaque = opaque;
WindowPeer peer = (WindowPeer)getPeer();
if (peer != null) {
peer.setOpaque(opaque);
}
}
}
private void updateWindow(BufferedImage backBuffer) {
synchronized (getTreeLock()) {
WindowPeer peer = (WindowPeer)getPeer();
if (peer != null) {
peer.updateWindow(backBuffer);
}
}
}
private static final Color TRANSPARENT_BACKGROUND_COLOR = new Color(0, 0, 0, 0);
private static void setLayersOpaque(Component component, boolean isOpaque) {
// Shouldn't use instanceof to avoid loading Swing classes
// if it's a pure AWT application.
if (Component.doesImplement(component, "javax.swing.RootPaneContainer")) {
javax.swing.RootPaneContainer rpc = (javax.swing.RootPaneContainer)component;
javax.swing.JRootPane root = rpc.getRootPane();
javax.swing.JLayeredPane lp = root.getLayeredPane();
Container c = root.getContentPane();
javax.swing.JComponent content =
(c instanceof javax.swing.JComponent) ? (javax.swing.JComponent)c : null;
javax.swing.JComponent gp =
(rpc.getGlassPane() instanceof javax.swing.JComponent) ?
(javax.swing.JComponent)rpc.getGlassPane() : null;
if (gp != null) {
gp.setDoubleBuffered(isOpaque);
}
lp.setOpaque(isOpaque);
root.setOpaque(isOpaque);
root.setDoubleBuffered(isOpaque); //XXX: the "white rect" workaround
if (content != null) {
content.setOpaque(isOpaque);
content.setDoubleBuffered(isOpaque); //XXX: the "white rect" workaround
// Iterate down one level to see whether we have a JApplet
// (which is also a RootPaneContainer) which requires processing
int numChildren = content.getComponentCount();
if (numChildren > 0) {
Component child = content.getComponent(0);
// It's OK to use instanceof here because we've
// already loaded the RootPaneContainer class by now
if (child instanceof javax.swing.RootPaneContainer) {
setLayersOpaque(child, isOpaque);
}
}
}
}
Color bg = component.getBackground();
boolean hasTransparentBg = TRANSPARENT_BACKGROUND_COLOR.equals(bg);
Container container = null;
if (component instanceof Container) {
container = (Container) component;
}
if (isOpaque) {
if (hasTransparentBg) {
// Note: we use the SystemColor.window color as the default.
// This color is used in the WindowPeer implementations to
// initialize the background color of the window if it is null.
// (This might not be the right thing to do for other
// RootPaneContainers we might be invoked with)
Color newColor = null;
if (container != null && container.preserveBackgroundColor != null) {
newColor = container.preserveBackgroundColor;
} else {
newColor = SystemColor.window;
}
component.setBackground(newColor);
}
} else {
if (!hasTransparentBg && container != null) {
container.preserveBackgroundColor = bg;
}
component.setBackground(TRANSPARENT_BACKGROUND_COLOR);
}
}
// ************************** MIXING CODE ******************************* // ************************** MIXING CODE *******************************
// A window has a parent, but it does NOT have a container // A window has a parent, but it does NOT have a container
...@@ -3341,6 +3583,42 @@ public class Window extends Container implements Accessible { ...@@ -3341,6 +3583,42 @@ public class Window extends Container implements Accessible {
// ****************** END OF MIXING CODE ******************************** // ****************** END OF MIXING CODE ********************************
static {
AWTAccessor.setWindowAccessor(new AWTAccessor.WindowAccessor() {
public float getOpacity(Window window) {
return window.opacity;
}
public void setOpacity(Window window, float opacity) {
window.setOpacity(opacity);
}
public Shape getShape(Window window) {
return window.getShape();
}
public void setShape(Window window, Shape shape) {
window.setShape(shape);
}
public boolean isOpaque(Window window) {
/*
return window.getBackground().getAlpha() < 255;
*/
synchronized (window.getTreeLock()) {
return window.opaque;
}
}
public void setOpaque(Window window, boolean opaque) {
/*
Color bg = window.getBackground();
window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
opaque ? 255 : 0));
*/
window.setOpaque(opaque);
}
public void updateWindow(Window window, BufferedImage backBuffer) {
window.updateWindow(backBuffer);
}
}); // WindowAccessor
} // static
} // class Window } // class Window
......
/* /*
* Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,8 @@ package java.awt.peer; ...@@ -27,6 +27,8 @@ package java.awt.peer;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage;
/** /**
* The peer interface for {@link Window}. * The peer interface for {@link Window}.
* *
...@@ -92,4 +94,26 @@ public interface WindowPeer extends ContainerPeer { ...@@ -92,4 +94,26 @@ public interface WindowPeer extends ContainerPeer {
* @see Window#setIconImages(java.util.List) * @see Window#setIconImages(java.util.List)
*/ */
void updateIconImages(); void updateIconImages();
/**
* Sets the level of opacity for the window.
*
* @see Window#setOpacity(float)
*/
void setOpacity(float opacity);
/**
* Enables the per-pixel alpha support for the window.
*
* @see Window#setBackground(Color)
*/
void setOpaque(boolean isOpaque);
/**
* Updates the native part of non-opaque window using
* the given image with color+alpha values for each pixel.
*
* @see Window#setBackground(Color)
*/
void updateWindow(BufferedImage backBuffer);
} }
/* /*
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -34,6 +34,7 @@ import java.security.AccessController; ...@@ -34,6 +34,7 @@ import java.security.AccessController;
import java.util.*; import java.util.*;
import java.applet.*; import java.applet.*;
import sun.awt.AWTAccessor;
import sun.awt.AppContext; import sun.awt.AppContext;
import sun.awt.DisplayChangedListener; import sun.awt.DisplayChangedListener;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
...@@ -716,6 +717,44 @@ public class RepaintManager ...@@ -716,6 +717,44 @@ public class RepaintManager
} }
} }
private Map<Component,Rectangle>
updateWindows(Map<Component,Rectangle> dirtyComponents)
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
if (!(toolkit instanceof SunToolkit &&
((SunToolkit)toolkit).needUpdateWindow()))
{
return dirtyComponents;
}
Set<Window> windows = new HashSet<Window>();
Set<Component> dirtyComps = dirtyComponents.keySet();
for (Iterator<Component> it = dirtyComps.iterator(); it.hasNext();) {
Component dirty = it.next();
Window window = dirty instanceof Window ?
(Window)dirty :
SwingUtilities.getWindowAncestor(dirty);
if (window != null &&
!AWTAccessor.getWindowAccessor().isOpaque(window))
{
// if this component's toplevel is perpixel translucent, it will
// be repainted below
it.remove();
// add to the set of windows to update (so that we don't update
// the window many times for each component to be repainted that
// belongs to this window)
windows.add(window);
}
}
for (Window window : windows) {
AWTAccessor.getWindowAccessor().updateWindow(window, null);
}
return dirtyComponents;
}
/** /**
* Paint all of the components that have been marked dirty. * Paint all of the components that have been marked dirty.
* *
...@@ -749,6 +788,10 @@ public class RepaintManager ...@@ -749,6 +788,10 @@ public class RepaintManager
int localBoundsW; int localBoundsW;
Enumeration keys; Enumeration keys;
// the components belonging to perpixel-translucent windows will be
// removed from the list
tmpDirtyComponents = updateWindows(tmpDirtyComponents);
roots = new ArrayList<Component>(count); roots = new ArrayList<Component>(count);
for (Component dirty : tmpDirtyComponents.keySet()) { for (Component dirty : tmpDirtyComponents.keySet()) {
......
/* /*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
package sun.awt; package sun.awt;
import java.awt.*; import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import sun.misc.Unsafe; import sun.misc.Unsafe;
/** The AWTAccessor utility class. /** The AWTAccessor utility class.
...@@ -35,37 +38,124 @@ import sun.misc.Unsafe; ...@@ -35,37 +38,124 @@ import sun.misc.Unsafe;
* for another example. * for another example.
*/ */
public final class AWTAccessor { public final class AWTAccessor {
private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final Unsafe unsafe = Unsafe.getUnsafe();
/** We don't need any objects of this class. /*
* We don't need any objects of this class.
* It's rather a collection of static methods * It's rather a collection of static methods
* and interfaces. * and interfaces.
*/ */
private AWTAccessor() { private AWTAccessor() {
} }
/** An accessor for the java.awt.Component class. /*
* An interface of accessor for the java.awt.Component class.
*/ */
public interface ComponentAccessor { public interface ComponentAccessor {
// See 6797587 /*
// Also see: 6776743, 6768307, and 6768332. * Sets whether the native background erase for a component
/** * has been disabled via SunToolkit.disableBackgroundErase().
*/
void setBackgroundEraseDisabled(Component comp, boolean disabled);
/*
* Indicates whether the native background erase for a
* component has been disabled via
* SunToolkit.disableBackgroundErase().
*/
boolean getBackgroundEraseDisabled(Component comp);
/*
*
* Gets the bounds of this component in the form of a
* <code>Rectangle</code> object. The bounds specify this
* component's width, height, and location relative to
* its parent.
*/
Rectangle getBounds(Component comp);
/*
* Sets the shape of a lw component to cut out from hw components. * Sets the shape of a lw component to cut out from hw components.
*
* See 6797587, 6776743, 6768307, and 6768332 for details
*/ */
void setMixingCutoutShape(Component comp, Shape shape); void setMixingCutoutShape(Component comp, Shape shape);
} }
/* The java.awt.Component class accessor object. /*
* An interface of accessor for java.awt.Window class.
*/
public interface WindowAccessor {
/*
* Get opacity level of the given window.
*/
float getOpacity(Window window);
/*
* Set opacity level to the given window.
*/
void setOpacity(Window window, float opacity);
/*
* Get a shape assigned to the given window.
*/
Shape getShape(Window window);
/*
* Set a shape to the given window.
*/
void setShape(Window window, Shape shape);
/*
* Identify whether the given window is opaque (true)
* or translucent (false).
*/
boolean isOpaque(Window window);
/*
* Set the opaque preoperty to the given window.
*/
void setOpaque(Window window, boolean isOpaque);
/*
* Update the image of a non-opaque (translucent) window.
*/
void updateWindow(Window window, BufferedImage backBuffer);
}
/*
* An accessor for the AWTEvent class.
*/
public interface AWTEventAccessor {
/*
*
* Sets the flag on this AWTEvent indicating that it was
* generated by the system.
*/
void setSystemGenerated(AWTEvent ev);
/*
*
* Indicates whether this AWTEvent was generated by the system.
*/
boolean isSystemGenerated(AWTEvent ev);
}
/*
* The java.awt.Component class accessor object.
*/ */
private static ComponentAccessor componentAccessor; private static ComponentAccessor componentAccessor;
/** Set an accessor object for the java.awt.Component class. /*
* The java.awt.Window class accessor object.
*/
private static WindowAccessor windowAccessor;
/*
* The java.awt.AWTEvent class accessor object.
*/
private static AWTEventAccessor awtEventAccessor;
/*
* Set an accessor object for the java.awt.Component class.
*/ */
public static void setComponentAccessor(ComponentAccessor ca) { public static void setComponentAccessor(ComponentAccessor ca) {
componentAccessor = ca; componentAccessor = ca;
} }
/** Retrieve the accessor object for the java.awt.Window class. /*
* Retrieve the accessor object for the java.awt.Window class.
*/ */
public static ComponentAccessor getComponentAccessor() { public static ComponentAccessor getComponentAccessor() {
if (componentAccessor == null) { if (componentAccessor == null) {
...@@ -74,4 +164,35 @@ public final class AWTAccessor { ...@@ -74,4 +164,35 @@ public final class AWTAccessor {
return componentAccessor; return componentAccessor;
} }
/*
* Set an accessor object for the java.awt.Window class.
*/
public static void setWindowAccessor(WindowAccessor wa) {
windowAccessor = wa;
}
/*
* Retrieve the accessor object for the java.awt.Window class.
*/
public static WindowAccessor getWindowAccessor() {
if (windowAccessor == null) {
unsafe.ensureClassInitialized(Window.class);
}
return windowAccessor;
}
/*
* Set an accessor object for the java.awt.AWTEvent class.
*/
public static void setAWTEventAccessor(AWTEventAccessor aea) {
awtEventAccessor = aea;
}
/*
* Retrieve the accessor object for the java.awt.AWTEvent class.
*/
public static AWTEventAccessor getAWTEventAccessor() {
return awtEventAccessor;
}
} }
/* /*
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -585,5 +585,12 @@ public abstract class EmbeddedFrame extends Frame ...@@ -585,5 +585,12 @@ public abstract class EmbeddedFrame extends Frame
} }
public void updateMinimumSize() { public void updateMinimumSize() {
} }
}
public void setOpacity(float opacity) {
}
public void setOpaque(boolean isOpaque) {
}
public void updateWindow(BufferedImage backBuffer) {
}
}
} // class EmbeddedFrame } // class EmbeddedFrame
/* /*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,14 +32,10 @@ import java.awt.dnd.peer.DragSourceContextPeer; ...@@ -32,14 +32,10 @@ import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.peer.*; import java.awt.peer.*;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.im.spi.InputMethodDescriptor;
import java.awt.image.*; import java.awt.image.*;
import java.awt.geom.AffineTransform;
import java.awt.TrayIcon; import java.awt.TrayIcon;
import java.awt.SystemTray; import java.awt.SystemTray;
import java.io.*;
import java.net.URL; import java.net.URL;
import java.net.JarURLConnection;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Condition;
...@@ -49,7 +45,6 @@ import java.util.logging.Logger; ...@@ -49,7 +45,6 @@ import java.util.logging.Logger;
import sun.misc.SoftCache; import sun.misc.SoftCache;
import sun.font.FontDesignMetrics; import sun.font.FontDesignMetrics;
import sun.awt.im.InputContext; import sun.awt.im.InputContext;
import sun.awt.im.SimpleInputMethodWindow;
import sun.awt.image.*; import sun.awt.image.*;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import sun.security.action.GetBooleanAction; import sun.security.action.GetBooleanAction;
...@@ -824,16 +819,31 @@ public abstract class SunToolkit extends Toolkit ...@@ -824,16 +819,31 @@ public abstract class SunToolkit extends Toolkit
} }
/** /**
* Disables erasing of background on the canvas before painting * Disables erasing of background on the canvas before painting if
* if this is supported by the current toolkit. * this is supported by the current toolkit. It is recommended to
* * call this method early, before the Canvas becomes displayable,
* @throws IllegalStateException if the canvas is not displayable * because some Toolkit implementations do not support changing
* @see java.awt.Component#isDisplayable * this property once the Canvas becomes displayable.
*/ */
public void disableBackgroundErase(Canvas canvas) { public void disableBackgroundErase(Canvas canvas) {
if (!canvas.isDisplayable()) { disableBackgroundEraseImpl(canvas);
throw new IllegalStateException("Canvas must have a valid peer"); }
}
/**
* Disables the native erasing of the background on the given
* component before painting if this is supported by the current
* toolkit. This only has an effect for certain components such as
* Canvas, Panel and Window. It is recommended to call this method
* early, before the Component becomes displayable, because some
* Toolkit implementations do not support changing this property
* once the Component becomes displayable.
*/
public void disableBackgroundErase(Component component) {
disableBackgroundEraseImpl(component);
}
private void disableBackgroundEraseImpl(Component component) {
AWTAccessor.getComponentAccessor().setBackgroundEraseDisabled(component, true);
} }
/** /**
...@@ -1972,6 +1982,18 @@ public abstract class SunToolkit extends Toolkit ...@@ -1972,6 +1982,18 @@ public abstract class SunToolkit extends Toolkit
AWTAutoShutdown.getInstance().dumpPeers(aLog); AWTAutoShutdown.getInstance().dumpPeers(aLog);
} }
/**
* Returns the <code>Window</code> ancestor of the component <code>comp</code>.
* @return Window ancestor of the component or component by itself if it is Window;
* null, if component is not a part of window hierarchy
*/
public static Window getContainingWindow(Component comp) {
while (comp != null && !(comp instanceof Window)) {
comp = comp.getParent();
}
return (Window)comp;
}
private static Boolean sunAwtDisableMixing = null; private static Boolean sunAwtDisableMixing = null;
/** /**
...@@ -1995,6 +2017,73 @@ public abstract class SunToolkit extends Toolkit ...@@ -1995,6 +2017,73 @@ public abstract class SunToolkit extends Toolkit
public boolean isNativeGTKAvailable() { public boolean isNativeGTKAvailable() {
return false; return false;
} }
// Cosntant alpha
public boolean isWindowOpacitySupported() {
return false;
}
// Shaping
public boolean isWindowShapingSupported() {
return false;
}
// Per-pixel alpha
public boolean isWindowTranslucencySupported() {
return false;
}
public boolean isTranslucencyCapable(GraphicsConfiguration gc) {
return false;
}
/**
* Returns whether or not a containing top level window for the passed
* component is
* {@link com.sun.awt.AWTUtilities.Translucency#PERPIXEL_TRANSLUCENT PERPIXEL_TRANSLUCENT}.
*
* @param c a Component which toplevel's to check
* @return {@code true} if the passed component is not null and has a
* containing toplevel window which is opaque (so per-pixel translucency
* is not enabled), {@code false} otherwise
* @see com.sun.awt.AWTUtilities.Translucency#PERPIXEL_TRANSLUCENT
* @see com.sun.awt.AWTUtilities#isWindowOpaque(Window)
*/
public static boolean isContainingTopLevelOpaque(Component c) {
Window w = getContainingWindow(c);
// return w != null && (w).isOpaque();
return w != null && com.sun.awt.AWTUtilities.isWindowOpaque(w);
}
/**
* Returns whether or not a containing top level window for the passed
* component is
* {@link com.sun.awt.AWTUtilities.Translucency#TRANSLUCENT TRANSLUCENT}.
*
* @param c a Component which toplevel's to check
* @return {@code true} if the passed component is not null and has a
* containing toplevel window which has opacity less than
* 1.0f (which means that it is translucent), {@code false} otherwise
* @see com.sun.awt.AWTUtilities.Translucency#TRANSLUCENT
* @see com.sun.awt.AWTUtilities#getWindowOpacity(Window)
*/
public static boolean isContainingTopLevelTranslucent(Component c) {
Window w = getContainingWindow(c);
// return w != null && (w).getOpacity() < 1.0f;
return w != null && com.sun.awt.AWTUtilities.getWindowOpacity((Window)w) < 1.0f;
}
/**
* Returns whether the native system requires using the peer.updateWindow()
* method to update the contents of a non-opaque window, or if usual
* painting procedures are sufficient. The default return value covers
* the X11 systems. On MS Windows this method is overriden in WToolkit
* to return true.
*/
public boolean needUpdateWindow() {
return false;
}
} // class SunToolkit } // class SunToolkit
......
/*
* Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#include "utility/rect.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* bitsPerPixel must be 32 for now.
* outBuf must be large enough to conatin all the rectangles.
*/
int BitmapToYXBandedRectangles(int bitsPerPixel, int width, int height, unsigned char * buf, RECT_T * outBuf)
{
//XXX: we might want to reuse the code in the splashscreen library,
// though we'd have to deal with the ALPHA_THRESHOLD and different
// image formats in this case.
int widthBytes = width * bitsPerPixel / 8;
int alignedWidth = (((widthBytes - 1) / 4) + 1) * 4;
RECT_T * out = outBuf;
RECT_T *pPrevLine = NULL, *pFirst = out, *pThis = pFirst;
int i, j, i0;
int length;
for (j = 0; j < height; j++) {
/* generate data for a scanline */
unsigned char *pSrc = (unsigned char *) buf + j * alignedWidth;
RECT_T *pLine = pThis;
i = 0;
do {
// pSrc[0,1,2] == B,G,R; pSrc[3] == Alpha
while (i < width && !pSrc[3]) {
pSrc += 4;
++i;
}
if (i >= width)
break;
i0 = i;
while (i < width && pSrc[3]) {
pSrc += 4;
++i;
}
RECT_SET(*pThis, i0, j, i - i0, 1);
++pThis;
} while (i < width);
/* check if the previous scanline is exactly the same, merge if so
(this is the only optimization we can use for YXBanded rectangles,
and win32 supports YXBanded only */
length = pThis - pLine;
if (pPrevLine && pLine - pPrevLine == length) {
for (i = 0; i < length && RECT_EQ_X(pPrevLine[i], pLine[i]); ++i) {
}
if (i == pLine - pPrevLine) {
// do merge
for (i = 0; i < length; i++) {
RECT_INC_HEIGHT(pPrevLine[i]);
}
pThis = pLine;
continue;
}
}
/* or else use the generated scanline */
pPrevLine = pLine;
}
return pThis - pFirst;
}
#if defined(__cplusplus)
}
#endif
/* /*
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -252,6 +252,8 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt ...@@ -252,6 +252,8 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
XAtom XA_NET_WM_WINDOW_TYPE = XAtom.get("_NET_WM_WINDOW_TYPE"); XAtom XA_NET_WM_WINDOW_TYPE = XAtom.get("_NET_WM_WINDOW_TYPE");
XAtom XA_NET_WM_WINDOW_TYPE_DIALOG = XAtom.get("_NET_WM_WINDOW_TYPE_DIALOG"); XAtom XA_NET_WM_WINDOW_TYPE_DIALOG = XAtom.get("_NET_WM_WINDOW_TYPE_DIALOG");
XAtom XA_NET_WM_WINDOW_OPACITY = XAtom.get("_NET_WM_WINDOW_OPACITY");
/* For _NET_WM_STATE ClientMessage requests */ /* For _NET_WM_STATE ClientMessage requests */
final static int _NET_WM_STATE_REMOVE =0; /* remove/unset property */ final static int _NET_WM_STATE_REMOVE =0; /* remove/unset property */
final static int _NET_WM_STATE_ADD =1; /* add/set property */ final static int _NET_WM_STATE_ADD =1; /* add/set property */
...@@ -289,6 +291,12 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt ...@@ -289,6 +291,12 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE_MODAL); boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE_MODAL);
return res; return res;
} }
boolean doOpacityProtocol() {
boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_WINDOW_OPACITY);
return res;
}
boolean isWMName(String name) { boolean isWMName(String name) {
if (!active()) { if (!active()) {
return false; return false;
......
/* /*
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -2273,4 +2273,36 @@ public final class XToolkit extends UNIXToolkit implements Runnable { ...@@ -2273,4 +2273,36 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
public boolean areExtraMouseButtonsEnabled() throws HeadlessException { public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
return areExtraMouseButtonsEnabled; return areExtraMouseButtonsEnabled;
} }
@Override
public boolean isWindowOpacitySupported() {
XNETProtocol net_protocol = XWM.getWM().getNETProtocol();
if (net_protocol == null) {
return false;
}
return net_protocol.doOpacityProtocol();
}
@Override
public boolean isWindowShapingSupported() {
return XlibUtil.isShapingSupported();
}
@Override
public boolean isWindowTranslucencySupported() {
//NOTE: it may not be supported. The actual check is being performed
// at com.sun.awt.AWTUtilities(). In X11 we need to check
// whether there's any translucency-capable GC available.
return true;
}
@Override
public boolean isTranslucencyCapable(GraphicsConfiguration gc) {
if (!(gc instanceof X11GraphicsConfig)) {
return false;
}
return ((X11GraphicsConfig)gc).isTranslucencyCapable();
}
} }
/* /*
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,6 +30,8 @@ import java.awt.event.ComponentEvent; ...@@ -30,6 +30,8 @@ import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.peer.ComponentPeer; import java.awt.peer.ComponentPeer;
import java.awt.peer.WindowPeer; import java.awt.peer.WindowPeer;
...@@ -42,6 +44,7 @@ import java.util.Vector; ...@@ -42,6 +44,7 @@ import java.util.Vector;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import sun.awt.AWTAccessor;
import sun.awt.ComponentAccessor; import sun.awt.ComponentAccessor;
import sun.awt.WindowAccessor; import sun.awt.WindowAccessor;
import sun.awt.DisplayChangedListener; import sun.awt.DisplayChangedListener;
...@@ -49,6 +52,8 @@ import sun.awt.SunToolkit; ...@@ -49,6 +52,8 @@ import sun.awt.SunToolkit;
import sun.awt.X11GraphicsDevice; import sun.awt.X11GraphicsDevice;
import sun.awt.X11GraphicsEnvironment; import sun.awt.X11GraphicsEnvironment;
import sun.java2d.pipe.Region;
class XWindowPeer extends XPanelPeer implements WindowPeer, class XWindowPeer extends XPanelPeer implements WindowPeer,
DisplayChangedListener { DisplayChangedListener {
...@@ -260,6 +265,10 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, ...@@ -260,6 +265,10 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
setSaveUnder(true); setSaveUnder(true);
updateIconImages(); updateIconImages();
updateShape();
updateOpacity();
// no need in updateOpaque() as it is no-op
} }
public void updateIconImages() { public void updateIconImages() {
...@@ -417,6 +426,22 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, ...@@ -417,6 +426,22 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
return defaultIconInfo; return defaultIconInfo;
} }
private void updateShape() {
// Shape shape = ((Window)target).getShape();
Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
if (shape != null) {
applyShape(Region.getInstance(shape, null));
}
}
private void updateOpacity() {
// float opacity = ((Window)target).getOpacity();
float opacity = AWTAccessor.getWindowAccessor().getOpacity((Window)target);
if (opacity < 1.0f) {
setOpacity(opacity);
}
}
public void updateMinimumSize() { public void updateMinimumSize() {
//This function only saves minimumSize value in XWindowPeer //This function only saves minimumSize value in XWindowPeer
//Setting WMSizeHints is implemented in XDecoratedPeer //Setting WMSizeHints is implemented in XDecoratedPeer
...@@ -2064,4 +2089,44 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, ...@@ -2064,4 +2089,44 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
} }
super.handleButtonPressRelease(xev); super.handleButtonPressRelease(xev);
} }
public void print(Graphics g) {
// We assume we print the whole frame,
// so we expect no clip was set previously
Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
if (shape != null) {
g.setClip(shape);
}
super.print(g);
}
@Override
public void setOpacity(float opacity) {
final long maxOpacity = 0xffffffffl;
long iOpacity = (long)(opacity * maxOpacity);
if (iOpacity < 0) {
iOpacity = 0;
}
if (iOpacity > maxOpacity) {
iOpacity = maxOpacity;
}
XAtom netWmWindowOpacityAtom = XAtom.get("_NET_WM_WINDOW_OPACITY");
if (iOpacity == maxOpacity) {
netWmWindowOpacityAtom.DeleteProperty(getWindow());
} else {
netWmWindowOpacityAtom.setCard32Property(getWindow(), iOpacity);
}
}
@Override
public void setOpaque(boolean isOpaque) {
// no-op
}
@Override
public void updateWindow(BufferedImage backBuffer) {
// no-op
}
} }
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -859,14 +859,14 @@ public class WrapperGenerator { ...@@ -859,14 +859,14 @@ public class WrapperGenerator {
pw.println("\n\tlong pData;"); pw.println("\n\tlong pData;");
pw.println("\n\tpublic long getPData() { return pData; }"); pw.println("\n\tpublic long getPData() { return pData; }");
pw.println("\n\n\t" + stp.getJavaClassName() + "(long addr) {"); pw.println("\n\n\tpublic " + stp.getJavaClassName() + "(long addr) {");
if (generateLog) { if (generateLog) {
pw.println("\t\tlog.finest(\"Creating\");"); pw.println("\t\tlog.finest(\"Creating\");");
} }
pw.println("\t\tpData=addr;"); pw.println("\t\tpData=addr;");
pw.println("\t\tshould_free_memory = false;"); pw.println("\t\tshould_free_memory = false;");
pw.println("\t}"); pw.println("\t}");
pw.println("\n\n\t" + stp.getJavaClassName() + "() {"); pw.println("\n\n\tpublic " + stp.getJavaClassName() + "() {");
if (generateLog) { if (generateLog) {
pw.println("\t\tlog.finest(\"Creating\");"); pw.println("\t\tlog.finest(\"Creating\");");
} }
......
...@@ -750,6 +750,7 @@ AwtGraphicsConfigData ...@@ -750,6 +750,7 @@ AwtGraphicsConfigData
pixelStride int pixelStride int
color_data pointer ColorData color_data pointer ColorData
glxInfo pointer glxInfo pointer
isTranslucencySupported int
AwtScreenData AwtScreenData
numConfigs int numConfigs int
......
/* /*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -450,4 +450,13 @@ public class X11GraphicsConfig extends GraphicsConfiguration ...@@ -450,4 +450,13 @@ public class X11GraphicsConfig extends GraphicsConfiguration
return 0x00; // UNDEFINED return 0x00; // UNDEFINED
} }
} }
/*
@Override
*/
public boolean isTranslucencyCapable() {
return isTranslucencyCapable(getAData());
}
private native boolean isTranslucencyCapable(long x11ConfigData);
} }
/* /*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -354,6 +354,48 @@ makeDefaultConfig(JNIEnv *env, int screen) { ...@@ -354,6 +354,48 @@ makeDefaultConfig(JNIEnv *env, int screen) {
return NULL; return NULL;
} }
/* Note: until we include the <X11/extensions/Xrender.h> explicitly
* we have to define a couple of things ourselves.
*/
typedef unsigned long PictFormat;
#define PictTypeIndexed 0
#define PictTypeDirect 1
typedef struct {
short red;
short redMask;
short green;
short greenMask;
short blue;
short blueMask;
short alpha;
short alphaMask;
} XRenderDirectFormat;
typedef struct {
PictFormat id;
int type;
int depth;
XRenderDirectFormat direct;
Colormap colormap;
} XRenderPictFormat;
#define PictFormatID (1 << 0)
#define PictFormatType (1 << 1)
#define PictFormatDepth (1 << 2)
#define PictFormatRed (1 << 3)
#define PictFormatRedMask (1 << 4)
#define PictFormatGreen (1 << 5)
#define PictFormatGreenMask (1 << 6)
#define PictFormatBlue (1 << 7)
#define PictFormatBlueMask (1 << 8)
#define PictFormatAlpha (1 << 9)
#define PictFormatAlphaMask (1 << 10)
#define PictFormatColormap (1 << 11)
typedef XRenderPictFormat *
XRenderFindVisualFormatFunc (Display *dpy, _Xconst Visual *visual);
static void static void
getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {
...@@ -367,6 +409,9 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { ...@@ -367,6 +409,9 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {
int ind; int ind;
char errmsg[128]; char errmsg[128];
int xinawareScreen; int xinawareScreen;
void* xrenderLibHandle = NULL;
XRenderFindVisualFormatFunc *XRenderFindVisualFormat = NULL;
int major_opcode, first_event, first_error;
if (usingXinerama) { if (usingXinerama) {
xinawareScreen = 0; xinawareScreen = 0;
...@@ -449,6 +494,26 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { ...@@ -449,6 +494,26 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {
graphicsConfigs[0] = defaultConfig; graphicsConfigs[0] = defaultConfig;
nConfig = 1; /* reserve index 0 for default config */ nConfig = 1; /* reserve index 0 for default config */
// Only use the RENDER extension if it is available on the X server
if (XQueryExtension(awt_display, "RENDER",
&major_opcode, &first_event, &first_error))
{
xrenderLibHandle = dlopen("libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL);
#ifndef __linux__ /* SOLARIS */
if (xrenderLibHandle == NULL) {
xrenderLibHandle = dlopen("/usr/sfw/lib/libXrender.so.1",
RTLD_LAZY | RTLD_GLOBAL);
}
#endif
if (xrenderLibHandle != NULL) {
XRenderFindVisualFormat =
(XRenderFindVisualFormatFunc*)dlsym(xrenderLibHandle,
"XRenderFindVisualFormat");
}
}
for (i = 0; i < nTrue; i++) { for (i = 0; i < nTrue; i++) {
if (XVisualIDFromVisual(pVITrue[i].visual) == if (XVisualIDFromVisual(pVITrue[i].visual) ==
XVisualIDFromVisual(defaultConfig->awt_visInfo.visual) || XVisualIDFromVisual(defaultConfig->awt_visInfo.visual) ||
...@@ -462,6 +527,21 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { ...@@ -462,6 +527,21 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {
graphicsConfigs [ind]->awt_depth = pVITrue [i].depth; graphicsConfigs [ind]->awt_depth = pVITrue [i].depth;
memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVITrue [i], memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVITrue [i],
sizeof (XVisualInfo)); sizeof (XVisualInfo));
if (XRenderFindVisualFormat != NULL) {
XRenderPictFormat *format = XRenderFindVisualFormat (awt_display,
pVITrue [i].visual);
if (format &&
format->type == PictTypeDirect &&
format->direct.alphaMask)
{
graphicsConfigs [ind]->isTranslucencySupported = 1;
}
}
}
if (xrenderLibHandle != NULL) {
dlclose(xrenderLibHandle);
xrenderLibHandle = NULL;
} }
for (i = 0; i < n8p; i++) { for (i = 0; i < n8p; i++) {
...@@ -1505,6 +1585,26 @@ Java_sun_awt_X11GraphicsConfig_swapBuffers ...@@ -1505,6 +1585,26 @@ Java_sun_awt_X11GraphicsConfig_swapBuffers
AWT_FLUSH_UNLOCK(); AWT_FLUSH_UNLOCK();
} }
/*
* Class: sun_awt_X11GraphicsConfig
* Method: isTranslucencyCapable
* Signature: (J)V
*/
JNIEXPORT jboolean JNICALL
Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable
(JNIEnv *env, jobject this, jlong configData)
{
#ifdef HEADLESS
return JNI_FALSE;
#else
AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)jlong_to_ptr(configData);
if (aData == NULL) {
return JNI_FALSE;
}
return (jboolean)aData->isTranslucencySupported;
#endif
}
/* /*
* Class: sun_awt_X11GraphicsDevice * Class: sun_awt_X11GraphicsDevice
* Method: isDBESupported * Method: isDBESupported
......
/* /*
* Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -135,6 +135,7 @@ typedef struct _AwtGraphicsConfigData { ...@@ -135,6 +135,7 @@ typedef struct _AwtGraphicsConfigData {
int pixelStride; /* Used in X11SurfaceData.c */ int pixelStride; /* Used in X11SurfaceData.c */
ColorData *color_data; ColorData *color_data;
struct _GLXGraphicsConfigInfo *glxInfo; struct _GLXGraphicsConfigInfo *glxInfo;
int isTranslucencySupported; /* Uses Xrender to find this out. */
} AwtGraphicsConfigData; } AwtGraphicsConfigData;
typedef AwtGraphicsConfigData* AwtGraphicsConfigDataPtr; typedef AwtGraphicsConfigData* AwtGraphicsConfigDataPtr;
......
/* /*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -331,4 +331,12 @@ public class Win32GraphicsConfig extends GraphicsConfiguration ...@@ -331,4 +331,12 @@ public class Win32GraphicsConfig extends GraphicsConfiguration
} }
// the rest of the flip actions are not supported // the rest of the flip actions are not supported
} }
/*
@Override
*/
public boolean isTranslucencyCapable() {
//XXX: worth checking if 8-bit? Anyway, it doesn't hurt.
return true;
}
} }
/* /*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -393,4 +393,11 @@ public class Win32GraphicsEnvironment ...@@ -393,4 +393,11 @@ public class Win32GraphicsEnvironment
private static void dwmCompositionChanged(boolean enabled) { private static void dwmCompositionChanged(boolean enabled) {
isDWMCompositionEnabled = enabled; isDWMCompositionEnabled = enabled;
} }
/**
* Used to find out if the OS is Windows Vista or later.
*
* @return {@code true} if the OS is Vista or later, {@code false} otherwise
*/
public static native boolean isVistaOS();
} }
/*
* Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.awt.windows;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Window;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.VolatileImage;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import sun.awt.image.BufImgSurfaceData;
import sun.java2d.DestSurfaceProvider;
import sun.java2d.InvalidPipeException;
import sun.java2d.Surface;
import sun.java2d.pipe.RenderQueue;
import sun.java2d.pipe.hw.AccelGraphicsConfig;
import sun.java2d.pipe.hw.AccelSurface;
import sun.security.action.GetPropertyAction;
import static java.awt.image.VolatileImage.*;
import static java.awt.Transparency.*;
import static sun.java2d.pipe.hw.AccelSurface.*;
import static sun.java2d.pipe.hw.ContextCapabilities.*;
/**
* This class handles the updates of the non-opaque windows.
* The window associated with the peer is updated either given an image or
* the window is repainted to an internal buffer which is then used to update
* the window.
*
* Note: this class does not attempt to be thread safe, it is expected to be
* called from a single thread (EDT).
*/
public abstract class TranslucentWindowPainter {
protected Window window;
protected WWindowPeer peer;
// REMIND: we probably would want to remove this later
private static final boolean forceOpt =
Boolean.valueOf(AccessController.doPrivileged(
new GetPropertyAction("sun.java2d.twp.forceopt", "false")));
private static final boolean forceSW =
Boolean.valueOf(AccessController.doPrivileged(
new GetPropertyAction("sun.java2d.twp.forcesw", "false")));
/**
* Creates an instance of the painter for particular peer.
*/
public static TranslucentWindowPainter createInstance(WWindowPeer peer) {
GraphicsConfiguration gc = peer.getGraphicsConfiguration();
if (!forceSW && gc instanceof AccelGraphicsConfig) {
String gcName = gc.getClass().getSimpleName();
AccelGraphicsConfig agc = (AccelGraphicsConfig)gc;
// this is a heuristic to check that we have a pcix board
// (those have higher transfer rate from gpu to cpu)
if ((agc.getContextCapabilities().getCaps() & CAPS_PS30) != 0 ||
forceOpt)
{
// we check for name to avoid loading classes unnecessarily if
// a pipeline isn't enabled
if (gcName.startsWith("D3D")) {
return new VIOptD3DWindowPainter(peer);
} else if (forceOpt && gcName.startsWith("WGL")) {
// on some boards (namely, ATI, even on pcix bus) ogl is
// very slow reading pixels back so for now it is disabled
// unless forced
return new VIOptWGLWindowPainter(peer);
}
}
}
return new BIWindowPainter(peer);
}
protected TranslucentWindowPainter(WWindowPeer peer) {
this.peer = peer;
this.window = (Window)peer.getTarget();
}
/**
* Creates (if needed), clears and returns the buffer for this painter.
*/
protected abstract Image getBackBuffer();
/**
* Updates the the window associated with this painter with the contents
* of the passed image.
* The image can not be null, and NPE will be thrown if it is.
*/
protected abstract boolean update(Image bb);
/**
* Flushes the resources associated with the painter. They will be
* recreated as needed.
*/
public abstract void flush();
/**
* Updates the window associated with the painter given the passed image.
* If the passed image is null the painter will use its own buffer for
* rendering the contents of the window into it and updating the window.
*
* If the passed buffer has dimensions different from the window, it is
* copied into the internal buffer first and the latter is used to update
* the window.
*
* @param bb the image to update the non opaque window with, or null.
* If not null, the image must be of ARGB_PRE type.
*/
public void updateWindow(Image bb) {
boolean done = false;
if (bb != null && (window.getWidth() != bb.getWidth(null) ||
window.getHeight() != bb.getHeight(null)))
{
Image ourBB = getBackBuffer();
Graphics2D g = (Graphics2D)ourBB.getGraphics();
g.drawImage(bb, 0, 0, null);
g.dispose();
bb = ourBB;
}
do {
if (bb == null) {
bb = getBackBuffer();
Graphics2D g = (Graphics2D)bb.getGraphics();
try {
window.paintAll(g);
} finally {
g.dispose();
}
}
peer.paintAppletWarning((Graphics2D)bb.getGraphics(),
bb.getWidth(null), bb.getHeight(null));
done = update(bb);
// in case they passed us a lost VI, next time around we'll use our
// own bb because we can not validate and restore the contents of
// their VI
if (!done) {
bb = null;
}
} while (!done);
}
private static final Image clearImage(Image bb) {
Graphics2D g = (Graphics2D)bb.getGraphics();
int w = bb.getWidth(null);
int h = bb.getHeight(null);
g.setComposite(AlphaComposite.Src);
g.setColor(new Color(0, 0, 0, 0));
g.fillRect(0, 0, w, h);
return bb;
}
/**
* A painter which uses BufferedImage as the internal buffer. The window
* is painted into this buffer, and the contents then are uploaded
* into the layered window.
*
* This painter handles all types of images passed to its paint(Image)
* method (VI, BI, regular Images).
*/
private static class BIWindowPainter extends TranslucentWindowPainter {
private WeakReference<BufferedImage> biRef;
protected BIWindowPainter(WWindowPeer peer) {
super(peer);
}
private BufferedImage getBIBackBuffer() {
int w = window.getWidth();
int h = window.getHeight();
BufferedImage bb = biRef == null ? null : biRef.get();
if (bb == null || bb.getWidth() != w || bb.getHeight() != h) {
if (bb != null) {
bb.flush();
bb = null;
}
bb = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
biRef = new WeakReference<BufferedImage>(bb);
}
return (BufferedImage)clearImage(bb);
}
@Override
protected Image getBackBuffer() {
return getBIBackBuffer();
}
@Override
protected boolean update(Image bb) {
VolatileImage viBB = null;
if (bb instanceof BufferedImage) {
BufferedImage bi = (BufferedImage)bb;
int data[] =
((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
return true;
} else if (bb instanceof VolatileImage) {
viBB = (VolatileImage)bb;
if (bb instanceof DestSurfaceProvider) {
Surface s = ((DestSurfaceProvider)bb).getDestSurface();
if (s instanceof BufImgSurfaceData) {
// the image is probably lost, upload the data from the
// backup surface to avoid creating another heap-based
// image (the parent's buffer)
int w = viBB.getWidth();
int h = viBB.getHeight();
BufImgSurfaceData bisd = (BufImgSurfaceData)s;
int data[] = ((DataBufferInt)bisd.getRaster(0,0,w,h).
getDataBuffer()).getData();
peer.updateWindowImpl(data, w, h);
return true;
}
}
}
// copy the passed image into our own buffer, then upload
BufferedImage bi = getBIBackBuffer();
Graphics2D g = (Graphics2D)bi.getGraphics();
g.setComposite(AlphaComposite.Src);
g.drawImage(bb, 0, 0, null);
int data[] =
((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
return (viBB != null ? !viBB.contentsLost() : true);
}
public void flush() {
if (biRef != null) {
biRef.clear();
}
}
}
/**
* A version of the painter which uses VolatileImage as the internal buffer.
* The window is painted into this VI and then copied into the parent's
* Java heap-based buffer (which is then uploaded to the layered window)
*/
private static class VIWindowPainter extends BIWindowPainter {
private WeakReference<VolatileImage> viRef;
protected VIWindowPainter(WWindowPeer peer) {
super(peer);
}
@Override
protected Image getBackBuffer() {
int w = window.getWidth();
int h = window.getHeight();
GraphicsConfiguration gc = peer.getGraphicsConfiguration();
VolatileImage viBB = viRef == null ? null : viRef.get();
if (viBB == null || viBB.getWidth() != w || viBB.getHeight() != h ||
viBB.validate(gc) == IMAGE_INCOMPATIBLE)
{
if (viBB != null) {
viBB.flush();
viBB = null;
}
if (gc instanceof AccelGraphicsConfig) {
AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc);
viBB = agc.createCompatibleVolatileImage(w, h,
TRANSLUCENT,
RT_PLAIN);
}
if (viBB == null) {
viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT);
}
viBB.validate(gc);
viRef = new WeakReference<VolatileImage>(viBB);
}
return clearImage(viBB);
}
@Override
public void flush() {
if (viRef != null) {
VolatileImage viBB = viRef.get();
if (viBB != null) {
viBB.flush();
viBB = null;
}
viRef.clear();
}
}
}
/**
* Optimized version of hw painter. Uses VolatileImages for the
* buffer, and uses an optimized path to pull the data from those into
* the layered window, bypassing Java heap-based image.
*/
private abstract static class VIOptWindowPainter extends VIWindowPainter {
protected VIOptWindowPainter(WWindowPeer peer) {
super(peer);
}
protected abstract boolean updateWindowAccel(long psdops, int w, int h);
@Override
protected boolean update(Image bb) {
if (bb instanceof DestSurfaceProvider) {
Surface s = ((DestSurfaceProvider)bb).getDestSurface();
if (s instanceof AccelSurface) {
final int w = bb.getWidth(null);
final int h = bb.getHeight(null);
final boolean arr[] = { false };
final AccelSurface as = (AccelSurface)s;
RenderQueue rq = as.getContext().getRenderQueue();
rq.lock();
try {
as.getContext().validateContext(as);
rq.flushAndInvokeNow(new Runnable() {
public void run() {
long psdops = as.getNativeOps();
arr[0] = updateWindowAccel(psdops, w, h);
}
});
} catch (InvalidPipeException e) {
// ignore, false will be returned
} finally {
rq.unlock();
}
return arr[0];
}
}
return super.update(bb);
}
}
private static class VIOptD3DWindowPainter extends VIOptWindowPainter {
protected VIOptD3DWindowPainter(WWindowPeer peer) {
super(peer);
}
@Override
protected boolean updateWindowAccel(long psdops, int w, int h) {
// note: this method is executed on the toolkit thread, no sync is
// necessary at the native level, and a pointer to peer can be used
return sun.java2d.d3d.D3DSurfaceData.
updateWindowAccelImpl(psdops, peer.getData(), w, h);
}
}
private static class VIOptWGLWindowPainter extends VIOptWindowPainter {
protected VIOptWGLWindowPainter(WWindowPeer peer) {
super(peer);
}
@Override
protected boolean updateWindowAccel(long psdops, int w, int h) {
// note: part of this method which deals with GDI will be on the
// toolkit thread
return sun.java2d.opengl.WGLSurfaceData.
updateWindowAccelImpl(psdops, peer, w, h);
}
}
}
/* /*
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,6 +28,7 @@ import java.awt.*; ...@@ -28,6 +28,7 @@ import java.awt.*;
import java.awt.peer.*; import java.awt.peer.*;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import sun.awt.AWTAccessor;
import sun.awt.ComponentAccessor; import sun.awt.ComponentAccessor;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.awt.Win32GraphicsDevice; import sun.awt.Win32GraphicsDevice;
...@@ -110,16 +111,20 @@ class WCanvasPeer extends WComponentPeer implements CanvasPeer { ...@@ -110,16 +111,20 @@ class WCanvasPeer extends WComponentPeer implements CanvasPeer {
} }
public void print(Graphics g) { public void print(Graphics g) {
Dimension d = ((Component)target).getSize(); if (!(target instanceof Window) ||
if (g instanceof Graphics2D || AWTAccessor.getWindowAccessor().isOpaque((Window)target))
g instanceof sun.awt.Graphics2Delegate) { {
// background color is setup correctly, so just use clearRect Dimension d = ((Component)target).getSize();
g.clearRect(0, 0, d.width, d.height); if (g instanceof Graphics2D ||
} else { g instanceof sun.awt.Graphics2Delegate) {
// emulate clearRect // background color is setup correctly, so just use clearRect
g.setColor(((Component)target).getBackground()); g.clearRect(0, 0, d.width, d.height);
g.fillRect(0, 0, d.width, d.height); } else {
g.setColor(((Component)target).getForeground()); // emulate clearRect
g.setColor(((Component)target).getBackground());
g.fillRect(0, 0, d.width, d.height);
g.setColor(((Component)target).getForeground());
}
} }
super.print(g); super.print(g);
} }
......
/* /*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -39,21 +39,22 @@ import java.awt.event.PaintEvent; ...@@ -39,21 +39,22 @@ import java.awt.event.PaintEvent;
import java.awt.event.InvocationEvent; import java.awt.event.InvocationEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import sun.awt.Win32GraphicsConfig; import sun.awt.Win32GraphicsConfig;
import sun.awt.Win32GraphicsEnvironment;
import sun.java2d.InvalidPipeException; import sun.java2d.InvalidPipeException;
import sun.java2d.SurfaceData; import sun.java2d.SurfaceData;
import sun.java2d.d3d.D3DScreenUpdateManager;
import static sun.java2d.d3d.D3DSurfaceData.*;
import sun.java2d.ScreenUpdateManager; import sun.java2d.ScreenUpdateManager;
import sun.java2d.d3d.D3DSurfaceData;
import sun.java2d.opengl.OGLSurfaceData; import sun.java2d.opengl.OGLSurfaceData;
import sun.java2d.pipe.Region;
import sun.awt.DisplayChangedListener; import sun.awt.DisplayChangedListener;
import sun.awt.PaintEventDispatcher; import sun.awt.PaintEventDispatcher;
import sun.awt.SunToolkit;
import sun.awt.event.IgnorePaintEvent; import sun.awt.event.IgnorePaintEvent;
import java.awt.dnd.DropTarget; import java.awt.dnd.DropTarget;
import java.awt.dnd.peer.DropTargetPeer; import java.awt.dnd.peer.DropTargetPeer;
import sun.awt.ComponentAccessor; import sun.awt.ComponentAccessor;
import java.util.logging.*; import java.util.logging.*;
...@@ -186,7 +187,7 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -186,7 +187,7 @@ public abstract class WComponentPeer extends WObjectPeer
cont.invalidate(); cont.invalidate();
cont.validate(); cont.validate();
if (surfaceData instanceof D3DWindowSurfaceData || if (surfaceData instanceof D3DSurfaceData.D3DWindowSurfaceData ||
surfaceData instanceof OGLSurfaceData) surfaceData instanceof OGLSurfaceData)
{ {
// When OGL or D3D is enabled, it is necessary to // When OGL or D3D is enabled, it is necessary to
...@@ -258,7 +259,7 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -258,7 +259,7 @@ public abstract class WComponentPeer extends WObjectPeer
int[] pix = createPrintedPixels(0, startY, totalW, h); int[] pix = createPrintedPixels(0, startY, totalW, h);
if (pix != null) { if (pix != null) {
BufferedImage bim = new BufferedImage(totalW, h, BufferedImage bim = new BufferedImage(totalW, h,
BufferedImage.TYPE_INT_RGB); BufferedImage.TYPE_INT_ARGB);
bim.setRGB(0, 0, totalW, h, pix, 0, totalW); bim.setRGB(0, 0, totalW, h, pix, 0, totalW);
g.drawImage(bim, 0, startY, null); g.drawImage(bim, 0, startY, null);
bim.flush(); bim.flush();
...@@ -895,25 +896,6 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -895,25 +896,6 @@ public abstract class WComponentPeer extends WObjectPeer
public void setBoundsOperation(int operation) { public void setBoundsOperation(int operation) {
} }
native void setRectangularShape(int lox, int loy, int hix, int hiy,
sun.java2d.pipe.Region region);
// REMIND: Temp workaround for issues with using HW acceleration
// in the browser on Vista when DWM is enabled.
// @return true if the toplevel container is not an EmbeddedFrame or
// if this EmbeddedFrame is acceleration capable, false otherwise
private static final boolean isContainingTopLevelAccelCapable(Component c) {
while (c != null && !(c instanceof WEmbeddedFrame)) {
c = c.getParent();
}
if (c == null) {
return true;
}
return ((WEmbeddedFramePeer)c.getPeer()).isAccelCapable();
}
/** /**
* Returns whether this component is capable of being hw accelerated. * Returns whether this component is capable of being hw accelerated.
* More specifically, whether rendering to this component or a * More specifically, whether rendering to this component or a
...@@ -928,28 +910,36 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -928,28 +910,36 @@ public abstract class WComponentPeer extends WObjectPeer
* @see com.sun.awt.AWTUtilities.Translucency#TRANSLUCENT * @see com.sun.awt.AWTUtilities.Translucency#TRANSLUCENT
*/ */
public boolean isAccelCapable() { public boolean isAccelCapable() {
// REMIND: Temp workaround for issues with using HW acceleration
// in the browser on Vista when DWM is enabled
if (!isContainingTopLevelAccelCapable((Component)target)) {
return false;
}
// REMIND: translucent windows support-related
/*
boolean isTranslucent = boolean isTranslucent =
SunToolkit.isContainingTopLevelTranslucent((Component)target); SunToolkit.isContainingTopLevelTranslucent((Component)target);
// D3D/OGL and translucent windows interacted poorly in Windows XP; // D3D/OGL and translucent windows interacted poorly in Windows XP;
// these problems are no longer present in Vista // these problems are no longer present in Vista
return !isTranslucent || Win32GraphicsEnvironment.isVistaOS(); return !isTranslucent || Win32GraphicsEnvironment.isVistaOS();
*/ }
return true;
native void setRectangularShape(int lox, int loy, int hix, int hiy,
Region region);
// REMIND: Temp workaround for issues with using HW acceleration
// in the browser on Vista when DWM is enabled.
// @return true if the toplevel container is not an EmbeddedFrame or
// if this EmbeddedFrame is acceleration capable, false otherwise
private static final boolean isContainingTopLevelAccelCapable(Component c) {
while (c != null && !(c instanceof WEmbeddedFrame)) {
c = c.getParent();
}
if (c == null) {
return true;
}
return ((WEmbeddedFramePeer)c.getPeer()).isAccelCapable();
} }
/** /**
* Applies the shape to the native component window. * Applies the shape to the native component window.
* @since 1.7 * @since 1.7
*/ */
public void applyShape(sun.java2d.pipe.Region shape) { public void applyShape(Region shape) {
if (shapeLog.isLoggable(Level.FINER)) { if (shapeLog.isLoggable(Level.FINER)) {
shapeLog.finer( shapeLog.finer(
"*** INFO: Setting shape: PEER: " + this "*** INFO: Setting shape: PEER: " + this
......
/* /*
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -244,4 +244,10 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { ...@@ -244,4 +244,10 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
public boolean isRestackSupported() { public boolean isRestackSupported() {
return false; return false;
} }
// The effects are not supported for system dialogs.
public void applyShape(sun.java2d.pipe.Region shape) {}
public void setOpacity(float opacity) {}
public void setOpaque(boolean isOpaque) {}
public void updateWindow(java.awt.image.BufferedImage backBuffer) {}
} }
/* /*
* Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -156,4 +156,10 @@ public class WPrintDialogPeer extends WWindowPeer implements DialogPeer { ...@@ -156,4 +156,10 @@ public class WPrintDialogPeer extends WWindowPeer implements DialogPeer {
public boolean isRestackSupported() { public boolean isRestackSupported() {
return false; return false;
} }
// The effects are not supported for system dialogs.
public void applyShape(sun.java2d.pipe.Region shape) {}
public void setOpacity(float opacity) {}
public void setOpaque(boolean isOpaque) {}
public void updateWindow(java.awt.image.BufferedImage backBuffer) {}
} }
/* /*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -975,4 +975,34 @@ public class WToolkit extends SunToolkit implements Runnable { ...@@ -975,4 +975,34 @@ public class WToolkit extends SunToolkit implements Runnable {
public boolean areExtraMouseButtonsEnabled() throws HeadlessException { public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
return areExtraMouseButtonsEnabled; return areExtraMouseButtonsEnabled;
} }
@Override
public boolean isWindowOpacitySupported() {
// supported in Win2K and later
return true;
}
@Override
public boolean isWindowShapingSupported() {
return true;
}
@Override
public boolean isWindowTranslucencySupported() {
// supported in Win2K and later
return true;
}
@Override
public boolean isTranslucencyCapable(GraphicsConfiguration gc) {
//XXX: worth checking if 8-bit? Anyway, it doesn't hurt.
return true;
}
// On MS Windows one must use the peer.updateWindow() to implement
// non-opaque windows.
@Override
public boolean needUpdateWindow() {
return true;
}
} }
/* /*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,17 +31,15 @@ import java.awt.peer.*; ...@@ -31,17 +31,15 @@ import java.awt.peer.*;
import java.beans.*; import java.beans.*;
import java.lang.ref.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.security.*;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import java.util.logging.*; import java.util.logging.*;
import sun.awt.*; import sun.awt.*;
import sun.awt.image.*;
import sun.java2d.pipe.Region;
public class WWindowPeer extends WPanelPeer implements WindowPeer { public class WWindowPeer extends WPanelPeer implements WindowPeer {
...@@ -52,6 +50,10 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer { ...@@ -52,6 +50,10 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
// extends WWindowPeer, not WDialogPeer // extends WWindowPeer, not WDialogPeer
private WWindowPeer modalBlocker = null; private WWindowPeer modalBlocker = null;
private boolean isOpaque;
private volatile TranslucentWindowPainter painter;
/* /*
* A key used for storing a list of active windows in AppContext. The value * A key used for storing a list of active windows in AppContext. The value
* is a list of windows, sorted by the time of activation: later a window is * is a list of windows, sorted by the time of activation: later a window is
...@@ -91,9 +93,18 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer { ...@@ -91,9 +93,18 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
l.remove(this); l.remove(this);
} }
} }
// Remove ourself from the Map of DisplayChangeListeners // Remove ourself from the Map of DisplayChangeListeners
GraphicsConfiguration gc = getGraphicsConfiguration(); GraphicsConfiguration gc = getGraphicsConfiguration();
((Win32GraphicsDevice)gc.getDevice()).removeDisplayChangedListener(this); ((Win32GraphicsDevice)gc.getDevice()).removeDisplayChangedListener(this);
TranslucentWindowPainter currentPainter = painter;
if (currentPainter != null) {
currentPainter.flush();
// don't set the current one to null here; reduces the chances of
// MT issues (like NPEs)
}
super.disposeImpl(); super.disposeImpl();
} }
...@@ -158,6 +169,10 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer { ...@@ -158,6 +169,10 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
initActiveWindowsTracking((Window)target); initActiveWindowsTracking((Window)target);
updateIconImages(); updateIconImages();
updateShape();
updateOpacity();
updateOpaque();
} }
native void createAwtWindow(WComponentPeer parent); native void createAwtWindow(WComponentPeer parent);
...@@ -191,6 +206,8 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer { ...@@ -191,6 +206,8 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
if (((Window)target).isAlwaysOnTopSupported() && alwaysOnTop) { if (((Window)target).isAlwaysOnTopSupported() && alwaysOnTop) {
setAlwaysOnTop(alwaysOnTop); setAlwaysOnTop(alwaysOnTop);
} }
updateWindow(null);
} }
// Synchronize the insets members (here & in helper) with actual window // Synchronize the insets members (here & in helper) with actual window
...@@ -273,6 +290,31 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer { ...@@ -273,6 +290,31 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
} }
} }
private void updateShape() {
// Shape shape = ((Window)target).getShape();
Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
if (shape != null) {
applyShape(Region.getInstance(shape, null));
}
}
private void updateOpacity() {
// float opacity = ((Window)target).getOpacity();
float opacity = AWTAccessor.getWindowAccessor().getOpacity((Window)target);
if (opacity < 1.0f) {
setOpacity(opacity);
}
}
private void updateOpaque() {
this.isOpaque = true;
// boolean opaque = ((Window)target).isOpaque();
boolean opaque = AWTAccessor.getWindowAccessor().isOpaque((Window)target);
if (!opaque) {
setOpaque(opaque);
}
}
native void setMinSize(int width, int height); native void setMinSize(int width, int height);
/* /*
...@@ -525,6 +567,135 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer { ...@@ -525,6 +567,135 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
} }
@Override
public void print(Graphics g) {
// We assume we print the whole frame,
// so we expect no clip was set previously
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();
}
}
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);
updateWindow(null);
}
private native void setOpaqueImpl(boolean isOpaque);
public void setOpaque(boolean isOpaque) {
Window target = (Window)getTarget();
SunToolkit sunToolkit = (SunToolkit)target.getToolkit();
if (!sunToolkit.isWindowTranslucencySupported() ||
!sunToolkit.isTranslucencyCapable(target.getGraphicsConfiguration()))
{
return;
}
boolean opaqueChanged = this.isOpaque != isOpaque;
boolean isVistaOS = Win32GraphicsEnvironment.isVistaOS();
if (opaqueChanged && !isVistaOS){
// non-Vista OS: only replace the surface data if the opacity
// status changed (see WComponentPeer.isAccelCapable() for more)
replaceSurfaceDataRecursively(target);
}
this.isOpaque = isOpaque;
setOpaqueImpl(isOpaque);
if (opaqueChanged) {
if (isOpaque) {
TranslucentWindowPainter currentPainter = painter;
if (currentPainter != null) {
currentPainter.flush();
painter = null;
}
} else {
painter = TranslucentWindowPainter.createInstance(this);
}
}
if (opaqueChanged && isVistaOS) {
// On Vista: setting the window non-opaque makes the window look
// rectangular, though still catching the mouse clicks within
// its shape only. To restore the correct visual appearance
// of the window (i.e. w/ the correct shape) we have to reset
// the shape.
Shape shape = AWTAccessor.getWindowAccessor().getShape(target);
if (shape != null) {
AWTAccessor.getWindowAccessor().setShape(target, shape);
}
}
updateWindow(null);
}
public native void updateWindowImpl(int[] data, int width, int height);
public void updateWindow(BufferedImage backBuffer) {
if (isOpaque) {
return;
}
TranslucentWindowPainter currentPainter = painter;
if (currentPainter != null) {
currentPainter.updateWindow(backBuffer);
} else if (log.isLoggable(Level.FINER)) {
log.log(Level.FINER,
"Translucent window painter is null in updateWindow");
}
}
/**
* Paints the Applet Warning into the passed Graphics2D. This method is
* called by the TranslucentWindowPainter before updating the layered
* window.
*
* @param g Graphics context to paint the warning to
* @param w the width of the area
* @param h the height of the area
* @see TranslucentWindowPainter
*/
public void paintAppletWarning(Graphics2D g, int w, int h) {
// REMIND: the applet warning needs to be painted here
}
/* /*
* The method maps the list of the active windows to the window's AppContext, * The method maps the list of the active windows to the window's AppContext,
* then the method registers ActiveWindowListener, GuiDisposedListener listeners; * then the method registers ActiveWindowListener, GuiDisposedListener listeners;
......
/* /*
* Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2004-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -72,9 +72,8 @@ public abstract class WGLSurfaceData extends OGLSurfaceData { ...@@ -72,9 +72,8 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
// the OGL pipeline can render directly to the screen and interfere // the OGL pipeline can render directly to the screen and interfere
// with layered windows, which is why we don't allow accelerated // with layered windows, which is why we don't allow accelerated
// surfaces in this case // surfaces in this case
if (!peer.isAccelCapable()) if (!peer.isAccelCapable() ||
// REMIND: commented until toplevel translucency is implemented !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
// || !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
{ {
return null; return null;
} }
...@@ -93,9 +92,8 @@ public abstract class WGLSurfaceData extends OGLSurfaceData { ...@@ -93,9 +92,8 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
// the OGL pipeline can render directly to the screen and interfere // the OGL pipeline can render directly to the screen and interfere
// with layered windows, which is why we don't allow accelerated // with layered windows, which is why we don't allow accelerated
// surfaces in this case // surfaces in this case
if (!peer.isAccelCapable()) if (!peer.isAccelCapable() ||
// REMIND: commented until toplevel translucency is implemented !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
// || !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
{ {
return null; return null;
} }
......
/* /*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -43,5 +43,15 @@ typedef RECT RECT_T; ...@@ -43,5 +43,15 @@ typedef RECT RECT_T;
#define RECT_INC_HEIGHT(r) (r).bottom++ #define RECT_INC_HEIGHT(r) (r).bottom++
#if defined(__cplusplus)
extern "C" {
#endif
int BitmapToYXBandedRectangles(int bitsPerPixel, int width, int height,
unsigned char * buf, RECT_T * outBuf);
#if defined(__cplusplus)
}
#endif
#endif // _AWT_RECT_H #endif // _AWT_RECT_H
/* /*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -613,17 +613,15 @@ JNICALL Java_sun_java2d_d3d_D3DSurfaceData_updateWindowAccelImpl ...@@ -613,17 +613,15 @@ JNICALL Java_sun_java2d_d3d_D3DSurfaceData_updateWindowAccelImpl
res = pTmpSurface->LockRect(&lockedRect, NULL, D3DLOCK_NOSYSLOCK); res = pTmpSurface->LockRect(&lockedRect, NULL, D3DLOCK_NOSYSLOCK);
if (SUCCEEDED(res)) { if (SUCCEEDED(res)) {
// REMIND: commented until translucent window support is integrated hBitmap =
// hBitmap = BitmapUtil::CreateBitmapFromARGBPre(w, h,
// BitmapUtil::CreateBitmapFromARGBPre(w, h, lockedRect.Pitch,
// lockedRect.Pitch, (int*)lockedRect.pBits);
// (int*)lockedRect.pBits);
pTmpSurface->UnlockRect(); pTmpSurface->UnlockRect();
} }
RETURN_STATUS_IF_NULL(hBitmap, JNI_FALSE); RETURN_STATUS_IF_NULL(hBitmap, JNI_FALSE);
// REMIND: commented until translucent window support is integrated window->UpdateWindow(env, NULL, w, h, hBitmap);
// window->UpdateWindow(env, NULL, w, h, hBitmap);
// hBitmap is released in UpdateWindow // hBitmap is released in UpdateWindow
......
/* /*
* Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2004-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -625,17 +625,15 @@ JNIEXPORT jboolean JNICALL ...@@ -625,17 +625,15 @@ JNIEXPORT jboolean JNICALL
j2d_glPixelStorei(GL_PACK_ALIGNMENT, 4); j2d_glPixelStorei(GL_PACK_ALIGNMENT, 4);
// the pixels read from the surface are already premultiplied // the pixels read from the surface are already premultiplied
// REMIND: commented until translucent window support is integrated hBitmap = BitmapUtil_CreateBitmapFromARGBPre(w, h, scanStride,
// hBitmap = BitmapUtil_CreateBitmapFromARGBPre(w, h, scanStride, (int*)pDst);
// (int*)pDst);
free(pDst); free(pDst);
if (hBitmap == NULL) { if (hBitmap == NULL) {
return JNI_FALSE; return JNI_FALSE;
} }
// REMIND: commented until translucent window support is integrated AwtWindow_UpdateWindow(env, peer, w, h, hBitmap);
// AwtWindow_UpdateWindow(env, peer, w, h, hBitmap);
// hBitmap is released in UpdateWindow // hBitmap is released in UpdateWindow
......
/* /*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2006-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,9 +28,14 @@ ...@@ -28,9 +28,14 @@
#include <windowsx.h> #include <windowsx.h>
#include <zmouse.h> #include <zmouse.h>
#include "GraphicsPrimitiveMgr.h"
#include "awt.h" #include "awt.h"
#include "awt_BitmapUtil.h" #include "awt_BitmapUtil.h"
// Platform-dependent RECT_[EQ | SET | INC_HEIGHT] macros
#include "utility/rect.h"
HBITMAP BitmapUtil::CreateTransparencyMaskFromARGB(int width, int height, int* imageData) HBITMAP BitmapUtil::CreateTransparencyMaskFromARGB(int width, int height, int* imageData)
{ {
//Scan lines should be aligned to word boundary //Scan lines should be aligned to word boundary
...@@ -148,3 +153,222 @@ HBITMAP BitmapUtil::CreateV4BitmapFromARGB(int width, int height, int* imageData ...@@ -148,3 +153,222 @@ HBITMAP BitmapUtil::CreateV4BitmapFromARGB(int width, int height, int* imageData
::GdiFlush(); ::GdiFlush();
return hBitmap; return hBitmap;
} }
/*
* Creates 32-bit premultiplied ARGB bitmap from specified ARGBPre data.
* This function may not work on OS prior to Win95.
* See MSDN articles for CreateDIBitmap, BITMAPINFOHEADER,
* BITMAPV4HEADER, BITMAPV5HEADER for additional info.
*/
HBITMAP BitmapUtil::CreateBitmapFromARGBPre(int width, int height,
int srcStride,
int* imageData)
{
BITMAPINFOHEADER bmi;
void *bitmapBits = NULL;
ZeroMemory(&bmi, sizeof(bmi));
bmi.biSize = sizeof(bmi);
bmi.biWidth = width;
bmi.biHeight = -height;
bmi.biPlanes = 1;
bmi.biBitCount = 32;
bmi.biCompression = BI_RGB;
HBITMAP hBitmap =
::CreateDIBSection(NULL, (BITMAPINFO *) & bmi, DIB_RGB_COLORS,
&bitmapBits, NULL, 0);
if (!bitmapBits) {
return NULL;
}
int dstStride = width * 4;
if (srcStride == dstStride) {
memcpy(bitmapBits, (void*)imageData, srcStride * height);
} else if (height > 0) {
void *pSrcPixels = (void*)imageData;
void *pDstPixels = bitmapBits;
do {
memcpy(pDstPixels, pSrcPixels, dstStride);
pSrcPixels = PtrAddBytes(pSrcPixels, srcStride);
pDstPixels = PtrAddBytes(pDstPixels, dstStride);
} while (--height > 0);
}
return hBitmap;
}
extern "C" {
/**
* This method is called from the WGL pipeline when it needs to create a bitmap
* needed to update the layered window.
*/
HBITMAP BitmapUtil_CreateBitmapFromARGBPre(int width, int height,
int srcStride,
int* imageData)
{
return BitmapUtil::CreateBitmapFromARGBPre(width, height,
srcStride, imageData);
}
} /* extern "C" */
/**
* Transforms the given bitmap into an HRGN representing the transparency
* of the bitmap. The bitmap MUST BE 32bpp. Alpha value == 0 is considered
* transparent, alpha > 0 - opaque.
*/
HRGN BitmapUtil::BitmapToRgn(HBITMAP hBitmap)
{
HDC hdc = ::CreateCompatibleDC(NULL);
::SelectObject(hdc, hBitmap);
BITMAPINFOEX bi;
::ZeroMemory(&bi, sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BOOL r = ::GetDIBits(hdc, hBitmap, 0, 0, NULL,
reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS);
if (!r || bi.bmiHeader.biBitCount != 32)
{
::DeleteDC(hdc);
return NULL;
}
UINT width = bi.bmiHeader.biWidth;
UINT height = abs(bi.bmiHeader.biHeight);
BYTE * buf = (BYTE*)safe_Malloc(bi.bmiHeader.biSizeImage);
bi.bmiHeader.biHeight = -height;
::GetDIBits(hdc, hBitmap, 0, height, buf,
reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS);
/* reserving memory for the worst case */
RGNDATA * pRgnData = (RGNDATA *) safe_Malloc(sizeof(RGNDATAHEADER) +
sizeof(RECT) * (width / 2 + 1) * height);
RGNDATAHEADER * pRgnHdr = (RGNDATAHEADER *) pRgnData;
pRgnHdr->dwSize = sizeof(RGNDATAHEADER);
pRgnHdr->iType = RDH_RECTANGLES;
pRgnHdr->nRgnSize = 0;
pRgnHdr->rcBound.top = 0;
pRgnHdr->rcBound.left = 0;
pRgnHdr->rcBound.bottom = height;
pRgnHdr->rcBound.right = width;
pRgnHdr->nCount = BitmapToYXBandedRectangles(32, width, height, buf,
(RECT_T *) (((BYTE *) pRgnData) + sizeof(RGNDATAHEADER)));
HRGN rgn = ::ExtCreateRegion(NULL,
sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount,
pRgnData);
free(pRgnData);
::DeleteDC(hdc);
free(buf);
return rgn;
}
/**
* Makes a copy of the given bitmap. Blends every pixel of the source
* with the given blendColor and alpha. If alpha == 0, the function
* simply makes a plain copy of the source without any blending.
*/
HBITMAP BitmapUtil::BlendCopy(HBITMAP hSrcBitmap, COLORREF blendColor,
BYTE alpha)
{
HDC hdc = ::CreateCompatibleDC(NULL);
HBITMAP oldBitmap = (HBITMAP)::SelectObject(hdc, hSrcBitmap);
BITMAPINFOEX bi;
::ZeroMemory(&bi, sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BOOL r = ::GetDIBits(hdc, hSrcBitmap, 0, 0, NULL,
reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS);
if (!r || bi.bmiHeader.biBitCount != 32)
{
::DeleteDC(hdc);
return NULL;
}
UINT width = bi.bmiHeader.biWidth;
UINT height = abs(bi.bmiHeader.biHeight);
BYTE * buf = (BYTE*)safe_Malloc(bi.bmiHeader.biSizeImage);
bi.bmiHeader.biHeight = -height;
::GetDIBits(hdc, hSrcBitmap, 0, height, buf,
reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS);
UINT widthBytes = width * bi.bmiHeader.biBitCount / 8;
UINT alignedWidth = (((widthBytes - 1) / 4) + 1) * 4;
UINT i, j;
for (j = 0; j < height; j++) {
BYTE *pSrc = (BYTE *) buf + j * alignedWidth;
for (i = 0; i < width; i++, pSrc += 4) {
// Note: if the current alpha is zero, the other three color
// components may (theoretically) contain some uninitialized
// data. The developer does not expect to display them,
// hence we handle this situation differently.
if (pSrc[3] == 0) {
pSrc[0] = GetBValue(blendColor) * alpha / 255;
pSrc[1] = GetGValue(blendColor) * alpha / 255;
pSrc[2] = GetRValue(blendColor) * alpha / 255;
pSrc[3] = alpha;
} else {
pSrc[0] = (GetBValue(blendColor) * alpha / 255) +
(pSrc[0] * (255 - alpha) / 255);
pSrc[1] = (GetGValue(blendColor) * alpha / 255) +
(pSrc[1] * (255 - alpha) / 255);
pSrc[2] = (GetRValue(blendColor) * alpha / 255) +
(pSrc[2] * (255 - alpha) / 255);
pSrc[3] = (alpha * alpha / 255) +
(pSrc[3] * (255 - alpha) / 255);
}
}
}
HBITMAP hDstBitmap = ::CreateDIBitmap(hdc,
reinterpret_cast<BITMAPINFOHEADER*>(&bi),
CBM_INIT,
buf,
reinterpret_cast<BITMAPINFO*>(&bi),
DIB_RGB_COLORS
);
::SelectObject(hdc, oldBitmap);
::DeleteDC(hdc);
free(buf);
return hDstBitmap;
}
/**
* Creates a 32 bit ARGB bitmap. Returns the bitmap handle. The *bitmapBits
* contains the pointer to the bitmap data or NULL if an error occured.
*/
HBITMAP BitmapUtil::CreateARGBBitmap(int width, int height, void ** bitmapBitsPtr)
{
BITMAPINFOHEADER bmi;
::ZeroMemory(&bmi, sizeof(bmi));
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biWidth = width;
bmi.biHeight = -height;
bmi.biPlanes = 1;
bmi.biBitCount = 32;
bmi.biCompression = BI_RGB;
return ::CreateDIBSection(NULL, (BITMAPINFO *) & bmi, DIB_RGB_COLORS,
bitmapBitsPtr, NULL, 0);
}
/* /*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2006-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -45,6 +45,32 @@ public: ...@@ -45,6 +45,32 @@ public:
*/ */
static HBITMAP CreateV4BitmapFromARGB(int width, int height, int* imageData); static HBITMAP CreateV4BitmapFromARGB(int width, int height, int* imageData);
/**
* Creates 32-bit premultiplied ARGB V4 Bitmap (Win95-compatible) from
* specified ARGB Pre input data.
*/
static HBITMAP CreateBitmapFromARGBPre(int width, int height,
int srcStride,
int* imageData);
/**
* Transforms the given bitmap into an HRGN representing the transparency
* of the bitmap.
*/
static HRGN BitmapToRgn(HBITMAP hBitmap);
/**
* Makes a copy of the given bitmap. Blends every pixel of the source
* with the given blendColor and alpha. If alpha == 0, the function
* simply makes a plain copy of the source without any blending.
*/
static HBITMAP BlendCopy(HBITMAP hSrcBitmap, COLORREF blendColor, BYTE alpha);
/**
* Creates a 32 bit ARGB bitmap. Returns the bitmap handle.
* The pointer to the bitmap data is stored into bitmapBitsPtr.
*/
static HBITMAP CreateARGBBitmap(int width, int height, void ** bitmapBitsPtr);
}; };
#endif #endif
/* /*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -199,9 +199,6 @@ BOOL AwtComponent::sm_rtl = PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC || ...@@ -199,9 +199,6 @@ BOOL AwtComponent::sm_rtl = PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC ||
BOOL AwtComponent::sm_rtlReadingOrder = BOOL AwtComponent::sm_rtlReadingOrder =
PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC; PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC;
UINT AwtComponent::sm_95WheelMessage = WM_NULL;
UINT AwtComponent::sm_95WheelSupport = WM_NULL;
HWND AwtComponent::sm_cursorOn; HWND AwtComponent::sm_cursorOn;
BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE; BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE;
...@@ -4562,6 +4559,25 @@ HDC AwtComponent::GetDCFromComponent() ...@@ -4562,6 +4559,25 @@ HDC AwtComponent::GetDCFromComponent()
return hdc; return hdc;
} }
void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size)
{
RECT eraseR = { 0, 0, size.cx, size.cy };
VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush()));
}
void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
{
if (bitmapBits) {
DWORD* dest = (DWORD*)bitmapBits;
//XXX: might be optimized to use one loop (cy*cx -> 0).
for (int i = 0; i < size.cy; i++ ) {
for (int j = 0; j < size.cx; j++ ) {
((BYTE*)(dest++))[3] = alpha;
}
}
}
}
jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) { jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
...@@ -6107,15 +6123,12 @@ void AwtComponent::_SetRectangularShape(void *param) ...@@ -6107,15 +6123,12 @@ void AwtComponent::_SetRectangularShape(void *param)
AwtComponent *c = NULL; AwtComponent *c = NULL;
PDATA pData; PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret); JNI_CHECK_PEER_GOTO(self, ret);
c = (AwtComponent *)pData; c = (AwtComponent *)pData;
if (::IsWindow(c->GetHWnd())) if (::IsWindow(c->GetHWnd())) {
{
HRGN hRgn = NULL; HRGN hRgn = NULL;
if (region || x1 || x2 || y1 || y2) { if (region || x1 || x2 || y1 || y2) {
// If all the params are zeros, the shape must be simply reset. // If all the params are zeros, the shape must be simply reset.
// Otherwise, convert it into a region. // Otherwise, convert it into a region.
......
/* /*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -434,9 +434,6 @@ public: ...@@ -434,9 +434,6 @@ public:
/* Functions for MouseWheel support on Windows95 /* Functions for MouseWheel support on Windows95
* These should only be called if running on 95 * These should only be called if running on 95
*/ */
static void Wheel95Init();
INLINE static UINT Wheel95GetMsg() {return sm_95WheelMessage;}
static UINT Wheel95GetScrLines();
/* Determines whether the component is obscured by another window */ /* Determines whether the component is obscured by another window */
// Called on Toolkit thread // Called on Toolkit thread
...@@ -715,9 +712,9 @@ protected: ...@@ -715,9 +712,9 @@ protected:
virtual void SetDragCapture(UINT flags); virtual void SetDragCapture(UINT flags);
virtual void ReleaseDragCapture(UINT flags); virtual void ReleaseDragCapture(UINT flags);
// 95 support for mouse wheel //These functions are overridden in AwtWindow to handle non-opaque windows.
static UINT sm_95WheelMessage; virtual void FillBackground(HDC hMemoryDC, SIZE &size);
static UINT sm_95WheelSupport; virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
private: private:
/* A bitmask keeps the button's numbers as MK_LBUTTON, MK_MBUTTON, MK_RBUTTON /* A bitmask keeps the button's numbers as MK_LBUTTON, MK_MBUTTON, MK_RBUTTON
......
/* /*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include "awt.h" #include "awt.h"
#include <jlong.h>
#include "awt_Component.h" #include "awt_Component.h"
#include "awt_Container.h" #include "awt_Container.h"
#include "awt_Frame.h" #include "awt_Frame.h"
...@@ -88,7 +90,6 @@ struct ReshapeFrameStruct { ...@@ -88,7 +90,6 @@ struct ReshapeFrameStruct {
jint x, y; jint x, y;
jint w, h; jint w, h;
}; };
// struct for _SetIconImagesData // struct for _SetIconImagesData
struct SetIconImagesDataStruct { struct SetIconImagesDataStruct {
jobject window; jobject window;
...@@ -97,7 +98,6 @@ struct SetIconImagesDataStruct { ...@@ -97,7 +98,6 @@ struct SetIconImagesDataStruct {
jintArray smallIconRaster; jintArray smallIconRaster;
jint smw, smh; jint smw, smh;
}; };
// struct for _SetMinSize() method // struct for _SetMinSize() method
// and other methods setting sizes // and other methods setting sizes
struct SizeStruct { struct SizeStruct {
...@@ -114,6 +114,24 @@ struct ModalDisableStruct { ...@@ -114,6 +114,24 @@ struct ModalDisableStruct {
jobject window; jobject window;
jlong blockerHWnd; jlong blockerHWnd;
}; };
// struct for _SetOpacity() method
struct OpacityStruct {
jobject window;
jint iOpacity;
};
// struct for _SetOpaque() method
struct OpaqueStruct {
jobject window;
jboolean isOpaque;
};
// struct for _UpdateWindow() method
struct UpdateWindowStruct {
jobject window;
jintArray data;
HBITMAP hBitmap;
jint width, height;
};
/************************************************************************ /************************************************************************
* AwtWindow fields * AwtWindow fields
*/ */
...@@ -162,6 +180,11 @@ AwtWindow::AwtWindow() { ...@@ -162,6 +180,11 @@ AwtWindow::AwtWindow() {
::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtWindow::CBTFilter, ::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtWindow::CBTFilter,
0, AwtToolkit::MainThread()); 0, AwtToolkit::MainThread());
} }
m_opaque = TRUE;
m_opacity = 0xff;
::InitializeCriticalSection(&contentBitmapCS);
} }
AwtWindow::~AwtWindow() AwtWindow::~AwtWindow()
...@@ -1839,6 +1862,216 @@ void AwtWindow::DoUpdateIcon() ...@@ -1839,6 +1862,216 @@ void AwtWindow::DoUpdateIcon()
//Does nothing for windows, is overriden for frames and dialogs //Does nothing for windows, is overriden for frames and dialogs
} }
void AwtWindow::RedrawWindow()
{
if (isOpaque()) {
::RedrawWindow(GetHWnd(), NULL, NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
} else {
::EnterCriticalSection(&contentBitmapCS);
if (hContentBitmap != NULL) {
UpdateWindowImpl(contentWidth, contentHeight, hContentBitmap);
}
::LeaveCriticalSection(&contentBitmapCS);
}
}
void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque)
{
BYTE old_opacity = getOpacity();
BOOL old_opaque = isOpaque();
if (opacity == old_opacity && opaque == old_opaque) {
return;
}
setOpacity(opacity);
setOpaque(opaque);
HWND hwnd = GetHWnd();
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
if (opaque != old_opaque) {
::EnterCriticalSection(&contentBitmapCS);
if (hContentBitmap != NULL) {
::DeleteObject(hContentBitmap);
hContentBitmap = NULL;
}
::LeaveCriticalSection(&contentBitmapCS);
}
if (opaque && opacity == 0xff) {
// Turn off all the effects
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style & ~WS_EX_LAYERED);
// Ask the window to repaint itself and all the children
RedrawWindow();
} else {
// We're going to enable some effects
if (!(ex_style & WS_EX_LAYERED)) {
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style | WS_EX_LAYERED);
} else {
if ((opaque && opacity < 0xff) ^ (old_opaque && old_opacity < 0xff)) {
// _One_ of the modes uses the SetLayeredWindowAttributes.
// Need to reset the style in this case.
// If both modes are simple (i.e. just changing the opacity level),
// no need to reset the style.
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style & ~WS_EX_LAYERED);
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style | WS_EX_LAYERED);
}
}
if (opaque) {
// Simple opacity mode
::SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), opacity, LWA_ALPHA);
}
}
}
static HBITMAP CreateBitmapFromRaster(JNIEnv* env, jintArray raster, jint w, jint h)
{
HBITMAP image = NULL;
if (raster != NULL) {
int* rasterBuffer = NULL;
try {
rasterBuffer = (int *)env->GetPrimitiveArrayCritical(raster, 0);
JNI_CHECK_NULL_GOTO(rasterBuffer, "raster data", done);
image = BitmapUtil::CreateBitmapFromARGBPre(w, h, w*4, rasterBuffer);
} catch (...) {
if (rasterBuffer != NULL) {
env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
}
throw;
}
if (rasterBuffer != NULL) {
env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
}
}
done:
return image;
}
void AwtWindow::UpdateWindowImpl(int width, int height, HBITMAP hBitmap)
{
if (isOpaque()) {
return;
}
HWND hWnd = GetHWnd();
HDC hdcDst = ::GetDC(NULL);
HDC hdcSrc = ::CreateCompatibleDC(NULL);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdcSrc, hBitmap);
//XXX: this code doesn't paint the children (say, the java.awt.Button)!
//So, if we ever want to support HWs here, we need to repaint them
//in some other way...
//::SendMessage(hWnd, WM_PRINT, (WPARAM)hdcSrc, /*PRF_CHECKVISIBLE |*/
// PRF_CHILDREN /*| PRF_CLIENT | PRF_NONCLIENT*/);
POINT ptSrc;
ptSrc.x = ptSrc.y = 0;
RECT rect;
POINT ptDst;
SIZE size;
::GetWindowRect(hWnd, &rect);
ptDst.x = rect.left;
ptDst.y = rect.top;
size.cx = width;
size.cy = height;
BLENDFUNCTION bf;
bf.SourceConstantAlpha = getOpacity();
bf.AlphaFormat = AC_SRC_ALPHA;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
::UpdateLayeredWindow(hWnd, hdcDst, &ptDst, &size, hdcSrc, &ptSrc,
RGB(0, 0, 0), &bf, ULW_ALPHA);
::ReleaseDC(NULL, hdcDst);
::SelectObject(hdcSrc, hOldBitmap);
::DeleteDC(hdcSrc);
}
void AwtWindow::UpdateWindow(JNIEnv* env, jintArray data, int width, int height,
HBITMAP hNewBitmap)
{
if (isOpaque()) {
return;
}
HBITMAP hBitmap;
if (hNewBitmap == NULL) {
if (data == NULL) {
return;
}
hBitmap = CreateBitmapFromRaster(env, data, width, height);
if (hBitmap == NULL) {
return;
}
} else {
hBitmap = hNewBitmap;
}
::EnterCriticalSection(&contentBitmapCS);
if (hContentBitmap != NULL) {
::DeleteObject(hContentBitmap);
}
hContentBitmap = hBitmap;
contentWidth = width;
contentHeight = height;
UpdateWindowImpl(width, height, hBitmap);
::LeaveCriticalSection(&contentBitmapCS);
}
void AwtWindow::FillBackground(HDC hMemoryDC, SIZE &size)
{
if (isOpaque()) {
AwtCanvas::FillBackground(hMemoryDC, size);
}
}
void AwtWindow::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
{
if (isOpaque()) {
AwtCanvas::FillAlpha(bitmapBits, size, alpha);
}
}
/*
* Fixed 6353381: it's improved fix for 4792958
* which was backed-out to avoid 5059656
*/
BOOL AwtWindow::HasValidRect()
{
RECT inside;
RECT outside;
if (::IsIconic(GetHWnd())) {
return FALSE;
}
::GetClientRect(GetHWnd(), &inside);
::GetWindowRect(GetHWnd(), &outside);
BOOL isZeroClientArea = (inside.right == 0 && inside.bottom == 0);
BOOL isInvalidLocation = ((outside.left == -32000 && outside.top == -32000) || // Win2k && WinXP
(outside.left == 32000 && outside.top == 32000) || // Win95 && Win98
(outside.left == 3000 && outside.top == 3000)); // Win95 && Win98
// the bounds correspond to iconic state
if (isZeroClientArea && isInvalidLocation)
{
return FALSE;
}
return TRUE;
}
void AwtWindow::_SetIconImagesData(void * param) void AwtWindow::_SetIconImagesData(void * param)
{ {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
...@@ -2009,36 +2242,68 @@ void AwtWindow::_ModalEnable(void *param) ...@@ -2009,36 +2242,68 @@ void AwtWindow::_ModalEnable(void *param)
env->DeleteGlobalRef(self); env->DeleteGlobalRef(self);
} }
/* void AwtWindow::_SetOpacity(void* param)
* Fixed 6353381: it's improved fix for 4792958
* which was backed-out to avoid 5059656
*/
BOOL AwtWindow::HasValidRect()
{ {
RECT inside; JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
RECT outside;
if (::IsIconic(GetHWnd())) { OpacityStruct *os = (OpacityStruct *)param;
return FALSE; jobject self = os->window;
} BYTE iOpacity = (BYTE)os->iOpacity;
::GetClientRect(GetHWnd(), &inside); PDATA pData;
::GetWindowRect(GetHWnd(), &outside); JNI_CHECK_PEER_GOTO(self, ret);
AwtWindow *window = (AwtWindow *)pData;
BOOL isZeroClientArea = (inside.right == 0 && inside.bottom == 0); window->SetTranslucency(iOpacity, window->isOpaque());
BOOL isInvalidLocation = ((outside.left == -32000 && outside.top == -32000) || // Win2k && WinXP
(outside.left == 32000 && outside.top == 32000) || // Win95 && Win98
(outside.left == 3000 && outside.top == 3000)); // Win95 && Win98
// the bounds correspond to iconic state ret:
if (isZeroClientArea && isInvalidLocation) env->DeleteGlobalRef(self);
{ delete os;
return FALSE; }
}
return TRUE; void AwtWindow::_SetOpaque(void* param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
OpaqueStruct *os = (OpaqueStruct *)param;
jobject self = os->window;
BOOL isOpaque = (BOOL)os->isOpaque;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
AwtWindow *window = (AwtWindow *)pData;
window->SetTranslucency(window->getOpacity(), isOpaque);
ret:
env->DeleteGlobalRef(self);
delete os;
}
void AwtWindow::_UpdateWindow(void* param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
UpdateWindowStruct *uws = (UpdateWindowStruct *)param;
jobject self = uws->window;
jintArray data = uws->data;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
AwtWindow *window = (AwtWindow *)pData;
window->UpdateWindow(env, data, (int)uws->width, (int)uws->height,
uws->hBitmap);
ret:
env->DeleteGlobalRef(self);
if (data != NULL) {
env->DeleteGlobalRef(data);
}
delete uws;
} }
extern "C" { extern "C" {
/* /*
...@@ -2489,4 +2754,93 @@ Java_sun_awt_windows_WWindowPeer_nativeUngrab(JNIEnv *env, jobject self) ...@@ -2489,4 +2754,93 @@ Java_sun_awt_windows_WWindowPeer_nativeUngrab(JNIEnv *env, jobject self)
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setOpacity
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setOpacity(JNIEnv *env, jobject self,
jint iOpacity)
{
TRY;
OpacityStruct *os = new OpacityStruct;
os->window = env->NewGlobalRef(self);
os->iOpacity = iOpacity;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpacity, os);
// global refs and mds are deleted in _SetMinSize
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setOpaqueImpl
* Signature: (Z)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setOpaqueImpl(JNIEnv *env, jobject self,
jboolean isOpaque)
{
TRY;
OpaqueStruct *os = new OpaqueStruct;
os->window = env->NewGlobalRef(self);
os->isOpaque = isOpaque;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpaque, os);
// global refs and mds are deleted in _SetMinSize
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: updateWindowImpl
* Signature: ([III)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_updateWindowImpl(JNIEnv *env, jobject self,
jintArray data,
jint width, jint height)
{
TRY;
UpdateWindowStruct *uws = new UpdateWindowStruct;
uws->window = env->NewGlobalRef(self);
uws->data = (jintArray)env->NewGlobalRef(data);
uws->hBitmap = NULL;
uws->width = width;
uws->height = height;
AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
// global refs and mds are deleted in _UpdateWindow
CATCH_BAD_ALLOC;
}
/**
* This method is called from the WGL pipeline when it needs to update
* the layered window WindowPeer's C++ level object.
*/
void AwtWindow_UpdateWindow(JNIEnv *env, jobject peer,
jint width, jint height, HBITMAP hBitmap)
{
TRY;
UpdateWindowStruct *uws = new UpdateWindowStruct;
uws->window = env->NewGlobalRef(peer);
uws->data = NULL;
uws->hBitmap = hBitmap;
uws->width = width;
uws->height = height;
AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
// global refs and mds are deleted in _UpdateWindow
CATCH_BAD_ALLOC;
}
} /* extern "C" */ } /* extern "C" */
/* /*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -182,6 +182,9 @@ public: ...@@ -182,6 +182,9 @@ public:
void moveToDefaultLocation(); /* moves Window to X,Y specified by Window Manger */ void moveToDefaultLocation(); /* moves Window to X,Y specified by Window Manger */
void UpdateWindow(JNIEnv* env, jintArray data, int width, int height,
HBITMAP hNewBitmap = NULL);
INLINE virtual BOOL IsTopLevel() { return TRUE; } INLINE virtual BOOL IsTopLevel() { return TRUE; }
static AwtWindow * GetGrabbedWindow() { return m_grabbedWindow; } static AwtWindow * GetGrabbedWindow() { return m_grabbedWindow; }
...@@ -204,6 +207,9 @@ public: ...@@ -204,6 +207,9 @@ public:
static void _SetModalExcludedNativeProp(void *param); static void _SetModalExcludedNativeProp(void *param);
static void _ModalDisable(void *param); static void _ModalDisable(void *param);
static void _ModalEnable(void *param); static void _ModalEnable(void *param);
static void _SetOpacity(void* param);
static void _SetOpaque(void* param);
static void _UpdateWindow(void* param);
inline static BOOL IsResizing() { inline static BOOL IsResizing() {
return sm_resizing; return sm_resizing;
...@@ -228,6 +234,32 @@ private: ...@@ -228,6 +234,32 @@ private:
// from its hierarchy when shown. Currently applied to instances of // from its hierarchy when shown. Currently applied to instances of
// javax/swing/Popup$HeavyWeightWindow class. // javax/swing/Popup$HeavyWeightWindow class.
BYTE m_opacity; // The opacity level. == 0xff by default (when opacity mode is disabled)
BOOL m_opaque; // Whether the window uses the perpixel translucency (false), or not (true).
inline BYTE getOpacity() {
return m_opacity;
}
inline void setOpacity(BYTE opacity) {
m_opacity = opacity;
}
inline BOOL isOpaque() {
return m_opaque;
}
inline void setOpaque(BOOL opaque) {
m_opaque = opaque;
}
CRITICAL_SECTION contentBitmapCS;
HBITMAP hContentBitmap;
UINT contentWidth;
UINT contentHeight;
void RedrawWindow();
void SetTranslucency(BYTE opacity, BOOL opaque);
void UpdateWindowImpl(int width, int height, HBITMAP hBitmap);
protected: protected:
BOOL m_isResizable; BOOL m_isResizable;
static AwtWindow* m_grabbedWindow; // Current grabbing window static AwtWindow* m_grabbedWindow; // Current grabbing window
...@@ -236,6 +268,10 @@ protected: ...@@ -236,6 +268,10 @@ protected:
BOOL m_iconInherited; /* TRUE if icon is inherited from the owner */ BOOL m_iconInherited; /* TRUE if icon is inherited from the owner */
BOOL m_filterFocusAndActivation; /* Used in the WH_CBT hook */ BOOL m_filterFocusAndActivation; /* Used in the WH_CBT hook */
//These are used in AwtComponent::CreatePrintedPixels. They are overridden
//here to handle non-opaque windows.
virtual void FillBackground(HDC hMemoryDC, SIZE &size);
virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
private: private:
int m_screenNum; int m_screenNum;
......
/*
* Copyright 2008-2009 Sun Microsystems, Inc. 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.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test %I% %E%
* @bug 6683728
* @summary Tests that a JApplet in a translucent JFrame works properly
* @author Kenneth.Russell@sun.com: area=Graphics
* @compile -XDignore.symbol.file=true TranslucentJAppletTest.java
* @run main/manual/othervm TranslucentJAppletTest
*/
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class TranslucentJAppletTest {
private static JFrame frame;
private static volatile boolean paintComponentCalled = false;
private static void initAndShowGUI() {
frame = new JFrame();
JApplet applet = new JApplet();
JPanel panel = new JPanel() {
protected void paintComponent(Graphics g) {
paintComponentCalled = true;
g.setColor(Color.RED);
g.fillOval(0, 0, getWidth(), getHeight());
}
};
panel.setDoubleBuffered(false);
panel.setOpaque(false);
applet.add(panel);
frame.add(applet);
frame.setBounds(100, 100, 200, 200);
frame.setUndecorated(true);
com.sun.awt.AWTUtilities.setWindowOpaque(frame, false);
frame.setVisible(true);
}
public static void main(String[] args)
throws Exception
{
sun.awt.SunToolkit tk = (sun.awt.SunToolkit)Toolkit.getDefaultToolkit();
Robot r = new Robot();
Color color1 = r.getPixelColor(100, 100); // (0, 0) in frame coordinates
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
initAndShowGUI();
}
});
tk.realSync();
if (!paintComponentCalled) {
throw new RuntimeException("Test FAILED: panel's paintComponent() method is not called");
}
Color newColor1 = r.getPixelColor(100, 100);
// unfortunately, robot.getPixelColor() doesn't work for some unknown reason
// Color newColor2 = r.getPixelColor(200, 200);
BufferedImage bim = r.createScreenCapture(new Rectangle(200, 200, 1, 1));
Color newColor2 = new Color(bim.getRGB(0, 0));
// Frame must be transparent at (100, 100) in screen coords
if (!color1.equals(newColor1)) {
System.err.println("color1 = " + color1);
System.err.println("newColor1 = " + newColor1);
throw new RuntimeException("Test FAILED: frame pixel at (0, 0) is not transparent");
}
// Frame must be RED at (200, 200) in screen coords
if (!newColor2.equals(Color.RED)) {
System.err.println("newColor2 = " + newColor2);
throw new RuntimeException("Test FAILED: frame pixel at (100, 100) is not red (transparent?)");
}
System.out.println("Test PASSED");
}
}
/*
* Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import com.sun.awt.AWTUtilities;
import static com.sun.awt.AWTUtilities.Translucency.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Canvas;
import java.awt.Component;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.util.Random;
import java.awt.geom.Ellipse2D;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TSFrame {
static volatile boolean done = false;
static final boolean useSwing = System.getProperty("useswing") != null;
static final boolean useShape = System.getProperty("useshape") != null;
static final boolean useTransl = System.getProperty("usetransl") != null;
static final boolean useNonOpaque = System.getProperty("usenonop") != null;
static final Random rnd = new Random();
private static void render(Graphics g, int w, int h, boolean useNonOpaque) {
if (useNonOpaque) {
Graphics2D g2d = (Graphics2D)g;
GradientPaint p =
new GradientPaint(0.0f, 0.0f,
new Color(rnd.nextInt(0xffffff)),
w, h,
new Color(rnd.nextInt(0xff),
rnd.nextInt(0xff),
rnd.nextInt(0xff), 0),
true);
g2d.setPaint(p);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.fillOval(0, 0, w, h);
} else {
g.setColor(new Color(rnd.nextInt(0xffffff)));
g.fillRect(0, 0, w, h);
}
}
private static class MyCanvas extends Canvas {
@Override
public void paint(Graphics g) {
render(g, getWidth(), getHeight(), false);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 100);
}
}
private static class NonOpaqueJFrame extends JFrame {
NonOpaqueJFrame(GraphicsConfiguration gc) {
super("NonOpaque Swing JFrame", gc);
JPanel p = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
render(g, getWidth(), getHeight(), true);
g.setColor(Color.red);
g.drawString("Non-Opaque Swing JFrame", 10, 15);
}
};
p.setDoubleBuffered(false);
p.setOpaque(false);
add(p);
setUndecorated(true);
}
}
private static class NonOpaqueJAppletFrame extends JFrame {
JPanel p;
NonOpaqueJAppletFrame(GraphicsConfiguration gc) {
super("NonOpaque Swing JAppletFrame", gc);
JApplet ja = new JApplet() {
public void paint(Graphics g) {
super.paint(g);
System.err.println("JAppletFrame paint called");
}
};
p = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
render(g, getWidth(), getHeight(), true);
g.setColor(Color.red);
g.drawString("Non-Opaque Swing JFrame", 10, 15);
}
};
p.setDoubleBuffered(false);
p.setOpaque(false);
ja.add(p);
add(ja);
setUndecorated(true);
}
}
private static class NonOpaqueFrame extends Frame {
NonOpaqueFrame(GraphicsConfiguration gc) {
super("NonOpaque AWT Frame", gc);
// uncomment to test with hw child
// setLayout(null);
// Component c = new Panel() {
// public void paint(Graphics g) {
// g.setColor(new Color(1.0f, 1.0f, 1.0f, 0.5f));
// g.fillRect(0, 0, getWidth(), getHeight());
// }
// };
// c.setSize(100, 100);
// c.setBackground(Color.red);
// c.setForeground(Color.red);
// add(c);
// c.setLocation(130, 130);
}
@Override
public void paint(Graphics g) {
render(g, getWidth(), getHeight(), true);
g.setColor(Color.red);
g.drawString("Non-Opaque AWT Frame", 10, 15);
}
}
private static class MyJPanel extends JPanel {
@Override
public void paintComponent(Graphics g) {
render(g, getWidth(), getHeight(), false);
}
}
public static Frame createGui(GraphicsConfiguration gc,
final boolean useSwing,
final boolean useShape,
final boolean useTransl,
final boolean useNonOpaque,
final float factor)
{
Frame frame;
done = false;
if (gc == null) {
gc = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
}
if (useNonOpaque) {
if (useSwing) {
frame = new NonOpaqueJFrame(gc);
// frame = new NonOpaqueJAppletFrame(gc);
} else {
frame = new NonOpaqueFrame(gc);
}
animateComponent(frame);
} else if (useSwing) {
frame = new JFrame("Swing Frame", gc);
JComponent p = new JButton("Swing!");
p.setPreferredSize(new Dimension(200, 100));
frame.add("North", p);
p = new MyJPanel();
animateComponent(p);
frame.add("Center", p);
} else {
frame = new Frame("AWT Frame", gc) {
public void paint(Graphics g) {
g.setColor(Color.red);
g.fillRect(0, 0, 100, 100);
}
};
frame.setLayout(new BorderLayout());
Canvas c = new MyCanvas();
frame.add("North", c);
animateComponent(c);
c = new MyCanvas();
frame.add("Center", c);
animateComponent(c);
c = new MyCanvas();
frame.add("South", c);
animateComponent(c);
}
final Frame finalFrame = frame;
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
finalFrame.dispose();
done = true;
}
});
frame.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
finalFrame.dispose();
done = true;
}
});
frame.setPreferredSize(new Dimension(800, 600));
if (useShape) {
frame.setUndecorated(true);
}
frame.setLocation(450, 10);
frame.pack();
if (useShape) {
if (AWTUtilities.isTranslucencySupported(PERPIXEL_TRANSPARENT)) {
System.out.println("applying PERPIXEL_TRANSPARENT");
AWTUtilities.setWindowShape(frame,
new Ellipse2D.Double(0, 0, frame.getWidth(),
frame.getHeight()/3));
frame.setTitle("PERPIXEL_TRANSPARENT");
} else {
System.out.println("Passed: PERPIXEL_TRANSPARENT unsupported");
}
}
if (useTransl) {
if (AWTUtilities.isTranslucencySupported(TRANSLUCENT)) {
System.out.println("applying TRANSLUCENT");
AWTUtilities.setWindowOpacity(frame, factor);
frame.setTitle("TRANSLUCENT");
} else {
System.out.println("Passed: TRANSLUCENT unsupported");
}
}
if (useNonOpaque) {
if (AWTUtilities.isTranslucencySupported(PERPIXEL_TRANSLUCENT) &&
AWTUtilities.isTranslucencyCapable(gc))
{
System.out.println("applying PERPIXEL_TRANSLUCENT");
AWTUtilities.setWindowOpaque(frame, false);
frame.setTitle("PERPIXEL_TRANSLUCENT");
} else {
System.out.println("Passed: PERPIXEL_TRANSLUCENT unsupported");
}
}
frame.setVisible(true);
return frame;
}
public static void stopThreads() {
done = true;
}
private static void animateComponent(final Component comp) {
Thread t = new Thread(new Runnable() {
public void run() {
do {
try {
Thread.sleep(50);
} catch (InterruptedException ex) {}
comp.repaint();
} while (!done);
}
});
t.start();
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
TSFrame.createGui(null, useSwing,
useShape,
useTransl,
useNonOpaque,
0.7f);
}
});
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="createDisposeGrp">
</Component>
</NonVisualComponents>
<Properties>
<Property name="defaultCloseOperation" type="int" value="3"/>
<Property name="title" type="java.lang.String" value="TranslucentShapedFrameTest"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="transparencySld" pref="375" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="shapedCb" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="nonOpaqueChb" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="useSwingCb" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="102" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="314" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="passedBtn" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="failedBtn" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="241" max="-2" attributes="0"/>
</Group>
<Component id="jScrollPane1" alignment="1" pref="375" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="createFrameBtn" min="-2" pref="187" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="disposeFrameBtn" min="-2" pref="182" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="transparencySld" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="shapedCb" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="nonOpaqueChb" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="useSwingCb" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="disposeFrameBtn" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="createFrameBtn" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="148" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="passedBtn" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="failedBtn" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" value="Frame Opacity:"/>
</Properties>
</Component>
<Component class="javax.swing.JSlider" name="transparencySld">
<Properties>
<Property name="majorTickSpacing" type="int" value="10"/>
<Property name="minorTickSpacing" type="int" value="5"/>
<Property name="paintLabels" type="boolean" value="true"/>
<Property name="paintTicks" type="boolean" value="true"/>
<Property name="value" type="int" value="100"/>
</Properties>
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="transparencySldStateChanged"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="shapedCb">
<Properties>
<Property name="text" type="java.lang.String" value="Shaped Frame"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
<EmptyBorder bottom="0" left="0" right="0" top="0"/>
</Border>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[0, 0, 0, 0]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="shapedCbActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="nonOpaqueChb">
<Properties>
<Property name="text" type="java.lang.String" value="Non Opaque Frame"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
<EmptyBorder bottom="0" left="0" right="0" top="0"/>
</Border>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[0, 0, 0, 0]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="nonOpaqueChbActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="jTextArea1">
<Properties>
<Property name="columns" type="int" value="20"/>
<Property name="rows" type="int" value="5"/>
<Property name="text" type="java.lang.String" value="Create translucent and/or shaped, or&#xa;non-opaque frame. Make sure it behaves&#xa;correctly (no artifacts left on the screen&#xa;when dragging - if dragging is possible).&#xa;Click &quot;Passed&quot; if the test behaves correctly,&#xa;&quot;Falied&quot; otherwise."/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" value="Instructions:"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="passedBtn">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="64" green="ff" red="81" type="rgb"/>
</Property>
<Property name="text" type="java.lang.String" value="Passed"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="passedBtnActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="failedBtn">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" id="red" palette="1" red="ff" type="palette"/>
</Property>
<Property name="text" type="java.lang.String" value="Failed"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="failedBtnActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JToggleButton" name="createFrameBtn">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="createDisposeGrp"/>
</Property>
<Property name="text" type="java.lang.String" value="Create Frame"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="createFrameBtnActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JToggleButton" name="disposeFrameBtn">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="createDisposeGrp"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Dispose Frame"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="disposeFrameBtnActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="useSwingCb">
<Properties>
<Property name="text" type="java.lang.String" value="Use JFrame"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
<EmptyBorder bottom="0" left="0" right="0" top="0"/>
</Border>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[0, 0, 0, 0]"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册