提交 cfd6114d 编写于 作者: D dcherepanov

6829180: Removing focused component from a window causes a JVM crash for JDK7b50+ on WinXP/Vista

Summary: access pData on the toolkit thread
Reviewed-by: art, anthony, naoto
上级 53db92bb
...@@ -1254,6 +1254,8 @@ void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) { ...@@ -1254,6 +1254,8 @@ void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) {
WIN_MSG(WM_AWT_CREATECONTEXT) WIN_MSG(WM_AWT_CREATECONTEXT)
WIN_MSG(WM_AWT_DESTROYCONTEXT) WIN_MSG(WM_AWT_DESTROYCONTEXT)
WIN_MSG(WM_AWT_ASSOCIATECONTEXT) WIN_MSG(WM_AWT_ASSOCIATECONTEXT)
WIN_MSG(WM_AWT_GET_DEFAULT_IME_HANDLER)
WIN_MSG(WM_AWT_HANDLE_NATIVE_IME_EVENT)
WIN_MSG(WM_AWT_PRE_KEYDOWN) WIN_MSG(WM_AWT_PRE_KEYDOWN)
WIN_MSG(WM_AWT_PRE_KEYUP) WIN_MSG(WM_AWT_PRE_KEYUP)
WIN_MSG(WM_AWT_PRE_SYSKEYDOWN) WIN_MSG(WM_AWT_PRE_SYSKEYDOWN)
......
...@@ -91,16 +91,19 @@ Java_sun_awt_windows_WInputMethod_enableNativeIME(JNIEnv *env, jobject self, job ...@@ -91,16 +91,19 @@ Java_sun_awt_windows_WInputMethod_enableNativeIME(JNIEnv *env, jobject self, job
{ {
TRY; TRY;
//get C++ Class of Focused Component jobject selfGlobalRef = env->NewGlobalRef(self);
if (peer == 0) return; jobject peerGlobalRef = env->NewGlobalRef(peer);
AwtComponent* p = (AwtComponent*)JNI_GET_PDATA(peer);
if (p == 0) return; EnableNativeIMEStruct *enis = new EnableNativeIMEStruct;
p->SetInputMethod(self, useNativeCompWindow); enis->self = selfGlobalRef;
enis->peer = peerGlobalRef;
enis->context = context;
enis->useNativeCompWindow = useNativeCompWindow;
// use special message to call ImmAssociateContext() in main thread.
AwtToolkit::GetInstance().SendMessage(WM_AWT_ASSOCIATECONTEXT, AwtToolkit::GetInstance().SendMessage(WM_AWT_ASSOCIATECONTEXT,
reinterpret_cast<WPARAM>(p->GetHWnd()), context); reinterpret_cast<WPARAM>(enis), (LPARAM)0);
// global refs are deleted in message handler
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
...@@ -116,16 +119,18 @@ Java_sun_awt_windows_WInputMethod_disableNativeIME(JNIEnv *env, jobject self, jo ...@@ -116,16 +119,18 @@ Java_sun_awt_windows_WInputMethod_disableNativeIME(JNIEnv *env, jobject self, jo
{ {
TRY_NO_VERIFY; TRY_NO_VERIFY;
//get C++ Class of Focused Component jobject peerGlobalRef = env->NewGlobalRef(peer);
if (peer == 0) return; // self reference is not used
AwtComponent* p = (AwtComponent*)JNI_GET_PDATA(peer);
if (p == 0) return;
p->SetInputMethod(NULL, TRUE); EnableNativeIMEStruct *enis = new EnableNativeIMEStruct;
enis->self = NULL;
enis->peer = peerGlobalRef;
enis->context = NULL;
enis->useNativeCompWindow = JNI_TRUE;
// use special message to call ImmAssociateContext() in main thread.
AwtToolkit::GetInstance().SendMessage(WM_AWT_ASSOCIATECONTEXT, AwtToolkit::GetInstance().SendMessage(WM_AWT_ASSOCIATECONTEXT,
reinterpret_cast<WPARAM>(p->GetHWnd()), NULL); reinterpret_cast<WPARAM>(enis), (LPARAM)0);
// global refs are deleted in message handler
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
...@@ -167,23 +172,14 @@ Java_sun_awt_windows_WInputMethod_handleNativeIMEEvent(JNIEnv *env, jobject self ...@@ -167,23 +172,14 @@ Java_sun_awt_windows_WInputMethod_handleNativeIMEEvent(JNIEnv *env, jobject self
if (id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST && if (id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST &&
id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST) id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST)
{ {
long modifiers = p->GetJavaModifiers(); jobject peerGlobalRef = env->NewGlobalRef(peer);
if (msg.message==WM_CHAR || msg.message==WM_SYSCHAR) {
WCHAR unicodeChar = L'\0'; // use special message to access pData on the toolkit thread
unicodeChar = (WCHAR)msg.wParam; AwtToolkit::GetInstance().SendMessage(WM_AWT_HANDLE_NATIVE_IME_EVENT,
p->SendKeyEvent(java_awt_event_KeyEvent_KEY_TYPED, reinterpret_cast<WPARAM>(peerGlobalRef),
0, //to be fixed nowMillis(), reinterpret_cast<LPARAM>(&msg));
java_awt_event_KeyEvent_CHAR_UNDEFINED, // global ref is deleted in message handler
unicodeChar,
modifiers,
java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
&msg);
} else {
MSG* pCopiedMsg = new MSG;
*pCopiedMsg = msg;
p->SendMessage(WM_AWT_HANDLE_EVENT, (WPARAM) FALSE,
(LPARAM) pCopiedMsg);
}
(env)->SetBooleanField(event, AwtAWTEvent::consumedID, JNI_TRUE); (env)->SetBooleanField(event, AwtAWTEvent::consumedID, JNI_TRUE);
} }
...@@ -373,22 +369,27 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WInputMethod_setStatusWindowVisible ...@@ -373,22 +369,27 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WInputMethod_setStatusWindowVisible
Windows system creates a default input method window for the Windows system creates a default input method window for the
toolkit thread. toolkit thread.
*/ */
HWND hwndIME = AwtToolkit::GetInstance().GetInputMethodWindow();
if (hwndIME == NULL) {
if (peer == NULL) {
return;
}
AwtComponent* p = (AwtComponent*)JNI_GET_PDATA(peer); HWND defaultIMEHandler = AwtToolkit::GetInstance().GetInputMethodWindow();
if (p == NULL || (hwndIME = ImmGetDefaultIMEWnd(p->GetHWnd())) == NULL) {
return; if (defaultIMEHandler == NULL)
} {
jobject peerGlobalRef = env->NewGlobalRef(peer);
AwtToolkit::GetInstance().SetInputMethodWindow(hwndIME); // use special message to access pData on the toolkit thread
LRESULT res = AwtToolkit::GetInstance().SendMessage(WM_AWT_GET_DEFAULT_IME_HANDLER,
reinterpret_cast<WPARAM>(peerGlobalRef), 0);
// global ref is deleted in message handler
if (res == TRUE) {
defaultIMEHandler = AwtToolkit::GetInstance().GetInputMethodWindow();
}
} }
::SendMessage(hwndIME, WM_IME_CONTROL, if (defaultIMEHandler != NULL) {
visible ? IMC_OPENSTATUSWINDOW : IMC_CLOSESTATUSWINDOW, 0); ::SendMessage(defaultIMEHandler, WM_IME_CONTROL,
visible ? IMC_OPENSTATUSWINDOW : IMC_CLOSESTATUSWINDOW, 0);
}
} }
/* /*
...@@ -417,6 +418,7 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WInputMethod_openCandidateWindow ...@@ -417,6 +418,7 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WInputMethod_openCandidateWindow
// use special message to open candidate window in main thread. // use special message to open candidate window in main thread.
AwtToolkit::GetInstance().SendMessage(WM_AWT_OPENCANDIDATEWINDOW, AwtToolkit::GetInstance().SendMessage(WM_AWT_OPENCANDIDATEWINDOW,
(WPARAM)peerGlobalRef, MAKELONG(x, y)); (WPARAM)peerGlobalRef, MAKELONG(x, y));
// global ref is deleted in message handler
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
......
...@@ -804,8 +804,73 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message, ...@@ -804,8 +804,73 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
return 0; return 0;
} }
case WM_AWT_ASSOCIATECONTEXT: { case WM_AWT_ASSOCIATECONTEXT: {
AwtComponent *p = AwtComponent::GetComponent((HWND)wParam); EnableNativeIMEStruct *data = (EnableNativeIMEStruct*)wParam;
p->ImmAssociateContext((HIMC)lParam);
jobject peer = data->peer;
jobject self = data->self;
jint context = data->context;
jboolean useNativeCompWindow = data->useNativeCompWindow;
AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
if (comp != NULL)
{
comp->SetInputMethod(self, useNativeCompWindow);
comp->ImmAssociateContext((HIMC)context);
}
if (peer != NULL) {
env->DeleteGlobalRef(peer);
}
if (self != NULL) {
env->DeleteGlobalRef(self);
}
delete data;
return 0;
}
case WM_AWT_GET_DEFAULT_IME_HANDLER: {
LRESULT ret = (LRESULT)FALSE;
jobject peer = (jobject)wParam;
AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
if (comp != NULL) {
HWND defaultIMEHandler = ImmGetDefaultIMEWnd(comp->GetHWnd());
if (defaultIMEHandler != NULL) {
AwtToolkit::GetInstance().SetInputMethodWindow(defaultIMEHandler);
ret = (LRESULT)TRUE;
}
}
if (peer != NULL) {
env->DeleteGlobalRef(peer);
}
return ret;
}
case WM_AWT_HANDLE_NATIVE_IME_EVENT: {
jobject peer = (jobject)wParam;
AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
MSG* msg = (MSG*)lParam;
long modifiers = comp->GetJavaModifiers();
if ((comp != NULL) && (msg->message==WM_CHAR || msg->message==WM_SYSCHAR)) {
WCHAR unicodeChar = (WCHAR)msg->wParam;
comp->SendKeyEvent(java_awt_event_KeyEvent_KEY_TYPED,
0, //to be fixed nowMillis(),
java_awt_event_KeyEvent_CHAR_UNDEFINED,
unicodeChar,
modifiers,
java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
msg);
} else if (comp != NULL) {
MSG* pCopiedMsg = new MSG;
*pCopiedMsg = *msg;
comp->SendMessage(WM_AWT_HANDLE_EVENT, (WPARAM) FALSE,
(LPARAM) pCopiedMsg);
}
if (peer != NULL) {
env->DeleteGlobalRef(peer);
}
return 0; return 0;
} }
case WM_AWT_ENDCOMPOSITION: { case WM_AWT_ENDCOMPOSITION: {
......
...@@ -61,6 +61,14 @@ class AwtDropTarget; ...@@ -61,6 +61,14 @@ class AwtDropTarget;
typedef VOID (CALLBACK* IDLEPROC)(VOID); typedef VOID (CALLBACK* IDLEPROC)(VOID);
typedef BOOL (CALLBACK* PEEKMESSAGEPROC)(MSG&); typedef BOOL (CALLBACK* PEEKMESSAGEPROC)(MSG&);
// Struct for _WInputMethod_enable|disableNativeIME method
struct EnableNativeIMEStruct {
jobject self;
jobject peer;
jint context;
jboolean useNativeCompWindow;
};
/* /*
* class JNILocalFrame * class JNILocalFrame
* Push/PopLocalFrame helper * Push/PopLocalFrame helper
......
...@@ -208,6 +208,8 @@ enum { ...@@ -208,6 +208,8 @@ enum {
WM_AWT_CREATECONTEXT, WM_AWT_CREATECONTEXT,
WM_AWT_DESTROYCONTEXT, WM_AWT_DESTROYCONTEXT,
WM_AWT_ASSOCIATECONTEXT, WM_AWT_ASSOCIATECONTEXT,
WM_AWT_GET_DEFAULT_IME_HANDLER,
WM_AWT_HANDLE_NATIVE_IME_EVENT,
WM_AWT_PRE_KEYDOWN, WM_AWT_PRE_KEYDOWN,
WM_AWT_PRE_KEYUP, WM_AWT_PRE_KEYUP,
WM_AWT_PRE_SYSKEYDOWN, WM_AWT_PRE_SYSKEYDOWN,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册