6794764: Translucent windows are completely repainted on every paint event, on Windows
authorart
Thu, 21 May 2009 12:29:25 +0400
changeset 1222b33466bb2fed
parent 1221 315f315b8d3c
child 1223 97ece6b3d84f
6794764: Translucent windows are completely repainted on every paint event, on Windows
6719382: Printing of AWT components on windows is not working
6726866: Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel
6683775: Painting artifacts is seen when panel is made setOpaque(false) for a translucent window
Reviewed-by: anthony, tdv, alexp
src/share/classes/java/awt/GraphicsConfiguration.java
src/share/classes/java/awt/GraphicsDevice.java
src/share/classes/java/awt/Window.java
src/share/classes/java/awt/peer/WindowPeer.java
src/share/classes/javax/swing/DefaultDesktopManager.java
src/share/classes/javax/swing/JComponent.java
src/share/classes/javax/swing/RepaintManager.java
src/share/classes/sun/awt/AWTAccessor.java
src/share/classes/sun/awt/EmbeddedFrame.java
src/solaris/classes/sun/awt/X11/XWindowPeer.java
src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java
src/windows/classes/sun/awt/windows/WCanvasPeer.java
src/windows/classes/sun/awt/windows/WComponentPeer.java
src/windows/classes/sun/awt/windows/WObjectPeer.java
src/windows/classes/sun/awt/windows/WWindowPeer.java
src/windows/native/sun/windows/awt_Component.cpp
src/windows/native/sun/windows/awt_Component.h
src/windows/native/sun/windows/awt_Window.cpp
src/windows/native/sun/windows/awt_Window.h
test/javax/swing/JComponent/6683775/bug6683775.java
test/javax/swing/JInternalFrame/6726866/bug6726866.html
test/javax/swing/JInternalFrame/6726866/bug6726866.java
     1.1 --- a/src/share/classes/java/awt/GraphicsConfiguration.java	Tue May 19 17:03:13 2009 +0400
     1.2 +++ b/src/share/classes/java/awt/GraphicsConfiguration.java	Thu May 21 12:29:25 2009 +0400
     1.3 @@ -436,7 +436,7 @@
     1.4      }
     1.5  
     1.6      /**
     1.7 -     * Returns whether this GraphicsConfiguration supports
     1.8 +     * Returns whether this {@code GraphicsConfiguration} supports
     1.9       * the {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
    1.10       * PERPIXEL_TRANSLUCENT} kind of translucency.
    1.11       *
     2.1 --- a/src/share/classes/java/awt/GraphicsDevice.java	Tue May 19 17:03:13 2009 +0400
     2.2 +++ b/src/share/classes/java/awt/GraphicsDevice.java	Thu May 21 12:29:25 2009 +0400
     2.3 @@ -246,7 +246,7 @@
     2.4       * Simulated full-screen mode resizes
     2.5       * the window to the size of the screen and positions it at (0,0).
     2.6       * <p>
     2.7 -     * When entering full-screen mode, if the window to be used as the
     2.8 +     * When entering full-screen mode, if the window to be used as a
     2.9       * full-screen window is not visible, this method will make it visible.
    2.10       * It will remain visible when returning to windowed mode.
    2.11       * <p>
    2.12 @@ -261,9 +261,9 @@
    2.13       *
    2.14       * @param w a window to use as the full-screen window; {@code null}
    2.15       * if returning to windowed mode.  Some platforms expect the
    2.16 -     * fullscreen window to be a top-level component (i.e., a Frame);
    2.17 -     * therefore it is preferable to use a Frame here rather than a
    2.18 -     * Window.
    2.19 +     * fullscreen window to be a top-level component (i.e., a {@code Frame});
    2.20 +     * therefore it is preferable to use a {@code Frame} here rather than a
    2.21 +     * {@code Window}.
    2.22       *
    2.23       * @see #isFullScreenSupported
    2.24       * @see #getFullScreenWindow
     3.1 --- a/src/share/classes/java/awt/Window.java	Tue May 19 17:03:13 2009 +0400
     3.2 +++ b/src/share/classes/java/awt/Window.java	Thu May 21 12:29:25 2009 +0400
     3.3 @@ -296,7 +296,7 @@
     3.4      transient boolean isInShow = false;
     3.5  
     3.6      /*
     3.7 -     * Opacity level of the window
     3.8 +     * The opacity level of the window
     3.9       *
    3.10       * @serial
    3.11       * @see #setOpacity(float)
    3.12 @@ -306,7 +306,7 @@
    3.13      private float opacity = 1.0f;
    3.14  
    3.15      /*
    3.16 -     * The shape assigned to this window. This field is set to null if
    3.17 +     * The shape assigned to this window. This field is set to {@code null} if
    3.18       * no shape is set (rectangular window).
    3.19       *
    3.20       * @serial
    3.21 @@ -3592,10 +3592,10 @@
    3.22      @Override
    3.23      public void setBackground(Color bgColor) {
    3.24          Color oldBg = getBackground();
    3.25 +        super.setBackground(bgColor);
    3.26          if (oldBg != null && oldBg.equals(bgColor)) {
    3.27              return;
    3.28          }
    3.29 -        super.setBackground(bgColor);
    3.30          int oldAlpha = oldBg != null ? oldBg.getAlpha() : 255;
    3.31          int alpha = bgColor.getAlpha();
    3.32          if ((oldAlpha == 255) && (alpha < 255)) { // non-opaque window
    3.33 @@ -3623,16 +3623,37 @@
    3.34          }
    3.35      }
    3.36  
    3.37 -    private void updateWindow(BufferedImage backBuffer) {
    3.38 +    private void updateWindow() {
    3.39          synchronized (getTreeLock()) {
    3.40              WindowPeer peer = (WindowPeer)getPeer();
    3.41              if (peer != null) {
    3.42 -                peer.updateWindow(backBuffer);
    3.43 +                peer.updateWindow();
    3.44              }
    3.45          }
    3.46      }
    3.47  
    3.48 -    private static final Color TRANSPARENT_BACKGROUND_COLOR = new Color(0, 0, 0, 0);
    3.49 +    /**
    3.50 +     * {@inheritDoc}
    3.51 +     *
    3.52 +     * @since 1.7
    3.53 +     */
    3.54 +    @Override
    3.55 +    public void paint(Graphics g) {
    3.56 +        Color bgColor = getBackground();
    3.57 +        if ((bgColor != null) && (bgColor.getAlpha() < 255)) {
    3.58 +            Graphics gg = g.create();
    3.59 +            try {
    3.60 +                if (gg instanceof Graphics2D) {
    3.61 +                    gg.setColor(bgColor);
    3.62 +                    ((Graphics2D)gg).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
    3.63 +                    gg.fillRect(0, 0, getWidth(), getHeight());
    3.64 +                }
    3.65 +            } finally {
    3.66 +                gg.dispose();
    3.67 +            }
    3.68 +        }
    3.69 +        super.paint(g);
    3.70 +    }
    3.71  
    3.72      private static void setLayersOpaque(Component component, boolean isOpaque) {
    3.73          // Shouldn't use instanceof to avoid loading Swing classes
    3.74 @@ -3644,18 +3665,10 @@
    3.75              Container c = root.getContentPane();
    3.76              javax.swing.JComponent content =
    3.77                  (c instanceof javax.swing.JComponent) ? (javax.swing.JComponent)c : null;
    3.78 -            javax.swing.JComponent gp =
    3.79 -                (rpc.getGlassPane() instanceof javax.swing.JComponent) ?
    3.80 -                (javax.swing.JComponent)rpc.getGlassPane() : null;
    3.81 -            if (gp != null) {
    3.82 -                gp.setDoubleBuffered(isOpaque);
    3.83 -            }
    3.84              lp.setOpaque(isOpaque);
    3.85              root.setOpaque(isOpaque);
    3.86 -            root.setDoubleBuffered(isOpaque);
    3.87              if (content != null) {
    3.88                  content.setOpaque(isOpaque);
    3.89 -                content.setDoubleBuffered(isOpaque);
    3.90  
    3.91                  // Iterate down one level to see whether we have a JApplet
    3.92                  // (which is also a RootPaneContainer) which requires processing
    3.93 @@ -3748,8 +3761,8 @@
    3.94                  window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
    3.95                                                 opaque ? 255 : 0));
    3.96              }
    3.97 -            public void updateWindow(Window window, BufferedImage backBuffer) {
    3.98 -                window.updateWindow(backBuffer);
    3.99 +            public void updateWindow(Window window) {
   3.100 +                window.updateWindow();
   3.101              }
   3.102  
   3.103              public Dimension getSecurityWarningSize(Window window) {
     4.1 --- a/src/share/classes/java/awt/peer/WindowPeer.java	Tue May 19 17:03:13 2009 +0400
     4.2 +++ b/src/share/classes/java/awt/peer/WindowPeer.java	Thu May 21 12:29:25 2009 +0400
     4.3 @@ -110,12 +110,11 @@
     4.4      void setOpaque(boolean isOpaque);
     4.5  
     4.6      /**
     4.7 -     * Updates the native part of non-opaque window using
     4.8 -     * the given image with color+alpha values for each pixel.
     4.9 +     * Updates the native part of non-opaque window.
    4.10       *
    4.11       * @see Window#setBackground(Color)
    4.12       */
    4.13 -    void updateWindow(BufferedImage backBuffer);
    4.14 +    void updateWindow();
    4.15  
    4.16      /**
    4.17       * Instructs the peer to update the position of the security warning.
     5.1 --- a/src/share/classes/javax/swing/DefaultDesktopManager.java	Tue May 19 17:03:13 2009 +0400
     5.2 +++ b/src/share/classes/javax/swing/DefaultDesktopManager.java	Thu May 21 12:29:25 2009 +0400
     5.3 @@ -34,6 +34,9 @@
     5.4  import java.awt.event.ComponentAdapter;
     5.5  import java.awt.event.ComponentEvent;
     5.6  
     5.7 +import sun.awt.AWTAccessor;
     5.8 +import sun.awt.SunToolkit;
     5.9 +
    5.10  /** This is an implementation of the <code>DesktopManager</code>.
    5.11    * It currently implements the basic behaviors for managing
    5.12    * <code>JInternalFrame</code>s in an arbitrary parent.
    5.13 @@ -361,7 +364,7 @@
    5.14                g.dispose();
    5.15              }
    5.16          } else if (dragMode == FASTER_DRAG_MODE) {
    5.17 -          dragFrameFaster(f, newX, newY);
    5.18 +            dragFrameFaster(f, newX, newY);
    5.19          } else {
    5.20              setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight());
    5.21          }
    5.22 @@ -634,13 +637,8 @@
    5.23  
    5.24        boolean floaterCollision = isFloaterCollision(previousBounds, currentBounds);
    5.25  
    5.26 -    // System.out.println(previousBounds);
    5.27        JComponent parent = (JComponent)f.getParent();
    5.28        Rectangle visBounds = previousBounds.intersection(desktopBounds);
    5.29 -    //  System.out.println(previousBounds);
    5.30 -
    5.31 -
    5.32 -     // System.out.println(visBounds);
    5.33  
    5.34        RepaintManager currentManager = RepaintManager.currentManager(f);
    5.35  
    5.36 @@ -682,7 +680,6 @@
    5.37            } else {
    5.38                dirtyRects = new Rectangle[1];
    5.39                dirtyRects[0] = previousBounds;
    5.40 -              //  System.out.println("no intersection");
    5.41            };
    5.42  
    5.43            // Fix the damage
    5.44 @@ -701,14 +698,22 @@
    5.45  
    5.46                    parent.paintImmediately(dirtyRects[i]);
    5.47                    ((JInternalFrame)f).isDragging = true;
    5.48 -
    5.49 -                  // System.out.println(dirtyRects[i]);
    5.50                }
    5.51  
    5.52            }
    5.53        } finally {
    5.54            currentManager.endPaint();
    5.55        }
    5.56 +
    5.57 +      // update window if it's non-opaque
    5.58 +      Window topLevel = SwingUtilities.getWindowAncestor(f);
    5.59 +      Toolkit tk = Toolkit.getDefaultToolkit();
    5.60 +      if (!AWTAccessor.getWindowAccessor().isOpaque(topLevel) &&
    5.61 +          (tk instanceof SunToolkit) &&
    5.62 +          ((SunToolkit)tk).needUpdateWindow())
    5.63 +      {
    5.64 +          AWTAccessor.getWindowAccessor().updateWindow(topLevel);
    5.65 +      }
    5.66     }
    5.67  
    5.68     private boolean isFloaterCollision(Rectangle moveFrom, Rectangle moveTo) {
     6.1 --- a/src/share/classes/javax/swing/JComponent.java	Tue May 19 17:03:13 2009 +0400
     6.2 +++ b/src/share/classes/javax/swing/JComponent.java	Thu May 21 12:29:25 2009 +0400
     6.3 @@ -1021,8 +1021,10 @@
     6.4  
     6.5              int bw,bh;
     6.6              boolean printing = getFlag(IS_PRINTING);
     6.7 -            if(!printing && repaintManager.isDoubleBufferingEnabled() &&
     6.8 -               !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered()) {
     6.9 +            if (!printing && repaintManager.isDoubleBufferingEnabled() &&
    6.10 +                !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered() &&
    6.11 +                (getFlag(IS_REPAINTING) || repaintManager.isPainting()))
    6.12 +            {
    6.13                  repaintManager.beginPaint();
    6.14                  try {
    6.15                      repaintManager.paint(this, this, co, clipX, clipY, clipW,
     7.1 --- a/src/share/classes/javax/swing/RepaintManager.java	Tue May 19 17:03:13 2009 +0400
     7.2 +++ b/src/share/classes/javax/swing/RepaintManager.java	Thu May 21 12:29:25 2009 +0400
     7.3 @@ -43,7 +43,6 @@
     7.4  
     7.5  import com.sun.java.swing.SwingUtilities3;
     7.6  
     7.7 -
     7.8  /**
     7.9   * This class manages repaint requests, allowing the number
    7.10   * of repaints to be minimized, for example by collapsing multiple
    7.11 @@ -717,14 +716,12 @@
    7.12          }
    7.13      }
    7.14  
    7.15 -    private Map<Component,Rectangle>
    7.16 -        updateWindows(Map<Component,Rectangle> dirtyComponents)
    7.17 -    {
    7.18 +    private void updateWindows(Map<Component,Rectangle> dirtyComponents) {
    7.19          Toolkit toolkit = Toolkit.getDefaultToolkit();
    7.20          if (!(toolkit instanceof SunToolkit &&
    7.21                ((SunToolkit)toolkit).needUpdateWindow()))
    7.22          {
    7.23 -            return dirtyComponents;
    7.24 +            return;
    7.25          }
    7.26  
    7.27          Set<Window> windows = new HashSet<Window>();
    7.28 @@ -734,25 +731,20 @@
    7.29              Window window = dirty instanceof Window ?
    7.30                  (Window)dirty :
    7.31                  SwingUtilities.getWindowAncestor(dirty);
    7.32 -
    7.33              if (window != null &&
    7.34                  !AWTAccessor.getWindowAccessor().isOpaque(window))
    7.35              {
    7.36 -                // if this component's toplevel is perpixel translucent, it will
    7.37 -                // be repainted below
    7.38 -                it.remove();
    7.39 -                // add to the set of windows to update (so that we don't update
    7.40 -                // the window many times for each component to be repainted that
    7.41 -                // belongs to this window)
    7.42                  windows.add(window);
    7.43              }
    7.44          }
    7.45  
    7.46          for (Window window : windows) {
    7.47 -            AWTAccessor.getWindowAccessor().updateWindow(window, null);
    7.48 +            AWTAccessor.getWindowAccessor().updateWindow(window);
    7.49          }
    7.50 +    }
    7.51  
    7.52 -        return dirtyComponents;
    7.53 +    boolean isPainting() {
    7.54 +        return painting;
    7.55      }
    7.56  
    7.57      /**
    7.58 @@ -788,10 +780,6 @@
    7.59          int localBoundsW;
    7.60          Enumeration keys;
    7.61  
    7.62 -        // the components belonging to perpixel-translucent windows will be
    7.63 -        // removed from the list
    7.64 -        tmpDirtyComponents = updateWindows(tmpDirtyComponents);
    7.65 -
    7.66          roots = new ArrayList<Component>(count);
    7.67  
    7.68          for (Component dirty : tmpDirtyComponents.keySet()) {
    7.69 @@ -799,13 +787,11 @@
    7.70          }
    7.71  
    7.72          count = roots.size();
    7.73 -        //        System.out.println("roots size is " + count);
    7.74          painting = true;
    7.75          try {
    7.76              for(i=0 ; i < count ; i++) {
    7.77                  dirtyComponent = roots.get(i);
    7.78                  rect = tmpDirtyComponents.get(dirtyComponent);
    7.79 -                //            System.out.println("Should refresh :" + rect);
    7.80                  localBoundsH = dirtyComponent.getHeight();
    7.81                  localBoundsW = dirtyComponent.getWidth();
    7.82  
    7.83 @@ -848,6 +834,9 @@
    7.84          } finally {
    7.85              painting = false;
    7.86          }
    7.87 +
    7.88 +        updateWindows(tmpDirtyComponents);
    7.89 +
    7.90          tmpDirtyComponents.clear();
    7.91      }
    7.92  
    7.93 @@ -1004,6 +993,16 @@
    7.94              return delegate.getVolatileOffscreenBuffer(c, proposedWidth,
    7.95                                                          proposedHeight);
    7.96          }
    7.97 +
    7.98 +        // If the window is non-opaque, it's double-buffered at peer's level
    7.99 +        Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
   7.100 +        if (!AWTAccessor.getWindowAccessor().isOpaque(w)) {
   7.101 +            Toolkit tk = Toolkit.getDefaultToolkit();
   7.102 +            if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
   7.103 +                return null;
   7.104 +            }
   7.105 +        }
   7.106 +
   7.107          GraphicsConfiguration config = c.getGraphicsConfiguration();
   7.108          if (config == null) {
   7.109              config = GraphicsEnvironment.getLocalGraphicsEnvironment().
   7.110 @@ -1031,6 +1030,15 @@
   7.111          DoubleBufferInfo doubleBuffer;
   7.112          int width, height;
   7.113  
   7.114 +        // If the window is non-opaque, it's double-buffered at peer's level
   7.115 +        Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
   7.116 +        if (!AWTAccessor.getWindowAccessor().isOpaque(w)) {
   7.117 +            Toolkit tk = Toolkit.getDefaultToolkit();
   7.118 +            if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
   7.119 +                return null;
   7.120 +            }
   7.121 +        }
   7.122 +
   7.123          if (standardDoubleBuffer == null) {
   7.124              standardDoubleBuffer = new DoubleBufferInfo();
   7.125          }
     8.1 --- a/src/share/classes/sun/awt/AWTAccessor.java	Tue May 19 17:03:13 2009 +0400
     8.2 +++ b/src/share/classes/sun/awt/AWTAccessor.java	Thu May 21 12:29:25 2009 +0400
     8.3 @@ -132,7 +132,7 @@
     8.4          /*
     8.5           * Update the image of a non-opaque (translucent) window.
     8.6           */
     8.7 -        void updateWindow(Window window, BufferedImage backBuffer);
     8.8 +        void updateWindow(Window window);
     8.9  
    8.10          /** Get the size of the security warning.
    8.11           */
     9.1 --- a/src/share/classes/sun/awt/EmbeddedFrame.java	Tue May 19 17:03:13 2009 +0400
     9.2 +++ b/src/share/classes/sun/awt/EmbeddedFrame.java	Thu May 21 12:29:25 2009 +0400
     9.3 @@ -592,8 +592,9 @@
     9.4          public void setOpaque(boolean isOpaque) {
     9.5          }
     9.6  
     9.7 -        public void updateWindow(BufferedImage bi) {
     9.8 +        public void updateWindow() {
     9.9          }
    9.10 +
    9.11          public void repositionSecurityWarning() {
    9.12          }
    9.13       }
    10.1 --- a/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Tue May 19 17:03:13 2009 +0400
    10.2 +++ b/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Thu May 21 12:29:25 2009 +0400
    10.3 @@ -2058,7 +2058,7 @@
    10.4      }
    10.5  
    10.6      @Override
    10.7 -    public void updateWindow(BufferedImage backBuffer) {
    10.8 +    public void updateWindow() {
    10.9          // no-op
   10.10      }
   10.11  }
    11.1 --- a/src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java	Tue May 19 17:03:13 2009 +0400
    11.2 +++ b/src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java	Thu May 21 12:29:25 2009 +0400
    11.3 @@ -105,9 +105,10 @@
    11.4      }
    11.5  
    11.6      /**
    11.7 -     * Creates (if needed), clears and returns the buffer for this painter.
    11.8 +     * Creates (if needed), clears (if requested) and returns the buffer
    11.9 +     * for this painter.
   11.10       */
   11.11 -    protected abstract Image getBackBuffer();
   11.12 +    protected abstract Image getBackBuffer(boolean clear);
   11.13  
   11.14      /**
   11.15       * Updates the the window associated with this painter with the contents
   11.16 @@ -123,31 +124,16 @@
   11.17      public abstract void flush();
   11.18  
   11.19      /**
   11.20 -     * Updates the window associated with the painter given the passed image.
   11.21 -     * If the passed image is null the painter will use its own buffer for
   11.22 -     * rendering the contents of the window into it and updating the window.
   11.23 +     * Updates the window associated with the painter.
   11.24       *
   11.25 -     * If the passed buffer has dimensions different from the window, it is
   11.26 -     * copied into the internal buffer first and the latter is used to update
   11.27 -     * the window.
   11.28 -     *
   11.29 -     * @param bb the image to update the non opaque window with, or null.
   11.30 -     * If not null, the image must be of ARGB_PRE type.
   11.31 +     * @param repaint indicates if the window should be completely repainted
   11.32 +     * to the back buffer using {@link java.awt.Window#paintAll} before update.
   11.33       */
   11.34 -    public void updateWindow(Image bb) {
   11.35 +    public void updateWindow(boolean repaint) {
   11.36          boolean done = false;
   11.37 -        if (bb != null && (window.getWidth()  != bb.getWidth(null) ||
   11.38 -                           window.getHeight() != bb.getHeight(null)))
   11.39 -        {
   11.40 -            Image ourBB = getBackBuffer();
   11.41 -            Graphics2D g = (Graphics2D)ourBB.getGraphics();
   11.42 -            g.drawImage(bb, 0, 0, null);
   11.43 -            g.dispose();
   11.44 -            bb = ourBB;
   11.45 -        }
   11.46 -        do {
   11.47 -            if (bb == null) {
   11.48 -                bb = getBackBuffer();
   11.49 +        Image bb = getBackBuffer(repaint);
   11.50 +        while (!done) {
   11.51 +            if (repaint) {
   11.52                  Graphics2D g = (Graphics2D)bb.getGraphics();
   11.53                  try {
   11.54                      window.paintAll(g);
   11.55 @@ -156,17 +142,12 @@
   11.56                  }
   11.57              }
   11.58  
   11.59 -            peer.paintAppletWarning((Graphics2D)bb.getGraphics(),
   11.60 -                                    bb.getWidth(null), bb.getHeight(null));
   11.61 -
   11.62              done = update(bb);
   11.63 -            // in case they passed us a lost VI, next time around we'll use our
   11.64 -            // own bb because we can not validate and restore the contents of
   11.65 -            // their VI
   11.66              if (!done) {
   11.67 -                bb = null;
   11.68 +                repaint = true;
   11.69 +                bb = getBackBuffer(true);
   11.70              }
   11.71 -        } while (!done);
   11.72 +        }
   11.73      }
   11.74  
   11.75      private static final Image clearImage(Image bb) {
   11.76 @@ -190,30 +171,24 @@
   11.77       * method (VI, BI, regular Images).
   11.78       */
   11.79      private static class BIWindowPainter extends TranslucentWindowPainter {
   11.80 -        private WeakReference<BufferedImage> biRef;
   11.81 +        private BufferedImage backBuffer;
   11.82  
   11.83          protected BIWindowPainter(WWindowPeer peer) {
   11.84              super(peer);
   11.85          }
   11.86  
   11.87 -        private BufferedImage getBIBackBuffer() {
   11.88 +        @Override
   11.89 +        protected Image getBackBuffer(boolean clear) {
   11.90              int w = window.getWidth();
   11.91              int h = window.getHeight();
   11.92 -            BufferedImage bb = biRef == null ? null : biRef.get();
   11.93 -            if (bb == null || bb.getWidth() != w || bb.getHeight() != h) {
   11.94 -                if (bb != null) {
   11.95 -                    bb.flush();
   11.96 -                    bb = null;
   11.97 -                }
   11.98 -                bb = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
   11.99 -                biRef = new WeakReference<BufferedImage>(bb);
  11.100 +            if (backBuffer == null ||
  11.101 +                backBuffer.getWidth() != w ||
  11.102 +                backBuffer.getHeight() != h)
  11.103 +            {
  11.104 +                flush();
  11.105 +                backBuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
  11.106              }
  11.107 -            return (BufferedImage)clearImage(bb);
  11.108 -        }
  11.109 -
  11.110 -        @Override
  11.111 -        protected Image getBackBuffer() {
  11.112 -            return getBIBackBuffer();
  11.113 +            return clear ? (BufferedImage)clearImage(backBuffer) : backBuffer;
  11.114          }
  11.115  
  11.116          @Override
  11.117 @@ -246,10 +221,7 @@
  11.118              }
  11.119  
  11.120              // copy the passed image into our own buffer, then upload
  11.121 -            BufferedImage bi = getBIBackBuffer();
  11.122 -            Graphics2D g = (Graphics2D)bi.getGraphics();
  11.123 -            g.setComposite(AlphaComposite.Src);
  11.124 -            g.drawImage(bb, 0, 0, null);
  11.125 +            BufferedImage bi = (BufferedImage)clearImage(backBuffer);
  11.126  
  11.127              int data[] =
  11.128                  ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
  11.129 @@ -259,8 +231,9 @@
  11.130          }
  11.131  
  11.132          public void flush() {
  11.133 -            if (biRef != null) {
  11.134 -                biRef.clear();
  11.135 +            if (backBuffer != null) {
  11.136 +                backBuffer.flush();
  11.137 +                backBuffer = null;
  11.138              }
  11.139          }
  11.140      }
  11.141 @@ -271,27 +244,22 @@
  11.142       * Java heap-based buffer (which is then uploaded to the layered window)
  11.143       */
  11.144      private static class VIWindowPainter extends BIWindowPainter {
  11.145 -        private WeakReference<VolatileImage> viRef;
  11.146 +        private VolatileImage viBB;
  11.147  
  11.148          protected VIWindowPainter(WWindowPeer peer) {
  11.149              super(peer);
  11.150          }
  11.151  
  11.152          @Override
  11.153 -        protected Image getBackBuffer() {
  11.154 +        protected Image getBackBuffer(boolean clear) {
  11.155              int w = window.getWidth();
  11.156              int h = window.getHeight();
  11.157              GraphicsConfiguration gc = peer.getGraphicsConfiguration();
  11.158  
  11.159 -            VolatileImage viBB = viRef == null ? null : viRef.get();
  11.160 -
  11.161              if (viBB == null || viBB.getWidth() != w || viBB.getHeight() != h ||
  11.162                  viBB.validate(gc) == IMAGE_INCOMPATIBLE)
  11.163              {
  11.164 -                if (viBB != null) {
  11.165 -                    viBB.flush();
  11.166 -                    viBB = null;
  11.167 -                }
  11.168 +                flush();
  11.169  
  11.170                  if (gc instanceof AccelGraphicsConfig) {
  11.171                      AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc);
  11.172 @@ -303,21 +271,16 @@
  11.173                      viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT);
  11.174                  }
  11.175                  viBB.validate(gc);
  11.176 -                viRef = new WeakReference<VolatileImage>(viBB);
  11.177              }
  11.178  
  11.179 -            return clearImage(viBB);
  11.180 +            return clear ? clearImage(viBB) : viBB;
  11.181          }
  11.182  
  11.183          @Override
  11.184          public void flush() {
  11.185 -            if (viRef != null) {
  11.186 -                VolatileImage viBB = viRef.get();
  11.187 -                if (viBB != null) {
  11.188 -                    viBB.flush();
  11.189 -                    viBB = null;
  11.190 -                }
  11.191 -                viRef.clear();
  11.192 +            if (viBB != null) {
  11.193 +                viBB.flush();
  11.194 +                viBB = null;
  11.195              }
  11.196          }
  11.197      }
    12.1 --- a/src/windows/classes/sun/awt/windows/WCanvasPeer.java	Tue May 19 17:03:13 2009 +0400
    12.2 +++ b/src/windows/classes/sun/awt/windows/WCanvasPeer.java	Thu May 21 12:29:25 2009 +0400
    12.3 @@ -78,25 +78,6 @@
    12.4          super.paint(g);
    12.5      }
    12.6  
    12.7 -    public void print(Graphics g) {
    12.8 -        if (!(target instanceof Window) ||
    12.9 -            AWTAccessor.getWindowAccessor().isOpaque((Window)target))
   12.10 -        {
   12.11 -            Dimension d = ((Component)target).getSize();
   12.12 -            if (g instanceof Graphics2D ||
   12.13 -                g instanceof sun.awt.Graphics2Delegate) {
   12.14 -                // background color is setup correctly, so just use clearRect
   12.15 -                g.clearRect(0, 0, d.width, d.height);
   12.16 -            } else {
   12.17 -                // emulate clearRect
   12.18 -                g.setColor(((Component)target).getBackground());
   12.19 -                g.fillRect(0, 0, d.width, d.height);
   12.20 -                g.setColor(((Component)target).getForeground());
   12.21 -            }
   12.22 -        }
   12.23 -        super.print(g);
   12.24 -    }
   12.25 -
   12.26      public boolean shouldClearRectBeforePaint() {
   12.27          return eraseBackground;
   12.28      }
    13.1 --- a/src/windows/classes/sun/awt/windows/WComponentPeer.java	Tue May 19 17:03:13 2009 +0400
    13.2 +++ b/src/windows/classes/sun/awt/windows/WComponentPeer.java	Thu May 21 12:29:25 2009 +0400
    13.3 @@ -239,7 +239,8 @@
    13.4  
    13.5      private static final double BANDING_DIVISOR = 4.0;
    13.6      private native int[] createPrintedPixels(int srcX, int srcY,
    13.7 -                                             int srcW, int srcH);
    13.8 +                                             int srcW, int srcH,
    13.9 +                                             int alpha);
   13.10      public void print(Graphics g) {
   13.11  
   13.12          Component comp = (Component)target;
   13.13 @@ -261,7 +262,9 @@
   13.14              }
   13.15              int h = endY - startY + 1;
   13.16  
   13.17 -            int[] pix = createPrintedPixels(0, startY, totalW, h);
   13.18 +            Color bgColor = comp.getBackground();
   13.19 +            int[] pix = createPrintedPixels(0, startY, totalW, h,
   13.20 +                                            bgColor == null ? 255 : bgColor.getAlpha());
   13.21              if (pix != null) {
   13.22                  BufferedImage bim = new BufferedImage(totalW, h,
   13.23                                                BufferedImage.TYPE_INT_ARGB);
    14.1 --- a/src/windows/classes/sun/awt/windows/WObjectPeer.java	Tue May 19 17:03:13 2009 +0400
    14.2 +++ b/src/windows/classes/sun/awt/windows/WObjectPeer.java	Thu May 21 12:29:25 2009 +0400
    14.3 @@ -42,6 +42,9 @@
    14.4      // set from JNI if any errors in creating the peer occur
    14.5      protected Error createError = null;
    14.6  
    14.7 +    // used to synchronize the state of this peer
    14.8 +    private final Object stateLock = new Object();
    14.9 +
   14.10      public static WObjectPeer getPeerForTarget(Object t) {
   14.11          WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t);
   14.12          return peer;
   14.13 @@ -55,6 +58,10 @@
   14.14          return target;
   14.15      }
   14.16  
   14.17 +    public final Object getStateLock() {
   14.18 +        return stateLock;
   14.19 +    }
   14.20 +
   14.21      /*
   14.22       * Subclasses should override disposeImpl() instead of dispose(). Client
   14.23       * code should always invoke dispose(), never disposeImpl().
    15.1 --- a/src/windows/classes/sun/awt/windows/WWindowPeer.java	Tue May 19 17:03:13 2009 +0400
    15.2 +++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java	Thu May 21 12:29:25 2009 +0400
    15.3 @@ -54,7 +54,7 @@
    15.4  
    15.5      private boolean isOpaque;
    15.6  
    15.7 -    private volatile TranslucentWindowPainter painter;
    15.8 +    private TranslucentWindowPainter painter;
    15.9  
   15.10      /*
   15.11       * A key used for storing a list of active windows in AppContext. The value
   15.12 @@ -106,11 +106,13 @@
   15.13          GraphicsConfiguration gc = getGraphicsConfiguration();
   15.14          ((Win32GraphicsDevice)gc.getDevice()).removeDisplayChangedListener(this);
   15.15  
   15.16 -        TranslucentWindowPainter currentPainter = painter;
   15.17 -        if (currentPainter != null) {
   15.18 -            currentPainter.flush();
   15.19 -            // don't set the current one to null here; reduces the chances of
   15.20 -            // MT issues (like NPEs)
   15.21 +        synchronized (getStateLock()) {
   15.22 +            TranslucentWindowPainter currentPainter = painter;
   15.23 +            if (currentPainter != null) {
   15.24 +                currentPainter.flush();
   15.25 +                // don't set the current one to null here; reduces the chances of
   15.26 +                // MT issues (like NPEs)
   15.27 +            }
   15.28          }
   15.29  
   15.30          super.disposeImpl();
   15.31 @@ -178,9 +180,23 @@
   15.32  
   15.33          updateIconImages();
   15.34  
   15.35 -        updateShape();
   15.36 -        updateOpacity();
   15.37 -        updateOpaque();
   15.38 +        Shape shape = ((Window)target).getShape();
   15.39 +        if (shape != null) {
   15.40 +            applyShape(Region.getInstance(shape, null));
   15.41 +        }
   15.42 +
   15.43 +        float opacity = ((Window)target).getOpacity();
   15.44 +        if (opacity < 1.0f) {
   15.45 +            setOpacity(opacity);
   15.46 +        }
   15.47 +
   15.48 +        synchronized (getStateLock()) {
   15.49 +            // default value of a boolean field is 'false', so set isOpaque to
   15.50 +            // true here explicitly
   15.51 +            this.isOpaque = true;
   15.52 +            Color bgColor = ((Window)target).getBackground();
   15.53 +            setOpaque((bgColor == null) || (bgColor.getAlpha() == 255));
   15.54 +        }
   15.55      }
   15.56  
   15.57      native void createAwtWindow(WComponentPeer parent);
   15.58 @@ -214,7 +230,11 @@
   15.59              setAlwaysOnTop(alwaysOnTop);
   15.60          }
   15.61  
   15.62 -        updateWindow(null);
   15.63 +        synchronized (getStateLock()) {
   15.64 +            if (!isOpaque) {
   15.65 +                updateWindow(true);
   15.66 +            }
   15.67 +        }
   15.68      }
   15.69  
   15.70      // Synchronize the insets members (here & in helper) with actual window
   15.71 @@ -334,29 +354,6 @@
   15.72          }
   15.73      }
   15.74  
   15.75 -    private void updateShape() {
   15.76 -        Shape shape = ((Window)target).getShape();
   15.77 -        if (shape != null) {
   15.78 -            applyShape(Region.getInstance(shape, null));
   15.79 -        }
   15.80 -    }
   15.81 -
   15.82 -    private void updateOpacity() {
   15.83 -        float opacity = ((Window)target).getOpacity();
   15.84 -        if (opacity < 1.0f) {
   15.85 -            setOpacity(opacity);
   15.86 -        }
   15.87 -    }
   15.88 -
   15.89 -    private void updateOpaque() {
   15.90 -        this.isOpaque = true;
   15.91 -        // boolean opaque = ((Window)target).isOpaque();
   15.92 -        boolean opaque = AWTAccessor.getWindowAccessor().isOpaque((Window)target);
   15.93 -        if (!opaque) {
   15.94 -            setOpaque(opaque);
   15.95 -        }
   15.96 -    }
   15.97 -
   15.98      native void setMinSize(int width, int height);
   15.99  
  15.100  /*
  15.101 @@ -579,6 +576,26 @@
  15.102          }
  15.103      }
  15.104  
  15.105 +    @Override
  15.106 +    public Graphics getGraphics() {
  15.107 +        synchronized (getStateLock()) {
  15.108 +            if (!isOpaque) {
  15.109 +                return painter.getBackBuffer(false).getGraphics();
  15.110 +            }
  15.111 +        }
  15.112 +        return super.getGraphics();
  15.113 +    }
  15.114 +
  15.115 +    @Override
  15.116 +    public void setBackground(Color c) {
  15.117 +        super.setBackground(c);
  15.118 +        synchronized (getStateLock()) {
  15.119 +            if (!isOpaque && ((Window)target).isVisible()) {
  15.120 +                updateWindow(true);
  15.121 +            }
  15.122 +        }
  15.123 +    }
  15.124 +
  15.125      private native void setOpacity(int iOpacity);
  15.126  
  15.127      public void setOpacity(float opacity) {
  15.128 @@ -600,12 +617,23 @@
  15.129          }
  15.130  
  15.131          setOpacity(iOpacity);
  15.132 -        updateWindow(null);
  15.133 +
  15.134 +        synchronized (getStateLock()) {
  15.135 +            if (!isOpaque && ((Window)target).isVisible()) {
  15.136 +                updateWindow(true);
  15.137 +            }
  15.138 +        }
  15.139      }
  15.140  
  15.141      private native void setOpaqueImpl(boolean isOpaque);
  15.142  
  15.143      public void setOpaque(boolean isOpaque) {
  15.144 +        synchronized (getStateLock()) {
  15.145 +            if (this.isOpaque == isOpaque) {
  15.146 +                return;
  15.147 +            }
  15.148 +        }
  15.149 +
  15.150          Window target = (Window)getTarget();
  15.151  
  15.152          if (!isOpaque) {
  15.153 @@ -617,20 +645,17 @@
  15.154              }
  15.155          }
  15.156  
  15.157 -        boolean opaqueChanged = this.isOpaque != isOpaque;
  15.158          boolean isVistaOS = Win32GraphicsEnvironment.isVistaOS();
  15.159  
  15.160 -        if (opaqueChanged && !isVistaOS){
  15.161 +        if (!isVistaOS) {
  15.162              // non-Vista OS: only replace the surface data if the opacity
  15.163              // status changed (see WComponentPeer.isAccelCapable() for more)
  15.164              replaceSurfaceDataRecursively(target);
  15.165          }
  15.166  
  15.167 -        this.isOpaque = isOpaque;
  15.168 -
  15.169 -        setOpaqueImpl(isOpaque);
  15.170 -
  15.171 -        if (opaqueChanged) {
  15.172 +        synchronized (getStateLock()) {
  15.173 +            this.isOpaque = isOpaque;
  15.174 +            setOpaqueImpl(isOpaque);
  15.175              if (isOpaque) {
  15.176                  TranslucentWindowPainter currentPainter = painter;
  15.177                  if (currentPainter != null) {
  15.178 @@ -642,7 +667,7 @@
  15.179              }
  15.180          }
  15.181  
  15.182 -        if (opaqueChanged && isVistaOS) {
  15.183 +        if (isVistaOS) {
  15.184              // On Vista: setting the window non-opaque makes the window look
  15.185              // rectangular, though still catching the mouse clicks within
  15.186              // its shape only. To restore the correct visual appearance
  15.187 @@ -654,42 +679,33 @@
  15.188              }
  15.189          }
  15.190  
  15.191 -        updateWindow(null);
  15.192 +        if (((Window)target).isVisible()) {
  15.193 +            updateWindow(true);
  15.194 +        }
  15.195      }
  15.196  
  15.197      public native void updateWindowImpl(int[] data, int width, int height);
  15.198  
  15.199 -    public void updateWindow(BufferedImage backBuffer) {
  15.200 -        if (isOpaque) {
  15.201 -            return;
  15.202 -        }
  15.203 -
  15.204 -        Component target = (Component)this.target;
  15.205 -        if (target.getWidth() <= 0 || target.getHeight() <= 0) {
  15.206 -            return;
  15.207 -        }
  15.208 -
  15.209 -        TranslucentWindowPainter currentPainter = painter;
  15.210 -        if (currentPainter != null) {
  15.211 -            currentPainter.updateWindow(backBuffer);
  15.212 -        } else if (log.isLoggable(Level.FINER)) {
  15.213 -            log.log(Level.FINER,
  15.214 -                    "Translucent window painter is null in updateWindow");
  15.215 -        }
  15.216 +    public void updateWindow() {
  15.217 +        updateWindow(false);
  15.218      }
  15.219  
  15.220 -    /**
  15.221 -     * Paints the Applet Warning into the passed Graphics2D. This method is
  15.222 -     * called by the TranslucentWindowPainter before updating the layered
  15.223 -     * window.
  15.224 -     *
  15.225 -     * @param g Graphics context to paint the warning to
  15.226 -     * @param w the width of the area
  15.227 -     * @param h the height of the area
  15.228 -     * @see TranslucentWindowPainter
  15.229 -     */
  15.230 -    public void paintAppletWarning(Graphics2D g, int w, int h) {
  15.231 -        // REMIND: the applet warning needs to be painted here
  15.232 +    private void updateWindow(boolean repaint) {
  15.233 +        Window w = (Window)target;
  15.234 +        synchronized (getStateLock()) {
  15.235 +            if (isOpaque || !w.isVisible() ||
  15.236 +                (w.getWidth() <= 0) || (w.getHeight() <= 0))
  15.237 +            {
  15.238 +                return;
  15.239 +            }
  15.240 +            TranslucentWindowPainter currentPainter = painter;
  15.241 +            if (currentPainter != null) {
  15.242 +                currentPainter.updateWindow(repaint);
  15.243 +            } else if (log.isLoggable(Level.FINER)) {
  15.244 +                log.log(Level.FINER,
  15.245 +                        "Translucent window painter is null in updateWindow");
  15.246 +            }
  15.247 +        }
  15.248      }
  15.249  
  15.250      /*
    16.1 --- a/src/windows/native/sun/windows/awt_Component.cpp	Tue May 19 17:03:13 2009 +0400
    16.2 +++ b/src/windows/native/sun/windows/awt_Component.cpp	Thu May 21 12:29:25 2009 +0400
    16.3 @@ -30,6 +30,7 @@
    16.4  
    16.5  #include "jlong.h"
    16.6  #include "awt_AWTEvent.h"
    16.7 +#include "awt_BitmapUtil.h"
    16.8  #include "awt_Component.h"
    16.9  #include "awt_Cursor.h"
   16.10  #include "awt_Dimension.h"
   16.11 @@ -127,6 +128,7 @@
   16.12      jobject component;
   16.13      int srcx, srcy;
   16.14      int srcw, srch;
   16.15 +    jint alpha;
   16.16  };
   16.17  // Struct for _SetRectangularShape() method
   16.18  struct SetRectangularShapeStruct {
   16.19 @@ -361,8 +363,8 @@
   16.20  AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) {
   16.21      AwtComponent *component =
   16.22          (AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
   16.23 -    DASSERT( !IsBadReadPtr(component, sizeof(AwtComponent)) );
   16.24 -    DASSERT( component->GetHWnd() == hWnd );
   16.25 +    DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) );
   16.26 +    DASSERT(!component || component->GetHWnd() == hWnd );
   16.27      return component;
   16.28  }
   16.29  
   16.30 @@ -1918,11 +1920,14 @@
   16.31            mr = mrConsume;
   16.32            break;
   16.33        }
   16.34 -      case WM_AWT_CREATE_PRINTED_PIXELS:
   16.35 -          retValue = (LRESULT)CreatePrintedPixels(*((SIZE *)wParam),
   16.36 -                                                  *((SIZE *)lParam));
   16.37 +      case WM_AWT_CREATE_PRINTED_PIXELS: {
   16.38 +          CreatePrintedPixelsStruct* cpps = (CreatePrintedPixelsStruct*)wParam;
   16.39 +          SIZE loc = { cpps->srcx, cpps->srcy };
   16.40 +          SIZE size = { cpps->srcw, cpps->srch };
   16.41 +          retValue = (LRESULT)CreatePrintedPixels(loc, size, cpps->alpha);
   16.42            mr = mrConsume;
   16.43            break;
   16.44 +      }
   16.45        case WM_UNDOCUMENTED_CLICKMENUBAR:
   16.46        {
   16.47            if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) {
   16.48 @@ -4526,18 +4531,20 @@
   16.49  
   16.50  void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
   16.51  {
   16.52 -    if (bitmapBits) {
   16.53 -        DWORD* dest = (DWORD*)bitmapBits;
   16.54 -        //XXX: might be optimized to use one loop (cy*cx -> 0).
   16.55 -        for (int i = 0; i < size.cy; i++ ) {
   16.56 -            for (int j = 0; j < size.cx; j++ ) {
   16.57 -                ((BYTE*)(dest++))[3] = alpha;
   16.58 -            }
   16.59 +    if (!bitmapBits) {
   16.60 +        return;
   16.61 +    }
   16.62 +
   16.63 +    DWORD* dest = (DWORD*)bitmapBits;
   16.64 +    //XXX: might be optimized to use one loop (cy*cx -> 0)
   16.65 +    for (int i = 0; i < size.cy; i++ ) {
   16.66 +        for (int j = 0; j < size.cx; j++ ) {
   16.67 +            ((BYTE*)(dest++))[3] = alpha;
   16.68          }
   16.69      }
   16.70  }
   16.71  
   16.72 -jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {
   16.73 +jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) {
   16.74      JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
   16.75  
   16.76      if (!::IsWindowVisible(GetHWnd())) {
   16.77 @@ -4549,12 +4556,12 @@
   16.78          return NULL;
   16.79      }
   16.80      HDC hMemoryDC = ::CreateCompatibleDC(hdc);
   16.81 -    HBITMAP hBitmap = ::CreateCompatibleBitmap(hdc, size.cx, size.cy);
   16.82 +    void *bitmapBits = NULL;
   16.83 +    HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, &bitmapBits);
   16.84      HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap);
   16.85      SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc);
   16.86  
   16.87 -    RECT eraseR = { 0, 0, size.cx, size.cy };
   16.88 -    VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush()));
   16.89 +    FillBackground(hMemoryDC, size);
   16.90  
   16.91      VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL));
   16.92  
   16.93 @@ -4562,6 +4569,14 @@
   16.94      // above.
   16.95      SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT);
   16.96  
   16.97 +    // First make sure the system completed any drawing to the bitmap.
   16.98 +    ::GdiFlush();
   16.99 +
  16.100 +    // WM_PRINT does not fill the alpha-channel of the ARGB bitmap
  16.101 +    // leaving it equal to zero. Hence we need to fill it manually. Otherwise
  16.102 +    // the pixels will be considered transparent when interpreting the data.
  16.103 +    FillAlpha(bitmapBits, size, alpha);
  16.104 +
  16.105      ::SelectObject(hMemoryDC, hOldBitmap);
  16.106  
  16.107      BITMAPINFO bmi;
  16.108 @@ -5937,10 +5952,6 @@
  16.109  
  16.110      CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param;
  16.111      jobject self = cpps->component;
  16.112 -    jint srcx = cpps->srcx;
  16.113 -    jint srcy = cpps->srcy;
  16.114 -    jint srcw = cpps->srcw;
  16.115 -    jint srch = cpps->srch;
  16.116  
  16.117      jintArray result = NULL;
  16.118      AwtComponent *c = NULL;
  16.119 @@ -5950,12 +5961,7 @@
  16.120      c = (AwtComponent *)pData;
  16.121      if (::IsWindow(c->GetHWnd()))
  16.122      {
  16.123 -        SIZE loc = { srcx, srcy };
  16.124 -        SIZE size = { srcw, srch };
  16.125 -
  16.126 -        result = (jintArray)
  16.127 -            c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)&loc,
  16.128 -                          (LPARAM)&size);
  16.129 +        result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0);
  16.130      }
  16.131  ret:
  16.132      env->DeleteGlobalRef(self);
  16.133 @@ -6749,7 +6755,7 @@
  16.134   */
  16.135  JNIEXPORT jintArray JNICALL
  16.136  Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env,
  16.137 -    jobject self, jint srcX, jint srcY, jint srcW, jint srcH)
  16.138 +    jobject self, jint srcX, jint srcY, jint srcW, jint srcH, jint alpha)
  16.139  {
  16.140      TRY;
  16.141  
  16.142 @@ -6761,6 +6767,7 @@
  16.143      cpps->srcy = srcY;
  16.144      cpps->srcw = srcW;
  16.145      cpps->srch = srcH;
  16.146 +    cpps->alpha = alpha;
  16.147  
  16.148      jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall(
  16.149          (void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps);
    17.1 --- a/src/windows/native/sun/windows/awt_Component.h	Tue May 19 17:03:13 2009 +0400
    17.2 +++ b/src/windows/native/sun/windows/awt_Component.h	Thu May 21 12:29:25 2009 +0400
    17.3 @@ -596,7 +596,7 @@
    17.4  
    17.5      void UpdateColorModel();
    17.6  
    17.7 -    jintArray CreatePrintedPixels(SIZE &loc, SIZE &size);
    17.8 +    jintArray CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha);
    17.9  
   17.10      /*
   17.11       * HWND, AwtComponent and Java Peer interaction
   17.12 @@ -738,7 +738,6 @@
   17.13      virtual void SetDragCapture(UINT flags);
   17.14      virtual void ReleaseDragCapture(UINT flags);
   17.15  
   17.16 -    //These functions are overridden in AwtWindow to handle non-opaque windows.
   17.17      virtual void FillBackground(HDC hMemoryDC, SIZE &size);
   17.18      virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
   17.19  
    18.1 --- a/src/windows/native/sun/windows/awt_Window.cpp	Tue May 19 17:03:13 2009 +0400
    18.2 +++ b/src/windows/native/sun/windows/awt_Window.cpp	Thu May 21 12:29:25 2009 +0400
    18.3 @@ -464,7 +464,7 @@
    18.4          size_t length = env->GetStringLength(javaWarningString) + 1;
    18.5          warningString = new WCHAR[length];
    18.6          env->GetStringRegion(javaWarningString, 0,
    18.7 -                static_cast<jsize>(length - 1), warningString);
    18.8 +                static_cast<jsize>(length - 1), reinterpret_cast<jchar*>(warningString));
    18.9          warningString[length-1] = L'\0';
   18.10  
   18.11          env->DeleteLocalRef(javaWarningString);
   18.12 @@ -2651,20 +2651,6 @@
   18.13      ::LeaveCriticalSection(&contentBitmapCS);
   18.14  }
   18.15  
   18.16 -void AwtWindow::FillBackground(HDC hMemoryDC, SIZE &size)
   18.17 -{
   18.18 -    if (isOpaque()) {
   18.19 -        AwtCanvas::FillBackground(hMemoryDC, size);
   18.20 -    }
   18.21 -}
   18.22 -
   18.23 -void AwtWindow::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
   18.24 -{
   18.25 -    if (isOpaque()) {
   18.26 -        AwtCanvas::FillAlpha(bitmapBits, size, alpha);
   18.27 -    }
   18.28 -}
   18.29 -
   18.30  /*
   18.31   * Fixed 6353381: it's improved fix for 4792958
   18.32   * which was backed-out to avoid 5059656
    19.1 --- a/src/windows/native/sun/windows/awt_Window.h	Tue May 19 17:03:13 2009 +0400
    19.2 +++ b/src/windows/native/sun/windows/awt_Window.h	Thu May 21 12:29:25 2009 +0400
    19.3 @@ -343,11 +343,6 @@
    19.4      BOOL m_iconInherited;     /* TRUE if icon is inherited from the owner */
    19.5      BOOL m_filterFocusAndActivation; /* Used in the WH_CBT hook */
    19.6  
    19.7 -    //These are used in AwtComponent::CreatePrintedPixels. They are overridden
    19.8 -    //here to handle non-opaque windows.
    19.9 -    virtual void FillBackground(HDC hMemoryDC, SIZE &size);
   19.10 -    virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
   19.11 -
   19.12      inline BOOL IsUntrusted() {
   19.13          return warningString != NULL;
   19.14      }
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/javax/swing/JComponent/6683775/bug6683775.java	Thu May 21 12:29:25 2009 +0400
    20.3 @@ -0,0 +1,82 @@
    20.4 +/* @test
    20.5 +   @bug 6683775 6794764
    20.6 +   @summary Painting artifacts is seen when panel is made setOpaque(false) for a translucent window
    20.7 +   @author Alexander Potochkin
    20.8 +   @run main bug6683775
    20.9 +*/
   20.10 +
   20.11 +import com.sun.awt.AWTUtilities;
   20.12 +import sun.awt.SunToolkit;
   20.13 +
   20.14 +import javax.swing.*;
   20.15 +import java.awt.*;
   20.16 +import java.awt.image.BufferedImage;
   20.17 +
   20.18 +public class bug6683775 {
   20.19 +    public static void main(String[] args) throws Exception {
   20.20 +        GraphicsConfiguration gc = getGC();
   20.21 +        if (!AWTUtilities.isTranslucencySupported(
   20.22 +                AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT)
   20.23 +                || gc == null) {
   20.24 +            return;
   20.25 +        }
   20.26 +        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
   20.27 +        Robot robot = new Robot();
   20.28 +        final JFrame testFrame = new JFrame(gc);
   20.29 +
   20.30 +        SwingUtilities.invokeLater(new Runnable() {
   20.31 +            public void run() {
   20.32 +                JFrame backgroundFrame = new JFrame("Background frame");
   20.33 +                backgroundFrame.setUndecorated(true);
   20.34 +                JPanel panel = new JPanel();
   20.35 +                panel.setBackground(Color.RED);
   20.36 +                backgroundFrame.add(panel);
   20.37 +                backgroundFrame.setSize(200, 200);
   20.38 +                backgroundFrame.setVisible(true);
   20.39 +
   20.40 +                testFrame.setUndecorated(true);
   20.41 +                JPanel p = new JPanel();
   20.42 +                p.setOpaque(false);
   20.43 +                testFrame.add(p);
   20.44 +                AWTUtilities.setWindowOpaque(testFrame, false);
   20.45 +                testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   20.46 +                testFrame.setSize(400, 400);
   20.47 +                testFrame.setLocation(0, 0);
   20.48 +                testFrame.setVisible(true);
   20.49 +            }
   20.50 +        });
   20.51 +
   20.52 +        toolkit.realSync();
   20.53 +
   20.54 +        //robot.getPixelColor() didn't work right for some reason
   20.55 +        BufferedImage capture = robot.createScreenCapture(new Rectangle(100, 100));
   20.56 +
   20.57 +        int redRGB = Color.RED.getRGB();
   20.58 +        if (redRGB != capture.getRGB(10, 10)) {
   20.59 +            throw new RuntimeException("Transparent frame is not transparent!");
   20.60 +        }
   20.61 +    }
   20.62 +
   20.63 +    private static GraphicsConfiguration getGC() {
   20.64 +        GraphicsConfiguration transparencyCapableGC =
   20.65 +                GraphicsEnvironment.getLocalGraphicsEnvironment()
   20.66 +                        .getDefaultScreenDevice().getDefaultConfiguration();
   20.67 +        if (!AWTUtilities.isTranslucencyCapable(transparencyCapableGC)) {
   20.68 +            transparencyCapableGC = null;
   20.69 +
   20.70 +            GraphicsEnvironment env =
   20.71 +                    GraphicsEnvironment.getLocalGraphicsEnvironment();
   20.72 +            GraphicsDevice[] devices = env.getScreenDevices();
   20.73 +
   20.74 +            for (int i = 0; i < devices.length && transparencyCapableGC == null; i++) {
   20.75 +                GraphicsConfiguration[] configs = devices[i].getConfigurations();
   20.76 +                for (int j = 0; j < configs.length && transparencyCapableGC == null; j++) {
   20.77 +                    if (AWTUtilities.isTranslucencyCapable(configs[j])) {
   20.78 +                        transparencyCapableGC = configs[j];
   20.79 +                    }
   20.80 +                }
   20.81 +            }
   20.82 +        }
   20.83 +        return transparencyCapableGC;
   20.84 +    }
   20.85 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/test/javax/swing/JInternalFrame/6726866/bug6726866.html	Thu May 21 12:29:25 2009 +0400
    21.3 @@ -0,0 +1,7 @@
    21.4 +<html>
    21.5 +<body>
    21.6 +<applet  code="bug6726866.class" width=400 height=100></applet>
    21.7 +Drag the internal frame inside the green undecorated window,
    21.8 +if you can drag it the test passes, otherwise fails.
    21.9 +</body>
   21.10 +</html>
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/test/javax/swing/JInternalFrame/6726866/bug6726866.java	Thu May 21 12:29:25 2009 +0400
    22.3 @@ -0,0 +1,44 @@
    22.4 +/* @test
    22.5 +   @bug 6726866
    22.6 +   @summary Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel
    22.7 +   @author Alexander Potochkin
    22.8 +   @run applet/manual=yesno bug6726866.html
    22.9 +*/
   22.10 +
   22.11 +import javax.swing.*;
   22.12 +import java.awt.*;
   22.13 +import java.lang.reflect.Method;
   22.14 +
   22.15 +public class bug6726866 extends JApplet {
   22.16 +
   22.17 +    public void init() {
   22.18 +        JFrame frame = new JFrame("bug6726866");
   22.19 +        frame.setUndecorated(true);
   22.20 +        setWindowNonOpaque(frame);
   22.21 +
   22.22 +        JDesktopPane desktop = new JDesktopPane();
   22.23 +        desktop.setBackground(Color.GREEN);
   22.24 +        JInternalFrame iFrame = new JInternalFrame("Test", true, true, true, true);
   22.25 +        iFrame.add(new JLabel("internal Frame"));
   22.26 +        iFrame.setBounds(10, 10, 300, 200);
   22.27 +        iFrame.setVisible(true);
   22.28 +        desktop.add(iFrame);
   22.29 +        frame.add(desktop);
   22.30 +
   22.31 +        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   22.32 +        frame.setSize(400, 400);
   22.33 +        frame.setVisible(true);
   22.34 +        frame.toFront();
   22.35 +    }
   22.36 +
   22.37 +    private void setWindowNonOpaque(Window w) {
   22.38 +        try {
   22.39 +            Class<?> c = Class.forName("com.sun.awt.AWTUtilities");
   22.40 +            Method m = c.getMethod("setWindowOpaque", Window.class, boolean.class);
   22.41 +            m.invoke(null, w, false);
   22.42 +        }
   22.43 +        catch (Exception e) {
   22.44 +            e.printStackTrace();
   22.45 +        }
   22.46 +    }
   22.47 +}