--- a/jdk/src/share/classes/java/applet/Applet.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/java/applet/Applet.java Wed Nov 18 17:17:56 2009 -0800
@@ -230,6 +230,21 @@
}
/**
+ * Indicates if this container is a validate root.
+ * <p>
+ * {@code Applet} objects are the validate roots, and, therefore, they
+ * override this method to return {@code true}.
+ *
+ * @return {@code true}
+ * @since 1.7
+ * @see java.awt.Container#isValidateRoot
+ */
+ @Override
+ public boolean isValidateRoot() {
+ return true;
+ }
+
+ /**
* Requests that the argument string be displayed in the
* "status window". Many browsers and applet viewers
* provide such a window, where the application can inform users of
--- a/jdk/src/share/classes/java/awt/AWTPermission.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/java/awt/AWTPermission.java Wed Nov 18 17:17:56 2009 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2005 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
@@ -92,7 +92,15 @@
* <td>Enter full-screen exclusive mode</td>
* <td>Entering full-screen exclusive mode allows direct access to
* low-level graphics card memory. This could be used to spoof the
- * system, since the program is in direct control of rendering.</td>
+ * system, since the program is in direct control of rendering. Depending on
+ * the implementation, the security warning may not be shown for the windows
+ * used to enter the full-screen exclusive mode (assuming that the {@code
+ * fullScreenExclusive} permission has been granted to this application). Note
+ * that this behavior does not mean that the {@code
+ * showWindowWithoutWarningBanner} permission will be automatically granted to
+ * the application which has the {@code fullScreenExclusive} permission:
+ * non-full-screen windows will continue to be shown with the security
+ * warning.</td>
* </tr>
*
* <tr>
--- a/jdk/src/share/classes/java/awt/Component.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Component.java Wed Nov 18 17:17:56 2009 -0800
@@ -2764,8 +2764,11 @@
}
/**
- * Ensures that this component has a valid layout. This method is
- * primarily intended to operate on instances of <code>Container</code>.
+ * Validates this component.
+ * <p>
+ * The meaning of the term <i>validating</i> is defined by the ancestors of
+ * this class. See {@link Container#validate} for more details.
+ *
* @see #invalidate
* @see #doLayout()
* @see LayoutManager
@@ -2794,12 +2797,24 @@
}
/**
- * Invalidates this component. This component and all parents
- * above it are marked as needing to be laid out. This method can
- * be called often, so it needs to execute quickly.
+ * Invalidates this component and its ancestors.
+ * <p>
+ * All the ancestors of this component up to the nearest validate root are
+ * marked invalid also. If there is no a validate root container for this
+ * component, all of its ancestors up to the root of the hierarchy are
+ * marked invalid as well. Marking a container <i>invalid</i> indicates
+ * that the container needs to be laid out.
+ * <p>
+ * This method is called automatically when any layout-related information
+ * changes (e.g. setting the bounds of the component, or adding the
+ * component to a container).
+ * <p>
+ * This method might be called often, so it should work fast.
+ *
* @see #validate
* @see #doLayout
* @see LayoutManager
+ * @see java.awt.Container#isValidateRoot
* @since JDK1.0
*/
public void invalidate() {
@@ -2818,9 +2833,18 @@
if (!isMaximumSizeSet()) {
maxSize = null;
}
- if (parent != null) {
- parent.invalidateIfValid();
- }
+ invalidateParent();
+ }
+ }
+
+ /**
+ * Invalidates the parent of this component if any.
+ *
+ * This method MUST BE invoked under the TreeLock.
+ */
+ void invalidateParent() {
+ if (parent != null) {
+ parent.invalidateIfValid();
}
}
@@ -6727,12 +6751,13 @@
}
}
} else {
- // It's native. If the parent is lightweight it
- // will need some help.
- Container parent = this.parent;
- if (parent != null && parent.peer instanceof LightweightPeer) {
+ // It's native. If the parent is lightweight it will need some
+ // help.
+ Container parent = getContainer();
+ if (parent != null && parent.isLightweight()) {
relocateComponent();
- if (!isRecursivelyVisible()) {
+ if (!parent.isRecursivelyVisibleUpToHeavyweightContainer())
+ {
peer.setVisible(false);
}
}
--- a/jdk/src/share/classes/java/awt/Container.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Container.java Wed Nov 18 17:17:56 2009 -0800
@@ -1492,20 +1492,59 @@
}
/**
- * Invalidates the container. The container and all parents
- * above it are marked as needing to be laid out. This method can
- * be called often, so it needs to execute quickly.
+ * Indicates if this container is a <i>validate root</i>.
+ * <p>
+ * Layout-related changes, such as bounds of the validate root descendants,
+ * do not affect the layout of the validate root parent. This peculiarity
+ * enables the {@code invalidate()} method to stop invalidating the
+ * component hierarchy when the method encounters a validate root.
+ * <p>
+ * If a component hierarchy contains validate roots, the {@code validate()}
+ * method must be invoked on the validate root of a previously invalidated
+ * component, rather than on the top-level container (such as a {@code
+ * Frame} object) to restore the validity of the hierarchy later.
+ * <p>
+ * The {@code Window} class and the {@code Applet} class are the validate
+ * roots in AWT. Swing introduces more validate roots.
*
- * <p> If the {@code LayoutManager} installed on this container is
- * an instance of {@code LayoutManager2}, then
- * {@link LayoutManager2#invalidateLayout(Container)} is invoked on
- * it supplying this {@code Container} as the argument.
+ * @return whether this container is a validate root
+ * @see #invalidate
+ * @see java.awt.Component#invalidate
+ * @see javax.swing.JComponent#isValidateRoot
+ * @see javax.swing.JComponent#revalidate
+ * @since 1.7
+ */
+ public boolean isValidateRoot() {
+ return false;
+ }
+
+ /**
+ * Invalidates the parent of the container unless the container
+ * is a validate root.
+ */
+ @Override
+ void invalidateParent() {
+ if (!isValidateRoot()) {
+ super.invalidateParent();
+ }
+ }
+
+ /**
+ * Invalidates the container.
+ * <p>
+ * If the {@code LayoutManager} installed on this container is an instance
+ * of the {@code LayoutManager2} interface, then
+ * the {@link LayoutManager2#invalidateLayout(Container)} method is invoked
+ * on it supplying this {@code Container} as the argument.
+ * <p>
+ * Afterwards this method marks this container invalid, and invalidates its
+ * ancestors. See the {@link Component#invalidate} method for more details.
*
* @see #validate
* @see #layout
- * @see LayoutManager
- * @see LayoutManager2#invalidateLayout(Container)
+ * @see LayoutManager2
*/
+ @Override
public void invalidate() {
LayoutManager layoutMgr = this.layoutMgr;
if (layoutMgr instanceof LayoutManager2) {
@@ -1518,52 +1557,90 @@
/**
* Validates this container and all of its subcomponents.
* <p>
- * The <code>validate</code> method is used to cause a container
- * to lay out its subcomponents again. It should be invoked when
- * this container's subcomponents are modified (added to or
- * removed from the container, or layout-related information
- * changed) after the container has been displayed.
- *
- * <p>If this {@code Container} is not valid, this method invokes
+ * Validating a container means laying out its subcomponents.
+ * Layout-related changes, such as setting the bounds of a component, or
+ * adding a component to the container, invalidate the container
+ * automatically. Note that the ancestors of the container may be
+ * invalidated also (see {@link Component#invalidate} for details.)
+ * Therefore, to restore the validity of the hierarchy, the {@code
+ * validate()} method should be invoked on a validate root of an
+ * invalidated component, or on the top-most container if the hierarchy
+ * does not contain validate roots.
+ * <p>
+ * Validating the container may be a quite time-consuming operation. For
+ * performance reasons a developer may postpone the validation of the
+ * hierarchy till a set of layout-related operations completes, e.g. after
+ * adding all the children to the container.
+ * <p>
+ * If this {@code Container} is not valid, this method invokes
* the {@code validateTree} method and marks this {@code Container}
* as valid. Otherwise, no action is performed.
- * <p>
- * Note that the {@code invalidate()} method may invalidate not only the
- * component it is called upon, but also the parents of the component.
- * Therefore, to restore the validity of the hierarchy, the {@code
- * validate()} method must be invoked on the top-most invalid container of
- * the hierarchy. For performance reasons a developer may postpone the
- * validation of the hierarchy till a bunch of layout-related operations
- * completes, e.g. after adding all the children to the container.
*
* @see #add(java.awt.Component)
* @see #invalidate
+ * @see Container#isValidateRoot
* @see javax.swing.JComponent#revalidate()
* @see #validateTree
*/
public void validate() {
- /* Avoid grabbing lock unless really necessary. */
- if (!isValid()) {
- boolean updateCur = false;
- synchronized (getTreeLock()) {
- if (!isValid() && peer != null) {
- ContainerPeer p = null;
- if (peer instanceof ContainerPeer) {
- p = (ContainerPeer) peer;
- }
- if (p != null) {
- p.beginValidate();
- }
- validateTree();
- if (p != null) {
- p.endValidate();
+ boolean updateCur = false;
+ synchronized (getTreeLock()) {
+ if ((!isValid() || descendUnconditionallyWhenValidating)
+ && peer != null)
+ {
+ ContainerPeer p = null;
+ if (peer instanceof ContainerPeer) {
+ p = (ContainerPeer) peer;
+ }
+ if (p != null) {
+ p.beginValidate();
+ }
+ validateTree();
+ if (p != null) {
+ p.endValidate();
+ // Avoid updating cursor if this is an internal call.
+ // See validateUnconditionally() for details.
+ if (!descendUnconditionallyWhenValidating) {
updateCur = isVisible();
}
}
}
- if (updateCur) {
- updateCursorImmediately();
+ }
+ if (updateCur) {
+ updateCursorImmediately();
+ }
+ }
+
+ /**
+ * Indicates whether valid containers should also traverse their
+ * children and call the validateTree() method on them.
+ *
+ * Synchronization: TreeLock.
+ *
+ * The field is allowed to be static as long as the TreeLock itself is
+ * static.
+ *
+ * @see #validateUnconditionally()
+ */
+ private static boolean descendUnconditionallyWhenValidating = false;
+
+ /**
+ * Unconditionally validate the component hierarchy.
+ */
+ final void validateUnconditionally() {
+ boolean updateCur = false;
+ synchronized (getTreeLock()) {
+ descendUnconditionallyWhenValidating = true;
+
+ validate();
+ if (peer instanceof ContainerPeer) {
+ updateCur = isVisible();
}
+
+ descendUnconditionallyWhenValidating = false;
+ }
+ if (updateCur) {
+ updateCursorImmediately();
}
}
@@ -1578,16 +1655,20 @@
*/
protected void validateTree() {
checkTreeLock();
- if (!isValid()) {
+ if (!isValid() || descendUnconditionallyWhenValidating) {
if (peer instanceof ContainerPeer) {
((ContainerPeer)peer).beginLayout();
}
- doLayout();
+ if (!isValid()) {
+ doLayout();
+ }
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if ( (comp instanceof Container)
&& !(comp instanceof Window)
- && !comp.isValid()) {
+ && (!comp.isValid() ||
+ descendUnconditionallyWhenValidating))
+ {
((Container)comp).validateTree();
} else {
comp.validate();
@@ -4092,16 +4173,29 @@
}
}
- /*
+ /**
+ * Checks if the container and its direct lightweight containers are
+ * visible.
+ *
* Consider the heavyweight container hides or shows the HW descendants
* automatically. Therefore we care of LW containers' visibility only.
+ *
+ * This method MUST be invoked under the TreeLock.
*/
- private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
+ final boolean isRecursivelyVisibleUpToHeavyweightContainer() {
if (!isLightweight()) {
return true;
}
- return isVisible() && (getContainer() == null ||
- getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
+
+ for (Container cont = getContainer();
+ cont != null && cont.isLightweight();
+ cont = cont.getContainer())
+ {
+ if (!cont.isVisible()) {
+ return false;
+ }
+ }
+ return true;
}
@Override
--- a/jdk/src/share/classes/java/awt/EventQueue.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/java/awt/EventQueue.java Wed Nov 18 17:17:56 2009 -0800
@@ -1027,7 +1027,9 @@
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
- lock.wait();
+ while (!event.isDispatched()) {
+ lock.wait();
+ }
}
Throwable eventThrowable = event.getThrowable();
--- a/jdk/src/share/classes/java/awt/Frame.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Frame.java Wed Nov 18 17:17:56 2009 -0800
@@ -845,8 +845,11 @@
* others by setting those fields you want to accept from system
* to <code>Integer.MAX_VALUE</code>.
* <p>
- * On some systems only the size portion of the bounds is taken
- * into account.
+ * Note, the given maximized bounds are used as a hint for the native
+ * system, because the underlying platform may not support setting the
+ * location and/or size of the maximized windows. If that is the case, the
+ * provided values do not affect the appearance of the frame in the
+ * maximized state.
*
* @param bounds bounds for the maximized state
* @see #getMaximizedBounds()
--- a/jdk/src/share/classes/java/awt/Window.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Window.java Wed Nov 18 17:17:56 2009 -0800
@@ -767,7 +767,7 @@
isPacked = true;
}
- validate();
+ validateUnconditionally();
}
/**
@@ -943,7 +943,7 @@
if (peer == null) {
addNotify();
}
- validate();
+ validateUnconditionally();
isInShow = true;
if (visible) {
@@ -2600,6 +2600,21 @@
}
/**
+ * Indicates if this container is a validate root.
+ * <p>
+ * {@code Window} objects are the validate roots, and, therefore, they
+ * override this method to return {@code true}.
+ *
+ * @return {@code true}
+ * @since 1.7
+ * @see java.awt.Container#isValidateRoot
+ */
+ @Override
+ public boolean isValidateRoot() {
+ return true;
+ }
+
+ /**
* Dispatches an event to this window or one of its sub components.
* @param e the event
*/
--- a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java Wed Nov 18 17:17:56 2009 -0800
@@ -1184,7 +1184,7 @@
*/
public boolean isRepresentationClassRemote() {
- return java.rmi.Remote.class.isAssignableFrom(representationClass);
+ return DataTransferer.isRemote(representationClass);
}
/**
--- a/jdk/src/share/classes/java/awt/event/InvocationEvent.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/java/awt/event/InvocationEvent.java Wed Nov 18 17:17:56 2009 -0800
@@ -78,11 +78,22 @@
/**
* The (potentially null) Object whose notifyAll() method will be called
- * immediately after the Runnable.run() method returns.
+ * immediately after the Runnable.run() method has returned or thrown an exception.
+ *
+ * @see #isDispatched
*/
protected Object notifier;
/**
+ * Indicates whether the <code>run()</code> method of the <code>runnable</code>
+ * was executed or not.
+ *
+ * @see #isDispatched
+ * @since 1.7
+ */
+ private volatile boolean dispatched = false;
+
+ /**
* Set to true if dispatch() catches Throwable and stores it in the
* exception instance variable. If false, Throwables are propagated up
* to the EventDispatchThread's dispatch loop.
@@ -144,7 +155,7 @@
* source which will execute the runnable's <code>run</code>
* method when dispatched. If notifier is non-<code>null</code>,
* <code>notifyAll()</code> will be called on it
- * immediately after <code>run</code> returns.
+ * immediately after <code>run</code> has returned or thrown an exception.
* <p>An invocation of the form <tt>InvocationEvent(source,
* runnable, notifier, catchThrowables)</tt>
* behaves in exactly the same way as the invocation of
@@ -159,7 +170,8 @@
* executed
* @param notifier The {@code Object} whose <code>notifyAll</code>
* method will be called after
- * <code>Runnable.run</code> has returned
+ * <code>Runnable.run</code> has returned or
+ * thrown an exception
* @param catchThrowables Specifies whether <code>dispatch</code>
* should catch Throwable when executing
* the <code>Runnable</code>'s <code>run</code>
@@ -180,8 +192,8 @@
* Constructs an <code>InvocationEvent</code> with the specified
* source and ID which will execute the runnable's <code>run</code>
* method when dispatched. If notifier is non-<code>null</code>,
- * <code>notifyAll</code> will be called on it
- * immediately after <code>run</code> returns.
+ * <code>notifyAll</code> will be called on it immediately after
+ * <code>run</code> has returned or thrown an exception.
* <p>This method throws an
* <code>IllegalArgumentException</code> if <code>source</code>
* is <code>null</code>.
@@ -195,7 +207,8 @@
* <code>run</code> method will be executed
* @param notifier The <code>Object</code> whose <code>notifyAll</code>
* method will be called after
- * <code>Runnable.run</code> has returned
+ * <code>Runnable.run</code> has returned or
+ * thrown an exception
* @param catchThrowables Specifies whether <code>dispatch</code>
* should catch Throwable when executing the
* <code>Runnable</code>'s <code>run</code>
@@ -217,27 +230,33 @@
/**
* Executes the Runnable's <code>run()</code> method and notifies the
- * notifier (if any) when <code>run()</code> returns.
+ * notifier (if any) when <code>run()</code> has returned or thrown an exception.
+ *
+ * @see #isDispatched
*/
public void dispatch() {
- if (catchExceptions) {
- try {
+ try {
+ if (catchExceptions) {
+ try {
+ runnable.run();
+ }
+ catch (Throwable t) {
+ if (t instanceof Exception) {
+ exception = (Exception) t;
+ }
+ throwable = t;
+ }
+ }
+ else {
runnable.run();
}
- catch (Throwable t) {
- if (t instanceof Exception) {
- exception = (Exception) t;
+ } finally {
+ dispatched = true;
+
+ if (notifier != null) {
+ synchronized (notifier) {
+ notifier.notifyAll();
}
- throwable = t;
- }
- }
- else {
- runnable.run();
- }
-
- if (notifier != null) {
- synchronized (notifier) {
- notifier.notifyAll();
}
}
}
@@ -278,6 +297,40 @@
}
/**
+ * Returns {@code true} if the event is dispatched or any exception is
+ * thrown while dispatching, {@code false} otherwise. The method should
+ * be called by a waiting thread that calls the {@code notifier.wait()} method.
+ * Since spurious wakeups are possible (as explained in {@link Object#wait()}),
+ * this method should be used in a waiting loop to ensure that the event
+ * got dispatched:
+ * <pre>
+ * while (!event.isDispatched()) {
+ * notifier.wait();
+ * }
+ * </pre>
+ * If the waiting thread wakes up without dispatching the event,
+ * the {@code isDispatched()} method returns {@code false}, and
+ * the {@code while} loop executes once more, thus, causing
+ * the awakened thread to revert to the waiting mode.
+ * <p>
+ * If the {@code notifier.notifyAll()} happens before the waiting thread
+ * enters the {@code notifier.wait()} method, the {@code while} loop ensures
+ * that the waiting thread will not enter the {@code notifier.wait()} method.
+ * Otherwise, there is no guarantee that the waiting thread will ever be woken
+ * from the wait.
+ *
+ * @return {@code true} if the event has been dispatched, or any exception
+ * has been thrown while dispatching, {@code false} otherwise
+ * @see #dispatch
+ * @see #notifier
+ * @see #catchExceptions
+ * @since 1.7
+ */
+ public boolean isDispatched() {
+ return dispatched;
+ }
+
+ /**
* Returns a parameter string identifying this event.
* This method is useful for event-logging and for debugging.
*
--- a/jdk/src/share/classes/javax/swing/JComponent.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JComponent.java Wed Nov 18 17:17:56 2009 -0800
@@ -795,7 +795,6 @@
* @see java.awt.Container#paint
*/
protected void paintChildren(Graphics g) {
- boolean isJComponent;
Graphics sg = g;
synchronized(getTreeLock()) {
@@ -826,12 +825,21 @@
}
}
boolean printing = getFlag(IS_PRINTING);
+ final Window window = SwingUtilities.getWindowAncestor(this);
+ final boolean isWindowOpaque = window == null || window.isOpaque();
for (; i >= 0 ; i--) {
Component comp = getComponent(i);
- isJComponent = (comp instanceof JComponent);
- if (comp != null &&
- (isJComponent || isLightweightComponent(comp)) &&
- (comp.isVisible() == true)) {
+ if (comp == null) {
+ continue;
+ }
+
+ final boolean isJComponent = comp instanceof JComponent;
+
+ // Enable painting of heavyweights in non-opaque windows.
+ // See 6884960
+ if ((!isWindowOpaque || isJComponent ||
+ isLightweightComponent(comp)) && comp.isVisible())
+ {
Rectangle cr;
cr = comp.getBounds(tmpRect);
@@ -887,6 +895,8 @@
}
}
} else {
+ // The component is either lightweight, or
+ // heavyweight in a non-opaque window
if (!printing) {
comp.paint(cg);
}
@@ -4868,7 +4878,9 @@
* @see #revalidate
* @see java.awt.Component#invalidate
* @see java.awt.Container#validate
- */
+ * @see java.awt.Container#isValidateRoot
+ */
+ @Override
public boolean isValidateRoot() {
return false;
}
--- a/jdk/src/share/classes/javax/swing/JRootPane.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JRootPane.java Wed Nov 18 17:17:56 2009 -0800
@@ -725,8 +725,10 @@
* because both classes override <code>isValidateRoot</code> to return true.
*
* @see JComponent#isValidateRoot
+ * @see java.awt.Container#isValidateRoot
* @return true
*/
+ @Override
public boolean isValidateRoot() {
return true;
}
--- a/jdk/src/share/classes/javax/swing/JScrollPane.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JScrollPane.java Wed Nov 18 17:17:56 2009 -0800
@@ -453,10 +453,12 @@
* @see java.awt.Container#validate
* @see JComponent#revalidate
* @see JComponent#isValidateRoot
+ * @see java.awt.Container#isValidateRoot
*
* @beaninfo
* hidden: true
*/
+ @Override
public boolean isValidateRoot() {
return true;
}
--- a/jdk/src/share/classes/javax/swing/JSplitPane.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JSplitPane.java Wed Nov 18 17:17:56 2009 -0800
@@ -947,10 +947,12 @@
*
* @return true
* @see JComponent#revalidate
+ * @see java.awt.Container#isValidateRoot
*
* @beaninfo
* hidden: true
*/
+ @Override
public boolean isValidateRoot() {
return true;
}
--- a/jdk/src/share/classes/javax/swing/JTextField.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JTextField.java Wed Nov 18 17:17:56 2009 -0800
@@ -288,7 +288,9 @@
*
* @see JComponent#revalidate
* @see JComponent#isValidateRoot
+ * @see java.awt.Container#isValidateRoot
*/
+ @Override
public boolean isValidateRoot() {
return SwingUtilities2.getViewport(this) == null;
}
--- a/jdk/src/share/classes/javax/swing/JViewport.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JViewport.java Wed Nov 18 17:17:56 2009 -0800
@@ -469,49 +469,12 @@
* is the synchronous version of a <code>revalidate</code>.
*/
private void validateView() {
- Component validateRoot = null;
+ Component validateRoot = SwingUtilities.getValidateRoot(this, false);
- /* Find the first JComponent ancestor of this component whose
- * isValidateRoot() method returns true.
- */
- for(Component c = this; c != null; c = c.getParent()) {
- if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
- return;
- }
- if ((c instanceof JComponent) &&
- (((JComponent)c).isValidateRoot())) {
- validateRoot = c;
- break;
- }
- }
-
- // If no validateRoot, nothing to validate from.
if (validateRoot == null) {
return;
}
- // Make sure all ancestors are visible.
- Component root = null;
-
- for(Component c = validateRoot; c != null; c = c.getParent()) {
- // We don't check isVisible here, otherwise if the component
- // is contained in something like a JTabbedPane when the
- // component is made visible again it won't have scrolled
- // to the correct location.
- if (c.getPeer() == null) {
- return;
- }
- if ((c instanceof Window) || (c instanceof Applet)) {
- root = c;
- break;
- }
- }
-
- // Make sure there is a Window ancestor.
- if (root == null) {
- return;
- }
-
// Validate the root.
validateRoot.validate();
--- a/jdk/src/share/classes/javax/swing/RepaintManager.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/RepaintManager.java Wed Nov 18 17:17:56 2009 -0800
@@ -310,47 +310,13 @@
delegate.addInvalidComponent(invalidComponent);
return;
}
- Component validateRoot = null;
+ Component validateRoot =
+ SwingUtilities.getValidateRoot(invalidComponent, true);
- /* Find the first JComponent ancestor of this component whose
- * isValidateRoot() method returns true.
- */
- for(Component c = invalidComponent; c != null; c = c.getParent()) {
- if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
- return;
- }
- if ((c instanceof JComponent) && (((JComponent)c).isValidateRoot())) {
- validateRoot = c;
- break;
- }
- }
-
- /* There's no validateRoot to apply validate to, so we're done.
- */
if (validateRoot == null) {
return;
}
- /* If the validateRoot and all of its ancestors aren't visible
- * then we don't do anything. While we're walking up the tree
- * we find the root Window or Applet.
- */
- Component root = null;
-
- for(Component c = validateRoot; c != null; c = c.getParent()) {
- if (!c.isVisible() || (c.getPeer() == null)) {
- return;
- }
- if ((c instanceof Window) || (c instanceof Applet)) {
- root = c;
- break;
- }
- }
-
- if (root == null) {
- return;
- }
-
/* Lazily create the invalidateComponents vector and add the
* validateRoot if it's not there already. If this validateRoot
* is already in the vector, we're done.
--- a/jdk/src/share/classes/javax/swing/SwingUtilities.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/SwingUtilities.java Wed Nov 18 17:17:56 2009 -0800
@@ -1967,4 +1967,54 @@
SwingUtilities.updateComponentTreeUI(component);
}
}
+
+ /**
+ * Retrieves the validate root of a given container.
+ *
+ * If the container is contained within a {@code CellRendererPane}, this
+ * method returns {@code null} due to the synthetic nature of the {@code
+ * CellRendererPane}.
+ * <p>
+ * The component hierarchy must be displayable up to the toplevel component
+ * (either a {@code Frame} or an {@code Applet} object.) Otherwise this
+ * method returns {@code null}.
+ * <p>
+ * If the {@code visibleOnly} argument is {@code true}, the found validate
+ * root and all its parents up to the toplevel component must also be
+ * visible. Otherwise this method returns {@code null}.
+ *
+ * @return the validate root of the given container or null
+ * @see java.awt.Component#isDisplayable()
+ * @see java.awt.Component#isVisible()
+ * @since 1.7
+ */
+ static Container getValidateRoot(Container c, boolean visibleOnly) {
+ Container root = null;
+
+ for (; c != null; c = c.getParent())
+ {
+ if (!c.isDisplayable() || c instanceof CellRendererPane) {
+ return null;
+ }
+ if (c.isValidateRoot()) {
+ root = c;
+ break;
+ }
+ }
+
+ if (root == null) {
+ return null;
+ }
+
+ for (; c != null; c = c.getParent()) {
+ if (!c.isDisplayable() || (visibleOnly && !c.isVisible())) {
+ return null;
+ }
+ if (c instanceof Window || c instanceof Applet) {
+ return root;
+ }
+ }
+
+ return null;
+ }
}
--- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Nov 18 17:17:56 2009 -0800
@@ -63,8 +63,6 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.rmi.MarshalledObject;
-
import java.security.AccessControlContext;
import java.security.AccessControlException;
import java.security.AccessController;
@@ -494,6 +492,13 @@
}
/**
+ * Returns {@code true} if the given type is a java.rmi.Remote.
+ */
+ public static boolean isRemote(Class<?> type) {
+ return RMI.isRemote(type);
+ }
+
+ /**
* Returns an Iterator which traverses a SortedSet of Strings which are
* a total order of the standard character sets supported by the JRE. The
* ordering follows the same principles as DataFlavor.selectBestTextFlavor.
@@ -1360,7 +1365,7 @@
// Source data is an RMI object
} else if (flavor.isRepresentationClassRemote()) {
- MarshalledObject mo = new MarshalledObject(obj);
+ Object mo = RMI.newMarshalledObject(obj);
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(mo);
oos.close();
@@ -1671,7 +1676,7 @@
try {
byte[] ba = inputStreamToByteArray(str);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba));
- Object ret = ((MarshalledObject)(ois.readObject())).get();
+ Object ret = RMI.getMarshalledObject(ois.readObject());
ois.close();
str.close();
return ret;
@@ -2669,8 +2674,12 @@
Integer.valueOf(0));
nonTextRepresentationsMap.put(java.io.Serializable.class,
Integer.valueOf(1));
- nonTextRepresentationsMap.put(java.rmi.Remote.class,
- Integer.valueOf(2));
+
+ Class<?> remoteClass = RMI.remoteClass();
+ if (remoteClass != null) {
+ nonTextRepresentationsMap.put(remoteClass,
+ Integer.valueOf(2));
+ }
nonTextRepresentations =
Collections.unmodifiableMap(nonTextRepresentationsMap);
@@ -2900,4 +2909,95 @@
}
}
}
+
+ /**
+ * A class that provides access to java.rmi.Remote and java.rmi.MarshalledObject
+ * without creating a static dependency.
+ */
+ private static class RMI {
+ private static final Class<?> remoteClass = getClass("java.rmi.Remote");
+ private static final Class<?> marshallObjectClass =
+ getClass("java.rmi.MarshalledObject");
+ private static final Constructor<?> marshallCtor =
+ getConstructor(marshallObjectClass, Object.class);
+ private static final Method marshallGet =
+ getMethod(marshallObjectClass, "get");
+
+ private static Class<?> getClass(String name) {
+ try {
+ return Class.forName(name, true, null);
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ private static Constructor<?> getConstructor(Class<?> c, Class<?>... types) {
+ try {
+ return (c == null) ? null : c.getDeclaredConstructor(types);
+ } catch (NoSuchMethodException x) {
+ throw new AssertionError(x);
+ }
+ }
+
+ private static Method getMethod(Class<?> c, String name, Class<?>... types) {
+ try {
+ return (c == null) ? null : c.getMethod(name, types);
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Returns {@code true} if the given class is java.rmi.Remote.
+ */
+ static boolean isRemote(Class<?> c) {
+ return (remoteClass == null) ? null : remoteClass.isAssignableFrom(c);
+ }
+
+ /**
+ * Returns java.rmi.Remote.class if RMI is present; otherwise {@code null}.
+ */
+ static Class<?> remoteClass() {
+ return remoteClass;
+ }
+
+ /**
+ * Returns a new MarshalledObject containing the serialized representation
+ * of the given object.
+ */
+ static Object newMarshalledObject(Object obj) throws IOException {
+ try {
+ return marshallCtor.newInstance(obj);
+ } catch (InstantiationException x) {
+ throw new AssertionError(x);
+ } catch (IllegalAccessException x) {
+ throw new AssertionError(x);
+ } catch (InvocationTargetException x) {
+ Throwable cause = x.getCause();
+ if (cause instanceof IOException)
+ throw (IOException)cause;
+ throw new AssertionError(x);
+ }
+ }
+
+ /**
+ * Returns a new copy of the contained marshalled object.
+ */
+ static Object getMarshalledObject(Object obj)
+ throws IOException, ClassNotFoundException
+ {
+ try {
+ return marshallGet.invoke(obj);
+ } catch (IllegalAccessException x) {
+ throw new AssertionError(x);
+ } catch (InvocationTargetException x) {
+ Throwable cause = x.getCause();
+ if (cause instanceof IOException)
+ throw (IOException)cause;
+ if (cause instanceof ClassNotFoundException)
+ throw (ClassNotFoundException)cause;
+ throw new AssertionError(x);
+ }
+ }
+ }
}
--- a/jdk/src/share/classes/sun/awt/im/InputMethodManager.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/share/classes/sun/awt/im/InputMethodManager.java Wed Nov 18 17:17:56 2009 -0800
@@ -358,7 +358,9 @@
AppContext requesterAppContext = SunToolkit.targetToAppContext(requester);
synchronized (lock) {
SunToolkit.postEvent(requesterAppContext, event);
- lock.wait();
+ while (!event.isDispatched()) {
+ lock.wait();
+ }
}
Throwable eventThrowable = event.getThrowable();
--- a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java Wed Nov 18 17:17:56 2009 -0800
@@ -534,71 +534,71 @@
return entry.getSite(x, y);
}
+ /*
+ * Note: this method should be called under AWT lock.
+ */
public void registerDropSite(long window) {
+ assert XToolkit.isAWTLockHeldByCurrentThread();
+
if (window == 0) {
throw new IllegalArgumentException();
}
XDropTargetEventProcessor.activate();
- XToolkit.awtLock();
- try {
- long toplevel = getToplevelWindow(window);
+ long toplevel = getToplevelWindow(window);
- /*
- * No window with WM_STATE property is found.
- * Since the window can be a plugin window reparented to the browser
- * toplevel, we cannot determine which window will eventually have
- * WM_STATE property set. So we schedule a timer callback that will
- * periodically attempt to find an ancestor with WM_STATE and
- * register the drop site appropriately.
- */
- if (toplevel == 0) {
- addDelayedRegistrationEntry(window);
- return;
+ /*
+ * No window with WM_STATE property is found.
+ * Since the window can be a plugin window reparented to the browser
+ * toplevel, we cannot determine which window will eventually have
+ * WM_STATE property set. So we schedule a timer callback that will
+ * periodically attempt to find an ancestor with WM_STATE and
+ * register the drop site appropriately.
+ */
+ if (toplevel == 0) {
+ addDelayedRegistrationEntry(window);
+ return;
+ }
+
+ if (toplevel == window) {
+ Iterator dropTargetProtocols =
+ XDragAndDropProtocols.getDropTargetProtocols();
+
+ while (dropTargetProtocols.hasNext()) {
+ XDropTargetProtocol dropTargetProtocol =
+ (XDropTargetProtocol)dropTargetProtocols.next();
+ dropTargetProtocol.registerDropTarget(toplevel);
}
-
- if (toplevel == window) {
- Iterator dropTargetProtocols =
- XDragAndDropProtocols.getDropTargetProtocols();
-
- while (dropTargetProtocols.hasNext()) {
- XDropTargetProtocol dropTargetProtocol =
- (XDropTargetProtocol)dropTargetProtocols.next();
- dropTargetProtocol.registerDropTarget(toplevel);
- }
- } else {
- registerEmbeddedDropSite(toplevel, window);
- }
- } finally {
- XToolkit.awtUnlock();
+ } else {
+ registerEmbeddedDropSite(toplevel, window);
}
}
+ /*
+ * Note: this method should be called under AWT lock.
+ */
public void unregisterDropSite(long window) {
+ assert XToolkit.isAWTLockHeldByCurrentThread();
+
if (window == 0) {
throw new IllegalArgumentException();
}
- XToolkit.awtLock();
- try {
- long toplevel = getToplevelWindow(window);
+ long toplevel = getToplevelWindow(window);
- if (toplevel == window) {
- Iterator dropProtocols =
- XDragAndDropProtocols.getDropTargetProtocols();
-
- removeDelayedRegistrationEntry(window);
+ if (toplevel == window) {
+ Iterator dropProtocols =
+ XDragAndDropProtocols.getDropTargetProtocols();
- while (dropProtocols.hasNext()) {
- XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
- dropProtocol.unregisterDropTarget(window);
- }
- } else {
- unregisterEmbeddedDropSite(toplevel, window);
+ removeDelayedRegistrationEntry(window);
+
+ while (dropProtocols.hasNext()) {
+ XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
+ dropProtocol.unregisterDropTarget(window);
}
- } finally {
- XToolkit.awtUnlock();
+ } else {
+ unregisterEmbeddedDropSite(toplevel, window);
}
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Wed Nov 18 17:17:56 2009 -0800
@@ -1509,4 +1509,24 @@
return new XAtomList();
}
+ /**
+ * Indicates if the window is currently in the FSEM.
+ * Synchronization: state lock.
+ */
+ private boolean fullScreenExclusiveModeState = false;
+
+ // Implementation of the X11ComponentPeer
+ @Override
+ public void setFullScreenExclusiveModeState(boolean state) {
+ synchronized (getStateLock()) {
+ fullScreenExclusiveModeState = state;
+ }
+ }
+
+ public final boolean isFullScreenExclusiveMode() {
+ synchronized (getStateLock()) {
+ return fullScreenExclusiveModeState;
+ }
+ }
+
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Wed Nov 18 17:17:56 2009 -0800
@@ -1079,31 +1079,39 @@
updateSecurityWarningVisibility();
}
+ @Override
+ public void setFullScreenExclusiveModeState(boolean state) {
+ super.setFullScreenExclusiveModeState(state);
+ 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;
- }
+ boolean show = false;
+
+ if (!isFullScreenExclusiveMode()) {
+ int state = getWMState();
- if (isMouseAbove() || warningWindow.isMouseAbove())
- {
- show = true;
+ // 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;
+ }
}
}
@@ -1756,25 +1764,36 @@
}
}
+ // should be synchronized on awtLock
private int dropTargetCount = 0;
- public synchronized void addDropTarget() {
- if (dropTargetCount == 0) {
- long window = getWindow();
- if (window != 0) {
- XDropTargetRegistry.getRegistry().registerDropSite(window);
+ public void addDropTarget() {
+ XToolkit.awtLock();
+ try {
+ if (dropTargetCount == 0) {
+ long window = getWindow();
+ if (window != 0) {
+ XDropTargetRegistry.getRegistry().registerDropSite(window);
+ }
}
+ dropTargetCount++;
+ } finally {
+ XToolkit.awtUnlock();
}
- dropTargetCount++;
}
- public synchronized void removeDropTarget() {
- dropTargetCount--;
- if (dropTargetCount == 0) {
- long window = getWindow();
- if (window != 0) {
- XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+ public void removeDropTarget() {
+ XToolkit.awtLock();
+ try {
+ dropTargetCount--;
+ if (dropTargetCount == 0) {
+ long window = getWindow();
+ if (window != 0) {
+ XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+ }
}
+ } finally {
+ XToolkit.awtUnlock();
}
}
void addRootPropertyEventDispatcher() {
@@ -1837,13 +1856,18 @@
}
}
- protected synchronized void updateDropTarget() {
- if (dropTargetCount > 0) {
- long window = getWindow();
- if (window != 0) {
- XDropTargetRegistry.getRegistry().unregisterDropSite(window);
- XDropTargetRegistry.getRegistry().registerDropSite(window);
+ protected void updateDropTarget() {
+ XToolkit.awtLock();
+ try {
+ if (dropTargetCount > 0) {
+ long window = getWindow();
+ if (window != 0) {
+ XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+ XDropTargetRegistry.getRegistry().registerDropSite(window);
+ }
}
+ } finally {
+ XToolkit.awtUnlock();
}
}
--- a/jdk/src/solaris/classes/sun/awt/X11ComponentPeer.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11ComponentPeer.java Wed Nov 18 17:17:56 2009 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2005 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
@@ -39,4 +39,5 @@
Rectangle getBounds();
Graphics getGraphics();
Object getTarget();
+ void setFullScreenExclusiveModeState(boolean state);
}
--- a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java Wed Nov 18 17:17:56 2009 -0800
@@ -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
@@ -306,12 +306,14 @@
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
if (peer != null) {
enterFullScreenExclusive(peer.getContentWindow());
+ peer.setFullScreenExclusiveModeState(true);
}
}
private static void exitFullScreenExclusive(Window w) {
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
if (peer != null) {
+ peer.setFullScreenExclusiveModeState(false);
exitFullScreenExclusive(peer.getContentWindow());
}
}
--- a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Wed Nov 18 17:17:56 2009 -0800
@@ -1654,6 +1654,7 @@
#ifndef HEADLESS
#define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
+#define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN
typedef Status
(*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);
@@ -1680,6 +1681,9 @@
Rotation rotation,
short rate,
Time timestamp);
+typedef Rotation
+ (*XRRConfigRotationsType)(XRRScreenConfiguration *config,
+ Rotation *current_rotation);
static XRRQueryVersionType awt_XRRQueryVersion;
static XRRGetScreenInfoType awt_XRRGetScreenInfo;
@@ -1689,6 +1693,7 @@
static XRRConfigSizesType awt_XRRConfigSizes;
static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration;
static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate;
+static XRRConfigRotationsType awt_XRRConfigRotations;
#define LOAD_XRANDR_FUNC(f) \
do { \
@@ -1755,6 +1760,7 @@
LOAD_XRANDR_FUNC(XRRConfigSizes);
LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration);
LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate);
+ LOAD_XRANDR_FUNC(XRRConfigRotations);
return JNI_TRUE;
}
@@ -1765,6 +1771,7 @@
{
jclass displayModeClass;
jmethodID cid;
+ jint validRefreshRate = refreshRate;
displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode");
if (JNU_IsNull(env, displayModeClass)) {
@@ -1780,8 +1787,13 @@
return NULL;
}
+ // early versions of xrandr may report "empty" rates (6880694)
+ if (validRefreshRate <= 0) {
+ validRefreshRate = REFRESH_RATE_UNKNOWN;
+ }
+
return (*env)->NewObject(env, displayModeClass, cid,
- width, height, bitDepth, refreshRate);
+ width, height, bitDepth, validRefreshRate);
}
static void
@@ -1926,8 +1938,7 @@
curRate = awt_XRRConfigCurrentRate(config);
if ((sizes != NULL) &&
- (curSizeIndex < nsizes) &&
- (curRate > 0))
+ (curSizeIndex < nsizes))
{
XRRScreenSize curSize = sizes[curSizeIndex];
displayMode = X11GD_CreateDisplayMode(env,
@@ -2004,6 +2015,7 @@
jboolean success = JNI_FALSE;
XRRScreenConfiguration *config;
Drawable root;
+ Rotation currentRotation = RR_Rotate_0;
AWT_LOCK();
@@ -2015,6 +2027,7 @@
short chosenRate = -1;
int nsizes;
XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);
+ awt_XRRConfigRotations(config, ¤tRotation);
if (sizes != NULL) {
int i, j;
@@ -2048,7 +2061,7 @@
Status status =
awt_XRRSetScreenConfigAndRate(awt_display, config, root,
chosenSizeIndex,
- RR_Rotate_0,
+ currentRotation,
chosenRate,
CurrentTime);
--- a/jdk/src/solaris/native/sun/xawt/XToolkit.c Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/solaris/native/sun/xawt/XToolkit.c Wed Nov 18 17:17:56 2009 -0800
@@ -677,7 +677,7 @@
jstring ret = NULL;
keystr = JNU_GetStringPlatformChars(env, key, NULL);
- if (key) {
+ if (keystr) {
ptr = getenv(keystr);
if (ptr) {
ret = JNU_NewStringPlatform(env, (const char *) ptr);
--- a/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java Wed Nov 18 17:17:56 2009 -0800
@@ -353,6 +353,7 @@
}
WWindowPeer peer = (WWindowPeer)old.getPeer();
if (peer != null) {
+ peer.setFullScreenExclusiveModeState(false);
// we used to destroy the buffers on exiting fs mode, this
// is no longer needed since fs change will cause a surface
// data replacement
@@ -370,12 +371,15 @@
addFSWindowListener(w);
// Enter full screen exclusive mode.
WWindowPeer peer = (WWindowPeer)w.getPeer();
- synchronized(peer) {
- enterFullScreenExclusive(screen, peer);
- // Note: removed replaceSurfaceData() call because
- // changing the window size or making it visible
- // will cause this anyway, and both of these events happen
- // as part of switching into fullscreen mode.
+ if (peer != null) {
+ synchronized(peer) {
+ enterFullScreenExclusive(screen, peer);
+ // Note: removed replaceSurfaceData() call because
+ // changing the window size or making it visible
+ // will cause this anyway, and both of these events happen
+ // as part of switching into fullscreen mode.
+ }
+ peer.setFullScreenExclusiveModeState(true);
}
// fix for 4868278
--- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Wed Nov 18 17:17:56 2009 -0800
@@ -550,8 +550,34 @@
final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
public Graphics getGraphics() {
+ if (isDisposed()) {
+ return null;
+ }
+
+ Component target = (Component)getTarget();
+ Window window = SunToolkit.getContainingWindow(target);
+ if (window != null && !window.isOpaque()) {
+ // Non-opaque windows do not support heavyweight children.
+ // Redirect all painting to the Window's Graphics instead.
+ // The caller is responsible for calling the
+ // WindowPeer.updateWindow() after painting has finished.
+ int x = 0, y = 0;
+ for (Component c = target; c != window; c = c.getParent()) {
+ x += c.getX();
+ y += c.getY();
+ }
+
+ Graphics g =
+ ((WWindowPeer)window.getPeer()).getTranslucentGraphics();
+
+ g.translate(x, y);
+ g.clipRect(0, 0, target.getWidth(), target.getHeight());
+
+ return g;
+ }
+
SurfaceData surfaceData = this.surfaceData;
- if (!isDisposed() && surfaceData != null) {
+ if (surfaceData != null) {
/* Fix for bug 4746122. Color and Font shouldn't be null */
Color bgColor = background;
if (bgColor == null) {
--- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Wed Nov 18 17:17:56 2009 -0800
@@ -510,6 +510,9 @@
private native int getScreenImOn();
+ // Used in Win32GraphicsDevice.
+ public final native void setFullScreenExclusiveModeState(boolean state);
+
/*
* ----END DISPLAY CHANGE SUPPORT----
*/
@@ -575,11 +578,17 @@
}
}
+ public final Graphics getTranslucentGraphics() {
+ synchronized (getStateLock()) {
+ return isOpaque ? null : painter.getBackBuffer(false).getGraphics();
+ }
+ }
+
@Override
public Graphics getGraphics() {
synchronized (getStateLock()) {
if (!isOpaque) {
- return painter.getBackBuffer(false).getGraphics();
+ return getTranslucentGraphics();
}
}
return super.getGraphics();
--- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Wed Nov 18 17:17:56 2009 -0800
@@ -59,7 +59,7 @@
};
typedef struct tagBitmapheader {
- BITMAPINFOHEADER bmiHeader;
+ BITMAPV5HEADER bmiHeader;
DWORD dwMasks[256];
} Bitmapheader, *LPBITMAPHEADER;
@@ -638,12 +638,12 @@
HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH)
{
- Bitmapheader bmhHeader;
+ Bitmapheader bmhHeader = {0};
HDC hDC;
char *ptrImageData;
HBITMAP hbmpBitmap;
HBITMAP hBitmap;
- int nNumChannels = 3;
+ int nNumChannels = 4;
if (!hW) {
hW = ::GetDesktopWindow();
@@ -653,14 +653,20 @@
return NULL;
}
- memset(&bmhHeader, 0, sizeof(Bitmapheader));
- bmhHeader.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmhHeader.bmiHeader.biWidth = nW;
- bmhHeader.bmiHeader.biHeight = -nH;
- bmhHeader.bmiHeader.biPlanes = 1;
+ bmhHeader.bmiHeader.bV5Size = sizeof(BITMAPV5HEADER);
+ bmhHeader.bmiHeader.bV5Width = nW;
+ bmhHeader.bmiHeader.bV5Height = -nH;
+ bmhHeader.bmiHeader.bV5Planes = 1;
- bmhHeader.bmiHeader.biBitCount = 24;
- bmhHeader.bmiHeader.biCompression = BI_RGB;
+ bmhHeader.bmiHeader.bV5BitCount = 32;
+ bmhHeader.bmiHeader.bV5Compression = BI_BITFIELDS;
+
+ // The following mask specification specifies a supported 32 BPP
+ // alpha format for Windows XP.
+ bmhHeader.bmiHeader.bV5RedMask = 0x00FF0000;
+ bmhHeader.bmiHeader.bV5GreenMask = 0x0000FF00;
+ bmhHeader.bmiHeader.bV5BlueMask = 0x000000FF;
+ bmhHeader.bmiHeader.bV5AlphaMask = 0xFF000000;
hbmpBitmap = ::CreateDIBSection(hDC, (BITMAPINFO*)&(bmhHeader),
DIB_RGB_COLORS,
@@ -674,6 +680,7 @@
}
for (int nOutern = 0; nOutern < nH; nOutern++) {
for (int nInner = 0; nInner < nSS; nInner++) {
+ dstPtr[3] = (*srcPtr >> 0x18) & 0xFF;
dstPtr[2] = (*srcPtr >> 0x10) & 0xFF;
dstPtr[1] = (*srcPtr >> 0x08) & 0xFF;
dstPtr[0] = *srcPtr & 0xFF;
--- a/jdk/src/windows/native/sun/windows/awt_Window.cpp Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Wed Nov 18 17:17:56 2009 -0800
@@ -143,6 +143,11 @@
jobject window;
};
+struct SetFullScreenExclusiveModeStateStruct {
+ jobject window;
+ jboolean isFSEMState;
+};
+
/************************************************************************
* AwtWindow fields
@@ -915,7 +920,9 @@
bool show = false;
- if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED) {
+ if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED &&
+ !isFullScreenExclusiveMode())
+ {
if (AwtComponent::GetFocusedWindow() == GetHWnd()) {
show = true;
}
@@ -2954,6 +2961,25 @@
delete uws;
}
+void AwtWindow::_SetFullScreenExclusiveModeState(void *param)
+{
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ SetFullScreenExclusiveModeStateStruct * data =
+ (SetFullScreenExclusiveModeStateStruct*)param;
+ jobject self = data->window;
+ jboolean state = data->isFSEMState;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+ AwtWindow *window = (AwtWindow *)pData;
+
+ window->setFullScreenExclusiveModeState(state != 0);
+
+ ret:
+ env->DeleteGlobalRef(self);
+ delete data;
+}
extern "C" {
@@ -3335,6 +3361,29 @@
/*
* Class: sun_awt_windows_WWindowPeer
+ * Method: setFullScreenExclusiveModeState
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv *env,
+ jobject self, jboolean state)
+{
+ TRY;
+
+ SetFullScreenExclusiveModeStateStruct *data =
+ new SetFullScreenExclusiveModeStateStruct;
+ data->window = env->NewGlobalRef(self);
+ data->isFSEMState = state;
+
+ AwtToolkit::GetInstance().SyncCall(
+ AwtWindow::_SetFullScreenExclusiveModeState, data);
+ // global ref and data are deleted in the invoked method
+
+ CATCH_BAD_ALLOC;
+}
+
+/*
+ * Class: sun_awt_windows_WWindowPeer
* Method: modalDisable
* Signature: (J)V
*/
--- a/jdk/src/windows/native/sun/windows/awt_Window.h Wed Nov 18 17:16:27 2009 -0800
+++ b/jdk/src/windows/native/sun/windows/awt_Window.h Wed Nov 18 17:17:56 2009 -0800
@@ -229,6 +229,7 @@
static void _SetOpaque(void* param);
static void _UpdateWindow(void* param);
static void _RepositionSecurityWarning(void* param);
+ static void _SetFullScreenExclusiveModeState(void* param);
inline static BOOL IsResizing() {
return sm_resizing;
@@ -331,6 +332,16 @@
static void SetLayered(HWND window, bool layered);
static bool IsLayered(HWND window);
+ BOOL fullScreenExclusiveModeState;
+ inline void setFullScreenExclusiveModeState(BOOL isEntered) {
+ fullScreenExclusiveModeState = isEntered;
+ UpdateSecurityWarningVisibility();
+ }
+ inline BOOL isFullScreenExclusiveMode() {
+ return fullScreenExclusiveModeState;
+ }
+
+
public:
void UpdateSecurityWarningVisibility();
static bool IsWarningWindow(HWND hWnd);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java Wed Nov 18 17:17:56 2009 -0800
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test
+ @bug 6852592
+ @summary invalidate() must stop when it encounters a validate root
+ @author anthony.petrov@sun.com
+ @run main InvalidateMustRespectValidateRoots
+*/
+
+import javax.swing.*;
+import java.awt.event.*;
+
+public class InvalidateMustRespectValidateRoots {
+ private static volatile JRootPane rootPane;
+
+ public static void main(String args[]) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ // The JRootPane is a validate root. We'll check if
+ // invalidate() stops on the root pane, or goes further
+ // up to the frame.
+ JFrame frame = new JFrame();
+ final JButton button = new JButton();
+
+ frame.add(button);
+
+ // To enable running the test manually: use the Ctrl-Shift-F1
+ // to print the component hierarchy to the console
+ button.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ if (button.isValid()) {
+ button.invalidate();
+ } else {
+ button.revalidate();
+ }
+ }
+ });
+
+ rootPane = frame.getRootPane();
+
+ // Now the component hierarchy looks like:
+ // frame
+ // --> rootPane
+ // --> layered pane
+ // --> content pane
+ // --> button
+
+ // Make all components valid first via showing the frame
+ // We have to make the frame visible. Otherwise revalidate() is
+ // useless (see RepaintManager.addInvalidComponent()).
+ frame.pack(); // To enable running this test manually
+ frame.setVisible(true);
+
+ if (!frame.isValid()) {
+ throw new RuntimeException(
+ "setVisible(true) failed to validate the frame");
+ }
+
+ // Now invalidate the button
+ button.invalidate();
+
+ // Check if the 'valid' status is what we expect it to be
+ if (rootPane.isValid()) {
+ throw new RuntimeException(
+ "invalidate() failed to invalidate the root pane");
+ }
+
+ if (!frame.isValid()) {
+ throw new RuntimeException(
+ "invalidate() invalidated the frame");
+ }
+
+ // Now validate the hierarchy again
+ button.revalidate();
+
+ // Now let the validation happen on the EDT
+ }
+ });
+
+ Thread.sleep(1000);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ // Check if the root pane finally became valid
+ if (!rootPane.isValid()) {
+ throw new RuntimeException(
+ "revalidate() failed to validate the hierarchy");
+ }
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/InvocationEvent/InvocationEventTest.java Wed Nov 18 17:17:56 2009 -0800
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test
+ @bug 6852111
+ @summary Unhandled 'spurious wakeup' in java.awt.EventQueue.invokeAndWait()
+ @author dmitry.cherepanov@sun.com: area=awt.event
+ @run main InvocationEventTest
+*/
+
+/**
+ * InvocationEventTest.java
+ *
+ * summary: Tests new isDispatched method of the InvocationEvent class
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class InvocationEventTest
+{
+ public static void main(String []s) throws Exception
+ {
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ Runnable runnable = new Runnable() {
+ public void run() {
+ }
+ };
+ Object lock = new Object();
+ InvocationEvent event = new InvocationEvent(tk, runnable, lock, true);
+
+ if (event.isDispatched()) {
+ throw new RuntimeException(" Initially, the event shouldn't be dispatched ");
+ }
+
+ synchronized(lock) {
+ tk.getSystemEventQueue().postEvent(event);
+ while(!event.isDispatched()) {
+ lock.wait();
+ }
+ }
+
+ if(!event.isDispatched()) {
+ throw new RuntimeException(" Finally, the event should be dispatched ");
+ }
+ }
+}