提交 a0f3e845 编写于 作者: M mcherkas

8167110: Windows peering issue

7155957: closed/java/awt/MenuBar/MenuBarStress1/MenuBarStress1.java hangs on win 64 bit with jdk8
8079595: Resizing dialog which is JWindow parent makes JVM crash
8147842: IME Composition Window is displayed at incorrect location
Reviewed-by: serb
上级 ed37ef44
......@@ -411,9 +411,9 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
items.removeElementAt(index);
MenuPeer peer = (MenuPeer)this.peer;
if (peer != null) {
peer.delItem(index);
mi.removeNotify();
mi.parent = null;
peer.delItem(index);
}
}
}
......
......@@ -222,7 +222,6 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
if (m.parent != null) {
m.parent.remove(m);
}
menus.addElement(m);
m.parent = this;
MenuBarPeer peer = (MenuBarPeer)this.peer;
......@@ -232,6 +231,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
}
peer.addMenu(m);
}
menus.addElement(m);
return m;
}
}
......@@ -248,9 +248,9 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
menus.removeElementAt(index);
MenuBarPeer peer = (MenuBarPeer)this.peer;
if (peer != null) {
peer.delMenu(index);
m.removeNotify();
m.parent = null;
peer.delMenu(index);
}
if (helpMenu == m) {
helpMenu = null;
......
......@@ -75,7 +75,7 @@ public abstract class MenuComponent implements java.io.Serializable {
* @see #setFont(Font)
* @see #getFont()
*/
Font font;
volatile Font font;
/**
* The menu component's name, which defaults to <code>null</code>.
......@@ -292,11 +292,13 @@ public abstract class MenuComponent implements java.io.Serializable {
* @see java.awt.font.TextAttribute
*/
public void setFont(Font f) {
font = f;
//Fixed 6312943: NullPointerException in method MenuComponent.setFont(Font)
MenuComponentPeer peer = this.peer;
if (peer != null) {
peer.setFont(f);
synchronized (getTreeLock()) {
font = f;
//Fixed 6312943: NullPointerException in method MenuComponent.setFont(Font)
MenuComponentPeer peer = this.peer;
if (peer != null) {
peer.setFont(f);
}
}
}
......
......@@ -71,7 +71,7 @@ class WMenuItemPeer extends WObjectPeer implements MenuItemPeer {
enable(false);
}
public void readShortcutLabel() {
private void readShortcutLabel() {
//Fix for 6288578: PIT. Windows: Shortcuts displayed for the menuitems in a popup menu
WMenuPeer ancestor = parent;
while (ancestor != null && !(ancestor instanceof WMenuBarPeer)) {
......@@ -115,7 +115,7 @@ class WMenuItemPeer extends WObjectPeer implements MenuItemPeer {
readShortcutLabel();
}
protected void checkMenuCreation()
void checkMenuCreation()
{
// fix for 5088782: check if menu peer is created successfully
if (pData == 0)
......
......@@ -34,16 +34,16 @@ abstract class WObjectPeer {
}
// The Windows handle for the native widget.
long pData;
volatile long pData;
// if the native peer has been destroyed
boolean destroyed = false;
private volatile boolean destroyed;
// The associated AWT object.
Object target;
volatile Object target;
private volatile boolean disposed;
// set from JNI if any errors in creating the peer occur
protected Error createError = null;
volatile Error createError = null;
// used to synchronize the state of this peer
private final Object stateLock = new Object();
......
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2016, 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
......@@ -3766,7 +3766,10 @@ void AwtComponent::OpenCandidateWindow(int x, int y)
HWND hWnd = GetHWnd();
HWND hTop = GetTopLevelParentForWindow(hWnd);
::ClientToScreen(hTop, &p);
if (!m_bitsCandType) {
SetCandidateWindow(m_bitsCandType, x - p.x, y - p.y);
return;
}
for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) {
if ( m_bitsCandType & bits )
SetCandidateWindow(iCandType, x - p.x, y - p.y);
......@@ -3784,7 +3787,7 @@ void AwtComponent::SetCandidateWindow(int iCandType, int x, int y)
HIMC hIMC = ImmGetContext(hwnd);
CANDIDATEFORM cf;
cf.dwIndex = iCandType;
cf.dwStyle = CFS_CANDIDATEPOS;
cf.dwStyle = CFS_POINT;
cf.ptCurrentPos.x = x;
cf.ptCurrentPos.y = y;
......@@ -3816,8 +3819,12 @@ MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam)
MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType)
{
if (!m_useNativeCompWindow && subMsg == IMN_OPENCANDIDATE) {
m_bitsCandType = bitsCandType;
if (!m_useNativeCompWindow) {
if (subMsg == IMN_OPENCANDIDATE) {
m_bitsCandType = subMsg;
} else if (subMsg != IMN_SETCANDIDATEPOS) {
m_bitsCandType = 0;
}
InquireCandidatePosition();
return mrConsume;
}
......@@ -4078,14 +4085,14 @@ HWND AwtComponent::GetProxyFocusOwner()
return (HWND)NULL;
}
/* Call DefWindowProc for the focus proxy, if any */
/* Redirects message to the focus proxy, if any */
void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam,
LPARAM lParam, LRESULT &retVal, MsgRouting &mr)
{
if (mr != mrConsume) {
HWND proxy = GetProxyFocusOwner();
if (proxy != NULL && ::IsWindowEnabled(proxy)) {
retVal = ComCtl32Util::GetInstance().DefWindowProc(NULL, proxy, message, wParam, lParam);
retVal = ::DefWindowProc(proxy, message, wParam, lParam);
mr = mrConsume;
}
}
......@@ -4164,7 +4171,7 @@ MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo)
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (drawInfo.CtlType == ODT_MENU) {
if (drawInfo.itemData != 0) {
if (IsMenu((HMENU)drawInfo.hwndItem) && drawInfo.itemData != 0) {
AwtMenu* menu = (AwtMenu*)(drawInfo.itemData);
menu->DrawItem(drawInfo);
}
......
......@@ -34,6 +34,13 @@
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
*/
/***********************************************************************/
// struct for _DelItem() method
struct DelItemStruct {
jobject menuitem;
jint index;
};
/************************************************************************
* AwtMenuItem fields
*/
......@@ -64,7 +71,6 @@ void AwtMenu::Dispose()
::DestroyMenu(m_hMenu);
m_hMenu = NULL;
}
AwtMenuItem::Dispose();
}
......@@ -73,7 +79,7 @@ LPCTSTR AwtMenu::GetClassName() {
}
/* Create a new AwtMenu object and menu. */
AwtMenu* AwtMenu::Create(jobject self, AwtMenu* parentMenu)
AwtMenu* AwtMenu::Create(jobject self, jobject parent)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
......@@ -85,6 +91,9 @@ AwtMenu* AwtMenu::Create(jobject self, AwtMenu* parentMenu)
return NULL;
}
JNI_CHECK_NULL_GOTO(parent, "peer", done);
AwtMenu* parentMenu = (AwtMenu*) JNI_GET_PDATA(parent);
target = env->GetObjectField(self, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
......@@ -119,6 +128,46 @@ done:
return menu;
}
void AwtMenu::_AddSeparator(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject self = (jobject)param;
AwtMenu *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenu *)pData;
m->AddSeparator();
ret:
env->DeleteGlobalRef(self);
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenu::_AddSeparator, param);
}
}
void AwtMenu::_DelItem(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
DelItemStruct *dis = (DelItemStruct*) param;
jobject self = dis->menuitem;
jint index = dis->index;
AwtMenu *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenu *)pData;
m->DeleteItem(static_cast<UINT>(index));
ret:
env->DeleteGlobalRef(self);
delete dis;
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenu::_DelItem, param);
}
}
void AwtMenu::UpdateLayout()
{
UpdateLayout(GetHMenu());
......@@ -239,6 +288,7 @@ AwtMenuItem* AwtMenu::GetItem(jobject target, jint index)
}
jobject menuItem = env->CallObjectMethod(target, AwtMenu::getItemMID,
index);
if (!menuItem) return NULL; // menu item was removed concurrently
DASSERT(!safe_ExceptionOccurred(env));
jobject wMenuItemPeer = GetPeerForTarget(env, menuItem);
......@@ -264,9 +314,9 @@ void AwtMenu::DrawItems(DRAWITEMSTRUCT& drawInfo)
}
/* target is a java.awt.Menu */
jobject target = GetTarget(env);
if(!target || env->ExceptionCheck()) return;
int nCount = CountItem(target);
for (int i = 0; i < nCount; i++) {
for (int i = 0; i < nCount && !env->ExceptionCheck(); i++) {
AwtMenuItem* awtMenuItem = GetItem(target, i);
if (awtMenuItem != NULL) {
SendDrawItem(awtMenuItem, drawInfo);
......@@ -294,8 +344,9 @@ void AwtMenu::MeasureItems(HDC hDC, MEASUREITEMSTRUCT& measureInfo)
}
/* target is a java.awt.Menu */
jobject target = GetTarget(env);
if(!target || env->ExceptionCheck()) return;
int nCount = CountItem(target);
for (int i = 0; i < nCount; i++) {
for (int i = 0; i < nCount && !env->ExceptionCheck(); i++) {
AwtMenuItem* awtMenuItem = GetItem(target, i);
if (awtMenuItem != NULL) {
SendMeasureItem(awtMenuItem, hDC, measureInfo);
......@@ -321,24 +372,6 @@ BOOL AwtMenu::IsTopMenu()
return (GetMenuBar() == GetMenuContainer());
}
LRESULT AwtMenu::WinThreadExecProc(ExecuteArgs * args)
{
switch( args->cmdId ) {
case MENU_ADDSEPARATOR:
this->AddSeparator();
break;
case MENU_DELITEM:
this->DeleteItem(static_cast<UINT>(args->param1));
break;
default:
AwtMenuItem::WinThreadExecProc(args);
break;
}
return 0L;
}
/************************************************************************
* WMenuPeer native methods
*/
......@@ -380,15 +413,14 @@ Java_sun_awt_windows_WMenuPeer_addSeparator(JNIEnv *env, jobject self)
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(self);
jobject selfGlobalRef = env->NewGlobalRef(self);
AwtObject::WinThreadExec(self, AwtMenu::MENU_ADDSEPARATOR);
AwtToolkit::GetInstance().SyncCall(AwtMenu::_AddSeparator, selfGlobalRef);
// selfGlobalRef is deleted in _AddSeparator
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WMenuPeer
* Method: delItem
......@@ -400,10 +432,12 @@ Java_sun_awt_windows_WMenuPeer_delItem(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(self);
DelItemStruct *dis = new DelItemStruct;
dis->menuitem = env->NewGlobalRef(self);
dis->index = index;
AwtObject::WinThreadExec(self, AwtMenu::MENU_DELITEM, index);
AwtToolkit::GetInstance().SyncCall(AwtMenu::_DelItem, dis);
// global refs and dis are deleted in _DelItem
CATCH_BAD_ALLOC;
}
......@@ -419,13 +453,8 @@ Java_sun_awt_windows_WMenuPeer_createMenu(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(menuBar);
AwtMenuBar* awtMenuBar = (AwtMenuBar *)pData;
AwtToolkit::CreateComponent(self, awtMenuBar,
(AwtToolkit::ComponentFactory)AwtMenu::Create,FALSE);
JNI_CHECK_PEER_CREATION_RETURN(self);
AwtToolkit::CreateComponent(self, menuBar,
(AwtToolkit::ComponentFactory)AwtMenu::Create);
CATCH_BAD_ALLOC;
}
......@@ -441,13 +470,8 @@ Java_sun_awt_windows_WMenuPeer_createSubMenu(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(menu);
AwtMenu* awtMenu = (AwtMenu *)pData;
AwtToolkit::CreateComponent(self, awtMenu,
(AwtToolkit::ComponentFactory)AwtMenu::Create,FALSE);
JNI_CHECK_PEER_CREATION_RETURN(self);
AwtToolkit::CreateComponent(self, menu,
(AwtToolkit::ComponentFactory)AwtMenu::Create);
CATCH_BAD_ALLOC;
}
......
......@@ -42,13 +42,6 @@ class AwtMenuBar;
class AwtMenu : public AwtMenuItem {
public:
// id's for methods executed on toolkit thread
enum {
MENU_ADDSEPARATOR = MENUITEM_LAST+1,
MENU_DELITEM,
MENU_LAST
};
/* method ids for java.awt.Menu */
static jmethodID countItemsMID;
static jmethodID getItemMID;
......@@ -61,7 +54,7 @@ public:
virtual LPCTSTR GetClassName();
/* Create a new AwtMenu. This must be run on the main thread. */
static AwtMenu* Create(jobject self, AwtMenu* parentMenu);
static AwtMenu* Create(jobject self, jobject parent);
INLINE HMENU GetHMenu() { return m_hMenu; }
INLINE void SetHMenu(HMENU hMenu) {
......@@ -94,9 +87,9 @@ public:
void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo);
void MeasureItems(HDC hDC, MEASUREITEMSTRUCT& measureInfo);
virtual LRESULT WinThreadExecProc(ExecuteArgs * args);
// invoked on Toolkit thread
static void _AddSeparator(void *param);
static void _DelItem(void *param);
static void _CreateMenu(void *param);
static void _CreateSubMenu(void *param);
virtual BOOL IsSeparator() { return FALSE; }
......
......@@ -29,6 +29,12 @@
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
*/
/***********************************************************************/
// struct for _DelItem() method
struct DelItemStruct {
jobject menuitem;
jint index;
};
/***********************************************************************/
// struct for _AddMenu() method
struct AddMenuStruct {
......@@ -130,18 +136,6 @@ HWND AwtMenuBar::GetOwnerHWnd()
return myFrame->GetHWnd();
}
void AwtMenuBar::SendDrawItem(AwtMenuItem* awtMenuItem,
DRAWITEMSTRUCT& drawInfo)
{
awtMenuItem->DrawItem(drawInfo);
}
void AwtMenuBar::SendMeasureItem(AwtMenuItem* awtMenuItem,
HDC hDC, MEASUREITEMSTRUCT& measureInfo)
{
awtMenuItem->MeasureItem(hDC, measureInfo);
}
int AwtMenuBar::CountItem(jobject menuBar)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
......@@ -159,13 +153,16 @@ AwtMenuItem* AwtMenuBar::GetItem(jobject target, long index)
}
jobject menu = env->CallObjectMethod(target, AwtMenuBar::getMenuMID,index);
if (!menu) return NULL; // menu item was removed concurrently
DASSERT(!safe_ExceptionOccurred(env));
jobject menuItemPeer = GetPeerForTarget(env, menu);
PDATA pData;
JNI_CHECK_PEER_RETURN_NULL(menuItemPeer);
AwtMenuItem* awtMenuItem = (AwtMenuItem*)pData;
AwtMenuItem* awtMenuItem = NULL;
JNI_CHECK_PEER_GOTO(menuItemPeer, done);
awtMenuItem = (AwtMenuItem*)pData;
done:
env->DeleteLocalRef(menu);
env->DeleteLocalRef(menuItemPeer);
......@@ -212,20 +209,6 @@ void AwtMenuBar::RedrawMenuBar() {
VERIFY(::DrawMenuBar(GetOwnerHWnd()));
}
LRESULT AwtMenuBar::WinThreadExecProc(ExecuteArgs * args)
{
switch( args->cmdId ) {
case MENUBAR_DELITEM:
this->DeleteItem(static_cast<UINT>(args->param1));
break;
default:
AwtMenu::WinThreadExecProc(args);
break;
}
return 0L;
}
void AwtMenuBar::_AddMenu(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
......@@ -254,6 +237,28 @@ ret:
delete ams;
}
void AwtMenuBar::_DelItem(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
DelItemStruct *dis = (DelItemStruct*) param;
jobject self = dis->menuitem;
jint index = dis->index;
AwtMenuBar *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenuBar *)pData;
m->DeleteItem(static_cast<UINT>(index));
ret:
env->DeleteGlobalRef(self);
delete dis;
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenuBar::_DelItem, param);
}
}
/************************************************************************
* MenuBar native methods
*/
......@@ -322,9 +327,12 @@ Java_sun_awt_windows_WMenuBarPeer_delMenu(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(self);
AwtObject::WinThreadExec(self, AwtMenuBar::MENUBAR_DELITEM, (LPARAM)index);
DelItemStruct *dis = new DelItemStruct;
dis->menuitem = env->NewGlobalRef(self);
dis->index = index;
AwtToolkit::GetInstance().SyncCall(AwtMenuBar::_DelItem, dis);
// global refs and dis are deleted in _DelItem
CATCH_BAD_ALLOC;
}
......@@ -343,9 +351,6 @@ Java_sun_awt_windows_WMenuBarPeer_create(JNIEnv *env, jobject self,
AwtToolkit::CreateComponent(self, frame,
(AwtToolkit::ComponentFactory)
AwtMenuBar::Create);
PDATA pData;
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}
......
......@@ -42,10 +42,6 @@ class AwtFrame;
class AwtMenuBar : public AwtMenu {
public:
// id's for methods executed on toolkit thread
enum MenuExecIds {
MENUBAR_DELITEM = MENU_LAST+1
};
/* java.awt.MenuBar method ids */
static jmethodID getMenuCountMID;
......@@ -73,20 +69,15 @@ public:
AwtMenuItem* GetItem(jobject target, long index);
int CountItem(jobject menuBar);
void SendDrawItem(AwtMenuItem* awtMenuItem,
DRAWITEMSTRUCT& drawInfo);
void SendMeasureItem(AwtMenuItem* awtMenuItem,
HDC hDC, MEASUREITEMSTRUCT& measureInfo);
void DrawItem(DRAWITEMSTRUCT& drawInfo);
void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo);
void AddItem(AwtMenuItem* item);
void DeleteItem(UINT index);
virtual LRESULT WinThreadExecProc(ExecuteArgs * args);
// called on Toolkit thread
static void _AddMenu(void *param);
static void _DelItem(void *param);
protected:
AwtFrame* m_frame;
};
......
......@@ -50,6 +50,16 @@ struct SetLabelStruct {
jobject menuitem;
jstring label;
};
// struct for _SetEnable() method
struct SetEnableStruct {
jobject menuitem;
jboolean isEnabled;
};
// struct for _setState() method
struct SetStateStruct {
jobject menuitem;
jboolean isChecked;
};
/************************************************************************
* AwtMenuItem fields
*/
......@@ -104,6 +114,7 @@ void AwtMenuItem::RemoveCmdID()
{
if (m_freeId) {
AwtToolkit::GetInstance().RemoveCmdID( GetID() );
m_freeId = FALSE;
}
}
void AwtMenuItem::Dispose()
......@@ -112,6 +123,7 @@ void AwtMenuItem::Dispose()
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (m_peerObject != NULL) {
JNI_SET_DESTROYED(m_peerObject);
JNI_SET_PDATA(m_peerObject, NULL);
env->DeleteGlobalRef(m_peerObject);
m_peerObject = NULL;
......@@ -205,13 +217,12 @@ AwtMenuItem* AwtMenuItem::Create(jobject peer, jobject menuPeer)
if (env->EnsureLocalCapacity(1) < 0) {
return NULL;
}
PDATA pData;
JNI_CHECK_PEER_RETURN_NULL(menuPeer);
JNI_CHECK_NULL_RETURN_NULL(menuPeer, "peer");
/* target is a java.awt.MenuItem */
target = env->GetObjectField(peer, AwtObject::targetID);
AwtMenu* menu = (AwtMenu *)pData;
AwtMenu* menu = (AwtMenu *)JNI_GET_PDATA(menuPeer);
item = new AwtMenuItem();
jboolean isCheckbox =
(jboolean)env->GetBooleanField(peer, AwtMenuItem::isCheckboxID);
......@@ -222,7 +233,9 @@ AwtMenuItem* AwtMenuItem::Create(jobject peer, jobject menuPeer)
item->LinkObjects(env, peer);
item->SetMenuContainer(menu);
item->SetNewID();
menu->AddItem(item);
if (menu != NULL) {
menu->AddItem(item);
}
} catch (...) {
env->DeleteLocalRef(target);
throw;
......@@ -763,30 +776,6 @@ void AwtMenuItem::UpdateContainerLayout() {
}
}
LRESULT AwtMenuItem::WinThreadExecProc(ExecuteArgs * args)
{
switch( args->cmdId ) {
case MENUITEM_ENABLE:
{
BOOL isEnabled = (BOOL)args->param1;
this->Enable(isEnabled);
}
break;
case MENUITEM_SETSTATE:
{
BOOL isChecked = (BOOL)args->param1;
this->SetState(isChecked);
}
break;
default:
AwtObject::WinThreadExecProc(args);
break;
}
return 0L;
}
void AwtMenuItem::_SetLabel(void *param) {
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
......@@ -886,6 +875,53 @@ ret:
}
}
void AwtMenuItem::_SetEnable(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetEnableStruct *ses = (SetEnableStruct*) param;
jobject self = ses->menuitem;
jboolean isEnabled = ses->isEnabled;
AwtMenuItem *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenuItem *)pData;
m->Enable(isEnabled);
ret:
env->DeleteGlobalRef(self);
delete ses;
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_SetEnable, param);
}
}
void AwtMenuItem::_SetState(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetStateStruct *sts = (SetStateStruct*) param;
jobject self = sts->menuitem;
jboolean isChecked = sts->isChecked;
AwtMenuItem *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenuItem *)pData;
m->SetState(isChecked);
ret:
env->DeleteGlobalRef(self);
delete sts;
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_SetState, param);
}
}
BOOL AwtMenuItem::IsSeparator() {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (env->EnsureLocalCapacity(2) < 0) {
......@@ -1049,13 +1085,9 @@ Java_sun_awt_windows_WMenuItemPeer_create(JNIEnv *env, jobject self,
{
TRY;
JNI_CHECK_NULL_RETURN(menu, "null Menu");
AwtToolkit::CreateComponent(self, menu,
(AwtToolkit::ComponentFactory)
AwtMenuItem::Create);
PDATA pData;
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}
......@@ -1070,9 +1102,12 @@ Java_sun_awt_windows_WMenuItemPeer_enable(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(self);
AwtObject::WinThreadExec(self, AwtMenuItem::MENUITEM_ENABLE, (LPARAM)on );
SetEnableStruct *ses = new SetEnableStruct;
ses->menuitem = env->NewGlobalRef(self);
ses->isEnabled = on;
AwtToolkit::GetInstance().SyncCall(AwtMenuItem::_SetEnable, ses);
// global refs and ses are deleted in _SetEnable
CATCH_BAD_ALLOC;
}
......@@ -1111,9 +1146,12 @@ Java_sun_awt_windows_WCheckboxMenuItemPeer_setState(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(self);
AwtObject::WinThreadExec(self, AwtMenuItem::MENUITEM_SETSTATE, (LPARAM)on);
SetStateStruct *sts = new SetStateStruct;
sts->menuitem = env->NewGlobalRef(self);
sts->isChecked = on;
AwtToolkit::GetInstance().SyncCall(AwtMenuItem::_SetState, sts);
// global refs and sts are deleted in _SetState
CATCH_BAD_ALLOC;
}
......
......@@ -45,13 +45,6 @@ class AwtMenu;
class AwtMenuItem : public AwtObject {
public:
// id's for methods executed on toolkit thread
enum {
MENUITEM_ENABLE,
MENUITEM_SETSTATE,
MENUITEM_LAST
};
/* java.awt.MenuComponent fields */
static jfieldID fontID;
static jfieldID appContextID;
......@@ -154,13 +147,14 @@ public:
*/
MsgRouting WmNotify(UINT notifyCode);
virtual LRESULT WinThreadExecProc(ExecuteArgs * args);
virtual BOOL IsDisabledAndPopup() {
return FALSE;
}
virtual BOOL IsSeparator();
// invoked on Toolkit thread
static void _SetState(void *param);
static void _SetEnable(void *param);
static void _SetLabel(void *param);
static void _UpdateLayout(void *param);
......
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2016, 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
......@@ -65,7 +65,7 @@ LPCTSTR AwtPopupMenu::GetClassName() {
}
/* Create a new AwtPopupMenu object and menu. */
AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent)
AwtPopupMenu* AwtPopupMenu::Create(jobject self, jobject parent)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
......@@ -77,6 +77,9 @@ AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent)
return NULL;
}
JNI_CHECK_NULL_GOTO(parent, "peer", done);
AwtComponent* awtParent = (AwtComponent*) JNI_GET_PDATA(parent);
target = env->GetObjectField(self, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
......@@ -94,7 +97,7 @@ AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent)
popupMenu->SetHMenu(hMenu);
popupMenu->LinkObjects(env, self);
popupMenu->SetParent(parent);
popupMenu->SetParent(awtParent);
} catch (...) {
env->DeleteLocalRef(target);
throw;
......@@ -274,12 +277,8 @@ Java_sun_awt_windows_WPopupMenuPeer_createMenu(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtComponent* awtParent = (AwtComponent *)pData;
AwtToolkit::CreateComponent(
self, awtParent, (AwtToolkit::ComponentFactory)AwtPopupMenu::Create, FALSE);
JNI_CHECK_PEER_CREATION_RETURN(self);
self, parent, (AwtToolkit::ComponentFactory)AwtPopupMenu::Create);
CATCH_BAD_ALLOC;
}
......
......@@ -47,7 +47,7 @@ public:
virtual LPCTSTR GetClassName();
/* Create a new AwtPopupMenu. This must be run on the main thread. */
static AwtPopupMenu* Create(jobject self, AwtComponent* parent);
static AwtPopupMenu* Create(jobject self, jobject parent);
/* Display the popup modally. */
void Show(JNIEnv *env, jobject event, BOOL isTrayIconPopup);
......
......@@ -172,6 +172,9 @@ safe_ExceptionOccurred(JNIEnv *env) throw (std::bad_alloc) {
env->ExceptionClear();
// rethrow exception
env->Throw(xcp);
// temp solution to reveal all concurrency issues in jtreg and JCK
// we will switch it back to silent mode before the release
env->ExceptionDescribe();
return xcp;
}
}
......
/*
* Copyright (c) 2015 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 8079595
@summary Resizing dialog which is JWindow parent makes JVM crash
@author Semyon Sadetsky
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
public class ShowChildWhileResizingTest {
private static Window dialog;
private static Timer timer;
private static Point point;
public static void main(String[] args) throws Exception {
dialog = new Frame();
dialog.add(new JPanel());
dialog.setVisible(true);
dialog.setBounds(100, 100, 200, 200);
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
final Window dependentWindow = new JWindow(dialog);
JPanel panel = new JPanel();
panel.add(new JButton("button"));
dependentWindow.add(panel);
dependentWindow.setVisible(true);
dependentWindow.setBounds(0, 0, 50, 50);
timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dependentWindow
.setVisible(!dependentWindow.isVisible());
}
});
timer.start();
}
});
Robot robot = new Robot();
robot.setAutoDelay(5);
robot.delay(300);
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
point = dialog.getLocationOnScreen();
}
});
robot.mouseMove(point.x + 200 - dialog.getInsets().right/2,
point.y + 200 - dialog.getInsets().bottom/2);
robot.mousePress(InputEvent.BUTTON1_MASK);
for(int i = 0; i < 100; i++) {
robot.mouseMove(point.x + 200 + i, point.y + 200 + i);
}
robot.mouseRelease(InputEvent.BUTTON1_MASK);
timer.stop();
dialog.dispose();
System.out.println("ok");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册