Merge
This commit is contained in:
commit
b1415f3d2d
@ -85,3 +85,13 @@ vpath %.c $(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen
|
||||
CPPFLAGS += -I$(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen -I$(SHARE_SRC)/native/$(PKGDIR)/splashscreen
|
||||
CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/image/jpeg -I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3
|
||||
|
||||
ifeq ($(PLATFORM), linux)
|
||||
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||
# 64-bit gcc has problems compiling MMX instructions.
|
||||
# Google it for more details. Possibly the newer versions of
|
||||
# the PNG-library and/or the new compiler will not need this
|
||||
# option in the future.
|
||||
CPPFLAGS += -DPNG_NO_MMX_CODE
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2002-2008 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
|
||||
@ -246,7 +246,7 @@ $(SIZES): $(SIZERS)
|
||||
@if [ "$(DOCOMPARE)$(suffix $@)" = "true.64" ]; then \
|
||||
$(ECHO) COMPARING $@ and $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
|
||||
$(DIFF) $@ $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
|
||||
fi
|
||||
fi
|
||||
|
||||
$(TEMPDIR)/.gen.wrappers: $(SIZES) $(WRAPPER_GENERATOR_CLASS) $(XLIBTYPES)
|
||||
$(BOOT_JAVA_CMD) -cp $(WRAPPER_GENERATOR_TEMPDIR) WrapperGenerator \
|
||||
@ -256,10 +256,11 @@ touch.wrappers: $(TEMPDIR)/.gen.wrappers
|
||||
$(MKDIR) -p $(TEMPDIR)
|
||||
$(TOUCH) $(TEMPDIR)/.gen.wrappers
|
||||
|
||||
generated.clean:
|
||||
generated.clean:
|
||||
$(RM) -r $(WRAPPER_GENERATOR_TEMPDIR)
|
||||
$(RM) -r $(WRAPPER_GENERATOR_DIR)
|
||||
$(RM) -r $(GEN_DIR)/*.java
|
||||
$(RM) -r $(TEMPDIR)/.gen_icons
|
||||
|
||||
ifdef OPENJDK
|
||||
ICONS_PATH_PREFIX=$(PLATFORM_SRC)
|
||||
|
@ -634,6 +634,11 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
*/
|
||||
private PropertyChangeSupport changeSupport;
|
||||
|
||||
private transient final Object changeSupportLock = new Object();
|
||||
private Object getChangeSupportLock() {
|
||||
return changeSupportLock;
|
||||
}
|
||||
|
||||
boolean isPacked = false;
|
||||
|
||||
/**
|
||||
@ -935,24 +940,26 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
*/
|
||||
public GraphicsConfiguration getGraphicsConfiguration() {
|
||||
synchronized(getTreeLock()) {
|
||||
GraphicsConfiguration gc = graphicsConfig;
|
||||
Component parent = getParent();
|
||||
while ((gc == null) && (parent != null)) {
|
||||
gc = parent.getGraphicsConfiguration();
|
||||
parent = parent.getParent();
|
||||
if (graphicsConfig != null) {
|
||||
return graphicsConfig;
|
||||
} else if (getParent() != null) {
|
||||
return getParent().getGraphicsConfiguration();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return gc;
|
||||
}
|
||||
}
|
||||
|
||||
final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
|
||||
GraphicsConfiguration gc = this.graphicsConfig;
|
||||
Component par = this.parent;
|
||||
while ((gc == null) && (par != null)) {
|
||||
gc = par.getGraphicsConfiguration_NoClientCode();
|
||||
par = par.parent;
|
||||
GraphicsConfiguration graphicsConfig = this.graphicsConfig;
|
||||
Container parent = this.parent;
|
||||
if (graphicsConfig != null) {
|
||||
return graphicsConfig;
|
||||
} else if (parent != null) {
|
||||
return parent.getGraphicsConfiguration_NoClientCode();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return gc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4602,7 +4609,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
e.isPopupTrigger(),
|
||||
e.getScrollType(),
|
||||
e.getScrollAmount(),
|
||||
e.getWheelRotation());
|
||||
e.getWheelRotation(),
|
||||
e.getPreciseWheelRotation());
|
||||
((AWTEvent)e).copyPrivateDataInto(newMWE);
|
||||
// When dispatching a wheel event to
|
||||
// ancestor, there is no need trying to find descendant
|
||||
@ -6484,7 +6492,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
// will need some help.
|
||||
Container parent = this.parent;
|
||||
if (parent != null && parent.peer instanceof LightweightPeer) {
|
||||
nativeInLightFixer = new NativeInLightFixer();
|
||||
relocateComponent();
|
||||
}
|
||||
}
|
||||
invalidate();
|
||||
@ -6595,10 +6603,6 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
}
|
||||
}
|
||||
|
||||
if (nativeInLightFixer != null) {
|
||||
nativeInLightFixer.uninstall();
|
||||
}
|
||||
|
||||
ComponentPeer p = peer;
|
||||
if (p != null) {
|
||||
boolean isLightweight = isLightweight();
|
||||
@ -7836,15 +7840,17 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
* @see #getPropertyChangeListeners
|
||||
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
||||
*/
|
||||
public synchronized void addPropertyChangeListener(
|
||||
public void addPropertyChangeListener(
|
||||
PropertyChangeListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
synchronized (getChangeSupportLock()) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
if (changeSupport == null) {
|
||||
changeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
changeSupport.addPropertyChangeListener(listener);
|
||||
}
|
||||
if (changeSupport == null) {
|
||||
changeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
changeSupport.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7860,12 +7866,14 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
* @see #getPropertyChangeListeners
|
||||
* @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
|
||||
*/
|
||||
public synchronized void removePropertyChangeListener(
|
||||
public void removePropertyChangeListener(
|
||||
PropertyChangeListener listener) {
|
||||
if (listener == null || changeSupport == null) {
|
||||
return;
|
||||
synchronized (getChangeSupportLock()) {
|
||||
if (listener == null || changeSupport == null) {
|
||||
return;
|
||||
}
|
||||
changeSupport.removePropertyChangeListener(listener);
|
||||
}
|
||||
changeSupport.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7882,11 +7890,13 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
* @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
|
||||
if (changeSupport == null) {
|
||||
return new PropertyChangeListener[0];
|
||||
public PropertyChangeListener[] getPropertyChangeListeners() {
|
||||
synchronized (getChangeSupportLock()) {
|
||||
if (changeSupport == null) {
|
||||
return new PropertyChangeListener[0];
|
||||
}
|
||||
return changeSupport.getPropertyChangeListeners();
|
||||
}
|
||||
return changeSupport.getPropertyChangeListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7920,16 +7930,18 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
* @see #getPropertyChangeListeners(java.lang.String)
|
||||
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
||||
*/
|
||||
public synchronized void addPropertyChangeListener(
|
||||
public void addPropertyChangeListener(
|
||||
String propertyName,
|
||||
PropertyChangeListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
synchronized (getChangeSupportLock()) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
if (changeSupport == null) {
|
||||
changeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
changeSupport.addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
if (changeSupport == null) {
|
||||
changeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
changeSupport.addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7948,13 +7960,15 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
* @see #getPropertyChangeListeners(java.lang.String)
|
||||
* @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
|
||||
*/
|
||||
public synchronized void removePropertyChangeListener(
|
||||
public void removePropertyChangeListener(
|
||||
String propertyName,
|
||||
PropertyChangeListener listener) {
|
||||
if (listener == null || changeSupport == null) {
|
||||
return;
|
||||
synchronized (getChangeSupportLock()) {
|
||||
if (listener == null || changeSupport == null) {
|
||||
return;
|
||||
}
|
||||
changeSupport.removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
changeSupport.removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7971,12 +7985,14 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
* @see #getPropertyChangeListeners
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized PropertyChangeListener[] getPropertyChangeListeners(
|
||||
public PropertyChangeListener[] getPropertyChangeListeners(
|
||||
String propertyName) {
|
||||
if (changeSupport == null) {
|
||||
return new PropertyChangeListener[0];
|
||||
synchronized (getChangeSupportLock()) {
|
||||
if (changeSupport == null) {
|
||||
return new PropertyChangeListener[0];
|
||||
}
|
||||
return changeSupport.getPropertyChangeListeners(propertyName);
|
||||
}
|
||||
return changeSupport.getPropertyChangeListeners(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7991,7 +8007,10 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
*/
|
||||
protected void firePropertyChange(String propertyName,
|
||||
Object oldValue, Object newValue) {
|
||||
PropertyChangeSupport changeSupport = this.changeSupport;
|
||||
PropertyChangeSupport changeSupport;
|
||||
synchronized (getChangeSupportLock()) {
|
||||
changeSupport = this.changeSupport;
|
||||
}
|
||||
if (changeSupport == null ||
|
||||
(oldValue != null && newValue != null && oldValue.equals(newValue))) {
|
||||
return;
|
||||
@ -8491,8 +8510,6 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
setComponentOrientation(orientation);
|
||||
}
|
||||
|
||||
transient NativeInLightFixer nativeInLightFixer;
|
||||
|
||||
/**
|
||||
* Checks that this component meets the prerequesites to be focus owner:
|
||||
* - it is enabled, visible, focusable
|
||||
@ -8518,188 +8535,25 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
}
|
||||
|
||||
/**
|
||||
* This odd class is to help out a native component that has been
|
||||
* embedded in a lightweight component. Moving lightweight
|
||||
* components around and changing their visibility is not seen
|
||||
* by the native window system. This is a feature for lightweights,
|
||||
* but a problem for native components that depend upon the
|
||||
* lightweights. An instance of this class listens to the lightweight
|
||||
* parents of an associated native component (the outer class).
|
||||
*
|
||||
* @author Timothy Prinzing
|
||||
* Fix the location of the HW component in a LW container hierarchy.
|
||||
*/
|
||||
final class NativeInLightFixer implements ComponentListener, ContainerListener {
|
||||
|
||||
NativeInLightFixer() {
|
||||
lightParents = new Vector();
|
||||
install(parent);
|
||||
}
|
||||
|
||||
void install(Container parent) {
|
||||
lightParents.clear();
|
||||
Container p = parent;
|
||||
boolean isLwParentsVisible = true;
|
||||
// stash a reference to the components that are being observed so that
|
||||
// we can reliably remove ourself as a listener later.
|
||||
for (; p.peer instanceof LightweightPeer; p = p.parent) {
|
||||
|
||||
// register listeners and stash a reference
|
||||
p.addComponentListener(this);
|
||||
p.addContainerListener(this);
|
||||
lightParents.addElement(p);
|
||||
isLwParentsVisible &= p.isVisible();
|
||||
final void relocateComponent() {
|
||||
synchronized (getTreeLock()) {
|
||||
if (peer == null) {
|
||||
return;
|
||||
}
|
||||
// register with the native host (native parent of associated native)
|
||||
// to get notified if the top-level lightweight is removed.
|
||||
nativeHost = p;
|
||||
p.addContainerListener(this);
|
||||
|
||||
// kick start the fixup. Since the event isn't looked at
|
||||
// we can simulate movement notification.
|
||||
componentMoved(null);
|
||||
if (!isLwParentsVisible) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (peer != null) {
|
||||
peer.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uninstall() {
|
||||
if (nativeHost != null) {
|
||||
removeReferences();
|
||||
}
|
||||
}
|
||||
|
||||
// --- ComponentListener -------------------------------------------
|
||||
|
||||
/**
|
||||
* Invoked when one of the lightweight parents has been resized.
|
||||
* This doesn't change the position of the native child so it
|
||||
* is ignored.
|
||||
*/
|
||||
public void componentResized(ComponentEvent e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when one of the lightweight parents has been moved.
|
||||
* The native peer must be told of the new position which is
|
||||
* relative to the native container that is hosting the
|
||||
* lightweight components.
|
||||
*/
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
synchronized (getTreeLock()) {
|
||||
int nativeX = x;
|
||||
int nativeY = y;
|
||||
for(Component c = parent; (c != null) &&
|
||||
(c.peer instanceof LightweightPeer);
|
||||
c = c.parent) {
|
||||
|
||||
nativeX += c.x;
|
||||
nativeY += c.y;
|
||||
}
|
||||
if (peer != null) {
|
||||
peer.setBounds(nativeX, nativeY, width, height,
|
||||
ComponentPeer.SET_LOCATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a lightweight parent component has been
|
||||
* shown. The associated native component must also be
|
||||
* shown if it hasn't had an overriding hide done on it.
|
||||
*/
|
||||
public void componentShown(ComponentEvent e) {
|
||||
if (shouldShow()) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (peer != null) {
|
||||
peer.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when one of the lightweight parents become visible.
|
||||
* Returns true if component and all its lightweight
|
||||
* parents are visible.
|
||||
*/
|
||||
private boolean shouldShow() {
|
||||
boolean isLwParentsVisible = visible;
|
||||
for (int i = lightParents.size() - 1;
|
||||
i >= 0 && isLwParentsVisible;
|
||||
i--)
|
||||
int nativeX = x;
|
||||
int nativeY = y;
|
||||
for (Component cont = getContainer();
|
||||
cont != null && cont.isLightweight();
|
||||
cont = cont.getContainer())
|
||||
{
|
||||
isLwParentsVisible &=
|
||||
((Container) lightParents.elementAt(i)).isVisible();
|
||||
nativeX += cont.x;
|
||||
nativeY += cont.y;
|
||||
}
|
||||
return isLwParentsVisible;
|
||||
peer.setBounds(nativeX, nativeY, width, height,
|
||||
ComponentPeer.SET_LOCATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when component has been hidden.
|
||||
*/
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
if (visible) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (peer != null) {
|
||||
peer.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- ContainerListener ------------------------------------
|
||||
|
||||
/**
|
||||
* Invoked when a component has been added to a lightweight
|
||||
* parent. This doesn't effect the native component.
|
||||
*/
|
||||
public void componentAdded(ContainerEvent e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a lightweight parent has been removed.
|
||||
* This means the services of this listener are no longer
|
||||
* required and it should remove all references (ie
|
||||
* registered listeners).
|
||||
*/
|
||||
public void componentRemoved(ContainerEvent e) {
|
||||
Component c = e.getChild();
|
||||
if (c == Component.this) {
|
||||
removeReferences();
|
||||
} else {
|
||||
int n = lightParents.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Container p = (Container) lightParents.elementAt(i);
|
||||
if (p == c) {
|
||||
removeReferences();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes references to this object so it can be
|
||||
* garbage collected.
|
||||
*/
|
||||
void removeReferences() {
|
||||
int n = lightParents.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Container c = (Container) lightParents.elementAt(i);
|
||||
c.removeComponentListener(this);
|
||||
c.removeContainerListener(this);
|
||||
}
|
||||
nativeHost.removeContainerListener(this);
|
||||
lightParents.clear();
|
||||
nativeHost = null;
|
||||
}
|
||||
|
||||
Vector lightParents;
|
||||
Container nativeHost;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -9452,6 +9306,19 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
|
||||
// ************************** MIXING CODE *******************************
|
||||
|
||||
/**
|
||||
* Check whether we can trust the current bounds of the component.
|
||||
* The return value of false indicates that the container of the
|
||||
* component is invalid, and therefore needs to be layed out, which would
|
||||
* probably mean changing the bounds of its children.
|
||||
* Null-layout of the container or absence of the container mean
|
||||
* the bounds of the component are final and can be trusted.
|
||||
*/
|
||||
private boolean areBoundsValid() {
|
||||
Container cont = getContainer();
|
||||
return cont == null || cont.isValid() || cont.getLayout() == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the shape to the component
|
||||
* @param shape Shape to be applied to the component
|
||||
@ -9475,7 +9342,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
// to modify the object outside of the mixing code.
|
||||
this.compoundShape = shape;
|
||||
|
||||
if (isValid()) {
|
||||
if (areBoundsValid()) {
|
||||
Point compAbsolute = getLocationOnWindow();
|
||||
|
||||
if (mixingLog.isLoggable(Level.FINER)) {
|
||||
@ -9602,7 +9469,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
|
||||
void applyCurrentShape() {
|
||||
checkTreeLock();
|
||||
if (!isValid()) {
|
||||
if (!areBoundsValid()) {
|
||||
return; // Because applyCompoundShape() ignores such components anyway
|
||||
}
|
||||
if (mixingLog.isLoggable(Level.FINE)) {
|
||||
|
@ -832,16 +832,8 @@ public class Container extends Component {
|
||||
}
|
||||
if (!comp.isLightweight() && isLightweight()) {
|
||||
// If component is heavyweight and one of the containers is lightweight
|
||||
// some NativeInLightFixer activity should be performed
|
||||
if (!curParent.isLightweight()) {
|
||||
// Moving from heavyweight container to lightweight container - should create NativeInLightFixer
|
||||
// since addNotify does this
|
||||
comp.nativeInLightFixer = new NativeInLightFixer();
|
||||
} else {
|
||||
// Component already has NativeInLightFixer - just reinstall it
|
||||
// because hierarchy changed and he needs to rebuild list of parents to listen.
|
||||
comp.nativeInLightFixer.install(this);
|
||||
}
|
||||
// the location of the component should be fixed.
|
||||
comp.relocateComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2267,53 +2259,56 @@ public class Container extends Component {
|
||||
EventTargetFilter filter,
|
||||
boolean searchHeavyweightChildren,
|
||||
boolean searchHeavyweightDescendants) {
|
||||
int ncomponents = this.ncomponents;
|
||||
Component component[] = this.component;
|
||||
synchronized (getTreeLock()) {
|
||||
int ncomponents = this.ncomponents;
|
||||
Component component[] = this.component;
|
||||
|
||||
for (int i = 0 ; i < ncomponents ; i++) {
|
||||
Component comp = component[i];
|
||||
if (comp != null && comp.visible &&
|
||||
((!searchHeavyweightChildren &&
|
||||
comp.peer instanceof LightweightPeer) ||
|
||||
(searchHeavyweightChildren &&
|
||||
!(comp.peer instanceof LightweightPeer))) &&
|
||||
comp.contains(x - comp.x, y - comp.y)) {
|
||||
for (int i = 0 ; i < ncomponents ; i++) {
|
||||
Component comp = component[i];
|
||||
if (comp != null && comp.visible &&
|
||||
((!searchHeavyweightChildren &&
|
||||
comp.peer instanceof LightweightPeer) ||
|
||||
(searchHeavyweightChildren &&
|
||||
!(comp.peer instanceof LightweightPeer))) &&
|
||||
comp.contains(x - comp.x, y - comp.y)) {
|
||||
|
||||
// found a component that intersects the point, see if there is
|
||||
// a deeper possibility.
|
||||
if (comp instanceof Container) {
|
||||
Container child = (Container) comp;
|
||||
Component deeper = child.getMouseEventTarget(x - child.x,
|
||||
y - child.y,
|
||||
includeSelf,
|
||||
filter,
|
||||
searchHeavyweightDescendants);
|
||||
if (deeper != null) {
|
||||
return deeper;
|
||||
}
|
||||
} else {
|
||||
if (filter.accept(comp)) {
|
||||
// there isn't a deeper target, but this component is a
|
||||
// target
|
||||
return comp;
|
||||
// found a component that intersects the point, see if there
|
||||
// is a deeper possibility.
|
||||
if (comp instanceof Container) {
|
||||
Container child = (Container) comp;
|
||||
Component deeper = child.getMouseEventTarget(
|
||||
x - child.x,
|
||||
y - child.y,
|
||||
includeSelf,
|
||||
filter,
|
||||
searchHeavyweightDescendants);
|
||||
if (deeper != null) {
|
||||
return deeper;
|
||||
}
|
||||
} else {
|
||||
if (filter.accept(comp)) {
|
||||
// there isn't a deeper target, but this component
|
||||
// is a target
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isPeerOK;
|
||||
boolean isMouseOverMe;
|
||||
|
||||
isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
|
||||
isMouseOverMe = contains(x,y);
|
||||
|
||||
// didn't find a child target, return this component if it's
|
||||
// a possible target
|
||||
if (isMouseOverMe && isPeerOK && filter.accept(this)) {
|
||||
return this;
|
||||
}
|
||||
// no possible target
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isPeerOK;
|
||||
boolean isMouseOverMe;
|
||||
|
||||
isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
|
||||
isMouseOverMe = contains(x,y);
|
||||
|
||||
// didn't find a child target, return this component if it's a possible
|
||||
// target
|
||||
if (isMouseOverMe && isPeerOK && filter.accept(this)) {
|
||||
return this;
|
||||
}
|
||||
// no possible target
|
||||
return null;
|
||||
}
|
||||
|
||||
static interface EventTargetFilter {
|
||||
@ -3950,6 +3945,83 @@ public class Container extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
private void recursiveShowHeavyweightChildren() {
|
||||
if (!hasHeavyweightDescendants() || !isVisible()) {
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < getComponentCount(); index++) {
|
||||
Component comp = getComponent(index);
|
||||
if (comp.isLightweight()) {
|
||||
if (comp instanceof Container) {
|
||||
((Container)comp).recursiveShowHeavyweightChildren();
|
||||
}
|
||||
} else {
|
||||
if (comp.isVisible()) {
|
||||
ComponentPeer peer = comp.getPeer();
|
||||
if (peer != null) {
|
||||
peer.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void recursiveHideHeavyweightChildren() {
|
||||
if (!hasHeavyweightDescendants()) {
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < getComponentCount(); index++) {
|
||||
Component comp = getComponent(index);
|
||||
if (comp.isLightweight()) {
|
||||
if (comp instanceof Container) {
|
||||
((Container)comp).recursiveHideHeavyweightChildren();
|
||||
}
|
||||
} else {
|
||||
if (comp.isVisible()) {
|
||||
ComponentPeer peer = comp.getPeer();
|
||||
if (peer != null) {
|
||||
peer.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void recursiveRelocateHeavyweightChildren(Point origin) {
|
||||
for (int index = 0; index < getComponentCount(); index++) {
|
||||
Component comp = getComponent(index);
|
||||
if (comp.isLightweight()) {
|
||||
if (comp instanceof Container &&
|
||||
((Container)comp).hasHeavyweightDescendants())
|
||||
{
|
||||
final Point newOrigin = new Point(origin);
|
||||
newOrigin.translate(comp.getX(), comp.getY());
|
||||
((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
|
||||
}
|
||||
} else {
|
||||
ComponentPeer peer = comp.getPeer();
|
||||
if (peer != null) {
|
||||
peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
|
||||
comp.getWidth(), comp.getHeight(),
|
||||
ComponentPeer.SET_LOCATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Consider the heavyweight container hides or shows the HW descendants
|
||||
* automatically. Therefore we care of LW containers' visibility only.
|
||||
*/
|
||||
private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
|
||||
if (!isLightweight()) {
|
||||
return true;
|
||||
}
|
||||
return isVisible() && (getContainer() == null ||
|
||||
getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
|
||||
}
|
||||
|
||||
@Override
|
||||
void mixOnShowing() {
|
||||
synchronized (getTreeLock()) {
|
||||
if (mixingLog.isLoggable(Level.FINE)) {
|
||||
@ -3958,6 +4030,10 @@ public class Container extends Component {
|
||||
|
||||
boolean isLightweight = isLightweight();
|
||||
|
||||
if (isLightweight && isRecursivelyVisibleUpToHeavyweightContainer()) {
|
||||
recursiveShowHeavyweightChildren();
|
||||
}
|
||||
|
||||
if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) {
|
||||
recursiveApplyCurrentShape();
|
||||
}
|
||||
@ -3966,6 +4042,42 @@ public class Container extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void mixOnHiding(boolean isLightweight) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (mixingLog.isLoggable(Level.FINE)) {
|
||||
mixingLog.fine("this = " + this +
|
||||
"; isLightweight=" + isLightweight);
|
||||
}
|
||||
if (isLightweight) {
|
||||
recursiveHideHeavyweightChildren();
|
||||
}
|
||||
super.mixOnHiding(isLightweight);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void mixOnReshaping() {
|
||||
synchronized (getTreeLock()) {
|
||||
if (mixingLog.isLoggable(Level.FINE)) {
|
||||
mixingLog.fine("this = " + this);
|
||||
}
|
||||
if (isLightweight() && hasHeavyweightDescendants()) {
|
||||
final Point origin = new Point(getX(), getY());
|
||||
for (Container cont = getContainer();
|
||||
cont != null && cont.isLightweight();
|
||||
cont = cont.getContainer())
|
||||
{
|
||||
origin.translate(cont.getX(), cont.getY());
|
||||
}
|
||||
|
||||
recursiveRelocateHeavyweightChildren(origin);
|
||||
}
|
||||
super.mixOnReshaping();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void mixOnZOrderChanging(int oldZorder, int newZorder) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (mixingLog.isLoggable(Level.FINE)) {
|
||||
@ -4431,7 +4543,8 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
|
||||
e.isPopupTrigger(),
|
||||
((MouseWheelEvent)e).getScrollType(),
|
||||
((MouseWheelEvent)e).getScrollAmount(),
|
||||
((MouseWheelEvent)e).getWheelRotation());
|
||||
((MouseWheelEvent)e).getWheelRotation(),
|
||||
((MouseWheelEvent)e).getPreciseWheelRotation());
|
||||
}
|
||||
else {
|
||||
retargeted = new MouseEvent(target,
|
||||
|
@ -154,7 +154,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
private boolean doRestoreFocus(Component toFocus, Component vetoedComponent,
|
||||
boolean clearOnFailure)
|
||||
{
|
||||
if (toFocus.isShowing() && toFocus.isFocusable() &&
|
||||
if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.isFocusable() &&
|
||||
toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK)) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,6 @@
|
||||
*/
|
||||
package java.awt;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.event.*;
|
||||
import java.awt.im.InputContext;
|
||||
import java.awt.image.BufferStrategy;
|
||||
@ -355,18 +354,21 @@ public class Window extends Container implements Accessible {
|
||||
static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
|
||||
final WeakReference<Window> owner;
|
||||
final WeakReference weakThis;
|
||||
final AppContext context;
|
||||
final WeakReference<AppContext> context;
|
||||
WindowDisposerRecord(AppContext context, Window victim) {
|
||||
owner = new WeakReference<Window>(victim.getOwner());
|
||||
weakThis = victim.weakThis;
|
||||
this.context = context;
|
||||
this.context = new WeakReference<AppContext>(context);
|
||||
}
|
||||
public void dispose() {
|
||||
Window parent = owner.get();
|
||||
if (parent != null) {
|
||||
parent.removeOwnedWindow(weakThis);
|
||||
}
|
||||
Window.removeFromWindowList(context, weakThis);
|
||||
AppContext ac = context.get();
|
||||
if (null != ac) {
|
||||
Window.removeFromWindowList(ac, weakThis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -824,7 +826,10 @@ public class Window extends Container implements Accessible {
|
||||
static private final AtomicBoolean
|
||||
beforeFirstWindowShown = new AtomicBoolean(true);
|
||||
|
||||
static final void closeSplashScreen() {
|
||||
final void closeSplashScreen() {
|
||||
if (isTrayIconWindow) {
|
||||
return;
|
||||
}
|
||||
if (beforeFirstWindowShown.getAndSet(false)) {
|
||||
SunToolkit.closeSplashScreen();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 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
|
||||
@ -49,7 +49,6 @@ import java.util.WeakHashMap;
|
||||
|
||||
import sun.awt.datatransfer.DataTransferer;
|
||||
|
||||
|
||||
/**
|
||||
* The SystemFlavorMap is a configurable map between "natives" (Strings), which
|
||||
* correspond to platform-specific data formats, and "flavors" (DataFlavors),
|
||||
@ -117,15 +116,50 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
/**
|
||||
* Maps native Strings to Lists of DataFlavors (or base type Strings for
|
||||
* text DataFlavors).
|
||||
* Do not use the field directly, use getNativeToFlavor() instead.
|
||||
*/
|
||||
private Map nativeToFlavor = new HashMap();
|
||||
|
||||
/**
|
||||
* Accessor to nativeToFlavor map. Since we use lazy initialization we must
|
||||
* use this accessor instead of direct access to the field which may not be
|
||||
* initialized yet. This method will initialize the field if needed.
|
||||
*
|
||||
* @return nativeToFlavor
|
||||
*/
|
||||
private Map getNativeToFlavor() {
|
||||
if (!isMapInitialized) {
|
||||
initSystemFlavorMap();
|
||||
}
|
||||
return nativeToFlavor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
|
||||
* native Strings.
|
||||
* Do not use the field directly, use getFlavorToNative() instead.
|
||||
*/
|
||||
private Map flavorToNative = new HashMap();
|
||||
|
||||
/**
|
||||
* Accessor to flavorToNative map. Since we use lazy initialization we must
|
||||
* use this accessor instead of direct access to the field which may not be
|
||||
* initialized yet. This method will initialize the field if needed.
|
||||
*
|
||||
* @return flavorToNative
|
||||
*/
|
||||
private synchronized Map getFlavorToNative() {
|
||||
if (!isMapInitialized) {
|
||||
initSystemFlavorMap();
|
||||
}
|
||||
return flavorToNative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows if the object has been initialized.
|
||||
*/
|
||||
private boolean isMapInitialized = false;
|
||||
|
||||
/**
|
||||
* Caches the result of getNativesForFlavor(). Maps DataFlavors to
|
||||
* SoftReferences which reference Lists of String natives.
|
||||
@ -169,15 +203,24 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
return fm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SystemFlavorMap by reading flavormap.properties and
|
||||
* AWT.DnD.flavorMapFileURL.
|
||||
*/
|
||||
private SystemFlavorMap() {
|
||||
BufferedReader flavormapDotProperties = (BufferedReader)
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a SystemFlavorMap by reading flavormap.properties and
|
||||
* AWT.DnD.flavorMapFileURL.
|
||||
* For thread-safety must be called under lock on this.
|
||||
*/
|
||||
private void initSystemFlavorMap() {
|
||||
if (isMapInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
isMapInitialized = true;
|
||||
BufferedReader flavormapDotProperties =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
new java.security.PrivilegedAction<BufferedReader>() {
|
||||
public BufferedReader run() {
|
||||
String fileName =
|
||||
System.getProperty("java.home") +
|
||||
File.separator +
|
||||
@ -197,12 +240,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
});
|
||||
|
||||
BufferedReader flavormapURL = (BufferedReader)
|
||||
BufferedReader flavormapURL =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
String url = Toolkit.getDefaultToolkit().getProperty
|
||||
("AWT.DnD.flavorMapFileURL", null);
|
||||
new java.security.PrivilegedAction<BufferedReader>() {
|
||||
public BufferedReader run() {
|
||||
String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
|
||||
|
||||
if (url == null) {
|
||||
return null;
|
||||
@ -237,7 +279,6 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied code from java.util.Properties. Parsing the data ourselves is the
|
||||
* only way to handle duplicate keys and values.
|
||||
@ -388,11 +429,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
// For text/* flavors, store mappings in separate maps to
|
||||
// enable dynamic mapping generation at a run-time.
|
||||
if ("text".equals(flavor.getPrimaryType())) {
|
||||
store(value, key, flavorToNative);
|
||||
store(key, value, nativeToFlavor);
|
||||
store(value, key, getFlavorToNative());
|
||||
store(key, value, getNativeToFlavor());
|
||||
} else {
|
||||
store(flavor, key, flavorToNative);
|
||||
store(key, flavor, nativeToFlavor);
|
||||
store(flavor, key, getFlavorToNative());
|
||||
store(key, flavor, getNativeToFlavor());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -494,7 +535,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
* only if the specified native is encoded as a Java MIME type.
|
||||
*/
|
||||
private List nativeToFlavorLookup(String nat) {
|
||||
List flavors = (List)nativeToFlavor.get(nat);
|
||||
List flavors = (List)getNativeToFlavor().get(nat);
|
||||
|
||||
if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
|
||||
DataTransferer transferer = DataTransferer.getInstance();
|
||||
@ -530,15 +571,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
|
||||
if (flavor != null) {
|
||||
flavors = new ArrayList(1);
|
||||
nativeToFlavor.put(nat, flavors);
|
||||
getNativeToFlavor().put(nat, flavors);
|
||||
flavors.add(flavor);
|
||||
getFlavorsForNativeCache.remove(nat);
|
||||
getFlavorsForNativeCache.remove(null);
|
||||
|
||||
List natives = (List)flavorToNative.get(flavor);
|
||||
List natives = (List)getFlavorToNative().get(flavor);
|
||||
if (natives == null) {
|
||||
natives = new ArrayList(1);
|
||||
flavorToNative.put(flavor, natives);
|
||||
getFlavorToNative().put(flavor, natives);
|
||||
}
|
||||
natives.add(nat);
|
||||
getNativesForFlavorCache.remove(flavor);
|
||||
@ -559,7 +600,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
*/
|
||||
private List flavorToNativeLookup(final DataFlavor flav,
|
||||
final boolean synthesize) {
|
||||
List natives = (List)flavorToNative.get(flav);
|
||||
List natives = (List)getFlavorToNative().get(flav);
|
||||
|
||||
if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
|
||||
DataTransferer transferer = DataTransferer.getInstance();
|
||||
@ -584,15 +625,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
if (synthesize) {
|
||||
String encoded = encodeDataFlavor(flav);
|
||||
natives = new ArrayList(1);
|
||||
flavorToNative.put(flav, natives);
|
||||
getFlavorToNative().put(flav, natives);
|
||||
natives.add(encoded);
|
||||
getNativesForFlavorCache.remove(flav);
|
||||
getNativesForFlavorCache.remove(null);
|
||||
|
||||
List flavors = (List)nativeToFlavor.get(encoded);
|
||||
List flavors = (List)getNativeToFlavor().get(encoded);
|
||||
if (flavors == null) {
|
||||
flavors = new ArrayList(1);
|
||||
nativeToFlavor.put(encoded, flavors);
|
||||
getNativeToFlavor().put(encoded, flavors);
|
||||
}
|
||||
flavors.add(flav);
|
||||
getFlavorsForNativeCache.remove(encoded);
|
||||
@ -645,7 +686,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
if (flav == null) {
|
||||
retval = new ArrayList(nativeToFlavor.keySet());
|
||||
retval = new ArrayList(getNativeToFlavor().keySet());
|
||||
} else if (disabledMappingGenerationKeys.contains(flav)) {
|
||||
// In this case we shouldn't synthesize a native for this flavor,
|
||||
// since its mappings were explicitly specified.
|
||||
@ -655,7 +696,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
// For text/* flavors, flavor-to-native mappings specified in
|
||||
// flavormap.properties are stored per flavor's base type.
|
||||
if ("text".equals(flav.getPrimaryType())) {
|
||||
retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
|
||||
retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
|
||||
if (retval != null) {
|
||||
// To prevent the List stored in the map from modification.
|
||||
retval = new ArrayList(retval);
|
||||
@ -663,7 +704,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
// Also include text/plain natives, but don't duplicate Strings
|
||||
List textPlainList = (List)flavorToNative.get(TEXT_PLAIN_BASE_TYPE);
|
||||
List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE);
|
||||
|
||||
if (textPlainList != null && !textPlainList.isEmpty()) {
|
||||
// To prevent the List stored in the map from modification.
|
||||
@ -699,7 +740,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
}
|
||||
} else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
|
||||
retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
|
||||
retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
|
||||
|
||||
if (retval == null || retval.isEmpty()) {
|
||||
retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
|
||||
@ -1025,10 +1066,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
throw new NullPointerException("null arguments not permitted");
|
||||
}
|
||||
|
||||
List natives = (List)flavorToNative.get(flav);
|
||||
List natives = (List)getFlavorToNative().get(flav);
|
||||
if (natives == null) {
|
||||
natives = new ArrayList(1);
|
||||
flavorToNative.put(flav, natives);
|
||||
getFlavorToNative().put(flav, natives);
|
||||
} else if (natives.contains(nat)) {
|
||||
return;
|
||||
}
|
||||
@ -1071,7 +1112,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
throw new NullPointerException("null arguments not permitted");
|
||||
}
|
||||
|
||||
flavorToNative.remove(flav);
|
||||
getFlavorToNative().remove(flav);
|
||||
for (int i = 0; i < natives.length; i++) {
|
||||
addUnencodedNativeForFlavor(flav, natives[i]);
|
||||
}
|
||||
@ -1105,10 +1146,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
throw new NullPointerException("null arguments not permitted");
|
||||
}
|
||||
|
||||
List flavors = (List)nativeToFlavor.get(nat);
|
||||
List flavors = (List)getNativeToFlavor().get(nat);
|
||||
if (flavors == null) {
|
||||
flavors = new ArrayList(1);
|
||||
nativeToFlavor.put(nat, flavors);
|
||||
getNativeToFlavor().put(nat, flavors);
|
||||
} else if (flavors.contains(flav)) {
|
||||
return;
|
||||
}
|
||||
@ -1150,7 +1191,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
throw new NullPointerException("null arguments not permitted");
|
||||
}
|
||||
|
||||
nativeToFlavor.remove(nat);
|
||||
getNativeToFlavor().remove(nat);
|
||||
for (int i = 0; i < flavors.length; i++) {
|
||||
addFlavorForUnencodedNative(nat, flavors[i]);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 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
|
||||
@ -110,7 +110,11 @@ public class DropTarget implements DropTargetListener, Serializable {
|
||||
setActive(act);
|
||||
}
|
||||
|
||||
if (fm != null) flavorMap = fm;
|
||||
if (fm != null) {
|
||||
flavorMap = fm;
|
||||
} else {
|
||||
flavorMap = SystemFlavorMap.getDefaultFlavorMap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -850,5 +854,5 @@ public class DropTarget implements DropTargetListener, Serializable {
|
||||
* The FlavorMap
|
||||
*/
|
||||
|
||||
private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
|
||||
private transient FlavorMap flavorMap;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2007 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
|
||||
@ -74,6 +74,19 @@ import java.awt.Component;
|
||||
* methods for conforming to the underlying platform settings. These
|
||||
* platform settings can be changed at any time by the user. MouseWheelEvents
|
||||
* reflect the most recent settings.
|
||||
* <P>
|
||||
* The <code>MouseWheelEvent</code> class includes methods for
|
||||
* getting the number of "clicks" by which the mouse wheel is rotated.
|
||||
* The {@link #getWheelRotation} method returns the integer number
|
||||
* of "clicks" corresponding to the number of notches by which the wheel was
|
||||
* rotated. In addition to this method, the <code>MouseWheelEvent</code>
|
||||
* class provides the {@link #getPreciseWheelRotation} method which returns
|
||||
* a double number of "clicks" in case a partial rotation occurred.
|
||||
* The {@link #getPreciseWheelRotation} method is useful if a mouse supports
|
||||
* a high-resolution wheel, such as a freely rotating wheel with no
|
||||
* notches. Applications can benefit by using this method to process
|
||||
* mouse wheel events more precisely, and thus, making visual perception
|
||||
* smoother.
|
||||
*
|
||||
* @author Brent Christian
|
||||
* @see MouseWheelListener
|
||||
@ -131,6 +144,13 @@ public class MouseWheelEvent extends MouseEvent {
|
||||
*/
|
||||
int wheelRotation;
|
||||
|
||||
/**
|
||||
* Indicates how far the mouse wheel was rotated.
|
||||
*
|
||||
* @see #getPreciseWheelRotation
|
||||
*/
|
||||
double preciseWheelRotation;
|
||||
|
||||
/*
|
||||
* serialVersionUID
|
||||
*/
|
||||
@ -165,8 +185,8 @@ public class MouseWheelEvent extends MouseEvent {
|
||||
* <code>WHEEL_BLOCK_SCROLL</code>
|
||||
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
|
||||
* the number of units to be scrolled
|
||||
* @param wheelRotation the amount that the mouse wheel was rotated (the
|
||||
* number of "clicks")
|
||||
* @param wheelRotation the integer number of "clicks" by which the mouse
|
||||
* wheel was rotated
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>source</code> is null
|
||||
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
|
||||
@ -211,8 +231,8 @@ public class MouseWheelEvent extends MouseEvent {
|
||||
* <code>WHEEL_BLOCK_SCROLL</code>
|
||||
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
|
||||
* the number of units to be scrolled
|
||||
* @param wheelRotation the amount that the mouse wheel was rotated (the
|
||||
* number of "clicks")
|
||||
* @param wheelRotation the integer number of "clicks" by which the mouse
|
||||
* wheel was rotated
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>source</code> is null
|
||||
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
|
||||
@ -223,12 +243,68 @@ public class MouseWheelEvent extends MouseEvent {
|
||||
int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
|
||||
int scrollType, int scrollAmount, int wheelRotation) {
|
||||
|
||||
this(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger,
|
||||
scrollType, scrollAmount, wheelRotation, wheelRotation);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a <code>MouseWheelEvent</code> object with the specified
|
||||
* source component, type, modifiers, coordinates, absolute coordinates,
|
||||
* scroll type, scroll amount, and wheel rotation.
|
||||
* <p>Note that passing in an invalid <code>id</code> parameter results
|
||||
* in unspecified behavior. This method throws an
|
||||
* <code>IllegalArgumentException</code> if <code>source</code> equals
|
||||
* <code>null</code>.
|
||||
* <p>Even if inconsistent values for relative and absolute coordinates
|
||||
* are passed to the constructor, a <code>MouseWheelEvent</code> instance
|
||||
* is still created and no exception is thrown.
|
||||
*
|
||||
* @param source the <code>Component</code> that originated the event
|
||||
* @param id the integer value that identifies the event
|
||||
* @param when a long value that gives the time when the event occurred
|
||||
* @param modifiers the modifier keys down during event
|
||||
* (shift, ctrl, alt, meta)
|
||||
* @param x the horizontal <code>x</code> coordinate for the
|
||||
* mouse location
|
||||
* @param y the vertical <code>y</code> coordinate for the
|
||||
* mouse location
|
||||
* @param xAbs the absolute horizontal <code>x</code> coordinate for
|
||||
* the mouse location
|
||||
* @param yAbs the absolute vertical <code>y</code> coordinate for
|
||||
* the mouse location
|
||||
* @param clickCount the number of mouse clicks associated with the event
|
||||
* @param popupTrigger a boolean value, <code>true</code> if this event is a trigger
|
||||
* for a popup-menu
|
||||
* @param scrollType the type of scrolling which should take place in
|
||||
* response to this event; valid values are
|
||||
* <code>WHEEL_UNIT_SCROLL</code> and
|
||||
* <code>WHEEL_BLOCK_SCROLL</code>
|
||||
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
|
||||
* the number of units to be scrolled
|
||||
* @param wheelRotation the integer number of "clicks" by which the mouse wheel
|
||||
* was rotated
|
||||
* @param preciseWheelRotation the double number of "clicks" by which the mouse wheel
|
||||
* was rotated
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>source</code> is null
|
||||
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
|
||||
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int)
|
||||
* @since 1.7
|
||||
*/
|
||||
public MouseWheelEvent (Component source, int id, long when, int modifiers,
|
||||
int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
|
||||
int scrollType, int scrollAmount, int wheelRotation, double preciseWheelRotation) {
|
||||
|
||||
super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount,
|
||||
popupTrigger, MouseEvent.NOBUTTON);
|
||||
|
||||
this.scrollType = scrollType;
|
||||
this.scrollAmount = scrollAmount;
|
||||
this.wheelRotation = wheelRotation;
|
||||
this.preciseWheelRotation = preciseWheelRotation;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -267,16 +343,34 @@ public class MouseWheelEvent extends MouseEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of "clicks" the mouse wheel was rotated.
|
||||
* Returns the number of "clicks" the mouse wheel was rotated, as an integer.
|
||||
* A partial rotation may occur if the mouse supports a high-resolution wheel.
|
||||
* In this case, the method returns zero until a full "click" has been accumulated.
|
||||
*
|
||||
* @return negative values if the mouse wheel was rotated up/away from
|
||||
* the user, and positive values if the mouse wheel was rotated down/
|
||||
* towards the user
|
||||
* @see #getPreciseWheelRotation
|
||||
*/
|
||||
public int getWheelRotation() {
|
||||
return wheelRotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of "clicks" the mouse wheel was rotated, as a double.
|
||||
* A partial rotation may occur if the mouse supports a high-resolution wheel.
|
||||
* In this case, the return value will include a fractional "click".
|
||||
*
|
||||
* @return negative values if the mouse wheel was rotated up or away from
|
||||
* the user, and positive values if the mouse wheel was rotated down or
|
||||
* towards the user
|
||||
* @see #getWheelRotation
|
||||
* @since 1.7
|
||||
*/
|
||||
public double getPreciseWheelRotation() {
|
||||
return preciseWheelRotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a convenience method to aid in the implementation of
|
||||
* the common-case MouseWheelListener - to scroll a ScrollPane or
|
||||
@ -348,6 +442,6 @@ public class MouseWheelEvent extends MouseEvent {
|
||||
}
|
||||
return super.paramString()+",scrollType="+scrollTypeStr+
|
||||
",scrollAmount="+getScrollAmount()+",wheelRotation="+
|
||||
getWheelRotation();
|
||||
getWheelRotation()+",preciseWheelRotation="+getPreciseWheelRotation();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 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
|
||||
@ -40,6 +40,8 @@ import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
@ -126,6 +128,7 @@ import java.beans.PropertyChangeListener;
|
||||
* @author Fred Ecks
|
||||
*/
|
||||
public final class AppContext {
|
||||
private static final Logger log = Logger.getLogger("sun.awt.AppContext");
|
||||
|
||||
/* Since the contents of an AppContext are unique to each Java
|
||||
* session, this class should never be serialized. */
|
||||
@ -143,13 +146,15 @@ public final class AppContext {
|
||||
* Returns a set containing all <code>AppContext</code>s.
|
||||
*/
|
||||
public static Set<AppContext> getAppContexts() {
|
||||
return new HashSet<AppContext>(threadGroup2appContext.values());
|
||||
synchronized (threadGroup2appContext) {
|
||||
return new HashSet<AppContext>(threadGroup2appContext.values());
|
||||
}
|
||||
}
|
||||
|
||||
/* The main "system" AppContext, used by everything not otherwise
|
||||
contained in another AppContext.
|
||||
*/
|
||||
private static AppContext mainAppContext = null;
|
||||
private static volatile AppContext mainAppContext = null;
|
||||
|
||||
/*
|
||||
* The hash map associated with this AppContext. A private delegate
|
||||
@ -174,31 +179,30 @@ public final class AppContext {
|
||||
public static final String DISPOSED_PROPERTY_NAME = "disposed";
|
||||
public static final String GUI_DISPOSED = "guidisposed";
|
||||
|
||||
private boolean isDisposed = false; // true if AppContext is disposed
|
||||
private volatile boolean isDisposed = false; // true if AppContext is disposed
|
||||
|
||||
public boolean isDisposed() {
|
||||
return isDisposed;
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
// On the main Thread, we get the ThreadGroup, make a corresponding
|
||||
// AppContext, and instantiate the Java EventQueue. This way, legacy
|
||||
// code is unaffected by the move to multiple AppContext ability.
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
ThreadGroup currentThreadGroup =
|
||||
Thread.currentThread().getThreadGroup();
|
||||
ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
|
||||
while (parentThreadGroup != null) {
|
||||
// Find the root ThreadGroup to construct our main AppContext
|
||||
currentThreadGroup = parentThreadGroup;
|
||||
parentThreadGroup = currentThreadGroup.getParent();
|
||||
public Object run() {
|
||||
ThreadGroup currentThreadGroup =
|
||||
Thread.currentThread().getThreadGroup();
|
||||
ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
|
||||
while (parentThreadGroup != null) {
|
||||
// Find the root ThreadGroup to construct our main AppContext
|
||||
currentThreadGroup = parentThreadGroup;
|
||||
parentThreadGroup = currentThreadGroup.getParent();
|
||||
}
|
||||
mainAppContext = new AppContext(currentThreadGroup);
|
||||
numAppContexts = 1;
|
||||
return mainAppContext;
|
||||
}
|
||||
mainAppContext = new AppContext(currentThreadGroup);
|
||||
numAppContexts = 1;
|
||||
return mainAppContext;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -209,7 +213,7 @@ public final class AppContext {
|
||||
* number is 1. If so, it returns the sole AppContext without
|
||||
* checking Thread.currentThread().
|
||||
*/
|
||||
private static int numAppContexts;
|
||||
private static volatile int numAppContexts;
|
||||
|
||||
/*
|
||||
* The context ClassLoader that was used to create this AppContext.
|
||||
@ -236,14 +240,15 @@ public final class AppContext {
|
||||
threadGroup2appContext.put(threadGroup, this);
|
||||
|
||||
this.contextClassLoader =
|
||||
(ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
public ClassLoader run() {
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static MostRecentThreadAppContext mostRecentThreadAppContext = null;
|
||||
private static final ThreadLocal<AppContext> threadAppContext =
|
||||
new ThreadLocal<AppContext>();
|
||||
|
||||
/**
|
||||
* Returns the appropriate AppContext for the caller,
|
||||
@ -260,59 +265,46 @@ public final class AppContext {
|
||||
if (numAppContexts == 1) // If there's only one system-wide,
|
||||
return mainAppContext; // return the main system AppContext.
|
||||
|
||||
final Thread currentThread = Thread.currentThread();
|
||||
AppContext appContext = threadAppContext.get();
|
||||
|
||||
AppContext appContext = null;
|
||||
if (null == appContext) {
|
||||
appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
|
||||
{
|
||||
public AppContext run() {
|
||||
// Get the current ThreadGroup, and look for it and its
|
||||
// parents in the hash from ThreadGroup to AppContext --
|
||||
// it should be found, because we use createNewContext()
|
||||
// when new AppContext objects are created.
|
||||
ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
|
||||
ThreadGroup threadGroup = currentThreadGroup;
|
||||
AppContext context = threadGroup2appContext.get(threadGroup);
|
||||
while (context == null) {
|
||||
threadGroup = threadGroup.getParent();
|
||||
if (threadGroup == null) {
|
||||
// If we get here, we're running under a ThreadGroup that
|
||||
// has no AppContext associated with it. This should never
|
||||
// happen, because createNewContext() should be used by the
|
||||
// toolkit to create the ThreadGroup that everything runs
|
||||
// under.
|
||||
throw new RuntimeException("Invalid ThreadGroup");
|
||||
}
|
||||
context = threadGroup2appContext.get(threadGroup);
|
||||
}
|
||||
// In case we did anything in the above while loop, we add
|
||||
// all the intermediate ThreadGroups to threadGroup2appContext
|
||||
// so we won't spin again.
|
||||
for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
|
||||
threadGroup2appContext.put(tg, context);
|
||||
}
|
||||
// Now we're done, so we cache the latest key/value pair.
|
||||
// (we do this before checking with any AWTSecurityManager, so if
|
||||
// this Thread equates with the main AppContext in the cache, it
|
||||
// still will)
|
||||
threadAppContext.set(context);
|
||||
|
||||
// Note: this most recent Thread/AppContext caching is thread-hot.
|
||||
// A simple test using SwingSet found that 96.8% of lookups
|
||||
// were matched using the most recent Thread/AppContext. By
|
||||
// instantiating a simple MostRecentThreadAppContext object on
|
||||
// cache misses, the cache hits can be processed without
|
||||
// synchronization.
|
||||
|
||||
MostRecentThreadAppContext recent = mostRecentThreadAppContext;
|
||||
if ((recent != null) && (recent.thread == currentThread)) {
|
||||
appContext = recent.appContext; // Cache hit
|
||||
} else {
|
||||
appContext = (AppContext)AccessController.doPrivileged(
|
||||
new PrivilegedAction() {
|
||||
public Object run() {
|
||||
// Get the current ThreadGroup, and look for it and its
|
||||
// parents in the hash from ThreadGroup to AppContext --
|
||||
// it should be found, because we use createNewContext()
|
||||
// when new AppContext objects are created.
|
||||
ThreadGroup currentThreadGroup = currentThread.getThreadGroup();
|
||||
ThreadGroup threadGroup = currentThreadGroup;
|
||||
AppContext context = threadGroup2appContext.get(threadGroup);
|
||||
while (context == null) {
|
||||
threadGroup = threadGroup.getParent();
|
||||
if (threadGroup == null) {
|
||||
// If we get here, we're running under a ThreadGroup that
|
||||
// has no AppContext associated with it. This should never
|
||||
// happen, because createNewContext() should be used by the
|
||||
// toolkit to create the ThreadGroup that everything runs
|
||||
// under.
|
||||
throw new RuntimeException("Invalid ThreadGroup");
|
||||
return context;
|
||||
}
|
||||
context = threadGroup2appContext.get(threadGroup);
|
||||
}
|
||||
// In case we did anything in the above while loop, we add
|
||||
// all the intermediate ThreadGroups to threadGroup2appContext
|
||||
// so we won't spin again.
|
||||
for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
|
||||
threadGroup2appContext.put(tg, context);
|
||||
}
|
||||
// Now we're done, so we cache the latest key/value pair.
|
||||
// (we do this before checking with any AWTSecurityManager, so if
|
||||
// this Thread equates with the main AppContext in the cache, it
|
||||
// still will)
|
||||
mostRecentThreadAppContext =
|
||||
new MostRecentThreadAppContext(currentThread, context);
|
||||
|
||||
return context;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (appContext == mainAppContext) {
|
||||
@ -321,9 +313,9 @@ public final class AppContext {
|
||||
// allow it to choose the AppContext to return.
|
||||
SecurityManager securityManager = System.getSecurityManager();
|
||||
if ((securityManager != null) &&
|
||||
(securityManager instanceof AWTSecurityManager)) {
|
||||
AWTSecurityManager awtSecMgr =
|
||||
(AWTSecurityManager)securityManager;
|
||||
(securityManager instanceof AWTSecurityManager))
|
||||
{
|
||||
AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager;
|
||||
AppContext secAppContext = awtSecMgr.getAppContext();
|
||||
if (secAppContext != null) {
|
||||
appContext = secAppContext; // Return what we're told
|
||||
@ -385,7 +377,13 @@ public final class AppContext {
|
||||
public void run() {
|
||||
Window[] windowsToDispose = Window.getOwnerlessWindows();
|
||||
for (Window w : windowsToDispose) {
|
||||
w.dispose();
|
||||
try {
|
||||
w.dispose();
|
||||
} catch (Throwable t) {
|
||||
if (log.isLoggable(Level.FINER)) {
|
||||
log.log(Level.FINER, "exception occured while disposing app context", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
@ -444,7 +442,7 @@ public final class AppContext {
|
||||
// Threads in the ThreadGroup to exit.
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
long endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
|
||||
long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
|
||||
while ((this.threadGroup.activeCount() > 0) &&
|
||||
(System.currentTimeMillis() < endTime)) {
|
||||
try {
|
||||
@ -459,7 +457,7 @@ public final class AppContext {
|
||||
// Threads in the ThreadGroup to die.
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
|
||||
endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
|
||||
while ((this.threadGroup.activeCount() > 0) &&
|
||||
(System.currentTimeMillis() < endTime)) {
|
||||
try {
|
||||
@ -478,10 +476,7 @@ public final class AppContext {
|
||||
}
|
||||
threadGroup2appContext.remove(this.threadGroup);
|
||||
|
||||
MostRecentThreadAppContext recent = mostRecentThreadAppContext;
|
||||
if ((recent != null) && (recent.appContext == this))
|
||||
mostRecentThreadAppContext = null;
|
||||
// If the "most recent" points to this, clear it for GC
|
||||
threadAppContext.set(null);
|
||||
|
||||
// Finally, we destroy the ThreadGroup entirely.
|
||||
try {
|
||||
@ -664,6 +659,7 @@ public final class AppContext {
|
||||
* Returns a string representation of this AppContext.
|
||||
* @since 1.2
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]";
|
||||
}
|
||||
@ -769,15 +765,6 @@ public final class AppContext {
|
||||
}
|
||||
}
|
||||
|
||||
final class MostRecentThreadAppContext {
|
||||
final Thread thread;
|
||||
final AppContext appContext;
|
||||
MostRecentThreadAppContext(Thread key, AppContext value) {
|
||||
thread = key;
|
||||
appContext = value;
|
||||
}
|
||||
}
|
||||
|
||||
final class MostRecentKeyValue {
|
||||
Object key;
|
||||
Object value;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 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
|
||||
@ -270,62 +270,58 @@ public abstract class DataTransferer {
|
||||
* instead, null will be returned.
|
||||
*/
|
||||
public static DataTransferer getInstance() {
|
||||
if (transferer == null) {
|
||||
synchronized (DataTransferer.class) {
|
||||
if (transferer == null) {
|
||||
final String name = SunToolkit.
|
||||
getDataTransfererClassName();
|
||||
if (name != null) {
|
||||
PrivilegedAction action = new PrivilegedAction() {
|
||||
public Object run() {
|
||||
Class cls = null;
|
||||
Method method = null;
|
||||
Object ret = null;
|
||||
synchronized (DataTransferer.class) {
|
||||
if (transferer == null) {
|
||||
final String name = SunToolkit.getDataTransfererClassName();
|
||||
if (name != null) {
|
||||
PrivilegedAction<DataTransferer> action = new PrivilegedAction<DataTransferer>()
|
||||
{
|
||||
public DataTransferer run() {
|
||||
Class cls = null;
|
||||
Method method = null;
|
||||
DataTransferer ret = null;
|
||||
|
||||
try {
|
||||
cls = Class.forName(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
ClassLoader cl = ClassLoader.
|
||||
getSystemClassLoader();
|
||||
if (cl != null) {
|
||||
try {
|
||||
cls = cl.loadClass(name);
|
||||
} catch (ClassNotFoundException ee) {
|
||||
ee.printStackTrace();
|
||||
throw new AWTError("DataTransferer not found: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cls != null) {
|
||||
try {
|
||||
cls = Class.forName(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
ClassLoader cl = ClassLoader.
|
||||
getSystemClassLoader();
|
||||
if (cl != null) {
|
||||
try {
|
||||
method = cls.getDeclaredMethod
|
||||
("getInstanceImpl");
|
||||
method.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
throw new AWTError("Cannot instantiate DataTransferer: " + name);
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
throw new AWTError("Access is denied for DataTransferer: " + name);
|
||||
cls = cl.loadClass(name);
|
||||
} catch (ClassNotFoundException ee) {
|
||||
ee.printStackTrace();
|
||||
throw new AWTError("DataTransferer not found: " + name);
|
||||
}
|
||||
}
|
||||
if (method != null) {
|
||||
try {
|
||||
ret = method.invoke(null);
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
throw new AWTError("Cannot instantiate DataTransferer: " + name);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
throw new AWTError("Cannot access DataTransferer: " + name);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
transferer = (DataTransferer)
|
||||
AccessController.doPrivileged(action);
|
||||
}
|
||||
if (cls != null) {
|
||||
try {
|
||||
method = cls.getDeclaredMethod("getInstanceImpl");
|
||||
method.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
throw new AWTError("Cannot instantiate DataTransferer: " + name);
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
throw new AWTError("Access is denied for DataTransferer: " + name);
|
||||
}
|
||||
}
|
||||
if (method != null) {
|
||||
try {
|
||||
ret = (DataTransferer) method.invoke(null);
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
throw new AWTError("Cannot instantiate DataTransferer: " + name);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
throw new AWTError("Cannot access DataTransferer: " + name);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
transferer = AccessController.doPrivileged(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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,6 +39,8 @@ import sun.misc.Unsafe;
|
||||
* @since 1.5
|
||||
*/
|
||||
class MotifDnDConstants {
|
||||
// utility class can not be instantiated
|
||||
private MotifDnDConstants() {}
|
||||
// Note that offsets in all native structures below do not depend on the
|
||||
// architecture.
|
||||
private static final Unsafe unsafe = XlibWrapper.unsafe;
|
||||
@ -55,8 +57,7 @@ class MotifDnDConstants {
|
||||
XAtom.get("XmTRANSFER_SUCCESS");
|
||||
static final XAtom XA_XmTRANSFER_FAILURE =
|
||||
XAtom.get("XmTRANSFER_FAILURE");
|
||||
static final XSelection MotifDnDSelection =
|
||||
new XSelection(XA_MOTIF_ATOM_0, null);
|
||||
static final XSelection MotifDnDSelection = new XSelection(XA_MOTIF_ATOM_0);
|
||||
|
||||
public static final byte MOTIF_DND_PROTOCOL_VERSION = 0;
|
||||
|
||||
@ -231,6 +232,9 @@ class MotifDnDConstants {
|
||||
}
|
||||
|
||||
public static final class Swapper {
|
||||
// utility class can not be instantiated
|
||||
private Swapper() {}
|
||||
|
||||
public static short swap(short s) {
|
||||
return (short)(((s & 0xFF00) >>> 8) | ((s & 0xFF) << 8));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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
|
||||
@ -933,7 +933,7 @@ class MotifDnDDropTargetProtocol extends XDropTargetProtocol {
|
||||
|
||||
XSelection selection = XSelection.getSelection(selectionAtom);
|
||||
if (selection == null) {
|
||||
selection = new XSelection(selectionAtom, null);
|
||||
selection = new XSelection(selectionAtom);
|
||||
}
|
||||
|
||||
return selection.getData(format, time_stamp);
|
||||
@ -1056,7 +1056,7 @@ class MotifDnDDropTargetProtocol extends XDropTargetProtocol {
|
||||
// the original structure can be freed before this
|
||||
// SunDropTargetEvent is dispatched.
|
||||
if (xclient != null) {
|
||||
int size = new XClientMessageEvent(nativeCtxt).getSize();
|
||||
int size = XClientMessageEvent.getSize();
|
||||
|
||||
nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
|
||||
|
||||
|
30
jdk/src/solaris/classes/sun/awt/X11/OwnershipListener.java
Normal file
30
jdk/src/solaris/classes/sun/awt/X11/OwnershipListener.java
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package sun.awt.X11;
|
||||
|
||||
interface OwnershipListener {
|
||||
public void ownershipChanged(final boolean isOwner);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2008 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
|
||||
@ -58,7 +58,7 @@ package sun.awt.X11;
|
||||
import sun.misc.Unsafe;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class XAtom {
|
||||
public final class XAtom {
|
||||
|
||||
// Order of lock: XAWTLock -> XAtom.class
|
||||
|
||||
@ -175,7 +175,7 @@ public class XAtom {
|
||||
public static XAtom get(String name) {
|
||||
XAtom xatom = lookup(name);
|
||||
if (xatom == null) {
|
||||
xatom = new XAtom(name);
|
||||
xatom = new XAtom(XToolkit.getDisplay(), name);
|
||||
}
|
||||
return xatom;
|
||||
}
|
||||
@ -232,10 +232,6 @@ public class XAtom {
|
||||
this(display, name, true);
|
||||
}
|
||||
|
||||
private XAtom(String name) {
|
||||
this(XToolkit.getDisplay(), name, true);
|
||||
}
|
||||
|
||||
public XAtom(String name, boolean autoIntern) {
|
||||
this(XToolkit.getDisplay(), name, autoIntern);
|
||||
}
|
||||
@ -262,7 +258,7 @@ public class XAtom {
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
public XAtom(long display, String name, boolean autoIntern) {
|
||||
private XAtom(long display, String name, boolean autoIntern) {
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
if (autoIntern) {
|
||||
@ -651,28 +647,6 @@ public class XAtom {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes atom with name and display values
|
||||
*/
|
||||
public void setValues(long display, String name, boolean autoIntern) {
|
||||
this.display = display;
|
||||
this.name = name;
|
||||
if (autoIntern) {
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
atom = XlibWrapper.InternAtom(display,name,0);
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
register();
|
||||
}
|
||||
|
||||
public void setValues(long display, long atom) {
|
||||
this.display = display;
|
||||
this.atom = atom;
|
||||
register();
|
||||
}
|
||||
public void setValues(long display, String name, long atom) {
|
||||
this.display = display;
|
||||
this.atom = atom;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,30 +26,32 @@
|
||||
package sun.awt.X11;
|
||||
|
||||
import java.awt.datatransfer.Transferable;
|
||||
|
||||
import java.util.SortedMap;
|
||||
import java.util.Set;
|
||||
import java.util.Iterator;
|
||||
import java.util.HashSet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.security.AccessController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import sun.awt.UNIXToolkit;
|
||||
import sun.awt.datatransfer.DataTransferer;
|
||||
import sun.awt.datatransfer.SunClipboard;
|
||||
import sun.awt.datatransfer.ClipboardTransferable;
|
||||
|
||||
import sun.security.action.GetIntegerAction;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A class which interfaces with the X11 selection service in order to support
|
||||
* data transfer via Clipboard operations.
|
||||
*/
|
||||
public class XClipboard extends SunClipboard implements Runnable {
|
||||
public final class XClipboard extends SunClipboard implements OwnershipListener
|
||||
{
|
||||
private final XSelection selection;
|
||||
// Time of calling XConvertSelection().
|
||||
private long convertSelectionTime;
|
||||
// The flag used not to call XConvertSelection() if the previous SelectionNotify
|
||||
// has not been processed by checkChange().
|
||||
private volatile boolean isSelectionNotifyProcessed;
|
||||
// The property in which the owner should place requested targets
|
||||
// when tracking changes of available data flavors (practically targets).
|
||||
private volatile XAtom targetsPropertyAtom;
|
||||
|
||||
private static final Object classLock = new Object();
|
||||
|
||||
@ -57,31 +59,33 @@ public class XClipboard extends SunClipboard implements Runnable {
|
||||
|
||||
private static int pollInterval;
|
||||
|
||||
private static Set listenedClipboards;
|
||||
|
||||
private static Map<Long, XClipboard> targetsAtom2Clipboard;
|
||||
|
||||
/**
|
||||
* Creates a system clipboard object.
|
||||
*/
|
||||
public XClipboard(String name, String selectionName) {
|
||||
super(name);
|
||||
selection = new XSelection(XAtom.get(selectionName), this);
|
||||
selection = new XSelection(XAtom.get(selectionName));
|
||||
selection.registerOwershipListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* The action to be run when we lose ownership
|
||||
/*
|
||||
* NOTE: This method may be called by privileged threads.
|
||||
* DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||
*/
|
||||
public void run() {
|
||||
lostOwnershipImpl();
|
||||
public void ownershipChanged(final boolean isOwner) {
|
||||
if (isOwner) {
|
||||
checkChangeHere(contents);
|
||||
} else {
|
||||
lostOwnershipImpl();
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized void setContentsNative(Transferable contents) {
|
||||
SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable
|
||||
(contents, DataTransferer.adaptFlavorMap(flavorMap));
|
||||
long[] formats =
|
||||
DataTransferer.getInstance().keysToLongArray(formatMap);
|
||||
long[] formats = DataTransferer.keysToLongArray(formatMap);
|
||||
|
||||
if (!selection.setOwner(contents, formatMap, formats,
|
||||
XToolkit.getCurrentServerTime())) {
|
||||
@ -94,6 +98,7 @@ public class XClipboard extends SunClipboard implements Runnable {
|
||||
return selection.getSelectionAtom().getAtom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Transferable getContents(Object requestor) {
|
||||
if (contents != null) {
|
||||
return contents;
|
||||
@ -115,62 +120,163 @@ public class XClipboard extends SunClipboard implements Runnable {
|
||||
return selection.getData(format, XToolkit.getCurrentServerTime());
|
||||
}
|
||||
|
||||
// Called on the toolkit thread under awtLock.
|
||||
public void checkChange(long[] formats) {
|
||||
if (!selection.isOwner()) {
|
||||
super.checkChange(formats);
|
||||
}
|
||||
}
|
||||
|
||||
void checkChangeHere(Transferable contents) {
|
||||
private void checkChangeHere(Transferable contents) {
|
||||
if (areFlavorListenersRegistered()) {
|
||||
super.checkChange(DataTransferer.getInstance().
|
||||
checkChange(DataTransferer.getInstance().
|
||||
getFormatsForTransferableAsArray(contents, flavorMap));
|
||||
}
|
||||
}
|
||||
|
||||
protected void registerClipboardViewerChecked() {
|
||||
if (pollInterval <= 0) {
|
||||
pollInterval = ((Integer)AccessController.doPrivileged(
|
||||
new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
|
||||
defaultPollInterval))).intValue();
|
||||
private static int getPollInterval() {
|
||||
synchronized (XClipboard.classLock) {
|
||||
if (pollInterval <= 0) {
|
||||
pollInterval = defaultPollInterval;
|
||||
pollInterval = AccessController.doPrivileged(
|
||||
new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
|
||||
defaultPollInterval));
|
||||
if (pollInterval <= 0) {
|
||||
pollInterval = defaultPollInterval;
|
||||
}
|
||||
}
|
||||
return pollInterval;
|
||||
}
|
||||
selection.initializeSelectionForTrackingChanges();
|
||||
}
|
||||
|
||||
private XAtom getTargetsPropertyAtom() {
|
||||
if (null == targetsPropertyAtom) {
|
||||
targetsPropertyAtom =
|
||||
XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selection.getSelectionAtom().getName());
|
||||
}
|
||||
return targetsPropertyAtom;
|
||||
}
|
||||
|
||||
protected void registerClipboardViewerChecked() {
|
||||
// for XConvertSelection() to be called for the first time in getTargetsDelayed()
|
||||
isSelectionNotifyProcessed = true;
|
||||
|
||||
boolean mustSchedule = false;
|
||||
synchronized (XClipboard.classLock) {
|
||||
if (listenedClipboards == null) {
|
||||
listenedClipboards = new HashSet(2);
|
||||
if (targetsAtom2Clipboard == null) {
|
||||
targetsAtom2Clipboard = new HashMap<Long, XClipboard>(2);
|
||||
}
|
||||
mustSchedule = targetsAtom2Clipboard.isEmpty();
|
||||
targetsAtom2Clipboard.put(getTargetsPropertyAtom().getAtom(), this);
|
||||
if (mustSchedule) {
|
||||
XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
|
||||
new SelectionNotifyHandler());
|
||||
}
|
||||
mustSchedule = listenedClipboards.isEmpty();
|
||||
listenedClipboards.add(this);
|
||||
}
|
||||
if (mustSchedule) {
|
||||
XToolkit.schedule(new CheckChangeTimerTask(), pollInterval);
|
||||
XToolkit.schedule(new CheckChangeTimerTask(), XClipboard.getPollInterval());
|
||||
}
|
||||
}
|
||||
|
||||
private static class CheckChangeTimerTask implements Runnable {
|
||||
public void run() {
|
||||
for (Iterator iter = listenedClipboards.iterator(); iter.hasNext();) {
|
||||
XClipboard clpbrd = (XClipboard)iter.next();
|
||||
clpbrd.selection.getTargetsDelayed();
|
||||
for (XClipboard clpbrd : targetsAtom2Clipboard.values()) {
|
||||
clpbrd.getTargetsDelayed();
|
||||
}
|
||||
synchronized (XClipboard.classLock) {
|
||||
if (listenedClipboards != null && !listenedClipboards.isEmpty()) {
|
||||
XToolkit.schedule(this, pollInterval);
|
||||
if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
|
||||
XToolkit.schedule(this, XClipboard.getPollInterval());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class SelectionNotifyHandler implements XEventDispatcher {
|
||||
public void dispatchEvent(XEvent ev) {
|
||||
if (ev.get_type() == XlibWrapper.SelectionNotify) {
|
||||
final XSelectionEvent xse = ev.get_xselection();
|
||||
XClipboard clipboard = null;
|
||||
synchronized (XClipboard.classLock) {
|
||||
if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
|
||||
XToolkit.removeEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), this);
|
||||
return;
|
||||
}
|
||||
final long propertyAtom = xse.get_property();
|
||||
clipboard = targetsAtom2Clipboard.get(propertyAtom);
|
||||
}
|
||||
if (null != clipboard) {
|
||||
clipboard.checkChange(xse);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void unregisterClipboardViewerChecked() {
|
||||
selection.deinitializeSelectionForTrackingChanges();
|
||||
isSelectionNotifyProcessed = false;
|
||||
synchronized (XClipboard.classLock) {
|
||||
listenedClipboards.remove(this);
|
||||
targetsAtom2Clipboard.remove(getTargetsPropertyAtom().getAtom());
|
||||
}
|
||||
}
|
||||
|
||||
// checkChange() will be called on SelectionNotify
|
||||
private void getTargetsDelayed() {
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
long curTime = System.currentTimeMillis();
|
||||
if (isSelectionNotifyProcessed || curTime >= (convertSelectionTime + UNIXToolkit.getDatatransferTimeout()))
|
||||
{
|
||||
convertSelectionTime = curTime;
|
||||
XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
|
||||
selection.getSelectionAtom().getAtom(),
|
||||
XDataTransferer.TARGETS_ATOM.getAtom(),
|
||||
getTargetsPropertyAtom().getAtom(),
|
||||
XWindow.getXAWTRootWindow().getWindow(),
|
||||
XlibWrapper.CurrentTime);
|
||||
isSelectionNotifyProcessed = false;
|
||||
}
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Tracks changes of available formats.
|
||||
* NOTE: This method may be called by privileged threads.
|
||||
* DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||
*/
|
||||
private void checkChange(XSelectionEvent xse) {
|
||||
final long propertyAtom = xse.get_property();
|
||||
if (propertyAtom != getTargetsPropertyAtom().getAtom()) {
|
||||
// wrong atom
|
||||
return;
|
||||
}
|
||||
|
||||
final XAtom selectionAtom = XAtom.get(xse.get_selection());
|
||||
final XSelection changedSelection = XSelection.getSelection(selectionAtom);
|
||||
|
||||
if (null == changedSelection || changedSelection != selection) {
|
||||
// unknown selection - do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
isSelectionNotifyProcessed = true;
|
||||
|
||||
if (selection.isOwner()) {
|
||||
// selection is owner - do not need formats
|
||||
return;
|
||||
}
|
||||
|
||||
long[] formats = null;
|
||||
|
||||
if (propertyAtom == XlibWrapper.None) {
|
||||
// We treat None property atom as "empty selection".
|
||||
formats = new long[0];
|
||||
} else {
|
||||
WindowPropertyGetter targetsGetter =
|
||||
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
||||
XAtom.get(propertyAtom), 0,
|
||||
XSelection.MAX_LENGTH, true,
|
||||
XlibWrapper.AnyPropertyType);
|
||||
try {
|
||||
targetsGetter.execute();
|
||||
formats = XSelection.getFormats(targetsGetter);
|
||||
} finally {
|
||||
targetsGetter.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
checkChange(formats);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,17 +31,13 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.DefaultKeyboardFocusManager;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Event;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.MenuBar;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.SystemColor;
|
||||
import java.awt.Toolkit;
|
||||
@ -60,12 +56,9 @@ import java.awt.event.InvocationEvent;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.awt.peer.CanvasPeer;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
import java.awt.peer.ContainerPeer;
|
||||
import java.awt.peer.LightweightPeer;
|
||||
import java.awt.peer.PanelPeer;
|
||||
import java.awt.peer.WindowPeer;
|
||||
import java.lang.reflect.*;
|
||||
import java.security.*;
|
||||
import java.util.Collection;
|
||||
@ -821,7 +814,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
|
||||
public void setFont(Font f) {
|
||||
synchronized (getStateLock()) {
|
||||
if (f == null) {
|
||||
f = defaultFont;
|
||||
f = XWindow.getDefaultFont();
|
||||
}
|
||||
font = f;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 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,16 +39,37 @@ import sun.awt.ComponentAccessor;
|
||||
* This class implements window which serves as content window for decorated frames.
|
||||
* Its purpose to provide correct events dispatching for the complex
|
||||
* constructs such as decorated frames.
|
||||
*
|
||||
* It should always be located at (- left inset, - top inset) in the associated
|
||||
* decorated window. So coordinates in it would be the same as java coordinates.
|
||||
*/
|
||||
public class XContentWindow extends XWindow implements XConstants {
|
||||
public final class XContentWindow extends XWindow implements XConstants {
|
||||
private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow");
|
||||
|
||||
XDecoratedPeer parentFrame;
|
||||
static XContentWindow createContent(XDecoratedPeer parentFrame) {
|
||||
final WindowDimensions dims = parentFrame.getDimensions();
|
||||
Rectangle rec = dims.getBounds();
|
||||
// Fix for - set the location of the content window to the (-left inset, -top inset)
|
||||
Insets ins = dims.getInsets();
|
||||
if (ins != null) {
|
||||
rec.x = -ins.left;
|
||||
rec.y = -ins.top;
|
||||
} else {
|
||||
rec.x = 0;
|
||||
rec.y = 0;
|
||||
}
|
||||
final XContentWindow cw = new XContentWindow(parentFrame, rec);
|
||||
cw.xSetVisible(true);
|
||||
return cw;
|
||||
}
|
||||
|
||||
private final XDecoratedPeer parentFrame;
|
||||
|
||||
// A list of expose events that come when the parentFrame is iconified
|
||||
private java.util.List<SavedExposeEvent> iconifiedExposeEvents = new java.util.ArrayList<SavedExposeEvent>();
|
||||
private final java.util.List<SavedExposeEvent> iconifiedExposeEvents =
|
||||
new java.util.ArrayList<SavedExposeEvent>();
|
||||
|
||||
XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
|
||||
private XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
|
||||
super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds);
|
||||
this.parentFrame = parentFrame;
|
||||
}
|
||||
@ -63,9 +84,6 @@ public class XContentWindow extends XWindow implements XConstants {
|
||||
}
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
xSetVisible(true);
|
||||
}
|
||||
protected String getWMName() {
|
||||
return "Content window";
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ import java.util.logging.Logger;
|
||||
import sun.awt.ComponentAccessor;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
class XDecoratedPeer extends XWindowPeer {
|
||||
abstract class XDecoratedPeer extends XWindowPeer {
|
||||
private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer");
|
||||
private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
|
||||
private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
|
||||
@ -98,8 +98,7 @@ class XDecoratedPeer extends XWindowPeer {
|
||||
// happen after the X window is created.
|
||||
initResizability();
|
||||
updateSizeHints(dimensions);
|
||||
content = createContent(dimensions);
|
||||
content.initialize();
|
||||
content = XContentWindow.createContent(this);
|
||||
if (warningWindow != null) {
|
||||
warningWindow.toFront();
|
||||
}
|
||||
@ -160,20 +159,6 @@ class XDecoratedPeer extends XWindowPeer {
|
||||
}
|
||||
}
|
||||
|
||||
XContentWindow createContent(WindowDimensions dims) {
|
||||
Rectangle rec = dims.getBounds();
|
||||
// Fix for - set the location of the content window to the (-left inset, -top inset)
|
||||
Insets ins = dims.getInsets();
|
||||
if (ins != null) {
|
||||
rec.x = -ins.left;
|
||||
rec.y = -ins.top;
|
||||
} else {
|
||||
rec.x = 0;
|
||||
rec.y = 0;
|
||||
}
|
||||
return new XContentWindow(this, rec);
|
||||
}
|
||||
|
||||
XFocusProxyWindow createFocusProxy() {
|
||||
return new XFocusProxyWindow(this);
|
||||
}
|
||||
@ -286,7 +271,7 @@ class XDecoratedPeer extends XWindowPeer {
|
||||
return;
|
||||
}
|
||||
Component t = (Component)target;
|
||||
if (getDecorations() == winAttr.AWT_DECOR_NONE) {
|
||||
if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
|
||||
setReparented(true);
|
||||
insets_corrected = true;
|
||||
reshape(dimensions, SET_SIZE, false);
|
||||
@ -471,6 +456,15 @@ class XDecoratedPeer extends XWindowPeer {
|
||||
if (insLog.isLoggable(Level.FINE)) {
|
||||
insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
|
||||
}
|
||||
if (userReshape) {
|
||||
// We handle only userReshape == true cases. It means that
|
||||
// if the window manager or any other part of the windowing
|
||||
// system sets inappropriate size for this window, we can
|
||||
// do nothing but accept it.
|
||||
Rectangle reqBounds = newDimensions.getBounds();
|
||||
Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height);
|
||||
newDimensions = new WindowDimensions(newBounds, newDimensions.getInsets(), newDimensions.isClientSizeSet());
|
||||
}
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
if (!isReparented() || !isVisible()) {
|
||||
@ -586,6 +580,49 @@ class XDecoratedPeer extends XWindowPeer {
|
||||
reshape(dims, operation, userReshape);
|
||||
}
|
||||
|
||||
// This method gets overriden in XFramePeer & XDialogPeer.
|
||||
abstract boolean isTargetUndecorated();
|
||||
|
||||
@Override
|
||||
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||
// We don't restrict the setBounds() operation if the code is trusted.
|
||||
if (!hasWarningWindow()) {
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
|
||||
// If it's undecorated or is not currently visible,
|
||||
// apply the same constraints as for the Window.
|
||||
if (!isVisible() || isTargetUndecorated()) {
|
||||
return super.constrainBounds(x, y, width, height);
|
||||
}
|
||||
|
||||
// If it's visible & decorated, constraint the size only
|
||||
int newX = x;
|
||||
int newY = y;
|
||||
int newW = width;
|
||||
int newH = height;
|
||||
|
||||
GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
|
||||
Rectangle sB = gc.getBounds();
|
||||
Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
|
||||
|
||||
Rectangle curBounds = getBounds();
|
||||
|
||||
int maxW = Math.max(sB.width - sIn.left - sIn.right, curBounds.width);
|
||||
int maxH = Math.max(sB.height - sIn.top - sIn.bottom, curBounds.height);
|
||||
|
||||
// First make sure the size is withing the visible part of the screen
|
||||
if (newW > maxW) {
|
||||
newW = maxW;
|
||||
}
|
||||
|
||||
if (newH > maxH) {
|
||||
newH = maxH;
|
||||
}
|
||||
|
||||
return new Rectangle(newX, newY, newW, newH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ComponentPeer#setBounds
|
||||
*/
|
||||
@ -651,12 +688,12 @@ class XDecoratedPeer extends XWindowPeer {
|
||||
}
|
||||
if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
|
||||
&& !XWM.isNonReparentingWM()
|
||||
&& getDecorations() != winAttr.AWT_DECOR_NONE) {
|
||||
&& getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
|
||||
insLog.fine("- visible but not reparented, skipping");
|
||||
return;
|
||||
}
|
||||
//Last chance to correct insets
|
||||
if (!insets_corrected && getDecorations() != winAttr.AWT_DECOR_NONE) {
|
||||
if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
|
||||
long parent = XlibUtil.getParentWindow(window);
|
||||
Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
|
||||
if (insLog.isLoggable(Level.FINER)) {
|
||||
@ -824,7 +861,7 @@ class XDecoratedPeer extends XWindowPeer {
|
||||
fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE);
|
||||
}
|
||||
winAttr.functions = fs;
|
||||
XWM.setShellNotResizable(this, dimensions, dimensions.getScreenBounds(), false);
|
||||
XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,7 +907,7 @@ class XDecoratedPeer extends XWindowPeer {
|
||||
return getSize().height;
|
||||
}
|
||||
|
||||
public WindowDimensions getDimensions() {
|
||||
final public WindowDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,8 @@ class XDialogPeer extends XDecoratedPeer implements DialogPeer {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTargetUndecorated() {
|
||||
@Override
|
||||
boolean isTargetUndecorated() {
|
||||
if (undecorated != null) {
|
||||
return undecorated.booleanValue();
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -48,8 +48,7 @@ class XDnDConstants {
|
||||
static final XAtom XA_XdndStatus = XAtom.get("XdndStatus");
|
||||
static final XAtom XA_XdndFinished = XAtom.get("XdndFinished");
|
||||
|
||||
static final XSelection XDnDSelection =
|
||||
new XSelection(XA_XdndSelection, null);
|
||||
static final XSelection XDnDSelection = new XSelection(XA_XdndSelection);
|
||||
|
||||
public static final int XDND_MIN_PROTOCOL_VERSION = 3;
|
||||
public static final int XDND_PROTOCOL_VERSION = 5;
|
||||
|
@ -647,12 +647,6 @@ public class XEmbedCanvasPeer extends XCanvasPeer implements WindowFocusListener
|
||||
}
|
||||
if (isXEmbedActive()) {
|
||||
switch ((int)msg.get_data(1)) {
|
||||
case _SUN_XEMBED_START:
|
||||
// Child has finished initialization and waits for notify
|
||||
xembed.processXEmbedInfo();
|
||||
|
||||
notifyChildEmbedded();
|
||||
break;
|
||||
case XEMBED_REQUEST_FOCUS:
|
||||
requestXEmbedFocus();
|
||||
break;
|
||||
|
@ -74,7 +74,6 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
notifyReady();
|
||||
}
|
||||
|
||||
void handleClientMessage(XEvent xev) {
|
||||
@ -84,7 +83,6 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
|
||||
if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Embedded message: " + msgidToString((int)msg.get_data(1)));
|
||||
switch ((int)msg.get_data(1)) {
|
||||
case XEMBED_EMBEDDED_NOTIFY: // Notification about embedding protocol start
|
||||
// NOTE: May be called two times because we send _SUN_XEMBED_START
|
||||
active = true;
|
||||
server = getEmbedder(embedded, msg);
|
||||
// Check if window is reparented. If not - it was created with
|
||||
@ -223,13 +221,4 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
|
||||
long getX11Mods(AWTKeyStroke stroke) {
|
||||
return XWindow.getXModifiers(stroke);
|
||||
}
|
||||
|
||||
void notifyReady() {
|
||||
long wnd = server;
|
||||
if (wnd == 0) {
|
||||
// Server is still 0, get the parent
|
||||
wnd = embedded.getParentWindowHandle();
|
||||
}
|
||||
sendMessage(wnd, _SUN_XEMBED_START);
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ public class XEmbedHelper {
|
||||
final static int XEMBED_REGISTER_ACCELERATOR = 12;
|
||||
final static int XEMBED_UNREGISTER_ACCELERATOR= 13;
|
||||
final static int XEMBED_ACTIVATE_ACCELERATOR = 14;
|
||||
final static int _SUN_XEMBED_START = 1119;
|
||||
|
||||
final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108;
|
||||
final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109;
|
||||
@ -151,8 +150,6 @@ public class XEmbedHelper {
|
||||
return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY";
|
||||
case NON_STANDARD_XEMBED_GTK_GRAB_KEY:
|
||||
return "NON_STANDARD_XEMBED_GTK_GRAB_KEY";
|
||||
case _SUN_XEMBED_START:
|
||||
return "XEMBED_START";
|
||||
case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK:
|
||||
return "KeyPress";
|
||||
case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK:
|
||||
|
@ -177,13 +177,6 @@ public class XEmbedServerTester implements XEventDispatcher {
|
||||
embedCompletely();
|
||||
}
|
||||
|
||||
public void test3_2() {
|
||||
embedCompletely();
|
||||
int res = getEventPos();
|
||||
sendMessage(XEmbedHelper._SUN_XEMBED_START);
|
||||
waitEmbeddedNotify(res);
|
||||
}
|
||||
|
||||
public void test3_3() {
|
||||
reparent = true;
|
||||
embedCompletely();
|
||||
|
@ -184,6 +184,12 @@ public class XEmbeddedFramePeer extends XFramePeer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||
// We don't constrain the bounds of the EmbeddedFrames
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
|
||||
// don't use getBounds() inherited from XDecoratedPeer
|
||||
public Rectangle getBounds() {
|
||||
return new Rectangle(x, y, width, height);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,15 +24,18 @@
|
||||
*/
|
||||
package sun.awt.X11;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.awt.*;
|
||||
import java.awt.peer.*;
|
||||
import java.awt.event.*;
|
||||
import sun.awt.im.*;
|
||||
import sun.awt.*;
|
||||
import java.util.logging.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.MenuBar;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.peer.FramePeer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
|
||||
private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer");
|
||||
@ -92,7 +95,8 @@ class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTargetUndecorated() {
|
||||
@Override
|
||||
boolean isTargetUndecorated() {
|
||||
if (undecorated != null) {
|
||||
return undecorated.booleanValue();
|
||||
} else {
|
||||
@ -285,19 +289,20 @@ class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
|
||||
* Let's see if this is a window state protocol message, and
|
||||
* if it is - decode a new state in terms of java constants.
|
||||
*/
|
||||
Integer newState = XWM.getWM().isStateChange(this, ev);
|
||||
if (newState == null) {
|
||||
if (!XWM.getWM().isStateChange(this, ev)) {
|
||||
stateLog.finer("either not a state atom or state has not been changed");
|
||||
return;
|
||||
}
|
||||
|
||||
int changed = state ^ newState.intValue();
|
||||
final int newState = XWM.getWM().getState(this);
|
||||
int changed = state ^ newState;
|
||||
if (changed == 0) {
|
||||
stateLog.finer("State is the same: " + state);
|
||||
return;
|
||||
}
|
||||
|
||||
int old_state = state;
|
||||
state = newState.intValue();
|
||||
state = newState;
|
||||
|
||||
if ((changed & Frame.ICONIFIED) != 0) {
|
||||
if ((state & Frame.ICONIFIED) != 0) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2008 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
|
||||
@ -218,7 +218,7 @@ public class XMenuItemPeer implements MenuItemPeer {
|
||||
|
||||
Font getTargetFont() {
|
||||
if (target == null) {
|
||||
return XWindow.defaultFont;
|
||||
return XWindow.getDefaultFont();
|
||||
}
|
||||
try {
|
||||
return (Font)m_getFont.invoke(target, new Object[0]);
|
||||
@ -227,7 +227,7 @@ public class XMenuItemPeer implements MenuItemPeer {
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return XWindow.defaultFont;
|
||||
return XWindow.getDefaultFont();
|
||||
}
|
||||
|
||||
String getTargetLabel() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,17 +26,15 @@
|
||||
|
||||
package sun.awt.X11;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Frame;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.LogManager;
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.*;
|
||||
|
||||
class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol {
|
||||
final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
|
||||
final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol
|
||||
{
|
||||
private final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
|
||||
private final static Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XNETProtocol");
|
||||
private static Logger stateLog = Logger.getLogger("sun.awt.X11.states.XNETProtocol");
|
||||
|
||||
/**
|
||||
* XStateProtocol
|
||||
@ -276,6 +274,7 @@ class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol {
|
||||
|
||||
boolean doStateProtocol() {
|
||||
boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE);
|
||||
stateLog.finer("doStateProtocol() returns " + res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2008 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
|
||||
@ -187,7 +187,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer {
|
||||
//Fix for 6267144: PIT: Popup menu label is not shown, XToolkit
|
||||
Font getTargetFont() {
|
||||
if (popupMenuTarget == null) {
|
||||
return XWindow.defaultFont;
|
||||
return XWindow.getDefaultFont();
|
||||
}
|
||||
try {
|
||||
return (Font)m_getFont.invoke(popupMenuTarget, new Object[0]);
|
||||
@ -196,7 +196,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer {
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return XWindow.defaultFont;
|
||||
return XWindow.getDefaultFont();
|
||||
}
|
||||
|
||||
String getTargetLabel() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,9 +32,6 @@ import java.io.IOException;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Collections;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
import sun.awt.SunToolkit;
|
||||
@ -45,7 +42,7 @@ import sun.awt.datatransfer.DataTransferer;
|
||||
/**
|
||||
* A class which interfaces with the X11 selection service.
|
||||
*/
|
||||
public class XSelection {
|
||||
public final class XSelection {
|
||||
|
||||
/* Maps atoms to XSelection instances. */
|
||||
private static final Hashtable<XAtom, XSelection> table = new Hashtable<XAtom, XSelection>();
|
||||
@ -69,8 +66,6 @@ public class XSelection {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
/* The selection timeout. */
|
||||
private static long SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
|
||||
|
||||
/* The PropertyNotify event handler for incremental data transfer. */
|
||||
private static final XEventDispatcher incrementalTransferHandler =
|
||||
@ -84,11 +79,6 @@ public class XSelection {
|
||||
|
||||
/* The X atom for the underlying selection. */
|
||||
private final XAtom selectionAtom;
|
||||
/*
|
||||
* XClipboard.run() is to be called when we lose ownership.
|
||||
* XClipbioard.checkChange() is to be called when tracking changes of flavors.
|
||||
*/
|
||||
private final XClipboard clipboard;
|
||||
|
||||
/*
|
||||
* Owner-related variables - protected with synchronized (this).
|
||||
@ -109,17 +99,8 @@ public class XSelection {
|
||||
private long ownershipTime = 0;
|
||||
// True if we are the owner of this selection.
|
||||
private boolean isOwner;
|
||||
// The property in which the owner should place requested targets
|
||||
// when tracking changes of available data flavors (practically targets).
|
||||
private volatile XAtom targetsPropertyAtom;
|
||||
// A set of these property atoms.
|
||||
private static volatile Set targetsPropertyAtoms;
|
||||
// The flag used not to call XConvertSelection() if the previous SelectionNotify
|
||||
// has not been processed by checkChange().
|
||||
private volatile boolean isSelectionNotifyProcessed;
|
||||
// Time of calling XConvertSelection().
|
||||
private long convertSelectionTime;
|
||||
|
||||
private OwnershipListener ownershipListener = null;
|
||||
private final Object stateLock = new Object();
|
||||
|
||||
static {
|
||||
XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
|
||||
@ -141,12 +122,11 @@ public class XSelection {
|
||||
* @param clpbrd the corresponding clipoboard
|
||||
* @exception NullPointerException if atom is <code>null</code>.
|
||||
*/
|
||||
public XSelection(XAtom atom, XClipboard clpbrd) {
|
||||
public XSelection(XAtom atom) {
|
||||
if (atom == null) {
|
||||
throw new NullPointerException("Null atom");
|
||||
}
|
||||
selectionAtom = atom;
|
||||
clipboard = clpbrd;
|
||||
table.put(selectionAtom, this);
|
||||
}
|
||||
|
||||
@ -154,25 +134,9 @@ public class XSelection {
|
||||
return selectionAtom;
|
||||
}
|
||||
|
||||
void initializeSelectionForTrackingChanges() {
|
||||
targetsPropertyAtom = XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selectionAtom.getName());
|
||||
if (targetsPropertyAtoms == null) {
|
||||
targetsPropertyAtoms = Collections.synchronizedSet(new HashSet(2));
|
||||
}
|
||||
targetsPropertyAtoms.add(Long.valueOf(targetsPropertyAtom.getAtom()));
|
||||
// for XConvertSelection() to be called for the first time in getTargetsDelayed()
|
||||
isSelectionNotifyProcessed = true;
|
||||
}
|
||||
|
||||
void deinitializeSelectionForTrackingChanges() {
|
||||
if (targetsPropertyAtoms != null && targetsPropertyAtom != null) {
|
||||
targetsPropertyAtoms.remove(Long.valueOf(targetsPropertyAtom.getAtom()));
|
||||
}
|
||||
isSelectionNotifyProcessed = false;
|
||||
}
|
||||
|
||||
public synchronized boolean setOwner(Transferable contents, Map formatMap,
|
||||
long[] formats, long time) {
|
||||
long[] formats, long time)
|
||||
{
|
||||
long owner = XWindow.getXAWTRootWindow().getWindow();
|
||||
long selection = selectionAtom.getAtom();
|
||||
|
||||
@ -192,15 +156,12 @@ public class XSelection {
|
||||
XlibWrapper.XSetSelectionOwner(XToolkit.getDisplay(),
|
||||
selection, owner, time);
|
||||
if (XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(),
|
||||
selection) != owner) {
|
||||
|
||||
selection) != owner)
|
||||
{
|
||||
reset();
|
||||
return false;
|
||||
}
|
||||
isOwner = true;
|
||||
if (clipboard != null) {
|
||||
clipboard.checkChangeHere(contents);
|
||||
}
|
||||
setOwnerProp(true);
|
||||
return true;
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
@ -217,7 +178,7 @@ public class XSelection {
|
||||
do {
|
||||
DataTransferer.getInstance().processDataConversionRequests();
|
||||
XToolkit.awtLockWait(250);
|
||||
} while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + SELECTION_TIMEOUT);
|
||||
} while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + UNIXToolkit.getDatatransferTimeout());
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
@ -232,11 +193,9 @@ public class XSelection {
|
||||
throw new Error("UNIMPLEMENTED");
|
||||
}
|
||||
|
||||
long[] formats = null;
|
||||
long[] targets = null;
|
||||
|
||||
synchronized (lock) {
|
||||
SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
|
||||
|
||||
WindowPropertyGetter targetsGetter =
|
||||
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
||||
selectionPropertyAtom, 0, MAX_LENGTH,
|
||||
@ -267,23 +226,25 @@ public class XSelection {
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
formats = getFormats(targetsGetter);
|
||||
targets = getFormats(targetsGetter);
|
||||
} finally {
|
||||
targetsGetter.dispose();
|
||||
}
|
||||
}
|
||||
return formats;
|
||||
return targets;
|
||||
}
|
||||
|
||||
private static long[] getFormats(WindowPropertyGetter targetsGetter) {
|
||||
static long[] getFormats(WindowPropertyGetter targetsGetter) {
|
||||
long[] formats = null;
|
||||
|
||||
if (targetsGetter.isExecuted() && !targetsGetter.isDisposed() &&
|
||||
(targetsGetter.getActualType() == XAtom.XA_ATOM ||
|
||||
targetsGetter.getActualType() == XDataTransferer.TARGETS_ATOM.getAtom()) &&
|
||||
targetsGetter.getActualFormat() == 32) {
|
||||
|
||||
int count = (int)targetsGetter.getNumberOfItems();
|
||||
targetsGetter.getActualFormat() == 32)
|
||||
{
|
||||
// we accept property with TARGETS type to be compatible with old jdks
|
||||
// see 6607163
|
||||
int count = targetsGetter.getNumberOfItems();
|
||||
if (count > 0) {
|
||||
long atoms = targetsGetter.getData();
|
||||
formats = new long[count];
|
||||
@ -297,26 +258,6 @@ public class XSelection {
|
||||
return formats != null ? formats : new long[0];
|
||||
}
|
||||
|
||||
// checkChange() will be called on SelectionNotify
|
||||
void getTargetsDelayed() {
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
long curTime = System.currentTimeMillis();
|
||||
if (isSelectionNotifyProcessed || curTime >= convertSelectionTime + SELECTION_TIMEOUT) {
|
||||
convertSelectionTime = curTime;
|
||||
XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
|
||||
getSelectionAtom().getAtom(),
|
||||
XDataTransferer.TARGETS_ATOM.getAtom(),
|
||||
targetsPropertyAtom.getAtom(),
|
||||
XWindow.getXAWTRootWindow().getWindow(),
|
||||
XlibWrapper.CurrentTime);
|
||||
isSelectionNotifyProcessed = false;
|
||||
}
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Requests the selection data in the specified format and returns
|
||||
* the data provided by the owner.
|
||||
@ -329,8 +270,6 @@ public class XSelection {
|
||||
byte[] data = null;
|
||||
|
||||
synchronized (lock) {
|
||||
SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
|
||||
|
||||
WindowPropertyGetter dataGetter =
|
||||
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
||||
selectionPropertyAtom, 0, MAX_LENGTH,
|
||||
@ -379,7 +318,7 @@ public class XSelection {
|
||||
dataGetter.getActualFormat());
|
||||
}
|
||||
|
||||
int count = (int)dataGetter.getNumberOfItems();
|
||||
int count = dataGetter.getNumberOfItems();
|
||||
|
||||
if (count <= 0) {
|
||||
throw new IOException("INCR data is missed.");
|
||||
@ -455,7 +394,7 @@ public class XSelection {
|
||||
incrDataGetter.getActualFormat());
|
||||
}
|
||||
|
||||
count = (int)incrDataGetter.getNumberOfItems();
|
||||
count = incrDataGetter.getNumberOfItems();
|
||||
|
||||
if (count == 0) {
|
||||
break;
|
||||
@ -489,7 +428,7 @@ public class XSelection {
|
||||
dataGetter.getActualFormat());
|
||||
}
|
||||
|
||||
int count = (int)dataGetter.getNumberOfItems();
|
||||
int count = dataGetter.getNumberOfItems();
|
||||
if (count > 0) {
|
||||
data = new byte[count];
|
||||
long ptr = dataGetter.getData();
|
||||
@ -511,11 +450,14 @@ public class XSelection {
|
||||
return isOwner;
|
||||
}
|
||||
|
||||
public void lostOwnership() {
|
||||
isOwner = false;
|
||||
if (clipboard != null) {
|
||||
clipboard.run();
|
||||
}
|
||||
// To be MT-safe this method should be called under awtLock.
|
||||
private void setOwnerProp(boolean f) {
|
||||
isOwner = f;
|
||||
fireOwnershipChanges(isOwner);
|
||||
}
|
||||
|
||||
private void lostOwnership() {
|
||||
setOwnerProp(false);
|
||||
}
|
||||
|
||||
public synchronized void reset() {
|
||||
@ -595,125 +537,39 @@ public class XSelection {
|
||||
|
||||
private void handleSelectionRequest(XSelectionRequestEvent xsre) {
|
||||
long property = xsre.get_property();
|
||||
long requestor = xsre.get_requestor();
|
||||
long requestTime = xsre.get_time();
|
||||
long format = xsre.get_target();
|
||||
int dataFormat = 0;
|
||||
final long requestor = xsre.get_requestor();
|
||||
final long requestTime = xsre.get_time();
|
||||
final long format = xsre.get_target();
|
||||
boolean conversionSucceeded = false;
|
||||
|
||||
if (ownershipTime != 0 &&
|
||||
(requestTime == XlibWrapper.CurrentTime ||
|
||||
requestTime >= ownershipTime)) {
|
||||
|
||||
property = xsre.get_property();
|
||||
|
||||
(requestTime == XlibWrapper.CurrentTime || requestTime >= ownershipTime))
|
||||
{
|
||||
// Handle MULTIPLE requests as per ICCCM.
|
||||
if (format == XDataTransferer.MULTIPLE_ATOM.getAtom()) {
|
||||
// The property cannot be 0 for a MULTIPLE request.
|
||||
if (property != 0) {
|
||||
// First retrieve the list of requested targets.
|
||||
WindowPropertyGetter wpg =
|
||||
new WindowPropertyGetter(requestor, XAtom.get(property), 0,
|
||||
MAX_LENGTH, false,
|
||||
XlibWrapper.AnyPropertyType);
|
||||
try {
|
||||
wpg.execute();
|
||||
|
||||
if (wpg.getActualFormat() == 32 &&
|
||||
(wpg.getNumberOfItems() % 2) == 0) {
|
||||
long count = wpg.getNumberOfItems() / 2;
|
||||
long pairsPtr = wpg.getData();
|
||||
boolean writeBack = false;
|
||||
for (int i = 0; i < count; i++) {
|
||||
long target = Native.getLong(pairsPtr, 2*i);
|
||||
long prop = Native.getLong(pairsPtr, 2*i + 1);
|
||||
|
||||
if (!convertAndStore(requestor, target, prop)) {
|
||||
// To report failure, we should replace the
|
||||
// target atom with 0 in the MULTIPLE property.
|
||||
Native.putLong(pairsPtr, 2*i, 0);
|
||||
writeBack = true;
|
||||
}
|
||||
}
|
||||
if (writeBack) {
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
|
||||
property,
|
||||
wpg.getActualType(),
|
||||
wpg.getActualFormat(),
|
||||
XlibWrapper.PropModeReplace,
|
||||
wpg.getData(),
|
||||
wpg.getNumberOfItems());
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
conversionSucceeded = true;
|
||||
}
|
||||
} finally {
|
||||
wpg.dispose();
|
||||
}
|
||||
}
|
||||
conversionSucceeded = handleMultipleRequest(requestor, property);
|
||||
} else {
|
||||
|
||||
// Support for obsolete clients as per ICCCM.
|
||||
if (property == 0) {
|
||||
if (property == XlibWrapper.None) {
|
||||
property = format;
|
||||
}
|
||||
|
||||
if (format == XDataTransferer.TARGETS_ATOM.getAtom()) {
|
||||
long nativeDataPtr = 0;
|
||||
int count = 0;
|
||||
dataFormat = 32;
|
||||
|
||||
// Use a local copy to avoid synchronization.
|
||||
long[] formatsLocal = formats;
|
||||
|
||||
if (formatsLocal == null) {
|
||||
throw new IllegalStateException("Not an owner.");
|
||||
}
|
||||
|
||||
count = formatsLocal.length;
|
||||
|
||||
try {
|
||||
if (count > 0) {
|
||||
nativeDataPtr = Native.allocateLongArray(count);
|
||||
Native.put(nativeDataPtr, formatsLocal);
|
||||
}
|
||||
|
||||
conversionSucceeded = true;
|
||||
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
|
||||
property, format, dataFormat,
|
||||
XlibWrapper.PropModeReplace,
|
||||
nativeDataPtr, count);
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
} finally {
|
||||
if (nativeDataPtr != 0) {
|
||||
XlibWrapper.unsafe.freeMemory(nativeDataPtr);
|
||||
nativeDataPtr = 0;
|
||||
}
|
||||
}
|
||||
conversionSucceeded = handleTargetsRequest(property, requestor);
|
||||
} else {
|
||||
conversionSucceeded = convertAndStore(requestor, format,
|
||||
property);
|
||||
conversionSucceeded = convertAndStore(requestor, format, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!conversionSucceeded) {
|
||||
// Zero property indicates conversion failure.
|
||||
property = 0;
|
||||
// None property indicates conversion failure.
|
||||
property = XlibWrapper.None;
|
||||
}
|
||||
|
||||
XSelectionEvent xse = new XSelectionEvent();
|
||||
try {
|
||||
xse.set_type((int)XlibWrapper.SelectionNotify);
|
||||
xse.set_type(XlibWrapper.SelectionNotify);
|
||||
xse.set_send_event(true);
|
||||
xse.set_requestor(requestor);
|
||||
xse.set_selection(selectionAtom.getAtom());
|
||||
@ -733,40 +589,123 @@ public class XSelection {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkChange(XSelectionEvent xse) {
|
||||
if (targetsPropertyAtoms == null || targetsPropertyAtoms.isEmpty()) {
|
||||
// We are not tracking changes.
|
||||
return;
|
||||
private boolean handleMultipleRequest(final long requestor, long property) {
|
||||
if (XlibWrapper.None == property) {
|
||||
// The property cannot be None for a MULTIPLE request.
|
||||
return false;
|
||||
}
|
||||
|
||||
long propertyAtom = xse.get_property();
|
||||
long[] formats = null;
|
||||
boolean conversionSucceeded = false;
|
||||
|
||||
if (propertyAtom == XlibWrapper.None) {
|
||||
// We threat None property atom as "empty selection".
|
||||
formats = new long[0];
|
||||
} else if (!targetsPropertyAtoms.contains(Long.valueOf(propertyAtom))) {
|
||||
return;
|
||||
} else {
|
||||
WindowPropertyGetter targetsGetter =
|
||||
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
||||
XAtom.get(propertyAtom), 0, MAX_LENGTH,
|
||||
true, XlibWrapper.AnyPropertyType);
|
||||
// First retrieve the list of requested targets.
|
||||
WindowPropertyGetter wpg =
|
||||
new WindowPropertyGetter(requestor, XAtom.get(property),
|
||||
0, MAX_LENGTH, false,
|
||||
XlibWrapper.AnyPropertyType);
|
||||
try {
|
||||
wpg.execute();
|
||||
|
||||
if (wpg.getActualFormat() == 32 && (wpg.getNumberOfItems() % 2) == 0) {
|
||||
final long count = wpg.getNumberOfItems() / 2;
|
||||
final long pairsPtr = wpg.getData();
|
||||
boolean writeBack = false;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
long target = Native.getLong(pairsPtr, 2 * i);
|
||||
long prop = Native.getLong(pairsPtr, 2 * i + 1);
|
||||
|
||||
if (!convertAndStore(requestor, target, prop)) {
|
||||
// To report failure, we should replace the
|
||||
// target atom with 0 in the MULTIPLE property.
|
||||
Native.putLong(pairsPtr, 2 * i, 0);
|
||||
writeBack = true;
|
||||
}
|
||||
}
|
||||
if (writeBack) {
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
XlibWrapper.XChangeProperty(XToolkit.getDisplay(),
|
||||
requestor,
|
||||
property,
|
||||
wpg.getActualType(),
|
||||
wpg.getActualFormat(),
|
||||
XlibWrapper.PropModeReplace,
|
||||
wpg.getData(),
|
||||
wpg.getNumberOfItems());
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
conversionSucceeded = true;
|
||||
}
|
||||
} finally {
|
||||
wpg.dispose();
|
||||
}
|
||||
|
||||
return conversionSucceeded;
|
||||
}
|
||||
|
||||
private boolean handleTargetsRequest(long property, long requestor)
|
||||
throws IllegalStateException
|
||||
{
|
||||
boolean conversionSucceeded = false;
|
||||
// Use a local copy to avoid synchronization.
|
||||
long[] formatsLocal = formats;
|
||||
|
||||
if (formatsLocal == null) {
|
||||
throw new IllegalStateException("Not an owner.");
|
||||
}
|
||||
|
||||
long nativeDataPtr = 0;
|
||||
|
||||
try {
|
||||
final int count = formatsLocal.length;
|
||||
final int dataFormat = 32;
|
||||
|
||||
if (count > 0) {
|
||||
nativeDataPtr = Native.allocateLongArray(count);
|
||||
Native.put(nativeDataPtr, formatsLocal);
|
||||
}
|
||||
|
||||
conversionSucceeded = true;
|
||||
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
targetsGetter.execute();
|
||||
formats = getFormats(targetsGetter);
|
||||
XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
|
||||
property, XAtom.XA_ATOM, dataFormat,
|
||||
XlibWrapper.PropModeReplace,
|
||||
nativeDataPtr, count);
|
||||
} finally {
|
||||
targetsGetter.dispose();
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
} finally {
|
||||
if (nativeDataPtr != 0) {
|
||||
XlibWrapper.unsafe.freeMemory(nativeDataPtr);
|
||||
nativeDataPtr = 0;
|
||||
}
|
||||
}
|
||||
return conversionSucceeded;
|
||||
}
|
||||
|
||||
XAtom selectionAtom = XAtom.get(xse.get_selection());
|
||||
XSelection selection = getSelection(selectionAtom);
|
||||
if (selection != null) {
|
||||
selection.isSelectionNotifyProcessed = true;
|
||||
if (selection.clipboard != null) {
|
||||
selection.clipboard.checkChange(formats);
|
||||
}
|
||||
private void fireOwnershipChanges(final boolean isOwner) {
|
||||
OwnershipListener l = null;
|
||||
synchronized (stateLock) {
|
||||
l = ownershipListener;
|
||||
}
|
||||
if (null != l) {
|
||||
l.ownershipChanged(isOwner);
|
||||
}
|
||||
}
|
||||
|
||||
void registerOwershipListener(OwnershipListener l) {
|
||||
synchronized (stateLock) {
|
||||
ownershipListener = l;
|
||||
}
|
||||
}
|
||||
|
||||
void unregisterOwnershipListener() {
|
||||
synchronized (stateLock) {
|
||||
ownershipListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -774,10 +713,9 @@ public class XSelection {
|
||||
public void dispatchEvent(XEvent ev) {
|
||||
switch (ev.get_type()) {
|
||||
case XlibWrapper.SelectionNotify: {
|
||||
XSelectionEvent xse = ev.get_xselection();
|
||||
checkChange(xse);
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
XSelectionEvent xse = ev.get_xselection();
|
||||
// Ignore the SelectionNotify event if it is not the response to our last request.
|
||||
if (propertyGetter != null && xse.get_time() == lastRequestServerTime) {
|
||||
// The property will be None in case of convertion failure.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,11 +25,9 @@
|
||||
package sun.awt.X11;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.peer.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import sun.awt.*;
|
||||
import java.util.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.dnd.DragSource;
|
||||
import java.awt.dnd.DragGestureListener;
|
||||
import java.awt.dnd.DragGestureEvent;
|
||||
@ -37,20 +35,27 @@ import java.awt.dnd.DragGestureRecognizer;
|
||||
import java.awt.dnd.MouseDragGestureRecognizer;
|
||||
import java.awt.dnd.InvalidDnDOperationException;
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
import java.awt.image.*;
|
||||
import java.security.*;
|
||||
import java.awt.im.InputMethodHighlight;
|
||||
import java.awt.im.spi.InputMethodDescriptor;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.peer.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
import java.util.logging.*;
|
||||
import sun.awt.*;
|
||||
import sun.font.FontManager;
|
||||
import sun.misc.PerformanceLogger;
|
||||
import sun.print.PrintJob2D;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
public class XToolkit extends UNIXToolkit implements Runnable, XConstants {
|
||||
public final class XToolkit extends UNIXToolkit implements Runnable, XConstants
|
||||
{
|
||||
private static Logger log = Logger.getLogger("sun.awt.X11.XToolkit");
|
||||
private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XToolkit");
|
||||
private static final Logger timeoutTaskLog = Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit");
|
||||
@ -1871,9 +1876,7 @@ public class XToolkit extends UNIXToolkit implements Runnable, XConstants {
|
||||
}
|
||||
|
||||
public boolean isAlwaysOnTopSupported() {
|
||||
Iterator iter = XWM.getWM().getProtocols(XLayerProtocol.class).iterator();
|
||||
while (iter.hasNext()) {
|
||||
XLayerProtocol proto = (XLayerProtocol)iter.next();
|
||||
for (XLayerProtocol proto : XWM.getWM().getProtocols(XLayerProtocol.class)) {
|
||||
if (proto.supportsLayer(XLayerProtocol.LAYER_ALWAYS_ON_TOP)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,11 +31,8 @@ import java.awt.peer.TrayIconPeer;
|
||||
import sun.awt.*;
|
||||
import java.awt.image.*;
|
||||
import java.text.BreakIterator;
|
||||
import java.util.Vector;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.AbstractQueue;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
@ -629,7 +626,7 @@ public class XTrayIconPeer implements TrayIconPeer {
|
||||
final static int TOOLTIP_MAX_LENGTH = 64;
|
||||
final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5;
|
||||
final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220);
|
||||
final static Font TOOLTIP_TEXT_FONT = XWindow.defaultFont;
|
||||
final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont();
|
||||
|
||||
Tooltip(XTrayIconPeer xtiPeer, Frame parent) {
|
||||
super(parent, Color.black);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,20 +31,23 @@
|
||||
package sun.awt.X11;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
import java.util.regex.*;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
import java.awt.Insets;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Class incapsulating knowledge about window managers in general
|
||||
* Descendants should provide some information about specific window manager.
|
||||
*/
|
||||
class XWM implements MWMConstants, XUtilConstants {
|
||||
final class XWM implements MWMConstants, XUtilConstants
|
||||
{
|
||||
|
||||
private final static Logger log = Logger.getLogger("sun.awt.X11.XWM");
|
||||
private final static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWM");
|
||||
@ -1026,21 +1029,21 @@ class XWM implements MWMConstants, XUtilConstants {
|
||||
/*****************************************************************************\
|
||||
* Protocols support
|
||||
*/
|
||||
HashMap<Class<?>, Collection<XProtocol>> protocolsMap = new HashMap<Class<?>, Collection<XProtocol>>();
|
||||
private HashMap<Class<?>, Collection<?>> protocolsMap = new HashMap<Class<?>, Collection<?>>();
|
||||
/**
|
||||
* Returns all protocols supporting given protocol interface
|
||||
*/
|
||||
Collection<XProtocol> getProtocols(Class protocolInterface) {
|
||||
Collection<XProtocol> res = protocolsMap.get(protocolInterface);
|
||||
<T> Collection<T> getProtocols(Class<T> protocolInterface) {
|
||||
Collection<T> res = (Collection<T>) protocolsMap.get(protocolInterface);
|
||||
if (res != null) {
|
||||
return (Collection<XProtocol>)res;
|
||||
return res;
|
||||
} else {
|
||||
return new LinkedList<XProtocol>();
|
||||
return new LinkedList<T>();
|
||||
}
|
||||
}
|
||||
|
||||
void addProtocol(Class protocolInterface, XProtocol protocol) {
|
||||
Collection<XProtocol> protocols = getProtocols(protocolInterface);
|
||||
private <T> void addProtocol(Class<T> protocolInterface, T protocol) {
|
||||
Collection<T> protocols = getProtocols(protocolInterface);
|
||||
protocols.add(protocol);
|
||||
protocolsMap.put(protocolInterface, protocols);
|
||||
}
|
||||
@ -1085,9 +1088,7 @@ class XWM implements MWMConstants, XUtilConstants {
|
||||
}
|
||||
/* FALLTROUGH */
|
||||
case Frame.MAXIMIZED_BOTH:
|
||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
||||
while (iter.hasNext()) {
|
||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
||||
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||
if (proto.supportsState(state)) {
|
||||
return true;
|
||||
}
|
||||
@ -1105,10 +1106,8 @@ class XWM implements MWMConstants, XUtilConstants {
|
||||
|
||||
|
||||
int getExtendedState(XWindowPeer window) {
|
||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
||||
int state = 0;
|
||||
while (iter.hasNext()) {
|
||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
||||
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||
state |= proto.getState(window);
|
||||
}
|
||||
if (state != 0) {
|
||||
@ -1127,18 +1126,17 @@ class XWM implements MWMConstants, XUtilConstants {
|
||||
|
||||
/*
|
||||
* Check if property change is a window state protocol message.
|
||||
* If it is - return the new state as Integer, otherwise return null
|
||||
*/
|
||||
Integer isStateChange(XDecoratedPeer window, XPropertyEvent e) {
|
||||
boolean isStateChange(XDecoratedPeer window, XPropertyEvent e) {
|
||||
if (!window.isShowing()) {
|
||||
stateLog.finer("Window is not showing");
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
int wm_state = window.getWMState();
|
||||
if (wm_state == XlibWrapper.WithdrawnState) {
|
||||
stateLog.finer("WithdrawnState");
|
||||
return null;
|
||||
return false;
|
||||
} else {
|
||||
stateLog.finer("Window WM_STATE is " + wm_state);
|
||||
}
|
||||
@ -1147,26 +1145,26 @@ class XWM implements MWMConstants, XUtilConstants {
|
||||
is_state_change = true;
|
||||
}
|
||||
|
||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
||||
while (iter.hasNext()) {
|
||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
||||
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||
is_state_change |= proto.isStateChange(e);
|
||||
stateLog.finest(proto + ": is state changed = " + is_state_change);
|
||||
}
|
||||
int res = 0;
|
||||
return is_state_change;
|
||||
}
|
||||
|
||||
if (is_state_change) {
|
||||
if (wm_state == XlibWrapper.IconicState) {
|
||||
res = Frame.ICONIFIED;
|
||||
} else {
|
||||
res = Frame.NORMAL;
|
||||
}
|
||||
res |= getExtendedState(window);
|
||||
}
|
||||
if (is_state_change) {
|
||||
return Integer.valueOf(res);
|
||||
/*
|
||||
* Returns current state (including extended) of a given window.
|
||||
*/
|
||||
int getState(XDecoratedPeer window) {
|
||||
int res = 0;
|
||||
final int wm_state = window.getWMState();
|
||||
if (wm_state == XlibWrapper.IconicState) {
|
||||
res = Frame.ICONIFIED;
|
||||
} else {
|
||||
return null;
|
||||
res = Frame.NORMAL;
|
||||
}
|
||||
res |= getExtendedState(window);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*****************************************************************************\
|
||||
@ -1180,9 +1178,7 @@ class XWM implements MWMConstants, XUtilConstants {
|
||||
* in XLayerProtocol
|
||||
*/
|
||||
void setLayer(XWindowPeer window, int layer) {
|
||||
Iterator iter = getProtocols(XLayerProtocol.class).iterator();
|
||||
while (iter.hasNext()) {
|
||||
XLayerProtocol proto = (XLayerProtocol)iter.next();
|
||||
for (XLayerProtocol proto : getProtocols(XLayerProtocol.class)) {
|
||||
if (proto.supportsLayer(layer)) {
|
||||
proto.setLayer(window, layer);
|
||||
}
|
||||
@ -1191,9 +1187,7 @@ class XWM implements MWMConstants, XUtilConstants {
|
||||
}
|
||||
|
||||
void setExtendedState(XWindowPeer window, int state) {
|
||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
||||
while (iter.hasNext()) {
|
||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
||||
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||
if (proto.supportsState(state)) {
|
||||
proto.setState(window, state);
|
||||
break;
|
||||
@ -1239,9 +1233,7 @@ class XWM implements MWMConstants, XUtilConstants {
|
||||
void unshadeKludge(XDecoratedPeer window) {
|
||||
assert(window.isShowing());
|
||||
|
||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
||||
while (iter.hasNext()) {
|
||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
||||
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||
proto.unshadeKludge(window);
|
||||
}
|
||||
XToolkit.XSync();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2008 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,8 +92,16 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
SurfaceData surfaceData;
|
||||
|
||||
XRepaintArea paintArea;
|
||||
|
||||
// fallback default font object
|
||||
final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
|
||||
private static Font defaultFont;
|
||||
|
||||
static synchronized Font getDefaultFont() {
|
||||
if (null == defaultFont) {
|
||||
defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
|
||||
}
|
||||
return defaultFont;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keeps all buttons which were pressed at the time of the last mouse
|
||||
@ -333,7 +341,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
}
|
||||
Font font = afont;
|
||||
if (font == null) {
|
||||
font = defaultFont;
|
||||
font = XWindow.getDefaultFont();
|
||||
}
|
||||
return new SunGraphics2D(surfData, fgColor, bgColor, font);
|
||||
}
|
||||
@ -902,13 +910,11 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
|
||||
super.handleConfigureNotifyEvent(xev);
|
||||
insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}",
|
||||
new Object[] {xev, isEventDisabled(xev)});
|
||||
new Object[] {xev.get_xconfigure(), isEventDisabled(xev)});
|
||||
if (isEventDisabled(xev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
long eventWindow = xev.get_xany().get_window();
|
||||
|
||||
// if ( Check if it's a resize, a move, or a stacking order change )
|
||||
// {
|
||||
Rectangle bounds = getBounds();
|
||||
@ -982,7 +988,6 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
// called directly from this package, unlike handleKeyRelease.
|
||||
// un-final it if you need to override it in a subclass.
|
||||
final void handleKeyPress(XKeyEvent ev) {
|
||||
int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
|
||||
long keysym[] = new long[2];
|
||||
char unicodeKey = 0;
|
||||
keysym[0] = NoSymbol;
|
||||
@ -1066,7 +1071,6 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
}
|
||||
// un-private it if you need to call it from elsewhere
|
||||
private void handleKeyRelease(XKeyEvent ev) {
|
||||
int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
|
||||
long keysym[] = new long[2];
|
||||
char unicodeKey = 0;
|
||||
keysym[0] = NoSymbol;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2008 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
|
||||
@ -112,9 +112,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
PARENT_WINDOW, Long.valueOf(0)}));
|
||||
}
|
||||
|
||||
// fallback default font object
|
||||
static Font defaultFont;
|
||||
|
||||
/*
|
||||
* This constant defines icon size recommended for using.
|
||||
* Apparently, we should use XGetIconSizes which should
|
||||
@ -162,10 +159,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
|
||||
Font f = target.getFont();
|
||||
if (f == null) {
|
||||
if (defaultFont == null) {
|
||||
defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
|
||||
}
|
||||
f = defaultFont;
|
||||
f = XWindow.getDefaultFont();
|
||||
target.setFont(f);
|
||||
// we should not call setFont because it will call a repaint
|
||||
// which the peer may not be ready to do yet.
|
||||
@ -188,6 +182,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
|
||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||
((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
|
||||
|
||||
Rectangle bounds = (Rectangle)(params.get(BOUNDS));
|
||||
params.put(BOUNDS, constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height));
|
||||
}
|
||||
|
||||
private void initWMProtocols() {
|
||||
@ -437,6 +434,56 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
return ownerPeer;
|
||||
}
|
||||
|
||||
// This method is overriden at the XDecoratedPeer to handle
|
||||
// decorated windows a bit differently.
|
||||
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||
// We don't restrict the setBounds() operation if the code is trusted.
|
||||
if (!hasWarningWindow()) {
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
|
||||
// The window bounds should be within the visible part of the screen
|
||||
int newX = x;
|
||||
int newY = y;
|
||||
int newW = width;
|
||||
int newH = height;
|
||||
|
||||
// Now check each point is within the visible part of the screen
|
||||
GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
|
||||
Rectangle sB = gc.getBounds();
|
||||
Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
|
||||
|
||||
int screenX = sB.x + sIn.left;
|
||||
int screenY = sB.y + sIn.top;
|
||||
int screenW = sB.width - sIn.left - sIn.right;
|
||||
int screenH = sB.height - sIn.top - sIn.bottom;
|
||||
|
||||
|
||||
// First make sure the size is withing the visible part of the screen
|
||||
if (newW > screenW) {
|
||||
newW = screenW;
|
||||
}
|
||||
|
||||
if (newH > screenH) {
|
||||
newH = screenH;
|
||||
}
|
||||
|
||||
// Tweak the location if needed
|
||||
if (newX < screenX) {
|
||||
newX = screenX;
|
||||
} else if (newX + newW > screenX + screenW) {
|
||||
newX = screenX + screenW - newW;
|
||||
}
|
||||
|
||||
if (newY < screenY) {
|
||||
newY = screenY;
|
||||
} else if (newY + newH > screenY + screenH) {
|
||||
newY = screenY + screenH - newH;
|
||||
}
|
||||
|
||||
return new Rectangle(newX, newY, newW, newH);
|
||||
}
|
||||
|
||||
//Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges
|
||||
//the window but fails to revalidate, Sol-CDE
|
||||
//This bug is regression for
|
||||
@ -445,10 +492,14 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
//Note that this function is overriden in XDecoratedPeer so event
|
||||
//posting is not changing for decorated peers
|
||||
public void setBounds(int x, int y, int width, int height, int op) {
|
||||
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
Rectangle oldBounds = getBounds();
|
||||
super.setBounds(x, y, width, height, op);
|
||||
|
||||
super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
|
||||
|
||||
Rectangle bounds = getBounds();
|
||||
|
||||
XSizeHints hints = getHints();
|
||||
@ -1035,7 +1086,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
return !(target instanceof Frame || target instanceof Dialog);
|
||||
}
|
||||
boolean hasWarningWindow() {
|
||||
return warningWindow != null;
|
||||
return ((Window)target).getWarningString() != null;
|
||||
}
|
||||
|
||||
// The height of menu bar window
|
||||
|
@ -102,4 +102,9 @@ class MDialogPeer extends MWindowPeer implements DialogPeer, MInputMethodControl
|
||||
public void blockWindows(java.util.List<Window> toBlock) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
final boolean isTargetUndecorated() {
|
||||
return ((Dialog)target).isUndecorated();
|
||||
}
|
||||
}
|
||||
|
@ -204,4 +204,10 @@ public class MEmbeddedFramePeer extends MFramePeer {
|
||||
}
|
||||
|
||||
public native Rectangle getBoundsPrivate();
|
||||
|
||||
@Override
|
||||
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||
// We don't constrain the bounds of the EmbeddedFrames
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
@ -503,4 +503,9 @@ class MFramePeer extends MWindowPeer implements FramePeer, MInputMethodControl {
|
||||
public Rectangle getBoundsPrivate() {
|
||||
return getBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
final boolean isTargetUndecorated() {
|
||||
return ((Frame)target).isUndecorated();
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,12 @@ DisplayChangedListener {
|
||||
insets.right = getInset("awt.frame.rightInset", -1);
|
||||
}
|
||||
|
||||
Rectangle bounds = target.getBounds();
|
||||
sysX = bounds.x;
|
||||
sysY = bounds.y;
|
||||
sysW = bounds.width;
|
||||
sysH = bounds.height;
|
||||
|
||||
super.init(target);
|
||||
InputMethodManager imm = InputMethodManager.getInstance();
|
||||
String menuString = imm.getTriggerMenuString();
|
||||
@ -150,6 +156,7 @@ DisplayChangedListener {
|
||||
|
||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||
((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
|
||||
|
||||
}
|
||||
|
||||
/* Support for multiple icons is not implemented in MAWT */
|
||||
@ -246,6 +253,8 @@ DisplayChangedListener {
|
||||
// NOTE: This method may be called by privileged threads.
|
||||
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||
public void handleResize(int width, int height) {
|
||||
sysW = width;
|
||||
sysH = height;
|
||||
|
||||
// REMIND: Is this secure? Can client code subclass input method?
|
||||
if (!tcList.isEmpty() &&
|
||||
@ -268,6 +277,8 @@ DisplayChangedListener {
|
||||
}
|
||||
|
||||
public void handleMoved(int x, int y) {
|
||||
sysX = x;
|
||||
sysY = y;
|
||||
postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
|
||||
}
|
||||
|
||||
@ -505,4 +516,87 @@ DisplayChangedListener {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private final boolean hasWarningWindow() {
|
||||
return ((Window)target).getWarningString() != null;
|
||||
}
|
||||
|
||||
// This method is overriden at Dialog and Frame peers.
|
||||
boolean isTargetUndecorated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private volatile int sysX = 0;
|
||||
private volatile int sysY = 0;
|
||||
private volatile int sysW = 0;
|
||||
private volatile int sysH = 0;
|
||||
|
||||
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||
// We don't restrict the setBounds() operation if the code is trusted.
|
||||
if (!hasWarningWindow()) {
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
|
||||
int newX = x;
|
||||
int newY = y;
|
||||
int newW = width;
|
||||
int newH = height;
|
||||
|
||||
GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
|
||||
Rectangle sB = gc.getBounds();
|
||||
Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
|
||||
|
||||
int screenW = sB.width - sIn.left - sIn.right;
|
||||
int screenH = sB.height - sIn.top - sIn.bottom;
|
||||
|
||||
// If it's undecorated or is not currently visible,
|
||||
// then check each point is within the visible part of the screen
|
||||
if (!target.isVisible() || isTargetUndecorated()) {
|
||||
int screenX = sB.x + sIn.left;
|
||||
int screenY = sB.y + sIn.top;
|
||||
|
||||
// First make sure the size is withing the visible part of the screen
|
||||
if (newW > screenW) {
|
||||
newW = screenW;
|
||||
}
|
||||
|
||||
if (newH > screenH) {
|
||||
newH = screenH;
|
||||
}
|
||||
|
||||
// Tweak the location if needed
|
||||
if (newX < screenX) {
|
||||
newX = screenX;
|
||||
} else if (newX + newW > screenX + screenW) {
|
||||
newX = screenX + screenW - newW;
|
||||
}
|
||||
|
||||
if (newY < screenY) {
|
||||
newY = screenY;
|
||||
} else if (newY + newH > screenY + screenH) {
|
||||
newY = screenY + screenH - newH;
|
||||
}
|
||||
} else {
|
||||
int maxW = Math.max(screenW, sysW);
|
||||
int maxH = Math.max(screenH, sysH);
|
||||
|
||||
// Make sure the size is withing the visible part of the screen
|
||||
// OR is less that the current size of the window.
|
||||
if (newW > maxW) {
|
||||
newW = maxW;
|
||||
}
|
||||
|
||||
if (newH > maxH) {
|
||||
newH = maxH;
|
||||
}
|
||||
}
|
||||
|
||||
return new Rectangle(newX, newY, newW, newH);
|
||||
}
|
||||
|
||||
public void setBounds(int x, int y, int width, int height, int op) {
|
||||
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||
super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -108,11 +108,18 @@ class WDialogPeer extends WWindowPeer implements DialogPeer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isTargetUndecorated() {
|
||||
return ((Dialog)target).isUndecorated();
|
||||
}
|
||||
|
||||
public void reshape(int x, int y, int width, int height) {
|
||||
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||
|
||||
if (((Dialog)target).isUndecorated()) {
|
||||
super.reshape(x,y,width,height);
|
||||
super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
|
||||
} else {
|
||||
reshapeFrame(x,y,width,height);
|
||||
reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,4 +65,10 @@ public class WEmbeddedFramePeer extends WFramePeer {
|
||||
public native Rectangle getBoundsPrivate();
|
||||
|
||||
public native void synthesizeWmActivate(boolean doActivate);
|
||||
|
||||
@Override
|
||||
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||
// We don't constrain the bounds of the EmbeddedFrames
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
@ -64,11 +64,18 @@ class WFramePeer extends WWindowPeer implements FramePeer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isTargetUndecorated() {
|
||||
return ((Frame)target).isUndecorated();
|
||||
}
|
||||
|
||||
public void reshape(int x, int y, int width, int height) {
|
||||
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||
|
||||
if (((Frame)target).isUndecorated()) {
|
||||
super.reshape(x,y,width,height);
|
||||
super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
|
||||
} else {
|
||||
reshapeFrame(x,y,width,height);
|
||||
reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,8 +30,12 @@ abstract class WObjectPeer {
|
||||
initIDs();
|
||||
}
|
||||
|
||||
long pData; // The Windows handle for the native widget.
|
||||
Object target; // The associated AWT object.
|
||||
// The Windows handle for the native widget.
|
||||
long pData;
|
||||
// if the native peer has been destroyed
|
||||
boolean destroyed = false;
|
||||
// The associated AWT object.
|
||||
Object target;
|
||||
|
||||
private volatile boolean disposed;
|
||||
|
||||
|
@ -434,6 +434,97 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
|
||||
private native void nativeGrab();
|
||||
private native void nativeUngrab();
|
||||
|
||||
private final boolean hasWarningWindow() {
|
||||
return ((Window)target).getWarningString() != null;
|
||||
}
|
||||
|
||||
boolean isTargetUndecorated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// These are the peer bounds. They get updated at:
|
||||
// 1. the WWindowPeer.setBounds() method.
|
||||
// 2. the native code (on WM_SIZE/WM_MOVE)
|
||||
private volatile int sysX = 0;
|
||||
private volatile int sysY = 0;
|
||||
private volatile int sysW = 0;
|
||||
private volatile int sysH = 0;
|
||||
|
||||
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||
// We don't restrict the setBounds() operation if the code is trusted.
|
||||
if (!hasWarningWindow()) {
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
|
||||
int newX = x;
|
||||
int newY = y;
|
||||
int newW = width;
|
||||
int newH = height;
|
||||
|
||||
GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
|
||||
Rectangle sB = gc.getBounds();
|
||||
Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
|
||||
|
||||
int screenW = sB.width - sIn.left - sIn.right;
|
||||
int screenH = sB.height - sIn.top - sIn.bottom;
|
||||
|
||||
// If it's undecorated or is not currently visible
|
||||
if (!((Window)target).isVisible() || isTargetUndecorated()) {
|
||||
// Now check each point is within the visible part of the screen
|
||||
int screenX = sB.x + sIn.left;
|
||||
int screenY = sB.y + sIn.top;
|
||||
|
||||
// First make sure the size is withing the visible part of the screen
|
||||
if (newW > screenW) {
|
||||
newW = screenW;
|
||||
}
|
||||
|
||||
if (newH > screenH) {
|
||||
newH = screenH;
|
||||
}
|
||||
|
||||
// Tweak the location if needed
|
||||
if (newX < screenX) {
|
||||
newX = screenX;
|
||||
} else if (newX + newW > screenX + screenW) {
|
||||
newX = screenX + screenW - newW;
|
||||
}
|
||||
|
||||
if (newY < screenY) {
|
||||
newY = screenY;
|
||||
} else if (newY + newH > screenY + screenH) {
|
||||
newY = screenY + screenH - newH;
|
||||
}
|
||||
} else {
|
||||
int maxW = Math.max(screenW, sysW);
|
||||
int maxH = Math.max(screenH, sysH);
|
||||
|
||||
// Make sure the size is withing the visible part of the screen
|
||||
// OR less that the current size of the window.
|
||||
if (newW > maxW) {
|
||||
newW = maxW;
|
||||
}
|
||||
|
||||
if (newH > maxH) {
|
||||
newH = maxH;
|
||||
}
|
||||
}
|
||||
|
||||
return new Rectangle(newX, newY, newW, newH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(int x, int y, int width, int height, int op) {
|
||||
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||
|
||||
sysX = newBounds.x;
|
||||
sysY = newBounds.y;
|
||||
sysW = newBounds.width;
|
||||
sysH = newBounds.height;
|
||||
|
||||
super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
|
||||
}
|
||||
|
||||
/*
|
||||
* The method maps the list of the active windows to the window's AppContext,
|
||||
* then the method registers ActiveWindowListener, GuiDisposedListener listeners;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2008 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
|
||||
@ -47,7 +47,7 @@ typedef AwtObject* PDATA;
|
||||
JNI_CHECK_NULL_GOTO(peer, "peer", where); \
|
||||
pData = JNI_GET_PDATA(peer); \
|
||||
if (pData == NULL) { \
|
||||
JNU_ThrowNullPointerException(env, "null pData"); \
|
||||
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
|
||||
goto where; \
|
||||
} \
|
||||
}
|
||||
@ -63,7 +63,7 @@ typedef AwtObject* PDATA;
|
||||
JNI_CHECK_NULL_RETURN(peer, "peer"); \
|
||||
pData = JNI_GET_PDATA(peer); \
|
||||
if (pData == NULL) { \
|
||||
JNU_ThrowNullPointerException(env, "null pData"); \
|
||||
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
@ -96,7 +96,7 @@ typedef AwtObject* PDATA;
|
||||
JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \
|
||||
pData = JNI_GET_PDATA(peer); \
|
||||
if (pData == NULL) { \
|
||||
JNU_ThrowNullPointerException(env, "null pData"); \
|
||||
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
@ -105,16 +105,27 @@ typedef AwtObject* PDATA;
|
||||
JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \
|
||||
pData = JNI_GET_PDATA(peer); \
|
||||
if (pData == NULL) { \
|
||||
JNU_ThrowNullPointerException(env, "null pData"); \
|
||||
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
|
||||
return val; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) { \
|
||||
jboolean destroyed = JNI_GET_DESTROYED(peer); \
|
||||
if (destroyed != JNI_TRUE) { \
|
||||
JNU_ThrowNullPointerException(env, "null pData"); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID)
|
||||
#define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID)
|
||||
|
||||
#define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \
|
||||
AwtObject::pDataID, \
|
||||
(jlong)data)
|
||||
AwtObject::pDataID, \
|
||||
(jlong)data)
|
||||
#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer, \
|
||||
AwtObject::destroyedID, \
|
||||
JNI_TRUE)
|
||||
/* /NEW JNI */
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2008 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
|
||||
@ -226,6 +226,8 @@ BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE;
|
||||
CriticalSection windowMoveLock;
|
||||
BOOL windowMoveLockHeld = FALSE;
|
||||
|
||||
int AwtComponent::sm_wheelRotationAmount = 0;
|
||||
|
||||
/************************************************************************
|
||||
* AwtComponent methods
|
||||
*/
|
||||
@ -2074,6 +2076,8 @@ MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus)
|
||||
sm_realFocusOpposite = NULL;
|
||||
}
|
||||
|
||||
sm_wheelRotationAmount = 0;
|
||||
|
||||
SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus);
|
||||
|
||||
return mrDoDefault;
|
||||
@ -2105,6 +2109,7 @@ MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus)
|
||||
}
|
||||
|
||||
sm_focusOwner = NULL;
|
||||
sm_wheelRotationAmount = 0;
|
||||
|
||||
SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus);
|
||||
return mrDoDefault;
|
||||
@ -2190,8 +2195,11 @@ AwtComponent::AwtSetFocus()
|
||||
DWORD fgProcessID;
|
||||
::GetWindowThreadProcessId(fgWindow, &fgProcessID);
|
||||
|
||||
if (fgProcessID != ::GetCurrentProcessId()) {
|
||||
// fix for 6458497. we shouldn't request focus if it is out of our application.
|
||||
if (fgProcessID != ::GetCurrentProcessId()
|
||||
&& !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID))
|
||||
{
|
||||
// fix for 6458497. we shouldn't request focus if it is out of both
|
||||
// our and embedder process.
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -2619,9 +2627,13 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y,
|
||||
BOOL result;
|
||||
UINT platformLines;
|
||||
|
||||
sm_wheelRotationAmount += wheelRotation;
|
||||
|
||||
// AWT interprets wheel rotation differently than win32, so we need to
|
||||
// decode wheel amount.
|
||||
jint newWheelRotation = wheelRotation / (-1 * WHEEL_DELTA);
|
||||
jint roundedWheelRotation = sm_wheelRotationAmount / (-1 * WHEEL_DELTA);
|
||||
jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA);
|
||||
|
||||
MSG msg;
|
||||
|
||||
if (IS_WIN95 && !IS_WIN98) {
|
||||
@ -2654,7 +2666,9 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y,
|
||||
|
||||
SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(),
|
||||
eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType,
|
||||
scrollLines, newWheelRotation, &msg);
|
||||
scrollLines, roundedWheelRotation, preciseWheelRotation, &msg);
|
||||
|
||||
sm_wheelRotationAmount %= WHEEL_DELTA;
|
||||
return mrConsume;
|
||||
}
|
||||
|
||||
@ -4986,8 +5000,8 @@ void
|
||||
AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
|
||||
jint modifiers, jint clickCount,
|
||||
jboolean popupTrigger, jint scrollType,
|
||||
jint scrollAmount, jint wheelRotation,
|
||||
MSG *pMsg)
|
||||
jint scrollAmount, jint roundedWheelRotation,
|
||||
jdouble preciseWheelRotation, MSG *pMsg)
|
||||
{
|
||||
/* Code based not so loosely on AwtComponent::SendMouseEvent */
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
@ -5015,7 +5029,7 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
|
||||
if (mouseWheelEventConst == NULL) {
|
||||
mouseWheelEventConst =
|
||||
env->GetMethodID(mouseWheelEventCls, "<init>",
|
||||
"(Ljava/awt/Component;IJIIIIZIII)V");
|
||||
"(Ljava/awt/Component;IJIIIIIIZIIID)V");
|
||||
DASSERT(mouseWheelEventConst);
|
||||
}
|
||||
if (env->EnsureLocalCapacity(2) < 0) {
|
||||
@ -5023,14 +5037,16 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
|
||||
}
|
||||
jobject target = GetTarget(env);
|
||||
DTRACE_PRINTLN("creating MWE in JNI");
|
||||
|
||||
jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls,
|
||||
mouseWheelEventConst,
|
||||
target,
|
||||
id, when, modifiers,
|
||||
x+insets.left, y+insets.top,
|
||||
0, 0,
|
||||
clickCount, popupTrigger,
|
||||
scrollType, scrollAmount,
|
||||
wheelRotation);
|
||||
roundedWheelRotation, preciseWheelRotation);
|
||||
if (safe_ExceptionOccurred(env)) {
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
@ -5400,6 +5416,7 @@ void AwtComponent::UnlinkObjects()
|
||||
if (m_peerObject) {
|
||||
env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);
|
||||
JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
|
||||
JNI_SET_DESTROYED(m_peerObject);
|
||||
env->DeleteGlobalRef(m_peerObject);
|
||||
m_peerObject = NULL;
|
||||
}
|
||||
@ -5408,7 +5425,13 @@ void AwtComponent::UnlinkObjects()
|
||||
void AwtComponent::Enable(BOOL bEnable)
|
||||
{
|
||||
sm_suppressFocusAndActivation = TRUE;
|
||||
|
||||
if (bEnable && IsTopLevel()) {
|
||||
// we should not enable blocked toplevels
|
||||
bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
|
||||
}
|
||||
::EnableWindow(GetHWnd(), bEnable);
|
||||
|
||||
sm_suppressFocusAndActivation = FALSE;
|
||||
CriticalSection::Lock l(GetLock());
|
||||
VerifyState();
|
||||
|
@ -392,7 +392,7 @@ public:
|
||||
jint modifiers, jint clickCount,
|
||||
jboolean popupTrigger, jint scrollType,
|
||||
jint scrollAmount, jint wheelRotation,
|
||||
MSG *msg = NULL);
|
||||
jdouble preciseWheelRotation, MSG *msg = NULL);
|
||||
|
||||
/*
|
||||
* Allocate and initialize a new java.awt.event.FocusEvent, and
|
||||
@ -785,7 +785,9 @@ private:
|
||||
int windowMoveLockPosCX;
|
||||
int windowMoveLockPosCY;
|
||||
|
||||
private:
|
||||
// 6524352: support finer-resolution
|
||||
static int sm_wheelRotationAmount;
|
||||
|
||||
/*
|
||||
* The association list of children's IDs and corresponding components.
|
||||
* Some components like Choice or List are required their sizes while
|
||||
|
@ -273,6 +273,10 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
|
||||
{
|
||||
HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
|
||||
HWND topMostBlocker = blocker;
|
||||
HWND prevForegroundWindow = ::GetForegroundWindow();
|
||||
if (::IsWindow(blocker)) {
|
||||
::BringWindowToTop(hWnd);
|
||||
}
|
||||
while (::IsWindow(blocker)) {
|
||||
topMostBlocker = blocker;
|
||||
::BringWindowToTop(blocker);
|
||||
@ -282,7 +286,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
|
||||
// no beep/flash if the mouse was clicked in the taskbar menu
|
||||
// or the dialog is currently inactive
|
||||
if ((::WindowFromPoint(mhs->pt) == hWnd) &&
|
||||
(::GetForegroundWindow() == topMostBlocker))
|
||||
(prevForegroundWindow == topMostBlocker))
|
||||
{
|
||||
::MessageBeep(MB_OK);
|
||||
// some heuristics: 3 times x 64 milliseconds
|
||||
@ -292,6 +296,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
|
||||
::BringWindowToTop(topMostBlocker);
|
||||
::SetForegroundWindow(topMostBlocker);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2008 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
|
||||
@ -221,8 +221,7 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent)
|
||||
|
||||
// Update target's dimensions to reflect this embedded window.
|
||||
::GetClientRect(frame->m_hwnd, &rect);
|
||||
::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect,
|
||||
2);
|
||||
::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2);
|
||||
|
||||
env->SetIntField(target, AwtComponent::xID, rect.left);
|
||||
env->SetIntField(target, AwtComponent::yID, rect.top);
|
||||
@ -231,6 +230,7 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent)
|
||||
env->SetIntField(target, AwtComponent::heightID,
|
||||
rect.bottom-rect.top);
|
||||
frame->InitPeerGraphicsConfig(env, self);
|
||||
AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent);
|
||||
} else {
|
||||
jint state = env->GetIntField(target, AwtFrame::stateID);
|
||||
DWORD exStyle;
|
||||
@ -408,8 +408,9 @@ MsgRouting AwtFrame::WmShowWindow(BOOL show, UINT status)
|
||||
* message. This breaks Java focus. To workaround the problem we
|
||||
* set the toplevel being shown foreground programmatically.
|
||||
* The fix is localized to non-foreground process case only.
|
||||
* (See also: 6599270)
|
||||
*/
|
||||
if (show == TRUE && status == 0) {
|
||||
if (!IsEmbeddedFrame() && show == TRUE && status == 0) {
|
||||
HWND fgHWnd = ::GetForegroundWindow();
|
||||
if (fgHWnd != NULL) {
|
||||
DWORD fgProcessID;
|
||||
@ -495,7 +496,7 @@ MsgRouting AwtFrame::WmMouseMove(UINT flags, int x, int y) {
|
||||
|
||||
::SetWindowPos(GetHWnd(), NULL, r.left, r.top,
|
||||
r.right-r.left, r.bottom-r.top,
|
||||
SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER |
|
||||
SWP_NOACTIVATE | SWP_NOZORDER |
|
||||
SWP_NOCOPYBITS | SWP_DEFERERASE);
|
||||
}
|
||||
return mrConsume;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2008 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,6 +39,7 @@ static BOOL reportEvents = FALSE;
|
||||
*/
|
||||
|
||||
jfieldID AwtObject::pDataID;
|
||||
jfieldID AwtObject::destroyedID;
|
||||
jfieldID AwtObject::targetID;
|
||||
jclass AwtObject::wObjectPeerClass;
|
||||
jmethodID AwtObject::getPeerForTargetMID;
|
||||
@ -223,6 +224,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) {
|
||||
|
||||
AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls);
|
||||
AwtObject::pDataID = env->GetFieldID(cls, "pData", "J");
|
||||
AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z");
|
||||
AwtObject::targetID = env->GetFieldID(cls, "target",
|
||||
"Ljava/lang/Object;");
|
||||
|
||||
@ -233,6 +235,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) {
|
||||
AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;");
|
||||
|
||||
DASSERT(AwtObject::pDataID != NULL);
|
||||
DASSERT(AwtObject::destroyedID != NULL);
|
||||
DASSERT(AwtObject::targetID != NULL);
|
||||
DASSERT(AwtObject::getPeerForTargetMID != NULL);
|
||||
DASSERT(AwtObject::createErrorID != NULL);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2008 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
|
||||
@ -51,6 +51,7 @@ public:
|
||||
|
||||
/* sun.awt.windows.WObjectPeer field and method ids */
|
||||
static jfieldID pDataID;
|
||||
static jfieldID destroyedID;
|
||||
static jfieldID targetID;
|
||||
|
||||
static jmethodID getPeerForTargetMID;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -354,6 +354,7 @@ AwtToolkit::AwtToolkit() {
|
||||
m_dllHandle = NULL;
|
||||
|
||||
m_displayChanged = FALSE;
|
||||
m_embedderProcessID = 0;
|
||||
|
||||
// XXX: keyboard mapping should really be moved out of AwtComponent
|
||||
AwtComponent::InitDynamicKeyMapTable();
|
||||
@ -1442,49 +1443,17 @@ void hang_if_shutdown(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a reference to the class java.awt.Component.
|
||||
*/
|
||||
jclass
|
||||
getComponentClass(JNIEnv *env)
|
||||
// for now we support only one embedder, but should be ready for future
|
||||
void AwtToolkit::RegisterEmbedderProcessId(HWND embedder)
|
||||
{
|
||||
static jclass componentCls = NULL;
|
||||
|
||||
// get global reference of java/awt/Component class (run only once)
|
||||
if (componentCls == NULL) {
|
||||
jclass componentClsLocal = env->FindClass("java/awt/Component");
|
||||
DASSERT(componentClsLocal != NULL);
|
||||
if (componentClsLocal == NULL) {
|
||||
/* exception already thrown */
|
||||
return NULL;
|
||||
}
|
||||
componentCls = (jclass)env->NewGlobalRef(componentClsLocal);
|
||||
env->DeleteLocalRef(componentClsLocal);
|
||||
if (m_embedderProcessID) {
|
||||
// we already set embedder process and do not expect
|
||||
// two different processes to embed the same AwtToolkit
|
||||
return;
|
||||
}
|
||||
return componentCls;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns a reference to the class java.awt.MenuComponent.
|
||||
*/
|
||||
jclass
|
||||
getMenuComponentClass(JNIEnv *env)
|
||||
{
|
||||
static jclass menuComponentCls = NULL;
|
||||
|
||||
// get global reference of java/awt/MenuComponent class (run only once)
|
||||
if (menuComponentCls == NULL) {
|
||||
jclass menuComponentClsLocal = env->FindClass("java/awt/MenuComponent");
|
||||
DASSERT(menuComponentClsLocal != NULL);
|
||||
if (menuComponentClsLocal == NULL) {
|
||||
/* exception already thrown */
|
||||
return NULL;
|
||||
}
|
||||
menuComponentCls = (jclass)env->NewGlobalRef(menuComponentClsLocal);
|
||||
env->DeleteLocalRef(menuComponentClsLocal);
|
||||
}
|
||||
return menuComponentCls;
|
||||
embedder = ::GetAncestor(embedder, GA_ROOT);
|
||||
::GetWindowThreadProcessId(embedder, &m_embedderProcessID);
|
||||
}
|
||||
|
||||
JNIEnv* AwtToolkit::m_env;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2008 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
|
||||
@ -426,10 +426,17 @@ private:
|
||||
*/
|
||||
private:
|
||||
BOOL m_displayChanged; /* Tracks displayChanged events */
|
||||
// 0 means we are not embedded.
|
||||
DWORD m_embedderProcessID;
|
||||
|
||||
public:
|
||||
BOOL HasDisplayChanged() { return m_displayChanged; }
|
||||
void ResetDisplayChanged() { m_displayChanged = FALSE; }
|
||||
void RegisterEmbedderProcessId(HWND);
|
||||
BOOL IsEmbedderProcessId(const DWORD processID) const
|
||||
{
|
||||
return m_embedderProcessID && (processID == m_embedderProcessID);
|
||||
}
|
||||
|
||||
private:
|
||||
static JNIEnv *m_env;
|
||||
|
@ -125,6 +125,11 @@ jfieldID AwtWindow::autoRequestFocusID;
|
||||
jclass AwtWindow::wwindowPeerCls;
|
||||
jmethodID AwtWindow::getActiveWindowsMID;
|
||||
|
||||
jfieldID AwtWindow::sysXID;
|
||||
jfieldID AwtWindow::sysYID;
|
||||
jfieldID AwtWindow::sysWID;
|
||||
jfieldID AwtWindow::sysHID;
|
||||
|
||||
int AwtWindow::ms_instanceCounter = 0;
|
||||
HHOOK AwtWindow::ms_hCBTFilter;
|
||||
AwtWindow * AwtWindow::m_grabbedWindow = NULL;
|
||||
@ -180,7 +185,6 @@ void AwtWindow::Dispose()
|
||||
}
|
||||
|
||||
::RemoveProp(GetHWnd(), ModalBlockerProp);
|
||||
::RemoveProp(GetHWnd(), ModalSaveWSEXProp);
|
||||
|
||||
if (m_grabbedWindow == this) {
|
||||
Ungrab();
|
||||
@ -330,8 +334,11 @@ LRESULT CALLBACK AwtWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
|
||||
AwtComponent *comp = AwtComponent::GetComponent((HWND)wParam);
|
||||
|
||||
if (comp != NULL && comp->IsTopLevel() && !((AwtWindow*)comp)->IsFocusableWindow()) {
|
||||
return 1; // Don't change focus/activation.
|
||||
if (comp != NULL && comp->IsTopLevel()) {
|
||||
AwtWindow* win = (AwtWindow*)comp;
|
||||
if (!win->IsFocusableWindow() || win->m_filterFocusAndActivation) {
|
||||
return 1; // Don't change focus/activation.
|
||||
}
|
||||
}
|
||||
}
|
||||
return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
|
||||
@ -1053,6 +1060,8 @@ MsgRouting AwtWindow::WmMove(int x, int y)
|
||||
|
||||
(env)->SetIntField(target, AwtComponent::xID, rect.left);
|
||||
(env)->SetIntField(target, AwtComponent::yID, rect.top);
|
||||
(env)->SetIntField(peer, AwtWindow::sysXID, rect.left);
|
||||
(env)->SetIntField(peer, AwtWindow::sysYID, rect.top);
|
||||
SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
|
||||
|
||||
env->DeleteLocalRef(target);
|
||||
@ -1116,6 +1125,11 @@ MsgRouting AwtWindow::WmSize(UINT type, int w, int h)
|
||||
|
||||
(env)->SetIntField(target, AwtComponent::widthID, newWidth);
|
||||
(env)->SetIntField(target, AwtComponent::heightID, newHeight);
|
||||
|
||||
jobject peer = GetPeer(env);
|
||||
(env)->SetIntField(peer, AwtWindow::sysWID, newWidth);
|
||||
(env)->SetIntField(peer, AwtWindow::sysHID, newHeight);
|
||||
|
||||
if (!AwtWindow::IsResizing()) {
|
||||
WindowResized();
|
||||
}
|
||||
@ -1455,20 +1469,17 @@ void AwtWindow::SetModalBlocker(HWND window, HWND blocker) {
|
||||
if (!::IsWindow(window)) {
|
||||
return;
|
||||
}
|
||||
DWORD exStyle = ::GetWindowLong(window, GWL_EXSTYLE);
|
||||
|
||||
if (::IsWindow(blocker)) {
|
||||
// save WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
|
||||
DWORD saveStyle = exStyle & (AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW);
|
||||
::SetProp(window, ModalSaveWSEXProp, reinterpret_cast<HANDLE>(saveStyle));
|
||||
::SetWindowLong(window, GWL_EXSTYLE, (exStyle | AWT_WS_EX_NOACTIVATE) & ~WS_EX_APPWINDOW);
|
||||
::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
|
||||
::EnableWindow(window, FALSE);
|
||||
} else {
|
||||
// restore WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
|
||||
DWORD saveStyle = reinterpret_cast<DWORD>(::GetProp(window, ModalSaveWSEXProp));
|
||||
::SetWindowLong(window, GWL_EXSTYLE,
|
||||
(exStyle & ~(AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW)) | saveStyle);
|
||||
::RemoveProp(window, ModalSaveWSEXProp);
|
||||
::RemoveProp(window, ModalBlockerProp);
|
||||
AwtComponent *comp = AwtComponent::GetComponent(window);
|
||||
// we don't expect to be called with non-java HWNDs
|
||||
DASSERT(comp && comp->IsTopLevel());
|
||||
// we should not unblock disabled toplevels
|
||||
::EnableWindow(window, comp->isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1754,17 +1765,22 @@ void AwtWindow::_ReshapeFrame(void *param)
|
||||
// Fix for 4459064 : do not enforce thresholds for embedded frames
|
||||
if (!p->IsEmbeddedFrame())
|
||||
{
|
||||
jobject peer = p->GetPeer(env);
|
||||
int minWidth = ::GetSystemMetrics(SM_CXMIN);
|
||||
int minHeight = ::GetSystemMetrics(SM_CYMIN);
|
||||
if (w < minWidth)
|
||||
{
|
||||
env->SetIntField(target, AwtComponent::widthID,
|
||||
w = minWidth);
|
||||
env->SetIntField(peer, AwtWindow::sysWID,
|
||||
w);
|
||||
}
|
||||
if (h < minHeight)
|
||||
{
|
||||
env->SetIntField(target, AwtComponent::heightID,
|
||||
h = minHeight);
|
||||
env->SetIntField(peer, AwtWindow::sysHID,
|
||||
h);
|
||||
}
|
||||
}
|
||||
env->DeleteLocalRef(target);
|
||||
@ -2148,6 +2164,11 @@ Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls)
|
||||
env->GetStaticMethodID(cls, "getActiveWindowHandles", "()[J");
|
||||
DASSERT(AwtWindow::getActiveWindowsMID != NULL);
|
||||
|
||||
AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I");
|
||||
AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I");
|
||||
AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I");
|
||||
AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I");
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
// property name tagging windows disabled by modality
|
||||
static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp");
|
||||
static LPCTSTR ModalSaveWSEXProp = TEXT("SunAwtModalSaveWSEXProp");
|
||||
static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp");
|
||||
|
||||
#ifndef WH_MOUSE_LL
|
||||
@ -63,6 +62,12 @@ public:
|
||||
/* long[] getActiveWindowHandles() method in WWindowPeer */
|
||||
static jmethodID getActiveWindowsMID;
|
||||
|
||||
// The coordinates at the peer.
|
||||
static jfieldID sysXID;
|
||||
static jfieldID sysYID;
|
||||
static jfieldID sysWID;
|
||||
static jfieldID sysHID;
|
||||
|
||||
AwtWindow();
|
||||
virtual ~AwtWindow();
|
||||
|
||||
|
@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright 2008 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 6581927
|
||||
@summary Non-focusable frame should honor the size of the frame buttons/decorations when resizing
|
||||
@library ../../regtesthelpers
|
||||
@build Util
|
||||
@author anthony.petrov@...: area=awt.toplevel
|
||||
@run main NonFocusableResizableTooSmall
|
||||
*/
|
||||
|
||||
/**
|
||||
* NonFocusableResizableTooSmall.java
|
||||
*
|
||||
* summary: Non-focusable frame should honor the size of the frame buttons/decorations when resizing
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import test.java.awt.regtesthelpers.Util;
|
||||
|
||||
public class NonFocusableResizableTooSmall
|
||||
{
|
||||
|
||||
//*** test-writer defined static variables go here ***
|
||||
|
||||
|
||||
private static void init()
|
||||
{
|
||||
//*** Create instructions for the user here ***
|
||||
|
||||
String[] instructions =
|
||||
{
|
||||
"This is an AUTOMATIC test, simply wait until it is done.",
|
||||
"The result (passed or failed) will be shown in the",
|
||||
"message window below."
|
||||
};
|
||||
Sysout.createDialog( );
|
||||
Sysout.printInstructions( instructions );
|
||||
|
||||
final Frame frame = new Frame();
|
||||
frame.setFocusableWindowState(false);
|
||||
frame.setSize(200, 100);
|
||||
frame.setVisible(true);
|
||||
|
||||
final Robot robot = Util.createRobot();
|
||||
robot.setAutoDelay(20);
|
||||
|
||||
// To be sure the window is shown and packed
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
final Insets insets = frame.getInsets();
|
||||
System.out.println("The insets of the frame: " + insets);
|
||||
if (insets.right == 0 || insets.bottom == 0) {
|
||||
System.out.println("The test environment must have non-zero right & bottom insets!");
|
||||
pass();
|
||||
return;
|
||||
}
|
||||
|
||||
// Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip")
|
||||
final Rectangle bounds1 = frame.getBounds();
|
||||
System.out.println("The bounds before resizing: " + bounds1);
|
||||
|
||||
robot.mouseMove(bounds1.x + bounds1.width - 1, bounds1.y + bounds1.height - 1);
|
||||
|
||||
// ... and start resizing to some very small
|
||||
robot.mousePress( InputEvent.BUTTON1_MASK );
|
||||
|
||||
// Now resize the frame so that the width is smaller
|
||||
// than the widths of the left and the right borders.
|
||||
// The sum of widths of the icon of the frame + the control-buttons
|
||||
// (close, minimize, etc.) should be definitely larger!
|
||||
robot.mouseMove(bounds1.x + insets.left + insets.right - 5, bounds1.y + bounds1.height - 1);
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
robot.mouseRelease( InputEvent.BUTTON1_MASK );
|
||||
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
// Check the current bounds of the frame
|
||||
final Rectangle bounds2 = frame.getBounds();
|
||||
System.out.println("The bounds after resizing: " + bounds2);
|
||||
|
||||
if (bounds2.width <= (insets.left + insets.right)) {
|
||||
fail("The frame has been resized to very small.");
|
||||
}
|
||||
pass();
|
||||
}//End init()
|
||||
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Standard Test Machinery Section
|
||||
* DO NOT modify anything in this section -- it's a
|
||||
* standard chunk of code which has all of the
|
||||
* synchronisation necessary for the test harness.
|
||||
* By keeping it the same in all tests, it is easier
|
||||
* to read and understand someone else's test, as
|
||||
* well as insuring that all tests behave correctly
|
||||
* with the test harness.
|
||||
* There is a section following this for test-
|
||||
* classes
|
||||
******************************************************/
|
||||
private static boolean theTestPassed = false;
|
||||
private static boolean testGeneratedInterrupt = false;
|
||||
private static String failureMessage = "";
|
||||
|
||||
private static Thread mainThread = null;
|
||||
|
||||
private static int sleepTime = 300000;
|
||||
|
||||
// Not sure about what happens if multiple of this test are
|
||||
// instantiated in the same VM. Being static (and using
|
||||
// static vars), it aint gonna work. Not worrying about
|
||||
// it for now.
|
||||
public static void main( String args[] ) throws InterruptedException
|
||||
{
|
||||
mainThread = Thread.currentThread();
|
||||
try
|
||||
{
|
||||
init();
|
||||
}
|
||||
catch( TestPassedException e )
|
||||
{
|
||||
//The test passed, so just return from main and harness will
|
||||
// interepret this return as a pass
|
||||
return;
|
||||
}
|
||||
//At this point, neither test pass nor test fail has been
|
||||
// called -- either would have thrown an exception and ended the
|
||||
// test, so we know we have multiple threads.
|
||||
|
||||
//Test involves other threads, so sleep and wait for them to
|
||||
// called pass() or fail()
|
||||
try
|
||||
{
|
||||
Thread.sleep( sleepTime );
|
||||
//Timed out, so fail the test
|
||||
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
//The test harness may have interrupted the test. If so, rethrow the exception
|
||||
// so that the harness gets it and deals with it.
|
||||
if( ! testGeneratedInterrupt ) throw e;
|
||||
|
||||
//reset flag in case hit this code more than once for some reason (just safety)
|
||||
testGeneratedInterrupt = false;
|
||||
|
||||
if ( theTestPassed == false )
|
||||
{
|
||||
throw new RuntimeException( failureMessage );
|
||||
}
|
||||
}
|
||||
|
||||
}//main
|
||||
|
||||
public static synchronized void setTimeoutTo( int seconds )
|
||||
{
|
||||
sleepTime = seconds * 1000;
|
||||
}
|
||||
|
||||
public static synchronized void pass()
|
||||
{
|
||||
Sysout.println( "The test passed." );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//first check if this is executing in main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//Still in the main thread, so set the flag just for kicks,
|
||||
// and throw a test passed exception which will be caught
|
||||
// and end the test.
|
||||
theTestPassed = true;
|
||||
throw new TestPassedException();
|
||||
}
|
||||
theTestPassed = true;
|
||||
testGeneratedInterrupt = true;
|
||||
mainThread.interrupt();
|
||||
}//pass()
|
||||
|
||||
public static synchronized void fail()
|
||||
{
|
||||
//test writer didn't specify why test failed, so give generic
|
||||
fail( "it just plain failed! :-)" );
|
||||
}
|
||||
|
||||
public static synchronized void fail( String whyFailed )
|
||||
{
|
||||
Sysout.println( "The test failed: " + whyFailed );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//check if this called from main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//If main thread, fail now 'cause not sleeping
|
||||
throw new RuntimeException( whyFailed );
|
||||
}
|
||||
theTestPassed = false;
|
||||
testGeneratedInterrupt = true;
|
||||
failureMessage = whyFailed;
|
||||
mainThread.interrupt();
|
||||
}//fail()
|
||||
|
||||
}// class NonFocusableResizableTooSmall
|
||||
|
||||
//This exception is used to exit from any level of call nesting
|
||||
// when it's determined that the test has passed, and immediately
|
||||
// end the test.
|
||||
class TestPassedException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
||||
//*********** End Standard Test Machinery Section **********
|
||||
|
||||
|
||||
//************ Begin classes defined for the test ****************
|
||||
|
||||
// if want to make listeners, here is the recommended place for them, then instantiate
|
||||
// them in init()
|
||||
|
||||
/* Example of a class which may be written as part of a test
|
||||
class NewClass implements anInterface
|
||||
{
|
||||
static int newVar = 0;
|
||||
|
||||
public void eventDispatched(AWTEvent e)
|
||||
{
|
||||
//Counting events to see if we get enough
|
||||
eventCount++;
|
||||
|
||||
if( eventCount == 20 )
|
||||
{
|
||||
//got enough events, so pass
|
||||
|
||||
NonFocusableResizableTooSmall.pass();
|
||||
}
|
||||
else if( tries == 20 )
|
||||
{
|
||||
//tried too many times without getting enough events so fail
|
||||
|
||||
NonFocusableResizableTooSmall.fail();
|
||||
}
|
||||
|
||||
}// eventDispatched()
|
||||
|
||||
}// NewClass class
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//************** End classes defined for the test *******************
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
Standard Test Machinery
|
||||
DO NOT modify anything below -- it's a standard
|
||||
chunk of code whose purpose is to make user
|
||||
interaction uniform, and thereby make it simpler
|
||||
to read and understand someone else's test.
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery.
|
||||
It creates a dialog (with the instructions), and is the interface
|
||||
for sending text messages to the user.
|
||||
To print the instructions, send an array of strings to Sysout.createDialog
|
||||
WithInstructions method. Put one line of instructions per array entry.
|
||||
To display a message for the tester to see, simply call Sysout.println
|
||||
with the string to be displayed.
|
||||
This mimics System.out.println but works within the test harness as well
|
||||
as standalone.
|
||||
*/
|
||||
|
||||
class Sysout
|
||||
{
|
||||
private static TestDialog dialog;
|
||||
|
||||
public static void createDialogWithInstructions( String[] instructions )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
dialog.printInstructions( instructions );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
public static void createDialog( )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
String[] defInstr = { "Instructions will appear here. ", "" } ;
|
||||
dialog.printInstructions( defInstr );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
|
||||
public static void printInstructions( String[] instructions )
|
||||
{
|
||||
dialog.printInstructions( instructions );
|
||||
}
|
||||
|
||||
|
||||
public static void println( String messageIn )
|
||||
{
|
||||
dialog.displayMessage( messageIn );
|
||||
System.out.println(messageIn);
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery. It provides a place for the
|
||||
test instructions to be displayed, and a place for interactive messages
|
||||
to the user to be displayed.
|
||||
To have the test instructions displayed, see Sysout.
|
||||
To have a message to the user be displayed, see Sysout.
|
||||
Do not call anything in this dialog directly.
|
||||
*/
|
||||
class TestDialog extends Dialog
|
||||
{
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog( Frame frame, String name )
|
||||
{
|
||||
super( frame, name );
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||
add( "North", instructionsText );
|
||||
|
||||
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||
add("Center", messageText);
|
||||
|
||||
pack();
|
||||
|
||||
setVisible(true);
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions( String[] instructions )
|
||||
{
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText( "" );
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for( int i=0; i < instructions.length; i++ )
|
||||
{
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[ i ];
|
||||
while( remainingStr.length() > 0 )
|
||||
{
|
||||
//if longer than max then chop off first max chars to print
|
||||
if( remainingStr.length() >= maxStringLength )
|
||||
{
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf( ' ', maxStringLength - 1 );
|
||||
|
||||
if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring( 0, posOfSpace + 1 );
|
||||
remainingStr = remainingStr.substring( posOfSpace + 1 );
|
||||
}
|
||||
//else just print
|
||||
else
|
||||
{
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append( printStr + "\n" );
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage( String messageIn )
|
||||
{
|
||||
messageText.append( messageIn + "\n" );
|
||||
System.out.println(messageIn);
|
||||
}
|
||||
|
||||
}// TestDialog class
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2007 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 %W% %E%
|
||||
@bug 6598089
|
||||
@summary Tests restoring focus on a single disabled coponent
|
||||
@author Anton Tarasov: area=awt-focus
|
||||
@library ../../regtesthelpers
|
||||
@build Util
|
||||
@run main RestoreFocusOnDisabledComponentTest
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.applet.Applet;
|
||||
import test.java.awt.regtesthelpers.Util;
|
||||
|
||||
/*
|
||||
* The bug is not reproducible on Windows.
|
||||
*/
|
||||
public class RestoreFocusOnDisabledComponentTest extends Applet {
|
||||
Frame frame = new Frame("Frame") {public String toString() {return "FRAME";}};
|
||||
Button b0 = new Button("button0") {public String toString() {return "B-0";}};
|
||||
Button b1 = new Button("button1") {public String toString() {return "B-1";}};
|
||||
volatile int nFocused;
|
||||
Robot robot;
|
||||
|
||||
public static void main(String[] args) {
|
||||
RestoreFocusOnDisabledComponentTest app = new RestoreFocusOnDisabledComponentTest();
|
||||
app.init();
|
||||
app.start();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
robot = Util.createRobot();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
frame.add(b0);
|
||||
frame.add(b1);
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.pack();
|
||||
|
||||
frame.setVisible(true);
|
||||
|
||||
Util.waitForIdle(robot);
|
||||
KeyboardFocusManager.setCurrentKeyboardFocusManager(new DefaultKeyboardFocusManager() {
|
||||
public boolean dispatchEvent(AWTEvent e) {
|
||||
if (e.getID() == FocusEvent.FOCUS_GAINED) {
|
||||
// Trying to emulate timings. b1 should be disabled just by the time it gets
|
||||
// FOCUS_GAINED event. The latter is a result of disabling b0 that initiates
|
||||
// focus auto transfer.
|
||||
if (e.getSource() == b1) {
|
||||
b1.setEnabled(false);
|
||||
|
||||
} else if (e.getSource() == b0) {
|
||||
if (++nFocused > 10) {
|
||||
nFocused = -1;
|
||||
throw new TestFailedException("Focus went into busy loop!");
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.dispatchEvent(e);
|
||||
}
|
||||
});
|
||||
// Initiating focus auto transfer.
|
||||
// Focus will be requested to b1. When FOCUS_GAINED is being dispatched to b1, it will
|
||||
// be disabled. This will trigger focus restoring. Focus will be requested to b0 (the
|
||||
// last opposite component). When FOCUS_GAINED is being dispatched to b0, it will
|
||||
// also be disabled. However, the last opposite component (and the most recent focus owner)
|
||||
// will still be b0. When DKFM initiates focus restoring it should detect restoring
|
||||
// on the same component and break.
|
||||
b0.setEnabled(false);
|
||||
|
||||
Util.waitForIdle(robot);
|
||||
if (nFocused != -1) {
|
||||
System.out.println("Test passed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestFailedException extends RuntimeException {
|
||||
TestFailedException(String msg) {
|
||||
super("Test failed: " + msg);
|
||||
}
|
||||
}
|
||||
|
411
jdk/test/java/awt/Mixing/ValidBounds.java
Normal file
411
jdk/test/java/awt/Mixing/ValidBounds.java
Normal file
@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright 2007 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 6637796
|
||||
@summary Shape should be correctly updated on invalid components
|
||||
@author anthony.petrov@...: area=awt.mixing
|
||||
@library ../regtesthelpers
|
||||
@build Util
|
||||
@run main ValidBounds
|
||||
*/
|
||||
|
||||
/**
|
||||
* ValidBounds.java
|
||||
*
|
||||
* summary: Shape should be correctly updated on invalid components
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import test.java.awt.regtesthelpers.Util;
|
||||
|
||||
public class ValidBounds
|
||||
{
|
||||
|
||||
static volatile boolean clickPassed = false;
|
||||
|
||||
private static void init()
|
||||
{
|
||||
//*** Create instructions for the user here ***
|
||||
|
||||
String[] instructions =
|
||||
{
|
||||
"This is an AUTOMATIC test, simply wait until it is done.",
|
||||
"The result (passed or failed) will be shown in the",
|
||||
"message window below."
|
||||
};
|
||||
Sysout.createDialog( );
|
||||
Sysout.printInstructions( instructions );
|
||||
|
||||
|
||||
// Create the frame and the button
|
||||
Frame f = new Frame();
|
||||
f.setBounds(100, 100, 400, 300);
|
||||
|
||||
Button b = new Button("OK");
|
||||
|
||||
f.setLayout(null);
|
||||
f.add(b);
|
||||
b.setBounds(50, 50, 200, 50);
|
||||
|
||||
b.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent e) {
|
||||
clickPassed = true;
|
||||
}
|
||||
});
|
||||
|
||||
f.setVisible(true);
|
||||
|
||||
// Let's make the button much smaller first...
|
||||
Robot robot = Util.createRobot();
|
||||
robot.setAutoDelay(20);
|
||||
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
b.setBounds(50, 50, 5, 5);
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
// ... and now let's enlarge it.
|
||||
b.setBounds(50, 50, 200, 50);
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
// If the button doesn't receive the click, it means that the test
|
||||
// failed: the shape of the button was not enlarged.
|
||||
Point heavyLoc = b.getLocationOnScreen();
|
||||
robot.mouseMove(heavyLoc.x + 20, heavyLoc.y + 20);
|
||||
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
if (clickPassed) {
|
||||
pass();
|
||||
} else {
|
||||
fail("The button cannot be clicked.");
|
||||
}
|
||||
}//End init()
|
||||
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Standard Test Machinery Section
|
||||
* DO NOT modify anything in this section -- it's a
|
||||
* standard chunk of code which has all of the
|
||||
* synchronisation necessary for the test harness.
|
||||
* By keeping it the same in all tests, it is easier
|
||||
* to read and understand someone else's test, as
|
||||
* well as insuring that all tests behave correctly
|
||||
* with the test harness.
|
||||
* There is a section following this for test-
|
||||
* classes
|
||||
******************************************************/
|
||||
private static boolean theTestPassed = false;
|
||||
private static boolean testGeneratedInterrupt = false;
|
||||
private static String failureMessage = "";
|
||||
|
||||
private static Thread mainThread = null;
|
||||
|
||||
private static int sleepTime = 300000;
|
||||
|
||||
// Not sure about what happens if multiple of this test are
|
||||
// instantiated in the same VM. Being static (and using
|
||||
// static vars), it aint gonna work. Not worrying about
|
||||
// it for now.
|
||||
public static void main( String args[] ) throws InterruptedException
|
||||
{
|
||||
mainThread = Thread.currentThread();
|
||||
try
|
||||
{
|
||||
init();
|
||||
}
|
||||
catch( TestPassedException e )
|
||||
{
|
||||
//The test passed, so just return from main and harness will
|
||||
// interepret this return as a pass
|
||||
return;
|
||||
}
|
||||
//At this point, neither test pass nor test fail has been
|
||||
// called -- either would have thrown an exception and ended the
|
||||
// test, so we know we have multiple threads.
|
||||
|
||||
//Test involves other threads, so sleep and wait for them to
|
||||
// called pass() or fail()
|
||||
try
|
||||
{
|
||||
Thread.sleep( sleepTime );
|
||||
//Timed out, so fail the test
|
||||
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
//The test harness may have interrupted the test. If so, rethrow the exception
|
||||
// so that the harness gets it and deals with it.
|
||||
if( ! testGeneratedInterrupt ) throw e;
|
||||
|
||||
//reset flag in case hit this code more than once for some reason (just safety)
|
||||
testGeneratedInterrupt = false;
|
||||
|
||||
if ( theTestPassed == false )
|
||||
{
|
||||
throw new RuntimeException( failureMessage );
|
||||
}
|
||||
}
|
||||
|
||||
}//main
|
||||
|
||||
public static synchronized void setTimeoutTo( int seconds )
|
||||
{
|
||||
sleepTime = seconds * 1000;
|
||||
}
|
||||
|
||||
public static synchronized void pass()
|
||||
{
|
||||
Sysout.println( "The test passed." );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//first check if this is executing in main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//Still in the main thread, so set the flag just for kicks,
|
||||
// and throw a test passed exception which will be caught
|
||||
// and end the test.
|
||||
theTestPassed = true;
|
||||
throw new TestPassedException();
|
||||
}
|
||||
theTestPassed = true;
|
||||
testGeneratedInterrupt = true;
|
||||
mainThread.interrupt();
|
||||
}//pass()
|
||||
|
||||
public static synchronized void fail()
|
||||
{
|
||||
//test writer didn't specify why test failed, so give generic
|
||||
fail( "it just plain failed! :-)" );
|
||||
}
|
||||
|
||||
public static synchronized void fail( String whyFailed )
|
||||
{
|
||||
Sysout.println( "The test failed: " + whyFailed );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//check if this called from main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//If main thread, fail now 'cause not sleeping
|
||||
throw new RuntimeException( whyFailed );
|
||||
}
|
||||
theTestPassed = false;
|
||||
testGeneratedInterrupt = true;
|
||||
failureMessage = whyFailed;
|
||||
mainThread.interrupt();
|
||||
}//fail()
|
||||
|
||||
}// class ValidBounds
|
||||
|
||||
//This exception is used to exit from any level of call nesting
|
||||
// when it's determined that the test has passed, and immediately
|
||||
// end the test.
|
||||
class TestPassedException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
||||
//*********** End Standard Test Machinery Section **********
|
||||
|
||||
|
||||
//************ Begin classes defined for the test ****************
|
||||
|
||||
// if want to make listeners, here is the recommended place for them, then instantiate
|
||||
// them in init()
|
||||
|
||||
/* Example of a class which may be written as part of a test
|
||||
class NewClass implements anInterface
|
||||
{
|
||||
static int newVar = 0;
|
||||
|
||||
public void eventDispatched(AWTEvent e)
|
||||
{
|
||||
//Counting events to see if we get enough
|
||||
eventCount++;
|
||||
|
||||
if( eventCount == 20 )
|
||||
{
|
||||
//got enough events, so pass
|
||||
|
||||
ValidBounds.pass();
|
||||
}
|
||||
else if( tries == 20 )
|
||||
{
|
||||
//tried too many times without getting enough events so fail
|
||||
|
||||
ValidBounds.fail();
|
||||
}
|
||||
|
||||
}// eventDispatched()
|
||||
|
||||
}// NewClass class
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//************** End classes defined for the test *******************
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
Standard Test Machinery
|
||||
DO NOT modify anything below -- it's a standard
|
||||
chunk of code whose purpose is to make user
|
||||
interaction uniform, and thereby make it simpler
|
||||
to read and understand someone else's test.
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery.
|
||||
It creates a dialog (with the instructions), and is the interface
|
||||
for sending text messages to the user.
|
||||
To print the instructions, send an array of strings to Sysout.createDialog
|
||||
WithInstructions method. Put one line of instructions per array entry.
|
||||
To display a message for the tester to see, simply call Sysout.println
|
||||
with the string to be displayed.
|
||||
This mimics System.out.println but works within the test harness as well
|
||||
as standalone.
|
||||
*/
|
||||
|
||||
class Sysout
|
||||
{
|
||||
private static TestDialog dialog;
|
||||
|
||||
public static void createDialogWithInstructions( String[] instructions )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
dialog.printInstructions( instructions );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
public static void createDialog( )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
String[] defInstr = { "Instructions will appear here. ", "" } ;
|
||||
dialog.printInstructions( defInstr );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
|
||||
public static void printInstructions( String[] instructions )
|
||||
{
|
||||
dialog.printInstructions( instructions );
|
||||
}
|
||||
|
||||
|
||||
public static void println( String messageIn )
|
||||
{
|
||||
dialog.displayMessage( messageIn );
|
||||
System.out.println(messageIn);
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery. It provides a place for the
|
||||
test instructions to be displayed, and a place for interactive messages
|
||||
to the user to be displayed.
|
||||
To have the test instructions displayed, see Sysout.
|
||||
To have a message to the user be displayed, see Sysout.
|
||||
Do not call anything in this dialog directly.
|
||||
*/
|
||||
class TestDialog extends Dialog
|
||||
{
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog( Frame frame, String name )
|
||||
{
|
||||
super( frame, name );
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||
add( "North", instructionsText );
|
||||
|
||||
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||
add("Center", messageText);
|
||||
|
||||
pack();
|
||||
|
||||
setVisible(true);
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions( String[] instructions )
|
||||
{
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText( "" );
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for( int i=0; i < instructions.length; i++ )
|
||||
{
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[ i ];
|
||||
while( remainingStr.length() > 0 )
|
||||
{
|
||||
//if longer than max then chop off first max chars to print
|
||||
if( remainingStr.length() >= maxStringLength )
|
||||
{
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf( ' ', maxStringLength - 1 );
|
||||
|
||||
if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring( 0, posOfSpace + 1 );
|
||||
remainingStr = remainingStr.substring( posOfSpace + 1 );
|
||||
}
|
||||
//else just print
|
||||
else
|
||||
{
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append( printStr + "\n" );
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage( String messageIn )
|
||||
{
|
||||
messageText.append( messageIn + "\n" );
|
||||
System.out.println(messageIn);
|
||||
}
|
||||
|
||||
}// TestDialog class
|
@ -0,0 +1,466 @@
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
@test %I% %E%
|
||||
@bug 4080029
|
||||
@summary Modal Dialog block input to all frame windows not just its parent.
|
||||
@author dmitry.cherepanov: area=awt.modal
|
||||
@run main/manual CloseBlocker
|
||||
*/
|
||||
|
||||
/**
|
||||
* ManualMainTest.java
|
||||
*
|
||||
* summary: The test opens and closes blocker dialog, the test verifies
|
||||
* that active window is correct when the dialog is closed.
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
public class CloseBlocker
|
||||
{
|
||||
|
||||
private static void init()
|
||||
{
|
||||
//*** Create instructions for the user here ***
|
||||
|
||||
String[] instructions =
|
||||
{
|
||||
" the test will be run 6 times, to start next test just close all ",
|
||||
" windows of previous; the instructions are the same for all tests: ",
|
||||
" 1) there are two frames (one the frames has 'show modal' button), ",
|
||||
" 2) press the button to show a dialog, ",
|
||||
" 3) close the dialog (an alternative scenario - activate another",
|
||||
" native window before closing the dialog), ",
|
||||
" 4) the frame with button should become next active window, ",
|
||||
" if it's true, then the test passed, otherwise, it failed. ",
|
||||
" Press 'pass' button only after all of the 6 tests are completed, ",
|
||||
" the number of the currently executed test is displayed on the ",
|
||||
" output window. "
|
||||
};
|
||||
Sysout.createDialog( );
|
||||
Sysout.printInstructions( instructions );
|
||||
|
||||
test(true, true, false);
|
||||
test(true, true, true);
|
||||
test(false, true, false); // 3rd parameter has no affect for ownerless
|
||||
|
||||
test(true, false, false);
|
||||
test(true, false, true);
|
||||
test(false, false, false); // 3rd parameter has no affect for ownerless
|
||||
|
||||
}//End init()
|
||||
|
||||
private static final Object obj = new Object();
|
||||
private static int counter = 0;
|
||||
|
||||
/*
|
||||
* The ownerless parameter indicates whether the blocker dialog
|
||||
* has owner. The usual parameter indicates whether the blocker
|
||||
* dialog is a Java dialog (non-native dialog like file dialog).
|
||||
*/
|
||||
private static void test(final boolean ownerless, final boolean usual, final boolean initiallyOwnerIsActive) {
|
||||
|
||||
Sysout.print(" * test #" + (++counter) + " is running ... ");
|
||||
|
||||
final Frame active = new Frame();
|
||||
final Frame nonactive = new Frame();
|
||||
Button button = new Button("show modal");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
Dialog dialog = null;
|
||||
Frame parent = ownerless ? null : (initiallyOwnerIsActive? active : nonactive);
|
||||
if (usual) {
|
||||
dialog = new Dialog(parent, "Sample", true);
|
||||
} else {
|
||||
dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
|
||||
}
|
||||
dialog.addWindowListener(new WindowAdapter(){
|
||||
public void windowClosing(WindowEvent e){
|
||||
e.getWindow().dispose();
|
||||
}
|
||||
});
|
||||
dialog.setBounds(200, 200, 200, 200);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
active.add(button);
|
||||
active.setBounds(200, 400, 200, 200);
|
||||
WindowAdapter adapter = new WindowAdapter(){
|
||||
public void windowClosing(WindowEvent e){
|
||||
active.dispose();
|
||||
nonactive.dispose();
|
||||
synchronized(obj) {
|
||||
obj.notify();
|
||||
}
|
||||
}
|
||||
};
|
||||
active.addWindowListener(adapter);
|
||||
active.setVisible(true);
|
||||
|
||||
nonactive.setBounds(400, 400, 200, 200);
|
||||
nonactive.addWindowListener(adapter);
|
||||
nonactive.setVisible(true);
|
||||
|
||||
synchronized(obj) {
|
||||
try{
|
||||
obj.wait();
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
Sysout.println(" completed. ");
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* Standard Test Machinery Section
|
||||
* DO NOT modify anything in this section -- it's a
|
||||
* standard chunk of code which has all of the
|
||||
* synchronisation necessary for the test harness.
|
||||
* By keeping it the same in all tests, it is easier
|
||||
* to read and understand someone else's test, as
|
||||
* well as insuring that all tests behave correctly
|
||||
* with the test harness.
|
||||
* There is a section following this for test-defined
|
||||
* classes
|
||||
******************************************************/
|
||||
private static boolean theTestPassed = false;
|
||||
private static boolean testGeneratedInterrupt = false;
|
||||
private static String failureMessage = "";
|
||||
|
||||
private static Thread mainThread = null;
|
||||
|
||||
private static int sleepTime = 300000;
|
||||
|
||||
public static void main( String args[] ) throws InterruptedException
|
||||
{
|
||||
mainThread = Thread.currentThread();
|
||||
try
|
||||
{
|
||||
init();
|
||||
}
|
||||
catch( TestPassedException e )
|
||||
{
|
||||
//The test passed, so just return from main and harness will
|
||||
// interepret this return as a pass
|
||||
return;
|
||||
}
|
||||
//At this point, neither test passed nor test failed has been
|
||||
// called -- either would have thrown an exception and ended the
|
||||
// test, so we know we have multiple threads.
|
||||
|
||||
//Test involves other threads, so sleep and wait for them to
|
||||
// called pass() or fail()
|
||||
try
|
||||
{
|
||||
Thread.sleep( sleepTime );
|
||||
//Timed out, so fail the test
|
||||
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
if( ! testGeneratedInterrupt ) throw e;
|
||||
|
||||
//reset flag in case hit this code more than once for some reason (just safety)
|
||||
testGeneratedInterrupt = false;
|
||||
if ( theTestPassed == false )
|
||||
{
|
||||
throw new RuntimeException( failureMessage );
|
||||
}
|
||||
}
|
||||
|
||||
}//main
|
||||
|
||||
public static synchronized void setTimeoutTo( int seconds )
|
||||
{
|
||||
sleepTime = seconds * 1000;
|
||||
}
|
||||
|
||||
public static synchronized void pass()
|
||||
{
|
||||
Sysout.println( "The test passed." );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//first check if this is executing in main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//Still in the main thread, so set the flag just for kicks,
|
||||
// and throw a test passed exception which will be caught
|
||||
// and end the test.
|
||||
theTestPassed = true;
|
||||
throw new TestPassedException();
|
||||
}
|
||||
//pass was called from a different thread, so set the flag and interrupt
|
||||
// the main thead.
|
||||
theTestPassed = true;
|
||||
testGeneratedInterrupt = true;
|
||||
mainThread.interrupt();
|
||||
}//pass()
|
||||
|
||||
public static synchronized void fail()
|
||||
{
|
||||
//test writer didn't specify why test failed, so give generic
|
||||
fail( "it just plain failed! :-)" );
|
||||
}
|
||||
|
||||
public static synchronized void fail( String whyFailed )
|
||||
{
|
||||
Sysout.println( "The test failed: " + whyFailed );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//check if this called from main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//If main thread, fail now 'cause not sleeping
|
||||
throw new RuntimeException( whyFailed );
|
||||
}
|
||||
theTestPassed = false;
|
||||
testGeneratedInterrupt = true;
|
||||
failureMessage = whyFailed;
|
||||
mainThread.interrupt();
|
||||
}//fail()
|
||||
|
||||
}// class ManualMainTest
|
||||
|
||||
//This exception is used to exit from any level of call nesting
|
||||
// when it's determined that the test has passed, and immediately
|
||||
// end the test.
|
||||
class TestPassedException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
||||
//*********** End Standard Test Machinery Section **********
|
||||
|
||||
|
||||
//************ Begin classes defined for the test ****************
|
||||
|
||||
// make listeners in a class defined here, and instantiate them in init()
|
||||
|
||||
/* Example of a class which may be written as part of a test
|
||||
class NewClass implements anInterface
|
||||
{
|
||||
static int newVar = 0;
|
||||
|
||||
public void eventDispatched(AWTEvent e)
|
||||
{
|
||||
//Counting events to see if we get enough
|
||||
eventCount++;
|
||||
|
||||
if( eventCount == 20 )
|
||||
{
|
||||
//got enough events, so pass
|
||||
|
||||
ManualMainTest.pass();
|
||||
}
|
||||
else if( tries == 20 )
|
||||
{
|
||||
//tried too many times without getting enough events so fail
|
||||
|
||||
ManualMainTest.fail();
|
||||
}
|
||||
|
||||
}// eventDispatched()
|
||||
|
||||
}// NewClass class
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//************** End classes defined for the test *******************
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
Standard Test Machinery
|
||||
DO NOT modify anything below -- it's a standard
|
||||
chunk of code whose purpose is to make user
|
||||
interaction uniform, and thereby make it simpler
|
||||
to read and understand someone else's test.
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery.
|
||||
It creates a dialog (with the instructions), and is the interface
|
||||
for sending text messages to the user.
|
||||
To print the instructions, send an array of strings to Sysout.createDialog
|
||||
WithInstructions method. Put one line of instructions per array entry.
|
||||
To display a message for the tester to see, simply call Sysout.println
|
||||
with the string to be displayed.
|
||||
This mimics System.out.println but works within the test harness as well
|
||||
as standalone.
|
||||
*/
|
||||
|
||||
class Sysout
|
||||
{
|
||||
private static TestDialog dialog;
|
||||
|
||||
public static void createDialogWithInstructions( String[] instructions )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
dialog.printInstructions( instructions );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
public static void createDialog( )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
String[] defInstr = { "Instructions will appear here. ", "" } ;
|
||||
dialog.printInstructions( defInstr );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
|
||||
public static void printInstructions( String[] instructions )
|
||||
{
|
||||
dialog.printInstructions( instructions );
|
||||
}
|
||||
|
||||
|
||||
public static void println( String messageIn )
|
||||
{
|
||||
dialog.displayMessage( messageIn, true );
|
||||
}
|
||||
|
||||
public static void print( String messageIn )
|
||||
{
|
||||
dialog.displayMessage( messageIn, false );
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery. It provides a place for the
|
||||
test instructions to be displayed, and a place for interactive messages
|
||||
to the user to be displayed.
|
||||
To have the test instructions displayed, see Sysout.
|
||||
To have a message to the user be displayed, see Sysout.
|
||||
Do not call anything in this dialog directly.
|
||||
*/
|
||||
class TestDialog extends Dialog implements ActionListener
|
||||
{
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
Panel buttonP = new Panel();
|
||||
Button passB = new Button( "pass" );
|
||||
Button failB = new Button( "fail" );
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog( Frame frame, String name )
|
||||
{
|
||||
super( frame, name );
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||
add( "North", instructionsText );
|
||||
|
||||
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||
add("Center", messageText);
|
||||
|
||||
passB = new Button( "pass" );
|
||||
passB.setActionCommand( "pass" );
|
||||
passB.addActionListener( this );
|
||||
buttonP.add( "East", passB );
|
||||
|
||||
failB = new Button( "fail" );
|
||||
failB.setActionCommand( "fail" );
|
||||
failB.addActionListener( this );
|
||||
buttonP.add( "West", failB );
|
||||
|
||||
add( "South", buttonP );
|
||||
pack();
|
||||
|
||||
setVisible(true);
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions( String[] instructions )
|
||||
{
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText( "" );
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for( int i=0; i < instructions.length; i++ )
|
||||
{
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[ i ];
|
||||
while( remainingStr.length() > 0 )
|
||||
{
|
||||
//if longer than max then chop off first max chars to print
|
||||
if( remainingStr.length() >= maxStringLength )
|
||||
{
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf( ' ', maxStringLength - 1 );
|
||||
|
||||
if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring( 0, posOfSpace + 1 );
|
||||
remainingStr = remainingStr.substring( posOfSpace + 1 );
|
||||
}
|
||||
//else just print
|
||||
else
|
||||
{
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append( printStr + "\n" );
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage( String messageIn, boolean nextLine )
|
||||
{
|
||||
messageText.append( messageIn + (nextLine? "\n" : "") );
|
||||
System.out.println(messageIn);
|
||||
}
|
||||
|
||||
//catch presses of the passed and failed buttons.
|
||||
//simply call the standard pass() or fail() static methods of
|
||||
//ManualMainTest
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
if( e.getActionCommand() == "pass" )
|
||||
{
|
||||
CloseBlocker.pass();
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseBlocker.fail();
|
||||
}
|
||||
}
|
||||
|
||||
}// TestDialog class
|
@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
@test %I% %E%
|
||||
@bug 4080029
|
||||
@summary Modal Dialog block input to all frame windows not just its parent.
|
||||
@author dmitry.cherepanov: area=awt.modal
|
||||
@run main/manual OverBlocker
|
||||
*/
|
||||
|
||||
/**
|
||||
* OverBlocker.java
|
||||
*
|
||||
* summary: The test verifies that if user tries to activate the blocked dialog
|
||||
* then the blocker dialog appears over the other windows
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
public class OverBlocker
|
||||
{
|
||||
|
||||
private static void init()
|
||||
{
|
||||
//*** Create instructions for the user here ***
|
||||
|
||||
String[] instructions =
|
||||
{
|
||||
" the test will be run 4 times, to start next test just close all ",
|
||||
" windows of previous; the instructions are the same for all tests: ",
|
||||
" 1) there is a frame with 'show modal' button, ",
|
||||
" 2) press the button to show a dialog, ",
|
||||
" 3) activate any non-Java application, move the app over the dialog, ",
|
||||
" 4) click on the frame by mouse, ",
|
||||
" 5) make sure that the dialog comes up from the application and ",
|
||||
" now the dialog overlaps the app as well as the frame, ",
|
||||
" if it's true, then the test passed, otherwise, it failed. ",
|
||||
" Press 'pass' button only after all of the 4 tests are completed, ",
|
||||
" the number of the currently executed test is displayed on the ",
|
||||
" output window. "
|
||||
};
|
||||
Sysout.createDialog( );
|
||||
Sysout.printInstructions( instructions );
|
||||
|
||||
test(false, true);
|
||||
test(true, true);
|
||||
test(true, false);
|
||||
test(false, false);
|
||||
|
||||
}//End init()
|
||||
|
||||
private static final Object obj = new Object();
|
||||
private static int counter = 0;
|
||||
|
||||
/*
|
||||
* The ownerless parameter indicates whether the blocker dialog
|
||||
* has owner. The usual parameter indicates whether the blocker
|
||||
* dialog is a Java dialog (non-native dialog like file dialog).
|
||||
*/
|
||||
private static void test(final boolean ownerless, final boolean usual) {
|
||||
|
||||
Sysout.print(" * test #" + (++counter) + " is running ... ");
|
||||
|
||||
final Frame frame = new Frame();
|
||||
Button button = new Button("show modal");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
Dialog dialog = null;
|
||||
Frame parent = ownerless ? null : frame;
|
||||
if (usual) {
|
||||
dialog = new Dialog(parent, "Sample", true);
|
||||
} else {
|
||||
dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
|
||||
}
|
||||
dialog.addWindowListener(new WindowAdapter(){
|
||||
public void windowClosing(WindowEvent e){
|
||||
e.getWindow().dispose();
|
||||
}
|
||||
});
|
||||
dialog.setBounds(200, 200, 200, 200);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
});
|
||||
frame.add(button);
|
||||
frame.setBounds(400, 400, 200, 200);
|
||||
frame.addWindowListener(new WindowAdapter(){
|
||||
public void windowClosing(WindowEvent e){
|
||||
e.getWindow().dispose();
|
||||
synchronized(obj) {
|
||||
obj.notify();
|
||||
}
|
||||
}
|
||||
});
|
||||
frame.setVisible(true);
|
||||
|
||||
synchronized(obj) {
|
||||
try{
|
||||
obj.wait();
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
Sysout.println(" completed. ");
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* Standard Test Machinery Section
|
||||
* DO NOT modify anything in this section -- it's a
|
||||
* standard chunk of code which has all of the
|
||||
* synchronisation necessary for the test harness.
|
||||
* By keeping it the same in all tests, it is easier
|
||||
* to read and understand someone else's test, as
|
||||
* well as insuring that all tests behave correctly
|
||||
* with the test harness.
|
||||
* There is a section following this for test-defined
|
||||
* classes
|
||||
******************************************************/
|
||||
private static boolean theTestPassed = false;
|
||||
private static boolean testGeneratedInterrupt = false;
|
||||
private static String failureMessage = "";
|
||||
|
||||
private static Thread mainThread = null;
|
||||
|
||||
private static int sleepTime = 300000;
|
||||
|
||||
public static void main( String args[] ) throws InterruptedException
|
||||
{
|
||||
mainThread = Thread.currentThread();
|
||||
try
|
||||
{
|
||||
init();
|
||||
}
|
||||
catch( TestPassedException e )
|
||||
{
|
||||
//The test passed, so just return from main and harness will
|
||||
// interepret this return as a pass
|
||||
return;
|
||||
}
|
||||
//At this point, neither test passed nor test failed has been
|
||||
// called -- either would have thrown an exception and ended the
|
||||
// test, so we know we have multiple threads.
|
||||
|
||||
//Test involves other threads, so sleep and wait for them to
|
||||
// called pass() or fail()
|
||||
try
|
||||
{
|
||||
Thread.sleep( sleepTime );
|
||||
//Timed out, so fail the test
|
||||
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
if( ! testGeneratedInterrupt ) throw e;
|
||||
|
||||
//reset flag in case hit this code more than once for some reason (just safety)
|
||||
testGeneratedInterrupt = false;
|
||||
if ( theTestPassed == false )
|
||||
{
|
||||
throw new RuntimeException( failureMessage );
|
||||
}
|
||||
}
|
||||
|
||||
}//main
|
||||
|
||||
public static synchronized void setTimeoutTo( int seconds )
|
||||
{
|
||||
sleepTime = seconds * 1000;
|
||||
}
|
||||
|
||||
public static synchronized void pass()
|
||||
{
|
||||
Sysout.println( "The test passed." );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//first check if this is executing in main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//Still in the main thread, so set the flag just for kicks,
|
||||
// and throw a test passed exception which will be caught
|
||||
// and end the test.
|
||||
theTestPassed = true;
|
||||
throw new TestPassedException();
|
||||
}
|
||||
//pass was called from a different thread, so set the flag and interrupt
|
||||
// the main thead.
|
||||
theTestPassed = true;
|
||||
testGeneratedInterrupt = true;
|
||||
mainThread.interrupt();
|
||||
}//pass()
|
||||
|
||||
public static synchronized void fail()
|
||||
{
|
||||
//test writer didn't specify why test failed, so give generic
|
||||
fail( "it just plain failed! :-)" );
|
||||
}
|
||||
|
||||
public static synchronized void fail( String whyFailed )
|
||||
{
|
||||
Sysout.println( "The test failed: " + whyFailed );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//check if this called from main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//If main thread, fail now 'cause not sleeping
|
||||
throw new RuntimeException( whyFailed );
|
||||
}
|
||||
theTestPassed = false;
|
||||
testGeneratedInterrupt = true;
|
||||
failureMessage = whyFailed;
|
||||
mainThread.interrupt();
|
||||
}//fail()
|
||||
|
||||
}// class ManualMainTest
|
||||
|
||||
//This exception is used to exit from any level of call nesting
|
||||
// when it's determined that the test has passed, and immediately
|
||||
// end the test.
|
||||
class TestPassedException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
||||
//*********** End Standard Test Machinery Section **********
|
||||
|
||||
|
||||
//************ Begin classes defined for the test ****************
|
||||
|
||||
// make listeners in a class defined here, and instantiate them in init()
|
||||
|
||||
/* Example of a class which may be written as part of a test
|
||||
class NewClass implements anInterface
|
||||
{
|
||||
static int newVar = 0;
|
||||
|
||||
public void eventDispatched(AWTEvent e)
|
||||
{
|
||||
//Counting events to see if we get enough
|
||||
eventCount++;
|
||||
|
||||
if( eventCount == 20 )
|
||||
{
|
||||
//got enough events, so pass
|
||||
|
||||
ManualMainTest.pass();
|
||||
}
|
||||
else if( tries == 20 )
|
||||
{
|
||||
//tried too many times without getting enough events so fail
|
||||
|
||||
ManualMainTest.fail();
|
||||
}
|
||||
|
||||
}// eventDispatched()
|
||||
|
||||
}// NewClass class
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//************** End classes defined for the test *******************
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
Standard Test Machinery
|
||||
DO NOT modify anything below -- it's a standard
|
||||
chunk of code whose purpose is to make user
|
||||
interaction uniform, and thereby make it simpler
|
||||
to read and understand someone else's test.
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery.
|
||||
It creates a dialog (with the instructions), and is the interface
|
||||
for sending text messages to the user.
|
||||
To print the instructions, send an array of strings to Sysout.createDialog
|
||||
WithInstructions method. Put one line of instructions per array entry.
|
||||
To display a message for the tester to see, simply call Sysout.println
|
||||
with the string to be displayed.
|
||||
This mimics System.out.println but works within the test harness as well
|
||||
as standalone.
|
||||
*/
|
||||
|
||||
class Sysout
|
||||
{
|
||||
private static TestDialog dialog;
|
||||
|
||||
public static void createDialogWithInstructions( String[] instructions )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
dialog.printInstructions( instructions );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
public static void createDialog( )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
String[] defInstr = { "Instructions will appear here. ", "" } ;
|
||||
dialog.printInstructions( defInstr );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
|
||||
public static void printInstructions( String[] instructions )
|
||||
{
|
||||
dialog.printInstructions( instructions );
|
||||
}
|
||||
|
||||
|
||||
public static void println( String messageIn )
|
||||
{
|
||||
dialog.displayMessage( messageIn, true );
|
||||
}
|
||||
|
||||
public static void print( String messageIn )
|
||||
{
|
||||
dialog.displayMessage( messageIn, false );
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery. It provides a place for the
|
||||
test instructions to be displayed, and a place for interactive messages
|
||||
to the user to be displayed.
|
||||
To have the test instructions displayed, see Sysout.
|
||||
To have a message to the user be displayed, see Sysout.
|
||||
Do not call anything in this dialog directly.
|
||||
*/
|
||||
class TestDialog extends Dialog implements ActionListener
|
||||
{
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
Panel buttonP = new Panel();
|
||||
Button passB = new Button( "pass" );
|
||||
Button failB = new Button( "fail" );
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog( Frame frame, String name )
|
||||
{
|
||||
super( frame, name );
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||
add( "North", instructionsText );
|
||||
|
||||
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||
add("Center", messageText);
|
||||
|
||||
passB = new Button( "pass" );
|
||||
passB.setActionCommand( "pass" );
|
||||
passB.addActionListener( this );
|
||||
buttonP.add( "East", passB );
|
||||
|
||||
failB = new Button( "fail" );
|
||||
failB.setActionCommand( "fail" );
|
||||
failB.addActionListener( this );
|
||||
buttonP.add( "West", failB );
|
||||
|
||||
add( "South", buttonP );
|
||||
pack();
|
||||
|
||||
setVisible(true);
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions( String[] instructions )
|
||||
{
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText( "" );
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for( int i=0; i < instructions.length; i++ )
|
||||
{
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[ i ];
|
||||
while( remainingStr.length() > 0 )
|
||||
{
|
||||
//if longer than max then chop off first max chars to print
|
||||
if( remainingStr.length() >= maxStringLength )
|
||||
{
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf( ' ', maxStringLength - 1 );
|
||||
|
||||
if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring( 0, posOfSpace + 1 );
|
||||
remainingStr = remainingStr.substring( posOfSpace + 1 );
|
||||
}
|
||||
//else just print
|
||||
else
|
||||
{
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append( printStr + "\n" );
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage( String messageIn, boolean nextLine )
|
||||
{
|
||||
messageText.append( messageIn + (nextLine? "\n" : "") );
|
||||
System.out.println(messageIn);
|
||||
}
|
||||
|
||||
//catch presses of the passed and failed buttons.
|
||||
//simply call the standard pass() or fail() static methods of
|
||||
//ManualMainTest
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
if( e.getActionCommand() == "pass" )
|
||||
{
|
||||
OverBlocker.pass();
|
||||
}
|
||||
else
|
||||
{
|
||||
OverBlocker.fail();
|
||||
}
|
||||
}
|
||||
|
||||
}// TestDialog class
|
403
jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java
Normal file
403
jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java
Normal file
@ -0,0 +1,403 @@
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
@test %I% %E%
|
||||
@bug 6572263 6571808
|
||||
@summary PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList
|
||||
@author dmitry.cherepanov: area=awt.modal
|
||||
@run main/manual Winkey
|
||||
*/
|
||||
|
||||
/**
|
||||
* Winkey.java
|
||||
*
|
||||
* summary: the test verifies that pressing combination of Windows key
|
||||
* and M key to minimize all windows doesn't break AWT modality
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
public class Winkey
|
||||
{
|
||||
|
||||
private static void init()
|
||||
{
|
||||
//*** Create instructions for the user here ***
|
||||
|
||||
String[] instructions =
|
||||
{
|
||||
" 1. there is a frame with a 'show modal' button, ",
|
||||
" 2. press the button to show a modal dialog, ",
|
||||
" 3. the modal dialog will be shown over the frame, ",
|
||||
" 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ",
|
||||
" ",
|
||||
" 5.1. press combination Windows Key and M key to minimize all windows, ",
|
||||
" 5.2. press combination Windows Key and D key to show desktop, ",
|
||||
" 5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ",
|
||||
" 5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)",
|
||||
" ",
|
||||
" 6. make sure that the dialog and the frame are visible, ",
|
||||
" the bounds of the windows should be the same as before, ",
|
||||
" if it's true, then the test passed; otherwise, it failed. "
|
||||
};
|
||||
Sysout.createDialog( );
|
||||
Sysout.printInstructions( instructions );
|
||||
|
||||
final Frame frame = new Frame();
|
||||
Button button = new Button("show modal");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
FileDialog dialog = new FileDialog((Frame)null, "Sample", FileDialog.LOAD);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
});
|
||||
frame.add(button);
|
||||
frame.setBounds(400, 400, 200, 200);
|
||||
frame.setVisible(true);
|
||||
|
||||
}//End init()
|
||||
|
||||
/*****************************************************
|
||||
* Standard Test Machinery Section
|
||||
* DO NOT modify anything in this section -- it's a
|
||||
* standard chunk of code which has all of the
|
||||
* synchronisation necessary for the test harness.
|
||||
* By keeping it the same in all tests, it is easier
|
||||
* to read and understand someone else's test, as
|
||||
* well as insuring that all tests behave correctly
|
||||
* with the test harness.
|
||||
* There is a section following this for test-defined
|
||||
* classes
|
||||
******************************************************/
|
||||
private static boolean theTestPassed = false;
|
||||
private static boolean testGeneratedInterrupt = false;
|
||||
private static String failureMessage = "";
|
||||
|
||||
private static Thread mainThread = null;
|
||||
|
||||
private static int sleepTime = 300000;
|
||||
|
||||
public static void main( String args[] ) throws InterruptedException
|
||||
{
|
||||
mainThread = Thread.currentThread();
|
||||
try
|
||||
{
|
||||
init();
|
||||
}
|
||||
catch( TestPassedException e )
|
||||
{
|
||||
//The test passed, so just return from main and harness will
|
||||
// interepret this return as a pass
|
||||
return;
|
||||
}
|
||||
//At this point, neither test passed nor test failed has been
|
||||
// called -- either would have thrown an exception and ended the
|
||||
// test, so we know we have multiple threads.
|
||||
|
||||
//Test involves other threads, so sleep and wait for them to
|
||||
// called pass() or fail()
|
||||
try
|
||||
{
|
||||
Thread.sleep( sleepTime );
|
||||
//Timed out, so fail the test
|
||||
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
if( ! testGeneratedInterrupt ) throw e;
|
||||
|
||||
//reset flag in case hit this code more than once for some reason (just safety)
|
||||
testGeneratedInterrupt = false;
|
||||
if ( theTestPassed == false )
|
||||
{
|
||||
throw new RuntimeException( failureMessage );
|
||||
}
|
||||
}
|
||||
|
||||
}//main
|
||||
|
||||
public static synchronized void setTimeoutTo( int seconds )
|
||||
{
|
||||
sleepTime = seconds * 1000;
|
||||
}
|
||||
|
||||
public static synchronized void pass()
|
||||
{
|
||||
Sysout.println( "The test passed." );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//first check if this is executing in main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//Still in the main thread, so set the flag just for kicks,
|
||||
// and throw a test passed exception which will be caught
|
||||
// and end the test.
|
||||
theTestPassed = true;
|
||||
throw new TestPassedException();
|
||||
}
|
||||
//pass was called from a different thread, so set the flag and interrupt
|
||||
// the main thead.
|
||||
theTestPassed = true;
|
||||
testGeneratedInterrupt = true;
|
||||
mainThread.interrupt();
|
||||
}//pass()
|
||||
|
||||
public static synchronized void fail()
|
||||
{
|
||||
//test writer didn't specify why test failed, so give generic
|
||||
fail( "it just plain failed! :-)" );
|
||||
}
|
||||
|
||||
public static synchronized void fail( String whyFailed )
|
||||
{
|
||||
Sysout.println( "The test failed: " + whyFailed );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//check if this called from main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//If main thread, fail now 'cause not sleeping
|
||||
throw new RuntimeException( whyFailed );
|
||||
}
|
||||
theTestPassed = false;
|
||||
testGeneratedInterrupt = true;
|
||||
failureMessage = whyFailed;
|
||||
mainThread.interrupt();
|
||||
}//fail()
|
||||
|
||||
}// class ManualMainTest
|
||||
|
||||
//This exception is used to exit from any level of call nesting
|
||||
// when it's determined that the test has passed, and immediately
|
||||
// end the test.
|
||||
class TestPassedException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
||||
//*********** End Standard Test Machinery Section **********
|
||||
|
||||
|
||||
//************ Begin classes defined for the test ****************
|
||||
|
||||
// make listeners in a class defined here, and instantiate them in init()
|
||||
|
||||
/* Example of a class which may be written as part of a test
|
||||
class NewClass implements anInterface
|
||||
{
|
||||
static int newVar = 0;
|
||||
|
||||
public void eventDispatched(AWTEvent e)
|
||||
{
|
||||
//Counting events to see if we get enough
|
||||
eventCount++;
|
||||
|
||||
if( eventCount == 20 )
|
||||
{
|
||||
//got enough events, so pass
|
||||
|
||||
ManualMainTest.pass();
|
||||
}
|
||||
else if( tries == 20 )
|
||||
{
|
||||
//tried too many times without getting enough events so fail
|
||||
|
||||
ManualMainTest.fail();
|
||||
}
|
||||
|
||||
}// eventDispatched()
|
||||
|
||||
}// NewClass class
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//************** End classes defined for the test *******************
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
Standard Test Machinery
|
||||
DO NOT modify anything below -- it's a standard
|
||||
chunk of code whose purpose is to make user
|
||||
interaction uniform, and thereby make it simpler
|
||||
to read and understand someone else's test.
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery.
|
||||
It creates a dialog (with the instructions), and is the interface
|
||||
for sending text messages to the user.
|
||||
To print the instructions, send an array of strings to Sysout.createDialog
|
||||
WithInstructions method. Put one line of instructions per array entry.
|
||||
To display a message for the tester to see, simply call Sysout.println
|
||||
with the string to be displayed.
|
||||
This mimics System.out.println but works within the test harness as well
|
||||
as standalone.
|
||||
*/
|
||||
|
||||
class Sysout
|
||||
{
|
||||
private static TestDialog dialog;
|
||||
|
||||
public static void createDialogWithInstructions( String[] instructions )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
dialog.printInstructions( instructions );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
public static void createDialog( )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
String[] defInstr = { "Instructions will appear here. ", "" } ;
|
||||
dialog.printInstructions( defInstr );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
|
||||
public static void printInstructions( String[] instructions )
|
||||
{
|
||||
dialog.printInstructions( instructions );
|
||||
}
|
||||
|
||||
|
||||
public static void println( String messageIn )
|
||||
{
|
||||
dialog.displayMessage( messageIn );
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery. It provides a place for the
|
||||
test instructions to be displayed, and a place for interactive messages
|
||||
to the user to be displayed.
|
||||
To have the test instructions displayed, see Sysout.
|
||||
To have a message to the user be displayed, see Sysout.
|
||||
Do not call anything in this dialog directly.
|
||||
*/
|
||||
class TestDialog extends Dialog implements ActionListener
|
||||
{
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
Panel buttonP = new Panel();
|
||||
Button passB = new Button( "pass" );
|
||||
Button failB = new Button( "fail" );
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog( Frame frame, String name )
|
||||
{
|
||||
super( frame, name );
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||
add( "North", instructionsText );
|
||||
|
||||
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||
add("Center", messageText);
|
||||
|
||||
passB = new Button( "pass" );
|
||||
passB.setActionCommand( "pass" );
|
||||
passB.addActionListener( this );
|
||||
buttonP.add( "East", passB );
|
||||
|
||||
failB = new Button( "fail" );
|
||||
failB.setActionCommand( "fail" );
|
||||
failB.addActionListener( this );
|
||||
buttonP.add( "West", failB );
|
||||
|
||||
add( "South", buttonP );
|
||||
pack();
|
||||
|
||||
setVisible(true);
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions( String[] instructions )
|
||||
{
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText( "" );
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for( int i=0; i < instructions.length; i++ )
|
||||
{
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[ i ];
|
||||
while( remainingStr.length() > 0 )
|
||||
{
|
||||
//if longer than max then chop off first max chars to print
|
||||
if( remainingStr.length() >= maxStringLength )
|
||||
{
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf( ' ', maxStringLength - 1 );
|
||||
|
||||
if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring( 0, posOfSpace + 1 );
|
||||
remainingStr = remainingStr.substring( posOfSpace + 1 );
|
||||
}
|
||||
//else just print
|
||||
else
|
||||
{
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append( printStr + "\n" );
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage( String messageIn )
|
||||
{
|
||||
messageText.append( messageIn + "\n" );
|
||||
System.out.println(messageIn);
|
||||
}
|
||||
|
||||
//catch presses of the passed and failed buttons.
|
||||
//simply call the standard pass() or fail() static methods of
|
||||
//ManualMainTest
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
if( e.getActionCommand() == "pass" )
|
||||
{
|
||||
Winkey.pass();
|
||||
}
|
||||
else
|
||||
{
|
||||
Winkey.fail();
|
||||
}
|
||||
}
|
||||
|
||||
}// TestDialog class
|
432
jdk/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java
Normal file
432
jdk/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java
Normal file
@ -0,0 +1,432 @@
|
||||
/*
|
||||
* Copyright 2007 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 %W% %E% %I%, %G%
|
||||
@bug 6524352
|
||||
@summary support for high-resolution mouse wheel
|
||||
@author dmitry cherepanov: area=awt.event
|
||||
@run main/manual SmoothWheel
|
||||
*/
|
||||
|
||||
/**
|
||||
* SmoothWheel.java
|
||||
*
|
||||
* summary:
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
public class SmoothWheel
|
||||
{
|
||||
|
||||
//*** test-writer defined static variables go here ***
|
||||
|
||||
|
||||
private static void init()
|
||||
{
|
||||
String[] instructions =
|
||||
{
|
||||
"1. the test is for high-resolution mouse wheel only, ",
|
||||
" refer to the cr# 6524352 for more info about such devices, ",
|
||||
"2. you'll see a frame, the frame contains a checkbox, ",
|
||||
"3. initially, the state of the checkbox is off, ",
|
||||
" use mouse wheel over the frame, ",
|
||||
" and the frame will change its size gradually, ",
|
||||
"4. turn on the checkbox, ",
|
||||
" use mouse wheel again over the frame, ",
|
||||
" now the frame will change its size smoothly, ",
|
||||
"5. if the frame has always the same size or",
|
||||
" if the frame changes its size equally in 3,4 cases, ",
|
||||
" then the test failed. Otherwise, it passed."
|
||||
};
|
||||
|
||||
Sysout.createDialog( );
|
||||
Sysout.printInstructions( instructions );
|
||||
|
||||
final Frame frame = new Frame();
|
||||
final Checkbox checkbox = new Checkbox("smooth wheel?");
|
||||
checkbox.setState(false);
|
||||
|
||||
frame.setLayout (new FlowLayout());
|
||||
frame.add(checkbox);
|
||||
|
||||
frame.addMouseWheelListener(new MouseWheelListener() {
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
Sysout.println(e.toString());
|
||||
double wheelRotation = 0;
|
||||
if (checkbox.getState()) {
|
||||
wheelRotation = e.getPreciseWheelRotation();
|
||||
} else {
|
||||
wheelRotation = e.getWheelRotation();
|
||||
}
|
||||
Dimension size = frame.getSize();
|
||||
size.width += 10 * wheelRotation;
|
||||
size.height += 10 * wheelRotation;
|
||||
frame.setSize(size);
|
||||
}
|
||||
});
|
||||
|
||||
frame.setBounds(200, 200, 200, 200);
|
||||
frame.setVisible(true);
|
||||
|
||||
}//End init()
|
||||
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Standard Test Machinery Section
|
||||
* DO NOT modify anything in this section -- it's a
|
||||
* standard chunk of code which has all of the
|
||||
* synchronisation necessary for the test harness.
|
||||
* By keeping it the same in all tests, it is easier
|
||||
* to read and understand someone else's test, as
|
||||
* well as insuring that all tests behave correctly
|
||||
* with the test harness.
|
||||
* There is a section following this for test-defined
|
||||
* classes
|
||||
******************************************************/
|
||||
private static boolean theTestPassed = false;
|
||||
private static boolean testGeneratedInterrupt = false;
|
||||
private static String failureMessage = "";
|
||||
|
||||
private static Thread mainThread = null;
|
||||
|
||||
private static int sleepTime = 300000;
|
||||
|
||||
public static void main( String args[] ) throws InterruptedException
|
||||
{
|
||||
mainThread = Thread.currentThread();
|
||||
try
|
||||
{
|
||||
init();
|
||||
}
|
||||
catch( TestPassedException e )
|
||||
{
|
||||
//The test passed, so just return from main and harness will
|
||||
// interepret this return as a pass
|
||||
return;
|
||||
}
|
||||
//At this point, neither test passed nor test failed has been
|
||||
// called -- either would have thrown an exception and ended the
|
||||
// test, so we know we have multiple threads.
|
||||
|
||||
//Test involves other threads, so sleep and wait for them to
|
||||
// called pass() or fail()
|
||||
try
|
||||
{
|
||||
Thread.sleep( sleepTime );
|
||||
//Timed out, so fail the test
|
||||
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
if( ! testGeneratedInterrupt ) throw e;
|
||||
|
||||
//reset flag in case hit this code more than once for some reason (just safety)
|
||||
testGeneratedInterrupt = false;
|
||||
if ( theTestPassed == false )
|
||||
{
|
||||
throw new RuntimeException( failureMessage );
|
||||
}
|
||||
}
|
||||
|
||||
}//main
|
||||
|
||||
public static synchronized void setTimeoutTo( int seconds )
|
||||
{
|
||||
sleepTime = seconds * 1000;
|
||||
}
|
||||
|
||||
public static synchronized void pass()
|
||||
{
|
||||
Sysout.println( "The test passed." );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//first check if this is executing in main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//Still in the main thread, so set the flag just for kicks,
|
||||
// and throw a test passed exception which will be caught
|
||||
// and end the test.
|
||||
theTestPassed = true;
|
||||
throw new TestPassedException();
|
||||
}
|
||||
//pass was called from a different thread, so set the flag and interrupt
|
||||
// the main thead.
|
||||
theTestPassed = true;
|
||||
testGeneratedInterrupt = true;
|
||||
if (mainThread != null){
|
||||
mainThread.interrupt();
|
||||
}
|
||||
}//pass()
|
||||
|
||||
public static synchronized void fail()
|
||||
{
|
||||
//test writer didn't specify why test failed, so give generic
|
||||
fail( "it just plain failed! :-)" );
|
||||
}
|
||||
|
||||
public static synchronized void fail( String whyFailed )
|
||||
{
|
||||
Sysout.println( "The test failed: " + whyFailed );
|
||||
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||
//check if this called from main thread
|
||||
if ( mainThread == Thread.currentThread() )
|
||||
{
|
||||
//If main thread, fail now 'cause not sleeping
|
||||
throw new RuntimeException( whyFailed );
|
||||
}
|
||||
theTestPassed = false;
|
||||
testGeneratedInterrupt = true;
|
||||
failureMessage = whyFailed;
|
||||
mainThread.interrupt();
|
||||
}//fail()
|
||||
|
||||
}// class ManualMainTest
|
||||
|
||||
//This exception is used to exit from any level of call nesting
|
||||
// when it's determined that the test has passed, and immediately
|
||||
// end the test.
|
||||
class TestPassedException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
||||
//*********** End Standard Test Machinery Section **********
|
||||
|
||||
|
||||
//************ Begin classes defined for the test ****************
|
||||
|
||||
// make listeners in a class defined here, and instantiate them in init()
|
||||
|
||||
/* Example of a class which may be written as part of a test
|
||||
class NewClass implements anInterface
|
||||
{
|
||||
static int newVar = 0;
|
||||
|
||||
public void eventDispatched(AWTEvent e)
|
||||
{
|
||||
//Counting events to see if we get enough
|
||||
eventCount++;
|
||||
|
||||
if( eventCount == 20 )
|
||||
{
|
||||
//got enough events, so pass
|
||||
|
||||
ManualMainTest.pass();
|
||||
}
|
||||
else if( tries == 20 )
|
||||
{
|
||||
//tried too many times without getting enough events so fail
|
||||
|
||||
ManualMainTest.fail();
|
||||
}
|
||||
|
||||
}// eventDispatched()
|
||||
|
||||
}// NewClass class
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//************** End classes defined for the test *******************
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
Standard Test Machinery
|
||||
DO NOT modify anything below -- it's a standard
|
||||
chunk of code whose purpose is to make user
|
||||
interaction uniform, and thereby make it simpler
|
||||
to read and understand someone else's test.
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery.
|
||||
It creates a dialog (with the instructions), and is the interface
|
||||
for sending text messages to the user.
|
||||
To print the instructions, send an array of strings to Sysout.createDialog
|
||||
WithInstructions method. Put one line of instructions per array entry.
|
||||
To display a message for the tester to see, simply call Sysout.println
|
||||
with the string to be displayed.
|
||||
This mimics System.out.println but works within the test harness as well
|
||||
as standalone.
|
||||
*/
|
||||
|
||||
class Sysout
|
||||
{
|
||||
private static TestDialog dialog;
|
||||
private static boolean numbering = false;
|
||||
private static int messageNumber = 0;
|
||||
|
||||
public static void createDialogWithInstructions( String[] instructions )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
dialog.printInstructions( instructions );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
public static void createDialog( )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
String[] defInstr = { "Instructions will appear here. ", "" } ;
|
||||
dialog.printInstructions( defInstr );
|
||||
dialog.setVisible(true);
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
|
||||
/* Enables message counting for the tester. */
|
||||
public static void enableNumbering(boolean enable){
|
||||
numbering = enable;
|
||||
}
|
||||
|
||||
public static void printInstructions( String[] instructions )
|
||||
{
|
||||
dialog.printInstructions( instructions );
|
||||
}
|
||||
|
||||
|
||||
public static void println( String messageIn )
|
||||
{
|
||||
if (numbering) {
|
||||
messageIn = "" + messageNumber + " " + messageIn;
|
||||
messageNumber++;
|
||||
}
|
||||
dialog.displayMessage( messageIn );
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
/**
|
||||
This is part of the standard test machinery. It provides a place for the
|
||||
test instructions to be displayed, and a place for interactive messages
|
||||
to the user to be displayed.
|
||||
To have the test instructions displayed, see Sysout.
|
||||
To have a message to the user be displayed, see Sysout.
|
||||
Do not call anything in this dialog directly.
|
||||
*/
|
||||
class TestDialog extends Dialog implements ActionListener
|
||||
{
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
Panel buttonP = new Panel();
|
||||
Button passB = new Button( "pass" );
|
||||
Button failB = new Button( "fail" );
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog( Frame frame, String name )
|
||||
{
|
||||
super( frame, name );
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||
add( "North", instructionsText );
|
||||
|
||||
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||
add("Center", messageText);
|
||||
|
||||
passB = new Button( "pass" );
|
||||
passB.setActionCommand( "pass" );
|
||||
passB.addActionListener( this );
|
||||
buttonP.add( "East", passB );
|
||||
|
||||
failB = new Button( "fail" );
|
||||
failB.setActionCommand( "fail" );
|
||||
failB.addActionListener( this );
|
||||
buttonP.add( "West", failB );
|
||||
|
||||
add( "South", buttonP );
|
||||
pack();
|
||||
|
||||
setVisible(true);
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions( String[] instructions )
|
||||
{
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText( "" );
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for( int i=0; i < instructions.length; i++ )
|
||||
{
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[ i ];
|
||||
while( remainingStr.length() > 0 )
|
||||
{
|
||||
//if longer than max then chop off first max chars to print
|
||||
if( remainingStr.length() >= maxStringLength )
|
||||
{
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf( ' ', maxStringLength - 1 );
|
||||
|
||||
if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring( 0, posOfSpace + 1 );
|
||||
remainingStr = remainingStr.substring( posOfSpace + 1 );
|
||||
}
|
||||
//else just print
|
||||
else
|
||||
{
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append( printStr + "\n" );
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage( String messageIn )
|
||||
{
|
||||
messageText.append( messageIn + "\n" );
|
||||
System.out.println(messageIn);
|
||||
}
|
||||
|
||||
//catch presses of the passed and failed buttons.
|
||||
//simply call the standard pass() or fail() static methods of
|
||||
//ManualMainTest
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
if( e.getActionCommand() == "pass" )
|
||||
{
|
||||
SmoothWheel.pass();
|
||||
}
|
||||
else
|
||||
{
|
||||
SmoothWheel.fail();
|
||||
}
|
||||
}
|
||||
|
||||
}// TestDialog class
|
Loading…
Reference in New Issue
Block a user