aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlana <none@none>2009-04-09 13:12:58 -0700
committerlana <none@none>2009-04-09 13:12:58 -0700
commiteb3b76ea51e2441625f57b66bb7b5814d9abb341 (patch)
treec3297c6d46ecd0d9570ca67090122aa0299a286f /src
parent016dd007e21e20d9b59186ffbd4857acbf430237 (diff)
parent9ef44fa316c87f58aabdb936a5a3c9eb89f89099 (diff)
Merge
Diffstat (limited to 'src')
-rw-r--r--src/share/classes/com/sun/awt/AWTUtilities.java362
-rw-r--r--src/share/classes/com/sun/awt/SecurityWarning.java169
-rw-r--r--src/share/classes/java/awt/AWTKeyStroke.java5
-rw-r--r--src/share/classes/java/awt/Canvas.java13
-rw-r--r--src/share/classes/java/awt/Component.java173
-rw-r--r--src/share/classes/java/awt/Container.java206
-rw-r--r--src/share/classes/java/awt/DefaultKeyboardFocusManager.java2
-rw-r--r--src/share/classes/java/awt/Dialog.java2
-rw-r--r--src/share/classes/java/awt/Frame.java36
-rw-r--r--src/share/classes/java/awt/GraphicsConfiguration.java18
-rw-r--r--src/share/classes/java/awt/GraphicsDevice.java135
-rw-r--r--src/share/classes/java/awt/KeyboardFocusManager.java111
-rw-r--r--src/share/classes/java/awt/MenuItem.java6
-rw-r--r--src/share/classes/java/awt/MenuShortcut.java18
-rw-r--r--src/share/classes/java/awt/Window.java423
-rw-r--r--src/share/classes/java/awt/event/KeyEvent.java58
-rw-r--r--src/share/classes/java/awt/peer/CanvasPeer.java10
-rw-r--r--src/share/classes/java/awt/peer/ComponentPeer.java12
-rw-r--r--src/share/classes/java/awt/peer/ContainerPeer.java17
-rw-r--r--src/share/classes/java/awt/peer/WindowPeer.java31
-rw-r--r--src/share/classes/javax/swing/AbstractButton.java5
-rw-r--r--src/share/classes/javax/swing/Action.java6
-rw-r--r--src/share/classes/javax/swing/JComponent.java19
-rw-r--r--src/share/classes/javax/swing/JLabel.java10
-rw-r--r--src/share/classes/javax/swing/JTabbedPane.java6
-rw-r--r--src/share/classes/javax/swing/KeyStroke.java8
-rw-r--r--src/share/classes/javax/swing/KeyboardManager.java27
-rw-r--r--src/share/classes/javax/swing/RepaintManager.java45
-rw-r--r--src/share/classes/javax/swing/SwingUtilities.java11
-rw-r--r--src/share/classes/sun/awt/AWTAccessor.java268
-rw-r--r--src/share/classes/sun/awt/ComponentAccessor.java16
-rw-r--r--src/share/classes/sun/awt/EmbeddedFrame.java13
-rw-r--r--src/share/classes/sun/awt/ExtendedKeyCodes.java670
-rw-r--r--src/share/classes/sun/awt/HeadlessToolkit.java6
-rw-r--r--src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java153
-rw-r--r--src/share/classes/sun/awt/NullComponentPeer.java28
-rw-r--r--src/share/classes/sun/awt/SunToolkit.java123
-rw-r--r--src/share/native/sun/awt/utility/rect.c102
-rw-r--r--src/solaris/classes/sun/awt/X11/InfoWindow.java495
-rw-r--r--src/solaris/classes/sun/awt/X11/XBaseWindow.java54
-rw-r--r--src/solaris/classes/sun/awt/X11/XCanvasPeer.java80
-rw-r--r--src/solaris/classes/sun/awt/X11/XComponentPeer.java208
-rw-r--r--src/solaris/classes/sun/awt/X11/XConstants.java17
-rw-r--r--src/solaris/classes/sun/awt/X11/XDecoratedPeer.java6
-rw-r--r--src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java14
-rw-r--r--src/solaris/classes/sun/awt/X11/XFileDialogPeer.java30
-rw-r--r--src/solaris/classes/sun/awt/X11/XFramePeer.java20
-rw-r--r--src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java155
-rw-r--r--src/solaris/classes/sun/awt/X11/XKeysym.java58
-rw-r--r--src/solaris/classes/sun/awt/X11/XNETProtocol.java64
-rw-r--r--src/solaris/classes/sun/awt/X11/XPanelPeer.java33
-rw-r--r--src/solaris/classes/sun/awt/X11/XToolkit.java184
-rw-r--r--src/solaris/classes/sun/awt/X11/XTrayIconPeer.java456
-rw-r--r--src/solaris/classes/sun/awt/X11/XWM.java2
-rw-r--r--src/solaris/classes/sun/awt/X11/XWarningWindow.java375
-rw-r--r--src/solaris/classes/sun/awt/X11/XWindow.java231
-rw-r--r--src/solaris/classes/sun/awt/X11/XWindowPeer.java261
-rw-r--r--src/solaris/classes/sun/awt/X11/XlibWrapper.java35
-rw-r--r--src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java7
-rw-r--r--src/solaris/classes/sun/awt/X11/generator/sizes.64-solaris-i386213
-rw-r--r--src/solaris/classes/sun/awt/X11/generator/xlibtypes.txt231
-rw-r--r--src/solaris/classes/sun/awt/X11/keysym2ucs.h60
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-bw16.pngbin0 -> 463 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-bw24.pngbin0 -> 682 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-bw32.pngbin0 -> 795 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-bw48.pngbin0 -> 1137 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-interim16.pngbin0 -> 489 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-interim24.pngbin0 -> 741 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-interim32.pngbin0 -> 871 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-interim48.pngbin0 -> 1387 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-yellow16.pngbin0 -> 477 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-yellow24.pngbin0 -> 749 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-yellow32.pngbin0 -> 866 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11/security-icon-yellow48.pngbin0 -> 1323 bytes
-rw-r--r--src/solaris/classes/sun/awt/X11GraphicsConfig.java11
-rw-r--r--src/solaris/classes/sun/awt/motif/MToolkit.java4
-rw-r--r--src/solaris/native/sun/awt/awt_Component.h5
-rw-r--r--src/solaris/native/sun/awt/awt_GraphicsEnv.c102
-rw-r--r--src/solaris/native/sun/awt/awt_Window.h1
-rw-r--r--src/solaris/native/sun/awt/awt_p.h3
-rw-r--r--src/solaris/native/sun/awt/utility/rect.h11
-rw-r--r--src/solaris/native/sun/xawt/XToolkit.c6
-rw-r--r--src/solaris/native/sun/xawt/XlibWrapper.c198
-rw-r--r--src/windows/classes/sun/awt/Win32GraphicsConfig.java10
-rw-r--r--src/windows/classes/sun/awt/Win32GraphicsDevice.java1
-rw-r--r--src/windows/classes/sun/awt/Win32GraphicsEnvironment.java9
-rw-r--r--src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java398
-rw-r--r--src/windows/classes/sun/awt/windows/WCanvasPeer.java65
-rw-r--r--src/windows/classes/sun/awt/windows/WChoicePeer.java36
-rw-r--r--src/windows/classes/sun/awt/windows/WComponentPeer.java208
-rw-r--r--src/windows/classes/sun/awt/windows/WFileDialogPeer.java20
-rw-r--r--src/windows/classes/sun/awt/windows/WFramePeer.java29
-rw-r--r--src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java75
-rw-r--r--src/windows/classes/sun/awt/windows/WPanelPeer.java28
-rw-r--r--src/windows/classes/sun/awt/windows/WPrintDialogPeer.java20
-rw-r--r--src/windows/classes/sun/awt/windows/WScrollPanePeer.java6
-rw-r--r--src/windows/classes/sun/awt/windows/WToolkit.java38
-rw-r--r--src/windows/classes/sun/awt/windows/WWindowPeer.java297
-rw-r--r--src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java17
-rw-r--r--src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java12
-rw-r--r--src/windows/native/sun/awt/utility/rect.h12
-rw-r--r--src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp14
-rw-r--r--src/windows/native/sun/java2d/opengl/WGLSurfaceData.c10
-rw-r--r--src/windows/native/sun/windows/ComCtl32Util.cpp4
-rw-r--r--src/windows/native/sun/windows/ComCtl32Util.h6
-rw-r--r--src/windows/native/sun/windows/DllUtil.cpp87
-rw-r--r--src/windows/native/sun/windows/DllUtil.h97
-rw-r--r--src/windows/native/sun/windows/awt.rc7
-rw-r--r--src/windows/native/sun/windows/awt_BitmapUtil.cpp226
-rw-r--r--src/windows/native/sun/windows/awt_BitmapUtil.h28
-rw-r--r--src/windows/native/sun/windows/awt_Button.cpp61
-rw-r--r--src/windows/native/sun/windows/awt_Button.h6
-rw-r--r--src/windows/native/sun/windows/awt_Canvas.cpp27
-rw-r--r--src/windows/native/sun/windows/awt_Checkbox.cpp46
-rw-r--r--src/windows/native/sun/windows/awt_Checkbox.h3
-rw-r--r--src/windows/native/sun/windows/awt_Choice.cpp198
-rw-r--r--src/windows/native/sun/windows/awt_Choice.h12
-rw-r--r--src/windows/native/sun/windows/awt_Component.cpp805
-rw-r--r--src/windows/native/sun/windows/awt_Component.h112
-rw-r--r--src/windows/native/sun/windows/awt_Dialog.cpp105
-rw-r--r--src/windows/native/sun/windows/awt_Dialog.h7
-rw-r--r--src/windows/native/sun/windows/awt_FileDialog.cpp12
-rw-r--r--src/windows/native/sun/windows/awt_Frame.cpp241
-rw-r--r--src/windows/native/sun/windows/awt_Frame.h32
-rw-r--r--src/windows/native/sun/windows/awt_InputMethod.cpp4
-rw-r--r--src/windows/native/sun/windows/awt_KeyEvent.cpp15
-rw-r--r--src/windows/native/sun/windows/awt_KeyEvent.h5
-rw-r--r--src/windows/native/sun/windows/awt_KeyboardFocusManager.cpp97
-rw-r--r--src/windows/native/sun/windows/awt_KeyboardFocusManager.h43
-rw-r--r--src/windows/native/sun/windows/awt_List.cpp119
-rw-r--r--src/windows/native/sun/windows/awt_List.h9
-rw-r--r--src/windows/native/sun/windows/awt_Panel.cpp78
-rw-r--r--src/windows/native/sun/windows/awt_Panel.h3
-rw-r--r--src/windows/native/sun/windows/awt_PrintDialog.cpp14
-rw-r--r--src/windows/native/sun/windows/awt_PrintJob.cpp12
-rw-r--r--src/windows/native/sun/windows/awt_ScrollPane.cpp16
-rw-r--r--src/windows/native/sun/windows/awt_ScrollPane.h3
-rw-r--r--src/windows/native/sun/windows/awt_Scrollbar.cpp65
-rw-r--r--src/windows/native/sun/windows/awt_Scrollbar.h7
-rw-r--r--src/windows/native/sun/windows/awt_TextArea.cpp53
-rw-r--r--src/windows/native/sun/windows/awt_TextComponent.cpp30
-rw-r--r--src/windows/native/sun/windows/awt_TextComponent.h7
-rw-r--r--src/windows/native/sun/windows/awt_TextField.cpp224
-rw-r--r--src/windows/native/sun/windows/awt_Toolkit.cpp193
-rw-r--r--src/windows/native/sun/windows/awt_Toolkit.h45
-rw-r--r--src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp42
-rw-r--r--src/windows/native/sun/windows/awt_Window.cpp1400
-rw-r--r--src/windows/native/sun/windows/awt_Window.h130
-rw-r--r--src/windows/native/sun/windows/awtmsg.h3
-rw-r--r--src/windows/native/sun/windows/security_warning.icobin0 -> 17542 bytes
-rw-r--r--src/windows/native/sun/windows/security_warning_bw.icobin0 -> 17542 bytes
-rw-r--r--src/windows/native/sun/windows/security_warning_int.icobin0 -> 17542 bytes
152 files changed, 9650 insertions, 3347 deletions
diff --git a/src/share/classes/com/sun/awt/AWTUtilities.java b/src/share/classes/com/sun/awt/AWTUtilities.java
index 818ac6f53..bf0628b47 100644
--- a/src/share/classes/com/sun/awt/AWTUtilities.java
+++ b/src/share/classes/com/sun/awt/AWTUtilities.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,17 +26,37 @@
package com.sun.awt;
import java.awt.*;
-import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor;
+import sun.awt.SunToolkit;
/**
* A collection of utility methods for AWT.
*
* The functionality provided by the static methods of the class includes:
* <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.
* </ul>
* <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
* for limited use outside of the core platform. This API may change
* drastically between update release, and it may even be
@@ -50,6 +70,344 @@ public final class 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.
*
diff --git a/src/share/classes/com/sun/awt/SecurityWarning.java b/src/share/classes/com/sun/awt/SecurityWarning.java
new file mode 100644
index 000000000..46dea3854
--- /dev/null
+++ b/src/share/classes/com/sun/awt/SecurityWarning.java
@@ -0,0 +1,169 @@
+/*
+ * 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);
+ }
+}
+
diff --git a/src/share/classes/java/awt/AWTKeyStroke.java b/src/share/classes/java/awt/AWTKeyStroke.java
index 12e43dc0a..35f57bae3 100644
--- a/src/share/classes/java/awt/AWTKeyStroke.java
+++ b/src/share/classes/java/awt/AWTKeyStroke.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -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_SPACE</code>
* </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>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
diff --git a/src/share/classes/java/awt/Canvas.java b/src/share/classes/java/awt/Canvas.java
index 04b3bc2dc..86315e7c1 100644
--- a/src/share/classes/java/awt/Canvas.java
+++ b/src/share/classes/java/awt/Canvas.java
@@ -25,6 +25,7 @@
package java.awt;
import java.awt.image.BufferStrategy;
+import java.awt.peer.CanvasPeer;
import javax.accessibility.*;
/**
@@ -65,7 +66,17 @@ public class Canvas extends Component implements Accessible {
*/
public Canvas(GraphicsConfiguration config) {
this();
- graphicsConfig = config;
+ setGraphicsConfiguration(config);
+ }
+
+ @Override
+ void setGraphicsConfiguration(GraphicsConfiguration gc) {
+ CanvasPeer peer = (CanvasPeer)getPeer();
+ if (peer != null) {
+ gc = peer.getAppropriateGraphicsConfiguration(gc);
+ }
+
+ super.setGraphicsConfiguration(gc);
}
/**
diff --git a/src/share/classes/java/awt/Component.java b/src/share/classes/java/awt/Component.java
index afe091dcc..03743332f 100644
--- a/src/share/classes/java/awt/Component.java
+++ b/src/share/classes/java/awt/Component.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -300,7 +300,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
* @see GraphicsConfiguration
* @see #getGraphicsConfiguration
*/
- transient GraphicsConfiguration graphicsConfig = null;
+ private transient GraphicsConfiguration graphicsConfig = null;
/**
* A reference to a <code>BufferStrategy</code> object
@@ -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 {
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) {
Region region = shape == null ? null :
Region.getInstance(shape, null);
@@ -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,
*/
public GraphicsConfiguration getGraphicsConfiguration() {
synchronized(getTreeLock()) {
- if (graphicsConfig != null) {
- return graphicsConfig;
- } else if (getParent() != null) {
- return getParent().getGraphicsConfiguration();
- } else {
- return null;
- }
+ return getGraphicsConfiguration_NoClientCode();
}
}
final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
- GraphicsConfiguration graphicsConfig = this.graphicsConfig;
- Container parent = this.parent;
- if (graphicsConfig != null) {
- return graphicsConfig;
- } else if (parent != null) {
- return parent.getGraphicsConfiguration_NoClientCode();
- } else {
- return null;
- }
+ return graphicsConfig;
}
- /**
- * 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() {
+ void setGraphicsConfiguration(GraphicsConfiguration gc) {
synchronized(getTreeLock()) {
- graphicsConfig = null;
- }
- }
+ graphicsConfig = gc;
- /*
- * Not called on Component, but needed for Canvas and Window
- */
- 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;
+ ComponentPeer peer = getPeer();
+ if (peer != null) {
+ peer.updateGraphicsData(gc);
}
}
}
@@ -6663,23 +6666,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
// Update stacking order
- if (parent != null && parent.peer != null) {
- 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();
- }
- }
+ peer.setZOrder(getHWPeerAboveMe());
if (!isAddNotifyComplete) {
mixOnShowing();
@@ -7170,8 +7157,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
requestFocusHelper(false, true);
}
- void requestFocus(CausedFocusEvent.Cause cause) {
- requestFocusHelper(false, true, cause);
+ boolean requestFocus(CausedFocusEvent.Cause cause) {
+ return requestFocusHelper(false, true, cause);
}
/**
@@ -7456,7 +7443,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
// 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
focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
- if (focusOwner != null && getContainingWindow(focusOwner) != window) {
+ if (focusOwner != null && focusOwner.getContainingWindow() != window) {
focusOwner = null;
}
}
@@ -8689,31 +8676,9 @@ public abstract class Component implements ImageObserver, MenuContainer,
* null, if component is not a part of window hierarchy
*/
Window getContainingWindow() {
- return 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;
+ return SunToolkit.getContainingWindow(this);
}
-
-
-
-
-
-
-
-
-
-
/**
* Initialize JNI field and method IDs
*/
@@ -9575,6 +9540,27 @@ public abstract class Component implements ImageObserver, MenuContainer,
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() {
checkTreeLock();
Container parent = getContainer();
@@ -9827,4 +9813,29 @@ public abstract class Component implements ImageObserver, MenuContainer,
}
// ****************** 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);
+ }
}
diff --git a/src/share/classes/java/awt/Container.java b/src/share/classes/java/awt/Container.java
index 04425d5a4..9a184a7a2 100644
--- a/src/share/classes/java/awt/Container.java
+++ b/src/share/classes/java/awt/Container.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -167,6 +167,9 @@ public class Container extends Component {
transient int listeningBoundsChildren;
transient int descendantsCount;
+ /* Non-opaque window support -- see Window.setLayersOpaque */
+ transient Color preserveBackgroundColor = null;
+
/**
* JDK 1.1 serialVersionUID
*/
@@ -267,9 +270,13 @@ public class Container extends Component {
/**
* 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.
* @see #getComponent
* @since JDK1.1
+ * @see Component#getTreeLock()
*/
public int getComponentCount() {
return countComponents();
@@ -281,43 +288,65 @@ public class Container extends Component {
*/
@Deprecated
public int countComponents() {
- synchronized (getTreeLock()) {
- return component.size();
- }
+ // This method is not synchronized under AWT tree lock.
+ // Instead, the calling code is responsible for the
+ // synchronization. See 6784816 for details.
+ return component.size();
}
/**
* 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.
* @return the n<sup>th</sup> component in this container.
* @exception ArrayIndexOutOfBoundsException
* if the n<sup>th</sup> value does not exist.
+ * @see Component#getTreeLock()
*/
public Component getComponent(int n) {
- synchronized (getTreeLock()) {
- if ((n < 0) || (n >= component.size())) {
- throw new ArrayIndexOutOfBoundsException("No such child: " + n);
- }
+ // This method is not synchronized under AWT tree lock.
+ // Instead, the calling code is responsible for the
+ // synchronization. See 6784816 for details.
+ try {
return component.get(n);
+ } catch (IndexOutOfBoundsException z) {
+ throw new ArrayIndexOutOfBoundsException("No such child: " + n);
}
}
/**
* 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.
+ * @see Component#getTreeLock()
*/
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();
}
+
// NOTE: This method may be called by privileged threads.
// This functionality is implemented in a package-private method
// to insure that it cannot be overridden by client subclasses.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
final Component[] getComponents_NoClientCode() {
+ return component.toArray(EMPTY_ARRAY);
+ }
+
+ /*
+ * Wrapper for getComponents() method with a proper synchronization.
+ */
+ Component[] getComponentsSync() {
synchronized (getTreeLock()) {
- return component.toArray(EMPTY_ARRAY);
+ return getComponents();
}
- } // getComponents_NoClientCode()
+ }
/**
* Determines the insets of this container, which indicate the size
@@ -503,6 +532,9 @@ public class Container extends Component {
adjustDescendants(-(comp.countHierarchyMembers()));
comp.parent = null;
+ if (needRemoveNotify) {
+ comp.setGraphicsConfiguration(null);
+ }
component.remove(index);
invalidateIfValid();
@@ -643,10 +675,7 @@ public class Container extends Component {
// each HW descendant independently.
return !comp.peer.isReparentSupported();
} else {
- // if container didn't change we still might need to recreate component's window as
- // 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();
+ return false;
}
}
@@ -786,6 +815,7 @@ public class Container extends Component {
component.add(index, comp);
}
comp.parent = this;
+ comp.setGraphicsConfiguration(getGraphicsConfiguration());
adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
@@ -802,11 +832,6 @@ public class Container extends Component {
if (peer != null) {
if (comp.peer == null) { // Remove notify was called or it didn't have peer - create new one
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.
// In both cases we need to reparent native widgets.
Container newNativeContainer = getHeavyweightContainer();
@@ -815,13 +840,8 @@ public class Container extends Component {
// Native container changed - need to reparent native widgets
newNativeContainer.reparentChild(comp);
}
- // If component still has a peer and it is either container or heavyweight
- // 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();
- }
+ comp.peer.setZOrder(comp.getHWPeerAboveMe());
+
if (!comp.isLightweight() && isLightweight()) {
// If component is heavyweight and one of the containers is lightweight
// the location of the component should be fixed.
@@ -1034,9 +1054,9 @@ public class Container extends Component {
}
checkAddToSelf(comp);
checkNotAWindow(comp);
- if (thisGC != null) {
- comp.checkGD(thisGC.getDevice().getIDstring());
- }
+ if (thisGC != null) {
+ comp.checkGD(thisGC.getDevice().getIDstring());
+ }
/* Reparent the component and tidy up the tree's state. */
if (comp.parent != null) {
@@ -1053,6 +1073,7 @@ public class Container extends Component {
component.add(index, comp);
}
comp.parent = this;
+ comp.setGraphicsConfiguration(thisGC);
adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
@@ -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
* the same GraphicsDevice as this Container. If not, throws an
@@ -1148,6 +1182,7 @@ public class Container extends Component {
comp.parent = null;
component.remove(index);
+ comp.setGraphicsConfiguration(null);
invalidateIfValid();
if (containerListener != null ||
@@ -1224,6 +1259,7 @@ public class Container extends Component {
layoutMgr.removeLayoutComponent(comp);
}
comp.parent = null;
+ comp.setGraphicsConfiguration(null);
if (containerListener != null ||
(eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
@@ -1339,7 +1375,7 @@ public class Container extends Component {
}
private int getListenersCount(int id, boolean enabledOnToolkit) {
- assert Thread.holdsLock(getTreeLock());
+ checkTreeLock();
if (enabledOnToolkit) {
return descendantsCount;
}
@@ -1357,7 +1393,7 @@ public class Container extends Component {
final int createHierarchyEvents(int id, Component changed,
Container changedParent, long changeFlags, boolean enabledOnToolkit)
{
- assert Thread.holdsLock(getTreeLock());
+ checkTreeLock();
int listeners = getListenersCount(id, enabledOnToolkit);
for (int count = listeners, i = 0; count > 0; i++) {
@@ -1372,7 +1408,7 @@ public class Container extends Component {
final void createChildHierarchyEvents(int id, long changeFlags,
boolean enabledOnToolkit)
{
- assert Thread.holdsLock(getTreeLock());
+ checkTreeLock();
if (component.isEmpty()) {
return;
}
@@ -1507,6 +1543,7 @@ public class Container extends Component {
* @see #validate
*/
protected void validateTree() {
+ checkTreeLock();
if (!isValid()) {
if (peer instanceof ContainerPeer) {
((ContainerPeer)peer).beginLayout();
@@ -1783,7 +1820,7 @@ public class Container extends Component {
// super.paint(); -- Don't bother, since it's a NOP.
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 {
}
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 {
public void paintComponents(Graphics g) {
if (isShowing()) {
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 {
void paintHeavyweightComponents(Graphics g) {
if (isShowing()) {
GraphicsCallback.PaintHeavyweightComponentsCallback.getInstance().
- runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS |
- GraphicsCallback.HEAVYWEIGHTS);
+ runComponents(getComponentsSync(), g,
+ GraphicsCallback.LIGHTWEIGHTS | GraphicsCallback.HEAVYWEIGHTS);
}
}
@@ -1887,7 +1924,7 @@ public class Container extends Component {
public void printComponents(Graphics g) {
if (isShowing()) {
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 {
void printHeavyweightComponents(Graphics g) {
if (isShowing()) {
GraphicsCallback.PrintHeavyweightComponentsCallback.getInstance().
- runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS |
- GraphicsCallback.HEAVYWEIGHTS);
+ runComponents(getComponentsSync(), g,
+ GraphicsCallback.LIGHTWEIGHTS | GraphicsCallback.HEAVYWEIGHTS);
}
}
@@ -2460,9 +2497,7 @@ public class Container extends Component {
* @since 1.2
*/
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 {
* The addition of this feature is temporary, pending the
* adoption of new, public API which exports this feature.
*/
- final Component findComponentAt(int x, int y, boolean ignoreEnabled)
- {
- if (isRecursivelyVisible()){
- return findComponentAtImpl(x, y, ignoreEnabled);
+ final Component findComponentAt(int x, int y, boolean ignoreEnabled) {
+ synchronized (getTreeLock()) {
+ if (isRecursivelyVisible()){
+ return findComponentAtImpl(x, y, ignoreEnabled);
+ }
}
return null;
}
final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled){
+ checkTreeLock();
+
if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
return null;
}
// Two passes: see comment in sun.awt.SunGraphicsCallback
- synchronized (getTreeLock()) {
- for (int i = 0; i < component.size(); i++) {
- Component comp = component.get(i);
- if (comp != null &&
- !(comp.peer instanceof LightweightPeer)) {
- if (comp instanceof Container) {
- comp = ((Container)comp).findComponentAtImpl(x - comp.x,
- y - comp.y,
- ignoreEnabled);
- } else {
- comp = comp.locate(x - comp.x, y - comp.y);
- }
- if (comp != null && comp.visible &&
- (ignoreEnabled || comp.enabled))
- {
- return comp;
- }
+ for (int i = 0; i < component.size(); i++) {
+ Component comp = component.get(i);
+ if (comp != null &&
+ !(comp.peer instanceof LightweightPeer)) {
+ if (comp instanceof Container) {
+ comp = ((Container)comp).findComponentAtImpl(x - comp.x,
+ y - comp.y,
+ ignoreEnabled);
+ } else {
+ comp = comp.locate(x - comp.x, y - comp.y);
+ }
+ if (comp != null && comp.visible &&
+ (ignoreEnabled || comp.enabled))
+ {
+ return comp;
}
}
- for (int i = 0; i < component.size(); i++) {
- Component comp = component.get(i);
- if (comp != null &&
- comp.peer instanceof LightweightPeer) {
- if (comp instanceof Container) {
- comp = ((Container)comp).findComponentAtImpl(x - comp.x,
- y - comp.y,
- ignoreEnabled);
- } else {
- comp = comp.locate(x - comp.x, y - comp.y);
- }
- if (comp != null && comp.visible &&
- (ignoreEnabled || comp.enabled))
- {
- return comp;
- }
+ }
+ for (int i = 0; i < component.size(); i++) {
+ Component comp = component.get(i);
+ if (comp != null &&
+ comp.peer instanceof LightweightPeer) {
+ if (comp instanceof Container) {
+ comp = ((Container)comp).findComponentAtImpl(x - comp.x,
+ y - comp.y,
+ ignoreEnabled);
+ } else {
+ comp = comp.locate(x - comp.x, y - comp.y);
+ }
+ if (comp != null && comp.visible &&
+ (ignoreEnabled || comp.enabled))
+ {
+ return comp;
}
}
}
+
return this;
}
@@ -2584,13 +2621,6 @@ public class Container extends Component {
for (int i = 0; i < component.size(); i++) {
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 {
private void writeObject(ObjectOutputStream s) throws IOException {
ObjectOutputStream.PutField f = s.putFields();
f.put("ncomponents", component.size());
- f.put("component", component.toArray(EMPTY_ARRAY));
+ f.put("component", getComponentsSync());
f.put("layoutMgr", layoutMgr);
f.put("dispatcher", dispatcher);
f.put("maxSize", maxSize);
diff --git a/src/share/classes/java/awt/DefaultKeyboardFocusManager.java b/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
index 5dd0d9061..71342bdae 100644
--- a/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
+++ b/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
@@ -479,7 +479,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
// that a Component outside of the focused Window receives a
// FOCUS_GAINED event. We synthesize a WINDOW_GAINED_FOCUS
// event in that case.
- final Window newFocusedWindow = Component.getContainingWindow(newFocusOwner);
+ final Window newFocusedWindow = SunToolkit.getContainingWindow(newFocusOwner);
final Window currentFocusedWindow = getGlobalFocusedWindow();
if (newFocusedWindow != null &&
newFocusedWindow != currentFocusedWindow)
diff --git a/src/share/classes/java/awt/Dialog.java b/src/share/classes/java/awt/Dialog.java
index 310e52350..a67d94a32 100644
--- a/src/share/classes/java/awt/Dialog.java
+++ b/src/share/classes/java/awt/Dialog.java
@@ -1226,7 +1226,7 @@ public class Dialog extends Window {
synchronized (getTreeLock()) {
if (keepBlockingEDT) {
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();
if (showAppContext != curAppContext) {
// Wake up event dispatch thread on which the dialog was
diff --git a/src/share/classes/java/awt/Frame.java b/src/share/classes/java/awt/Frame.java
index 290f7f9bb..761b9b842 100644
--- a/src/share/classes/java/awt/Frame.java
+++ b/src/share/classes/java/awt/Frame.java
@@ -36,6 +36,7 @@ import java.io.ObjectInputStream;
import java.io.IOException;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
+import sun.awt.AWTAccessor;
import java.lang.ref.WeakReference;
import javax.accessibility.*;
@@ -738,11 +739,15 @@ public class Frame extends Window implements MenuContainer {
* @since 1.4
* @see java.awt.Window#addWindowStateListener
*/
- public synchronized void setExtendedState(int state) {
+ public void setExtendedState(int state) {
if ( !isFrameStateSupported( state ) ) {
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;
if (peer != null) {
peer.setState(state);
@@ -804,12 +809,27 @@ public class Frame extends Window implements MenuContainer {
* @see #setExtendedState(int)
* @since 1.4
*/
- public synchronized int getExtendedState() {
- FramePeer peer = (FramePeer)this.peer;
- if (peer != null) {
- state = peer.getState();
+ public int getExtendedState() {
+ synchronized (getObjectLock()) {
+ return state;
}
- 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 {
if (resizable) {
str += ",resizable";
}
- getExtendedState(); // sync with peer
+ int state = getExtendedState();
if (state == NORMAL) {
str += ",normal";
}
diff --git a/src/share/classes/java/awt/GraphicsConfiguration.java b/src/share/classes/java/awt/GraphicsConfiguration.java
index 03b147f8a..c520d310b 100644
--- a/src/share/classes/java/awt/GraphicsConfiguration.java
+++ b/src/share/classes/java/awt/GraphicsConfiguration.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -434,4 +434,20 @@ public abstract class GraphicsConfiguration {
}
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;
}
+}
diff --git a/src/share/classes/java/awt/GraphicsDevice.java b/src/share/classes/java/awt/GraphicsDevice.java
index 47b578129..920687150 100644
--- a/src/share/classes/java/awt/GraphicsDevice.java
+++ b/src/share/classes/java/awt/GraphicsDevice.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,10 @@
package java.awt;
import java.awt.image.ColorModel;
+
+import sun.awt.AWTAccessor;
import sun.awt.AppContext;
+import sun.awt.SunToolkit;
/**
* The <code>GraphicsDevice</code> class describes the graphics devices
@@ -109,6 +112,31 @@ public abstract class GraphicsDevice {
*/
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>.
* @return the type of this <code>GraphicsDevice</code>, which can
@@ -235,6 +263,21 @@ public abstract class GraphicsDevice {
* @since 1.4
*/
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 the window went into fs mode before it was realized it may
// have (0,0) dimensions
@@ -424,4 +467,94 @@ public abstract class GraphicsDevice {
public int getAvailableAcceleratedMemory() {
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;
+ }
}
diff --git a/src/share/classes/java/awt/KeyboardFocusManager.java b/src/share/classes/java/awt/KeyboardFocusManager.java
index b84b93b02..521c70403 100644
--- a/src/share/classes/java/awt/KeyboardFocusManager.java
+++ b/src/share/classes/java/awt/KeyboardFocusManager.java
@@ -61,6 +61,7 @@ import sun.awt.HeadlessToolkit;
import sun.awt.SunToolkit;
import sun.awt.CausedFocusEvent;
import sun.awt.KeyboardFocusManagerPeerProvider;
+import sun.awt.AWTAccessor;
/**
* The KeyboardFocusManager is responsible for managing the active and focused
@@ -118,6 +119,32 @@ public abstract class KeyboardFocusManager
if (!GraphicsEnvironment.isHeadless()) {
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;
@@ -2208,7 +2235,7 @@ public abstract class KeyboardFocusManager
boolean temporary, boolean focusedWindowChangeAllowed,
long time)
{
- Window parentWindow = Component.getContainingWindow(heavyweight);
+ Window parentWindow = SunToolkit.getContainingWindow(heavyweight);
if (parentWindow == null || !parentWindow.syncLWRequests) {
return false;
}
@@ -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,
* or null if this is a duplicate request. The active Window is useful
@@ -2542,7 +2497,7 @@ public abstract class KeyboardFocusManager
(HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER);
Component activeWindow = ((hwFocusRequest != null)
- ? Component.getContainingWindow(hwFocusRequest.heavyweight)
+ ? SunToolkit.getContainingWindow(hwFocusRequest.heavyweight)
: nativeFocusedWindow);
while (activeWindow != null &&
!((activeWindow instanceof Frame) ||
@@ -3013,8 +2968,8 @@ public abstract class KeyboardFocusManager
}
private static boolean focusedWindowChanged(Component to, Component from) {
- Window wto = Component.getContainingWindow(to);
- Window wfrom = Component.getContainingWindow(from);
+ Window wto = SunToolkit.getContainingWindow(to);
+ Window wfrom = SunToolkit.getContainingWindow(from);
if (wto == null && wfrom == null) {
return true;
}
@@ -3028,8 +2983,8 @@ public abstract class KeyboardFocusManager
}
private static boolean isTemporary(Component to, Component from) {
- Window wto = Component.getContainingWindow(to);
- Window wfrom = Component.getContainingWindow(from);
+ Window wto = SunToolkit.getContainingWindow(to);
+ Window wfrom = SunToolkit.getContainingWindow(from);
if (wto == null && wfrom == null) {
return false;
}
diff --git a/src/share/classes/java/awt/MenuItem.java b/src/share/classes/java/awt/MenuItem.java
index 71dd760a9..c8596d74f 100644
--- a/src/share/classes/java/awt/MenuItem.java
+++ b/src/share/classes/java/awt/MenuItem.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -398,9 +398,11 @@ public class MenuItem extends MenuComponent implements Accessible {
boolean handleShortcut(KeyEvent e) {
MenuShortcut s = new MenuShortcut(e.getKeyCode(),
(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
// 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.
if (e.getID() == KeyEvent.KEY_PRESSED) {
doMenuEvent(e.getWhen(), e.getModifiers());
diff --git a/src/share/classes/java/awt/MenuShortcut.java b/src/share/classes/java/awt/MenuShortcut.java
index 50eef973f..004cf7c44 100644
--- a/src/share/classes/java/awt/MenuShortcut.java
+++ b/src/share/classes/java/awt/MenuShortcut.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,21 @@ import java.awt.event.KeyEvent;
* For example, a menu shortcut for Ctrl-a (assuming that Control is
* the accelerator key) would be created with code like the following:
* <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>
* The accelerator key is platform-dependent and may be obtained
* via {@link Toolkit#getMenuShortcutKeyMask}.
diff --git a/src/share/classes/java/awt/Window.java b/src/share/classes/java/awt/Window.java
index 2651729f2..01d9ff59d 100644
--- a/src/share/classes/java/awt/Window.java
+++ b/src/share/classes/java/awt/Window.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,10 @@
package java.awt;
import java.awt.event.*;
+import java.awt.geom.Point2D;
import java.awt.im.InputContext;
import java.awt.image.BufferStrategy;
+import java.awt.image.BufferedImage;
import java.awt.peer.ComponentPeer;
import java.awt.peer.WindowPeer;
import java.beans.PropertyChangeListener;
@@ -49,6 +51,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.accessibility.*;
+import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.CausedFocusEvent;
import sun.awt.SunToolkit;
@@ -291,6 +294,25 @@ public class Window extends Container implements Accessible {
*/
transient boolean isInShow = false;
+ /*
+ * Opacity level of the window
+ *
+ * @see #setOpacity(float)
+ * @see #getOpacity()
+ * @since 1.7
+ */
+ private float opacity = 1.0f;
+
+ /*
+ * The shape assigned to this window. This field is set to null if
+ * no shape is set (rectangular window).
+ *
+ * @see #getShape()
+ * @see #setShape(Shape)
+ * @since 1.7
+ */
+ private Shape shape = null;
+
private static final String base = "win";
private static int nameCounter = 0;
@@ -305,6 +327,23 @@ public class Window extends Container implements Accessible {
transient boolean isTrayIconWindow = false;
+ /**
+ * These fields are initialized in the native peer code
+ * or via AWTAccessor's WindowAccessor.
+ */
+ private transient volatile int securityWarningWidth = 0;
+ private transient volatile int securityWarningHeight = 0;
+
+ /**
+ * These fields represent the desired location for the security
+ * warning if this window is untrusted.
+ * See com.sun.awt.SecurityWarning for more details.
+ */
+ private transient double securityWarningPointX = 2.0;
+ private transient double securityWarningPointY = 0.0;
+ private transient float securityWarningAlignmentX = RIGHT_ALIGNMENT;
+ private transient float securityWarningAlignmentY = TOP_ALIGNMENT;
+
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
@@ -373,6 +412,18 @@ public class Window extends Container implements Accessible {
}
}
+ private GraphicsConfiguration initGC(GraphicsConfiguration gc) {
+ GraphicsEnvironment.checkHeadless();
+
+ if (gc == null) {
+ gc = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration();
+ }
+ setGraphicsConfiguration(gc);
+
+ return gc;
+ }
+
private void init(GraphicsConfiguration gc) {
GraphicsEnvironment.checkHeadless();
@@ -384,14 +435,10 @@ public class Window extends Container implements Accessible {
setWarningString();
this.cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
this.visible = false;
- if (gc == null) {
- this.graphicsConfig =
- GraphicsEnvironment.getLocalGraphicsEnvironment().
- getDefaultScreenDevice().getDefaultConfiguration();
- } else {
- this.graphicsConfig = gc;
- }
- if (graphicsConfig.getDevice().getType() !=
+
+ gc = initGC(gc);
+
+ if (gc.getDevice().getType() !=
GraphicsDevice.TYPE_RASTER_SCREEN) {
throw new IllegalArgumentException("not a screen device");
}
@@ -399,8 +446,8 @@ public class Window extends Container implements Accessible {
/* offset the initial location with the original of the screen */
/* and any insets */
- Rectangle screenBounds = graphicsConfig.getBounds();
- Insets screenInsets = getToolkit().getScreenInsets(graphicsConfig);
+ Rectangle screenBounds = gc.getBounds();
+ Insets screenInsets = getToolkit().getScreenInsets(gc);
int x = getX() + screenBounds.x + screenInsets.left;
int y = getY() + screenBounds.y + screenInsets.top;
if (x != this.x || y != this.y) {
@@ -2744,7 +2791,7 @@ public class Window extends Container implements Accessible {
sun.java2d.Disposer.addRecord(anchor, new WindowDisposerRecord(appContext, this));
addToWindowList();
-
+ initGC(null);
}
private void deserializeResources(ObjectInputStream s)
@@ -2849,6 +2896,15 @@ public class Window extends Container implements Accessible {
if(aot) {
setAlwaysOnTop(aot); // since 1.5; subject to permission check
}
+ shape = (Shape)f.get("shape", null);
+ opacity = (Float)f.get("opacity", 1.0f);
+
+ this.securityWarningWidth = 0;
+ this.securityWarningHeight = 0;
+ this.securityWarningPointX = 2.0;
+ this.securityWarningPointY = 0.0;
+ this.securityWarningAlignmentX = RIGHT_ALIGNMENT;
+ this.securityWarningAlignmentY = TOP_ALIGNMENT;
deserializeResources(s);
}
@@ -2916,41 +2972,18 @@ public class Window extends Container implements Accessible {
} // inner class AccessibleAWTWindow
- /**
- * This method returns the GraphicsConfiguration used by this Window.
- * @since 1.3
- */
- public GraphicsConfiguration getGraphicsConfiguration() {
- //NOTE: for multiscreen, this will need to take into account
- //which screen the window is on/mostly on instead of returning the
- //default or constructor argument config.
- synchronized(getTreeLock()) {
- if (graphicsConfig == null && !GraphicsEnvironment.isHeadless()) {
- graphicsConfig =
- GraphicsEnvironment. getLocalGraphicsEnvironment().
- getDefaultScreenDevice().
- getDefaultConfiguration();
- }
- return graphicsConfig;
- }
- }
-
- /**
- * Reset this Window's GraphicsConfiguration to match its peer.
- */
- void resetGC() {
- if (!GraphicsEnvironment.isHeadless()) {
- // use the peer's GC
- setGCFromPeer();
- // if it's still null, use the default
- if (graphicsConfig == null) {
- graphicsConfig = GraphicsEnvironment.
+ @Override
+ void setGraphicsConfiguration(GraphicsConfiguration gc) {
+ if (gc == null) {
+ gc = GraphicsEnvironment.
getLocalGraphicsEnvironment().
getDefaultScreenDevice().
getDefaultConfiguration();
- }
+ }
+ synchronized (getTreeLock()) {
+ super.setGraphicsConfiguration(gc);
if (log.isLoggable(Level.FINER)) {
- log.finer("+ Window.resetGC(): new GC is \n+ " + graphicsConfig + "\n+ this is " + this);
+ log.finer("+ Window.setGraphicsConfiguration(): new GC is \n+ " + getGraphicsConfiguration_NoClientCode() + "\n+ this is " + this);
}
}
}
@@ -3010,13 +3043,13 @@ public class Window extends Container implements Accessible {
// target location
int dx = 0, dy = 0;
// target GC
- GraphicsConfiguration gc = this.graphicsConfig;
+ GraphicsConfiguration gc = getGraphicsConfiguration_NoClientCode();
Rectangle gcBounds = gc.getBounds();
Dimension windowSize = getSize();
// search a top-level of c
- Window componentWindow = Component.getContainingWindow(c);
+ Window componentWindow = SunToolkit.getContainingWindow(c);
if ((c == null) || (componentWindow == null)) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
@@ -3304,6 +3337,225 @@ public class Window extends Container implements Accessible {
}
+ // ******************** SHAPES & TRANSPARENCY CODE ********************
+
+ /**
+ * JavaDoc
+ */
+ /*public */float getOpacity() {
+ synchronized (getTreeLock()) {
+ return opacity;
+ }
+ }
+
+ /**
+ * JavaDoc
+ */
+ /*public */void setOpacity(float opacity) {
+ synchronized (getTreeLock()) {
+ if (opacity < 0.0f || opacity > 1.0f) {
+ throw new IllegalArgumentException(
+ "The value of opacity should be in the range [0.0f .. 1.0f].");
+ }
+ GraphicsConfiguration gc = getGraphicsConfiguration();
+ GraphicsDevice gd = gc.getDevice();
+ if (!gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT)) {
+ throw new UnsupportedOperationException(
+ "TRANSLUCENT translucency is not supported.");
+ }
+ if ((gc.getDevice().getFullScreenWindow() == this) && (opacity < 1.0f)) {
+ throw new IllegalArgumentException(
+ "Setting opacity for full-screen window is not supported.");
+ }
+ this.opacity = opacity;
+ WindowPeer peer = (WindowPeer)getPeer();
+ if (peer != null) {
+ peer.setOpacity(opacity);
+ }
+ }
+ }
+
+ /**
+ * JavaDoc
+ */
+ /*public */Shape getShape() {
+ synchronized (getTreeLock()) {
+ return shape;
+ }
+ }
+
+ /**
+ * JavaDoc
+ *
+ * @param window the window to set the shape to
+ * @param shape the shape to set to the window
+ * @throws IllegalArgumentException if the window is in full screen mode,
+ * and the shape is not null
+ */
+ /*public */void setShape(Shape shape) {
+ synchronized (getTreeLock()) {
+ GraphicsConfiguration gc = getGraphicsConfiguration();
+ GraphicsDevice gd = gc.getDevice();
+ if (!gd.isWindowTranslucencySupported(
+ GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT))
+ {
+ throw new UnsupportedOperationException(
+ "PERPIXEL_TRANSPARENT translucency is not supported.");
+ }
+ if ((gc.getDevice().getFullScreenWindow() == this) && (shape != null)) {
+ throw new IllegalArgumentException(
+ "Setting shape for full-screen window is not supported.");
+ }
+ this.shape = shape;
+ WindowPeer peer = (WindowPeer)getPeer();
+ if (peer != null) {
+ peer.applyShape(shape == null ? null : Region.getInstance(shape, null));
+ }
+ }
+ }
+
+ /**
+ * JavaDoc
+ */
+/*
+ @Override
+ public void setBackground(Color bgColor) {
+ int alpha = bgColor.getAlpha();
+ if (alpha < 255) { // non-opaque window
+ GraphicsConfiguration gc = getGraphicsConfiguration();
+ GraphicsDevice gd = gc.getDevice();
+ if (gc.getDevice().getFullScreenWindow() == this) {
+ throw new IllegalArgumentException(
+ "Making full-screen window non opaque is not supported.");
+ }
+ if (!gc.isTranslucencyCapable()) {
+ GraphicsConfiguration capableGC = gd.getTranslucencyCapableGC();
+ if (capableGC == null) {
+ throw new IllegalArgumentException(
+ "PERPIXEL_TRANSLUCENT translucency is not supported");
+ }
+ // TODO: change GC
+ }
+ setLayersOpaque(this, false);
+ }
+
+ super.setBackground(bgColor);
+
+ WindowPeer peer = (WindowPeer)getPeer();
+ if (peer != null) {
+ peer.setOpaque(alpha == 255);
+ }
+ }
+*/
+
+ private transient boolean opaque = true;
+
+ void setOpaque(boolean opaque) {
+ synchronized (getTreeLock()) {
+ GraphicsConfiguration gc = getGraphicsConfiguration();
+ if (!opaque && !com.sun.awt.AWTUtilities.isTranslucencyCapable(gc)) {
+ throw new IllegalArgumentException(
+ "The window must use a translucency-compatible graphics configuration");
+ }
+ if (!com.sun.awt.AWTUtilities.isTranslucencySupported(
+ com.sun.awt.AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT))
+ {
+ throw new UnsupportedOperationException(
+ "PERPIXEL_TRANSLUCENT translucency is not supported.");
+ }
+ if ((gc.getDevice().getFullScreenWindow() == this) && !opaque) {
+ throw new IllegalArgumentException(
+ "Making full-screen window non opaque is not supported.");
+ }
+ setLayersOpaque(this, opaque);
+ this.opaque = opaque;
+ WindowPeer peer = (WindowPeer)getPeer();
+ if (peer != null) {
+ peer.setOpaque(opaque);
+ }
+ }
+ }
+
+ private void updateWindow(BufferedImage backBuffer) {
+ synchronized (getTreeLock()) {
+ WindowPeer peer = (WindowPeer)getPeer();
+ if (peer != null) {
+ peer.updateWindow(backBuffer);
+ }
+ }
+ }
+
+ private static final Color TRANSPARENT_BACKGROUND_COLOR = new Color(0, 0, 0, 0);
+
+ private static void setLayersOpaque(Component component, boolean isOpaque) {
+ // Shouldn't use instanceof to avoid loading Swing classes
+ // if it's a pure AWT application.
+ if (Component.doesImplement(component, "javax.swing.RootPaneContainer")) {
+ javax.swing.RootPaneContainer rpc = (javax.swing.RootPaneContainer)component;
+ javax.swing.JRootPane root = rpc.getRootPane();
+ javax.swing.JLayeredPane lp = root.getLayeredPane();
+ Container c = root.getContentPane();
+ javax.swing.JComponent content =
+ (c instanceof javax.swing.JComponent) ? (javax.swing.JComponent)c : null;
+ javax.swing.JComponent gp =
+ (rpc.getGlassPane() instanceof javax.swing.JComponent) ?
+ (javax.swing.JComponent)rpc.getGlassPane() : null;
+ if (gp != null) {
+ gp.setDoubleBuffered(isOpaque);
+ }
+ lp.setOpaque(isOpaque);
+ root.setOpaque(isOpaque);
+ root.setDoubleBuffered(isOpaque); //XXX: the "white rect" workaround
+ if (content != null) {
+ content.setOpaque(isOpaque);
+ content.setDoubleBuffered(isOpaque); //XXX: the "white rect" workaround
+
+ // Iterate down one level to see whether we have a JApplet
+ // (which is also a RootPaneContainer) which requires processing
+ int numChildren = content.getComponentCount();
+ if (numChildren > 0) {
+ Component child = content.getComponent(0);
+ // It's OK to use instanceof here because we've
+ // already loaded the RootPaneContainer class by now
+ if (child instanceof javax.swing.RootPaneContainer) {
+ setLayersOpaque(child, isOpaque);
+ }
+ }
+ }
+ }
+
+ Color bg = component.getBackground();
+ boolean hasTransparentBg = TRANSPARENT_BACKGROUND_COLOR.equals(bg);
+
+ Container container = null;
+ if (component instanceof Container) {
+ container = (Container) component;
+ }
+
+ if (isOpaque) {
+ if (hasTransparentBg) {
+ // Note: we use the SystemColor.window color as the default.
+ // This color is used in the WindowPeer implementations to
+ // initialize the background color of the window if it is null.
+ // (This might not be the right thing to do for other
+ // RootPaneContainers we might be invoked with)
+ Color newColor = null;
+ if (container != null && container.preserveBackgroundColor != null) {
+ newColor = container.preserveBackgroundColor;
+ } else {
+ newColor = SystemColor.window;
+ }
+ component.setBackground(newColor);
+ }
+ } else {
+ if (!hasTransparentBg && container != null) {
+ container.preserveBackgroundColor = bg;
+ }
+ component.setBackground(TRANSPARENT_BACKGROUND_COLOR);
+ }
+ }
+
+
// ************************** MIXING CODE *******************************
// A window has a parent, but it does NOT have a container
@@ -3341,6 +3593,87 @@ public class Window extends Container implements Accessible {
// ****************** END OF MIXING CODE ********************************
+ // This method gets the window location/size as reported by the native
+ // system since the locally cached values may represent outdated data.
+ // NOTE: this method is invoked on the toolkit thread, and therefore
+ // is not supposed to become public/user-overridable.
+ private Point2D calculateSecurityWarningPosition(double x, double y,
+ double w, double h)
+ {
+ return new Point2D.Double(
+ x + w * securityWarningAlignmentX + securityWarningPointX,
+ y + h * securityWarningAlignmentY + securityWarningPointY);
+ }
+
+ static {
+ AWTAccessor.setWindowAccessor(new AWTAccessor.WindowAccessor() {
+ public float getOpacity(Window window) {
+ return window.opacity;
+ }
+ public void setOpacity(Window window, float opacity) {
+ window.setOpacity(opacity);
+ }
+ public Shape getShape(Window window) {
+ return window.getShape();
+ }
+ public void setShape(Window window, Shape shape) {
+ window.setShape(shape);
+ }
+ public boolean isOpaque(Window window) {
+ /*
+ return window.getBackground().getAlpha() < 255;
+ */
+ synchronized (window.getTreeLock()) {
+ return window.opaque;
+ }
+ }
+ public void setOpaque(Window window, boolean opaque) {
+ /*
+ Color bg = window.getBackground();
+ window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
+ opaque ? 255 : 0));
+ */
+ window.setOpaque(opaque);
+ }
+ public void updateWindow(Window window, BufferedImage backBuffer) {
+ window.updateWindow(backBuffer);
+ }
+
+ public Dimension getSecurityWarningSize(Window window) {
+ return new Dimension(window.securityWarningWidth,
+ window.securityWarningHeight);
+ }
+
+ public void setSecurityWarningSize(Window window, int width, int height)
+ {
+ window.securityWarningWidth = width;
+ window.securityWarningHeight = height;
+ }
+
+ public void setSecurityWarningPosition(Window window,
+ Point2D point, float alignmentX, float alignmentY)
+ {
+ window.securityWarningPointX = point.getX();
+ window.securityWarningPointY = point.getY();
+ window.securityWarningAlignmentX = alignmentX;
+ window.securityWarningAlignmentY = alignmentY;
+
+ synchronized (window.getTreeLock()) {
+ WindowPeer peer = (WindowPeer)window.getPeer();
+ if (peer != null) {
+ peer.repositionSecurityWarning();
+ }
+ }
+ }
+
+ public Point2D calculateSecurityWarningPosition(Window window,
+ double x, double y, double w, double h)
+ {
+ return window.calculateSecurityWarningPosition(x, y, w, h);
+ }
+ }); // WindowAccessor
+ } // static
+
} // class Window
diff --git a/src/share/classes/java/awt/event/KeyEvent.java b/src/share/classes/java/awt/event/KeyEvent.java
index 039675702..1c0d3723d 100644
--- a/src/share/classes/java/awt/event/KeyEvent.java
+++ b/src/share/classes/java/awt/event/KeyEvent.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,15 +65,16 @@ import java.io.ObjectInputStream;
* <p>
* For key pressed and key released events, the getKeyCode method returns
* 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>
* <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
* 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
- * being pressed or released is indicated by the getKeyCode method, which returns
- * a virtual key code.
+ * being pressed or released is indicated by the {@code getKeyCode} and {@code getExtendedKeyCode}
+ * methods, which return a virtual key code.
*
* <p>
* <em>Virtual key codes</em> are used to report which keyboard key has
@@ -111,6 +112,11 @@ import java.io.ObjectInputStream;
* 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
* 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,
* there is no keycode for the question mark because there is no keyboard
* for which it appears on the primary layer.
@@ -891,6 +897,12 @@ public class KeyEvent extends InputEvent {
*/
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
*/
@@ -1315,6 +1327,9 @@ public class KeyEvent extends InputEvent {
return numpad + "-" + c;
}
+ if ((keyCode & 0x01000000) != 0) {
+ return String.valueOf((char)(keyCode ^ 0x01000000 ));
+ }
String unknown = Toolkit.getProperty("AWT.unknown", "Unknown");
return unknown + " keyCode: 0x" + Integer.toString(keyCode, 16);
}
@@ -1551,9 +1566,44 @@ public class KeyEvent extends InputEvent {
str.append("KEY_LOCATION_UNKNOWN");
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();
}
+ /**
+ * 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
diff --git a/src/share/classes/java/awt/peer/CanvasPeer.java b/src/share/classes/java/awt/peer/CanvasPeer.java
index bbf6a1110..94b8d189d 100644
--- a/src/share/classes/java/awt/peer/CanvasPeer.java
+++ b/src/share/classes/java/awt/peer/CanvasPeer.java
@@ -25,6 +25,7 @@
package java.awt.peer;
import java.awt.Canvas;
+import java.awt.GraphicsConfiguration;
/**
* The peer interface for {@link Canvas}.
@@ -36,4 +37,13 @@ import java.awt.Canvas;
* instances.
*/
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);
}
diff --git a/src/share/classes/java/awt/peer/ComponentPeer.java b/src/share/classes/java/awt/peer/ComponentPeer.java
index e71ab27f7..3c26d5c4f 100644
--- a/src/share/classes/java/awt/peer/ComponentPeer.java
+++ b/src/share/classes/java/awt/peer/ComponentPeer.java
@@ -539,4 +539,16 @@ public interface ComponentPeer {
*/
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);
}
diff --git a/src/share/classes/java/awt/peer/ContainerPeer.java b/src/share/classes/java/awt/peer/ContainerPeer.java
index 092a54f2a..8bb3f10c1 100644
--- a/src/share/classes/java/awt/peer/ContainerPeer.java
+++ b/src/share/classes/java/awt/peer/ContainerPeer.java
@@ -76,21 +76,4 @@ public interface ContainerPeer extends ComponentPeer {
* @see Container#validateTree()
*/
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();
}
diff --git a/src/share/classes/java/awt/peer/WindowPeer.java b/src/share/classes/java/awt/peer/WindowPeer.java
index 7b5da857f..5cacef3c4 100644
--- a/src/share/classes/java/awt/peer/WindowPeer.java
+++ b/src/share/classes/java/awt/peer/WindowPeer.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,8 @@ package java.awt.peer;
import java.awt.*;
+import java.awt.image.BufferedImage;
+
/**
* The peer interface for {@link Window}.
*
@@ -92,4 +94,31 @@ public interface WindowPeer extends ContainerPeer {
* @see Window#setIconImages(java.util.List)
*/
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();
}
diff --git a/src/share/classes/javax/swing/AbstractButton.java b/src/share/classes/javax/swing/AbstractButton.java
index d48108101..06a48991d 100644
--- a/src/share/classes/javax/swing/AbstractButton.java
+++ b/src/share/classes/javax/swing/AbstractButton.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* 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
* A mnemonic must correspond to a single key on the keyboard
* and should be specified using one of the <code>VK_XXX</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
* with the corresponding keycode would cause the button to be
* activated whether or not the Shift modifier was pressed.
diff --git a/src/share/classes/javax/swing/Action.java b/src/share/classes/javax/swing/Action.java
index c996244fd..4a13a42da 100644
--- a/src/share/classes/javax/swing/Action.java
+++ b/src/share/classes/javax/swing/Action.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -272,7 +272,9 @@ public interface Action extends ActionListener {
* one of the <code>KeyEvent</code> key codes. The value is
* commonly used to specify a mnemonic. For example:
* <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
*/
diff --git a/src/share/classes/javax/swing/JComponent.java b/src/share/classes/javax/swing/JComponent.java
index 831dc717a..ebed19256 100644
--- a/src/share/classes/javax/swing/JComponent.java
+++ b/src/share/classes/javax/swing/JComponent.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* 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,
return false;
}
// 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 ksE = null;
if (e.getID() == KeyEvent.KEY_TYPED) {
ks = KeyStroke.getKeyStroke(e.getKeyChar());
@@ -2896,9 +2899,18 @@ public abstract class JComponent extends Container implements Serializable,
else {
ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
(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))
return true;
@@ -2910,6 +2922,9 @@ public abstract class JComponent extends Container implements Serializable,
while (parent != null && !(parent instanceof Window) &&
!(parent instanceof Applet)) {
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,
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
return true;
diff --git a/src/share/classes/javax/swing/JLabel.java b/src/share/classes/javax/swing/JLabel.java
index 417892a83..a9641b9be 100644
--- a/src/share/classes/javax/swing/JLabel.java
+++ b/src/share/classes/javax/swing/JLabel.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* 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
* @see #setDisplayedMnemonic(int)
*/
public void setDisplayedMnemonic(char aChar) {
- int vk = (int) aChar;
- if(vk >= 'a' && vk <='z')
- vk -= ('a' - 'A');
- setDisplayedMnemonic(vk);
+ int vk = java.awt.event.KeyEvent.getExtendedKeyCodeForChar(aChar);
+ if (vk != java.awt.event.KeyEvent.VK_UNDEFINED) {
+ setDisplayedMnemonic(vk);
+ }
}
diff --git a/src/share/classes/javax/swing/JTabbedPane.java b/src/share/classes/javax/swing/JTabbedPane.java
index 2c74189fd..e53cde113 100644
--- a/src/share/classes/javax/swing/JTabbedPane.java
+++ b/src/share/classes/javax/swing/JTabbedPane.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1628,7 +1628,9 @@ public class JTabbedPane extends JComponent
* <p>
* A mnemonic must correspond to a single key on the keyboard
* 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
* with the corresponding keycode would cause the button to be
* activated whether or not the Shift modifier was pressed.
diff --git a/src/share/classes/javax/swing/KeyStroke.java b/src/share/classes/javax/swing/KeyStroke.java
index 8a1e860ce..2eb3c41d5 100644
--- a/src/share/classes/javax/swing/KeyStroke.java
+++ b/src/share/classes/javax/swing/KeyStroke.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -162,6 +162,9 @@ public class KeyStroke extends AWTKeyStroke {
* <li>java.awt.event.KeyEvent.VK_TAB
* <li>java.awt.event.KeyEvent.VK_SPACE
* </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>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
@@ -210,6 +213,9 @@ public class KeyStroke extends AWTKeyStroke {
* <li>java.awt.event.KeyEvent.VK_TAB
* <li>java.awt.event.KeyEvent.VK_SPACE
* </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>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
diff --git a/src/share/classes/javax/swing/KeyboardManager.java b/src/share/classes/javax/swing/KeyboardManager.java
index 1e4f032ae..e88139e9f 100644
--- a/src/share/classes/javax/swing/KeyboardManager.java
+++ b/src/share/classes/javax/swing/KeyboardManager.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -212,19 +212,35 @@ class KeyboardManager {
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 ksE = null;
if(e.getID() == KeyEvent.KEY_TYPED) {
ks=KeyStroke.getKeyStroke(e.getKeyChar());
} else {
+ if(e.getKeyCode() != e.getExtendedKeyCode()) {
+ ksE=KeyStroke.getKeyStroke(e.getExtendedKeyCode(), e.getModifiers(), !pressed);
+ }
ks=KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers(), !pressed);
}
Hashtable keyMap = containerMap.get(topAncestor);
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) {
// don't do anything
@@ -269,7 +285,12 @@ class KeyboardManager {
while (iter.hasMoreElements()) {
JMenuBar mb = (JMenuBar)iter.nextElement();
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()) {
return true;
}
diff --git a/src/share/classes/javax/swing/RepaintManager.java b/src/share/classes/javax/swing/RepaintManager.java
index f51bf4ec2..4e022d0a6 100644
--- a/src/share/classes/javax/swing/RepaintManager.java
+++ b/src/share/classes/javax/swing/RepaintManager.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@ import java.security.AccessController;
import java.util.*;
import java.applet.*;
+import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.DisplayChangedListener;
import sun.awt.SunToolkit;
@@ -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.
*
@@ -749,6 +788,10 @@ public class RepaintManager
int localBoundsW;
Enumeration keys;
+ // the components belonging to perpixel-translucent windows will be
+ // removed from the list
+ tmpDirtyComponents = updateWindows(tmpDirtyComponents);
+
roots = new ArrayList<Component>(count);
for (Component dirty : tmpDirtyComponents.keySet()) {
diff --git a/src/share/classes/javax/swing/SwingUtilities.java b/src/share/classes/javax/swing/SwingUtilities.java
index 0493510a7..21a75ce1d 100644
--- a/src/share/classes/javax/swing/SwingUtilities.java
+++ b/src/share/classes/javax/swing/SwingUtilities.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1589,15 +1589,6 @@ public class SwingUtilities implements SwingConstants
* processing the key bindings associated with JComponents.
*/
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;
}
diff --git a/src/share/classes/sun/awt/AWTAccessor.java b/src/share/classes/sun/awt/AWTAccessor.java
index 41b933c4a..a82ba3146 100644
--- a/src/share/classes/sun/awt/AWTAccessor.java
+++ b/src/share/classes/sun/awt/AWTAccessor.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,46 +26,229 @@
package sun.awt;
import java.awt.*;
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+
import sun.misc.Unsafe;
-/** The AWTAccessor utility class.
+/**
+ * The AWTAccessor utility class.
* The main purpose of this class is to enable accessing
* private and package-private fields of classes from
* different classes/packages. See sun.misc.SharedSecretes
* for another example.
*/
public final class AWTAccessor {
+
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
* and interfaces.
*/
private AWTAccessor() {
}
- /** An accessor for the java.awt.Component class.
+ /*
+ * An interface of accessor for the java.awt.Component class.
*/
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.
+ *
+ * See 6797587, 6776743, 6768307, and 6768332 for details
*/
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;
- /** 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) {
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() {
if (componentAccessor == null) {
@@ -74,4 +257,69 @@ public final class AWTAccessor {
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;
+ }
}
diff --git a/src/share/classes/sun/awt/ComponentAccessor.java b/src/share/classes/sun/awt/ComponentAccessor.java
index af3abcf8a..49a383815 100644
--- a/src/share/classes/sun/awt/ComponentAccessor.java
+++ b/src/share/classes/sun/awt/ComponentAccessor.java
@@ -73,7 +73,6 @@ public class ComponentAccessor
private static Field fieldPacked;
private static Field fieldIgnoreRepaint;
private static Field fieldPeer;
- private static Method methodResetGC;
private static Field fieldVisible;
private static Method methodIsEnabledImpl;
private static Method methodGetCursorNoClientCode;
@@ -124,9 +123,6 @@ public class ComponentAccessor
fieldPeer = componentClass.getDeclaredField("peer");
fieldPeer.setAccessible(true);
- methodResetGC = componentClass.getDeclaredMethod("resetGC", (Class[]) null);
- methodResetGC.setAccessible(true);
-
fieldVisible = componentClass.getDeclaredField("visible");
fieldVisible.setAccessible(true);
@@ -425,18 +421,6 @@ public class ComponentAccessor
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) {
try {
return fieldVisible.getBoolean(c);
diff --git a/src/share/classes/sun/awt/EmbeddedFrame.java b/src/share/classes/sun/awt/EmbeddedFrame.java
index d7450bebe..7b77862d5 100644
--- a/src/share/classes/sun/awt/EmbeddedFrame.java
+++ b/src/share/classes/sun/awt/EmbeddedFrame.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -585,5 +585,14 @@ public abstract class EmbeddedFrame extends Frame
}
public void updateMinimumSize() {
}
- }
+
+ public void setOpacity(float opacity) {
+ }
+ public void setOpaque(boolean isOpaque) {
+ }
+ public void updateWindow(BufferedImage backBuffer) {
+ }
+ public void repositionSecurityWarning() {
+ }
+ }
} // class EmbeddedFrame
diff --git a/src/share/classes/sun/awt/ExtendedKeyCodes.java b/src/share/classes/sun/awt/ExtendedKeyCodes.java
new file mode 100644
index 000000000..37dfafb72
--- /dev/null
+++ b/src/share/classes/sun/awt/ExtendedKeyCodes.java
@@ -0,0 +1,670 @@
+package sun.awt;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.awt.event.KeyEvent;
+
+public class ExtendedKeyCodes {
+ /**
+ * ATTN: These are the readonly hashes with load factor == 1;
+ * adding a value, please set the inital capacity to exact number of items
+ * or higher.
+ */
+ // Keycodes declared in KeyEvent.java with corresponding Unicode values.
+ private final static HashMap<Integer, Integer> regularKeyCodesMap =
+ new HashMap<Integer,Integer>(122, 1.0f);
+
+ // Keycodes derived from Unicode values. Here should be collected codes
+ // for characters appearing on the primary layer of at least one
+ // known keyboard layout. For instance, sterling sign is on the primary layer
+ // of the Mac Italian layout.
+ private final static HashSet<Integer> extendedKeyCodesSet =
+ new HashSet<Integer>(501, 1.0f);
+ final public static int getExtendedKeyCodeForChar( int c ) {
+ int rc = KeyEvent.VK_UNDEFINED;
+ int uc = Character.toUpperCase( c );
+ int lc = Character.toLowerCase( c );
+ if (regularKeyCodesMap.containsKey( c )) {
+ if(regularKeyCodesMap.containsKey(uc)) {
+ return regularKeyCodesMap.get( uc );
+ }
+ return regularKeyCodesMap.get( c );
+ }
+ uc += 0x01000000;
+ lc += 0x01000000;
+ if (extendedKeyCodesSet.contains( uc )) {
+ return uc;
+ }else if (extendedKeyCodesSet.contains( lc )) {
+ return lc;
+ }
+ return rc;
+ }
+ static {
+ regularKeyCodesMap.put(0x0a, KeyEvent.VK_ENTER);
+ regularKeyCodesMap.put(0x08, KeyEvent.VK_BACK_SPACE);
+ regularKeyCodesMap.put(0x09, KeyEvent.VK_TAB);
+ regularKeyCodesMap.put(0x1B, KeyEvent.VK_ESCAPE);
+ regularKeyCodesMap.put(0x20, KeyEvent.VK_SPACE);
+ regularKeyCodesMap.put(0x21, KeyEvent.VK_PAGE_UP);
+ regularKeyCodesMap.put(0x22, KeyEvent.VK_PAGE_DOWN);
+ regularKeyCodesMap.put(0x23, KeyEvent.VK_END);
+ regularKeyCodesMap.put(0x24, KeyEvent.VK_HOME);
+ regularKeyCodesMap.put(0x25, KeyEvent.VK_LEFT);
+ regularKeyCodesMap.put(0x26, KeyEvent.VK_UP);
+ regularKeyCodesMap.put(0x27, KeyEvent.VK_RIGHT);
+ regularKeyCodesMap.put(0x28, KeyEvent.VK_DOWN);
+ regularKeyCodesMap.put(0x2C, KeyEvent.VK_COMMA);
+ regularKeyCodesMap.put(0x2D, KeyEvent.VK_MINUS);
+ regularKeyCodesMap.put(0x2E, KeyEvent.VK_PERIOD);
+ regularKeyCodesMap.put(0x2F, KeyEvent.VK_SLASH);
+ regularKeyCodesMap.put(0x30, KeyEvent.VK_0);
+ regularKeyCodesMap.put(0x31, KeyEvent.VK_1);
+ regularKeyCodesMap.put(0x32, KeyEvent.VK_2);
+ regularKeyCodesMap.put(0x33, KeyEvent.VK_3);
+ regularKeyCodesMap.put(0x34, KeyEvent.VK_4);
+ regularKeyCodesMap.put(0x35, KeyEvent.VK_5);
+ regularKeyCodesMap.put(0x36, KeyEvent.VK_6);
+ regularKeyCodesMap.put(0x37, KeyEvent.VK_7);
+ regularKeyCodesMap.put(0x38, KeyEvent.VK_8);
+ regularKeyCodesMap.put(0x39, KeyEvent.VK_9);
+ regularKeyCodesMap.put(0x3B, KeyEvent.VK_SEMICOLON);
+ regularKeyCodesMap.put(0x3D, KeyEvent.VK_EQUALS);
+ regularKeyCodesMap.put(0x41, KeyEvent.VK_A);
+ regularKeyCodesMap.put(0x61, KeyEvent.VK_A);
+ regularKeyCodesMap.put(0x42, KeyEvent.VK_B);
+ regularKeyCodesMap.put(0x62, KeyEvent.VK_B);
+ regularKeyCodesMap.put(0x43, KeyEvent.VK_C);
+ regularKeyCodesMap.put(0x63, KeyEvent.VK_C);
+ regularKeyCodesMap.put(0x44, KeyEvent.VK_D);
+ regularKeyCodesMap.put(0x64, KeyEvent.VK_D);
+ regularKeyCodesMap.put(0x45, KeyEvent.VK_E);
+ regularKeyCodesMap.put(0x65, KeyEvent.VK_E);
+ regularKeyCodesMap.put(0x46, KeyEvent.VK_F);
+ regularKeyCodesMap.put(0x66, KeyEvent.VK_F);
+ regularKeyCodesMap.put(0x47, KeyEvent.VK_G);
+ regularKeyCodesMap.put(0x67, KeyEvent.VK_G);
+ regularKeyCodesMap.put(0x48, KeyEvent.VK_H);
+ regularKeyCodesMap.put(0x68, KeyEvent.VK_H);
+ regularKeyCodesMap.put(0x49, KeyEvent.VK_I);
+ regularKeyCodesMap.put(0x69, KeyEvent.VK_I);
+ regularKeyCodesMap.put(0x4A, KeyEvent.VK_J);
+ regularKeyCodesMap.put(0x6A, KeyEvent.VK_J);
+ regularKeyCodesMap.put(0x4B, KeyEvent.VK_K);
+ regularKeyCodesMap.put(0x6B, KeyEvent.VK_K);
+ regularKeyCodesMap.put(0x4C, KeyEvent.VK_L);
+ regularKeyCodesMap.put(0x6C, KeyEvent.VK_L);
+ regularKeyCodesMap.put(0x4D, KeyEvent.VK_M);
+ regularKeyCodesMap.put(0x6D, KeyEvent.VK_M);
+ regularKeyCodesMap.put(0x4E, KeyEvent.VK_N);
+ regularKeyCodesMap.put(0x6E, KeyEvent.VK_N);
+ regularKeyCodesMap.put(0x4F, KeyEvent.VK_O);
+ regularKeyCodesMap.put(0x6F, KeyEvent.VK_O);
+ regularKeyCodesMap.put(0x50, KeyEvent.VK_P);
+ regularKeyCodesMap.put(0x70, KeyEvent.VK_P);
+ regularKeyCodesMap.put(0x51, KeyEvent.VK_Q);
+ regularKeyCodesMap.put(0x71, KeyEvent.VK_Q);
+ regularKeyCodesMap.put(0x52, KeyEvent.VK_R);
+ regularKeyCodesMap.put(0x72, KeyEvent.VK_R);
+ regularKeyCodesMap.put(0x53, KeyEvent.VK_S);
+ regularKeyCodesMap.put(0x73, KeyEvent.VK_S);
+ regularKeyCodesMap.put(0x54, KeyEvent.VK_T);
+ regularKeyCodesMap.put(0x74, KeyEvent.VK_T);
+ regularKeyCodesMap.put(0x55, KeyEvent.VK_U);
+ regularKeyCodesMap.put(0x75, KeyEvent.VK_U);
+ regularKeyCodesMap.put(0x56, KeyEvent.VK_V);
+ regularKeyCodesMap.put(0x76, KeyEvent.VK_V);
+ regularKeyCodesMap.put(0x57, KeyEvent.VK_W);
+ regularKeyCodesMap.put(0x77, KeyEvent.VK_W);
+ regularKeyCodesMap.put(0x58, KeyEvent.VK_X);
+ regularKeyCodesMap.put(0x78, KeyEvent.VK_X);
+ regularKeyCodesMap.put(0x59, KeyEvent.VK_Y);
+ regularKeyCodesMap.put(0x79, KeyEvent.VK_Y);
+ regularKeyCodesMap.put(0x5A, KeyEvent.VK_Z);
+ regularKeyCodesMap.put(0x7A, KeyEvent.VK_Z);
+ regularKeyCodesMap.put(0x5B, KeyEvent.VK_OPEN_BRACKET);
+ regularKeyCodesMap.put(0x5C, KeyEvent.VK_BACK_SLASH);
+ regularKeyCodesMap.put(0x5D, KeyEvent.VK_CLOSE_BRACKET);
+// regularKeyCodesMap.put(0x60, KeyEvent.VK_NUMPAD0);
+// regularKeyCodesMap.put(0x61, KeyEvent.VK_NUMPAD1);
+// regularKeyCodesMap.put(0x62, KeyEvent.VK_NUMPAD2);
+// regularKeyCodesMap.put(0x63, KeyEvent.VK_NUMPAD3);
+// regularKeyCodesMap.put(0x64, KeyEvent.VK_NUMPAD4);
+// regularKeyCodesMap.put(0x65, KeyEvent.VK_NUMPAD5);
+// regularKeyCodesMap.put(0x66, KeyEvent.VK_NUMPAD6);
+// regularKeyCodesMap.put(0x67, KeyEvent.VK_NUMPAD7);
+// regularKeyCodesMap.put(0x68, KeyEvent.VK_NUMPAD8);
+// regularKeyCodesMap.put(0x69, KeyEvent.VK_NUMPAD9);
+ regularKeyCodesMap.put(0x6A, KeyEvent.VK_MULTIPLY);
+ regularKeyCodesMap.put(0x6B, KeyEvent.VK_ADD);
+ regularKeyCodesMap.put(0x6C, KeyEvent.VK_SEPARATER);
+ regularKeyCodesMap.put(0x6D, KeyEvent.VK_SUBTRACT);
+ regularKeyCodesMap.put(0x6E, KeyEvent.VK_DECIMAL);
+ regularKeyCodesMap.put(0x6F, KeyEvent.VK_DIVIDE);
+ regularKeyCodesMap.put(0x7F, KeyEvent.VK_DELETE);
+ regularKeyCodesMap.put(0xC0, KeyEvent.VK_BACK_QUOTE);
+ regularKeyCodesMap.put(0xDE, KeyEvent.VK_QUOTE);
+ regularKeyCodesMap.put(0x26, KeyEvent.VK_AMPERSAND);
+ regularKeyCodesMap.put(0x2A, KeyEvent.VK_ASTERISK);
+ regularKeyCodesMap.put(0x22, KeyEvent.VK_QUOTEDBL);
+ regularKeyCodesMap.put(0x3C, KeyEvent.VK_LESS);
+ regularKeyCodesMap.put(0x3E, KeyEvent.VK_GREATER);
+ regularKeyCodesMap.put(0x7B, KeyEvent.VK_BRACELEFT);
+ regularKeyCodesMap.put(0x7D, KeyEvent.VK_BRACERIGHT);
+ regularKeyCodesMap.put(0x40, KeyEvent.VK_AT);
+ regularKeyCodesMap.put(0x3A, KeyEvent.VK_COLON);
+ regularKeyCodesMap.put(0x5E, KeyEvent.VK_CIRCUMFLEX);
+ regularKeyCodesMap.put(0x24, KeyEvent.VK_DOLLAR);
+ regularKeyCodesMap.put(0x20AC, KeyEvent.VK_EURO_SIGN);
+ regularKeyCodesMap.put(0x21, KeyEvent.VK_EXCLAMATION_MARK);
+ regularKeyCodesMap.put(0xA1, KeyEvent.VK_INVERTED_EXCLAMATION_MARK);
+ regularKeyCodesMap.put(0x28, KeyEvent.VK_LEFT_PARENTHESIS);
+ regularKeyCodesMap.put(0x23, KeyEvent.VK_NUMBER_SIGN);
+ regularKeyCodesMap.put(0x2B, KeyEvent.VK_PLUS);
+ regularKeyCodesMap.put(0x29, KeyEvent.VK_RIGHT_PARENTHESIS);
+ regularKeyCodesMap.put(0x5F, KeyEvent.VK_UNDERSCORE);
+
+
+ extendedKeyCodesSet.add(0x01000000+0x0060);
+ extendedKeyCodesSet.add(0x01000000+0x007C);
+ extendedKeyCodesSet.add(0x01000000+0x007E);
+ extendedKeyCodesSet.add(0x01000000+0x00A2);
+ extendedKeyCodesSet.add(0x01000000+0x00A3);
+ extendedKeyCodesSet.add(0x01000000+0x00A5);
+ extendedKeyCodesSet.add(0x01000000+0x00A7);
+ extendedKeyCodesSet.add(0x01000000+0x00A8);
+ extendedKeyCodesSet.add(0x01000000+0x00AB);
+ extendedKeyCodesSet.add(0x01000000+0x00B0);
+ extendedKeyCodesSet.add(0x01000000+0x00B1);
+ extendedKeyCodesSet.add(0x01000000+0x00B2);
+ extendedKeyCodesSet.add(0x01000000+0x00B3);
+ extendedKeyCodesSet.add(0x01000000+0x00B4);
+ extendedKeyCodesSet.add(0x01000000+0x00B5);
+ extendedKeyCodesSet.add(0x01000000+0x00B6);
+ extendedKeyCodesSet.add(0x01000000+0x00B7);
+ extendedKeyCodesSet.add(0x01000000+0x00B9);
+ extendedKeyCodesSet.add(0x01000000+0x00BA);
+ extendedKeyCodesSet.add(0x01000000+0x00BB);
+ extendedKeyCodesSet.add(0x01000000+0x00BC);
+ extendedKeyCodesSet.add(0x01000000+0x00BD);
+ extendedKeyCodesSet.add(0x01000000+0x00BE);
+ extendedKeyCodesSet.add(0x01000000+0x00BF);
+ extendedKeyCodesSet.add(0x01000000+0x00C4);
+ extendedKeyCodesSet.add(0x01000000+0x00C5);
+ extendedKeyCodesSet.add(0x01000000+0x00C6);
+ extendedKeyCodesSet.add(0x01000000+0x00C7);
+ extendedKeyCodesSet.add(0x01000000+0x00D1);
+ extendedKeyCodesSet.add(0x01000000+0x00D6);
+ extendedKeyCodesSet.add(0x01000000+0x00D7);
+ extendedKeyCodesSet.add(0x01000000+0x00D8);
+ extendedKeyCodesSet.add(0x01000000+0x00DF);
+ extendedKeyCodesSet.add(0x01000000+0x00E0);
+ extendedKeyCodesSet.add(0x01000000+0x00E1);
+ extendedKeyCodesSet.add(0x01000000+0x00E2);
+ extendedKeyCodesSet.add(0x01000000+0x00E4);
+ extendedKeyCodesSet.add(0x01000000+0x00E5);
+ extendedKeyCodesSet.add(0x01000000+0x00E6);
+ extendedKeyCodesSet.add(0x01000000+0x00E7);
+ extendedKeyCodesSet.add(0x01000000+0x00E8);
+ extendedKeyCodesSet.add(0x01000000+0x00E9);
+ extendedKeyCodesSet.add(0x01000000+0x00EA);
+ extendedKeyCodesSet.add(0x01000000+0x00EB);
+ extendedKeyCodesSet.add(0x01000000+0x00EC);
+ extendedKeyCodesSet.add(0x01000000+0x00ED);
+ extendedKeyCodesSet.add(0x01000000+0x00EE);
+ extendedKeyCodesSet.add(0x01000000+0x00F0);
+ extendedKeyCodesSet.add(0x01000000+0x00F1);
+ extendedKeyCodesSet.add(0x01000000+0x00F2);
+ extendedKeyCodesSet.add(0x01000000+0x00F3);
+ extendedKeyCodesSet.add(0x01000000+0x00F4);
+ extendedKeyCodesSet.add(0x01000000+0x00F5);
+ extendedKeyCodesSet.add(0x01000000+0x00F6);
+ extendedKeyCodesSet.add(0x01000000+0x00F7);
+ extendedKeyCodesSet.add(0x01000000+0x00F8);
+ extendedKeyCodesSet.add(0x01000000+0x00F9);
+ extendedKeyCodesSet.add(0x01000000+0x00FA);
+ extendedKeyCodesSet.add(0x01000000+0x00FB);
+ extendedKeyCodesSet.add(0x01000000+0x00FC);
+ extendedKeyCodesSet.add(0x01000000+0x00FD);
+ extendedKeyCodesSet.add(0x01000000+0x00FE);
+ extendedKeyCodesSet.add(0x01000000+0x0105);
+ extendedKeyCodesSet.add(0x01000000+0x02DB);
+ extendedKeyCodesSet.add(0x01000000+0x0142);
+ extendedKeyCodesSet.add(0x01000000+0x013E);
+ extendedKeyCodesSet.add(0x01000000+0x015B);
+ extendedKeyCodesSet.add(0x01000000+0x0161);
+ extendedKeyCodesSet.add(0x01000000+0x015F);
+ extendedKeyCodesSet.add(0x01000000+0x0165);
+ extendedKeyCodesSet.add(0x01000000+0x017E);
+ extendedKeyCodesSet.add(0x01000000+0x017C);
+ extendedKeyCodesSet.add(0x01000000+0x0103);
+ extendedKeyCodesSet.add(0x01000000+0x0107);
+ extendedKeyCodesSet.add(0x01000000+0x010D);
+ extendedKeyCodesSet.add(0x01000000+0x0119);
+ extendedKeyCodesSet.add(0x01000000+0x011B);
+ extendedKeyCodesSet.add(0x01000000+0x0111);
+ extendedKeyCodesSet.add(0x01000000+0x0148);
+ extendedKeyCodesSet.add(0x01000000+0x0151);
+ extendedKeyCodesSet.add(0x01000000+0x0171);
+ extendedKeyCodesSet.add(0x01000000+0x0159);
+ extendedKeyCodesSet.add(0x01000000+0x016F);
+ extendedKeyCodesSet.add(0x01000000+0x0163);
+ extendedKeyCodesSet.add(0x01000000+0x02D9);
+ extendedKeyCodesSet.add(0x01000000+0x0130);
+ extendedKeyCodesSet.add(0x01000000+0x0127);
+ extendedKeyCodesSet.add(0x01000000+0x0125);
+ extendedKeyCodesSet.add(0x01000000+0x0131);
+ extendedKeyCodesSet.add(0x01000000+0x011F);
+ extendedKeyCodesSet.add(0x01000000+0x0135);
+ extendedKeyCodesSet.add(0x01000000+0x010B);
+ extendedKeyCodesSet.add(0x01000000+0x0109);
+ extendedKeyCodesSet.add(0x01000000+0x0121);
+ extendedKeyCodesSet.add(0x01000000+0x011D);
+ extendedKeyCodesSet.add(0x01000000+0x016D);
+ extendedKeyCodesSet.add(0x01000000+0x015D);
+ extendedKeyCodesSet.add(0x01000000+0x0138);
+ extendedKeyCodesSet.add(0x01000000+0x0157);
+ extendedKeyCodesSet.add(0x01000000+0x013C);
+ extendedKeyCodesSet.add(0x01000000+0x0113);
+ extendedKeyCodesSet.add(0x01000000+0x0123);
+ extendedKeyCodesSet.add(0x01000000+0x0167);
+ extendedKeyCodesSet.add(0x01000000+0x014B);
+ extendedKeyCodesSet.add(0x01000000+0x0101);
+ extendedKeyCodesSet.add(0x01000000+0x012F);
+ extendedKeyCodesSet.add(0x01000000+0x0117);
+ extendedKeyCodesSet.add(0x01000000+0x012B);
+ extendedKeyCodesSet.add(0x01000000+0x0146);
+ extendedKeyCodesSet.add(0x01000000+0x014D);
+ extendedKeyCodesSet.add(0x01000000+0x0137);
+ extendedKeyCodesSet.add(0x01000000+0x0173);
+ extendedKeyCodesSet.add(0x01000000+0x016B);
+ extendedKeyCodesSet.add(0x01000000+0x0153);
+ extendedKeyCodesSet.add(0x01000000+0x30FC);
+ extendedKeyCodesSet.add(0x01000000+0x30A2);
+ extendedKeyCodesSet.add(0x01000000+0x30A4);
+ extendedKeyCodesSet.add(0x01000000+0x30A6);
+ extendedKeyCodesSet.add(0x01000000+0x30A8);
+ extendedKeyCodesSet.add(0x01000000+0x30AA);
+ extendedKeyCodesSet.add(0x01000000+0x30AB);
+ extendedKeyCodesSet.add(0x01000000+0x30AD);
+ extendedKeyCodesSet.add(0x01000000+0x30AF);
+ extendedKeyCodesSet.add(0x01000000+0x30B1);
+ extendedKeyCodesSet.add(0x01000000+0x30B3);
+ extendedKeyCodesSet.add(0x01000000+0x30B5);
+ extendedKeyCodesSet.add(0x01000000+0x30B7);
+ extendedKeyCodesSet.add(0x01000000+0x30B9);
+ extendedKeyCodesSet.add(0x01000000+0x30BB);
+ extendedKeyCodesSet.add(0x01000000+0x30BD);
+ extendedKeyCodesSet.add(0x01000000+0x30BF);
+ extendedKeyCodesSet.add(0x01000000+0x30C1);
+ extendedKeyCodesSet.add(0x01000000+0x30C4);
+ extendedKeyCodesSet.add(0x01000000+0x30C6);
+ extendedKeyCodesSet.add(0x01000000+0x30C8);
+ extendedKeyCodesSet.add(0x01000000+0x30CA);
+ extendedKeyCodesSet.add(0x01000000+0x30CB);
+ extendedKeyCodesSet.add(0x01000000+0x30CC);
+ extendedKeyCodesSet.add(0x01000000+0x30CD);
+ extendedKeyCodesSet.add(0x01000000+0x30CE);
+ extendedKeyCodesSet.add(0x01000000+0x30CF);
+ extendedKeyCodesSet.add(0x01000000+0x30D2);
+ extendedKeyCodesSet.add(0x01000000+0x30D5);
+ extendedKeyCodesSet.add(0x01000000+0x30D8);
+ extendedKeyCodesSet.add(0x01000000+0x30DB);
+ extendedKeyCodesSet.add(0x01000000+0x30DE);
+ extendedKeyCodesSet.add(0x01000000+0x30DF);
+ extendedKeyCodesSet.add(0x01000000+0x30E0);
+ extendedKeyCodesSet.add(0x01000000+0x30E1);
+ extendedKeyCodesSet.add(0x01000000+0x30E2);
+ extendedKeyCodesSet.add(0x01000000+0x30E4);
+ extendedKeyCodesSet.add(0x01000000+0x30E6);
+ extendedKeyCodesSet.add(0x01000000+0x30E8);
+ extendedKeyCodesSet.add(0x01000000+0x30E9);
+ extendedKeyCodesSet.add(0x01000000+0x30EA);
+ extendedKeyCodesSet.add(0x01000000+0x30EB);
+ extendedKeyCodesSet.add(0x01000000+0x30EC);
+ extendedKeyCodesSet.add(0x01000000+0x30ED);
+ extendedKeyCodesSet.add(0x01000000+0x30EF);
+ extendedKeyCodesSet.add(0x01000000+0x30F3);
+ extendedKeyCodesSet.add(0x01000000+0x309B);
+ extendedKeyCodesSet.add(0x01000000+0x309C);
+ extendedKeyCodesSet.add(0x01000000+0x06F0);
+ extendedKeyCodesSet.add(0x01000000+0x06F1);
+ extendedKeyCodesSet.add(0x01000000+0x06F2);
+ extendedKeyCodesSet.add(0x01000000+0x06F3);
+ extendedKeyCodesSet.add(0x01000000+0x06F4);
+ extendedKeyCodesSet.add(0x01000000+0x06F5);
+ extendedKeyCodesSet.add(0x01000000+0x06F6);
+ extendedKeyCodesSet.add(0x01000000+0x06F7);
+ extendedKeyCodesSet.add(0x01000000+0x06F8);
+ extendedKeyCodesSet.add(0x01000000+0x06F9);
+ extendedKeyCodesSet.add(0x01000000+0x0670);
+ extendedKeyCodesSet.add(0x01000000+0x067E);
+ extendedKeyCodesSet.add(0x01000000+0x0686);
+ extendedKeyCodesSet.add(0x01000000+0x060C);
+ extendedKeyCodesSet.add(0x01000000+0x06D4);
+ extendedKeyCodesSet.add(0x01000000+0x0660);
+ extendedKeyCodesSet.add(0x01000000+0x0661);
+ extendedKeyCodesSet.add(0x01000000+0x0662);
+ extendedKeyCodesSet.add(0x01000000+0x0663);
+ extendedKeyCodesSet.add(0x01000000+0x0664);
+ extendedKeyCodesSet.add(0x01000000+0x0665);
+ extendedKeyCodesSet.add(0x01000000+0x0666);
+ extendedKeyCodesSet.add(0x01000000+0x0667);
+ extendedKeyCodesSet.add(0x01000000+0x0668);
+ extendedKeyCodesSet.add(0x01000000+0x0669);
+ extendedKeyCodesSet.add(0x01000000+0x061B);
+ extendedKeyCodesSet.add(0x01000000+0x0621);
+ extendedKeyCodesSet.add(0x01000000+0x0624);
+ extendedKeyCodesSet.add(0x01000000+0x0626);
+ extendedKeyCodesSet.add(0x01000000+0x0627);
+ extendedKeyCodesSet.add(0x01000000+0x0628);
+ extendedKeyCodesSet.add(0x01000000+0x0629);
+ extendedKeyCodesSet.add(0x01000000+0x062A);
+ extendedKeyCodesSet.add(0x01000000+0x062B);
+ extendedKeyCodesSet.add(0x01000000+0x062C);
+ extendedKeyCodesSet.add(0x01000000+0x062D);
+ extendedKeyCodesSet.add(0x01000000+0x062E);
+ extendedKeyCodesSet.add(0x01000000+0x062F);
+ extendedKeyCodesSet.add(0x01000000+0x0630);
+ extendedKeyCodesSet.add(0x01000000+0x0631);
+ extendedKeyCodesSet.add(0x01000000+0x0632);
+ extendedKeyCodesSet.add(0x01000000+0x0633);
+ extendedKeyCodesSet.add(0x01000000+0x0634);
+ extendedKeyCodesSet.add(0x01000000+0x0635);
+ extendedKeyCodesSet.add(0x01000000+0x0636);
+ extendedKeyCodesSet.add(0x01000000+0x0637);
+ extendedKeyCodesSet.add(0x01000000+0x0638);
+ extendedKeyCodesSet.add(0x01000000+0x0639);
+ extendedKeyCodesSet.add(0x01000000+0x063A);
+ extendedKeyCodesSet.add(0x01000000+0x0641);
+ extendedKeyCodesSet.add(0x01000000+0x0642);
+ extendedKeyCodesSet.add(0x01000000+0x0643);
+ extendedKeyCodesSet.add(0x01000000+0x0644);
+ extendedKeyCodesSet.add(0x01000000+0x0645);
+ extendedKeyCodesSet.add(0x01000000+0x0646);
+ extendedKeyCodesSet.add(0x01000000+0x0647);
+ extendedKeyCodesSet.add(0x01000000+0x0648);
+ extendedKeyCodesSet.add(0x01000000+0x0649);
+ extendedKeyCodesSet.add(0x01000000+0x064A);
+ extendedKeyCodesSet.add(0x01000000+0x064E);
+ extendedKeyCodesSet.add(0x01000000+0x064F);
+ extendedKeyCodesSet.add(0x01000000+0x0650);
+ extendedKeyCodesSet.add(0x01000000+0x0652);
+ extendedKeyCodesSet.add(0x01000000+0x0698);
+ extendedKeyCodesSet.add(0x01000000+0x06A4);
+ extendedKeyCodesSet.add(0x01000000+0x06A9);
+ extendedKeyCodesSet.add(0x01000000+0x06AF);
+ extendedKeyCodesSet.add(0x01000000+0x06BE);
+ extendedKeyCodesSet.add(0x01000000+0x06CC);
+ extendedKeyCodesSet.add(0x01000000+0x06CC);
+ extendedKeyCodesSet.add(0x01000000+0x06D2);
+ extendedKeyCodesSet.add(0x01000000+0x0493);
+ extendedKeyCodesSet.add(0x01000000+0x0497);
+ extendedKeyCodesSet.add(0x01000000+0x049B);
+ extendedKeyCodesSet.add(0x01000000+0x049D);
+ extendedKeyCodesSet.add(0x01000000+0x04A3);
+ extendedKeyCodesSet.add(0x01000000+0x04AF);
+ extendedKeyCodesSet.add(0x01000000+0x04B1);
+ extendedKeyCodesSet.add(0x01000000+0x04B3);
+ extendedKeyCodesSet.add(0x01000000+0x04B9);
+ extendedKeyCodesSet.add(0x01000000+0x04BB);
+ extendedKeyCodesSet.add(0x01000000+0x04D9);
+ extendedKeyCodesSet.add(0x01000000+0x04E9);
+ extendedKeyCodesSet.add(0x01000000+0x0452);
+ extendedKeyCodesSet.add(0x01000000+0x0453);
+ extendedKeyCodesSet.add(0x01000000+0x0451);
+ extendedKeyCodesSet.add(0x01000000+0x0454);
+ extendedKeyCodesSet.add(0x01000000+0x0455);
+ extendedKeyCodesSet.add(0x01000000+0x0456);
+ extendedKeyCodesSet.add(0x01000000+0x0457);
+ extendedKeyCodesSet.add(0x01000000+0x0458);
+ extendedKeyCodesSet.add(0x01000000+0x0459);
+ extendedKeyCodesSet.add(0x01000000+0x045A);
+ extendedKeyCodesSet.add(0x01000000+0x045B);
+ extendedKeyCodesSet.add(0x01000000+0x045C);
+ extendedKeyCodesSet.add(0x01000000+0x0491);
+ extendedKeyCodesSet.add(0x01000000+0x045E);
+ extendedKeyCodesSet.add(0x01000000+0x045F);
+ extendedKeyCodesSet.add(0x01000000+0x2116);
+ extendedKeyCodesSet.add(0x01000000+0x044E);
+ extendedKeyCodesSet.add(0x01000000+0x0430);
+ extendedKeyCodesSet.add(0x01000000+0x0431);
+ extendedKeyCodesSet.add(0x01000000+0x0446);
+ extendedKeyCodesSet.add(0x01000000+0x0434);
+ extendedKeyCodesSet.add(0x01000000+0x0435);
+ extendedKeyCodesSet.add(0x01000000+0x0444);
+ extendedKeyCodesSet.add(0x01000000+0x0433);
+ extendedKeyCodesSet.add(0x01000000+0x0445);
+ extendedKeyCodesSet.add(0x01000000+0x0438);
+ extendedKeyCodesSet.add(0x01000000+0x0439);
+ extendedKeyCodesSet.add(0x01000000+0x043A);
+ extendedKeyCodesSet.add(0x01000000+0x043B);
+ extendedKeyCodesSet.add(0x01000000+0x043C);
+ extendedKeyCodesSet.add(0x01000000+0x043D);
+ extendedKeyCodesSet.add(0x01000000+0x043E);
+ extendedKeyCodesSet.add(0x01000000+0x043F);
+ extendedKeyCodesSet.add(0x01000000+0x044F);
+ extendedKeyCodesSet.add(0x01000000+0x0440);
+ extendedKeyCodesSet.add(0x01000000+0x0441);
+ extendedKeyCodesSet.add(0x01000000+0x0442);
+ extendedKeyCodesSet.add(0x01000000+0x0443);
+ extendedKeyCodesSet.add(0x01000000+0x0436);
+ extendedKeyCodesSet.add(0x01000000+0x0432);
+ extendedKeyCodesSet.add(0x01000000+0x044C);
+ extendedKeyCodesSet.add(0x01000000+0x044B);
+ extendedKeyCodesSet.add(0x01000000+0x0437);
+ extendedKeyCodesSet.add(0x01000000+0x0448);
+ extendedKeyCodesSet.add(0x01000000+0x044D);
+ extendedKeyCodesSet.add(0x01000000+0x0449);
+ extendedKeyCodesSet.add(0x01000000+0x0447);
+ extendedKeyCodesSet.add(0x01000000+0x044A);
+ extendedKeyCodesSet.add(0x01000000+0x2015);
+ extendedKeyCodesSet.add(0x01000000+0x03B1);
+ extendedKeyCodesSet.add(0x01000000+0x03B2);
+ extendedKeyCodesSet.add(0x01000000+0x03B3);
+ extendedKeyCodesSet.add(0x01000000+0x03B4);
+ extendedKeyCodesSet.add(0x01000000+0x03B5);
+ extendedKeyCodesSet.add(0x01000000+0x03B6);
+ extendedKeyCodesSet.add(0x01000000+0x03B7);
+ extendedKeyCodesSet.add(0x01000000+0x03B8);
+ extendedKeyCodesSet.add(0x01000000+0x03B9);
+ extendedKeyCodesSet.add(0x01000000+0x03BA);
+ extendedKeyCodesSet.add(0x01000000+0x03BB);
+ extendedKeyCodesSet.add(0x01000000+0x03BC);
+ extendedKeyCodesSet.add(0x01000000+0x03BD);
+ extendedKeyCodesSet.add(0x01000000+0x03BE);
+ extendedKeyCodesSet.add(0x01000000+0x03BF);
+ extendedKeyCodesSet.add(0x01000000+0x03C0);
+ extendedKeyCodesSet.add(0x01000000+0x03C1);
+ extendedKeyCodesSet.add(0x01000000+0x03C3);
+ extendedKeyCodesSet.add(0x01000000+0x03C2);
+ extendedKeyCodesSet.add(0x01000000+0x03C4);
+ extendedKeyCodesSet.add(0x01000000+0x03C5);
+ extendedKeyCodesSet.add(0x01000000+0x03C6);
+ extendedKeyCodesSet.add(0x01000000+0x03C7);
+ extendedKeyCodesSet.add(0x01000000+0x03C8);
+ extendedKeyCodesSet.add(0x01000000+0x03C9);
+ extendedKeyCodesSet.add(0x01000000+0x2190);
+ extendedKeyCodesSet.add(0x01000000+0x2192);
+ extendedKeyCodesSet.add(0x01000000+0x2193);
+ extendedKeyCodesSet.add(0x01000000+0x2013);
+ extendedKeyCodesSet.add(0x01000000+0x201C);
+ extendedKeyCodesSet.add(0x01000000+0x201D);
+ extendedKeyCodesSet.add(0x01000000+0x201E);
+ extendedKeyCodesSet.add(0x01000000+0x05D0);
+ extendedKeyCodesSet.add(0x01000000+0x05D1);
+ extendedKeyCodesSet.add(0x01000000+0x05D2);
+ extendedKeyCodesSet.add(0x01000000+0x05D3);
+ extendedKeyCodesSet.add(0x01000000+0x05D4);
+ extendedKeyCodesSet.add(0x01000000+0x05D5);
+ extendedKeyCodesSet.add(0x01000000+0x05D6);
+ extendedKeyCodesSet.add(0x01000000+0x05D7);
+ extendedKeyCodesSet.add(0x01000000+0x05D8);
+ extendedKeyCodesSet.add(0x01000000+0x05D9);
+ extendedKeyCodesSet.add(0x01000000+0x05DA);
+ extendedKeyCodesSet.add(0x01000000+0x05DB);
+ extendedKeyCodesSet.add(0x01000000+0x05DC);
+ extendedKeyCodesSet.add(0x01000000+0x05DD);
+ extendedKeyCodesSet.add(0x01000000+0x05DE);
+ extendedKeyCodesSet.add(0x01000000+0x05DF);
+ extendedKeyCodesSet.add(0x01000000+0x05E0);
+ extendedKeyCodesSet.add(0x01000000+0x05E1);
+ extendedKeyCodesSet.add(0x01000000+0x05E2);
+ extendedKeyCodesSet.add(0x01000000+0x05E3);
+ extendedKeyCodesSet.add(0x01000000+0x05E4);
+ extendedKeyCodesSet.add(0x01000000+0x05E5);
+ extendedKeyCodesSet.add(0x01000000+0x05E6);
+ extendedKeyCodesSet.add(0x01000000+0x05E7);
+ extendedKeyCodesSet.add(0x01000000+0x05E8);
+ extendedKeyCodesSet.add(0x01000000+0x05E9);
+ extendedKeyCodesSet.add(0x01000000+0x05EA);
+ extendedKeyCodesSet.add(0x01000000+0x0E01);
+ extendedKeyCodesSet.add(0x01000000+0x0E02);
+ extendedKeyCodesSet.add(0x01000000+0x0E03);
+ extendedKeyCodesSet.add(0x01000000+0x0E04);
+ extendedKeyCodesSet.add(0x01000000+0x0E05);
+ extendedKeyCodesSet.add(0x01000000+0x0E07);
+ extendedKeyCodesSet.add(0x01000000+0x0E08);
+ extendedKeyCodesSet.add(0x01000000+0x0E0A);
+ extendedKeyCodesSet.add(0x01000000+0x0E0C);
+ extendedKeyCodesSet.add(0x01000000+0x0E14);
+ extendedKeyCodesSet.add(0x01000000+0x0E15);
+ extendedKeyCodesSet.add(0x01000000+0x0E16);
+ extendedKeyCodesSet.add(0x01000000+0x0E17);
+ extendedKeyCodesSet.add(0x01000000+0x0E19);
+ extendedKeyCodesSet.add(0x01000000+0x0E1A);
+ extendedKeyCodesSet.add(0x01000000+0x0E1B);
+ extendedKeyCodesSet.add(0x01000000+0x0E1C);
+ extendedKeyCodesSet.add(0x01000000+0x0E1D);
+ extendedKeyCodesSet.add(0x01000000+0x0E1E);
+ extendedKeyCodesSet.add(0x01000000+0x0E1F);
+ extendedKeyCodesSet.add(0x01000000+0x0E20);
+ extendedKeyCodesSet.add(0x01000000+0x0E21);
+ extendedKeyCodesSet.add(0x01000000+0x0E22);
+ extendedKeyCodesSet.add(0x01000000+0x0E23);
+ extendedKeyCodesSet.add(0x01000000+0x0E25);
+ extendedKeyCodesSet.add(0x01000000+0x0E27);
+ extendedKeyCodesSet.add(0x01000000+0x0E2A);
+ extendedKeyCodesSet.add(0x01000000+0x0E2B);
+ extendedKeyCodesSet.add(0x01000000+0x0E2D);
+ extendedKeyCodesSet.add(0x01000000+0x0E30);
+ extendedKeyCodesSet.add(0x01000000+0x0E31);
+ extendedKeyCodesSet.add(0x01000000+0x0E32);
+ extendedKeyCodesSet.add(0x01000000+0x0E33);
+ extendedKeyCodesSet.add(0x01000000+0x0E34);
+ extendedKeyCodesSet.add(0x01000000+0x0E35);
+ extendedKeyCodesSet.add(0x01000000+0x0E36);
+ extendedKeyCodesSet.add(0x01000000+0x0E37);
+ extendedKeyCodesSet.add(0x01000000+0x0E38);
+ extendedKeyCodesSet.add(0x01000000+0x0E39);
+ extendedKeyCodesSet.add(0x01000000+0x0E3F);
+ extendedKeyCodesSet.add(0x01000000+0x0E40);
+ extendedKeyCodesSet.add(0x01000000+0x0E41);
+ extendedKeyCodesSet.add(0x01000000+0x0E43);
+ extendedKeyCodesSet.add(0x01000000+0x0E44);
+ extendedKeyCodesSet.add(0x01000000+0x0E45);
+ extendedKeyCodesSet.add(0x01000000+0x0E46);
+ extendedKeyCodesSet.add(0x01000000+0x0E47);
+ extendedKeyCodesSet.add(0x01000000+0x0E48);
+ extendedKeyCodesSet.add(0x01000000+0x0E49);
+ extendedKeyCodesSet.add(0x01000000+0x0E50);
+ extendedKeyCodesSet.add(0x01000000+0x0E51);
+ extendedKeyCodesSet.add(0x01000000+0x0E52);
+ extendedKeyCodesSet.add(0x01000000+0x0E53);
+ extendedKeyCodesSet.add(0x01000000+0x0E54);
+ extendedKeyCodesSet.add(0x01000000+0x0E55);
+ extendedKeyCodesSet.add(0x01000000+0x0E56);
+ extendedKeyCodesSet.add(0x01000000+0x0E57);
+ extendedKeyCodesSet.add(0x01000000+0x0E58);
+ extendedKeyCodesSet.add(0x01000000+0x0E59);
+ extendedKeyCodesSet.add(0x01000000+0x0587);
+ extendedKeyCodesSet.add(0x01000000+0x0589);
+ extendedKeyCodesSet.add(0x01000000+0x0589);
+ extendedKeyCodesSet.add(0x01000000+0x055D);
+ extendedKeyCodesSet.add(0x01000000+0x055D);
+ extendedKeyCodesSet.add(0x01000000+0x055B);
+ extendedKeyCodesSet.add(0x01000000+0x055B);
+ extendedKeyCodesSet.add(0x01000000+0x055E);
+ extendedKeyCodesSet.add(0x01000000+0x055E);
+ extendedKeyCodesSet.add(0x01000000+0x0561);
+ extendedKeyCodesSet.add(0x01000000+0x0562);
+ extendedKeyCodesSet.add(0x01000000+0x0563);
+ extendedKeyCodesSet.add(0x01000000+0x0564);
+ extendedKeyCodesSet.add(0x01000000+0x0565);
+ extendedKeyCodesSet.add(0x01000000+0x0566);
+ extendedKeyCodesSet.add(0x01000000+0x0567);
+ extendedKeyCodesSet.add(0x01000000+0x0568);
+ extendedKeyCodesSet.add(0x01000000+0x0569);
+ extendedKeyCodesSet.add(0x01000000+0x056A);
+ extendedKeyCodesSet.add(0x01000000+0x056B);
+ extendedKeyCodesSet.add(0x01000000+0x056C);
+ extendedKeyCodesSet.add(0x01000000+0x056D);
+ extendedKeyCodesSet.add(0x01000000+0x056E);
+ extendedKeyCodesSet.add(0x01000000+0x056F);
+ extendedKeyCodesSet.add(0x01000000+0x0570);
+ extendedKeyCodesSet.add(0x01000000+0x0571);
+ extendedKeyCodesSet.add(0x01000000+0x0572);
+ extendedKeyCodesSet.add(0x01000000+0x0573);
+ extendedKeyCodesSet.add(0x01000000+0x0574);
+ extendedKeyCodesSet.add(0x01000000+0x0575);
+ extendedKeyCodesSet.add(0x01000000+0x0576);
+ extendedKeyCodesSet.add(0x01000000+0x0577);
+ extendedKeyCodesSet.add(0x01000000+0x0578);
+ extendedKeyCodesSet.add(0x01000000+0x0579);
+ extendedKeyCodesSet.add(0x01000000+0x057A);
+ extendedKeyCodesSet.add(0x01000000+0x057B);
+ extendedKeyCodesSet.add(0x01000000+0x057C);
+ extendedKeyCodesSet.add(0x01000000+0x057D);
+ extendedKeyCodesSet.add(0x01000000+0x057E);
+ extendedKeyCodesSet.add(0x01000000+0x057F);
+ extendedKeyCodesSet.add(0x01000000+0x0580);
+ extendedKeyCodesSet.add(0x01000000+0x0581);
+ extendedKeyCodesSet.add(0x01000000+0x0582);
+ extendedKeyCodesSet.add(0x01000000+0x0583);
+ extendedKeyCodesSet.add(0x01000000+0x0584);
+ extendedKeyCodesSet.add(0x01000000+0x0585);
+ extendedKeyCodesSet.add(0x01000000+0x0586);
+ extendedKeyCodesSet.add(0x01000000+0x10D0);
+ extendedKeyCodesSet.add(0x01000000+0x10D1);
+ extendedKeyCodesSet.add(0x01000000+0x10D2);
+ extendedKeyCodesSet.add(0x01000000+0x10D3);
+ extendedKeyCodesSet.add(0x01000000+0x10D4);
+ extendedKeyCodesSet.add(0x01000000+0x10D5);
+ extendedKeyCodesSet.add(0x01000000+0x10D6);
+ extendedKeyCodesSet.add(0x01000000+0x10D7);
+ extendedKeyCodesSet.add(0x01000000+0x10D8);
+ extendedKeyCodesSet.add(0x01000000+0x10D9);
+ extendedKeyCodesSet.add(0x01000000+0x10DA);
+ extendedKeyCodesSet.add(0x01000000+0x10DB);
+ extendedKeyCodesSet.add(0x01000000+0x10DC);
+ extendedKeyCodesSet.add(0x01000000+0x10DD);
+ extendedKeyCodesSet.add(0x01000000+0x10DE);
+ extendedKeyCodesSet.add(0x01000000+0x10DF);
+ extendedKeyCodesSet.add(0x01000000+0x10E0);
+ extendedKeyCodesSet.add(0x01000000+0x10E1);
+ extendedKeyCodesSet.add(0x01000000+0x10E2);
+ extendedKeyCodesSet.add(0x01000000+0x10E3);
+ extendedKeyCodesSet.add(0x01000000+0x10E4);
+ extendedKeyCodesSet.add(0x01000000+0x10E5);
+ extendedKeyCodesSet.add(0x01000000+0x10E6);
+ extendedKeyCodesSet.add(0x01000000+0x10E7);
+ extendedKeyCodesSet.add(0x01000000+0x10E8);
+ extendedKeyCodesSet.add(0x01000000+0x10E9);
+ extendedKeyCodesSet.add(0x01000000+0x10EA);
+ extendedKeyCodesSet.add(0x01000000+0x10EB);
+ extendedKeyCodesSet.add(0x01000000+0x10EC);
+ extendedKeyCodesSet.add(0x01000000+0x10ED);
+ extendedKeyCodesSet.add(0x01000000+0x10EE);
+ extendedKeyCodesSet.add(0x01000000+0x10EF);
+ extendedKeyCodesSet.add(0x01000000+0x10F0);
+ extendedKeyCodesSet.add(0x01000000+0x01E7);
+ extendedKeyCodesSet.add(0x01000000+0x0259);
+ extendedKeyCodesSet.add(0x01000000+0x1EB9);
+ extendedKeyCodesSet.add(0x01000000+0x1ECB);
+ extendedKeyCodesSet.add(0x01000000+0x1ECD);
+ extendedKeyCodesSet.add(0x01000000+0x1EE5);
+ extendedKeyCodesSet.add(0x01000000+0x01A1);
+ extendedKeyCodesSet.add(0x01000000+0x01B0);
+ extendedKeyCodesSet.add(0x01000000+0x20AB);
+ }
+}
diff --git a/src/share/classes/sun/awt/HeadlessToolkit.java b/src/share/classes/sun/awt/HeadlessToolkit.java
index 18ccc446b..cfc5a47a3 100644
--- a/src/share/classes/sun/awt/HeadlessToolkit.java
+++ b/src/share/classes/sun/awt/HeadlessToolkit.java
@@ -179,9 +179,9 @@ public class HeadlessToolkit extends Toolkit
throw new HeadlessException();
}
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) throws HeadlessException {
- KeyboardFocusManagerPeerImpl peer = new KeyboardFocusManagerPeerImpl(manager);
- return peer;
+ public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
+ throws HeadlessException {
+ throw new HeadlessException();
}
public TrayIconPeer createTrayIcon(TrayIcon target)
diff --git a/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java b/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java
index 0d47a3fd2..6a8708a2a 100644
--- a/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java
+++ b/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,47 +27,150 @@ package sun.awt;
import java.awt.Component;
import java.awt.KeyboardFocusManager;
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.ComponentPeer;
import java.lang.reflect.InvocationTargetException;
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 {
- static native Window getNativeFocusedWindow();
- static native Component getNativeFocusOwner();
- static native void clearNativeGlobalFocusOwner(Window activeWindow);
+ // The constants are copied from java.awt.KeyboardFocusManager
+ public static final int SNFH_FAILURE = 0;
+ public static final int SNFH_SUCCESS_HANDLED = 1;
+ public static final int SNFH_SUCCESS_PROCEED = 2;
- KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) {
+ protected KeyboardFocusManager manager;
+
+ public KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) {
+ this.manager = manager;
}
- public Window getCurrentFocusedWindow() {
- return getNativeFocusedWindow();
+ @Override
+ 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() {
- return getNativeFocusOwner();
+ // WARNING: Don't call it on the Toolkit thread.
+ 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) {
- try {
- if (m_removeLastFocusRequest == null) {
- m_removeLastFocusRequest = SunToolkit.getMethod(KeyboardFocusManager.class, "removeLastFocusRequest",
- new Class[] {Component.class});
- }
- m_removeLastFocusRequest.invoke(null, new Object[]{heavyweight});
- } catch (InvocationTargetException ite) {
- ite.printStackTrace();
- } catch (IllegalAccessException ex) {
- ex.printStackTrace();
- }
+ kfmAccessor.removeLastFocusRequest(heavyweight);
+ }
+
+ // WARNING: Don't call it on the Toolkit thread.
+ public static boolean processSynchronousLightweightTransfer(Component heavyweight,
+ Component descendant,
+ boolean temporary,
+ boolean focusedWindowChangeAllowed,
+ long time)
+ {
+ return kfmAccessor.processSynchronousLightweightTransfer(
+ heavyweight, descendant, temporary, focusedWindowChangeAllowed, time);
}
}
diff --git a/src/share/classes/sun/awt/NullComponentPeer.java b/src/share/classes/sun/awt/NullComponentPeer.java
index 8818c4728..471aa75b5 100644
--- a/src/share/classes/sun/awt/NullComponentPeer.java
+++ b/src/share/classes/sun/awt/NullComponentPeer.java
@@ -278,19 +278,6 @@ public class NullComponentPeer implements LightweightPeer,
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() {
}
@@ -305,4 +292,19 @@ public class NullComponentPeer implements LightweightPeer,
*/
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;
+ }
}
diff --git a/src/share/classes/sun/awt/SunToolkit.java b/src/share/classes/sun/awt/SunToolkit.java
index 7c6f74856..ac99f4bab 100644
--- a/src/share/classes/sun/awt/SunToolkit.java
+++ b/src/share/classes/sun/awt/SunToolkit.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,14 +32,10 @@ import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.peer.*;
import java.awt.event.WindowEvent;
import java.awt.event.KeyEvent;
-import java.awt.im.spi.InputMethodDescriptor;
import java.awt.image.*;
-import java.awt.geom.AffineTransform;
import java.awt.TrayIcon;
import java.awt.SystemTray;
-import java.io.*;
import java.net.URL;
-import java.net.JarURLConnection;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
@@ -49,7 +45,6 @@ import java.util.logging.Logger;
import sun.misc.SoftCache;
import sun.font.FontDesignMetrics;
import sun.awt.im.InputContext;
-import sun.awt.im.SimpleInputMethodWindow;
import sun.awt.image.*;
import sun.security.action.GetPropertyAction;
import sun.security.action.GetBooleanAction;
@@ -225,10 +220,8 @@ public abstract class SunToolkit extends Toolkit
public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
throws AWTException;
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) throws HeadlessException {
- KeyboardFocusManagerPeerImpl peer = new KeyboardFocusManagerPeerImpl(manager);
- return peer;
- }
+ public abstract KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
+ throws HeadlessException;
/**
* The AWT lock is typically only used on Unix platforms to synchronize
@@ -824,16 +817,31 @@ public abstract class SunToolkit extends Toolkit
}
/**
- * Disables erasing of background on the canvas before painting
- * if this is supported by the current toolkit.
- *
- * @throws IllegalStateException if the canvas is not displayable
- * @see java.awt.Component#isDisplayable
+ * Disables erasing of background on the canvas before painting if
+ * this is supported by the current toolkit. It is recommended to
+ * call this method early, before the Canvas becomes displayable,
+ * because some Toolkit implementations do not support changing
+ * this property once the Canvas becomes displayable.
*/
public void disableBackgroundErase(Canvas canvas) {
- if (!canvas.isDisplayable()) {
- throw new IllegalStateException("Canvas must have a valid peer");
- }
+ disableBackgroundEraseImpl(canvas);
+ }
+
+ /**
+ * 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
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;
/**
@@ -1995,6 +2015,73 @@ public abstract class SunToolkit extends Toolkit
public boolean isNativeGTKAvailable() {
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
diff --git a/src/share/native/sun/awt/utility/rect.c b/src/share/native/sun/awt/utility/rect.c
new file mode 100644
index 000000000..00bbecb6e
--- /dev/null
+++ b/src/share/native/sun/awt/utility/rect.c
@@ -0,0 +1,102 @@
+/*
+ * 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
diff --git a/src/solaris/classes/sun/awt/X11/InfoWindow.java b/src/solaris/classes/sun/awt/X11/InfoWindow.java
new file mode 100644
index 000000000..ea485b2be
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/InfoWindow.java
@@ -0,0 +1,495 @@
+/*
+ * 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;
+ }
+ }
+ }
+}
+
diff --git a/src/solaris/classes/sun/awt/X11/XBaseWindow.java b/src/solaris/classes/sun/awt/X11/XBaseWindow.java
index ace8b5830..46491e04c 100644
--- a/src/solaris/classes/sun/awt/X11/XBaseWindow.java
+++ b/src/solaris/classes/sun/awt/X11/XBaseWindow.java
@@ -842,27 +842,35 @@ public class XBaseWindow {
| XConstants.ButtonMotionMask);
final int ownerEvents = 1;
- int ptrGrab = XlibWrapper.XGrabPointer(XToolkit.getDisplay(),
- getContentWindow(), ownerEvents, eventMask, XConstants.GrabModeAsync,
- XConstants.GrabModeAsync, XConstants.None, (XWM.isMotif() ? XToolkit.arrowCursor : XConstants.None),
- XConstants.CurrentTime);
- // Check grab results to be consistent with X server grab
- if (ptrGrab != XConstants.GrabSuccess) {
- XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);
- XAwtState.setGrabWindow(null);
- grabLog.fine(" Grab Failure - mouse");
- return false;
- }
- int keyGrab = XlibWrapper.XGrabKeyboard(XToolkit.getDisplay(),
- getContentWindow(), ownerEvents, XConstants.GrabModeAsync, XConstants.GrabModeAsync,
- XConstants.CurrentTime);
- if (keyGrab != XConstants.GrabSuccess) {
- XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);
- XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);
- XAwtState.setGrabWindow(null);
- grabLog.fine(" Grab Failure - keyboard");
- return false;
+ //6714678: IDE (Netbeans, Eclipse, JDeveloper) Debugger hangs
+ //process on Linux
+ //The user must pass the sun.awt.disablegrab property to disable
+ //taking grabs. This prevents hanging of the GUI when a breakpoint
+ //is hit while a popup window taking the grab is open.
+ if (!XToolkit.getSunAwtDisableGrab()) {
+ int ptrGrab = XlibWrapper.XGrabPointer(XToolkit.getDisplay(),
+ getContentWindow(), ownerEvents, eventMask, XConstants.GrabModeAsync,
+ XConstants.GrabModeAsync, XConstants.None, (XWM.isMotif() ? XToolkit.arrowCursor : XConstants.None),
+ XConstants.CurrentTime);
+ // Check grab results to be consistent with X server grab
+ if (ptrGrab != XConstants.GrabSuccess) {
+ XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);
+ XAwtState.setGrabWindow(null);
+ grabLog.fine(" Grab Failure - mouse");
+ return false;
+ }
+
+ int keyGrab = XlibWrapper.XGrabKeyboard(XToolkit.getDisplay(),
+ getContentWindow(), ownerEvents, XConstants.GrabModeAsync, XConstants.GrabModeAsync,
+ XConstants.CurrentTime);
+ if (keyGrab != XConstants.GrabSuccess) {
+ XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);
+ XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);
+ XAwtState.setGrabWindow(null);
+ grabLog.fine(" Grab Failure - keyboard");
+ return false;
+ }
}
if (prevGrabWindow != null) {
prevGrabWindow.ungrabInputImpl();
@@ -882,8 +890,10 @@ public class XBaseWindow {
grabLog.log(Level.FINE, "UnGrab input on {0}", new Object[] {grabWindow});
if (grabWindow != null) {
grabWindow.ungrabInputImpl();
- XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);
- XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);
+ if (!XToolkit.getSunAwtDisableGrab()) {
+ XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);
+ XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);
+ }
XAwtState.setGrabWindow(null);
// we need to call XFlush() here to force ungrab
// see 6384219 for details
diff --git a/src/solaris/classes/sun/awt/X11/XCanvasPeer.java b/src/solaris/classes/sun/awt/X11/XCanvasPeer.java
index 4c38c88b9..8fc6f1f7d 100644
--- a/src/solaris/classes/sun/awt/X11/XCanvasPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XCanvasPeer.java
@@ -27,7 +27,6 @@ package sun.awt.X11;
import java.awt.*;
import java.awt.peer.*;
-import sun.awt.ComponentAccessor;
import sun.awt.SunToolkit;
import sun.awt.X11GraphicsConfig;
@@ -54,60 +53,45 @@ class XCanvasPeer extends XComponentPeer implements CanvasPeer {
}
}
- void resetTargetGC(Component target) {
- ComponentAccessor.resetGC(target);
- }
-
- /*
- * Called when the Window this
- * Canvas is on is moved onto another Xinerama screen.
- *
- * Canvases can be created with a non-defulat GraphicsConfiguration. The
- * GraphicsConfiguration needs to be changed to one on the new screen,
- * preferably with the same visual ID.
- *
- * Up-called for other windows peer instances (XPanelPeer, XWindowPeer).
- *
- * Should only be called from the event thread.
- */
- public void displayChanged(int screenNum) {
- resetLocalGC(screenNum);
- resetTargetGC(target);
- }
-
- /* Set graphicsConfig to a GraphicsConfig with the same visual on the new
+ /* Get a GraphicsConfig with the same visual on the new
* screen, which should be easy in Xinerama mode.
- *
- * Should only be called from displayChanged(), and therefore only from
- * the event thread.
*/
- void resetLocalGC(int screenNum) {
+ public GraphicsConfiguration getAppropriateGraphicsConfiguration(
+ GraphicsConfiguration gc)
+ {
+ if (graphicsConfig == null || gc == null) {
+ return gc;
+ }
// Opt: Only need to do if we're not using the default GC
- if (graphicsConfig != null) {
- X11GraphicsConfig parentgc;
- // save vis id of current gc
- int visual = graphicsConfig.getVisual();
- X11GraphicsDevice newDev = (X11GraphicsDevice) GraphicsEnvironment.
- getLocalGraphicsEnvironment().
- getScreenDevices()[screenNum];
-
- for (int i = 0; i < newDev.getNumConfigs(screenNum); i++) {
- if (visual == newDev.getConfigVisualId(i, screenNum)) {
- // use that
- graphicsConfig = (X11GraphicsConfig)newDev.getConfigurations()[i];
- break;
- }
- }
- // just in case...
- if (graphicsConfig == null) {
- graphicsConfig = (X11GraphicsConfig) GraphicsEnvironment.
- getLocalGraphicsEnvironment().
- getScreenDevices()[screenNum].
- getDefaultConfiguration();
+ int screenNum = ((X11GraphicsDevice)gc.getDevice()).getScreen();
+
+ X11GraphicsConfig parentgc;
+ // save vis id of current gc
+ int visual = graphicsConfig.getVisual();
+
+ X11GraphicsDevice newDev = (X11GraphicsDevice) GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getScreenDevices()[screenNum];
+
+ for (int i = 0; i < newDev.getNumConfigs(screenNum); i++) {
+ if (visual == newDev.getConfigVisualId(i, screenNum)) {
+ // use that
+ graphicsConfig = (X11GraphicsConfig)newDev.getConfigurations()[i];
+ break;
}
}
+ // just in case...
+ if (graphicsConfig == null) {
+ graphicsConfig = (X11GraphicsConfig) GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getScreenDevices()[screenNum].
+ getDefaultConfiguration();
+ }
+
+ return graphicsConfig;
}
+
protected boolean shouldFocusOnClick() {
// Canvas should always be able to be focused by mouse clicks.
return true;
diff --git a/src/solaris/classes/sun/awt/X11/XComponentPeer.java b/src/solaris/classes/sun/awt/X11/XComponentPeer.java
index 8a14cfe5f..26db17c72 100644
--- a/src/solaris/classes/sun/awt/X11/XComponentPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XComponentPeer.java
@@ -35,6 +35,7 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
@@ -76,11 +77,6 @@ import sun.java2d.pipe.Region;
public class XComponentPeer extends XWindow implements ComponentPeer, DropTargetPeer,
BackBufferCapsProvider
{
- /* FIX ME: these constants copied from java.awt.KeyboardFocusManager */
- static final int SNFH_FAILURE = 0;
- static final int SNFH_SUCCESS_HANDLED = 1;
- static final int SNFH_SUCCESS_PROCEED = 2;
-
private static final Logger log = Logger.getLogger("sun.awt.X11.XComponentPeer");
private static final Logger buffersLog = Logger.getLogger("sun.awt.X11.XComponentPeer.multibuffer");
private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XComponentPeer");
@@ -166,7 +162,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
enableLog.log(Level.FINE, "Initial enable state: {0}", new Object[] {Boolean.valueOf(enabled)});
if (target.isVisible()) {
- show();
+ setVisible(true);
}
}
@@ -314,113 +310,27 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
return null;
}
- /**
- * Returns whether or not this component should be given focus on mouse click.
- * Default implementation return whether or not this peer is "focusable"
- * Descendants might want to override it to extend/restrict conditions at which this
- * component should be focused by click (see MCanvasPeer and MPanelPeer)
- */
- protected boolean shouldFocusOnClick() {
- return isFocusable();
- }
-
- /**
- * Checks whether or not this component would be focused by native system if it would be allowed to do so.
- * Currently it checks that it displayable, visible, enabled and focusable.
- */
- static boolean canBeFocusedByClick(Component component) {
- if (component == null) {
- return false;
- } else {
- return component.isDisplayable() && component.isVisible() && component.isEnabled() && component.isFocusable();
- }
- }
-
- static Window getContainingWindow(Component comp) {
- while (comp != null && !(comp instanceof Window)) {
- comp = comp.getParent();
- }
-
- return (Window)comp;
- }
-
- static Method processSynchronousLightweightTransferMethod;
- static boolean processSynchronousLightweightTransfer(Component heavyweight, Component descendant,
- boolean temporary, boolean focusedWindowChangeAllowed,
- long time)
- {
- try {
- if (processSynchronousLightweightTransferMethod == null) {
- processSynchronousLightweightTransferMethod =
- (Method)AccessController.doPrivileged(
- new PrivilegedExceptionAction() {
- public Object run() throws IllegalAccessException, NoSuchMethodException
- {
- Method m = KeyboardFocusManager.class.
- getDeclaredMethod("processSynchronousLightweightTransfer",
- new Class[] {Component.class, Component.class,
- Boolean.TYPE, Boolean.TYPE,
- Long.TYPE});
- m.setAccessible(true);
- return m;
- }
- });
- }
- Object[] params = new Object[] {
- heavyweight,
- descendant,
- Boolean.valueOf(temporary),
- Boolean.valueOf(focusedWindowChangeAllowed),
- Long.valueOf(time)
- };
- return ((Boolean)processSynchronousLightweightTransferMethod.invoke(null, params)).booleanValue();
- } catch (PrivilegedActionException pae) {
- pae.printStackTrace();
- return false;
- } catch (IllegalAccessException iae) {
- iae.printStackTrace();
- return false;
- } catch (IllegalArgumentException iaee) {
- iaee.printStackTrace();
- return false;
- } catch (InvocationTargetException ite) {
- ite.printStackTrace();
- return false;
- }
- }
-
- static Method requestFocusWithCause;
-
- static void callRequestFocus(Component target, CausedFocusEvent.Cause cause) {
- if (requestFocusWithCause == null) {
- requestFocusWithCause = SunToolkit.getMethod(Component.class, "requestFocus", new Class[] {CausedFocusEvent.Cause.class});
- }
- if (requestFocusWithCause != null) {
- try {
- requestFocusWithCause.invoke(target, new Object[] {cause});
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
+ // TODO: consider moving it to KeyboardFocusManagerPeerImpl
final public boolean requestFocus(Component lightweightChild, boolean temporary,
- boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause)
+ boolean focusedWindowChangeAllowed, long time,
+ CausedFocusEvent.Cause cause)
{
- if (processSynchronousLightweightTransfer(target, lightweightChild, temporary,
+ if (XKeyboardFocusManagerPeer.
+ processSynchronousLightweightTransfer(target, lightweightChild, temporary,
focusedWindowChangeAllowed, time))
{
return true;
}
- int result = XKeyboardFocusManagerPeer
- .shouldNativelyFocusHeavyweight(target, lightweightChild,
- temporary, focusedWindowChangeAllowed, time, cause);
+ int result = XKeyboardFocusManagerPeer.
+ shouldNativelyFocusHeavyweight(target, lightweightChild,
+ temporary, focusedWindowChangeAllowed,
+ time, cause);
switch (result) {
- case SNFH_FAILURE:
+ case XKeyboardFocusManagerPeer.SNFH_FAILURE:
return false;
- case SNFH_SUCCESS_PROCEED:
+ case XKeyboardFocusManagerPeer.SNFH_SUCCESS_PROCEED:
// Currently we just generate focus events like we deal with lightweight instead of calling
// XSetInputFocus on native window
if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Proceeding with request to " +
@@ -433,7 +343,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
* focus owner which had focus before WLF. So, we should not add request record for such requests
* but store this component in mostRecent - and return true as before for compatibility.
*/
- Window parentWindow = getContainingWindow(target);
+ Window parentWindow = SunToolkit.getContainingWindow(target);
if (parentWindow == null) {
return rejectFocusRequestHelper("WARNING: Parent window is null");
}
@@ -454,14 +364,13 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
if (!(res && parentWindow.isFocused())) {
return rejectFocusRequestHelper("Waiting for asynchronous processing of the request");
}
-
- // NOTE: We simulate heavyweight behavior of Motif - component receives focus right
- // after request, not after event. Normally, we should better listen for event
- // by listeners.
- return XKeyboardFocusManagerPeer.simulateMotifRequestFocus(lightweightChild, target, temporary,
- focusedWindowChangeAllowed, time, cause);
+ return XKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
+ (Component)target,
+ temporary,
+ focusedWindowChangeAllowed,
+ time, cause);
// Motif compatibility code
- case SNFH_SUCCESS_HANDLED:
+ case XKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
// Either lightweight or excessive request - all events are generated.
return true;
}
@@ -470,7 +379,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
private boolean rejectFocusRequestHelper(String logMsg) {
if (focusLog.isLoggable(Level.FINER)) focusLog.finer(logMsg);
- KeyboardFocusManagerPeerImpl.removeLastFocusRequest(target);
+ XKeyboardFocusManagerPeer.removeLastFocusRequest(target);
return false;
}
@@ -496,10 +405,6 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
xSetVisible(b);
}
- public void show() {
- setVisible(true);
- }
-
public void hide() {
setVisible(false);
}
@@ -618,8 +523,9 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
void handleJavaMouseEvent(MouseEvent e) {
switch (e.getID()) {
case MouseEvent.MOUSE_PRESSED:
- if (target == e.getSource() && shouldFocusOnClick()
- && !target.isFocusOwner() && canBeFocusedByClick(target))
+ if (target == e.getSource() &&
+ !target.isFocusOwner() &&
+ XKeyboardFocusManagerPeer.shouldFocusOnClick(target))
{
XWindowPeer parentXWindow = getParentTopLevel();
Window parentWindow = ((Window)parentXWindow.getTarget());
@@ -633,7 +539,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
// WindowEvent wfg = new WindowEvent(parentWindow, WindowEvent.WINDOW_GAINED_FOCUS);
// parentWindow.dispatchEvent(wfg);
// }
- callRequestFocus(target, CausedFocusEvent.Cause.MOUSE_EVENT);
+ XKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);
}
break;
}
@@ -1418,59 +1324,21 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
}
}
- public void restack() {
- synchronized(target.getTreeLock()) {
- // Build the list of X windows in the window corresponding to this container
- // This list is already in correct Java stacking order
- Container cont = (Container)target;
- Vector order = new Vector(cont.getComponentCount());
- HashSet set = new HashSet();
-
- addTree(order, set, cont);
-
- XToolkit.awtLock();
- try {
- // Get the current list of X window in X window. Some of the windows
- // might be only native
- XQueryTree qt = new XQueryTree(getContentWindow());
- try {
- if (qt.execute() != 0) {
- if (qt.get_nchildren() != 0) {
- long pchildren = qt.get_children();
- int j = 0; // index to insert
- for (int i = 0; i < qt.get_nchildren(); i++) {
- Long w = Long.valueOf(Native.getLong(pchildren, i));
- if (!set.contains(w)) {
- set.add(w);
- order.add(j++, w);
- }
- }
- }
- }
-
- if (order.size() != 0) {
- // Create native array of the windows
- long windows = Native.allocateLongArray(order.size());
- Native.putLong(windows, order);
-
- // Restack native window according to the new order
- XlibWrapper.XRestackWindows(XToolkit.getDisplay(), windows, order.size());
+ /**
+ * 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) {
+ long aboveWindow = (above != null) ? ((XComponentPeer)above).getWindow() : 0;
- XlibWrapper.unsafe.freeMemory(windows);
- }
- } finally {
- qt.dispose();
- }
- } finally {
- XToolkit.awtUnlock();
- }
+ XToolkit.awtLock();
+ try{
+ XlibWrapper.SetZOrder(XToolkit.getDisplay(), getWindow(), aboveWindow);
+ }finally{
+ XToolkit.awtUnlock();
}
}
- public boolean isRestackSupported() {
- return true;
- }
-
private void addTree(Collection order, Set set, Container cont) {
for (int i = 0; i < cont.getComponentCount(); i++) {
Component comp = cont.getComponent(i);
@@ -1560,4 +1428,8 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
}
}
}
+
+ public void updateGraphicsData(GraphicsConfiguration gc) {
+ initGraphicsConfiguration();
+ }
}
diff --git a/src/solaris/classes/sun/awt/X11/XConstants.java b/src/solaris/classes/sun/awt/X11/XConstants.java
index 7d9077ee6..23275398a 100644
--- a/src/solaris/classes/sun/awt/X11/XConstants.java
+++ b/src/solaris/classes/sun/awt/X11/XConstants.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -684,4 +684,19 @@ final public class XConstants {
public static final int LSBFirst = 0 ;
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
+
}
diff --git a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
index 42ccabee3..739713dd7 100644
--- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
@@ -383,7 +383,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
dimensions.setInsets(getRealInsets());
insets_corrected = true;
- if (isMaximized() || isNull(correction)) {
+ if (isMaximized()) {
return;
}
@@ -451,7 +451,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
public Insets getInsets() {
Insets in = copy(getRealInsets());
- in.top += getMenuBarHeight() + getWarningWindowHeight();
+ in.top += getMenuBarHeight();
if (insLog.isLoggable(Level.FINEST)) {
insLog.log(Level.FINEST, "Get insets returns {0}", new Object[] {in});
}
@@ -802,6 +802,8 @@ abstract class XDecoratedPeer extends XWindowPeer {
}
reconfigureContentWindow(newDimensions);
updateChildrenSizes();
+
+ repositionSecurityWarning();
}
private void checkShellRectSize(Rectangle shellRect) {
diff --git a/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java b/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java
index e4500043a..b3474ffdb 100644
--- a/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java
@@ -184,6 +184,7 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
fl = new FocusEvent(currentOwner, FocusEvent.FOCUS_LOST, false, lightweightChild);
}
+ // TODO: do we need to wrap in sequenced?
if (fl != null) {
postEvent(XComponentPeer.wrapInSequenced(fl));
}
@@ -203,9 +204,9 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
temporary, false, time, cause);
switch (result) {
- case XComponentPeer.SNFH_FAILURE:
+ case XKeyboardFocusManagerPeer.SNFH_FAILURE:
return false;
- case XComponentPeer.SNFH_SUCCESS_PROCEED:
+ case XKeyboardFocusManagerPeer.SNFH_SUCCESS_PROCEED:
// Currently we just generate focus events like we deal with lightweight instead of calling
// XSetInputFocus on native window
@@ -235,9 +236,11 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
// NOTE: We simulate heavyweight behavior of Motif - component receives focus right
// after request, not after event. Normally, we should better listen for event
// by listeners.
+
+ // TODO: consider replacing with XKeyboardFocusManagerPeer.deliverFocus
return simulateMotifRequestFocus(lightweightChild, temporary, focusedWindowChangeAllowed, time);
// Motif compatibility code
- case XComponentPeer.SNFH_SUCCESS_HANDLED:
+ case XKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
// Either lightweight or excessive requiest - all events are generated.
return true;
}
@@ -379,4 +382,9 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
public void applyShape(Region shape) {
}
+
+ public void setZOrder(ComponentPeer above) {
+ }
+
+ public void updateGraphicsData(GraphicsConfiguration gc) {}
}
diff --git a/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java b/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java
index 0675847af..0b8085e75 100644
--- a/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java
@@ -739,7 +739,17 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
this.filter = filter;
}
- public void show() {
+
+ public void dispose() {
+ FileDialog fd = (FileDialog)fileDialog;
+ if (fd != null) {
+ fd.removeAll();
+ }
+ super.dispose();
+ }
+
+ // 03/02/2005 b5097243 Pressing 'ESC' on a file dlg does not dispose the dlg on Xtoolkit
+ public void setVisible(boolean b){
if (fileDialog == null) {
init((FileDialog)target);
}
@@ -754,34 +764,20 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
setFile(savedFile);
}
- super.show();
- selectionField.requestFocusInWindow();
- }
-
- public void dispose() {
- FileDialog fd = (FileDialog)fileDialog;
- if (fd != null) {
- fd.removeAll();
- }
- super.dispose();
- }
-
- // 03/02/2005 b5097243 Pressing 'ESC' on a file dlg does not dispose the dlg on Xtoolkit
- public void setVisible(boolean b){
super.setVisible(b);
if (b == true){
// See 6240074 for more information
XChoicePeer choicePeer = (XChoicePeer)pathChoice.getPeer();
choicePeer.addXChoicePeerListener(this);
-
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
}else{
// See 6240074 for more information
XChoicePeer choicePeer = (XChoicePeer)pathChoice.getPeer();
choicePeer.removeXChoicePeerListener();
-
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this);
}
+
+ selectionField.requestFocusInWindow();
}
/*
diff --git a/src/solaris/classes/sun/awt/X11/XFramePeer.java b/src/solaris/classes/sun/awt/X11/XFramePeer.java
index 3820bf610..22cb163eb 100644
--- a/src/solaris/classes/sun/awt/X11/XFramePeer.java
+++ b/src/solaris/classes/sun/awt/X11/XFramePeer.java
@@ -36,6 +36,7 @@ import java.awt.Rectangle;
import java.awt.peer.FramePeer;
import java.util.logging.Level;
import java.util.logging.Logger;
+import sun.awt.AWTAccessor;
class XFramePeer extends XDecoratedPeer implements FramePeer {
private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer");
@@ -231,13 +232,19 @@ class XFramePeer extends XDecoratedPeer implements FramePeer {
}
}
- public int getState() { return state; }
+ public int getState() {
+ synchronized(getStateLock()) {
+ return state;
+ }
+ }
public void setState(int newState) {
- if (!isShowing()) {
- stateLog.finer("Frame is not showing");
- state = newState;
- return;
+ synchronized(getStateLock()) {
+ if (!isShowing()) {
+ stateLog.finer("Frame is not showing");
+ state = newState;
+ return;
+ }
}
changeState(newState);
}
@@ -296,6 +303,9 @@ class XFramePeer extends XDecoratedPeer implements FramePeer {
int old_state = state;
state = newState;
+ // sync target with peer
+ AWTAccessor.getFrameAccessor().setExtendedState((Frame)target, state);
+
if ((changed & Frame.ICONIFIED) != 0) {
if ((state & Frame.ICONIFIED) != 0) {
stateLog.finer("Iconified");
diff --git a/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java b/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java
index c4a10be59..19c213441 100644
--- a/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java
@@ -31,6 +31,7 @@ import java.awt.Window;
import java.awt.event.FocusEvent;
import java.awt.peer.KeyboardFocusManagerPeer;
+import java.awt.peer.ComponentPeer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -40,136 +41,90 @@ import java.util.logging.Logger;
import sun.awt.CausedFocusEvent;
import sun.awt.SunToolkit;
+import sun.awt.KeyboardFocusManagerPeerImpl;
-public class XKeyboardFocusManagerPeer implements KeyboardFocusManagerPeer {
+public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XKeyboardFocusManagerPeer");
- KeyboardFocusManager manager;
-
- XKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
- this.manager = manager;
- }
private static Object lock = new Object() {};
private static Component currentFocusOwner;
private static Window currentFocusedWindow;
- static void setCurrentNativeFocusOwner(Component comp) {
- if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Setting current native focus owner " + comp);
- synchronized(lock) {
- currentFocusOwner = comp;
- }
- }
-
- static void setCurrentNativeFocusedWindow(Window win) {
- if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Setting current native focused window " + win);
- synchronized(lock) {
- currentFocusedWindow = win;
- }
+ XKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+ super(manager);
}
- static Component getCurrentNativeFocusOwner() {
- synchronized(lock) {
- return currentFocusOwner;
- }
+ @Override
+ public void setCurrentFocusOwner(Component comp) {
+ setCurrentNativeFocusOwner(comp);
}
- static Window getCurrentNativeFocusedWindow() {
- synchronized(lock) {
- return currentFocusedWindow;
- }
+ @Override
+ public Component getCurrentFocusOwner() {
+ return getCurrentNativeFocusOwner();
}
+ @Override
public Window getCurrentFocusedWindow() {
return getCurrentNativeFocusedWindow();
}
- public void setCurrentFocusOwner(Component comp) {
- setCurrentNativeFocusOwner(comp);
+ public static void setCurrentNativeFocusOwner(Component comp) {
+ synchronized (lock) {
+ currentFocusOwner = comp;
+ }
}
- public Component getCurrentFocusOwner() {
- return getCurrentNativeFocusOwner();
+ public static Component getCurrentNativeFocusOwner() {
+ synchronized(lock) {
+ return currentFocusOwner;
+ }
}
- 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) {
-// XComponentPeer nativePeer = XComponentPeer.getNativeContainer(focusOwner);
-// if (nativePeer != null) {
- FocusEvent fl = new CausedFocusEvent(focusOwner, FocusEvent.FOCUS_LOST, false, null,
- CausedFocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER);
- XWindow.sendEvent(fl);
-// }
+ public static void setCurrentNativeFocusedWindow(Window win) {
+ if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Setting current native focused window " + win);
+ XWindowPeer from = null, to = null;
+
+ synchronized(lock) {
+ if (currentFocusedWindow != null) {
+ from = (XWindowPeer)currentFocusedWindow.getPeer();
}
- }
- }
- static boolean simulateMotifRequestFocus(Component lightweightChild, Component target, boolean temporary,
- boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause)
- {
- if (lightweightChild == null) {
- lightweightChild = (Component)target;
+ currentFocusedWindow = win;
+
+ if (currentFocusedWindow != null) {
+ to = (XWindowPeer)currentFocusedWindow.getPeer();
+ }
}
- Component currentOwner = XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
- if (currentOwner != null && currentOwner.getPeer() == null) {
- currentOwner = null;
+
+ if (from != null) {
+ from.updateSecurityWarningVisibility();
}
- if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Simulating transfer from " + currentOwner + " to " + lightweightChild);
- FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED, false, currentOwner, cause);
- FocusEvent fl = null;
- if (currentOwner != null) {
- fl = new CausedFocusEvent(currentOwner, FocusEvent.FOCUS_LOST, false, lightweightChild, cause);
+ if (to != null) {
+ to.updateSecurityWarningVisibility();
}
+ }
- if (fl != null) {
- XWindow.sendEvent(fl);
+ public static Window getCurrentNativeFocusedWindow() {
+ synchronized(lock) {
+ return currentFocusedWindow;
}
- XWindow.sendEvent(fg);
- return true;
}
- static Method shouldNativelyFocusHeavyweightMethod;
-
- static int shouldNativelyFocusHeavyweight(Component heavyweight,
- Component descendant, boolean temporary,
- boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause)
+ // TODO: do something to eliminate this forwarding
+ public static boolean deliverFocus(Component lightweightChild,
+ Component target,
+ boolean temporary,
+ boolean focusedWindowChangeAllowed,
+ long time,
+ CausedFocusEvent.Cause cause)
{
- if (shouldNativelyFocusHeavyweightMethod == null) {
- Class[] arg_types =
- new Class[] { Component.class,
- Component.class,
- Boolean.TYPE,
- Boolean.TYPE,
- Long.TYPE,
- CausedFocusEvent.Cause.class
- };
-
- shouldNativelyFocusHeavyweightMethod =
- SunToolkit.getMethod(KeyboardFocusManager.class,
- "shouldNativelyFocusHeavyweight",
- arg_types);
- }
- Object[] args = new Object[] { heavyweight,
- descendant,
- Boolean.valueOf(temporary),
- Boolean.valueOf(focusedWindowChangeAllowed),
- Long.valueOf(time), cause};
-
- int result = XComponentPeer.SNFH_FAILURE;
- if (shouldNativelyFocusHeavyweightMethod != null) {
- try {
- result = ((Integer) shouldNativelyFocusHeavyweightMethod.invoke(null, args)).intValue();
- }
- catch (IllegalAccessException e) {
- assert false;
- }
- catch (InvocationTargetException e) {
- assert false;
- }
- }
-
- return result;
+ return KeyboardFocusManagerPeerImpl.deliverFocus(lightweightChild,
+ target,
+ temporary,
+ focusedWindowChangeAllowed,
+ time,
+ cause,
+ getCurrentNativeFocusOwner());
}
}
diff --git a/src/solaris/classes/sun/awt/X11/XKeysym.java b/src/solaris/classes/sun/awt/X11/XKeysym.java
index 9ec3d1c71..bac5aba2a 100644
--- a/src/solaris/classes/sun/awt/X11/XKeysym.java
+++ b/src/solaris/classes/sun/awt/X11/XKeysym.java
@@ -1,7 +1,7 @@
// This is a generated file: do not edit! Edit keysym2ucs.h if necessary.
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-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
@@ -89,14 +89,47 @@ public class XKeysym {
Character ch = keysym2UCSHash.get(ks);
return ch == null ? (char)0 : ch.charValue();
}
+ static long xkeycode2keysym_noxkb(XKeyEvent ev, int ndx) {
+ XToolkit.awtLock();
+ try {
+ return XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx);
+ } finally {
+ XToolkit.awtUnlock();
+ }
+ }
+ static long xkeycode2keysym_xkb(XKeyEvent ev, int ndx) {
+ XToolkit.awtLock();
+ try {
+ int mods = ev.get_state();
+ if ((ndx == 0) && ((mods & XConstants.ShiftMask) != 0)) {
+ // I don't know all possible meanings of 'ndx' in case of XKB
+ // and don't want to speculate. But this particular case
+ // clearly means that caller needs a so called primary keysym.
+ mods ^= XConstants.ShiftMask;
+ }
+ XlibWrapper.XkbTranslateKeyCode(XToolkit.getXKBKbdDesc(), ev.get_keycode(),
+ mods, XlibWrapper.iarg1, XlibWrapper.larg3);
+ //XXX unconsumed modifiers?
+ return Native.getLong(XlibWrapper.larg3);
+ } finally {
+ XToolkit.awtUnlock();
+ }
+ }
static long xkeycode2keysym(XKeyEvent ev, int ndx) {
XToolkit.awtLock();
try {
- return XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx );
+ if (XToolkit.canUseXKBCalls()) {
+ return xkeycode2keysym_xkb(ev, ndx);
+ }else{
+ return xkeycode2keysym_noxkb(ev, ndx);
+ }
} finally {
XToolkit.awtUnlock();
}
}
+ static long xkeycode2primary_keysym(XKeyEvent ev) {
+ return xkeycode2keysym(ev, 0);
+ }
public static boolean isKPEvent( XKeyEvent ev )
{
// Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
@@ -198,6 +231,27 @@ public class XKeysym {
Keysym2JavaKeycode jkc = getJavaKeycode( ev );
return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode();
}
+ /**
+ * Return an integer java keycode apprx as it was before extending keycodes range.
+ * This call would ignore for instance XKB and process whatever is on the bottom
+ * of keysym stack. Result will not depend on actual locale, will differ between
+ * dual/multiple keyboard setup systems (e.g. English+Russian vs French+Russian)
+ * but will be someway compatible with old releases.
+ */
+ static int getLegacyJavaKeycodeOnly( XKeyEvent ev ) {
+ long keysym = XConstants.NoSymbol;
+ int ndx = 0;
+ if( (ev.get_state() & XToolkit.numLockMask) != 0 &&
+ isKPEvent(ev)) {
+ keysym = getKeypadKeysym( ev );
+ } else {
+ // we only need primary-layer keysym to derive a java keycode.
+ ndx = 0;
+ keysym = xkeycode2keysym_noxkb(ev, ndx);
+ }
+ Keysym2JavaKeycode jkc = keysym2JavaKeycodeHash.get( keysym );
+ return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode();
+ }
static long javaKeycode2Keysym( int jkey ) {
Long ks = javaKeycode2KeysymHash.get( jkey );
return (ks == null ? 0 : ks.longValue());
diff --git a/src/solaris/classes/sun/awt/X11/XNETProtocol.java b/src/solaris/classes/sun/awt/X11/XNETProtocol.java
index 68145a74f..1bc8829d9 100644
--- a/src/solaris/classes/sun/awt/X11/XNETProtocol.java
+++ b/src/solaris/classes/sun/awt/X11/XNETProtocol.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -169,6 +169,34 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
return ((layer == LAYER_ALWAYS_ON_TOP) || (layer == LAYER_NORMAL)) && doLayerProtocol();
}
+ public void requestState(XWindow window, XAtom state, boolean isAdd) {
+ XClientMessageEvent req = new XClientMessageEvent();
+ try {
+ req.set_type((int)XConstants.ClientMessage);
+ req.set_window(window.getWindow());
+ req.set_message_type(XA_NET_WM_STATE.getAtom());
+ req.set_format(32);
+ req.set_data(0, isAdd ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);
+ req.set_data(1, state.getAtom());
+ // Fix for 6735584: req.data[2] must be set to 0 when only one property is changed
+ req.set_data(2, 0);
+ log.log(Level.FINE, "Setting _NET_STATE atom {0} on {1} for {2}", new Object[] {state, window, Boolean.valueOf(isAdd)});
+ XToolkit.awtLock();
+ try {
+ XlibWrapper.XSendEvent(XToolkit.getDisplay(),
+ XlibWrapper.RootWindow(XToolkit.getDisplay(), window.getScreenNumber()),
+ false,
+ XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask,
+ req.pData);
+ }
+ finally {
+ XToolkit.awtUnlock();
+ }
+ } finally {
+ req.dispose();
+ }
+ }
+
/**
* Helper function to set/reset one state in NET_WM_STATE
* If window is showing then it uses ClientMessage, otherwise adjusts NET_WM_STATE list
@@ -181,31 +209,7 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
new Object[] {Boolean.valueOf(window.isWithdrawn()), Boolean.valueOf(window.isVisible()),
Boolean.valueOf(window.isMapped()), Boolean.valueOf(window.isShowing())});
if (window.isShowing()) {
- XClientMessageEvent req = new XClientMessageEvent();
- try {
- req.set_type((int)XConstants.ClientMessage);
- req.set_window(window.getWindow());
- req.set_message_type(XA_NET_WM_STATE.getAtom());
- req.set_format(32);
- req.set_data(0, (!set) ? _NET_WM_STATE_REMOVE : _NET_WM_STATE_ADD);
- req.set_data(1, state.getAtom());
- // Fix for 6735584: req.data[2] must be set to 0 when only one property is changed
- req.set_data(2, 0);
- log.log(Level.FINE, "Setting _NET_STATE atom {0} on {1} for {2}", new Object[] {state, window, Boolean.valueOf(set)});
- XToolkit.awtLock();
- try {
- XlibWrapper.XSendEvent(XToolkit.getDisplay(),
- XlibWrapper.RootWindow(XToolkit.getDisplay(), window.getScreenNumber()),
- false,
- XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask,
- req.pData);
- }
- finally {
- XToolkit.awtUnlock();
- }
- } finally {
- req.dispose();
- }
+ requestState(window, state, set);
} else {
XAtomList net_wm_state = window.getNETWMState();
log.log(Level.FINE, "Current state on {0} is {1}", new Object[] {window, net_wm_state});
@@ -252,6 +256,8 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
XAtom XA_NET_WM_WINDOW_TYPE = XAtom.get("_NET_WM_WINDOW_TYPE");
XAtom XA_NET_WM_WINDOW_TYPE_DIALOG = XAtom.get("_NET_WM_WINDOW_TYPE_DIALOG");
+ XAtom XA_NET_WM_WINDOW_OPACITY = XAtom.get("_NET_WM_WINDOW_OPACITY");
+
/* For _NET_WM_STATE ClientMessage requests */
final static int _NET_WM_STATE_REMOVE =0; /* remove/unset property */
final static int _NET_WM_STATE_ADD =1; /* add/set property */
@@ -289,6 +295,12 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE_MODAL);
return res;
}
+
+ boolean doOpacityProtocol() {
+ boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_WINDOW_OPACITY);
+ return res;
+ }
+
boolean isWMName(String name) {
if (!active()) {
return false;
diff --git a/src/solaris/classes/sun/awt/X11/XPanelPeer.java b/src/solaris/classes/sun/awt/X11/XPanelPeer.java
index aac632569..c070fcf3a 100644
--- a/src/solaris/classes/sun/awt/X11/XPanelPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XPanelPeer.java
@@ -130,39 +130,6 @@ public class XPanelPeer extends XCanvasPeer implements PanelPeer {
return getInsets();
}
- /*
- * This method is called from XWindowPeer.displayChanged, when
- * the window this Panel is on is moved to the new screen, or
- * display mode is changed.
- *
- * The notification is propagated to the child Canvas components.
- * Top-level windows and other Panels are notified too as their
- * peers are subclasses of XCanvasPeer.
- */
- public void displayChanged(int screenNum) {
- super.displayChanged(screenNum);
- displayChanged((Container)target, screenNum);
- }
-
- /*
- * Recursively iterates through all the HW and LW children
- * of the container and calls displayChanged() for HW peers.
- * Iteration through children peers only is not enough as the
- * displayChanged notification may not be propagated to HW
- * components inside LW containers, see 4452373 for details.
- */
- private static void displayChanged(Container target, int screenNum) {
- Component children[] = ((Container)target).getComponents();
- for (Component child : children) {
- ComponentPeer cpeer = child.getPeer();
- if (cpeer instanceof XCanvasPeer) {
- ((XCanvasPeer)cpeer).displayChanged(screenNum);
- } else if (child instanceof Container) {
- displayChanged((Container)child, screenNum);
- }
- }
- }
-
public void dispose() {
if (embedder != null) {
embedder.deinstall();
diff --git a/src/solaris/classes/sun/awt/X11/XToolkit.java b/src/solaris/classes/sun/awt/X11/XToolkit.java
index c3011dfa6..8a5030c83 100644
--- a/src/solaris/classes/sun/awt/X11/XToolkit.java
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,7 @@ import sun.awt.*;
import sun.font.FontManager;
import sun.misc.PerformanceLogger;
import sun.print.PrintJob2D;
+import sun.security.action.GetBooleanAction;
public final class XToolkit extends UNIXToolkit implements Runnable {
private static Logger log = Logger.getLogger("sun.awt.X11.XToolkit");
@@ -291,6 +292,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
if (XlibWrapper.XSetLocaleModifiers("") == null) {
log.finer("X locale modifiers are not supported, using default");
}
+ tryXKB();
AwtScreenData defaultScreen = new AwtScreenData(XToolkit.getDefaultScreenData());
awt_defaultFg = defaultScreen.get_blackpixel();
@@ -313,6 +315,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
if (xs != null) {
((XAWTXSettings)xs).dispose();
}
+ freeXKB();
if (log.isLoggable(Level.FINE)) {
dumpPeers();
}
@@ -591,6 +594,9 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
if (ev.get_type() != XConstants.NoExpose) {
eventNumber++;
}
+ if (awt_UseXKB_Calls && ev.get_type() == awt_XKBBaseEventCode) {
+ processXkbChanges(ev);
+ }
if (XDropTargetEventProcessor.processEvent(ev) ||
XDragSourceContextPeer.processEvent(ev)) {
@@ -2093,8 +2099,12 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
static boolean awt_ServerInquired = false;
static boolean awt_IsXsunServer = false;
- static boolean awt_XKBInquired = false;
static boolean awt_UseXKB = false;
+ static boolean awt_UseXKB_Calls = false;
+ static int awt_XKBBaseEventCode = 0;
+ static int awt_XKBEffectiveGroup = 0; // so far, I don't use it leaving all calculations
+ // to XkbTranslateKeyCode
+ static long awt_XKBDescPtr = 0;
/**
Try to understand if it is Xsun server.
By now (2005) Sun is vendor of Xsun and Xorg servers; we only return true if Xsun is running.
@@ -2124,23 +2134,143 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
awtUnlock();
}
}
+ static boolean isXKBenabled() {
+ awtLock();
+ try {
+ return awt_UseXKB;
+ } finally {
+ awtUnlock();
+ }
+ }
+
/**
Query XKEYBOARD extension.
+ If possible, initialize xkb library.
*/
- static boolean isXKBenabled() {
+ static boolean tryXKB() {
awtLock();
try {
- if( awt_XKBInquired ) {
- return awt_UseXKB;
- }
- awt_XKBInquired = true;
String name = "XKEYBOARD";
+ // First, if there is extension at all.
awt_UseXKB = XlibWrapper.XQueryExtension( getDisplay(), name, XlibWrapper.larg1, XlibWrapper.larg2, XlibWrapper.larg3);
+ if( awt_UseXKB ) {
+ // There is a keyboard extension. Check if a client library is compatible.
+ // If not, don't use xkb calls.
+ // In this case we still may be Xkb-capable application.
+ awt_UseXKB_Calls = XlibWrapper.XkbLibraryVersion( XlibWrapper.larg1, XlibWrapper.larg2);
+ if( awt_UseXKB_Calls ) {
+ awt_UseXKB_Calls = XlibWrapper.XkbQueryExtension( getDisplay(), XlibWrapper.larg1, XlibWrapper.larg2,
+ XlibWrapper.larg3, XlibWrapper.larg4, XlibWrapper.larg5);
+ if( awt_UseXKB_Calls ) {
+ awt_XKBBaseEventCode = Native.getInt(XlibWrapper.larg2);
+ XlibWrapper.XkbSelectEvents (getDisplay(),
+ XConstants.XkbUseCoreKbd,
+ XConstants.XkbNewKeyboardNotifyMask |
+ XConstants.XkbMapNotifyMask ,//|
+ //XConstants.XkbStateNotifyMask,
+ XConstants.XkbNewKeyboardNotifyMask |
+ XConstants.XkbMapNotifyMask );//|
+ //XConstants.XkbStateNotifyMask);
+
+ XlibWrapper.XkbSelectEventDetails(getDisplay(), XConstants.XkbUseCoreKbd,
+ XConstants.XkbStateNotify,
+ XConstants.XkbGroupStateMask,
+ XConstants.XkbGroupStateMask);
+ //XXX ? XkbGroupLockMask last, XkbAllStateComponentsMask before last?
+ awt_XKBDescPtr = XlibWrapper.XkbGetMap(getDisplay(),
+ XConstants.XkbKeyTypesMask |
+ XConstants.XkbKeySymsMask |
+ XConstants.XkbModifierMapMask |
+ XConstants.XkbVirtualModsMask,
+ XConstants.XkbUseCoreKbd);
+ }
+ }
+ }
return awt_UseXKB;
} finally {
awtUnlock();
}
}
+ static boolean canUseXKBCalls() {
+ awtLock();
+ try {
+ return awt_UseXKB_Calls;
+ } finally {
+ awtUnlock();
+ }
+ }
+ static int getXKBEffectiveGroup() {
+ awtLock();
+ try {
+ return awt_XKBEffectiveGroup;
+ } finally {
+ awtUnlock();
+ }
+ }
+ static int getXKBBaseEventCode() {
+ awtLock();
+ try {
+ return awt_XKBBaseEventCode;
+ } finally {
+ awtUnlock();
+ }
+ }
+ static long getXKBKbdDesc() {
+ awtLock();
+ try {
+ return awt_XKBDescPtr;
+ } finally {
+ awtUnlock();
+ }
+ }
+ void freeXKB() {
+ awtLock();
+ try {
+ if (awt_UseXKB_Calls && awt_XKBDescPtr != 0) {
+ XlibWrapper.XkbFreeKeyboard(awt_XKBDescPtr, 0xFF, true);
+ }
+ } finally {
+ awtUnlock();
+ }
+ }
+ private void processXkbChanges(XEvent ev) {
+ // mapping change --> refresh kbd map
+ // state change --> get a new effective group; do I really need it
+ // or that should be left for XkbTranslateKeyCode?
+ XkbEvent xke = new XkbEvent( ev.getPData() );
+ int xkb_type = xke.get_any().get_xkb_type();
+ switch( xkb_type ) {
+ case XConstants.XkbNewKeyboardNotify :
+ if( awt_XKBDescPtr != 0 ) {
+ freeXKB();
+ }
+ awt_XKBDescPtr = XlibWrapper.XkbGetMap(getDisplay(),
+ XConstants.XkbKeyTypesMask |
+ XConstants.XkbKeySymsMask |
+ XConstants.XkbModifierMapMask |
+ XConstants.XkbVirtualModsMask,
+ XConstants.XkbUseCoreKbd);
+ //System.out.println("XkbNewKeyboard:"+(xke.get_new_kbd()));
+ break;
+ case XConstants.XkbMapNotify :
+ //TODO: provide a simple unit test.
+ XlibWrapper.XkbGetUpdatedMap(getDisplay(),
+ XConstants.XkbKeyTypesMask |
+ XConstants.XkbKeySymsMask |
+ XConstants.XkbModifierMapMask |
+ XConstants.XkbVirtualModsMask,
+ awt_XKBDescPtr);
+ //System.out.println("XkbMap:"+(xke.get_map()));
+ break;
+ case XConstants.XkbStateNotify :
+ // May use it later e.g. to obtain an effective group etc.
+ //System.out.println("XkbState:"+(xke.get_state()));
+ break;
+ default:
+ //System.out.println("XkbEvent of xkb_type "+xkb_type);
+ break;
+ }
+ }
private static long eventNumber;
public static long getEventNumber() {
@@ -2273,4 +2403,44 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
return areExtraMouseButtonsEnabled;
}
+
+ @Override
+ public boolean isWindowOpacitySupported() {
+ XNETProtocol net_protocol = XWM.getWM().getNETProtocol();
+
+ if (net_protocol == null) {
+ return false;
+ }
+
+ return net_protocol.doOpacityProtocol();
+ }
+
+ @Override
+ public boolean isWindowShapingSupported() {
+ return XlibUtil.isShapingSupported();
+ }
+
+ @Override
+ public boolean isWindowTranslucencySupported() {
+ //NOTE: it may not be supported. The actual check is being performed
+ // at com.sun.awt.AWTUtilities(). In X11 we need to check
+ // whether there's any translucency-capable GC available.
+ return true;
+ }
+
+ @Override
+ public boolean isTranslucencyCapable(GraphicsConfiguration gc) {
+ if (!(gc instanceof X11GraphicsConfig)) {
+ return false;
+ }
+ return ((X11GraphicsConfig)gc).isTranslucencyCapable();
+ }
+
+ /**
+ * Returns the value of "sun.awt.disablegrab" property. Default
+ * value is {@code false}.
+ */
+ public static boolean getSunAwtDisableGrab() {
+ return AccessController.doPrivileged(new GetBooleanAction("sun.awt.disablegrab"));
+ }
}
diff --git a/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java b/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java
index ff690bf9d..b1243abac 100644
--- a/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java
@@ -38,15 +38,18 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.lang.reflect.InvocationTargetException;
-public class XTrayIconPeer implements TrayIconPeer {
+public class XTrayIconPeer implements TrayIconPeer,
+ InfoWindow.Balloon.LiveArguments,
+ InfoWindow.Tooltip.LiveArguments
+{
private static final Logger ctrLog = Logger.getLogger("sun.awt.X11.XTrayIconPeer.centering");
TrayIcon target;
TrayIconEventProxy eventProxy;
XTrayIconEmbeddedFrame eframe;
TrayIconCanvas canvas;
- Balloon balloon;
- Tooltip tooltip;
+ InfoWindow.Balloon balloon;
+ InfoWindow.Tooltip tooltip;
PopupMenu popup;
String tooltipString;
boolean isTrayIconDisplayed;
@@ -255,8 +258,8 @@ public class XTrayIconPeer implements TrayIconPeer {
eframe.setVisible(true);
updateImage();
- balloon = new Balloon(this, eframe);
- tooltip = new Tooltip(this, eframe);
+ balloon = new InfoWindow.Balloon(eframe, target, this);
+ tooltip = new InfoWindow.Tooltip(eframe, target, this);
addListeners();
}
@@ -300,6 +303,10 @@ public class XTrayIconPeer implements TrayIconPeer {
tooltipString = tooltip;
}
+ public String getTooltipString() {
+ return tooltipString;
+ }
+
public void updateImage() {
Runnable r = new Runnable() {
public void run() {
@@ -385,7 +392,7 @@ public class XTrayIconPeer implements TrayIconPeer {
return eframe.getLocationOnScreen();
}
- private Rectangle getBounds() {
+ public Rectangle getBounds() {
Point loc = getLocationOnScreen();
return new Rectangle(loc.x, loc.y, loc.x + TRAY_ICON_WIDTH, loc.y + TRAY_ICON_HEIGHT);
}
@@ -399,10 +406,14 @@ public class XTrayIconPeer implements TrayIconPeer {
return ((XEmbeddedFramePeer)eframe.getPeer()).getWindow();
}
- boolean isDisposed() {
+ public boolean isDisposed() {
return isDisposed;
}
+ public String getActionCommand() {
+ return target.getActionCommand();
+ }
+
static class TrayIconEventProxy implements MouseListener, MouseMotionListener {
XTrayIconPeer xtiPeer;
@@ -474,8 +485,8 @@ public class XTrayIconPeer implements TrayIconPeer {
}
static boolean isTrayIconStuffWindow(Window w) {
- return (w instanceof Tooltip) ||
- (w instanceof Balloon) ||
+ return (w instanceof InfoWindow.Tooltip) ||
+ (w instanceof InfoWindow.Balloon) ||
(w instanceof XTrayIconEmbeddedFrame);
}
@@ -530,7 +541,7 @@ public class XTrayIconPeer implements TrayIconPeer {
}
}
- static class IconCanvas extends Canvas {
+ public static class IconCanvas extends Canvas {
volatile Image image;
IconObserver observer;
int width, height;
@@ -608,429 +619,4 @@ public class XTrayIconPeer implements TrayIconPeer {
}
}
}
-
- // ***************************************
- // Classes for toolitp and balloon windows
- // ***************************************
-
- static class Tooltip extends InfoWindow {
- XTrayIconPeer xtiPeer;
- Label textLabel = new Label("");
- Runnable starter = new Runnable() {
- public void run() {
- display();
- }};
-
- final static int TOOLTIP_SHOW_TIME = 10000;
- final static int TOOLTIP_START_DELAY_TIME = 1000;
- final static int TOOLTIP_MAX_LENGTH = 64;
- final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5;
- final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220);
- final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont();
-
- Tooltip(XTrayIconPeer xtiPeer, Frame parent) {
- super(parent, Color.black);
- this.xtiPeer = xtiPeer;
-
- 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!
- */
- void display() {
- String tip = xtiPeer.tooltipString;
- if (tip == null) {
- return;
- } else if (tip.length() > TOOLTIP_MAX_LENGTH) {
- textLabel.setText(tip.substring(0, TOOLTIP_MAX_LENGTH));
- } else {
- textLabel.setText(tip);
- }
-
- // Execute on EDT to avoid deadlock (see 6280857).
- SunToolkit.executeOnEventHandlerThread(xtiPeer.target, new Runnable() {
- public void run() {
- if (xtiPeer.isDisposed()) {
- return;
- }
- Point pointer = (Point)AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- if (!isPointerOverTrayIcon(xtiPeer.getBounds())) {
- return null;
- }
- return MouseInfo.getPointerInfo().getLocation();
- }
- });
- if (pointer == null) {
- return;
- }
- show(new Point(pointer.x, pointer.y), TOOLTIP_MOUSE_CURSOR_INDENT);
- }
- });
- }
-
- void enter() {
- XToolkit.schedule(starter, TOOLTIP_START_DELAY_TIME);
- }
-
- void exit() {
- XToolkit.remove(starter);
- if (isVisible()) {
- hide();
- }
- }
-
- 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));
- }
- }
-
- static class Balloon extends InfoWindow {
- final static int BALLOON_SHOW_TIME = 10000;
- final static int BALLOON_TEXT_MAX_LENGTH = 256;
- final static int BALLOON_WORD_LINE_MAX_LENGTH = 16;
- final static int BALLOON_WORD_LINE_MAX_COUNT = 4;
- final static int BALLOON_ICON_WIDTH = 32;
- final static int BALLOON_ICON_HEIGHT = 32;
- final static int BALLOON_TRAY_ICON_INDENT = 0;
- final static Color BALLOON_CAPTION_BACKGROUND_COLOR = new Color(200, 200 ,255);
- final static Font BALLOON_CAPTION_FONT = new Font(Font.DIALOG, Font.BOLD, 12);
-
- XTrayIconPeer xtiPeer;
- Panel mainPanel = new Panel();
- Panel captionPanel = new Panel();
- Label captionLabel = new Label("");
- Button closeButton = new Button("X");
- Panel textPanel = new Panel();
- IconCanvas iconCanvas = new IconCanvas(BALLOON_ICON_WIDTH, BALLOON_ICON_HEIGHT);
- Label[] lineLabels = new Label[BALLOON_WORD_LINE_MAX_COUNT];
- ActionPerformer ap = new ActionPerformer();
-
- Image iconImage;
- Image errorImage;
- Image warnImage;
- Image infoImage;
- boolean gtkImagesLoaded;
-
- Displayer displayer = new Displayer();
-
- Balloon(final XTrayIconPeer xtiPeer, Frame parent) {
- super(parent, new Color(90, 80 ,190));
- this.xtiPeer = xtiPeer;
-
- 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();
- }
-
- 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(xtiPeer.target, new Runnable() {
- public void run() {
- if (xtiPeer.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();
- }
-
- 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;
- }
- }
-
- 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(xtiPeer.target, ActionEvent.ACTION_PERFORMED,
- xtiPeer.target.getActionCommand(),
- e.getWhen(), e.getModifiers());
- Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(aev);
- }
- }
- }
-
- 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));
- }
- }
-
- class Message {
- String caption, text, messageType;
-
- Message(String caption, String text, String messageType) {
- this.caption = caption;
- this.text = text;
- this.messageType = messageType;
- }
- }
- }
-
- static class InfoWindow extends Window {
- Container container;
- Closer closer;
-
- InfoWindow(Frame parent, Color borderColor) {
- super(parent);
- container = new Container() {
- 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;
- }
-
- 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(InfoWindow.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);
- }
-
- InfoWindow.super.show();
- InfoWindow.this.closer.schedule();
- }
-
- public void hide() {
- closer.close();
- }
-
- 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();
- }
- }
- });
- }
- }
- }
}
diff --git a/src/solaris/classes/sun/awt/X11/XWM.java b/src/solaris/classes/sun/awt/X11/XWM.java
index c3adec9aa..66ac1e0d7 100644
--- a/src/solaris/classes/sun/awt/X11/XWM.java
+++ b/src/solaris/classes/sun/awt/X11/XWM.java
@@ -896,7 +896,7 @@ final class XWM
/*
* Set MWM decorations. Set MWM functions depending on resizability.
*/
- static void setMotifDecor(XWindowPeer window, boolean resizable, int decorations, int functions) {
+ static void setMotifDecor(XWindow window, boolean resizable, int decorations, int functions) {
/* Apparently some WMs don't implement MWM_*_ALL semantic correctly */
if ((decorations & MWMConstants.MWM_DECOR_ALL) != 0
&& (decorations != MWMConstants.MWM_DECOR_ALL))
diff --git a/src/solaris/classes/sun/awt/X11/XWarningWindow.java b/src/solaris/classes/sun/awt/X11/XWarningWindow.java
index f53034d0d..adb536440 100644
--- a/src/solaris/classes/sun/awt/X11/XWarningWindow.java
+++ b/src/solaris/classes/sun/awt/X11/XWarningWindow.java
@@ -25,16 +25,194 @@
package sun.awt.X11;
import java.awt.*;
+import java.awt.event.*;
+import java.awt.geom.Point2D;
+import java.lang.ref.WeakReference;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.pipe.Region;
+import sun.awt.AWTAccessor;
+import sun.awt.SunToolkit;
class XWarningWindow extends XWindow {
- final static int defaultHeight = 27;
+ private final static int showingDelay = 330;
+ private final static int hidingDelay = 2000;
- Window ownerWindow;
- XWarningWindow(Window ownerWindow, long parentWindow) {
- super(ownerWindow, parentWindow);
+ private final Window ownerWindow;
+ private WeakReference<XWindowPeer> ownerPeer;
+
+ public final Window getOwnerWindow() {
+ return ownerWindow;
+ }
+ private long parentWindow;
+
+ private final static String OWNER = "OWNER";
+
+ private static XIconInfo[][] icons;
+
+ private InfoWindow.Tooltip tooltip;
+
+ private static synchronized XIconInfo getSecurityIconInfo(int size, int num) {
+ if (icons == null) {
+ icons = new XIconInfo[4][3];
+ if (XlibWrapper.dataModel == 32) {
+ icons[0][0] = new XIconInfo(XAWTIcon32_security_icon_bw16_png.security_icon_bw16_png);
+ icons[0][1] = new XIconInfo(XAWTIcon32_security_icon_interim16_png.security_icon_interim16_png);
+ icons[0][2] = new XIconInfo(XAWTIcon32_security_icon_yellow16_png.security_icon_yellow16_png);
+ icons[1][0] = new XIconInfo(XAWTIcon32_security_icon_bw24_png.security_icon_bw24_png);
+ icons[1][1] = new XIconInfo(XAWTIcon32_security_icon_interim24_png.security_icon_interim24_png);
+ icons[1][2] = new XIconInfo(XAWTIcon32_security_icon_yellow24_png.security_icon_yellow24_png);
+ icons[2][0] = new XIconInfo(XAWTIcon32_security_icon_bw32_png.security_icon_bw32_png);
+ icons[2][1] = new XIconInfo(XAWTIcon32_security_icon_interim32_png.security_icon_interim32_png);
+ icons[2][2] = new XIconInfo(XAWTIcon32_security_icon_yellow32_png.security_icon_yellow32_png);
+ icons[3][0] = new XIconInfo(XAWTIcon32_security_icon_bw48_png.security_icon_bw48_png);
+ icons[3][1] = new XIconInfo(XAWTIcon32_security_icon_interim48_png.security_icon_interim48_png);
+ icons[3][2] = new XIconInfo(XAWTIcon32_security_icon_yellow48_png.security_icon_yellow48_png);
+ } else {
+ icons[0][0] = new XIconInfo(XAWTIcon64_security_icon_bw16_png.security_icon_bw16_png);
+ icons[0][1] = new XIconInfo(XAWTIcon64_security_icon_interim16_png.security_icon_interim16_png);
+ icons[0][2] = new XIconInfo(XAWTIcon64_security_icon_yellow16_png.security_icon_yellow16_png);
+ icons[1][0] = new XIconInfo(XAWTIcon64_security_icon_bw24_png.security_icon_bw24_png);
+ icons[1][1] = new XIconInfo(XAWTIcon64_security_icon_interim24_png.security_icon_interim24_png);
+ icons[1][2] = new XIconInfo(XAWTIcon64_security_icon_yellow24_png.security_icon_yellow24_png);
+ icons[2][0] = new XIconInfo(XAWTIcon64_security_icon_bw32_png.security_icon_bw32_png);
+ icons[2][1] = new XIconInfo(XAWTIcon64_security_icon_interim32_png.security_icon_interim32_png);
+ icons[2][2] = new XIconInfo(XAWTIcon64_security_icon_yellow32_png.security_icon_yellow32_png);
+ icons[3][0] = new XIconInfo(XAWTIcon64_security_icon_bw48_png.security_icon_bw48_png);
+ icons[3][1] = new XIconInfo(XAWTIcon64_security_icon_interim48_png.security_icon_interim48_png);
+ icons[3][2] = new XIconInfo(XAWTIcon64_security_icon_yellow48_png.security_icon_yellow48_png);
+ }
+ }
+ final int sizeIndex = size % icons.length;
+ return icons[sizeIndex][num % icons[sizeIndex].length];
+ }
+
+ private volatile int currentIcon = 0;
+
+ /* -1 - uninitialized yet
+ * 0 - 16x16
+ * 1 - 24x24
+ * 2 - 32x32
+ * 3 - 48x48
+ */
+ private volatile int currentSize = -1;
+
+ /** Indicates whether the shape of the window must be updated
+ */
+ private volatile boolean sizeUpdated = true;
+
+ private synchronized boolean updateIconSize() {
+ int newSize = currentSize;
+
+ if (ownerWindow != null) {
+ Insets insets = ownerWindow.getInsets();
+ int max = Math.max(insets.top, Math.max(insets.bottom,
+ Math.max(insets.left, insets.right)));
+ if (max < 24) {
+ newSize = 0;
+ } else if (max < 32) {
+ newSize = 1;
+ } else if (max < 48) {
+ newSize = 2;
+ } else {
+ newSize = 3;
+ }
+ }
+ if (newSize != currentSize) {
+ currentSize = newSize;
+ sizeUpdated = true;
+ }
+ return sizeUpdated;
+ }
+
+ private synchronized XIconInfo getSecurityIconInfo() {
+ updateIconSize();
+ return getSecurityIconInfo(currentSize, currentIcon);
+ }
+
+ XWarningWindow(final Window ownerWindow, long parentWindow, XWindowPeer ownerPeer) {
+ super(new XCreateWindowParams(new Object[] {
+ TARGET, ownerWindow,
+ OWNER, Long.valueOf(parentWindow)
+ }));
this.ownerWindow = ownerWindow;
- xSetVisible(true);
- toFront();
+ this.parentWindow = parentWindow;
+ this.tooltip = new InfoWindow.Tooltip(null, getTarget(),
+ new InfoWindow.Tooltip.LiveArguments() {
+ public boolean isDisposed() {
+ return XWarningWindow.this.isDisposed();
+ }
+ public Rectangle getBounds() {
+ return XWarningWindow.this.getBounds();
+ }
+ public String getTooltipString() {
+ return XWarningWindow.this.ownerWindow.getWarningString();
+ }
+ });
+ this.ownerPeer = new WeakReference<XWindowPeer>(ownerPeer);
+ }
+
+ private void requestNoTaskbar() {
+ XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
+ if (netProtocol != null) {
+ netProtocol.requestState(this, netProtocol.XA_NET_WM_STATE_SKIP_TASKBAR, true);
+ }
+ }
+
+ @Override
+ void postInit(XCreateWindowParams params) {
+ super.postInit(params);
+ XToolkit.awtLock();
+ try {
+ XWM.setMotifDecor(this, false, 0, 0);
+ XWM.setOLDecor(this, false, 0);
+
+ long parentWindow = ((Long)params.get(OWNER)).longValue();
+ XlibWrapper.XSetTransientFor(XToolkit.getDisplay(),
+ getWindow(), parentWindow);
+
+ XWMHints hints = getWMHints();
+ hints.set_flags(hints.get_flags() | (int)XUtilConstants.InputHint | (int)XUtilConstants.StateHint);
+ hints.set_input(false);
+ hints.set_initial_state(XUtilConstants.NormalState);
+ XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
+
+ initWMProtocols();
+ requestNoTaskbar();
+ } finally {
+ XToolkit.awtUnlock();
+ }
+ }
+
+ private void updateWarningWindowBounds() {
+ XWindowPeer peer = ownerPeer.get();
+ if (peer != null) {
+ synchronized (this) {
+ if (updateIconSize()) {
+ XIconInfo ico = getSecurityIconInfo();
+ XToolkit.awtLock();
+ try {
+ XlibWrapper.SetBitmapShape(XToolkit.getDisplay(), getWindow(),
+ ico.getWidth(), ico.getHeight(), ico.getIntData());
+ } finally {
+ XToolkit.awtUnlock();
+ }
+ sizeUpdated = false;
+ AWTAccessor.getWindowAccessor().setSecurityWarningSize(
+ ownerWindow, ico.getWidth(), ico.getHeight());
+ }
+ }
+ peer.repositionSecurityWarning();
+ }
+ }
+
+ /**
+ * @param x,y,w,h coordinates of the untrusted window
+ */
+ public void reposition(int x, int y, int w, int h) {
+ Point2D point = AWTAccessor.getWindowAccessor().
+ calculateSecurityWarningPosition(ownerWindow,
+ x, y, w, h);
+ reshape((int)point.getX(), (int)point.getY(), getWidth(), getHeight());
}
protected String getWMName() {
@@ -49,33 +227,19 @@ class XWarningWindow extends XWindow {
getFont());
}
void paint(Graphics g, int x, int y, int width, int height) {
- String warningString = getWarningString();
- Rectangle bounds = getBounds();
- bounds.x = 0;
- bounds.y = 0;
- Rectangle updateRect = new Rectangle(x, y, width, height);
- if (updateRect.intersects(bounds)) {
- Rectangle updateArea = updateRect.intersection(bounds);
- g.setClip(updateArea);
- g.setColor(getBackground());
- g.fillRect(updateArea.x, updateArea.y, updateArea.width, updateArea.height);
- g.setColor(getColor());
- g.setFont(getFont());
- FontMetrics fm = g.getFontMetrics();
- int warningWidth = fm.stringWidth(warningString);
- int w_x = (bounds.width - warningWidth)/2;
- int w_y = (bounds.height + fm.getMaxAscent() - fm.getMaxDescent())/2;
- g.drawString(warningString, w_x, w_y);
- g.drawLine(bounds.x, bounds.y+bounds.height-1, bounds.x+bounds.width-1, bounds.y+bounds.height-1);
- }
+ g.drawImage(getSecurityIconInfo().getImage(), 0, 0, null);
}
String getWarningString() {
return ownerWindow.getWarningString();
}
+ int getWidth() {
+ return getSecurityIconInfo().getWidth();
+ }
+
int getHeight() {
- return defaultHeight; // should implement depending on Font
+ return getSecurityIconInfo().getHeight();
}
Color getBackground() {
@@ -97,6 +261,7 @@ class XWarningWindow extends XWindow {
}
}
+ @Override
public void handleExposeEvent(XEvent xev) {
super.handleExposeEvent(xev);
@@ -105,18 +270,156 @@ class XWarningWindow extends XWindow {
final int y = xe.get_y();
final int width = xe.get_width();
final int height = xe.get_height();
- EventQueue.invokeLater(new Runnable() {
- public void run() {
- Graphics g = getGraphics();
- try {
- paint(g, x, y, width, height);
- } finally {
- g.dispose();
- }
- }
- });
+ SunToolkit.executeOnEventHandlerThread(target,
+ new Runnable() {
+ public void run() {
+ Graphics g = getGraphics();
+ try {
+ paint(g, x, y, width, height);
+ } finally {
+ g.dispose();
+ }
+ }
+ });
}
+
+ @Override
protected boolean isEventDisabled(XEvent e) {
return true;
}
+
+ /** Send a synthetic UnmapNotify in order to withdraw the window.
+ */
+ private void withdraw() {
+ XEvent req = new XEvent();
+ try {
+ long root;
+ XToolkit.awtLock();
+ try {
+ root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
+ }
+ finally {
+ XToolkit.awtUnlock();
+ }
+
+ req.set_type(XConstants.UnmapNotify);
+
+ XUnmapEvent umev = req.get_xunmap();
+
+ umev.set_event(root);
+ umev.set_window(getWindow());
+ umev.set_from_configure(false);
+
+ XToolkit.awtLock();
+ try {
+ XlibWrapper.XSendEvent(XToolkit.getDisplay(),
+ root,
+ false,
+ XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask,
+ req.pData);
+ }
+ finally {
+ XToolkit.awtUnlock();
+ }
+ } finally {
+ req.dispose();
+ }
+ }
+
+ @Override
+ protected void stateChanged(long time, int oldState, int newState) {
+ if (newState == XUtilConstants.IconicState) {
+ super.xSetVisible(false);
+ withdraw();
+ }
+ }
+
+ @Override
+ protected void setMouseAbove(boolean above) {
+ super.setMouseAbove(above);
+ XWindowPeer p = ownerPeer.get();
+ if (p != null) {
+ p.updateSecurityWarningVisibility();
+ }
+ }
+
+ @Override
+ protected void enterNotify(long window) {
+ super.enterNotify(window);
+ if (window == getWindow()) {
+ tooltip.enter();
+ }
+ }
+
+ @Override
+ protected void leaveNotify(long window) {
+ super.leaveNotify(window);
+ if (window == getWindow()) {
+ tooltip.exit();
+ }
+ }
+
+ @Override
+ public void xSetVisible(boolean visible) {
+ super.xSetVisible(visible);
+
+ // The _NET_WM_STATE_SKIP_TASKBAR got reset upon hiding/showing,
+ // so we request it every time whenever we change the visibility.
+ requestNoTaskbar();
+ }
+
+ private final Runnable hidingTask = new Runnable() {
+ public void run() {
+ xSetVisible(false);
+ }
+ };
+
+ private final Runnable showingTask = new Runnable() {
+ public void run() {
+ new Thread() {
+ public void run() {
+ if (!isVisible()) {
+ xSetVisible(true);
+ updateWarningWindowBounds();
+ }
+ repaint();
+ if (currentIcon > 0) {
+ currentIcon--;
+ XToolkit.schedule(showingTask, showingDelay);
+ }
+ }}.start();
+ }
+ };
+
+ public void setSecurityWarningVisible(boolean visible) {
+ setSecurityWarningVisible(visible, true);
+ }
+
+ public void setSecurityWarningVisible(boolean visible, boolean doSchedule) {
+ if (visible) {
+ XToolkit.remove(hidingTask);
+ XToolkit.remove(showingTask);
+ if (isVisible()) {
+ currentIcon = 0;
+ } else {
+ currentIcon = 3;
+ }
+ if (doSchedule) {
+ XToolkit.schedule(showingTask, 1);
+ } else {
+ showingTask.run();
+ }
+ } else {
+ XToolkit.remove(showingTask);
+ XToolkit.remove(hidingTask);
+ if (!isVisible()) {
+ return;
+ }
+ if (doSchedule) {
+ XToolkit.schedule(hidingTask, hidingDelay);
+ } else {
+ hidingTask.run();
+ }
+ }
+ }
}
diff --git a/src/solaris/classes/sun/awt/X11/XWindow.java b/src/solaris/classes/sun/awt/X11/XWindow.java
index 5601273d8..6c517b196 100644
--- a/src/solaris/classes/sun/awt/X11/XWindow.java
+++ b/src/solaris/classes/sun/awt/X11/XWindow.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,15 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
int oldWidth = -1;
int oldHeight = -1;
+ protected PropMwmHints mwm_hints;
+ protected static XAtom wm_protocols;
+ protected static XAtom wm_delete_window;
+ protected static XAtom wm_take_focus;
+
+ private boolean stateChanged; // Indicates whether the value on savedState is valid
+ private int savedState; // Holds last known state of the top-level window
+
+ XWindowAttributesData winAttr;
protected X11GraphicsConfig graphicsConfig;
protected AwtGraphicsConfigData graphicsConfigData;
@@ -119,6 +128,9 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
private native static void initIDs();
private static Field isPostedField;
+ private static Field rawCodeField;
+ private static Field primaryLevelUnicodeField;
+ private static Field extendedKeyCodeField;
static {
initIDs();
}
@@ -218,6 +230,20 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
}
params.putIfNull(BACKING_STORE, XToolkit.getBackingStoreType());
+
+ XToolkit.awtLock();
+ try {
+ if (wm_protocols == null) {
+ wm_protocols = XAtom.get("WM_PROTOCOLS");
+ wm_delete_window = XAtom.get("WM_DELETE_WINDOW");
+ wm_take_focus = XAtom.get("WM_TAKE_FOCUS");
+ }
+ }
+ finally {
+ XToolkit.awtUnlock();
+ }
+ winAttr = new XWindowAttributesData();
+ savedState = XUtilConstants.WithdrawnState;
}
void postInit(XCreateWindowParams params) {
@@ -832,12 +858,42 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
public native boolean x11inputMethodLookupString(long event, long [] keysymArray);
native boolean haveCurrentX11InputMethodInstance();
+ private boolean mouseAboveMe;
+
+ public boolean isMouseAbove() {
+ synchronized (getStateLock()) {
+ return mouseAboveMe;
+ }
+ }
+ protected void setMouseAbove(boolean above) {
+ synchronized (getStateLock()) {
+ mouseAboveMe = above;
+ }
+ }
+
+ protected void enterNotify(long window) {
+ if (window == getWindow()) {
+ setMouseAbove(true);
+ }
+ }
+ protected void leaveNotify(long window) {
+ if (window == getWindow()) {
+ setMouseAbove(false);
+ }
+ }
+
public void handleXCrossingEvent(XEvent xev) {
super.handleXCrossingEvent(xev);
XCrossingEvent xce = xev.get_xcrossing();
if (eventLog.isLoggable(Level.FINEST)) eventLog.finest(xce.toString());
+ if (xce.get_type() == XConstants.EnterNotify) {
+ enterNotify(xce.get_window());
+ } else { // LeaveNotify:
+ leaveNotify(xce.get_window());
+ }
+
// Skip event If it was caused by a grab
// This is needed because on displays with focus-follows-mouse on MousePress X system generates
// two XCrossing events with mode != NormalNotify. First of them notifies that the mouse has left
@@ -984,7 +1040,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
Parameter is a keysym basically from keysymdef.h
XXX: how about vendor keys? Is there some with Unicode value and not in the list?
*/
- char keysymToUnicode( long keysym, int state ) {
+ int keysymToUnicode( long keysym, int state ) {
return XKeysym.convertKeysym( keysym, state );
}
int keyEventType2Id( int xEventType ) {
@@ -994,6 +1050,13 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
static private long xkeycodeToKeysym(XKeyEvent ev) {
return XKeysym.getKeysym( ev );
}
+ private long xkeycodeToPrimaryKeysym(XKeyEvent ev) {
+ return XKeysym.xkeycode2primary_keysym( ev );
+ }
+ static private int primaryUnicode2JavaKeycode(int uni) {
+ return (uni > 0? sun.awt.ExtendedKeyCodes.getExtendedKeyCodeForChar(uni) : 0);
+ //return (uni > 0? uni + 0x01000000 : 0);
+ }
void logIncomingKeyEvent(XKeyEvent ev) {
keyEventLog.fine("--XWindow.java:handleKeyEvent:"+ev);
dumpKeysymArray(ev);
@@ -1012,7 +1075,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
// un-final it if you need to override it in a subclass.
final void handleKeyPress(XKeyEvent ev) {
long keysym[] = new long[2];
- char unicodeKey = 0;
+ int unicodeKey = 0;
keysym[0] = XConstants.NoSymbol;
if (keyEventLog.isLoggable(Level.FINE)) {
@@ -1057,19 +1120,36 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
if( jkc == null ) {
jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
}
+
+ // Take the first keysym from a keysym array associated with the XKeyevent
+ // and convert it to Unicode. Then, even if a Java keycode for the keystroke
+ // is undefined, we still have a guess of what has been engraved on a keytop.
+ int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
+
if (keyEventLog.isLoggable(Level.FINE)) {
keyEventLog.fine(">>>Fire Event:"+
(ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
"jkeycode:decimal="+jkc.getJavaKeycode()+
- ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "
+ ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
+ " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
+ ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
);
}
+
+ int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
+ int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
+ primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
+ jkc.getJavaKeycode();
postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
ev.get_time(),
- jkc.getJavaKeycode(),
+ jkeyToReturn,
(unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
jkc.getKeyLocation(),
- ev.get_state(),ev.getPData(), XKeyEvent.getSize());
+ ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
+ unicodeFromPrimaryKeysym,
+ jkeyExtended);
+
+
if( unicodeKey > 0 ) {
keyEventLog.fine("fire _TYPED on "+unicodeKey);
postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
@@ -1077,7 +1157,10 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
java.awt.event.KeyEvent.VK_UNDEFINED,
unicodeKey,
java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN,
- ev.get_state(),ev.getPData(), XKeyEvent.getSize());
+ ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)0,
+ unicodeFromPrimaryKeysym,
+ java.awt.event.KeyEvent.VK_UNDEFINED);
+
}
@@ -1095,7 +1178,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
// un-private it if you need to call it from elsewhere
private void handleKeyRelease(XKeyEvent ev) {
long keysym[] = new long[2];
- char unicodeKey = 0;
+ int unicodeKey = 0;
keysym[0] = XConstants.NoSymbol;
if (keyEventLog.isLoggable(Level.FINE)) {
@@ -1113,7 +1196,9 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
keyEventLog.fine(">>>Fire Event:"+
(ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
"jkeycode:decimal="+jkc.getJavaKeycode()+
- ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "
+ ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
+ " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
+ ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
);
}
// We obtain keysym from IM and derive unicodeKey from it for KeyPress only.
@@ -1124,15 +1209,76 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
// That's why we use the same procedure as if there was no IM instance: do-it-yourself unicode.
unicodeKey = keysymToUnicode( xkeycodeToKeysym(ev), ev.get_state() );
+ // Take a first keysym from a keysym array associated with the XKeyevent
+ // and convert it to Unicode. Then, even if Java keycode for the keystroke
+ // is undefined, we still will have a guess of what was engraved on a keytop.
+ int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
+
+ int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
+ int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
+ primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
+ jkc.getJavaKeycode();
postKeyEvent( java.awt.event.KeyEvent.KEY_RELEASED,
ev.get_time(),
- jkc.getJavaKeycode(),
+ jkeyToReturn,
(unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
jkc.getKeyLocation(),
- ev.get_state(),ev.getPData(), XKeyEvent.getSize());
+ ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
+ unicodeFromPrimaryKeysym,
+ jkeyExtended);
+
}
+ /*
+ * XmNiconic and Map/UnmapNotify (that XmNiconic relies on) are
+ * unreliable, since mapping changes can happen for a virtual desktop
+ * switch or MacOS style shading that became quite popular under X as
+ * well. Yes, it probably should not be this way, as it violates
+ * ICCCM, but reality is that quite a lot of window managers abuse
+ * mapping state.
+ */
+ int getWMState() {
+ if (stateChanged) {
+ stateChanged = false;
+ WindowPropertyGetter getter =
+ new WindowPropertyGetter(window, XWM.XA_WM_STATE, 0, 1, false,
+ XWM.XA_WM_STATE);
+ try {
+ int status = getter.execute();
+ if (status != XConstants.Success || getter.getData() == 0) {
+ return savedState = XUtilConstants.WithdrawnState;
+ }
+
+ if (getter.getActualType() != XWM.XA_WM_STATE.getAtom() && getter.getActualFormat() != 32) {
+ return savedState = XUtilConstants.WithdrawnState;
+ }
+ savedState = (int)Native.getCard32(getter.getData());
+ } finally {
+ getter.dispose();
+ }
+ }
+ return savedState;
+ }
+
+ /**
+ * Override this methods to get notifications when top-level window state changes. The state is
+ * meant in terms of ICCCM: WithdrawnState, IconicState, NormalState
+ */
+ protected void stateChanged(long time, int oldState, int newState) {
+ }
+
+ @Override
+ public void handlePropertyNotify(XEvent xev) {
+ super.handlePropertyNotify(xev);
+ XPropertyEvent ev = xev.get_xproperty();
+ if (ev.get_atom() == XWM.XA_WM_STATE.getAtom()) {
+ // State has changed, invalidate saved value
+ stateChanged = true;
+ stateChanged(ev.get_time(), savedState, getWMState());
+ }
+ }
+
public void reshape(Rectangle bounds) {
reshape(bounds.x, bounds.y, bounds.width, bounds.height);
}
@@ -1277,20 +1423,77 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
}
}
- public void postKeyEvent(int id, long when, int keyCode, char keyChar,
- int keyLocation, int state, long event, int eventSize)
+ public void postKeyEvent(int id, long when, int keyCode, int keyChar,
+ int keyLocation, int state, long event, int eventSize, long rawCode,
+ int unicodeFromPrimaryKeysym, int extendedKeyCode)
+
{
long jWhen = XToolkit.nowMillisUTC_offset(when);
int modifiers = getModifiers(state, 0, keyCode);
+ if (rawCodeField == null) {
+ rawCodeField = XToolkit.getField(KeyEvent.class, "rawCode");
+ }
+ if (primaryLevelUnicodeField == null) {
+ primaryLevelUnicodeField = XToolkit.getField(KeyEvent.class, "primaryLevelUnicode");
+ }
+ if (extendedKeyCodeField == null) {
+ extendedKeyCodeField = XToolkit.getField(KeyEvent.class, "extendedKeyCode");
+ }
+
KeyEvent ke = new KeyEvent((Component)getEventSource(), id, jWhen,
- modifiers, keyCode, keyChar, keyLocation);
+ modifiers, keyCode, (char)keyChar, keyLocation);
if (event != 0) {
byte[] data = Native.toBytes(event, eventSize);
setBData(ke, data);
}
+ try {
+ rawCodeField.set(ke, rawCode);
+ primaryLevelUnicodeField.set(ke, (long)unicodeFromPrimaryKeysym);
+ extendedKeyCodeField.set(ke, (long)extendedKeyCode);
+ } catch (IllegalArgumentException e) {
+ assert(false);
+ } catch (IllegalAccessException e) {
+ assert(false);
+ }
postEventToEventQueue(ke);
}
static native int getAWTKeyCodeForKeySym(int keysym);
static native int getKeySymForAWTKeyCode(int keycode);
+
+ /* These two methods are actually applicable to toplevel windows only.
+ * However, the functionality is required by both the XWindowPeer and
+ * XWarningWindow, both of which have the XWindow as a common ancestor.
+ * See XWM.setMotifDecor() for details.
+ */
+ public PropMwmHints getMWMHints() {
+ if (mwm_hints == null) {
+ mwm_hints = new PropMwmHints();
+ if (!XWM.XA_MWM_HINTS.getAtomData(getWindow(), mwm_hints.pData, MWMConstants.PROP_MWM_HINTS_ELEMENTS)) {
+ mwm_hints.zero();
+ }
+ }
+ return mwm_hints;
+ }
+
+ public void setMWMHints(PropMwmHints hints) {
+ mwm_hints = hints;
+ if (hints != null) {
+ XWM.XA_MWM_HINTS.setAtomData(getWindow(), mwm_hints.pData, MWMConstants.PROP_MWM_HINTS_ELEMENTS);
+ }
+ }
+
+ protected final void initWMProtocols() {
+ wm_protocols.setAtomListProperty(this, getWMProtocols());
+ }
+
+ /**
+ * Returns list of protocols which should be installed on this window.
+ * Descendants can override this method to add class-specific protocols
+ */
+ protected XAtomList getWMProtocols() {
+ // No protocols on simple window
+ return new XAtomList();
+ }
+
}
diff --git a/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/src/solaris/classes/sun/awt/X11/XWindowPeer.java
index 5666cab8c..41807dbf0 100644
--- a/src/solaris/classes/sun/awt/X11/XWindowPeer.java
+++ b/src/solaris/classes/sun/awt/X11/XWindowPeer.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,8 @@ import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.WindowEvent;
+import java.awt.image.BufferedImage;
+
import java.awt.peer.ComponentPeer;
import java.awt.peer.WindowPeer;
@@ -42,13 +44,17 @@ import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
+import sun.awt.AWTAccessor;
import sun.awt.ComponentAccessor;
import sun.awt.WindowAccessor;
+import sun.awt.AWTAccessor;
import sun.awt.DisplayChangedListener;
import sun.awt.SunToolkit;
import sun.awt.X11GraphicsDevice;
import sun.awt.X11GraphicsEnvironment;
+import sun.java2d.pipe.Region;
+
class XWindowPeer extends XPanelPeer implements WindowPeer,
DisplayChangedListener {
@@ -61,16 +67,11 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
// should be synchronized on awtLock
private static Set<XWindowPeer> windows = new HashSet<XWindowPeer>();
- static XAtom wm_protocols;
- static XAtom wm_delete_window;
- static XAtom wm_take_focus;
- XWindowAttributesData winAttr;
private boolean cachedFocusableWindow;
XWarningWindow warningWindow;
private boolean alwaysOnTop;
- PropMwmHints mwm_hints;
private boolean locationByPlatform;
Dialog modalBlocker;
@@ -87,8 +88,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
private boolean grab = false; // Whether to do a grab during showing
private boolean isMapped = false; // Is this window mapped or not
- private boolean stateChanged; // Indicates whether the value on savedState is valid
- private int savedState; // Holds last known state of the top-level window
private boolean mustControlStackPosition = false; // Am override-redirect not on top
private XEventDispatcher rootPropertyEventDispatcher = null;
@@ -135,25 +134,18 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
super.preInit(params);
params.putIfNull(BIT_GRAVITY, Integer.valueOf(XConstants.NorthWestGravity));
- savedState = XUtilConstants.WithdrawnState;
+ long eventMask = 0;
+ if (params.containsKey(EVENT_MASK)) {
+ eventMask = ((Long)params.get(EVENT_MASK));
+ }
+ eventMask |= XConstants.VisibilityChangeMask;
+ params.put(EVENT_MASK, eventMask);
+
XA_NET_WM_STATE = XAtom.get("_NET_WM_STATE");
- winAttr = new XWindowAttributesData();
params.put(OVERRIDE_REDIRECT, Boolean.valueOf(isOverrideRedirect()));
- SunToolkit.awtLock();
- try {
- windows.add(this);
- if (wm_protocols == null) {
- wm_protocols = XAtom.get("WM_PROTOCOLS");
- wm_delete_window = XAtom.get("WM_DELETE_WINDOW");
- wm_take_focus = XAtom.get("WM_TAKE_FOCUS");
- }
- }
- finally {
- SunToolkit.awtUnlock();
- }
cachedFocusableWindow = isFocusableWindow();
Font f = target.getFont();
@@ -186,20 +178,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
params.put(BOUNDS, constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height));
}
- private void initWMProtocols() {
- wm_protocols.setAtomListProperty(this, getWMProtocols());
- }
-
- /**
- * Returns list of protocols which should be installed on this window.
- * Descendants can override this method to add class-specific protocols
- */
- protected XAtomList getWMProtocols() {
- // No protocols on simple window
- return new XAtomList();
- }
-
-
protected String getWMName() {
String name = target.getName();
if (name == null || name.trim().equals("")) {
@@ -253,13 +231,17 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
// accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip
// and TrayIcon balloon windows without a warning window.
if (!WindowAccessor.isTrayIconWindow((Window)target)) {
- warningWindow = new XWarningWindow((Window)target, getWindow());
+ warningWindow = new XWarningWindow((Window)target, getWindow(), this);
}
}
setSaveUnder(true);
updateIconImages();
+
+ updateShape();
+ updateOpacity();
+ // no need in updateOpaque() as it is no-op
}
public void updateIconImages() {
@@ -417,6 +399,22 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
return defaultIconInfo;
}
+ private void updateShape() {
+ // Shape shape = ((Window)target).getShape();
+ Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+ if (shape != null) {
+ applyShape(Region.getInstance(shape, null));
+ }
+ }
+
+ private void updateOpacity() {
+ // float opacity = ((Window)target).getOpacity();
+ float opacity = AWTAccessor.getWindowAccessor().getOpacity((Window)target);
+ if (opacity < 1.0f) {
+ setOpacity(opacity);
+ }
+ }
+
public void updateMinimumSize() {
//This function only saves minimumSize value in XWindowPeer
//Setting WMSizeHints is implemented in XDecoratedPeer
@@ -513,10 +511,15 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
}
- if (!bounds.getSize().equals(oldBounds.getSize())) {
+ boolean isResized = !bounds.getSize().equals(oldBounds.getSize());
+ boolean isMoved = !bounds.getLocation().equals(oldBounds.getLocation());
+ if (isMoved || isResized) {
+ repositionSecurityWarning();
+ }
+ if (isResized) {
postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_RESIZED));
}
- if (!bounds.getLocation().equals(oldBounds.getLocation())) {
+ if (isMoved) {
postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_MOVED));
}
} finally {
@@ -539,7 +542,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
}
public Insets getInsets() {
- return new Insets(getWarningWindowHeight(), 0, 0, 0);
+ return new Insets(0, 0, 0, 0);
}
// NOTE: This method may be called by privileged threads.
@@ -686,6 +689,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
int curScreenNum = ((X11GraphicsDevice)getGraphicsConfiguration().getDevice()).getScreen();
int newScreenNum = 0;
GraphicsDevice gds[] = XToolkit.localEnv.getScreenDevices();
+ GraphicsConfiguration newGC = null;
Rectangle screenBounds;
for (int i = 0; i < gds.length; i++) {
@@ -701,11 +705,13 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
if (intAmt == area) {
// Completely on this screen - done!
newScreenNum = i;
+ newGC = gds[i].getDefaultConfiguration();
break;
}
if (intAmt > largestAmt) {
largestAmt = intAmt;
newScreenNum = i;
+ newGC = gds[i].getDefaultConfiguration();
}
}
}
@@ -713,28 +719,20 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
if (log.isLoggable(Level.FINEST)) {
log.finest("XWindowPeer: Moved to a new screen");
}
- draggedToNewScreen(newScreenNum);
+ executeDisplayChangedOnEDT(newGC);
}
}
- /* Xinerama
- * called to update our GC when dragged onto another screen
- */
- public void draggedToNewScreen(int screenNum) {
- executeDisplayChangedOnEDT(screenNum);
- }
-
/**
* Helper method that executes the displayChanged(screen) method on
* the event dispatch thread. This method is used in the Xinerama case
* and after display mode change events.
*/
- private void executeDisplayChangedOnEDT(final int screenNum) {
+ private void executeDisplayChangedOnEDT(final GraphicsConfiguration gc) {
Runnable dc = new Runnable() {
public void run() {
- // Updates this window's GC and notifies all the children.
- // See XPanelPeer/XCanvasPeer.displayChanged(int) for details.
- displayChanged(screenNum);
+ AWTAccessor.getComponentAccessor().
+ setGraphicsConfiguration((Component)target, gc);
}
};
SunToolkit.executeOnEventHandlerThread((Component)target, dc);
@@ -745,9 +743,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
* X11GraphicsDevice when the display mode has been changed.
*/
public void displayChanged() {
- GraphicsConfiguration gc = getGraphicsConfiguration();
- int curScreenNum = ((X11GraphicsDevice)gc.getDevice()).getScreen();
- executeDisplayChangedOnEDT(curScreenNum);
+ executeDisplayChangedOnEDT(getGraphicsConfiguration());
}
/**
@@ -761,6 +757,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
* Overridden to check if we need to update our GraphicsDevice/Config
* Added for 4934052.
*/
+ @Override
public void handleConfigureNotifyEvent(XEvent xev) {
// TODO: We create an XConfigureEvent every time we override
// handleConfigureNotify() - too many!
@@ -774,8 +771,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
// there could be a race condition in which a ComponentListener could
// see the old screen.
super.handleConfigureNotifyEvent(xev);
- // for 5085647: no applet warning window visible
- updateChildrenSizes();
+ repositionSecurityWarning();
}
final void requestXFocus(long time) {
@@ -1053,6 +1049,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
}
updateFocusability();
promoteDefaultPosition();
+ if (!vis && warningWindow != null) {
+ warningWindow.setSecurityWarningVisible(false, false);
+ }
super.setVisible(vis);
if (!vis && !isWithdrawn()) {
// ICCCM, 4.1.4. Changing Window State:
@@ -1082,6 +1081,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
if (isOverrideRedirect() && vis) {
updateChildrenSizes();
}
+ repositionSecurityWarning();
}
protected void suppressWmTakeFocus(boolean doSuppress) {
@@ -1099,21 +1099,64 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
return 0;
}
- // The height of area used to display Applet's warning about securit
- int getWarningWindowHeight() {
- if (warningWindow != null) {
- return warningWindow.getHeight();
- } else {
- return 0;
- }
- }
-
// Called when shell changes its size and requires children windows
// to update their sizes appropriately
void updateChildrenSizes() {
+ }
+
+ public void repositionSecurityWarning() {
+ // NOTE: On KWin if the window/border snapping option is enabled,
+ // the Java window may be swinging while it's being moved.
+ // This doesn't make the application unusable though looks quite ugly.
+ // Probobly we need to find some hint to assign to our Security
+ // Warning window in order to exclude it from the snapping option.
+ // We are not currently aware of existance of such a property.
if (warningWindow != null) {
- warningWindow.reshape(0, getMenuBarHeight(), getSize().width, warningWindow.getHeight());
+ // We can't use the coordinates stored in the XBaseWindow since
+ // they are zeros for decorated frames.
+ int x = ComponentAccessor.getX(target);
+ int y = ComponentAccessor.getY(target);
+ int width = ComponentAccessor.getWidth(target);
+ int height = ComponentAccessor.getHeight(target);
+ warningWindow.reposition(x, y, width, height);
+ }
+ }
+
+ @Override
+ protected void setMouseAbove(boolean above) {
+ super.setMouseAbove(above);
+ updateSecurityWarningVisibility();
+ }
+
+ public void updateSecurityWarningVisibility() {
+ if (warningWindow == null) {
+ return;
+ }
+
+ boolean show = false;
+
+ int state = getWMState();
+
+ if (!isVisible()) {
+ return; // The warning window should already be hidden.
+ }
+
+ // getWMState() always returns 0 (Withdrawn) for simple windows. Hence
+ // we ignore the state for such windows.
+ if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
+ if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() ==
+ getTarget())
+ {
+ show = true;
+ }
+
+ if (isMouseAbove() || warningWindow.isMouseAbove())
+ {
+ show = true;
+ }
}
+
+ warningWindow.setSecurityWarningVisible(show);
}
boolean isOverrideRedirect() {
@@ -1165,16 +1208,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
// if (ve.get_state() == XlibWrapper.VisibilityUnobscured) {
// // raiseInputMethodWindow
// }
- }
-
- public void handlePropertyNotify(XEvent xev) {
- super.handlePropertyNotify(xev);
- XPropertyEvent ev = xev.get_xproperty();
- if (ev.get_atom() == XWM.XA_WM_STATE.getAtom()) {
- // State has changed, invalidate saved value
- stateChanged = true;
- stateChanged(ev.get_time(), savedState, getWMState());
- }
+ repositionSecurityWarning();
}
void handleRootPropertyNotify(XEvent xev) {
@@ -1275,6 +1309,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
* Override this methods to get notifications when top-level window state changes. The state is
* meant in terms of ICCCM: WithdrawnState, IconicState, NormalState
*/
+ @Override
protected void stateChanged(long time, int oldState, int newState) {
// Fix for 6401700, 6412803
// If this window is modal blocked, it is put into the transient_for
@@ -1288,38 +1323,8 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
for (ToplevelStateListener topLevelListenerTmp : toplevelStateListeners) {
topLevelListenerTmp.stateChangedICCCM(oldState, newState);
}
- }
-
-
- /*
- * XmNiconic and Map/UnmapNotify (that XmNiconic relies on) are
- * unreliable, since mapping changes can happen for a virtual desktop
- * switch or MacOS style shading that became quite popular under X as
- * well. Yes, it probably should not be this way, as it violates
- * ICCCM, but reality is that quite a lot of window managers abuse
- * mapping state.
- */
- int getWMState() {
- if (stateChanged) {
- stateChanged = false;
- WindowPropertyGetter getter =
- new WindowPropertyGetter(window, XWM.XA_WM_STATE, 0, 1, false,
- XWM.XA_WM_STATE);
- try {
- int status = getter.execute();
- if (status != XConstants.Success || getter.getData() == 0) {
- return savedState = XUtilConstants.WithdrawnState;
- }
- if (getter.getActualType() != XWM.XA_WM_STATE.getAtom() && getter.getActualFormat() != 32) {
- return savedState = XUtilConstants.WithdrawnState;
- }
- savedState = (int)Native.getCard32(getter.getData());
- } finally {
- getter.dispose();
- }
- }
- return savedState;
+ updateSecurityWarningVisibility();
}
boolean isWithdrawn() {
@@ -2064,4 +2069,44 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
}
super.handleButtonPressRelease(xev);
}
+
+ public void print(Graphics g) {
+ // We assume we print the whole frame,
+ // so we expect no clip was set previously
+ Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+ if (shape != null) {
+ g.setClip(shape);
+ }
+ super.print(g);
+ }
+
+ @Override
+ public void setOpacity(float opacity) {
+ final long maxOpacity = 0xffffffffl;
+ long iOpacity = (long)(opacity * maxOpacity);
+ if (iOpacity < 0) {
+ iOpacity = 0;
+ }
+ if (iOpacity > maxOpacity) {
+ iOpacity = maxOpacity;
+ }
+
+ XAtom netWmWindowOpacityAtom = XAtom.get("_NET_WM_WINDOW_OPACITY");
+
+ if (iOpacity == maxOpacity) {
+ netWmWindowOpacityAtom.DeleteProperty(getWindow());
+ } else {
+ netWmWindowOpacityAtom.setCard32Property(getWindow(), iOpacity);
+ }
+ }
+
+ @Override
+ public void setOpaque(boolean isOpaque) {
+ // no-op
+ }
+
+ @Override
+ public void updateWindow(BufferedImage backBuffer) {
+ // no-op
+ }
}
diff --git a/src/solaris/classes/sun/awt/X11/XlibWrapper.java b/src/solaris/classes/sun/awt/X11/XlibWrapper.java
index eb6d5e775..0de0dc861 100644
--- a/src/solaris/classes/sun/awt/X11/XlibWrapper.java
+++ b/src/solaris/classes/sun/awt/X11/XlibWrapper.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -156,6 +156,8 @@ Window w;
static native void XLowerWindow(long display, long window);
static native void XRestackWindows(long display, long windows, int length);
+ static native void XConfigureWindow(long display, long window,
+ long value_mask, long values);
static native void XSetInputFocus(long display, long window);
static native void XSetInputFocus2(long display, long window, long time);
static native long XGetInputFocus(long display);
@@ -490,6 +492,21 @@ static native String XSetLocaleModifiers(String modifier_list);
static native int XKeysymToKeycode(long display, long keysym);
+ // xkb-related
+ static native int XkbGetEffectiveGroup(long display);
+ static native long XkbKeycodeToKeysym(long display, int keycode, int group, int level);
+ static native void XkbSelectEvents(long display, long device, long bits_to_change, long values_for_bits);
+ static native void XkbSelectEventDetails(long display, long device, long event_type,
+ long bits_to_change, long values_for_bits);
+ static native boolean XkbQueryExtension(long display, long opcode_rtrn, long event_rtrn,
+ long error_rtrn, long major_in_out, long minor_in_out);
+ static native boolean XkbLibraryVersion(long lib_major_in_out, long lib_minor_in_out);
+ static native long XkbGetMap(long display, long which, long device_spec);
+ static native long XkbGetUpdatedMap(long display, long which, long xkb);
+ static native void XkbFreeKeyboard(long xkb, long which, boolean free_all);
+ static native boolean XkbTranslateKeyCode(long xkb, int keycode, long mods, long mods_rtrn, long keysym_rtrn);
+
+
static native void XConvertCase(long keysym,
long keysym_lowercase,
long keysym_uppercase);
@@ -533,6 +550,13 @@ static native String XSetLocaleModifiers(String modifier_list);
static native void SetRectangularShape(long display, long window,
int lox, int loy, int hix, int hiy,
sun.java2d.pipe.Region region);
+ /** Each int in the bitmap array is one pixel with a 32-bit color:
+ * R, G, B, and Alpha.
+ */
+ static native void SetBitmapShape(long display, long window,
+ int width, int height, int[] bitmap);
+
+ static native void SetZOrder(long display, long window, long above);
/* Global memory area used for X lib parameter passing */
@@ -608,6 +632,15 @@ static native String XSetLocaleModifiers(String modifier_list);
}
return buf.toString();
}
+ static String getEventToString( int type ) {
+ if( (type >= 0) && (type < eventToString.length)) {
+ return eventToString[type];
+ }else if( type == XToolkit.getXKBBaseEventCode() ) {
+ //XXX TODO various xkb types
+ return "XkbEvent";
+ }
+ return eventToString[0];
+ }
private static boolean getBuildInternal() {
String javaVersion = XToolkit.getSystemProperty("java.version");
diff --git a/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java b/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java
index 84cfa254e..3ad8662bf 100644
--- a/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java
+++ b/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -859,14 +859,14 @@ public class WrapperGenerator {
pw.println("\n\tlong pData;");
pw.println("\n\tpublic long getPData() { return pData; }");
- pw.println("\n\n\t" + stp.getJavaClassName() + "(long addr) {");
+ pw.println("\n\n\tpublic " + stp.getJavaClassName() + "(long addr) {");
if (generateLog) {
pw.println("\t\tlog.finest(\"Creating\");");
}
pw.println("\t\tpData=addr;");
pw.println("\t\tshould_free_memory = false;");
pw.println("\t}");
- pw.println("\n\n\t" + stp.getJavaClassName() + "() {");
+ pw.println("\n\n\tpublic " + stp.getJavaClassName() + "() {");
if (generateLog) {
pw.println("\t\tlog.finest(\"Creating\");");
}
@@ -1138,6 +1138,7 @@ public class WrapperGenerator {
pw.println("/* This file is an automatically generated file, please do not edit this file, modify the XlibParser.java file instead !*/\n" );
pw.println("#include <X11/Xlib.h>\n#include <X11/Xutil.h>\n#include <X11/Xos.h>\n#include <X11/Xatom.h>\n#include <stdio.h>\n");
pw.println("#include <X11/extensions/Xdbe.h>");
+ pw.println("#include <X11/XKBlib.h>");
pw.println("#include \"awt_p.h\"");
pw.println("#include \"color.h\"");
pw.println("#include \"colordata.h\"");
diff --git a/src/solaris/classes/sun/awt/X11/generator/sizes.64-solaris-i386 b/src/solaris/classes/sun/awt/X11/generator/sizes.64-solaris-i386
index 38ec9071b..bdeeee25e 100644
--- a/src/solaris/classes/sun/awt/X11/generator/sizes.64-solaris-i386
+++ b/src/solaris/classes/sun/awt/X11/generator/sizes.64-solaris-i386
@@ -16,10 +16,38 @@ XIMStringConversionCallbackStruct.operation 8
XIMStringConversionCallbackStruct.factor 10
XIMStringConversionCallbackStruct.text 16
XIMStringConversionCallbackStruct 24
+XkbNewKeyboardNotifyEvent.type 0
+XkbNewKeyboardNotifyEvent.serial 8
+XkbNewKeyboardNotifyEvent.send_event 16
+XkbNewKeyboardNotifyEvent.display 24
+XkbNewKeyboardNotifyEvent.time 32
+XkbNewKeyboardNotifyEvent.xkb_type 40
+XkbNewKeyboardNotifyEvent.device 44
+XkbNewKeyboardNotifyEvent.old_device 48
+XkbNewKeyboardNotifyEvent.min_key_code 52
+XkbNewKeyboardNotifyEvent.max_key_code 56
+XkbNewKeyboardNotifyEvent.old_min_key_code 60
+XkbNewKeyboardNotifyEvent.old_max_key_code 64
+XkbNewKeyboardNotifyEvent.changed 68
+XkbNewKeyboardNotifyEvent.req_major 72
+XkbNewKeyboardNotifyEvent.req_minor 73
+XkbNewKeyboardNotifyEvent 80
XTimeCoord.time 0
XTimeCoord.x 8
XTimeCoord.y 10
XTimeCoord 16
+XkbCompatMapNotifyEvent.type 0
+XkbCompatMapNotifyEvent.serial 8
+XkbCompatMapNotifyEvent.send_event 16
+XkbCompatMapNotifyEvent.display 24
+XkbCompatMapNotifyEvent.time 32
+XkbCompatMapNotifyEvent.xkb_type 40
+XkbCompatMapNotifyEvent.device 44
+XkbCompatMapNotifyEvent.changed_groups 48
+XkbCompatMapNotifyEvent.first_si 52
+XkbCompatMapNotifyEvent.num_si 56
+XkbCompatMapNotifyEvent.num_total_si 60
+XkbCompatMapNotifyEvent 64
XIMStatusDrawCallbackStruct.type 0
XIMStatusDrawCallbackStruct.data 8
XIMStatusDrawCallbackStruct 16
@@ -289,6 +317,22 @@ XVisualInfo.blue_mask 48
XVisualInfo.colormap_size 56
XVisualInfo.bits_per_rgb 60
XVisualInfo 64
+XkbControlsNotifyEvent.type 0
+XkbControlsNotifyEvent.serial 8
+XkbControlsNotifyEvent.send_event 16
+XkbControlsNotifyEvent.display 24
+XkbControlsNotifyEvent.time 32
+XkbControlsNotifyEvent.xkb_type 40
+XkbControlsNotifyEvent.device 44
+XkbControlsNotifyEvent.changed_ctrls 48
+XkbControlsNotifyEvent.enabled_ctrls 52
+XkbControlsNotifyEvent.enabled_ctrl_changes 56
+XkbControlsNotifyEvent.num_groups 60
+XkbControlsNotifyEvent.keycode 64
+XkbControlsNotifyEvent.event_type 65
+XkbControlsNotifyEvent.req_major 66
+XkbControlsNotifyEvent.req_minor 67
+XkbControlsNotifyEvent 72
PropMwmHints.flags 0
PropMwmHints.functions 8
PropMwmHints.decorations 16
@@ -310,8 +354,26 @@ XAnyEvent.send_event 16
XAnyEvent.display 24
XAnyEvent.window 32
XAnyEvent 40
+XkbIndicatorNotifyEvent.type 0
+XkbIndicatorNotifyEvent.serial 8
+XkbIndicatorNotifyEvent.send_event 16
+XkbIndicatorNotifyEvent.display 24
+XkbIndicatorNotifyEvent.time 32
+XkbIndicatorNotifyEvent.xkb_type 40
+XkbIndicatorNotifyEvent.device 44
+XkbIndicatorNotifyEvent.changed 48
+XkbIndicatorNotifyEvent.state 52
+XkbIndicatorNotifyEvent 56
XIMPreeditStateNotifyCallbackStruct.state 0
XIMPreeditStateNotifyCallbackStruct 8
+XkbAnyEvent.type 0
+XkbAnyEvent.serial 8
+XkbAnyEvent.send_event 16
+XkbAnyEvent.display 24
+XkbAnyEvent.time 32
+XkbAnyEvent.xkb_type 40
+XkbAnyEvent.device 44
+XkbAnyEvent 48
XMotionEvent.type 0
XMotionEvent.serial 8
XMotionEvent.send_event 16
@@ -334,6 +396,23 @@ XIMHotKeyTriggers 16
XIMStyles.count_styles 0
XIMStyles.supported_styles 8
XIMStyles 16
+XkbExtensionDeviceNotifyEvent.type 0
+XkbExtensionDeviceNotifyEvent.serial 8
+XkbExtensionDeviceNotifyEvent.send_event 16
+XkbExtensionDeviceNotifyEvent.display 24
+XkbExtensionDeviceNotifyEvent.time 32
+XkbExtensionDeviceNotifyEvent.xkb_type 40
+XkbExtensionDeviceNotifyEvent.device 44
+XkbExtensionDeviceNotifyEvent.reason 48
+XkbExtensionDeviceNotifyEvent.supported 52
+XkbExtensionDeviceNotifyEvent.unsupported 56
+XkbExtensionDeviceNotifyEvent.first_btn 60
+XkbExtensionDeviceNotifyEvent.num_btns 64
+XkbExtensionDeviceNotifyEvent.leds_defined 68
+XkbExtensionDeviceNotifyEvent.led_state 72
+XkbExtensionDeviceNotifyEvent.led_class 76
+XkbExtensionDeviceNotifyEvent.led_id 80
+XkbExtensionDeviceNotifyEvent 88
XwcTextItem.chars 0
XwcTextItem.nchars 8
XwcTextItem.delta 12
@@ -419,6 +498,20 @@ XKeyEvent.state 80
XKeyEvent.keycode 84
XKeyEvent.same_screen 88
XKeyEvent 96
+XkbActionMessageEvent.type 0
+XkbActionMessageEvent.serial 8
+XkbActionMessageEvent.send_event 16
+XkbActionMessageEvent.display 24
+XkbActionMessageEvent.time 32
+XkbActionMessageEvent.xkb_type 40
+XkbActionMessageEvent.device 44
+XkbActionMessageEvent.keycode 48
+XkbActionMessageEvent.press 52
+XkbActionMessageEvent.key_event_follows 56
+XkbActionMessageEvent.group 60
+XkbActionMessageEvent.mods 64
+XkbActionMessageEvent.message 68
+XkbActionMessageEvent 80
XdbeSwapInfo.swap_window 0
XdbeSwapInfo.swap_action 8
XdbeSwapInfo 16
@@ -458,6 +551,18 @@ Visual 56
XOMOrientation.num_orientation 0
XOMOrientation.orientation 8
XOMOrientation 16
+XkbAccessXNotifyEvent.type 0
+XkbAccessXNotifyEvent.serial 8
+XkbAccessXNotifyEvent.send_event 16
+XkbAccessXNotifyEvent.display 24
+XkbAccessXNotifyEvent.time 32
+XkbAccessXNotifyEvent.xkb_type 40
+XkbAccessXNotifyEvent.device 44
+XkbAccessXNotifyEvent.detail 48
+XkbAccessXNotifyEvent.keycode 52
+XkbAccessXNotifyEvent.sk_delay 56
+XkbAccessXNotifyEvent.debounce_delay 60
+XkbAccessXNotifyEvent 64
XWindowAttributes.x 0
XWindowAttributes.y 4
XWindowAttributes.width 8
@@ -528,6 +633,33 @@ awtImageData.wsImageFormat 4
awtImageData.clrdata 16
awtImageData.convert 48
awtImageData 560
+XkbStateNotifyEvent.type 0
+XkbStateNotifyEvent.serial 8
+XkbStateNotifyEvent.send_event 16
+XkbStateNotifyEvent.display 24
+XkbStateNotifyEvent.time 32
+XkbStateNotifyEvent.xkb_type 40
+XkbStateNotifyEvent.device 44
+XkbStateNotifyEvent.changed 48
+XkbStateNotifyEvent.group 52
+XkbStateNotifyEvent.base_group 56
+XkbStateNotifyEvent.latched_group 60
+XkbStateNotifyEvent.locked_group 64
+XkbStateNotifyEvent.mods 68
+XkbStateNotifyEvent.base_mods 72
+XkbStateNotifyEvent.latched_mods 76
+XkbStateNotifyEvent.locked_mods 80
+XkbStateNotifyEvent.compat_state 84
+XkbStateNotifyEvent.grab_mods 88
+XkbStateNotifyEvent.compat_grab_mods 89
+XkbStateNotifyEvent.lookup_mods 90
+XkbStateNotifyEvent.compat_lookup_mods 91
+XkbStateNotifyEvent.ptr_buttons 92
+XkbStateNotifyEvent.keycode 96
+XkbStateNotifyEvent.event_type 97
+XkbStateNotifyEvent.req_major 98
+XkbStateNotifyEvent.req_minor 99
+XkbStateNotifyEvent 104
XExposeEvent.type 0
XExposeEvent.serial 8
XExposeEvent.send_event 16
@@ -539,6 +671,33 @@ XExposeEvent.width 48
XExposeEvent.height 52
XExposeEvent.count 56
XExposeEvent 64
+XkbMapNotifyEvent.type 0
+XkbMapNotifyEvent.serial 8
+XkbMapNotifyEvent.send_event 16
+XkbMapNotifyEvent.display 24
+XkbMapNotifyEvent.time 32
+XkbMapNotifyEvent.xkb_type 40
+XkbMapNotifyEvent.device 44
+XkbMapNotifyEvent.changed 48
+XkbMapNotifyEvent.flags 52
+XkbMapNotifyEvent.first_type 56
+XkbMapNotifyEvent.num_types 60
+XkbMapNotifyEvent.min_key_code 64
+XkbMapNotifyEvent.max_key_code 65
+XkbMapNotifyEvent.first_key_sym 66
+XkbMapNotifyEvent.first_key_act 67
+XkbMapNotifyEvent.first_key_behavior 68
+XkbMapNotifyEvent.first_key_explicit 69
+XkbMapNotifyEvent.first_modmap_key 70
+XkbMapNotifyEvent.first_vmodmap_key 71
+XkbMapNotifyEvent.num_key_syms 72
+XkbMapNotifyEvent.num_key_acts 76
+XkbMapNotifyEvent.num_key_behaviors 80
+XkbMapNotifyEvent.num_key_explicit 84
+XkbMapNotifyEvent.num_modmap_keys 88
+XkbMapNotifyEvent.num_vmodmap_keys 92
+XkbMapNotifyEvent.vmods 96
+XkbMapNotifyEvent 104
XGCValues.function 0
XGCValues.plane_mask 8
XGCValues.foreground 16
@@ -583,6 +742,22 @@ XMapEvent.event 32
XMapEvent.window 40
XMapEvent.override_redirect 48
XMapEvent 56
+XkbBellNotifyEvent.type 0
+XkbBellNotifyEvent.serial 8
+XkbBellNotifyEvent.send_event 16
+XkbBellNotifyEvent.display 24
+XkbBellNotifyEvent.time 32
+XkbBellNotifyEvent.xkb_type 40
+XkbBellNotifyEvent.device 44
+XkbBellNotifyEvent.percent 48
+XkbBellNotifyEvent.pitch 52
+XkbBellNotifyEvent.duration 56
+XkbBellNotifyEvent.bell_class 60
+XkbBellNotifyEvent.bell_id 64
+XkbBellNotifyEvent.name 72
+XkbBellNotifyEvent.window 80
+XkbBellNotifyEvent.event_only 88
+XkbBellNotifyEvent 96
XIMStringConversionText.length 0
XIMStringConversionText.feedback 8
XIMStringConversionText.encoding_is_wchar 16
@@ -596,6 +771,21 @@ XKeyboardState.led_mask 16
XKeyboardState.global_auto_repeat 24
XKeyboardState.auto_repeats 28
XKeyboardState 64
+XkbEvent.type 0
+XkbEvent.any 0
+XkbEvent.new_kbd 0
+XkbEvent.map 0
+XkbEvent.state 0
+XkbEvent.ctrls 0
+XkbEvent.indicators 0
+XkbEvent.names 0
+XkbEvent.compat 0
+XkbEvent.bell 0
+XkbEvent.message 0
+XkbEvent.accessx 0
+XkbEvent.device 0
+XkbEvent.core 0
+XkbEvent 192
XPoint.x 0
XPoint.y 2
XPoint 4
@@ -633,6 +823,26 @@ XRectangle.y 2
XRectangle.width 4
XRectangle.height 6
XRectangle 8
+XkbNamesNotifyEvent.type 0
+XkbNamesNotifyEvent.serial 8
+XkbNamesNotifyEvent.send_event 16
+XkbNamesNotifyEvent.display 24
+XkbNamesNotifyEvent.time 32
+XkbNamesNotifyEvent.xkb_type 40
+XkbNamesNotifyEvent.device 44
+XkbNamesNotifyEvent.changed 48
+XkbNamesNotifyEvent.first_type 52
+XkbNamesNotifyEvent.num_types 56
+XkbNamesNotifyEvent.first_lvl 60
+XkbNamesNotifyEvent.num_lvls 64
+XkbNamesNotifyEvent.num_aliases 68
+XkbNamesNotifyEvent.num_radio_groups 72
+XkbNamesNotifyEvent.changed_vmods 76
+XkbNamesNotifyEvent.changed_groups 80
+XkbNamesNotifyEvent.changed_indicators 84
+XkbNamesNotifyEvent.first_key 88
+XkbNamesNotifyEvent.num_keys 92
+XkbNamesNotifyEvent 96
XCreateWindowEvent.type 0
XCreateWindowEvent.serial 8
XCreateWindowEvent.send_event 16
@@ -774,7 +984,8 @@ AwtGraphicsConfigData.monoPixmapGC 128
AwtGraphicsConfigData.pixelStride 136
AwtGraphicsConfigData.color_data 144
AwtGraphicsConfigData.glxInfo 152
-AwtGraphicsConfigData 160
+AwtGraphicsConfigData.isTranslucencySupported 160
+AwtGraphicsConfigData 168
XColor.pixel 0
XColor.red 8
XColor.green 10
diff --git a/src/solaris/classes/sun/awt/X11/generator/xlibtypes.txt b/src/solaris/classes/sun/awt/X11/generator/xlibtypes.txt
index 21bc3ce02..8f691353f 100644
--- a/src/solaris/classes/sun/awt/X11/generator/xlibtypes.txt
+++ b/src/solaris/classes/sun/awt/X11/generator/xlibtypes.txt
@@ -119,7 +119,7 @@ XIMStringConversionText
length short
feedback pointer
encoding_is_wchar Bool
- string pointer
+ string pointer
XKeymapEvent
type int
serial long
@@ -574,7 +574,7 @@ XImage
f.get_pixel pointer
f.put_pixel pointer
f.sub_image pointer
- f.add_pixel pointer
+ f.add_pixel pointer
XIMValuesList
count_values short
supported_values pointer
@@ -728,7 +728,7 @@ ColorData
awt_icmLUT pointer int
awt_icmLUT2Colors pointer byte
img_grays pointer byte
- img_clr_tbl pointer byte
+ img_clr_tbl pointer byte
img_oda_red pointer byte
img_oda_green pointer byte
img_oda_blue pointer byte
@@ -750,6 +750,7 @@ AwtGraphicsConfigData
pixelStride int
color_data pointer ColorData
glxInfo pointer
+ isTranslucencySupported int
AwtScreenData
numConfigs int
@@ -797,3 +798,227 @@ XEvent
xerror struct XErrorEvent
xkeymap struct XKeymapEvent
pad array long 24
+
+XkbAnyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+
+XkbNewKeyboardNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ old_device int
+ min_key_code int
+ max_key_code int
+ old_min_key_code int
+ old_max_key_code int
+ changed int
+ req_major byte
+ req_minor byte
+
+XkbMapNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed int
+ flags int
+ first_type int
+ num_types int
+ min_key_code int
+ max_key_code int
+ first_key_sym int
+ first_key_act int
+ first_key_behavior int
+ first_key_explicit int
+ first_modmap_key int
+ first_vmodmap_key int
+ num_key_syms int
+ num_key_acts int
+ num_key_behaviors int
+ num_key_explicit int
+ num_modmap_keys int
+ num_vmodmap_keys int
+ vmods int
+
+XkbStateNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed int
+ group int
+ base_group int
+ latched_group int
+ locked_group int
+ mods int
+ base_mods int
+ latched_mods int
+ locked_mods int
+ compat_state int
+ grab_mods byte
+ compat_grab_mods byte
+ lookup_mods byte
+ compat_lookup_mods byte
+ ptr_buttons int
+ keycode int
+ event_type byte
+ req_major byte
+ req_minor byte
+
+XkbControlsNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed_ctrls int
+ enabled_ctrls int
+ enabled_ctrl_changes int
+ num_groups int
+ keycode int
+ event_type byte
+ req_major byte
+ req_minor byte
+
+XkbIndicatorNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed int
+ state int
+
+XkbNamesNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed int
+ first_type int
+ num_types int
+ first_lvl int
+ num_lvls int
+ num_aliases int
+ num_radio_groups int
+ changed_vmods int
+ changed_groups int
+ changed_indicators int
+ first_key int
+ num_keys int
+
+
+XkbCompatMapNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed_groups int
+ first_si int
+ num_si int
+ num_total_si int
+
+XkbBellNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ percent int
+ pitch int
+ duration int
+ bell_class int
+ bell_id int
+ name Atom
+ window long
+ event_only Bool
+
+XkbActionMessageEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ keycode int
+ press Bool
+ key_event_follows Bool
+ group int
+ mods int
+ message array byte 7 //XkbActionMessageLength+1
+
+XkbAccessXNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ detail int
+ keycode int
+ sk_delay int
+ debounce_delay int
+
+XkbExtensionDeviceNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ reason int
+ supported int
+ unsupported int
+ first_btn int
+ num_btns int
+ leds_defined int
+ led_state int
+ led_class int
+ led_id int
+
+XkbEvent
+ type int
+ any struct XkbAnyEvent
+ new_kbd struct XkbNewKeyboardNotifyEvent
+ map struct XkbMapNotifyEvent
+ state struct XkbStateNotifyEvent
+ ctrls struct XkbControlsNotifyEvent
+ indicators struct XkbIndicatorNotifyEvent
+ names struct XkbNamesNotifyEvent
+ compat struct XkbCompatMapNotifyEvent
+ bell struct XkbBellNotifyEvent
+ message struct XkbActionMessageEvent
+ accessx struct XkbAccessXNotifyEvent
+ device struct XkbExtensionDeviceNotifyEvent
+ core struct XEvent
diff --git a/src/solaris/classes/sun/awt/X11/keysym2ucs.h b/src/solaris/classes/sun/awt/X11/keysym2ucs.h
index c59ffde04..c47ac18f9 100644
--- a/src/solaris/classes/sun/awt/X11/keysym2ucs.h
+++ b/src/solaris/classes/sun/awt/X11/keysym2ucs.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-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
@@ -39,7 +39,7 @@
*/
tojava /*
-tojava * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+tojava * Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
tojava * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
tojava *
tojava * This code is free software; you can redistribute it and/or modify it
@@ -127,14 +127,47 @@ tojava
tojava Character ch = keysym2UCSHash.get(ks);
tojava return ch == null ? (char)0 : ch.charValue();
tojava }
+tojava static long xkeycode2keysym_noxkb(XKeyEvent ev, int ndx) {
+tojava XToolkit.awtLock();
+tojava try {
+tojava return XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx);
+tojava } finally {
+tojava XToolkit.awtUnlock();
+tojava }
+tojava }
+tojava static long xkeycode2keysym_xkb(XKeyEvent ev, int ndx) {
+tojava XToolkit.awtLock();
+tojava try {
+tojava int mods = ev.get_state();
+tojava if ((ndx == 0) && ((mods & XConstants.ShiftMask) != 0)) {
+tojava // I don't know all possible meanings of 'ndx' in case of XKB
+tojava // and don't want to speculate. But this particular case
+tojava // clearly means that caller needs a so called primary keysym.
+tojava mods ^= XConstants.ShiftMask;
+tojava }
+tojava XlibWrapper.XkbTranslateKeyCode(XToolkit.getXKBKbdDesc(), ev.get_keycode(),
+tojava mods, XlibWrapper.iarg1, XlibWrapper.larg3);
+tojava //XXX unconsumed modifiers?
+tojava return Native.getLong(XlibWrapper.larg3);
+tojava } finally {
+tojava XToolkit.awtUnlock();
+tojava }
+tojava }
tojava static long xkeycode2keysym(XKeyEvent ev, int ndx) {
tojava XToolkit.awtLock();
tojava try {
-tojava return XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx );
+tojava if (XToolkit.canUseXKBCalls()) {
+tojava return xkeycode2keysym_xkb(ev, ndx);
+tojava }else{
+tojava return xkeycode2keysym_noxkb(ev, ndx);
+tojava }
tojava } finally {
tojava XToolkit.awtUnlock();
tojava }
tojava }
+tojava static long xkeycode2primary_keysym(XKeyEvent ev) {
+tojava return xkeycode2keysym(ev, 0);
+tojava }
tojava public static boolean isKPEvent( XKeyEvent ev )
tojava {
tojava // Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
@@ -236,6 +269,27 @@ tojava static int getJavaKeycodeOnly( XKeyEvent ev ) {
tojava Keysym2JavaKeycode jkc = getJavaKeycode( ev );
tojava return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode();
tojava }
+tojava /**
+tojava * Return an integer java keycode apprx as it was before extending keycodes range.
+tojava * This call would ignore for instance XKB and process whatever is on the bottom
+tojava * of keysym stack. Result will not depend on actual locale, will differ between
+tojava * dual/multiple keyboard setup systems (e.g. English+Russian vs French+Russian)
+tojava * but will be someway compatible with old releases.
+tojava */
+tojava static int getLegacyJavaKeycodeOnly( XKeyEvent ev ) {
+tojava long keysym = XConstants.NoSymbol;
+tojava int ndx = 0;
+tojava if( (ev.get_state() & XToolkit.numLockMask) != 0 &&
+tojava isKPEvent(ev)) {
+tojava keysym = getKeypadKeysym( ev );
+tojava } else {
+tojava // we only need primary-layer keysym to derive a java keycode.
+tojava ndx = 0;
+tojava keysym = xkeycode2keysym_noxkb(ev, ndx);
+tojava }
+tojava Keysym2JavaKeycode jkc = keysym2JavaKeycodeHash.get( keysym );
+tojava return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode();
+tojava }
tojava static long javaKeycode2Keysym( int jkey ) {
tojava Long ks = javaKeycode2KeysymHash.get( jkey );
tojava return (ks == null ? 0 : ks.longValue());
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-bw16.png b/src/solaris/classes/sun/awt/X11/security-icon-bw16.png
new file mode 100644
index 000000000..98dcd0f4e
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-bw16.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-bw24.png b/src/solaris/classes/sun/awt/X11/security-icon-bw24.png
new file mode 100644
index 000000000..5e5acae2e
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-bw24.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-bw32.png b/src/solaris/classes/sun/awt/X11/security-icon-bw32.png
new file mode 100644
index 000000000..9d92b96e2
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-bw32.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-bw48.png b/src/solaris/classes/sun/awt/X11/security-icon-bw48.png
new file mode 100644
index 000000000..961536422
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-bw48.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-interim16.png b/src/solaris/classes/sun/awt/X11/security-icon-interim16.png
new file mode 100644
index 000000000..f543f65d8
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-interim16.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-interim24.png b/src/solaris/classes/sun/awt/X11/security-icon-interim24.png
new file mode 100644
index 000000000..753a2adab
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-interim24.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-interim32.png b/src/solaris/classes/sun/awt/X11/security-icon-interim32.png
new file mode 100644
index 000000000..9ea41d490
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-interim32.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-interim48.png b/src/solaris/classes/sun/awt/X11/security-icon-interim48.png
new file mode 100644
index 000000000..b619966b8
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-interim48.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-yellow16.png b/src/solaris/classes/sun/awt/X11/security-icon-yellow16.png
new file mode 100644
index 000000000..8dd91a928
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-yellow16.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-yellow24.png b/src/solaris/classes/sun/awt/X11/security-icon-yellow24.png
new file mode 100644
index 000000000..0a3205ff6
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-yellow24.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-yellow32.png b/src/solaris/classes/sun/awt/X11/security-icon-yellow32.png
new file mode 100644
index 000000000..6e178672b
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-yellow32.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11/security-icon-yellow48.png b/src/solaris/classes/sun/awt/X11/security-icon-yellow48.png
new file mode 100644
index 000000000..fcbfd7ff5
--- /dev/null
+++ b/src/solaris/classes/sun/awt/X11/security-icon-yellow48.png
Binary files differ
diff --git a/src/solaris/classes/sun/awt/X11GraphicsConfig.java b/src/solaris/classes/sun/awt/X11GraphicsConfig.java
index 8ea5717ac..aa4b52720 100644
--- a/src/solaris/classes/sun/awt/X11GraphicsConfig.java
+++ b/src/solaris/classes/sun/awt/X11GraphicsConfig.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -450,4 +450,13 @@ public class X11GraphicsConfig extends GraphicsConfiguration
return 0x00; // UNDEFINED
}
}
+
+ /*
+ @Override
+ */
+ public boolean isTranslucencyCapable() {
+ return isTranslucencyCapable(getAData());
+ }
+
+ private native boolean isTranslucencyCapable(long x11ConfigData);
}
diff --git a/src/solaris/classes/sun/awt/motif/MToolkit.java b/src/solaris/classes/sun/awt/motif/MToolkit.java
index 717990da2..672e6e2bc 100644
--- a/src/solaris/classes/sun/awt/motif/MToolkit.java
+++ b/src/solaris/classes/sun/awt/motif/MToolkit.java
@@ -336,6 +336,10 @@ public class MToolkit extends UNIXToolkit implements Runnable {
return null;
}
+ public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+ return null;
+ }
+
//public MEmbeddedFramePeer createEmbeddedFrame(MEmbeddedFrame target)
//{
//MEmbeddedFramePeer peer = new MEmbeddedFramePeer(target);
diff --git a/src/solaris/native/sun/awt/awt_Component.h b/src/solaris/native/sun/awt/awt_Component.h
index 8ee7fe82f..d6ee776be 100644
--- a/src/solaris/native/sun/awt/awt_Component.h
+++ b/src/solaris/native/sun/awt/awt_Component.h
@@ -41,7 +41,6 @@ struct ComponentIDs {
jfieldID appContext;
jmethodID getParent;
jmethodID getLocationOnScreen;
- jmethodID resetGCMID;
};
/* field and method IDs for Container */
@@ -65,7 +64,3 @@ struct MComponentPeerIDs {
extern void processTree(Widget from, Widget to, Boolean action);
#endif // HEADLESS
-/* fieldIDs for Canvas fields that may be accessed from C */
-struct CanvasIDs {
- jmethodID setGCFromPeerMID;
-};
diff --git a/src/solaris/native/sun/awt/awt_GraphicsEnv.c b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
index 03f5c23d1..2e80cf720 100644
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c
+++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -354,6 +354,48 @@ makeDefaultConfig(JNIEnv *env, int screen) {
return NULL;
}
+/* Note: until we include the <X11/extensions/Xrender.h> explicitly
+ * we have to define a couple of things ourselves.
+ */
+typedef unsigned long PictFormat;
+#define PictTypeIndexed 0
+#define PictTypeDirect 1
+
+typedef struct {
+ short red;
+ short redMask;
+ short green;
+ short greenMask;
+ short blue;
+ short blueMask;
+ short alpha;
+ short alphaMask;
+} XRenderDirectFormat;
+
+typedef struct {
+ PictFormat id;
+ int type;
+ int depth;
+ XRenderDirectFormat direct;
+ Colormap colormap;
+} XRenderPictFormat;
+
+#define PictFormatID (1 << 0)
+#define PictFormatType (1 << 1)
+#define PictFormatDepth (1 << 2)
+#define PictFormatRed (1 << 3)
+#define PictFormatRedMask (1 << 4)
+#define PictFormatGreen (1 << 5)
+#define PictFormatGreenMask (1 << 6)
+#define PictFormatBlue (1 << 7)
+#define PictFormatBlueMask (1 << 8)
+#define PictFormatAlpha (1 << 9)
+#define PictFormatAlphaMask (1 << 10)
+#define PictFormatColormap (1 << 11)
+
+typedef XRenderPictFormat *
+XRenderFindVisualFormatFunc (Display *dpy, _Xconst Visual *visual);
+
static void
getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {
@@ -367,6 +409,9 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {
int ind;
char errmsg[128];
int xinawareScreen;
+ void* xrenderLibHandle = NULL;
+ XRenderFindVisualFormatFunc *XRenderFindVisualFormat = NULL;
+ int major_opcode, first_event, first_error;
if (usingXinerama) {
xinawareScreen = 0;
@@ -449,6 +494,26 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {
graphicsConfigs[0] = defaultConfig;
nConfig = 1; /* reserve index 0 for default config */
+ // Only use the RENDER extension if it is available on the X server
+ if (XQueryExtension(awt_display, "RENDER",
+ &major_opcode, &first_event, &first_error))
+ {
+ xrenderLibHandle = dlopen("libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL);
+
+#ifndef __linux__ /* SOLARIS */
+ if (xrenderLibHandle == NULL) {
+ xrenderLibHandle = dlopen("/usr/sfw/lib/libXrender.so.1",
+ RTLD_LAZY | RTLD_GLOBAL);
+ }
+#endif
+
+ if (xrenderLibHandle != NULL) {
+ XRenderFindVisualFormat =
+ (XRenderFindVisualFormatFunc*)dlsym(xrenderLibHandle,
+ "XRenderFindVisualFormat");
+ }
+ }
+
for (i = 0; i < nTrue; i++) {
if (XVisualIDFromVisual(pVITrue[i].visual) ==
XVisualIDFromVisual(defaultConfig->awt_visInfo.visual) ||
@@ -462,6 +527,21 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) {
graphicsConfigs [ind]->awt_depth = pVITrue [i].depth;
memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVITrue [i],
sizeof (XVisualInfo));
+ if (XRenderFindVisualFormat != NULL) {
+ XRenderPictFormat *format = XRenderFindVisualFormat (awt_display,
+ pVITrue [i].visual);
+ if (format &&
+ format->type == PictTypeDirect &&
+ format->direct.alphaMask)
+ {
+ graphicsConfigs [ind]->isTranslucencySupported = 1;
+ }
+ }
+ }
+
+ if (xrenderLibHandle != NULL) {
+ dlclose(xrenderLibHandle);
+ xrenderLibHandle = NULL;
}
for (i = 0; i < n8p; i++) {
@@ -1506,6 +1586,26 @@ Java_sun_awt_X11GraphicsConfig_swapBuffers
}
/*
+ * Class: sun_awt_X11GraphicsConfig
+ * Method: isTranslucencyCapable
+ * Signature: (J)V
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_awt_X11GraphicsConfig_isTranslucencyCapable
+ (JNIEnv *env, jobject this, jlong configData)
+{
+#ifdef HEADLESS
+ return JNI_FALSE;
+#else
+ AwtGraphicsConfigDataPtr aData = (AwtGraphicsConfigDataPtr)jlong_to_ptr(configData);
+ if (aData == NULL) {
+ return JNI_FALSE;
+ }
+ return (jboolean)aData->isTranslucencySupported;
+#endif
+}
+
+/*
* Class: sun_awt_X11GraphicsDevice
* Method: isDBESupported
* Signature: ()Z
diff --git a/src/solaris/native/sun/awt/awt_Window.h b/src/solaris/native/sun/awt/awt_Window.h
index 875f55b2f..a93e4ad34 100644
--- a/src/solaris/native/sun/awt/awt_Window.h
+++ b/src/solaris/native/sun/awt/awt_Window.h
@@ -28,7 +28,6 @@
/* fieldIDs for Window fields that may be accessed from C */
struct WindowIDs {
jfieldID warningString;
- jmethodID resetGCMID;
jfieldID locationByPlatform;
jfieldID isAutoRequestFocus;
};
diff --git a/src/solaris/native/sun/awt/awt_p.h b/src/solaris/native/sun/awt/awt_p.h
index fb4f513f7..73e5dd0a8 100644
--- a/src/solaris/native/sun/awt/awt_p.h
+++ b/src/solaris/native/sun/awt/awt_p.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -135,6 +135,7 @@ typedef struct _AwtGraphicsConfigData {
int pixelStride; /* Used in X11SurfaceData.c */
ColorData *color_data;
struct _GLXGraphicsConfigInfo *glxInfo;
+ int isTranslucencySupported; /* Uses Xrender to find this out. */
} AwtGraphicsConfigData;
typedef AwtGraphicsConfigData* AwtGraphicsConfigDataPtr;
diff --git a/src/solaris/native/sun/awt/utility/rect.h b/src/solaris/native/sun/awt/utility/rect.h
index 102d147a2..d5ca97588 100644
--- a/src/solaris/native/sun/awt/utility/rect.h
+++ b/src/solaris/native/sun/awt/utility/rect.h
@@ -43,4 +43,15 @@ typedef XRectangle RECT_T;
#define RECT_INC_HEIGHT(r) (r).height++
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int BitmapToYXBandedRectangles(int bitsPerPixel, int width, int height,
+ unsigned char * buf, RECT_T * outBuf);
+
+#if defined(__cplusplus)
+}
+#endif
+
#endif // _AWT_RECT_H
diff --git a/src/solaris/native/sun/xawt/XToolkit.c b/src/solaris/native/sun/xawt/XToolkit.c
index ac3fecc0c..3b9669cb9 100644
--- a/src/solaris/native/sun/xawt/XToolkit.c
+++ b/src/solaris/native/sun/xawt/XToolkit.c
@@ -182,9 +182,6 @@ Java_java_awt_Component_initIDs
(*env)->GetMethodID(env, cls, "getLocationOnScreen_NoTreeLock",
"()Ljava/awt/Point;");
- componentIDs.resetGCMID =
- (*env)->GetMethodID(env, cls, "resetGC", "()V");
-
keyclass = (*env)->FindClass(env, "java/awt/event/KeyEvent");
DASSERT (keyclass != NULL);
@@ -197,9 +194,6 @@ Java_java_awt_Component_initIDs
"Lsun/awt/AppContext;");
(*env)->DeleteLocalRef(env, keyclass);
-
- DASSERT(componentIDs.resetGCMID);
-
}
diff --git a/src/solaris/native/sun/xawt/XlibWrapper.c b/src/solaris/native/sun/xawt/XlibWrapper.c
index aee5cf9b0..93953af16 100644
--- a/src/solaris/native/sun/xawt/XlibWrapper.c
+++ b/src/solaris/native/sun/xawt/XlibWrapper.c
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,9 @@
#include <jvm.h>
#include <Region.h>
+#include "utility/rect.h"
+#include <X11/XKBlib.h>
#if defined(DEBUG) || defined(INTERNAL_BUILD)
static jmethodID lockIsHeldMID = NULL;
@@ -305,6 +307,20 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XRestackWindows
/*
* Class: XlibWrapper
+ * Method: XConfigureWindow
+ * Signature: (JJJJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XConfigureWindow
+(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong value_mask,
+ jlong values)
+{
+ AWT_CHECK_HAVE_LOCK();
+ XConfigureWindow((Display*)jlong_to_ptr(display), (Window)window,
+ (unsigned int)value_mask, (XWindowChanges*)jlong_to_ptr(values));
+}
+
+/*
+ * Class: XlibWrapper
* Method: XSetInputFocus
* Signature: (JJ)V
*/
@@ -434,6 +450,79 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XSelectInput
XSelectInput((Display *) jlong_to_ptr(display), (Window) window, mask);
}
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbSelectEvents
+(JNIEnv *env, jclass clazz, jlong display, jlong device, jlong bits_to_change, jlong values_for_bits)
+{
+ AWT_CHECK_HAVE_LOCK();
+ XkbSelectEvents((Display *) jlong_to_ptr(display), (unsigned int)device,
+ (unsigned long)bits_to_change,
+ (unsigned long)values_for_bits);
+}
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbSelectEventDetails
+(JNIEnv *env, jclass clazz, jlong display, jlong device, jlong event_type, jlong bits_to_change, jlong values_for_bits)
+{
+ AWT_CHECK_HAVE_LOCK();
+ XkbSelectEventDetails((Display *) jlong_to_ptr(display), (unsigned int)device,
+ (unsigned int) event_type,
+ (unsigned long)bits_to_change,
+ (unsigned long)values_for_bits);
+}
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbQueryExtension
+(JNIEnv *env, jclass clazz, jlong display, jlong opcode_rtrn, jlong event_rtrn,
+ jlong error_rtrn, jlong major_in_out, jlong minor_in_out)
+{
+ AWT_CHECK_HAVE_LOCK();
+ return XkbQueryExtension( (Display *) jlong_to_ptr(display),
+ (int *) jlong_to_ptr(opcode_rtrn),
+ (int *) jlong_to_ptr(event_rtrn),
+ (int *) jlong_to_ptr(error_rtrn),
+ (int *) jlong_to_ptr(major_in_out),
+ (int *) jlong_to_ptr(minor_in_out));
+}
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbLibraryVersion
+(JNIEnv *env, jclass clazz, jlong lib_major_in_out, jlong lib_minor_in_out)
+{
+ AWT_CHECK_HAVE_LOCK();
+ *((int *)lib_major_in_out) = XkbMajorVersion;
+ *((int *)lib_minor_in_out) = XkbMinorVersion;
+ return XkbLibraryVersion((int *)jlong_to_ptr(lib_major_in_out), (int *)jlong_to_ptr(lib_minor_in_out));
+}
+
+JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetMap
+(JNIEnv *env, jclass clazz, jlong display, jlong which, jlong device_spec)
+{
+ AWT_CHECK_HAVE_LOCK();
+ return (jlong) XkbGetMap( (Display *) jlong_to_ptr(display),
+ (unsigned int) which,
+ (unsigned int) device_spec);
+}
+JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap
+(JNIEnv *env, jclass clazz, jlong display, jlong which, jlong xkb)
+{
+ AWT_CHECK_HAVE_LOCK();
+ return (jlong) XkbGetUpdatedMap( (Display *) jlong_to_ptr(display),
+ (unsigned int) which,
+ (XkbDescPtr) jlong_to_ptr(xkb));
+}
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard
+(JNIEnv *env, jclass clazz, jlong xkb, jlong which, jboolean free_all)
+{
+ AWT_CHECK_HAVE_LOCK();
+ XkbFreeKeyboard(jlong_to_ptr(xkb), (unsigned int)which, free_all);
+}
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode
+(JNIEnv *env, jclass clazz, jlong xkb, jint keycode, jlong mods, jlong mods_rtrn, jlong keysym_rtrn)
+{
+ Bool b;
+ b = XkbTranslateKeyCode((XkbDescPtr)xkb, (unsigned int)keycode, (unsigned int)mods,
+ (unsigned int *)jlong_to_ptr(mods_rtrn),
+ (KeySym *)jlong_to_ptr(keysym_rtrn));
+ //printf("native, input: keycode:0x%0X; mods:0x%0X\n", keycode, mods);
+ //printf("native, output: keysym:0x%0X; mods:0x%0X\n", *(unsigned int *)jlong_to_ptr(keysym_rtrn), *(unsigned int *)jlong_to_ptr(mods_rtrn));
+ return b;
+}
+
+
/*
* Class: sun_awt_X11_XlibWrapper
* Method: XNextEvent
@@ -1658,6 +1747,39 @@ Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym(JNIEnv *env, jclass clazz,
}
JNIEXPORT jint JNICALL
+Java_sun_awt_X11_XlibWrapper_XkbGetEffectiveGroup(JNIEnv *env, jclass clazz,
+ jlong display) {
+ XkbStateRec sr;
+ AWT_CHECK_HAVE_LOCK();
+ memset(&sr, 0, sizeof(XkbStateRec));
+ XkbGetState((Display*) jlong_to_ptr(display), XkbUseCoreKbd, &sr);
+// printf("-------------------------------------VVVV\n");
+// printf(" group:0x%0X\n",sr.group);
+// printf(" base_group:0x%0X\n",sr.base_group);
+// printf(" latched_group:0x%0X\n",sr.latched_group);
+// printf(" locked_group:0x%0X\n",sr.locked_group);
+// printf(" mods:0x%0X\n",sr.mods);
+// printf(" base_mods:0x%0X\n",sr.base_mods);
+// printf(" latched_mods:0x%0X\n",sr.latched_mods);
+// printf(" locked_mods:0x%0X\n",sr.locked_mods);
+// printf(" compat_state:0x%0X\n",sr.compat_state);
+// printf(" grab_mods:0x%0X\n",sr.grab_mods);
+// printf(" compat_grab_mods:0x%0X\n",sr.compat_grab_mods);
+// printf(" lookup_mods:0x%0X\n",sr.lookup_mods);
+// printf(" compat_lookup_mods:0x%0X\n",sr.compat_lookup_mods);
+// printf(" ptr_buttons:0x%0X\n",sr.ptr_buttons);
+// printf("-------------------------------------^^^^\n");
+ return (jint)(sr.group);
+}
+JNIEXPORT jlong JNICALL
+Java_sun_awt_X11_XlibWrapper_XkbKeycodeToKeysym(JNIEnv *env, jclass clazz,
+ jlong display, jint keycode,
+ jint group, jint level) {
+ AWT_CHECK_HAVE_LOCK();
+ return XkbKeycodeToKeysym((Display*) jlong_to_ptr(display), (unsigned int)keycode, (unsigned int)group, (unsigned int)level);
+}
+
+JNIEXPORT jint JNICALL
Java_sun_awt_X11_XlibWrapper_XKeysymToKeycode(JNIEnv *env, jclass clazz,
jlong display, jlong keysym) {
AWT_CHECK_HAVE_LOCK();
@@ -1945,3 +2067,77 @@ Java_sun_awt_X11_XlibWrapper_SetRectangularShape
ShapeBounding, 0, 0, None, ShapeSet);
}
}
+
+/*
+ * Class: XlibWrapper
+ * Method: SetZOrder
+ */
+
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XlibWrapper_SetZOrder
+(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong above)
+{
+ AWT_CHECK_HAVE_LOCK();
+
+ XWindowChanges wc;
+ wc.sibling = (Window)jlong_to_ptr(above);
+
+ unsigned int value_mask = CWStackMode;
+
+ if (above == 0) {
+ wc.stack_mode = Above;
+ } else {
+ wc.stack_mode = Below;
+ value_mask |= CWSibling;
+ }
+
+ XConfigureWindow((Display *)jlong_to_ptr(display),
+ (Window)jlong_to_ptr(window),
+ value_mask, &wc );
+}
+
+/*
+ * Class: XlibWrapper
+ * Method: SetBitmapShape
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XlibWrapper_SetBitmapShape
+(JNIEnv *env, jclass clazz, jlong display, jlong window,
+ jint width, jint height, jintArray bitmap)
+{
+ jsize len;
+ jint *values;
+ jboolean isCopy = JNI_FALSE;
+ size_t worstBufferSize = (size_t)((width / 2 + 1) * height);
+ RECT_T * pRect;
+
+ AWT_CHECK_HAVE_LOCK();
+
+ len = (*env)->GetArrayLength(env, bitmap);
+ if (len == 0 || len < width * height) {
+ return;
+ }
+
+ values = (*env)->GetIntArrayElements(env, bitmap, &isCopy);
+ if (JNU_IsNull(env, values)) {
+ return;
+ }
+
+ pRect = (RECT_T *)malloc(worstBufferSize * sizeof(RECT_T));
+
+ /* Note: the values[0] and values[1] are supposed to contain the width
+ * and height (see XIconInfo.getIntData() for details). So, we do +2.
+ */
+ int numrects = BitmapToYXBandedRectangles(32, (int)width, (int)height,
+ (unsigned char *)(values + 2), pRect);
+
+ XShapeCombineRectangles((Display *)jlong_to_ptr(display), (Window)jlong_to_ptr(window),
+ ShapeClip, 0, 0, pRect, numrects, ShapeSet, YXBanded);
+ XShapeCombineRectangles((Display *)jlong_to_ptr(display), (Window)jlong_to_ptr(window),
+ ShapeBounding, 0, 0, pRect, numrects, ShapeSet, YXBanded);
+
+ free(pRect);
+
+ (*env)->ReleaseIntArrayElements(env, bitmap, values, JNI_ABORT);
+}
+
diff --git a/src/windows/classes/sun/awt/Win32GraphicsConfig.java b/src/windows/classes/sun/awt/Win32GraphicsConfig.java
index d24ce0eb1..2eefb33f1 100644
--- a/src/windows/classes/sun/awt/Win32GraphicsConfig.java
+++ b/src/windows/classes/sun/awt/Win32GraphicsConfig.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -331,4 +331,12 @@ public class Win32GraphicsConfig extends GraphicsConfiguration
}
// the rest of the flip actions are not supported
}
+
+ /*
+ @Override
+ */
+ public boolean isTranslucencyCapable() {
+ //XXX: worth checking if 8-bit? Anyway, it doesn't hurt.
+ return true;
+ }
}
diff --git a/src/windows/classes/sun/awt/Win32GraphicsDevice.java b/src/windows/classes/sun/awt/Win32GraphicsDevice.java
index ba4769813..1da339ce9 100644
--- a/src/windows/classes/sun/awt/Win32GraphicsDevice.java
+++ b/src/windows/classes/sun/awt/Win32GraphicsDevice.java
@@ -380,7 +380,6 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
// fix for 4868278
peer.updateGC();
- peer.resetTargetGC();
}
}
diff --git a/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java b/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java
index 73b73dbb0..69723c113 100644
--- a/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java
+++ b/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -398,4 +398,11 @@ public class Win32GraphicsEnvironment
public boolean isDisplayLocal() {
return true;
}
+
+ /**
+ * Used to find out if the OS is Windows Vista or later.
+ *
+ * @return {@code true} if the OS is Vista or later, {@code false} otherwise
+ */
+ public static native boolean isVistaOS();
}
diff --git a/src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java b/src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java
new file mode 100644
index 000000000..9f8193f99
--- /dev/null
+++ b/src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.awt.windows;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Window;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.VolatileImage;
+import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import sun.awt.image.BufImgSurfaceData;
+import sun.java2d.DestSurfaceProvider;
+import sun.java2d.InvalidPipeException;
+import sun.java2d.Surface;
+import sun.java2d.pipe.RenderQueue;
+import sun.java2d.pipe.hw.AccelGraphicsConfig;
+import sun.java2d.pipe.hw.AccelSurface;
+import sun.security.action.GetPropertyAction;
+
+import static java.awt.image.VolatileImage.*;
+import static java.awt.Transparency.*;
+import static sun.java2d.pipe.hw.AccelSurface.*;
+import static sun.java2d.pipe.hw.ContextCapabilities.*;
+
+/**
+ * This class handles the updates of the non-opaque windows.
+ * The window associated with the peer is updated either given an image or
+ * the window is repainted to an internal buffer which is then used to update
+ * the window.
+ *
+ * Note: this class does not attempt to be thread safe, it is expected to be
+ * called from a single thread (EDT).
+ */
+public abstract class TranslucentWindowPainter {
+
+ protected Window window;
+ protected WWindowPeer peer;
+
+ // REMIND: we probably would want to remove this later
+ private static final boolean forceOpt =
+ Boolean.valueOf(AccessController.doPrivileged(
+ new GetPropertyAction("sun.java2d.twp.forceopt", "false")));
+ private static final boolean forceSW =
+ Boolean.valueOf(AccessController.doPrivileged(
+ new GetPropertyAction("sun.java2d.twp.forcesw", "false")));
+
+ /**
+ * Creates an instance of the painter for particular peer.
+ */
+ public static TranslucentWindowPainter createInstance(WWindowPeer peer) {
+ GraphicsConfiguration gc = peer.getGraphicsConfiguration();
+ if (!forceSW && gc instanceof AccelGraphicsConfig) {
+ String gcName = gc.getClass().getSimpleName();
+ AccelGraphicsConfig agc = (AccelGraphicsConfig)gc;
+ // this is a heuristic to check that we have a pcix board
+ // (those have higher transfer rate from gpu to cpu)
+ if ((agc.getContextCapabilities().getCaps() & CAPS_PS30) != 0 ||
+ forceOpt)
+ {
+ // we check for name to avoid loading classes unnecessarily if
+ // a pipeline isn't enabled
+ if (gcName.startsWith("D3D")) {
+ return new VIOptD3DWindowPainter(peer);
+ } else if (forceOpt && gcName.startsWith("WGL")) {
+ // on some boards (namely, ATI, even on pcix bus) ogl is
+ // very slow reading pixels back so for now it is disabled
+ // unless forced
+ return new VIOptWGLWindowPainter(peer);
+ }
+ }
+ }
+ return new BIWindowPainter(peer);
+ }
+
+ protected TranslucentWindowPainter(WWindowPeer peer) {
+ this.peer = peer;
+ this.window = (Window)peer.getTarget();
+ }
+
+ /**
+ * Creates (if needed), clears and returns the buffer for this painter.
+ */
+ protected abstract Image getBackBuffer();
+
+ /**
+ * Updates the the window associated with this painter with the contents
+ * of the passed image.
+ * The image can not be null, and NPE will be thrown if it is.
+ */
+ protected abstract boolean update(Image bb);
+
+ /**
+ * Flushes the resources associated with the painter. They will be
+ * recreated as needed.
+ */
+ public abstract void flush();
+
+ /**
+ * Updates the window associated with the painter given the passed image.
+ * If the passed image is null the painter will use its own buffer for
+ * rendering the contents of the window into it and updating the window.
+ *
+ * If the passed buffer has dimensions different from the window, it is
+ * copied into the internal buffer first and the latter is used to update
+ * the window.
+ *
+ * @param bb the image to update the non opaque window with, or null.
+ * If not null, the image must be of ARGB_PRE type.
+ */
+ public void updateWindow(Image bb) {
+ boolean done = false;
+ if (bb != null && (window.getWidth() != bb.getWidth(null) ||
+ window.getHeight() != bb.getHeight(null)))
+ {
+ Image ourBB = getBackBuffer();
+ Graphics2D g = (Graphics2D)ourBB.getGraphics();
+ g.drawImage(bb, 0, 0, null);
+ g.dispose();
+ bb = ourBB;
+ }
+ do {
+ if (bb == null) {
+ bb = getBackBuffer();
+ Graphics2D g = (Graphics2D)bb.getGraphics();
+ try {
+ window.paintAll(g);
+ } finally {
+ g.dispose();
+ }
+ }
+
+ peer.paintAppletWarning((Graphics2D)bb.getGraphics(),
+ bb.getWidth(null), bb.getHeight(null));
+
+ done = update(bb);
+ // in case they passed us a lost VI, next time around we'll use our
+ // own bb because we can not validate and restore the contents of
+ // their VI
+ if (!done) {
+ bb = null;
+ }
+ } while (!done);
+ }
+
+ private static final Image clearImage(Image bb) {
+ Graphics2D g = (Graphics2D)bb.getGraphics();
+ int w = bb.getWidth(null);
+ int h = bb.getHeight(null);
+
+ g.setComposite(AlphaComposite.Src);
+ g.setColor(new Color(0, 0, 0, 0));
+ g.fillRect(0, 0, w, h);
+
+ return bb;
+ }
+
+ /**
+ * A painter which uses BufferedImage as the internal buffer. The window
+ * is painted into this buffer, and the contents then are uploaded
+ * into the layered window.
+ *
+ * This painter handles all types of images passed to its paint(Image)
+ * method (VI, BI, regular Images).
+ */
+ private static class BIWindowPainter extends TranslucentWindowPainter {
+ private WeakReference<BufferedImage> biRef;
+
+ protected BIWindowPainter(WWindowPeer peer) {
+ super(peer);
+ }
+
+ private BufferedImage getBIBackBuffer() {
+ int w = window.getWidth();
+ int h = window.getHeight();
+ BufferedImage bb = biRef == null ? null : biRef.get();
+ if (bb == null || bb.getWidth() != w || bb.getHeight() != h) {
+ if (bb != null) {
+ bb.flush();
+ bb = null;
+ }
+ bb = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
+ biRef = new WeakReference<BufferedImage>(bb);
+ }
+ return (BufferedImage)clearImage(bb);
+ }
+
+ @Override
+ protected Image getBackBuffer() {
+ return getBIBackBuffer();
+ }
+
+ @Override
+ protected boolean update(Image bb) {
+ VolatileImage viBB = null;
+
+ if (bb instanceof BufferedImage) {
+ BufferedImage bi = (BufferedImage)bb;
+ int data[] =
+ ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
+ return true;
+ } else if (bb instanceof VolatileImage) {
+ viBB = (VolatileImage)bb;
+ if (bb instanceof DestSurfaceProvider) {
+ Surface s = ((DestSurfaceProvider)bb).getDestSurface();
+ if (s instanceof BufImgSurfaceData) {
+ // the image is probably lost, upload the data from the
+ // backup surface to avoid creating another heap-based
+ // image (the parent's buffer)
+ int w = viBB.getWidth();
+ int h = viBB.getHeight();
+ BufImgSurfaceData bisd = (BufImgSurfaceData)s;
+ int data[] = ((DataBufferInt)bisd.getRaster(0,0,w,h).
+ getDataBuffer()).getData();
+ peer.updateWindowImpl(data, w, h);
+ return true;
+ }
+ }
+ }
+
+ // copy the passed image into our own buffer, then upload
+ BufferedImage bi = getBIBackBuffer();
+ Graphics2D g = (Graphics2D)bi.getGraphics();
+ g.setComposite(AlphaComposite.Src);
+ g.drawImage(bb, 0, 0, null);
+
+ int data[] =
+ ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
+
+ return (viBB != null ? !viBB.contentsLost() : true);
+ }
+
+ public void flush() {
+ if (biRef != null) {
+ biRef.clear();
+ }
+ }
+ }
+
+ /**
+ * A version of the painter which uses VolatileImage as the internal buffer.
+ * The window is painted into this VI and then copied into the parent's
+ * Java heap-based buffer (which is then uploaded to the layered window)
+ */
+ private static class VIWindowPainter extends BIWindowPainter {
+ private WeakReference<VolatileImage> viRef;
+
+ protected VIWindowPainter(WWindowPeer peer) {
+ super(peer);
+ }
+
+ @Override
+ protected Image getBackBuffer() {
+ int w = window.getWidth();
+ int h = window.getHeight();
+ GraphicsConfiguration gc = peer.getGraphicsConfiguration();
+
+ VolatileImage viBB = viRef == null ? null : viRef.get();
+
+ if (viBB == null || viBB.getWidth() != w || viBB.getHeight() != h ||
+ viBB.validate(gc) == IMAGE_INCOMPATIBLE)
+ {
+ if (viBB != null) {
+ viBB.flush();
+ viBB = null;
+ }
+
+ if (gc instanceof AccelGraphicsConfig) {
+ AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc);
+ viBB = agc.createCompatibleVolatileImage(w, h,
+ TRANSLUCENT,
+ RT_PLAIN);
+ }
+ if (viBB == null) {
+ viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT);
+ }
+ viBB.validate(gc);
+ viRef = new WeakReference<VolatileImage>(viBB);
+ }
+
+ return clearImage(viBB);
+ }
+
+ @Override
+ public void flush() {
+ if (viRef != null) {
+ VolatileImage viBB = viRef.get();
+ if (viBB != null) {
+ viBB.flush();
+ viBB = null;
+ }
+ viRef.clear();
+ }
+ }
+ }
+
+ /**
+ * Optimized version of hw painter. Uses VolatileImages for the
+ * buffer, and uses an optimized path to pull the data from those into
+ * the layered window, bypassing Java heap-based image.
+ */
+ private abstract static class VIOptWindowPainter extends VIWindowPainter {
+
+ protected VIOptWindowPainter(WWindowPeer peer) {
+ super(peer);
+ }
+
+ protected abstract boolean updateWindowAccel(long psdops, int w, int h);
+
+ @Override
+ protected boolean update(Image bb) {
+ if (bb instanceof DestSurfaceProvider) {
+ Surface s = ((DestSurfaceProvider)bb).getDestSurface();
+ if (s instanceof AccelSurface) {
+ final int w = bb.getWidth(null);
+ final int h = bb.getHeight(null);
+ final boolean arr[] = { false };
+ final AccelSurface as = (AccelSurface)s;
+ RenderQueue rq = as.getContext().getRenderQueue();
+ rq.lock();
+ try {
+ as.getContext().validateContext(as);
+ rq.flushAndInvokeNow(new Runnable() {
+ public void run() {
+ long psdops = as.getNativeOps();
+ arr[0] = updateWindowAccel(psdops, w, h);
+ }
+ });
+ } catch (InvalidPipeException e) {
+ // ignore, false will be returned
+ } finally {
+ rq.unlock();
+ }
+ return arr[0];
+ }
+ }
+ return super.update(bb);
+ }
+ }
+
+ private static class VIOptD3DWindowPainter extends VIOptWindowPainter {
+
+ protected VIOptD3DWindowPainter(WWindowPeer peer) {
+ super(peer);
+ }
+
+ @Override
+ protected boolean updateWindowAccel(long psdops, int w, int h) {
+ // note: this method is executed on the toolkit thread, no sync is
+ // necessary at the native level, and a pointer to peer can be used
+ return sun.java2d.d3d.D3DSurfaceData.
+ updateWindowAccelImpl(psdops, peer.getData(), w, h);
+ }
+ }
+
+ private static class VIOptWGLWindowPainter extends VIOptWindowPainter {
+
+ protected VIOptWGLWindowPainter(WWindowPeer peer) {
+ super(peer);
+ }
+
+ @Override
+ protected boolean updateWindowAccel(long psdops, int w, int h) {
+ // note: part of this method which deals with GDI will be on the
+ // toolkit thread
+ return sun.java2d.opengl.WGLSurfaceData.
+ updateWindowAccelImpl(psdops, peer, w, h);
+ }
+ }
+}
diff --git a/src/windows/classes/sun/awt/windows/WCanvasPeer.java b/src/windows/classes/sun/awt/windows/WCanvasPeer.java
index 5d88a0c37..b97a3787b 100644
--- a/src/windows/classes/sun/awt/windows/WCanvasPeer.java
+++ b/src/windows/classes/sun/awt/windows/WCanvasPeer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@ import java.awt.*;
import java.awt.peer.*;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
+import sun.awt.AWTAccessor;
import sun.awt.ComponentAccessor;
import sun.awt.SunToolkit;
import sun.awt.Win32GraphicsDevice;
@@ -37,44 +38,12 @@ class WCanvasPeer extends WComponentPeer implements CanvasPeer {
private boolean eraseBackground;
- Method resetGCMethod;
-
// Toolkit & peer internals
WCanvasPeer(Component target) {
super(target);
}
- /*
- * From the DisplayChangedListener interface.
- *
- * Overrides WComponentPeer version because Canvases can be created with
- * a non-defulat GraphicsConfiguration, which is no longer valid.
- * Up-called for other windows peer instances (WPanelPeer, WWindowPeer).
- */
- public void displayChanged() {
- clearLocalGC();
- resetTargetGC();
- super.displayChanged();
- }
-
- /*
- * Reset the graphicsConfiguration member of our target Component.
- * Component.resetGC() is a package-private method, so we have to call it
- * through reflection.
- */
- public void resetTargetGC() {
- ComponentAccessor.resetGC((Component)target);
- }
-
- /*
- * Clears the peer's winGraphicsConfig member.
- * Overridden by WWindowPeer, which shouldn't have a null winGraphicsConfig.
- */
- void clearLocalGC() {
- winGraphicsConfig = null;
- }
-
native void create(WComponentPeer parent);
void initialize() {
@@ -110,16 +79,20 @@ class WCanvasPeer extends WComponentPeer implements CanvasPeer {
}
public void print(Graphics g) {
- Dimension d = ((Component)target).getSize();
- if (g instanceof Graphics2D ||
- g instanceof sun.awt.Graphics2Delegate) {
- // background color is setup correctly, so just use clearRect
- g.clearRect(0, 0, d.width, d.height);
- } else {
- // emulate clearRect
- g.setColor(((Component)target).getBackground());
- g.fillRect(0, 0, d.width, d.height);
- g.setColor(((Component)target).getForeground());
+ if (!(target instanceof Window) ||
+ AWTAccessor.getWindowAccessor().isOpaque((Window)target))
+ {
+ Dimension d = ((Component)target).getSize();
+ if (g instanceof Graphics2D ||
+ g instanceof sun.awt.Graphics2Delegate) {
+ // background color is setup correctly, so just use clearRect
+ g.clearRect(0, 0, d.width, d.height);
+ } else {
+ // emulate clearRect
+ g.setColor(((Component)target).getBackground());
+ g.fillRect(0, 0, d.width, d.height);
+ g.setColor(((Component)target).getForeground());
+ }
}
super.print(g);
}
@@ -147,4 +120,10 @@ class WCanvasPeer extends WComponentPeer implements CanvasPeer {
*/
private native void setNativeBackgroundErase(boolean doErase,
boolean doEraseOnResize);
+
+ public GraphicsConfiguration getAppropriateGraphicsConfiguration(
+ GraphicsConfiguration gc)
+ {
+ return gc;
+ }
}
diff --git a/src/windows/classes/sun/awt/windows/WChoicePeer.java b/src/windows/classes/sun/awt/windows/WChoicePeer.java
index 20ab610ff..b72e6f741 100644
--- a/src/windows/classes/sun/awt/windows/WChoicePeer.java
+++ b/src/windows/classes/sun/awt/windows/WChoicePeer.java
@@ -27,6 +27,10 @@ package sun.awt.windows;
import java.awt.*;
import java.awt.peer.*;
import java.awt.event.ItemEvent;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.event.WindowAdapter;
+import sun.awt.SunToolkit;
class WChoicePeer extends WComponentPeer implements ChoicePeer {
@@ -70,6 +74,8 @@ class WChoicePeer extends WComponentPeer implements ChoicePeer {
public synchronized native void reshape(int x, int y, int width, int height);
+ private WindowListener windowListener;
+
// Toolkit & peer internals
WChoicePeer(Choice target) {
@@ -91,9 +97,38 @@ class WChoicePeer extends WComponentPeer implements ChoicePeer {
select(opt.getSelectedIndex());
}
}
+
+ Window parentWindow = SunToolkit.getContainingWindow((Component)target);
+ if (parentWindow != null) {
+ WWindowPeer wpeer = (WWindowPeer)parentWindow.getPeer();
+ if (wpeer != null) {
+ windowListener = new WindowAdapter() {
+ public void windowIconified(WindowEvent e) {
+ closeList();
+ }
+ public void windowClosing(WindowEvent e) {
+ closeList();
+ }
+ };
+ wpeer.addWindowListener(windowListener);
+ }
+ }
super.initialize();
}
+ protected void disposeImpl() {
+ // TODO: we should somehow reset the listener when the choice
+ // is moved to another toplevel without destroying its peer.
+ Window parentWindow = SunToolkit.getContainingWindow((Component)target);
+ if (parentWindow != null) {
+ WWindowPeer wpeer = (WWindowPeer)parentWindow.getPeer();
+ if (wpeer != null) {
+ wpeer.removeWindowListener(windowListener);
+ }
+ }
+ super.disposeImpl();
+ }
+
// native callbacks
void handleAction(final int index) {
@@ -121,4 +156,5 @@ class WChoicePeer extends WComponentPeer implements ChoicePeer {
return getMinimumSize();
}
+ native void closeList();
}
diff --git a/src/windows/classes/sun/awt/windows/WComponentPeer.java b/src/windows/classes/sun/awt/windows/WComponentPeer.java
index afbd170cc..6ad608452 100644
--- a/src/windows/classes/sun/awt/windows/WComponentPeer.java
+++ b/src/windows/classes/sun/awt/windows/WComponentPeer.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,27 +38,32 @@ import java.awt.image.ColorModel;
import java.awt.event.PaintEvent;
import java.awt.event.InvocationEvent;
import java.awt.event.KeyEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.InputEvent;
import sun.awt.Win32GraphicsConfig;
+import sun.awt.Win32GraphicsEnvironment;
import sun.java2d.InvalidPipeException;
import sun.java2d.SurfaceData;
-import sun.java2d.d3d.D3DScreenUpdateManager;
-import static sun.java2d.d3d.D3DSurfaceData.*;
import sun.java2d.ScreenUpdateManager;
+import sun.java2d.d3d.D3DSurfaceData;
import sun.java2d.opengl.OGLSurfaceData;
+import sun.java2d.pipe.Region;
import sun.awt.DisplayChangedListener;
import sun.awt.PaintEventDispatcher;
+import sun.awt.SunToolkit;
import sun.awt.event.IgnorePaintEvent;
import java.awt.dnd.DropTarget;
import java.awt.dnd.peer.DropTargetPeer;
import sun.awt.ComponentAccessor;
-
import java.util.logging.*;
public abstract class WComponentPeer extends WObjectPeer
- implements ComponentPeer, DropTargetPeer, DisplayChangedListener
+ implements ComponentPeer, DropTargetPeer
{
/**
* Handle to native window
@@ -67,6 +72,7 @@ public abstract class WComponentPeer extends WObjectPeer
private static final Logger log = Logger.getLogger("sun.awt.windows.WComponentPeer");
private static final Logger shapeLog = Logger.getLogger("sun.awt.windows.shape.WComponentPeer");
+ private static final Logger focusLog = Logger.getLogger("sun.awt.windows.focus.WComponentPeer");
// ComponentPeer implementation
SurfaceData surfaceData;
@@ -186,7 +192,7 @@ public abstract class WComponentPeer extends WObjectPeer
cont.invalidate();
cont.validate();
- if (surfaceData instanceof D3DWindowSurfaceData ||
+ if (surfaceData instanceof D3DSurfaceData.D3DWindowSurfaceData ||
surfaceData instanceof OGLSurfaceData)
{
// When OGL or D3D is enabled, it is necessary to
@@ -258,7 +264,7 @@ public abstract class WComponentPeer extends WObjectPeer
int[] pix = createPrintedPixels(0, startY, totalW, h);
if (pix != null) {
BufferedImage bim = new BufferedImage(totalW, h,
- BufferedImage.TYPE_INT_RGB);
+ BufferedImage.TYPE_INT_ARGB);
bim.setRGB(0, 0, totalW, h, pix, 0, totalW);
g.drawImage(bim, 0, startY, null);
bim.flush();
@@ -295,14 +301,35 @@ public abstract class WComponentPeer extends WObjectPeer
// on handling '\n' to prevent it from being passed to native code
public boolean handleJavaKeyEvent(KeyEvent e) { return false; }
+ public void handleJavaMouseEvent(MouseEvent e) {
+ switch (e.getID()) {
+ case MouseEvent.MOUSE_PRESSED:
+ // Note that Swing requests focus in its own mouse event handler.
+ if (target == e.getSource() &&
+ !((Component)target).isFocusOwner() &&
+ WKeyboardFocusManagerPeer.shouldFocusOnClick((Component)target))
+ {
+ WKeyboardFocusManagerPeer.requestFocusFor((Component)target,
+ CausedFocusEvent.Cause.MOUSE_EVENT);
+ }
+ break;
+ }
+ }
+
native void nativeHandleEvent(AWTEvent e);
public void handleEvent(AWTEvent e) {
int id = e.getID();
- if (((Component)target).isEnabled() && (e instanceof KeyEvent) && !((KeyEvent)e).isConsumed()) {
- if (handleJavaKeyEvent((KeyEvent)e)) {
- return;
+ if ((e instanceof InputEvent) && !((InputEvent)e).isConsumed() &&
+ ((Component)target).isEnabled())
+ {
+ if (e instanceof MouseEvent && !(e instanceof MouseWheelEvent)) {
+ handleJavaMouseEvent((MouseEvent) e);
+ } else if (e instanceof KeyEvent) {
+ if (handleJavaKeyEvent((KeyEvent)e)) {
+ return;
+ }
}
}
@@ -318,6 +345,9 @@ public abstract class WComponentPeer extends WObjectPeer
paintArea.paint(target,shouldClearRectBeforePaint());
}
return;
+ case FocusEvent.FOCUS_LOST:
+ case FocusEvent.FOCUS_GAINED:
+ handleJavaFocusEvent((FocusEvent)e);
default:
break;
}
@@ -326,6 +356,13 @@ public abstract class WComponentPeer extends WObjectPeer
nativeHandleEvent(e);
}
+ void handleJavaFocusEvent(FocusEvent fe) {
+ if (focusLog.isLoggable(Level.FINER)) focusLog.finer(fe.toString());
+ setFocus(fe.getID() == FocusEvent.FOCUS_GAINED);
+ }
+
+ native void setFocus(boolean doSetFocus);
+
public Dimension getMinimumSize() {
return ((Component)target).getSize();
}
@@ -451,15 +488,8 @@ public abstract class WComponentPeer extends WObjectPeer
}
}
- /**
- * From the DisplayChangedListener interface.
- *
- * Called after a change in the display mode. This event
- * triggers replacing the surfaceData object (since that object
- * reflects the current display depth information, which has
- * just changed).
- */
- public void displayChanged() {
+ public void updateGraphicsData(GraphicsConfiguration gc) {
+ winGraphicsConfig = (Win32GraphicsConfig)gc;
try {
replaceSurfaceData();
} catch (InvalidPipeException e) {
@@ -467,13 +497,6 @@ public abstract class WComponentPeer extends WObjectPeer
}
}
- /**
- * Part of the DisplayChangedListener interface: components
- * do not need to react to this event
- */
- public void paletteChanged() {
- }
-
//This will return null for Components not yet added to a Container
public ColorModel getColorModel() {
GraphicsConfiguration gc = getGraphicsConfiguration();
@@ -585,22 +608,64 @@ public abstract class WComponentPeer extends WObjectPeer
WGlobalCursorManager.getCursorManager().updateCursorImmediately();
}
- native static boolean processSynchronousLightweightTransfer(Component heavyweight, Component descendant,
- boolean temporary, boolean focusedWindowChangeAllowed,
- long time);
- public boolean requestFocus
- (Component lightweightChild, boolean temporary,
- boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause) {
- if (processSynchronousLightweightTransfer((Component)target, lightweightChild, temporary,
- focusedWindowChangeAllowed, time)) {
+ // TODO: consider moving it to KeyboardFocusManagerPeerImpl
+ public boolean requestFocus(Component lightweightChild, boolean temporary,
+ boolean focusedWindowChangeAllowed, long time,
+ CausedFocusEvent.Cause cause)
+ {
+ if (WKeyboardFocusManagerPeer.
+ processSynchronousLightweightTransfer((Component)target, lightweightChild, temporary,
+ focusedWindowChangeAllowed, time))
+ {
return true;
- } else {
- return _requestFocus(lightweightChild, temporary, focusedWindowChangeAllowed, time, cause);
}
+
+ int result = WKeyboardFocusManagerPeer
+ .shouldNativelyFocusHeavyweight((Component)target, lightweightChild,
+ temporary, focusedWindowChangeAllowed,
+ time, cause);
+
+ switch (result) {
+ case WKeyboardFocusManagerPeer.SNFH_FAILURE:
+ return false;
+ case WKeyboardFocusManagerPeer.SNFH_SUCCESS_PROCEED:
+ if (focusLog.isLoggable(Level.FINER)) {
+ focusLog.finer("Proceeding with request to " + lightweightChild + " in " + target);
+ }
+ Window parentWindow = SunToolkit.getContainingWindow((Component)target);
+ if (parentWindow == null) {
+ return rejectFocusRequestHelper("WARNING: Parent window is null");
+ }
+ WWindowPeer wpeer = (WWindowPeer)parentWindow.getPeer();
+ if (wpeer == null) {
+ return rejectFocusRequestHelper("WARNING: Parent window's peer is null");
+ }
+ boolean res = wpeer.requestWindowFocus(cause);
+
+ if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Requested window focus: " + res);
+ // If parent window can be made focused and has been made focused(synchronously)
+ // then we can proceed with children, otherwise we retreat.
+ if (!(res && parentWindow.isFocused())) {
+ return rejectFocusRequestHelper("Waiting for asynchronous processing of the request");
+ }
+ return WKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
+ (Component)target,
+ temporary,
+ focusedWindowChangeAllowed,
+ time, cause);
+
+ case WKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
+ // Either lightweight or excessive request - all events are generated.
+ return true;
+ }
+ return false;
+ }
+
+ private boolean rejectFocusRequestHelper(String logMsg) {
+ if (focusLog.isLoggable(Level.FINER)) focusLog.finer(logMsg);
+ WKeyboardFocusManagerPeer.removeLastFocusRequest((Component)target);
+ return false;
}
- public native boolean _requestFocus
- (Component lightweightChild, boolean temporary,
- boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause);
public Image createImage(ImageProducer producer) {
return new ToolkitImage(producer);
@@ -713,7 +778,7 @@ public abstract class WComponentPeer extends WObjectPeer
* NOTE: This is called on the privileged toolkit thread. Do not
* call directly into user code using this thread!
*/
- void handlePaint(int x, int y, int w, int h) {
+ public void handlePaint(int x, int y, int w, int h) {
postPaintIfNecessary(x, y, w, h);
}
@@ -731,9 +796,12 @@ public abstract class WComponentPeer extends WObjectPeer
* Post an event. Queue it for execution by the callback thread.
*/
void postEvent(AWTEvent event) {
+ preprocessPostEvent(event);
WToolkit.postEvent(WToolkit.targetToAppContext(target), event);
}
+ void preprocessPostEvent(AWTEvent event) {}
+
// Routines to support deferred window positioning.
public void beginLayout() {
// Skip all painting till endLayout
@@ -895,25 +963,6 @@ public abstract class WComponentPeer extends WObjectPeer
public void setBoundsOperation(int operation) {
}
-
- native void setRectangularShape(int lox, int loy, int hix, int hiy,
- sun.java2d.pipe.Region region);
-
-
- // REMIND: Temp workaround for issues with using HW acceleration
- // in the browser on Vista when DWM is enabled.
- // @return true if the toplevel container is not an EmbeddedFrame or
- // if this EmbeddedFrame is acceleration capable, false otherwise
- private static final boolean isContainingTopLevelAccelCapable(Component c) {
- while (c != null && !(c instanceof WEmbeddedFrame)) {
- c = c.getParent();
- }
- if (c == null) {
- return true;
- }
- return ((WEmbeddedFramePeer)c.getPeer()).isAccelCapable();
- }
-
/**
* Returns whether this component is capable of being hw accelerated.
* More specifically, whether rendering to this component or a
@@ -928,28 +977,36 @@ public abstract class WComponentPeer extends WObjectPeer
* @see com.sun.awt.AWTUtilities.Translucency#TRANSLUCENT
*/
public boolean isAccelCapable() {
- // REMIND: Temp workaround for issues with using HW acceleration
- // in the browser on Vista when DWM is enabled
- if (!isContainingTopLevelAccelCapable((Component)target)) {
- return false;
- }
-
- // REMIND: translucent windows support-related
-/*
boolean isTranslucent =
SunToolkit.isContainingTopLevelTranslucent((Component)target);
// D3D/OGL and translucent windows interacted poorly in Windows XP;
// these problems are no longer present in Vista
return !isTranslucent || Win32GraphicsEnvironment.isVistaOS();
-*/
- return true;
+ }
+
+ native void setRectangularShape(int lox, int loy, int hix, int hiy,
+ Region region);
+
+
+ // REMIND: Temp workaround for issues with using HW acceleration
+ // in the browser on Vista when DWM is enabled.
+ // @return true if the toplevel container is not an EmbeddedFrame or
+ // if this EmbeddedFrame is acceleration capable, false otherwise
+ private static final boolean isContainingTopLevelAccelCapable(Component c) {
+ while (c != null && !(c instanceof WEmbeddedFrame)) {
+ c = c.getParent();
+ }
+ if (c == null) {
+ return true;
+ }
+ return ((WEmbeddedFramePeer)c.getPeer()).isAccelCapable();
}
/**
* Applies the shape to the native component window.
* @since 1.7
*/
- public void applyShape(sun.java2d.pipe.Region shape) {
+ public void applyShape(Region shape) {
if (shapeLog.isLoggable(Level.FINER)) {
shapeLog.finer(
"*** INFO: Setting shape: PEER: " + this
@@ -965,4 +1022,15 @@ public abstract class WComponentPeer extends WObjectPeer
}
}
+ /**
+ * Lowers this component at the bottom of the above component. If the above parameter
+ * is null then the method places this component at the top of the Z-order.
+ */
+ public void setZOrder(ComponentPeer above) {
+ long aboveHWND = (above != null) ? ((WComponentPeer)above).getHWnd() : 0;
+
+ setZOrder(aboveHWND);
+ }
+
+ private native void setZOrder(long above);
}
diff --git a/src/windows/classes/sun/awt/windows/WFileDialogPeer.java b/src/windows/classes/sun/awt/windows/WFileDialogPeer.java
index 548dc3d41..1c90ae2e5 100644
--- a/src/windows/classes/sun/awt/windows/WFileDialogPeer.java
+++ b/src/windows/classes/sun/awt/windows/WFileDialogPeer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -231,17 +231,9 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
*/
private static native void initIDs();
- /**
- * WFileDialogPeer doesn't have native pData so we don't do restack on it
- * @see java.awt.peer.ContainerPeer#restack
- */
- public void restack() {
- }
-
- /**
- * @see java.awt.peer.ContainerPeer#isRestackSupported
- */
- public boolean isRestackSupported() {
- return false;
- }
+ // The effects are not supported for system dialogs.
+ public void applyShape(sun.java2d.pipe.Region shape) {}
+ public void setOpacity(float opacity) {}
+ public void setOpaque(boolean isOpaque) {}
+ public void updateWindow(java.awt.image.BufferedImage backBuffer) {}
}
diff --git a/src/windows/classes/sun/awt/windows/WFramePeer.java b/src/windows/classes/sun/awt/windows/WFramePeer.java
index 2353daf3d..79bf6b77e 100644
--- a/src/windows/classes/sun/awt/windows/WFramePeer.java
+++ b/src/windows/classes/sun/awt/windows/WFramePeer.java
@@ -25,27 +25,46 @@
package sun.awt.windows;
import java.util.Vector;
+
import java.awt.*;
import java.awt.peer.*;
import java.awt.image.ImageObserver;
-import sun.awt.image.ImageRepresentation;
-import sun.awt.image.IntegerComponentRaster;
-import sun.awt.image.ToolkitImage;
+
import java.awt.image.Raster;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.BufferedImage;
-import sun.awt.im.*;
-import sun.awt.Win32GraphicsDevice;
+
import java.awt.image.ColorModel;
+import sun.awt.image.ImageRepresentation;
+import sun.awt.image.IntegerComponentRaster;
+import sun.awt.image.ToolkitImage;
+import sun.awt.im.*;
+import sun.awt.Win32GraphicsDevice;
+import sun.awt.AWTAccessor;
class WFramePeer extends WWindowPeer implements FramePeer {
+ static {
+ initIDs();
+ }
+
+ // initialize JNI field and method IDs
+ private static native void initIDs();
+
// FramePeer implementation
public native void setState(int state);
public native int getState();
+ // sync target and peer
+ public void setExtendedState(int state) {
+ AWTAccessor.getFrameAccessor().setExtendedState((Frame)target, state);
+ }
+ public int getExtendedState() {
+ return AWTAccessor.getFrameAccessor().getExtendedState((Frame)target);
+ }
+
// Convenience methods to save us from trouble of extracting
// Rectangle fields in native code.
private native void setMaximizedBounds(int x, int y, int w, int h);
diff --git a/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java b/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java
new file mode 100644
index 000000000..892899603
--- /dev/null
+++ b/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java
@@ -0,0 +1,75 @@
+/*
+ * 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.windows;
+
+import java.awt.KeyboardFocusManager;
+import java.awt.Window;
+import java.awt.Component;
+import java.awt.peer.ComponentPeer;
+import sun.awt.KeyboardFocusManagerPeerImpl;
+import sun.awt.CausedFocusEvent;
+
+class WKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
+ static native void setNativeFocusOwner(ComponentPeer peer);
+ static native Component getNativeFocusOwner();
+ static native Window getNativeFocusedWindow();
+
+ WKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+ super(manager);
+ }
+
+ @Override
+ public void setCurrentFocusOwner(Component comp) {
+ setNativeFocusOwner(comp != null ? comp.getPeer() : null);
+ }
+
+ @Override
+ public Component getCurrentFocusOwner() {
+ return getNativeFocusOwner();
+ }
+
+ @Override
+ public Window getCurrentFocusedWindow() {
+ return getNativeFocusedWindow();
+ }
+
+ public static boolean deliverFocus(Component lightweightChild,
+ Component target,
+ boolean temporary,
+ boolean focusedWindowChangeAllowed,
+ long time,
+ CausedFocusEvent.Cause cause)
+ {
+ // TODO: do something to eliminate this forwarding
+ return KeyboardFocusManagerPeerImpl.deliverFocus(lightweightChild,
+ target,
+ temporary,
+ focusedWindowChangeAllowed,
+ time,
+ cause,
+ getNativeFocusOwner());
+ }
+}
diff --git a/src/windows/classes/sun/awt/windows/WPanelPeer.java b/src/windows/classes/sun/awt/windows/WPanelPeer.java
index 8a0d7ffbc..10ca42314 100644
--- a/src/windows/classes/sun/awt/windows/WPanelPeer.java
+++ b/src/windows/classes/sun/awt/windows/WPanelPeer.java
@@ -100,34 +100,6 @@ class WPanelPeer extends WCanvasPeer implements PanelPeer {
return getInsets();
}
- /*
- * From the DisplayChangedListener interface. Often is
- * up-called from a WWindowPeer instance.
- */
- public void displayChanged() {
- super.displayChanged();
- displayChanged((Container)target);
- }
-
- /*
- * Recursively iterates through all the HW and LW children
- * of the container and calls displayChanged() for HW peers.
- * Iteration through children peers only is not enough as the
- * displayChanged notification may not be propagated to HW
- * components inside LW containers, see 4452373 for details.
- */
- private static void displayChanged(Container target) {
- Component children[] = ((Container)target).getComponents();
- for (Component child : children) {
- ComponentPeer cpeer = child.getPeer();
- if (cpeer instanceof WComponentPeer) {
- ((WComponentPeer)cpeer).displayChanged();
- } else if (child instanceof Container) {
- displayChanged((Container)child);
- }
- }
- }
-
private native void pRestack(Object[] peers);
private void restack(Container cont, Vector peers) {
for (int i = 0; i < cont.getComponentCount(); i++) {
diff --git a/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java b/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java
index c1e06f53c..90ca88279 100644
--- a/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java
+++ b/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -143,17 +143,9 @@ public class WPrintDialogPeer extends WWindowPeer implements DialogPeer {
*/
private static native void initIDs();
- /**
- * WPrintDialogPeer doesn't have native pData so we don't do restack on it
- * @see java.awt.peer.ContainerPeer#restack
- */
- public void restack() {
- }
-
- /**
- * @see java.awt.peer.ContainerPeer#isRestackSupported
- */
- public boolean isRestackSupported() {
- return false;
- }
+ // The effects are not supported for system dialogs.
+ public void applyShape(sun.java2d.pipe.Region shape) {}
+ public void setOpacity(float opacity) {}
+ public void setOpaque(boolean isOpaque) {}
+ public void updateWindow(java.awt.image.BufferedImage backBuffer) {}
}
diff --git a/src/windows/classes/sun/awt/windows/WScrollPanePeer.java b/src/windows/classes/sun/awt/windows/WScrollPanePeer.java
index 70b3725cf..2e8c5e60b 100644
--- a/src/windows/classes/sun/awt/windows/WScrollPanePeer.java
+++ b/src/windows/classes/sun/awt/windows/WScrollPanePeer.java
@@ -269,10 +269,4 @@ class WScrollPanePeer extends WPanelPeer implements ScrollPanePeer {
}
}
- /**
- * @see java.awt.peer.ContainerPeer#restack
- */
- public void restack() {
- // Since ScrollPane can only have one child its restacking does nothing.
- }
}
diff --git a/src/windows/classes/sun/awt/windows/WToolkit.java b/src/windows/classes/sun/awt/windows/WToolkit.java
index 55c1dde09..62011b9b8 100644
--- a/src/windows/classes/sun/awt/windows/WToolkit.java
+++ b/src/windows/classes/sun/awt/windows/WToolkit.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -494,6 +494,12 @@ public class WToolkit extends SunToolkit implements Runnable {
return true;
}
+ public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
+ throws HeadlessException
+ {
+ return new WKeyboardFocusManagerPeer(manager);
+ }
+
protected native void setDynamicLayoutNative(boolean b);
public void setDynamicLayout(boolean b) {
@@ -975,4 +981,34 @@ public class WToolkit extends SunToolkit implements Runnable {
public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
return areExtraMouseButtonsEnabled;
}
+
+ @Override
+ public boolean isWindowOpacitySupported() {
+ // supported in Win2K and later
+ return true;
+ }
+
+ @Override
+ public boolean isWindowShapingSupported() {
+ return true;
+ }
+
+ @Override
+ public boolean isWindowTranslucencySupported() {
+ // supported in Win2K and later
+ return true;
+ }
+
+ @Override
+ public boolean isTranslucencyCapable(GraphicsConfiguration gc) {
+ //XXX: worth checking if 8-bit? Anyway, it doesn't hurt.
+ return true;
+ }
+
+ // On MS Windows one must use the peer.updateWindow() to implement
+ // non-opaque windows.
+ @Override
+ public boolean needUpdateWindow() {
+ return true;
+ }
}
diff --git a/src/windows/classes/sun/awt/windows/WWindowPeer.java b/src/windows/classes/sun/awt/windows/WWindowPeer.java
index 6afdb2be6..3c6240209 100644
--- a/src/windows/classes/sun/awt/windows/WWindowPeer.java
+++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,19 +31,19 @@ import java.awt.peer.*;
import java.beans.*;
-import java.lang.ref.*;
import java.lang.reflect.*;
-import java.security.*;
-
import java.util.*;
import java.util.List;
import java.util.logging.*;
import sun.awt.*;
-import sun.awt.image.*;
-public class WWindowPeer extends WPanelPeer implements WindowPeer {
+import sun.java2d.pipe.Region;
+
+public class WWindowPeer extends WPanelPeer implements WindowPeer,
+ DisplayChangedListener
+{
private static final Logger log = Logger.getLogger("sun.awt.windows.WWindowPeer");
private static final Logger screenLog = Logger.getLogger("sun.awt.windows.screen.WWindowPeer");
@@ -52,6 +52,10 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
// extends WWindowPeer, not WDialogPeer
private WWindowPeer modalBlocker = null;
+ private boolean isOpaque;
+
+ private volatile TranslucentWindowPainter painter;
+
/*
* A key used for storing a list of active windows in AppContext. The value
* is a list of windows, sorted by the time of activation: later a window is
@@ -73,6 +77,12 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
private final static PropertyChangeListener guiDisposedListener =
new GuiDisposedListener();
+ /*
+ * Called (on the Toolkit thread) before the appropriate
+ * WindowStateEvent is posted to the EventQueue.
+ */
+ private WindowListener windowListener;
+
/**
* Initialize JNI field IDs
*/
@@ -91,9 +101,18 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
l.remove(this);
}
}
+
// Remove ourself from the Map of DisplayChangeListeners
GraphicsConfiguration gc = getGraphicsConfiguration();
((Win32GraphicsDevice)gc.getDevice()).removeDisplayChangedListener(this);
+
+ TranslucentWindowPainter currentPainter = painter;
+ if (currentPainter != null) {
+ currentPainter.flush();
+ // don't set the current one to null here; reduces the chances of
+ // MT issues (like NPEs)
+ }
+
super.disposeImpl();
}
@@ -158,6 +177,10 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
initActiveWindowsTracking((Window)target);
updateIconImages();
+
+ updateShape();
+ updateOpacity();
+ updateOpaque();
}
native void createAwtWindow(WComponentPeer parent);
@@ -183,7 +206,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
// super.displayChanged() in WWindowPeer.displayChanged() regardless of whether
// GraphicsDevice was really changed, or not. So we need to track it here.
updateGC();
- resetTargetGC();
realShow();
updateMinimumSize();
@@ -191,6 +213,8 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
if (((Window)target).isAlwaysOnTopSupported() && alwaysOnTop) {
setAlwaysOnTop(alwaysOnTop);
}
+
+ updateWindow(null);
}
// Synchronize the insets members (here & in helper) with actual window
@@ -214,27 +238,64 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
int[] smallIconRaster, int smw, int smh);
synchronized native void reshapeFrame(int x, int y, int width, int height);
- public boolean requestWindowFocus() {
- // Win32 window doesn't need this
- return false;
+
+ public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
+ if (!focusAllowedFor()) {
+ return false;
+ }
+ return requestWindowFocus(cause == CausedFocusEvent.Cause.MOUSE_EVENT);
}
+ public native boolean requestWindowFocus(boolean isMouseEventCause);
public boolean focusAllowedFor() {
- Window target = (Window)this.target;
- if (!target.isVisible() ||
- !target.isEnabled() ||
- !target.isFocusable())
+ Window window = (Window)this.target;
+ if (!window.isVisible() ||
+ !window.isEnabled() ||
+ !window.isFocusableWindow())
{
return false;
}
-
if (isModalBlocked()) {
return false;
}
-
return true;
}
+ public void hide() {
+ WindowListener listener = windowListener;
+ if (listener != null) {
+ // We're not getting WINDOW_CLOSING from the native code when hiding
+ // the window programmatically. So, create it and notify the listener.
+ listener.windowClosing(new WindowEvent((Window)target, WindowEvent.WINDOW_CLOSING));
+ }
+ super.hide();
+ }
+
+ // WARNING: it's called on the Toolkit thread!
+ void preprocessPostEvent(AWTEvent event) {
+ if (event instanceof WindowEvent) {
+ WindowListener listener = windowListener;
+ if (listener != null) {
+ switch(event.getID()) {
+ case WindowEvent.WINDOW_CLOSING:
+ listener.windowClosing((WindowEvent)event);
+ break;
+ case WindowEvent.WINDOW_ICONIFIED:
+ listener.windowIconified((WindowEvent)event);
+ break;
+ }
+ }
+ }
+ }
+
+ synchronized void addWindowListener(WindowListener l) {
+ windowListener = AWTEventMulticaster.add(windowListener, l);
+ }
+
+ synchronized void removeWindowListener(WindowListener l) {
+ windowListener = AWTEventMulticaster.remove(windowListener, l);
+ }
+
public void updateMinimumSize() {
Dimension minimumSize = null;
if (((Component)target).isMinimumSizeSet()) {
@@ -273,6 +334,31 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
}
}
+ private void updateShape() {
+ // Shape shape = ((Window)target).getShape();
+ Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+ if (shape != null) {
+ applyShape(Region.getInstance(shape, null));
+ }
+ }
+
+ private void updateOpacity() {
+ // float opacity = ((Window)target).getOpacity();
+ float opacity = AWTAccessor.getWindowAccessor().getOpacity((Window)target);
+ if (opacity < 1.0f) {
+ setOpacity(opacity);
+ }
+ }
+
+ private void updateOpaque() {
+ this.isOpaque = true;
+ // boolean opaque = ((Window)target).isOpaque();
+ boolean opaque = AWTAccessor.getWindowAccessor().isOpaque((Window)target);
+ if (!opaque) {
+ setOpaque(opaque);
+ }
+ }
+
native void setMinSize(int width, int height);
/*
@@ -358,14 +444,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
});
}
-
- /*
- * Called from WCanvasPeer.displayChanged().
- * Override to do nothing - Window and WWindowPeer GC must never be set to
- * null!
- */
- void clearLocalGC() {}
-
public void updateGC() {
int scrn = getScreenImOn();
if (screenLog.isLoggable(Level.FINER)) {
@@ -404,18 +482,36 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
oldDev.removeDisplayChangedListener(this);
newDev.addDisplayChangedListener(this);
}
+
+ SunToolkit.executeOnEventHandlerThread((Component)target,
+ new Runnable() {
+ public void run() {
+ AWTAccessor.getComponentAccessor().
+ setGraphicsConfiguration((Component)target, winGraphicsConfig);
+ }
+ });
}
- /*
- * From the DisplayChangedListener interface
+ /**
+ * From the DisplayChangedListener interface.
*
* This method handles a display change - either when the display settings
* are changed, or when the window has been dragged onto a different
* display.
+ * Called after a change in the display mode. This event
+ * triggers replacing the surfaceData object (since that object
+ * reflects the current display depth information, which has
+ * just changed).
*/
public void displayChanged() {
updateGC();
- super.displayChanged();
+ }
+
+ /**
+ * Part of the DisplayChangedListener interface: components
+ * do not need to react to this event
+ */
+ public void paletteChanged() {
}
private native int getScreenImOn();
@@ -451,8 +547,10 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
private volatile int sysH = 0;
Rectangle constrainBounds(int x, int y, int width, int height) {
+ GraphicsConfiguration gc = this.winGraphicsConfig;
+
// We don't restrict the setBounds() operation if the code is trusted.
- if (!hasWarningWindow()) {
+ if (!hasWarningWindow() || gc == null) {
return new Rectangle(x, y, width, height);
}
@@ -461,24 +559,24 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
int newW = width;
int newH = height;
- GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
Rectangle sB = gc.getBounds();
- Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
+ Insets sIn = Toolkit.getDefaultToolkit().getScreenInsets(gc);
int screenW = sB.width - sIn.left - sIn.right;
int screenH = sB.height - sIn.top - sIn.bottom;
// If it's undecorated or is not currently visible
- if (!((Window)target).isVisible() || isTargetUndecorated()) {
+ if (!AWTAccessor.getComponentAccessor().isVisible_NoClientCode(
+ (Component)target) || isTargetUndecorated())
+ {
// Now check each point is within the visible part of the screen
int screenX = sB.x + sIn.left;
int screenY = sB.y + sIn.top;
- // First make sure the size is withing the visible part of the screen
+ // First make sure the size is within the visible part of the screen
if (newW > screenW) {
newW = screenW;
}
-
if (newH > screenH) {
newH = screenH;
}
@@ -489,7 +587,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
} else if (newX + newW > screenX + screenW) {
newX = screenX + screenW - newW;
}
-
if (newY < screenY) {
newY = screenY;
} else if (newY + newH > screenY + screenH) {
@@ -504,7 +601,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
if (newW > maxW) {
newW = maxW;
}
-
if (newH > maxH) {
newH = maxH;
}
@@ -513,6 +609,8 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
return new Rectangle(newX, newY, newW, newH);
}
+ public native void repositionSecurityWarning();
+
@Override
public void setBounds(int x, int y, int width, int height, int op) {
Rectangle newBounds = constrainBounds(x, y, width, height);
@@ -525,6 +623,135 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
}
+ @Override
+ public void print(Graphics g) {
+ // We assume we print the whole frame,
+ // so we expect no clip was set previously
+ Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+ if (shape != null) {
+ g.setClip(shape);
+ }
+ super.print(g);
+ }
+
+ private void replaceSurfaceDataRecursively(Component c) {
+ if (c instanceof Container) {
+ for (Component child : ((Container)c).getComponents()) {
+ replaceSurfaceDataRecursively(child);
+ }
+ }
+ ComponentPeer cp = c.getPeer();
+ if (cp instanceof WComponentPeer) {
+ ((WComponentPeer)cp).replaceSurfaceDataLater();
+ }
+ }
+
+ private native void setOpacity(int iOpacity);
+
+ public void setOpacity(float opacity) {
+ if (!((SunToolkit)((Window)target).getToolkit()).
+ isWindowOpacitySupported())
+ {
+ return;
+ }
+
+ replaceSurfaceDataRecursively((Component)getTarget());
+
+ final int maxOpacity = 0xff;
+ int iOpacity = (int)(opacity * maxOpacity);
+ if (iOpacity < 0) {
+ iOpacity = 0;
+ }
+ if (iOpacity > maxOpacity) {
+ iOpacity = maxOpacity;
+ }
+
+ setOpacity(iOpacity);
+ updateWindow(null);
+ }
+
+ private native void setOpaqueImpl(boolean isOpaque);
+
+ public void setOpaque(boolean isOpaque) {
+ Window target = (Window)getTarget();
+
+ SunToolkit sunToolkit = (SunToolkit)target.getToolkit();
+ if (!sunToolkit.isWindowTranslucencySupported() ||
+ !sunToolkit.isTranslucencyCapable(target.getGraphicsConfiguration()))
+ {
+ return;
+ }
+
+ boolean opaqueChanged = this.isOpaque != isOpaque;
+ boolean isVistaOS = Win32GraphicsEnvironment.isVistaOS();
+
+ if (opaqueChanged && !isVistaOS){
+ // non-Vista OS: only replace the surface data if the opacity
+ // status changed (see WComponentPeer.isAccelCapable() for more)
+ replaceSurfaceDataRecursively(target);
+ }
+
+ this.isOpaque = isOpaque;
+
+ setOpaqueImpl(isOpaque);
+
+ if (opaqueChanged) {
+ if (isOpaque) {
+ TranslucentWindowPainter currentPainter = painter;
+ if (currentPainter != null) {
+ currentPainter.flush();
+ painter = null;
+ }
+ } else {
+ painter = TranslucentWindowPainter.createInstance(this);
+ }
+ }
+
+ if (opaqueChanged && isVistaOS) {
+ // On Vista: setting the window non-opaque makes the window look
+ // rectangular, though still catching the mouse clicks within
+ // its shape only. To restore the correct visual appearance
+ // of the window (i.e. w/ the correct shape) we have to reset
+ // the shape.
+ Shape shape = AWTAccessor.getWindowAccessor().getShape(target);
+ if (shape != null) {
+ AWTAccessor.getWindowAccessor().setShape(target, shape);
+ }
+ }
+
+ updateWindow(null);
+ }
+
+ public native void updateWindowImpl(int[] data, int width, int height);
+
+ public void updateWindow(BufferedImage backBuffer) {
+ if (isOpaque) {
+ return;
+ }
+
+ TranslucentWindowPainter currentPainter = painter;
+ if (currentPainter != null) {
+ currentPainter.updateWindow(backBuffer);
+ } else if (log.isLoggable(Level.FINER)) {
+ log.log(Level.FINER,
+ "Translucent window painter is null in updateWindow");
+ }
+ }
+
+ /**
+ * Paints the Applet Warning into the passed Graphics2D. This method is
+ * called by the TranslucentWindowPainter before updating the layered
+ * window.
+ *
+ * @param g Graphics context to paint the warning to
+ * @param w the width of the area
+ * @param h the height of the area
+ * @see TranslucentWindowPainter
+ */
+ public void paintAppletWarning(Graphics2D g, int w, int h) {
+ // REMIND: the applet warning needs to be painted here
+ }
+
/*
* The method maps the list of the active windows to the window's AppContext,
* then the method registers ActiveWindowListener, GuiDisposedListener listeners;
diff --git a/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java b/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java
index b3b0fa8d5..53ae895dd 100644
--- a/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java
+++ b/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@ import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import sun.awt.SunToolkit;
+import sun.awt.AWTAccessor;
import sun.awt.Win32GraphicsConfig;
import sun.awt.windows.WComponentPeer;
import sun.java2d.InvalidPipeException;
@@ -284,14 +285,12 @@ public class D3DScreenUpdateManager extends ScreenUpdateManager
* @param peer for which target's the repaint should be issued
*/
private void repaintPeerTarget(WComponentPeer peer) {
- // we don't want to call user code on our priveleged
- // thread, delegate to EDT
- final Component target = (Component)peer.getTarget();
- SunToolkit.executeOnEventHandlerThread(target, new Runnable() {
- public void run() {
- target.repaint();
- }
- });
+ Component target = (Component)peer.getTarget();
+ Rectangle bounds = AWTAccessor.getComponentAccessor().getBounds(target);
+ // the system-level painting operations should call the handlePaint()
+ // method of the WComponentPeer class to repaint the component;
+ // calling repaint() forces AWT to make call to update()
+ peer.handlePaint(0, 0, bounds.width, bounds.height);
}
/**
diff --git a/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java b/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java
index 27997aa8c..4164264a1 100644
--- a/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java
+++ b/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2004-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -72,9 +72,8 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
// the OGL pipeline can render directly to the screen and interfere
// with layered windows, which is why we don't allow accelerated
// surfaces in this case
- if (!peer.isAccelCapable())
- // REMIND: commented until toplevel translucency is implemented
-// || !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
+ if (!peer.isAccelCapable() ||
+ !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
{
return null;
}
@@ -93,9 +92,8 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
// the OGL pipeline can render directly to the screen and interfere
// with layered windows, which is why we don't allow accelerated
// surfaces in this case
- if (!peer.isAccelCapable())
- // REMIND: commented until toplevel translucency is implemented
-// || !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
+ if (!peer.isAccelCapable() ||
+ !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
{
return null;
}
diff --git a/src/windows/native/sun/awt/utility/rect.h b/src/windows/native/sun/awt/utility/rect.h
index bc250e2ac..a8e9fc28b 100644
--- a/src/windows/native/sun/awt/utility/rect.h
+++ b/src/windows/native/sun/awt/utility/rect.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,5 +43,15 @@ typedef RECT RECT_T;
#define RECT_INC_HEIGHT(r) (r).bottom++
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int BitmapToYXBandedRectangles(int bitsPerPixel, int width, int height,
+ unsigned char * buf, RECT_T * outBuf);
+
+#if defined(__cplusplus)
+}
+#endif
#endif // _AWT_RECT_H
diff --git a/src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp b/src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp
index 9c865dc97..c6d4bb1b3 100644
--- a/src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp
+++ b/src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -613,17 +613,15 @@ JNICALL Java_sun_java2d_d3d_D3DSurfaceData_updateWindowAccelImpl
res = pTmpSurface->LockRect(&lockedRect, NULL, D3DLOCK_NOSYSLOCK);
if (SUCCEEDED(res)) {
- // REMIND: commented until translucent window support is integrated
-// hBitmap =
-// BitmapUtil::CreateBitmapFromARGBPre(w, h,
-// lockedRect.Pitch,
-// (int*)lockedRect.pBits);
+ hBitmap =
+ BitmapUtil::CreateBitmapFromARGBPre(w, h,
+ lockedRect.Pitch,
+ (int*)lockedRect.pBits);
pTmpSurface->UnlockRect();
}
RETURN_STATUS_IF_NULL(hBitmap, JNI_FALSE);
- // REMIND: commented until translucent window support is integrated
-// window->UpdateWindow(env, NULL, w, h, hBitmap);
+ window->UpdateWindow(env, NULL, w, h, hBitmap);
// hBitmap is released in UpdateWindow
diff --git a/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c b/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c
index 71d5e8764..3c3e09cec 100644
--- a/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c
+++ b/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2004-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -625,17 +625,15 @@ JNIEXPORT jboolean JNICALL
j2d_glPixelStorei(GL_PACK_ALIGNMENT, 4);
// the pixels read from the surface are already premultiplied
- // REMIND: commented until translucent window support is integrated
-// hBitmap = BitmapUtil_CreateBitmapFromARGBPre(w, h, scanStride,
-// (int*)pDst);
+ hBitmap = BitmapUtil_CreateBitmapFromARGBPre(w, h, scanStride,
+ (int*)pDst);
free(pDst);
if (hBitmap == NULL) {
return JNI_FALSE;
}
- // REMIND: commented until translucent window support is integrated
- // AwtWindow_UpdateWindow(env, peer, w, h, hBitmap);
+ AwtWindow_UpdateWindow(env, peer, w, h, hBitmap);
// hBitmap is released in UpdateWindow
diff --git a/src/windows/native/sun/windows/ComCtl32Util.cpp b/src/windows/native/sun/windows/ComCtl32Util.cpp
index ac69cf3af..8ac9d764a 100644
--- a/src/windows/native/sun/windows/ComCtl32Util.cpp
+++ b/src/windows/native/sun/windows/ComCtl32Util.cpp
@@ -27,6 +27,7 @@
#include "ComCtl32Util.h"
ComCtl32Util::ComCtl32Util() {
+ m_bToolTipControlInitialized = FALSE;
}
ComCtl32Util::~ComCtl32Util() {
@@ -36,7 +37,8 @@ void ComCtl32Util::InitLibraries() {
INITCOMMONCONTROLSEX iccex;
memset(&iccex, 0, sizeof(INITCOMMONCONTROLSEX));
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
- ::InitCommonControlsEx(&iccex);
+ iccex.dwICC = ICC_TAB_CLASSES;
+ m_bToolTipControlInitialized = ::InitCommonControlsEx(&iccex);
}
WNDPROC ComCtl32Util::SubclassHWND(HWND hwnd, WNDPROC _WindowProc) {
diff --git a/src/windows/native/sun/windows/ComCtl32Util.h b/src/windows/native/sun/windows/ComCtl32Util.h
index e137b43d0..642667709 100644
--- a/src/windows/native/sun/windows/ComCtl32Util.h
+++ b/src/windows/native/sun/windows/ComCtl32Util.h
@@ -40,6 +40,10 @@ class ComCtl32Util
void InitLibraries();
+ INLINE BOOL IsToolTipControlInitialized() {
+ return m_bToolTipControlInitialized;
+ }
+
WNDPROC SubclassHWND(HWND hwnd, WNDPROC _WindowProc);
// DefWindowProc is the same as returned from SubclassHWND
void UnsubclassHWND(HWND hwnd, WNDPROC _WindowProc, WNDPROC _DefWindowProc);
@@ -50,6 +54,8 @@ class ComCtl32Util
ComCtl32Util();
~ComCtl32Util();
+ BOOL m_bToolTipControlInitialized;
+
// comctl32.dll version 6 window proc
static LRESULT CALLBACK SharedWindowProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam,
diff --git a/src/windows/native/sun/windows/DllUtil.cpp b/src/windows/native/sun/windows/DllUtil.cpp
new file mode 100644
index 000000000..0c7077144
--- /dev/null
+++ b/src/windows/native/sun/windows/DllUtil.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+
+#include "DllUtil.h"
+
+// Disable warning about using this in the initializer list.
+#pragma warning( disable : 4355)
+
+DllUtil::~DllUtil()
+{
+ if (module != NULL) {
+ ::FreeLibrary(module);
+ module = NULL;
+ }
+}
+
+HMODULE DllUtil::GetModule()
+{
+ if (!module) {
+ module = ::LoadLibrary(name);
+ }
+ return module;
+}
+
+FARPROC DllUtil::GetProcAddress(LPCSTR name)
+{
+ if (GetModule()) {
+ return ::GetProcAddress(GetModule(), name);
+ }
+ throw LibraryUnavailableException();
+}
+
+DwmAPI & DwmAPI::GetInstance()
+{
+ static DwmAPI dll;
+ return dll;
+}
+
+DwmAPI::DwmAPI() :
+ DllUtil(_T("DWMAPI.DLL")),
+ DwmIsCompositionEnabledFunction((DllUtil*)this, "DwmIsCompositionEnabled"),
+ DwmGetWindowAttributeFunction((DllUtil*)this, "DwmGetWindowAttribute")
+{
+}
+
+HRESULT DwmAPI::DwmIsCompositionEnabled(BOOL * pfEnabled)
+{
+ if (GetInstance().DwmIsCompositionEnabledFunction()) {
+ return GetInstance().DwmIsCompositionEnabledFunction()(pfEnabled);
+ }
+ throw FunctionUnavailableException();
+}
+
+HRESULT DwmAPI::DwmGetWindowAttribute(HWND hwnd, DWORD dwAttribute,
+ PVOID pvAttribute, DWORD cbAttribute)
+{
+ if (GetInstance().DwmGetWindowAttributeFunction()) {
+ return GetInstance().DwmGetWindowAttributeFunction()(hwnd, dwAttribute,
+ pvAttribute, cbAttribute);
+ }
+ throw FunctionUnavailableException();
+}
+
+
diff --git a/src/windows/native/sun/windows/DllUtil.h b/src/windows/native/sun/windows/DllUtil.h
new file mode 100644
index 000000000..307d93d2b
--- /dev/null
+++ b/src/windows/native/sun/windows/DllUtil.h
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+#ifndef DLLUTIL_H
+#define DLLUTIL_H
+
+#include <tchar.h>
+#include <windows.h>
+
+/**
+ * Utility class to handle dynamically loadable libraries.
+ *
+ * NOTE: THIS CLASS IS NOT THREAD-SAFE!
+ */
+class DllUtil {
+ public:
+ class Exception {};
+ class LibraryUnavailableException : public Exception {};
+ class FunctionUnavailableException : public Exception {};
+
+ FARPROC GetProcAddress(LPCSTR name);
+
+ protected:
+ DllUtil(const TCHAR * name) : name(name), module(NULL) {}
+ virtual ~DllUtil();
+
+ HMODULE GetModule();
+
+ template <class FunctionType> class Function {
+ public:
+ Function(DllUtil * dll, LPCSTR name) :
+ dll(dll), name(name), function(NULL) {}
+
+ inline FunctionType operator () () {
+ if (!function) {
+ function = (FunctionType)dll->GetProcAddress(name);
+ }
+ return function;
+ }
+
+ private:
+ DllUtil * const dll;
+ LPCSTR name;
+
+ FunctionType function;
+ };
+
+ private:
+ const TCHAR * const name;
+ HMODULE module;
+};
+
+class DwmAPI : public DllUtil {
+ public:
+ // See DWMWINDOWATTRIBUTE enum in dwmapi.h
+ static const DWORD DWMWA_EXTENDED_FRAME_BOUNDS = 9;
+
+ static HRESULT DwmIsCompositionEnabled(BOOL * pfEnabled);
+ static HRESULT DwmGetWindowAttribute(HWND hwnd, DWORD dwAttribute,
+ PVOID pvAttribute, DWORD cbAttribute);
+
+ private:
+ static DwmAPI & GetInstance();
+ DwmAPI();
+
+ typedef HRESULT (WINAPI *DwmIsCompositionEnabledType)(BOOL*);
+ Function<DwmIsCompositionEnabledType> DwmIsCompositionEnabledFunction;
+
+ typedef HRESULT (WINAPI *DwmGetWindowAttributeType)(HWND hwnd, DWORD dwAttribute,
+ PVOID pvAttribute, DWORD cbAttribute);
+ Function<DwmGetWindowAttributeType> DwmGetWindowAttributeFunction;
+};
+
+#endif // DLLUTIL_H
+
diff --git a/src/windows/native/sun/windows/awt.rc b/src/windows/native/sun/windows/awt.rc
index c9c3f1721..7eb4d41af 100644
--- a/src/windows/native/sun/windows/awt.rc
+++ b/src/windows/native/sun/windows/awt.rc
@@ -35,6 +35,13 @@ HAND_CURSOR CURSOR DISCARDABLE "hand.cur"
AWT_ICON ICON DISCARDABLE "awt.ico"
CHECK_BITMAP BITMAP DISCARDABLE "check.bmp"
+// Note: the number of icons used is specified in the
+// securityWarningIconCounter constant in awt_Toolkit.cpp.
+SECURITY_WARNING_0 ICON DISCARDABLE "security_warning_bw.ico"
+SECURITY_WARNING_1 ICON DISCARDABLE "security_warning_int.ico"
+SECURITY_WARNING_2 ICON DISCARDABLE "security_warning.ico"
+
+
/////////////////////////////////////////////////////////////////////////////
//
// Version
diff --git a/src/windows/native/sun/windows/awt_BitmapUtil.cpp b/src/windows/native/sun/windows/awt_BitmapUtil.cpp
index 64c52e2f8..10e71b3e6 100644
--- a/src/windows/native/sun/windows/awt_BitmapUtil.cpp
+++ b/src/windows/native/sun/windows/awt_BitmapUtil.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2006-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,9 +28,14 @@
#include <windowsx.h>
#include <zmouse.h>
+#include "GraphicsPrimitiveMgr.h"
+
#include "awt.h"
#include "awt_BitmapUtil.h"
+// Platform-dependent RECT_[EQ | SET | INC_HEIGHT] macros
+#include "utility/rect.h"
+
HBITMAP BitmapUtil::CreateTransparencyMaskFromARGB(int width, int height, int* imageData)
{
//Scan lines should be aligned to word boundary
@@ -148,3 +153,222 @@ HBITMAP BitmapUtil::CreateV4BitmapFromARGB(int width, int height, int* imageData
::GdiFlush();
return hBitmap;
}
+
+/*
+ * Creates 32-bit premultiplied ARGB bitmap from specified ARGBPre data.
+ * This function may not work on OS prior to Win95.
+ * See MSDN articles for CreateDIBitmap, BITMAPINFOHEADER,
+ * BITMAPV4HEADER, BITMAPV5HEADER for additional info.
+ */
+HBITMAP BitmapUtil::CreateBitmapFromARGBPre(int width, int height,
+ int srcStride,
+ int* imageData)
+{
+ BITMAPINFOHEADER bmi;
+ void *bitmapBits = NULL;
+
+ ZeroMemory(&bmi, sizeof(bmi));
+ bmi.biSize = sizeof(bmi);
+ bmi.biWidth = width;
+ bmi.biHeight = -height;
+ bmi.biPlanes = 1;
+ bmi.biBitCount = 32;
+ bmi.biCompression = BI_RGB;
+
+ HBITMAP hBitmap =
+ ::CreateDIBSection(NULL, (BITMAPINFO *) & bmi, DIB_RGB_COLORS,
+ &bitmapBits, NULL, 0);
+
+ if (!bitmapBits) {
+ return NULL;
+ }
+
+ int dstStride = width * 4;
+
+ if (srcStride == dstStride) {
+ memcpy(bitmapBits, (void*)imageData, srcStride * height);
+ } else if (height > 0) {
+ void *pSrcPixels = (void*)imageData;
+ void *pDstPixels = bitmapBits;
+ do {
+ memcpy(pDstPixels, pSrcPixels, dstStride);
+ pSrcPixels = PtrAddBytes(pSrcPixels, srcStride);
+ pDstPixels = PtrAddBytes(pDstPixels, dstStride);
+ } while (--height > 0);
+ }
+
+ return hBitmap;
+}
+
+extern "C" {
+
+/**
+ * This method is called from the WGL pipeline when it needs to create a bitmap
+ * needed to update the layered window.
+ */
+HBITMAP BitmapUtil_CreateBitmapFromARGBPre(int width, int height,
+ int srcStride,
+ int* imageData)
+{
+ return BitmapUtil::CreateBitmapFromARGBPre(width, height,
+ srcStride, imageData);
+
+}
+
+} /* extern "C" */
+
+
+/**
+ * Transforms the given bitmap into an HRGN representing the transparency
+ * of the bitmap. The bitmap MUST BE 32bpp. Alpha value == 0 is considered
+ * transparent, alpha > 0 - opaque.
+ */
+HRGN BitmapUtil::BitmapToRgn(HBITMAP hBitmap)
+{
+ HDC hdc = ::CreateCompatibleDC(NULL);
+ ::SelectObject(hdc, hBitmap);
+
+ BITMAPINFOEX bi;
+ ::ZeroMemory(&bi, sizeof(bi));
+
+ bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+
+ BOOL r = ::GetDIBits(hdc, hBitmap, 0, 0, NULL,
+ reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS);
+
+ if (!r || bi.bmiHeader.biBitCount != 32)
+ {
+ ::DeleteDC(hdc);
+ return NULL;
+ }
+
+ UINT width = bi.bmiHeader.biWidth;
+ UINT height = abs(bi.bmiHeader.biHeight);
+
+ BYTE * buf = (BYTE*)safe_Malloc(bi.bmiHeader.biSizeImage);
+ bi.bmiHeader.biHeight = -height;
+ ::GetDIBits(hdc, hBitmap, 0, height, buf,
+ reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS);
+
+ /* reserving memory for the worst case */
+ RGNDATA * pRgnData = (RGNDATA *) safe_Malloc(sizeof(RGNDATAHEADER) +
+ sizeof(RECT) * (width / 2 + 1) * height);
+ RGNDATAHEADER * pRgnHdr = (RGNDATAHEADER *) pRgnData;
+ pRgnHdr->dwSize = sizeof(RGNDATAHEADER);
+ pRgnHdr->iType = RDH_RECTANGLES;
+ pRgnHdr->nRgnSize = 0;
+ pRgnHdr->rcBound.top = 0;
+ pRgnHdr->rcBound.left = 0;
+ pRgnHdr->rcBound.bottom = height;
+ pRgnHdr->rcBound.right = width;
+
+ pRgnHdr->nCount = BitmapToYXBandedRectangles(32, width, height, buf,
+ (RECT_T *) (((BYTE *) pRgnData) + sizeof(RGNDATAHEADER)));
+
+ HRGN rgn = ::ExtCreateRegion(NULL,
+ sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount,
+ pRgnData);
+
+ free(pRgnData);
+ ::DeleteDC(hdc);
+ free(buf);
+
+ return rgn;
+}
+
+/**
+ * Makes a copy of the given bitmap. Blends every pixel of the source
+ * with the given blendColor and alpha. If alpha == 0, the function
+ * simply makes a plain copy of the source without any blending.
+ */
+HBITMAP BitmapUtil::BlendCopy(HBITMAP hSrcBitmap, COLORREF blendColor,
+ BYTE alpha)
+{
+ HDC hdc = ::CreateCompatibleDC(NULL);
+ HBITMAP oldBitmap = (HBITMAP)::SelectObject(hdc, hSrcBitmap);
+
+ BITMAPINFOEX bi;
+ ::ZeroMemory(&bi, sizeof(bi));
+
+ bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+
+ BOOL r = ::GetDIBits(hdc, hSrcBitmap, 0, 0, NULL,
+ reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS);
+
+ if (!r || bi.bmiHeader.biBitCount != 32)
+ {
+ ::DeleteDC(hdc);
+ return NULL;
+ }
+
+ UINT width = bi.bmiHeader.biWidth;
+ UINT height = abs(bi.bmiHeader.biHeight);
+
+ BYTE * buf = (BYTE*)safe_Malloc(bi.bmiHeader.biSizeImage);
+ bi.bmiHeader.biHeight = -height;
+ ::GetDIBits(hdc, hSrcBitmap, 0, height, buf,
+ reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS);
+
+ UINT widthBytes = width * bi.bmiHeader.biBitCount / 8;
+ UINT alignedWidth = (((widthBytes - 1) / 4) + 1) * 4;
+ UINT i, j;
+
+ for (j = 0; j < height; j++) {
+ BYTE *pSrc = (BYTE *) buf + j * alignedWidth;
+ for (i = 0; i < width; i++, pSrc += 4) {
+ // Note: if the current alpha is zero, the other three color
+ // components may (theoretically) contain some uninitialized
+ // data. The developer does not expect to display them,
+ // hence we handle this situation differently.
+ if (pSrc[3] == 0) {
+ pSrc[0] = GetBValue(blendColor) * alpha / 255;
+ pSrc[1] = GetGValue(blendColor) * alpha / 255;
+ pSrc[2] = GetRValue(blendColor) * alpha / 255;
+ pSrc[3] = alpha;
+ } else {
+ pSrc[0] = (GetBValue(blendColor) * alpha / 255) +
+ (pSrc[0] * (255 - alpha) / 255);
+ pSrc[1] = (GetGValue(blendColor) * alpha / 255) +
+ (pSrc[1] * (255 - alpha) / 255);
+ pSrc[2] = (GetRValue(blendColor) * alpha / 255) +
+ (pSrc[2] * (255 - alpha) / 255);
+ pSrc[3] = (alpha * alpha / 255) +
+ (pSrc[3] * (255 - alpha) / 255);
+ }
+ }
+ }
+
+ HBITMAP hDstBitmap = ::CreateDIBitmap(hdc,
+ reinterpret_cast<BITMAPINFOHEADER*>(&bi),
+ CBM_INIT,
+ buf,
+ reinterpret_cast<BITMAPINFO*>(&bi),
+ DIB_RGB_COLORS
+ );
+
+ ::SelectObject(hdc, oldBitmap);
+ ::DeleteDC(hdc);
+ free(buf);
+
+ return hDstBitmap;
+}
+
+/**
+ * Creates a 32 bit ARGB bitmap. Returns the bitmap handle. The *bitmapBits
+ * contains the pointer to the bitmap data or NULL if an error occured.
+ */
+HBITMAP BitmapUtil::CreateARGBBitmap(int width, int height, void ** bitmapBitsPtr)
+{
+ BITMAPINFOHEADER bmi;
+
+ ::ZeroMemory(&bmi, sizeof(bmi));
+ bmi.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.biWidth = width;
+ bmi.biHeight = -height;
+ bmi.biPlanes = 1;
+ bmi.biBitCount = 32;
+ bmi.biCompression = BI_RGB;
+
+ return ::CreateDIBSection(NULL, (BITMAPINFO *) & bmi, DIB_RGB_COLORS,
+ bitmapBitsPtr, NULL, 0);
+}
diff --git a/src/windows/native/sun/windows/awt_BitmapUtil.h b/src/windows/native/sun/windows/awt_BitmapUtil.h
index b32f3fe0a..2c039232f 100644
--- a/src/windows/native/sun/windows/awt_BitmapUtil.h
+++ b/src/windows/native/sun/windows/awt_BitmapUtil.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2006-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,32 @@ public:
*/
static HBITMAP CreateV4BitmapFromARGB(int width, int height, int* imageData);
+ /**
+ * Creates 32-bit premultiplied ARGB V4 Bitmap (Win95-compatible) from
+ * specified ARGB Pre input data.
+ */
+ static HBITMAP CreateBitmapFromARGBPre(int width, int height,
+ int srcStride,
+ int* imageData);
+
+ /**
+ * Transforms the given bitmap into an HRGN representing the transparency
+ * of the bitmap.
+ */
+ static HRGN BitmapToRgn(HBITMAP hBitmap);
+
+ /**
+ * Makes a copy of the given bitmap. Blends every pixel of the source
+ * with the given blendColor and alpha. If alpha == 0, the function
+ * simply makes a plain copy of the source without any blending.
+ */
+ static HBITMAP BlendCopy(HBITMAP hSrcBitmap, COLORREF blendColor, BYTE alpha);
+
+ /**
+ * Creates a 32 bit ARGB bitmap. Returns the bitmap handle.
+ * The pointer to the bitmap data is stored into bitmapBitsPtr.
+ */
+ static HBITMAP CreateARGBBitmap(int width, int height, void ** bitmapBitsPtr);
};
#endif
diff --git a/src/windows/native/sun/windows/awt_Button.cpp b/src/windows/native/sun/windows/awt_Button.cpp
index 3764655cb..2fb620fcd 100644
--- a/src/windows/native/sun/windows/awt_Button.cpp
+++ b/src/windows/native/sun/windows/awt_Button.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
#include "awt_Button.h"
#include "awt_Canvas.h"
#include "awt_Window.h"
-#include "awt_KeyboardFocusManager.h"
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
*/
@@ -143,19 +142,6 @@ done:
return c;
}
-BOOL AwtButton::ActMouseMessage(MSG * pMsg) {
- if (!IsFocusingMessage(pMsg->message)) {
- return FALSE;
- }
-
- if (pMsg->message == WM_LBUTTONDOWN) {
- SendMessage(BM_SETSTATE, TRUE, 0);
- } else if (pMsg->message == WM_LBUTTONUP) {
- SendMessage(BM_SETSTATE, FALSE, 0);
- }
- return TRUE;
-}
-
MsgRouting
AwtButton::WmMouseDown(UINT flags, int x, int y, int button)
{
@@ -204,23 +190,6 @@ AwtButton::NotifyListeners()
(jint)AwtComponent::GetJavaModifiers());
}
-/* 4531849 fix. Previous to 1.4, mouse clicks and typing space bar on a
- * Button would notify ActionListeners via WM_COMMAND/WmNotify(). In 1.4, mouse
- * grabs are done for all presses in order to correctly send drag and release
- * events. However, WM_COMMAND message aren't sent when the mouse is grabbed,
- * so ActionListeners for mouse clicks are sent via WmMouseUp/WmNotify().
- * For some reason, if the right mouse button is held down when left-clicking
- * on a Button, WM_COMMAND _IS_ sent. This resulted in two ActionEvents being
- * sent in this case. To fix the problem, we handle typing space bar similar to
- * left clicks - in WmKeyUp(), and do nothing for WM_COMMAND. -bchristi
- */
-MsgRouting
-AwtButton::WmKeyUp(UINT wkey, UINT repCnt, UINT flags, BOOL system)
-{
- MsgRouting mrResult = AwtComponent::WmKeyUp(wkey, repCnt, flags, system);
- return mrResult;
-}
-
MsgRouting
AwtButton::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo)
{
@@ -293,18 +262,26 @@ MsgRouting AwtButton::WmPaint(HDC)
return mrDoDefault;
}
+BOOL AwtButton::IsFocusingMouseMessage(MSG *pMsg) {
+ return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONUP;
+}
+
+BOOL AwtButton::IsFocusingKeyMessage(MSG *pMsg) {
+ return (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) &&
+ pMsg->wParam == VK_SPACE;
+}
+
MsgRouting AwtButton::HandleEvent(MSG *msg, BOOL synthetic)
{
- if (AwtComponent::sm_focusOwner != GetHWnd() &&
- (msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONDBLCLK))
- {
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject target = GetTarget(env);
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::heavyweightButtonDownMID,
- target, ((jlong)msg->time) & 0xFFFFFFFF);
- env->DeleteLocalRef(target);
+ if (IsFocusingMouseMessage(msg)) {
+ SendMessage(BM_SETSTATE, msg->message == WM_LBUTTONDOWN ? TRUE : FALSE, 0);
+ delete msg;
+ return mrConsume;
+ }
+ if (IsFocusingKeyMessage(msg)) {
+ SendMessage(BM_SETSTATE, msg->message == WM_KEYDOWN ? TRUE : FALSE, 0);
+ delete msg;
+ return mrConsume;
}
return AwtComponent::HandleEvent(msg, synthetic);
}
diff --git a/src/windows/native/sun/windows/awt_Button.h b/src/windows/native/sun/windows/awt_Button.h
index 795fbf9b5..5e6d2754a 100644
--- a/src/windows/native/sun/windows/awt_Button.h
+++ b/src/windows/native/sun/windows/awt_Button.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2004 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,13 +50,13 @@ public:
/* Windows message handler functions */
MsgRouting WmMouseDown(UINT flags, int x, int y, int button);
MsgRouting WmMouseUp(UINT flags, int x, int y, int button);
- MsgRouting WmKeyUp(UINT vkey, UINT repCnt, UINT flags, BOOL system);
MsgRouting OwnerDrawItem(UINT ctrlId, DRAWITEMSTRUCT& drawInfo);
MsgRouting WmPaint(HDC hDC);
MsgRouting HandleEvent(MSG *msg, BOOL synthetic);
- BOOL ActMouseMessage(MSG * pMsg);
+ BOOL IsFocusingMouseMessage(MSG *pMsg);
+ BOOL IsFocusingKeyMessage(MSG *pMsg);
// called on Toolkit thread from JNI
static void _SetLabel(void *param);
diff --git a/src/windows/native/sun/windows/awt_Canvas.cpp b/src/windows/native/sun/windows/awt_Canvas.cpp
index 4988152b8..b03a79817 100644
--- a/src/windows/native/sun/windows/awt_Canvas.cpp
+++ b/src/windows/native/sun/windows/awt_Canvas.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
#include "awt_Toolkit.h"
#include "awt_Canvas.h"
#include "awt_Win32GraphicsConfig.h"
-#include "awt_KeyboardFocusManager.h"
#include "awt_Window.h"
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
@@ -176,27 +175,9 @@ MsgRouting AwtCanvas::WmPaint(HDC)
MsgRouting AwtCanvas::HandleEvent(MSG *msg, BOOL synthetic)
{
- if (msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONDBLCLK) {
- /*
- * Fix for BugTraq ID 4041703: keyDown not being invoked.
- * Give the focus to a Canvas or Panel if it doesn't have heavyweight
- * subcomponents so that they will behave the same way as on Solaris
- * providing a possibility of giving keyboard focus to an empty Applet.
- * Since ScrollPane doesn't receive focus on mouse press on Solaris,
- * HandleEvent() is overriden there to do nothing with focus.
- */
- if (AwtComponent::sm_focusOwner != GetHWnd() &&
- ::GetWindow(GetHWnd(), GW_CHILD) == NULL)
- {
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject target = GetTarget(env);
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::heavyweightButtonDownMID,
- target, ((jlong)msg->time) & 0xFFFFFFFF);
- env->DeleteLocalRef(target);
- AwtSetFocus();
- }
+ if (IsFocusingMouseMessage(msg)) {
+ delete msg;
+ return mrConsume;
}
return AwtComponent::HandleEvent(msg, synthetic);
}
diff --git a/src/windows/native/sun/windows/awt_Checkbox.cpp b/src/windows/native/sun/windows/awt_Checkbox.cpp
index 2e8cf9923..2830e5681 100644
--- a/src/windows/native/sun/windows/awt_Checkbox.cpp
+++ b/src/windows/native/sun/windows/awt_Checkbox.cpp
@@ -26,7 +26,6 @@
#include "awt.h"
#include "awt_Toolkit.h"
#include "awt_Checkbox.h"
-#include "awt_KeyboardFocusManager.h"
#include "awt_Canvas.h"
#include "awt_Window.h"
@@ -143,17 +142,6 @@ done:
return checkbox;
}
-BOOL AwtCheckbox::ActMouseMessage(MSG* pMsg) {
- if (!IsFocusingMessage(pMsg->message)) {
- return FALSE;
- }
-
- if (pMsg->message == WM_LBUTTONDOWN) {
- SendMessage(BM_SETSTATE, ~SendMessage(BM_GETSTATE, 0, 0), 0);
- }
- return TRUE;
-}
-
MsgRouting
AwtCheckbox::WmMouseUp(UINT flags, int x, int y, int button)
{
@@ -329,18 +317,32 @@ MsgRouting AwtCheckbox::WmPaint(HDC)
return mrDoDefault;
}
+BOOL AwtCheckbox::IsFocusingMouseMessage(MSG *pMsg) {
+ return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONUP;
+}
+
+BOOL AwtCheckbox::IsFocusingKeyMessage(MSG *pMsg) {
+ return (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) &&
+ pMsg->wParam == VK_SPACE;
+}
+
MsgRouting AwtCheckbox::HandleEvent(MSG *msg, BOOL synthetic)
{
- if (IsFocusable() && AwtComponent::sm_focusOwner != GetHWnd() &&
- (msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONDBLCLK))
- {
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject target = GetTarget(env);
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::heavyweightButtonDownMID,
- target, ((jlong)msg->time) & 0xFFFFFFFF);
- env->DeleteLocalRef(target);
+ if (IsFocusingMouseMessage(msg)) {
+ SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_LBUTTONDOWN ? TRUE : FALSE));
+ delete msg;
+ return mrConsume;
+ }
+ if (IsFocusingKeyMessage(msg)) {
+ SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_KEYDOWN ? TRUE : FALSE));
+ if (msg->message == WM_KEYDOWN) {
+ m_fLButtonDowned = TRUE;
+ } else if (m_fLButtonDowned == TRUE) {
+ WmNotify(BN_CLICKED);
+ m_fLButtonDowned = TRUE;
+ }
+ delete msg;
+ return mrConsume;
}
return AwtComponent::HandleEvent(msg, synthetic);
}
diff --git a/src/windows/native/sun/windows/awt_Checkbox.h b/src/windows/native/sun/windows/awt_Checkbox.h
index 581afcd65..4d913da00 100644
--- a/src/windows/native/sun/windows/awt_Checkbox.h
+++ b/src/windows/native/sun/windows/awt_Checkbox.h
@@ -69,7 +69,8 @@ public:
MsgRouting HandleEvent(MSG *msg, BOOL synthetic);
- BOOL ActMouseMessage(MSG* pMsg);
+ BOOL IsFocusingMouseMessage(MSG *pMsg);
+ BOOL IsFocusingKeyMessage(MSG *pMsg);
// called on Toolkit thread from JNI
static void _SetLabel(void *param);
diff --git a/src/windows/native/sun/windows/awt_Choice.cpp b/src/windows/native/sun/windows/awt_Choice.cpp
index ca7adb0ed..03fdde96f 100644
--- a/src/windows/native/sun/windows/awt_Choice.cpp
+++ b/src/windows/native/sun/windows/awt_Choice.cpp
@@ -23,14 +23,17 @@
* have any questions.
*/
+#include <windowsx.h>
+
#include "awt_Toolkit.h"
#include "awt_Choice.h"
-#include "awt_KeyboardFocusManager.h"
#include "awt_Canvas.h"
#include "awt_Dimension.h"
#include "awt_Container.h"
+#include "ComCtl32Util.h"
+
#include <java_awt_Toolkit.h>
#include <java_awt_FontMetrics.h>
#include <java_awt_event_InputEvent.h>
@@ -71,18 +74,31 @@ BOOL AwtChoice::mouseCapture = FALSE;
/* Bug #4338368: consume the spurious MouseUp when the choice loses focus */
BOOL AwtChoice::skipNextMouseUp = FALSE;
+
+BOOL AwtChoice::sm_isMouseMoveInList = FALSE;
+
+static const UINT MINIMUM_NUMBER_OF_VISIBLE_ITEMS = 8;
+
/*************************************************************************
* AwtChoice class methods
*/
AwtChoice::AwtChoice() {
- killFocusRouting = mrPassAlong;
+ m_hList = NULL;
+ m_listDefWindowProc = NULL;
}
LPCTSTR AwtChoice::GetClassName() {
return TEXT("COMBOBOX"); /* System provided combobox class */
}
+void AwtChoice::Dispose() {
+ if (m_hList != NULL && m_listDefWindowProc != NULL) {
+ ComCtl32Util::GetInstance().UnsubclassHWND(m_hList, ListWindowProc, m_listDefWindowProc);
+ }
+ AwtComponent::Dispose();
+}
+
AwtChoice* AwtChoice::Create(jobject peer, jobject parent) {
@@ -162,6 +178,10 @@ AwtChoice* AwtChoice::Create(jobject peer, jobject parent) {
env->SetIntField(target, AwtComponent::widthID, (jint) rc.right);
env->SetIntField(target, AwtComponent::heightID, (jint) rc.bottom);
+ if (IS_WINXP) {
+ ::SendMessage(c->GetHWnd(), CB_SETMINVISIBLE, (WPARAM) MINIMUM_NUMBER_OF_VISIBLE_ITEMS, 0);
+ }
+
env->DeleteLocalRef(dimension);
}
} catch (...) {
@@ -175,24 +195,13 @@ done:
return c;
}
-BOOL AwtChoice::ActMouseMessage(MSG* pMsg) {
- if (!IsFocusingMessage(pMsg->message)) {
- return FALSE;
- }
-
- if (pMsg->message == WM_LBUTTONDOWN) {
- SendMessage(CB_SHOWDROPDOWN, ~SendMessage(CB_GETDROPPEDSTATE, 0, 0), 0);
- }
- return TRUE;
-}
-
// calculate height of drop-down list part of the combobox
// to show all the items up to a maximum of eight
int AwtChoice::GetDropDownHeight()
{
int itemHeight =(int)::SendMessage(GetHWnd(), CB_GETITEMHEIGHT, (UINT)0,0);
int numItemsToShow = (int)::SendMessage(GetHWnd(), CB_GETCOUNT, 0,0);
- numItemsToShow = numItemsToShow > 8 ? 8 : numItemsToShow;
+ numItemsToShow = min(MINIMUM_NUMBER_OF_VISIBLE_ITEMS, numItemsToShow);
// drop-down height snaps to nearest line, so add a
// fudge factor of 1/2 line to ensure last line shows
return itemHeight*numItemsToShow + itemHeight/2;
@@ -253,6 +262,7 @@ void AwtChoice::SetDragCapture(UINT flags)
}
return;
}
+
// don't want to interfere with other controls
if (::GetCapture() == NULL) {
::SetCapture(GetHWnd());
@@ -370,6 +380,58 @@ void AwtChoice::SetFont(AwtFont* font)
env->DeleteLocalRef(target);
}
+static int lastClickX = -1;
+static int lastClickY = -1;
+
+LRESULT CALLBACK AwtChoice::ListWindowProc(HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ /*
+ * We don't pass the choice WM_LBUTTONDOWN message. As the result the choice's list
+ * doesn't forward mouse messages it captures. Below we do forward what we need.
+ */
+
+ TRY;
+
+ DASSERT(::IsWindow(hwnd));
+
+ switch (message) {
+ case WM_LBUTTONDOWN: {
+ DWORD curPos = ::GetMessagePos();
+ lastClickX = GET_X_LPARAM(curPos);
+ lastClickY = GET_Y_LPARAM(curPos);
+ break;
+ }
+ case WM_MOUSEMOVE: {
+ RECT rect;
+ ::GetClientRect(hwnd, &rect);
+
+ POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
+ if (::PtInRect(&rect, pt)) {
+ sm_isMouseMoveInList = TRUE;
+ }
+
+ POINT lastPt = {lastClickX, lastClickY};
+ ::ScreenToClient(hwnd, &lastPt);
+ if (::PtInRect(&rect, lastPt)) {
+ break; // ignore when dragging inside the list
+ }
+ }
+ case WM_LBUTTONUP: {
+ lastClickX = -1;
+ lastClickY = -1;
+
+ AwtChoice *c = (AwtChoice *)::GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if (c != NULL) {
+ // forward the msg to the choice
+ c->WindowProc(message, wParam, lParam);
+ }
+ }
+ }
+ return ComCtl32Util::GetInstance().DefWindowProc(NULL, hwnd, message, wParam, lParam);
+
+ CATCH_BAD_ALLOC_RET(0);
+}
MsgRouting AwtChoice::WmNotify(UINT notifyCode)
@@ -379,15 +441,24 @@ MsgRouting AwtChoice::WmNotify(UINT notifyCode)
if (itemSelect != CB_ERR){
DoCallback("handleAction", "(I)V", itemSelect);
}
- } else if (notifyCode == CBN_DROPDOWN && !IsFocusable()) {
- // While non-focusable Choice is shown all WM_KILLFOCUS messages should be consumed.
- killFocusRouting = mrConsume;
- } else if (notifyCode == CBN_CLOSEUP && !IsFocusable()) {
- // When non-focusable Choice is about to close, send it synthetic WM_KILLFOCUS
- // message that should be processed by the native widget only. This will allow
- // the native widget to properly process WM_KILLFOCUS that was earlier consumed.
- killFocusRouting = mrDoDefault;
- ::PostMessage(GetHWnd(), WM_KILLFOCUS, (LPARAM)sm_focusOwner, 0);
+ } else if (notifyCode == CBN_DROPDOWN) {
+
+ if (m_hList == NULL) {
+ COMBOBOXINFO cbi;
+ cbi.cbSize = sizeof(COMBOBOXINFO);
+ ::GetComboBoxInfo(GetHWnd(), &cbi);
+ m_hList = cbi.hwndList;
+ m_listDefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(m_hList, ListWindowProc);
+ DASSERT(::GetWindowLongPtr(m_hList, GWLP_USERDATA) == NULL);
+ ::SetWindowLongPtr(m_hList, GWLP_USERDATA, (LONG_PTR)this);
+ }
+ sm_isMouseMoveInList = FALSE;
+
+ // Clicking in the dropdown list steals focus from the proxy.
+ // So, set the focus-restore flag up.
+ SetRestoreFocus(TRUE);
+ } else if (notifyCode == CBN_CLOSEUP) {
+ SetRestoreFocus(FALSE);
}
return mrDoDefault;
}
@@ -414,19 +485,7 @@ MsgRouting
AwtChoice::WmKillFocus(HWND hWndGotFocus)
{
skipNextMouseUp = TRUE;
-
- switch (killFocusRouting) {
- case mrConsume:
- return mrConsume;
- case mrDoDefault:
- killFocusRouting = mrPassAlong;
- return mrDoDefault;
- case mrPassAlong:
- return AwtComponent::WmKillFocus(hWndGotFocus);
- }
-
- DASSERT(false); // must never reach here
- return mrDoDefault;
+ return AwtComponent::WmKillFocus(hWndGotFocus);
}
MsgRouting
@@ -441,27 +500,17 @@ AwtChoice::WmMouseUp(UINT flags, int x, int y, int button)
MsgRouting AwtChoice::HandleEvent(MSG *msg, BOOL synthetic)
{
- /*
- * 6366006
- * Note: the event can be sent in two cases:
- * 1) The Choice is closed and user clicks on it to drop it down.
- * 2) The Choice is non-focusable, it's droped down, user
- * clicks on it (or outside) to close it.
- * So, if the Choice is in droped down state, we shouldn't call
- * heavyweightButtonDown() method. Otherwise it will set a typeahead marker
- * that won't be removed, because no focus events will be generated.
- */
- if (AwtComponent::sm_focusOwner != GetHWnd() &&
- (msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONDBLCLK) &&
- !IsChoiceOpened())
+ if (IsFocusingMouseMessage(msg)) {
+ SendMessage(CB_SHOWDROPDOWN, ~SendMessage(CB_GETDROPPEDSTATE, 0, 0), 0);
+ delete msg;
+ return mrConsume;
+ }
+ // To simulate the native behavior, we close the list on WM_LBUTTONUP if
+ // WM_MOUSEMOVE has been dedected on the list since it has been dropped down.
+ if (msg->message == WM_LBUTTONUP && SendMessage(CB_GETDROPPEDSTATE, 0, 0) &&
+ sm_isMouseMoveInList)
{
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject target = GetTarget(env);
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::heavyweightButtonDownMID,
- target, ((jlong)msg->time) & 0xFFFFFFFF);
- env->DeleteLocalRef(target);
+ SendMessage(CB_SHOWDROPDOWN, FALSE, 0);
}
return AwtComponent::HandleEvent(msg, synthetic);
}
@@ -618,6 +667,26 @@ done:
env->DeleteGlobalRef(choice);
}
+void AwtChoice::_CloseList(void *param)
+{
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ jobject choice = (jobject)param;
+
+ AwtChoice *c = NULL;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(choice, done);
+
+ c = (AwtChoice *)pData;
+ if (::IsWindow(c->GetHWnd()) && c->SendMessage(CB_GETDROPPEDSTATE, 0, 0)) {
+ c->SendMessage(CB_SHOWDROPDOWN, FALSE, 0);
+ }
+
+done:
+ env->DeleteGlobalRef(choice);
+}
+
/************************************************************************
* WChoicePeer native methods
*/
@@ -752,6 +821,23 @@ Java_sun_awt_windows_WChoicePeer_create(JNIEnv *env, jobject self,
CATCH_BAD_ALLOC;
}
+/*
+ * Class: sun_awt_windows_WChoicePeer
+ * Method: closeList
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WChoicePeer_closeList(JNIEnv *env, jobject self)
+{
+ TRY;
+
+ jobject selfGlobalRef = env->NewGlobalRef(self);
+
+ AwtToolkit::GetInstance().SyncCall(AwtChoice::_CloseList, (void *)selfGlobalRef);
+ // global ref is deleted in _CloseList
+
+ CATCH_BAD_ALLOC;
+}
} /* extern "C" */
diff --git a/src/windows/native/sun/windows/awt_Choice.h b/src/windows/native/sun/windows/awt_Choice.h
index 075cb0c5e..35e917474 100644
--- a/src/windows/native/sun/windows/awt_Choice.h
+++ b/src/windows/native/sun/windows/awt_Choice.h
@@ -43,6 +43,8 @@ public:
virtual LPCTSTR GetClassName();
static AwtChoice* Create(jobject peer, jobject hParent);
+ virtual void Dispose();
+
virtual void Reshape(int x, int y, int w, int h);
void ResetDropDownHeight();
int GetDropDownHeight();
@@ -75,9 +77,6 @@ public:
virtual void SetDragCapture(UINT flags);
virtual void ReleaseDragCapture(UINT flags);
- BOOL ActMouseMessage(MSG * pMsg);
- INLINE BOOL AwtChoice::IsChoiceOpened() {return SendMessage(CB_GETDROPPEDSTATE, 0, 0);}
-
static BOOL mouseCapture;
static BOOL skipNextMouseUp;
@@ -87,11 +86,16 @@ public:
static void _AddItems(void *param);
static void _Remove(void *param);
static void _RemoveAll(void *param);
+ static void _CloseList(void *param);
private:
int GetFieldHeight();
int GetTotalHeight();
- MsgRouting killFocusRouting;
+ static BOOL sm_isMouseMoveInList;
+ HWND m_hList;
+ WNDPROC m_listDefWindowProc;
+ static LRESULT CALLBACK ListWindowProc(HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
};
#endif /* AWT_CHOICE_H */
diff --git a/src/windows/native/sun/windows/awt_Component.cpp b/src/windows/native/sun/windows/awt_Component.cpp
index 6f0df2e44..9db8ec4b8 100644
--- a/src/windows/native/sun/windows/awt_Component.cpp
+++ b/src/windows/native/sun/windows/awt_Component.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,6 @@
#include "awt_InputTextInfor.h"
#include "awt_Insets.h"
#include "awt_KeyEvent.h"
-#include "awt_KeyboardFocusManager.h"
#include "awt_MenuItem.h"
#include "awt_MouseEvent.h"
#include "awt_Palette.h"
@@ -58,7 +57,6 @@
#include <java_awt_Event.h>
#include <java_awt_event_KeyEvent.h>
#include <java_awt_Insets.h>
-#include <java_awt_KeyboardFocusManager.h>
#include <sun_awt_windows_WPanelPeer.h>
#include <java_awt_event_InputEvent.h>
#include <java_awt_event_InputMethodEvent.h>
@@ -94,12 +92,13 @@ extern "C" {
BOOL g_bUserHasChangedInputLang = FALSE;
}
-BOOL AwtComponent::sm_suppressFocusAndActivation;
-HWND AwtComponent::sm_focusOwner;
-HWND AwtComponent::sm_focusedWindow;
-HWND AwtComponent::sm_realFocusOpposite;
+BOOL AwtComponent::sm_suppressFocusAndActivation = FALSE;
+BOOL AwtComponent::sm_restoreFocusAndActivation = FALSE;
+HWND AwtComponent::sm_focusOwner = NULL;
+HWND AwtComponent::sm_focusedWindow = NULL;
BOOL AwtComponent::sm_bMenuLoop = FALSE;
AwtComponent* AwtComponent::sm_getComponentCache = NULL;
+BOOL AwtComponent::sm_inSynthesizeFocus = FALSE;
/************************************************************************/
// Struct for _Reshape() and ReshapeNoCheck() methods
@@ -123,15 +122,6 @@ struct SetFontStruct {
jobject component;
jobject font;
};
-// Struct for _RequestFocus() method
-struct RequestFocusStruct {
- jobject component;
- jobject lightweightChild;
- jboolean temporary;
- jboolean focusedWindowChangeAllowed;
- jlong time;
- jobject cause;
-};
// Struct for _CreatePrintedPixels() method
struct CreatePrintedPixelsStruct {
jobject component;
@@ -149,6 +139,16 @@ struct GetInsetsStruct {
jobject window;
RECT *insets;
};
+// Struct for _SetZOrder function
+struct SetZOrderStruct {
+ jobject component;
+ jlong above;
+};
+// Struct for _SetFocus function
+struct SetFocusStruct {
+ jobject component;
+ jboolean doSetFocus;
+};
/************************************************************************/
//////////////////////////////////////////////////////////////////////////
@@ -199,8 +199,7 @@ BOOL AwtComponent::sm_rtl = PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC ||
BOOL AwtComponent::sm_rtlReadingOrder =
PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC;
-UINT AwtComponent::sm_95WheelMessage = WM_NULL;
-UINT AwtComponent::sm_95WheelSupport = WM_NULL;
+BOOL AwtComponent::sm_PrimaryDynamicTableBuilt = FALSE;
HWND AwtComponent::sm_cursorOn;
BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE;
@@ -208,8 +207,6 @@ BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE;
CriticalSection windowMoveLock;
BOOL windowMoveLockHeld = FALSE;
-int AwtComponent::sm_wheelRotationAmount = 0;
-
/************************************************************************
* AwtComponent methods
*/
@@ -237,7 +234,6 @@ AwtComponent::AwtComponent()
m_InputMethod = NULL;
m_useNativeCompWindow = TRUE;
m_PendingLeadByte = 0;
- m_skipNextSetFocus = FALSE;
m_bitsCandType = 0;
windowMoveLockPosX = 0;
@@ -250,6 +246,12 @@ AwtComponent::AwtComponent()
m_bSubclassed = FALSE;
m_MessagesProcessing = 0;
+ m_wheelRotationAmount = 0;
+ if (!sm_PrimaryDynamicTableBuilt) {
+ // do it once.
+ AwtComponent::BuildPrimaryDynamicTable();
+ sm_PrimaryDynamicTableBuilt = TRUE;
+ }
}
AwtComponent::~AwtComponent()
@@ -265,8 +267,7 @@ AwtComponent::~AwtComponent()
* the native one anymore. So we can safely destroy component's
* handle.
*/
- AwtToolkit::DestroyComponentHWND(m_hwnd);
- m_hwnd = NULL;
+ DestroyHWnd();
if (sm_getComponentCache == this) {
sm_getComponentCache = NULL;
@@ -275,15 +276,8 @@ AwtComponent::~AwtComponent()
void AwtComponent::Dispose()
{
- if (sm_focusOwner == GetHWnd()) {
- ::SetFocus(NULL);
- }
- if (sm_focusedWindow == GetHWnd()) {
- sm_focusedWindow = NULL;
- }
- if (sm_realFocusOpposite == GetHWnd()) {
- sm_realFocusOpposite = NULL;
- }
+ // NOTE: in case the component/toplevel was focused, Java should
+ // have already taken care of proper transfering it or clearing.
if (m_hdwp != NULL) {
// end any deferred window positioning, regardless
@@ -588,6 +582,17 @@ AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title,
}
/*
+ * Destroy this window's HWND
+ */
+void AwtComponent::DestroyHWnd() {
+ if (m_hwnd != NULL) {
+ AwtToolkit::DestroyComponentHWND(m_hwnd);
+ //AwtToolkit::DestroyComponent(this);
+ m_hwnd = NULL;
+ }
+}
+
+/*
* Returns hwnd for target on non Toolkit thread
*/
HWND
@@ -888,27 +893,8 @@ void AwtComponent::Show()
void AwtComponent::Hide()
{
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject peer = GetPeer(env);
- BOOL oldValue = sm_suppressFocusAndActivation;
m_visible = false;
-
- // On disposal the focus owner actually loses focus at the moment of hiding.
- // So, focus change suppression (if requested) should be made here.
- if (GetHWnd() == sm_focusOwner &&
- !JNU_CallMethodByName(env, NULL, peer, "isAutoFocusTransferOnDisposal", "()Z").z)
- {
- sm_suppressFocusAndActivation = TRUE;
- // The native system may autotransfer focus on hiding to the parent
- // of the component. Nevertheless this focus change won't be posted
- // to the Java level, we're better to avoid this. Anyway, after
- // the disposal focus should be requested to the right component.
- ::SetFocus(NULL);
- sm_focusOwner = NULL;
- }
::ShowWindow(GetHWnd(), SW_HIDE);
-
- sm_suppressFocusAndActivation = oldValue;
}
BOOL
@@ -1252,6 +1238,7 @@ void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) {
WIN_MSG(WM_AWT_COMPONENT_SHOW)
WIN_MSG(WM_AWT_COMPONENT_HIDE)
WIN_MSG(WM_AWT_COMPONENT_SETFOCUS)
+ WIN_MSG(WM_AWT_WINDOW_SETACTIVE)
WIN_MSG(WM_AWT_LIST_SETMULTISELECT)
WIN_MSG(WM_AWT_HANDLE_EVENT)
WIN_MSG(WM_AWT_PRINT_COMPONENT)
@@ -1503,67 +1490,54 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
sm_bMenuLoop = FALSE;
break;
+ // We don't expect any focus messages on non-proxy component,
+ // except those that came from Java.
case WM_SETFOCUS:
- mr = (!sm_suppressFocusAndActivation && !m_skipNextSetFocus)
- ? WmSetFocus((HWND)wParam) : mrConsume;
- m_skipNextSetFocus = FALSE;
+ if (sm_inSynthesizeFocus) {
+ mr = WmSetFocus((HWND)wParam);
+ } else {
+ mr = mrConsume;
+ }
break;
case WM_KILLFOCUS:
- mr = (!sm_suppressFocusAndActivation)
- ? WmKillFocus((HWND)wParam) : mrConsume;
+ if (sm_inSynthesizeFocus) {
+ mr = WmKillFocus((HWND)wParam);
+ } else {
+ mr = mrConsume;
+ }
break;
- case WM_ACTIVATE:
- {
+ case WM_ACTIVATE: {
UINT nState = LOWORD(wParam);
BOOL fMinimized = (BOOL)HIWORD(wParam);
+ mr = mrConsume;
+
if (!sm_suppressFocusAndActivation &&
(!fMinimized || (nState == WA_INACTIVE)))
{
mr = WmActivate(nState, fMinimized, (HWND)lParam);
- m_skipNextSetFocus = FALSE;
+
// When the window is deactivated, send WM_IME_ENDCOMPOSITION
// message to deactivate the composition window so that
// it won't receive keyboard input focus.
if (ImmGetContext() != NULL) {
DefWindowProc(WM_IME_ENDCOMPOSITION, 0, 0);
}
- } else {
- if (!sm_suppressFocusAndActivation
- && fMinimized && (nState != WA_INACTIVE))
- {
- m_skipNextSetFocus = TRUE;
- }
- mr = mrConsume;
}
+ break;
+ }
+ case WM_MOUSEACTIVATE: {
+ AwtWindow *window = GetContainer();
+ if (window && window->IsFocusableWindow()) {
+ // AWT/Swing will later request focus to a proper component
+ // on handling the Java mouse event. Anyway, we have to
+ // activate the window here as it works both for AWT & Swing.
+ // Do it in our own fassion,
+ window->AwtSetActiveWindow(TRUE, LOWORD(lParam)/*hittest*/);
+ }
+ mr = mrConsume;
+ retValue = MA_NOACTIVATE;
+ break;
}
- break;
- case WM_MOUSEACTIVATE: {
- AwtWindow * window = (AwtWindow*)GetComponent((HWND)wParam);
- if (window != NULL) {
- if (!window->IsFocusableWindow()) {
- // if it is non-focusable window we can return
- // MA_NOACTIVATExxx and it will not be activated. We
- // return NOACTIVATE for a client part of the window so we
- // receive mouse event responsible for activation. We
- // return NOACTIVEA for Frame's non-client so user be able
- // to resize and move frames by title and borders. We
- // return NOACTIVATEANDEAT for Window non-client area as
- // there is noone to listen for this event.
- mr = mrConsume;
- if ((window == this) && LOWORD(lParam) != HTCLIENT ) {
- if (window->IsSimpleWindow()) {
- retValue = MA_NOACTIVATEANDEAT;
- } else {
- retValue = MA_NOACTIVATE;
- }
- } else {
- retValue = MA_NOACTIVATE;
- }
- }
- }
- break;
- }
-
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
@@ -1920,7 +1894,15 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_AWT_COMPONENT_SETFOCUS:
- retValue = (LRESULT)WmComponentSetFocus((WmComponentSetFocusData *)wParam);
+ if ((BOOL)wParam) {
+ retValue = SynthesizeWmSetFocus(GetHWnd(), NULL);
+ } else {
+ retValue = SynthesizeWmKillFocus(GetHWnd(), NULL);
+ }
+ mr = mrConsume;
+ break;
+ case WM_AWT_WINDOW_SETACTIVE:
+ retValue = (LRESULT)((AwtWindow*)this)->AwtSetActiveWindow((BOOL)wParam);
mr = mrConsume;
break;
@@ -2048,188 +2030,16 @@ MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status)
MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus)
{
- if (sm_focusOwner == GetHWnd()) {
- sm_realFocusOpposite = NULL;
- return mrConsume;
- }
-
- HWND toplevelHWnd = AwtComponent::GetTopLevelParentForWindow(GetHWnd());
- AwtComponent *comp = AwtComponent::GetComponent(toplevelHWnd);
-
- if (comp && comp->IsEmbeddedFrame() &&
- !((AwtFrame*)comp)->activateEmbeddedFrameOnSetFocus(hWndLostFocus))
- {
- // Fix for 6562716.
- // In order that AwtSetFocus() returns FALSE.
- sm_suppressFocusAndActivation = TRUE;
- ::SetFocus(NULL);
- sm_suppressFocusAndActivation = FALSE;
-
- return mrConsume;
- }
-
- sm_focusOwner = GetHWnd();
- sm_focusedWindow = toplevelHWnd;
-
- if (sm_realFocusOpposite != NULL) {
- hWndLostFocus = sm_realFocusOpposite;
- sm_realFocusOpposite = NULL;
- }
-
- sm_wheelRotationAmount = 0;
-
- SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus);
-
+ m_wheelRotationAmount = 0;
return mrDoDefault;
}
MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus)
{
- if (sm_focusOwner != NULL && sm_focusOwner == hWndGotFocus) {
- return mrConsume;
- }
-
- if (sm_focusOwner != GetHWnd()) {
- if (sm_focusOwner != NULL) {
- if (hWndGotFocus != NULL &&
- AwtComponent::GetComponent(hWndGotFocus) != NULL)
- {
- sm_realFocusOpposite = sm_focusOwner;
- }
- ::SendMessage(sm_focusOwner, WM_KILLFOCUS, (WPARAM)hWndGotFocus,
- 0);
- }
- return mrConsume;
- }
-
- AwtComponent *comp = AwtComponent::GetComponent(sm_focusedWindow);
-
- if (comp && comp->IsEmbeddedFrame()) {
- ((AwtFrame*)comp)->deactivateEmbeddedFrameOnKillFocus(hWndGotFocus);
- }
-
- sm_focusOwner = NULL;
- sm_wheelRotationAmount = 0;
-
- SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus);
+ m_wheelRotationAmount = 0;
return mrDoDefault;
}
-jboolean
-AwtComponent::WmComponentSetFocus(WmComponentSetFocusData *data)
-{
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- if (env->EnsureLocalCapacity(1) < 0) {
- env->DeleteGlobalRef(data->lightweightChild);
- delete data;
- return JNI_FALSE;
- }
-
- jboolean result = JNI_FALSE;
-
- BOOL setSuppressFocusAndActivation = FALSE;
-
- /*
- * This is a fix for 4628933.
- * If sm_suppressFocusAndActivation is TRUE here then
- * this means that we dispatch WM_COMPONENT_SET_FOCUS inside
- * dispatching bounce activation, this unlikely but possible.
- * So we reset sm_suppressFocusAndActivation to give a chance
- * to dispatch focus events which will generate due this focus
- * request to Java.
- *
- * son@sparc.spb.su
- */
- if (sm_suppressFocusAndActivation) {
- sm_suppressFocusAndActivation = FALSE;
- setSuppressFocusAndActivation = TRUE;
- }
-
- jobject heavyweight = GetTarget(env);
- jint retval = env->CallStaticIntMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::shouldNativelyFocusHeavyweightMID,
- heavyweight, data->lightweightChild, data->temporary,
- data->focusedWindowChangeAllowed, data->time, data->cause);
-
- if (retval == java_awt_KeyboardFocusManager_SNFH_SUCCESS_HANDLED) {
- result = JNI_TRUE;
- } else if (retval == java_awt_KeyboardFocusManager_SNFH_SUCCESS_PROCEED) {
- result = (AwtSetFocus()) ? JNI_TRUE : JNI_FALSE;
- if (result == JNI_FALSE) {
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::removeLastFocusRequestMID,
- heavyweight);
- }
- } else {
- DASSERT(retval == java_awt_KeyboardFocusManager_SNFH_FAILURE);
- result = JNI_FALSE;
- }
- env->DeleteLocalRef(heavyweight);
-
- /*
- * Set sm_suppressFocusAndActivation back to TRUE if needed.
- * Fix for 4628933 (son@sparc.spb.su)
- */
- if (setSuppressFocusAndActivation) {
- sm_suppressFocusAndActivation = TRUE;
- }
-
- env->DeleteGlobalRef(data->lightweightChild);
- delete data;
- return result;
-}
-
-BOOL
-AwtComponent::AwtSetFocus()
-{
- HWND hwnd = GetHWnd();
-
- if (sm_focusOwner == hwnd) {
- return TRUE;
- }
-
- HWND fgWindow = ::GetForegroundWindow();
- if (NULL != fgWindow) {
- DWORD fgProcessID;
- ::GetWindowThreadProcessId(fgWindow, &fgProcessID);
-
- if (fgProcessID != ::GetCurrentProcessId()
- && !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID))
- {
- // fix for 6458497. we shouldn't request focus if it is out of both
- // our and embedder process.
- return FALSE;
- }
- }
-
- AwtWindow *pCont = GetContainer();
- AwtFrame *owner = pCont ? pCont->GetOwningFrameOrDialog() : NULL;
-
- if (owner == NULL) {
- ::SetFocus(hwnd);
- if (::GetFocus() != hwnd) {
- return FALSE;
- }
- } else {
- HWND oldFocusOwner = sm_focusOwner;
- if (oldFocusOwner != NULL) {
- ::SendMessage(oldFocusOwner, WM_KILLFOCUS, (WPARAM)hwnd, 0);
- }
-
- sm_suppressFocusAndActivation = TRUE;
- ::SetActiveWindow(owner->GetHWnd());
- ::SetFocus(owner->GetProxyFocusOwner());
- sm_suppressFocusAndActivation = FALSE;
-
- sm_focusedWindow = GetTopLevelParentForWindow(GetHWnd());
- ::SendMessage(hwnd, WM_SETFOCUS, (WPARAM)oldFocusOwner, 0);
- }
-
- return TRUE;
-}
-
MsgRouting AwtComponent::WmCtlColor(HDC hDC, HWND hCtrl,
UINT ctlColor, HBRUSH& retBrush)
{
@@ -2524,7 +2334,6 @@ MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button)
AwtWindow::GetGrabbedWindow()->Ungrab();
}
}
-
return mrConsume;
}
@@ -2638,11 +2447,11 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y,
BOOL result;
UINT platformLines;
- sm_wheelRotationAmount += wheelRotation;
+ m_wheelRotationAmount += wheelRotation;
// AWT interprets wheel rotation differently than win32, so we need to
// decode wheel amount.
- jint roundedWheelRotation = sm_wheelRotationAmount / (-1 * WHEEL_DELTA);
+ jint roundedWheelRotation = m_wheelRotationAmount / (-1 * WHEEL_DELTA);
jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA);
MSG msg;
@@ -2668,7 +2477,9 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y,
eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType,
scrollLines, roundedWheelRotation, preciseWheelRotation, &msg);
- sm_wheelRotationAmount %= WHEEL_DELTA;
+ m_wheelRotationAmount %= WHEEL_DELTA;
+ // this message could be propagated up to the parent chain
+ // by the mouse message post processors
return mrConsume;
}
@@ -3088,6 +2899,19 @@ static const CharToVKEntry charToDeadVKTable[] = {
{0,0}
};
+// The full map of the current keyboard state including
+// windows virtual key, scancode, java virtual key, and unicode
+// for this key sans modifiers.
+// All but first element may be 0.
+// XXX in the update releases this is an addition to the unchanged existing code
+struct DynPrimaryKeymapEntry {
+ UINT wkey;
+ UINT scancode;
+ UINT jkey;
+ WCHAR unicode;
+};
+
+static DynPrimaryKeymapEntry dynPrimaryKeymap[256];
void
AwtComponent::InitDynamicKeyMapTable()
@@ -3096,6 +2920,8 @@ AwtComponent::InitDynamicKeyMapTable()
if (!kbdinited) {
AwtComponent::BuildDynamicKeyMapTable();
+ // We cannot build it here since JNI is not available yet:
+ //AwtComponent::BuildPrimaryDynamicTable();
kbdinited = TRUE;
}
}
@@ -3321,7 +3147,11 @@ UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)
for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
- return dynamicKeyMapTable[j].javaKey;
+ if (dynamicKeyMapTable[j].javaKey != java_awt_event_KeyEvent_VK_UNDEFINED) {
+ return dynamicKeyMapTable[j].javaKey;
+ }else{
+ break;
+ }
}
}
@@ -3398,6 +3228,122 @@ BOOL AwtComponent::IsNumPadKey(UINT vkey, BOOL extended)
return FALSE;
}
+static void
+resetKbdState( BYTE kstate[256]) {
+ BYTE tmpState[256];
+ WCHAR wc[2];
+ memmove(tmpState, kstate, sizeof(kstate));
+ tmpState[VK_SHIFT] = 0;
+ tmpState[VK_CONTROL] = 0;
+ tmpState[VK_MENU] = 0;
+
+ ::ToUnicodeEx(VK_SPACE,::MapVirtualKey(VK_SPACE, 0), tmpState, wc, 2, 0, GetKeyboardLayout(0));
+}
+
+// XXX in the update releases this is an addition to the unchanged existing code
+// After the call, a table will have a unicode associated with a windows virtual keycode
+// sans modifiers. With some further simplification, one can
+// derive java keycode from it, and anyway we will pass this unicode value
+// all the way up in a comment to a KeyEvent.
+void
+AwtComponent::BuildPrimaryDynamicTable() {
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ // XXX: how about that?
+ //CriticalSection::Lock l(GetLock());
+ //if (GetPeer(env) == NULL) {
+ // /* event received during termination. */
+ // return;
+ //}
+
+ HKL hkl = GetKeyboardLayout();
+ UINT sc = 0;
+ BYTE kbdState[AwtToolkit::KB_STATE_SIZE];
+ memset(kbdState, 0, sizeof (kbdState));
+
+ // Use JNI call to obtain java key code. We should keep a list
+ // of currently available keycodes in a single place.
+ static jclass extKeyCodesCls;
+ if( extKeyCodesCls == NULL) {
+ jclass extKeyCodesClsLocal = env->FindClass("sun/awt/ExtendedKeyCodes");
+ DASSERT(extKeyCodesClsLocal);
+ if (extKeyCodesClsLocal == NULL) {
+ /* exception already thrown */
+ return;
+ }
+ extKeyCodesCls = (jclass)env->NewGlobalRef(extKeyCodesClsLocal);
+ env->DeleteLocalRef(extKeyCodesClsLocal);
+ }
+ static jmethodID getExtendedKeyCodeForChar;
+ if (getExtendedKeyCodeForChar == NULL) {
+ getExtendedKeyCodeForChar =
+ env->GetStaticMethodID(extKeyCodesCls, "getExtendedKeyCodeForChar", "(I)I");
+ DASSERT(getExtendedKeyCodeForChar);
+ }
+ jint extJKC; //extended Java key code
+
+ for (UINT i = 0; i < 256; i++) {
+ dynPrimaryKeymap[i].wkey = i;
+ dynPrimaryKeymap[i].jkey = java_awt_event_KeyEvent_VK_UNDEFINED;
+ dynPrimaryKeymap[i].unicode = 0;
+
+ if ((sc = MapVirtualKey (i, 0)) == 0) {
+ dynPrimaryKeymap[i].scancode = 0;
+ continue;
+ }
+ dynPrimaryKeymap[i].scancode = sc;
+
+ // XXX process cases like VK_SHIFT etc.
+ kbdState[i] = 0x80; // "key pressed".
+ WCHAR wc[16];
+ int k = ::ToUnicodeEx(i, sc, kbdState, wc, 16, 0, hkl);
+ if (k == 1) {
+ // unicode
+ dynPrimaryKeymap[i].unicode = wc[0];
+ if (dynPrimaryKeymap[i].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) {
+ // Convert unicode to java keycode.
+ //dynPrimaryKeymap[i].jkey = ((UINT)(wc[0]) + 0x01000000);
+ //
+ //XXX If this key in on the keypad, we should force a special value equal to
+ //XXX an old java keycode: but how to say if it is a keypad key?
+ //XXX We'll do it in WmKeyUp/Down.
+ extJKC = env->CallStaticIntMethod(extKeyCodesCls,
+ getExtendedKeyCodeForChar, (jint)(wc[0]));
+ dynPrimaryKeymap[i].jkey = extJKC;
+ }
+ }else if (k == -1) {
+ // dead key: use charToDeadVKTable
+ dynPrimaryKeymap[i].unicode = wc[0];
+ resetKbdState( kbdState );
+ for (const CharToVKEntry *map = charToDeadVKTable; map->c != 0; ++map) {
+ if (wc[0] == map->c) {
+ dynPrimaryKeymap[i].jkey = map->javaKey;
+ break;
+ }
+ }
+ } else if (k == 0) {
+ // reset
+ resetKbdState( kbdState );
+ }else {
+ printf ("++++Whats that? wkey 0x%x (%d)\n", i,i);
+ }
+ kbdState[i] = 0; // "key unpressed"
+ }
+}
+void
+AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers)
+{
+ if( wkey && wkey < 256 ) {
+ if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) {
+ // At the creation time,
+ // dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /"
+ dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
+ }
+ if(dynPrimaryKeymap[wkey].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) {
+ // E.g. it is non-unicode key
+ dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
+ }
+ }
+}
UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
{
@@ -3554,10 +3500,12 @@ MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt,
jint keyLocation = GetKeyLocation(wkey, flags);
UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
+ UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
+
SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
TimeHelper::windowsToUTC(msg.time), jkey, character,
- modifiers, keyLocation, &msg);
+ modifiers, keyLocation, (jlong)wkey, &msg);
// bugid 4724007: Windows does not create a WM_CHAR for the Del key
// for some reason, so we need to create the KEY_TYPED event on the
@@ -3569,7 +3517,7 @@ MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt,
TimeHelper::windowsToUTC(msg.time),
java_awt_event_KeyEvent_VK_UNDEFINED,
character, modifiers,
- java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN);
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0);
}
return mrConsume;
@@ -3594,10 +3542,11 @@ MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt,
jint keyLocation = GetKeyLocation(wkey, flags);
UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD);
+ UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
TimeHelper::windowsToUTC(msg.time), jkey, character,
- modifiers, keyLocation, &msg);
+ modifiers, keyLocation, (jlong)wkey, &msg);
return mrConsume;
}
@@ -3613,6 +3562,7 @@ MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout)
m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID
m_CodePage = LangToCodePage(m_idLang);
BuildDynamicKeyMapTable(); // compute new mappings for VK_OEM
+ BuildPrimaryDynamicTable();
return mrConsume; // do not propagate to children
}
@@ -3643,7 +3593,7 @@ MsgRouting AwtComponent::WmIMEChar(UINT character, UINT repCnt, UINT flags, BOOL
TimeHelper::windowsToUTC(msg.time),
java_awt_event_KeyEvent_VK_UNDEFINED,
unicodeChar, modifiers,
- java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN,
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
&msg);
return mrConsume;
}
@@ -3712,7 +3662,7 @@ MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags,
TimeHelper::windowsToUTC(msg.time),
java_awt_event_KeyEvent_VK_UNDEFINED,
unicodeChar, modifiers,
- java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN,
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
&msg);
return mrConsume;
}
@@ -4033,14 +3983,15 @@ HIMC AwtComponent::ImmAssociateContext(HIMC himc)
HWND AwtComponent::GetProxyFocusOwner()
{
- AwtWindow * window = GetContainer();
+ AwtWindow *window = GetContainer();
if (window != 0) {
- AwtFrame * owner = window->GetOwningFrameOrDialog();
+ AwtFrame *owner = window->GetOwningFrameOrDialog();
if (owner != 0) {
return owner->GetProxyFocusOwner();
+ } else if (!window->IsSimpleWindow()) { // isn't an owned simple window
+ return ((AwtFrame*)window)->GetProxyFocusOwner();
}
}
-
return (HWND)NULL;
}
@@ -4562,6 +4513,25 @@ HDC AwtComponent::GetDCFromComponent()
return hdc;
}
+void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size)
+{
+ RECT eraseR = { 0, 0, size.cx, size.cy };
+ VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush()));
+}
+
+void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
+{
+ if (bitmapBits) {
+ DWORD* dest = (DWORD*)bitmapBits;
+ //XXX: might be optimized to use one loop (cy*cx -> 0).
+ for (int i = 0; i < size.cy; i++ ) {
+ for (int j = 0; j < size.cx; j++ ) {
+ ((BYTE*)(dest++))[3] = alpha;
+ }
+ }
+ }
+}
+
jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -4619,26 +4589,53 @@ jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {
return pixelArray;
}
-void *
-AwtComponent::GetNativeFocusOwner() {
+void* AwtComponent::SetNativeFocusOwner(void *self) {
+ if (self == NULL) {
+ // It means that the KFM wants to set focus to null
+ sm_focusOwner = NULL;
+ return NULL;
+ }
+
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ AwtComponent *c = NULL;
+ jobject peer = (jobject)self;
+
+ PDATA pData;
+ JNI_CHECK_NULL_GOTO(peer, "peer", ret);
+ pData = JNI_GET_PDATA(peer);
+ if (pData == NULL) {
+ goto ret;
+ }
+ c = (AwtComponent *)pData;
+
+ret:
+ if (c && ::IsWindow(c->GetHWnd())) {
+ sm_focusOwner = c->GetHWnd();
+ AwtFrame *owner = (AwtFrame*)GetComponent(c->GetProxyToplevelContainer());
+ if (owner) {
+ owner->SetLastProxiedFocusOwner(sm_focusOwner);
+ }
+ } else {
+ sm_focusOwner = NULL;
+ }
+ env->DeleteGlobalRef(peer);
+ return NULL;
+}
+
+void* AwtComponent::GetNativeFocusedWindow() {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
AwtComponent *comp =
- AwtComponent::GetComponent(AwtComponent::sm_focusOwner);
+ AwtComponent::GetComponent(AwtComponent::GetFocusedWindow());
return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL;
}
-void *
-AwtComponent::GetNativeFocusedWindow() {
+
+void* AwtComponent::GetNativeFocusOwner() {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
AwtComponent *comp =
- AwtComponent::GetComponent(AwtComponent::sm_focusedWindow);
+ AwtComponent::GetComponent(AwtComponent::sm_focusOwner);
return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL;
}
-void
-AwtComponent::ClearGlobalFocusOwner() {
- if (AwtComponent::sm_focusOwner != NULL) {
- ::SetFocus(NULL);
- }
-}
AwtComponent* AwtComponent::SearchChild(UINT id) {
ChildListItem* child;
@@ -4674,7 +4671,7 @@ void AwtComponent::RemoveChild(UINT id) {
}
void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked,
- jint modifiers, jint keyLocation, MSG *pMsg)
+ jint modifiers, jint keyLocation, jlong nativeCode, MSG *pMsg)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
CriticalSection::Lock l(GetLock());
@@ -4711,6 +4708,18 @@ void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked,
if (safe_ExceptionOccurred(env)) env->ExceptionDescribe();
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(keyEvent != NULL);
+ env->SetLongField(keyEvent, AwtKeyEvent::rawCodeID, nativeCode);
+ if( nativeCode && nativeCode < 256 ) {
+ env->SetLongField(keyEvent, AwtKeyEvent::primaryLevelUnicodeID, (jlong)(dynPrimaryKeymap[nativeCode].unicode));
+ env->SetLongField(keyEvent, AwtKeyEvent::extendedKeyCodeID, (jlong)(dynPrimaryKeymap[nativeCode].jkey));
+ if( nativeCode < 255 ) {
+ env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(dynPrimaryKeymap[nativeCode].scancode));
+ }else if( pMsg != NULL ) {
+ // unknown key with virtual keycode 0xFF.
+ // Its scancode is not in the table, pickup it from the message.
+ env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(HIWORD(pMsg->lParam) & 0xFF));
+ }
+ }
if (pMsg != NULL) {
AwtAWTEvent::saveMSG(env, pMsg, keyEvent);
}
@@ -4724,16 +4733,17 @@ void
AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when,
jint raw, jint cooked,
jint modifiers, jint keyLocation,
+ jlong nativeCode,
MSG *msg)
{
/*
* if focus owner is null, but focused window isn't
* we will send key event to focused window
*/
- HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : sm_focusedWindow);
+ HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : AwtComponent::GetFocusedWindow());
if (hwndTarget == GetHWnd()) {
- SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, msg);
+ SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, nativeCode, msg);
} else {
AwtComponent *target = NULL;
if (hwndTarget != NULL) {
@@ -4744,7 +4754,7 @@ AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when,
}
if (target != NULL) {
target->SendKeyEvent(id, when, raw, cooked, modifiers,
- keyLocation, msg);
+ keyLocation, nativeCode, msg);
}
}
}
@@ -5158,14 +5168,7 @@ void AwtComponent::SynthesizeMouseMessage(JNIEnv *env, jobject mouseEvent)
jint x = (env)->GetIntField(mouseEvent, AwtMouseEvent::xID);
jint y = (env)->GetIntField(mouseEvent, AwtMouseEvent::yID);
MSG* msg = CreateMessage(message, wParam, MAKELPARAM(x, y), x, y);
- // If the window is not focusable but if this is a focusing
- // message we should skip it then and perform our own actions.
- AwtWindow *pCont = GetContainer();
- if ((pCont && pCont->IsFocusableWindow()) || !ActMouseMessage(msg)) {
- PostHandleEventMessage(msg, TRUE);
- } else {
- delete msg;
- }
+ PostHandleEventMessage(msg, TRUE);
}
BOOL AwtComponent::InheritsNativeMouseWheelBehavior() {return false;}
@@ -5251,15 +5254,14 @@ void AwtComponent::UnlinkObjects()
void AwtComponent::Enable(BOOL bEnable)
{
- sm_suppressFocusAndActivation = TRUE;
-
if (bEnable && IsTopLevel()) {
// we should not enable blocked toplevels
bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
}
+ // Shouldn't trigger native focus change
+ // (only the proxy may be the native focus owner).
::EnableWindow(GetHWnd(), bEnable);
- sm_suppressFocusAndActivation = FALSE;
CriticalSection::Lock l(GetLock());
VerifyState();
}
@@ -5286,23 +5288,12 @@ void AwtComponent::DestroyDropTarget() {
}
}
-/**
- * Special procedure responsible for performing the actions which
- * usually happen with component when mouse buttons are being
- * pressed. It is required in case of non-focusable components - we
- * don't pass mouse messages directly to the windows because otherwise
- * it will try to focus component first which we don't want. This
- * function receives MSG and should return TRUE if it processed the
- * message and no furhter processing is allowed, FALSE otherwise.
- * Default implementation returns TRUE it is the message on which
- * Windows try to focus the component. Descendant components write
- * their own implementation of this procedure.
- */
-BOOL AwtComponent::ActMouseMessage(MSG * pMsg) {
- if (IsFocusingMessage(pMsg->message)) {
- return TRUE;
- }
- return FALSE;
+BOOL AwtComponent::IsFocusingMouseMessage(MSG *pMsg) {
+ return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK;
+}
+
+BOOL AwtComponent::IsFocusingKeyMessage(MSG *pMsg) {
+ return pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE;
}
void AwtComponent::_Show(void *param)
@@ -5640,22 +5631,12 @@ void AwtComponent::_NativeHandleEvent(void *param)
return;
}
- /* Post the message directly to the subclassed component. */
- if (self && (pData = JNI_GET_PDATA(self))) {
- AwtComponent* p = (AwtComponent*)pData;
- // If the window is not focusable but if this is a focusing
- // message we should skip it then and perform our own actions.
- AwtWindow *pCont = (AwtWindow*)(p->GetContainer());
- if ((pCont && pCont->IsFocusableWindow()) ||
- !p->ActMouseMessage(&msg))
- {
- // Create copy for local msg
- MSG* pCopiedMsg = new MSG;
- memmove(pCopiedMsg, &msg, sizeof(MSG));
- // Event handler deletes msg
- p->PostHandleEventMessage(pCopiedMsg, FALSE);
- }
- }
+ // Create copy for local msg
+ MSG* pCopiedMsg = new MSG;
+ memmove(pCopiedMsg, &msg, sizeof(MSG));
+ // Event handler deletes msg
+ p->PostHandleEventMessage(pCopiedMsg, FALSE);
+
env->DeleteGlobalRef(self);
env->DeleteGlobalRef(event);
delete nhes;
@@ -5777,19 +5758,15 @@ ret:
delete sfs;
}
-jboolean AwtComponent::_RequestFocus(void *param)
+// Sets or kills focus for a component.
+void AwtComponent::_SetFocus(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- RequestFocusStruct *rfs = (RequestFocusStruct *)param;
- jobject self = rfs->component;
- jobject lightweightChild = rfs->lightweightChild;
- jboolean temporary = rfs->temporary;
- jboolean focusedWindowChangeAllowed = rfs->focusedWindowChangeAllowed;
- jlong time = rfs->time;
- jobject cause = rfs->cause;
+ SetFocusStruct *sfs = (SetFocusStruct *)param;
+ jobject self = sfs->component;
+ jboolean doSetFocus = sfs->doSetFocus;
- jboolean result = JNI_FALSE;
AwtComponent *c = NULL;
PDATA pData;
@@ -5801,25 +5778,13 @@ jboolean AwtComponent::_RequestFocus(void *param)
}
c = (AwtComponent *)pData;
- if (::IsWindow(c->GetHWnd()))
- {
- WmComponentSetFocusData *data = new WmComponentSetFocusData;
- data->lightweightChild = env->NewGlobalRef(lightweightChild);
- data->temporary = temporary;
- data->focusedWindowChangeAllowed = focusedWindowChangeAllowed;
- data->time = time;
- data->cause = cause;
- result = (jboolean)c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)data, 0);
- // data and global ref in it are deleted in WmComponentSetFocus
+ if (::IsWindow(c->GetHWnd())) {
+ c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)doSetFocus, 0);
}
ret:
env->DeleteGlobalRef(self);
- env->DeleteGlobalRef(lightweightChild);
- env->DeleteGlobalRef(cause);
- delete rfs;
-
- return result;
+ delete sfs;
}
void AwtComponent::_Start(void *param)
@@ -6082,9 +6047,9 @@ void AwtComponent::SetParent(void * param) {
HWND selfWnd = comps[0]->GetHWnd();
HWND parentWnd = comps[1]->GetHWnd();
if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) {
- sm_suppressFocusAndActivation = TRUE;
+ // Shouldn't trigger native focus change
+ // (only the proxy may be the native focus owner).
::SetParent(selfWnd, parentWnd);
- sm_suppressFocusAndActivation = FALSE;
}
}
delete[] comps;
@@ -6107,15 +6072,12 @@ void AwtComponent::_SetRectangularShape(void *param)
AwtComponent *c = NULL;
-
-
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
+
c = (AwtComponent *)pData;
- if (::IsWindow(c->GetHWnd()))
- {
+ if (::IsWindow(c->GetHWnd())) {
HRGN hRgn = NULL;
-
if (region || x1 || x2 || y1 || y2) {
// If all the params are zeros, the shape must be simply reset.
// Otherwise, convert it into a region.
@@ -6157,6 +6119,33 @@ ret:
delete data;
}
+void AwtComponent::_SetZOrder(void *param) {
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ SetZOrderStruct *data = (SetZOrderStruct *)param;
+ jobject self = data->component;
+ HWND above = HWND_TOP;
+ if (data->above != 0) {
+ above = reinterpret_cast<HWND>(data->above);
+ }
+
+ AwtComponent *c = NULL;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+
+ c = (AwtComponent *)pData;
+ if (::IsWindow(c->GetHWnd())) {
+ ::SetWindowPos(c->GetHWnd(), above, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS);
+ }
+
+ret:
+ env->DeleteGlobalRef(self);
+
+ delete data;
+}
+
void AwtComponent::PostUngrabEvent() {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject target = GetTarget(env);
@@ -6173,6 +6162,14 @@ void AwtComponent::PostUngrabEvent() {
}
}
+void AwtComponent::SetFocusedWindow(HWND window)
+{
+ HWND old = sm_focusedWindow;
+ sm_focusedWindow = window;
+
+ AwtWindow::FocusedWindowChanged(old, window);
+}
+
/************************************************************************
* Component native methods
*/
@@ -6587,31 +6584,25 @@ Java_sun_awt_windows_WComponentPeer__1setFont(JNIEnv *env, jobject self,
/*
* Class: sun_awt_windows_WComponentPeer
- * Method: requestFocus
- * Signature: (Ljava/awt/Component;ZZJ)Z
+ * Method: focusGained
+ * Signature: (Z)
*/
-JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WComponentPeer__1requestFocus
- (JNIEnv *env, jobject self, jobject lightweightChild, jboolean temporary,
- jboolean focusedWindowChangeAllowed, jlong time, jobject cause)
+JNIEXPORT void JNICALL Java_sun_awt_windows_WComponentPeer_setFocus
+ (JNIEnv *env, jobject self, jboolean doSetFocus)
{
TRY;
jobject selfGlobalRef = env->NewGlobalRef(self);
- jobject lightweightChildGlobalRef = env->NewGlobalRef(lightweightChild);
- RequestFocusStruct *rfs = new RequestFocusStruct;
- rfs->component = selfGlobalRef;
- rfs->lightweightChild = lightweightChildGlobalRef;
- rfs->temporary = temporary;
- rfs->focusedWindowChangeAllowed = focusedWindowChangeAllowed;
- rfs->time = time;
- rfs->cause = env->NewGlobalRef(cause);
+ SetFocusStruct *sfs = new SetFocusStruct;
+ sfs->component = selfGlobalRef;
+ sfs->doSetFocus = doSetFocus;
- return (jboolean)AwtToolkit::GetInstance().SyncCall(
- (void*(*)(void*))AwtComponent::_RequestFocus, rfs);
- // global refs and rfs are deleted in _RequestFocus
+ AwtToolkit::GetInstance().SyncCall(
+ (void*(*)(void*))AwtComponent::_SetFocus, sfs);
+ // global refs and self are deleted in _SetFocus
- CATCH_BAD_ALLOC_RET(JNI_FALSE);
+ CATCH_BAD_ALLOC;
}
/*
@@ -6823,25 +6814,6 @@ Java_sun_awt_windows_WComponentPeer_isObscured(JNIEnv* env,
CATCH_BAD_ALLOC_RET(NULL);
}
-JNIEXPORT jboolean JNICALL
-Java_sun_awt_windows_WComponentPeer_processSynchronousLightweightTransfer(JNIEnv *env, jclass cls,
- jobject heavyweight,
- jobject descendant,
- jboolean temporary,
- jboolean focusedWindowChangeAllowed,
- jlong time)
-{
- TRY;
-
- return env->CallStaticBooleanMethod(AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::processSynchronousTransfer,
- heavyweight, descendant, temporary,
- focusedWindowChangeAllowed,
- time);
-
- CATCH_BAD_ALLOC_RET(JNI_TRUE);
-}
-
JNIEXPORT void JNICALL
Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) {
TRY;
@@ -6883,6 +6855,21 @@ Java_sun_awt_windows_WComponentPeer_setRectangularShape(JNIEnv* env, jobject sel
CATCH_BAD_ALLOC;
}
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WComponentPeer_setZOrder(JNIEnv* env, jobject self, jlong above)
+{
+ TRY;
+
+ SetZOrderStruct * data = new SetZOrderStruct;
+ data->component = env->NewGlobalRef(self);
+ data->above = above;
+
+ AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetZOrder, data);
+ // global refs and data are deleted in _SetLower
+
+ CATCH_BAD_ALLOC;
+}
+
} /* extern "C" */
diff --git a/src/windows/native/sun/windows/awt_Component.h b/src/windows/native/sun/windows/awt_Component.h
index 0c18961ed..8eec52be8 100644
--- a/src/windows/native/sun/windows/awt_Component.h
+++ b/src/windows/native/sun/windows/awt_Component.h
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,8 +78,6 @@ class AwtPopupMenu;
class AwtDropTarget;
-struct WmComponentSetFocusData;
-
/*
* Message routing codes
*/
@@ -139,12 +137,13 @@ public:
virtual void RegisterClass();
virtual void UnregisterClass();
- void CreateHWnd(JNIEnv *env, LPCWSTR title,
+ virtual void CreateHWnd(JNIEnv *env, LPCWSTR title,
DWORD windowStyle, DWORD windowExStyle,
int x, int y, int w, int h,
HWND hWndParent, HMENU hMenu,
COLORREF colorForeground, COLORREF colorBackground,
jobject peer);
+ virtual void DestroyHWnd();
void InitPeerGraphicsConfig(JNIEnv *env, jobject peer);
virtual void Dispose();
@@ -221,17 +220,10 @@ public:
virtual BOOL IsContainer() { return FALSE;} // Plain components can't
/**
- * Perform some actions which by default are being performed by Default Window procedure of
- * this window class
- * For detailed comments see implementation in awt_Component.cpp
- */
- virtual BOOL ActMouseMessage(MSG * pMsg);
- /**
- * Returns TRUE if this message will this component to become focused. Returns FALSE otherwise.
+ * Returns TRUE if this message will trigger native focus change, FALSE otherwise.
*/
- inline BOOL IsFocusingMessage(UINT message) {
- return message == WM_LBUTTONDOWN || message == WM_LBUTTONUP || message == WM_LBUTTONDBLCLK;
- }
+ virtual BOOL IsFocusingKeyMessage(MSG *pMsg);
+ virtual BOOL IsFocusingMouseMessage(MSG *pMsg);
BOOL IsFocusable();
@@ -373,7 +365,7 @@ public:
}
void SendKeyEventToFocusOwner(jint id, jlong when, jint raw, jint cooked,
- jint modifiers, jint keyLocation,
+ jint modifiers, jint keyLocation, jlong nativeCode,
MSG *msg = NULL);
/*
* Allocate and initialize a new java.awt.event.KeyEvent, and
@@ -381,7 +373,7 @@ public:
* from the target.
*/
void SendKeyEvent(jint id, jlong when, jint raw, jint cooked,
- jint modifiers, jint keyLocation,
+ jint modifiers, jint keyLocation, jlong nativeCode,
MSG *msg = NULL);
/*
@@ -431,13 +423,6 @@ public:
*/
virtual BOOL InheritsNativeMouseWheelBehavior();
- /* Functions for MouseWheel support on Windows95
- * These should only be called if running on 95
- */
- static void Wheel95Init();
- INLINE static UINT Wheel95GetMsg() {return sm_95WheelMessage;}
- static UINT Wheel95GetScrLines();
-
/* Determines whether the component is obscured by another window */
// Called on Toolkit thread
static jboolean _IsObscured(void *param);
@@ -457,6 +442,7 @@ public:
static UINT GetButtonMK(int mouseButton);
static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers);
static void JavaKeyToWindowsKey(UINT javaKey, UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey);
+ static void UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers);
INLINE static void AwtComponent::JavaKeyToWindowsKey(UINT javaKey,
UINT *windowsKey, UINT *modifiers)
@@ -480,6 +466,12 @@ public:
HIMC ImmGetContext();
HIMC ImmAssociateContext(HIMC himc);
HWND GetProxyFocusOwner();
+
+ INLINE HWND GetProxyToplevelContainer() {
+ HWND proxyHWnd = GetProxyFocusOwner();
+ return ::GetAncestor(proxyHWnd, GA_ROOT); // a browser in case of EmbeddedFrame
+ }
+
void CallProxyDefWindowProc(UINT message,
WPARAM wParam,
LPARAM lParam,
@@ -517,11 +509,6 @@ public:
virtual MsgRouting WmShowWindow(BOOL show, UINT status);
virtual MsgRouting WmSetFocus(HWND hWndLost);
virtual MsgRouting WmKillFocus(HWND hWndGot);
- jboolean WmComponentSetFocus(WmComponentSetFocusData *data);
- // Use instead of ::SetFocus to maintain special focusing semantics for
- // Windows which are not Frames/Dialogs.
- BOOL AwtSetFocus();
-
virtual MsgRouting WmCtlColor(HDC hDC, HWND hCtrl,
UINT ctlColor, HBRUSH& retBrush);
virtual MsgRouting WmHScroll(UINT scrollCode, UINT pos, HWND hScrollBar);
@@ -611,10 +598,6 @@ public:
jintArray CreatePrintedPixels(SIZE &loc, SIZE &size);
- static void * GetNativeFocusOwner();
- static void * GetNativeFocusedWindow();
- static void ClearGlobalFocusOwner();
-
/*
* HWND, AwtComponent and Java Peer interaction
*
@@ -673,7 +656,6 @@ public:
static void _SetForeground(void *param);
static void _SetBackground(void *param);
static void _SetFont(void *param);
- static jboolean _RequestFocus(void *param);
static void _Start(void *param);
static void _BeginValidate(void *param);
static void _EndValidate(void *param);
@@ -683,10 +665,40 @@ public:
static jintArray _CreatePrintedPixels(void *param);
static jboolean _NativeHandlesWheelScrolling(void *param);
static void _SetRectangularShape(void *param);
+ static void _SetZOrder(void *param);
static HWND sm_focusOwner;
+
+private:
static HWND sm_focusedWindow;
+public:
+ static inline HWND GetFocusedWindow() { return sm_focusedWindow; }
+ static void SetFocusedWindow(HWND window);
+
+ static void _SetFocus(void *param);
+
+ static void *SetNativeFocusOwner(void *self);
+ static void *GetNativeFocusedWindow();
+ static void *GetNativeFocusOwner();
+
+ static BOOL sm_inSynthesizeFocus;
+
+ // Execute on Toolkit only.
+ INLINE static LRESULT SynthesizeWmSetFocus(HWND targetHWnd, HWND oppositeHWnd) {
+ sm_inSynthesizeFocus = TRUE;
+ LRESULT res = ::SendMessage(targetHWnd, WM_SETFOCUS, (WPARAM)oppositeHWnd, 0);
+ sm_inSynthesizeFocus = FALSE;
+ return res;
+ }
+ // Execute on Toolkit only.
+ INLINE static LRESULT SynthesizeWmKillFocus(HWND targetHWnd, HWND oppositeHWnd) {
+ sm_inSynthesizeFocus = TRUE;
+ LRESULT res = ::SendMessage(targetHWnd, WM_KILLFOCUS, (WPARAM)oppositeHWnd, 0);
+ sm_inSynthesizeFocus = FALSE;
+ return res;
+ }
+
static BOOL sm_bMenuLoop;
static INLINE BOOL isMenuLoopActive() {
return sm_bMenuLoop;
@@ -710,14 +722,25 @@ protected:
BOOL m_visible; /* copy of Component.visible */
static BOOL sm_suppressFocusAndActivation;
- static HWND sm_realFocusOpposite;
+ static BOOL sm_restoreFocusAndActivation;
+
+ /*
+ * The function sets the focus-restore flag ON/OFF.
+ * When the flag is ON, focus is restored immidiately after the proxy loses it.
+ * All focus messages are suppressed. It's also assumed that sm_focusedWindow and
+ * sm_focusOwner don't change after the flag is set ON and before it's set OFF.
+ */
+ static INLINE void SetRestoreFocus(BOOL doSet) {
+ sm_suppressFocusAndActivation = doSet;
+ sm_restoreFocusAndActivation = doSet;
+ }
virtual void SetDragCapture(UINT flags);
virtual void ReleaseDragCapture(UINT flags);
- // 95 support for mouse wheel
- static UINT sm_95WheelMessage;
- static UINT sm_95WheelSupport;
+ //These functions are overridden in AwtWindow to handle non-opaque windows.
+ virtual void FillBackground(HDC hMemoryDC, SIZE &size);
+ virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
private:
/* A bitmask keeps the button's numbers as MK_LBUTTON, MK_MBUTTON, MK_RBUTTON
@@ -761,6 +784,8 @@ private:
static BOOL sm_rtl;
static BOOL sm_rtlReadingOrder;
+ static BOOL sm_PrimaryDynamicTableBuilt;
+
jobject m_InputMethod;
BOOL m_useNativeCompWindow;
LPARAM m_bitsCandType;
@@ -780,8 +805,6 @@ private:
static BOOL m_QueryNewPaletteCalled;
- BOOL m_skipNextSetFocus;
-
static AwtComponent* sm_getComponentCache; // a cache for the GetComponent(..) method.
int windowMoveLockPosX;
@@ -790,7 +813,7 @@ private:
int windowMoveLockPosCY;
// 6524352: support finer-resolution
- static int sm_wheelRotationAmount;
+ int m_wheelRotationAmount;
/*
* The association list of children's IDs and corresponding components.
@@ -826,6 +849,7 @@ private:
AwtComponent* SearchChild(UINT id);
void RemoveChild(UINT id) ;
static BOOL IsNavigationKey(UINT wkey);
+ static void BuildPrimaryDynamicTable();
ChildListItem* m_childList;
@@ -876,14 +900,6 @@ public:
void RealizePalettes(int screen);
};
-struct WmComponentSetFocusData {
- jobject lightweightChild;
- jboolean temporary;
- jboolean focusedWindowChangeAllowed;
- jlong time;
- jobject cause;
-};
-
void ReleaseDCList(HWND hwnd, DCList &list);
void MoveDCToPassiveList(HDC hDC);
diff --git a/src/windows/native/sun/windows/awt_Dialog.cpp b/src/windows/native/sun/windows/awt_Dialog.cpp
index ecf74549d..147bcf711 100644
--- a/src/windows/native/sun/windows/awt_Dialog.cpp
+++ b/src/windows/native/sun/windows/awt_Dialog.cpp
@@ -230,25 +230,8 @@ LRESULT CALLBACK AwtDialog::ModalFilterProc(int code,
if (::IsIconic(hWnd)) {
::ShowWindow(hWnd, SW_RESTORE);
}
- HWND topMostBlocker = blocker;
- HWND toolkitHWnd = AwtToolkit::GetInstance().GetHWnd();
- while (::IsWindow(blocker)) {
- topMostBlocker = blocker;
- // fix for 6494032: restore the blocker if it was minimized
- // together with its parent frame; in such cases the check
- // ::IsIconic() for the blocker returns false, so we use
- // ::IsWindowVisible() instead
- if (!::IsWindowVisible(topMostBlocker) &&
- (topMostBlocker != toolkitHWnd))
- {
- ::ShowWindow(topMostBlocker, SW_SHOWNA);
- }
- ::BringWindowToTop(blocker);
- blocker = AwtWindow::GetModalBlocker(blocker);
- }
- if (topMostBlocker != toolkitHWnd) {
- ::SetForegroundWindow(topMostBlocker);
- }
+ PopupAllDialogs(blocker, TRUE, ::GetForegroundWindow(), FALSE);
+ // return 1 to prevent the system from allowing the operation
return 1;
}
return CallNextHookEx(0, code, wParam, lParam);
@@ -271,30 +254,11 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
(wParam == WM_NCRBUTTONDOWN))
{
HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
- HWND topMostBlocker = blocker;
- HWND prevForegroundWindow = ::GetForegroundWindow();
if (::IsWindow(blocker)) {
- ::BringWindowToTop(hWnd);
- }
- while (::IsWindow(blocker)) {
- topMostBlocker = blocker;
- ::BringWindowToTop(blocker);
- blocker = AwtWindow::GetModalBlocker(blocker);
- }
- if (::IsWindow(topMostBlocker)) {
- // no beep/flash if the mouse was clicked in the taskbar menu
- // or the dialog is currently inactive
- if ((::WindowFromPoint(mhs->pt) == hWnd) &&
- (prevForegroundWindow == topMostBlocker))
- {
- ::MessageBeep(MB_OK);
- // some heuristics: 3 times x 64 milliseconds
- AwtWindow::FlashWindowEx(topMostBlocker, 3, 64, FLASHW_CAPTION);
- }
- if (topMostBlocker != AwtToolkit::GetInstance().GetHWnd()) {
- ::BringWindowToTop(topMostBlocker);
- ::SetForegroundWindow(topMostBlocker);
- }
+ BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd);
+ PopupAllDialogs(hWnd, FALSE, ::GetForegroundWindow(), onTaskbar);
+ // return a nonzero value to prevent the system from passing
+ // the message to the target window procedure
return 1;
}
}
@@ -303,6 +267,63 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
return CallNextHookEx(0, nCode, wParam, lParam);
}
+/*
+ * The function goes through the heirarchy of the blocker dialogs and
+ * popups all the dialogs. Note that the function starts from the top
+ * blocker dialog and goes down to the dialog which is the bottom dialog.
+ * Using another traversal may cause to the flickering issue as a bottom
+ * dialog will cover a top dialog for some period of time.
+ */
+void AwtDialog::PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
+{
+ HWND blocker = AwtWindow::GetModalBlocker(dialog);
+ BOOL isBlocked = ::IsWindow(blocker);
+ if (isBlocked) {
+ PopupAllDialogs(blocker, isModalHook, prevFGWindow, onTaskbar);
+ }
+ PopupOneDialog(dialog, blocker, isModalHook, prevFGWindow, onTaskbar);
+}
+
+/*
+ * The function popups the dialog, it distinguishes non-blocked dialogs
+ * and activates the dialogs (sets as foreground window). If the dialog is
+ * blocked, then it changes the Z-order of the dialog.
+ */
+void AwtDialog::PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
+{
+ if (dialog == AwtToolkit::GetInstance().GetHWnd()) {
+ return;
+ }
+
+ // fix for 6494032
+ if (isModalHook && !::IsWindowVisible(dialog)) {
+ ::ShowWindow(dialog, SW_SHOWNA);
+ }
+
+ BOOL isBlocked = ::IsWindow(blocker);
+ UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
+
+ if (isBlocked) {
+ ::SetWindowPos(dialog, blocker, 0, 0, 0, 0, flags);
+ } else {
+ ::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags);
+ // no beep/flash if the mouse was clicked in the taskbar menu
+ // or the dialog is currently inactive
+ if (!isModalHook && !onTaskbar && (dialog == prevFGWindow)) {
+ AnimateModalBlocker(dialog);
+ }
+ ::BringWindowToTop(dialog);
+ ::SetForegroundWindow(dialog);
+ }
+}
+
+void AwtDialog::AnimateModalBlocker(HWND window)
+{
+ ::MessageBeep(MB_OK);
+ // some heuristics: 3 times x 64 milliseconds
+ AwtWindow::FlashWindowEx(window, 3, 64, FLASHW_CAPTION);
+}
+
LRESULT CALLBACK AwtDialog::MouseHookProc_NonTT(int nCode,
WPARAM wParam, LPARAM lParam)
{
diff --git a/src/windows/native/sun/windows/awt_Dialog.h b/src/windows/native/sun/windows/awt_Dialog.h
index 41ab6ad05..a697a8c9b 100644
--- a/src/windows/native/sun/windows/awt_Dialog.h
+++ b/src/windows/native/sun/windows/awt_Dialog.h
@@ -76,7 +76,7 @@ public:
* Thus we don't have to perform any transitive (a blocker of a blocker) checks.
*/
INLINE virtual BOOL IsFocusedWindowModalBlocker() {
- return (sm_focusedWindow != NULL) && (GetModalBlocker(sm_focusedWindow) == GetHWnd());
+ return (AwtComponent::GetFocusedWindow() != NULL) && (GetModalBlocker(AwtComponent::GetFocusedWindow()) == GetHWnd());
}
// finds and activates some window after the modal dialog is hidden
@@ -113,6 +113,9 @@ private:
*/
static void ModalPerformActivation(HWND hWnd);
+ static void PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
+ static void PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
+
public:
// WH_CBT hook procedure used in modality, prevents modal
@@ -129,6 +132,8 @@ public:
// example on browser's thread when running in Java Plugin
static LRESULT CALLBACK MouseHookProc_NonTT(int code,
WPARAM wParam, LPARAM lParam);
+
+ static void AnimateModalBlocker(HWND window);
};
#endif /* AWT_DIALOG_H */
diff --git a/src/windows/native/sun/windows/awt_FileDialog.cpp b/src/windows/native/sun/windows/awt_FileDialog.cpp
index 84339e40e..080e8d427 100644
--- a/src/windows/native/sun/windows/awt_FileDialog.cpp
+++ b/src/windows/native/sun/windows/awt_FileDialog.cpp
@@ -101,7 +101,8 @@ LRESULT CALLBACK FileDialogWndProc(HWND hWnd, UINT message,
}
}
- return ComCtl32Util::GetInstance().DefWindowProc(NULL, hWnd, message, wParam, lParam);
+ WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hWnd, NativeDialogWndProcProp));
+ return ComCtl32Util::GetInstance().DefWindowProc(lpfnWndProc, hWnd, message, wParam, lParam);
}
static UINT_PTR CALLBACK
@@ -135,16 +136,19 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
}
// subclass dialog's parent to receive additional messages
- ComCtl32Util::GetInstance().SubclassHWND(parent,
- FileDialogWndProc);
+ WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(parent,
+ FileDialogWndProc);
+ ::SetProp(parent, NativeDialogWndProcProp, reinterpret_cast<HANDLE>(lpfnWndProc));
break;
}
case WM_DESTROY: {
+ WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(parent, NativeDialogWndProcProp));
ComCtl32Util::GetInstance().UnsubclassHWND(parent,
FileDialogWndProc,
- NULL);
+ lpfnWndProc);
::RemoveProp(parent, ModalDialogPeerProp);
+ ::RemoveProp(parent, NativeDialogWndProcProp);
break;
}
case WM_NOTIFY: {
diff --git a/src/windows/native/sun/windows/awt_Frame.cpp b/src/windows/native/sun/windows/awt_Frame.cpp
index 60738e693..50f41d102 100644
--- a/src/windows/native/sun/windows/awt_Frame.cpp
+++ b/src/windows/native/sun/windows/awt_Frame.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,8 +39,6 @@
#include <sun_awt_windows_WEmbeddedFramePeer.h>
-BOOL isAppActive = FALSE;
-
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
*/
@@ -90,8 +88,10 @@ struct BlockedThreadStruct {
*/
jfieldID AwtFrame::handleID;
-jfieldID AwtFrame::stateID;
+
jfieldID AwtFrame::undecoratedID;
+jmethodID AwtFrame::getExtendedStateMID;
+jmethodID AwtFrame::setExtendedStateMID;
jmethodID AwtFrame::activateEmbeddingTopLevelMID;
@@ -110,6 +110,7 @@ AwtFrame::AwtFrame() {
m_isInputMethodWindow = FALSE;
m_isUndecorated = FALSE;
m_proxyFocusOwner = NULL;
+ m_lastProxiedFocusOwner = NULL;
m_actualFocusedWindow = NULL;
m_iconic = FALSE;
m_zoomed = FALSE;
@@ -232,7 +233,7 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent)
frame->InitPeerGraphicsConfig(env, self);
AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent);
} else {
- jint state = env->GetIntField(target, AwtFrame::stateID);
+ jint state = env->CallIntMethod(self, AwtFrame::getExtendedStateMID);
DWORD exStyle;
DWORD style;
@@ -285,7 +286,6 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent)
::GetSysColor(COLOR_WINDOWTEXT),
::GetSysColor(COLOR_WINDOWFRAME),
self);
-
/*
* Reshape here instead of during create, so that a
* WM_NCCALCSIZE is sent.
@@ -319,12 +319,13 @@ LRESULT CALLBACK AwtFrame::ProxyWindowProc(HWND hwnd, UINT message,
AwtComponent::GetComponentImpl(::GetParent(hwnd));
if (!parent || parent->GetProxyFocusOwner() != hwnd ||
- message == AwtComponent::WmAwtIsComponent)
+ message == AwtComponent::WmAwtIsComponent ||
+ message == WM_GETOBJECT)
{
return ComCtl32Util::GetInstance().DefWindowProc(NULL, hwnd, message, wParam, lParam);
}
- AwtComponent *p = NULL;
+ AwtComponent *focusOwner = NULL;
// IME and input language related messages need to be sent to a window
// which has the Java input focus
switch (message) {
@@ -342,16 +343,37 @@ LRESULT CALLBACK AwtFrame::ProxyWindowProc(HWND hwnd, UINT message,
case WM_IME_KEYUP:
case WM_INPUTLANGCHANGEREQUEST:
case WM_INPUTLANGCHANGE:
- p = AwtComponent::GetComponent(sm_focusOwner);
- if (p != NULL) {
- return p->WindowProc(message, wParam, lParam);
+ // TODO: when a Choice's list is dropped down and we're scrolling in
+ // the list WM_MOUSEWHEEL messages come to the poxy, not to the list. Why?
+ case WM_MOUSEWHEEL:
+ focusOwner = AwtComponent::GetComponent(parent->GetLastProxiedFocusOwner());
+ if (focusOwner != NULL) {
+ return focusOwner->WindowProc(message, wParam, lParam);
}
break;
+ case WM_SETFOCUS:
+ if (!sm_suppressFocusAndActivation && parent->IsEmbeddedFrame()) {
+ parent->AwtSetActiveWindow();
+ }
+ return 0;
+ case WM_KILLFOCUS:
+ if (!sm_suppressFocusAndActivation && parent->IsEmbeddedFrame()) {
+ AwtWindow::SynthesizeWmActivate(FALSE, parent->GetHWnd(), NULL);
+
+ } else if (sm_restoreFocusAndActivation) {
+ if (AwtComponent::GetFocusedWindow() != NULL) {
+ AwtWindow *focusedWindow = (AwtWindow*)GetComponent(AwtComponent::GetFocusedWindow());
+ if (focusedWindow != NULL) {
+ // Will just silently restore native focus & activation.
+ focusedWindow->AwtSetActiveWindow();
+ }
+ }
+ }
+ return 0;
case 0x0127: // WM_CHANGEUISTATE
case 0x0128: // WM_UPDATEUISTATE
return 0;
}
-
return parent->WindowProc(message, wParam, lParam);
CATCH_BAD_ALLOC_RET(0);
@@ -554,7 +576,6 @@ MsgRouting AwtFrame::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) {
if (m_grabbedWindow != NULL/* && !m_grabbedWindow->IsOneOfOwnersOf(this)*/) {
m_grabbedWindow->Ungrab();
}
-
if (!IsFocusableWindow() && (button & LEFT_BUTTON)) {
switch (hitTest) {
case HTTOP:
@@ -586,11 +607,6 @@ MsgRouting AwtFrame::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) {
return AwtWindow::WmNcMouseDown(hitTest, x, y, button);
}
-MsgRouting AwtFrame::WmWindowPosChanged(LPARAM windowPos) {
- return mrDoDefault;
-}
-
-
// Override AwtWindow::Reshape() to handle minimized/maximized
// frames (see 6525850, 4065534)
void AwtFrame::Reshape(int x, int y, int width, int height)
@@ -827,6 +843,11 @@ MsgRouting AwtFrame::WmGetMinMaxInfo(LPMINMAXINFO lpmmi)
MsgRouting AwtFrame::WmSize(UINT type, int w, int h)
{
+ currentWmSizeState = type;
+ if (currentWmSizeState == SIZE_MINIMIZED) {
+ UpdateSecurityWarningVisibility();
+ }
+
if (m_ignoreWmSize) {
return mrDoDefault;
}
@@ -883,6 +904,11 @@ MsgRouting AwtFrame::WmSize(UINT type, int w, int h)
if (changed != 0) {
DTRACE_PRINTLN2("AwtFrame::WmSize: reporting state change %x -> %x",
oldState, newState);
+
+ // sync target with peer
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ env->CallVoidMethod(GetPeer(env), AwtFrame::setExtendedStateMID, newState);
+
// report (de)iconification to old clients
if (changed & java_awt_Frame_ICONIFIED) {
if (newState & java_awt_Frame_ICONIFIED) {
@@ -907,33 +933,16 @@ MsgRouting AwtFrame::WmSize(UINT type, int w, int h)
MsgRouting AwtFrame::WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
{
jint type;
- BOOL doActivateFrame = TRUE;
if (nState != WA_INACTIVE) {
- if (!::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) {
- ::SetFocus(NULL); // The KeyboardFocusManager will set focus later
- type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS;
- isAppActive = TRUE;
- sm_focusedWindow = GetHWnd();
-
- /*
- * Fix for 4823903.
- * If the window to be focused is actually not this Frame
- * and it's visible then send it WM_ACTIVATE.
- */
- if (m_actualFocusedWindow != NULL) {
- HWND hwnd = m_actualFocusedWindow->GetHWnd();
-
- if (hwnd != NULL && ::IsWindowVisible(hwnd)) {
-
- ::SendMessage(hwnd, WM_ACTIVATE, MAKEWPARAM(nState, fMinimized), (LPARAM)opposite);
- doActivateFrame = FALSE;
- }
- m_actualFocusedWindow = NULL;
- }
- } else {
- doActivateFrame = FALSE;
+ if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())) ||
+ CheckActivateActualFocusedWindow(opposite))
+ {
+ return mrConsume;
}
+ type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS;
+ AwtComponent::SetFocusedWindow(GetHWnd());
+
} else {
if (!::IsWindow(AwtWindow::GetModalBlocker(opposite))) {
// If deactivation happens because of press on grabbing
@@ -955,37 +964,63 @@ MsgRouting AwtFrame::WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
}
}
}
+ CheckRetainActualFocusedWindow(opposite);
- // If actual focused window is not this Frame
- if (sm_focusedWindow != GetHWnd()) {
+ type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS;
+ AwtComponent::SetFocusedWindow(NULL);
+ sm_focusOwner = NULL;
+ }
+ }
- // Check that the Frame is going to be really inactive (i.e. the opposite is not its owned window)
- if (opposite != NULL) {
- AwtWindow *wOpposite = (AwtWindow *)AwtComponent::GetComponent(opposite);
+ SendWindowEvent(type, opposite);
+ return mrConsume;
+}
- if (wOpposite != NULL &&
- wOpposite->GetOwningFrameOrDialog() != this)
- {
- AwtWindow *window = (AwtWindow *)AwtComponent::GetComponent(sm_focusedWindow);
+BOOL AwtFrame::CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd)
+{
+ if (m_actualFocusedWindow != NULL) {
+ HWND hwnd = m_actualFocusedWindow->GetHWnd();
+ if (hwnd != NULL && ::IsWindowVisible(hwnd)) {
+ SynthesizeWmActivate(TRUE, hwnd, deactivatedOpositeHWnd);
+ return TRUE;
+ }
+ m_actualFocusedWindow = NULL;
+ }
+ return FALSE;
+}
- // If actual focused window is one of Frame's owned windows
- if (window != NULL && window->GetOwningFrameOrDialog() == this) {
- m_actualFocusedWindow = window;
- }
- }
+void AwtFrame::CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd)
+{
+ // If actual focused window is not this Frame
+ if (AwtComponent::GetFocusedWindow() != GetHWnd()) {
+ // Make sure the actual focused window is an owned window of this frame
+ AwtWindow *focusedWindow = (AwtWindow *)AwtComponent::GetComponent(AwtComponent::GetFocusedWindow());
+ if (focusedWindow != NULL && focusedWindow->GetOwningFrameOrDialog() == this) {
+
+ // Check that the opposite window is not this frame, nor an owned window of this frame
+ if (activatedOpositeHWnd != NULL) {
+ AwtWindow *oppositeWindow = (AwtWindow *)AwtComponent::GetComponent(activatedOpositeHWnd);
+ if (oppositeWindow && oppositeWindow != this &&
+ oppositeWindow->GetOwningFrameOrDialog() != this)
+ {
+ m_actualFocusedWindow = focusedWindow;
}
+ } else {
+ m_actualFocusedWindow = focusedWindow;
}
-
- type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS;
- isAppActive = FALSE;
- sm_focusedWindow = NULL;
}
}
+}
- if (doActivateFrame) {
- SendWindowEvent(type, opposite);
+BOOL AwtFrame::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
+{
+ if (hittest == HTCLIENT) {
+ // Don't let the actualFocusedWindow to steal focus if:
+ // a) the frame is clicked in its client area;
+ // b) focus is requested to some of the frame's child.
+ m_actualFocusedWindow = NULL;
}
- return mrConsume;
+ return AwtWindow::AwtSetActiveWindow(isMouseEventCause);
}
MsgRouting AwtFrame::WmEnterMenuLoop(BOOL isTrackPopupMenu)
@@ -1161,60 +1196,6 @@ LRESULT AwtFrame::WinThreadExecProc(ExecuteArgs * args)
return 0L;
}
-/*
- * hWndLostFocus - the opposite component
- * Returns TRUE if WM_SETFOCUS may be processed further, otherwise FALSE.
- */
-BOOL AwtFrame::activateEmbeddedFrameOnSetFocus(HWND hWndLostFocus) {
-
- // If the EmbeddedFrame is not yet active, then this is either:
- // - requesting focus on smth in the EmbeddedFrame, or
- // - Alt hitting in IE while its menu is active (see 6374321).
- // In both these cases we get WM_SETFOCUS without WM_ACTIVATE
- // on the EmbeddedFrame.
- if (sm_focusedWindow != GetHWnd()) {
- HWND oppositeToplevelHWnd = AwtComponent::GetTopLevelParentForWindow(hWndLostFocus);
-
- // As we get WM_SETFOCUS from the native system we expect
- // the native toplevel be set to the active window.
- HWND activeWindowHWnd = ::GetActiveWindow();
- DASSERT(activeWindowHWnd == ::GetAncestor(GetHWnd(), GA_ROOT));
-
- // See 6538154.
- ::BringWindowToTop(activeWindowHWnd);
- ::SetForegroundWindow(activeWindowHWnd);
-
- SynthesizeWmActivate(TRUE, oppositeToplevelHWnd);
-
- return FALSE;
- }
- // If the EmbeddedFrame is already active, then this is a mouse click
- // or activation (by Alt-Tab, start etc).
- return TRUE;
-}
-
-/*
- * hWndGotFocus - the opposite component
- * Returns TRUE if WM_KILLFOCUS may be processed further, otherwise FALSE.
- */
-BOOL AwtFrame::deactivateEmbeddedFrameOnKillFocus(HWND hWndGotFocus) {
- HWND oppositeToplevelHWnd = AwtComponent::GetTopLevelParentForWindow(hWndGotFocus);
-
- if (oppositeToplevelHWnd != sm_focusedWindow) {
- SynthesizeWmActivate(FALSE, oppositeToplevelHWnd);
- }
- return TRUE;
-}
-
-/*
- * Execute on Toolkit only.
- */
-void AwtFrame::SynthesizeWmActivate(BOOL doActivate, HWND opposite) {
- if (::IsWindowVisible(GetHWnd())) {
- ::SendMessage(GetHWnd(), WM_ACTIVATE, MAKEWPARAM(doActivate ? WA_ACTIVE : WA_INACTIVE, FALSE), (LPARAM) opposite);
- }
-}
-
void AwtFrame::_SynthesizeWmActivate(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -1229,7 +1210,7 @@ void AwtFrame::_SynthesizeWmActivate(void *param)
JNI_CHECK_PEER_GOTO(self, ret);
frame = (AwtFrame *)pData;
- frame->SynthesizeWmActivate(doActivate, NULL);
+ SynthesizeWmActivate(doActivate, frame->GetHWnd(), NULL);
ret:
env->DeleteGlobalRef(self);
@@ -1594,7 +1575,7 @@ void AwtFrame::_NotifyModalBlocked(void *param)
extern "C" {
/*
- * Class: sun_awt_windows_WFramePeer
+ * Class: java_awt_Frame
* Method: initIDs
* Signature: ()V
*/
@@ -1603,9 +1584,6 @@ Java_java_awt_Frame_initIDs(JNIEnv *env, jclass cls)
{
TRY;
- AwtFrame::stateID = env->GetFieldID(cls, "state", "I");
- DASSERT(AwtFrame::stateID != NULL);
-
AwtFrame::undecoratedID = env->GetFieldID(cls,"undecorated","Z");
DASSERT(AwtFrame::undecoratedID != NULL);
@@ -1614,6 +1592,25 @@ Java_java_awt_Frame_initIDs(JNIEnv *env, jclass cls)
/*
* Class: sun_awt_windows_WFramePeer
+ * Method: initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WFramePeer_initIDs(JNIEnv *env, jclass cls)
+{
+ TRY;
+
+ AwtFrame::setExtendedStateMID = env->GetMethodID(cls, "setExtendedState", "(I)V");
+ AwtFrame::getExtendedStateMID = env->GetMethodID(cls, "getExtendedState", "()I");
+
+ DASSERT(AwtFrame::setExtendedStateMID);
+ DASSERT(AwtFrame::getExtendedStateMID);
+
+ CATCH_BAD_ALLOC;
+}
+
+/*
+ * Class: sun_awt_windows_WFramePeer
* Method: setState
* Signature: (I)V
*/
diff --git a/src/windows/native/sun/windows/awt_Frame.h b/src/windows/native/sun/windows/awt_Frame.h
index 3634f9592..a5821329e 100644
--- a/src/windows/native/sun/windows/awt_Frame.h
+++ b/src/windows/native/sun/windows/awt_Frame.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,14 +48,14 @@ public:
FRAME_SETMENUBAR
};
- /* int handle field for sun.awt.windows.WEmbeddedFrame */
+ /* java.awt.Frame fields and method IDs */
+ static jfieldID undecoratedID;
+
+ /* sun.awt.windows.WEmbeddedFrame fields and method IDs */
static jfieldID handleID;
- /* int state field for java.awt.Frame */
- static jfieldID stateID;
-
- /* boolean undecorated field for java.awt.Frame */
- static jfieldID undecoratedID;
+ static jmethodID setExtendedStateMID;
+ static jmethodID getExtendedStateMID;
/* method id for WEmbeddedFrame.requestActivate() method */
static jmethodID activateEmbeddingTopLevelMID;
@@ -108,7 +108,6 @@ public:
MsgRouting WmNcMouseDown(WPARAM hitTest, int x, int y, int button);
MsgRouting WmNcMouseUp(WPARAM hitTest, int x, int y, int button);
MsgRouting WmGetIcon(WPARAM iconType, LRESULT& retVal);
- MsgRouting WmWindowPosChanged(LPARAM windowPos);
MsgRouting WmShowWindow(BOOL show, UINT status);
virtual MsgRouting WmSysCommand(UINT uCmdType, int xPos, int yPos);
@@ -133,11 +132,6 @@ public:
// adjusts the IME candidate window position if needed
void AdjustCandidateWindowPos();
- void SynthesizeWmActivate(BOOL doActivate, HWND opposite);
-
- BOOL activateEmbeddedFrameOnSetFocus(HWND hWndLostFocus);
- BOOL deactivateEmbeddedFrameOnKillFocus(HWND hWndGotFocus);
-
// invoked on Toolkit thread
static jobject _GetBoundsPrivate(void *param);
@@ -153,6 +147,14 @@ public:
virtual void Reshape(int x, int y, int width, int height);
+ virtual BOOL AwtSetActiveWindow(BOOL isMouseEventCause = FALSE, UINT hittest = HTCLIENT);
+
+ void CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd);
+ BOOL CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd);
+
+ INLINE HWND GetLastProxiedFocusOwner() { return m_lastProxiedFocusOwner; }
+ INLINE void SetLastProxiedFocusOwner(HWND hwnd) { m_lastProxiedFocusOwner = hwnd; }
+
protected:
/* The frame is undecorated. */
BOOL m_isUndecorated;
@@ -189,6 +191,10 @@ private:
or an AwtDialog (or one of its children) has the logical input focus. */
HWND m_proxyFocusOwner;
+ /* Retains the last/current sm_focusOwner proxied. Actually, it should be
+ * a component of an owned window last/currently active. */
+ HWND m_lastProxiedFocusOwner;
+
/*
* Fix for 4823903.
* Retains a focus proxied window to set the focus correctly
diff --git a/src/windows/native/sun/windows/awt_InputMethod.cpp b/src/windows/native/sun/windows/awt_InputMethod.cpp
index bd78cdaf3..f23e1e1f6 100644
--- a/src/windows/native/sun/windows/awt_InputMethod.cpp
+++ b/src/windows/native/sun/windows/awt_InputMethod.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -176,7 +176,7 @@ Java_sun_awt_windows_WInputMethod_handleNativeIMEEvent(JNIEnv *env, jobject self
java_awt_event_KeyEvent_CHAR_UNDEFINED,
unicodeChar,
modifiers,
- java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN,
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
&msg);
} else {
MSG* pCopiedMsg = new MSG;
diff --git a/src/windows/native/sun/windows/awt_KeyEvent.cpp b/src/windows/native/sun/windows/awt_KeyEvent.cpp
index cc795cfc8..0559741d4 100644
--- a/src/windows/native/sun/windows/awt_KeyEvent.cpp
+++ b/src/windows/native/sun/windows/awt_KeyEvent.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-1999 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,10 @@
jfieldID AwtKeyEvent::keyCodeID;
jfieldID AwtKeyEvent::keyCharID;
+jfieldID AwtKeyEvent::rawCodeID;
+jfieldID AwtKeyEvent::primaryLevelUnicodeID;
+jfieldID AwtKeyEvent::scancodeID;
+jfieldID AwtKeyEvent::extendedKeyCodeID;
/************************************************************************
* AwtKeyEvent native methods
@@ -45,9 +49,18 @@ Java_java_awt_event_KeyEvent_initIDs(JNIEnv *env, jclass cls) {
AwtKeyEvent::keyCodeID = env->GetFieldID(cls, "keyCode", "I");
AwtKeyEvent::keyCharID = env->GetFieldID(cls, "keyChar", "C");
+ AwtKeyEvent::rawCodeID = env->GetFieldID(cls, "rawCode", "J");
+ AwtKeyEvent::primaryLevelUnicodeID = env->GetFieldID(cls, "primaryLevelUnicode", "J");
+ AwtKeyEvent::scancodeID = env->GetFieldID(cls, "scancode", "J");
+ AwtKeyEvent::extendedKeyCodeID = env->GetFieldID(cls, "extendedKeyCode", "J");
+
DASSERT(AwtKeyEvent::keyCodeID != NULL);
DASSERT(AwtKeyEvent::keyCharID != NULL);
+ DASSERT(AwtKeyEvent::rawCodeID != NULL);
+ DASSERT(AwtKeyEvent::primaryLevelUnicodeID != NULL);
+ DASSERT(AwtKeyEvent::scancodeID != NULL);
+ DASSERT(AwtKeyEvent::extendedKeyCodeID != NULL);
CATCH_BAD_ALLOC;
}
diff --git a/src/windows/native/sun/windows/awt_KeyEvent.h b/src/windows/native/sun/windows/awt_KeyEvent.h
index 2489051ea..0e47eacec 100644
--- a/src/windows/native/sun/windows/awt_KeyEvent.h
+++ b/src/windows/native/sun/windows/awt_KeyEvent.h
@@ -39,7 +39,10 @@ public:
/* java.awt.KeyEvent field ids */
static jfieldID keyCodeID;
static jfieldID keyCharID;
-
+ static jfieldID rawCodeID;
+ static jfieldID primaryLevelUnicodeID;
+ static jfieldID scancodeID;
+ static jfieldID extendedKeyCodeID;
};
#endif // AWT_KEYEVENT_H
diff --git a/src/windows/native/sun/windows/awt_KeyboardFocusManager.cpp b/src/windows/native/sun/windows/awt_KeyboardFocusManager.cpp
index 907f0a303..146dd0398 100644
--- a/src/windows/native/sun/windows/awt_KeyboardFocusManager.cpp
+++ b/src/windows/native/sun/windows/awt_KeyboardFocusManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2004 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,30 +24,20 @@
*/
#include "awt.h"
-#include "awt_KeyboardFocusManager.h"
#include "awt_Component.h"
#include "awt_Toolkit.h"
#include <java_awt_KeyboardFocusManager.h>
-
-jclass AwtKeyboardFocusManager::keyboardFocusManagerCls;
-jmethodID AwtKeyboardFocusManager::shouldNativelyFocusHeavyweightMID;
-jmethodID AwtKeyboardFocusManager::heavyweightButtonDownMID;
-jmethodID AwtKeyboardFocusManager::markClearGlobalFocusOwnerMID;
-jmethodID AwtKeyboardFocusManager::removeLastFocusRequestMID;
-jfieldID AwtKeyboardFocusManager::isProxyActive;
-jmethodID AwtKeyboardFocusManager::processSynchronousTransfer;
+#include <jni.h>
static jobject getNativeFocusState(JNIEnv *env, void*(*ftn)()) {
- jobject lFocusState = NULL;
+ jobject gFocusState = (jobject)AwtToolkit::GetInstance().SyncCall(ftn);
- jobject gFocusState = reinterpret_cast<jobject>(AwtToolkit::GetInstance().
- InvokeFunction(ftn));
if (gFocusState != NULL) {
- lFocusState = env->NewLocalRef(gFocusState);
+ jobject lFocusState = env->NewLocalRef(gFocusState);
env->DeleteGlobalRef(gFocusState);
+ return lFocusState;
}
-
- return lFocusState;
+ return NULL;
}
extern "C" {
@@ -61,53 +51,35 @@ JNIEXPORT void JNICALL
Java_java_awt_KeyboardFocusManager_initIDs
(JNIEnv *env, jclass cls)
{
- TRY;
-
- AwtKeyboardFocusManager::keyboardFocusManagerCls = (jclass)
- env->NewGlobalRef(cls);
- AwtKeyboardFocusManager::shouldNativelyFocusHeavyweightMID =
- env->GetStaticMethodID(cls, "shouldNativelyFocusHeavyweight",
- "(Ljava/awt/Component;Ljava/awt/Component;ZZJLsun/awt/CausedFocusEvent$Cause;)I");
- AwtKeyboardFocusManager::heavyweightButtonDownMID =
- env->GetStaticMethodID(cls, "heavyweightButtonDown",
- "(Ljava/awt/Component;J)V");
- AwtKeyboardFocusManager::markClearGlobalFocusOwnerMID =
- env->GetStaticMethodID(cls, "markClearGlobalFocusOwner",
- "()Ljava/awt/Window;");
- AwtKeyboardFocusManager::removeLastFocusRequestMID =
- env->GetStaticMethodID(cls, "removeLastFocusRequest",
- "(Ljava/awt/Component;)V");
-
- AwtKeyboardFocusManager::processSynchronousTransfer =
- env->GetStaticMethodID(cls, "processSynchronousLightweightTransfer",
- "(Ljava/awt/Component;Ljava/awt/Component;ZZJ)Z");
+}
- jclass keyclass = env->FindClass("java/awt/event/KeyEvent");
- DASSERT (keyclass != NULL);
+/*
+ * Class: sun_awt_windows_WKeyboardFocusManagerPeer
+ * Method: setNativeFocusOwner
+ * Signature: (Lsun/awt/windows/WComponentPeer)
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WKeyboardFocusManagerPeer_setNativeFocusOwner
+ (JNIEnv *env, jclass cls, jobject compPeer)
+{
+ TRY;
- AwtKeyboardFocusManager::isProxyActive =
- env->GetFieldID(keyclass, "isProxyActive", "Z");
+ jobject peerGlobalRef = env->NewGlobalRef(compPeer);
- env->DeleteLocalRef(keyclass);
+ AwtToolkit::GetInstance().SyncCall(AwtComponent::SetNativeFocusOwner,
+ (void*)peerGlobalRef);
+ // peerGlobalRef is deleted in SetNativeFocusOwner
- DASSERT(AwtKeyboardFocusManager::keyboardFocusManagerCls != NULL);
- DASSERT(AwtKeyboardFocusManager::shouldNativelyFocusHeavyweightMID !=
- NULL);
- DASSERT(AwtKeyboardFocusManager::heavyweightButtonDownMID != NULL);
- DASSERT(AwtKeyboardFocusManager::markClearGlobalFocusOwnerMID != NULL);
- DASSERT(AwtKeyboardFocusManager::removeLastFocusRequestMID != NULL);
- DASSERT(AwtKeyboardFocusManager::processSynchronousTransfer != NULL);
CATCH_BAD_ALLOC;
}
-
/*
- * Class: sun_awt_KeyboardFocusManagerPeerImpl
+ * Class: sun_awt_windows_WKeyboardFocusManagerPeer
* Method: getNativeFocusOwner
- * Signature: ()Ljava/awt/Component;
+ * Signature: (Lsun/awt/windows/WComponentPeer)
*/
JNIEXPORT jobject JNICALL
-Java_sun_awt_KeyboardFocusManagerPeerImpl_getNativeFocusOwner
+Java_sun_awt_windows_WKeyboardFocusManagerPeer_getNativeFocusOwner
(JNIEnv *env, jclass cls)
{
TRY;
@@ -118,12 +90,12 @@ Java_sun_awt_KeyboardFocusManagerPeerImpl_getNativeFocusOwner
}
/*
- * Class: sun_awt_KeyboardFocusManagerPeerImpl
+ * Class: sun_awt_windows_WKeyboardFocusManagerPeer
* Method: getNativeFocusedWindow
* Signature: ()Ljava/awt/Window;
*/
JNIEXPORT jobject JNICALL
-Java_sun_awt_KeyboardFocusManagerPeerImpl_getNativeFocusedWindow
+Java_sun_awt_windows_WKeyboardFocusManagerPeer_getNativeFocusedWindow
(JNIEnv *env, jclass cls)
{
TRY;
@@ -132,21 +104,4 @@ Java_sun_awt_KeyboardFocusManagerPeerImpl_getNativeFocusedWindow
CATCH_BAD_ALLOC_RET(NULL);
}
-
-/*
- * Class: sun_awt_KeyboardFocusManagerPeerImpl
- * Method: clearNativeGlobalFocusOwner
- * Signature: (Ljava/awt/Window;)V
- */
-JNIEXPORT void JNICALL
-Java_sun_awt_KeyboardFocusManagerPeerImpl_clearNativeGlobalFocusOwner
- (JNIEnv *env, jobject self, jobject activeWindow)
-{
- TRY;
-
- AwtToolkit::GetInstance().InvokeFunction
- ((void*(*)(void))AwtComponent::ClearGlobalFocusOwner);
-
- CATCH_BAD_ALLOC;
-}
}
diff --git a/src/windows/native/sun/windows/awt_KeyboardFocusManager.h b/src/windows/native/sun/windows/awt_KeyboardFocusManager.h
deleted file mode 100644
index 26087c21a..000000000
--- a/src/windows/native/sun/windows/awt_KeyboardFocusManager.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2001-2002 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.
- */
-
-#ifndef AWT_KEYBOARDFOCUSMANAGER_H
-#define AWT_KEYBOARDFOCUSMANAGER_H
-
-#include <jni.h>
-
-class AwtKeyboardFocusManager {
-public:
-
- static jclass keyboardFocusManagerCls;
- static jmethodID shouldNativelyFocusHeavyweightMID;
- static jmethodID heavyweightButtonDownMID;
- static jmethodID markClearGlobalFocusOwnerMID;
- static jmethodID removeLastFocusRequestMID;
- static jfieldID isProxyActive;
- static jmethodID processSynchronousTransfer;
-};
-
-#endif // AWT_KEYBOARDFOCUSMANAGER_H
diff --git a/src/windows/native/sun/windows/awt_List.cpp b/src/windows/native/sun/windows/awt_List.cpp
index 20844de78..453025ec9 100644
--- a/src/windows/native/sun/windows/awt_List.cpp
+++ b/src/windows/native/sun/windows/awt_List.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
*/
#include "awt_List.h"
-#include "awt_KeyboardFocusManager.h"
#include "awt_Canvas.h"
#include "awt_Dimension.h"
#include "awt_Toolkit.h"
@@ -154,28 +153,6 @@ done:
return c;
}
-BOOL AwtList::ActMouseMessage(MSG * pMsg) {
- if (!IsFocusingMessage(pMsg->message)) {
- return FALSE;
- }
-
- if (pMsg->message == WM_LBUTTONDOWN) {
- LONG item = static_cast<LONG>(SendListMessage(LB_ITEMFROMPOINT, 0, pMsg->lParam));
- if (item != LB_ERR) {
- if (isMultiSelect) {
- if (IsItemSelected(item)) {
- Deselect(item);
- } else {
- Select(item);
- }
- } else {
- Select(item);
- }
- }
- }
- return TRUE;
-}
-
void AwtList::SetDragCapture(UINT flags)
{
// don't want to interfere with other controls
@@ -473,17 +450,11 @@ AwtList::WmMouseDown(UINT flags, int x, int y, int button)
}
/*
- * Fix for 6240202. List being inside a non-focusable Window (or non-focusable List
- * being a single component inside a focusable Window) won't trigger ActionEvent by
- * double click. All focus events will be filtered (in the AWT focus hook) for such
- * a Window containing the List. In such a case OS Windows won't generate WM_COMMAND
- * (and no WmNotify() will be called for the List). Here we call WmCommand()
- * synthetically.
+ * As we consume WM_LBUTONDOWN the list won't trigger ActionEvent by double click.
+ * We trigger it ourselves. (see also 6240202)
*/
int clickCount = GetClickCount();
- if (button == LEFT_BUTTON && clickCount >= 2 && clickCount % 2 == 0 &&
- !GetContainer()->IsFocusableWindow())
- {
+ if (button == LEFT_BUTTON && clickCount >= 2 && clickCount % 2 == 0) {
WmCommand(0, GetListHandle(), LBN_DBLCLK);
}
return mrResult;
@@ -500,67 +471,32 @@ AwtList::WmCtlColor(HDC hDC, HWND hCtrl, UINT ctlColor, HBRUSH& retBrush)
return mrConsume;
}
-// Override WmSetFocus and WmKillFocus so that they operate on the List handle
-// instead of the wrapper handle. Otherwise, the methods are the same as their
-// AwtComponent counterparts.
-
-MsgRouting AwtList::WmSetFocus(HWND hWndLostFocus) {
- if (sm_focusOwner == GetListHandle()) {
- sm_realFocusOpposite = NULL;
- return mrConsume;
- }
-
- sm_focusOwner = GetListHandle();
-
- if (sm_realFocusOpposite != NULL) {
- hWndLostFocus = sm_realFocusOpposite;
- sm_realFocusOpposite = NULL;
- }
-
- SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus);
-
- return mrDoDefault;
+BOOL AwtList::IsFocusingMouseMessage(MSG *pMsg)
+{
+ return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK;
}
-MsgRouting AwtList::WmKillFocus(HWND hWndGotFocus) {
- if (sm_focusOwner != NULL && sm_focusOwner == hWndGotFocus) {
- return mrConsume;
- }
-
- if (sm_focusOwner != GetListHandle()) {
- if (sm_focusOwner != NULL) {
- if (hWndGotFocus != NULL &&
- AwtComponent::GetComponent(hWndGotFocus) != NULL)
- {
- sm_realFocusOpposite = sm_focusOwner;
+MsgRouting AwtList::HandleEvent(MSG *msg, BOOL synthetic)
+{
+ if (IsFocusingMouseMessage(msg)) {
+ LONG item = static_cast<LONG>(SendListMessage(LB_ITEMFROMPOINT, 0, msg->lParam));
+ if (item != LB_ERR) {
+ if (isMultiSelect) {
+ if (IsItemSelected(item)) {
+ Deselect(item);
+ } else {
+ Select(item);
}
- ::SendMessage(sm_focusOwner, WM_KILLFOCUS, (WPARAM)hWndGotFocus,
- 0);
+ } else {
+ Select(item);
+ }
}
+ delete msg;
return mrConsume;
}
-
- sm_focusOwner = NULL;
-
- SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus);
-
- return mrDoDefault;
-}
-
-MsgRouting AwtList::HandleEvent(MSG *msg, BOOL synthetic)
-{
- if (AwtComponent::sm_focusOwner != GetListHandle() &&
- (msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONDBLCLK))
- {
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject target = GetTarget(env);
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::heavyweightButtonDownMID,
- target, ((jlong)msg->time) & 0xFFFFFFFF);
- env->DeleteLocalRef(target);
+ if (msg->message == WM_KEYDOWN && msg->wParam == VK_RETURN) {
+ WmNotify(LBN_DBLCLK);
}
-
return AwtComponent::HandleEvent(msg, synthetic);
}
@@ -607,15 +543,6 @@ AwtList::WmNotify(UINT notifyCode)
return mrDoDefault;
}
-MsgRouting
-AwtList::WmKeyDown(UINT wkey, UINT repCnt, UINT flags, BOOL system)
-{
- if (wkey == VK_RETURN) {
- WmNotify(LBN_DBLCLK);
- }
- return AwtComponent::WmKeyDown(wkey, repCnt, flags, system);
-}
-
BOOL AwtList::InheritsNativeMouseWheelBehavior() {return true;}
jint AwtList::_GetMaxWidth(void *param)
diff --git a/src/windows/native/sun/windows/awt_List.h b/src/windows/native/sun/windows/awt_List.h
index 832e41c2c..5389c6334 100644
--- a/src/windows/native/sun/windows/awt_List.h
+++ b/src/windows/native/sun/windows/awt_List.h
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -97,8 +97,6 @@ public:
}
}
- BOOL ActMouseMessage(MSG* pMsg);
-
// Netscape : Change the font on the list and redraw the
// items nicely.
virtual void SetFont(AwtFont *pFont);
@@ -116,7 +114,6 @@ public:
MsgRouting WmMouseDown(UINT flags, int x, int y, int button);
MsgRouting WmMouseUp(UINT flags, int x, int y, int button);
MsgRouting WmNotify(UINT notifyCode);
- MsgRouting WmKeyDown(UINT vkey, UINT repCnt, UINT flags, BOOL system);
/* for multifont list */
MsgRouting OwnerDrawItem(UINT ctrlId, DRAWITEMSTRUCT& drawInfo);
@@ -127,8 +124,6 @@ public:
MsgRouting WmCtlColor(HDC hDC, HWND hCtrl, UINT ctlColor,
HBRUSH& retBrush);
- MsgRouting WmSetFocus(HWND hWndLostFocus);
- MsgRouting WmKillFocus(HWND hWndGotFocus);
MsgRouting HandleEvent(MSG *msg, BOOL synthetic);
@@ -170,6 +165,8 @@ public:
virtual BOOL InheritsNativeMouseWheelBehavior();
+ virtual BOOL IsFocusingMouseMessage(MSG *pMsg);
+
// some methods called on Toolkit thread
static jint _GetMaxWidth(void *param);
static void _UpdateMaxItemWidth(void *param);
diff --git a/src/windows/native/sun/windows/awt_Panel.cpp b/src/windows/native/sun/windows/awt_Panel.cpp
index 62c90bf54..5f0e42673 100644
--- a/src/windows/native/sun/windows/awt_Panel.cpp
+++ b/src/windows/native/sun/windows/awt_Panel.cpp
@@ -34,70 +34,6 @@
jfieldID AwtPanel::insets_ID;
-static char* AWTPANEL_RESTACK_MSG_1 = "Peers array is null";
-static char* AWTPANEL_RESTACK_MSG_2 = "Peer null in JNI";
-static char* AWTPANEL_RESTACK_MSG_3 = "Native resources unavailable";
-static char* AWTPANEL_RESTACK_MSG_4 = "Child peer is null";
-
-void* AwtPanel::Restack(void * param) {
- TRY;
-
- JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobjectArray peers = (jobjectArray)param;
-
- int peerCount = env->GetArrayLength(peers);
- if (peerCount < 1) {
- env->DeleteGlobalRef(peers);
- return AWTPANEL_RESTACK_MSG_1;
- }
-
- jobject self = env->GetObjectArrayElement(peers, 0);
- // It's entirely possible that our native resources have been destroyed
- // before our java peer - if we're dispose()d, for instance.
- // Alert caller w/ IllegalComponentStateException.
- if (self == NULL) {
- env->DeleteGlobalRef(peers);
- return AWTPANEL_RESTACK_MSG_2;
- }
- PDATA pData = JNI_GET_PDATA(self);
- if (pData == NULL) {
- env->DeleteGlobalRef(peers);
- env->DeleteLocalRef(self);
- return AWTPANEL_RESTACK_MSG_3;
- }
-
- AwtPanel* panel = (AwtPanel*)pData;
-
- HWND prevWindow = 0;
-
- for (int i = 1; i < peerCount; i++) {
- jobject peer = env->GetObjectArrayElement(peers, i);
- if (peer == NULL) {
- // Nonsense
- env->DeleteGlobalRef(peers);
- env->DeleteLocalRef(self);
- return AWTPANEL_RESTACK_MSG_4;
- }
- PDATA child_pData = JNI_GET_PDATA(peer);
- if (child_pData == NULL) {
- env->DeleteLocalRef(peer);
- env->DeleteGlobalRef(peers);
- env->DeleteLocalRef(self);
- return AWTPANEL_RESTACK_MSG_3;
- }
- AwtComponent* child_comp = (AwtComponent*)child_pData;
- ::SetWindowPos(child_comp->GetHWnd(), prevWindow, 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS);
- prevWindow = child_comp->GetHWnd();
- env->DeleteLocalRef(peer);
- }
- env->DeleteGlobalRef(peers);
- env->DeleteLocalRef(self);
-
- CATCH_BAD_ALLOC_RET("Allocation error");
- return NULL;
-}
-
/************************************************************************
* AwtPanel native methods
*/
@@ -116,18 +52,4 @@ Java_sun_awt_windows_WPanelPeer_initIDs(JNIEnv *env, jclass cls) {
CATCH_BAD_ALLOC;
}
-JNIEXPORT void JNICALL
-Java_sun_awt_windows_WPanelPeer_pRestack(JNIEnv *env, jobject self, jobjectArray peers) {
-
- TRY;
-
- const char * error = (const char*)AwtToolkit::GetInstance().InvokeFunction(AwtPanel::Restack, env->NewGlobalRef(peers));
- if (error != NULL) {
- JNU_ThrowByName(env, "java/awt/IllegalComponentStateException", error);
- }
-
- CATCH_BAD_ALLOC;
-}
-
-
} /* extern "C" */
diff --git a/src/windows/native/sun/windows/awt_Panel.h b/src/windows/native/sun/windows/awt_Panel.h
index 2e9ed6649..93084c716 100644
--- a/src/windows/native/sun/windows/awt_Panel.h
+++ b/src/windows/native/sun/windows/awt_Panel.h
@@ -35,11 +35,8 @@
class AwtPanel {
public:
- static void* Restack(void * param);
-
/* java.awt.Panel field ids */
static jfieldID insets_ID;
-
};
#endif // AWT_PANEL_H
diff --git a/src/windows/native/sun/windows/awt_PrintDialog.cpp b/src/windows/native/sun/windows/awt_PrintDialog.cpp
index 762ae2673..14c7750cb 100644
--- a/src/windows/native/sun/windows/awt_PrintDialog.cpp
+++ b/src/windows/native/sun/windows/awt_PrintDialog.cpp
@@ -65,7 +65,8 @@ LRESULT CALLBACK PrintDialogWndProc(HWND hWnd, UINT message,
}
}
- return ComCtl32Util::GetInstance().DefWindowProc(NULL, hWnd, message, wParam, lParam);
+ WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hWnd, NativeDialogWndProcProp));
+ return ComCtl32Util::GetInstance().DefWindowProc(lpfnWndProc, hWnd, message, wParam, lParam);
}
static UINT_PTR CALLBACK
@@ -87,7 +88,7 @@ PrintDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
DWORD style = ::GetClassLong(hdlg, GCL_STYLE);
::SetClassLong(hdlg,GCL_STYLE, style & ~CS_SAVEBITS);
- ::SetFocus(hdlg);
+ ::SetFocus(hdlg); // will not break synthetic focus as hdlg is a native toplevel
// set appropriate icon for parentless dialogs
jobject awtParent = env->GetObjectField(peer, AwtPrintDialog::parentID);
@@ -99,16 +100,19 @@ PrintDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
}
// subclass dialog's parent to receive additional messages
- ComCtl32Util::GetInstance().SubclassHWND(hdlg,
- PrintDialogWndProc);
+ WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(hdlg,
+ PrintDialogWndProc);
+ ::SetProp(hdlg, NativeDialogWndProcProp, reinterpret_cast<HANDLE>(lpfnWndProc));
break;
}
case WM_DESTROY: {
+ WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hdlg, NativeDialogWndProcProp));
ComCtl32Util::GetInstance().UnsubclassHWND(hdlg,
PrintDialogWndProc,
- NULL);
+ lpfnWndProc);
::RemoveProp(hdlg, ModalDialogPeerProp);
+ ::RemoveProp(hdlg, NativeDialogWndProcProp);
break;
}
}
diff --git a/src/windows/native/sun/windows/awt_PrintJob.cpp b/src/windows/native/sun/windows/awt_PrintJob.cpp
index 9136b7864..c33397786 100644
--- a/src/windows/native/sun/windows/awt_PrintJob.cpp
+++ b/src/windows/native/sun/windows/awt_PrintJob.cpp
@@ -2885,7 +2885,8 @@ LRESULT CALLBACK PageDialogWndProc(HWND hWnd, UINT message,
}
}
- return ComCtl32Util::GetInstance().DefWindowProc(NULL, hWnd, message, wParam, lParam);
+ WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hWnd, NativeDialogWndProcProp));
+ return ComCtl32Util::GetInstance().DefWindowProc(lpfnWndProc, hWnd, message, wParam, lParam);
}
/**
@@ -2919,16 +2920,19 @@ static UINT CALLBACK pageDlgHook(HWND hDlg, UINT msg,
}
// subclass dialog's parent to receive additional messages
- ComCtl32Util::GetInstance().SubclassHWND(hDlg,
- PageDialogWndProc);
+ WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(hDlg,
+ PageDialogWndProc);
+ ::SetProp(hDlg, NativeDialogWndProcProp, reinterpret_cast<HANDLE>(lpfnWndProc));
break;
}
case WM_DESTROY: {
+ WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hDlg, NativeDialogWndProcProp));
ComCtl32Util::GetInstance().UnsubclassHWND(hDlg,
PageDialogWndProc,
- NULL);
+ lpfnWndProc);
::RemoveProp(hDlg, ModalDialogPeerProp);
+ ::RemoveProp(hDlg, NativeDialogWndProcProp);
break;
}
}
diff --git a/src/windows/native/sun/windows/awt_ScrollPane.cpp b/src/windows/native/sun/windows/awt_ScrollPane.cpp
index 4d41e0b0c..bf11ecca3 100644
--- a/src/windows/native/sun/windows/awt_ScrollPane.cpp
+++ b/src/windows/native/sun/windows/awt_ScrollPane.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -361,13 +361,6 @@ void AwtScrollPane::PostScrollEvent(int orient, int scrollCode, int pos) {
DASSERT(!safe_ExceptionOccurred(env));
}
-BOOL AwtScrollPane::ActMouseMessage(MSG* pMsg) {
- if (!IsFocusingMessage(pMsg->message)) {
- return FALSE;
- }
- return TRUE;
-}
-
MsgRouting
AwtScrollPane::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
{
@@ -412,13 +405,10 @@ MsgRouting AwtScrollPane::WmHScroll(UINT scrollCode, UINT pos, HWND hScrollPane)
return mrConsume;
}
-/*
- * Fix for BugTraq ID 4041703: keyDown not being invoked.
- * This method overrides AwtCanvas::HandleEvent() since we
- * don't want ScrollPanel to receive focus on mouse press.
- */
MsgRouting AwtScrollPane::HandleEvent(MSG *msg, BOOL synthetic)
{
+ // SunAwtScrollPane control doesn't cause activation on mouse/key events,
+ // so we can safely (for synthetic focus) pass them to the system proc.
return AwtComponent::HandleEvent(msg, synthetic);
}
diff --git a/src/windows/native/sun/windows/awt_ScrollPane.h b/src/windows/native/sun/windows/awt_ScrollPane.h
index c58363969..326e7fa75 100644
--- a/src/windows/native/sun/windows/awt_ScrollPane.h
+++ b/src/windows/native/sun/windows/awt_ScrollPane.h
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,7 +65,6 @@ public:
virtual void Reshape(int x, int y, int w, int h);
virtual void BeginValidate() {}
virtual void EndValidate() {}
- BOOL ActMouseMessage(MSG* pMsg);
/*
* Fix for bug 4046446
diff --git a/src/windows/native/sun/windows/awt_Scrollbar.cpp b/src/windows/native/sun/windows/awt_Scrollbar.cpp
index 879c1847f..27b1b5ddb 100644
--- a/src/windows/native/sun/windows/awt_Scrollbar.cpp
+++ b/src/windows/native/sun/windows/awt_Scrollbar.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
#include "awt_Scrollbar.h"
#include "awt_Canvas.h"
#include "awt_Window.h"
-#include "awt_KeyboardFocusManager.h"
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
*/
@@ -61,7 +60,6 @@ AwtScrollbar::AwtScrollbar() {
m_orientation = SB_HORZ;
m_lineIncr = 0;
m_pageIncr = 0;
- m_ignoreFocusEvents = FALSE;
m_prevCallback = NULL;
m_prevCallbackPos = 0;
ms_instanceCounter++;
@@ -221,7 +219,6 @@ AwtScrollbar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
return retValue;
}
-
MsgRouting
AwtScrollbar::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
{
@@ -265,17 +262,10 @@ AwtScrollbar::WmMouseDown(UINT flags, int x, int y, int button)
MsgRouting
AwtScrollbar::HandleEvent(MSG *msg, BOOL synthetic)
{
- if (msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONDBLCLK) {
- if (IsFocusable() && AwtComponent::sm_focusOwner != GetHWnd()) {
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject target = GetTarget(env);
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::heavyweightButtonDownMID,
- target, ((jlong)msg->time) & 0xFFFFFFFF);
- env->DeleteLocalRef(target);
- AwtSetFocus();
- }
+ // SCROLLBAR control doesn't cause activation on mouse/key events,
+ // so we can safely (for synthetic focus) pass them to the system proc.
+
+ if (IsFocusingMouseMessage(msg)) {
// Left button press was already routed to default window
// procedure in the WmMouseDown above. Propagating synthetic
// press seems like a bad idea as internal message loop
@@ -283,54 +273,19 @@ AwtScrollbar::HandleEvent(MSG *msg, BOOL synthetic)
delete msg;
return mrConsume;
}
- else {
- return AwtComponent::HandleEvent(msg, synthetic);
- }
+ return AwtComponent::HandleEvent(msg, synthetic);
}
-
// Work around a windows bug descrbed in KB article Q73839. Reset
// focus on scrollbars to update focus indicator. The article advises
-// to disable/enable the scrollbar, but simply resetting the focus is
-// sufficient.
+// to disable/enable the scrollbar.
void
AwtScrollbar::UpdateFocusIndicator()
{
if (IsFocusable()) {
- m_ignoreFocusEvents = TRUE;
- ::SetFocus(NULL);
- AwtSetFocus();
- m_ignoreFocusEvents = FALSE;
- }
-}
-
-MsgRouting
-AwtScrollbar::WmKillFocus(HWND hWndGot)
-{
- if (m_ignoreFocusEvents) {
- // We are voluntary giving up focus and will get it back
- // immediately. This is necessary to force windows to update
- // the focus indicator.
- sm_focusOwner = NULL;
- return mrDoDefault;
- }
- else {
- return AwtComponent::WmKillFocus(hWndGot);
- }
-}
-
-MsgRouting
-AwtScrollbar::WmSetFocus(HWND hWndLost)
-{
- if (m_ignoreFocusEvents) {
- // We have voluntary gave up focus and are getting it back
- // now. This is necessary to force windows to update the
- // focus indicator.
- sm_focusOwner = GetHWnd();
- return mrDoDefault;
- }
- else {
- return AwtComponent::WmSetFocus(hWndLost);
+ // todo: doesn't work
+ SendMessage((WPARAM)ESB_DISABLE_BOTH);
+ SendMessage((WPARAM)ESB_ENABLE_BOTH);
}
}
diff --git a/src/windows/native/sun/windows/awt_Scrollbar.h b/src/windows/native/sun/windows/awt_Scrollbar.h
index 4fcac523c..44763cd23 100644
--- a/src/windows/native/sun/windows/awt_Scrollbar.h
+++ b/src/windows/native/sun/windows/awt_Scrollbar.h
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -69,10 +69,6 @@ public:
virtual MsgRouting WmHScroll(UINT scrollCode, UINT pos, HWND hScrollBar);
virtual MsgRouting WmVScroll(UINT scrollCode, UINT pos, HWND hScrollBar);
- // Work around KB Q73839 bug.
- virtual MsgRouting WmSetFocus(HWND hWndLost);
- virtual MsgRouting WmKillFocus(HWND hWndGot);
-
// Prevent KB Q102552 race.
virtual MsgRouting WmMouseDown(UINT flags, int x, int y, int button);
virtual MsgRouting WmNcHitTest(UINT x, UINT y, LRESULT& retVal);
@@ -91,7 +87,6 @@ private:
int m_pageIncr;
// Work around KB Q73839 bug.
- BOOL m_ignoreFocusEvents;
void UpdateFocusIndicator();
// Don't do redundant callbacks.
diff --git a/src/windows/native/sun/windows/awt_TextArea.cpp b/src/windows/native/sun/windows/awt_TextArea.cpp
index e0d4c6158..b99de8d23 100644
--- a/src/windows/native/sun/windows/awt_TextArea.cpp
+++ b/src/windows/native/sun/windows/awt_TextArea.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,9 @@
#include "awt_Toolkit.h"
#include "awt_TextArea.h"
#include "awt_TextComponent.h"
-#include "awt_KeyboardFocusManager.h"
#include "awt_Canvas.h"
#include "awt_Window.h"
+#include "awt_Frame.h"
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
*/
@@ -362,13 +362,6 @@ AwtTextArea::EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
DASSERT(::IsWindow(::GetParent(hWnd)));
switch (message) {
- case WM_SETFOCUS:
- ::SendMessage(::GetParent(hWnd), EM_HIDESELECTION, FALSE, 0);
- break;
- case WM_KILLFOCUS:
- ::SendMessage(::GetParent(hWnd), EM_HIDESELECTION, TRUE, 0);
- break;
-
case WM_UNDO:
case WM_CUT:
case WM_COPY:
@@ -400,7 +393,6 @@ AwtTextArea::EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
MsgRouting
AwtTextArea::WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos) {
-
/* Use the system provided edit control class to generate context menu. */
if (m_hEditCtrl == NULL) {
DWORD dwStyle = WS_CHILD;
@@ -494,22 +486,11 @@ AwtTextArea::WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos) {
VERIFY(::ClientToScreen(GetHWnd(), &p));
}
- ::SendMessage(m_hEditCtrl, WM_CONTEXTMENU, (WPARAM)m_hEditCtrl,
- MAKELPARAM(p.x, p.y));
- /*
- * After the context menu is dismissed focus is owned by the edit contol.
- * Return focus to parent.
- */
- if (IsFocusable() && AwtComponent::sm_focusOwner != GetHWnd()) {
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject target = GetTarget(env);
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::heavyweightButtonDownMID,
- target, TimeHelper::getMessageTimeUTC());
- env->DeleteLocalRef(target);
- AwtSetFocus();
- }
+ // The context menu steals focus from the proxy.
+ // So, set the focus-restore flag up.
+ SetRestoreFocus(TRUE);
+ ::SendMessage(m_hEditCtrl, WM_CONTEXTMENU, (WPARAM)m_hEditCtrl, MAKELPARAM(p.x, p.y));
+ SetRestoreFocus(FALSE);
return mrConsume;
}
@@ -558,20 +539,11 @@ AwtTextArea::HandleEvent(MSG *msg, BOOL synthetic)
* By consuming WM_MOUSEMOVE messages we also don't give
* the RichEdit control a chance to recognize a drag gesture
* and initiate its own drag-n-drop operation.
+ *
+ * The workaround also allows us to implement synthetic focus mechanism.
+ *
*/
- if (msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONDBLCLK) {
-
- if (IsFocusable() && AwtComponent::sm_focusOwner != GetHWnd()) {
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject target = GetTarget(env);
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::heavyweightButtonDownMID,
- target, ((jlong)msg->time) & 0xFFFFFFFF);
- env->DeleteLocalRef(target);
- AwtSetFocus();
- }
-
+ if (IsFocusingMouseMessage(msg)) {
CHARRANGE cr;
LONG lCurPos = EditGetCharFromPos(msg->pt);
@@ -717,6 +689,7 @@ AwtTextArea::HandleEvent(MSG *msg, BOOL synthetic)
p.x = -1;
p.y = -1;
}
+
if (!::PostMessage(GetHWnd(), WM_CONTEXTMENU, (WPARAM)GetHWnd(),
MAKELPARAM(p.x, p.y))) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -724,6 +697,8 @@ AwtTextArea::HandleEvent(MSG *msg, BOOL synthetic)
env->ExceptionDescribe();
env->ExceptionClear();
}
+ delete msg;
+ return mrConsume;
} else if (msg->message == WM_MOUSEWHEEL) {
// 4417236: If there is an old version of RichEd32.dll which
// does not provide the mouse wheel scrolling we have to
diff --git a/src/windows/native/sun/windows/awt_TextComponent.cpp b/src/windows/native/sun/windows/awt_TextComponent.cpp
index 9920b9252..e0a7af74d 100644
--- a/src/windows/native/sun/windows/awt_TextComponent.cpp
+++ b/src/windows/native/sun/windows/awt_TextComponent.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
#include "awt_Toolkit.h"
#include "awt_TextComponent.h"
-#include "awt_KeyboardFocusManager.h"
#include "awt_Canvas.h"
#include "jni.h"
@@ -62,9 +61,9 @@ jfieldID AwtTextComponent::canAccessClipboardID;
AwtTextComponent::AwtTextComponent() {
m_synthetic = FALSE;
- m_lStartPos = -1;
- m_lEndPos = -1;
- m_lLastPos = -1;
+ m_lStartPos = -1;
+ m_lEndPos = -1;
+ m_lLastPos = -1;
m_isLFonly = FALSE;
m_EOLchecked = FALSE;
// javaEventsMask = 0; // accessibility support
@@ -74,10 +73,6 @@ LPCTSTR AwtTextComponent::GetClassName() {
return TEXT("EDIT"); /* System provided edit control class */
}
-BOOL AwtTextComponent::ActMouseMessage(MSG* pMsg) {
- return FALSE;
-}
-
/* Set a suitable font to IME against the component font. */
void AwtTextComponent::SetFont(AwtFont* font)
{
@@ -143,23 +138,16 @@ AwtTextComponent::WmNotify(UINT notifyCode)
return mrDoDefault;
}
+BOOL AwtTextComponent::IsFocusingMouseMessage(MSG *pMsg)
+{
+ return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK;
+}
+
MsgRouting
AwtTextComponent::HandleEvent(MSG *msg, BOOL synthetic)
{
MsgRouting returnVal;
- if (AwtComponent::sm_focusOwner != GetHWnd() && IsFocusable() &&
- (msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONDBLCLK))
- {
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- jobject target = GetTarget(env);
- env->CallStaticVoidMethod
- (AwtKeyboardFocusManager::keyboardFocusManagerCls,
- AwtKeyboardFocusManager::heavyweightButtonDownMID,
- target, ((jlong)msg->time) & 0xFFFFFFFF);
- env->DeleteLocalRef(target);
- }
-
/*
* Store the 'synthetic' parameter so that the WM_PASTE security check
* happens only for synthetic events.
diff --git a/src/windows/native/sun/windows/awt_TextComponent.h b/src/windows/native/sun/windows/awt_TextComponent.h
index 32a430baf..c6068b523 100644
--- a/src/windows/native/sun/windows/awt_TextComponent.h
+++ b/src/windows/native/sun/windows/awt_TextComponent.h
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -69,8 +69,6 @@ public:
// called on Toolkit thread from JNI
static jstring _GetText(void *param);
- BOOL ActMouseMessage(MSG* pMsg);
-
void SetFont(AwtFont* font);
/*
@@ -80,6 +78,8 @@ public:
MsgRouting HandleEvent(MSG *msg, BOOL synthetic);
MsgRouting WmPaste();
+ virtual BOOL IsFocusingMouseMessage(MSG *pMsg);
+
/* To be fully implemented in a future release
MsgRouting WmKeyDown(UINT wkey, UINT repCnt,
@@ -125,7 +125,6 @@ private:
LONG m_lEndPos;
LONG m_lLastPos;
-
HFONT m_hFont;
//im --- end
diff --git a/src/windows/native/sun/windows/awt_TextField.cpp b/src/windows/native/sun/windows/awt_TextField.cpp
index 975fd20bc..49095d3e3 100644
--- a/src/windows/native/sun/windows/awt_TextField.cpp
+++ b/src/windows/native/sun/windows/awt_TextField.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
#include "awt_Toolkit.h"
#include "awt_TextField.h"
#include "awt_TextComponent.h"
-#include "awt_KeyboardFocusManager.h"
#include "awt_Canvas.h"
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
@@ -150,135 +149,130 @@ AwtTextField::HandleEvent(MSG *msg, BOOL synthetic)
* By consuming WM_MOUSEMOVE messages we also don't give
* the RichEdit control a chance to recognize a drag gesture
* and initiate its own drag-n-drop operation.
+ *
+ * The workaround also allows us to implement synthetic focus mechanism.
*/
- /**
- * In non-focusable mode we don't pass mouse messages to native window thus making user unable
- * to select the text. Below is the code from awt_TextArea.cpp which implements selection
- * functionality. For safety this code is only being executed in non-focusable mode.
- */
- if (!IsFocusable()) {
- if (msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONDBLCLK) {
+ if (IsFocusingMouseMessage(msg)) {
+ CHARRANGE cr;
+
+ LONG lCurPos = EditGetCharFromPos(msg->pt);
+
+ EditGetSel(cr);
+ /*
+ * NOTE: Plain EDIT control always clears selection on mouse
+ * button press. We are clearing the current selection only if
+ * the mouse pointer is not over the selected region.
+ * In this case we sacrifice backward compatibility
+ * to allow dnd of the current selection.
+ */
+ if (msg->message == WM_LBUTTONDBLCLK) {
+ SetStartSelectionPos(static_cast<LONG>(SendMessage(
+ EM_FINDWORDBREAK, WB_MOVEWORDLEFT, lCurPos)));
+ SetEndSelectionPos(static_cast<LONG>(SendMessage(
+ EM_FINDWORDBREAK, WB_MOVEWORDRIGHT, lCurPos)));
+ } else {
+ SetStartSelectionPos(lCurPos);
+ SetEndSelectionPos(lCurPos);
+ }
+ cr.cpMin = GetStartSelectionPos();
+ cr.cpMax = GetEndSelectionPos();
+ EditSetSel(cr);
+
+ delete msg;
+ return mrConsume;
+ } else if (msg->message == WM_LBUTTONUP) {
+
+ /*
+ * If the left mouse button is pressed on the selected region
+ * we don't clear the current selection. We clear it on button
+ * release instead. This is to allow dnd of the current selection.
+ */
+ if (GetStartSelectionPos() == -1 && GetEndSelectionPos() == -1) {
CHARRANGE cr;
LONG lCurPos = EditGetCharFromPos(msg->pt);
- EditGetSel(cr);
- /*
- * NOTE: Plain EDIT control always clears selection on mouse
- * button press. We are clearing the current selection only if
- * the mouse pointer is not over the selected region.
- * In this case we sacrifice backward compatibility
- * to allow dnd of the current selection.
- */
- if (msg->message == WM_LBUTTONDBLCLK) {
- SetStartSelectionPos(static_cast<LONG>(SendMessage(
- EM_FINDWORDBREAK, WB_MOVEWORDLEFT, lCurPos)));
- SetEndSelectionPos(static_cast<LONG>(SendMessage(
- EM_FINDWORDBREAK, WB_MOVEWORDRIGHT, lCurPos)));
- } else {
- SetStartSelectionPos(lCurPos);
- SetEndSelectionPos(lCurPos);
- }
- cr.cpMin = GetStartSelectionPos();
- cr.cpMax = GetEndSelectionPos();
+ cr.cpMin = lCurPos;
+ cr.cpMax = lCurPos;
EditSetSel(cr);
+ }
- delete msg;
- return mrConsume;
- } else if (msg->message == WM_LBUTTONUP) {
+ /*
+ * Cleanup the state variables when left mouse button is released.
+ * These state variables are designed to reflect the selection state
+ * while the left mouse button is pressed and be set to -1 otherwise.
+ */
+ SetStartSelectionPos(-1);
+ SetEndSelectionPos(-1);
+ SetLastSelectionPos(-1);
+
+ delete msg;
+ return mrConsume;
+ } else if (msg->message == WM_MOUSEMOVE && (msg->wParam & MK_LBUTTON)) {
+
+ /*
+ * We consume WM_MOUSEMOVE while the left mouse button is pressed,
+ * so we have to simulate autoscrolling when mouse is moved outside
+ * of the client area.
+ */
+ POINT p;
+ RECT r;
+ BOOL bScrollLeft = FALSE;
+ BOOL bScrollRight = FALSE;
+ BOOL bScrollUp = FALSE;
+ BOOL bScrollDown = FALSE;
+
+ p.x = msg->pt.x;
+ p.y = msg->pt.y;
+ VERIFY(::GetClientRect(GetHWnd(), &r));
+
+ if (p.x < 0) {
+ bScrollLeft = TRUE;
+ p.x = 0;
+ } else if (p.x > r.right) {
+ bScrollRight = TRUE;
+ p.x = r.right - 1;
+ }
+ LONG lCurPos = EditGetCharFromPos(p);
- /*
- * If the left mouse button is pressed on the selected region
- * we don't clear the current selection. We clear it on button
- * release instead. This is to allow dnd of the current selection.
- */
- if (GetStartSelectionPos() == -1 && GetEndSelectionPos() == -1) {
- CHARRANGE cr;
+ if (GetStartSelectionPos() != -1 &&
+ GetEndSelectionPos() != -1 &&
+ lCurPos != GetLastSelectionPos()) {
- LONG lCurPos = EditGetCharFromPos(msg->pt);
+ CHARRANGE cr;
- cr.cpMin = lCurPos;
- cr.cpMax = lCurPos;
- EditSetSel(cr);
- }
+ SetLastSelectionPos(lCurPos);
- /*
- * Cleanup the state variables when left mouse button is released.
- * These state variables are designed to reflect the selection state
- * while the left mouse button is pressed and be set to -1 otherwise.
- */
- SetStartSelectionPos(-1);
- SetEndSelectionPos(-1);
- SetLastSelectionPos(-1);
+ cr.cpMin = GetStartSelectionPos();
+ cr.cpMax = GetLastSelectionPos();
- delete msg;
- return mrConsume;
- } else if (msg->message == WM_MOUSEMOVE && (msg->wParam & MK_LBUTTON)) {
+ EditSetSel(cr);
+ }
+ if (bScrollLeft == TRUE || bScrollRight == TRUE) {
+ SCROLLINFO si;
+ memset(&si, 0, sizeof(si));
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
+
+ VERIFY(::GetScrollInfo(GetHWnd(), SB_HORZ, &si));
+ if (bScrollLeft == TRUE) {
+ si.nPos = si.nPos - si.nPage / 2;
+ si.nPos = max(si.nMin, si.nPos);
+ } else if (bScrollRight == TRUE) {
+ si.nPos = si.nPos + si.nPage / 2;
+ si.nPos = min(si.nPos, si.nMax);
+ }
/*
- * We consume WM_MOUSEMOVE while the left mouse button is pressed,
- * so we have to simulate autoscrolling when mouse is moved outside
- * of the client area.
+ * Okay to use 16-bit position since RichEdit control adjusts
+ * its scrollbars so that their range is always 16-bit.
*/
- POINT p;
- RECT r;
- BOOL bScrollLeft = FALSE;
- BOOL bScrollRight = FALSE;
- BOOL bScrollUp = FALSE;
- BOOL bScrollDown = FALSE;
-
- p.x = msg->pt.x;
- p.y = msg->pt.y;
- VERIFY(::GetClientRect(GetHWnd(), &r));
-
- if (p.x < 0) {
- bScrollLeft = TRUE;
- p.x = 0;
- } else if (p.x > r.right) {
- bScrollRight = TRUE;
- p.x = r.right - 1;
- }
- LONG lCurPos = EditGetCharFromPos(p);
-
- if (GetStartSelectionPos() != -1 &&
- GetEndSelectionPos() != -1 &&
- lCurPos != GetLastSelectionPos()) {
-
- CHARRANGE cr;
-
- SetLastSelectionPos(lCurPos);
-
- cr.cpMin = GetStartSelectionPos();
- cr.cpMax = GetLastSelectionPos();
-
- EditSetSel(cr);
- }
-
- if (bScrollLeft == TRUE || bScrollRight == TRUE) {
- SCROLLINFO si;
- memset(&si, 0, sizeof(si));
- si.cbSize = sizeof(si);
- si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
-
- VERIFY(::GetScrollInfo(GetHWnd(), SB_HORZ, &si));
- if (bScrollLeft == TRUE) {
- si.nPos = si.nPos - si.nPage / 2;
- si.nPos = max(si.nMin, si.nPos);
- } else if (bScrollRight == TRUE) {
- si.nPos = si.nPos + si.nPage / 2;
- si.nPos = min(si.nPos, si.nMax);
- }
- /*
- * Okay to use 16-bit position since RichEdit control adjusts
- * its scrollbars so that their range is always 16-bit.
- */
- DASSERT(abs(si.nPos) < 0x8000);
- SendMessage(WM_HSCROLL,
- MAKEWPARAM(SB_THUMBPOSITION, LOWORD(si.nPos)));
- }
- delete msg;
- return mrConsume;
+ DASSERT(abs(si.nPos) < 0x8000);
+ SendMessage(WM_HSCROLL,
+ MAKEWPARAM(SB_THUMBPOSITION, LOWORD(si.nPos)));
}
+ delete msg;
+ return mrConsume;
}
/*
* Store the 'synthetic' parameter so that the WM_PASTE security check
diff --git a/src/windows/native/sun/windows/awt_Toolkit.cpp b/src/windows/native/sun/windows/awt_Toolkit.cpp
index c4292826a..4a7cc16c5 100644
--- a/src/windows/native/sun/windows/awt_Toolkit.cpp
+++ b/src/windows/native/sun/windows/awt_Toolkit.cpp
@@ -56,6 +56,7 @@
#include "debug_mem.h"
#include "ComCtl32Util.h"
+#include "DllUtil.h"
#include "D3DPipelineManager.h"
@@ -334,6 +335,8 @@ AwtToolkit::AwtToolkit() {
m_mouseDown = FALSE;
m_hGetMessageHook = 0;
+ m_hMouseLLHook = 0;
+ m_lastWindowUnderMouse = NULL;
m_timer = 0;
m_cmdIDs = new AwtCmdIDList();
@@ -483,6 +486,7 @@ BOOL AwtToolkit::Dispose() {
tk.UnregisterClass();
::UnhookWindowsHookEx(tk.m_hGetMessageHook);
+ UninstallMouseLowLevelHook();
tk.m_mainThreadId = 0;
@@ -960,6 +964,79 @@ LRESULT CALLBACK AwtToolkit::GetMessageFilter(int code,
CATCH_BAD_ALLOC_RET(0);
}
+void AwtToolkit::InstallMouseLowLevelHook()
+{
+ // We need the low-level hook since we need to process mouse move
+ // messages outside of our windows.
+ m_hMouseLLHook = ::SetWindowsHookEx(WH_MOUSE_LL,
+ (HOOKPROC)MouseLowLevelHook,
+ GetModuleHandle(), NULL);
+
+ // Reset the old value
+ m_lastWindowUnderMouse = NULL;
+}
+
+void AwtToolkit::UninstallMouseLowLevelHook()
+{
+ if (m_hMouseLLHook != 0) {
+ ::UnhookWindowsHookEx(m_hMouseLLHook);
+ m_hMouseLLHook = 0;
+ }
+}
+
+LRESULT CALLBACK AwtToolkit::MouseLowLevelHook(int code,
+ WPARAM wParam, LPARAM lParam)
+{
+ TRY;
+
+ if (code >= 0 && wParam == WM_MOUSEMOVE) {
+ POINT pt = ((MSLLHOOKSTRUCT*)lParam)->pt;
+
+ // We can't use GA_ROOTOWNER since in this case we'll go up to
+ // the root Java toplevel, not the actual owned toplevel.
+ HWND hwnd = ::GetAncestor(::WindowFromPoint(pt), GA_ROOT);
+
+ AwtToolkit& tk = AwtToolkit::GetInstance();
+
+ if (tk.m_lastWindowUnderMouse != hwnd) {
+ AwtWindow *fw = NULL, *tw = NULL;
+
+ if (tk.m_lastWindowUnderMouse) {
+ fw = (AwtWindow*)
+ AwtComponent::GetComponent(tk.m_lastWindowUnderMouse);
+ }
+ if (hwnd) {
+ tw = (AwtWindow*)AwtComponent::GetComponent(hwnd);
+ }
+
+ tk.m_lastWindowUnderMouse = hwnd;
+
+ if (fw) {
+ fw->UpdateSecurityWarningVisibility();
+ }
+ // ... however, because we use GA_ROOT, we may find the warningIcon
+ // which is not a Java windows.
+ if (AwtWindow::IsWarningWindow(hwnd)) {
+ hwnd = ::GetParent(hwnd);
+ if (hwnd) {
+ tw = (AwtWindow*)AwtComponent::GetComponent(hwnd);
+ }
+ tk.m_lastWindowUnderMouse = hwnd;
+ }
+ if (tw) {
+ tw->UpdateSecurityWarningVisibility();
+ }
+
+
+ }
+ }
+
+ return ::CallNextHookEx(AwtToolkit::GetInstance().m_hMouseLLHook, code,
+ wParam, lParam);
+
+ CATCH_BAD_ALLOC_RET(0);
+}
+
/*
* The main message loop
*/
@@ -1376,6 +1453,47 @@ HICON AwtToolkit::GetAwtIconSm()
return defaultIconSm;
}
+HICON AwtToolkit::GetSecurityWarningIcon(UINT index, UINT w, UINT h)
+{
+ //Note: should not exceed 10 because of the current implementation.
+ static const int securityWarningIconCounter = 3;
+
+ static HICON securityWarningIcon[securityWarningIconCounter] = {NULL, NULL, NULL};;
+ static UINT securityWarningIconWidth[securityWarningIconCounter] = {0, 0, 0};
+ static UINT securityWarningIconHeight[securityWarningIconCounter] = {0, 0, 0};
+
+ index = AwtToolkit::CalculateWave(index, securityWarningIconCounter);
+
+ if (securityWarningIcon[index] == NULL ||
+ w != securityWarningIconWidth[index] ||
+ h != securityWarningIconHeight[index])
+ {
+ if (securityWarningIcon[index] != NULL)
+ {
+ ::DestroyIcon(securityWarningIcon[index]);
+ }
+
+ static const wchar_t securityWarningIconName[] = L"SECURITY_WARNING_";
+ wchar_t iconResourceName[sizeof(securityWarningIconName) + 2];
+ ::ZeroMemory(iconResourceName, sizeof(iconResourceName));
+ wcscpy(iconResourceName, securityWarningIconName);
+
+ wchar_t strIndex[2];
+ ::ZeroMemory(strIndex, sizeof(strIndex));
+ strIndex[0] = L'0' + index;
+
+ wcscat(iconResourceName, strIndex);
+
+ securityWarningIcon[index] = (HICON)::LoadImage(GetModuleHandle(),
+ iconResourceName,
+ IMAGE_ICON, w, h, LR_DEFAULTCOLOR);
+ securityWarningIconWidth[index] = w;
+ securityWarningIconHeight[index] = h;
+ }
+
+ return securityWarningIcon[index];
+}
+
void AwtToolkit::SetHeapCheck(long flag) {
if (flag) {
printf("heap checking not supported with this build\n");
@@ -1428,6 +1546,49 @@ JNIEnv* AwtToolkit::GetEnv() {
(JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_2) : m_env;
}
+BOOL AwtToolkit::GetScreenInsets(int screenNum, RECT * rect)
+{
+ /* if primary display */
+ if (screenNum == 0) {
+ RECT rRW;
+ if (::SystemParametersInfo(SPI_GETWORKAREA,0,(void *) &rRW,0) == TRUE) {
+ rect->top = rRW.top;
+ rect->left = rRW.left;
+ rect->bottom = ::GetSystemMetrics(SM_CYSCREEN) - rRW.bottom;
+ rect->right = ::GetSystemMetrics(SM_CXSCREEN) - rRW.right;
+ return TRUE;
+ }
+ }
+ /* if additional display */
+ else {
+ MONITORINFO *miInfo;
+ miInfo = AwtWin32GraphicsDevice::GetMonitorInfo(screenNum);
+ if (miInfo) {
+ rect->top = miInfo->rcWork.top - miInfo->rcMonitor.top;
+ rect->left = miInfo->rcWork.left - miInfo->rcMonitor.left;
+ rect->bottom = miInfo->rcMonitor.bottom - miInfo->rcWork.bottom;
+ rect->right = miInfo->rcMonitor.right - miInfo->rcWork.right;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+void AwtToolkit::GetWindowRect(HWND hWnd, LPRECT lpRect)
+{
+ try {
+ if (S_OK == DwmAPI::DwmGetWindowAttribute(hWnd,
+ DwmAPI::DWMWA_EXTENDED_FRAME_BOUNDS,
+ lpRect, sizeof(*lpRect)))
+ {
+ return;
+ }
+ } catch (const DllUtil::Exception &) {}
+
+ ::GetWindowRect(hWnd, lpRect);
+}
+
/************************************************************************
* Toolkit native methods
*/
@@ -1756,7 +1917,6 @@ Java_sun_awt_windows_WToolkit_getScreenHeight(JNIEnv *env, jobject self)
CATCH_BAD_ALLOC_RET(0);
}
-
/*
* Class: sun_awt_windows_WToolkit
* Method: getSreenInsets
@@ -1768,34 +1928,17 @@ Java_sun_awt_windows_WToolkit_getScreenInsets(JNIEnv *env,
jint screen)
{
jobject insets = NULL;
- RECT rRW;
- LPMONITORINFO miInfo;
+ RECT rect;
TRY;
-/* if primary display */
- if (screen == 0) {
- if (::SystemParametersInfo(SPI_GETWORKAREA,0,(void *) &rRW,0) == TRUE) {
- insets = env->NewObject(env->FindClass("java/awt/Insets"),
- AwtToolkit::insetsMID,
- rRW.top,
- rRW.left,
- ::GetSystemMetrics(SM_CYSCREEN) - rRW.bottom,
- ::GetSystemMetrics(SM_CXSCREEN) - rRW.right);
- }
- }
-
-/* if additional display */
- else {
- miInfo = AwtWin32GraphicsDevice::GetMonitorInfo(screen);
- if (miInfo) {
- insets = env->NewObject(env->FindClass("java/awt/Insets"),
+ if (AwtToolkit::GetScreenInsets(screen, &rect)) {
+ insets = env->NewObject(env->FindClass("java/awt/Insets"),
AwtToolkit::insetsMID,
- miInfo->rcWork.top - miInfo->rcMonitor.top,
- miInfo->rcWork.left - miInfo->rcMonitor.left,
- miInfo->rcMonitor.bottom - miInfo->rcWork.bottom,
- miInfo->rcMonitor.right - miInfo->rcWork.right);
- }
+ rect.top,
+ rect.left,
+ rect.bottom,
+ rect.right);
}
if (safe_ExceptionOccurred(env)) {
diff --git a/src/windows/native/sun/windows/awt_Toolkit.h b/src/windows/native/sun/windows/awt_Toolkit.h
index d76546fa4..3bb07712a 100644
--- a/src/windows/native/sun/windows/awt_Toolkit.h
+++ b/src/windows/native/sun/windows/awt_Toolkit.h
@@ -210,6 +210,8 @@ public:
LPARAM lParam);
static LRESULT CALLBACK ForegroundIdleFilter(int code, WPARAM wParam,
LPARAM lParam);
+ static LRESULT CALLBACK MouseLowLevelHook(int code, WPARAM wParam,
+ LPARAM lParam);
INLINE static AwtToolkit& GetInstance() { return theInstance; }
INLINE void SetPeer(JNIEnv *env, jobject wToolkit) {
@@ -311,6 +313,30 @@ public:
HICON GetAwtIcon();
HICON GetAwtIconSm();
+ // Calculate a wave-like value out of the integer 'value' and
+ // the specified period.
+ // The argument 'value' is an integer 0, 1, 2, ... *infinity*.
+ //
+ // Examples:
+ // Period == 3
+ // Generated sequence: 0 1 2 1 0 .....
+ //
+ // Period == 4
+ // Generated sequence: 0 1 2 3 2 1 0 .....
+ static inline UINT CalculateWave(UINT value, const UINT period) {
+ if (period < 2) {
+ return 0;
+ }
+ // -2 is necessary to avoid repeating extreme values (0 and period-1)
+ value %= period * 2 -2;
+ if (value >= period) {
+ value = period * 2 -2 - value;
+ }
+ return value;
+ }
+
+ HICON GetSecurityWarningIcon(UINT index, UINT w, UINT h);
+
/* Turns on/off dialog modality for the system. */
INLINE AwtDialog* SetModal(AwtDialog* frame) {
AwtDialog* previousDialog = m_pModalDialog;
@@ -368,6 +394,7 @@ private:
BOOL m_mouseDown;
HHOOK m_hGetMessageHook;
+ HHOOK m_hMouseLLHook;
UINT_PTR m_timer;
class AwtCmdIDList* m_cmdIDs;
@@ -411,6 +438,24 @@ public:
public:
static void SetEnv(JNIEnv *env);
static JNIEnv* GetEnv();
+
+ static BOOL GetScreenInsets(int screenNum, RECT * rect);
+
+ // If the DWM is active, this function uses
+ // DwmGetWindowAttribute()/DWMWA_EXTENDED_FRAME_BOUNDS.
+ // Otherwise, fall back to regular ::GetWindowRect().
+ // See 6711576 for more details.
+ static void GetWindowRect(HWND hWnd, LPRECT lpRect);
+
+ private:
+ // The window handle of a toplevel window last seen under the mouse cursor.
+ // See MouseLowLevelHook() for details.
+ HWND m_lastWindowUnderMouse;
+ public:
+ HWND GetWindowUnderMouse() { return m_lastWindowUnderMouse; }
+
+ void InstallMouseLowLevelHook();
+ void UninstallMouseLowLevelHook();
};
/*
diff --git a/src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp b/src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp
index 1617d54e6..150ff8f07 100644
--- a/src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp
+++ b/src/windows/native/sun/windows/awt_Win32GraphicsEnv.cpp
@@ -29,6 +29,7 @@
#include "awt_Win32GraphicsDevice.h"
#include "Devices.h"
#include "WindowsFlags.h"
+#include "DllUtil.h"
BOOL DWMIsCompositionEnabled();
@@ -89,13 +90,8 @@ void DWMResetCompositionEnabled() {
/**
* Returns true if dwm composition is enabled, false if it is not applicable
* (if the OS is not Vista) or dwm composition is disabled.
- *
- * Note: since DWM composition state changes are very rare we load/unload the
- * dll on every change.
*/
BOOL DWMIsCompositionEnabled() {
- typedef HRESULT (WINAPI DwmIsCompositionEnabledFunc)(BOOL*);
-
// cheaper to check than whether it's vista or not
if (dwmIsCompositionEnabled != DWM_COMP_UNDEFINED) {
return (BOOL)dwmIsCompositionEnabled;
@@ -107,32 +103,22 @@ BOOL DWMIsCompositionEnabled() {
}
BOOL bRes = FALSE;
- HMODULE hDwmApiDll = ::LoadLibrary(TEXT("dwmapi.dll"));
-
- if (hDwmApiDll != NULL) {
- DwmIsCompositionEnabledFunc *lpDwmIsCompEnabled =
- (DwmIsCompositionEnabledFunc*)
- GetProcAddress(hDwmApiDll, "DwmIsCompositionEnabled");
- if (lpDwmIsCompEnabled != NULL) {
- BOOL bEnabled;
- HRESULT res = lpDwmIsCompEnabled(&bEnabled);
- if (SUCCEEDED(res)) {
- bRes = bEnabled;
- J2dTraceLn1(J2D_TRACE_VERBOSE, " composition enabled: %d",bRes);
- } else {
- J2dTraceLn1(J2D_TRACE_ERROR,
- "IsDWMCompositionEnabled: error %x when detecting"\
- "if composition is enabled", res);
- }
+
+ try {
+ BOOL bEnabled;
+ HRESULT res = DwmAPI::DwmIsCompositionEnabled(&bEnabled);
+ if (SUCCEEDED(res)) {
+ bRes = bEnabled;
+ J2dTraceLn1(J2D_TRACE_VERBOSE, " composition enabled: %d",bRes);
} else {
- J2dTraceLn(J2D_TRACE_ERROR,
- "IsDWMCompositionEnabled: no DwmIsCompositionEnabled() "\
- "in dwmapi.dll");
+ J2dTraceLn1(J2D_TRACE_ERROR,
+ "IsDWMCompositionEnabled: error %x when detecting"\
+ "if composition is enabled", res);
}
- ::FreeLibrary(hDwmApiDll);
- } else {
+ } catch (const DllUtil::Exception &) {
J2dTraceLn(J2D_TRACE_ERROR,
- "IsDWMCompositionEnabled: error opening dwmapi.dll");
+ "IsDWMCompositionEnabled: no DwmIsCompositionEnabled() "\
+ "in dwmapi.dll or dwmapi.dll cannot be loaded");
}
dwmIsCompositionEnabled = bRes;
diff --git a/src/windows/native/sun/windows/awt_Window.cpp b/src/windows/native/sun/windows/awt_Window.cpp
index 0c9bce121..88bcd8ecc 100644
--- a/src/windows/native/sun/windows/awt_Window.cpp
+++ b/src/windows/native/sun/windows/awt_Window.cpp
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,12 @@
#include "awt.h"
+#include <jlong.h>
+
#include "awt_Component.h"
#include "awt_Container.h"
#include "awt_Frame.h"
+#include "awt_Dialog.h"
#include "awt_Insets.h"
#include "awt_Panel.h"
#include "awt_Toolkit.h"
@@ -35,6 +38,7 @@
#include "awt_Win32GraphicsDevice.h"
#include "awt_BitmapUtil.h"
#include "awt_IconCursor.h"
+#include "ComCtl32Util.h"
#include "java_awt_Insets.h"
#include <java_awt_Container.h>
@@ -88,7 +92,6 @@ struct ReshapeFrameStruct {
jint x, y;
jint w, h;
};
-
// struct for _SetIconImagesData
struct SetIconImagesDataStruct {
jobject window;
@@ -97,7 +100,6 @@ struct SetIconImagesDataStruct {
jintArray smallIconRaster;
jint smw, smh;
};
-
// struct for _SetMinSize() method
// and other methods setting sizes
struct SizeStruct {
@@ -114,6 +116,34 @@ struct ModalDisableStruct {
jobject window;
jlong blockerHWnd;
};
+// struct for _SetOpacity() method
+struct OpacityStruct {
+ jobject window;
+ jint iOpacity;
+};
+// struct for _SetOpaque() method
+struct OpaqueStruct {
+ jobject window;
+ jboolean isOpaque;
+};
+// struct for _UpdateWindow() method
+struct UpdateWindowStruct {
+ jobject window;
+ jintArray data;
+ HBITMAP hBitmap;
+ jint width, height;
+};
+// Struct for _RequestWindowFocus() method
+struct RequestWindowFocusStruct {
+ jobject component;
+ jboolean isMouseEventCause;
+};
+// struct for _RepositionSecurityWarning() method
+struct RepositionSecurityWarningStruct {
+ jobject window;
+};
+
+
/************************************************************************
* AwtWindow fields
*/
@@ -121,17 +151,23 @@ struct ModalDisableStruct {
jfieldID AwtWindow::warningStringID;
jfieldID AwtWindow::locationByPlatformID;
jfieldID AwtWindow::autoRequestFocusID;
+jfieldID AwtWindow::securityWarningWidthID;
+jfieldID AwtWindow::securityWarningHeightID;
jfieldID AwtWindow::sysXID;
jfieldID AwtWindow::sysYID;
jfieldID AwtWindow::sysWID;
jfieldID AwtWindow::sysHID;
+jmethodID AwtWindow::getWarningStringMID;
+jmethodID AwtWindow::calculateSecurityWarningPositionMID;
+
int AwtWindow::ms_instanceCounter = 0;
HHOOK AwtWindow::ms_hCBTFilter;
AwtWindow * AwtWindow::m_grabbedWindow = NULL;
HWND AwtWindow::sm_retainingHierarchyZOrderInShow = NULL;
BOOL AwtWindow::sm_resizing = FALSE;
+UINT AwtWindow::untrustedWindowsCounter = 0;
/************************************************************************
* AwtWindow class methods
@@ -162,10 +198,34 @@ AwtWindow::AwtWindow() {
::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtWindow::CBTFilter,
0, AwtToolkit::MainThread());
}
+
+ m_opaque = TRUE;
+ m_opacity = 0xff;
+
+
+ warningString = NULL;
+ warningWindow = NULL;
+ securityTooltipWindow = NULL;
+ securityWarningAnimationStage = 0;
+ currentWmSizeState = SIZE_RESTORED;
+
+ hContentBitmap = NULL;
+
+ ::InitializeCriticalSection(&contentBitmapCS);
}
AwtWindow::~AwtWindow()
{
+ if (warningString != NULL) {
+ delete [] warningString;
+ }
+ ::EnterCriticalSection(&contentBitmapCS);
+ if (hContentBitmap != NULL) {
+ ::DeleteObject(hContentBitmap);
+ hContentBitmap = NULL;
+ }
+ ::LeaveCriticalSection(&contentBitmapCS);
+ ::DeleteCriticalSection(&contentBitmapCS);
}
void AwtWindow::Dispose()
@@ -204,10 +264,10 @@ AwtWindow::Grab() {
}
m_grabbed = TRUE;
m_grabbedWindow = this;
- if (sm_focusedWindow == NULL && IsFocusableWindow()) {
+ if (AwtComponent::GetFocusedWindow() == NULL && IsFocusableWindow()) {
// we shouldn't perform grab in this case (see 4841881 & 6539458)
Ungrab();
- } else if (GetHWnd() != sm_focusedWindow) {
+ } else if (GetHWnd() != AwtComponent::GetFocusedWindow()) {
_ToFront(env->NewGlobalRef(GetPeer(env)));
// Global ref was deleted in _ToFront
}
@@ -301,12 +361,40 @@ MsgRouting AwtWindow::WmWindowPosChanging(LPARAM windowPos) {
return mrDoDefault;
}
+void AwtWindow::RepositionSecurityWarning(JNIEnv *env)
+{
+ RECT rect;
+ CalculateWarningWindowBounds(env, &rect);
+
+ ::SetWindowPos(warningWindow, HWND_NOTOPMOST,
+ rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOZORDER
+ );
+}
+
MsgRouting AwtWindow::WmWindowPosChanged(LPARAM windowPos) {
- if (IsRetainingHierarchyZOrder() && ((WINDOWPOS *)windowPos)->flags & SWP_SHOWWINDOW) {
+ WINDOWPOS * wp = (WINDOWPOS *)windowPos;
+
+ if (IsRetainingHierarchyZOrder() && wp->flags & SWP_SHOWWINDOW) {
// By this time all the windows from the hierarchy are already notified about z-order change.
// Thus we may and we should reset the trigger in order not to affect other changes.
sm_retainingHierarchyZOrderInShow = NULL;
}
+
+ // Reposition the warning window
+ if (IsUntrusted() && warningWindow != NULL) {
+ if (wp->flags & SWP_HIDEWINDOW) {
+ UpdateSecurityWarningVisibility();
+ }
+
+ RepositionSecurityWarning((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2));
+
+ if (wp->flags & SWP_SHOWWINDOW) {
+ UpdateSecurityWarningVisibility();
+ }
+ }
+
return mrDoDefault;
}
@@ -326,21 +414,597 @@ void AwtWindow::FillClassInfo(WNDCLASSEX *lpwc)
lpwc->cbWndExtra = DLGWINDOWEXTRA;
}
+bool AwtWindow::IsWarningWindow(HWND hWnd)
+{
+ const UINT len = 128;
+ TCHAR windowClassName[len];
+
+ ::RealGetWindowClass(hWnd, windowClassName, len);
+ return 0 == _tcsncmp(windowClassName,
+ AwtWindow::GetWarningWindowClassName(), len);
+}
+
LRESULT CALLBACK AwtWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
- AwtComponent *comp = AwtComponent::GetComponent((HWND)wParam);
+ HWND hWnd = (HWND)wParam;
+ AwtComponent *comp = AwtComponent::GetComponent(hWnd);
+
+ if (comp == NULL) {
+ // Check if it's a security warning icon
+ // See: 5091224, 6181725, 6732583
+ if (AwtWindow::IsWarningWindow(hWnd)) {
+ return 1;
+ }
+ } else {
+ if (comp->IsTopLevel()) {
+ AwtWindow* win = (AwtWindow*)comp;
- if (comp != NULL && comp->IsTopLevel()) {
- AwtWindow* win = (AwtWindow*)comp;
- if (!win->IsFocusableWindow() || win->m_filterFocusAndActivation) {
- return 1; // Don't change focus/activation.
+ if (!win->IsFocusableWindow() ||
+ win->m_filterFocusAndActivation)
+ {
+ return 1; // Don't change focus/activation.
+ }
}
}
}
return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
}
+void AwtWindow::InitSecurityWarningSize(JNIEnv *env)
+{
+ warningWindowWidth = ::GetSystemMetrics(SM_CXSMICON);
+ warningWindowHeight = ::GetSystemMetrics(SM_CYSMICON);
+
+ jobject target = GetTarget(env);
+
+ env->SetIntField(target, AwtWindow::securityWarningWidthID,
+ warningWindowWidth);
+ env->SetIntField(target, AwtWindow::securityWarningHeightID,
+ warningWindowHeight);
+
+ env->DeleteLocalRef(target);
+}
+
+void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title,
+ DWORD windowStyle,
+ DWORD windowExStyle,
+ int x, int y, int w, int h,
+ HWND hWndParent, HMENU hMenu,
+ COLORREF colorForeground,
+ COLORREF colorBackground,
+ jobject peer)
+{
+ // Retrieve the warning string
+ // Note: we need to get it before CreateHWnd() happens because
+ // the isUntrusted() method may be invoked while the HWND
+ // is being created in response to some window messages.
+ jobject target = env->GetObjectField(peer, AwtObject::targetID);
+ jstring javaWarningString =
+ (jstring)env->CallObjectMethod(target, AwtWindow::getWarningStringMID);
+
+ if (javaWarningString != NULL) {
+ size_t length = env->GetStringLength(javaWarningString) + 1;
+ warningString = new WCHAR[length];
+ env->GetStringRegion(javaWarningString, 0,
+ static_cast<jsize>(length - 1), warningString);
+ warningString[length-1] = L'\0';
+
+ env->DeleteLocalRef(javaWarningString);
+ }
+ env->DeleteLocalRef(target);
+
+ AwtCanvas::CreateHWnd(env, title,
+ windowStyle,
+ windowExStyle,
+ x, y, w, h,
+ hWndParent, hMenu,
+ colorForeground,
+ colorBackground,
+ peer);
+
+ // Now we need to create the warning window.
+ CreateWarningWindow(env);
+}
+
+void AwtWindow::CreateWarningWindow(JNIEnv *env)
+{
+ if (!IsUntrusted()) {
+ return;
+ }
+
+ if (++AwtWindow::untrustedWindowsCounter == 1) {
+ AwtToolkit::GetInstance().InstallMouseLowLevelHook();
+ }
+
+ InitSecurityWarningSize(env);
+
+ RECT rect;
+ CalculateWarningWindowBounds(env, &rect);
+
+ RegisterWarningWindowClass();
+ warningWindow = ::CreateWindowEx(
+ WS_EX_NOACTIVATE | WS_EX_LAYERED,
+ GetWarningWindowClassName(),
+ warningString,
+ WS_POPUP,
+ rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ GetHWnd(), // owner
+ NULL, // menu
+ AwtToolkit::GetInstance().GetModuleHandle(),
+ NULL // lParam
+ );
+ if (warningWindow == NULL) {
+ //XXX: actually this is bad... We didn't manage to create the widow.
+ return;
+ }
+
+ HICON hIcon = GetSecurityWarningIcon();
+
+ ICONINFO ii;
+ ::GetIconInfo(hIcon, &ii);
+
+ //Note: we assume that every security icon has exactly the same shape.
+ HRGN rgn = BitmapUtil::BitmapToRgn(ii.hbmColor);
+ if (rgn) {
+ ::SetWindowRgn(warningWindow, rgn, TRUE);
+ }
+
+ // Now we need to create the tooltip control for this window.
+ if (!ComCtl32Util::GetInstance().IsToolTipControlInitialized()) {
+ return;
+ }
+
+ securityTooltipWindow = ::CreateWindowEx(
+ WS_EX_TOPMOST,
+ TOOLTIPS_CLASS,
+ NULL,
+ WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ warningWindow,
+ NULL,
+ AwtToolkit::GetInstance().GetModuleHandle(),
+ NULL
+ );
+
+ ::SetWindowPos(securityTooltipWindow,
+ HWND_TOPMOST, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+
+ // We currently don't expect changing the size of the window,
+ // hence we may not care of updating the TOOL position/size.
+ ::GetClientRect(warningWindow, &rect);
+
+ TOOLINFO ti;
+
+ ti.cbSize = sizeof(ti);
+ ti.uFlags = TTF_SUBCLASS;
+ ti.hwnd = warningWindow;
+ ti.hinst = AwtToolkit::GetInstance().GetModuleHandle();
+ ti.uId = 0;
+ ti.lpszText = warningString;
+ ti.rect.left = rect.left;
+ ti.rect.top = rect.top;
+ ti.rect.right = rect.right;
+ ti.rect.bottom = rect.bottom;
+
+ ::SendMessage(securityTooltipWindow, TTM_ADDTOOL,
+ 0, (LPARAM) (LPTOOLINFO) &ti);
+}
+
+void AwtWindow::DestroyWarningWindow()
+{
+ if (!IsUntrusted()) {
+ return;
+ }
+ if (--AwtWindow::untrustedWindowsCounter == 0) {
+ AwtToolkit::GetInstance().UninstallMouseLowLevelHook();
+ }
+ if (warningWindow != NULL) {
+ // Note that the warningWindow is an owned window, and hence
+ // it would be destroyed automatically. However, the window
+ // class may only be unregistered if there's no any single
+ // window left using this class. Thus, we're destroying the
+ // warning window manually. Note that the tooltip window
+ // will be destroyed automatically because it's an owned
+ // window as well.
+ ::DestroyWindow(warningWindow);
+ warningWindow = NULL;
+ securityTooltipWindow = NULL;
+ UnregisterWarningWindowClass();
+ }
+}
+
+void AwtWindow::DestroyHWnd()
+{
+ DestroyWarningWindow();
+ AwtCanvas::DestroyHWnd();
+}
+
+LPCTSTR AwtWindow::GetWarningWindowClassName()
+{
+ return TEXT("SunAwtWarningWindow");
+}
+
+void AwtWindow::FillWarningWindowClassInfo(WNDCLASS *lpwc)
+{
+ lpwc->style = 0L;
+ lpwc->lpfnWndProc = (WNDPROC)WarningWindowProc;
+ lpwc->cbClsExtra = 0;
+ lpwc->cbWndExtra = 0;
+ lpwc->hInstance = AwtToolkit::GetInstance().GetModuleHandle(),
+ lpwc->hIcon = AwtToolkit::GetInstance().GetAwtIcon();
+ lpwc->hCursor = ::LoadCursor(NULL, IDC_ARROW);
+ lpwc->hbrBackground = NULL;
+ lpwc->lpszMenuName = NULL;
+ lpwc->lpszClassName = AwtWindow::GetWarningWindowClassName();
+}
+
+void AwtWindow::RegisterWarningWindowClass()
+{
+ WNDCLASS wc;
+
+ ::ZeroMemory(&wc, sizeof(wc));
+
+ if (!::GetClassInfo(AwtToolkit::GetInstance().GetModuleHandle(),
+ AwtWindow::GetWarningWindowClassName(), &wc))
+ {
+ AwtWindow::FillWarningWindowClassInfo(&wc);
+ ATOM atom = ::RegisterClass(&wc);
+ DASSERT(atom != 0);
+ }
+}
+
+void AwtWindow::UnregisterWarningWindowClass()
+{
+ ::UnregisterClass(AwtWindow::GetWarningWindowClassName(), AwtToolkit::GetInstance().GetModuleHandle());
+}
+
+HICON AwtWindow::GetSecurityWarningIcon()
+{
+ HICON ico = AwtToolkit::GetInstance().GetSecurityWarningIcon(securityWarningAnimationStage,
+ warningWindowWidth, warningWindowHeight);
+ return ico;
+}
+
+// This function calculates the bounds of the warning window and stores them
+// into the RECT structure pointed by the argument rect.
+void AwtWindow::CalculateWarningWindowBounds(JNIEnv *env, LPRECT rect)
+{
+ RECT windowBounds;
+ AwtToolkit::GetWindowRect(GetHWnd(), &windowBounds);
+
+ jobject target = GetTarget(env);
+ jobject point2D = env->CallObjectMethod(target,
+ calculateSecurityWarningPositionMID,
+ (jdouble)windowBounds.left, (jdouble)windowBounds.top,
+ (jdouble)(windowBounds.right - windowBounds.left),
+ (jdouble)(windowBounds.bottom - windowBounds.top));
+ env->DeleteLocalRef(target);
+
+ static jclass point2DClassID = NULL;
+ static jmethodID point2DGetXMID = NULL;
+ static jmethodID point2DGetYMID = NULL;
+
+ if (point2DClassID == NULL) {
+ jclass point2DClassIDLocal = env->FindClass("java/awt/geom/Point2D");
+ point2DClassID = (jclass)env->NewGlobalRef(point2DClassIDLocal);
+ env->DeleteLocalRef(point2DClassIDLocal);
+ }
+
+ if (point2DGetXMID == NULL) {
+ point2DGetXMID = env->GetMethodID(point2DClassID, "getX", "()D");
+ }
+ if (point2DGetYMID == NULL) {
+ point2DGetYMID = env->GetMethodID(point2DClassID, "getY", "()D");
+ }
+
+
+ int x = (int)env->CallDoubleMethod(point2D, point2DGetXMID);
+ int y = (int)env->CallDoubleMethod(point2D, point2DGetYMID);
+
+ env->DeleteLocalRef(point2D);
+
+ //Make sure the warning is not far from the window bounds
+ x = max(x, windowBounds.left - (int)warningWindowWidth - 2);
+ x = min(x, windowBounds.right + (int)warningWindowWidth + 2);
+
+ y = max(y, windowBounds.top - (int)warningWindowHeight - 2);
+ y = min(y, windowBounds.bottom + (int)warningWindowHeight + 2);
+
+ // Now make sure the warning window is visible on the screen
+ HMONITOR hmon = MonitorFromWindow(GetHWnd(), MONITOR_DEFAULTTOPRIMARY);
+ DASSERT(hmon != NULL);
+
+ RECT monitorBounds;
+ RECT monitorInsets;
+
+ MonitorBounds(hmon, &monitorBounds);
+ if (!AwtToolkit::GetScreenInsets(m_screenNum, &monitorInsets)) {
+ ::ZeroMemory(&monitorInsets, sizeof(monitorInsets));
+ }
+
+ x = max(x, monitorBounds.left + monitorInsets.left);
+ x = min(x, monitorBounds.right - monitorInsets.right - (int)warningWindowWidth);
+
+ y = max(y, monitorBounds.top + monitorInsets.top);
+ y = min(y, monitorBounds.bottom - monitorInsets.bottom - (int)warningWindowHeight);
+
+ rect->left = x;
+ rect->top = y;
+ rect->right = rect->left + warningWindowWidth;
+ rect->bottom = rect->top + warningWindowHeight;
+}
+
+LRESULT CALLBACK AwtWindow::WarningWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_PAINT:
+ PaintWarningWindow(hwnd);
+ return 0;
+
+ case WM_MOUSEACTIVATE:
+ {
+ // Retrive the owner of the warning window.
+ HWND javaWindow = ::GetParent(hwnd);
+ if (javaWindow) {
+ // If the window is blocked by a modal dialog, substitute
+ // its handle with the topmost blocker.
+ HWND topmostBlocker = GetTopmostModalBlocker(javaWindow);
+ if (::IsWindow(topmostBlocker)) {
+ javaWindow = topmostBlocker;
+ }
+
+ ::BringWindowToTop(javaWindow);
+
+ AwtWindow * window =
+ (AwtWindow*)AwtComponent::GetComponent(javaWindow);
+ if (window == NULL) {
+ // Quite unlikely to go into here, but it's way better
+ // than getting a crash.
+ ::SetForegroundWindow(javaWindow);
+ } else {
+ // Activate the window if it is focusable and inactive
+ if (window->IsFocusableWindow() &&
+ javaWindow != ::GetActiveWindow()) {
+ ::SetForegroundWindow(javaWindow);
+ } else {
+ // ...otherwise just start the animation.
+ window->StartSecurityAnimation(akShow);
+ }
+ }
+
+ // In every case if there's a top-most blocker, we need to
+ // enable modal animation.
+ if (::IsWindow(topmostBlocker)) {
+ AwtDialog::AnimateModalBlocker(topmostBlocker);
+ }
+ }
+ return MA_NOACTIVATEANDEAT;
+ }
+ }
+ return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+void AwtWindow::PaintWarningWindow(HWND warningWindow)
+{
+ RECT updateRect;
+
+ if (!::GetUpdateRect(warningWindow, &updateRect, FALSE)) {
+ // got nothing to update
+ return;
+ }
+
+ PAINTSTRUCT ps;
+ HDC hdc = ::BeginPaint(warningWindow, &ps);
+ if (hdc == NULL) {
+ // indicates an error
+ return;
+ }
+
+ PaintWarningWindow(warningWindow, hdc);
+
+ ::EndPaint(warningWindow, &ps);
+}
+
+void AwtWindow::PaintWarningWindow(HWND warningWindow, HDC hdc)
+{
+ HWND javaWindow = ::GetParent(warningWindow);
+
+ AwtWindow * window = (AwtWindow*)AwtComponent::GetComponent(javaWindow);
+ if (window == NULL) {
+ return;
+ }
+
+ ::DrawIconEx(hdc, 0, 0, window->GetSecurityWarningIcon(),
+ window->warningWindowWidth, window->warningWindowHeight,
+ 0, NULL, DI_NORMAL);
+}
+
+static const UINT_PTR IDT_AWT_SECURITYANIMATION = 0x102;
+
+// Approximately 6 times a second. 0.75 seconds total.
+static const UINT securityAnimationTimerElapse = 150;
+static const UINT securityAnimationMaxIterations = 5;
+
+void AwtWindow::RepaintWarningWindow()
+{
+ HDC hdc = ::GetDC(warningWindow);
+ PaintWarningWindow(warningWindow, hdc);
+ ::ReleaseDC(warningWindow, hdc);
+}
+
+void AwtWindow::StartSecurityAnimation(AnimationKind kind)
+{
+ if (!IsUntrusted()) {
+ return;
+ }
+ if (warningWindow == NULL) {
+ return;
+ }
+
+ securityAnimationKind = kind;
+
+ securityWarningAnimationStage = 1;
+ ::SetTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION,
+ securityAnimationTimerElapse, NULL);
+
+ if (securityAnimationKind == akShow) {
+ ::SetWindowPos(warningWindow, HWND_NOTOPMOST, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
+ SWP_SHOWWINDOW);
+
+ ::SetLayeredWindowAttributes(warningWindow, RGB(0, 0, 0),
+ 0xFF, LWA_ALPHA);
+ ::RedrawWindow(warningWindow, NULL, NULL,
+ RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+ }
+}
+
+void AwtWindow::StopSecurityAnimation()
+{
+ if (!IsUntrusted()) {
+ return;
+ }
+ if (warningWindow == NULL) {
+ return;
+ }
+
+ securityWarningAnimationStage = 0;
+ ::KillTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION);
+
+ switch (securityAnimationKind) {
+ case akHide:
+ case akPreHide:
+ ::SetWindowPos(warningWindow, HWND_NOTOPMOST, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
+ SWP_HIDEWINDOW);
+ break;
+ case akShow:
+ RepaintWarningWindow();
+ break;
+ }
+
+ securityAnimationKind = akNone;
+}
+
+MsgRouting AwtWindow::WmTimer(UINT_PTR timerID)
+{
+ if (timerID != IDT_AWT_SECURITYANIMATION) {
+ return mrPassAlong;
+ }
+
+ if (securityWarningAnimationStage == 0) {
+ return mrConsume;
+ }
+
+ securityWarningAnimationStage++;
+ if (securityWarningAnimationStage >= securityAnimationMaxIterations) {
+ if (securityAnimationKind == akPreHide) {
+ // chain real hiding
+ StartSecurityAnimation(akHide);
+ } else {
+ StopSecurityAnimation();
+ }
+ } else {
+ switch (securityAnimationKind) {
+ case akHide:
+ {
+ BYTE opacity = ((int)0xFF *
+ (securityAnimationMaxIterations -
+ securityWarningAnimationStage)) /
+ securityAnimationMaxIterations;
+ ::SetLayeredWindowAttributes(warningWindow,
+ RGB(0, 0, 0), opacity, LWA_ALPHA);
+ }
+ break;
+ case akShow:
+ case akNone: // quite unlikely, but quite safe
+ RepaintWarningWindow();
+ break;
+ }
+ }
+
+ return mrConsume;
+}
+
+// The security warning is visible if:
+// 1. The window has the keyboard window focus, OR
+// 2. The mouse pointer is located within the window bounds,
+// or within the security warning icon.
+void AwtWindow::UpdateSecurityWarningVisibility()
+{
+ if (!IsUntrusted()) {
+ return;
+ }
+ if (warningWindow == NULL) {
+ return;
+ }
+
+ bool show = false;
+
+ if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED) {
+ if (AwtComponent::GetFocusedWindow() == GetHWnd()) {
+ show = true;
+ }
+
+ HWND hwnd = AwtToolkit::GetInstance().GetWindowUnderMouse();
+ if (hwnd == GetHWnd()) {
+ show = true;
+ }
+ if (hwnd == warningWindow) {
+ show = true;
+ }
+ }
+
+ if (show && (!::IsWindowVisible(warningWindow) ||
+ securityAnimationKind == akHide ||
+ securityAnimationKind == akPreHide)) {
+ StartSecurityAnimation(akShow);
+ }
+ if (!show && ::IsWindowVisible(warningWindow)) {
+ StartSecurityAnimation(akPreHide);
+ }
+}
+
+void AwtWindow::FocusedWindowChanged(HWND from, HWND to)
+{
+ AwtWindow * fw = (AwtWindow *)AwtComponent::GetComponent(from);
+ AwtWindow * tw = (AwtWindow *)AwtComponent::GetComponent(to);
+
+ if (fw != NULL) {
+ fw->UpdateSecurityWarningVisibility();
+ }
+ if (tw != NULL) {
+ tw->UpdateSecurityWarningVisibility();
+
+ // Flash on receiving the keyboard focus even if the warning
+ // has already been shown (e.g. by hovering with the mouse)
+ tw->StartSecurityAnimation(akShow);
+ }
+}
+
+void AwtWindow::_RepositionSecurityWarning(void* param)
+{
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ RepositionSecurityWarningStruct *rsws =
+ (RepositionSecurityWarningStruct *)param;
+ jobject self = rsws->window;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+ AwtWindow *window = (AwtWindow *)pData;
+
+ window->RepositionSecurityWarning(env);
+
+ ret:
+ env->DeleteGlobalRef(self);
+ delete rsws;
+}
+
/* Create a new AwtWindow object and window. */
AwtWindow* AwtWindow::Create(jobject self, jobject parent)
{
@@ -372,7 +1036,7 @@ AwtWindow* AwtWindow::Create(jobject self, jobject parent)
window->m_isRetainingHierarchyZOrder = TRUE;
}
DWORD style = WS_CLIPCHILDREN | WS_POPUP;
- DWORD exStyle = 0;
+ DWORD exStyle = WS_EX_NOACTIVATE;
if (GetRTL()) {
exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
if (GetRTLReadingOrder())
@@ -620,23 +1284,6 @@ BOOL AwtWindow::UpdateInsets(jobject insets)
::GetClientRect(GetHWnd(), &inside);
::GetWindowRect(GetHWnd(), &outside);
- jobject target = GetTarget(env);
- jstring warningString =
- (jstring)(env)->GetObjectField(target, AwtWindow::warningStringID);
- if (warningString != NULL) {
- ::CopyRect(&inside, &outside);
- DefWindowProc(WM_NCCALCSIZE, FALSE, (LPARAM)&inside);
- /*
- * Fix for BugTraq ID 4304024.
- * Calculate client rectangle in client coordinates.
- */
- VERIFY(::OffsetRect(&inside, -inside.left, -inside.top));
- extraBottomInsets = ::GetSystemMetrics(SM_CYCAPTION) +
- ((GetStyle() & WS_THICKFRAME) ? 2 : -2);
- }
- env->DeleteLocalRef(target);
- env->DeleteLocalRef(warningString);
-
/* Update our inset member */
if (outside.right - outside.left > 0 && outside.bottom - outside.top > 0) {
::MapWindowPoints(GetHWnd(), 0, (LPPOINT)&inside, 2);
@@ -863,45 +1510,93 @@ void AwtWindow::SendWindowEvent(jint id, HWND opposite,
env->DeleteLocalRef(event);
}
+BOOL AwtWindow::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
+{
+ // Fix for 6458497.
+ // Retreat if current foreground window is out of both our and embedder process.
+ // The exception is when activation is requested due to a mouse event.
+ if (!isMouseEventCause) {
+ HWND fgWindow = ::GetForegroundWindow();
+ if (NULL != fgWindow) {
+ DWORD fgProcessID;
+ ::GetWindowThreadProcessId(fgWindow, &fgProcessID);
+ if (fgProcessID != ::GetCurrentProcessId()
+ && !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID))
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ HWND proxyContainerHWnd = GetProxyToplevelContainer();
+ HWND proxyHWnd = GetProxyFocusOwner();
+
+ if (proxyContainerHWnd == NULL || proxyHWnd == NULL) {
+ return FALSE;
+ }
+
+ // Activate the proxy toplevel container
+ if (::GetActiveWindow() != proxyContainerHWnd) {
+ sm_suppressFocusAndActivation = TRUE;
+ ::BringWindowToTop(proxyContainerHWnd);
+ ::SetForegroundWindow(proxyContainerHWnd);
+ sm_suppressFocusAndActivation = FALSE;
+
+ if (::GetActiveWindow() != proxyContainerHWnd) {
+ return FALSE; // activation has been rejected
+ }
+ }
+
+ // Focus the proxy itself
+ if (::GetFocus() != proxyHWnd) {
+ sm_suppressFocusAndActivation = TRUE;
+ ::SetFocus(proxyHWnd);
+ sm_suppressFocusAndActivation = FALSE;
+
+ if (::GetFocus() != proxyHWnd) {
+ return FALSE; // focus has been rejected (that is unlikely)
+ }
+ }
+
+ const HWND focusedWindow = AwtComponent::GetFocusedWindow();
+ if (focusedWindow != GetHWnd()) {
+ if (focusedWindow != NULL) {
+ // Deactivate the old focused window
+ AwtWindow::SynthesizeWmActivate(FALSE, focusedWindow, GetHWnd());
+ }
+ // Activate the new focused window.
+ AwtWindow::SynthesizeWmActivate(TRUE, GetHWnd(), focusedWindow);
+ }
+ return TRUE;
+}
+
MsgRouting AwtWindow::WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
{
jint type;
if (nState != WA_INACTIVE) {
- ::SetFocus((sm_focusOwner == NULL ||
- AwtComponent::GetTopLevelParentForWindow(sm_focusOwner) !=
- GetHWnd()) ? NULL : sm_focusOwner);
type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS;
- AwtToolkit::GetInstance().
- InvokeFunctionLater(BounceActivation, this);
- sm_focusedWindow = GetHWnd();
+ AwtComponent::SetFocusedWindow(GetHWnd());
} else {
+ // The owner is not necassarily getting WM_ACTIVATE(WA_INACTIVE).
+ // So, initiate retaining the actualFocusedWindow.
+ AwtFrame *owner = GetOwningFrameOrDialog();
+ if (owner) {
+ owner->CheckRetainActualFocusedWindow(opposite);
+ }
+
if (m_grabbedWindow != NULL && !m_grabbedWindow->IsOneOfOwnersOf(this)) {
m_grabbedWindow->Ungrab();
}
type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS;
- sm_focusedWindow = NULL;
+ AwtComponent::SetFocusedWindow(NULL);
+ sm_focusOwner = NULL;
}
SendWindowEvent(type, opposite);
return mrConsume;
}
-void AwtWindow::BounceActivation(void *self) {
- AwtWindow *wSelf = (AwtWindow *)self;
-
- if (::GetActiveWindow() == wSelf->GetHWnd()) {
- AwtFrame *owner = wSelf->GetOwningFrameOrDialog();
-
- if (owner != NULL) {
- sm_suppressFocusAndActivation = TRUE;
- ::SetActiveWindow(owner->GetHWnd());
- ::SetFocus(owner->GetProxyFocusOwner());
- sm_suppressFocusAndActivation = FALSE;
- }
- }
-}
-
MsgRouting AwtWindow::WmCreate()
{
return mrDoDefault;
@@ -925,17 +1620,20 @@ MsgRouting AwtWindow::WmShowWindow(BOOL show, UINT status)
{
/*
* Original fix for 4810575. Modified for 6386592.
- * If an owned window (not frame/dialog) gets disposed we should synthesize
+ * If a simple window gets disposed we should synthesize
* WM_ACTIVATE for its nearest owner. This is not performed by default because
* the owner frame/dialog is natively active.
*/
HWND hwndSelf = GetHWnd();
- HWND hwndParent = ::GetParent(hwndSelf);
+ HWND hwndOwner = ::GetParent(hwndSelf);
- if (!show && IsSimpleWindow() && hwndSelf == sm_focusedWindow &&
- hwndParent != NULL && ::IsWindowVisible(hwndParent))
+ if (!show && IsSimpleWindow() && hwndSelf == AwtComponent::GetFocusedWindow() &&
+ hwndOwner != NULL && ::IsWindowVisible(hwndOwner))
{
- ::PostMessage(hwndParent, WM_ACTIVATE, (WPARAM)WA_ACTIVE, (LPARAM)hwndSelf);
+ AwtFrame *owner = (AwtFrame*)AwtComponent::GetComponent(hwndOwner);
+ if (owner != NULL) {
+ owner->AwtSetActiveWindow();
+ }
}
//Fixed 4842599: REGRESSION: JPopupMenu not Hidden Properly After Iconified and Deiconified
@@ -1034,7 +1732,10 @@ MsgRouting AwtWindow::WmSizing()
*/
MsgRouting AwtWindow::WmSize(UINT type, int w, int h)
{
+ currentWmSizeState = type;
+
if (type == SIZE_MINIMIZED) {
+ UpdateSecurityWarningVisibility();
return mrDoDefault;
}
@@ -1098,103 +1799,18 @@ MsgRouting AwtWindow::WmNcCalcSize(BOOL fCalcValidRects,
if (env->EnsureLocalCapacity(2) < 0) {
return mrConsume;
}
- jobject target = GetTarget(env);
- jstring warningString =
- (jstring)(env)->GetObjectField(target, AwtWindow::warningStringID);
- if (warningString != NULL) {
- RECT r;
- ::CopyRect(&r, &lpncsp->rgrc[0]);
- retVal = static_cast<UINT>(DefWindowProc(WM_NCCALCSIZE, fCalcValidRects,
- reinterpret_cast<LPARAM>(lpncsp)));
-
- /* Adjust non-client area for warning banner space. */
- m_warningRect.left = lpncsp->rgrc[0].left;
- m_warningRect.right = lpncsp->rgrc[0].right;
- m_warningRect.bottom = lpncsp->rgrc[0].bottom;
- m_warningRect.top =
- m_warningRect.bottom - ::GetSystemMetrics(SM_CYCAPTION);
- if (GetStyle() & WS_THICKFRAME) {
- m_warningRect.top -= 2;
- } else {
- m_warningRect.top += 2;
- }
-
- lpncsp->rgrc[0].bottom = (m_warningRect.top >= lpncsp->rgrc[0].top)
- ? m_warningRect.top
- : lpncsp->rgrc[0].top;
-
- /* Convert to window-relative coordinates. */
- ::OffsetRect(&m_warningRect, -r.left, -r.top);
-
- /* Notify target of Insets change. */
- if (HasValidRect()) {
- UpdateInsets(NULL);
- }
-
- mrRetVal = mrConsume;
- } else {
- // WM_NCCALCSIZE is usually in response to a resize, but
- // also can be triggered by SetWindowPos(SWP_FRAMECHANGED),
- // which means the insets will have changed - rnk 4/7/1998
- retVal = static_cast<UINT>(DefWindowProc(
- WM_NCCALCSIZE, fCalcValidRects, reinterpret_cast<LPARAM>(lpncsp)));
- if (HasValidRect()) {
- UpdateInsets(NULL);
- }
- mrRetVal = mrConsume;
+ // WM_NCCALCSIZE is usually in response to a resize, but
+ // also can be triggered by SetWindowPos(SWP_FRAMECHANGED),
+ // which means the insets will have changed - rnk 4/7/1998
+ retVal = static_cast<UINT>(DefWindowProc(
+ WM_NCCALCSIZE, fCalcValidRects, reinterpret_cast<LPARAM>(lpncsp)));
+ if (HasValidRect()) {
+ UpdateInsets(NULL);
}
- env->DeleteLocalRef(target);
- env->DeleteLocalRef(warningString);
+ mrRetVal = mrConsume;
return mrRetVal;
}
-MsgRouting AwtWindow::WmNcPaint(HRGN hrgn)
-{
- DefWindowProc(WM_NCPAINT, (WPARAM)hrgn, 0);
-
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- if (env->EnsureLocalCapacity(2) < 0) {
- return mrConsume;
- }
- jobject target = GetTarget(env);
- jstring warningString =
- (jstring)(env)->GetObjectField(target, AwtWindow::warningStringID);
- if (warningString != NULL) {
- RECT r;
- ::CopyRect(&r, &m_warningRect);
- HDC hDC = ::GetWindowDC(GetHWnd());
- DASSERT(hDC);
- int iSaveDC = ::SaveDC(hDC);
- VERIFY(::SelectClipRgn(hDC, NULL) != NULL);
- VERIFY(::FillRect(hDC, &m_warningRect, (HBRUSH)::GetStockObject(BLACK_BRUSH)));
-
- if (GetStyle() & WS_THICKFRAME) {
- /* draw edge */
- VERIFY(::DrawEdge(hDC, &r, EDGE_RAISED, BF_TOP));
- r.top += 2;
- VERIFY(::DrawEdge(hDC, &r, EDGE_SUNKEN, BF_RECT));
- ::InflateRect(&r, -2, -2);
- }
-
- /* draw warning text */
- LPCWSTR text = JNU_GetStringPlatformChars(env, warningString, NULL);
- VERIFY(::SetBkColor(hDC, ::GetSysColor(COLOR_BTNFACE)) != CLR_INVALID);
- VERIFY(::SetTextColor(hDC, ::GetSysColor(COLOR_BTNTEXT)) != CLR_INVALID);
- VERIFY(::SelectObject(hDC, ::GetStockObject(DEFAULT_GUI_FONT)) != NULL);
- VERIFY(::SetTextAlign(hDC, TA_LEFT | TA_BOTTOM) != GDI_ERROR);
- VERIFY(::ExtTextOut(hDC, r.left+2, r.bottom-1,
- ETO_CLIPPED | ETO_OPAQUE,
- &r, text, static_cast<UINT>(wcslen(text)), NULL));
- VERIFY(::RestoreDC(hDC, iSaveDC));
- ::ReleaseDC(GetHWnd(), hDC);
- JNU_ReleaseStringPlatformChars(env, warningString, text);
- }
-
- env->DeleteLocalRef(target);
- env->DeleteLocalRef(warningString);
- return mrConsume;
-}
-
MsgRouting AwtWindow::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
{
// If this window is blocked by modal dialog, return HTCLIENT for any point of it.
@@ -1420,6 +2036,19 @@ void AwtWindow::SetAndActivateModalBlocker(HWND window, HWND blocker) {
}
}
+HWND AwtWindow::GetTopmostModalBlocker(HWND window)
+{
+ HWND ret, blocker = NULL;
+
+ do {
+ ret = blocker;
+ blocker = AwtWindow::GetModalBlocker(window);
+ window = blocker;
+ } while (::IsWindow(blocker));
+
+ return ret;
+}
+
void AwtWindow::FlashWindowEx(HWND hWnd, UINT count, DWORD timeout, DWORD flags) {
FLASHWINFO fi;
fi.cbSize = sizeof(fi);
@@ -1430,6 +2059,38 @@ void AwtWindow::FlashWindowEx(HWND hWnd, UINT count, DWORD timeout, DWORD flags)
::FlashWindowEx(&fi);
}
+jboolean
+AwtWindow::_RequestWindowFocus(void *param)
+{
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ RequestWindowFocusStruct *rfs = (RequestWindowFocusStruct *)param;
+ jobject self = rfs->component;
+ jboolean isMouseEventCause = rfs->isMouseEventCause;
+
+ jboolean result = JNI_FALSE;
+ AwtWindow *window = NULL;
+
+ PDATA pData;
+ JNI_CHECK_NULL_GOTO(self, "peer", ret);
+ pData = JNI_GET_PDATA(self);
+ if (pData == NULL) {
+ // do nothing just return false
+ goto ret;
+ }
+
+ window = (AwtWindow *)pData;
+ if (::IsWindow(window->GetHWnd())) {
+ result = (jboolean)window->SendMessage(WM_AWT_WINDOW_SETACTIVE, (WPARAM)isMouseEventCause, 0);
+ }
+ret:
+ env->DeleteGlobalRef(self);
+
+ delete rfs;
+
+ return result;
+}
+
void AwtWindow::_ToFront(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -1839,6 +2500,216 @@ void AwtWindow::DoUpdateIcon()
//Does nothing for windows, is overriden for frames and dialogs
}
+void AwtWindow::RedrawWindow()
+{
+ if (isOpaque()) {
+ ::RedrawWindow(GetHWnd(), NULL, NULL,
+ RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+ } else {
+ ::EnterCriticalSection(&contentBitmapCS);
+ if (hContentBitmap != NULL) {
+ UpdateWindowImpl(contentWidth, contentHeight, hContentBitmap);
+ }
+ ::LeaveCriticalSection(&contentBitmapCS);
+ }
+}
+
+void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque)
+{
+ BYTE old_opacity = getOpacity();
+ BOOL old_opaque = isOpaque();
+
+ if (opacity == old_opacity && opaque == old_opaque) {
+ return;
+ }
+
+ setOpacity(opacity);
+ setOpaque(opaque);
+
+ HWND hwnd = GetHWnd();
+
+ LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
+
+ if (opaque != old_opaque) {
+ ::EnterCriticalSection(&contentBitmapCS);
+ if (hContentBitmap != NULL) {
+ ::DeleteObject(hContentBitmap);
+ hContentBitmap = NULL;
+ }
+ ::LeaveCriticalSection(&contentBitmapCS);
+ }
+
+ if (opaque && opacity == 0xff) {
+ // Turn off all the effects
+ ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style & ~WS_EX_LAYERED);
+ // Ask the window to repaint itself and all the children
+ RedrawWindow();
+ } else {
+ // We're going to enable some effects
+ if (!(ex_style & WS_EX_LAYERED)) {
+ ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style | WS_EX_LAYERED);
+ } else {
+ if ((opaque && opacity < 0xff) ^ (old_opaque && old_opacity < 0xff)) {
+ // _One_ of the modes uses the SetLayeredWindowAttributes.
+ // Need to reset the style in this case.
+ // If both modes are simple (i.e. just changing the opacity level),
+ // no need to reset the style.
+ ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style & ~WS_EX_LAYERED);
+ ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style | WS_EX_LAYERED);
+ }
+ }
+
+ if (opaque) {
+ // Simple opacity mode
+ ::SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), opacity, LWA_ALPHA);
+ }
+ }
+}
+
+static HBITMAP CreateBitmapFromRaster(JNIEnv* env, jintArray raster, jint w, jint h)
+{
+ HBITMAP image = NULL;
+ if (raster != NULL) {
+ int* rasterBuffer = NULL;
+ try {
+ rasterBuffer = (int *)env->GetPrimitiveArrayCritical(raster, 0);
+ JNI_CHECK_NULL_GOTO(rasterBuffer, "raster data", done);
+ image = BitmapUtil::CreateBitmapFromARGBPre(w, h, w*4, rasterBuffer);
+ } catch (...) {
+ if (rasterBuffer != NULL) {
+ env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
+ }
+ throw;
+ }
+ if (rasterBuffer != NULL) {
+ env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
+ }
+ }
+done:
+ return image;
+}
+
+void AwtWindow::UpdateWindowImpl(int width, int height, HBITMAP hBitmap)
+{
+ if (isOpaque()) {
+ return;
+ }
+
+ HWND hWnd = GetHWnd();
+ HDC hdcDst = ::GetDC(NULL);
+ HDC hdcSrc = ::CreateCompatibleDC(NULL);
+ HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdcSrc, hBitmap);
+
+ //XXX: this code doesn't paint the children (say, the java.awt.Button)!
+ //So, if we ever want to support HWs here, we need to repaint them
+ //in some other way...
+ //::SendMessage(hWnd, WM_PRINT, (WPARAM)hdcSrc, /*PRF_CHECKVISIBLE |*/
+ // PRF_CHILDREN /*| PRF_CLIENT | PRF_NONCLIENT*/);
+
+ POINT ptSrc;
+ ptSrc.x = ptSrc.y = 0;
+
+ RECT rect;
+ POINT ptDst;
+ SIZE size;
+
+ ::GetWindowRect(hWnd, &rect);
+ ptDst.x = rect.left;
+ ptDst.y = rect.top;
+ size.cx = width;
+ size.cy = height;
+
+ BLENDFUNCTION bf;
+
+ bf.SourceConstantAlpha = getOpacity();
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+
+ ::UpdateLayeredWindow(hWnd, hdcDst, &ptDst, &size, hdcSrc, &ptSrc,
+ RGB(0, 0, 0), &bf, ULW_ALPHA);
+
+ ::ReleaseDC(NULL, hdcDst);
+ ::SelectObject(hdcSrc, hOldBitmap);
+ ::DeleteDC(hdcSrc);
+}
+
+void AwtWindow::UpdateWindow(JNIEnv* env, jintArray data, int width, int height,
+ HBITMAP hNewBitmap)
+{
+ if (isOpaque()) {
+ return;
+ }
+
+ HBITMAP hBitmap;
+ if (hNewBitmap == NULL) {
+ if (data == NULL) {
+ return;
+ }
+ hBitmap = CreateBitmapFromRaster(env, data, width, height);
+ if (hBitmap == NULL) {
+ return;
+ }
+ } else {
+ hBitmap = hNewBitmap;
+ }
+
+ ::EnterCriticalSection(&contentBitmapCS);
+ if (hContentBitmap != NULL) {
+ ::DeleteObject(hContentBitmap);
+ }
+ hContentBitmap = hBitmap;
+ contentWidth = width;
+ contentHeight = height;
+ UpdateWindowImpl(width, height, hBitmap);
+ ::LeaveCriticalSection(&contentBitmapCS);
+}
+
+void AwtWindow::FillBackground(HDC hMemoryDC, SIZE &size)
+{
+ if (isOpaque()) {
+ AwtCanvas::FillBackground(hMemoryDC, size);
+ }
+}
+
+void AwtWindow::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
+{
+ if (isOpaque()) {
+ AwtCanvas::FillAlpha(bitmapBits, size, alpha);
+ }
+}
+
+/*
+ * Fixed 6353381: it's improved fix for 4792958
+ * which was backed-out to avoid 5059656
+ */
+BOOL AwtWindow::HasValidRect()
+{
+ RECT inside;
+ RECT outside;
+
+ if (::IsIconic(GetHWnd())) {
+ return FALSE;
+ }
+
+ ::GetClientRect(GetHWnd(), &inside);
+ ::GetWindowRect(GetHWnd(), &outside);
+
+ BOOL isZeroClientArea = (inside.right == 0 && inside.bottom == 0);
+ BOOL isInvalidLocation = ((outside.left == -32000 && outside.top == -32000) || // Win2k && WinXP
+ (outside.left == 32000 && outside.top == 32000) || // Win95 && Win98
+ (outside.left == 3000 && outside.top == 3000)); // Win95 && Win98
+
+ // the bounds correspond to iconic state
+ if (isZeroClientArea && isInvalidLocation)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
void AwtWindow::_SetIconImagesData(void * param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -1940,11 +2811,14 @@ void AwtWindow::_SetFocusableWindow(void *param)
window->m_isFocusableWindow = isFocusableWindow;
- if (!window->m_isFocusableWindow) {
- LONG isPopup = window->GetStyle() & WS_POPUP;
- window->SetStyleEx(window->GetStyleEx() | (isPopup ? 0 : WS_EX_APPWINDOW) | AWT_WS_EX_NOACTIVATE);
- } else {
- window->SetStyleEx(window->GetStyleEx() & ~WS_EX_APPWINDOW & ~AWT_WS_EX_NOACTIVATE);
+ // A simple window is permanently set to WS_EX_NOACTIVATE
+ if (!window->IsSimpleWindow()) {
+ if (!window->m_isFocusableWindow) {
+ LONG isPopup = window->GetStyle() & WS_POPUP;
+ window->SetStyleEx(window->GetStyleEx() | (isPopup ? 0 : WS_EX_APPWINDOW) | WS_EX_NOACTIVATE);
+ } else {
+ window->SetStyleEx(window->GetStyleEx() & ~WS_EX_APPWINDOW & ~WS_EX_NOACTIVATE);
+ }
}
ret:
@@ -2009,36 +2883,68 @@ void AwtWindow::_ModalEnable(void *param)
env->DeleteGlobalRef(self);
}
-/*
- * Fixed 6353381: it's improved fix for 4792958
- * which was backed-out to avoid 5059656
- */
-BOOL AwtWindow::HasValidRect()
+void AwtWindow::_SetOpacity(void* param)
{
- RECT inside;
- RECT outside;
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- if (::IsIconic(GetHWnd())) {
- return FALSE;
- }
+ OpacityStruct *os = (OpacityStruct *)param;
+ jobject self = os->window;
+ BYTE iOpacity = (BYTE)os->iOpacity;
- ::GetClientRect(GetHWnd(), &inside);
- ::GetWindowRect(GetHWnd(), &outside);
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+ AwtWindow *window = (AwtWindow *)pData;
- BOOL isZeroClientArea = (inside.right == 0 && inside.bottom == 0);
- BOOL isInvalidLocation = ((outside.left == -32000 && outside.top == -32000) || // Win2k && WinXP
- (outside.left == 32000 && outside.top == 32000) || // Win95 && Win98
- (outside.left == 3000 && outside.top == 3000)); // Win95 && Win98
+ window->SetTranslucency(iOpacity, window->isOpaque());
- // the bounds correspond to iconic state
- if (isZeroClientArea && isInvalidLocation)
- {
- return FALSE;
- }
+ ret:
+ env->DeleteGlobalRef(self);
+ delete os;
+}
- return TRUE;
+void AwtWindow::_SetOpaque(void* param)
+{
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ OpaqueStruct *os = (OpaqueStruct *)param;
+ jobject self = os->window;
+ BOOL isOpaque = (BOOL)os->isOpaque;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+ AwtWindow *window = (AwtWindow *)pData;
+
+ window->SetTranslucency(window->getOpacity(), isOpaque);
+
+ ret:
+ env->DeleteGlobalRef(self);
+ delete os;
+}
+
+void AwtWindow::_UpdateWindow(void* param)
+{
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ UpdateWindowStruct *uws = (UpdateWindowStruct *)param;
+ jobject self = uws->window;
+ jintArray data = uws->data;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+ AwtWindow *window = (AwtWindow *)pData;
+
+ window->UpdateWindow(env, data, (int)uws->width, (int)uws->height,
+ uws->hBitmap);
+
+ ret:
+ env->DeleteGlobalRef(self);
+ if (data != NULL) {
+ env->DeleteGlobalRef(data);
+ }
+ delete uws;
}
+
extern "C" {
/*
@@ -2055,8 +2961,16 @@ Java_java_awt_Window_initIDs(JNIEnv *env, jclass cls)
env->GetFieldID(cls, "warningString", "Ljava/lang/String;");
AwtWindow::locationByPlatformID =
env->GetFieldID(cls, "locationByPlatform", "Z");
+ AwtWindow::securityWarningWidthID =
+ env->GetFieldID(cls, "securityWarningWidth", "I");
+ AwtWindow::securityWarningHeightID =
+ env->GetFieldID(cls, "securityWarningHeight", "I");
+ AwtWindow::getWarningStringMID =
+ env->GetMethodID(cls, "getWarningString", "()Ljava/lang/String;");
AwtWindow::autoRequestFocusID =
env->GetFieldID(cls, "autoRequestFocus", "Z");
+ AwtWindow::calculateSecurityWarningPositionMID =
+ env->GetMethodID(cls, "calculateSecurityWarningPosition", "(DDDD)Ljava/awt/geom/Point2D;");
CATCH_BAD_ALLOC;
}
@@ -2489,4 +3403,138 @@ Java_sun_awt_windows_WWindowPeer_nativeUngrab(JNIEnv *env, jobject self)
CATCH_BAD_ALLOC;
}
+/*
+ * Class: sun_awt_windows_WWindowPeer
+ * Method: setOpacity
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WWindowPeer_setOpacity(JNIEnv *env, jobject self,
+ jint iOpacity)
+{
+ TRY;
+
+ OpacityStruct *os = new OpacityStruct;
+ os->window = env->NewGlobalRef(self);
+ os->iOpacity = iOpacity;
+
+ AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpacity, os);
+ // global refs and mds are deleted in _SetMinSize
+
+ CATCH_BAD_ALLOC;
+}
+
+/*
+ * Class: sun_awt_windows_WWindowPeer
+ * Method: setOpaqueImpl
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WWindowPeer_setOpaqueImpl(JNIEnv *env, jobject self,
+ jboolean isOpaque)
+{
+ TRY;
+
+ OpaqueStruct *os = new OpaqueStruct;
+ os->window = env->NewGlobalRef(self);
+ os->isOpaque = isOpaque;
+
+ AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpaque, os);
+ // global refs and mds are deleted in _SetMinSize
+
+ CATCH_BAD_ALLOC;
+}
+
+/*
+ * Class: sun_awt_windows_WWindowPeer
+ * Method: updateWindowImpl
+ * Signature: ([III)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WWindowPeer_updateWindowImpl(JNIEnv *env, jobject self,
+ jintArray data,
+ jint width, jint height)
+{
+ TRY;
+
+ UpdateWindowStruct *uws = new UpdateWindowStruct;
+ uws->window = env->NewGlobalRef(self);
+ uws->data = (jintArray)env->NewGlobalRef(data);
+ uws->hBitmap = NULL;
+ uws->width = width;
+ uws->height = height;
+
+ AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
+ // global refs and mds are deleted in _UpdateWindow
+
+ CATCH_BAD_ALLOC;
+}
+
+/**
+ * This method is called from the WGL pipeline when it needs to update
+ * the layered window WindowPeer's C++ level object.
+ */
+void AwtWindow_UpdateWindow(JNIEnv *env, jobject peer,
+ jint width, jint height, HBITMAP hBitmap)
+{
+ TRY;
+
+ UpdateWindowStruct *uws = new UpdateWindowStruct;
+ uws->window = env->NewGlobalRef(peer);
+ uws->data = NULL;
+ uws->hBitmap = hBitmap;
+ uws->width = width;
+ uws->height = height;
+
+ AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
+ // global refs and mds are deleted in _UpdateWindow
+
+ CATCH_BAD_ALLOC;
+}
+
+/*
+ * Class: sun_awt_windows_WComponentPeer
+ * Method: requestFocus
+ * Signature: (Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WWindowPeer_requestWindowFocus
+ (JNIEnv *env, jobject self, jboolean isMouseEventCause)
+{
+ TRY;
+
+ jobject selfGlobalRef = env->NewGlobalRef(self);
+
+ RequestWindowFocusStruct *rfs = new RequestWindowFocusStruct;
+ rfs->component = selfGlobalRef;
+ rfs->isMouseEventCause = isMouseEventCause;
+
+ return (jboolean)AwtToolkit::GetInstance().SyncCall(
+ (void*(*)(void*))AwtWindow::_RequestWindowFocus, rfs);
+ // global refs and rfs are deleted in _RequestWindowFocus
+
+ CATCH_BAD_ALLOC_RET(JNI_FALSE);
+}
+
+/*
+ * Class: sun_awt_windows_WWindowPeer
+ * Method: repositionSecurityWarning
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WWindowPeer_repositionSecurityWarning(JNIEnv *env,
+ jobject self)
+{
+ TRY;
+
+ RepositionSecurityWarningStruct *rsws =
+ new RepositionSecurityWarningStruct;
+ rsws->window = env->NewGlobalRef(self);
+
+ AwtToolkit::GetInstance().InvokeFunction(
+ AwtWindow::_RepositionSecurityWarning, rsws);
+ // global refs and mds are deleted in _RepositionSecurityWarning
+
+ CATCH_BAD_ALLOC;
+}
+
} /* extern "C" */
diff --git a/src/windows/native/sun/windows/awt_Window.h b/src/windows/native/sun/windows/awt_Window.h
index 9a252a25c..bf43150a7 100644
--- a/src/windows/native/sun/windows/awt_Window.h
+++ b/src/windows/native/sun/windows/awt_Window.h
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,14 +34,12 @@
// property name tagging windows disabled by modality
static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp");
static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp");
+static LPCTSTR NativeDialogWndProcProp = TEXT("SunAwtNativeDialogWndProcProp");
#ifndef WH_MOUSE_LL
#define WH_MOUSE_LL 14
#endif
-// WS_EX_NOACTIVATE is not defined in the headers we build with
-#define AWT_WS_EX_NOACTIVATE 0x08000000L
-
class AwtFrame;
/************************************************************************
@@ -56,6 +54,8 @@ public:
static jfieldID locationByPlatformID;
static jfieldID screenID; /* screen number passed over from WindowPeer */
static jfieldID autoRequestFocusID;
+ static jfieldID securityWarningWidthID;
+ static jfieldID securityWarningHeightID;
// The coordinates at the peer.
static jfieldID sysXID;
@@ -63,6 +63,9 @@ public:
static jfieldID sysWID;
static jfieldID sysHID;
+ static jmethodID getWarningStringMID;
+ static jmethodID calculateSecurityWarningPositionMID;
+
AwtWindow();
virtual ~AwtWindow();
@@ -152,11 +155,12 @@ public:
static void SetModalBlocker(HWND window, HWND blocker);
static void SetAndActivateModalBlocker(HWND window, HWND blocker);
+ static HWND GetTopmostModalBlocker(HWND window);
+
/*
* Windows message handler functions
*/
virtual MsgRouting WmActivate(UINT nState, BOOL fMinimized, HWND opposite);
- static void BounceActivation(void *self); // used by WmActivate
virtual MsgRouting WmCreate();
virtual MsgRouting WmClose();
virtual MsgRouting WmDestroy();
@@ -169,19 +173,36 @@ public:
virtual MsgRouting WmSettingChange(UINT wFlag, LPCTSTR pszSection);
virtual MsgRouting WmNcCalcSize(BOOL fCalcValidRects,
LPNCCALCSIZE_PARAMS lpncsp, LRESULT& retVal);
- virtual MsgRouting WmNcPaint(HRGN hrgn);
virtual MsgRouting WmNcHitTest(UINT x, UINT y, LRESULT& retVal);
virtual MsgRouting WmNcMouseDown(WPARAM hitTest, int x, int y, int button);
virtual MsgRouting WmGetIcon(WPARAM iconType, LRESULT& retVal);
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
virtual MsgRouting WmWindowPosChanging(LPARAM windowPos);
virtual MsgRouting WmWindowPosChanged(LPARAM windowPos);
+ virtual MsgRouting WmTimer(UINT_PTR timerID);
virtual MsgRouting HandleEvent(MSG *msg, BOOL synthetic);
virtual void WindowResized();
+ static jboolean _RequestWindowFocus(void *param);
+
+ virtual BOOL AwtSetActiveWindow(BOOL isMouseEventCause = FALSE, UINT hittest = HTCLIENT);
+
+ // Execute on Toolkit only.
+ INLINE static LRESULT SynthesizeWmActivate(BOOL doActivate, HWND targetHWnd, HWND oppositeHWnd) {
+ if (::IsWindowVisible(targetHWnd)) {
+ return ::SendMessage(targetHWnd, WM_ACTIVATE,
+ MAKEWPARAM(doActivate ? WA_ACTIVE : WA_INACTIVE, FALSE),
+ (LPARAM) oppositeHWnd);
+ }
+ return 1; // if not processed
+ }
+
void moveToDefaultLocation(); /* moves Window to X,Y specified by Window Manger */
+ void UpdateWindow(JNIEnv* env, jintArray data, int width, int height,
+ HBITMAP hNewBitmap = NULL);
+
INLINE virtual BOOL IsTopLevel() { return TRUE; }
static AwtWindow * GetGrabbedWindow() { return m_grabbedWindow; }
@@ -204,11 +225,25 @@ public:
static void _SetModalExcludedNativeProp(void *param);
static void _ModalDisable(void *param);
static void _ModalEnable(void *param);
+ static void _SetOpacity(void* param);
+ static void _SetOpaque(void* param);
+ static void _UpdateWindow(void* param);
+ static void _RepositionSecurityWarning(void* param);
inline static BOOL IsResizing() {
return sm_resizing;
}
+ virtual void CreateHWnd(JNIEnv *env, LPCWSTR title,
+ DWORD windowStyle, DWORD windowExStyle,
+ int x, int y, int w, int h,
+ HWND hWndParent, HMENU hMenu,
+ COLORREF colorForeground, COLORREF colorBackground,
+ jobject peer);
+ virtual void DestroyHWnd();
+
+ static void FocusedWindowChanged(HWND from, HWND to);
+
private:
static int ms_instanceCounter;
static HHOOK ms_hCBTFilter;
@@ -228,6 +263,79 @@ private:
// from its hierarchy when shown. Currently applied to instances of
// javax/swing/Popup$HeavyWeightWindow class.
+ BYTE m_opacity; // The opacity level. == 0xff by default (when opacity mode is disabled)
+ BOOL m_opaque; // Whether the window uses the perpixel translucency (false), or not (true).
+
+ inline BYTE getOpacity() {
+ return m_opacity;
+ }
+ inline void setOpacity(BYTE opacity) {
+ m_opacity = opacity;
+ }
+
+ inline BOOL isOpaque() {
+ return m_opaque;
+ }
+ inline void setOpaque(BOOL opaque) {
+ m_opaque = opaque;
+ }
+
+ CRITICAL_SECTION contentBitmapCS;
+ HBITMAP hContentBitmap;
+ UINT contentWidth;
+ UINT contentHeight;
+
+ void SetTranslucency(BYTE opacity, BOOL opaque);
+ void UpdateWindow(int width, int height, HBITMAP hBitmap);
+ void UpdateWindowImpl(int width, int height, HBITMAP hBitmap);
+ void RedrawWindow();
+
+ static UINT untrustedWindowsCounter;
+
+ WCHAR * warningString;
+
+ // The warning icon
+ HWND warningWindow;
+ // The tooltip that appears when hovering the icon
+ HWND securityTooltipWindow;
+
+ UINT warningWindowWidth;
+ UINT warningWindowHeight;
+ void InitSecurityWarningSize(JNIEnv *env);
+ HICON GetSecurityWarningIcon();
+
+ void CreateWarningWindow(JNIEnv *env);
+ void DestroyWarningWindow();
+ static LPCTSTR GetWarningWindowClassName();
+ void FillWarningWindowClassInfo(WNDCLASS *lpwc);
+ void RegisterWarningWindowClass();
+ void UnregisterWarningWindowClass();
+ static LRESULT CALLBACK WarningWindowProc(
+ HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ static void PaintWarningWindow(HWND warningWindow);
+ static void PaintWarningWindow(HWND warningWindow, HDC hdc);
+ void RepaintWarningWindow();
+ void CalculateWarningWindowBounds(JNIEnv *env, LPRECT rect);
+
+ void AnimateSecurityWarning(bool enable);
+ UINT securityWarningAnimationStage;
+
+ enum AnimationKind {
+ akNone, akShow, akPreHide, akHide
+ };
+
+ AnimationKind securityAnimationKind;
+
+ void StartSecurityAnimation(AnimationKind kind);
+ void StopSecurityAnimation();
+
+ void RepositionSecurityWarning(JNIEnv *env);
+
+public:
+ void UpdateSecurityWarningVisibility();
+ static bool IsWarningWindow(HWND hWnd);
+
protected:
BOOL m_isResizable;
static AwtWindow* m_grabbedWindow; // Current grabbing window
@@ -236,6 +344,16 @@ protected:
BOOL m_iconInherited; /* TRUE if icon is inherited from the owner */
BOOL m_filterFocusAndActivation; /* Used in the WH_CBT hook */
+ //These are used in AwtComponent::CreatePrintedPixels. They are overridden
+ //here to handle non-opaque windows.
+ virtual void FillBackground(HDC hMemoryDC, SIZE &size);
+ virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
+
+ inline BOOL IsUntrusted() {
+ return warningString != NULL;
+ }
+
+ UINT currentWmSizeState;
private:
int m_screenNum;
diff --git a/src/windows/native/sun/windows/awtmsg.h b/src/windows/native/sun/windows/awtmsg.h
index 35e436b53..8c0806219 100644
--- a/src/windows/native/sun/windows/awtmsg.h
+++ b/src/windows/native/sun/windows/awtmsg.h
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -194,6 +194,7 @@ enum {
WM_AWT_COMPONENT_SHOW,
WM_AWT_COMPONENT_HIDE,
WM_AWT_COMPONENT_SETFOCUS,
+ WM_AWT_WINDOW_SETACTIVE,
WM_AWT_LIST_SETMULTISELECT,
WM_AWT_HANDLE_EVENT,
WM_AWT_PRINT_COMPONENT,
diff --git a/src/windows/native/sun/windows/security_warning.ico b/src/windows/native/sun/windows/security_warning.ico
new file mode 100644
index 000000000..67793ed82
--- /dev/null
+++ b/src/windows/native/sun/windows/security_warning.ico
Binary files differ
diff --git a/src/windows/native/sun/windows/security_warning_bw.ico b/src/windows/native/sun/windows/security_warning_bw.ico
new file mode 100644
index 000000000..68a1824a2
--- /dev/null
+++ b/src/windows/native/sun/windows/security_warning_bw.ico
Binary files differ
diff --git a/src/windows/native/sun/windows/security_warning_int.ico b/src/windows/native/sun/windows/security_warning_int.ico
new file mode 100644
index 000000000..d773dca9e
--- /dev/null
+++ b/src/windows/native/sun/windows/security_warning_int.ico
Binary files differ