1/* 2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26#include "awt_Object.h" 27#include "ObjectList.h" 28 29#ifdef DEBUG 30static BOOL reportEvents = FALSE; 31#endif 32 33 34/************************************************************************ 35 * AwtObject fields 36 */ 37 38jfieldID AwtObject::pDataID; 39jfieldID AwtObject::destroyedID; 40jfieldID AwtObject::targetID; 41jclass AwtObject::wObjectPeerClass; 42jmethodID AwtObject::getPeerForTargetMID; 43jfieldID AwtObject::createErrorID; 44 45 46/************************************************************************ 47 * AwtObject methods 48 */ 49 50AwtObject::AwtObject() 51{ 52 theAwtObjectList.Add(this); 53 m_peerObject = NULL; 54 m_callbacksEnabled = TRUE; 55} 56 57AwtObject::~AwtObject() 58{ 59} 60 61void AwtObject::Dispose() 62{ 63 AwtToolkit::GetInstance().PostMessage(WM_AWT_DELETEOBJECT, (WPARAM)this, (LPARAM)0); 64} 65 66void AwtObject::_Dispose(jobject self) 67{ 68 TRY_NO_VERIFY; 69 70 CriticalSection::Lock l(AwtToolkit::GetInstance().GetSyncCS()); 71 72 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 73 jobject selfGlobalRef = env->NewGlobalRef(self); 74 75 // value 0 of lParam means that we should not attempt to enter the 76 // SyncCall critical section, as it was entered someshere earlier 77 AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)selfGlobalRef, (LPARAM)0); 78 79 CATCH_BAD_ALLOC; 80} 81 82void AwtObject::_Dispose(PDATA pData) 83{ 84 TRY_NO_VERIFY; 85 86 CriticalSection::Lock l(AwtToolkit::GetInstance().GetSyncCS()); 87 88 AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSEPDATA, (WPARAM)pData, (LPARAM)0); 89 90 CATCH_BAD_ALLOC; 91} 92/* 93 * Return the peer associated with some target. This information is 94 * maintained in a hashtable at the java level. 95 */ 96jobject AwtObject::GetPeerForTarget(JNIEnv *env, jobject target) 97{ 98 jobject result = 99 env->CallStaticObjectMethod(AwtObject::wObjectPeerClass, 100 AwtObject::getPeerForTargetMID, 101 target); 102 103 DASSERT(!safe_ExceptionOccurred(env)); 104 return result; 105} 106 107/* Execute a callback to the associated Java peer. */ 108void 109AwtObject::DoCallback(const char* methodName, const char* methodSig, ...) 110{ 111 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 112 113 /* don't callback during the create & initialization process */ 114 if (m_peerObject != NULL && m_callbacksEnabled) { 115 va_list args; 116 va_start(args, methodSig); 117#ifdef DEBUG 118 if (reportEvents) { 119 jstring targetStr = 120 (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env), 121 "getName", 122 "()Ljava/lang/String;").l; 123 DASSERT(!safe_ExceptionOccurred(env)); 124 LPCWSTR targetStrW = JNU_GetStringPlatformChars(env, targetStr, NULL); 125 printf("Posting %s%s method to %S\n", methodName, methodSig, targetStrW); 126 JNU_ReleaseStringPlatformChars(env, targetStr, targetStrW); 127 } 128#endif 129 /* caching would do much good here */ 130 JNU_CallMethodByNameV(env, NULL, GetPeer(env), 131 methodName, methodSig, args); 132 { 133 jthrowable exc = safe_ExceptionOccurred(env); 134 if (exc) { 135 env->DeleteLocalRef(exc); 136 env->ExceptionDescribe(); 137 env->ExceptionClear(); 138 } 139 } 140 DASSERT(!safe_ExceptionOccurred(env)); 141 va_end(args); 142 } 143} 144 145void AwtObject::SendEvent(jobject event) 146{ 147 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 148 149#ifdef DEBUG 150 if (reportEvents) { 151 jstring eventStr = JNU_ToString(env, event); 152 DASSERT(!safe_ExceptionOccurred(env)); 153 jstring targetStr = 154 (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env),"getName", 155 "()Ljava/lang/String;").l; 156 DASSERT(!safe_ExceptionOccurred(env)); 157 LPCWSTR eventStrW = JNU_GetStringPlatformChars(env, eventStr, NULL); 158 LPCWSTR targetStrW = JNU_GetStringPlatformChars(env, targetStr, NULL); 159 printf("Posting %S to %S\n", eventStrW, targetStrW); 160 JNU_ReleaseStringPlatformChars(env, eventStr, eventStrW); 161 JNU_ReleaseStringPlatformChars(env, targetStr, targetStrW); 162 } 163#endif 164 /* Post event to the system EventQueue. */ 165 JNU_CallMethodByName(env, NULL, GetPeer(env), "postEvent", 166 "(Ljava/awt/AWTEvent;)V", event); 167 { 168 jthrowable exc = safe_ExceptionOccurred(env); 169 if (exc) { 170 env->DeleteLocalRef(exc); 171 env->ExceptionDescribe(); 172 } 173 } 174 DASSERT(!safe_ExceptionOccurred(env)); 175} 176 177// 178// (static) 179// Switches to Windows thread via SendMessage and synchronously 180// calls AwtObject::WinThreadExecProc with the given command id 181// and parameters. 182// 183// Useful for writing code that needs to be synchronized with 184// what's happening on the Windows thread. 185// 186LRESULT AwtObject::WinThreadExec( 187 jobject peerObject, 188 UINT cmdId, 189 LPARAM param1, 190 LPARAM param2, 191 LPARAM param3, 192 LPARAM param4 ) 193{ 194 DASSERT( peerObject != NULL); 195 196 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 197 // since we pass peerObject to another thread we must 198 // make a global ref 199 jobject peerObjectGlobalRef = env->NewGlobalRef(peerObject); 200 201 ExecuteArgs args; 202 LRESULT retVal; 203 204 // setup arguments 205 args.cmdId = cmdId; 206 args.param1 = param1; 207 args.param2 = param2; 208 args.param3 = param3; 209 args.param4 = param4; 210 211 // call WinThreadExecProc on the toolkit thread 212 retVal = AwtToolkit::GetInstance().SendMessage(WM_AWT_EXECUTE_SYNC, 213 (WPARAM)peerObjectGlobalRef, 214 (LPARAM)&args); 215 return retVal; 216} 217 218LRESULT AwtObject::WinThreadExecProc(ExecuteArgs * args) 219{ 220 DASSERT(FALSE); // no default handler 221 return 0L; 222} 223 224/************************************************************************ 225 * WObjectPeer native methods 226 */ 227 228extern "C" { 229 230JNIEXPORT void JNICALL 231Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) { 232 TRY; 233 234 AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls); 235 DASSERT(AwtObject::wObjectPeerClass != NULL); 236 CHECK_NULL(AwtObject::wObjectPeerClass); 237 238 AwtObject::pDataID = env->GetFieldID(cls, "pData", "J"); 239 DASSERT(AwtObject::pDataID != NULL); 240 CHECK_NULL(AwtObject::pDataID); 241 242 AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z"); 243 DASSERT(AwtObject::destroyedID != NULL); 244 CHECK_NULL(AwtObject::destroyedID); 245 246 AwtObject::targetID = env->GetFieldID(cls, "target", 247 "Ljava/lang/Object;"); 248 DASSERT(AwtObject::targetID != NULL); 249 CHECK_NULL(AwtObject::targetID); 250 251 AwtObject::getPeerForTargetMID = 252 env->GetStaticMethodID(cls, "getPeerForTarget", 253 "(Ljava/lang/Object;)Lsun/awt/windows/WObjectPeer;"); 254 DASSERT(AwtObject::getPeerForTargetMID != NULL); 255 CHECK_NULL(AwtObject::getPeerForTargetMID); 256 257 AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;"); 258 DASSERT(AwtObject::createErrorID != NULL); 259 CHECK_NULL(AwtObject::createErrorID); 260 261 CATCH_BAD_ALLOC; 262} 263 264} /* extern "C" */ 265