1.1 --- a/make/sun/splashscreen/Makefile Wed Mar 26 17:48:05 2008 -0700
1.2 +++ b/make/sun/splashscreen/Makefile Thu Mar 27 12:09:50 2008 -0700
1.3 @@ -85,3 +85,13 @@
1.4 CPPFLAGS += -I$(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen -I$(SHARE_SRC)/native/$(PKGDIR)/splashscreen
1.5 CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/image/jpeg -I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3
1.6
1.7 +ifeq ($(PLATFORM), linux)
1.8 + ifeq ($(ARCH_DATA_MODEL), 64)
1.9 + # 64-bit gcc has problems compiling MMX instructions.
1.10 + # Google it for more details. Possibly the newer versions of
1.11 + # the PNG-library and/or the new compiler will not need this
1.12 + # option in the future.
1.13 + CPPFLAGS += -DPNG_NO_MMX_CODE
1.14 + endif
1.15 +endif
1.16 +
2.1 --- a/make/sun/xawt/Makefile Wed Mar 26 17:48:05 2008 -0700
2.2 +++ b/make/sun/xawt/Makefile Thu Mar 27 12:09:50 2008 -0700
2.3 @@ -1,5 +1,5 @@
2.4 #
2.5 -# Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
2.6 +# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
2.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2.8 #
2.9 # This code is free software; you can redistribute it and/or modify it
2.10 @@ -246,7 +246,7 @@
2.11 @if [ "$(DOCOMPARE)$(suffix $@)" = "true.64" ]; then \
2.12 $(ECHO) COMPARING $@ and $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
2.13 $(DIFF) $@ $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
2.14 - fi
2.15 + fi
2.16
2.17 $(TEMPDIR)/.gen.wrappers: $(SIZES) $(WRAPPER_GENERATOR_CLASS) $(XLIBTYPES)
2.18 $(BOOT_JAVA_CMD) -cp $(WRAPPER_GENERATOR_TEMPDIR) WrapperGenerator \
2.19 @@ -256,10 +256,11 @@
2.20 $(MKDIR) -p $(TEMPDIR)
2.21 $(TOUCH) $(TEMPDIR)/.gen.wrappers
2.22
2.23 -generated.clean:
2.24 +generated.clean:
2.25 $(RM) -r $(WRAPPER_GENERATOR_TEMPDIR)
2.26 $(RM) -r $(WRAPPER_GENERATOR_DIR)
2.27 $(RM) -r $(GEN_DIR)/*.java
2.28 + $(RM) -r $(TEMPDIR)/.gen_icons
2.29
2.30 ifdef OPENJDK
2.31 ICONS_PATH_PREFIX=$(PLATFORM_SRC)
3.1 --- a/src/share/classes/java/awt/Component.java Wed Mar 26 17:48:05 2008 -0700
3.2 +++ b/src/share/classes/java/awt/Component.java Thu Mar 27 12:09:50 2008 -0700
3.3 @@ -634,6 +634,11 @@
3.4 */
3.5 private PropertyChangeSupport changeSupport;
3.6
3.7 + private transient final Object changeSupportLock = new Object();
3.8 + private Object getChangeSupportLock() {
3.9 + return changeSupportLock;
3.10 + }
3.11 +
3.12 boolean isPacked = false;
3.13
3.14 /**
3.15 @@ -935,24 +940,26 @@
3.16 */
3.17 public GraphicsConfiguration getGraphicsConfiguration() {
3.18 synchronized(getTreeLock()) {
3.19 - GraphicsConfiguration gc = graphicsConfig;
3.20 - Component parent = getParent();
3.21 - while ((gc == null) && (parent != null)) {
3.22 - gc = parent.getGraphicsConfiguration();
3.23 - parent = parent.getParent();
3.24 - }
3.25 - return gc;
3.26 + if (graphicsConfig != null) {
3.27 + return graphicsConfig;
3.28 + } else if (getParent() != null) {
3.29 + return getParent().getGraphicsConfiguration();
3.30 + } else {
3.31 + return null;
3.32 + }
3.33 }
3.34 }
3.35
3.36 final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
3.37 - GraphicsConfiguration gc = this.graphicsConfig;
3.38 - Component par = this.parent;
3.39 - while ((gc == null) && (par != null)) {
3.40 - gc = par.getGraphicsConfiguration_NoClientCode();
3.41 - par = par.parent;
3.42 - }
3.43 - return gc;
3.44 + GraphicsConfiguration graphicsConfig = this.graphicsConfig;
3.45 + Container parent = this.parent;
3.46 + if (graphicsConfig != null) {
3.47 + return graphicsConfig;
3.48 + } else if (parent != null) {
3.49 + return parent.getGraphicsConfiguration_NoClientCode();
3.50 + } else {
3.51 + return null;
3.52 + }
3.53 }
3.54
3.55 /**
3.56 @@ -4602,7 +4609,8 @@
3.57 e.isPopupTrigger(),
3.58 e.getScrollType(),
3.59 e.getScrollAmount(),
3.60 - e.getWheelRotation());
3.61 + e.getWheelRotation(),
3.62 + e.getPreciseWheelRotation());
3.63 ((AWTEvent)e).copyPrivateDataInto(newMWE);
3.64 // When dispatching a wheel event to
3.65 // ancestor, there is no need trying to find descendant
3.66 @@ -6484,7 +6492,7 @@
3.67 // will need some help.
3.68 Container parent = this.parent;
3.69 if (parent != null && parent.peer instanceof LightweightPeer) {
3.70 - nativeInLightFixer = new NativeInLightFixer();
3.71 + relocateComponent();
3.72 }
3.73 }
3.74 invalidate();
3.75 @@ -6595,10 +6603,6 @@
3.76 }
3.77 }
3.78
3.79 - if (nativeInLightFixer != null) {
3.80 - nativeInLightFixer.uninstall();
3.81 - }
3.82 -
3.83 ComponentPeer p = peer;
3.84 if (p != null) {
3.85 boolean isLightweight = isLightweight();
3.86 @@ -7836,15 +7840,17 @@
3.87 * @see #getPropertyChangeListeners
3.88 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
3.89 */
3.90 - public synchronized void addPropertyChangeListener(
3.91 + public void addPropertyChangeListener(
3.92 PropertyChangeListener listener) {
3.93 - if (listener == null) {
3.94 - return;
3.95 - }
3.96 - if (changeSupport == null) {
3.97 - changeSupport = new PropertyChangeSupport(this);
3.98 - }
3.99 - changeSupport.addPropertyChangeListener(listener);
3.100 + synchronized (getChangeSupportLock()) {
3.101 + if (listener == null) {
3.102 + return;
3.103 + }
3.104 + if (changeSupport == null) {
3.105 + changeSupport = new PropertyChangeSupport(this);
3.106 + }
3.107 + changeSupport.addPropertyChangeListener(listener);
3.108 + }
3.109 }
3.110
3.111 /**
3.112 @@ -7860,12 +7866,14 @@
3.113 * @see #getPropertyChangeListeners
3.114 * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
3.115 */
3.116 - public synchronized void removePropertyChangeListener(
3.117 + public void removePropertyChangeListener(
3.118 PropertyChangeListener listener) {
3.119 - if (listener == null || changeSupport == null) {
3.120 - return;
3.121 - }
3.122 - changeSupport.removePropertyChangeListener(listener);
3.123 + synchronized (getChangeSupportLock()) {
3.124 + if (listener == null || changeSupport == null) {
3.125 + return;
3.126 + }
3.127 + changeSupport.removePropertyChangeListener(listener);
3.128 + }
3.129 }
3.130
3.131 /**
3.132 @@ -7882,11 +7890,13 @@
3.133 * @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
3.134 * @since 1.4
3.135 */
3.136 - public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
3.137 - if (changeSupport == null) {
3.138 - return new PropertyChangeListener[0];
3.139 - }
3.140 - return changeSupport.getPropertyChangeListeners();
3.141 + public PropertyChangeListener[] getPropertyChangeListeners() {
3.142 + synchronized (getChangeSupportLock()) {
3.143 + if (changeSupport == null) {
3.144 + return new PropertyChangeListener[0];
3.145 + }
3.146 + return changeSupport.getPropertyChangeListeners();
3.147 + }
3.148 }
3.149
3.150 /**
3.151 @@ -7920,16 +7930,18 @@
3.152 * @see #getPropertyChangeListeners(java.lang.String)
3.153 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
3.154 */
3.155 - public synchronized void addPropertyChangeListener(
3.156 + public void addPropertyChangeListener(
3.157 String propertyName,
3.158 PropertyChangeListener listener) {
3.159 - if (listener == null) {
3.160 - return;
3.161 - }
3.162 - if (changeSupport == null) {
3.163 - changeSupport = new PropertyChangeSupport(this);
3.164 - }
3.165 - changeSupport.addPropertyChangeListener(propertyName, listener);
3.166 + synchronized (getChangeSupportLock()) {
3.167 + if (listener == null) {
3.168 + return;
3.169 + }
3.170 + if (changeSupport == null) {
3.171 + changeSupport = new PropertyChangeSupport(this);
3.172 + }
3.173 + changeSupport.addPropertyChangeListener(propertyName, listener);
3.174 + }
3.175 }
3.176
3.177 /**
3.178 @@ -7948,13 +7960,15 @@
3.179 * @see #getPropertyChangeListeners(java.lang.String)
3.180 * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
3.181 */
3.182 - public synchronized void removePropertyChangeListener(
3.183 + public void removePropertyChangeListener(
3.184 String propertyName,
3.185 PropertyChangeListener listener) {
3.186 - if (listener == null || changeSupport == null) {
3.187 - return;
3.188 - }
3.189 - changeSupport.removePropertyChangeListener(propertyName, listener);
3.190 + synchronized (getChangeSupportLock()) {
3.191 + if (listener == null || changeSupport == null) {
3.192 + return;
3.193 + }
3.194 + changeSupport.removePropertyChangeListener(propertyName, listener);
3.195 + }
3.196 }
3.197
3.198 /**
3.199 @@ -7971,12 +7985,14 @@
3.200 * @see #getPropertyChangeListeners
3.201 * @since 1.4
3.202 */
3.203 - public synchronized PropertyChangeListener[] getPropertyChangeListeners(
3.204 + public PropertyChangeListener[] getPropertyChangeListeners(
3.205 String propertyName) {
3.206 - if (changeSupport == null) {
3.207 - return new PropertyChangeListener[0];
3.208 - }
3.209 - return changeSupport.getPropertyChangeListeners(propertyName);
3.210 + synchronized (getChangeSupportLock()) {
3.211 + if (changeSupport == null) {
3.212 + return new PropertyChangeListener[0];
3.213 + }
3.214 + return changeSupport.getPropertyChangeListeners(propertyName);
3.215 + }
3.216 }
3.217
3.218 /**
3.219 @@ -7991,7 +8007,10 @@
3.220 */
3.221 protected void firePropertyChange(String propertyName,
3.222 Object oldValue, Object newValue) {
3.223 - PropertyChangeSupport changeSupport = this.changeSupport;
3.224 + PropertyChangeSupport changeSupport;
3.225 + synchronized (getChangeSupportLock()) {
3.226 + changeSupport = this.changeSupport;
3.227 + }
3.228 if (changeSupport == null ||
3.229 (oldValue != null && newValue != null && oldValue.equals(newValue))) {
3.230 return;
3.231 @@ -8491,8 +8510,6 @@
3.232 setComponentOrientation(orientation);
3.233 }
3.234
3.235 - transient NativeInLightFixer nativeInLightFixer;
3.236 -
3.237 /**
3.238 * Checks that this component meets the prerequesites to be focus owner:
3.239 * - it is enabled, visible, focusable
3.240 @@ -8518,188 +8535,25 @@
3.241 }
3.242
3.243 /**
3.244 - * This odd class is to help out a native component that has been
3.245 - * embedded in a lightweight component. Moving lightweight
3.246 - * components around and changing their visibility is not seen
3.247 - * by the native window system. This is a feature for lightweights,
3.248 - * but a problem for native components that depend upon the
3.249 - * lightweights. An instance of this class listens to the lightweight
3.250 - * parents of an associated native component (the outer class).
3.251 - *
3.252 - * @author Timothy Prinzing
3.253 - */
3.254 - final class NativeInLightFixer implements ComponentListener, ContainerListener {
3.255 -
3.256 - NativeInLightFixer() {
3.257 - lightParents = new Vector();
3.258 - install(parent);
3.259 - }
3.260 -
3.261 - void install(Container parent) {
3.262 - lightParents.clear();
3.263 - Container p = parent;
3.264 - boolean isLwParentsVisible = true;
3.265 - // stash a reference to the components that are being observed so that
3.266 - // we can reliably remove ourself as a listener later.
3.267 - for (; p.peer instanceof LightweightPeer; p = p.parent) {
3.268 -
3.269 - // register listeners and stash a reference
3.270 - p.addComponentListener(this);
3.271 - p.addContainerListener(this);
3.272 - lightParents.addElement(p);
3.273 - isLwParentsVisible &= p.isVisible();
3.274 - }
3.275 - // register with the native host (native parent of associated native)
3.276 - // to get notified if the top-level lightweight is removed.
3.277 - nativeHost = p;
3.278 - p.addContainerListener(this);
3.279 -
3.280 - // kick start the fixup. Since the event isn't looked at
3.281 - // we can simulate movement notification.
3.282 - componentMoved(null);
3.283 - if (!isLwParentsVisible) {
3.284 - synchronized (getTreeLock()) {
3.285 - if (peer != null) {
3.286 - peer.hide();
3.287 - }
3.288 - }
3.289 - }
3.290 - }
3.291 -
3.292 - void uninstall() {
3.293 - if (nativeHost != null) {
3.294 - removeReferences();
3.295 - }
3.296 - }
3.297 -
3.298 - // --- ComponentListener -------------------------------------------
3.299 -
3.300 - /**
3.301 - * Invoked when one of the lightweight parents has been resized.
3.302 - * This doesn't change the position of the native child so it
3.303 - * is ignored.
3.304 - */
3.305 - public void componentResized(ComponentEvent e) {
3.306 - }
3.307 -
3.308 - /**
3.309 - * Invoked when one of the lightweight parents has been moved.
3.310 - * The native peer must be told of the new position which is
3.311 - * relative to the native container that is hosting the
3.312 - * lightweight components.
3.313 - */
3.314 - public void componentMoved(ComponentEvent e) {
3.315 - synchronized (getTreeLock()) {
3.316 - int nativeX = x;
3.317 - int nativeY = y;
3.318 - for(Component c = parent; (c != null) &&
3.319 - (c.peer instanceof LightweightPeer);
3.320 - c = c.parent) {
3.321 -
3.322 - nativeX += c.x;
3.323 - nativeY += c.y;
3.324 - }
3.325 - if (peer != null) {
3.326 - peer.setBounds(nativeX, nativeY, width, height,
3.327 - ComponentPeer.SET_LOCATION);
3.328 - }
3.329 - }
3.330 - }
3.331 -
3.332 - /**
3.333 - * Invoked when a lightweight parent component has been
3.334 - * shown. The associated native component must also be
3.335 - * shown if it hasn't had an overriding hide done on it.
3.336 - */
3.337 - public void componentShown(ComponentEvent e) {
3.338 - if (shouldShow()) {
3.339 - synchronized (getTreeLock()) {
3.340 - if (peer != null) {
3.341 - peer.show();
3.342 - }
3.343 - }
3.344 - }
3.345 - }
3.346 -
3.347 - /**
3.348 - * Invoked when one of the lightweight parents become visible.
3.349 - * Returns true if component and all its lightweight
3.350 - * parents are visible.
3.351 - */
3.352 - private boolean shouldShow() {
3.353 - boolean isLwParentsVisible = visible;
3.354 - for (int i = lightParents.size() - 1;
3.355 - i >= 0 && isLwParentsVisible;
3.356 - i--)
3.357 + * Fix the location of the HW component in a LW container hierarchy.
3.358 + */
3.359 + final void relocateComponent() {
3.360 + synchronized (getTreeLock()) {
3.361 + if (peer == null) {
3.362 + return;
3.363 + }
3.364 + int nativeX = x;
3.365 + int nativeY = y;
3.366 + for (Component cont = getContainer();
3.367 + cont != null && cont.isLightweight();
3.368 + cont = cont.getContainer())
3.369 {
3.370 - isLwParentsVisible &=
3.371 - ((Container) lightParents.elementAt(i)).isVisible();
3.372 - }
3.373 - return isLwParentsVisible;
3.374 - }
3.375 -
3.376 - /**
3.377 - * Invoked when component has been hidden.
3.378 - */
3.379 - public void componentHidden(ComponentEvent e) {
3.380 - if (visible) {
3.381 - synchronized (getTreeLock()) {
3.382 - if (peer != null) {
3.383 - peer.hide();
3.384 - }
3.385 - }
3.386 - }
3.387 - }
3.388 -
3.389 - // --- ContainerListener ------------------------------------
3.390 -
3.391 - /**
3.392 - * Invoked when a component has been added to a lightweight
3.393 - * parent. This doesn't effect the native component.
3.394 - */
3.395 - public void componentAdded(ContainerEvent e) {
3.396 - }
3.397 -
3.398 - /**
3.399 - * Invoked when a lightweight parent has been removed.
3.400 - * This means the services of this listener are no longer
3.401 - * required and it should remove all references (ie
3.402 - * registered listeners).
3.403 - */
3.404 - public void componentRemoved(ContainerEvent e) {
3.405 - Component c = e.getChild();
3.406 - if (c == Component.this) {
3.407 - removeReferences();
3.408 - } else {
3.409 - int n = lightParents.size();
3.410 - for (int i = 0; i < n; i++) {
3.411 - Container p = (Container) lightParents.elementAt(i);
3.412 - if (p == c) {
3.413 - removeReferences();
3.414 - break;
3.415 - }
3.416 - }
3.417 - }
3.418 - }
3.419 -
3.420 - /**
3.421 - * Removes references to this object so it can be
3.422 - * garbage collected.
3.423 - */
3.424 - void removeReferences() {
3.425 - int n = lightParents.size();
3.426 - for (int i = 0; i < n; i++) {
3.427 - Container c = (Container) lightParents.elementAt(i);
3.428 - c.removeComponentListener(this);
3.429 - c.removeContainerListener(this);
3.430 - }
3.431 - nativeHost.removeContainerListener(this);
3.432 - lightParents.clear();
3.433 - nativeHost = null;
3.434 - }
3.435 -
3.436 - Vector lightParents;
3.437 - Container nativeHost;
3.438 + nativeX += cont.x;
3.439 + nativeY += cont.y;
3.440 + }
3.441 + peer.setBounds(nativeX, nativeY, width, height,
3.442 + ComponentPeer.SET_LOCATION);
3.443 + }
3.444 }
3.445
3.446 /**
3.447 @@ -9453,6 +9307,19 @@
3.448 // ************************** MIXING CODE *******************************
3.449
3.450 /**
3.451 + * Check whether we can trust the current bounds of the component.
3.452 + * The return value of false indicates that the container of the
3.453 + * component is invalid, and therefore needs to be layed out, which would
3.454 + * probably mean changing the bounds of its children.
3.455 + * Null-layout of the container or absence of the container mean
3.456 + * the bounds of the component are final and can be trusted.
3.457 + */
3.458 + private boolean areBoundsValid() {
3.459 + Container cont = getContainer();
3.460 + return cont == null || cont.isValid() || cont.getLayout() == null;
3.461 + }
3.462 +
3.463 + /**
3.464 * Applies the shape to the component
3.465 * @param shape Shape to be applied to the component
3.466 */
3.467 @@ -9475,7 +9342,7 @@
3.468 // to modify the object outside of the mixing code.
3.469 this.compoundShape = shape;
3.470
3.471 - if (isValid()) {
3.472 + if (areBoundsValid()) {
3.473 Point compAbsolute = getLocationOnWindow();
3.474
3.475 if (mixingLog.isLoggable(Level.FINER)) {
3.476 @@ -9602,7 +9469,7 @@
3.477
3.478 void applyCurrentShape() {
3.479 checkTreeLock();
3.480 - if (!isValid()) {
3.481 + if (!areBoundsValid()) {
3.482 return; // Because applyCompoundShape() ignores such components anyway
3.483 }
3.484 if (mixingLog.isLoggable(Level.FINE)) {
4.1 --- a/src/share/classes/java/awt/Container.java Wed Mar 26 17:48:05 2008 -0700
4.2 +++ b/src/share/classes/java/awt/Container.java Thu Mar 27 12:09:50 2008 -0700
4.3 @@ -832,16 +832,8 @@
4.4 }
4.5 if (!comp.isLightweight() && isLightweight()) {
4.6 // If component is heavyweight and one of the containers is lightweight
4.7 - // some NativeInLightFixer activity should be performed
4.8 - if (!curParent.isLightweight()) {
4.9 - // Moving from heavyweight container to lightweight container - should create NativeInLightFixer
4.10 - // since addNotify does this
4.11 - comp.nativeInLightFixer = new NativeInLightFixer();
4.12 - } else {
4.13 - // Component already has NativeInLightFixer - just reinstall it
4.14 - // because hierarchy changed and he needs to rebuild list of parents to listen.
4.15 - comp.nativeInLightFixer.install(this);
4.16 - }
4.17 + // the location of the component should be fixed.
4.18 + comp.relocateComponent();
4.19 }
4.20 }
4.21 }
4.22 @@ -2267,53 +2259,56 @@
4.23 EventTargetFilter filter,
4.24 boolean searchHeavyweightChildren,
4.25 boolean searchHeavyweightDescendants) {
4.26 - int ncomponents = this.ncomponents;
4.27 - Component component[] = this.component;
4.28 -
4.29 - for (int i = 0 ; i < ncomponents ; i++) {
4.30 - Component comp = component[i];
4.31 - if (comp != null && comp.visible &&
4.32 - ((!searchHeavyweightChildren &&
4.33 - comp.peer instanceof LightweightPeer) ||
4.34 - (searchHeavyweightChildren &&
4.35 - !(comp.peer instanceof LightweightPeer))) &&
4.36 - comp.contains(x - comp.x, y - comp.y)) {
4.37 -
4.38 - // found a component that intersects the point, see if there is
4.39 - // a deeper possibility.
4.40 - if (comp instanceof Container) {
4.41 - Container child = (Container) comp;
4.42 - Component deeper = child.getMouseEventTarget(x - child.x,
4.43 - y - child.y,
4.44 - includeSelf,
4.45 - filter,
4.46 - searchHeavyweightDescendants);
4.47 - if (deeper != null) {
4.48 - return deeper;
4.49 - }
4.50 - } else {
4.51 - if (filter.accept(comp)) {
4.52 - // there isn't a deeper target, but this component is a
4.53 - // target
4.54 - return comp;
4.55 + synchronized (getTreeLock()) {
4.56 + int ncomponents = this.ncomponents;
4.57 + Component component[] = this.component;
4.58 +
4.59 + for (int i = 0 ; i < ncomponents ; i++) {
4.60 + Component comp = component[i];
4.61 + if (comp != null && comp.visible &&
4.62 + ((!searchHeavyweightChildren &&
4.63 + comp.peer instanceof LightweightPeer) ||
4.64 + (searchHeavyweightChildren &&
4.65 + !(comp.peer instanceof LightweightPeer))) &&
4.66 + comp.contains(x - comp.x, y - comp.y)) {
4.67 +
4.68 + // found a component that intersects the point, see if there
4.69 + // is a deeper possibility.
4.70 + if (comp instanceof Container) {
4.71 + Container child = (Container) comp;
4.72 + Component deeper = child.getMouseEventTarget(
4.73 + x - child.x,
4.74 + y - child.y,
4.75 + includeSelf,
4.76 + filter,
4.77 + searchHeavyweightDescendants);
4.78 + if (deeper != null) {
4.79 + return deeper;
4.80 + }
4.81 + } else {
4.82 + if (filter.accept(comp)) {
4.83 + // there isn't a deeper target, but this component
4.84 + // is a target
4.85 + return comp;
4.86 + }
4.87 }
4.88 }
4.89 }
4.90 +
4.91 + boolean isPeerOK;
4.92 + boolean isMouseOverMe;
4.93 +
4.94 + isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
4.95 + isMouseOverMe = contains(x,y);
4.96 +
4.97 + // didn't find a child target, return this component if it's
4.98 + // a possible target
4.99 + if (isMouseOverMe && isPeerOK && filter.accept(this)) {
4.100 + return this;
4.101 + }
4.102 + // no possible target
4.103 + return null;
4.104 }
4.105 -
4.106 - boolean isPeerOK;
4.107 - boolean isMouseOverMe;
4.108 -
4.109 - isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
4.110 - isMouseOverMe = contains(x,y);
4.111 -
4.112 - // didn't find a child target, return this component if it's a possible
4.113 - // target
4.114 - if (isMouseOverMe && isPeerOK && filter.accept(this)) {
4.115 - return this;
4.116 - }
4.117 - // no possible target
4.118 - return null;
4.119 }
4.120
4.121 static interface EventTargetFilter {
4.122 @@ -3950,6 +3945,83 @@
4.123 }
4.124 }
4.125
4.126 + private void recursiveShowHeavyweightChildren() {
4.127 + if (!hasHeavyweightDescendants() || !isVisible()) {
4.128 + return;
4.129 + }
4.130 + for (int index = 0; index < getComponentCount(); index++) {
4.131 + Component comp = getComponent(index);
4.132 + if (comp.isLightweight()) {
4.133 + if (comp instanceof Container) {
4.134 + ((Container)comp).recursiveShowHeavyweightChildren();
4.135 + }
4.136 + } else {
4.137 + if (comp.isVisible()) {
4.138 + ComponentPeer peer = comp.getPeer();
4.139 + if (peer != null) {
4.140 + peer.show();
4.141 + }
4.142 + }
4.143 + }
4.144 + }
4.145 + }
4.146 +
4.147 + private void recursiveHideHeavyweightChildren() {
4.148 + if (!hasHeavyweightDescendants()) {
4.149 + return;
4.150 + }
4.151 + for (int index = 0; index < getComponentCount(); index++) {
4.152 + Component comp = getComponent(index);
4.153 + if (comp.isLightweight()) {
4.154 + if (comp instanceof Container) {
4.155 + ((Container)comp).recursiveHideHeavyweightChildren();
4.156 + }
4.157 + } else {
4.158 + if (comp.isVisible()) {
4.159 + ComponentPeer peer = comp.getPeer();
4.160 + if (peer != null) {
4.161 + peer.hide();
4.162 + }
4.163 + }
4.164 + }
4.165 + }
4.166 + }
4.167 +
4.168 + private void recursiveRelocateHeavyweightChildren(Point origin) {
4.169 + for (int index = 0; index < getComponentCount(); index++) {
4.170 + Component comp = getComponent(index);
4.171 + if (comp.isLightweight()) {
4.172 + if (comp instanceof Container &&
4.173 + ((Container)comp).hasHeavyweightDescendants())
4.174 + {
4.175 + final Point newOrigin = new Point(origin);
4.176 + newOrigin.translate(comp.getX(), comp.getY());
4.177 + ((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
4.178 + }
4.179 + } else {
4.180 + ComponentPeer peer = comp.getPeer();
4.181 + if (peer != null) {
4.182 + peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
4.183 + comp.getWidth(), comp.getHeight(),
4.184 + ComponentPeer.SET_LOCATION);
4.185 + }
4.186 + }
4.187 + }
4.188 + }
4.189 +
4.190 + /*
4.191 + * Consider the heavyweight container hides or shows the HW descendants
4.192 + * automatically. Therefore we care of LW containers' visibility only.
4.193 + */
4.194 + private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
4.195 + if (!isLightweight()) {
4.196 + return true;
4.197 + }
4.198 + return isVisible() && (getContainer() == null ||
4.199 + getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
4.200 + }
4.201 +
4.202 + @Override
4.203 void mixOnShowing() {
4.204 synchronized (getTreeLock()) {
4.205 if (mixingLog.isLoggable(Level.FINE)) {
4.206 @@ -3958,6 +4030,10 @@
4.207
4.208 boolean isLightweight = isLightweight();
4.209
4.210 + if (isLightweight && isRecursivelyVisibleUpToHeavyweightContainer()) {
4.211 + recursiveShowHeavyweightChildren();
4.212 + }
4.213 +
4.214 if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) {
4.215 recursiveApplyCurrentShape();
4.216 }
4.217 @@ -3966,6 +4042,42 @@
4.218 }
4.219 }
4.220
4.221 + @Override
4.222 + void mixOnHiding(boolean isLightweight) {
4.223 + synchronized (getTreeLock()) {
4.224 + if (mixingLog.isLoggable(Level.FINE)) {
4.225 + mixingLog.fine("this = " + this +
4.226 + "; isLightweight=" + isLightweight);
4.227 + }
4.228 + if (isLightweight) {
4.229 + recursiveHideHeavyweightChildren();
4.230 + }
4.231 + super.mixOnHiding(isLightweight);
4.232 + }
4.233 + }
4.234 +
4.235 + @Override
4.236 + void mixOnReshaping() {
4.237 + synchronized (getTreeLock()) {
4.238 + if (mixingLog.isLoggable(Level.FINE)) {
4.239 + mixingLog.fine("this = " + this);
4.240 + }
4.241 + if (isLightweight() && hasHeavyweightDescendants()) {
4.242 + final Point origin = new Point(getX(), getY());
4.243 + for (Container cont = getContainer();
4.244 + cont != null && cont.isLightweight();
4.245 + cont = cont.getContainer())
4.246 + {
4.247 + origin.translate(cont.getX(), cont.getY());
4.248 + }
4.249 +
4.250 + recursiveRelocateHeavyweightChildren(origin);
4.251 + }
4.252 + super.mixOnReshaping();
4.253 + }
4.254 + }
4.255 +
4.256 + @Override
4.257 void mixOnZOrderChanging(int oldZorder, int newZorder) {
4.258 synchronized (getTreeLock()) {
4.259 if (mixingLog.isLoggable(Level.FINE)) {
4.260 @@ -4431,7 +4543,8 @@
4.261 e.isPopupTrigger(),
4.262 ((MouseWheelEvent)e).getScrollType(),
4.263 ((MouseWheelEvent)e).getScrollAmount(),
4.264 - ((MouseWheelEvent)e).getWheelRotation());
4.265 + ((MouseWheelEvent)e).getWheelRotation(),
4.266 + ((MouseWheelEvent)e).getPreciseWheelRotation());
4.267 }
4.268 else {
4.269 retargeted = new MouseEvent(target,
5.1 --- a/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Wed Mar 26 17:48:05 2008 -0700
5.2 +++ b/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Thu Mar 27 12:09:50 2008 -0700
5.3 @@ -154,7 +154,7 @@
5.4 private boolean doRestoreFocus(Component toFocus, Component vetoedComponent,
5.5 boolean clearOnFailure)
5.6 {
5.7 - if (toFocus.isShowing() && toFocus.isFocusable() &&
5.8 + if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.isFocusable() &&
5.9 toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK)) {
5.10 return true;
5.11 } else {
6.1 --- a/src/share/classes/java/awt/Window.java Wed Mar 26 17:48:05 2008 -0700
6.2 +++ b/src/share/classes/java/awt/Window.java Thu Mar 27 12:09:50 2008 -0700
6.3 @@ -1,5 +1,5 @@
6.4 /*
6.5 - * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
6.6 + * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved.
6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.8 *
6.9 * This code is free software; you can redistribute it and/or modify it
6.10 @@ -24,7 +24,6 @@
6.11 */
6.12 package java.awt;
6.13
6.14 -import java.applet.Applet;
6.15 import java.awt.event.*;
6.16 import java.awt.im.InputContext;
6.17 import java.awt.image.BufferStrategy;
6.18 @@ -355,18 +354,21 @@
6.19 static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
6.20 final WeakReference<Window> owner;
6.21 final WeakReference weakThis;
6.22 - final AppContext context;
6.23 + final WeakReference<AppContext> context;
6.24 WindowDisposerRecord(AppContext context, Window victim) {
6.25 owner = new WeakReference<Window>(victim.getOwner());
6.26 weakThis = victim.weakThis;
6.27 - this.context = context;
6.28 + this.context = new WeakReference<AppContext>(context);
6.29 }
6.30 public void dispose() {
6.31 Window parent = owner.get();
6.32 if (parent != null) {
6.33 parent.removeOwnedWindow(weakThis);
6.34 }
6.35 - Window.removeFromWindowList(context, weakThis);
6.36 + AppContext ac = context.get();
6.37 + if (null != ac) {
6.38 + Window.removeFromWindowList(ac, weakThis);
6.39 + }
6.40 }
6.41 }
6.42
6.43 @@ -824,7 +826,10 @@
6.44 static private final AtomicBoolean
6.45 beforeFirstWindowShown = new AtomicBoolean(true);
6.46
6.47 - static final void closeSplashScreen() {
6.48 + final void closeSplashScreen() {
6.49 + if (isTrayIconWindow) {
6.50 + return;
6.51 + }
6.52 if (beforeFirstWindowShown.getAndSet(false)) {
6.53 SunToolkit.closeSplashScreen();
6.54 }
7.1 --- a/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Wed Mar 26 17:48:05 2008 -0700
7.2 +++ b/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Thu Mar 27 12:09:50 2008 -0700
7.3 @@ -1,5 +1,5 @@
7.4 /*
7.5 - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
7.6 + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7.8 *
7.9 * This code is free software; you can redistribute it and/or modify it
7.10 @@ -49,7 +49,6 @@
7.11
7.12 import sun.awt.datatransfer.DataTransferer;
7.13
7.14 -
7.15 /**
7.16 * The SystemFlavorMap is a configurable map between "natives" (Strings), which
7.17 * correspond to platform-specific data formats, and "flavors" (DataFlavors),
7.18 @@ -117,16 +116,51 @@
7.19 /**
7.20 * Maps native Strings to Lists of DataFlavors (or base type Strings for
7.21 * text DataFlavors).
7.22 + * Do not use the field directly, use getNativeToFlavor() instead.
7.23 */
7.24 private Map nativeToFlavor = new HashMap();
7.25
7.26 /**
7.27 + * Accessor to nativeToFlavor map. Since we use lazy initialization we must
7.28 + * use this accessor instead of direct access to the field which may not be
7.29 + * initialized yet. This method will initialize the field if needed.
7.30 + *
7.31 + * @return nativeToFlavor
7.32 + */
7.33 + private Map getNativeToFlavor() {
7.34 + if (!isMapInitialized) {
7.35 + initSystemFlavorMap();
7.36 + }
7.37 + return nativeToFlavor;
7.38 + }
7.39 +
7.40 + /**
7.41 * Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
7.42 * native Strings.
7.43 + * Do not use the field directly, use getFlavorToNative() instead.
7.44 */
7.45 private Map flavorToNative = new HashMap();
7.46
7.47 /**
7.48 + * Accessor to flavorToNative map. Since we use lazy initialization we must
7.49 + * use this accessor instead of direct access to the field which may not be
7.50 + * initialized yet. This method will initialize the field if needed.
7.51 + *
7.52 + * @return flavorToNative
7.53 + */
7.54 + private synchronized Map getFlavorToNative() {
7.55 + if (!isMapInitialized) {
7.56 + initSystemFlavorMap();
7.57 + }
7.58 + return flavorToNative;
7.59 + }
7.60 +
7.61 + /**
7.62 + * Shows if the object has been initialized.
7.63 + */
7.64 + private boolean isMapInitialized = false;
7.65 +
7.66 + /**
7.67 * Caches the result of getNativesForFlavor(). Maps DataFlavors to
7.68 * SoftReferences which reference Lists of String natives.
7.69 */
7.70 @@ -169,15 +203,24 @@
7.71 return fm;
7.72 }
7.73
7.74 + private SystemFlavorMap() {
7.75 + }
7.76 +
7.77 /**
7.78 - * Constructs a SystemFlavorMap by reading flavormap.properties and
7.79 + * Initializes a SystemFlavorMap by reading flavormap.properties and
7.80 * AWT.DnD.flavorMapFileURL.
7.81 + * For thread-safety must be called under lock on this.
7.82 */
7.83 - private SystemFlavorMap() {
7.84 - BufferedReader flavormapDotProperties = (BufferedReader)
7.85 + private void initSystemFlavorMap() {
7.86 + if (isMapInitialized) {
7.87 + return;
7.88 + }
7.89 +
7.90 + isMapInitialized = true;
7.91 + BufferedReader flavormapDotProperties =
7.92 java.security.AccessController.doPrivileged(
7.93 - new java.security.PrivilegedAction() {
7.94 - public Object run() {
7.95 + new java.security.PrivilegedAction<BufferedReader>() {
7.96 + public BufferedReader run() {
7.97 String fileName =
7.98 System.getProperty("java.home") +
7.99 File.separator +
7.100 @@ -197,12 +240,11 @@
7.101 }
7.102 });
7.103
7.104 - BufferedReader flavormapURL = (BufferedReader)
7.105 + BufferedReader flavormapURL =
7.106 java.security.AccessController.doPrivileged(
7.107 - new java.security.PrivilegedAction() {
7.108 - public Object run() {
7.109 - String url = Toolkit.getDefaultToolkit().getProperty
7.110 - ("AWT.DnD.flavorMapFileURL", null);
7.111 + new java.security.PrivilegedAction<BufferedReader>() {
7.112 + public BufferedReader run() {
7.113 + String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
7.114
7.115 if (url == null) {
7.116 return null;
7.117 @@ -237,7 +279,6 @@
7.118 }
7.119 }
7.120 }
7.121 -
7.122 /**
7.123 * Copied code from java.util.Properties. Parsing the data ourselves is the
7.124 * only way to handle duplicate keys and values.
7.125 @@ -388,11 +429,11 @@
7.126 // For text/* flavors, store mappings in separate maps to
7.127 // enable dynamic mapping generation at a run-time.
7.128 if ("text".equals(flavor.getPrimaryType())) {
7.129 - store(value, key, flavorToNative);
7.130 - store(key, value, nativeToFlavor);
7.131 + store(value, key, getFlavorToNative());
7.132 + store(key, value, getNativeToFlavor());
7.133 } else {
7.134 - store(flavor, key, flavorToNative);
7.135 - store(key, flavor, nativeToFlavor);
7.136 + store(flavor, key, getFlavorToNative());
7.137 + store(key, flavor, getNativeToFlavor());
7.138 }
7.139 }
7.140 }
7.141 @@ -494,7 +535,7 @@
7.142 * only if the specified native is encoded as a Java MIME type.
7.143 */
7.144 private List nativeToFlavorLookup(String nat) {
7.145 - List flavors = (List)nativeToFlavor.get(nat);
7.146 + List flavors = (List)getNativeToFlavor().get(nat);
7.147
7.148 if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
7.149 DataTransferer transferer = DataTransferer.getInstance();
7.150 @@ -530,15 +571,15 @@
7.151
7.152 if (flavor != null) {
7.153 flavors = new ArrayList(1);
7.154 - nativeToFlavor.put(nat, flavors);
7.155 + getNativeToFlavor().put(nat, flavors);
7.156 flavors.add(flavor);
7.157 getFlavorsForNativeCache.remove(nat);
7.158 getFlavorsForNativeCache.remove(null);
7.159
7.160 - List natives = (List)flavorToNative.get(flavor);
7.161 + List natives = (List)getFlavorToNative().get(flavor);
7.162 if (natives == null) {
7.163 natives = new ArrayList(1);
7.164 - flavorToNative.put(flavor, natives);
7.165 + getFlavorToNative().put(flavor, natives);
7.166 }
7.167 natives.add(nat);
7.168 getNativesForFlavorCache.remove(flavor);
7.169 @@ -559,7 +600,7 @@
7.170 */
7.171 private List flavorToNativeLookup(final DataFlavor flav,
7.172 final boolean synthesize) {
7.173 - List natives = (List)flavorToNative.get(flav);
7.174 + List natives = (List)getFlavorToNative().get(flav);
7.175
7.176 if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
7.177 DataTransferer transferer = DataTransferer.getInstance();
7.178 @@ -584,15 +625,15 @@
7.179 if (synthesize) {
7.180 String encoded = encodeDataFlavor(flav);
7.181 natives = new ArrayList(1);
7.182 - flavorToNative.put(flav, natives);
7.183 + getFlavorToNative().put(flav, natives);
7.184 natives.add(encoded);
7.185 getNativesForFlavorCache.remove(flav);
7.186 getNativesForFlavorCache.remove(null);
7.187
7.188 - List flavors = (List)nativeToFlavor.get(encoded);
7.189 + List flavors = (List)getNativeToFlavor().get(encoded);
7.190 if (flavors == null) {
7.191 flavors = new ArrayList(1);
7.192 - nativeToFlavor.put(encoded, flavors);
7.193 + getNativeToFlavor().put(encoded, flavors);
7.194 }
7.195 flavors.add(flav);
7.196 getFlavorsForNativeCache.remove(encoded);
7.197 @@ -645,7 +686,7 @@
7.198 }
7.199
7.200 if (flav == null) {
7.201 - retval = new ArrayList(nativeToFlavor.keySet());
7.202 + retval = new ArrayList(getNativeToFlavor().keySet());
7.203 } else if (disabledMappingGenerationKeys.contains(flav)) {
7.204 // In this case we shouldn't synthesize a native for this flavor,
7.205 // since its mappings were explicitly specified.
7.206 @@ -655,7 +696,7 @@
7.207 // For text/* flavors, flavor-to-native mappings specified in
7.208 // flavormap.properties are stored per flavor's base type.
7.209 if ("text".equals(flav.getPrimaryType())) {
7.210 - retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
7.211 + retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
7.212 if (retval != null) {
7.213 // To prevent the List stored in the map from modification.
7.214 retval = new ArrayList(retval);
7.215 @@ -663,7 +704,7 @@
7.216 }
7.217
7.218 // Also include text/plain natives, but don't duplicate Strings
7.219 - List textPlainList = (List)flavorToNative.get(TEXT_PLAIN_BASE_TYPE);
7.220 + List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE);
7.221
7.222 if (textPlainList != null && !textPlainList.isEmpty()) {
7.223 // To prevent the List stored in the map from modification.
7.224 @@ -699,7 +740,7 @@
7.225 }
7.226 }
7.227 } else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
7.228 - retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
7.229 + retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
7.230
7.231 if (retval == null || retval.isEmpty()) {
7.232 retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
7.233 @@ -1025,10 +1066,10 @@
7.234 throw new NullPointerException("null arguments not permitted");
7.235 }
7.236
7.237 - List natives = (List)flavorToNative.get(flav);
7.238 + List natives = (List)getFlavorToNative().get(flav);
7.239 if (natives == null) {
7.240 natives = new ArrayList(1);
7.241 - flavorToNative.put(flav, natives);
7.242 + getFlavorToNative().put(flav, natives);
7.243 } else if (natives.contains(nat)) {
7.244 return;
7.245 }
7.246 @@ -1071,7 +1112,7 @@
7.247 throw new NullPointerException("null arguments not permitted");
7.248 }
7.249
7.250 - flavorToNative.remove(flav);
7.251 + getFlavorToNative().remove(flav);
7.252 for (int i = 0; i < natives.length; i++) {
7.253 addUnencodedNativeForFlavor(flav, natives[i]);
7.254 }
7.255 @@ -1105,10 +1146,10 @@
7.256 throw new NullPointerException("null arguments not permitted");
7.257 }
7.258
7.259 - List flavors = (List)nativeToFlavor.get(nat);
7.260 + List flavors = (List)getNativeToFlavor().get(nat);
7.261 if (flavors == null) {
7.262 flavors = new ArrayList(1);
7.263 - nativeToFlavor.put(nat, flavors);
7.264 + getNativeToFlavor().put(nat, flavors);
7.265 } else if (flavors.contains(flav)) {
7.266 return;
7.267 }
7.268 @@ -1150,7 +1191,7 @@
7.269 throw new NullPointerException("null arguments not permitted");
7.270 }
7.271
7.272 - nativeToFlavor.remove(nat);
7.273 + getNativeToFlavor().remove(nat);
7.274 for (int i = 0; i < flavors.length; i++) {
7.275 addFlavorForUnencodedNative(nat, flavors[i]);
7.276 }
8.1 --- a/src/share/classes/java/awt/dnd/DropTarget.java Wed Mar 26 17:48:05 2008 -0700
8.2 +++ b/src/share/classes/java/awt/dnd/DropTarget.java Thu Mar 27 12:09:50 2008 -0700
8.3 @@ -1,5 +1,5 @@
8.4 /*
8.5 - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
8.6 + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8.8 *
8.9 * This code is free software; you can redistribute it and/or modify it
8.10 @@ -110,7 +110,11 @@
8.11 setActive(act);
8.12 }
8.13
8.14 - if (fm != null) flavorMap = fm;
8.15 + if (fm != null) {
8.16 + flavorMap = fm;
8.17 + } else {
8.18 + flavorMap = SystemFlavorMap.getDefaultFlavorMap();
8.19 + }
8.20 }
8.21
8.22 /**
8.23 @@ -850,5 +854,5 @@
8.24 * The FlavorMap
8.25 */
8.26
8.27 - private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
8.28 + private transient FlavorMap flavorMap;
8.29 }
9.1 --- a/src/share/classes/java/awt/event/MouseWheelEvent.java Wed Mar 26 17:48:05 2008 -0700
9.2 +++ b/src/share/classes/java/awt/event/MouseWheelEvent.java Thu Mar 27 12:09:50 2008 -0700
9.3 @@ -1,5 +1,5 @@
9.4 /*
9.5 - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
9.6 + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9.8 *
9.9 * This code is free software; you can redistribute it and/or modify it
9.10 @@ -74,6 +74,19 @@
9.11 * methods for conforming to the underlying platform settings. These
9.12 * platform settings can be changed at any time by the user. MouseWheelEvents
9.13 * reflect the most recent settings.
9.14 + * <P>
9.15 + * The <code>MouseWheelEvent</code> class includes methods for
9.16 + * getting the number of "clicks" by which the mouse wheel is rotated.
9.17 + * The {@link #getWheelRotation} method returns the integer number
9.18 + * of "clicks" corresponding to the number of notches by which the wheel was
9.19 + * rotated. In addition to this method, the <code>MouseWheelEvent</code>
9.20 + * class provides the {@link #getPreciseWheelRotation} method which returns
9.21 + * a double number of "clicks" in case a partial rotation occurred.
9.22 + * The {@link #getPreciseWheelRotation} method is useful if a mouse supports
9.23 + * a high-resolution wheel, such as a freely rotating wheel with no
9.24 + * notches. Applications can benefit by using this method to process
9.25 + * mouse wheel events more precisely, and thus, making visual perception
9.26 + * smoother.
9.27 *
9.28 * @author Brent Christian
9.29 * @see MouseWheelListener
9.30 @@ -131,6 +144,13 @@
9.31 */
9.32 int wheelRotation;
9.33
9.34 + /**
9.35 + * Indicates how far the mouse wheel was rotated.
9.36 + *
9.37 + * @see #getPreciseWheelRotation
9.38 + */
9.39 + double preciseWheelRotation;
9.40 +
9.41 /*
9.42 * serialVersionUID
9.43 */
9.44 @@ -165,8 +185,8 @@
9.45 * <code>WHEEL_BLOCK_SCROLL</code>
9.46 * @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
9.47 * the number of units to be scrolled
9.48 - * @param wheelRotation the amount that the mouse wheel was rotated (the
9.49 - * number of "clicks")
9.50 + * @param wheelRotation the integer number of "clicks" by which the mouse
9.51 + * wheel was rotated
9.52 *
9.53 * @throws IllegalArgumentException if <code>source</code> is null
9.54 * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
9.55 @@ -211,8 +231,8 @@
9.56 * <code>WHEEL_BLOCK_SCROLL</code>
9.57 * @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
9.58 * the number of units to be scrolled
9.59 - * @param wheelRotation the amount that the mouse wheel was rotated (the
9.60 - * number of "clicks")
9.61 + * @param wheelRotation the integer number of "clicks" by which the mouse
9.62 + * wheel was rotated
9.63 *
9.64 * @throws IllegalArgumentException if <code>source</code> is null
9.65 * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
9.66 @@ -223,12 +243,68 @@
9.67 int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
9.68 int scrollType, int scrollAmount, int wheelRotation) {
9.69
9.70 + this(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger,
9.71 + scrollType, scrollAmount, wheelRotation, wheelRotation);
9.72 +
9.73 + }
9.74 +
9.75 +
9.76 + /**
9.77 + * Constructs a <code>MouseWheelEvent</code> object with the specified
9.78 + * source component, type, modifiers, coordinates, absolute coordinates,
9.79 + * scroll type, scroll amount, and wheel rotation.
9.80 + * <p>Note that passing in an invalid <code>id</code> parameter results
9.81 + * in unspecified behavior. This method throws an
9.82 + * <code>IllegalArgumentException</code> if <code>source</code> equals
9.83 + * <code>null</code>.
9.84 + * <p>Even if inconsistent values for relative and absolute coordinates
9.85 + * are passed to the constructor, a <code>MouseWheelEvent</code> instance
9.86 + * is still created and no exception is thrown.
9.87 + *
9.88 + * @param source the <code>Component</code> that originated the event
9.89 + * @param id the integer value that identifies the event
9.90 + * @param when a long value that gives the time when the event occurred
9.91 + * @param modifiers the modifier keys down during event
9.92 + * (shift, ctrl, alt, meta)
9.93 + * @param x the horizontal <code>x</code> coordinate for the
9.94 + * mouse location
9.95 + * @param y the vertical <code>y</code> coordinate for the
9.96 + * mouse location
9.97 + * @param xAbs the absolute horizontal <code>x</code> coordinate for
9.98 + * the mouse location
9.99 + * @param yAbs the absolute vertical <code>y</code> coordinate for
9.100 + * the mouse location
9.101 + * @param clickCount the number of mouse clicks associated with the event
9.102 + * @param popupTrigger a boolean value, <code>true</code> if this event is a trigger
9.103 + * for a popup-menu
9.104 + * @param scrollType the type of scrolling which should take place in
9.105 + * response to this event; valid values are
9.106 + * <code>WHEEL_UNIT_SCROLL</code> and
9.107 + * <code>WHEEL_BLOCK_SCROLL</code>
9.108 + * @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
9.109 + * the number of units to be scrolled
9.110 + * @param wheelRotation the integer number of "clicks" by which the mouse wheel
9.111 + * was rotated
9.112 + * @param preciseWheelRotation the double number of "clicks" by which the mouse wheel
9.113 + * was rotated
9.114 + *
9.115 + * @throws IllegalArgumentException if <code>source</code> is null
9.116 + * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
9.117 + * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int)
9.118 + * @since 1.7
9.119 + */
9.120 + public MouseWheelEvent (Component source, int id, long when, int modifiers,
9.121 + int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
9.122 + int scrollType, int scrollAmount, int wheelRotation, double preciseWheelRotation) {
9.123 +
9.124 super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount,
9.125 popupTrigger, MouseEvent.NOBUTTON);
9.126
9.127 this.scrollType = scrollType;
9.128 this.scrollAmount = scrollAmount;
9.129 this.wheelRotation = wheelRotation;
9.130 + this.preciseWheelRotation = preciseWheelRotation;
9.131 +
9.132 }
9.133
9.134 /**
9.135 @@ -267,17 +343,35 @@
9.136 }
9.137
9.138 /**
9.139 - * Returns the number of "clicks" the mouse wheel was rotated.
9.140 + * Returns the number of "clicks" the mouse wheel was rotated, as an integer.
9.141 + * A partial rotation may occur if the mouse supports a high-resolution wheel.
9.142 + * In this case, the method returns zero until a full "click" has been accumulated.
9.143 *
9.144 * @return negative values if the mouse wheel was rotated up/away from
9.145 * the user, and positive values if the mouse wheel was rotated down/
9.146 * towards the user
9.147 + * @see #getPreciseWheelRotation
9.148 */
9.149 public int getWheelRotation() {
9.150 return wheelRotation;
9.151 }
9.152
9.153 /**
9.154 + * Returns the number of "clicks" the mouse wheel was rotated, as a double.
9.155 + * A partial rotation may occur if the mouse supports a high-resolution wheel.
9.156 + * In this case, the return value will include a fractional "click".
9.157 + *
9.158 + * @return negative values if the mouse wheel was rotated up or away from
9.159 + * the user, and positive values if the mouse wheel was rotated down or
9.160 + * towards the user
9.161 + * @see #getWheelRotation
9.162 + * @since 1.7
9.163 + */
9.164 + public double getPreciseWheelRotation() {
9.165 + return preciseWheelRotation;
9.166 + }
9.167 +
9.168 + /**
9.169 * This is a convenience method to aid in the implementation of
9.170 * the common-case MouseWheelListener - to scroll a ScrollPane or
9.171 * JScrollPane by an amount which conforms to the platform settings.
9.172 @@ -348,6 +442,6 @@
9.173 }
9.174 return super.paramString()+",scrollType="+scrollTypeStr+
9.175 ",scrollAmount="+getScrollAmount()+",wheelRotation="+
9.176 - getWheelRotation();
9.177 + getWheelRotation()+",preciseWheelRotation="+getPreciseWheelRotation();
9.178 }
9.179 }
10.1 --- a/src/share/classes/sun/awt/AppContext.java Wed Mar 26 17:48:05 2008 -0700
10.2 +++ b/src/share/classes/sun/awt/AppContext.java Thu Mar 27 12:09:50 2008 -0700
10.3 @@ -1,5 +1,5 @@
10.4 /*
10.5 - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
10.6 + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10.8 *
10.9 * This code is free software; you can redistribute it and/or modify it
10.10 @@ -40,6 +40,8 @@
10.11 import java.util.Map;
10.12 import java.util.Set;
10.13 import java.util.HashSet;
10.14 +import java.util.logging.Level;
10.15 +import java.util.logging.Logger;
10.16 import java.beans.PropertyChangeSupport;
10.17 import java.beans.PropertyChangeListener;
10.18
10.19 @@ -126,6 +128,7 @@
10.20 * @author Fred Ecks
10.21 */
10.22 public final class AppContext {
10.23 + private static final Logger log = Logger.getLogger("sun.awt.AppContext");
10.24
10.25 /* Since the contents of an AppContext are unique to each Java
10.26 * session, this class should never be serialized. */
10.27 @@ -143,13 +146,15 @@
10.28 * Returns a set containing all <code>AppContext</code>s.
10.29 */
10.30 public static Set<AppContext> getAppContexts() {
10.31 - return new HashSet<AppContext>(threadGroup2appContext.values());
10.32 + synchronized (threadGroup2appContext) {
10.33 + return new HashSet<AppContext>(threadGroup2appContext.values());
10.34 + }
10.35 }
10.36
10.37 /* The main "system" AppContext, used by everything not otherwise
10.38 contained in another AppContext.
10.39 */
10.40 - private static AppContext mainAppContext = null;
10.41 + private static volatile AppContext mainAppContext = null;
10.42
10.43 /*
10.44 * The hash map associated with this AppContext. A private delegate
10.45 @@ -174,31 +179,30 @@
10.46 public static final String DISPOSED_PROPERTY_NAME = "disposed";
10.47 public static final String GUI_DISPOSED = "guidisposed";
10.48
10.49 - private boolean isDisposed = false; // true if AppContext is disposed
10.50 + private volatile boolean isDisposed = false; // true if AppContext is disposed
10.51
10.52 public boolean isDisposed() {
10.53 return isDisposed;
10.54 }
10.55
10.56 -
10.57 static {
10.58 // On the main Thread, we get the ThreadGroup, make a corresponding
10.59 // AppContext, and instantiate the Java EventQueue. This way, legacy
10.60 // code is unaffected by the move to multiple AppContext ability.
10.61 AccessController.doPrivileged(new PrivilegedAction() {
10.62 - public Object run() {
10.63 - ThreadGroup currentThreadGroup =
10.64 - Thread.currentThread().getThreadGroup();
10.65 - ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
10.66 - while (parentThreadGroup != null) {
10.67 - // Find the root ThreadGroup to construct our main AppContext
10.68 - currentThreadGroup = parentThreadGroup;
10.69 - parentThreadGroup = currentThreadGroup.getParent();
10.70 + public Object run() {
10.71 + ThreadGroup currentThreadGroup =
10.72 + Thread.currentThread().getThreadGroup();
10.73 + ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
10.74 + while (parentThreadGroup != null) {
10.75 + // Find the root ThreadGroup to construct our main AppContext
10.76 + currentThreadGroup = parentThreadGroup;
10.77 + parentThreadGroup = currentThreadGroup.getParent();
10.78 + }
10.79 + mainAppContext = new AppContext(currentThreadGroup);
10.80 + numAppContexts = 1;
10.81 + return mainAppContext;
10.82 }
10.83 - mainAppContext = new AppContext(currentThreadGroup);
10.84 - numAppContexts = 1;
10.85 - return mainAppContext;
10.86 - }
10.87 });
10.88 }
10.89
10.90 @@ -209,7 +213,7 @@
10.91 * number is 1. If so, it returns the sole AppContext without
10.92 * checking Thread.currentThread().
10.93 */
10.94 - private static int numAppContexts;
10.95 + private static volatile int numAppContexts;
10.96
10.97 /*
10.98 * The context ClassLoader that was used to create this AppContext.
10.99 @@ -236,14 +240,15 @@
10.100 threadGroup2appContext.put(threadGroup, this);
10.101
10.102 this.contextClassLoader =
10.103 - (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
10.104 - public Object run() {
10.105 + AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
10.106 + public ClassLoader run() {
10.107 return Thread.currentThread().getContextClassLoader();
10.108 }
10.109 });
10.110 }
10.111
10.112 - private static MostRecentThreadAppContext mostRecentThreadAppContext = null;
10.113 + private static final ThreadLocal<AppContext> threadAppContext =
10.114 + new ThreadLocal<AppContext>();
10.115
10.116 /**
10.117 * Returns the appropriate AppContext for the caller,
10.118 @@ -260,59 +265,46 @@
10.119 if (numAppContexts == 1) // If there's only one system-wide,
10.120 return mainAppContext; // return the main system AppContext.
10.121
10.122 - final Thread currentThread = Thread.currentThread();
10.123 + AppContext appContext = threadAppContext.get();
10.124
10.125 - AppContext appContext = null;
10.126 + if (null == appContext) {
10.127 + appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
10.128 + {
10.129 + public AppContext run() {
10.130 + // Get the current ThreadGroup, and look for it and its
10.131 + // parents in the hash from ThreadGroup to AppContext --
10.132 + // it should be found, because we use createNewContext()
10.133 + // when new AppContext objects are created.
10.134 + ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
10.135 + ThreadGroup threadGroup = currentThreadGroup;
10.136 + AppContext context = threadGroup2appContext.get(threadGroup);
10.137 + while (context == null) {
10.138 + threadGroup = threadGroup.getParent();
10.139 + if (threadGroup == null) {
10.140 + // If we get here, we're running under a ThreadGroup that
10.141 + // has no AppContext associated with it. This should never
10.142 + // happen, because createNewContext() should be used by the
10.143 + // toolkit to create the ThreadGroup that everything runs
10.144 + // under.
10.145 + throw new RuntimeException("Invalid ThreadGroup");
10.146 + }
10.147 + context = threadGroup2appContext.get(threadGroup);
10.148 + }
10.149 + // In case we did anything in the above while loop, we add
10.150 + // all the intermediate ThreadGroups to threadGroup2appContext
10.151 + // so we won't spin again.
10.152 + for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
10.153 + threadGroup2appContext.put(tg, context);
10.154 + }
10.155 + // Now we're done, so we cache the latest key/value pair.
10.156 + // (we do this before checking with any AWTSecurityManager, so if
10.157 + // this Thread equates with the main AppContext in the cache, it
10.158 + // still will)
10.159 + threadAppContext.set(context);
10.160
10.161 - // Note: this most recent Thread/AppContext caching is thread-hot.
10.162 - // A simple test using SwingSet found that 96.8% of lookups
10.163 - // were matched using the most recent Thread/AppContext. By
10.164 - // instantiating a simple MostRecentThreadAppContext object on
10.165 - // cache misses, the cache hits can be processed without
10.166 - // synchronization.
10.167 -
10.168 - MostRecentThreadAppContext recent = mostRecentThreadAppContext;
10.169 - if ((recent != null) && (recent.thread == currentThread)) {
10.170 - appContext = recent.appContext; // Cache hit
10.171 - } else {
10.172 - appContext = (AppContext)AccessController.doPrivileged(
10.173 - new PrivilegedAction() {
10.174 - public Object run() {
10.175 - // Get the current ThreadGroup, and look for it and its
10.176 - // parents in the hash from ThreadGroup to AppContext --
10.177 - // it should be found, because we use createNewContext()
10.178 - // when new AppContext objects are created.
10.179 - ThreadGroup currentThreadGroup = currentThread.getThreadGroup();
10.180 - ThreadGroup threadGroup = currentThreadGroup;
10.181 - AppContext context = threadGroup2appContext.get(threadGroup);
10.182 - while (context == null) {
10.183 - threadGroup = threadGroup.getParent();
10.184 - if (threadGroup == null) {
10.185 - // If we get here, we're running under a ThreadGroup that
10.186 - // has no AppContext associated with it. This should never
10.187 - // happen, because createNewContext() should be used by the
10.188 - // toolkit to create the ThreadGroup that everything runs
10.189 - // under.
10.190 - throw new RuntimeException("Invalid ThreadGroup");
10.191 + return context;
10.192 }
10.193 - context = threadGroup2appContext.get(threadGroup);
10.194 - }
10.195 - // In case we did anything in the above while loop, we add
10.196 - // all the intermediate ThreadGroups to threadGroup2appContext
10.197 - // so we won't spin again.
10.198 - for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
10.199 - threadGroup2appContext.put(tg, context);
10.200 - }
10.201 - // Now we're done, so we cache the latest key/value pair.
10.202 - // (we do this before checking with any AWTSecurityManager, so if
10.203 - // this Thread equates with the main AppContext in the cache, it
10.204 - // still will)
10.205 - mostRecentThreadAppContext =
10.206 - new MostRecentThreadAppContext(currentThread, context);
10.207 -
10.208 - return context;
10.209 - }
10.210 - });
10.211 + });
10.212 }
10.213
10.214 if (appContext == mainAppContext) {
10.215 @@ -321,9 +313,9 @@
10.216 // allow it to choose the AppContext to return.
10.217 SecurityManager securityManager = System.getSecurityManager();
10.218 if ((securityManager != null) &&
10.219 - (securityManager instanceof AWTSecurityManager)) {
10.220 - AWTSecurityManager awtSecMgr =
10.221 - (AWTSecurityManager)securityManager;
10.222 + (securityManager instanceof AWTSecurityManager))
10.223 + {
10.224 + AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager;
10.225 AppContext secAppContext = awtSecMgr.getAppContext();
10.226 if (secAppContext != null) {
10.227 appContext = secAppContext; // Return what we're told
10.228 @@ -385,7 +377,13 @@
10.229 public void run() {
10.230 Window[] windowsToDispose = Window.getOwnerlessWindows();
10.231 for (Window w : windowsToDispose) {
10.232 - w.dispose();
10.233 + try {
10.234 + w.dispose();
10.235 + } catch (Throwable t) {
10.236 + if (log.isLoggable(Level.FINER)) {
10.237 + log.log(Level.FINER, "exception occured while disposing app context", t);
10.238 + }
10.239 + }
10.240 }
10.241 AccessController.doPrivileged(new PrivilegedAction() {
10.242 public Object run() {
10.243 @@ -444,7 +442,7 @@
10.244 // Threads in the ThreadGroup to exit.
10.245
10.246 long startTime = System.currentTimeMillis();
10.247 - long endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
10.248 + long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
10.249 while ((this.threadGroup.activeCount() > 0) &&
10.250 (System.currentTimeMillis() < endTime)) {
10.251 try {
10.252 @@ -459,7 +457,7 @@
10.253 // Threads in the ThreadGroup to die.
10.254
10.255 startTime = System.currentTimeMillis();
10.256 - endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
10.257 + endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
10.258 while ((this.threadGroup.activeCount() > 0) &&
10.259 (System.currentTimeMillis() < endTime)) {
10.260 try {
10.261 @@ -478,10 +476,7 @@
10.262 }
10.263 threadGroup2appContext.remove(this.threadGroup);
10.264
10.265 - MostRecentThreadAppContext recent = mostRecentThreadAppContext;
10.266 - if ((recent != null) && (recent.appContext == this))
10.267 - mostRecentThreadAppContext = null;
10.268 - // If the "most recent" points to this, clear it for GC
10.269 + threadAppContext.set(null);
10.270
10.271 // Finally, we destroy the ThreadGroup entirely.
10.272 try {
10.273 @@ -664,6 +659,7 @@
10.274 * Returns a string representation of this AppContext.
10.275 * @since 1.2
10.276 */
10.277 + @Override
10.278 public String toString() {
10.279 return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]";
10.280 }
10.281 @@ -769,15 +765,6 @@
10.282 }
10.283 }
10.284
10.285 -final class MostRecentThreadAppContext {
10.286 - final Thread thread;
10.287 - final AppContext appContext;
10.288 - MostRecentThreadAppContext(Thread key, AppContext value) {
10.289 - thread = key;
10.290 - appContext = value;
10.291 - }
10.292 -}
10.293 -
10.294 final class MostRecentKeyValue {
10.295 Object key;
10.296 Object value;
11.1 --- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Mar 26 17:48:05 2008 -0700
11.2 +++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java Thu Mar 27 12:09:50 2008 -0700
11.3 @@ -1,5 +1,5 @@
11.4 /*
11.5 - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
11.6 + * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
11.8 *
11.9 * This code is free software; you can redistribute it and/or modify it
11.10 @@ -270,62 +270,58 @@
11.11 * instead, null will be returned.
11.12 */
11.13 public static DataTransferer getInstance() {
11.14 - if (transferer == null) {
11.15 - synchronized (DataTransferer.class) {
11.16 - if (transferer == null) {
11.17 - final String name = SunToolkit.
11.18 - getDataTransfererClassName();
11.19 - if (name != null) {
11.20 - PrivilegedAction action = new PrivilegedAction() {
11.21 - public Object run() {
11.22 - Class cls = null;
11.23 - Method method = null;
11.24 - Object ret = null;
11.25 + synchronized (DataTransferer.class) {
11.26 + if (transferer == null) {
11.27 + final String name = SunToolkit.getDataTransfererClassName();
11.28 + if (name != null) {
11.29 + PrivilegedAction<DataTransferer> action = new PrivilegedAction<DataTransferer>()
11.30 + {
11.31 + public DataTransferer run() {
11.32 + Class cls = null;
11.33 + Method method = null;
11.34 + DataTransferer ret = null;
11.35
11.36 - try {
11.37 - cls = Class.forName(name);
11.38 - } catch (ClassNotFoundException e) {
11.39 - ClassLoader cl = ClassLoader.
11.40 - getSystemClassLoader();
11.41 - if (cl != null) {
11.42 - try {
11.43 - cls = cl.loadClass(name);
11.44 - } catch (ClassNotFoundException ee) {
11.45 - ee.printStackTrace();
11.46 - throw new AWTError("DataTransferer not found: " + name);
11.47 - }
11.48 + try {
11.49 + cls = Class.forName(name);
11.50 + } catch (ClassNotFoundException e) {
11.51 + ClassLoader cl = ClassLoader.
11.52 + getSystemClassLoader();
11.53 + if (cl != null) {
11.54 + try {
11.55 + cls = cl.loadClass(name);
11.56 + } catch (ClassNotFoundException ee) {
11.57 + ee.printStackTrace();
11.58 + throw new AWTError("DataTransferer not found: " + name);
11.59 }
11.60 }
11.61 - if (cls != null) {
11.62 - try {
11.63 - method = cls.getDeclaredMethod
11.64 - ("getInstanceImpl");
11.65 - method.setAccessible(true);
11.66 - } catch (NoSuchMethodException e) {
11.67 - e.printStackTrace();
11.68 - throw new AWTError("Cannot instantiate DataTransferer: " + name);
11.69 - } catch (SecurityException e) {
11.70 - e.printStackTrace();
11.71 - throw new AWTError("Access is denied for DataTransferer: " + name);
11.72 - }
11.73 + }
11.74 + if (cls != null) {
11.75 + try {
11.76 + method = cls.getDeclaredMethod("getInstanceImpl");
11.77 + method.setAccessible(true);
11.78 + } catch (NoSuchMethodException e) {
11.79 + e.printStackTrace();
11.80 + throw new AWTError("Cannot instantiate DataTransferer: " + name);
11.81 + } catch (SecurityException e) {
11.82 + e.printStackTrace();
11.83 + throw new AWTError("Access is denied for DataTransferer: " + name);
11.84 }
11.85 - if (method != null) {
11.86 - try {
11.87 - ret = method.invoke(null);
11.88 - } catch (InvocationTargetException e) {
11.89 - e.printStackTrace();
11.90 - throw new AWTError("Cannot instantiate DataTransferer: " + name);
11.91 - } catch (IllegalAccessException e) {
11.92 - e.printStackTrace();
11.93 - throw new AWTError("Cannot access DataTransferer: " + name);
11.94 - }
11.95 + }
11.96 + if (method != null) {
11.97 + try {
11.98 + ret = (DataTransferer) method.invoke(null);
11.99 + } catch (InvocationTargetException e) {
11.100 + e.printStackTrace();
11.101 + throw new AWTError("Cannot instantiate DataTransferer: " + name);
11.102 + } catch (IllegalAccessException e) {
11.103 + e.printStackTrace();
11.104 + throw new AWTError("Cannot access DataTransferer: " + name);
11.105 }
11.106 - return ret;
11.107 }
11.108 - };
11.109 - transferer = (DataTransferer)
11.110 - AccessController.doPrivileged(action);
11.111 - }
11.112 + return ret;
11.113 + }
11.114 + };
11.115 + transferer = AccessController.doPrivileged(action);
11.116 }
11.117 }
11.118 }
12.1 --- a/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java Wed Mar 26 17:48:05 2008 -0700
12.2 +++ b/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java Thu Mar 27 12:09:50 2008 -0700
12.3 @@ -1,5 +1,5 @@
12.4 /*
12.5 - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
12.6 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.8 *
12.9 * This code is free software; you can redistribute it and/or modify it
12.10 @@ -39,6 +39,8 @@
12.11 * @since 1.5
12.12 */
12.13 class MotifDnDConstants {
12.14 + // utility class can not be instantiated
12.15 + private MotifDnDConstants() {}
12.16 // Note that offsets in all native structures below do not depend on the
12.17 // architecture.
12.18 private static final Unsafe unsafe = XlibWrapper.unsafe;
12.19 @@ -55,8 +57,7 @@
12.20 XAtom.get("XmTRANSFER_SUCCESS");
12.21 static final XAtom XA_XmTRANSFER_FAILURE =
12.22 XAtom.get("XmTRANSFER_FAILURE");
12.23 - static final XSelection MotifDnDSelection =
12.24 - new XSelection(XA_MOTIF_ATOM_0, null);
12.25 + static final XSelection MotifDnDSelection = new XSelection(XA_MOTIF_ATOM_0);
12.26
12.27 public static final byte MOTIF_DND_PROTOCOL_VERSION = 0;
12.28
12.29 @@ -231,6 +232,9 @@
12.30 }
12.31
12.32 public static final class Swapper {
12.33 + // utility class can not be instantiated
12.34 + private Swapper() {}
12.35 +
12.36 public static short swap(short s) {
12.37 return (short)(((s & 0xFF00) >>> 8) | ((s & 0xFF) << 8));
12.38 }
13.1 --- a/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java Wed Mar 26 17:48:05 2008 -0700
13.2 +++ b/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java Thu Mar 27 12:09:50 2008 -0700
13.3 @@ -1,5 +1,5 @@
13.4 /*
13.5 - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
13.6 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.8 *
13.9 * This code is free software; you can redistribute it and/or modify it
13.10 @@ -933,7 +933,7 @@
13.11
13.12 XSelection selection = XSelection.getSelection(selectionAtom);
13.13 if (selection == null) {
13.14 - selection = new XSelection(selectionAtom, null);
13.15 + selection = new XSelection(selectionAtom);
13.16 }
13.17
13.18 return selection.getData(format, time_stamp);
13.19 @@ -1056,7 +1056,7 @@
13.20 // the original structure can be freed before this
13.21 // SunDropTargetEvent is dispatched.
13.22 if (xclient != null) {
13.23 - int size = new XClientMessageEvent(nativeCtxt).getSize();
13.24 + int size = XClientMessageEvent.getSize();
13.25
13.26 nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
13.27
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/src/solaris/classes/sun/awt/X11/OwnershipListener.java Thu Mar 27 12:09:50 2008 -0700
14.3 @@ -0,0 +1,30 @@
14.4 +/*
14.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.7 + *
14.8 + * This code is free software; you can redistribute it and/or modify it
14.9 + * under the terms of the GNU General Public License version 2 only, as
14.10 + * published by the Free Software Foundation. Sun designates this
14.11 + * particular file as subject to the "Classpath" exception as provided
14.12 + * by Sun in the LICENSE file that accompanied this code.
14.13 + *
14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14.17 + * version 2 for more details (a copy is included in the LICENSE file that
14.18 + * accompanied this code).
14.19 + *
14.20 + * You should have received a copy of the GNU General Public License version
14.21 + * 2 along with this work; if not, write to the Free Software Foundation,
14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14.23 + *
14.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
14.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
14.26 + * have any questions.
14.27 + */
14.28 +
14.29 +package sun.awt.X11;
14.30 +
14.31 +interface OwnershipListener {
14.32 + public void ownershipChanged(final boolean isOwner);
14.33 +}
15.1 --- a/src/solaris/classes/sun/awt/X11/XAtom.java Wed Mar 26 17:48:05 2008 -0700
15.2 +++ b/src/solaris/classes/sun/awt/X11/XAtom.java Thu Mar 27 12:09:50 2008 -0700
15.3 @@ -1,5 +1,5 @@
15.4 /*
15.5 - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
15.6 + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
15.8 *
15.9 * This code is free software; you can redistribute it and/or modify it
15.10 @@ -58,7 +58,7 @@
15.11 import sun.misc.Unsafe;
15.12 import java.util.HashMap;
15.13
15.14 -public class XAtom {
15.15 +public final class XAtom {
15.16
15.17 // Order of lock: XAWTLock -> XAtom.class
15.18
15.19 @@ -175,7 +175,7 @@
15.20 public static XAtom get(String name) {
15.21 XAtom xatom = lookup(name);
15.22 if (xatom == null) {
15.23 - xatom = new XAtom(name);
15.24 + xatom = new XAtom(XToolkit.getDisplay(), name);
15.25 }
15.26 return xatom;
15.27 }
15.28 @@ -232,10 +232,6 @@
15.29 this(display, name, true);
15.30 }
15.31
15.32 - private XAtom(String name) {
15.33 - this(XToolkit.getDisplay(), name, true);
15.34 - }
15.35 -
15.36 public XAtom(String name, boolean autoIntern) {
15.37 this(XToolkit.getDisplay(), name, autoIntern);
15.38 }
15.39 @@ -262,7 +258,7 @@
15.40 * @since 1.5
15.41 */
15.42
15.43 - public XAtom(long display, String name, boolean autoIntern) {
15.44 + private XAtom(long display, String name, boolean autoIntern) {
15.45 this.name = name;
15.46 this.display = display;
15.47 if (autoIntern) {
15.48 @@ -651,28 +647,6 @@
15.49 }
15.50 }
15.51
15.52 - /**
15.53 - * Initializes atom with name and display values
15.54 - */
15.55 - public void setValues(long display, String name, boolean autoIntern) {
15.56 - this.display = display;
15.57 - this.name = name;
15.58 - if (autoIntern) {
15.59 - XToolkit.awtLock();
15.60 - try {
15.61 - atom = XlibWrapper.InternAtom(display,name,0);
15.62 - } finally {
15.63 - XToolkit.awtUnlock();
15.64 - }
15.65 - }
15.66 - register();
15.67 - }
15.68 -
15.69 - public void setValues(long display, long atom) {
15.70 - this.display = display;
15.71 - this.atom = atom;
15.72 - register();
15.73 - }
15.74 public void setValues(long display, String name, long atom) {
15.75 this.display = display;
15.76 this.atom = atom;
16.1 --- a/src/solaris/classes/sun/awt/X11/XClipboard.java Wed Mar 26 17:48:05 2008 -0700
16.2 +++ b/src/solaris/classes/sun/awt/X11/XClipboard.java Thu Mar 27 12:09:50 2008 -0700
16.3 @@ -1,5 +1,5 @@
16.4 /*
16.5 - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
16.6 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
16.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16.8 *
16.9 * This code is free software; you can redistribute it and/or modify it
16.10 @@ -26,30 +26,32 @@
16.11 package sun.awt.X11;
16.12
16.13 import java.awt.datatransfer.Transferable;
16.14 -
16.15 import java.util.SortedMap;
16.16 -import java.util.Set;
16.17 -import java.util.Iterator;
16.18 -import java.util.HashSet;
16.19 -
16.20 import java.io.IOException;
16.21 -
16.22 import java.security.AccessController;
16.23 -
16.24 +import java.util.HashMap;
16.25 +import java.util.Map;
16.26 +import sun.awt.UNIXToolkit;
16.27 import sun.awt.datatransfer.DataTransferer;
16.28 import sun.awt.datatransfer.SunClipboard;
16.29 import sun.awt.datatransfer.ClipboardTransferable;
16.30 -
16.31 import sun.security.action.GetIntegerAction;
16.32
16.33 -
16.34 -
16.35 /**
16.36 * A class which interfaces with the X11 selection service in order to support
16.37 * data transfer via Clipboard operations.
16.38 */
16.39 -public class XClipboard extends SunClipboard implements Runnable {
16.40 +public final class XClipboard extends SunClipboard implements OwnershipListener
16.41 +{
16.42 private final XSelection selection;
16.43 + // Time of calling XConvertSelection().
16.44 + private long convertSelectionTime;
16.45 + // The flag used not to call XConvertSelection() if the previous SelectionNotify
16.46 + // has not been processed by checkChange().
16.47 + private volatile boolean isSelectionNotifyProcessed;
16.48 + // The property in which the owner should place requested targets
16.49 + // when tracking changes of available data flavors (practically targets).
16.50 + private volatile XAtom targetsPropertyAtom;
16.51
16.52 private static final Object classLock = new Object();
16.53
16.54 @@ -57,31 +59,33 @@
16.55
16.56 private static int pollInterval;
16.57
16.58 - private static Set listenedClipboards;
16.59 -
16.60 + private static Map<Long, XClipboard> targetsAtom2Clipboard;
16.61
16.62 /**
16.63 * Creates a system clipboard object.
16.64 */
16.65 public XClipboard(String name, String selectionName) {
16.66 super(name);
16.67 - selection = new XSelection(XAtom.get(selectionName), this);
16.68 + selection = new XSelection(XAtom.get(selectionName));
16.69 + selection.registerOwershipListener(this);
16.70 }
16.71
16.72 - /**
16.73 - * The action to be run when we lose ownership
16.74 + /*
16.75 * NOTE: This method may be called by privileged threads.
16.76 * DO NOT INVOKE CLIENT CODE ON THIS THREAD!
16.77 */
16.78 - public void run() {
16.79 - lostOwnershipImpl();
16.80 + public void ownershipChanged(final boolean isOwner) {
16.81 + if (isOwner) {
16.82 + checkChangeHere(contents);
16.83 + } else {
16.84 + lostOwnershipImpl();
16.85 + }
16.86 }
16.87
16.88 protected synchronized void setContentsNative(Transferable contents) {
16.89 SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable
16.90 (contents, DataTransferer.adaptFlavorMap(flavorMap));
16.91 - long[] formats =
16.92 - DataTransferer.getInstance().keysToLongArray(formatMap);
16.93 + long[] formats = DataTransferer.keysToLongArray(formatMap);
16.94
16.95 if (!selection.setOwner(contents, formatMap, formats,
16.96 XToolkit.getCurrentServerTime())) {
16.97 @@ -94,6 +98,7 @@
16.98 return selection.getSelectionAtom().getAtom();
16.99 }
16.100
16.101 + @Override
16.102 public synchronized Transferable getContents(Object requestor) {
16.103 if (contents != null) {
16.104 return contents;
16.105 @@ -115,62 +120,163 @@
16.106 return selection.getData(format, XToolkit.getCurrentServerTime());
16.107 }
16.108
16.109 - // Called on the toolkit thread under awtLock.
16.110 - public void checkChange(long[] formats) {
16.111 - if (!selection.isOwner()) {
16.112 - super.checkChange(formats);
16.113 - }
16.114 - }
16.115 -
16.116 - void checkChangeHere(Transferable contents) {
16.117 + private void checkChangeHere(Transferable contents) {
16.118 if (areFlavorListenersRegistered()) {
16.119 - super.checkChange(DataTransferer.getInstance().
16.120 + checkChange(DataTransferer.getInstance().
16.121 getFormatsForTransferableAsArray(contents, flavorMap));
16.122 }
16.123 }
16.124
16.125 + private static int getPollInterval() {
16.126 + synchronized (XClipboard.classLock) {
16.127 + if (pollInterval <= 0) {
16.128 + pollInterval = AccessController.doPrivileged(
16.129 + new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
16.130 + defaultPollInterval));
16.131 + if (pollInterval <= 0) {
16.132 + pollInterval = defaultPollInterval;
16.133 + }
16.134 + }
16.135 + return pollInterval;
16.136 + }
16.137 + }
16.138 +
16.139 + private XAtom getTargetsPropertyAtom() {
16.140 + if (null == targetsPropertyAtom) {
16.141 + targetsPropertyAtom =
16.142 + XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selection.getSelectionAtom().getName());
16.143 + }
16.144 + return targetsPropertyAtom;
16.145 + }
16.146 +
16.147 protected void registerClipboardViewerChecked() {
16.148 - if (pollInterval <= 0) {
16.149 - pollInterval = ((Integer)AccessController.doPrivileged(
16.150 - new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
16.151 - defaultPollInterval))).intValue();
16.152 - if (pollInterval <= 0) {
16.153 - pollInterval = defaultPollInterval;
16.154 + // for XConvertSelection() to be called for the first time in getTargetsDelayed()
16.155 + isSelectionNotifyProcessed = true;
16.156 +
16.157 + boolean mustSchedule = false;
16.158 + synchronized (XClipboard.classLock) {
16.159 + if (targetsAtom2Clipboard == null) {
16.160 + targetsAtom2Clipboard = new HashMap<Long, XClipboard>(2);
16.161 + }
16.162 + mustSchedule = targetsAtom2Clipboard.isEmpty();
16.163 + targetsAtom2Clipboard.put(getTargetsPropertyAtom().getAtom(), this);
16.164 + if (mustSchedule) {
16.165 + XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
16.166 + new SelectionNotifyHandler());
16.167 }
16.168 }
16.169 - selection.initializeSelectionForTrackingChanges();
16.170 - boolean mustSchedule = false;
16.171 - synchronized (XClipboard.classLock) {
16.172 - if (listenedClipboards == null) {
16.173 - listenedClipboards = new HashSet(2);
16.174 - }
16.175 - mustSchedule = listenedClipboards.isEmpty();
16.176 - listenedClipboards.add(this);
16.177 - }
16.178 if (mustSchedule) {
16.179 - XToolkit.schedule(new CheckChangeTimerTask(), pollInterval);
16.180 + XToolkit.schedule(new CheckChangeTimerTask(), XClipboard.getPollInterval());
16.181 }
16.182 }
16.183
16.184 private static class CheckChangeTimerTask implements Runnable {
16.185 public void run() {
16.186 - for (Iterator iter = listenedClipboards.iterator(); iter.hasNext();) {
16.187 - XClipboard clpbrd = (XClipboard)iter.next();
16.188 - clpbrd.selection.getTargetsDelayed();
16.189 + for (XClipboard clpbrd : targetsAtom2Clipboard.values()) {
16.190 + clpbrd.getTargetsDelayed();
16.191 }
16.192 synchronized (XClipboard.classLock) {
16.193 - if (listenedClipboards != null && !listenedClipboards.isEmpty()) {
16.194 - XToolkit.schedule(this, pollInterval);
16.195 + if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
16.196 + XToolkit.schedule(this, XClipboard.getPollInterval());
16.197 + }
16.198 + }
16.199 + }
16.200 + }
16.201 +
16.202 + private static class SelectionNotifyHandler implements XEventDispatcher {
16.203 + public void dispatchEvent(XEvent ev) {
16.204 + if (ev.get_type() == XlibWrapper.SelectionNotify) {
16.205 + final XSelectionEvent xse = ev.get_xselection();
16.206 + XClipboard clipboard = null;
16.207 + synchronized (XClipboard.classLock) {
16.208 + if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
16.209 + XToolkit.removeEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), this);
16.210 + return;
16.211 + }
16.212 + final long propertyAtom = xse.get_property();
16.213 + clipboard = targetsAtom2Clipboard.get(propertyAtom);
16.214 + }
16.215 + if (null != clipboard) {
16.216 + clipboard.checkChange(xse);
16.217 }
16.218 }
16.219 }
16.220 }
16.221
16.222 protected void unregisterClipboardViewerChecked() {
16.223 - selection.deinitializeSelectionForTrackingChanges();
16.224 + isSelectionNotifyProcessed = false;
16.225 synchronized (XClipboard.classLock) {
16.226 - listenedClipboards.remove(this);
16.227 + targetsAtom2Clipboard.remove(getTargetsPropertyAtom().getAtom());
16.228 }
16.229 }
16.230
16.231 + // checkChange() will be called on SelectionNotify
16.232 + private void getTargetsDelayed() {
16.233 + XToolkit.awtLock();
16.234 + try {
16.235 + long curTime = System.currentTimeMillis();
16.236 + if (isSelectionNotifyProcessed || curTime >= (convertSelectionTime + UNIXToolkit.getDatatransferTimeout()))
16.237 + {
16.238 + convertSelectionTime = curTime;
16.239 + XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
16.240 + selection.getSelectionAtom().getAtom(),
16.241 + XDataTransferer.TARGETS_ATOM.getAtom(),
16.242 + getTargetsPropertyAtom().getAtom(),
16.243 + XWindow.getXAWTRootWindow().getWindow(),
16.244 + XlibWrapper.CurrentTime);
16.245 + isSelectionNotifyProcessed = false;
16.246 + }
16.247 + } finally {
16.248 + XToolkit.awtUnlock();
16.249 + }
16.250 + }
16.251 +
16.252 + /*
16.253 + * Tracks changes of available formats.
16.254 + * NOTE: This method may be called by privileged threads.
16.255 + * DO NOT INVOKE CLIENT CODE ON THIS THREAD!
16.256 + */
16.257 + private void checkChange(XSelectionEvent xse) {
16.258 + final long propertyAtom = xse.get_property();
16.259 + if (propertyAtom != getTargetsPropertyAtom().getAtom()) {
16.260 + // wrong atom
16.261 + return;
16.262 + }
16.263 +
16.264 + final XAtom selectionAtom = XAtom.get(xse.get_selection());
16.265 + final XSelection changedSelection = XSelection.getSelection(selectionAtom);
16.266 +
16.267 + if (null == changedSelection || changedSelection != selection) {
16.268 + // unknown selection - do nothing
16.269 + return;
16.270 + }
16.271 +
16.272 + isSelectionNotifyProcessed = true;
16.273 +
16.274 + if (selection.isOwner()) {
16.275 + // selection is owner - do not need formats
16.276 + return;
16.277 + }
16.278 +
16.279 + long[] formats = null;
16.280 +
16.281 + if (propertyAtom == XlibWrapper.None) {
16.282 + // We treat None property atom as "empty selection".
16.283 + formats = new long[0];
16.284 + } else {
16.285 + WindowPropertyGetter targetsGetter =
16.286 + new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
16.287 + XAtom.get(propertyAtom), 0,
16.288 + XSelection.MAX_LENGTH, true,
16.289 + XlibWrapper.AnyPropertyType);
16.290 + try {
16.291 + targetsGetter.execute();
16.292 + formats = XSelection.getFormats(targetsGetter);
16.293 + } finally {
16.294 + targetsGetter.dispose();
16.295 + }
16.296 + }
16.297 +
16.298 + checkChange(formats);
16.299 + }
16.300 }
17.1 --- a/src/solaris/classes/sun/awt/X11/XComponentPeer.java Wed Mar 26 17:48:05 2008 -0700
17.2 +++ b/src/solaris/classes/sun/awt/X11/XComponentPeer.java Thu Mar 27 12:09:50 2008 -0700
17.3 @@ -1,5 +1,5 @@
17.4 /*
17.5 - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
17.6 + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
17.8 *
17.9 * This code is free software; you can redistribute it and/or modify it
17.10 @@ -31,17 +31,13 @@
17.11 import java.awt.Component;
17.12 import java.awt.Container;
17.13 import java.awt.Cursor;
17.14 -import java.awt.DefaultKeyboardFocusManager;
17.15 import java.awt.Dimension;
17.16 -import java.awt.Event;
17.17 import java.awt.Font;
17.18 import java.awt.FontMetrics;
17.19 import java.awt.Graphics;
17.20 import java.awt.Image;
17.21 import java.awt.Insets;
17.22 import java.awt.KeyboardFocusManager;
17.23 -import java.awt.MenuBar;
17.24 -import java.awt.Point;
17.25 import java.awt.Rectangle;
17.26 import java.awt.SystemColor;
17.27 import java.awt.Toolkit;
17.28 @@ -60,12 +56,9 @@
17.29 import java.awt.image.ImageObserver;
17.30 import java.awt.image.ImageProducer;
17.31 import java.awt.image.VolatileImage;
17.32 -import java.awt.peer.CanvasPeer;
17.33 import java.awt.peer.ComponentPeer;
17.34 import java.awt.peer.ContainerPeer;
17.35 import java.awt.peer.LightweightPeer;
17.36 -import java.awt.peer.PanelPeer;
17.37 -import java.awt.peer.WindowPeer;
17.38 import java.lang.reflect.*;
17.39 import java.security.*;
17.40 import java.util.Collection;
17.41 @@ -821,7 +814,7 @@
17.42 public void setFont(Font f) {
17.43 synchronized (getStateLock()) {
17.44 if (f == null) {
17.45 - f = defaultFont;
17.46 + f = XWindow.getDefaultFont();
17.47 }
17.48 font = f;
17.49 }
18.1 --- a/src/solaris/classes/sun/awt/X11/XContentWindow.java Wed Mar 26 17:48:05 2008 -0700
18.2 +++ b/src/solaris/classes/sun/awt/X11/XContentWindow.java Thu Mar 27 12:09:50 2008 -0700
18.3 @@ -1,5 +1,5 @@
18.4 /*
18.5 - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
18.6 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18.8 *
18.9 * This code is free software; you can redistribute it and/or modify it
18.10 @@ -39,16 +39,37 @@
18.11 * This class implements window which serves as content window for decorated frames.
18.12 * Its purpose to provide correct events dispatching for the complex
18.13 * constructs such as decorated frames.
18.14 + *
18.15 + * It should always be located at (- left inset, - top inset) in the associated
18.16 + * decorated window. So coordinates in it would be the same as java coordinates.
18.17 */
18.18 -public class XContentWindow extends XWindow implements XConstants {
18.19 +public final class XContentWindow extends XWindow implements XConstants {
18.20 private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow");
18.21
18.22 - XDecoratedPeer parentFrame;
18.23 + static XContentWindow createContent(XDecoratedPeer parentFrame) {
18.24 + final WindowDimensions dims = parentFrame.getDimensions();
18.25 + Rectangle rec = dims.getBounds();
18.26 + // Fix for - set the location of the content window to the (-left inset, -top inset)
18.27 + Insets ins = dims.getInsets();
18.28 + if (ins != null) {
18.29 + rec.x = -ins.left;
18.30 + rec.y = -ins.top;
18.31 + } else {
18.32 + rec.x = 0;
18.33 + rec.y = 0;
18.34 + }
18.35 + final XContentWindow cw = new XContentWindow(parentFrame, rec);
18.36 + cw.xSetVisible(true);
18.37 + return cw;
18.38 + }
18.39 +
18.40 + private final XDecoratedPeer parentFrame;
18.41
18.42 // A list of expose events that come when the parentFrame is iconified
18.43 - private java.util.List<SavedExposeEvent> iconifiedExposeEvents = new java.util.ArrayList<SavedExposeEvent>();
18.44 + private final java.util.List<SavedExposeEvent> iconifiedExposeEvents =
18.45 + new java.util.ArrayList<SavedExposeEvent>();
18.46
18.47 - XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
18.48 + private XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
18.49 super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds);
18.50 this.parentFrame = parentFrame;
18.51 }
18.52 @@ -63,9 +84,6 @@
18.53 }
18.54 }
18.55
18.56 - void initialize() {
18.57 - xSetVisible(true);
18.58 - }
18.59 protected String getWMName() {
18.60 return "Content window";
18.61 }
19.1 --- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Wed Mar 26 17:48:05 2008 -0700
19.2 +++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Thu Mar 27 12:09:50 2008 -0700
19.3 @@ -36,7 +36,7 @@
19.4 import sun.awt.ComponentAccessor;
19.5 import sun.awt.SunToolkit;
19.6
19.7 -class XDecoratedPeer extends XWindowPeer {
19.8 +abstract class XDecoratedPeer extends XWindowPeer {
19.9 private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer");
19.10 private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
19.11 private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
19.12 @@ -98,8 +98,7 @@
19.13 // happen after the X window is created.
19.14 initResizability();
19.15 updateSizeHints(dimensions);
19.16 - content = createContent(dimensions);
19.17 - content.initialize();
19.18 + content = XContentWindow.createContent(this);
19.19 if (warningWindow != null) {
19.20 warningWindow.toFront();
19.21 }
19.22 @@ -160,20 +159,6 @@
19.23 }
19.24 }
19.25
19.26 - XContentWindow createContent(WindowDimensions dims) {
19.27 - Rectangle rec = dims.getBounds();
19.28 - // Fix for - set the location of the content window to the (-left inset, -top inset)
19.29 - Insets ins = dims.getInsets();
19.30 - if (ins != null) {
19.31 - rec.x = -ins.left;
19.32 - rec.y = -ins.top;
19.33 - } else {
19.34 - rec.x = 0;
19.35 - rec.y = 0;
19.36 - }
19.37 - return new XContentWindow(this, rec);
19.38 - }
19.39 -
19.40 XFocusProxyWindow createFocusProxy() {
19.41 return new XFocusProxyWindow(this);
19.42 }
19.43 @@ -286,7 +271,7 @@
19.44 return;
19.45 }
19.46 Component t = (Component)target;
19.47 - if (getDecorations() == winAttr.AWT_DECOR_NONE) {
19.48 + if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
19.49 setReparented(true);
19.50 insets_corrected = true;
19.51 reshape(dimensions, SET_SIZE, false);
19.52 @@ -471,6 +456,15 @@
19.53 if (insLog.isLoggable(Level.FINE)) {
19.54 insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
19.55 }
19.56 + if (userReshape) {
19.57 + // We handle only userReshape == true cases. It means that
19.58 + // if the window manager or any other part of the windowing
19.59 + // system sets inappropriate size for this window, we can
19.60 + // do nothing but accept it.
19.61 + Rectangle reqBounds = newDimensions.getBounds();
19.62 + Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height);
19.63 + newDimensions = new WindowDimensions(newBounds, newDimensions.getInsets(), newDimensions.isClientSizeSet());
19.64 + }
19.65 XToolkit.awtLock();
19.66 try {
19.67 if (!isReparented() || !isVisible()) {
19.68 @@ -586,6 +580,49 @@
19.69 reshape(dims, operation, userReshape);
19.70 }
19.71
19.72 + // This method gets overriden in XFramePeer & XDialogPeer.
19.73 + abstract boolean isTargetUndecorated();
19.74 +
19.75 + @Override
19.76 + Rectangle constrainBounds(int x, int y, int width, int height) {
19.77 + // We don't restrict the setBounds() operation if the code is trusted.
19.78 + if (!hasWarningWindow()) {
19.79 + return new Rectangle(x, y, width, height);
19.80 + }
19.81 +
19.82 + // If it's undecorated or is not currently visible,
19.83 + // apply the same constraints as for the Window.
19.84 + if (!isVisible() || isTargetUndecorated()) {
19.85 + return super.constrainBounds(x, y, width, height);
19.86 + }
19.87 +
19.88 + // If it's visible & decorated, constraint the size only
19.89 + int newX = x;
19.90 + int newY = y;
19.91 + int newW = width;
19.92 + int newH = height;
19.93 +
19.94 + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
19.95 + Rectangle sB = gc.getBounds();
19.96 + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
19.97 +
19.98 + Rectangle curBounds = getBounds();
19.99 +
19.100 + int maxW = Math.max(sB.width - sIn.left - sIn.right, curBounds.width);
19.101 + int maxH = Math.max(sB.height - sIn.top - sIn.bottom, curBounds.height);
19.102 +
19.103 + // First make sure the size is withing the visible part of the screen
19.104 + if (newW > maxW) {
19.105 + newW = maxW;
19.106 + }
19.107 +
19.108 + if (newH > maxH) {
19.109 + newH = maxH;
19.110 + }
19.111 +
19.112 + return new Rectangle(newX, newY, newW, newH);
19.113 + }
19.114 +
19.115 /**
19.116 * @see java.awt.peer.ComponentPeer#setBounds
19.117 */
19.118 @@ -651,12 +688,12 @@
19.119 }
19.120 if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
19.121 && !XWM.isNonReparentingWM()
19.122 - && getDecorations() != winAttr.AWT_DECOR_NONE) {
19.123 + && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
19.124 insLog.fine("- visible but not reparented, skipping");
19.125 return;
19.126 }
19.127 //Last chance to correct insets
19.128 - if (!insets_corrected && getDecorations() != winAttr.AWT_DECOR_NONE) {
19.129 + if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
19.130 long parent = XlibUtil.getParentWindow(window);
19.131 Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
19.132 if (insLog.isLoggable(Level.FINER)) {
19.133 @@ -824,7 +861,7 @@
19.134 fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE);
19.135 }
19.136 winAttr.functions = fs;
19.137 - XWM.setShellNotResizable(this, dimensions, dimensions.getScreenBounds(), false);
19.138 + XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false);
19.139 }
19.140 }
19.141
19.142 @@ -870,7 +907,7 @@
19.143 return getSize().height;
19.144 }
19.145
19.146 - public WindowDimensions getDimensions() {
19.147 + final public WindowDimensions getDimensions() {
19.148 return dimensions;
19.149 }
19.150
20.1 --- a/src/solaris/classes/sun/awt/X11/XDialogPeer.java Wed Mar 26 17:48:05 2008 -0700
20.2 +++ b/src/solaris/classes/sun/awt/X11/XDialogPeer.java Thu Mar 27 12:09:50 2008 -0700
20.3 @@ -88,7 +88,8 @@
20.4 }
20.5 }
20.6
20.7 - private boolean isTargetUndecorated() {
20.8 + @Override
20.9 + boolean isTargetUndecorated() {
20.10 if (undecorated != null) {
20.11 return undecorated.booleanValue();
20.12 } else {
21.1 --- a/src/solaris/classes/sun/awt/X11/XDnDConstants.java Wed Mar 26 17:48:05 2008 -0700
21.2 +++ b/src/solaris/classes/sun/awt/X11/XDnDConstants.java Thu Mar 27 12:09:50 2008 -0700
21.3 @@ -1,5 +1,5 @@
21.4 /*
21.5 - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
21.6 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
21.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
21.8 *
21.9 * This code is free software; you can redistribute it and/or modify it
21.10 @@ -48,8 +48,7 @@
21.11 static final XAtom XA_XdndStatus = XAtom.get("XdndStatus");
21.12 static final XAtom XA_XdndFinished = XAtom.get("XdndFinished");
21.13
21.14 - static final XSelection XDnDSelection =
21.15 - new XSelection(XA_XdndSelection, null);
21.16 + static final XSelection XDnDSelection = new XSelection(XA_XdndSelection);
21.17
21.18 public static final int XDND_MIN_PROTOCOL_VERSION = 3;
21.19 public static final int XDND_PROTOCOL_VERSION = 5;
22.1 --- a/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java Wed Mar 26 17:48:05 2008 -0700
22.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java Thu Mar 27 12:09:50 2008 -0700
22.3 @@ -647,12 +647,6 @@
22.4 }
22.5 if (isXEmbedActive()) {
22.6 switch ((int)msg.get_data(1)) {
22.7 - case _SUN_XEMBED_START:
22.8 - // Child has finished initialization and waits for notify
22.9 - xembed.processXEmbedInfo();
22.10 -
22.11 - notifyChildEmbedded();
22.12 - break;
22.13 case XEMBED_REQUEST_FOCUS:
22.14 requestXEmbedFocus();
22.15 break;
23.1 --- a/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Wed Mar 26 17:48:05 2008 -0700
23.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Thu Mar 27 12:09:50 2008 -0700
23.3 @@ -74,7 +74,6 @@
23.4 XToolkit.awtUnlock();
23.5 }
23.6 }
23.7 - notifyReady();
23.8 }
23.9
23.10 void handleClientMessage(XEvent xev) {
23.11 @@ -84,7 +83,6 @@
23.12 if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Embedded message: " + msgidToString((int)msg.get_data(1)));
23.13 switch ((int)msg.get_data(1)) {
23.14 case XEMBED_EMBEDDED_NOTIFY: // Notification about embedding protocol start
23.15 - // NOTE: May be called two times because we send _SUN_XEMBED_START
23.16 active = true;
23.17 server = getEmbedder(embedded, msg);
23.18 // Check if window is reparented. If not - it was created with
23.19 @@ -223,13 +221,4 @@
23.20 long getX11Mods(AWTKeyStroke stroke) {
23.21 return XWindow.getXModifiers(stroke);
23.22 }
23.23 -
23.24 - void notifyReady() {
23.25 - long wnd = server;
23.26 - if (wnd == 0) {
23.27 - // Server is still 0, get the parent
23.28 - wnd = embedded.getParentWindowHandle();
23.29 - }
23.30 - sendMessage(wnd, _SUN_XEMBED_START);
23.31 - }
23.32 }
24.1 --- a/src/solaris/classes/sun/awt/X11/XEmbedHelper.java Wed Mar 26 17:48:05 2008 -0700
24.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbedHelper.java Thu Mar 27 12:09:50 2008 -0700
24.3 @@ -58,7 +58,6 @@
24.4 final static int XEMBED_REGISTER_ACCELERATOR = 12;
24.5 final static int XEMBED_UNREGISTER_ACCELERATOR= 13;
24.6 final static int XEMBED_ACTIVATE_ACCELERATOR = 14;
24.7 - final static int _SUN_XEMBED_START = 1119;
24.8
24.9 final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108;
24.10 final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109;
24.11 @@ -151,8 +150,6 @@
24.12 return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY";
24.13 case NON_STANDARD_XEMBED_GTK_GRAB_KEY:
24.14 return "NON_STANDARD_XEMBED_GTK_GRAB_KEY";
24.15 - case _SUN_XEMBED_START:
24.16 - return "XEMBED_START";
24.17 case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK:
24.18 return "KeyPress";
24.19 case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK:
25.1 --- a/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java Wed Mar 26 17:48:05 2008 -0700
25.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java Thu Mar 27 12:09:50 2008 -0700
25.3 @@ -177,13 +177,6 @@
25.4 embedCompletely();
25.5 }
25.6
25.7 - public void test3_2() {
25.8 - embedCompletely();
25.9 - int res = getEventPos();
25.10 - sendMessage(XEmbedHelper._SUN_XEMBED_START);
25.11 - waitEmbeddedNotify(res);
25.12 - }
25.13 -
25.14 public void test3_3() {
25.15 reparent = true;
25.16 embedCompletely();
26.1 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Wed Mar 26 17:48:05 2008 -0700
26.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Thu Mar 27 12:09:50 2008 -0700
26.3 @@ -184,6 +184,12 @@
26.4 }
26.5 }
26.6
26.7 + @Override
26.8 + Rectangle constrainBounds(int x, int y, int width, int height) {
26.9 + // We don't constrain the bounds of the EmbeddedFrames
26.10 + return new Rectangle(x, y, width, height);
26.11 + }
26.12 +
26.13 // don't use getBounds() inherited from XDecoratedPeer
26.14 public Rectangle getBounds() {
26.15 return new Rectangle(x, y, width, height);
27.1 --- a/src/solaris/classes/sun/awt/X11/XFramePeer.java Wed Mar 26 17:48:05 2008 -0700
27.2 +++ b/src/solaris/classes/sun/awt/X11/XFramePeer.java Thu Mar 27 12:09:50 2008 -0700
27.3 @@ -1,5 +1,5 @@
27.4 /*
27.5 - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
27.6 + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
27.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
27.8 *
27.9 * This code is free software; you can redistribute it and/or modify it
27.10 @@ -24,15 +24,18 @@
27.11 */
27.12 package sun.awt.X11;
27.13
27.14 -import java.util.Vector;
27.15 -import java.awt.*;
27.16 -import java.awt.peer.*;
27.17 -import java.awt.event.*;
27.18 -import sun.awt.im.*;
27.19 -import sun.awt.*;
27.20 -import java.util.logging.*;
27.21 -import java.lang.reflect.Field;
27.22 -import java.util.*;
27.23 +import java.awt.Color;
27.24 +import java.awt.Dimension;
27.25 +import java.awt.Font;
27.26 +import java.awt.FontMetrics;
27.27 +import java.awt.Frame;
27.28 +import java.awt.Graphics;
27.29 +import java.awt.Insets;
27.30 +import java.awt.MenuBar;
27.31 +import java.awt.Rectangle;
27.32 +import java.awt.peer.FramePeer;
27.33 +import java.util.logging.Level;
27.34 +import java.util.logging.Logger;
27.35
27.36 class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
27.37 private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer");
27.38 @@ -92,7 +95,8 @@
27.39 }
27.40 }
27.41
27.42 - private boolean isTargetUndecorated() {
27.43 + @Override
27.44 + boolean isTargetUndecorated() {
27.45 if (undecorated != null) {
27.46 return undecorated.booleanValue();
27.47 } else {
27.48 @@ -285,19 +289,20 @@
27.49 * Let's see if this is a window state protocol message, and
27.50 * if it is - decode a new state in terms of java constants.
27.51 */
27.52 - Integer newState = XWM.getWM().isStateChange(this, ev);
27.53 - if (newState == null) {
27.54 + if (!XWM.getWM().isStateChange(this, ev)) {
27.55 + stateLog.finer("either not a state atom or state has not been changed");
27.56 return;
27.57 }
27.58
27.59 - int changed = state ^ newState.intValue();
27.60 + final int newState = XWM.getWM().getState(this);
27.61 + int changed = state ^ newState;
27.62 if (changed == 0) {
27.63 stateLog.finer("State is the same: " + state);
27.64 return;
27.65 }
27.66
27.67 int old_state = state;
27.68 - state = newState.intValue();
27.69 + state = newState;
27.70
27.71 if ((changed & Frame.ICONIFIED) != 0) {
27.72 if ((state & Frame.ICONIFIED) != 0) {
28.1 --- a/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java Wed Mar 26 17:48:05 2008 -0700
28.2 +++ b/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java Thu Mar 27 12:09:50 2008 -0700
28.3 @@ -1,5 +1,5 @@
28.4 /*
28.5 - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
28.6 + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
28.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
28.8 *
28.9 * This code is free software; you can redistribute it and/or modify it
28.10 @@ -218,7 +218,7 @@
28.11
28.12 Font getTargetFont() {
28.13 if (target == null) {
28.14 - return XWindow.defaultFont;
28.15 + return XWindow.getDefaultFont();
28.16 }
28.17 try {
28.18 return (Font)m_getFont.invoke(target, new Object[0]);
28.19 @@ -227,7 +227,7 @@
28.20 } catch (InvocationTargetException e) {
28.21 e.printStackTrace();
28.22 }
28.23 - return XWindow.defaultFont;
28.24 + return XWindow.getDefaultFont();
28.25 }
28.26
28.27 String getTargetLabel() {
29.1 --- a/src/solaris/classes/sun/awt/X11/XNETProtocol.java Wed Mar 26 17:48:05 2008 -0700
29.2 +++ b/src/solaris/classes/sun/awt/X11/XNETProtocol.java Thu Mar 27 12:09:50 2008 -0700
29.3 @@ -1,5 +1,5 @@
29.4 /*
29.5 - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
29.6 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
29.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
29.8 *
29.9 * This code is free software; you can redistribute it and/or modify it
29.10 @@ -26,17 +26,15 @@
29.11
29.12 package sun.awt.X11;
29.13
29.14 -import java.awt.*;
29.15 +import java.awt.Frame;
29.16 import java.util.logging.Level;
29.17 import java.util.logging.Logger;
29.18 -import java.util.logging.LogManager;
29.19 -import java.awt.*;
29.20 -import java.awt.image.*;
29.21 -import java.util.*;
29.22
29.23 -class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol {
29.24 - final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
29.25 +final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol
29.26 +{
29.27 + private final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
29.28 private final static Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XNETProtocol");
29.29 + private static Logger stateLog = Logger.getLogger("sun.awt.X11.states.XNETProtocol");
29.30
29.31 /**
29.32 * XStateProtocol
29.33 @@ -276,6 +274,7 @@
29.34
29.35 boolean doStateProtocol() {
29.36 boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE);
29.37 + stateLog.finer("doStateProtocol() returns " + res);
29.38 return res;
29.39 }
29.40
30.1 --- a/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java Wed Mar 26 17:48:05 2008 -0700
30.2 +++ b/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java Thu Mar 27 12:09:50 2008 -0700
30.3 @@ -1,5 +1,5 @@
30.4 /*
30.5 - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
30.6 + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
30.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
30.8 *
30.9 * This code is free software; you can redistribute it and/or modify it
30.10 @@ -187,7 +187,7 @@
30.11 //Fix for 6267144: PIT: Popup menu label is not shown, XToolkit
30.12 Font getTargetFont() {
30.13 if (popupMenuTarget == null) {
30.14 - return XWindow.defaultFont;
30.15 + return XWindow.getDefaultFont();
30.16 }
30.17 try {
30.18 return (Font)m_getFont.invoke(popupMenuTarget, new Object[0]);
30.19 @@ -196,7 +196,7 @@
30.20 } catch (InvocationTargetException e) {
30.21 e.printStackTrace();
30.22 }
30.23 - return XWindow.defaultFont;
30.24 + return XWindow.getDefaultFont();
30.25 }
30.26
30.27 String getTargetLabel() {
31.1 --- a/src/solaris/classes/sun/awt/X11/XSelection.java Wed Mar 26 17:48:05 2008 -0700
31.2 +++ b/src/solaris/classes/sun/awt/X11/XSelection.java Thu Mar 27 12:09:50 2008 -0700
31.3 @@ -1,5 +1,5 @@
31.4 /*
31.5 - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
31.6 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
31.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
31.8 *
31.9 * This code is free software; you can redistribute it and/or modify it
31.10 @@ -32,9 +32,6 @@
31.11
31.12 import java.util.Hashtable;
31.13 import java.util.Map;
31.14 -import java.util.Set;
31.15 -import java.util.HashSet;
31.16 -import java.util.Collections;
31.17
31.18 import sun.awt.AppContext;
31.19 import sun.awt.SunToolkit;
31.20 @@ -45,7 +42,7 @@
31.21 /**
31.22 * A class which interfaces with the X11 selection service.
31.23 */
31.24 -public class XSelection {
31.25 +public final class XSelection {
31.26
31.27 /* Maps atoms to XSelection instances. */
31.28 private static final Hashtable<XAtom, XSelection> table = new Hashtable<XAtom, XSelection>();
31.29 @@ -69,8 +66,6 @@
31.30 XToolkit.awtUnlock();
31.31 }
31.32 }
31.33 - /* The selection timeout. */
31.34 - private static long SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
31.35
31.36 /* The PropertyNotify event handler for incremental data transfer. */
31.37 private static final XEventDispatcher incrementalTransferHandler =
31.38 @@ -84,11 +79,6 @@
31.39
31.40 /* The X atom for the underlying selection. */
31.41 private final XAtom selectionAtom;
31.42 - /*
31.43 - * XClipboard.run() is to be called when we lose ownership.
31.44 - * XClipbioard.checkChange() is to be called when tracking changes of flavors.
31.45 - */
31.46 - private final XClipboard clipboard;
31.47
31.48 /*
31.49 * Owner-related variables - protected with synchronized (this).
31.50 @@ -109,17 +99,8 @@
31.51 private long ownershipTime = 0;
31.52 // True if we are the owner of this selection.
31.53 private boolean isOwner;
31.54 - // The property in which the owner should place requested targets
31.55 - // when tracking changes of available data flavors (practically targets).
31.56 - private volatile XAtom targetsPropertyAtom;
31.57 - // A set of these property atoms.
31.58 - private static volatile Set targetsPropertyAtoms;
31.59 - // The flag used not to call XConvertSelection() if the previous SelectionNotify
31.60 - // has not been processed by checkChange().
31.61 - private volatile boolean isSelectionNotifyProcessed;
31.62 - // Time of calling XConvertSelection().
31.63 - private long convertSelectionTime;
31.64 -
31.65 + private OwnershipListener ownershipListener = null;
31.66 + private final Object stateLock = new Object();
31.67
31.68 static {
31.69 XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
31.70 @@ -141,12 +122,11 @@
31.71 * @param clpbrd the corresponding clipoboard
31.72 * @exception NullPointerException if atom is <code>null</code>.
31.73 */
31.74 - public XSelection(XAtom atom, XClipboard clpbrd) {
31.75 + public XSelection(XAtom atom) {
31.76 if (atom == null) {
31.77 throw new NullPointerException("Null atom");
31.78 }
31.79 selectionAtom = atom;
31.80 - clipboard = clpbrd;
31.81 table.put(selectionAtom, this);
31.82 }
31.83
31.84 @@ -154,25 +134,9 @@
31.85 return selectionAtom;
31.86 }
31.87
31.88 - void initializeSelectionForTrackingChanges() {
31.89 - targetsPropertyAtom = XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selectionAtom.getName());
31.90 - if (targetsPropertyAtoms == null) {
31.91 - targetsPropertyAtoms = Collections.synchronizedSet(new HashSet(2));
31.92 - }
31.93 - targetsPropertyAtoms.add(Long.valueOf(targetsPropertyAtom.getAtom()));
31.94 - // for XConvertSelection() to be called for the first time in getTargetsDelayed()
31.95 - isSelectionNotifyProcessed = true;
31.96 - }
31.97 -
31.98 - void deinitializeSelectionForTrackingChanges() {
31.99 - if (targetsPropertyAtoms != null && targetsPropertyAtom != null) {
31.100 - targetsPropertyAtoms.remove(Long.valueOf(targetsPropertyAtom.getAtom()));
31.101 - }
31.102 - isSelectionNotifyProcessed = false;
31.103 - }
31.104 -
31.105 public synchronized boolean setOwner(Transferable contents, Map formatMap,
31.106 - long[] formats, long time) {
31.107 + long[] formats, long time)
31.108 + {
31.109 long owner = XWindow.getXAWTRootWindow().getWindow();
31.110 long selection = selectionAtom.getAtom();
31.111
31.112 @@ -192,15 +156,12 @@
31.113 XlibWrapper.XSetSelectionOwner(XToolkit.getDisplay(),
31.114 selection, owner, time);
31.115 if (XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(),
31.116 - selection) != owner) {
31.117 -
31.118 + selection) != owner)
31.119 + {
31.120 reset();
31.121 return false;
31.122 }
31.123 - isOwner = true;
31.124 - if (clipboard != null) {
31.125 - clipboard.checkChangeHere(contents);
31.126 - }
31.127 + setOwnerProp(true);
31.128 return true;
31.129 } finally {
31.130 XToolkit.awtUnlock();
31.131 @@ -217,7 +178,7 @@
31.132 do {
31.133 DataTransferer.getInstance().processDataConversionRequests();
31.134 XToolkit.awtLockWait(250);
31.135 - } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + SELECTION_TIMEOUT);
31.136 + } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + UNIXToolkit.getDatatransferTimeout());
31.137 } finally {
31.138 XToolkit.awtUnlock();
31.139 }
31.140 @@ -232,11 +193,9 @@
31.141 throw new Error("UNIMPLEMENTED");
31.142 }
31.143
31.144 - long[] formats = null;
31.145 + long[] targets = null;
31.146
31.147 synchronized (lock) {
31.148 - SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
31.149 -
31.150 WindowPropertyGetter targetsGetter =
31.151 new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
31.152 selectionPropertyAtom, 0, MAX_LENGTH,
31.153 @@ -267,23 +226,25 @@
31.154 } finally {
31.155 XToolkit.awtUnlock();
31.156 }
31.157 - formats = getFormats(targetsGetter);
31.158 + targets = getFormats(targetsGetter);
31.159 } finally {
31.160 targetsGetter.dispose();
31.161 }
31.162 }
31.163 - return formats;
31.164 + return targets;
31.165 }
31.166
31.167 - private static long[] getFormats(WindowPropertyGetter targetsGetter) {
31.168 + static long[] getFormats(WindowPropertyGetter targetsGetter) {
31.169 long[] formats = null;
31.170
31.171 if (targetsGetter.isExecuted() && !targetsGetter.isDisposed() &&
31.172 (targetsGetter.getActualType() == XAtom.XA_ATOM ||
31.173 targetsGetter.getActualType() == XDataTransferer.TARGETS_ATOM.getAtom()) &&
31.174 - targetsGetter.getActualFormat() == 32) {
31.175 -
31.176 - int count = (int)targetsGetter.getNumberOfItems();
31.177 + targetsGetter.getActualFormat() == 32)
31.178 + {
31.179 + // we accept property with TARGETS type to be compatible with old jdks
31.180 + // see 6607163
31.181 + int count = targetsGetter.getNumberOfItems();
31.182 if (count > 0) {
31.183 long atoms = targetsGetter.getData();
31.184 formats = new long[count];
31.185 @@ -297,26 +258,6 @@
31.186 return formats != null ? formats : new long[0];
31.187 }
31.188
31.189 - // checkChange() will be called on SelectionNotify
31.190 - void getTargetsDelayed() {
31.191 - XToolkit.awtLock();
31.192 - try {
31.193 - long curTime = System.currentTimeMillis();
31.194 - if (isSelectionNotifyProcessed || curTime >= convertSelectionTime + SELECTION_TIMEOUT) {
31.195 - convertSelectionTime = curTime;
31.196 - XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
31.197 - getSelectionAtom().getAtom(),
31.198 - XDataTransferer.TARGETS_ATOM.getAtom(),
31.199 - targetsPropertyAtom.getAtom(),
31.200 - XWindow.getXAWTRootWindow().getWindow(),
31.201 - XlibWrapper.CurrentTime);
31.202 - isSelectionNotifyProcessed = false;
31.203 - }
31.204 - } finally {
31.205 - XToolkit.awtUnlock();
31.206 - }
31.207 - }
31.208 -
31.209 /*
31.210 * Requests the selection data in the specified format and returns
31.211 * the data provided by the owner.
31.212 @@ -329,8 +270,6 @@
31.213 byte[] data = null;
31.214
31.215 synchronized (lock) {
31.216 - SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
31.217 -
31.218 WindowPropertyGetter dataGetter =
31.219 new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
31.220 selectionPropertyAtom, 0, MAX_LENGTH,
31.221 @@ -379,7 +318,7 @@
31.222 dataGetter.getActualFormat());
31.223 }
31.224
31.225 - int count = (int)dataGetter.getNumberOfItems();
31.226 + int count = dataGetter.getNumberOfItems();
31.227
31.228 if (count <= 0) {
31.229 throw new IOException("INCR data is missed.");
31.230 @@ -455,7 +394,7 @@
31.231 incrDataGetter.getActualFormat());
31.232 }
31.233
31.234 - count = (int)incrDataGetter.getNumberOfItems();
31.235 + count = incrDataGetter.getNumberOfItems();
31.236
31.237 if (count == 0) {
31.238 break;
31.239 @@ -489,7 +428,7 @@
31.240 dataGetter.getActualFormat());
31.241 }
31.242
31.243 - int count = (int)dataGetter.getNumberOfItems();
31.244 + int count = dataGetter.getNumberOfItems();
31.245 if (count > 0) {
31.246 data = new byte[count];
31.247 long ptr = dataGetter.getData();
31.248 @@ -511,11 +450,14 @@
31.249 return isOwner;
31.250 }
31.251
31.252 - public void lostOwnership() {
31.253 - isOwner = false;
31.254 - if (clipboard != null) {
31.255 - clipboard.run();
31.256 - }
31.257 + // To be MT-safe this method should be called under awtLock.
31.258 + private void setOwnerProp(boolean f) {
31.259 + isOwner = f;
31.260 + fireOwnershipChanges(isOwner);
31.261 + }
31.262 +
31.263 + private void lostOwnership() {
31.264 + setOwnerProp(false);
31.265 }
31.266
31.267 public synchronized void reset() {
31.268 @@ -595,125 +537,39 @@
31.269
31.270 private void handleSelectionRequest(XSelectionRequestEvent xsre) {
31.271 long property = xsre.get_property();
31.272 - long requestor = xsre.get_requestor();
31.273 - long requestTime = xsre.get_time();
31.274 - long format = xsre.get_target();
31.275 - int dataFormat = 0;
31.276 + final long requestor = xsre.get_requestor();
31.277 + final long requestTime = xsre.get_time();
31.278 + final long format = xsre.get_target();
31.279 boolean conversionSucceeded = false;
31.280
31.281 if (ownershipTime != 0 &&
31.282 - (requestTime == XlibWrapper.CurrentTime ||
31.283 - requestTime >= ownershipTime)) {
31.284 -
31.285 - property = xsre.get_property();
31.286 -
31.287 + (requestTime == XlibWrapper.CurrentTime || requestTime >= ownershipTime))
31.288 + {
31.289 // Handle MULTIPLE requests as per ICCCM.
31.290 if (format == XDataTransferer.MULTIPLE_ATOM.getAtom()) {
31.291 - // The property cannot be 0 for a MULTIPLE request.
31.292 - if (property != 0) {
31.293 - // First retrieve the list of requested targets.
31.294 - WindowPropertyGetter wpg =
31.295 - new WindowPropertyGetter(requestor, XAtom.get(property), 0,
31.296 - MAX_LENGTH, false,
31.297 - XlibWrapper.AnyPropertyType);
31.298 - try {
31.299 - wpg.execute();
31.300 -
31.301 - if (wpg.getActualFormat() == 32 &&
31.302 - (wpg.getNumberOfItems() % 2) == 0) {
31.303 - long count = wpg.getNumberOfItems() / 2;
31.304 - long pairsPtr = wpg.getData();
31.305 - boolean writeBack = false;
31.306 - for (int i = 0; i < count; i++) {
31.307 - long target = Native.getLong(pairsPtr, 2*i);
31.308 - long prop = Native.getLong(pairsPtr, 2*i + 1);
31.309 -
31.310 - if (!convertAndStore(requestor, target, prop)) {
31.311 - // To report failure, we should replace the
31.312 - // target atom with 0 in the MULTIPLE property.
31.313 - Native.putLong(pairsPtr, 2*i, 0);
31.314 - writeBack = true;
31.315 - }
31.316 - }
31.317 - if (writeBack) {
31.318 - XToolkit.awtLock();
31.319 - try {
31.320 - XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
31.321 - property,
31.322 - wpg.getActualType(),
31.323 - wpg.getActualFormat(),
31.324 - XlibWrapper.PropModeReplace,
31.325 - wpg.getData(),
31.326 - wpg.getNumberOfItems());
31.327 - } finally {
31.328 - XToolkit.awtUnlock();
31.329 - }
31.330 - }
31.331 - conversionSucceeded = true;
31.332 - }
31.333 - } finally {
31.334 - wpg.dispose();
31.335 - }
31.336 - }
31.337 + conversionSucceeded = handleMultipleRequest(requestor, property);
31.338 } else {
31.339 -
31.340 // Support for obsolete clients as per ICCCM.
31.341 - if (property == 0) {
31.342 + if (property == XlibWrapper.None) {
31.343 property = format;
31.344 }
31.345
31.346 if (format == XDataTransferer.TARGETS_ATOM.getAtom()) {
31.347 - long nativeDataPtr = 0;
31.348 - int count = 0;
31.349 - dataFormat = 32;
31.350 -
31.351 - // Use a local copy to avoid synchronization.
31.352 - long[] formatsLocal = formats;
31.353 -
31.354 - if (formatsLocal == null) {
31.355 - throw new IllegalStateException("Not an owner.");
31.356 - }
31.357 -
31.358 - count = formatsLocal.length;
31.359 -
31.360 - try {
31.361 - if (count > 0) {
31.362 - nativeDataPtr = Native.allocateLongArray(count);
31.363 - Native.put(nativeDataPtr, formatsLocal);
31.364 - }
31.365 -
31.366 - conversionSucceeded = true;
31.367 -
31.368 - XToolkit.awtLock();
31.369 - try {
31.370 - XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
31.371 - property, format, dataFormat,
31.372 - XlibWrapper.PropModeReplace,
31.373 - nativeDataPtr, count);
31.374 - } finally {
31.375 - XToolkit.awtUnlock();
31.376 - }
31.377 - } finally {
31.378 - if (nativeDataPtr != 0) {
31.379 - XlibWrapper.unsafe.freeMemory(nativeDataPtr);
31.380 - nativeDataPtr = 0;
31.381 - }
31.382 - }
31.383 + conversionSucceeded = handleTargetsRequest(property, requestor);
31.384 } else {
31.385 - conversionSucceeded = convertAndStore(requestor, format,
31.386 - property);
31.387 + conversionSucceeded = convertAndStore(requestor, format, property);
31.388 }
31.389 }
31.390 }
31.391
31.392 if (!conversionSucceeded) {
31.393 - // Zero property indicates conversion failure.
31.394 - property = 0;
31.395 + // None property indicates conversion failure.
31.396 + property = XlibWrapper.None;
31.397 }
31.398
31.399 XSelectionEvent xse = new XSelectionEvent();
31.400 try {
31.401 - xse.set_type((int)XlibWrapper.SelectionNotify);
31.402 + xse.set_type(XlibWrapper.SelectionNotify);
31.403 xse.set_send_event(true);
31.404 xse.set_requestor(requestor);
31.405 xse.set_selection(selectionAtom.getAtom());
31.406 @@ -733,40 +589,123 @@
31.407 }
31.408 }
31.409
31.410 - private static void checkChange(XSelectionEvent xse) {
31.411 - if (targetsPropertyAtoms == null || targetsPropertyAtoms.isEmpty()) {
31.412 - // We are not tracking changes.
31.413 - return;
31.414 + private boolean handleMultipleRequest(final long requestor, long property) {
31.415 + if (XlibWrapper.None == property) {
31.416 + // The property cannot be None for a MULTIPLE request.
31.417 + return false;
31.418 }
31.419
31.420 - long propertyAtom = xse.get_property();
31.421 - long[] formats = null;
31.422 + boolean conversionSucceeded = false;
31.423
31.424 - if (propertyAtom == XlibWrapper.None) {
31.425 - // We threat None property atom as "empty selection".
31.426 - formats = new long[0];
31.427 - } else if (!targetsPropertyAtoms.contains(Long.valueOf(propertyAtom))) {
31.428 - return;
31.429 - } else {
31.430 - WindowPropertyGetter targetsGetter =
31.431 - new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
31.432 - XAtom.get(propertyAtom), 0, MAX_LENGTH,
31.433 - true, XlibWrapper.AnyPropertyType);
31.434 + // First retrieve the list of requested targets.
31.435 + WindowPropertyGetter wpg =
31.436 + new WindowPropertyGetter(requestor, XAtom.get(property),
31.437 + 0, MAX_LENGTH, false,
31.438 + XlibWrapper.AnyPropertyType);
31.439 + try {
31.440 + wpg.execute();
31.441 +
31.442 + if (wpg.getActualFormat() == 32 && (wpg.getNumberOfItems() % 2) == 0) {
31.443 + final long count = wpg.getNumberOfItems() / 2;
31.444 + final long pairsPtr = wpg.getData();
31.445 + boolean writeBack = false;
31.446 +
31.447 + for (int i = 0; i < count; i++) {
31.448 + long target = Native.getLong(pairsPtr, 2 * i);
31.449 + long prop = Native.getLong(pairsPtr, 2 * i + 1);
31.450 +
31.451 + if (!convertAndStore(requestor, target, prop)) {
31.452 + // To report failure, we should replace the
31.453 + // target atom with 0 in the MULTIPLE property.
31.454 + Native.putLong(pairsPtr, 2 * i, 0);
31.455 + writeBack = true;
31.456 + }
31.457 + }
31.458 + if (writeBack) {
31.459 + XToolkit.awtLock();
31.460 + try {
31.461 + XlibWrapper.XChangeProperty(XToolkit.getDisplay(),
31.462 + requestor,
31.463 + property,
31.464 + wpg.getActualType(),
31.465 + wpg.getActualFormat(),
31.466 + XlibWrapper.PropModeReplace,
31.467 + wpg.getData(),
31.468 + wpg.getNumberOfItems());
31.469 + } finally {
31.470 + XToolkit.awtUnlock();
31.471 + }
31.472 + }
31.473 + conversionSucceeded = true;
31.474 + }
31.475 + } finally {
31.476 + wpg.dispose();
31.477 + }
31.478 +
31.479 + return conversionSucceeded;
31.480 + }
31.481 +
31.482 + private boolean handleTargetsRequest(long property, long requestor)
31.483 + throws IllegalStateException
31.484 + {
31.485 + boolean conversionSucceeded = false;
31.486 + // Use a local copy to avoid synchronization.
31.487 + long[] formatsLocal = formats;
31.488 +
31.489 + if (formatsLocal == null) {
31.490 + throw new IllegalStateException("Not an owner.");
31.491 + }
31.492 +
31.493 + long nativeDataPtr = 0;
31.494 +
31.495 + try {
31.496 + final int count = formatsLocal.length;
31.497 + final int dataFormat = 32;
31.498 +
31.499 + if (count > 0) {
31.500 + nativeDataPtr = Native.allocateLongArray(count);
31.501 + Native.put(nativeDataPtr, formatsLocal);
31.502 + }
31.503 +
31.504 + conversionSucceeded = true;
31.505 +
31.506 + XToolkit.awtLock();
31.507 try {
31.508 - targetsGetter.execute();
31.509 - formats = getFormats(targetsGetter);
31.510 + XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
31.511 + property, XAtom.XA_ATOM, dataFormat,
31.512 + XlibWrapper.PropModeReplace,
31.513 + nativeDataPtr, count);
31.514 } finally {
31.515 - targetsGetter.dispose();
31.516 + XToolkit.awtUnlock();
31.517 + }
31.518 + } finally {
31.519 + if (nativeDataPtr != 0) {
31.520 + XlibWrapper.unsafe.freeMemory(nativeDataPtr);
31.521 + nativeDataPtr = 0;
31.522 }
31.523 }
31.524 + return conversionSucceeded;
31.525 + }
31.526
31.527 - XAtom selectionAtom = XAtom.get(xse.get_selection());
31.528 - XSelection selection = getSelection(selectionAtom);
31.529 - if (selection != null) {
31.530 - selection.isSelectionNotifyProcessed = true;
31.531 - if (selection.clipboard != null) {
31.532 - selection.clipboard.checkChange(formats);
31.533 - }
31.534 + private void fireOwnershipChanges(final boolean isOwner) {
31.535 + OwnershipListener l = null;
31.536 + synchronized (stateLock) {
31.537 + l = ownershipListener;
31.538 + }
31.539 + if (null != l) {
31.540 + l.ownershipChanged(isOwner);
31.541 + }
31.542 + }
31.543 +
31.544 + void registerOwershipListener(OwnershipListener l) {
31.545 + synchronized (stateLock) {
31.546 + ownershipListener = l;
31.547 + }
31.548 + }
31.549 +
31.550 + void unregisterOwnershipListener() {
31.551 + synchronized (stateLock) {
31.552 + ownershipListener = null;
31.553 }
31.554 }
31.555
31.556 @@ -774,10 +713,9 @@
31.557 public void dispatchEvent(XEvent ev) {
31.558 switch (ev.get_type()) {
31.559 case XlibWrapper.SelectionNotify: {
31.560 - XSelectionEvent xse = ev.get_xselection();
31.561 - checkChange(xse);
31.562 XToolkit.awtLock();
31.563 try {
31.564 + XSelectionEvent xse = ev.get_xselection();
31.565 // Ignore the SelectionNotify event if it is not the response to our last request.
31.566 if (propertyGetter != null && xse.get_time() == lastRequestServerTime) {
31.567 // The property will be None in case of convertion failure.
32.1 --- a/src/solaris/classes/sun/awt/X11/XToolkit.java Wed Mar 26 17:48:05 2008 -0700
32.2 +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java Thu Mar 27 12:09:50 2008 -0700
32.3 @@ -1,5 +1,5 @@
32.4 /*
32.5 - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
32.6 + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
32.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
32.8 *
32.9 * This code is free software; you can redistribute it and/or modify it
32.10 @@ -25,11 +25,9 @@
32.11 package sun.awt.X11;
32.12
32.13 import java.awt.*;
32.14 -import java.awt.event.*;
32.15 -import java.awt.peer.*;
32.16 -import java.beans.PropertyChangeListener;
32.17 -import sun.awt.*;
32.18 -import java.util.*;
32.19 +import java.awt.event.InputEvent;
32.20 +import java.awt.event.MouseEvent;
32.21 +import java.awt.datatransfer.Clipboard;
32.22 import java.awt.dnd.DragSource;
32.23 import java.awt.dnd.DragGestureListener;
32.24 import java.awt.dnd.DragGestureEvent;
32.25 @@ -37,20 +35,27 @@
32.26 import java.awt.dnd.MouseDragGestureRecognizer;
32.27 import java.awt.dnd.InvalidDnDOperationException;
32.28 import java.awt.dnd.peer.DragSourceContextPeer;
32.29 -import java.awt.image.*;
32.30 -import java.security.*;
32.31 import java.awt.im.InputMethodHighlight;
32.32 import java.awt.im.spi.InputMethodDescriptor;
32.33 -import java.awt.datatransfer.Clipboard;
32.34 +import java.awt.image.ColorModel;
32.35 +import java.awt.peer.*;
32.36 +import java.beans.PropertyChangeListener;
32.37 +import java.lang.reflect.InvocationTargetException;
32.38 +import java.lang.reflect.Method;
32.39 +import java.security.AccessController;
32.40 +import java.security.PrivilegedAction;
32.41 +import java.util.*;
32.42 +import java.util.logging.Level;
32.43 +import java.util.logging.Logger;
32.44 import javax.swing.LookAndFeel;
32.45 import javax.swing.UIDefaults;
32.46 -import java.util.logging.*;
32.47 +import sun.awt.*;
32.48 import sun.font.FontManager;
32.49 import sun.misc.PerformanceLogger;
32.50 import sun.print.PrintJob2D;
32.51 -import java.lang.reflect.*;
32.52
32.53 -public class XToolkit extends UNIXToolkit implements Runnable, XConstants {
32.54 +public final class XToolkit extends UNIXToolkit implements Runnable, XConstants
32.55 +{
32.56 private static Logger log = Logger.getLogger("sun.awt.X11.XToolkit");
32.57 private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XToolkit");
32.58 private static final Logger timeoutTaskLog = Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit");
32.59 @@ -1871,9 +1876,7 @@
32.60 }
32.61
32.62 public boolean isAlwaysOnTopSupported() {
32.63 - Iterator iter = XWM.getWM().getProtocols(XLayerProtocol.class).iterator();
32.64 - while (iter.hasNext()) {
32.65 - XLayerProtocol proto = (XLayerProtocol)iter.next();
32.66 + for (XLayerProtocol proto : XWM.getWM().getProtocols(XLayerProtocol.class)) {
32.67 if (proto.supportsLayer(XLayerProtocol.LAYER_ALWAYS_ON_TOP)) {
32.68 return true;
32.69 }
33.1 --- a/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java Wed Mar 26 17:48:05 2008 -0700
33.2 +++ b/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java Thu Mar 27 12:09:50 2008 -0700
33.3 @@ -1,5 +1,5 @@
33.4 /*
33.5 - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
33.6 + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
33.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33.8 *
33.9 * This code is free software; you can redistribute it and/or modify it
33.10 @@ -31,11 +31,8 @@
33.11 import sun.awt.*;
33.12 import java.awt.image.*;
33.13 import java.text.BreakIterator;
33.14 -import java.util.Vector;
33.15 -import java.lang.reflect.Field;
33.16 import java.util.logging.Logger;
33.17 import java.util.logging.Level;
33.18 -import java.util.AbstractQueue;
33.19 import java.util.concurrent.ArrayBlockingQueue;
33.20 import java.security.AccessController;
33.21 import java.security.PrivilegedAction;
33.22 @@ -629,7 +626,7 @@
33.23 final static int TOOLTIP_MAX_LENGTH = 64;
33.24 final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5;
33.25 final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220);
33.26 - final static Font TOOLTIP_TEXT_FONT = XWindow.defaultFont;
33.27 + final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont();
33.28
33.29 Tooltip(XTrayIconPeer xtiPeer, Frame parent) {
33.30 super(parent, Color.black);
34.1 --- a/src/solaris/classes/sun/awt/X11/XWM.java Wed Mar 26 17:48:05 2008 -0700
34.2 +++ b/src/solaris/classes/sun/awt/X11/XWM.java Thu Mar 27 12:09:50 2008 -0700
34.3 @@ -1,5 +1,5 @@
34.4 /*
34.5 - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
34.6 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
34.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
34.8 *
34.9 * This code is free software; you can redistribute it and/or modify it
34.10 @@ -31,20 +31,23 @@
34.11 package sun.awt.X11;
34.12
34.13 import sun.misc.Unsafe;
34.14 -import java.util.regex.*;
34.15 +import java.awt.Insets;
34.16 import java.awt.Frame;
34.17 import java.awt.Rectangle;
34.18 -import java.util.*;
34.19 +import java.util.Collection;
34.20 +import java.util.HashMap;
34.21 +import java.util.LinkedList;
34.22 import java.util.logging.Level;
34.23 -import java.util.logging.LogManager;
34.24 import java.util.logging.Logger;
34.25 -import java.awt.Insets;
34.26 +import java.util.regex.Matcher;
34.27 +import java.util.regex.Pattern;
34.28
34.29 /**
34.30 * Class incapsulating knowledge about window managers in general
34.31 * Descendants should provide some information about specific window manager.
34.32 */
34.33 -class XWM implements MWMConstants, XUtilConstants {
34.34 +final class XWM implements MWMConstants, XUtilConstants
34.35 +{
34.36
34.37 private final static Logger log = Logger.getLogger("sun.awt.X11.XWM");
34.38 private final static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWM");
34.39 @@ -1026,21 +1029,21 @@
34.40 /*****************************************************************************\
34.41 * Protocols support
34.42 */
34.43 - HashMap<Class<?>, Collection<XProtocol>> protocolsMap = new HashMap<Class<?>, Collection<XProtocol>>();
34.44 + private HashMap<Class<?>, Collection<?>> protocolsMap = new HashMap<Class<?>, Collection<?>>();
34.45 /**
34.46 * Returns all protocols supporting given protocol interface
34.47 */
34.48 - Collection<XProtocol> getProtocols(Class protocolInterface) {
34.49 - Collection<XProtocol> res = protocolsMap.get(protocolInterface);
34.50 + <T> Collection<T> getProtocols(Class<T> protocolInterface) {
34.51 + Collection<T> res = (Collection<T>) protocolsMap.get(protocolInterface);
34.52 if (res != null) {
34.53 - return (Collection<XProtocol>)res;
34.54 + return res;
34.55 } else {
34.56 - return new LinkedList<XProtocol>();
34.57 + return new LinkedList<T>();
34.58 }
34.59 }
34.60
34.61 - void addProtocol(Class protocolInterface, XProtocol protocol) {
34.62 - Collection<XProtocol> protocols = getProtocols(protocolInterface);
34.63 + private <T> void addProtocol(Class<T> protocolInterface, T protocol) {
34.64 + Collection<T> protocols = getProtocols(protocolInterface);
34.65 protocols.add(protocol);
34.66 protocolsMap.put(protocolInterface, protocols);
34.67 }
34.68 @@ -1085,9 +1088,7 @@
34.69 }
34.70 /* FALLTROUGH */
34.71 case Frame.MAXIMIZED_BOTH:
34.72 - Iterator iter = getProtocols(XStateProtocol.class).iterator();
34.73 - while (iter.hasNext()) {
34.74 - XStateProtocol proto = (XStateProtocol)iter.next();
34.75 + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
34.76 if (proto.supportsState(state)) {
34.77 return true;
34.78 }
34.79 @@ -1105,10 +1106,8 @@
34.80
34.81
34.82 int getExtendedState(XWindowPeer window) {
34.83 - Iterator iter = getProtocols(XStateProtocol.class).iterator();
34.84 int state = 0;
34.85 - while (iter.hasNext()) {
34.86 - XStateProtocol proto = (XStateProtocol)iter.next();
34.87 + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
34.88 state |= proto.getState(window);
34.89 }
34.90 if (state != 0) {
34.91 @@ -1127,18 +1126,17 @@
34.92
34.93 /*
34.94 * Check if property change is a window state protocol message.
34.95 - * If it is - return the new state as Integer, otherwise return null
34.96 */
34.97 - Integer isStateChange(XDecoratedPeer window, XPropertyEvent e) {
34.98 + boolean isStateChange(XDecoratedPeer window, XPropertyEvent e) {
34.99 if (!window.isShowing()) {
34.100 stateLog.finer("Window is not showing");
34.101 - return null;
34.102 + return false;
34.103 }
34.104
34.105 int wm_state = window.getWMState();
34.106 if (wm_state == XlibWrapper.WithdrawnState) {
34.107 stateLog.finer("WithdrawnState");
34.108 - return null;
34.109 + return false;
34.110 } else {
34.111 stateLog.finer("Window WM_STATE is " + wm_state);
34.112 }
34.113 @@ -1147,26 +1145,26 @@
34.114 is_state_change = true;
34.115 }
34.116
34.117 - Iterator iter = getProtocols(XStateProtocol.class).iterator();
34.118 - while (iter.hasNext()) {
34.119 - XStateProtocol proto = (XStateProtocol)iter.next();
34.120 + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
34.121 is_state_change |= proto.isStateChange(e);
34.122 + stateLog.finest(proto + ": is state changed = " + is_state_change);
34.123 }
34.124 + return is_state_change;
34.125 + }
34.126 +
34.127 + /*
34.128 + * Returns current state (including extended) of a given window.
34.129 + */
34.130 + int getState(XDecoratedPeer window) {
34.131 int res = 0;
34.132 -
34.133 - if (is_state_change) {
34.134 - if (wm_state == XlibWrapper.IconicState) {
34.135 - res = Frame.ICONIFIED;
34.136 - } else {
34.137 - res = Frame.NORMAL;
34.138 - }
34.139 - res |= getExtendedState(window);
34.140 + final int wm_state = window.getWMState();
34.141 + if (wm_state == XlibWrapper.IconicState) {
34.142 + res = Frame.ICONIFIED;
34.143 + } else {
34.144 + res = Frame.NORMAL;
34.145 }
34.146 - if (is_state_change) {
34.147 - return Integer.valueOf(res);
34.148 - } else {
34.149 - return null;
34.150 - }
34.151 + res |= getExtendedState(window);
34.152 + return res;
34.153 }
34.154
34.155 /*****************************************************************************\
34.156 @@ -1180,9 +1178,7 @@
34.157 * in XLayerProtocol
34.158 */
34.159 void setLayer(XWindowPeer window, int layer) {
34.160 - Iterator iter = getProtocols(XLayerProtocol.class).iterator();
34.161 - while (iter.hasNext()) {
34.162 - XLayerProtocol proto = (XLayerProtocol)iter.next();
34.163 + for (XLayerProtocol proto : getProtocols(XLayerProtocol.class)) {
34.164 if (proto.supportsLayer(layer)) {
34.165 proto.setLayer(window, layer);
34.166 }
34.167 @@ -1191,9 +1187,7 @@
34.168 }
34.169
34.170 void setExtendedState(XWindowPeer window, int state) {
34.171 - Iterator iter = getProtocols(XStateProtocol.class).iterator();
34.172 - while (iter.hasNext()) {
34.173 - XStateProtocol proto = (XStateProtocol)iter.next();
34.174 + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
34.175 if (proto.supportsState(state)) {
34.176 proto.setState(window, state);
34.177 break;
34.178 @@ -1239,9 +1233,7 @@
34.179 void unshadeKludge(XDecoratedPeer window) {
34.180 assert(window.isShowing());
34.181
34.182 - Iterator iter = getProtocols(XStateProtocol.class).iterator();
34.183 - while (iter.hasNext()) {
34.184 - XStateProtocol proto = (XStateProtocol)iter.next();
34.185 + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
34.186 proto.unshadeKludge(window);
34.187 }
34.188 XToolkit.XSync();
35.1 --- a/src/solaris/classes/sun/awt/X11/XWindow.java Wed Mar 26 17:48:05 2008 -0700
35.2 +++ b/src/solaris/classes/sun/awt/X11/XWindow.java Thu Mar 27 12:09:50 2008 -0700
35.3 @@ -1,5 +1,5 @@
35.4 /*
35.5 - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
35.6 + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
35.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
35.8 *
35.9 * This code is free software; you can redistribute it and/or modify it
35.10 @@ -92,8 +92,16 @@
35.11 SurfaceData surfaceData;
35.12
35.13 XRepaintArea paintArea;
35.14 +
35.15 // fallback default font object
35.16 - final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
35.17 + private static Font defaultFont;
35.18 +
35.19 + static synchronized Font getDefaultFont() {
35.20 + if (null == defaultFont) {
35.21 + defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
35.22 + }
35.23 + return defaultFont;
35.24 + }
35.25
35.26 /*
35.27 * Keeps all buttons which were pressed at the time of the last mouse
35.28 @@ -333,7 +341,7 @@
35.29 }
35.30 Font font = afont;
35.31 if (font == null) {
35.32 - font = defaultFont;
35.33 + font = XWindow.getDefaultFont();
35.34 }
35.35 return new SunGraphics2D(surfData, fgColor, bgColor, font);
35.36 }
35.37 @@ -902,13 +910,11 @@
35.38
35.39 super.handleConfigureNotifyEvent(xev);
35.40 insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}",
35.41 - new Object[] {xev, isEventDisabled(xev)});
35.42 + new Object[] {xev.get_xconfigure(), isEventDisabled(xev)});
35.43 if (isEventDisabled(xev)) {
35.44 return;
35.45 }
35.46
35.47 - long eventWindow = xev.get_xany().get_window();
35.48 -
35.49 // if ( Check if it's a resize, a move, or a stacking order change )
35.50 // {
35.51 Rectangle bounds = getBounds();
35.52 @@ -982,7 +988,6 @@
35.53 // called directly from this package, unlike handleKeyRelease.
35.54 // un-final it if you need to override it in a subclass.
35.55 final void handleKeyPress(XKeyEvent ev) {
35.56 - int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
35.57 long keysym[] = new long[2];
35.58 char unicodeKey = 0;
35.59 keysym[0] = NoSymbol;
35.60 @@ -1066,7 +1071,6 @@
35.61 }
35.62 // un-private it if you need to call it from elsewhere
35.63 private void handleKeyRelease(XKeyEvent ev) {
35.64 - int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
35.65 long keysym[] = new long[2];
35.66 char unicodeKey = 0;
35.67 keysym[0] = NoSymbol;
36.1 --- a/src/solaris/classes/sun/awt/X11/XWindowPeer.java Wed Mar 26 17:48:05 2008 -0700
36.2 +++ b/src/solaris/classes/sun/awt/X11/XWindowPeer.java Thu Mar 27 12:09:50 2008 -0700
36.3 @@ -1,5 +1,5 @@
36.4 /*
36.5 - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
36.6 + * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
36.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
36.8 *
36.9 * This code is free software; you can redistribute it and/or modify it
36.10 @@ -112,9 +112,6 @@
36.11 PARENT_WINDOW, Long.valueOf(0)}));
36.12 }
36.13
36.14 - // fallback default font object
36.15 - static Font defaultFont;
36.16 -
36.17 /*
36.18 * This constant defines icon size recommended for using.
36.19 * Apparently, we should use XGetIconSizes which should
36.20 @@ -162,10 +159,7 @@
36.21
36.22 Font f = target.getFont();
36.23 if (f == null) {
36.24 - if (defaultFont == null) {
36.25 - defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
36.26 - }
36.27 - f = defaultFont;
36.28 + f = XWindow.getDefaultFont();
36.29 target.setFont(f);
36.30 // we should not call setFont because it will call a repaint
36.31 // which the peer may not be ready to do yet.
36.32 @@ -188,6 +182,9 @@
36.33
36.34 GraphicsConfiguration gc = getGraphicsConfiguration();
36.35 ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
36.36 +
36.37 + Rectangle bounds = (Rectangle)(params.get(BOUNDS));
36.38 + params.put(BOUNDS, constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height));
36.39 }
36.40
36.41 private void initWMProtocols() {
36.42 @@ -437,6 +434,56 @@
36.43 return ownerPeer;
36.44 }
36.45
36.46 + // This method is overriden at the XDecoratedPeer to handle
36.47 + // decorated windows a bit differently.
36.48 + Rectangle constrainBounds(int x, int y, int width, int height) {
36.49 + // We don't restrict the setBounds() operation if the code is trusted.
36.50 + if (!hasWarningWindow()) {
36.51 + return new Rectangle(x, y, width, height);
36.52 + }
36.53 +
36.54 + // The window bounds should be within the visible part of the screen
36.55 + int newX = x;
36.56 + int newY = y;
36.57 + int newW = width;
36.58 + int newH = height;
36.59 +
36.60 + // Now check each point is within the visible part of the screen
36.61 + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
36.62 + Rectangle sB = gc.getBounds();
36.63 + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
36.64 +
36.65 + int screenX = sB.x + sIn.left;
36.66 + int screenY = sB.y + sIn.top;
36.67 + int screenW = sB.width - sIn.left - sIn.right;
36.68 + int screenH = sB.height - sIn.top - sIn.bottom;
36.69 +
36.70 +
36.71 + // First make sure the size is withing the visible part of the screen
36.72 + if (newW > screenW) {
36.73 + newW = screenW;
36.74 + }
36.75 +
36.76 + if (newH > screenH) {
36.77 + newH = screenH;
36.78 + }
36.79 +
36.80 + // Tweak the location if needed
36.81 + if (newX < screenX) {
36.82 + newX = screenX;
36.83 + } else if (newX + newW > screenX + screenW) {
36.84 + newX = screenX + screenW - newW;
36.85 + }
36.86 +
36.87 + if (newY < screenY) {
36.88 + newY = screenY;
36.89 + } else if (newY + newH > screenY + screenH) {
36.90 + newY = screenY + screenH - newH;
36.91 + }
36.92 +
36.93 + return new Rectangle(newX, newY, newW, newH);
36.94 + }
36.95 +
36.96 //Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges
36.97 //the window but fails to revalidate, Sol-CDE
36.98 //This bug is regression for
36.99 @@ -445,10 +492,14 @@
36.100 //Note that this function is overriden in XDecoratedPeer so event
36.101 //posting is not changing for decorated peers
36.102 public void setBounds(int x, int y, int width, int height, int op) {
36.103 + Rectangle newBounds = constrainBounds(x, y, width, height);
36.104 +
36.105 XToolkit.awtLock();
36.106 try {
36.107 Rectangle oldBounds = getBounds();
36.108 - super.setBounds(x, y, width, height, op);
36.109 +
36.110 + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
36.111 +
36.112 Rectangle bounds = getBounds();
36.113
36.114 XSizeHints hints = getHints();
36.115 @@ -1035,7 +1086,7 @@
36.116 return !(target instanceof Frame || target instanceof Dialog);
36.117 }
36.118 boolean hasWarningWindow() {
36.119 - return warningWindow != null;
36.120 + return ((Window)target).getWarningString() != null;
36.121 }
36.122
36.123 // The height of menu bar window
37.1 --- a/src/solaris/classes/sun/awt/motif/MDialogPeer.java Wed Mar 26 17:48:05 2008 -0700
37.2 +++ b/src/solaris/classes/sun/awt/motif/MDialogPeer.java Thu Mar 27 12:09:50 2008 -0700
37.3 @@ -102,4 +102,9 @@
37.4 public void blockWindows(java.util.List<Window> toBlock) {
37.5 // do nothing
37.6 }
37.7 +
37.8 + @Override
37.9 + final boolean isTargetUndecorated() {
37.10 + return ((Dialog)target).isUndecorated();
37.11 + }
37.12 }
38.1 --- a/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java Wed Mar 26 17:48:05 2008 -0700
38.2 +++ b/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java Thu Mar 27 12:09:50 2008 -0700
38.3 @@ -204,4 +204,10 @@
38.4 }
38.5
38.6 public native Rectangle getBoundsPrivate();
38.7 +
38.8 + @Override
38.9 + Rectangle constrainBounds(int x, int y, int width, int height) {
38.10 + // We don't constrain the bounds of the EmbeddedFrames
38.11 + return new Rectangle(x, y, width, height);
38.12 + }
38.13 }
39.1 --- a/src/solaris/classes/sun/awt/motif/MFramePeer.java Wed Mar 26 17:48:05 2008 -0700
39.2 +++ b/src/solaris/classes/sun/awt/motif/MFramePeer.java Thu Mar 27 12:09:50 2008 -0700
39.3 @@ -503,4 +503,9 @@
39.4 public Rectangle getBoundsPrivate() {
39.5 return getBounds();
39.6 }
39.7 +
39.8 + @Override
39.9 + final boolean isTargetUndecorated() {
39.10 + return ((Frame)target).isUndecorated();
39.11 + }
39.12 }
40.1 --- a/src/solaris/classes/sun/awt/motif/MWindowPeer.java Wed Mar 26 17:48:05 2008 -0700
40.2 +++ b/src/solaris/classes/sun/awt/motif/MWindowPeer.java Thu Mar 27 12:09:50 2008 -0700
40.3 @@ -113,6 +113,12 @@
40.4 insets.right = getInset("awt.frame.rightInset", -1);
40.5 }
40.6
40.7 + Rectangle bounds = target.getBounds();
40.8 + sysX = bounds.x;
40.9 + sysY = bounds.y;
40.10 + sysW = bounds.width;
40.11 + sysH = bounds.height;
40.12 +
40.13 super.init(target);
40.14 InputMethodManager imm = InputMethodManager.getInstance();
40.15 String menuString = imm.getTriggerMenuString();
40.16 @@ -150,6 +156,7 @@
40.17
40.18 GraphicsConfiguration gc = getGraphicsConfiguration();
40.19 ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
40.20 +
40.21 }
40.22
40.23 /* Support for multiple icons is not implemented in MAWT */
40.24 @@ -246,6 +253,8 @@
40.25 // NOTE: This method may be called by privileged threads.
40.26 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
40.27 public void handleResize(int width, int height) {
40.28 + sysW = width;
40.29 + sysH = height;
40.30
40.31 // REMIND: Is this secure? Can client code subclass input method?
40.32 if (!tcList.isEmpty() &&
40.33 @@ -268,6 +277,8 @@
40.34 }
40.35
40.36 public void handleMoved(int x, int y) {
40.37 + sysX = x;
40.38 + sysY = y;
40.39 postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
40.40 }
40.41
40.42 @@ -505,4 +516,87 @@
40.43 }
40.44 return false;
40.45 }
40.46 +
40.47 + private final boolean hasWarningWindow() {
40.48 + return ((Window)target).getWarningString() != null;
40.49 + }
40.50 +
40.51 + // This method is overriden at Dialog and Frame peers.
40.52 + boolean isTargetUndecorated() {
40.53 + return true;
40.54 + }
40.55 +
40.56 + private volatile int sysX = 0;
40.57 + private volatile int sysY = 0;
40.58 + private volatile int sysW = 0;
40.59 + private volatile int sysH = 0;
40.60 +
40.61 + Rectangle constrainBounds(int x, int y, int width, int height) {
40.62 + // We don't restrict the setBounds() operation if the code is trusted.
40.63 + if (!hasWarningWindow()) {
40.64 + return new Rectangle(x, y, width, height);
40.65 + }
40.66 +
40.67 + int newX = x;
40.68 + int newY = y;
40.69 + int newW = width;
40.70 + int newH = height;
40.71 +
40.72 + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
40.73 + Rectangle sB = gc.getBounds();
40.74 + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
40.75 +
40.76 + int screenW = sB.width - sIn.left - sIn.right;
40.77 + int screenH = sB.height - sIn.top - sIn.bottom;
40.78 +
40.79 + // If it's undecorated or is not currently visible,
40.80 + // then check each point is within the visible part of the screen
40.81 + if (!target.isVisible() || isTargetUndecorated()) {
40.82 + int screenX = sB.x + sIn.left;
40.83 + int screenY = sB.y + sIn.top;
40.84 +
40.85 + // First make sure the size is withing the visible part of the screen
40.86 + if (newW > screenW) {
40.87 + newW = screenW;
40.88 + }
40.89 +
40.90 + if (newH > screenH) {
40.91 + newH = screenH;
40.92 + }
40.93 +
40.94 + // Tweak the location if needed
40.95 + if (newX < screenX) {
40.96 + newX = screenX;
40.97 + } else if (newX + newW > screenX + screenW) {
40.98 + newX = screenX + screenW - newW;
40.99 + }
40.100 +
40.101 + if (newY < screenY) {
40.102 + newY = screenY;
40.103 + } else if (newY + newH > screenY + screenH) {
40.104 + newY = screenY + screenH - newH;
40.105 + }
40.106 + } else {
40.107 + int maxW = Math.max(screenW, sysW);
40.108 + int maxH = Math.max(screenH, sysH);
40.109 +
40.110 + // Make sure the size is withing the visible part of the screen
40.111 + // OR is less that the current size of the window.
40.112 + if (newW > maxW) {
40.113 + newW = maxW;
40.114 + }
40.115 +
40.116 + if (newH > maxH) {
40.117 + newH = maxH;
40.118 + }
40.119 + }
40.120 +
40.121 + return new Rectangle(newX, newY, newW, newH);
40.122 + }
40.123 +
40.124 + public void setBounds(int x, int y, int width, int height, int op) {
40.125 + Rectangle newBounds = constrainBounds(x, y, width, height);
40.126 + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
40.127 + }
40.128 +
40.129 }
41.1 --- a/src/windows/classes/sun/awt/windows/WDialogPeer.java Wed Mar 26 17:48:05 2008 -0700
41.2 +++ b/src/windows/classes/sun/awt/windows/WDialogPeer.java Thu Mar 27 12:09:50 2008 -0700
41.3 @@ -108,11 +108,18 @@
41.4 }
41.5 }
41.6
41.7 + @Override
41.8 + boolean isTargetUndecorated() {
41.9 + return ((Dialog)target).isUndecorated();
41.10 + }
41.11 +
41.12 public void reshape(int x, int y, int width, int height) {
41.13 + Rectangle newBounds = constrainBounds(x, y, width, height);
41.14 +
41.15 if (((Dialog)target).isUndecorated()) {
41.16 - super.reshape(x,y,width,height);
41.17 + super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
41.18 } else {
41.19 - reshapeFrame(x,y,width,height);
41.20 + reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
41.21 }
41.22 }
41.23
42.1 --- a/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java Wed Mar 26 17:48:05 2008 -0700
42.2 +++ b/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java Thu Mar 27 12:09:50 2008 -0700
42.3 @@ -65,4 +65,10 @@
42.4 public native Rectangle getBoundsPrivate();
42.5
42.6 public native void synthesizeWmActivate(boolean doActivate);
42.7 +
42.8 + @Override
42.9 + Rectangle constrainBounds(int x, int y, int width, int height) {
42.10 + // We don't constrain the bounds of the EmbeddedFrames
42.11 + return new Rectangle(x, y, width, height);
42.12 + }
42.13 }
43.1 --- a/src/windows/classes/sun/awt/windows/WFramePeer.java Wed Mar 26 17:48:05 2008 -0700
43.2 +++ b/src/windows/classes/sun/awt/windows/WFramePeer.java Thu Mar 27 12:09:50 2008 -0700
43.3 @@ -64,11 +64,18 @@
43.4 }
43.5 }
43.6
43.7 + @Override
43.8 + boolean isTargetUndecorated() {
43.9 + return ((Frame)target).isUndecorated();
43.10 + }
43.11 +
43.12 public void reshape(int x, int y, int width, int height) {
43.13 + Rectangle newBounds = constrainBounds(x, y, width, height);
43.14 +
43.15 if (((Frame)target).isUndecorated()) {
43.16 - super.reshape(x,y,width,height);
43.17 + super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
43.18 } else {
43.19 - reshapeFrame(x,y,width,height);
43.20 + reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
43.21 }
43.22 }
43.23
44.1 --- a/src/windows/classes/sun/awt/windows/WObjectPeer.java Wed Mar 26 17:48:05 2008 -0700
44.2 +++ b/src/windows/classes/sun/awt/windows/WObjectPeer.java Thu Mar 27 12:09:50 2008 -0700
44.3 @@ -1,5 +1,5 @@
44.4 /*
44.5 - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
44.6 + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
44.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44.8 *
44.9 * This code is free software; you can redistribute it and/or modify it
44.10 @@ -30,8 +30,12 @@
44.11 initIDs();
44.12 }
44.13
44.14 - long pData; // The Windows handle for the native widget.
44.15 - Object target; // The associated AWT object.
44.16 + // The Windows handle for the native widget.
44.17 + long pData;
44.18 + // if the native peer has been destroyed
44.19 + boolean destroyed = false;
44.20 + // The associated AWT object.
44.21 + Object target;
44.22
44.23 private volatile boolean disposed;
44.24
45.1 --- a/src/windows/classes/sun/awt/windows/WWindowPeer.java Wed Mar 26 17:48:05 2008 -0700
45.2 +++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java Thu Mar 27 12:09:50 2008 -0700
45.3 @@ -434,6 +434,97 @@
45.4 private native void nativeGrab();
45.5 private native void nativeUngrab();
45.6
45.7 + private final boolean hasWarningWindow() {
45.8 + return ((Window)target).getWarningString() != null;
45.9 + }
45.10 +
45.11 + boolean isTargetUndecorated() {
45.12 + return true;
45.13 + }
45.14 +
45.15 + // These are the peer bounds. They get updated at:
45.16 + // 1. the WWindowPeer.setBounds() method.
45.17 + // 2. the native code (on WM_SIZE/WM_MOVE)
45.18 + private volatile int sysX = 0;
45.19 + private volatile int sysY = 0;
45.20 + private volatile int sysW = 0;
45.21 + private volatile int sysH = 0;
45.22 +
45.23 + Rectangle constrainBounds(int x, int y, int width, int height) {
45.24 + // We don't restrict the setBounds() operation if the code is trusted.
45.25 + if (!hasWarningWindow()) {
45.26 + return new Rectangle(x, y, width, height);
45.27 + }
45.28 +
45.29 + int newX = x;
45.30 + int newY = y;
45.31 + int newW = width;
45.32 + int newH = height;
45.33 +
45.34 + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
45.35 + Rectangle sB = gc.getBounds();
45.36 + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
45.37 +
45.38 + int screenW = sB.width - sIn.left - sIn.right;
45.39 + int screenH = sB.height - sIn.top - sIn.bottom;
45.40 +
45.41 + // If it's undecorated or is not currently visible
45.42 + if (!((Window)target).isVisible() || isTargetUndecorated()) {
45.43 + // Now check each point is within the visible part of the screen
45.44 + int screenX = sB.x + sIn.left;
45.45 + int screenY = sB.y + sIn.top;
45.46 +
45.47 + // First make sure the size is withing the visible part of the screen
45.48 + if (newW > screenW) {
45.49 + newW = screenW;
45.50 + }
45.51 +
45.52 + if (newH > screenH) {
45.53 + newH = screenH;
45.54 + }
45.55 +
45.56 + // Tweak the location if needed
45.57 + if (newX < screenX) {
45.58 + newX = screenX;
45.59 + } else if (newX + newW > screenX + screenW) {
45.60 + newX = screenX + screenW - newW;
45.61 + }
45.62 +
45.63 + if (newY < screenY) {
45.64 + newY = screenY;
45.65 + } else if (newY + newH > screenY + screenH) {
45.66 + newY = screenY + screenH - newH;
45.67 + }
45.68 + } else {
45.69 + int maxW = Math.max(screenW, sysW);
45.70 + int maxH = Math.max(screenH, sysH);
45.71 +
45.72 + // Make sure the size is withing the visible part of the screen
45.73 + // OR less that the current size of the window.
45.74 + if (newW > maxW) {
45.75 + newW = maxW;
45.76 + }
45.77 +
45.78 + if (newH > maxH) {
45.79 + newH = maxH;
45.80 + }
45.81 + }
45.82 +
45.83 + return new Rectangle(newX, newY, newW, newH);
45.84 + }
45.85 +
45.86 + @Override
45.87 + public void setBounds(int x, int y, int width, int height, int op) {
45.88 + Rectangle newBounds = constrainBounds(x, y, width, height);
45.89 +
45.90 + sysX = newBounds.x;
45.91 + sysY = newBounds.y;
45.92 + sysW = newBounds.width;
45.93 + sysH = newBounds.height;
45.94 +
45.95 + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
45.96 + }
45.97 +
45.98 /*
45.99 * The method maps the list of the active windows to the window's AppContext,
45.100 * then the method registers ActiveWindowListener, GuiDisposedListener listeners;
46.1 --- a/src/windows/native/sun/windows/awt.h Wed Mar 26 17:48:05 2008 -0700
46.2 +++ b/src/windows/native/sun/windows/awt.h Thu Mar 27 12:09:50 2008 -0700
46.3 @@ -1,5 +1,5 @@
46.4 /*
46.5 - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
46.6 + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
46.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
46.8 *
46.9 * This code is free software; you can redistribute it and/or modify it
46.10 @@ -47,7 +47,7 @@
46.11 JNI_CHECK_NULL_GOTO(peer, "peer", where); \
46.12 pData = JNI_GET_PDATA(peer); \
46.13 if (pData == NULL) { \
46.14 - JNU_ThrowNullPointerException(env, "null pData"); \
46.15 + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
46.16 goto where; \
46.17 } \
46.18 }
46.19 @@ -63,7 +63,7 @@
46.20 JNI_CHECK_NULL_RETURN(peer, "peer"); \
46.21 pData = JNI_GET_PDATA(peer); \
46.22 if (pData == NULL) { \
46.23 - JNU_ThrowNullPointerException(env, "null pData"); \
46.24 + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
46.25 return; \
46.26 } \
46.27 }
46.28 @@ -96,7 +96,7 @@
46.29 JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \
46.30 pData = JNI_GET_PDATA(peer); \
46.31 if (pData == NULL) { \
46.32 - JNU_ThrowNullPointerException(env, "null pData"); \
46.33 + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
46.34 return 0; \
46.35 } \
46.36 }
46.37 @@ -105,16 +105,27 @@
46.38 JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \
46.39 pData = JNI_GET_PDATA(peer); \
46.40 if (pData == NULL) { \
46.41 - JNU_ThrowNullPointerException(env, "null pData"); \
46.42 + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
46.43 return val; \
46.44 } \
46.45 }
46.46
46.47 +#define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) { \
46.48 + jboolean destroyed = JNI_GET_DESTROYED(peer); \
46.49 + if (destroyed != JNI_TRUE) { \
46.50 + JNU_ThrowNullPointerException(env, "null pData"); \
46.51 + } \
46.52 +}
46.53 +
46.54 #define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID)
46.55 +#define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID)
46.56
46.57 #define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \
46.58 - AwtObject::pDataID, \
46.59 - (jlong)data)
46.60 + AwtObject::pDataID, \
46.61 + (jlong)data)
46.62 +#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer, \
46.63 + AwtObject::destroyedID, \
46.64 + JNI_TRUE)
46.65 /* /NEW JNI */
46.66
46.67 /*
47.1 --- a/src/windows/native/sun/windows/awt_Component.cpp Wed Mar 26 17:48:05 2008 -0700
47.2 +++ b/src/windows/native/sun/windows/awt_Component.cpp Thu Mar 27 12:09:50 2008 -0700
47.3 @@ -1,5 +1,5 @@
47.4 /*
47.5 - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
47.6 + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
47.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
47.8 *
47.9 * This code is free software; you can redistribute it and/or modify it
47.10 @@ -226,6 +226,8 @@
47.11 CriticalSection windowMoveLock;
47.12 BOOL windowMoveLockHeld = FALSE;
47.13
47.14 +int AwtComponent::sm_wheelRotationAmount = 0;
47.15 +
47.16 /************************************************************************
47.17 * AwtComponent methods
47.18 */
47.19 @@ -2074,6 +2076,8 @@
47.20 sm_realFocusOpposite = NULL;
47.21 }
47.22
47.23 + sm_wheelRotationAmount = 0;
47.24 +
47.25 SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus);
47.26
47.27 return mrDoDefault;
47.28 @@ -2105,6 +2109,7 @@
47.29 }
47.30
47.31 sm_focusOwner = NULL;
47.32 + sm_wheelRotationAmount = 0;
47.33
47.34 SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus);
47.35 return mrDoDefault;
47.36 @@ -2190,8 +2195,11 @@
47.37 DWORD fgProcessID;
47.38 ::GetWindowThreadProcessId(fgWindow, &fgProcessID);
47.39
47.40 - if (fgProcessID != ::GetCurrentProcessId()) {
47.41 - // fix for 6458497. we shouldn't request focus if it is out of our application.
47.42 + if (fgProcessID != ::GetCurrentProcessId()
47.43 + && !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID))
47.44 + {
47.45 + // fix for 6458497. we shouldn't request focus if it is out of both
47.46 + // our and embedder process.
47.47 return FALSE;
47.48 }
47.49 }
47.50 @@ -2619,9 +2627,13 @@
47.51 BOOL result;
47.52 UINT platformLines;
47.53
47.54 + sm_wheelRotationAmount += wheelRotation;
47.55 +
47.56 // AWT interprets wheel rotation differently than win32, so we need to
47.57 // decode wheel amount.
47.58 - jint newWheelRotation = wheelRotation / (-1 * WHEEL_DELTA);
47.59 + jint roundedWheelRotation = sm_wheelRotationAmount / (-1 * WHEEL_DELTA);
47.60 + jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA);
47.61 +
47.62 MSG msg;
47.63
47.64 if (IS_WIN95 && !IS_WIN98) {
47.65 @@ -2654,7 +2666,9 @@
47.66
47.67 SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(),
47.68 eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType,
47.69 - scrollLines, newWheelRotation, &msg);
47.70 + scrollLines, roundedWheelRotation, preciseWheelRotation, &msg);
47.71 +
47.72 + sm_wheelRotationAmount %= WHEEL_DELTA;
47.73 return mrConsume;
47.74 }
47.75
47.76 @@ -4986,8 +5000,8 @@
47.77 AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
47.78 jint modifiers, jint clickCount,
47.79 jboolean popupTrigger, jint scrollType,
47.80 - jint scrollAmount, jint wheelRotation,
47.81 - MSG *pMsg)
47.82 + jint scrollAmount, jint roundedWheelRotation,
47.83 + jdouble preciseWheelRotation, MSG *pMsg)
47.84 {
47.85 /* Code based not so loosely on AwtComponent::SendMouseEvent */
47.86 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
47.87 @@ -5015,7 +5029,7 @@
47.88 if (mouseWheelEventConst == NULL) {
47.89 mouseWheelEventConst =
47.90 env->GetMethodID(mouseWheelEventCls, "<init>",
47.91 - "(Ljava/awt/Component;IJIIIIZIII)V");
47.92 + "(Ljava/awt/Component;IJIIIIIIZIIID)V");
47.93 DASSERT(mouseWheelEventConst);
47.94 }
47.95 if (env->EnsureLocalCapacity(2) < 0) {
47.96 @@ -5023,14 +5037,16 @@
47.97 }
47.98 jobject target = GetTarget(env);
47.99 DTRACE_PRINTLN("creating MWE in JNI");
47.100 +
47.101 jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls,
47.102 mouseWheelEventConst,
47.103 target,
47.104 id, when, modifiers,
47.105 x+insets.left, y+insets.top,
47.106 + 0, 0,
47.107 clickCount, popupTrigger,
47.108 scrollType, scrollAmount,
47.109 - wheelRotation);
47.110 + roundedWheelRotation, preciseWheelRotation);
47.111 if (safe_ExceptionOccurred(env)) {
47.112 env->ExceptionDescribe();
47.113 env->ExceptionClear();
47.114 @@ -5400,6 +5416,7 @@
47.115 if (m_peerObject) {
47.116 env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);
47.117 JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
47.118 + JNI_SET_DESTROYED(m_peerObject);
47.119 env->DeleteGlobalRef(m_peerObject);
47.120 m_peerObject = NULL;
47.121 }
47.122 @@ -5408,7 +5425,13 @@
47.123 void AwtComponent::Enable(BOOL bEnable)
47.124 {
47.125 sm_suppressFocusAndActivation = TRUE;
47.126 +
47.127 + if (bEnable && IsTopLevel()) {
47.128 + // we should not enable blocked toplevels
47.129 + bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
47.130 + }
47.131 ::EnableWindow(GetHWnd(), bEnable);
47.132 +
47.133 sm_suppressFocusAndActivation = FALSE;
47.134 CriticalSection::Lock l(GetLock());
47.135 VerifyState();
48.1 --- a/src/windows/native/sun/windows/awt_Component.h Wed Mar 26 17:48:05 2008 -0700
48.2 +++ b/src/windows/native/sun/windows/awt_Component.h Thu Mar 27 12:09:50 2008 -0700
48.3 @@ -392,7 +392,7 @@
48.4 jint modifiers, jint clickCount,
48.5 jboolean popupTrigger, jint scrollType,
48.6 jint scrollAmount, jint wheelRotation,
48.7 - MSG *msg = NULL);
48.8 + jdouble preciseWheelRotation, MSG *msg = NULL);
48.9
48.10 /*
48.11 * Allocate and initialize a new java.awt.event.FocusEvent, and
48.12 @@ -785,7 +785,9 @@
48.13 int windowMoveLockPosCX;
48.14 int windowMoveLockPosCY;
48.15
48.16 -private:
48.17 + // 6524352: support finer-resolution
48.18 + static int sm_wheelRotationAmount;
48.19 +
48.20 /*
48.21 * The association list of children's IDs and corresponding components.
48.22 * Some components like Choice or List are required their sizes while
49.1 --- a/src/windows/native/sun/windows/awt_Dialog.cpp Wed Mar 26 17:48:05 2008 -0700
49.2 +++ b/src/windows/native/sun/windows/awt_Dialog.cpp Thu Mar 27 12:09:50 2008 -0700
49.3 @@ -273,6 +273,10 @@
49.4 {
49.5 HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
49.6 HWND topMostBlocker = blocker;
49.7 + HWND prevForegroundWindow = ::GetForegroundWindow();
49.8 + if (::IsWindow(blocker)) {
49.9 + ::BringWindowToTop(hWnd);
49.10 + }
49.11 while (::IsWindow(blocker)) {
49.12 topMostBlocker = blocker;
49.13 ::BringWindowToTop(blocker);
49.14 @@ -282,7 +286,7 @@
49.15 // no beep/flash if the mouse was clicked in the taskbar menu
49.16 // or the dialog is currently inactive
49.17 if ((::WindowFromPoint(mhs->pt) == hWnd) &&
49.18 - (::GetForegroundWindow() == topMostBlocker))
49.19 + (prevForegroundWindow == topMostBlocker))
49.20 {
49.21 ::MessageBeep(MB_OK);
49.22 // some heuristics: 3 times x 64 milliseconds
49.23 @@ -292,6 +296,7 @@
49.24 ::BringWindowToTop(topMostBlocker);
49.25 ::SetForegroundWindow(topMostBlocker);
49.26 }
49.27 + return 1;
49.28 }
49.29 }
49.30 }
50.1 --- a/src/windows/native/sun/windows/awt_Frame.cpp Wed Mar 26 17:48:05 2008 -0700
50.2 +++ b/src/windows/native/sun/windows/awt_Frame.cpp Thu Mar 27 12:09:50 2008 -0700
50.3 @@ -1,5 +1,5 @@
50.4 /*
50.5 - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
50.6 + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
50.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
50.8 *
50.9 * This code is free software; you can redistribute it and/or modify it
50.10 @@ -221,8 +221,7 @@
50.11
50.12 // Update target's dimensions to reflect this embedded window.
50.13 ::GetClientRect(frame->m_hwnd, &rect);
50.14 - ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect,
50.15 - 2);
50.16 + ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2);
50.17
50.18 env->SetIntField(target, AwtComponent::xID, rect.left);
50.19 env->SetIntField(target, AwtComponent::yID, rect.top);
50.20 @@ -231,6 +230,7 @@
50.21 env->SetIntField(target, AwtComponent::heightID,
50.22 rect.bottom-rect.top);
50.23 frame->InitPeerGraphicsConfig(env, self);
50.24 + AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent);
50.25 } else {
50.26 jint state = env->GetIntField(target, AwtFrame::stateID);
50.27 DWORD exStyle;
50.28 @@ -408,8 +408,9 @@
50.29 * message. This breaks Java focus. To workaround the problem we
50.30 * set the toplevel being shown foreground programmatically.
50.31 * The fix is localized to non-foreground process case only.
50.32 + * (See also: 6599270)
50.33 */
50.34 - if (show == TRUE && status == 0) {
50.35 + if (!IsEmbeddedFrame() && show == TRUE && status == 0) {
50.36 HWND fgHWnd = ::GetForegroundWindow();
50.37 if (fgHWnd != NULL) {
50.38 DWORD fgProcessID;
50.39 @@ -495,7 +496,7 @@
50.40
50.41 ::SetWindowPos(GetHWnd(), NULL, r.left, r.top,
50.42 r.right-r.left, r.bottom-r.top,
50.43 - SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER |
50.44 + SWP_NOACTIVATE | SWP_NOZORDER |
50.45 SWP_NOCOPYBITS | SWP_DEFERERASE);
50.46 }
50.47 return mrConsume;
51.1 --- a/src/windows/native/sun/windows/awt_Object.cpp Wed Mar 26 17:48:05 2008 -0700
51.2 +++ b/src/windows/native/sun/windows/awt_Object.cpp Thu Mar 27 12:09:50 2008 -0700
51.3 @@ -1,5 +1,5 @@
51.4 /*
51.5 - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
51.6 + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
51.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
51.8 *
51.9 * This code is free software; you can redistribute it and/or modify it
51.10 @@ -39,6 +39,7 @@
51.11 */
51.12
51.13 jfieldID AwtObject::pDataID;
51.14 +jfieldID AwtObject::destroyedID;
51.15 jfieldID AwtObject::targetID;
51.16 jclass AwtObject::wObjectPeerClass;
51.17 jmethodID AwtObject::getPeerForTargetMID;
51.18 @@ -223,6 +224,7 @@
51.19
51.20 AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls);
51.21 AwtObject::pDataID = env->GetFieldID(cls, "pData", "J");
51.22 + AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z");
51.23 AwtObject::targetID = env->GetFieldID(cls, "target",
51.24 "Ljava/lang/Object;");
51.25
51.26 @@ -233,6 +235,7 @@
51.27 AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;");
51.28
51.29 DASSERT(AwtObject::pDataID != NULL);
51.30 + DASSERT(AwtObject::destroyedID != NULL);
51.31 DASSERT(AwtObject::targetID != NULL);
51.32 DASSERT(AwtObject::getPeerForTargetMID != NULL);
51.33 DASSERT(AwtObject::createErrorID != NULL);
52.1 --- a/src/windows/native/sun/windows/awt_Object.h Wed Mar 26 17:48:05 2008 -0700
52.2 +++ b/src/windows/native/sun/windows/awt_Object.h Thu Mar 27 12:09:50 2008 -0700
52.3 @@ -1,5 +1,5 @@
52.4 /*
52.5 - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
52.6 + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
52.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
52.8 *
52.9 * This code is free software; you can redistribute it and/or modify it
52.10 @@ -51,6 +51,7 @@
52.11
52.12 /* sun.awt.windows.WObjectPeer field and method ids */
52.13 static jfieldID pDataID;
52.14 + static jfieldID destroyedID;
52.15 static jfieldID targetID;
52.16
52.17 static jmethodID getPeerForTargetMID;
53.1 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp Wed Mar 26 17:48:05 2008 -0700
53.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp Thu Mar 27 12:09:50 2008 -0700
53.3 @@ -1,5 +1,5 @@
53.4 /*
53.5 - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
53.6 + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
53.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
53.8 *
53.9 * This code is free software; you can redistribute it and/or modify it
53.10 @@ -354,6 +354,7 @@
53.11 m_dllHandle = NULL;
53.12
53.13 m_displayChanged = FALSE;
53.14 + m_embedderProcessID = 0;
53.15
53.16 // XXX: keyboard mapping should really be moved out of AwtComponent
53.17 AwtComponent::InitDynamicKeyMapTable();
53.18 @@ -1442,49 +1443,17 @@
53.19 }
53.20 }
53.21
53.22 -/*
53.23 - * Returns a reference to the class java.awt.Component.
53.24 - */
53.25 -jclass
53.26 -getComponentClass(JNIEnv *env)
53.27 +// for now we support only one embedder, but should be ready for future
53.28 +void AwtToolkit::RegisterEmbedderProcessId(HWND embedder)
53.29 {
53.30 - static jclass componentCls = NULL;
53.31 + if (m_embedderProcessID) {
53.32 + // we already set embedder process and do not expect
53.33 + // two different processes to embed the same AwtToolkit
53.34 + return;
53.35 + }
53.36
53.37 - // get global reference of java/awt/Component class (run only once)
53.38 - if (componentCls == NULL) {
53.39 - jclass componentClsLocal = env->FindClass("java/awt/Component");
53.40 - DASSERT(componentClsLocal != NULL);
53.41 - if (componentClsLocal == NULL) {
53.42 - /* exception already thrown */
53.43 - return NULL;
53.44 - }
53.45 - componentCls = (jclass)env->NewGlobalRef(componentClsLocal);
53.46 - env->DeleteLocalRef(componentClsLocal);
53.47 - }
53.48 - return componentCls;
53.49 -}
53.50 -
53.51 -
53.52 -/*
53.53 - * Returns a reference to the class java.awt.MenuComponent.
53.54 - */
53.55 -jclass
53.56 -getMenuComponentClass(JNIEnv *env)
53.57 -{
53.58 - static jclass menuComponentCls = NULL;
53.59 -
53.60 - // get global reference of java/awt/MenuComponent class (run only once)
53.61 - if (menuComponentCls == NULL) {
53.62 - jclass menuComponentClsLocal = env->FindClass("java/awt/MenuComponent");
53.63 - DASSERT(menuComponentClsLocal != NULL);
53.64 - if (menuComponentClsLocal == NULL) {
53.65 - /* exception already thrown */
53.66 - return NULL;
53.67 - }
53.68 - menuComponentCls = (jclass)env->NewGlobalRef(menuComponentClsLocal);
53.69 - env->DeleteLocalRef(menuComponentClsLocal);
53.70 - }
53.71 - return menuComponentCls;
53.72 + embedder = ::GetAncestor(embedder, GA_ROOT);
53.73 + ::GetWindowThreadProcessId(embedder, &m_embedderProcessID);
53.74 }
53.75
53.76 JNIEnv* AwtToolkit::m_env;
54.1 --- a/src/windows/native/sun/windows/awt_Toolkit.h Wed Mar 26 17:48:05 2008 -0700
54.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.h Thu Mar 27 12:09:50 2008 -0700
54.3 @@ -1,5 +1,5 @@
54.4 /*
54.5 - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
54.6 + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
54.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
54.8 *
54.9 * This code is free software; you can redistribute it and/or modify it
54.10 @@ -426,10 +426,17 @@
54.11 */
54.12 private:
54.13 BOOL m_displayChanged; /* Tracks displayChanged events */
54.14 + // 0 means we are not embedded.
54.15 + DWORD m_embedderProcessID;
54.16
54.17 public:
54.18 BOOL HasDisplayChanged() { return m_displayChanged; }
54.19 void ResetDisplayChanged() { m_displayChanged = FALSE; }
54.20 + void RegisterEmbedderProcessId(HWND);
54.21 + BOOL IsEmbedderProcessId(const DWORD processID) const
54.22 + {
54.23 + return m_embedderProcessID && (processID == m_embedderProcessID);
54.24 + }
54.25
54.26 private:
54.27 static JNIEnv *m_env;
55.1 --- a/src/windows/native/sun/windows/awt_Window.cpp Wed Mar 26 17:48:05 2008 -0700
55.2 +++ b/src/windows/native/sun/windows/awt_Window.cpp Thu Mar 27 12:09:50 2008 -0700
55.3 @@ -125,6 +125,11 @@
55.4 jclass AwtWindow::wwindowPeerCls;
55.5 jmethodID AwtWindow::getActiveWindowsMID;
55.6
55.7 +jfieldID AwtWindow::sysXID;
55.8 +jfieldID AwtWindow::sysYID;
55.9 +jfieldID AwtWindow::sysWID;
55.10 +jfieldID AwtWindow::sysHID;
55.11 +
55.12 int AwtWindow::ms_instanceCounter = 0;
55.13 HHOOK AwtWindow::ms_hCBTFilter;
55.14 AwtWindow * AwtWindow::m_grabbedWindow = NULL;
55.15 @@ -180,7 +185,6 @@
55.16 }
55.17
55.18 ::RemoveProp(GetHWnd(), ModalBlockerProp);
55.19 - ::RemoveProp(GetHWnd(), ModalSaveWSEXProp);
55.20
55.21 if (m_grabbedWindow == this) {
55.22 Ungrab();
55.23 @@ -330,8 +334,11 @@
55.24 if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
55.25 AwtComponent *comp = AwtComponent::GetComponent((HWND)wParam);
55.26
55.27 - if (comp != NULL && comp->IsTopLevel() && !((AwtWindow*)comp)->IsFocusableWindow()) {
55.28 - return 1; // Don't change focus/activation.
55.29 + if (comp != NULL && comp->IsTopLevel()) {
55.30 + AwtWindow* win = (AwtWindow*)comp;
55.31 + if (!win->IsFocusableWindow() || win->m_filterFocusAndActivation) {
55.32 + return 1; // Don't change focus/activation.
55.33 + }
55.34 }
55.35 }
55.36 return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
55.37 @@ -1053,6 +1060,8 @@
55.38
55.39 (env)->SetIntField(target, AwtComponent::xID, rect.left);
55.40 (env)->SetIntField(target, AwtComponent::yID, rect.top);
55.41 + (env)->SetIntField(peer, AwtWindow::sysXID, rect.left);
55.42 + (env)->SetIntField(peer, AwtWindow::sysYID, rect.top);
55.43 SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
55.44
55.45 env->DeleteLocalRef(target);
55.46 @@ -1116,6 +1125,11 @@
55.47
55.48 (env)->SetIntField(target, AwtComponent::widthID, newWidth);
55.49 (env)->SetIntField(target, AwtComponent::heightID, newHeight);
55.50 +
55.51 + jobject peer = GetPeer(env);
55.52 + (env)->SetIntField(peer, AwtWindow::sysWID, newWidth);
55.53 + (env)->SetIntField(peer, AwtWindow::sysHID, newHeight);
55.54 +
55.55 if (!AwtWindow::IsResizing()) {
55.56 WindowResized();
55.57 }
55.58 @@ -1455,20 +1469,17 @@
55.59 if (!::IsWindow(window)) {
55.60 return;
55.61 }
55.62 - DWORD exStyle = ::GetWindowLong(window, GWL_EXSTYLE);
55.63 +
55.64 if (::IsWindow(blocker)) {
55.65 - // save WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
55.66 - DWORD saveStyle = exStyle & (AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW);
55.67 - ::SetProp(window, ModalSaveWSEXProp, reinterpret_cast<HANDLE>(saveStyle));
55.68 - ::SetWindowLong(window, GWL_EXSTYLE, (exStyle | AWT_WS_EX_NOACTIVATE) & ~WS_EX_APPWINDOW);
55.69 ::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
55.70 + ::EnableWindow(window, FALSE);
55.71 } else {
55.72 - // restore WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
55.73 - DWORD saveStyle = reinterpret_cast<DWORD>(::GetProp(window, ModalSaveWSEXProp));
55.74 - ::SetWindowLong(window, GWL_EXSTYLE,
55.75 - (exStyle & ~(AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW)) | saveStyle);
55.76 - ::RemoveProp(window, ModalSaveWSEXProp);
55.77 ::RemoveProp(window, ModalBlockerProp);
55.78 + AwtComponent *comp = AwtComponent::GetComponent(window);
55.79 + // we don't expect to be called with non-java HWNDs
55.80 + DASSERT(comp && comp->IsTopLevel());
55.81 + // we should not unblock disabled toplevels
55.82 + ::EnableWindow(window, comp->isEnabled());
55.83 }
55.84 }
55.85
55.86 @@ -1754,17 +1765,22 @@
55.87 // Fix for 4459064 : do not enforce thresholds for embedded frames
55.88 if (!p->IsEmbeddedFrame())
55.89 {
55.90 + jobject peer = p->GetPeer(env);
55.91 int minWidth = ::GetSystemMetrics(SM_CXMIN);
55.92 int minHeight = ::GetSystemMetrics(SM_CYMIN);
55.93 if (w < minWidth)
55.94 {
55.95 env->SetIntField(target, AwtComponent::widthID,
55.96 w = minWidth);
55.97 + env->SetIntField(peer, AwtWindow::sysWID,
55.98 + w);
55.99 }
55.100 if (h < minHeight)
55.101 {
55.102 env->SetIntField(target, AwtComponent::heightID,
55.103 h = minHeight);
55.104 + env->SetIntField(peer, AwtWindow::sysHID,
55.105 + h);
55.106 }
55.107 }
55.108 env->DeleteLocalRef(target);
55.109 @@ -2148,6 +2164,11 @@
55.110 env->GetStaticMethodID(cls, "getActiveWindowHandles", "()[J");
55.111 DASSERT(AwtWindow::getActiveWindowsMID != NULL);
55.112
55.113 + AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I");
55.114 + AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I");
55.115 + AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I");
55.116 + AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I");
55.117 +
55.118 CATCH_BAD_ALLOC;
55.119 }
55.120
56.1 --- a/src/windows/native/sun/windows/awt_Window.h Wed Mar 26 17:48:05 2008 -0700
56.2 +++ b/src/windows/native/sun/windows/awt_Window.h Thu Mar 27 12:09:50 2008 -0700
56.3 @@ -33,7 +33,6 @@
56.4
56.5 // property name tagging windows disabled by modality
56.6 static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp");
56.7 -static LPCTSTR ModalSaveWSEXProp = TEXT("SunAwtModalSaveWSEXProp");
56.8 static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp");
56.9
56.10 #ifndef WH_MOUSE_LL
56.11 @@ -63,6 +62,12 @@
56.12 /* long[] getActiveWindowHandles() method in WWindowPeer */
56.13 static jmethodID getActiveWindowsMID;
56.14
56.15 + // The coordinates at the peer.
56.16 + static jfieldID sysXID;
56.17 + static jfieldID sysYID;
56.18 + static jfieldID sysWID;
56.19 + static jfieldID sysHID;
56.20 +
56.21 AwtWindow();
56.22 virtual ~AwtWindow();
56.23
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
57.2 +++ b/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java Thu Mar 27 12:09:50 2008 -0700
57.3 @@ -0,0 +1,413 @@
57.4 +/*
57.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
57.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
57.7 + *
57.8 + * This code is free software; you can redistribute it and/or modify it
57.9 + * under the terms of the GNU General Public License version 2 only, as
57.10 + * published by the Free Software Foundation.
57.11 + *
57.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
57.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
57.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57.15 + * version 2 for more details (a copy is included in the LICENSE file that
57.16 + * accompanied this code).
57.17 + *
57.18 + * You should have received a copy of the GNU General Public License version
57.19 + * 2 along with this work; if not, write to the Free Software Foundation,
57.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
57.21 + *
57.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
57.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
57.24 + * have any questions.
57.25 + */
57.26 +
57.27 +/*
57.28 + @test
57.29 + @bug 6581927
57.30 + @summary Non-focusable frame should honor the size of the frame buttons/decorations when resizing
57.31 + @library ../../regtesthelpers
57.32 + @build Util
57.33 + @author anthony.petrov@...: area=awt.toplevel
57.34 + @run main NonFocusableResizableTooSmall
57.35 +*/
57.36 +
57.37 +/**
57.38 + * NonFocusableResizableTooSmall.java
57.39 + *
57.40 + * summary: Non-focusable frame should honor the size of the frame buttons/decorations when resizing
57.41 + */
57.42 +
57.43 +import java.awt.*;
57.44 +import java.awt.event.*;
57.45 +import test.java.awt.regtesthelpers.Util;
57.46 +
57.47 +public class NonFocusableResizableTooSmall
57.48 +{
57.49 +
57.50 + //*** test-writer defined static variables go here ***
57.51 +
57.52 +
57.53 + private static void init()
57.54 + {
57.55 + //*** Create instructions for the user here ***
57.56 +
57.57 + String[] instructions =
57.58 + {
57.59 + "This is an AUTOMATIC test, simply wait until it is done.",
57.60 + "The result (passed or failed) will be shown in the",
57.61 + "message window below."
57.62 + };
57.63 + Sysout.createDialog( );
57.64 + Sysout.printInstructions( instructions );
57.65 +
57.66 + final Frame frame = new Frame();
57.67 + frame.setFocusableWindowState(false);
57.68 + frame.setSize(200, 100);
57.69 + frame.setVisible(true);
57.70 +
57.71 + final Robot robot = Util.createRobot();
57.72 + robot.setAutoDelay(20);
57.73 +
57.74 + // To be sure the window is shown and packed
57.75 + Util.waitForIdle(robot);
57.76 +
57.77 + final Insets insets = frame.getInsets();
57.78 + System.out.println("The insets of the frame: " + insets);
57.79 + if (insets.right == 0 || insets.bottom == 0) {
57.80 + System.out.println("The test environment must have non-zero right & bottom insets!");
57.81 + pass();
57.82 + return;
57.83 + }
57.84 +
57.85 + // Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip")
57.86 + final Rectangle bounds1 = frame.getBounds();
57.87 + System.out.println("The bounds before resizing: " + bounds1);
57.88 +
57.89 + robot.mouseMove(bounds1.x + bounds1.width - 1, bounds1.y + bounds1.height - 1);
57.90 +
57.91 + // ... and start resizing to some very small
57.92 + robot.mousePress( InputEvent.BUTTON1_MASK );
57.93 +
57.94 + // Now resize the frame so that the width is smaller
57.95 + // than the widths of the left and the right borders.
57.96 + // The sum of widths of the icon of the frame + the control-buttons
57.97 + // (close, minimize, etc.) should be definitely larger!
57.98 + robot.mouseMove(bounds1.x + insets.left + insets.right - 5, bounds1.y + bounds1.height - 1);
57.99 + Util.waitForIdle(robot);
57.100 +
57.101 + robot.mouseRelease( InputEvent.BUTTON1_MASK );
57.102 +
57.103 + Util.waitForIdle(robot);
57.104 +
57.105 + // Check the current bounds of the frame
57.106 + final Rectangle bounds2 = frame.getBounds();
57.107 + System.out.println("The bounds after resizing: " + bounds2);
57.108 +
57.109 + if (bounds2.width <= (insets.left + insets.right)) {
57.110 + fail("The frame has been resized to very small.");
57.111 + }
57.112 + pass();
57.113 + }//End init()
57.114 +
57.115 +
57.116 +
57.117 + /*****************************************************
57.118 + * Standard Test Machinery Section
57.119 + * DO NOT modify anything in this section -- it's a
57.120 + * standard chunk of code which has all of the
57.121 + * synchronisation necessary for the test harness.
57.122 + * By keeping it the same in all tests, it is easier
57.123 + * to read and understand someone else's test, as
57.124 + * well as insuring that all tests behave correctly
57.125 + * with the test harness.
57.126 + * There is a section following this for test-
57.127 + * classes
57.128 + ******************************************************/
57.129 + private static boolean theTestPassed = false;
57.130 + private static boolean testGeneratedInterrupt = false;
57.131 + private static String failureMessage = "";
57.132 +
57.133 + private static Thread mainThread = null;
57.134 +
57.135 + private static int sleepTime = 300000;
57.136 +
57.137 + // Not sure about what happens if multiple of this test are
57.138 + // instantiated in the same VM. Being static (and using
57.139 + // static vars), it aint gonna work. Not worrying about
57.140 + // it for now.
57.141 + public static void main( String args[] ) throws InterruptedException
57.142 + {
57.143 + mainThread = Thread.currentThread();
57.144 + try
57.145 + {
57.146 + init();
57.147 + }
57.148 + catch( TestPassedException e )
57.149 + {
57.150 + //The test passed, so just return from main and harness will
57.151 + // interepret this return as a pass
57.152 + return;
57.153 + }
57.154 + //At this point, neither test pass nor test fail has been
57.155 + // called -- either would have thrown an exception and ended the
57.156 + // test, so we know we have multiple threads.
57.157 +
57.158 + //Test involves other threads, so sleep and wait for them to
57.159 + // called pass() or fail()
57.160 + try
57.161 + {
57.162 + Thread.sleep( sleepTime );
57.163 + //Timed out, so fail the test
57.164 + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
57.165 + }
57.166 + catch (InterruptedException e)
57.167 + {
57.168 + //The test harness may have interrupted the test. If so, rethrow the exception
57.169 + // so that the harness gets it and deals with it.
57.170 + if( ! testGeneratedInterrupt ) throw e;
57.171 +
57.172 + //reset flag in case hit this code more than once for some reason (just safety)
57.173 + testGeneratedInterrupt = false;
57.174 +
57.175 + if ( theTestPassed == false )
57.176 + {
57.177 + throw new RuntimeException( failureMessage );
57.178 + }
57.179 + }
57.180 +
57.181 + }//main
57.182 +
57.183 + public static synchronized void setTimeoutTo( int seconds )
57.184 + {
57.185 + sleepTime = seconds * 1000;
57.186 + }
57.187 +
57.188 + public static synchronized void pass()
57.189 + {
57.190 + Sysout.println( "The test passed." );
57.191 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
57.192 + //first check if this is executing in main thread
57.193 + if ( mainThread == Thread.currentThread() )
57.194 + {
57.195 + //Still in the main thread, so set the flag just for kicks,
57.196 + // and throw a test passed exception which will be caught
57.197 + // and end the test.
57.198 + theTestPassed = true;
57.199 + throw new TestPassedException();
57.200 + }
57.201 + theTestPassed = true;
57.202 + testGeneratedInterrupt = true;
57.203 + mainThread.interrupt();
57.204 + }//pass()
57.205 +
57.206 + public static synchronized void fail()
57.207 + {
57.208 + //test writer didn't specify why test failed, so give generic
57.209 + fail( "it just plain failed! :-)" );
57.210 + }
57.211 +
57.212 + public static synchronized void fail( String whyFailed )
57.213 + {
57.214 + Sysout.println( "The test failed: " + whyFailed );
57.215 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
57.216 + //check if this called from main thread
57.217 + if ( mainThread == Thread.currentThread() )
57.218 + {
57.219 + //If main thread, fail now 'cause not sleeping
57.220 + throw new RuntimeException( whyFailed );
57.221 + }
57.222 + theTestPassed = false;
57.223 + testGeneratedInterrupt = true;
57.224 + failureMessage = whyFailed;
57.225 + mainThread.interrupt();
57.226 + }//fail()
57.227 +
57.228 +}// class NonFocusableResizableTooSmall
57.229 +
57.230 +//This exception is used to exit from any level of call nesting
57.231 +// when it's determined that the test has passed, and immediately
57.232 +// end the test.
57.233 +class TestPassedException extends RuntimeException
57.234 +{
57.235 +}
57.236 +
57.237 +//*********** End Standard Test Machinery Section **********
57.238 +
57.239 +
57.240 +//************ Begin classes defined for the test ****************
57.241 +
57.242 +// if want to make listeners, here is the recommended place for them, then instantiate
57.243 +// them in init()
57.244 +
57.245 +/* Example of a class which may be written as part of a test
57.246 +class NewClass implements anInterface
57.247 + {
57.248 + static int newVar = 0;
57.249 +
57.250 + public void eventDispatched(AWTEvent e)
57.251 + {
57.252 + //Counting events to see if we get enough
57.253 + eventCount++;
57.254 +
57.255 + if( eventCount == 20 )
57.256 + {
57.257 + //got enough events, so pass
57.258 +
57.259 + NonFocusableResizableTooSmall.pass();
57.260 + }
57.261 + else if( tries == 20 )
57.262 + {
57.263 + //tried too many times without getting enough events so fail
57.264 +
57.265 + NonFocusableResizableTooSmall.fail();
57.266 + }
57.267 +
57.268 + }// eventDispatched()
57.269 +
57.270 + }// NewClass class
57.271 +
57.272 +*/
57.273 +
57.274 +
57.275 +//************** End classes defined for the test *******************
57.276 +
57.277 +
57.278 +
57.279 +
57.280 +/****************************************************
57.281 + Standard Test Machinery
57.282 + DO NOT modify anything below -- it's a standard
57.283 + chunk of code whose purpose is to make user
57.284 + interaction uniform, and thereby make it simpler
57.285 + to read and understand someone else's test.
57.286 + ****************************************************/
57.287 +
57.288 +/**
57.289 + This is part of the standard test machinery.
57.290 + It creates a dialog (with the instructions), and is the interface
57.291 + for sending text messages to the user.
57.292 + To print the instructions, send an array of strings to Sysout.createDialog
57.293 + WithInstructions method. Put one line of instructions per array entry.
57.294 + To display a message for the tester to see, simply call Sysout.println
57.295 + with the string to be displayed.
57.296 + This mimics System.out.println but works within the test harness as well
57.297 + as standalone.
57.298 + */
57.299 +
57.300 +class Sysout
57.301 +{
57.302 + private static TestDialog dialog;
57.303 +
57.304 + public static void createDialogWithInstructions( String[] instructions )
57.305 + {
57.306 + dialog = new TestDialog( new Frame(), "Instructions" );
57.307 + dialog.printInstructions( instructions );
57.308 + dialog.setVisible(true);
57.309 + println( "Any messages for the tester will display here." );
57.310 + }
57.311 +
57.312 + public static void createDialog( )
57.313 + {
57.314 + dialog = new TestDialog( new Frame(), "Instructions" );
57.315 + String[] defInstr = { "Instructions will appear here. ", "" } ;
57.316 + dialog.printInstructions( defInstr );
57.317 + dialog.setVisible(true);
57.318 + println( "Any messages for the tester will display here." );
57.319 + }
57.320 +
57.321 +
57.322 + public static void printInstructions( String[] instructions )
57.323 + {
57.324 + dialog.printInstructions( instructions );
57.325 + }
57.326 +
57.327 +
57.328 + public static void println( String messageIn )
57.329 + {
57.330 + dialog.displayMessage( messageIn );
57.331 + System.out.println(messageIn);
57.332 + }
57.333 +
57.334 +}// Sysout class
57.335 +
57.336 +/**
57.337 + This is part of the standard test machinery. It provides a place for the
57.338 + test instructions to be displayed, and a place for interactive messages
57.339 + to the user to be displayed.
57.340 + To have the test instructions displayed, see Sysout.
57.341 + To have a message to the user be displayed, see Sysout.
57.342 + Do not call anything in this dialog directly.
57.343 + */
57.344 +class TestDialog extends Dialog
57.345 +{
57.346 +
57.347 + TextArea instructionsText;
57.348 + TextArea messageText;
57.349 + int maxStringLength = 80;
57.350 +
57.351 + //DO NOT call this directly, go through Sysout
57.352 + public TestDialog( Frame frame, String name )
57.353 + {
57.354 + super( frame, name );
57.355 + int scrollBoth = TextArea.SCROLLBARS_BOTH;
57.356 + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
57.357 + add( "North", instructionsText );
57.358 +
57.359 + messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
57.360 + add("Center", messageText);
57.361 +
57.362 + pack();
57.363 +
57.364 + setVisible(true);
57.365 + }// TestDialog()
57.366 +
57.367 + //DO NOT call this directly, go through Sysout
57.368 + public void printInstructions( String[] instructions )
57.369 + {
57.370 + //Clear out any current instructions
57.371 + instructionsText.setText( "" );
57.372 +
57.373 + //Go down array of instruction strings
57.374 +
57.375 + String printStr, remainingStr;
57.376 + for( int i=0; i < instructions.length; i++ )
57.377 + {
57.378 + //chop up each into pieces maxSringLength long
57.379 + remainingStr = instructions[ i ];
57.380 + while( remainingStr.length() > 0 )
57.381 + {
57.382 + //if longer than max then chop off first max chars to print
57.383 + if( remainingStr.length() >= maxStringLength )
57.384 + {
57.385 + //Try to chop on a word boundary
57.386 + int posOfSpace = remainingStr.
57.387 + lastIndexOf( ' ', maxStringLength - 1 );
57.388 +
57.389 + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
57.390 +
57.391 + printStr = remainingStr.substring( 0, posOfSpace + 1 );
57.392 + remainingStr = remainingStr.substring( posOfSpace + 1 );
57.393 + }
57.394 + //else just print
57.395 + else
57.396 + {
57.397 + printStr = remainingStr;
57.398 + remainingStr = "";
57.399 + }
57.400 +
57.401 + instructionsText.append( printStr + "\n" );
57.402 +
57.403 + }// while
57.404 +
57.405 + }// for
57.406 +
57.407 + }//printInstructions()
57.408 +
57.409 + //DO NOT call this directly, go through Sysout
57.410 + public void displayMessage( String messageIn )
57.411 + {
57.412 + messageText.append( messageIn + "\n" );
57.413 + System.out.println(messageIn);
57.414 + }
57.415 +
57.416 +}// TestDialog class
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/test/java/awt/Focus/RestoreFocusOnDisabledComponentTest/RestoreFocusOnDisabledComponentTest.java Thu Mar 27 12:09:50 2008 -0700
58.3 @@ -0,0 +1,108 @@
58.4 +/*
58.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
58.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
58.7 + *
58.8 + * This code is free software; you can redistribute it and/or modify it
58.9 + * under the terms of the GNU General Public License version 2 only, as
58.10 + * published by the Free Software Foundation.
58.11 + *
58.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
58.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
58.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
58.15 + * version 2 for more details (a copy is included in the LICENSE file that
58.16 + * accompanied this code).
58.17 + *
58.18 + * You should have received a copy of the GNU General Public License version
58.19 + * 2 along with this work; if not, write to the Free Software Foundation,
58.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
58.21 + *
58.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
58.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
58.24 + * have any questions.
58.25 + */
58.26 +
58.27 +/*
58.28 + @test %W% %E%
58.29 + @bug 6598089
58.30 + @summary Tests restoring focus on a single disabled coponent
58.31 + @author Anton Tarasov: area=awt-focus
58.32 + @library ../../regtesthelpers
58.33 + @build Util
58.34 + @run main RestoreFocusOnDisabledComponentTest
58.35 +*/
58.36 +
58.37 +import java.awt.*;
58.38 +import java.awt.event.*;
58.39 +import java.applet.Applet;
58.40 +import test.java.awt.regtesthelpers.Util;
58.41 +
58.42 +/*
58.43 + * The bug is not reproducible on Windows.
58.44 + */
58.45 +public class RestoreFocusOnDisabledComponentTest extends Applet {
58.46 + Frame frame = new Frame("Frame") {public String toString() {return "FRAME";}};
58.47 + Button b0 = new Button("button0") {public String toString() {return "B-0";}};
58.48 + Button b1 = new Button("button1") {public String toString() {return "B-1";}};
58.49 + volatile int nFocused;
58.50 + Robot robot;
58.51 +
58.52 + public static void main(String[] args) {
58.53 + RestoreFocusOnDisabledComponentTest app = new RestoreFocusOnDisabledComponentTest();
58.54 + app.init();
58.55 + app.start();
58.56 + }
58.57 +
58.58 + public void init() {
58.59 + robot = Util.createRobot();
58.60 + }
58.61 +
58.62 + public void start() {
58.63 + frame.add(b0);
58.64 + frame.add(b1);
58.65 + frame.setLayout(new FlowLayout());
58.66 + frame.pack();
58.67 +
58.68 + frame.setVisible(true);
58.69 +
58.70 + Util.waitForIdle(robot);
58.71 + KeyboardFocusManager.setCurrentKeyboardFocusManager(new DefaultKeyboardFocusManager() {
58.72 + public boolean dispatchEvent(AWTEvent e) {
58.73 + if (e.getID() == FocusEvent.FOCUS_GAINED) {
58.74 + // Trying to emulate timings. b1 should be disabled just by the time it gets
58.75 + // FOCUS_GAINED event. The latter is a result of disabling b0 that initiates
58.76 + // focus auto transfer.
58.77 + if (e.getSource() == b1) {
58.78 + b1.setEnabled(false);
58.79 +
58.80 + } else if (e.getSource() == b0) {
58.81 + if (++nFocused > 10) {
58.82 + nFocused = -1;
58.83 + throw new TestFailedException("Focus went into busy loop!");
58.84 + }
58.85 + }
58.86 + }
58.87 + return super.dispatchEvent(e);
58.88 + }
58.89 + });
58.90 + // Initiating focus auto transfer.
58.91 + // Focus will be requested to b1. When FOCUS_GAINED is being dispatched to b1, it will
58.92 + // be disabled. This will trigger focus restoring. Focus will be requested to b0 (the
58.93 + // last opposite component). When FOCUS_GAINED is being dispatched to b0, it will
58.94 + // also be disabled. However, the last opposite component (and the most recent focus owner)
58.95 + // will still be b0. When DKFM initiates focus restoring it should detect restoring
58.96 + // on the same component and break.
58.97 + b0.setEnabled(false);
58.98 +
58.99 + Util.waitForIdle(robot);
58.100 + if (nFocused != -1) {
58.101 + System.out.println("Test passed.");
58.102 + }
58.103 + }
58.104 +}
58.105 +
58.106 +class TestFailedException extends RuntimeException {
58.107 + TestFailedException(String msg) {
58.108 + super("Test failed: " + msg);
58.109 + }
58.110 +}
58.111 +
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59.2 +++ b/test/java/awt/Mixing/ValidBounds.java Thu Mar 27 12:09:50 2008 -0700
59.3 @@ -0,0 +1,411 @@
59.4 +/*
59.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
59.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
59.7 + *
59.8 + * This code is free software; you can redistribute it and/or modify it
59.9 + * under the terms of the GNU General Public License version 2 only, as
59.10 + * published by the Free Software Foundation.
59.11 + *
59.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
59.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
59.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
59.15 + * version 2 for more details (a copy is included in the LICENSE file that
59.16 + * accompanied this code).
59.17 + *
59.18 + * You should have received a copy of the GNU General Public License version
59.19 + * 2 along with this work; if not, write to the Free Software Foundation,
59.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
59.21 + *
59.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
59.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
59.24 + * have any questions.
59.25 + */
59.26 +
59.27 +/*
59.28 + @test
59.29 + @bug 6637796
59.30 + @summary Shape should be correctly updated on invalid components
59.31 + @author anthony.petrov@...: area=awt.mixing
59.32 + @library ../regtesthelpers
59.33 + @build Util
59.34 + @run main ValidBounds
59.35 +*/
59.36 +
59.37 +/**
59.38 + * ValidBounds.java
59.39 + *
59.40 + * summary: Shape should be correctly updated on invalid components
59.41 + */
59.42 +
59.43 +import java.awt.*;
59.44 +import java.awt.event.*;
59.45 +import test.java.awt.regtesthelpers.Util;
59.46 +
59.47 +public class ValidBounds
59.48 +{
59.49 +
59.50 + static volatile boolean clickPassed = false;
59.51 +
59.52 + private static void init()
59.53 + {
59.54 + //*** Create instructions for the user here ***
59.55 +
59.56 + String[] instructions =
59.57 + {
59.58 + "This is an AUTOMATIC test, simply wait until it is done.",
59.59 + "The result (passed or failed) will be shown in the",
59.60 + "message window below."
59.61 + };
59.62 + Sysout.createDialog( );
59.63 + Sysout.printInstructions( instructions );
59.64 +
59.65 +
59.66 + // Create the frame and the button
59.67 + Frame f = new Frame();
59.68 + f.setBounds(100, 100, 400, 300);
59.69 +
59.70 + Button b = new Button("OK");
59.71 +
59.72 + f.setLayout(null);
59.73 + f.add(b);
59.74 + b.setBounds(50, 50, 200, 50);
59.75 +
59.76 + b.addActionListener(new java.awt.event.ActionListener() {
59.77 + public void actionPerformed(java.awt.event.ActionEvent e) {
59.78 + clickPassed = true;
59.79 + }
59.80 + });
59.81 +
59.82 + f.setVisible(true);
59.83 +
59.84 + // Let's make the button much smaller first...
59.85 + Robot robot = Util.createRobot();
59.86 + robot.setAutoDelay(20);
59.87 +
59.88 + Util.waitForIdle(robot);
59.89 +
59.90 + b.setBounds(50, 50, 5, 5);
59.91 + Util.waitForIdle(robot);
59.92 +
59.93 + // ... and now let's enlarge it.
59.94 + b.setBounds(50, 50, 200, 50);
59.95 + Util.waitForIdle(robot);
59.96 +
59.97 + // If the button doesn't receive the click, it means that the test
59.98 + // failed: the shape of the button was not enlarged.
59.99 + Point heavyLoc = b.getLocationOnScreen();
59.100 + robot.mouseMove(heavyLoc.x + 20, heavyLoc.y + 20);
59.101 +
59.102 + robot.mousePress(InputEvent.BUTTON1_MASK);
59.103 + robot.mouseRelease(InputEvent.BUTTON1_MASK);
59.104 + Util.waitForIdle(robot);
59.105 +
59.106 + if (clickPassed) {
59.107 + pass();
59.108 + } else {
59.109 + fail("The button cannot be clicked.");
59.110 + }
59.111 + }//End init()
59.112 +
59.113 +
59.114 +
59.115 + /*****************************************************
59.116 + * Standard Test Machinery Section
59.117 + * DO NOT modify anything in this section -- it's a
59.118 + * standard chunk of code which has all of the
59.119 + * synchronisation necessary for the test harness.
59.120 + * By keeping it the same in all tests, it is easier
59.121 + * to read and understand someone else's test, as
59.122 + * well as insuring that all tests behave correctly
59.123 + * with the test harness.
59.124 + * There is a section following this for test-
59.125 + * classes
59.126 + ******************************************************/
59.127 + private static boolean theTestPassed = false;
59.128 + private static boolean testGeneratedInterrupt = false;
59.129 + private static String failureMessage = "";
59.130 +
59.131 + private static Thread mainThread = null;
59.132 +
59.133 + private static int sleepTime = 300000;
59.134 +
59.135 + // Not sure about what happens if multiple of this test are
59.136 + // instantiated in the same VM. Being static (and using
59.137 + // static vars), it aint gonna work. Not worrying about
59.138 + // it for now.
59.139 + public static void main( String args[] ) throws InterruptedException
59.140 + {
59.141 + mainThread = Thread.currentThread();
59.142 + try
59.143 + {
59.144 + init();
59.145 + }
59.146 + catch( TestPassedException e )
59.147 + {
59.148 + //The test passed, so just return from main and harness will
59.149 + // interepret this return as a pass
59.150 + return;
59.151 + }
59.152 + //At this point, neither test pass nor test fail has been
59.153 + // called -- either would have thrown an exception and ended the
59.154 + // test, so we know we have multiple threads.
59.155 +
59.156 + //Test involves other threads, so sleep and wait for them to
59.157 + // called pass() or fail()
59.158 + try
59.159 + {
59.160 + Thread.sleep( sleepTime );
59.161 + //Timed out, so fail the test
59.162 + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
59.163 + }
59.164 + catch (InterruptedException e)
59.165 + {
59.166 + //The test harness may have interrupted the test. If so, rethrow the exception
59.167 + // so that the harness gets it and deals with it.
59.168 + if( ! testGeneratedInterrupt ) throw e;
59.169 +
59.170 + //reset flag in case hit this code more than once for some reason (just safety)
59.171 + testGeneratedInterrupt = false;
59.172 +
59.173 + if ( theTestPassed == false )
59.174 + {
59.175 + throw new RuntimeException( failureMessage );
59.176 + }
59.177 + }
59.178 +
59.179 + }//main
59.180 +
59.181 + public static synchronized void setTimeoutTo( int seconds )
59.182 + {
59.183 + sleepTime = seconds * 1000;
59.184 + }
59.185 +
59.186 + public static synchronized void pass()
59.187 + {
59.188 + Sysout.println( "The test passed." );
59.189 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
59.190 + //first check if this is executing in main thread
59.191 + if ( mainThread == Thread.currentThread() )
59.192 + {
59.193 + //Still in the main thread, so set the flag just for kicks,
59.194 + // and throw a test passed exception which will be caught
59.195 + // and end the test.
59.196 + theTestPassed = true;
59.197 + throw new TestPassedException();
59.198 + }
59.199 + theTestPassed = true;
59.200 + testGeneratedInterrupt = true;
59.201 + mainThread.interrupt();
59.202 + }//pass()
59.203 +
59.204 + public static synchronized void fail()
59.205 + {
59.206 + //test writer didn't specify why test failed, so give generic
59.207 + fail( "it just plain failed! :-)" );
59.208 + }
59.209 +
59.210 + public static synchronized void fail( String whyFailed )
59.211 + {
59.212 + Sysout.println( "The test failed: " + whyFailed );
59.213 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
59.214 + //check if this called from main thread
59.215 + if ( mainThread == Thread.currentThread() )
59.216 + {
59.217 + //If main thread, fail now 'cause not sleeping
59.218 + throw new RuntimeException( whyFailed );
59.219 + }
59.220 + theTestPassed = false;
59.221 + testGeneratedInterrupt = true;
59.222 + failureMessage = whyFailed;
59.223 + mainThread.interrupt();
59.224 + }//fail()
59.225 +
59.226 +}// class ValidBounds
59.227 +
59.228 +//This exception is used to exit from any level of call nesting
59.229 +// when it's determined that the test has passed, and immediately
59.230 +// end the test.
59.231 +class TestPassedException extends RuntimeException
59.232 +{
59.233 +}
59.234 +
59.235 +//*********** End Standard Test Machinery Section **********
59.236 +
59.237 +
59.238 +//************ Begin classes defined for the test ****************
59.239 +
59.240 +// if want to make listeners, here is the recommended place for them, then instantiate
59.241 +// them in init()
59.242 +
59.243 +/* Example of a class which may be written as part of a test
59.244 +class NewClass implements anInterface
59.245 + {
59.246 + static int newVar = 0;
59.247 +
59.248 + public void eventDispatched(AWTEvent e)
59.249 + {
59.250 + //Counting events to see if we get enough
59.251 + eventCount++;
59.252 +
59.253 + if( eventCount == 20 )
59.254 + {
59.255 + //got enough events, so pass
59.256 +
59.257 + ValidBounds.pass();
59.258 + }
59.259 + else if( tries == 20 )
59.260 + {
59.261 + //tried too many times without getting enough events so fail
59.262 +
59.263 + ValidBounds.fail();
59.264 + }
59.265 +
59.266 + }// eventDispatched()
59.267 +
59.268 + }// NewClass class
59.269 +
59.270 +*/
59.271 +
59.272 +
59.273 +//************** End classes defined for the test *******************
59.274 +
59.275 +
59.276 +
59.277 +
59.278 +/****************************************************
59.279 + Standard Test Machinery
59.280 + DO NOT modify anything below -- it's a standard
59.281 + chunk of code whose purpose is to make user
59.282 + interaction uniform, and thereby make it simpler
59.283 + to read and understand someone else's test.
59.284 + ****************************************************/
59.285 +
59.286 +/**
59.287 + This is part of the standard test machinery.
59.288 + It creates a dialog (with the instructions), and is the interface
59.289 + for sending text messages to the user.
59.290 + To print the instructions, send an array of strings to Sysout.createDialog
59.291 + WithInstructions method. Put one line of instructions per array entry.
59.292 + To display a message for the tester to see, simply call Sysout.println
59.293 + with the string to be displayed.
59.294 + This mimics System.out.println but works within the test harness as well
59.295 + as standalone.
59.296 + */
59.297 +
59.298 +class Sysout
59.299 +{
59.300 + private static TestDialog dialog;
59.301 +
59.302 + public static void createDialogWithInstructions( String[] instructions )
59.303 + {
59.304 + dialog = new TestDialog( new Frame(), "Instructions" );
59.305 + dialog.printInstructions( instructions );
59.306 + dialog.setVisible(true);
59.307 + println( "Any messages for the tester will display here." );
59.308 + }
59.309 +
59.310 + public static void createDialog( )
59.311 + {
59.312 + dialog = new TestDialog( new Frame(), "Instructions" );
59.313 + String[] defInstr = { "Instructions will appear here. ", "" } ;
59.314 + dialog.printInstructions( defInstr );
59.315 + dialog.setVisible(true);
59.316 + println( "Any messages for the tester will display here." );
59.317 + }
59.318 +
59.319 +
59.320 + public static void printInstructions( String[] instructions )
59.321 + {
59.322 + dialog.printInstructions( instructions );
59.323 + }
59.324 +
59.325 +
59.326 + public static void println( String messageIn )
59.327 + {
59.328 + dialog.displayMessage( messageIn );
59.329 + System.out.println(messageIn);
59.330 + }
59.331 +
59.332 +}// Sysout class
59.333 +
59.334 +/**
59.335 + This is part of the standard test machinery. It provides a place for the
59.336 + test instructions to be displayed, and a place for interactive messages
59.337 + to the user to be displayed.
59.338 + To have the test instructions displayed, see Sysout.
59.339 + To have a message to the user be displayed, see Sysout.
59.340 + Do not call anything in this dialog directly.
59.341 + */
59.342 +class TestDialog extends Dialog
59.343 +{
59.344 +
59.345 + TextArea instructionsText;
59.346 + TextArea messageText;
59.347 + int maxStringLength = 80;
59.348 +
59.349 + //DO NOT call this directly, go through Sysout
59.350 + public TestDialog( Frame frame, String name )
59.351 + {
59.352 + super( frame, name );
59.353 + int scrollBoth = TextArea.SCROLLBARS_BOTH;
59.354 + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
59.355 + add( "North", instructionsText );
59.356 +
59.357 + messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
59.358 + add("Center", messageText);
59.359 +
59.360 + pack();
59.361 +
59.362 + setVisible(true);
59.363 + }// TestDialog()
59.364 +
59.365 + //DO NOT call this directly, go through Sysout
59.366 + public void printInstructions( String[] instructions )
59.367 + {
59.368 + //Clear out any current instructions
59.369 + instructionsText.setText( "" );
59.370 +
59.371 + //Go down array of instruction strings
59.372 +
59.373 + String printStr, remainingStr;
59.374 + for( int i=0; i < instructions.length; i++ )
59.375 + {
59.376 + //chop up each into pieces maxSringLength long
59.377 + remainingStr = instructions[ i ];
59.378 + while( remainingStr.length() > 0 )
59.379 + {
59.380 + //if longer than max then chop off first max chars to print
59.381 + if( remainingStr.length() >= maxStringLength )
59.382 + {
59.383 + //Try to chop on a word boundary
59.384 + int posOfSpace = remainingStr.
59.385 + lastIndexOf( ' ', maxStringLength - 1 );
59.386 +
59.387 + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
59.388 +
59.389 + printStr = remainingStr.substring( 0, posOfSpace + 1 );
59.390 + remainingStr = remainingStr.substring( posOfSpace + 1 );
59.391 + }
59.392 + //else just print
59.393 + else
59.394 + {
59.395 + printStr = remainingStr;
59.396 + remainingStr = "";
59.397 + }
59.398 +
59.399 + instructionsText.append( printStr + "\n" );
59.400 +
59.401 + }// while
59.402 +
59.403 + }// for
59.404 +
59.405 + }//printInstructions()
59.406 +
59.407 + //DO NOT call this directly, go through Sysout
59.408 + public void displayMessage( String messageIn )
59.409 + {
59.410 + messageText.append( messageIn + "\n" );
59.411 + System.out.println(messageIn);
59.412 + }
59.413 +
59.414 +}// TestDialog class
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java Thu Mar 27 12:09:50 2008 -0700
60.3 @@ -0,0 +1,466 @@
60.4 +/*
60.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
60.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
60.7 + *
60.8 + * This code is free software; you can redistribute it and/or modify it
60.9 + * under the terms of the GNU General Public License version 2 only, as
60.10 + * published by the Free Software Foundation.
60.11 + *
60.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
60.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
60.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
60.15 + * version 2 for more details (a copy is included in the LICENSE file that
60.16 + * accompanied this code).
60.17 + *
60.18 + * You should have received a copy of the GNU General Public License version
60.19 + * 2 along with this work; if not, write to the Free Software Foundation,
60.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
60.21 + *
60.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
60.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
60.24 + * have any questions.
60.25 + */
60.26 +
60.27 +/*
60.28 + @test %I% %E%
60.29 + @bug 4080029
60.30 + @summary Modal Dialog block input to all frame windows not just its parent.
60.31 + @author dmitry.cherepanov: area=awt.modal
60.32 + @run main/manual CloseBlocker
60.33 +*/
60.34 +
60.35 +/**
60.36 + * ManualMainTest.java
60.37 + *
60.38 + * summary: The test opens and closes blocker dialog, the test verifies
60.39 + * that active window is correct when the dialog is closed.
60.40 + */
60.41 +
60.42 +import java.awt.*;
60.43 +import java.awt.event.*;
60.44 +
60.45 +public class CloseBlocker
60.46 +{
60.47 +
60.48 + private static void init()
60.49 + {
60.50 + //*** Create instructions for the user here ***
60.51 +
60.52 + String[] instructions =
60.53 + {
60.54 + " the test will be run 6 times, to start next test just close all ",
60.55 + " windows of previous; the instructions are the same for all tests: ",
60.56 + " 1) there are two frames (one the frames has 'show modal' button), ",
60.57 + " 2) press the button to show a dialog, ",
60.58 + " 3) close the dialog (an alternative scenario - activate another",
60.59 + " native window before closing the dialog), ",
60.60 + " 4) the frame with button should become next active window, ",
60.61 + " if it's true, then the test passed, otherwise, it failed. ",
60.62 + " Press 'pass' button only after all of the 6 tests are completed, ",
60.63 + " the number of the currently executed test is displayed on the ",
60.64 + " output window. "
60.65 + };
60.66 + Sysout.createDialog( );
60.67 + Sysout.printInstructions( instructions );
60.68 +
60.69 + test(true, true, false);
60.70 + test(true, true, true);
60.71 + test(false, true, false); // 3rd parameter has no affect for ownerless
60.72 +
60.73 + test(true, false, false);
60.74 + test(true, false, true);
60.75 + test(false, false, false); // 3rd parameter has no affect for ownerless
60.76 +
60.77 + }//End init()
60.78 +
60.79 + private static final Object obj = new Object();
60.80 + private static int counter = 0;
60.81 +
60.82 + /*
60.83 + * The ownerless parameter indicates whether the blocker dialog
60.84 + * has owner. The usual parameter indicates whether the blocker
60.85 + * dialog is a Java dialog (non-native dialog like file dialog).
60.86 + */
60.87 + private static void test(final boolean ownerless, final boolean usual, final boolean initiallyOwnerIsActive) {
60.88 +
60.89 + Sysout.print(" * test #" + (++counter) + " is running ... ");
60.90 +
60.91 + final Frame active = new Frame();
60.92 + final Frame nonactive = new Frame();
60.93 + Button button = new Button("show modal");
60.94 + button.addActionListener(new ActionListener() {
60.95 + public void actionPerformed(ActionEvent ae) {
60.96 + Dialog dialog = null;
60.97 + Frame parent = ownerless ? null : (initiallyOwnerIsActive? active : nonactive);
60.98 + if (usual) {
60.99 + dialog = new Dialog(parent, "Sample", true);
60.100 + } else {
60.101 + dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
60.102 + }
60.103 + dialog.addWindowListener(new WindowAdapter(){
60.104 + public void windowClosing(WindowEvent e){
60.105 + e.getWindow().dispose();
60.106 + }
60.107 + });
60.108 + dialog.setBounds(200, 200, 200, 200);
60.109 + dialog.setVisible(true);
60.110 + }
60.111 + });
60.112 +
60.113 + active.add(button);
60.114 + active.setBounds(200, 400, 200, 200);
60.115 + WindowAdapter adapter = new WindowAdapter(){
60.116 + public void windowClosing(WindowEvent e){
60.117 + active.dispose();
60.118 + nonactive.dispose();
60.119 + synchronized(obj) {
60.120 + obj.notify();
60.121 + }
60.122 + }
60.123 + };
60.124 + active.addWindowListener(adapter);
60.125 + active.setVisible(true);
60.126 +
60.127 + nonactive.setBounds(400, 400, 200, 200);
60.128 + nonactive.addWindowListener(adapter);
60.129 + nonactive.setVisible(true);
60.130 +
60.131 + synchronized(obj) {
60.132 + try{
60.133 + obj.wait();
60.134 + } catch(Exception e) {
60.135 + throw new RuntimeException(e);
60.136 + }
60.137 + }
60.138 +
60.139 + Sysout.println(" completed. ");
60.140 +
60.141 + }
60.142 +
60.143 + /*****************************************************
60.144 + * Standard Test Machinery Section
60.145 + * DO NOT modify anything in this section -- it's a
60.146 + * standard chunk of code which has all of the
60.147 + * synchronisation necessary for the test harness.
60.148 + * By keeping it the same in all tests, it is easier
60.149 + * to read and understand someone else's test, as
60.150 + * well as insuring that all tests behave correctly
60.151 + * with the test harness.
60.152 + * There is a section following this for test-defined
60.153 + * classes
60.154 + ******************************************************/
60.155 + private static boolean theTestPassed = false;
60.156 + private static boolean testGeneratedInterrupt = false;
60.157 + private static String failureMessage = "";
60.158 +
60.159 + private static Thread mainThread = null;
60.160 +
60.161 + private static int sleepTime = 300000;
60.162 +
60.163 + public static void main( String args[] ) throws InterruptedException
60.164 + {
60.165 + mainThread = Thread.currentThread();
60.166 + try
60.167 + {
60.168 + init();
60.169 + }
60.170 + catch( TestPassedException e )
60.171 + {
60.172 + //The test passed, so just return from main and harness will
60.173 + // interepret this return as a pass
60.174 + return;
60.175 + }
60.176 + //At this point, neither test passed nor test failed has been
60.177 + // called -- either would have thrown an exception and ended the
60.178 + // test, so we know we have multiple threads.
60.179 +
60.180 + //Test involves other threads, so sleep and wait for them to
60.181 + // called pass() or fail()
60.182 + try
60.183 + {
60.184 + Thread.sleep( sleepTime );
60.185 + //Timed out, so fail the test
60.186 + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
60.187 + }
60.188 + catch (InterruptedException e)
60.189 + {
60.190 + if( ! testGeneratedInterrupt ) throw e;
60.191 +
60.192 + //reset flag in case hit this code more than once for some reason (just safety)
60.193 + testGeneratedInterrupt = false;
60.194 + if ( theTestPassed == false )
60.195 + {
60.196 + throw new RuntimeException( failureMessage );
60.197 + }
60.198 + }
60.199 +
60.200 + }//main
60.201 +
60.202 + public static synchronized void setTimeoutTo( int seconds )
60.203 + {
60.204 + sleepTime = seconds * 1000;
60.205 + }
60.206 +
60.207 + public static synchronized void pass()
60.208 + {
60.209 + Sysout.println( "The test passed." );
60.210 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
60.211 + //first check if this is executing in main thread
60.212 + if ( mainThread == Thread.currentThread() )
60.213 + {
60.214 + //Still in the main thread, so set the flag just for kicks,
60.215 + // and throw a test passed exception which will be caught
60.216 + // and end the test.
60.217 + theTestPassed = true;
60.218 + throw new TestPassedException();
60.219 + }
60.220 + //pass was called from a different thread, so set the flag and interrupt
60.221 + // the main thead.
60.222 + theTestPassed = true;
60.223 + testGeneratedInterrupt = true;
60.224 + mainThread.interrupt();
60.225 + }//pass()
60.226 +
60.227 + public static synchronized void fail()
60.228 + {
60.229 + //test writer didn't specify why test failed, so give generic
60.230 + fail( "it just plain failed! :-)" );
60.231 + }
60.232 +
60.233 + public static synchronized void fail( String whyFailed )
60.234 + {
60.235 + Sysout.println( "The test failed: " + whyFailed );
60.236 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
60.237 + //check if this called from main thread
60.238 + if ( mainThread == Thread.currentThread() )
60.239 + {
60.240 + //If main thread, fail now 'cause not sleeping
60.241 + throw new RuntimeException( whyFailed );
60.242 + }
60.243 + theTestPassed = false;
60.244 + testGeneratedInterrupt = true;
60.245 + failureMessage = whyFailed;
60.246 + mainThread.interrupt();
60.247 + }//fail()
60.248 +
60.249 +}// class ManualMainTest
60.250 +
60.251 +//This exception is used to exit from any level of call nesting
60.252 +// when it's determined that the test has passed, and immediately
60.253 +// end the test.
60.254 +class TestPassedException extends RuntimeException
60.255 +{
60.256 +}
60.257 +
60.258 +//*********** End Standard Test Machinery Section **********
60.259 +
60.260 +
60.261 +//************ Begin classes defined for the test ****************
60.262 +
60.263 +// make listeners in a class defined here, and instantiate them in init()
60.264 +
60.265 +/* Example of a class which may be written as part of a test
60.266 +class NewClass implements anInterface
60.267 + {
60.268 + static int newVar = 0;
60.269 +
60.270 + public void eventDispatched(AWTEvent e)
60.271 + {
60.272 + //Counting events to see if we get enough
60.273 + eventCount++;
60.274 +
60.275 + if( eventCount == 20 )
60.276 + {
60.277 + //got enough events, so pass
60.278 +
60.279 + ManualMainTest.pass();
60.280 + }
60.281 + else if( tries == 20 )
60.282 + {
60.283 + //tried too many times without getting enough events so fail
60.284 +
60.285 + ManualMainTest.fail();
60.286 + }
60.287 +
60.288 + }// eventDispatched()
60.289 +
60.290 + }// NewClass class
60.291 +
60.292 +*/
60.293 +
60.294 +
60.295 +//************** End classes defined for the test *******************
60.296 +
60.297 +
60.298 +
60.299 +
60.300 +/****************************************************
60.301 + Standard Test Machinery
60.302 + DO NOT modify anything below -- it's a standard
60.303 + chunk of code whose purpose is to make user
60.304 + interaction uniform, and thereby make it simpler
60.305 + to read and understand someone else's test.
60.306 + ****************************************************/
60.307 +
60.308 +/**
60.309 + This is part of the standard test machinery.
60.310 + It creates a dialog (with the instructions), and is the interface
60.311 + for sending text messages to the user.
60.312 + To print the instructions, send an array of strings to Sysout.createDialog
60.313 + WithInstructions method. Put one line of instructions per array entry.
60.314 + To display a message for the tester to see, simply call Sysout.println
60.315 + with the string to be displayed.
60.316 + This mimics System.out.println but works within the test harness as well
60.317 + as standalone.
60.318 + */
60.319 +
60.320 +class Sysout
60.321 +{
60.322 + private static TestDialog dialog;
60.323 +
60.324 + public static void createDialogWithInstructions( String[] instructions )
60.325 + {
60.326 + dialog = new TestDialog( new Frame(), "Instructions" );
60.327 + dialog.printInstructions( instructions );
60.328 + dialog.setVisible(true);
60.329 + println( "Any messages for the tester will display here." );
60.330 + }
60.331 +
60.332 + public static void createDialog( )
60.333 + {
60.334 + dialog = new TestDialog( new Frame(), "Instructions" );
60.335 + String[] defInstr = { "Instructions will appear here. ", "" } ;
60.336 + dialog.printInstructions( defInstr );
60.337 + dialog.setVisible(true);
60.338 + println( "Any messages for the tester will display here." );
60.339 + }
60.340 +
60.341 +
60.342 + public static void printInstructions( String[] instructions )
60.343 + {
60.344 + dialog.printInstructions( instructions );
60.345 + }
60.346 +
60.347 +
60.348 + public static void println( String messageIn )
60.349 + {
60.350 + dialog.displayMessage( messageIn, true );
60.351 + }
60.352 +
60.353 + public static void print( String messageIn )
60.354 + {
60.355 + dialog.displayMessage( messageIn, false );
60.356 + }
60.357 +
60.358 +}// Sysout class
60.359 +
60.360 +/**
60.361 + This is part of the standard test machinery. It provides a place for the
60.362 + test instructions to be displayed, and a place for interactive messages
60.363 + to the user to be displayed.
60.364 + To have the test instructions displayed, see Sysout.
60.365 + To have a message to the user be displayed, see Sysout.
60.366 + Do not call anything in this dialog directly.
60.367 + */
60.368 +class TestDialog extends Dialog implements ActionListener
60.369 +{
60.370 +
60.371 + TextArea instructionsText;
60.372 + TextArea messageText;
60.373 + int maxStringLength = 80;
60.374 + Panel buttonP = new Panel();
60.375 + Button passB = new Button( "pass" );
60.376 + Button failB = new Button( "fail" );
60.377 +
60.378 + //DO NOT call this directly, go through Sysout
60.379 + public TestDialog( Frame frame, String name )
60.380 + {
60.381 + super( frame, name );
60.382 + int scrollBoth = TextArea.SCROLLBARS_BOTH;
60.383 + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
60.384 + add( "North", instructionsText );
60.385 +
60.386 + messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
60.387 + add("Center", messageText);
60.388 +
60.389 + passB = new Button( "pass" );
60.390 + passB.setActionCommand( "pass" );
60.391 + passB.addActionListener( this );
60.392 + buttonP.add( "East", passB );
60.393 +
60.394 + failB = new Button( "fail" );
60.395 + failB.setActionCommand( "fail" );
60.396 + failB.addActionListener( this );
60.397 + buttonP.add( "West", failB );
60.398 +
60.399 + add( "South", buttonP );
60.400 + pack();
60.401 +
60.402 + setVisible(true);
60.403 + }// TestDialog()
60.404 +
60.405 + //DO NOT call this directly, go through Sysout
60.406 + public void printInstructions( String[] instructions )
60.407 + {
60.408 + //Clear out any current instructions
60.409 + instructionsText.setText( "" );
60.410 +
60.411 + //Go down array of instruction strings
60.412 +
60.413 + String printStr, remainingStr;
60.414 + for( int i=0; i < instructions.length; i++ )
60.415 + {
60.416 + //chop up each into pieces maxSringLength long
60.417 + remainingStr = instructions[ i ];
60.418 + while( remainingStr.length() > 0 )
60.419 + {
60.420 + //if longer than max then chop off first max chars to print
60.421 + if( remainingStr.length() >= maxStringLength )
60.422 + {
60.423 + //Try to chop on a word boundary
60.424 + int posOfSpace = remainingStr.
60.425 + lastIndexOf( ' ', maxStringLength - 1 );
60.426 +
60.427 + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
60.428 +
60.429 + printStr = remainingStr.substring( 0, posOfSpace + 1 );
60.430 + remainingStr = remainingStr.substring( posOfSpace + 1 );
60.431 + }
60.432 + //else just print
60.433 + else
60.434 + {
60.435 + printStr = remainingStr;
60.436 + remainingStr = "";
60.437 + }
60.438 +
60.439 + instructionsText.append( printStr + "\n" );
60.440 +
60.441 + }// while
60.442 +
60.443 + }// for
60.444 +
60.445 + }//printInstructions()
60.446 +
60.447 + //DO NOT call this directly, go through Sysout
60.448 + public void displayMessage( String messageIn, boolean nextLine )
60.449 + {
60.450 + messageText.append( messageIn + (nextLine? "\n" : "") );
60.451 + System.out.println(messageIn);
60.452 + }
60.453 +
60.454 + //catch presses of the passed and failed buttons.
60.455 + //simply call the standard pass() or fail() static methods of
60.456 + //ManualMainTest
60.457 + public void actionPerformed( ActionEvent e )
60.458 + {
60.459 + if( e.getActionCommand() == "pass" )
60.460 + {
60.461 + CloseBlocker.pass();
60.462 + }
60.463 + else
60.464 + {
60.465 + CloseBlocker.fail();
60.466 + }
60.467 + }
60.468 +
60.469 +}// TestDialog class
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61.2 +++ b/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java Thu Mar 27 12:09:50 2008 -0700
61.3 @@ -0,0 +1,456 @@
61.4 +/*
61.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
61.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
61.7 + *
61.8 + * This code is free software; you can redistribute it and/or modify it
61.9 + * under the terms of the GNU General Public License version 2 only, as
61.10 + * published by the Free Software Foundation.
61.11 + *
61.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
61.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
61.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
61.15 + * version 2 for more details (a copy is included in the LICENSE file that
61.16 + * accompanied this code).
61.17 + *
61.18 + * You should have received a copy of the GNU General Public License version
61.19 + * 2 along with this work; if not, write to the Free Software Foundation,
61.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
61.21 + *
61.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
61.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
61.24 + * have any questions.
61.25 + */
61.26 +
61.27 +/*
61.28 + @test %I% %E%
61.29 + @bug 4080029
61.30 + @summary Modal Dialog block input to all frame windows not just its parent.
61.31 + @author dmitry.cherepanov: area=awt.modal
61.32 + @run main/manual OverBlocker
61.33 +*/
61.34 +
61.35 +/**
61.36 + * OverBlocker.java
61.37 + *
61.38 + * summary: The test verifies that if user tries to activate the blocked dialog
61.39 + * then the blocker dialog appears over the other windows
61.40 + */
61.41 +
61.42 +import java.awt.*;
61.43 +import java.awt.event.*;
61.44 +
61.45 +public class OverBlocker
61.46 +{
61.47 +
61.48 + private static void init()
61.49 + {
61.50 + //*** Create instructions for the user here ***
61.51 +
61.52 + String[] instructions =
61.53 + {
61.54 + " the test will be run 4 times, to start next test just close all ",
61.55 + " windows of previous; the instructions are the same for all tests: ",
61.56 + " 1) there is a frame with 'show modal' button, ",
61.57 + " 2) press the button to show a dialog, ",
61.58 + " 3) activate any non-Java application, move the app over the dialog, ",
61.59 + " 4) click on the frame by mouse, ",
61.60 + " 5) make sure that the dialog comes up from the application and ",
61.61 + " now the dialog overlaps the app as well as the frame, ",
61.62 + " if it's true, then the test passed, otherwise, it failed. ",
61.63 + " Press 'pass' button only after all of the 4 tests are completed, ",
61.64 + " the number of the currently executed test is displayed on the ",
61.65 + " output window. "
61.66 + };
61.67 + Sysout.createDialog( );
61.68 + Sysout.printInstructions( instructions );
61.69 +
61.70 + test(false, true);
61.71 + test(true, true);
61.72 + test(true, false);
61.73 + test(false, false);
61.74 +
61.75 + }//End init()
61.76 +
61.77 + private static final Object obj = new Object();
61.78 + private static int counter = 0;
61.79 +
61.80 + /*
61.81 + * The ownerless parameter indicates whether the blocker dialog
61.82 + * has owner. The usual parameter indicates whether the blocker
61.83 + * dialog is a Java dialog (non-native dialog like file dialog).
61.84 + */
61.85 + private static void test(final boolean ownerless, final boolean usual) {
61.86 +
61.87 + Sysout.print(" * test #" + (++counter) + " is running ... ");
61.88 +
61.89 + final Frame frame = new Frame();
61.90 + Button button = new Button("show modal");
61.91 + button.addActionListener(new ActionListener() {
61.92 + public void actionPerformed(ActionEvent ae) {
61.93 + Dialog dialog = null;
61.94 + Frame parent = ownerless ? null : frame;
61.95 + if (usual) {
61.96 + dialog = new Dialog(parent, "Sample", true);
61.97 + } else {
61.98 + dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
61.99 + }
61.100 + dialog.addWindowListener(new WindowAdapter(){
61.101 + public void windowClosing(WindowEvent e){
61.102 + e.getWindow().dispose();
61.103 + }
61.104 + });
61.105 + dialog.setBounds(200, 200, 200, 200);
61.106 + dialog.setVisible(true);
61.107 + }
61.108 + });
61.109 + frame.add(button);
61.110 + frame.setBounds(400, 400, 200, 200);
61.111 + frame.addWindowListener(new WindowAdapter(){
61.112 + public void windowClosing(WindowEvent e){
61.113 + e.getWindow().dispose();
61.114 + synchronized(obj) {
61.115 + obj.notify();
61.116 + }
61.117 + }
61.118 + });
61.119 + frame.setVisible(true);
61.120 +
61.121 + synchronized(obj) {
61.122 + try{
61.123 + obj.wait();
61.124 + } catch(Exception e) {
61.125 + throw new RuntimeException(e);
61.126 + }
61.127 + }
61.128 +
61.129 + Sysout.println(" completed. ");
61.130 +
61.131 + }
61.132 +
61.133 + /*****************************************************
61.134 + * Standard Test Machinery Section
61.135 + * DO NOT modify anything in this section -- it's a
61.136 + * standard chunk of code which has all of the
61.137 + * synchronisation necessary for the test harness.
61.138 + * By keeping it the same in all tests, it is easier
61.139 + * to read and understand someone else's test, as
61.140 + * well as insuring that all tests behave correctly
61.141 + * with the test harness.
61.142 + * There is a section following this for test-defined
61.143 + * classes
61.144 + ******************************************************/
61.145 + private static boolean theTestPassed = false;
61.146 + private static boolean testGeneratedInterrupt = false;
61.147 + private static String failureMessage = "";
61.148 +
61.149 + private static Thread mainThread = null;
61.150 +
61.151 + private static int sleepTime = 300000;
61.152 +
61.153 + public static void main( String args[] ) throws InterruptedException
61.154 + {
61.155 + mainThread = Thread.currentThread();
61.156 + try
61.157 + {
61.158 + init();
61.159 + }
61.160 + catch( TestPassedException e )
61.161 + {
61.162 + //The test passed, so just return from main and harness will
61.163 + // interepret this return as a pass
61.164 + return;
61.165 + }
61.166 + //At this point, neither test passed nor test failed has been
61.167 + // called -- either would have thrown an exception and ended the
61.168 + // test, so we know we have multiple threads.
61.169 +
61.170 + //Test involves other threads, so sleep and wait for them to
61.171 + // called pass() or fail()
61.172 + try
61.173 + {
61.174 + Thread.sleep( sleepTime );
61.175 + //Timed out, so fail the test
61.176 + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
61.177 + }
61.178 + catch (InterruptedException e)
61.179 + {
61.180 + if( ! testGeneratedInterrupt ) throw e;
61.181 +
61.182 + //reset flag in case hit this code more than once for some reason (just safety)
61.183 + testGeneratedInterrupt = false;
61.184 + if ( theTestPassed == false )
61.185 + {
61.186 + throw new RuntimeException( failureMessage );
61.187 + }
61.188 + }
61.189 +
61.190 + }//main
61.191 +
61.192 + public static synchronized void setTimeoutTo( int seconds )
61.193 + {
61.194 + sleepTime = seconds * 1000;
61.195 + }
61.196 +
61.197 + public static synchronized void pass()
61.198 + {
61.199 + Sysout.println( "The test passed." );
61.200 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
61.201 + //first check if this is executing in main thread
61.202 + if ( mainThread == Thread.currentThread() )
61.203 + {
61.204 + //Still in the main thread, so set the flag just for kicks,
61.205 + // and throw a test passed exception which will be caught
61.206 + // and end the test.
61.207 + theTestPassed = true;
61.208 + throw new TestPassedException();
61.209 + }
61.210 + //pass was called from a different thread, so set the flag and interrupt
61.211 + // the main thead.
61.212 + theTestPassed = true;
61.213 + testGeneratedInterrupt = true;
61.214 + mainThread.interrupt();
61.215 + }//pass()
61.216 +
61.217 + public static synchronized void fail()
61.218 + {
61.219 + //test writer didn't specify why test failed, so give generic
61.220 + fail( "it just plain failed! :-)" );
61.221 + }
61.222 +
61.223 + public static synchronized void fail( String whyFailed )
61.224 + {
61.225 + Sysout.println( "The test failed: " + whyFailed );
61.226 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
61.227 + //check if this called from main thread
61.228 + if ( mainThread == Thread.currentThread() )
61.229 + {
61.230 + //If main thread, fail now 'cause not sleeping
61.231 + throw new RuntimeException( whyFailed );
61.232 + }
61.233 + theTestPassed = false;
61.234 + testGeneratedInterrupt = true;
61.235 + failureMessage = whyFailed;
61.236 + mainThread.interrupt();
61.237 + }//fail()
61.238 +
61.239 +}// class ManualMainTest
61.240 +
61.241 +//This exception is used to exit from any level of call nesting
61.242 +// when it's determined that the test has passed, and immediately
61.243 +// end the test.
61.244 +class TestPassedException extends RuntimeException
61.245 +{
61.246 +}
61.247 +
61.248 +//*********** End Standard Test Machinery Section **********
61.249 +
61.250 +
61.251 +//************ Begin classes defined for the test ****************
61.252 +
61.253 +// make listeners in a class defined here, and instantiate them in init()
61.254 +
61.255 +/* Example of a class which may be written as part of a test
61.256 +class NewClass implements anInterface
61.257 + {
61.258 + static int newVar = 0;
61.259 +
61.260 + public void eventDispatched(AWTEvent e)
61.261 + {
61.262 + //Counting events to see if we get enough
61.263 + eventCount++;
61.264 +
61.265 + if( eventCount == 20 )
61.266 + {
61.267 + //got enough events, so pass
61.268 +
61.269 + ManualMainTest.pass();
61.270 + }
61.271 + else if( tries == 20 )
61.272 + {
61.273 + //tried too many times without getting enough events so fail
61.274 +
61.275 + ManualMainTest.fail();
61.276 + }
61.277 +
61.278 + }// eventDispatched()
61.279 +
61.280 + }// NewClass class
61.281 +
61.282 +*/
61.283 +
61.284 +
61.285 +//************** End classes defined for the test *******************
61.286 +
61.287 +
61.288 +
61.289 +
61.290 +/****************************************************
61.291 + Standard Test Machinery
61.292 + DO NOT modify anything below -- it's a standard
61.293 + chunk of code whose purpose is to make user
61.294 + interaction uniform, and thereby make it simpler
61.295 + to read and understand someone else's test.
61.296 + ****************************************************/
61.297 +
61.298 +/**
61.299 + This is part of the standard test machinery.
61.300 + It creates a dialog (with the instructions), and is the interface
61.301 + for sending text messages to the user.
61.302 + To print the instructions, send an array of strings to Sysout.createDialog
61.303 + WithInstructions method. Put one line of instructions per array entry.
61.304 + To display a message for the tester to see, simply call Sysout.println
61.305 + with the string to be displayed.
61.306 + This mimics System.out.println but works within the test harness as well
61.307 + as standalone.
61.308 + */
61.309 +
61.310 +class Sysout
61.311 +{
61.312 + private static TestDialog dialog;
61.313 +
61.314 + public static void createDialogWithInstructions( String[] instructions )
61.315 + {
61.316 + dialog = new TestDialog( new Frame(), "Instructions" );
61.317 + dialog.printInstructions( instructions );
61.318 + dialog.setVisible(true);
61.319 + println( "Any messages for the tester will display here." );
61.320 + }
61.321 +
61.322 + public static void createDialog( )
61.323 + {
61.324 + dialog = new TestDialog( new Frame(), "Instructions" );
61.325 + String[] defInstr = { "Instructions will appear here. ", "" } ;
61.326 + dialog.printInstructions( defInstr );
61.327 + dialog.setVisible(true);
61.328 + println( "Any messages for the tester will display here." );
61.329 + }
61.330 +
61.331 +
61.332 + public static void printInstructions( String[] instructions )
61.333 + {
61.334 + dialog.printInstructions( instructions );
61.335 + }
61.336 +
61.337 +
61.338 + public static void println( String messageIn )
61.339 + {
61.340 + dialog.displayMessage( messageIn, true );
61.341 + }
61.342 +
61.343 + public static void print( String messageIn )
61.344 + {
61.345 + dialog.displayMessage( messageIn, false );
61.346 + }
61.347 +
61.348 +}// Sysout class
61.349 +
61.350 +/**
61.351 + This is part of the standard test machinery. It provides a place for the
61.352 + test instructions to be displayed, and a place for interactive messages
61.353 + to the user to be displayed.
61.354 + To have the test instructions displayed, see Sysout.
61.355 + To have a message to the user be displayed, see Sysout.
61.356 + Do not call anything in this dialog directly.
61.357 + */
61.358 +class TestDialog extends Dialog implements ActionListener
61.359 +{
61.360 +
61.361 + TextArea instructionsText;
61.362 + TextArea messageText;
61.363 + int maxStringLength = 80;
61.364 + Panel buttonP = new Panel();
61.365 + Button passB = new Button( "pass" );
61.366 + Button failB = new Button( "fail" );
61.367 +
61.368 + //DO NOT call this directly, go through Sysout
61.369 + public TestDialog( Frame frame, String name )
61.370 + {
61.371 + super( frame, name );
61.372 + int scrollBoth = TextArea.SCROLLBARS_BOTH;
61.373 + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
61.374 + add( "North", instructionsText );
61.375 +
61.376 + messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
61.377 + add("Center", messageText);
61.378 +
61.379 + passB = new Button( "pass" );
61.380 + passB.setActionCommand( "pass" );
61.381 + passB.addActionListener( this );
61.382 + buttonP.add( "East", passB );
61.383 +
61.384 + failB = new Button( "fail" );
61.385 + failB.setActionCommand( "fail" );
61.386 + failB.addActionListener( this );
61.387 + buttonP.add( "West", failB );
61.388 +
61.389 + add( "South", buttonP );
61.390 + pack();
61.391 +
61.392 + setVisible(true);
61.393 + }// TestDialog()
61.394 +
61.395 + //DO NOT call this directly, go through Sysout
61.396 + public void printInstructions( String[] instructions )
61.397 + {
61.398 + //Clear out any current instructions
61.399 + instructionsText.setText( "" );
61.400 +
61.401 + //Go down array of instruction strings
61.402 +
61.403 + String printStr, remainingStr;
61.404 + for( int i=0; i < instructions.length; i++ )
61.405 + {
61.406 + //chop up each into pieces maxSringLength long
61.407 + remainingStr = instructions[ i ];
61.408 + while( remainingStr.length() > 0 )
61.409 + {
61.410 + //if longer than max then chop off first max chars to print
61.411 + if( remainingStr.length() >= maxStringLength )
61.412 + {
61.413 + //Try to chop on a word boundary
61.414 + int posOfSpace = remainingStr.
61.415 + lastIndexOf( ' ', maxStringLength - 1 );
61.416 +
61.417 + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
61.418 +
61.419 + printStr = remainingStr.substring( 0, posOfSpace + 1 );
61.420 + remainingStr = remainingStr.substring( posOfSpace + 1 );
61.421 + }
61.422 + //else just print
61.423 + else
61.424 + {
61.425 + printStr = remainingStr;
61.426 + remainingStr = "";
61.427 + }
61.428 +
61.429 + instructionsText.append( printStr + "\n" );
61.430 +
61.431 + }// while
61.432 +
61.433 + }// for
61.434 +
61.435 + }//printInstructions()
61.436 +
61.437 + //DO NOT call this directly, go through Sysout
61.438 + public void displayMessage( String messageIn, boolean nextLine )
61.439 + {
61.440 + messageText.append( messageIn + (nextLine? "\n" : "") );
61.441 + System.out.println(messageIn);
61.442 + }
61.443 +
61.444 + //catch presses of the passed and failed buttons.
61.445 + //simply call the standard pass() or fail() static methods of
61.446 + //ManualMainTest
61.447 + public void actionPerformed( ActionEvent e )
61.448 + {
61.449 + if( e.getActionCommand() == "pass" )
61.450 + {
61.451 + OverBlocker.pass();
61.452 + }
61.453 + else
61.454 + {
61.455 + OverBlocker.fail();
61.456 + }
61.457 + }
61.458 +
61.459 +}// TestDialog class
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java Thu Mar 27 12:09:50 2008 -0700
62.3 @@ -0,0 +1,403 @@
62.4 +/*
62.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
62.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
62.7 + *
62.8 + * This code is free software; you can redistribute it and/or modify it
62.9 + * under the terms of the GNU General Public License version 2 only, as
62.10 + * published by the Free Software Foundation.
62.11 + *
62.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
62.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
62.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
62.15 + * version 2 for more details (a copy is included in the LICENSE file that
62.16 + * accompanied this code).
62.17 + *
62.18 + * You should have received a copy of the GNU General Public License version
62.19 + * 2 along with this work; if not, write to the Free Software Foundation,
62.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
62.21 + *
62.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
62.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
62.24 + * have any questions.
62.25 + */
62.26 +
62.27 +/*
62.28 + @test %I% %E%
62.29 + @bug 6572263 6571808
62.30 + @summary PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList
62.31 + @author dmitry.cherepanov: area=awt.modal
62.32 + @run main/manual Winkey
62.33 +*/
62.34 +
62.35 +/**
62.36 + * Winkey.java
62.37 + *
62.38 + * summary: the test verifies that pressing combination of Windows key
62.39 + * and M key to minimize all windows doesn't break AWT modality
62.40 + */
62.41 +
62.42 +import java.awt.*;
62.43 +import java.awt.event.*;
62.44 +
62.45 +public class Winkey
62.46 +{
62.47 +
62.48 + private static void init()
62.49 + {
62.50 + //*** Create instructions for the user here ***
62.51 +
62.52 + String[] instructions =
62.53 + {
62.54 + " 1. there is a frame with a 'show modal' button, ",
62.55 + " 2. press the button to show a modal dialog, ",
62.56 + " 3. the modal dialog will be shown over the frame, ",
62.57 + " 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ",
62.58 + " ",
62.59 + " 5.1. press combination Windows Key and M key to minimize all windows, ",
62.60 + " 5.2. press combination Windows Key and D key to show desktop, ",
62.61 + " 5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ",
62.62 + " 5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)",
62.63 + " ",
62.64 + " 6. make sure that the dialog and the frame are visible, ",
62.65 + " the bounds of the windows should be the same as before, ",
62.66 + " if it's true, then the test passed; otherwise, it failed. "
62.67 + };
62.68 + Sysout.createDialog( );
62.69 + Sysout.printInstructions( instructions );
62.70 +
62.71 + final Frame frame = new Frame();
62.72 + Button button = new Button("show modal");
62.73 + button.addActionListener(new ActionListener() {
62.74 + public void actionPerformed(ActionEvent ae) {
62.75 + FileDialog dialog = new FileDialog((Frame)null, "Sample", FileDialog.LOAD);
62.76 + dialog.setVisible(true);
62.77 + }
62.78 + });
62.79 + frame.add(button);
62.80 + frame.setBounds(400, 400, 200, 200);
62.81 + frame.setVisible(true);
62.82 +
62.83 + }//End init()
62.84 +
62.85 + /*****************************************************
62.86 + * Standard Test Machinery Section
62.87 + * DO NOT modify anything in this section -- it's a
62.88 + * standard chunk of code which has all of the
62.89 + * synchronisation necessary for the test harness.
62.90 + * By keeping it the same in all tests, it is easier
62.91 + * to read and understand someone else's test, as
62.92 + * well as insuring that all tests behave correctly
62.93 + * with the test harness.
62.94 + * There is a section following this for test-defined
62.95 + * classes
62.96 + ******************************************************/
62.97 + private static boolean theTestPassed = false;
62.98 + private static boolean testGeneratedInterrupt = false;
62.99 + private static String failureMessage = "";
62.100 +
62.101 + private static Thread mainThread = null;
62.102 +
62.103 + private static int sleepTime = 300000;
62.104 +
62.105 + public static void main( String args[] ) throws InterruptedException
62.106 + {
62.107 + mainThread = Thread.currentThread();
62.108 + try
62.109 + {
62.110 + init();
62.111 + }
62.112 + catch( TestPassedException e )
62.113 + {
62.114 + //The test passed, so just return from main and harness will
62.115 + // interepret this return as a pass
62.116 + return;
62.117 + }
62.118 + //At this point, neither test passed nor test failed has been
62.119 + // called -- either would have thrown an exception and ended the
62.120 + // test, so we know we have multiple threads.
62.121 +
62.122 + //Test involves other threads, so sleep and wait for them to
62.123 + // called pass() or fail()
62.124 + try
62.125 + {
62.126 + Thread.sleep( sleepTime );
62.127 + //Timed out, so fail the test
62.128 + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
62.129 + }
62.130 + catch (InterruptedException e)
62.131 + {
62.132 + if( ! testGeneratedInterrupt ) throw e;
62.133 +
62.134 + //reset flag in case hit this code more than once for some reason (just safety)
62.135 + testGeneratedInterrupt = false;
62.136 + if ( theTestPassed == false )
62.137 + {
62.138 + throw new RuntimeException( failureMessage );
62.139 + }
62.140 + }
62.141 +
62.142 + }//main
62.143 +
62.144 + public static synchronized void setTimeoutTo( int seconds )
62.145 + {
62.146 + sleepTime = seconds * 1000;
62.147 + }
62.148 +
62.149 + public static synchronized void pass()
62.150 + {
62.151 + Sysout.println( "The test passed." );
62.152 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
62.153 + //first check if this is executing in main thread
62.154 + if ( mainThread == Thread.currentThread() )
62.155 + {
62.156 + //Still in the main thread, so set the flag just for kicks,
62.157 + // and throw a test passed exception which will be caught
62.158 + // and end the test.
62.159 + theTestPassed = true;
62.160 + throw new TestPassedException();
62.161 + }
62.162 + //pass was called from a different thread, so set the flag and interrupt
62.163 + // the main thead.
62.164 + theTestPassed = true;
62.165 + testGeneratedInterrupt = true;
62.166 + mainThread.interrupt();
62.167 + }//pass()
62.168 +
62.169 + public static synchronized void fail()
62.170 + {
62.171 + //test writer didn't specify why test failed, so give generic
62.172 + fail( "it just plain failed! :-)" );
62.173 + }
62.174 +
62.175 + public static synchronized void fail( String whyFailed )
62.176 + {
62.177 + Sysout.println( "The test failed: " + whyFailed );
62.178 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
62.179 + //check if this called from main thread
62.180 + if ( mainThread == Thread.currentThread() )
62.181 + {
62.182 + //If main thread, fail now 'cause not sleeping
62.183 + throw new RuntimeException( whyFailed );
62.184 + }
62.185 + theTestPassed = false;
62.186 + testGeneratedInterrupt = true;
62.187 + failureMessage = whyFailed;
62.188 + mainThread.interrupt();
62.189 + }//fail()
62.190 +
62.191 +}// class ManualMainTest
62.192 +
62.193 +//This exception is used to exit from any level of call nesting
62.194 +// when it's determined that the test has passed, and immediately
62.195 +// end the test.
62.196 +class TestPassedException extends RuntimeException
62.197 +{
62.198 +}
62.199 +
62.200 +//*********** End Standard Test Machinery Section **********
62.201 +
62.202 +
62.203 +//************ Begin classes defined for the test ****************
62.204 +
62.205 +// make listeners in a class defined here, and instantiate them in init()
62.206 +
62.207 +/* Example of a class which may be written as part of a test
62.208 +class NewClass implements anInterface
62.209 + {
62.210 + static int newVar = 0;
62.211 +
62.212 + public void eventDispatched(AWTEvent e)
62.213 + {
62.214 + //Counting events to see if we get enough
62.215 + eventCount++;
62.216 +
62.217 + if( eventCount == 20 )
62.218 + {
62.219 + //got enough events, so pass
62.220 +
62.221 + ManualMainTest.pass();
62.222 + }
62.223 + else if( tries == 20 )
62.224 + {
62.225 + //tried too many times without getting enough events so fail
62.226 +
62.227 + ManualMainTest.fail();
62.228 + }
62.229 +
62.230 + }// eventDispatched()
62.231 +
62.232 + }// NewClass class
62.233 +
62.234 +*/
62.235 +
62.236 +
62.237 +//************** End classes defined for the test *******************
62.238 +
62.239 +
62.240 +
62.241 +
62.242 +/****************************************************
62.243 + Standard Test Machinery
62.244 + DO NOT modify anything below -- it's a standard
62.245 + chunk of code whose purpose is to make user
62.246 + interaction uniform, and thereby make it simpler
62.247 + to read and understand someone else's test.
62.248 + ****************************************************/
62.249 +
62.250 +/**
62.251 + This is part of the standard test machinery.
62.252 + It creates a dialog (with the instructions), and is the interface
62.253 + for sending text messages to the user.
62.254 + To print the instructions, send an array of strings to Sysout.createDialog
62.255 + WithInstructions method. Put one line of instructions per array entry.
62.256 + To display a message for the tester to see, simply call Sysout.println
62.257 + with the string to be displayed.
62.258 + This mimics System.out.println but works within the test harness as well
62.259 + as standalone.
62.260 + */
62.261 +
62.262 +class Sysout
62.263 +{
62.264 + private static TestDialog dialog;
62.265 +
62.266 + public static void createDialogWithInstructions( String[] instructions )
62.267 + {
62.268 + dialog = new TestDialog( new Frame(), "Instructions" );
62.269 + dialog.printInstructions( instructions );
62.270 + dialog.setVisible(true);
62.271 + println( "Any messages for the tester will display here." );
62.272 + }
62.273 +
62.274 + public static void createDialog( )
62.275 + {
62.276 + dialog = new TestDialog( new Frame(), "Instructions" );
62.277 + String[] defInstr = { "Instructions will appear here. ", "" } ;
62.278 + dialog.printInstructions( defInstr );
62.279 + dialog.setVisible(true);
62.280 + println( "Any messages for the tester will display here." );
62.281 + }
62.282 +
62.283 +
62.284 + public static void printInstructions( String[] instructions )
62.285 + {
62.286 + dialog.printInstructions( instructions );
62.287 + }
62.288 +
62.289 +
62.290 + public static void println( String messageIn )
62.291 + {
62.292 + dialog.displayMessage( messageIn );
62.293 + }
62.294 +
62.295 +}// Sysout class
62.296 +
62.297 +/**
62.298 + This is part of the standard test machinery. It provides a place for the
62.299 + test instructions to be displayed, and a place for interactive messages
62.300 + to the user to be displayed.
62.301 + To have the test instructions displayed, see Sysout.
62.302 + To have a message to the user be displayed, see Sysout.
62.303 + Do not call anything in this dialog directly.
62.304 + */
62.305 +class TestDialog extends Dialog implements ActionListener
62.306 +{
62.307 +
62.308 + TextArea instructionsText;
62.309 + TextArea messageText;
62.310 + int maxStringLength = 80;
62.311 + Panel buttonP = new Panel();
62.312 + Button passB = new Button( "pass" );
62.313 + Button failB = new Button( "fail" );
62.314 +
62.315 + //DO NOT call this directly, go through Sysout
62.316 + public TestDialog( Frame frame, String name )
62.317 + {
62.318 + super( frame, name );
62.319 + int scrollBoth = TextArea.SCROLLBARS_BOTH;
62.320 + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
62.321 + add( "North", instructionsText );
62.322 +
62.323 + messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
62.324 + add("Center", messageText);
62.325 +
62.326 + passB = new Button( "pass" );
62.327 + passB.setActionCommand( "pass" );
62.328 + passB.addActionListener( this );
62.329 + buttonP.add( "East", passB );
62.330 +
62.331 + failB = new Button( "fail" );
62.332 + failB.setActionCommand( "fail" );
62.333 + failB.addActionListener( this );
62.334 + buttonP.add( "West", failB );
62.335 +
62.336 + add( "South", buttonP );
62.337 + pack();
62.338 +
62.339 + setVisible(true);
62.340 + }// TestDialog()
62.341 +
62.342 + //DO NOT call this directly, go through Sysout
62.343 + public void printInstructions( String[] instructions )
62.344 + {
62.345 + //Clear out any current instructions
62.346 + instructionsText.setText( "" );
62.347 +
62.348 + //Go down array of instruction strings
62.349 +
62.350 + String printStr, remainingStr;
62.351 + for( int i=0; i < instructions.length; i++ )
62.352 + {
62.353 + //chop up each into pieces maxSringLength long
62.354 + remainingStr = instructions[ i ];
62.355 + while( remainingStr.length() > 0 )
62.356 + {
62.357 + //if longer than max then chop off first max chars to print
62.358 + if( remainingStr.length() >= maxStringLength )
62.359 + {
62.360 + //Try to chop on a word boundary
62.361 + int posOfSpace = remainingStr.
62.362 + lastIndexOf( ' ', maxStringLength - 1 );
62.363 +
62.364 + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
62.365 +
62.366 + printStr = remainingStr.substring( 0, posOfSpace + 1 );
62.367 + remainingStr = remainingStr.substring( posOfSpace + 1 );
62.368 + }
62.369 + //else just print
62.370 + else
62.371 + {
62.372 + printStr = remainingStr;
62.373 + remainingStr = "";
62.374 + }
62.375 +
62.376 + instructionsText.append( printStr + "\n" );
62.377 +
62.378 + }// while
62.379 +
62.380 + }// for
62.381 +
62.382 + }//printInstructions()
62.383 +
62.384 + //DO NOT call this directly, go through Sysout
62.385 + public void displayMessage( String messageIn )
62.386 + {
62.387 + messageText.append( messageIn + "\n" );
62.388 + System.out.println(messageIn);
62.389 + }
62.390 +
62.391 + //catch presses of the passed and failed buttons.
62.392 + //simply call the standard pass() or fail() static methods of
62.393 + //ManualMainTest
62.394 + public void actionPerformed( ActionEvent e )
62.395 + {
62.396 + if( e.getActionCommand() == "pass" )
62.397 + {
62.398 + Winkey.pass();
62.399 + }
62.400 + else
62.401 + {
62.402 + Winkey.fail();
62.403 + }
62.404 + }
62.405 +
62.406 +}// TestDialog class
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
63.2 +++ b/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java Thu Mar 27 12:09:50 2008 -0700
63.3 @@ -0,0 +1,432 @@
63.4 +/*
63.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
63.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
63.7 + *
63.8 + * This code is free software; you can redistribute it and/or modify it
63.9 + * under the terms of the GNU General Public License version 2 only, as
63.10 + * published by the Free Software Foundation.
63.11 + *
63.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
63.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
63.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
63.15 + * version 2 for more details (a copy is included in the LICENSE file that
63.16 + * accompanied this code).
63.17 + *
63.18 + * You should have received a copy of the GNU General Public License version
63.19 + * 2 along with this work; if not, write to the Free Software Foundation,
63.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
63.21 + *
63.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
63.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
63.24 + * have any questions.
63.25 + */
63.26 +
63.27 +/*
63.28 + @test %W% %E% %I%, %G%
63.29 + @bug 6524352
63.30 + @summary support for high-resolution mouse wheel
63.31 + @author dmitry cherepanov: area=awt.event
63.32 + @run main/manual SmoothWheel
63.33 +*/
63.34 +
63.35 +/**
63.36 + * SmoothWheel.java
63.37 + *
63.38 + * summary:
63.39 + */
63.40 +
63.41 +import java.awt.*;
63.42 +import java.awt.event.*;
63.43 +
63.44 +public class SmoothWheel
63.45 +{
63.46 +
63.47 + //*** test-writer defined static variables go here ***
63.48 +
63.49 +
63.50 + private static void init()
63.51 + {
63.52 + String[] instructions =
63.53 + {
63.54 + "1. the test is for high-resolution mouse wheel only, ",
63.55 + " refer to the cr# 6524352 for more info about such devices, ",
63.56 + "2. you'll see a frame, the frame contains a checkbox, ",
63.57 + "3. initially, the state of the checkbox is off, ",
63.58 + " use mouse wheel over the frame, ",
63.59 + " and the frame will change its size gradually, ",
63.60 + "4. turn on the checkbox, ",
63.61 + " use mouse wheel again over the frame, ",
63.62 + " now the frame will change its size smoothly, ",
63.63 + "5. if the frame has always the same size or",
63.64 + " if the frame changes its size equally in 3,4 cases, ",
63.65 + " then the test failed. Otherwise, it passed."
63.66 + };
63.67 +
63.68 + Sysout.createDialog( );
63.69 + Sysout.printInstructions( instructions );
63.70 +
63.71 + final Frame frame = new Frame();
63.72 + final Checkbox checkbox = new Checkbox("smooth wheel?");
63.73 + checkbox.setState(false);
63.74 +
63.75 + frame.setLayout (new FlowLayout());
63.76 + frame.add(checkbox);
63.77 +
63.78 + frame.addMouseWheelListener(new MouseWheelListener() {
63.79 + public void mouseWheelMoved(MouseWheelEvent e) {
63.80 + Sysout.println(e.toString());
63.81 + double wheelRotation = 0;
63.82 + if (checkbox.getState()) {
63.83 + wheelRotation = e.getPreciseWheelRotation();
63.84 + } else {
63.85 + wheelRotation = e.getWheelRotation();
63.86 + }
63.87 + Dimension size = frame.getSize();
63.88 + size.width += 10 * wheelRotation;
63.89 + size.height += 10 * wheelRotation;
63.90 + frame.setSize(size);
63.91 + }
63.92 + });
63.93 +
63.94 + frame.setBounds(200, 200, 200, 200);
63.95 + frame.setVisible(true);
63.96 +
63.97 + }//End init()
63.98 +
63.99 +
63.100 +
63.101 + /*****************************************************
63.102 + * Standard Test Machinery Section
63.103 + * DO NOT modify anything in this section -- it's a
63.104 + * standard chunk of code which has all of the
63.105 + * synchronisation necessary for the test harness.
63.106 + * By keeping it the same in all tests, it is easier
63.107 + * to read and understand someone else's test, as
63.108 + * well as insuring that all tests behave correctly
63.109 + * with the test harness.
63.110 + * There is a section following this for test-defined
63.111 + * classes
63.112 + ******************************************************/
63.113 + private static boolean theTestPassed = false;
63.114 + private static boolean testGeneratedInterrupt = false;
63.115 + private static String failureMessage = "";
63.116 +
63.117 + private static Thread mainThread = null;
63.118 +
63.119 + private static int sleepTime = 300000;
63.120 +
63.121 + public static void main( String args[] ) throws InterruptedException
63.122 + {
63.123 + mainThread = Thread.currentThread();
63.124 + try
63.125 + {
63.126 + init();
63.127 + }
63.128 + catch( TestPassedException e )
63.129 + {
63.130 + //The test passed, so just return from main and harness will
63.131 + // interepret this return as a pass
63.132 + return;
63.133 + }
63.134 + //At this point, neither test passed nor test failed has been
63.135 + // called -- either would have thrown an exception and ended the
63.136 + // test, so we know we have multiple threads.
63.137 +
63.138 + //Test involves other threads, so sleep and wait for them to
63.139 + // called pass() or fail()
63.140 + try
63.141 + {
63.142 + Thread.sleep( sleepTime );
63.143 + //Timed out, so fail the test
63.144 + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
63.145 + }
63.146 + catch (InterruptedException e)
63.147 + {
63.148 + if( ! testGeneratedInterrupt ) throw e;
63.149 +
63.150 + //reset flag in case hit this code more than once for some reason (just safety)
63.151 + testGeneratedInterrupt = false;
63.152 + if ( theTestPassed == false )
63.153 + {
63.154 + throw new RuntimeException( failureMessage );
63.155 + }
63.156 + }
63.157 +
63.158 + }//main
63.159 +
63.160 + public static synchronized void setTimeoutTo( int seconds )
63.161 + {
63.162 + sleepTime = seconds * 1000;
63.163 + }
63.164 +
63.165 + public static synchronized void pass()
63.166 + {
63.167 + Sysout.println( "The test passed." );
63.168 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
63.169 + //first check if this is executing in main thread
63.170 + if ( mainThread == Thread.currentThread() )
63.171 + {
63.172 + //Still in the main thread, so set the flag just for kicks,
63.173 + // and throw a test passed exception which will be caught
63.174 + // and end the test.
63.175 + theTestPassed = true;
63.176 + throw new TestPassedException();
63.177 + }
63.178 + //pass was called from a different thread, so set the flag and interrupt
63.179 + // the main thead.
63.180 + theTestPassed = true;
63.181 + testGeneratedInterrupt = true;
63.182 + if (mainThread != null){
63.183 + mainThread.interrupt();
63.184 + }
63.185 + }//pass()
63.186 +
63.187 + public static synchronized void fail()
63.188 + {
63.189 + //test writer didn't specify why test failed, so give generic
63.190 + fail( "it just plain failed! :-)" );
63.191 + }
63.192 +
63.193 + public static synchronized void fail( String whyFailed )
63.194 + {
63.195 + Sysout.println( "The test failed: " + whyFailed );
63.196 + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
63.197 + //check if this called from main thread
63.198 + if ( mainThread == Thread.currentThread() )
63.199 + {
63.200 + //If main thread, fail now 'cause not sleeping
63.201 + throw new RuntimeException( whyFailed );
63.202 + }
63.203 + theTestPassed = false;
63.204 + testGeneratedInterrupt = true;
63.205 + failureMessage = whyFailed;
63.206 + mainThread.interrupt();
63.207 + }//fail()
63.208 +
63.209 +}// class ManualMainTest
63.210 +
63.211 +//This exception is used to exit from any level of call nesting
63.212 +// when it's determined that the test has passed, and immediately
63.213 +// end the test.
63.214 +class TestPassedException extends RuntimeException
63.215 +{
63.216 +}
63.217 +
63.218 +//*********** End Standard Test Machinery Section **********
63.219 +
63.220 +
63.221 +//************ Begin classes defined for the test ****************
63.222 +
63.223 +// make listeners in a class defined here, and instantiate them in init()
63.224 +
63.225 +/* Example of a class which may be written as part of a test
63.226 +class NewClass implements anInterface
63.227 + {
63.228 + static int newVar = 0;
63.229 +
63.230 + public void eventDispatched(AWTEvent e)
63.231 + {
63.232 + //Counting events to see if we get enough
63.233 + eventCount++;
63.234 +
63.235 + if( eventCount == 20 )
63.236 + {
63.237 + //got enough events, so pass
63.238 +
63.239 + ManualMainTest.pass();
63.240 + }
63.241 + else if( tries == 20 )
63.242 + {
63.243 + //tried too many times without getting enough events so fail
63.244 +
63.245 + ManualMainTest.fail();
63.246 + }
63.247 +
63.248 + }// eventDispatched()
63.249 +
63.250 + }// NewClass class
63.251 +
63.252 +*/
63.253 +
63.254 +
63.255 +//************** End classes defined for the test *******************
63.256 +
63.257 +
63.258 +
63.259 +
63.260 +/****************************************************
63.261 + Standard Test Machinery
63.262 + DO NOT modify anything below -- it's a standard
63.263 + chunk of code whose purpose is to make user
63.264 + interaction uniform, and thereby make it simpler
63.265 + to read and understand someone else's test.
63.266 + ****************************************************/
63.267 +
63.268 +/**
63.269 + This is part of the standard test machinery.
63.270 + It creates a dialog (with the instructions), and is the interface
63.271 + for sending text messages to the user.
63.272 + To print the instructions, send an array of strings to Sysout.createDialog
63.273 + WithInstructions method. Put one line of instructions per array entry.
63.274 + To display a message for the tester to see, simply call Sysout.println
63.275 + with the string to be displayed.
63.276 + This mimics System.out.println but works within the test harness as well
63.277 + as standalone.
63.278 + */
63.279 +
63.280 +class Sysout
63.281 +{
63.282 + private static TestDialog dialog;
63.283 + private static boolean numbering = false;
63.284 + private static int messageNumber = 0;
63.285 +
63.286 + public static void createDialogWithInstructions( String[] instructions )
63.287 + {
63.288 + dialog = new TestDialog( new Frame(), "Instructions" );
63.289 + dialog.printInstructions( instructions );
63.290 + dialog.setVisible(true);
63.291 + println( "Any messages for the tester will display here." );
63.292 + }
63.293 +
63.294 + public static void createDialog( )
63.295 + {
63.296 + dialog = new TestDialog( new Frame(), "Instructions" );
63.297 + String[] defInstr = { "Instructions will appear here. ", "" } ;
63.298 + dialog.printInstructions( defInstr );
63.299 + dialog.setVisible(true);
63.300 + println( "Any messages for the tester will display here." );
63.301 + }
63.302 +
63.303 +
63.304 + /* Enables message counting for the tester. */
63.305 + public static void enableNumbering(boolean enable){
63.306 + numbering = enable;
63.307 + }
63.308 +
63.309 + public static void printInstructions( String[] instructions )
63.310 + {
63.311 + dialog.printInstructions( instructions );
63.312 + }
63.313 +
63.314 +
63.315 + public static void println( String messageIn )
63.316 + {
63.317 + if (numbering) {
63.318 + messageIn = "" + messageNumber + " " + messageIn;
63.319 + messageNumber++;
63.320 + }
63.321 + dialog.displayMessage( messageIn );
63.322 + }
63.323 +
63.324 +}// Sysout class
63.325 +
63.326 +/**
63.327 + This is part of the standard test machinery. It provides a place for the
63.328 + test instructions to be displayed, and a place for interactive messages
63.329 + to the user to be displayed.
63.330 + To have the test instructions displayed, see Sysout.
63.331 + To have a message to the user be displayed, see Sysout.
63.332 + Do not call anything in this dialog directly.
63.333 + */
63.334 +class TestDialog extends Dialog implements ActionListener
63.335 +{
63.336 +
63.337 + TextArea instructionsText;
63.338 + TextArea messageText;
63.339 + int maxStringLength = 80;
63.340 + Panel buttonP = new Panel();
63.341 + Button passB = new Button( "pass" );
63.342 + Button failB = new Button( "fail" );
63.343 +
63.344 + //DO NOT call this directly, go through Sysout
63.345 + public TestDialog( Frame frame, String name )
63.346 + {
63.347 + super( frame, name );
63.348 + int scrollBoth = TextArea.SCROLLBARS_BOTH;
63.349 + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
63.350 + add( "North", instructionsText );
63.351 +
63.352 + messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
63.353 + add("Center", messageText);
63.354 +
63.355 + passB = new Button( "pass" );
63.356 + passB.setActionCommand( "pass" );
63.357 + passB.addActionListener( this );
63.358 + buttonP.add( "East", passB );
63.359 +
63.360 + failB = new Button( "fail" );
63.361 + failB.setActionCommand( "fail" );
63.362 + failB.addActionListener( this );
63.363 + buttonP.add( "West", failB );
63.364 +
63.365 + add( "South", buttonP );
63.366 + pack();
63.367 +
63.368 + setVisible(true);
63.369 + }// TestDialog()
63.370 +
63.371 + //DO NOT call this directly, go through Sysout
63.372 + public void printInstructions( String[] instructions )
63.373 + {
63.374 + //Clear out any current instructions
63.375 + instructionsText.setText( "" );
63.376 +
63.377 + //Go down array of instruction strings
63.378 +
63.379 + String printStr, remainingStr;
63.380 + for( int i=0; i < instructions.length; i++ )
63.381 + {
63.382 + //chop up each into pieces maxSringLength long
63.383 + remainingStr = instructions[ i ];
63.384 + while( remainingStr.length() > 0 )
63.385 + {
63.386 + //if longer than max then chop off first max chars to print
63.387 + if( remainingStr.length() >= maxStringLength )
63.388 + {
63.389 + //Try to chop on a word boundary
63.390 + int posOfSpace = remainingStr.
63.391 + lastIndexOf( ' ', maxStringLength - 1 );
63.392 +
63.393 + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
63.394 +
63.395 + printStr = remainingStr.substring( 0, posOfSpace + 1 );
63.396 + remainingStr = remainingStr.substring( posOfSpace + 1 );
63.397 + }
63.398 + //else just print
63.399 + else
63.400 + {
63.401 + printStr = remainingStr;
63.402 + remainingStr = "";
63.403 + }
63.404 +
63.405 + instructionsText.append( printStr + "\n" );
63.406 +
63.407 + }// while
63.408 +
63.409 + }// for
63.410 +
63.411 + }//printInstructions()
63.412 +
63.413 + //DO NOT call this directly, go through Sysout
63.414 + public void displayMessage( String messageIn )
63.415 + {
63.416 + messageText.append( messageIn + "\n" );
63.417 + System.out.println(messageIn);
63.418 + }
63.419 +
63.420 + //catch presses of the passed and failed buttons.
63.421 + //simply call the standard pass() or fail() static methods of
63.422 + //ManualMainTest
63.423 + public void actionPerformed( ActionEvent e )
63.424 + {
63.425 + if( e.getActionCommand() == "pass" )
63.426 + {
63.427 + SmoothWheel.pass();
63.428 + }
63.429 + else
63.430 + {
63.431 + SmoothWheel.fail();
63.432 + }
63.433 + }
63.434 +
63.435 +}// TestDialog class