提交 14aad851 编写于 作者: L lana

Merge

...@@ -71,6 +71,7 @@ STUBFILES = \ ...@@ -71,6 +71,7 @@ STUBFILES = \
$(STUBDIR)/Ole2.h \ $(STUBDIR)/Ole2.h \
$(STUBDIR)/Zmouse.h \ $(STUBDIR)/Zmouse.h \
$(STUBDIR)/cderr.h \ $(STUBDIR)/cderr.h \
$(STUBDIR)/commctrl.h \
$(STUBDIR)/commdlg.h \ $(STUBDIR)/commdlg.h \
$(STUBDIR)/direct.h \ $(STUBDIR)/direct.h \
$(STUBDIR)/d3dcom.h \ $(STUBDIR)/d3dcom.h \
......
# #
# 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 \
...@@ -199,5 +200,6 @@ FILES_cpp = \ ...@@ -199,5 +200,6 @@ FILES_cpp = \
ShellFolder2.cpp \ ShellFolder2.cpp \
ThemeReader.cpp \ ThemeReader.cpp \
ComCtl32Util.cpp \ ComCtl32Util.cpp \
DllUtil.cpp \
initIDs.cpp \ initIDs.cpp \
MouseInfo.cpp MouseInfo.cpp
# #
# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # Copyright 2000-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
...@@ -107,7 +107,8 @@ FILES_export = \ ...@@ -107,7 +107,8 @@ FILES_export = \
sun/java2d/x11/X11Renderer.java \ sun/java2d/x11/X11Renderer.java \
sun/java2d/x11/X11SurfaceData.java \ sun/java2d/x11/X11SurfaceData.java \
com/sun/java/swing/plaf/gtk/GTKEngine.java \ com/sun/java/swing/plaf/gtk/GTKEngine.java \
com/sun/java/swing/plaf/gtk/GTKStyle.java com/sun/java/swing/plaf/gtk/GTKStyle.java \
sun/awt/ExtendedKeyCodes.java
FILES_export2 = \ FILES_export2 = \
......
# #
# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. # Copyright 2000-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
...@@ -154,7 +154,7 @@ FILES_export2 = \ ...@@ -154,7 +154,7 @@ FILES_export2 = \
sun/awt/datatransfer/DataTransferer.java \ sun/awt/datatransfer/DataTransferer.java \
sun/awt/datatransfer/SunClipboard.java \ sun/awt/datatransfer/SunClipboard.java \
sun/awt/dnd/SunDragSourceContextPeer.java \ sun/awt/dnd/SunDragSourceContextPeer.java \
sun/awt/windows/WToolkitThreadBlockedHandler.java sun/awt/windows/WToolkitThreadBlockedHandler.java
FILES_export3 = \ FILES_export3 = \
java/awt/CheckboxMenuItem.java \ java/awt/CheckboxMenuItem.java \
...@@ -214,6 +214,7 @@ FILES_export3 = \ ...@@ -214,6 +214,7 @@ FILES_export3 = \
sun/awt/windows/WBufferStrategy.java \ sun/awt/windows/WBufferStrategy.java \
sun/awt/windows/WTrayIconPeer.java \ sun/awt/windows/WTrayIconPeer.java \
sun/awt/image/ImagingLib.java \ sun/awt/image/ImagingLib.java \
sun/awt/ExtendedKeyCodes.java \
sun/java2d/pipe/hw/AccelSurface.java \ sun/java2d/pipe/hw/AccelSurface.java \
sun/java2d/pipe/hw/AccelDeviceEventNotifier.java \ sun/java2d/pipe/hw/AccelDeviceEventNotifier.java \
sun/java2d/pipe/hw/ContextCapabilities.java \ sun/java2d/pipe/hw/ContextCapabilities.java \
......
# #
# 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
......
...@@ -6,11 +6,9 @@ runtime, it will probably work with other versions of that compiler. ...@@ -6,11 +6,9 @@ runtime, it will probably work with other versions of that compiler.
Included in this project is a generated file, make.depend, which lists Included in this project is a generated file, make.depend, which lists
all interdependencies of the source files. This file is generated *on all interdependencies of the source files. This file is generated *on
Solaris* with the following commands: Solaris or Linux* with the following command:
% sccs edit make.depend
% gnumake -f Depend.mak % gnumake -f Depend.mak
% sccs delget make.depend
This step only needs to be run when new files are added to the project, This step only needs to be run when new files are added to the project,
or include statements are changed. or include statements are changed.
......
此差异已折叠。
...@@ -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;
......
...@@ -78,4 +78,5 @@ FILES_c = \ ...@@ -78,4 +78,5 @@ FILES_c = \
awt_Plugin.c \ awt_Plugin.c \
gtk2_interface.c \ gtk2_interface.c \
swing_GTKEngine.c \ swing_GTKEngine.c \
swing_GTKStyle.c swing_GTKStyle.c \
rect.c
...@@ -79,6 +79,7 @@ vpath %.c $(SHARE_SRC)/native/sun/java2d ...@@ -79,6 +79,7 @@ vpath %.c $(SHARE_SRC)/native/sun/java2d
vpath %.c $(SHARE_SRC)/native/sun/java2d/loops vpath %.c $(SHARE_SRC)/native/sun/java2d/loops
vpath %.c $(SHARE_SRC)/native/sun/java2d/pipe vpath %.c $(SHARE_SRC)/native/sun/java2d/pipe
vpath %.c $(SHARE_SRC)/native/sun/awt/medialib vpath %.c $(SHARE_SRC)/native/sun/awt/medialib
vpath %.c $(SHARE_SRC)/native/sun/awt/utility
vpath %.cpp $(SHARE_SRC)/native/sun/image vpath %.cpp $(SHARE_SRC)/native/sun/image
vpath %.c $(SHARE_SRC)/native/sun/font vpath %.c $(SHARE_SRC)/native/sun/font
vpath %.c $(PLATFORM_SRC)/native/sun/awt/robot_child vpath %.c $(PLATFORM_SRC)/native/sun/awt/robot_child
...@@ -274,6 +275,23 @@ ICONS = \ ...@@ -274,6 +275,23 @@ ICONS = \
$(ICONS_PATH_PREFIX)/classes/sun/awt/X11/java-icon32.png \ $(ICONS_PATH_PREFIX)/classes/sun/awt/X11/java-icon32.png \
$(ICONS_PATH_PREFIX)/classes/sun/awt/X11/java-icon48.png $(ICONS_PATH_PREFIX)/classes/sun/awt/X11/java-icon48.png
ICONPATH=$(PLATFORM_SRC)/classes/sun/awt/X11
ICONS += \
$(ICONPATH)/security-icon-bw16.png \
$(ICONPATH)/security-icon-interim16.png \
$(ICONPATH)/security-icon-yellow16.png \
$(ICONPATH)/security-icon-bw24.png \
$(ICONPATH)/security-icon-interim24.png \
$(ICONPATH)/security-icon-yellow24.png \
$(ICONPATH)/security-icon-bw32.png \
$(ICONPATH)/security-icon-interim32.png \
$(ICONPATH)/security-icon-yellow32.png \
$(ICONPATH)/security-icon-bw48.png \
$(ICONPATH)/security-icon-interim48.png \
$(ICONPATH)/security-icon-yellow48.png
TEMPDIR_CLASSES = $(TEMPDIR)/classes TEMPDIR_CLASSES = $(TEMPDIR)/classes
$(TEMPDIR_CLASSES)/sun/awt/X11/ToBin.class: ToBin.java $(TEMPDIR_CLASSES)/sun/awt/X11/ToBin.class: ToBin.java
......
# #
# 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
...@@ -93,6 +93,9 @@ SUNWprivate_1.1 { ...@@ -93,6 +93,9 @@ SUNWprivate_1.1 {
Java_sun_awt_X11_XlibWrapper_XGetWMHints; Java_sun_awt_X11_XlibWrapper_XGetWMHints;
Java_sun_awt_X11_XlibWrapper_XShapeQueryExtension; Java_sun_awt_X11_XlibWrapper_XShapeQueryExtension;
Java_sun_awt_X11_XlibWrapper_SetRectangularShape; Java_sun_awt_X11_XlibWrapper_SetRectangularShape;
Java_sun_awt_X11_XlibWrapper_SetBitmapShape;
Java_sun_awt_X11_XlibWrapper_XConfigureWindow;
Java_sun_awt_X11_XlibWrapper_SetZOrder;
Java_sun_awt_X11_XToolkit_initIDs; Java_sun_awt_X11_XToolkit_initIDs;
Java_sun_awt_X11_XWindow_getNativeColor; Java_sun_awt_X11_XWindow_getNativeColor;
Java_sun_awt_X11_XWindow_getWMInsets; Java_sun_awt_X11_XWindow_getWMInsets;
...@@ -217,6 +220,7 @@ SUNWprivate_1.1 { ...@@ -217,6 +220,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;
...@@ -289,16 +293,26 @@ SUNWprivate_1.1 { ...@@ -289,16 +293,26 @@ SUNWprivate_1.1 {
Java_sun_awt_X11_XlibWrapper_XGetIconSizes; Java_sun_awt_X11_XlibWrapper_XGetIconSizes;
Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym; Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym;
Java_sun_awt_X11_XlibWrapper_XKeysymToKeycode; Java_sun_awt_X11_XlibWrapper_XKeysymToKeycode;
Java_sun_awt_X11_XlibWrapper_XQueryKeymap; Java_sun_awt_X11_XlibWrapper_XQueryKeymap;
Java_sun_awt_X11_XlibWrapper_XkbGetEffectiveGroup;
Java_sun_awt_X11_XlibWrapper_XkbSelectEvents;
Java_sun_awt_X11_XlibWrapper_XkbSelectEventDetails;
Java_sun_awt_X11_XlibWrapper_XkbKeycodeToKeysym;
Java_sun_awt_X11_XlibWrapper_XkbLibraryVersion;
Java_sun_awt_X11_XlibWrapper_XkbQueryExtension;
Java_sun_awt_X11_XlibWrapper_XkbGetMap;
Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap;
Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard;
Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode;
Java_sun_awt_X11_XlibWrapper_XGetModifierMapping; Java_sun_awt_X11_XlibWrapper_XGetModifierMapping;
Java_sun_awt_X11_XlibWrapper_XFreeModifiermap; Java_sun_awt_X11_XlibWrapper_XFreeModifiermap;
Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab; Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab;
Java_sun_awt_X11_XlibWrapper_XNextSecondaryLoopEvent; Java_sun_awt_X11_XlibWrapper_XNextSecondaryLoopEvent;
Java_sun_awt_X11_XlibWrapper_ExitSecondaryLoop; Java_sun_awt_X11_XlibWrapper_ExitSecondaryLoop;
Java_sun_awt_X11_XlibWrapper_XTextPropertyToStringList; Java_sun_awt_X11_XlibWrapper_XTextPropertyToStringList;
Java_sun_awt_X11_XlibWrapper_XGrabServer; Java_sun_awt_X11_XlibWrapper_XGrabServer;
Java_sun_awt_X11_XlibWrapper_XUngrabServer; Java_sun_awt_X11_XlibWrapper_XUngrabServer;
Java_sun_awt_X11_XlibWrapper_XPutBackEvent; Java_sun_awt_X11_XlibWrapper_XPutBackEvent;
Java_sun_awt_X11_XlibWrapper_XConvertCase; Java_sun_awt_X11_XlibWrapper_XConvertCase;
Java_sun_awt_X11_XlibWrapper_XSynchronize; Java_sun_awt_X11_XlibWrapper_XSynchronize;
Java_java_awt_FileDialog_initIDs; Java_java_awt_FileDialog_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 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 com.sun.awt;
import java.awt.*;
import java.awt.geom.*;
import sun.awt.AWTAccessor;
/**
* Security Warning control interface.
*
* This class provides a couple of methods that help a developer relocate
* the AWT security warning to an appropriate position relative to the current
* window size. A "top-level window" is an instance of the {@code Window}
* class (or its descendant, such as {@code JFrame}). The security warning
* is applied to all windows created by an untrusted code. All such windows
* have a non-null "warning string" (see {@link Window#getWarningString()}).
* <p>
* <b>WARNING</b>: This class is an implementation detail and only meant
* for limited use outside of the core platform. This API may change
* drastically between update release, and it may even be
* removed or be moved to some other packages or classes.
*/
public final class SecurityWarning {
/**
* The SecurityWarning class should not be instantiated
*/
private SecurityWarning() {
}
/**
* Gets the size of the security warning.
*
* The returned value is not valid until the peer has been created. Before
* invoking this method a developer must call the {@link Window#pack()},
* {@link Window#setVisible()}, or some other method that creates the peer.
*
* @param window the window to get the security warning size for
*
* @throws NullPointerException if the window argument is null
* @throws IllegalArgumentException if the window is trusted (i.e.
* the {@code getWarningString()} returns null)
*/
public static Dimension getSize(Window window) {
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
if (window.getWarningString() == null) {
throw new IllegalArgumentException(
"The window must have a non-null warning string.");
}
// We don't check for a non-null peer since it may be destroyed
// after assigning a valid value to the security warning size.
return AWTAccessor.getWindowAccessor().getSecurityWarningSize(window);
}
/**
* Sets the position of the security warning.
* <p>
* The {@code alignmentX} and {@code alignmentY} arguments specify the
* origin of the coordinate system used to calculate the position of the
* security warning. The values must be in the range [0.0f...1.0f]. The
* {@code 0.0f} value represents the left (top) edge of the rectangular
* bounds of the window. The {@code 1.0f} value represents the right
* (bottom) edge of the bounds. Whenever the size of the window changes,
* the origin of the coordinate system gets relocated accordingly. For
* convenience a developer may use the {@code Component.*_ALIGNMENT}
* constants to pass predefined values for these arguments.
* <p>
* The {@code point} argument specifies the location of the security
* warning in the coordinate system described above. If both {@code x} and
* {@code y} coordinates of the point are equal to zero, the warning will
* be located right in the origin of the coordinate system. On the other
* hand, if both {@code alignmentX} and {@code alignmentY} are equal to
* zero (i.e. the origin of the coordinate system is placed at the top-left
* corner of the window), then the {@code point} argument represents the
* absolute location of the security warning relative to the location of
* the window. The "absolute" in this case means that the position of the
* security warning is not effected by resizing of the window.
* <p>
* Note that the security warning managment code guarantees that:
* <ul>
* <li>The security warning cannot be located farther than two pixels from
* the rectangular bounds of the window (see {@link Window#getBounds}), and
* <li>The security warning is always visible on the screen.
* </ul>
* If either of the conditions is violated, the calculated position of the
* security warning is adjusted by the system to meet both these
* conditions.
* <p>
* The default position of the security warning is in the upper-right
* corner of the window, two pixels to the right from the right edge. This
* corresponds to the following arguments passed to this method:
* <ul>
* <li>{@code alignmentX = Component.RIGHT_ALIGNMENT}
* <li>{@code alignmentY = Component.TOP_ALIGNMENT}
* <li>{@code point = (2, 0)}
* </ul>
*
* @param window the window to set the position of the security warning for
* @param alignmentX the horizontal origin of the coordinate system
* @param alignmentY the vertical origin of the coordinate system
* @param point the position of the security warning in the specified
* coordinate system
*
* @throws NullPointerException if the window argument is null
* @throws NullPointerException if the point argument is null
* @throws IllegalArgumentException if the window is trusted (i.e.
* the {@code getWarningString()} returns null
* @throws IllegalArgumentException if the alignmentX or alignmentY
* arguments are not within the range [0.0f ... 1.0f]
*/
public static void setPosition(Window window, Point2D point,
float alignmentX, float alignmentY)
{
if (window == null) {
throw new NullPointerException(
"The window argument should not be null.");
}
if (window.getWarningString() == null) {
throw new IllegalArgumentException(
"The window must have a non-null warning string.");
}
if (point == null) {
throw new NullPointerException(
"The point argument must not be null");
}
if (alignmentX < 0.0f || alignmentX > 1.0f) {
throw new IllegalArgumentException(
"alignmentX must be in the range [0.0f ... 1.0f].");
}
if (alignmentY < 0.0f || alignmentY > 1.0f) {
throw new IllegalArgumentException(
"alignmentY must be in the range [0.0f ... 1.0f].");
}
AWTAccessor.getWindowAccessor().setSecurityWarningPosition(window,
point, alignmentX, alignmentY);
}
}
/* /*
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2000-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
...@@ -329,6 +329,9 @@ public class AWTKeyStroke implements Serializable { ...@@ -329,6 +329,9 @@ public class AWTKeyStroke implements Serializable {
* <li><code>java.awt.event.KeyEvent.VK_TAB</code> * <li><code>java.awt.event.KeyEvent.VK_TAB</code>
* <li><code>java.awt.event.KeyEvent.VK_SPACE</code> * <li><code>java.awt.event.KeyEvent.VK_SPACE</code>
* </ul> * </ul>
* Alternatively, the key code may be obtained by calling
* <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
*
* The modifiers consist of any combination of:<ul> * The modifiers consist of any combination of:<ul>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package java.awt; package java.awt;
import java.awt.image.BufferStrategy; import java.awt.image.BufferStrategy;
import java.awt.peer.CanvasPeer;
import javax.accessibility.*; import javax.accessibility.*;
/** /**
...@@ -65,7 +66,17 @@ public class Canvas extends Component implements Accessible { ...@@ -65,7 +66,17 @@ public class Canvas extends Component implements Accessible {
*/ */
public Canvas(GraphicsConfiguration config) { public Canvas(GraphicsConfiguration config) {
this(); this();
graphicsConfig = config; setGraphicsConfiguration(config);
}
@Override
void setGraphicsConfiguration(GraphicsConfiguration gc) {
CanvasPeer peer = (CanvasPeer)getPeer();
if (peer != null) {
gc = peer.getAppropriateGraphicsConfiguration(gc);
}
super.setGraphicsConfiguration(gc);
} }
/** /**
......
/* /*
* 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
...@@ -300,7 +300,7 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -300,7 +300,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
* @see GraphicsConfiguration * @see GraphicsConfiguration
* @see #getGraphicsConfiguration * @see #getGraphicsConfiguration
*/ */
transient GraphicsConfiguration graphicsConfig = null; private transient GraphicsConfiguration graphicsConfig = null;
/** /**
* A reference to a <code>BufferStrategy</code> object * A reference to a <code>BufferStrategy</code> object
...@@ -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);
...@@ -829,6 +845,22 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -829,6 +845,22 @@ public abstract class Component implements ImageObserver, MenuContainer,
} }
} }
} }
public void setGraphicsConfiguration(Component comp,
GraphicsConfiguration gc)
{
comp.setGraphicsConfiguration(gc);
}
public boolean requestFocus(Component comp, CausedFocusEvent.Cause cause) {
return comp.requestFocus(cause);
}
public boolean canBeFocusOwner(Component comp) {
return comp.canBeFocusOwner();
}
public boolean isVisible_NoClientCode(Component comp) {
return comp.isVisible_NoClientCode();
}
}); });
} }
...@@ -996,50 +1028,21 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -996,50 +1028,21 @@ public abstract class Component implements ImageObserver, MenuContainer,
*/ */
public GraphicsConfiguration getGraphicsConfiguration() { public GraphicsConfiguration getGraphicsConfiguration() {
synchronized(getTreeLock()) { synchronized(getTreeLock()) {
if (graphicsConfig != null) { return getGraphicsConfiguration_NoClientCode();
return graphicsConfig;
} else if (getParent() != null) {
return getParent().getGraphicsConfiguration();
} else {
return null;
}
} }
} }
final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() { final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
GraphicsConfiguration graphicsConfig = this.graphicsConfig; return graphicsConfig;
Container parent = this.parent;
if (graphicsConfig != null) {
return graphicsConfig;
} else if (parent != null) {
return parent.getGraphicsConfiguration_NoClientCode();
} else {
return null;
}
} }
/** void setGraphicsConfiguration(GraphicsConfiguration gc) {
* Resets this <code>Component</code>'s
* <code>GraphicsConfiguration</code> back to a default
* value. For most componenets, this is <code>null</code>.
* Called from the Toolkit thread, so NO CLIENT CODE.
*/
void resetGC() {
synchronized(getTreeLock()) { synchronized(getTreeLock()) {
graphicsConfig = null; graphicsConfig = gc;
}
}
/* ComponentPeer peer = getPeer();
* Not called on Component, but needed for Canvas and Window if (peer != null) {
*/ peer.updateGraphicsData(gc);
void setGCFromPeer() {
synchronized(getTreeLock()) {
if (peer != null) { // can't imagine how this will be false,
// but just in case
graphicsConfig = peer.getGraphicsConfiguration();
} else {
graphicsConfig = null;
} }
} }
} }
...@@ -6663,23 +6666,7 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -6663,23 +6666,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
// Update stacking order // Update stacking order
if (parent != null && parent.peer != null) { peer.setZOrder(getHWPeerAboveMe());
ContainerPeer parentContPeer = (ContainerPeer) parent.peer;
// if our parent is lightweight and we are not
// we should call restack on nearest heavyweight
// container.
if (parentContPeer instanceof LightweightPeer
&& ! (peer instanceof LightweightPeer))
{
Container hwParent = getNativeContainer();
if (hwParent != null && hwParent.peer != null) {
parentContPeer = (ContainerPeer) hwParent.peer;
}
}
if (parentContPeer.isRestackSupported()) {
parentContPeer.restack();
}
}
if (!isAddNotifyComplete) { if (!isAddNotifyComplete) {
mixOnShowing(); mixOnShowing();
...@@ -7170,8 +7157,8 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -7170,8 +7157,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
requestFocusHelper(false, true); requestFocusHelper(false, true);
} }
void requestFocus(CausedFocusEvent.Cause cause) { boolean requestFocus(CausedFocusEvent.Cause cause) {
requestFocusHelper(false, true, cause); return requestFocusHelper(false, true, cause);
} }
/** /**
...@@ -7456,7 +7443,7 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -7456,7 +7443,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,31 +8676,9 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -8689,31 +8676,9 @@ 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
*/ */
...@@ -9575,6 +9540,27 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -9575,6 +9540,27 @@ public abstract class Component implements ImageObserver, MenuContainer,
return nextAbove < 0 ? -1 : nextAbove; return nextAbove < 0 ? -1 : nextAbove;
} }
final ComponentPeer getHWPeerAboveMe() {
checkTreeLock();
Container cont = getContainer();
int indexAbove = getSiblingIndexAbove();
while (cont != null) {
for (int i = indexAbove; i > -1; i--) {
Component comp = cont.getComponent(i);
if (comp != null && comp.isDisplayable() && !comp.isLightweight()) {
return comp.getPeer();
}
}
indexAbove = cont.getSiblingIndexAbove();
cont = cont.getContainer();
}
return null;
}
final int getSiblingIndexBelow() { final int getSiblingIndexBelow() {
checkTreeLock(); checkTreeLock();
Container parent = getContainer(); Container parent = getContainer();
...@@ -9827,4 +9813,29 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -9827,4 +9813,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
*/ */
...@@ -267,9 +270,13 @@ public class Container extends Component { ...@@ -267,9 +270,13 @@ public class Container extends Component {
/** /**
* Gets the number of components in this panel. * Gets the number of components in this panel.
* <p>
* Note: This method should be called under AWT tree lock.
*
* @return the number of components in this panel. * @return the number of components in this panel.
* @see #getComponent * @see #getComponent
* @since JDK1.1 * @since JDK1.1
* @see Component#getTreeLock()
*/ */
public int getComponentCount() { public int getComponentCount() {
return countComponents(); return countComponents();
...@@ -281,43 +288,65 @@ public class Container extends Component { ...@@ -281,43 +288,65 @@ public class Container extends Component {
*/ */
@Deprecated @Deprecated
public int countComponents() { public int countComponents() {
synchronized (getTreeLock()) { // This method is not synchronized under AWT tree lock.
return component.size(); // Instead, the calling code is responsible for the
} // synchronization. See 6784816 for details.
return component.size();
} }
/** /**
* Gets the nth component in this container. * Gets the nth component in this container.
* <p>
* Note: This method should be called under AWT tree lock.
*
* @param n the index of the component to get. * @param n the index of the component to get.
* @return the n<sup>th</sup> component in this container. * @return the n<sup>th</sup> component in this container.
* @exception ArrayIndexOutOfBoundsException * @exception ArrayIndexOutOfBoundsException
* if the n<sup>th</sup> value does not exist. * if the n<sup>th</sup> value does not exist.
* @see Component#getTreeLock()
*/ */
public Component getComponent(int n) { public Component getComponent(int n) {
synchronized (getTreeLock()) { // This method is not synchronized under AWT tree lock.
if ((n < 0) || (n >= component.size())) { // Instead, the calling code is responsible for the
throw new ArrayIndexOutOfBoundsException("No such child: " + n); // synchronization. See 6784816 for details.
} try {
return component.get(n); return component.get(n);
} catch (IndexOutOfBoundsException z) {
throw new ArrayIndexOutOfBoundsException("No such child: " + n);
} }
} }
/** /**
* Gets all the components in this container. * Gets all the components in this container.
* <p>
* Note: This method should be called under AWT tree lock.
*
* @return an array of all the components in this container. * @return an array of all the components in this container.
* @see Component#getTreeLock()
*/ */
public Component[] getComponents() { public Component[] getComponents() {
// This method is not synchronized under AWT tree lock.
// Instead, the calling code is responsible for the
// synchronization. See 6784816 for details.
return getComponents_NoClientCode(); return getComponents_NoClientCode();
} }
// NOTE: This method may be called by privileged threads. // NOTE: This method may be called by privileged threads.
// This functionality is implemented in a package-private method // This functionality is implemented in a package-private method
// to insure that it cannot be overridden by client subclasses. // to insure that it cannot be overridden by client subclasses.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD! // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
final Component[] getComponents_NoClientCode() { final Component[] getComponents_NoClientCode() {
return component.toArray(EMPTY_ARRAY);
}
/*
* Wrapper for getComponents() method with a proper synchronization.
*/
Component[] getComponentsSync() {
synchronized (getTreeLock()) { synchronized (getTreeLock()) {
return component.toArray(EMPTY_ARRAY); return getComponents();
} }
} // getComponents_NoClientCode() }
/** /**
* Determines the insets of this container, which indicate the size * Determines the insets of this container, which indicate the size
...@@ -503,6 +532,9 @@ public class Container extends Component { ...@@ -503,6 +532,9 @@ public class Container extends Component {
adjustDescendants(-(comp.countHierarchyMembers())); adjustDescendants(-(comp.countHierarchyMembers()));
comp.parent = null; comp.parent = null;
if (needRemoveNotify) {
comp.setGraphicsConfiguration(null);
}
component.remove(index); component.remove(index);
invalidateIfValid(); invalidateIfValid();
...@@ -643,10 +675,7 @@ public class Container extends Component { ...@@ -643,10 +675,7 @@ public class Container extends Component {
// each HW descendant independently. // each HW descendant independently.
return !comp.peer.isReparentSupported(); return !comp.peer.isReparentSupported();
} else { } else {
// if container didn't change we still might need to recreate component's window as return false;
// changes to zorder should be reflected in native window stacking order and it might
// not be supported by the platform. This is important only for heavyweight child
return !((ContainerPeer)(newNativeContainer.peer)).isRestackSupported();
} }
} }
...@@ -786,6 +815,7 @@ public class Container extends Component { ...@@ -786,6 +815,7 @@ public class Container extends Component {
component.add(index, comp); component.add(index, comp);
} }
comp.parent = this; comp.parent = this;
comp.setGraphicsConfiguration(getGraphicsConfiguration());
adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK, adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK)); comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
...@@ -802,11 +832,6 @@ public class Container extends Component { ...@@ -802,11 +832,6 @@ public class Container extends Component {
if (peer != null) { if (peer != null) {
if (comp.peer == null) { // Remove notify was called or it didn't have peer - create new one if (comp.peer == null) { // Remove notify was called or it didn't have peer - create new one
comp.addNotify(); comp.addNotify();
// New created peer creates component on top of the stacking order
Container newNativeContainer = getHeavyweightContainer();
if (((ContainerPeer)newNativeContainer.getPeer()).isRestackSupported()) {
((ContainerPeer)newNativeContainer.getPeer()).restack();
}
} else { // Both container and child have peers, it means child peer should be reparented. } else { // Both container and child have peers, it means child peer should be reparented.
// In both cases we need to reparent native widgets. // In both cases we need to reparent native widgets.
Container newNativeContainer = getHeavyweightContainer(); Container newNativeContainer = getHeavyweightContainer();
...@@ -815,13 +840,8 @@ public class Container extends Component { ...@@ -815,13 +840,8 @@ public class Container extends Component {
// Native container changed - need to reparent native widgets // Native container changed - need to reparent native widgets
newNativeContainer.reparentChild(comp); newNativeContainer.reparentChild(comp);
} }
// If component still has a peer and it is either container or heavyweight comp.peer.setZOrder(comp.getHWPeerAboveMe());
// and restack is supported we have to restack native windows since order might have changed
if ((!comp.isLightweight() || (comp instanceof Container))
&& ((ContainerPeer)newNativeContainer.getPeer()).isRestackSupported())
{
((ContainerPeer)newNativeContainer.getPeer()).restack();
}
if (!comp.isLightweight() && isLightweight()) { if (!comp.isLightweight() && isLightweight()) {
// If component is heavyweight and one of the containers is lightweight // If component is heavyweight and one of the containers is lightweight
// the location of the component should be fixed. // the location of the component should be fixed.
...@@ -1034,9 +1054,9 @@ public class Container extends Component { ...@@ -1034,9 +1054,9 @@ public class Container extends Component {
} }
checkAddToSelf(comp); checkAddToSelf(comp);
checkNotAWindow(comp); checkNotAWindow(comp);
if (thisGC != null) { if (thisGC != null) {
comp.checkGD(thisGC.getDevice().getIDstring()); comp.checkGD(thisGC.getDevice().getIDstring());
} }
/* Reparent the component and tidy up the tree's state. */ /* Reparent the component and tidy up the tree's state. */
if (comp.parent != null) { if (comp.parent != null) {
...@@ -1053,6 +1073,7 @@ public class Container extends Component { ...@@ -1053,6 +1073,7 @@ public class Container extends Component {
component.add(index, comp); component.add(index, comp);
} }
comp.parent = this; comp.parent = this;
comp.setGraphicsConfiguration(thisGC);
adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK, adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK)); comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
...@@ -1091,6 +1112,19 @@ public class Container extends Component { ...@@ -1091,6 +1112,19 @@ public class Container extends Component {
} }
} }
@Override
void setGraphicsConfiguration(GraphicsConfiguration gc) {
synchronized (getTreeLock()) {
super.setGraphicsConfiguration(gc);
for (Component comp : component) {
if (comp != null) {
comp.setGraphicsConfiguration(gc);
}
}
}
}
/** /**
* Checks that all Components that this Container contains are on * Checks that all Components that this Container contains are on
* the same GraphicsDevice as this Container. If not, throws an * the same GraphicsDevice as this Container. If not, throws an
...@@ -1148,6 +1182,7 @@ public class Container extends Component { ...@@ -1148,6 +1182,7 @@ public class Container extends Component {
comp.parent = null; comp.parent = null;
component.remove(index); component.remove(index);
comp.setGraphicsConfiguration(null);
invalidateIfValid(); invalidateIfValid();
if (containerListener != null || if (containerListener != null ||
...@@ -1224,6 +1259,7 @@ public class Container extends Component { ...@@ -1224,6 +1259,7 @@ public class Container extends Component {
layoutMgr.removeLayoutComponent(comp); layoutMgr.removeLayoutComponent(comp);
} }
comp.parent = null; comp.parent = null;
comp.setGraphicsConfiguration(null);
if (containerListener != null || if (containerListener != null ||
(eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) { Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
...@@ -1339,7 +1375,7 @@ public class Container extends Component { ...@@ -1339,7 +1375,7 @@ public class Container extends Component {
} }
private int getListenersCount(int id, boolean enabledOnToolkit) { private int getListenersCount(int id, boolean enabledOnToolkit) {
assert Thread.holdsLock(getTreeLock()); checkTreeLock();
if (enabledOnToolkit) { if (enabledOnToolkit) {
return descendantsCount; return descendantsCount;
} }
...@@ -1357,7 +1393,7 @@ public class Container extends Component { ...@@ -1357,7 +1393,7 @@ public class Container extends Component {
final int createHierarchyEvents(int id, Component changed, final int createHierarchyEvents(int id, Component changed,
Container changedParent, long changeFlags, boolean enabledOnToolkit) Container changedParent, long changeFlags, boolean enabledOnToolkit)
{ {
assert Thread.holdsLock(getTreeLock()); checkTreeLock();
int listeners = getListenersCount(id, enabledOnToolkit); int listeners = getListenersCount(id, enabledOnToolkit);
for (int count = listeners, i = 0; count > 0; i++) { for (int count = listeners, i = 0; count > 0; i++) {
...@@ -1372,7 +1408,7 @@ public class Container extends Component { ...@@ -1372,7 +1408,7 @@ public class Container extends Component {
final void createChildHierarchyEvents(int id, long changeFlags, final void createChildHierarchyEvents(int id, long changeFlags,
boolean enabledOnToolkit) boolean enabledOnToolkit)
{ {
assert Thread.holdsLock(getTreeLock()); checkTreeLock();
if (component.isEmpty()) { if (component.isEmpty()) {
return; return;
} }
...@@ -1507,6 +1543,7 @@ public class Container extends Component { ...@@ -1507,6 +1543,7 @@ public class Container extends Component {
* @see #validate * @see #validate
*/ */
protected void validateTree() { protected void validateTree() {
checkTreeLock();
if (!isValid()) { if (!isValid()) {
if (peer instanceof ContainerPeer) { if (peer instanceof ContainerPeer) {
((ContainerPeer)peer).beginLayout(); ((ContainerPeer)peer).beginLayout();
...@@ -1783,7 +1820,7 @@ public class Container extends Component { ...@@ -1783,7 +1820,7 @@ public class Container extends Component {
// super.paint(); -- Don't bother, since it's a NOP. // super.paint(); -- Don't bother, since it's a NOP.
GraphicsCallback.PaintCallback.getInstance(). GraphicsCallback.PaintCallback.getInstance().
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS); runComponents(getComponentsSync(), g, GraphicsCallback.LIGHTWEIGHTS);
} }
} }
...@@ -1838,7 +1875,7 @@ public class Container extends Component { ...@@ -1838,7 +1875,7 @@ public class Container extends Component {
} }
GraphicsCallback.PrintCallback.getInstance(). GraphicsCallback.PrintCallback.getInstance().
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS); runComponents(getComponentsSync(), g, GraphicsCallback.LIGHTWEIGHTS);
} }
} }
...@@ -1851,7 +1888,7 @@ public class Container extends Component { ...@@ -1851,7 +1888,7 @@ public class Container extends Component {
public void paintComponents(Graphics g) { public void paintComponents(Graphics g) {
if (isShowing()) { if (isShowing()) {
GraphicsCallback.PaintAllCallback.getInstance(). GraphicsCallback.PaintAllCallback.getInstance().
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.TWO_PASSES); runComponents(getComponentsSync(), g, GraphicsCallback.TWO_PASSES);
} }
} }
...@@ -1873,8 +1910,8 @@ public class Container extends Component { ...@@ -1873,8 +1910,8 @@ public class Container extends Component {
void paintHeavyweightComponents(Graphics g) { void paintHeavyweightComponents(Graphics g) {
if (isShowing()) { if (isShowing()) {
GraphicsCallback.PaintHeavyweightComponentsCallback.getInstance(). GraphicsCallback.PaintHeavyweightComponentsCallback.getInstance().
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS | runComponents(getComponentsSync(), g,
GraphicsCallback.HEAVYWEIGHTS); GraphicsCallback.LIGHTWEIGHTS | GraphicsCallback.HEAVYWEIGHTS);
} }
} }
...@@ -1887,7 +1924,7 @@ public class Container extends Component { ...@@ -1887,7 +1924,7 @@ public class Container extends Component {
public void printComponents(Graphics g) { public void printComponents(Graphics g) {
if (isShowing()) { if (isShowing()) {
GraphicsCallback.PrintAllCallback.getInstance(). GraphicsCallback.PrintAllCallback.getInstance().
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.TWO_PASSES); runComponents(getComponentsSync(), g, GraphicsCallback.TWO_PASSES);
} }
} }
...@@ -1909,8 +1946,8 @@ public class Container extends Component { ...@@ -1909,8 +1946,8 @@ public class Container extends Component {
void printHeavyweightComponents(Graphics g) { void printHeavyweightComponents(Graphics g) {
if (isShowing()) { if (isShowing()) {
GraphicsCallback.PrintHeavyweightComponentsCallback.getInstance(). GraphicsCallback.PrintHeavyweightComponentsCallback.getInstance().
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS | runComponents(getComponentsSync(), g,
GraphicsCallback.HEAVYWEIGHTS); GraphicsCallback.LIGHTWEIGHTS | GraphicsCallback.HEAVYWEIGHTS);
} }
} }
...@@ -2460,9 +2497,7 @@ public class Container extends Component { ...@@ -2460,9 +2497,7 @@ public class Container extends Component {
* @since 1.2 * @since 1.2
*/ */
public Component findComponentAt(int x, int y) { public Component findComponentAt(int x, int y) {
synchronized (getTreeLock()) { return findComponentAt(x, y, true);
return findComponentAt(x, y, true);
}
} }
/** /**
...@@ -2475,58 +2510,60 @@ public class Container extends Component { ...@@ -2475,58 +2510,60 @@ public class Container extends Component {
* The addition of this feature is temporary, pending the * The addition of this feature is temporary, pending the
* adoption of new, public API which exports this feature. * adoption of new, public API which exports this feature.
*/ */
final Component findComponentAt(int x, int y, boolean ignoreEnabled) final Component findComponentAt(int x, int y, boolean ignoreEnabled) {
{ synchronized (getTreeLock()) {
if (isRecursivelyVisible()){ if (isRecursivelyVisible()){
return findComponentAtImpl(x, y, ignoreEnabled); return findComponentAtImpl(x, y, ignoreEnabled);
}
} }
return null; return null;
} }
final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled){ final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled){
checkTreeLock();
if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) { if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
return null; return null;
} }
// Two passes: see comment in sun.awt.SunGraphicsCallback // Two passes: see comment in sun.awt.SunGraphicsCallback
synchronized (getTreeLock()) { for (int i = 0; i < component.size(); i++) {
for (int i = 0; i < component.size(); i++) { Component comp = component.get(i);
Component comp = component.get(i); if (comp != null &&
if (comp != null && !(comp.peer instanceof LightweightPeer)) {
!(comp.peer instanceof LightweightPeer)) { if (comp instanceof Container) {
if (comp instanceof Container) { comp = ((Container)comp).findComponentAtImpl(x - comp.x,
comp = ((Container)comp).findComponentAtImpl(x - comp.x, y - comp.y,
y - comp.y, ignoreEnabled);
ignoreEnabled); } else {
} else { comp = comp.locate(x - comp.x, y - comp.y);
comp = comp.locate(x - comp.x, y - comp.y); }
} if (comp != null && comp.visible &&
if (comp != null && comp.visible && (ignoreEnabled || comp.enabled))
(ignoreEnabled || comp.enabled)) {
{ return comp;
return comp;
}
} }
} }
for (int i = 0; i < component.size(); i++) { }
Component comp = component.get(i); for (int i = 0; i < component.size(); i++) {
if (comp != null && Component comp = component.get(i);
comp.peer instanceof LightweightPeer) { if (comp != null &&
if (comp instanceof Container) { comp.peer instanceof LightweightPeer) {
comp = ((Container)comp).findComponentAtImpl(x - comp.x, if (comp instanceof Container) {
y - comp.y, comp = ((Container)comp).findComponentAtImpl(x - comp.x,
ignoreEnabled); y - comp.y,
} else { ignoreEnabled);
comp = comp.locate(x - comp.x, y - comp.y); } else {
} comp = comp.locate(x - comp.x, y - comp.y);
if (comp != null && comp.visible && }
(ignoreEnabled || comp.enabled)) if (comp != null && comp.visible &&
{ (ignoreEnabled || comp.enabled))
return comp; {
} return comp;
} }
} }
} }
return this; return this;
} }
...@@ -2584,13 +2621,6 @@ public class Container extends Component { ...@@ -2584,13 +2621,6 @@ public class Container extends Component {
for (int i = 0; i < component.size(); i++) { for (int i = 0; i < component.size(); i++) {
component.get(i).addNotify(); component.get(i).addNotify();
} }
// Update stacking order if native platform allows
ContainerPeer cpeer = (ContainerPeer)peer;
if (cpeer.isRestackSupported()) {
cpeer.restack();
}
} }
} }
...@@ -3488,7 +3518,7 @@ public class Container extends Component { ...@@ -3488,7 +3518,7 @@ public class Container extends Component {
private void writeObject(ObjectOutputStream s) throws IOException { private void writeObject(ObjectOutputStream s) throws IOException {
ObjectOutputStream.PutField f = s.putFields(); ObjectOutputStream.PutField f = s.putFields();
f.put("ncomponents", component.size()); f.put("ncomponents", component.size());
f.put("component", component.toArray(EMPTY_ARRAY)); f.put("component", getComponentsSync());
f.put("layoutMgr", layoutMgr); f.put("layoutMgr", layoutMgr);
f.put("dispatcher", dispatcher); f.put("dispatcher", dispatcher);
f.put("maxSize", maxSize); f.put("maxSize", maxSize);
......
...@@ -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)
......
...@@ -1226,7 +1226,7 @@ public class Dialog extends Window { ...@@ -1226,7 +1226,7 @@ public class Dialog extends Window {
synchronized (getTreeLock()) { synchronized (getTreeLock()) {
if (keepBlockingEDT) { if (keepBlockingEDT) {
keepBlockingEDT = false; keepBlockingEDT = false;
PeerEvent wakingEvent = new PeerEvent(this, new WakingRunnable(), PeerEvent.PRIORITY_EVENT); PeerEvent wakingEvent = new PeerEvent(getToolkit(), new WakingRunnable(), PeerEvent.PRIORITY_EVENT);
AppContext curAppContext = AppContext.getAppContext(); AppContext curAppContext = AppContext.getAppContext();
if (showAppContext != curAppContext) { if (showAppContext != curAppContext) {
// Wake up event dispatch thread on which the dialog was // Wake up event dispatch thread on which the dialog was
......
...@@ -36,6 +36,7 @@ import java.io.ObjectInputStream; ...@@ -36,6 +36,7 @@ import java.io.ObjectInputStream;
import java.io.IOException; import java.io.IOException;
import sun.awt.AppContext; import sun.awt.AppContext;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.awt.AWTAccessor;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import javax.accessibility.*; import javax.accessibility.*;
...@@ -738,11 +739,15 @@ public class Frame extends Window implements MenuContainer { ...@@ -738,11 +739,15 @@ public class Frame extends Window implements MenuContainer {
* @since 1.4 * @since 1.4
* @see java.awt.Window#addWindowStateListener * @see java.awt.Window#addWindowStateListener
*/ */
public synchronized void setExtendedState(int state) { public void setExtendedState(int state) {
if ( !isFrameStateSupported( state ) ) { if ( !isFrameStateSupported( state ) ) {
return; return;
} }
this.state = state; synchronized (getObjectLock()) {
this.state = state;
}
// peer.setState must be called outside of object lock
// synchronization block to avoid possible deadlock
FramePeer peer = (FramePeer)this.peer; FramePeer peer = (FramePeer)this.peer;
if (peer != null) { if (peer != null) {
peer.setState(state); peer.setState(state);
...@@ -804,12 +809,27 @@ public class Frame extends Window implements MenuContainer { ...@@ -804,12 +809,27 @@ public class Frame extends Window implements MenuContainer {
* @see #setExtendedState(int) * @see #setExtendedState(int)
* @since 1.4 * @since 1.4
*/ */
public synchronized int getExtendedState() { public int getExtendedState() {
FramePeer peer = (FramePeer)this.peer; synchronized (getObjectLock()) {
if (peer != null) { return state;
state = peer.getState();
} }
return state; }
static {
AWTAccessor.setFrameAccessor(
new AWTAccessor.FrameAccessor() {
public void setExtendedState(Frame frame, int state) {
synchronized(frame.getObjectLock()) {
frame.state = state;
}
}
public int getExtendedState(Frame frame) {
synchronized(frame.getObjectLock()) {
return frame.state;
}
}
}
);
} }
/** /**
...@@ -967,7 +987,7 @@ public class Frame extends Window implements MenuContainer { ...@@ -967,7 +987,7 @@ public class Frame extends Window implements MenuContainer {
if (resizable) { if (resizable) {
str += ",resizable"; str += ",resizable";
} }
getExtendedState(); // sync with peer int state = getExtendedState();
if (state == NORMAL) { if (state == NORMAL) {
str += ",normal"; str += ",normal";
} }
......
/* /*
* 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;
}
} }
...@@ -61,6 +61,7 @@ import sun.awt.HeadlessToolkit; ...@@ -61,6 +61,7 @@ import sun.awt.HeadlessToolkit;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.awt.CausedFocusEvent; import sun.awt.CausedFocusEvent;
import sun.awt.KeyboardFocusManagerPeerProvider; import sun.awt.KeyboardFocusManagerPeerProvider;
import sun.awt.AWTAccessor;
/** /**
* The KeyboardFocusManager is responsible for managing the active and focused * The KeyboardFocusManager is responsible for managing the active and focused
...@@ -118,6 +119,32 @@ public abstract class KeyboardFocusManager ...@@ -118,6 +119,32 @@ public abstract class KeyboardFocusManager
if (!GraphicsEnvironment.isHeadless()) { if (!GraphicsEnvironment.isHeadless()) {
initIDs(); initIDs();
} }
AWTAccessor.setKeyboardFocusManagerAccessor(
new AWTAccessor.KeyboardFocusManagerAccessor() {
public int shouldNativelyFocusHeavyweight(Component heavyweight,
Component descendant,
boolean temporary,
boolean focusedWindowChangeAllowed,
long time,
CausedFocusEvent.Cause cause)
{
return KeyboardFocusManager.shouldNativelyFocusHeavyweight(
heavyweight, descendant, temporary, focusedWindowChangeAllowed, time, cause);
}
public boolean processSynchronousLightweightTransfer(Component heavyweight,
Component descendant,
boolean temporary,
boolean focusedWindowChangeAllowed,
long time)
{
return KeyboardFocusManager.processSynchronousLightweightTransfer(
heavyweight, descendant, temporary, focusedWindowChangeAllowed, time);
}
public void removeLastFocusRequest(Component heavyweight) {
KeyboardFocusManager.removeLastFocusRequest(heavyweight);
}
}
);
} }
transient KeyboardFocusManagerPeer peer; transient KeyboardFocusManagerPeer peer;
...@@ -2208,7 +2235,7 @@ public abstract class KeyboardFocusManager ...@@ -2208,7 +2235,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;
} }
...@@ -2443,79 +2470,7 @@ public abstract class KeyboardFocusManager ...@@ -2443,79 +2470,7 @@ public abstract class KeyboardFocusManager
} }
} }
} }
static void heavyweightButtonDown(Component heavyweight, long time) {
heavyweightButtonDown(heavyweight, time, false);
}
static void heavyweightButtonDown(Component heavyweight, long time, boolean acceptDuplicates) {
if (log.isLoggable(Level.FINE)) {
if (heavyweight == null) {
log.log(Level.FINE, "Assertion (heavyweight != null) failed");
}
if (time == 0) {
log.log(Level.FINE, "Assertion (time != 0) failed");
}
}
KeyboardFocusManager manager = getCurrentKeyboardFocusManager(SunToolkit.targetToAppContext(heavyweight));
synchronized (heavyweightRequests) {
HeavyweightFocusRequest hwFocusRequest = getLastHWRequest();
Component currentNativeFocusOwner = (hwFocusRequest == null)
? manager.getNativeFocusOwner()
: hwFocusRequest.heavyweight;
// Behavior for all use cases:
// 1. Heavyweight leaf Components (e.g., Button, Checkbox, Choice,
// List, TextComponent, Canvas) that respond to button down.
//
// Native platform will generate a FOCUS_GAINED if and only if
// the Component is not the focus owner (or, will not be the
// focus owner when all outstanding focus requests are
// processed).
//
// 2. Panel with no descendants.
//
// Same as (1).
//
// 3. Panel with at least one heavyweight descendant.
//
// This function should NOT be called for this case!
//
// 4. Panel with only lightweight descendants.
//
// Native platform will generate a FOCUS_GAINED if and only if
// neither the Panel, nor any of its recursive, lightweight
// descendants, is the focus owner. However, we want a
// requestFocus() for any lightweight descendant to win out over
// the focus request for the Panel. To accomplish this, we
// differ from the algorithm for shouldNativelyFocusHeavyweight
// as follows:
// a. If the requestFocus() for a lightweight descendant has
// been fully handled by the time this function is invoked,
// then 'hwFocusRequest' will be null and 'heavyweight'
// will be the native focus owner. Do *not* synthesize a
// focus transfer to the Panel.
// b. If the requestFocus() for a lightweight descendant has
// been recorded, but not handled, then 'hwFocusRequest'
// will be non-null and 'hwFocusRequest.heavyweight' will
// equal 'heavyweight'. Do *not* append 'heavyweight' to
// hwFocusRequest.lightweightRequests.
// c. If the requestFocus() for a lightweight descendant is
// yet to be made, then post a new HeavyweightFocusRequest.
// If no lightweight descendant ever requests focus, then
// the Panel will get focus. If some descendant does, then
// the descendant will get focus by either a synthetic
// focus transfer, or a lightweightRequests focus transfer.
if (acceptDuplicates || heavyweight != currentNativeFocusOwner) {
getCurrentKeyboardFocusManager
(SunToolkit.targetToAppContext(heavyweight)).
enqueueKeyEvents(time, heavyweight);
heavyweightRequests.add
(new HeavyweightFocusRequest(heavyweight, heavyweight,
false, CausedFocusEvent.Cause.MOUSE_EVENT));
}
}
}
/** /**
* Returns the Window which will be active after processing this request, * Returns the Window which will be active after processing this request,
* or null if this is a duplicate request. The active Window is useful * or null if this is a duplicate request. The active Window is useful
...@@ -2542,7 +2497,7 @@ public abstract class KeyboardFocusManager ...@@ -2542,7 +2497,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 +2968,8 @@ public abstract class KeyboardFocusManager ...@@ -3013,8 +2968,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 +2983,8 @@ public abstract class KeyboardFocusManager ...@@ -3028,8 +2983,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
...@@ -398,9 +398,11 @@ public class MenuItem extends MenuComponent implements Accessible { ...@@ -398,9 +398,11 @@ public class MenuItem extends MenuComponent implements Accessible {
boolean handleShortcut(KeyEvent e) { boolean handleShortcut(KeyEvent e) {
MenuShortcut s = new MenuShortcut(e.getKeyCode(), MenuShortcut s = new MenuShortcut(e.getKeyCode(),
(e.getModifiers() & InputEvent.SHIFT_MASK) > 0); (e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
MenuShortcut sE = new MenuShortcut(e.getExtendedKeyCode(),
(e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
// Fix For 6185151: Menu shortcuts of all menuitems within a menu // Fix For 6185151: Menu shortcuts of all menuitems within a menu
// should be disabled when the menu itself is disabled // should be disabled when the menu itself is disabled
if (s.equals(shortcut) && isItemEnabled()) { if ((s.equals(shortcut) || sE.equals(shortcut)) && isItemEnabled()) {
// MenuShortcut match -- issue an event on keydown. // MenuShortcut match -- issue an event on keydown.
if (e.getID() == KeyEvent.KEY_PRESSED) { if (e.getID() == KeyEvent.KEY_PRESSED) {
doMenuEvent(e.getWhen(), e.getModifiers()); doMenuEvent(e.getWhen(), e.getModifiers());
......
/* /*
* Copyright 1996-2003 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
...@@ -34,7 +34,21 @@ import java.awt.event.KeyEvent; ...@@ -34,7 +34,21 @@ import java.awt.event.KeyEvent;
* For example, a menu shortcut for Ctrl-a (assuming that Control is * For example, a menu shortcut for Ctrl-a (assuming that Control is
* the accelerator key) would be created with code like the following: * the accelerator key) would be created with code like the following:
* <p> * <p>
* MenuShortcut ms = new MenuShortcut(KeyEvent.VK_A, false); * <code>MenuShortcut ms = new MenuShortcut(KeyEvent.VK_A, false);</code>
* <p> or alternatively
* <p>
* <code>MenuShortcut ms = new MenuShortcut(KeyEvent.getExtendedKeyCodeForChar('A'), false);</code>
* <p>
* Menu shortcuts may also be constructed for a wider set of keycodes
* using the <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code> call.
* For example, a menu shortcut for "Ctrl+cyrillic ef" is created by
* <p>
* <code>MenuShortcut ms = new MenuShortcut(KeyEvent.getExtendedKeyCodeForChar('\u0444'), false);</code>
* <p>
* Note that shortcuts created with a keycode or an extended keycode defined as a constant in <code>KeyEvent</code>
* work regardless of the current keyboard layout. However, a shortcut made of
* an extended keycode not listed in <code>KeyEvent</code>
* only work if the current keyboard layout produces a corresponding letter.
* <p> * <p>
* The accelerator key is platform-dependent and may be obtained * The accelerator key is platform-dependent and may be obtained
* via {@link Toolkit#getMenuShortcutKeyMask}. * via {@link Toolkit#getMenuShortcutKeyMask}.
......
/* /*
* 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
...@@ -65,15 +65,16 @@ import java.io.ObjectInputStream; ...@@ -65,15 +65,16 @@ import java.io.ObjectInputStream;
* <p> * <p>
* For key pressed and key released events, the getKeyCode method returns * For key pressed and key released events, the getKeyCode method returns
* the event's keyCode. For key typed events, the getKeyCode method * the event's keyCode. For key typed events, the getKeyCode method
* always returns VK_UNDEFINED. * always returns {@code VK_UNDEFINED}. The {@code getExtendedKeyCode} method
* may also be used with many international keyboard layouts.
* *
* <p> * <p>
* <em>"Key pressed" and "key released" events</em> are lower-level and depend * <em>"Key pressed" and "key released" events</em> are lower-level and depend
* on the platform and keyboard layout. They are generated whenever a key is * on the platform and keyboard layout. They are generated whenever a key is
* pressed or released, and are the only way to find out about keys that don't * pressed or released, and are the only way to find out about keys that don't
* generate character input (e.g., action keys, modifier keys, etc.). The key * generate character input (e.g., action keys, modifier keys, etc.). The key
* being pressed or released is indicated by the getKeyCode method, which returns * being pressed or released is indicated by the {@code getKeyCode} and {@code getExtendedKeyCode}
* a virtual key code. * methods, which return a virtual key code.
* *
* <p> * <p>
* <em>Virtual key codes</em> are used to report which keyboard key has * <em>Virtual key codes</em> are used to report which keyboard key has
...@@ -111,6 +112,11 @@ import java.io.ObjectInputStream; ...@@ -111,6 +112,11 @@ import java.io.ObjectInputStream;
* platform and keyboard layout. For example, the key that generates VK_Q * platform and keyboard layout. For example, the key that generates VK_Q
* when using a U.S. keyboard layout will generate VK_A when using a French * when using a U.S. keyboard layout will generate VK_A when using a French
* keyboard layout. * keyboard layout.
* <li>The key that generates {@code VK_Q} when using a U.S. keyboard layout also
* generates a unique code for Russian or Hebrew layout. There is no a
* {@code VK_} constant for these and many other codes in various layouts. These codes
* may be obtained by using {@code getExtendedKeyCode} and are used whenever
* a {@code VK_} constant is used.
* <li>Not all characters have a keycode associated with them. For example, * <li>Not all characters have a keycode associated with them. For example,
* there is no keycode for the question mark because there is no keyboard * there is no keycode for the question mark because there is no keyboard
* for which it appears on the primary layer. * for which it appears on the primary layer.
...@@ -891,6 +897,12 @@ public class KeyEvent extends InputEvent { ...@@ -891,6 +897,12 @@ public class KeyEvent extends InputEvent {
*/ */
int keyLocation; int keyLocation;
//set from native code.
private transient long rawCode = 0;
private transient long primaryLevelUnicode = 0;
private transient long scancode = 0; // for MS Windows only
private transient long extendedKeyCode = 0;
/* /*
* JDK 1.1 serialVersionUID * JDK 1.1 serialVersionUID
*/ */
...@@ -1315,6 +1327,9 @@ public class KeyEvent extends InputEvent { ...@@ -1315,6 +1327,9 @@ public class KeyEvent extends InputEvent {
return numpad + "-" + c; return numpad + "-" + c;
} }
if ((keyCode & 0x01000000) != 0) {
return String.valueOf((char)(keyCode ^ 0x01000000 ));
}
String unknown = Toolkit.getProperty("AWT.unknown", "Unknown"); String unknown = Toolkit.getProperty("AWT.unknown", "Unknown");
return unknown + " keyCode: 0x" + Integer.toString(keyCode, 16); return unknown + " keyCode: 0x" + Integer.toString(keyCode, 16);
} }
...@@ -1551,9 +1566,44 @@ public class KeyEvent extends InputEvent { ...@@ -1551,9 +1566,44 @@ public class KeyEvent extends InputEvent {
str.append("KEY_LOCATION_UNKNOWN"); str.append("KEY_LOCATION_UNKNOWN");
break; break;
} }
str.append(",rawCode=").append(rawCode);
str.append(",primaryLevelUnicode=").append(primaryLevelUnicode);
str.append(",scancode=").append(scancode);
str.append(",extendedKeyCode=0x").append(Long.toHexString(extendedKeyCode));
return str.toString(); return str.toString();
} }
/**
* Returns an extended key code for the event.
* The extended key code is a unique id assigned to a key on the keyboard
* just like {@code keyCode}. However, unlike {@code keyCode}, this value depends on the
* current keyboard layout. For instance, pressing the left topmost letter key
* in a common English layout produces the same value as {@code keyCode}, {@code VK_Q}.
* Pressing the same key in a regular Russian layout gives another code, unique for the
* letter "Cyrillic I short".
*
* @since 1.7
*
*/
public int getExtendedKeyCode() {
return (int)extendedKeyCode;
}
/**
* Returns an extended key code for a unicode character.
*
* @return for a unicode character with a corresponding {@code VK_} constant -- this
* {@code VK_} constant; for a character appearing on the primary
* level of a known keyboard layout -- a unique integer.
* If a character does not appear on the primary level of a known keyboard,
* {@code VK_UNDEFINED} is returned.
*
* @since 1.7
*
*/
public static int getExtendedKeyCodeForChar(int c) {
// Return a keycode (if any) associated with a character.
return sun.awt.ExtendedKeyCodes.getExtendedKeyCodeForChar(c);
}
/** /**
* Sets new modifiers by the old ones. The key modifiers * Sets new modifiers by the old ones. The key modifiers
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package java.awt.peer; package java.awt.peer;
import java.awt.Canvas; import java.awt.Canvas;
import java.awt.GraphicsConfiguration;
/** /**
* The peer interface for {@link Canvas}. * The peer interface for {@link Canvas}.
...@@ -36,4 +37,13 @@ import java.awt.Canvas; ...@@ -36,4 +37,13 @@ import java.awt.Canvas;
* instances. * instances.
*/ */
public interface CanvasPeer extends ComponentPeer { public interface CanvasPeer extends ComponentPeer {
/**
* Requests a GC that best suits this Canvas. The returned GC may differ
* from the requested GC passed as the argument to this method. This method
* must return a non-null value (given the argument is non-null as well).
*
* @since 1.7
*/
GraphicsConfiguration getAppropriateGraphicsConfiguration(
GraphicsConfiguration gc);
} }
...@@ -539,4 +539,16 @@ public interface ComponentPeer { ...@@ -539,4 +539,16 @@ public interface ComponentPeer {
*/ */
void applyShape(Region shape); void applyShape(Region shape);
/**
* Lowers this component at the bottom of the above HW peer. If the above parameter
* is null then the method places this component at the top of the Z-order.
*/
void setZOrder(ComponentPeer above);
/**
* Updates internal data structures related to the component's GC.
*
* @since 1.7
*/
void updateGraphicsData(GraphicsConfiguration gc);
} }
...@@ -76,21 +76,4 @@ public interface ContainerPeer extends ComponentPeer { ...@@ -76,21 +76,4 @@ public interface ContainerPeer extends ComponentPeer {
* @see Container#validateTree() * @see Container#validateTree()
*/ */
void endLayout(); void endLayout();
/**
* Restacks native windows - children of this native window - according to
* Java container order.
*
* @since 1.5
*/
void restack();
/**
* Indicates availability of restacking operation in this container.
*
* @return Returns true if restack is supported, false otherwise
*
* @since 1.5
*/
boolean isRestackSupported();
} }
/* /*
* 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,31 @@ public interface WindowPeer extends ContainerPeer { ...@@ -92,4 +94,31 @@ 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);
/**
* Instructs the peer to update the position of the security warning.
*/
void repositionSecurityWarning();
} }
/* /*
* 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
...@@ -1545,6 +1545,9 @@ public abstract class AbstractButton extends JComponent implements ItemSelectabl ...@@ -1545,6 +1545,9 @@ public abstract class AbstractButton extends JComponent implements ItemSelectabl
* A mnemonic must correspond to a single key on the keyboard * A mnemonic must correspond to a single key on the keyboard
* and should be specified using one of the <code>VK_XXX</code> * and should be specified using one of the <code>VK_XXX</code>
* keycodes defined in <code>java.awt.event.KeyEvent</code>. * keycodes defined in <code>java.awt.event.KeyEvent</code>.
* These codes and the wider array of codes for international
* keyboards may be obtained through
* <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
* Mnemonics are case-insensitive, therefore a key event * Mnemonics are case-insensitive, therefore a key event
* with the corresponding keycode would cause the button to be * with the corresponding keycode would cause the button to be
* activated whether or not the Shift modifier was pressed. * activated whether or not the Shift modifier was pressed.
......
/* /*
* Copyright 1997-2006 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
...@@ -272,7 +272,9 @@ public interface Action extends ActionListener { ...@@ -272,7 +272,9 @@ public interface Action extends ActionListener {
* one of the <code>KeyEvent</code> key codes. The value is * one of the <code>KeyEvent</code> key codes. The value is
* commonly used to specify a mnemonic. For example: * commonly used to specify a mnemonic. For example:
* <code>myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A)</code> * <code>myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A)</code>
* sets the mnemonic of <code>myAction</code> to 'a'. * sets the mnemonic of <code>myAction</code> to 'a', while
* <code>myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.getExtendedKeyCodeForChar('\u0444'))</code>
* sets the mnemonic of <code>myAction</code> to Cyrillic letter "Ef".
* *
* @since 1.3 * @since 1.3
*/ */
......
/* /*
* 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
...@@ -2888,7 +2888,10 @@ public abstract class JComponent extends Container implements Serializable, ...@@ -2888,7 +2888,10 @@ public abstract class JComponent extends Container implements Serializable,
return false; return false;
} }
// Get the KeyStroke // Get the KeyStroke
// There may be two keystrokes associated with a low-level key event;
// in this case a keystroke made of an extended key code has a priority.
KeyStroke ks; KeyStroke ks;
KeyStroke ksE = null;
if (e.getID() == KeyEvent.KEY_TYPED) { if (e.getID() == KeyEvent.KEY_TYPED) {
ks = KeyStroke.getKeyStroke(e.getKeyChar()); ks = KeyStroke.getKeyStroke(e.getKeyChar());
...@@ -2896,9 +2899,18 @@ public abstract class JComponent extends Container implements Serializable, ...@@ -2896,9 +2899,18 @@ public abstract class JComponent extends Container implements Serializable,
else { else {
ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(), ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
(pressed ? false:true)); (pressed ? false:true));
if (e.getKeyCode() != e.getExtendedKeyCode()) {
ksE = KeyStroke.getKeyStroke(e.getExtendedKeyCode(),e.getModifiers(),
(pressed ? false:true));
}
} }
/* Do we have a key binding for e? */ // Do we have a key binding for e?
// If we have a binding by an extended code, use it.
// If not, check for regular code binding.
if(ksE != null && processKeyBinding(ksE, e, WHEN_FOCUSED, pressed)) {
return true;
}
if(processKeyBinding(ks, e, WHEN_FOCUSED, pressed)) if(processKeyBinding(ks, e, WHEN_FOCUSED, pressed))
return true; return true;
...@@ -2910,6 +2922,9 @@ public abstract class JComponent extends Container implements Serializable, ...@@ -2910,6 +2922,9 @@ public abstract class JComponent extends Container implements Serializable,
while (parent != null && !(parent instanceof Window) && while (parent != null && !(parent instanceof Window) &&
!(parent instanceof Applet)) { !(parent instanceof Applet)) {
if(parent instanceof JComponent) { if(parent instanceof JComponent) {
if(ksE != null && ((JComponent)parent).processKeyBinding(ksE, e,
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
return true;
if(((JComponent)parent).processKeyBinding(ks, e, if(((JComponent)parent).processKeyBinding(ks, e,
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed)) WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
return true; 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
...@@ -503,10 +503,10 @@ public class JLabel extends JComponent implements SwingConstants, Accessible ...@@ -503,10 +503,10 @@ public class JLabel extends JComponent implements SwingConstants, Accessible
* @see #setDisplayedMnemonic(int) * @see #setDisplayedMnemonic(int)
*/ */
public void setDisplayedMnemonic(char aChar) { public void setDisplayedMnemonic(char aChar) {
int vk = (int) aChar; int vk = java.awt.event.KeyEvent.getExtendedKeyCodeForChar(aChar);
if(vk >= 'a' && vk <='z') if (vk != java.awt.event.KeyEvent.VK_UNDEFINED) {
vk -= ('a' - 'A'); setDisplayedMnemonic(vk);
setDisplayedMnemonic(vk); }
} }
......
/* /*
* 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
...@@ -1628,7 +1628,9 @@ public class JTabbedPane extends JComponent ...@@ -1628,7 +1628,9 @@ public class JTabbedPane extends JComponent
* <p> * <p>
* A mnemonic must correspond to a single key on the keyboard * A mnemonic must correspond to a single key on the keyboard
* and should be specified using one of the <code>VK_XXX</code> * and should be specified using one of the <code>VK_XXX</code>
* keycodes defined in <code>java.awt.event.KeyEvent</code>. * keycodes defined in <code>java.awt.event.KeyEvent</code>
* or one of the extended keycodes obtained through
* <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
* Mnemonics are case-insensitive, therefore a key event * Mnemonics are case-insensitive, therefore a key event
* with the corresponding keycode would cause the button to be * with the corresponding keycode would cause the button to be
* activated whether or not the Shift modifier was pressed. * activated whether or not the Shift modifier was pressed.
......
/* /*
* 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
...@@ -162,6 +162,9 @@ public class KeyStroke extends AWTKeyStroke { ...@@ -162,6 +162,9 @@ public class KeyStroke extends AWTKeyStroke {
* <li>java.awt.event.KeyEvent.VK_TAB * <li>java.awt.event.KeyEvent.VK_TAB
* <li>java.awt.event.KeyEvent.VK_SPACE * <li>java.awt.event.KeyEvent.VK_SPACE
* </ul> * </ul>
* Alternatively, the key code may be obtained by calling
* <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
*
* The modifiers consist of any combination of:<ul> * The modifiers consist of any combination of:<ul>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
...@@ -210,6 +213,9 @@ public class KeyStroke extends AWTKeyStroke { ...@@ -210,6 +213,9 @@ public class KeyStroke extends AWTKeyStroke {
* <li>java.awt.event.KeyEvent.VK_TAB * <li>java.awt.event.KeyEvent.VK_TAB
* <li>java.awt.event.KeyEvent.VK_SPACE * <li>java.awt.event.KeyEvent.VK_SPACE
* </ul> * </ul>
* Alternatively, the key code may be obtained by calling
* <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
*
* The modifiers consist of any combination of:<ul> * The modifiers consist of any combination of:<ul>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
......
/* /*
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1998-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
...@@ -212,19 +212,35 @@ class KeyboardManager { ...@@ -212,19 +212,35 @@ class KeyboardManager {
Thread.dumpStack(); Thread.dumpStack();
} }
// There may be two keystrokes associated with a low-level key event;
// in this case a keystroke made of an extended key code has a priority.
KeyStroke ks; KeyStroke ks;
KeyStroke ksE = null;
if(e.getID() == KeyEvent.KEY_TYPED) { if(e.getID() == KeyEvent.KEY_TYPED) {
ks=KeyStroke.getKeyStroke(e.getKeyChar()); ks=KeyStroke.getKeyStroke(e.getKeyChar());
} else { } else {
if(e.getKeyCode() != e.getExtendedKeyCode()) {
ksE=KeyStroke.getKeyStroke(e.getExtendedKeyCode(), e.getModifiers(), !pressed);
}
ks=KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers(), !pressed); ks=KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers(), !pressed);
} }
Hashtable keyMap = containerMap.get(topAncestor); Hashtable keyMap = containerMap.get(topAncestor);
if (keyMap != null) { // this container isn't registered, so bail if (keyMap != null) { // this container isn't registered, so bail
Object tmp = keyMap.get(ks); Object tmp = null;
// extended code has priority
if( ksE != null ) {
tmp = keyMap.get(ksE);
if( tmp != null ) {
ks = ksE;
}
}
if( tmp == null ) {
tmp = keyMap.get(ks);
}
if (tmp == null) { if (tmp == null) {
// don't do anything // don't do anything
...@@ -269,7 +285,12 @@ class KeyboardManager { ...@@ -269,7 +285,12 @@ class KeyboardManager {
while (iter.hasMoreElements()) { while (iter.hasMoreElements()) {
JMenuBar mb = (JMenuBar)iter.nextElement(); JMenuBar mb = (JMenuBar)iter.nextElement();
if ( mb.isShowing() && mb.isEnabled() ) { // don't want to give these out if ( mb.isShowing() && mb.isEnabled() ) { // don't want to give these out
fireBinding(mb, ks, e, pressed); if( !(ks.equals(ksE)) ) {
fireBinding(mb, ksE, e, pressed);
}
if(ks.equals(ksE) || !e.isConsumed()) {
fireBinding(mb, ks, e, pressed);
}
if (e.isConsumed()) { if (e.isConsumed()) {
return true; 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
...@@ -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 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
...@@ -1589,15 +1589,6 @@ public class SwingUtilities implements SwingConstants ...@@ -1589,15 +1589,6 @@ public class SwingUtilities implements SwingConstants
* processing the key bindings associated with JComponents. * processing the key bindings associated with JComponents.
*/ */
static boolean isValidKeyEventForKeyBindings(KeyEvent e) { static boolean isValidKeyEventForKeyBindings(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_TYPED) {
int mod = e.getModifiers();
if (((mod & ActionEvent.ALT_MASK) != 0) &&
((mod & ActionEvent.CTRL_MASK) == 0)) {
// filter out typed "alt-?" keys, but not those created
// with AltGr, and not control characters
return false;
}
}
return true; return true;
} }
......
/* /*
* 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,46 +26,229 @@ ...@@ -26,46 +26,229 @@
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.
* The main purpose of this class is to enable accessing * The main purpose of this class is to enable accessing
* private and package-private fields of classes from * private and package-private fields of classes from
* different classes/packages. See sun.misc.SharedSecretes * different classes/packages. See sun.misc.SharedSecretes
* 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);
/**
* Sets GraphicsConfiguration value for the component.
*/
void setGraphicsConfiguration(Component comp, GraphicsConfiguration gc);
/*
* Requests focus to the component.
*/
boolean requestFocus(Component comp, CausedFocusEvent.Cause cause);
/*
* Determines if the component can gain focus.
*/
boolean canBeFocusOwner(Component comp);
/**
* Returns whether the component is visible without invoking
* any client code.
*/
boolean isVisible_NoClientCode(Component comp);
}
/*
* 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);
/** Get the size of the security warning.
*/
Dimension getSecurityWarningSize(Window w);
/**
* Set the size of the security warning.
*/
void setSecurityWarningSize(Window w, int width, int height);
/** Set the position of the security warning.
*/
void setSecurityWarningPosition(Window w, Point2D point,
float alignmentX, float alignmentY);
/** Request to recalculate the new position of the security warning for
* the given window size/location as reported by the native system.
*/
Point2D calculateSecurityWarningPosition(Window window,
double x, double y, double w, double h);
}
/*
* 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);
}
/*
* An accessor for the java.awt.Frame class.
*/
public interface FrameAccessor {
/*
* Sets the state of this frame.
*/
void setExtendedState(Frame frame, int state);
/*
* Gets the state of this frame.
*/
int getExtendedState(Frame frame);
} }
/* The java.awt.Component class accessor object. /*
* An interface of accessor for the java.awt.KeyboardFocusManager class.
*/
public interface KeyboardFocusManagerAccessor {
/*
* Indicates whether the native implementation should
* proceed with a pending focus request for the heavyweight.
*/
int shouldNativelyFocusHeavyweight(Component heavyweight,
Component descendant,
boolean temporary,
boolean focusedWindowChangeAllowed,
long time,
CausedFocusEvent.Cause cause);
/*
* Delivers focus for the lightweight descendant of the heavyweight
* synchronously.
*/
boolean processSynchronousLightweightTransfer(Component heavyweight,
Component descendant,
boolean temporary,
boolean focusedWindowChangeAllowed,
long time);
/*
* Removes the last focus request for the heavyweight from the queue.
*/
void removeLastFocusRequest(Component heavyweight);
}
/*
* 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;
/*
* The java.awt.Frame class accessor object.
*/
private static FrameAccessor frameAccessor;
/*
* The java.awt.KeyboardFocusManager class accessor object.
*/
private static KeyboardFocusManagerAccessor kfmAccessor;
/*
* 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 +257,69 @@ public final class AWTAccessor { ...@@ -74,4 +257,69 @@ 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;
}
/*
* Set an accessor object for the java.awt.Frame class.
*/
public static void setFrameAccessor(FrameAccessor fa) {
frameAccessor = fa;
}
/*
* Retrieve the accessor object for the java.awt.Frame class.
*/
public static FrameAccessor getFrameAccessor() {
if (frameAccessor == null) {
unsafe.ensureClassInitialized(Frame.class);
}
return frameAccessor;
}
/*
* Set an accessor object for the java.awt.KeyboardFocusManager class.
*/
public static void setKeyboardFocusManagerAccessor(KeyboardFocusManagerAccessor kfma) {
kfmAccessor = kfma;
}
/*
* Retrieve the accessor object for the java.awt.KeyboardFocusManager class.
*/
public static KeyboardFocusManagerAccessor getKeyboardFocusManagerAccessor() {
if (kfmAccessor == null) {
unsafe.ensureClassInitialized(KeyboardFocusManager.class);
}
return kfmAccessor;
}
} }
...@@ -73,7 +73,6 @@ public class ComponentAccessor ...@@ -73,7 +73,6 @@ public class ComponentAccessor
private static Field fieldPacked; private static Field fieldPacked;
private static Field fieldIgnoreRepaint; private static Field fieldIgnoreRepaint;
private static Field fieldPeer; private static Field fieldPeer;
private static Method methodResetGC;
private static Field fieldVisible; private static Field fieldVisible;
private static Method methodIsEnabledImpl; private static Method methodIsEnabledImpl;
private static Method methodGetCursorNoClientCode; private static Method methodGetCursorNoClientCode;
...@@ -124,9 +123,6 @@ public class ComponentAccessor ...@@ -124,9 +123,6 @@ public class ComponentAccessor
fieldPeer = componentClass.getDeclaredField("peer"); fieldPeer = componentClass.getDeclaredField("peer");
fieldPeer.setAccessible(true); fieldPeer.setAccessible(true);
methodResetGC = componentClass.getDeclaredMethod("resetGC", (Class[]) null);
methodResetGC.setAccessible(true);
fieldVisible = componentClass.getDeclaredField("visible"); fieldVisible = componentClass.getDeclaredField("visible");
fieldVisible.setAccessible(true); fieldVisible.setAccessible(true);
...@@ -425,18 +421,6 @@ public class ComponentAccessor ...@@ -425,18 +421,6 @@ public class ComponentAccessor
return false; return false;
} }
public static void resetGC(Component c) {
try {
methodResetGC.invoke(c, (Object[]) null);
}
catch (IllegalAccessException e) {
log.log(Level.FINE, "Unable to access the Component object", e);
}
catch (InvocationTargetException e) {
log.log(Level.FINE, "Unable to invoke on the Component object", e);
}
}
public static boolean getVisible(Component c) { public static boolean getVisible(Component c) {
try { try {
return fieldVisible.getBoolean(c); return fieldVisible.getBoolean(c);
......
/* /*
* 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,14 @@ public abstract class EmbeddedFrame extends Frame ...@@ -585,5 +585,14 @@ 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) {
}
public void repositionSecurityWarning() {
}
}
} // class EmbeddedFrame } // class EmbeddedFrame
此差异已折叠。
...@@ -179,9 +179,9 @@ public class HeadlessToolkit extends Toolkit ...@@ -179,9 +179,9 @@ public class HeadlessToolkit extends Toolkit
throw new HeadlessException(); throw new HeadlessException();
} }
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) throws HeadlessException { public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
KeyboardFocusManagerPeerImpl peer = new KeyboardFocusManagerPeerImpl(manager); throws HeadlessException {
return peer; throw new HeadlessException();
} }
public TrayIconPeer createTrayIcon(TrayIcon target) public TrayIconPeer createTrayIcon(TrayIcon target)
......
/* /*
* 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
...@@ -27,47 +27,150 @@ package sun.awt; ...@@ -27,47 +27,150 @@ package sun.awt;
import java.awt.Component; import java.awt.Component;
import java.awt.KeyboardFocusManager; import java.awt.KeyboardFocusManager;
import java.awt.Window; import java.awt.Window;
import java.awt.Canvas;
import java.awt.Scrollbar;
import java.awt.Panel;
import java.awt.event.FocusEvent;
import java.awt.peer.KeyboardFocusManagerPeer; import java.awt.peer.KeyboardFocusManagerPeer;
import java.awt.peer.ComponentPeer;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManagerPeer {
private static final Logger focusLog = Logger.getLogger("sun.awt.focus.KeyboardFocusManagerPeerImpl");
private static AWTAccessor.KeyboardFocusManagerAccessor kfmAccessor =
AWTAccessor.getKeyboardFocusManagerAccessor();
public class KeyboardFocusManagerPeerImpl implements KeyboardFocusManagerPeer { // The constants are copied from java.awt.KeyboardFocusManager
static native Window getNativeFocusedWindow(); public static final int SNFH_FAILURE = 0;
static native Component getNativeFocusOwner(); public static final int SNFH_SUCCESS_HANDLED = 1;
static native void clearNativeGlobalFocusOwner(Window activeWindow); public static final int SNFH_SUCCESS_PROCEED = 2;
KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) { protected KeyboardFocusManager manager;
public KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) {
this.manager = manager;
} }
public Window getCurrentFocusedWindow() { @Override
return getNativeFocusedWindow(); public void clearGlobalFocusOwner(Window activeWindow) {
if (activeWindow != null) {
Component focusOwner = activeWindow.getFocusOwner();
if (focusLog.isLoggable(Level.FINE)) focusLog.fine("Clearing global focus owner " + focusOwner);
if (focusOwner != null) {
FocusEvent fl = new CausedFocusEvent(focusOwner, FocusEvent.FOCUS_LOST, false, null,
CausedFocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER);
SunToolkit.postPriorityEvent(fl);
}
}
}
/*
* WARNING: Don't call it on the Toolkit thread.
*
* Checks if the component:
* 1) accepts focus on click (in general)
* 2) may be a focus owner (in particular)
*/
public static boolean shouldFocusOnClick(Component component) {
boolean acceptFocusOnClick = false;
// A component is generally allowed to accept focus on click
// if its peer is focusable. There're some exceptions though.
// CANVAS & SCROLLBAR accept focus on click
if (component instanceof Canvas ||
component instanceof Scrollbar)
{
acceptFocusOnClick = true;
// PANEL, empty only, accepts focus on click
} else if (component instanceof Panel) {
acceptFocusOnClick = (((Panel)component).getComponentCount() == 0);
// Other components
} else {
ComponentPeer peer = (component != null ? component.getPeer() : null);
acceptFocusOnClick = (peer != null ? peer.isFocusable() : false);
}
return acceptFocusOnClick &&
AWTAccessor.getComponentAccessor().canBeFocusOwner(component);
} }
public void setCurrentFocusOwner(Component comp) { /*
* Posts proper lost/gain focus events to the event queue.
*/
public static boolean deliverFocus(Component lightweightChild,
Component target,
boolean temporary,
boolean focusedWindowChangeAllowed,
long time,
CausedFocusEvent.Cause cause,
Component currentFocusOwner) // provided by the descendant peers
{
if (lightweightChild == null) {
lightweightChild = (Component)target;
}
Component currentOwner = currentFocusOwner;
if (currentOwner != null && currentOwner.getPeer() == null) {
currentOwner = null;
}
if (currentOwner != null) {
FocusEvent fl = new CausedFocusEvent(currentOwner, FocusEvent.FOCUS_LOST,
false, lightweightChild, cause);
if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Posting focus event: " + fl);
SunToolkit.postPriorityEvent(fl);
}
FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED,
false, currentOwner, cause);
if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Posting focus event: " + fg);
SunToolkit.postPriorityEvent(fg);
return true;
} }
public Component getCurrentFocusOwner() { // WARNING: Don't call it on the Toolkit thread.
return getNativeFocusOwner(); public static boolean requestFocusFor(Component target, CausedFocusEvent.Cause cause) {
return AWTAccessor.getComponentAccessor().requestFocus(target, cause);
} }
public void clearGlobalFocusOwner(Window activeWindow) {
clearNativeGlobalFocusOwner(activeWindow); // WARNING: Don't call it on the Toolkit thread.
public static int shouldNativelyFocusHeavyweight(Component heavyweight,
Component descendant,
boolean temporary,
boolean focusedWindowChangeAllowed,
long time,
CausedFocusEvent.Cause cause)
{
return kfmAccessor.shouldNativelyFocusHeavyweight(
heavyweight, descendant, temporary, focusedWindowChangeAllowed, time, cause);
} }
static Method m_removeLastFocusRequest = null;
public static void removeLastFocusRequest(Component heavyweight) { public static void removeLastFocusRequest(Component heavyweight) {
try { kfmAccessor.removeLastFocusRequest(heavyweight);
if (m_removeLastFocusRequest == null) { }
m_removeLastFocusRequest = SunToolkit.getMethod(KeyboardFocusManager.class, "removeLastFocusRequest",
new Class[] {Component.class}); // WARNING: Don't call it on the Toolkit thread.
} public static boolean processSynchronousLightweightTransfer(Component heavyweight,
m_removeLastFocusRequest.invoke(null, new Object[]{heavyweight}); Component descendant,
} catch (InvocationTargetException ite) { boolean temporary,
ite.printStackTrace(); boolean focusedWindowChangeAllowed,
} catch (IllegalAccessException ex) { long time)
ex.printStackTrace(); {
} return kfmAccessor.processSynchronousLightweightTransfer(
heavyweight, descendant, temporary, focusedWindowChangeAllowed, time);
} }
} }
...@@ -278,19 +278,6 @@ public class NullComponentPeer implements LightweightPeer, ...@@ -278,19 +278,6 @@ public class NullComponentPeer implements LightweightPeer,
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* @see java.awt.peer.ContainerPeer#restack
*/
public void restack() {
throw new UnsupportedOperationException();
}
/**
* @see java.awt.peer.ContainerPeer#isRestackSupported
*/
public boolean isRestackSupported() {
return false;
}
public void layout() { public void layout() {
} }
...@@ -305,4 +292,19 @@ public class NullComponentPeer implements LightweightPeer, ...@@ -305,4 +292,19 @@ public class NullComponentPeer implements LightweightPeer,
*/ */
public void applyShape(Region shape) { public void applyShape(Region shape) {
} }
/**
* Lowers this component at the bottom of the above HW peer. If the above parameter
* is null then the method places this component at the top of the Z-order.
*/
public void setZOrder(ComponentPeer above) {
}
public void updateGraphicsData(GraphicsConfiguration gc) {}
public GraphicsConfiguration getAppropriateGraphicsConfiguration(
GraphicsConfiguration gc)
{
return gc;
}
} }
/* /*
* 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;
...@@ -225,10 +220,8 @@ public abstract class SunToolkit extends Toolkit ...@@ -225,10 +220,8 @@ public abstract class SunToolkit extends Toolkit
public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen) public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
throws AWTException; throws AWTException;
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) throws HeadlessException { public abstract KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
KeyboardFocusManagerPeerImpl peer = new KeyboardFocusManagerPeerImpl(manager); throws HeadlessException;
return peer;
}
/** /**
* The AWT lock is typically only used on Unix platforms to synchronize * The AWT lock is typically only used on Unix platforms to synchronize
...@@ -824,16 +817,31 @@ public abstract class SunToolkit extends Toolkit ...@@ -824,16 +817,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 +1980,18 @@ public abstract class SunToolkit extends Toolkit ...@@ -1972,6 +1980,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 +2015,73 @@ public abstract class SunToolkit extends Toolkit ...@@ -1995,6 +2015,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 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.X11;
import java.awt.*;
import java.awt.event.*;
import java.awt.peer.TrayIconPeer;
import sun.awt.*;
import java.awt.image.*;
import java.text.BreakIterator;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.concurrent.ArrayBlockingQueue;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.lang.reflect.InvocationTargetException;
/**
* An utility window class. This is a base class for Tooltip and Balloon.
*/
public abstract class InfoWindow extends Window {
private Container container;
private Closer closer;
protected InfoWindow(Frame parent, Color borderColor) {
super(parent);
container = new Container() {
@Override
public Insets getInsets() {
return new Insets(1, 1, 1, 1);
}
};
setLayout(new BorderLayout());
setBackground(borderColor);
add(container, BorderLayout.CENTER);
container.setLayout(new BorderLayout());
closer = new Closer();
}
public Component add(Component c) {
container.add(c, BorderLayout.CENTER);
return c;
}
protected void setCloser(Runnable action, int time) {
closer.set(action, time);
}
// Must be executed on EDT.
protected void show(Point corner, int indent) {
assert SunToolkit.isDispatchThreadForAppContext(this);
pack();
Dimension size = getSize();
// TODO: When 6356322 is fixed we should get screen bounds in
// this way: eframe.getGraphicsConfiguration().getBounds().
Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();
if (corner.x < scrSize.width/2 && corner.y < scrSize.height/2) { // 1st square
setLocation(corner.x + indent, corner.y + indent);
} else if (corner.x >= scrSize.width/2 && corner.y < scrSize.height/2) { // 2nd square
setLocation(corner.x - indent - size.width, corner.y + indent);
} else if (corner.x < scrSize.width/2 && corner.y >= scrSize.height/2) { // 3rd square
setLocation(corner.x + indent, corner.y - indent - size.height);
} else if (corner.x >= scrSize.width/2 && corner.y >= scrSize.height/2) { // 4th square
setLocation(corner.x - indent - size.width, corner.y - indent - size.height);
}
super.show();
closer.schedule();
}
public void hide() {
closer.close();
}
private class Closer implements Runnable {
Runnable action;
int time;
public void run() {
doClose();
}
void set(Runnable action, int time) {
this.action = action;
this.time = time;
}
void schedule() {
XToolkit.schedule(this, time);
}
void close() {
XToolkit.remove(this);
doClose();
}
// WARNING: this method may be executed on Toolkit thread.
private void doClose() {
SunToolkit.executeOnEventHandlerThread(InfoWindow.this, new Runnable() {
public void run() {
InfoWindow.super.hide();
invalidate();
if (action != null) {
action.run();
}
}
});
}
}
private interface LiveArguments {
/** Whether the target of the InfoWindow is disposed. */
boolean isDisposed();
/** The bounds of the target of the InfoWindow. */
Rectangle getBounds();
}
public static class Tooltip extends InfoWindow {
public interface LiveArguments extends InfoWindow.LiveArguments {
/** The tooltip to be displayed. */
String getTooltipString();
}
private final Object target;
private final LiveArguments liveArguments;
private final Label textLabel = new Label("");
private final Runnable starter = new Runnable() {
public void run() {
display();
}};
private final static int TOOLTIP_SHOW_TIME = 10000;
private final static int TOOLTIP_START_DELAY_TIME = 1000;
private final static int TOOLTIP_MAX_LENGTH = 64;
private final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5;
private final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220);
private final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont();
public Tooltip(Frame parent, Object target,
LiveArguments liveArguments)
{
super(parent, Color.black);
this.target = target;
this.liveArguments = liveArguments;
XTrayIconPeer.suppressWarningString(this);
setCloser(null, TOOLTIP_SHOW_TIME);
textLabel.setBackground(TOOLTIP_BACKGROUND_COLOR);
textLabel.setFont(TOOLTIP_TEXT_FONT);
add(textLabel);
}
/*
* WARNING: this method is executed on Toolkit thread!
*/
private void display() {
String tooltipString = liveArguments.getTooltipString();
if (tooltipString == null) {
return;
} else if (tooltipString.length() > TOOLTIP_MAX_LENGTH) {
textLabel.setText(tooltipString.substring(0, TOOLTIP_MAX_LENGTH));
} else {
textLabel.setText(tooltipString);
}
// Execute on EDT to avoid deadlock (see 6280857).
SunToolkit.executeOnEventHandlerThread(target, new Runnable() {
public void run() {
if (liveArguments.isDisposed()) {
return;
}
Point pointer = (Point)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
if (!isPointerOverTrayIcon(liveArguments.getBounds())) {
return null;
}
return MouseInfo.getPointerInfo().getLocation();
}
});
if (pointer == null) {
return;
}
show(new Point(pointer.x, pointer.y), TOOLTIP_MOUSE_CURSOR_INDENT);
}
});
}
public void enter() {
XToolkit.schedule(starter, TOOLTIP_START_DELAY_TIME);
}
public void exit() {
XToolkit.remove(starter);
if (isVisible()) {
hide();
}
}
private boolean isPointerOverTrayIcon(Rectangle trayRect) {
Point p = MouseInfo.getPointerInfo().getLocation();
return !(p.x < trayRect.x || p.x > (trayRect.x + trayRect.width) ||
p.y < trayRect.y || p.y > (trayRect.y + trayRect.height));
}
}
public static class Balloon extends InfoWindow {
public interface LiveArguments extends InfoWindow.LiveArguments {
/** The action to be performed upon clicking the baloon. */
String getActionCommand();
}
private final LiveArguments liveArguments;
private final Object target;
private final static int BALLOON_SHOW_TIME = 10000;
private final static int BALLOON_TEXT_MAX_LENGTH = 256;
private final static int BALLOON_WORD_LINE_MAX_LENGTH = 16;
private final static int BALLOON_WORD_LINE_MAX_COUNT = 4;
private final static int BALLOON_ICON_WIDTH = 32;
private final static int BALLOON_ICON_HEIGHT = 32;
private final static int BALLOON_TRAY_ICON_INDENT = 0;
private final static Color BALLOON_CAPTION_BACKGROUND_COLOR = new Color(200, 200 ,255);
private final static Font BALLOON_CAPTION_FONT = new Font(Font.DIALOG, Font.BOLD, 12);
private Panel mainPanel = new Panel();
private Panel captionPanel = new Panel();
private Label captionLabel = new Label("");
private Button closeButton = new Button("X");
private Panel textPanel = new Panel();
private XTrayIconPeer.IconCanvas iconCanvas = new XTrayIconPeer.IconCanvas(BALLOON_ICON_WIDTH, BALLOON_ICON_HEIGHT);
private Label[] lineLabels = new Label[BALLOON_WORD_LINE_MAX_COUNT];
private ActionPerformer ap = new ActionPerformer();
private Image iconImage;
private Image errorImage;
private Image warnImage;
private Image infoImage;
private boolean gtkImagesLoaded;
private Displayer displayer = new Displayer();
public Balloon(Frame parent, Object target, LiveArguments liveArguments) {
super(parent, new Color(90, 80 ,190));
this.liveArguments = liveArguments;
this.target = target;
XTrayIconPeer.suppressWarningString(this);
setCloser(new Runnable() {
public void run() {
if (textPanel != null) {
textPanel.removeAll();
textPanel.setSize(0, 0);
iconCanvas.setSize(0, 0);
XToolkit.awtLock();
try {
displayer.isDisplayed = false;
XToolkit.awtLockNotifyAll();
} finally {
XToolkit.awtUnlock();
}
}
}
}, BALLOON_SHOW_TIME);
add(mainPanel);
captionLabel.setFont(BALLOON_CAPTION_FONT);
captionLabel.addMouseListener(ap);
captionPanel.setLayout(new BorderLayout());
captionPanel.add(captionLabel, BorderLayout.WEST);
captionPanel.add(closeButton, BorderLayout.EAST);
captionPanel.setBackground(BALLOON_CAPTION_BACKGROUND_COLOR);
captionPanel.addMouseListener(ap);
closeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
hide();
}
});
mainPanel.setLayout(new BorderLayout());
mainPanel.setBackground(Color.white);
mainPanel.add(captionPanel, BorderLayout.NORTH);
mainPanel.add(iconCanvas, BorderLayout.WEST);
mainPanel.add(textPanel, BorderLayout.CENTER);
iconCanvas.addMouseListener(ap);
for (int i = 0; i < BALLOON_WORD_LINE_MAX_COUNT; i++) {
lineLabels[i] = new Label();
lineLabels[i].addMouseListener(ap);
lineLabels[i].setBackground(Color.white);
}
displayer.start();
}
public void display(String caption, String text, String messageType) {
if (!gtkImagesLoaded) {
loadGtkImages();
}
displayer.display(caption, text, messageType);
}
private void _display(String caption, String text, String messageType) {
captionLabel.setText(caption);
BreakIterator iter = BreakIterator.getWordInstance();
if (text != null) {
iter.setText(text);
int start = iter.first(), end;
int nLines = 0;
do {
end = iter.next();
if (end == BreakIterator.DONE ||
text.substring(start, end).length() >= 50)
{
lineLabels[nLines].setText(text.substring(start, end == BreakIterator.DONE ?
iter.last() : end));
textPanel.add(lineLabels[nLines++]);
start = end;
}
if (nLines == BALLOON_WORD_LINE_MAX_COUNT) {
if (end != BreakIterator.DONE) {
lineLabels[nLines - 1].setText(
new String(lineLabels[nLines - 1].getText() + " ..."));
}
break;
}
} while (end != BreakIterator.DONE);
textPanel.setLayout(new GridLayout(nLines, 1));
}
if ("ERROR".equals(messageType)) {
iconImage = errorImage;
} else if ("WARNING".equals(messageType)) {
iconImage = warnImage;
} else if ("INFO".equals(messageType)) {
iconImage = infoImage;
} else {
iconImage = null;
}
if (iconImage != null) {
Dimension tpSize = textPanel.getSize();
iconCanvas.setSize(BALLOON_ICON_WIDTH, (BALLOON_ICON_HEIGHT > tpSize.height ?
BALLOON_ICON_HEIGHT : tpSize.height));
iconCanvas.validate();
}
SunToolkit.executeOnEventHandlerThread(target, new Runnable() {
public void run() {
if (liveArguments.isDisposed()) {
return;
}
Point parLoc = getParent().getLocationOnScreen();
Dimension parSize = getParent().getSize();
show(new Point(parLoc.x + parSize.width/2, parLoc.y + parSize.height/2),
BALLOON_TRAY_ICON_INDENT);
if (iconImage != null) {
iconCanvas.updateImage(iconImage); // call it after the show(..) above
}
}
});
}
public void dispose() {
displayer.interrupt();
super.dispose();
}
private void loadGtkImages() {
if (!gtkImagesLoaded) {
errorImage = (Image)Toolkit.getDefaultToolkit().getDesktopProperty(
"gtk.icon.gtk-dialog-error.6.rtl");
warnImage = (Image)Toolkit.getDefaultToolkit().getDesktopProperty(
"gtk.icon.gtk-dialog-warning.6.rtl");
infoImage = (Image)Toolkit.getDefaultToolkit().getDesktopProperty(
"gtk.icon.gtk-dialog-info.6.rtl");
gtkImagesLoaded = true;
}
}
private class ActionPerformer extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
// hide the balloon by any click
hide();
if (e.getButton() == MouseEvent.BUTTON1) {
ActionEvent aev = new ActionEvent(target, ActionEvent.ACTION_PERFORMED,
liveArguments.getActionCommand(),
e.getWhen(), e.getModifiers());
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(aev);
}
}
}
private class Displayer extends Thread {
final int MAX_CONCURRENT_MSGS = 10;
ArrayBlockingQueue<Message> messageQueue = new ArrayBlockingQueue<Message>(MAX_CONCURRENT_MSGS);
boolean isDisplayed;
Displayer() {
setDaemon(true);
}
public void run() {
while (true) {
Message msg = null;
try {
msg = (Message)messageQueue.take();
} catch (InterruptedException e) {
return;
}
/*
* Wait till the previous message is displayed if any
*/
XToolkit.awtLock();
try {
while (isDisplayed) {
try {
XToolkit.awtLockWait();
} catch (InterruptedException e) {
return;
}
}
isDisplayed = true;
} finally {
XToolkit.awtUnlock();
}
_display(msg.caption, msg.text, msg.messageType);
}
}
void display(String caption, String text, String messageType) {
messageQueue.offer(new Message(caption, text, messageType));
}
}
private static class Message {
String caption, text, messageType;
Message(String caption, String text, String messageType) {
this.caption = caption;
this.text = text;
this.messageType = messageType;
}
}
}
}
/* /*
* 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
...@@ -684,4 +684,19 @@ final public class XConstants { ...@@ -684,4 +684,19 @@ final public class XConstants {
public static final int LSBFirst = 0 ; public static final int LSBFirst = 0 ;
public static final int MSBFirst = 1 ; public static final int MSBFirst = 1 ;
/* XKB support */
public static final int XkbUseCoreKbd = 0x0100 ;
public static final int XkbNewKeyboardNotify = 0;
public static final int XkbMapNotify = 1;
public static final int XkbStateNotify = 2;
public static final long XkbNewKeyboardNotifyMask = (1L << 0);
public static final long XkbMapNotifyMask = (1L << 1);
public static final long XkbStateNotifyMask = (1L << 2);
public static final long XkbGroupStateMask = (1L << 4);
public static final long XkbKeyTypesMask = (1L<<0);
public static final long XkbKeySymsMask = (1L<<1);
public static final long XkbModifierMapMask = (1L<<2);
public static final long XkbVirtualModsMask = (1L<<6); //server map
} }
...@@ -383,7 +383,7 @@ abstract class XDecoratedPeer extends XWindowPeer { ...@@ -383,7 +383,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
dimensions.setInsets(getRealInsets()); dimensions.setInsets(getRealInsets());
insets_corrected = true; insets_corrected = true;
if (isMaximized() || isNull(correction)) { if (isMaximized()) {
return; return;
} }
...@@ -451,7 +451,7 @@ abstract class XDecoratedPeer extends XWindowPeer { ...@@ -451,7 +451,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
public Insets getInsets() { public Insets getInsets() {
Insets in = copy(getRealInsets()); Insets in = copy(getRealInsets());
in.top += getMenuBarHeight() + getWarningWindowHeight(); in.top += getMenuBarHeight();
if (insLog.isLoggable(Level.FINEST)) { if (insLog.isLoggable(Level.FINEST)) {
insLog.log(Level.FINEST, "Get insets returns {0}", new Object[] {in}); insLog.log(Level.FINEST, "Get insets returns {0}", new Object[] {in});
} }
...@@ -802,6 +802,8 @@ abstract class XDecoratedPeer extends XWindowPeer { ...@@ -802,6 +802,8 @@ abstract class XDecoratedPeer extends XWindowPeer {
} }
reconfigureContentWindow(newDimensions); reconfigureContentWindow(newDimensions);
updateChildrenSizes(); updateChildrenSizes();
repositionSecurityWarning();
} }
private void checkShellRectSize(Rectangle shellRect) { private void checkShellRectSize(Rectangle shellRect) {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册