This commit is contained in:
Lana Steuck 2009-11-18 17:17:56 -08:00
commit 228f3f7726
34 changed files with 944 additions and 280 deletions

View File

@ -229,6 +229,21 @@ public class Applet extends Panel {
resize(d.width, d.height); resize(d.width, d.height);
} }
/**
* 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 * Requests that the argument string be displayed in the
* "status window". Many browsers and applet viewers * "status window". Many browsers and applet viewers

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -92,7 +92,15 @@ import java.security.BasicPermission;
* <td>Enter full-screen exclusive mode</td> * <td>Enter full-screen exclusive mode</td>
* <td>Entering full-screen exclusive mode allows direct access to * <td>Entering full-screen exclusive mode allows direct access to
* low-level graphics card memory. This could be used to spoof the * 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>
* *
* <tr> * <tr>

View File

@ -2764,8 +2764,11 @@ public abstract class Component implements ImageObserver, MenuContainer,
} }
/** /**
* Ensures that this component has a valid layout. This method is * Validates this component.
* primarily intended to operate on instances of <code>Container</code>. * <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 #invalidate
* @see #doLayout() * @see #doLayout()
* @see LayoutManager * @see LayoutManager
@ -2794,12 +2797,24 @@ public abstract class Component implements ImageObserver, MenuContainer,
} }
/** /**
* Invalidates this component. This component and all parents * Invalidates this component and its ancestors.
* above it are marked as needing to be laid out. This method can * <p>
* be called often, so it needs to execute quickly. * 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 #validate
* @see #doLayout * @see #doLayout
* @see LayoutManager * @see LayoutManager
* @see java.awt.Container#isValidateRoot
* @since JDK1.0 * @since JDK1.0
*/ */
public void invalidate() { public void invalidate() {
@ -2818,11 +2833,20 @@ public abstract class Component implements ImageObserver, MenuContainer,
if (!isMaximumSizeSet()) { if (!isMaximumSizeSet()) {
maxSize = null; maxSize = null;
} }
invalidateParent();
}
}
/**
* Invalidates the parent of this component if any.
*
* This method MUST BE invoked under the TreeLock.
*/
void invalidateParent() {
if (parent != null) { if (parent != null) {
parent.invalidateIfValid(); parent.invalidateIfValid();
} }
} }
}
/** Invalidates the component unless it is already invalid. /** Invalidates the component unless it is already invalid.
*/ */
@ -6727,12 +6751,13 @@ public abstract class Component implements ImageObserver, MenuContainer,
} }
} }
} else { } else {
// It's native. If the parent is lightweight it // It's native. If the parent is lightweight it will need some
// will need some help. // help.
Container parent = this.parent; Container parent = getContainer();
if (parent != null && parent.peer instanceof LightweightPeer) { if (parent != null && parent.isLightweight()) {
relocateComponent(); relocateComponent();
if (!isRecursivelyVisible()) { if (!parent.isRecursivelyVisibleUpToHeavyweightContainer())
{
peer.setVisible(false); peer.setVisible(false);
} }
} }

View File

@ -1492,20 +1492,59 @@ public class Container extends Component {
} }
/** /**
* Invalidates the container. The container and all parents * Indicates if this container is a <i>validate root</i>.
* above it are marked as needing to be laid out. This method can * <p>
* be called often, so it needs to execute quickly. * 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 * @return whether this container is a validate root
* an instance of {@code LayoutManager2}, then * @see #invalidate
* {@link LayoutManager2#invalidateLayout(Container)} is invoked on * @see java.awt.Component#invalidate
* it supplying this {@code Container} as the argument. * @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 #validate
* @see #layout * @see #layout
* @see LayoutManager * @see LayoutManager2
* @see LayoutManager2#invalidateLayout(Container)
*/ */
@Override
public void invalidate() { public void invalidate() {
LayoutManager layoutMgr = this.layoutMgr; LayoutManager layoutMgr = this.layoutMgr;
if (layoutMgr instanceof LayoutManager2) { if (layoutMgr instanceof LayoutManager2) {
@ -1518,35 +1557,37 @@ public class Container extends Component {
/** /**
* Validates this container and all of its subcomponents. * Validates this container and all of its subcomponents.
* <p> * <p>
* The <code>validate</code> method is used to cause a container * Validating a container means laying out its subcomponents.
* to lay out its subcomponents again. It should be invoked when * Layout-related changes, such as setting the bounds of a component, or
* this container's subcomponents are modified (added to or * adding a component to the container, invalidate the container
* removed from the container, or layout-related information * automatically. Note that the ancestors of the container may be
* changed) after the container has been displayed. * invalidated also (see {@link Component#invalidate} for details.)
* * Therefore, to restore the validity of the hierarchy, the {@code
* <p>If this {@code Container} is not valid, this method invokes * 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} * the {@code validateTree} method and marks this {@code Container}
* as valid. Otherwise, no action is performed. * 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 #add(java.awt.Component)
* @see #invalidate * @see #invalidate
* @see Container#isValidateRoot
* @see javax.swing.JComponent#revalidate() * @see javax.swing.JComponent#revalidate()
* @see #validateTree * @see #validateTree
*/ */
public void validate() { public void validate() {
/* Avoid grabbing lock unless really necessary. */
if (!isValid()) {
boolean updateCur = false; boolean updateCur = false;
synchronized (getTreeLock()) { synchronized (getTreeLock()) {
if (!isValid() && peer != null) { if ((!isValid() || descendUnconditionallyWhenValidating)
&& peer != null)
{
ContainerPeer p = null; ContainerPeer p = null;
if (peer instanceof ContainerPeer) { if (peer instanceof ContainerPeer) {
p = (ContainerPeer) peer; p = (ContainerPeer) peer;
@ -1557,14 +1598,50 @@ public class Container extends Component {
validateTree(); validateTree();
if (p != null) { if (p != null) {
p.endValidate(); p.endValidate();
// Avoid updating cursor if this is an internal call.
// See validateUnconditionally() for details.
if (!descendUnconditionallyWhenValidating) {
updateCur = isVisible(); updateCur = isVisible();
} }
} }
} }
}
if (updateCur) { if (updateCur) {
updateCursorImmediately(); 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 @@ public class Container extends Component {
*/ */
protected void validateTree() { protected void validateTree() {
checkTreeLock(); checkTreeLock();
if (!isValid()) { if (!isValid() || descendUnconditionallyWhenValidating) {
if (peer instanceof ContainerPeer) { if (peer instanceof ContainerPeer) {
((ContainerPeer)peer).beginLayout(); ((ContainerPeer)peer).beginLayout();
} }
if (!isValid()) {
doLayout(); doLayout();
}
for (int i = 0; i < component.size(); i++) { for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i); Component comp = component.get(i);
if ( (comp instanceof Container) if ( (comp instanceof Container)
&& !(comp instanceof Window) && !(comp instanceof Window)
&& !comp.isValid()) { && (!comp.isValid() ||
descendUnconditionallyWhenValidating))
{
((Container)comp).validateTree(); ((Container)comp).validateTree();
} else { } else {
comp.validate(); comp.validate();
@ -4092,16 +4173,29 @@ public class Container extends Component {
} }
} }
/* /**
* Checks if the container and its direct lightweight containers are
* visible.
*
* Consider the heavyweight container hides or shows the HW descendants * Consider the heavyweight container hides or shows the HW descendants
* automatically. Therefore we care of LW containers' visibility only. * 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()) { if (!isLightweight()) {
return true; 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 @Override

View File

@ -1027,8 +1027,10 @@ public class EventQueue {
synchronized (lock) { synchronized (lock) {
Toolkit.getEventQueue().postEvent(event); Toolkit.getEventQueue().postEvent(event);
while (!event.isDispatched()) {
lock.wait(); lock.wait();
} }
}
Throwable eventThrowable = event.getThrowable(); Throwable eventThrowable = event.getThrowable();
if (eventThrowable != null) { if (eventThrowable != null) {

View File

@ -845,8 +845,11 @@ public class Frame extends Window implements MenuContainer {
* others by setting those fields you want to accept from system * others by setting those fields you want to accept from system
* to <code>Integer.MAX_VALUE</code>. * to <code>Integer.MAX_VALUE</code>.
* <p> * <p>
* On some systems only the size portion of the bounds is taken * Note, the given maximized bounds are used as a hint for the native
* into account. * 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 * @param bounds bounds for the maximized state
* @see #getMaximizedBounds() * @see #getMaximizedBounds()

View File

@ -767,7 +767,7 @@ public class Window extends Container implements Accessible {
isPacked = true; isPacked = true;
} }
validate(); validateUnconditionally();
} }
/** /**
@ -943,7 +943,7 @@ public class Window extends Container implements Accessible {
if (peer == null) { if (peer == null) {
addNotify(); addNotify();
} }
validate(); validateUnconditionally();
isInShow = true; isInShow = true;
if (visible) { if (visible) {
@ -2599,6 +2599,21 @@ public class Window extends Container implements Accessible {
super.addPropertyChangeListener(propertyName, listener); super.addPropertyChangeListener(propertyName, listener);
} }
/**
* 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. * Dispatches an event to this window or one of its sub components.
* @param e the event * @param e the event

View File

@ -1184,7 +1184,7 @@ public class DataFlavor implements Externalizable, Cloneable {
*/ */
public boolean isRepresentationClassRemote() { public boolean isRepresentationClassRemote() {
return java.rmi.Remote.class.isAssignableFrom(representationClass); return DataTransferer.isRemote(representationClass);
} }
/** /**

View File

@ -78,10 +78,21 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
/** /**
* The (potentially null) Object whose notifyAll() method will be called * 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; 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 * Set to true if dispatch() catches Throwable and stores it in the
* exception instance variable. If false, Throwables are propagated up * exception instance variable. If false, Throwables are propagated up
@ -144,7 +155,7 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* source which will execute the runnable's <code>run</code> * source which will execute the runnable's <code>run</code>
* method when dispatched. If notifier is non-<code>null</code>, * method when dispatched. If notifier is non-<code>null</code>,
* <code>notifyAll()</code> will be called on it * <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, * <p>An invocation of the form <tt>InvocationEvent(source,
* runnable, notifier, catchThrowables)</tt> * runnable, notifier, catchThrowables)</tt>
* behaves in exactly the same way as the invocation of * behaves in exactly the same way as the invocation of
@ -159,7 +170,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* executed * executed
* @param notifier The {@code Object} whose <code>notifyAll</code> * @param notifier The {@code Object} whose <code>notifyAll</code>
* method will be called after * 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> * @param catchThrowables Specifies whether <code>dispatch</code>
* should catch Throwable when executing * should catch Throwable when executing
* the <code>Runnable</code>'s <code>run</code> * the <code>Runnable</code>'s <code>run</code>
@ -180,8 +192,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* Constructs an <code>InvocationEvent</code> with the specified * Constructs an <code>InvocationEvent</code> with the specified
* source and ID which will execute the runnable's <code>run</code> * source and ID which will execute the runnable's <code>run</code>
* method when dispatched. If notifier is non-<code>null</code>, * method when dispatched. If notifier is non-<code>null</code>,
* <code>notifyAll</code> will be called on it * <code>notifyAll</code> will be called on it immediately after
* immediately after <code>run</code> returns. * <code>run</code> has returned or thrown an exception.
* <p>This method throws an * <p>This method throws an
* <code>IllegalArgumentException</code> if <code>source</code> * <code>IllegalArgumentException</code> if <code>source</code>
* is <code>null</code>. * is <code>null</code>.
@ -195,7 +207,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* <code>run</code> method will be executed * <code>run</code> method will be executed
* @param notifier The <code>Object</code> whose <code>notifyAll</code> * @param notifier The <code>Object</code> whose <code>notifyAll</code>
* method will be called after * 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> * @param catchThrowables Specifies whether <code>dispatch</code>
* should catch Throwable when executing the * should catch Throwable when executing the
* <code>Runnable</code>'s <code>run</code> * <code>Runnable</code>'s <code>run</code>
@ -217,9 +230,12 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
/** /**
* Executes the Runnable's <code>run()</code> method and notifies the * 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() { public void dispatch() {
try {
if (catchExceptions) { if (catchExceptions) {
try { try {
runnable.run(); runnable.run();
@ -234,6 +250,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
else { else {
runnable.run(); runnable.run();
} }
} finally {
dispatched = true;
if (notifier != null) { if (notifier != null) {
synchronized (notifier) { synchronized (notifier) {
@ -241,6 +259,7 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
} }
} }
} }
}
/** /**
* Returns any Exception caught while executing the Runnable's <code>run() * Returns any Exception caught while executing the Runnable's <code>run()
@ -277,6 +296,40 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
return when; return when;
} }
/**
* 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. * Returns a parameter string identifying this event.
* This method is useful for event-logging and for debugging. * This method is useful for event-logging and for debugging.

View File

@ -795,7 +795,6 @@ public abstract class JComponent extends Container implements Serializable,
* @see java.awt.Container#paint * @see java.awt.Container#paint
*/ */
protected void paintChildren(Graphics g) { protected void paintChildren(Graphics g) {
boolean isJComponent;
Graphics sg = g; Graphics sg = g;
synchronized(getTreeLock()) { synchronized(getTreeLock()) {
@ -826,12 +825,21 @@ public abstract class JComponent extends Container implements Serializable,
} }
} }
boolean printing = getFlag(IS_PRINTING); boolean printing = getFlag(IS_PRINTING);
final Window window = SwingUtilities.getWindowAncestor(this);
final boolean isWindowOpaque = window == null || window.isOpaque();
for (; i >= 0 ; i--) { for (; i >= 0 ; i--) {
Component comp = getComponent(i); Component comp = getComponent(i);
isJComponent = (comp instanceof JComponent); if (comp == null) {
if (comp != null && continue;
(isJComponent || isLightweightComponent(comp)) && }
(comp.isVisible() == true)) {
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; Rectangle cr;
cr = comp.getBounds(tmpRect); cr = comp.getBounds(tmpRect);
@ -887,6 +895,8 @@ public abstract class JComponent extends Container implements Serializable,
} }
} }
} else { } else {
// The component is either lightweight, or
// heavyweight in a non-opaque window
if (!printing) { if (!printing) {
comp.paint(cg); comp.paint(cg);
} }
@ -4868,7 +4878,9 @@ public abstract class JComponent extends Container implements Serializable,
* @see #revalidate * @see #revalidate
* @see java.awt.Component#invalidate * @see java.awt.Component#invalidate
* @see java.awt.Container#validate * @see java.awt.Container#validate
* @see java.awt.Container#isValidateRoot
*/ */
@Override
public boolean isValidateRoot() { public boolean isValidateRoot() {
return false; return false;
} }

View File

@ -725,8 +725,10 @@ public class JRootPane extends JComponent implements Accessible {
* because both classes override <code>isValidateRoot</code> to return true. * because both classes override <code>isValidateRoot</code> to return true.
* *
* @see JComponent#isValidateRoot * @see JComponent#isValidateRoot
* @see java.awt.Container#isValidateRoot
* @return true * @return true
*/ */
@Override
public boolean isValidateRoot() { public boolean isValidateRoot() {
return true; return true;
} }

View File

@ -453,10 +453,12 @@ public class JScrollPane extends JComponent implements ScrollPaneConstants, Acce
* @see java.awt.Container#validate * @see java.awt.Container#validate
* @see JComponent#revalidate * @see JComponent#revalidate
* @see JComponent#isValidateRoot * @see JComponent#isValidateRoot
* @see java.awt.Container#isValidateRoot
* *
* @beaninfo * @beaninfo
* hidden: true * hidden: true
*/ */
@Override
public boolean isValidateRoot() { public boolean isValidateRoot() {
return true; return true;
} }

View File

@ -947,10 +947,12 @@ public class JSplitPane extends JComponent implements Accessible
* *
* @return true * @return true
* @see JComponent#revalidate * @see JComponent#revalidate
* @see java.awt.Container#isValidateRoot
* *
* @beaninfo * @beaninfo
* hidden: true * hidden: true
*/ */
@Override
public boolean isValidateRoot() { public boolean isValidateRoot() {
return true; return true;
} }

View File

@ -288,7 +288,9 @@ public class JTextField extends JTextComponent implements SwingConstants {
* *
* @see JComponent#revalidate * @see JComponent#revalidate
* @see JComponent#isValidateRoot * @see JComponent#isValidateRoot
* @see java.awt.Container#isValidateRoot
*/ */
@Override
public boolean isValidateRoot() { public boolean isValidateRoot() {
return SwingUtilities2.getViewport(this) == null; return SwingUtilities2.getViewport(this) == null;
} }

View File

@ -469,49 +469,12 @@ public class JViewport extends JComponent implements Accessible
* is the synchronous version of a <code>revalidate</code>. * is the synchronous version of a <code>revalidate</code>.
*/ */
private void validateView() { 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) { if (validateRoot == null) {
return; 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. // Validate the root.
validateRoot.validate(); validateRoot.validate();

View File

@ -310,47 +310,13 @@ public class RepaintManager
delegate.addInvalidComponent(invalidComponent); delegate.addInvalidComponent(invalidComponent);
return; 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) { if (validateRoot == null) {
return; 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 /* Lazily create the invalidateComponents vector and add the
* validateRoot if it's not there already. If this validateRoot * validateRoot if it's not there already. If this validateRoot
* is already in the vector, we're done. * is already in the vector, we're done.

View File

@ -1967,4 +1967,54 @@ public class SwingUtilities implements SwingConstants
SwingUtilities.updateComponentTreeUI(component); 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;
}
} }

View File

@ -63,8 +63,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.rmi.MarshalledObject;
import java.security.AccessControlContext; import java.security.AccessControlContext;
import java.security.AccessControlException; import java.security.AccessControlException;
import java.security.AccessController; import java.security.AccessController;
@ -493,6 +491,13 @@ public abstract class DataTransferer {
} }
} }
/**
* 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 * Returns an Iterator which traverses a SortedSet of Strings which are
* a total order of the standard character sets supported by the JRE. The * a total order of the standard character sets supported by the JRE. The
@ -1360,7 +1365,7 @@ search:
// Source data is an RMI object // Source data is an RMI object
} else if (flavor.isRepresentationClassRemote()) { } else if (flavor.isRepresentationClassRemote()) {
MarshalledObject mo = new MarshalledObject(obj); Object mo = RMI.newMarshalledObject(obj);
ObjectOutputStream oos = new ObjectOutputStream(bos); ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(mo); oos.writeObject(mo);
oos.close(); oos.close();
@ -1671,7 +1676,7 @@ search:
try { try {
byte[] ba = inputStreamToByteArray(str); byte[] ba = inputStreamToByteArray(str);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba)); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba));
Object ret = ((MarshalledObject)(ois.readObject())).get(); Object ret = RMI.getMarshalledObject(ois.readObject());
ois.close(); ois.close();
str.close(); str.close();
return ret; return ret;
@ -2669,8 +2674,12 @@ search:
Integer.valueOf(0)); Integer.valueOf(0));
nonTextRepresentationsMap.put(java.io.Serializable.class, nonTextRepresentationsMap.put(java.io.Serializable.class,
Integer.valueOf(1)); Integer.valueOf(1));
nonTextRepresentationsMap.put(java.rmi.Remote.class,
Class<?> remoteClass = RMI.remoteClass();
if (remoteClass != null) {
nonTextRepresentationsMap.put(remoteClass,
Integer.valueOf(2)); Integer.valueOf(2));
}
nonTextRepresentations = nonTextRepresentations =
Collections.unmodifiableMap(nonTextRepresentationsMap); Collections.unmodifiableMap(nonTextRepresentationsMap);
@ -2900,4 +2909,95 @@ search:
} }
} }
} }
/**
* 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);
}
}
}
} }

View File

@ -358,8 +358,10 @@ class ExecutableInputMethodManager extends InputMethodManager
AppContext requesterAppContext = SunToolkit.targetToAppContext(requester); AppContext requesterAppContext = SunToolkit.targetToAppContext(requester);
synchronized (lock) { synchronized (lock) {
SunToolkit.postEvent(requesterAppContext, event); SunToolkit.postEvent(requesterAppContext, event);
while (!event.isDispatched()) {
lock.wait(); lock.wait();
} }
}
Throwable eventThrowable = event.getThrowable(); Throwable eventThrowable = event.getThrowable();
if (eventThrowable != null) { if (eventThrowable != null) {

View File

@ -534,15 +534,18 @@ final class XDropTargetRegistry {
return entry.getSite(x, y); return entry.getSite(x, y);
} }
/*
* Note: this method should be called under AWT lock.
*/
public void registerDropSite(long window) { public void registerDropSite(long window) {
assert XToolkit.isAWTLockHeldByCurrentThread();
if (window == 0) { if (window == 0) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
XDropTargetEventProcessor.activate(); XDropTargetEventProcessor.activate();
XToolkit.awtLock();
try {
long toplevel = getToplevelWindow(window); long toplevel = getToplevelWindow(window);
/* /*
@ -570,18 +573,18 @@ final class XDropTargetRegistry {
} else { } else {
registerEmbeddedDropSite(toplevel, window); registerEmbeddedDropSite(toplevel, window);
} }
} finally {
XToolkit.awtUnlock();
}
} }
/*
* Note: this method should be called under AWT lock.
*/
public void unregisterDropSite(long window) { public void unregisterDropSite(long window) {
assert XToolkit.isAWTLockHeldByCurrentThread();
if (window == 0) { if (window == 0) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
XToolkit.awtLock();
try {
long toplevel = getToplevelWindow(window); long toplevel = getToplevelWindow(window);
if (toplevel == window) { if (toplevel == window) {
@ -597,9 +600,6 @@ final class XDropTargetRegistry {
} else { } else {
unregisterEmbeddedDropSite(toplevel, window); unregisterEmbeddedDropSite(toplevel, window);
} }
} finally {
XToolkit.awtUnlock();
}
} }
public void registerXEmbedClient(long canvasWindow, long clientWindow) { public void registerXEmbedClient(long canvasWindow, long clientWindow) {

View File

@ -1509,4 +1509,24 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
return new XAtomList(); 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;
}
}
} }

View File

@ -1079,19 +1079,26 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
updateSecurityWarningVisibility(); updateSecurityWarningVisibility();
} }
@Override
public void setFullScreenExclusiveModeState(boolean state) {
super.setFullScreenExclusiveModeState(state);
updateSecurityWarningVisibility();
}
public void updateSecurityWarningVisibility() { public void updateSecurityWarningVisibility() {
if (warningWindow == null) { if (warningWindow == null) {
return; return;
} }
boolean show = false;
int state = getWMState();
if (!isVisible()) { if (!isVisible()) {
return; // The warning window should already be hidden. return; // The warning window should already be hidden.
} }
boolean show = false;
if (!isFullScreenExclusiveMode()) {
int state = getWMState();
// getWMState() always returns 0 (Withdrawn) for simple windows. Hence // getWMState() always returns 0 (Withdrawn) for simple windows. Hence
// we ignore the state for such windows. // we ignore the state for such windows.
if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) { if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
@ -1106,6 +1113,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
show = true; show = true;
} }
} }
}
warningWindow.setSecurityWarningVisible(show, true); warningWindow.setSecurityWarningVisible(show, true);
} }
@ -1756,9 +1764,12 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
} }
} }
// should be synchronized on awtLock
private int dropTargetCount = 0; private int dropTargetCount = 0;
public synchronized void addDropTarget() { public void addDropTarget() {
XToolkit.awtLock();
try {
if (dropTargetCount == 0) { if (dropTargetCount == 0) {
long window = getWindow(); long window = getWindow();
if (window != 0) { if (window != 0) {
@ -1766,9 +1777,14 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
} }
} }
dropTargetCount++; dropTargetCount++;
} finally {
XToolkit.awtUnlock();
}
} }
public synchronized void removeDropTarget() { public void removeDropTarget() {
XToolkit.awtLock();
try {
dropTargetCount--; dropTargetCount--;
if (dropTargetCount == 0) { if (dropTargetCount == 0) {
long window = getWindow(); long window = getWindow();
@ -1776,6 +1792,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
XDropTargetRegistry.getRegistry().unregisterDropSite(window); XDropTargetRegistry.getRegistry().unregisterDropSite(window);
} }
} }
} finally {
XToolkit.awtUnlock();
}
} }
void addRootPropertyEventDispatcher() { void addRootPropertyEventDispatcher() {
if( rootPropertyEventDispatcher == null ) { if( rootPropertyEventDispatcher == null ) {
@ -1837,7 +1856,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
} }
} }
protected synchronized void updateDropTarget() { protected void updateDropTarget() {
XToolkit.awtLock();
try {
if (dropTargetCount > 0) { if (dropTargetCount > 0) {
long window = getWindow(); long window = getWindow();
if (window != 0) { if (window != 0) {
@ -1845,6 +1866,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
XDropTargetRegistry.getRegistry().registerDropSite(window); XDropTargetRegistry.getRegistry().registerDropSite(window);
} }
} }
} finally {
XToolkit.awtUnlock();
}
} }
public void setGrab(boolean grab) { public void setGrab(boolean grab) {

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,4 +39,5 @@ public interface X11ComponentPeer {
Rectangle getBounds(); Rectangle getBounds();
Graphics getGraphics(); Graphics getGraphics();
Object getTarget(); Object getTarget();
void setFullScreenExclusiveModeState(boolean state);
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -306,12 +306,14 @@ public class X11GraphicsDevice
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer(); X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
if (peer != null) { if (peer != null) {
enterFullScreenExclusive(peer.getContentWindow()); enterFullScreenExclusive(peer.getContentWindow());
peer.setFullScreenExclusiveModeState(true);
} }
} }
private static void exitFullScreenExclusive(Window w) { private static void exitFullScreenExclusive(Window w) {
X11ComponentPeer peer = (X11ComponentPeer)w.getPeer(); X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
if (peer != null) { if (peer != null) {
peer.setFullScreenExclusiveModeState(false);
exitFullScreenExclusive(peer.getContentWindow()); exitFullScreenExclusive(peer.getContentWindow());
} }
} }

View File

@ -1654,6 +1654,7 @@ Java_sun_awt_X11GraphicsEnvironment_getXineramaCenterPoint(JNIEnv *env,
#ifndef HEADLESS #ifndef HEADLESS
#define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI #define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
#define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN
typedef Status typedef Status
(*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp); (*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);
@ -1680,6 +1681,9 @@ typedef Status
Rotation rotation, Rotation rotation,
short rate, short rate,
Time timestamp); Time timestamp);
typedef Rotation
(*XRRConfigRotationsType)(XRRScreenConfiguration *config,
Rotation *current_rotation);
static XRRQueryVersionType awt_XRRQueryVersion; static XRRQueryVersionType awt_XRRQueryVersion;
static XRRGetScreenInfoType awt_XRRGetScreenInfo; static XRRGetScreenInfoType awt_XRRGetScreenInfo;
@ -1689,6 +1693,7 @@ static XRRConfigCurrentRateType awt_XRRConfigCurrentRate;
static XRRConfigSizesType awt_XRRConfigSizes; static XRRConfigSizesType awt_XRRConfigSizes;
static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration; static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration;
static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate; static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate;
static XRRConfigRotationsType awt_XRRConfigRotations;
#define LOAD_XRANDR_FUNC(f) \ #define LOAD_XRANDR_FUNC(f) \
do { \ do { \
@ -1755,6 +1760,7 @@ X11GD_InitXrandrFuncs(JNIEnv *env)
LOAD_XRANDR_FUNC(XRRConfigSizes); LOAD_XRANDR_FUNC(XRRConfigSizes);
LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration); LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration);
LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate); LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate);
LOAD_XRANDR_FUNC(XRRConfigRotations);
return JNI_TRUE; return JNI_TRUE;
} }
@ -1765,6 +1771,7 @@ X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height,
{ {
jclass displayModeClass; jclass displayModeClass;
jmethodID cid; jmethodID cid;
jint validRefreshRate = refreshRate;
displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode"); displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode");
if (JNU_IsNull(env, displayModeClass)) { if (JNU_IsNull(env, displayModeClass)) {
@ -1780,8 +1787,13 @@ X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height,
return NULL; return NULL;
} }
// early versions of xrandr may report "empty" rates (6880694)
if (validRefreshRate <= 0) {
validRefreshRate = REFRESH_RATE_UNKNOWN;
}
return (*env)->NewObject(env, displayModeClass, cid, return (*env)->NewObject(env, displayModeClass, cid,
width, height, bitDepth, refreshRate); width, height, bitDepth, validRefreshRate);
} }
static void static void
@ -1926,8 +1938,7 @@ Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode
curRate = awt_XRRConfigCurrentRate(config); curRate = awt_XRRConfigCurrentRate(config);
if ((sizes != NULL) && if ((sizes != NULL) &&
(curSizeIndex < nsizes) && (curSizeIndex < nsizes))
(curRate > 0))
{ {
XRRScreenSize curSize = sizes[curSizeIndex]; XRRScreenSize curSize = sizes[curSizeIndex];
displayMode = X11GD_CreateDisplayMode(env, displayMode = X11GD_CreateDisplayMode(env,
@ -2004,6 +2015,7 @@ Java_sun_awt_X11GraphicsDevice_configDisplayMode
jboolean success = JNI_FALSE; jboolean success = JNI_FALSE;
XRRScreenConfiguration *config; XRRScreenConfiguration *config;
Drawable root; Drawable root;
Rotation currentRotation = RR_Rotate_0;
AWT_LOCK(); AWT_LOCK();
@ -2015,6 +2027,7 @@ Java_sun_awt_X11GraphicsDevice_configDisplayMode
short chosenRate = -1; short chosenRate = -1;
int nsizes; int nsizes;
XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes); XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);
awt_XRRConfigRotations(config, &currentRotation);
if (sizes != NULL) { if (sizes != NULL) {
int i, j; int i, j;
@ -2048,7 +2061,7 @@ Java_sun_awt_X11GraphicsDevice_configDisplayMode
Status status = Status status =
awt_XRRSetScreenConfigAndRate(awt_display, config, root, awt_XRRSetScreenConfigAndRate(awt_display, config, root,
chosenSizeIndex, chosenSizeIndex,
RR_Rotate_0, currentRotation,
chosenRate, chosenRate,
CurrentTime); CurrentTime);

View File

@ -677,7 +677,7 @@ JNIEXPORT jstring JNICALL Java_sun_awt_X11_XToolkit_getEnv
jstring ret = NULL; jstring ret = NULL;
keystr = JNU_GetStringPlatformChars(env, key, NULL); keystr = JNU_GetStringPlatformChars(env, key, NULL);
if (key) { if (keystr) {
ptr = getenv(keystr); ptr = getenv(keystr);
if (ptr) { if (ptr) {
ret = JNU_NewStringPlatform(env, (const char *) ptr); ret = JNU_NewStringPlatform(env, (const char *) ptr);

View File

@ -353,6 +353,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
} }
WWindowPeer peer = (WWindowPeer)old.getPeer(); WWindowPeer peer = (WWindowPeer)old.getPeer();
if (peer != null) { if (peer != null) {
peer.setFullScreenExclusiveModeState(false);
// we used to destroy the buffers on exiting fs mode, this // we used to destroy the buffers on exiting fs mode, this
// is no longer needed since fs change will cause a surface // is no longer needed since fs change will cause a surface
// data replacement // data replacement
@ -370,6 +371,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
addFSWindowListener(w); addFSWindowListener(w);
// Enter full screen exclusive mode. // Enter full screen exclusive mode.
WWindowPeer peer = (WWindowPeer)w.getPeer(); WWindowPeer peer = (WWindowPeer)w.getPeer();
if (peer != null) {
synchronized(peer) { synchronized(peer) {
enterFullScreenExclusive(screen, peer); enterFullScreenExclusive(screen, peer);
// Note: removed replaceSurfaceData() call because // Note: removed replaceSurfaceData() call because
@ -377,6 +379,8 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
// will cause this anyway, and both of these events happen // will cause this anyway, and both of these events happen
// as part of switching into fullscreen mode. // as part of switching into fullscreen mode.
} }
peer.setFullScreenExclusiveModeState(true);
}
// fix for 4868278 // fix for 4868278
peer.updateGC(); peer.updateGC();

View File

@ -550,8 +550,34 @@ public abstract class WComponentPeer extends WObjectPeer
final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
public Graphics getGraphics() { 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; SurfaceData surfaceData = this.surfaceData;
if (!isDisposed() && surfaceData != null) { if (surfaceData != null) {
/* Fix for bug 4746122. Color and Font shouldn't be null */ /* Fix for bug 4746122. Color and Font shouldn't be null */
Color bgColor = background; Color bgColor = background;
if (bgColor == null) { if (bgColor == null) {

View File

@ -510,6 +510,9 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
private native int getScreenImOn(); private native int getScreenImOn();
// Used in Win32GraphicsDevice.
public final native void setFullScreenExclusiveModeState(boolean state);
/* /*
* ----END DISPLAY CHANGE SUPPORT---- * ----END DISPLAY CHANGE SUPPORT----
*/ */
@ -575,11 +578,17 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
} }
} }
public final Graphics getTranslucentGraphics() {
synchronized (getStateLock()) {
return isOpaque ? null : painter.getBackBuffer(false).getGraphics();
}
}
@Override @Override
public Graphics getGraphics() { public Graphics getGraphics() {
synchronized (getStateLock()) { synchronized (getStateLock()) {
if (!isOpaque) { if (!isOpaque) {
return painter.getBackBuffer(false).getGraphics(); return getTranslucentGraphics();
} }
} }
return super.getGraphics(); return super.getGraphics();

View File

@ -59,7 +59,7 @@ struct DisplayMessageStruct {
}; };
typedef struct tagBitmapheader { typedef struct tagBitmapheader {
BITMAPINFOHEADER bmiHeader; BITMAPV5HEADER bmiHeader;
DWORD dwMasks[256]; DWORD dwMasks[256];
} Bitmapheader, *LPBITMAPHEADER; } Bitmapheader, *LPBITMAPHEADER;
@ -638,12 +638,12 @@ void AwtTrayIcon::UnlinkObjects()
HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH) HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH)
{ {
Bitmapheader bmhHeader; Bitmapheader bmhHeader = {0};
HDC hDC; HDC hDC;
char *ptrImageData; char *ptrImageData;
HBITMAP hbmpBitmap; HBITMAP hbmpBitmap;
HBITMAP hBitmap; HBITMAP hBitmap;
int nNumChannels = 3; int nNumChannels = 4;
if (!hW) { if (!hW) {
hW = ::GetDesktopWindow(); hW = ::GetDesktopWindow();
@ -653,14 +653,20 @@ HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH)
return NULL; return NULL;
} }
memset(&bmhHeader, 0, sizeof(Bitmapheader)); bmhHeader.bmiHeader.bV5Size = sizeof(BITMAPV5HEADER);
bmhHeader.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmhHeader.bmiHeader.bV5Width = nW;
bmhHeader.bmiHeader.biWidth = nW; bmhHeader.bmiHeader.bV5Height = -nH;
bmhHeader.bmiHeader.biHeight = -nH; bmhHeader.bmiHeader.bV5Planes = 1;
bmhHeader.bmiHeader.biPlanes = 1;
bmhHeader.bmiHeader.biBitCount = 24; bmhHeader.bmiHeader.bV5BitCount = 32;
bmhHeader.bmiHeader.biCompression = BI_RGB; 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), hbmpBitmap = ::CreateDIBSection(hDC, (BITMAPINFO*)&(bmhHeader),
DIB_RGB_COLORS, DIB_RGB_COLORS,
@ -674,6 +680,7 @@ HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH)
} }
for (int nOutern = 0; nOutern < nH; nOutern++) { for (int nOutern = 0; nOutern < nH; nOutern++) {
for (int nInner = 0; nInner < nSS; nInner++) { for (int nInner = 0; nInner < nSS; nInner++) {
dstPtr[3] = (*srcPtr >> 0x18) & 0xFF;
dstPtr[2] = (*srcPtr >> 0x10) & 0xFF; dstPtr[2] = (*srcPtr >> 0x10) & 0xFF;
dstPtr[1] = (*srcPtr >> 0x08) & 0xFF; dstPtr[1] = (*srcPtr >> 0x08) & 0xFF;
dstPtr[0] = *srcPtr & 0xFF; dstPtr[0] = *srcPtr & 0xFF;

View File

@ -143,6 +143,11 @@ struct RepositionSecurityWarningStruct {
jobject window; jobject window;
}; };
struct SetFullScreenExclusiveModeStateStruct {
jobject window;
jboolean isFSEMState;
};
/************************************************************************ /************************************************************************
* AwtWindow fields * AwtWindow fields
@ -915,7 +920,9 @@ void AwtWindow::UpdateSecurityWarningVisibility()
bool show = false; bool show = false;
if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED) { if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED &&
!isFullScreenExclusiveMode())
{
if (AwtComponent::GetFocusedWindow() == GetHWnd()) { if (AwtComponent::GetFocusedWindow() == GetHWnd()) {
show = true; show = true;
} }
@ -2954,6 +2961,25 @@ void AwtWindow::_UpdateWindow(void* param)
delete uws; 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" { extern "C" {
@ -3333,6 +3359,29 @@ Java_sun_awt_windows_WWindowPeer_getScreenImOn(JNIEnv *env, jobject self)
CATCH_BAD_ALLOC_RET(-1); CATCH_BAD_ALLOC_RET(-1);
} }
/*
* 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 * Class: sun_awt_windows_WWindowPeer
* Method: modalDisable * Method: modalDisable

View File

@ -229,6 +229,7 @@ public:
static void _SetOpaque(void* param); static void _SetOpaque(void* param);
static void _UpdateWindow(void* param); static void _UpdateWindow(void* param);
static void _RepositionSecurityWarning(void* param); static void _RepositionSecurityWarning(void* param);
static void _SetFullScreenExclusiveModeState(void* param);
inline static BOOL IsResizing() { inline static BOOL IsResizing() {
return sm_resizing; return sm_resizing;
@ -331,6 +332,16 @@ private:
static void SetLayered(HWND window, bool layered); static void SetLayered(HWND window, bool layered);
static bool IsLayered(HWND window); static bool IsLayered(HWND window);
BOOL fullScreenExclusiveModeState;
inline void setFullScreenExclusiveModeState(BOOL isEntered) {
fullScreenExclusiveModeState = isEntered;
UpdateSecurityWarningVisibility();
}
inline BOOL isFullScreenExclusiveMode() {
return fullScreenExclusiveModeState;
}
public: public:
void UpdateSecurityWarningVisibility(); void UpdateSecurityWarningVisibility();
static bool IsWarningWindow(HWND hWnd); static bool IsWarningWindow(HWND hWnd);

View File

@ -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");
}
}
});
}
}

View File

@ -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 ");
}
}
}