6829180: Removing focused component from a window causes a JVM crash for JDK7b50+ on WinXP/Vista
Access pData on the toolkit thread Reviewed-by: art, anthony, naoto
This commit is contained in:
parent
eb1cb99d4e
commit
7019b37e8c
jdk/src/windows/native/sun/windows
@ -1254,6 +1254,8 @@ void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) {
|
||||
WIN_MSG(WM_AWT_CREATECONTEXT)
|
||||
WIN_MSG(WM_AWT_DESTROYCONTEXT)
|
||||
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_KEYUP)
|
||||
WIN_MSG(WM_AWT_PRE_SYSKEYDOWN)
|
||||
|
@ -91,16 +91,19 @@ Java_sun_awt_windows_WInputMethod_enableNativeIME(JNIEnv *env, jobject self, job
|
||||
{
|
||||
TRY;
|
||||
|
||||
//get C++ Class of Focused Component
|
||||
if (peer == 0) return;
|
||||
AwtComponent* p = (AwtComponent*)JNI_GET_PDATA(peer);
|
||||
if (p == 0) return;
|
||||
jobject selfGlobalRef = env->NewGlobalRef(self);
|
||||
jobject peerGlobalRef = env->NewGlobalRef(peer);
|
||||
|
||||
p->SetInputMethod(self, useNativeCompWindow);
|
||||
EnableNativeIMEStruct *enis = new EnableNativeIMEStruct;
|
||||
|
||||
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,
|
||||
reinterpret_cast<WPARAM>(p->GetHWnd()), context);
|
||||
reinterpret_cast<WPARAM>(enis), (LPARAM)0);
|
||||
// global refs are deleted in message handler
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
@ -116,16 +119,18 @@ Java_sun_awt_windows_WInputMethod_disableNativeIME(JNIEnv *env, jobject self, jo
|
||||
{
|
||||
TRY_NO_VERIFY;
|
||||
|
||||
//get C++ Class of Focused Component
|
||||
if (peer == 0) return;
|
||||
AwtComponent* p = (AwtComponent*)JNI_GET_PDATA(peer);
|
||||
if (p == 0) return;
|
||||
jobject peerGlobalRef = env->NewGlobalRef(peer);
|
||||
// self reference is not used
|
||||
|
||||
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,
|
||||
reinterpret_cast<WPARAM>(p->GetHWnd()), NULL);
|
||||
reinterpret_cast<WPARAM>(enis), (LPARAM)0);
|
||||
// global refs are deleted in message handler
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
@ -167,23 +172,14 @@ Java_sun_awt_windows_WInputMethod_handleNativeIMEEvent(JNIEnv *env, jobject self
|
||||
if (id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST &&
|
||||
id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST)
|
||||
{
|
||||
long modifiers = p->GetJavaModifiers();
|
||||
if (msg.message==WM_CHAR || msg.message==WM_SYSCHAR) {
|
||||
WCHAR unicodeChar = L'\0';
|
||||
unicodeChar = (WCHAR)msg.wParam;
|
||||
p->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 {
|
||||
MSG* pCopiedMsg = new MSG;
|
||||
*pCopiedMsg = msg;
|
||||
p->SendMessage(WM_AWT_HANDLE_EVENT, (WPARAM) FALSE,
|
||||
(LPARAM) pCopiedMsg);
|
||||
}
|
||||
jobject peerGlobalRef = env->NewGlobalRef(peer);
|
||||
|
||||
// use special message to access pData on the toolkit thread
|
||||
AwtToolkit::GetInstance().SendMessage(WM_AWT_HANDLE_NATIVE_IME_EVENT,
|
||||
reinterpret_cast<WPARAM>(peerGlobalRef),
|
||||
reinterpret_cast<LPARAM>(&msg));
|
||||
// global ref is deleted in message handler
|
||||
|
||||
(env)->SetBooleanField(event, AwtAWTEvent::consumedID, JNI_TRUE);
|
||||
}
|
||||
|
||||
@ -373,22 +369,27 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WInputMethod_setStatusWindowVisible
|
||||
Windows system creates a default input method window for the
|
||||
toolkit thread.
|
||||
*/
|
||||
HWND hwndIME = AwtToolkit::GetInstance().GetInputMethodWindow();
|
||||
if (hwndIME == NULL) {
|
||||
if (peer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
AwtComponent* p = (AwtComponent*)JNI_GET_PDATA(peer);
|
||||
if (p == NULL || (hwndIME = ImmGetDefaultIMEWnd(p->GetHWnd())) == NULL) {
|
||||
return;
|
||||
}
|
||||
HWND defaultIMEHandler = AwtToolkit::GetInstance().GetInputMethodWindow();
|
||||
|
||||
AwtToolkit::GetInstance().SetInputMethodWindow(hwndIME);
|
||||
if (defaultIMEHandler == NULL)
|
||||
{
|
||||
jobject peerGlobalRef = env->NewGlobalRef(peer);
|
||||
|
||||
// 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,
|
||||
visible ? IMC_OPENSTATUSWINDOW : IMC_CLOSESTATUSWINDOW, 0);
|
||||
if (defaultIMEHandler != NULL) {
|
||||
::SendMessage(defaultIMEHandler, WM_IME_CONTROL,
|
||||
visible ? IMC_OPENSTATUSWINDOW : IMC_CLOSESTATUSWINDOW, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -417,6 +418,7 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WInputMethod_openCandidateWindow
|
||||
// use special message to open candidate window in main thread.
|
||||
AwtToolkit::GetInstance().SendMessage(WM_AWT_OPENCANDIDATEWINDOW,
|
||||
(WPARAM)peerGlobalRef, MAKELONG(x, y));
|
||||
// global ref is deleted in message handler
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
@ -804,8 +804,73 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
return 0;
|
||||
}
|
||||
case WM_AWT_ASSOCIATECONTEXT: {
|
||||
AwtComponent *p = AwtComponent::GetComponent((HWND)wParam);
|
||||
p->ImmAssociateContext((HIMC)lParam);
|
||||
EnableNativeIMEStruct *data = (EnableNativeIMEStruct*)wParam;
|
||||
|
||||
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;
|
||||
}
|
||||
case WM_AWT_ENDCOMPOSITION: {
|
||||
|
@ -61,6 +61,14 @@ class AwtDropTarget;
|
||||
typedef VOID (CALLBACK* IDLEPROC)(VOID);
|
||||
typedef BOOL (CALLBACK* PEEKMESSAGEPROC)(MSG&);
|
||||
|
||||
// Struct for _WInputMethod_enable|disableNativeIME method
|
||||
struct EnableNativeIMEStruct {
|
||||
jobject self;
|
||||
jobject peer;
|
||||
jint context;
|
||||
jboolean useNativeCompWindow;
|
||||
};
|
||||
|
||||
/*
|
||||
* class JNILocalFrame
|
||||
* Push/PopLocalFrame helper
|
||||
|
@ -208,6 +208,8 @@ enum {
|
||||
WM_AWT_CREATECONTEXT,
|
||||
WM_AWT_DESTROYCONTEXT,
|
||||
WM_AWT_ASSOCIATECONTEXT,
|
||||
WM_AWT_GET_DEFAULT_IME_HANDLER,
|
||||
WM_AWT_HANDLE_NATIVE_IME_EVENT,
|
||||
WM_AWT_PRE_KEYDOWN,
|
||||
WM_AWT_PRE_KEYUP,
|
||||
WM_AWT_PRE_SYSKEYDOWN,
|
||||
|
Loading…
x
Reference in New Issue
Block a user