--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Thu Oct 28 15:46:39 2010 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Mon Nov 08 17:51:35 2010 +0300
@@ -6084,63 +6084,67 @@
void AwtComponent::_SetRectangularShape(void *param)
{
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-
- SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param;
- jobject self = data->component;
- jint x1 = data->x1;
- jint x2 = data->x2;
- jint y1 = data->y1;
- jint y2 = data->y2;
- jobject region = data->region;
-
- AwtComponent *c = NULL;
-
- PDATA pData;
- JNI_CHECK_PEER_GOTO(self, ret);
-
- c = (AwtComponent *)pData;
- if (::IsWindow(c->GetHWnd())) {
- HRGN hRgn = NULL;
- if (region || x1 || x2 || y1 || y2) {
- // If all the params are zeros, the shape must be simply reset.
- // Otherwise, convert it into a region.
- RGNDATA *pRgnData = NULL;
- RGNDATAHEADER *pRgnHdr;
-
- /* reserving memory for the worst case */
- size_t worstBufferSize = size_t(((x2 - x1) / 2 + 1) * (y2 - y1));
- pRgnData = (RGNDATA *) safe_Malloc(sizeof(RGNDATAHEADER) +
- sizeof(RECT_T) * worstBufferSize);
- pRgnHdr = (RGNDATAHEADER *) pRgnData;
-
- pRgnHdr->dwSize = sizeof(RGNDATAHEADER);
- pRgnHdr->iType = RDH_RECTANGLES;
- pRgnHdr->nRgnSize = 0;
- pRgnHdr->rcBound.top = 0;
- pRgnHdr->rcBound.left = 0;
- pRgnHdr->rcBound.bottom = LONG(y2 - y1);
- pRgnHdr->rcBound.right = LONG(x2 - x1);
-
- RECT_T * pRect = (RECT_T *) (((BYTE *) pRgnData) + sizeof(RGNDATAHEADER));
- pRgnHdr->nCount = RegionToYXBandedRectangles(env, x1, y1, x2, y2, region, &pRect, worstBufferSize);
-
- hRgn = ::ExtCreateRegion(NULL,
- sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData);
-
- free(pRgnData);
+ if (!AwtToolkit::IsMainThread()) {
+ AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetRectangularShape, param);
+ } else {
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param;
+ jobject self = data->component;
+ jint x1 = data->x1;
+ jint x2 = data->x2;
+ jint y1 = data->y1;
+ jint y2 = data->y2;
+ jobject region = data->region;
+
+ AwtComponent *c = NULL;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+
+ c = (AwtComponent *)pData;
+ if (::IsWindow(c->GetHWnd())) {
+ HRGN hRgn = NULL;
+ if (region || x1 || x2 || y1 || y2) {
+ // If all the params are zeros, the shape must be simply reset.
+ // Otherwise, convert it into a region.
+ RGNDATA *pRgnData = NULL;
+ RGNDATAHEADER *pRgnHdr;
+
+ /* reserving memory for the worst case */
+ size_t worstBufferSize = size_t(((x2 - x1) / 2 + 1) * (y2 - y1));
+ pRgnData = (RGNDATA *) safe_Malloc(sizeof(RGNDATAHEADER) +
+ sizeof(RECT_T) * worstBufferSize);
+ pRgnHdr = (RGNDATAHEADER *) pRgnData;
+
+ pRgnHdr->dwSize = sizeof(RGNDATAHEADER);
+ pRgnHdr->iType = RDH_RECTANGLES;
+ pRgnHdr->nRgnSize = 0;
+ pRgnHdr->rcBound.top = 0;
+ pRgnHdr->rcBound.left = 0;
+ pRgnHdr->rcBound.bottom = LONG(y2 - y1);
+ pRgnHdr->rcBound.right = LONG(x2 - x1);
+
+ RECT_T * pRect = (RECT_T *) (((BYTE *) pRgnData) + sizeof(RGNDATAHEADER));
+ pRgnHdr->nCount = RegionToYXBandedRectangles(env, x1, y1, x2, y2, region, &pRect, worstBufferSize);
+
+ hRgn = ::ExtCreateRegion(NULL,
+ sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData);
+
+ free(pRgnData);
+ }
+
+ ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE);
}
- ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE);
- }
-
ret:
- env->DeleteGlobalRef(self);
- if (region) {
- env->DeleteGlobalRef(region);
- }
-
- delete data;
+ env->DeleteGlobalRef(self);
+ if (region) {
+ env->DeleteGlobalRef(region);
+ }
+
+ delete data;
+ }
}
void AwtComponent::_SetZOrder(void *param) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java Mon Nov 08 17:51:35 2010 +0300
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 6988428
+ @summary Tests whether shape is always set
+ @author anthony.petrov@oracle.com: area=awt.toplevel
+ @run main ShapeNotSetSometimes
+*/
+
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.geom.*;
+
+
+public class ShapeNotSetSometimes {
+
+ private Frame backgroundFrame;
+ private Frame window;
+ private static final Color BACKGROUND_COLOR = Color.BLUE;
+ private Shape shape;
+ private int[][] pointsToCheck;
+
+ private static Robot robot;
+
+ public ShapeNotSetSometimes() throws Exception {
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ initializeGUI();
+ }
+ });
+ }
+
+ private void initializeGUI() {
+ backgroundFrame = new BackgroundFrame();
+ backgroundFrame.setUndecorated(true);
+ backgroundFrame.setSize(300, 300);
+ backgroundFrame.setLocation(20, 400);
+ backgroundFrame.setVisible(true);
+
+ shape = null;
+ String shape_name = null;
+ Area a;
+ GeneralPath gp;
+ shape_name = "Rounded-corners";
+ a = new Area();
+ a.add(new Area(new Rectangle2D.Float(50, 0, 100, 150)));
+ a.add(new Area(new Rectangle2D.Float(0, 50, 200, 50)));
+ a.add(new Area(new Ellipse2D.Float(0, 0, 100, 100)));
+ a.add(new Area(new Ellipse2D.Float(0, 50, 100, 100)));
+ a.add(new Area(new Ellipse2D.Float(100, 0, 100, 100)));
+ a.add(new Area(new Ellipse2D.Float(100, 50, 100, 100)));
+ shape = a;
+ pointsToCheck = new int[][] {
+ // inside shape
+ {106, 86}, {96, 38}, {76, 107}, {180, 25}, {24, 105},
+ {196, 77}, {165, 50}, {14, 113}, {89, 132}, {167, 117},
+ // outside shape
+ {165, 196}, {191, 163}, {146, 185}, {61, 170}, {148, 171},
+ {82, 172}, {186, 11}, {199, 141}, {13, 173}, {187, 3}
+ };
+
+ window = new TestFrame();
+ window.setUndecorated(true);
+ window.setSize(200, 200);
+ window.setLocation(70, 450);
+ window.setShape(shape);
+ window.setVisible(true);
+
+ System.out.println("Checking " + window.getClass().getSuperclass().getName() + " with " + shape_name + " shape (" + window.getShape() + ")...");
+ }
+
+ class BackgroundFrame extends Frame {
+
+ @Override
+ public void paint(Graphics g) {
+
+ g.setColor(BACKGROUND_COLOR);
+ g.fillRect(0, 0, 300, 300);
+
+ super.paint(g);
+ }
+ }
+
+ class TestFrame extends Frame {
+
+ @Override
+ public void paint(Graphics g) {
+
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, 200, 200);
+
+ super.paint(g);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ robot = new Robot();
+
+ for(int i = 0; i < 100; i++) {
+ System.out.println("Attempt " + i);
+ new ShapeNotSetSometimes().doTest();
+ }
+ }
+
+ private void doTest() throws Exception {
+ Point wls = backgroundFrame.getLocationOnScreen();
+
+ robot.mouseMove(wls.x + 5, wls.y + 5);
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.delay(10);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+ robot.delay(500);
+
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ window.requestFocus();
+ }
+ });
+
+ robot.waitForIdle();
+ try {
+ Thread.sleep(300);
+ } catch (InterruptedException e) {
+ // ignore this one
+ }
+
+ // check transparency
+ final int COUNT_TARGET = 10;
+
+ // checking outside points only
+ for(int i = COUNT_TARGET; i < COUNT_TARGET * 2; i++) {
+ int x = pointsToCheck[i][0];
+ int y = pointsToCheck[i][1];
+ boolean inside = i < COUNT_TARGET;
+ Color c = robot.getPixelColor(window.getX() + x, window.getY() + y);
+ System.out.println("checking " + x + ", " + y + ", color = " + c);
+ if (inside && BACKGROUND_COLOR.equals(c) || !inside && !BACKGROUND_COLOR.equals(c)) {
+ System.out.println("window.getX() = " + window.getX() + ", window.getY() = " + window.getY());
+ System.err.println("Checking for transparency failed: point: " +
+ (window.getX() + x) + ", " + (window.getY() + y) +
+ ", color = " + c + (inside ? " is of un" : " is not of ") +
+ "expected background color " + BACKGROUND_COLOR);
+ throw new RuntimeException("Test failed. The shape has not been applied.");
+ }
+ }
+
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ backgroundFrame.dispose();
+ window.dispose();
+ }
+ });
+ }
+}