1 /* 2 * Copyright (c) 1996, 2014, 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 #ifndef _AWT_H_ 27 #define _AWT_H_ 28 29 #ifndef _WIN32_WINNT 30 #define _WIN32_WINNT 0x0600 31 #endif 32 33 #ifndef _WIN32_IE 34 #define _WIN32_IE 0x0600 35 #endif 36 37 //#ifndef NTDDI_VERSION 38 //#define NTDDI_VERSION NTDDI_LONGHORN 39 //#endif 40 41 #include "stdhdrs.h" 42 #include "alloc.h" 43 #include "awt_Debug.h" 44 45 extern COLORREF DesktopColor2RGB(int colorIndex); 46 47 class AwtObject; 48 typedef AwtObject* PDATA; 49 50 #define JNI_IS_TRUE(obj) ((obj) ? JNI_TRUE : JNI_FALSE) 51 52 #define JNI_CHECK_NULL_GOTO(obj, msg, where) { \ 53 if (obj == NULL) { \ 54 env->ExceptionClear(); \ 55 JNU_ThrowNullPointerException(env, msg); \ 56 goto where; \ 57 } \ 58 } 59 60 #define JNI_CHECK_NULL_RETURN(obj, msg) { \ 61 if (obj == NULL) { \ 62 env->ExceptionClear(); \ 63 JNU_ThrowNullPointerException(env, msg); \ 64 return; \ 65 } \ 66 } 67 68 #define JNI_CHECK_PEER_CREATION_RETURN(peer) { \ 69 if (peer == NULL ) { \ 70 return; \ 71 } \ 72 pData = JNI_GET_PDATA(peer); \ 73 if (pData == NULL) { \ 74 return; \ 75 } \ 76 } 77 78 #define JNI_CHECK_NULL_RETURN_NULL(obj, msg) { \ 79 if (obj == NULL) { \ 80 env->ExceptionClear(); \ 81 JNU_ThrowNullPointerException(env, msg); \ 82 return 0; \ 83 } \ 84 } 85 86 #define JNI_CHECK_NULL_RETURN_VAL(obj, msg, val) { \ 87 if (obj == NULL) { \ 88 env->ExceptionClear(); \ 89 JNU_ThrowNullPointerException(env, msg); \ 90 return val; \ 91 } \ 92 } 93 94 /** 95 * This macros must be used under SyncCall or on the Toolkit thread. 96 */ 97 #define JNI_CHECK_PEER_GOTO(peer, where) { \ 98 JNI_CHECK_NULL_GOTO(peer, "peer", where); \ 99 pData = JNI_GET_PDATA(peer); \ 100 if (pData == NULL) { \ 101 THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ 102 goto where; \ 103 } \ 104 } 105 106 /** 107 * This macros must be used under SyncCall or on the Toolkit thread. 108 */ 109 #define JNI_CHECK_PEER_RETURN(peer) { \ 110 JNI_CHECK_NULL_RETURN(peer, "peer"); \ 111 pData = JNI_GET_PDATA(peer); \ 112 if (pData == NULL) { \ 113 THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ 114 return; \ 115 } \ 116 } 117 118 /** 119 * This macros must be used under SyncCall or on the Toolkit thread. 120 */ 121 #define JNI_CHECK_PEER_RETURN_NULL(peer) { \ 122 JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \ 123 pData = JNI_GET_PDATA(peer); \ 124 if (pData == NULL) { \ 125 THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ 126 return 0; \ 127 } \ 128 } 129 130 /** 131 * This macros must be used under SyncCall or on the Toolkit thread. 132 */ 133 #define JNI_CHECK_PEER_RETURN_VAL(peer, val) { \ 134 JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \ 135 pData = JNI_GET_PDATA(peer); \ 136 if (pData == NULL) { \ 137 THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ 138 return val; \ 139 } \ 140 } 141 142 #define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) { \ 143 jboolean destroyed = JNI_GET_DESTROYED(peer); \ 144 if (destroyed != JNI_TRUE) { \ 145 env->ExceptionClear(); \ 146 JNU_ThrowNullPointerException(env, "null pData"); \ 147 } \ 148 } 149 150 #define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID) 151 #define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID) 152 153 #define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \ 154 AwtObject::pDataID, \ 155 (jlong)data) 156 #define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer, \ 157 AwtObject::destroyedID, \ 158 JNI_TRUE) 159 /* /NEW JNI */ 160 161 /* 162 * IS_WIN64 returns TRUE on 64-bit Itanium 163 */ 164 #if defined (_WIN64) 165 #define IS_WIN64 TRUE 166 #else 167 #define IS_WIN64 FALSE 168 #endif 169 170 /* 171 * IS_WIN2000 returns TRUE on 2000, XP and Vista 172 * IS_WINXP returns TRUE on XP and Vista 173 * IS_WINVISTA returns TRUE on Vista 174 */ 175 #define IS_WIN2000 (LOBYTE(LOWORD(::GetVersion())) >= 5) 176 #define IS_WINXP ((IS_WIN2000 && HIBYTE(LOWORD(::GetVersion())) >= 1) || LOBYTE(LOWORD(::GetVersion())) > 5) 177 #define IS_WINVISTA (LOBYTE(LOWORD(::GetVersion())) >= 6) 178 179 #define IS_WINVER_ATLEAST(maj, min) \ 180 ((maj) < LOBYTE(LOWORD(::GetVersion())) || \ 181 (maj) == LOBYTE(LOWORD(::GetVersion())) && \ 182 (min) <= HIBYTE(LOWORD(::GetVersion()))) 183 184 /* 185 * macros to crack a LPARAM into two ints -- used for signed coordinates, 186 * such as with mouse messages. 187 */ 188 #define LO_INT(l) ((int)(short)(l)) 189 #define HI_INT(l) ((int)(short)(((DWORD)(l) >> 16) & 0xFFFF)) 190 191 extern JavaVM *jvm; 192 193 // Platform encoding is Unicode (UTF-16), re-define JNU_ functions 194 // to proper JNI functions. 195 #define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast<const jchar*>(x), static_cast<jsize>(_tcslen(x))) 196 #define JNU_GetStringPlatformChars(env, x, y) reinterpret_cast<LPCWSTR>(env->GetStringChars(x, y)) 197 #define JNU_ReleaseStringPlatformChars(env, x, y) env->ReleaseStringChars(x, reinterpret_cast<const jchar*>(y)) 198 199 /* 200 * Itanium symbols needed for 64-bit compilation. 201 * These are defined in winuser.h in the August 2001 MSDN update. 202 */ 203 #ifndef GCLP_HBRBACKGROUND 204 #ifdef _WIN64 205 #error Macros for GetClassLongPtr, etc. are for 32-bit windows only 206 #endif /* !_WIN64 */ 207 #define GetClassLongPtr GetClassLong 208 #define SetClassLongPtr SetClassLong 209 #define GCLP_HBRBACKGROUND GCL_HBRBACKGROUND 210 #define GCLP_HCURSOR GCL_HCURSOR 211 #define GCLP_HICON GCL_HICON 212 #define GCLP_HICONSM GCL_HICONSM 213 #define GCLP_HMODULE GCL_HMODULE 214 #define GCLP_MENUNAME GCL_MENUNAME 215 #define GCLP_WNDPROC GCL_WNDPROC 216 #define GetWindowLongPtr GetWindowLong 217 #define SetWindowLongPtr SetWindowLong 218 #define GWLP_WNDPROC GWL_WNDPROC 219 #define GWLP_HINSTANCE GWL_HINSTANCE 220 #define GWLP_HWNDPARENT GWL_HWNDPARENT 221 #define GWLP_ID GWL_ID 222 #define GWLP_USERDATA GWL_USERDATA 223 #define DWLP_DLGPROC DWL_DLGPROC 224 #define DWLP_MSGRESULT DWL_MSGRESULT 225 #define DWLP_USER DWL_USER 226 #endif /* !GCLP_HBRBACKGROUND */ 227 228 /* 229 * macros for saving and restoring FPU control word 230 * NOTE: float.h must be defined if using these macros 231 */ 232 #define SAVE_CONTROLWORD \ 233 unsigned int fpu_cw = _control87(0, 0); 234 235 #define RESTORE_CONTROLWORD \ 236 if (_control87(0, 0) != fpu_cw) { \ 237 _control87(fpu_cw, 0xffffffff); \ 238 } 239 240 /* 241 * checks if the current thread is/isn't the toolkit thread 242 */ 243 #if defined(DEBUG) || defined(INTERNAL_BUILD) 244 #define CHECK_IS_TOOLKIT_THREAD() \ 245 if (GetCurrentThreadId() != AwtToolkit::MainThread()) \ 246 { JNU_ThrowInternalError(env,"Operation is not permitted on non-toolkit thread!\n"); } 247 #define CHECK_ISNOT_TOOLKIT_THREAD() \ 248 if (GetCurrentThreadId() == AwtToolkit::MainThread()) \ 249 { JNU_ThrowInternalError(env,"Operation is not permitted on toolkit thread!\n"); } 250 #else 251 #define CHECK_IS_TOOLKIT_THREAD() 252 #define CHECK_ISNOT_TOOLKIT_THREAD() 253 #endif 254 255 256 struct EnvHolder 257 { 258 JavaVM *m_pVM; 259 JNIEnv *m_env; 260 bool m_isOwner; 261 EnvHolder( 262 JavaVM *pVM, 263 LPCSTR name = "COM holder", 264 jint ver = JNI_VERSION_1_2) 265 : m_pVM(pVM), 266 m_env((JNIEnv *)JNU_GetEnv(pVM, ver)), 267 m_isOwner(false) 268 { 269 if (NULL == m_env) { 270 JavaVMAttachArgs attachArgs; 271 attachArgs.version = ver; 272 attachArgs.name = const_cast<char *>(name); 273 attachArgs.group = NULL; 274 jint status = m_pVM->AttachCurrentThread( 275 (void**)&m_env, 276 &attachArgs); 277 m_isOwner = (NULL!=m_env); 278 } 279 } 280 ~EnvHolder() { 281 if (m_isOwner) { 282 m_pVM->DetachCurrentThread(); 283 } 284 } 285 operator bool() const { return NULL!=m_env; } 286 bool operator !() const { return NULL==m_env; } 287 operator JNIEnv*() const { return m_env; } 288 JNIEnv* operator ->() const { return m_env; } 289 }; 290 291 template <class T> 292 class JLocalRef { 293 JNIEnv* m_env; 294 T m_localJRef; 295 296 public: 297 JLocalRef(JNIEnv* env, T localJRef = NULL) 298 : m_env(env), 299 m_localJRef(localJRef) 300 {} 301 T Detach() { 302 T ret = m_localJRef; 303 m_localJRef = NULL; 304 return ret; 305 } 306 void Attach(T newValue) { 307 if (m_localJRef) { 308 m_env->DeleteLocalRef((jobject)m_localJRef); 309 } 310 m_localJRef = newValue; 311 } 312 313 operator T() { return m_localJRef; } 314 operator bool() { return NULL!=m_localJRef; } 315 bool operator !() { return NULL==m_localJRef; } 316 317 ~JLocalRef() { 318 if (m_localJRef) { 319 m_env->DeleteLocalRef((jobject)m_localJRef); 320 } 321 } 322 }; 323 324 typedef JLocalRef<jobject> JLObject; 325 typedef JLocalRef<jstring> JLString; 326 typedef JLocalRef<jclass> JLClass; 327 328 /* 329 * Class to encapsulate the extraction of the java string contents 330 * into a buffer and the cleanup of the buffer 331 */ 332 class JavaStringBuffer 333 { 334 protected: 335 LPWSTR m_pStr; 336 jsize m_dwSize; 337 LPWSTR getNonEmptyString() { 338 return (NULL==m_pStr) 339 ? L"" 340 : m_pStr; 341 } 342 343 public: 344 JavaStringBuffer(jsize cbTCharCount) { 345 m_dwSize = cbTCharCount; 346 m_pStr = (0 == m_dwSize) 347 ? NULL 348 : (LPWSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (m_dwSize+1), sizeof(WCHAR) ); 349 } 350 351 JavaStringBuffer(JNIEnv *env, jstring text) { 352 m_dwSize = (NULL == text) 353 ? 0 354 : env->GetStringLength(text); 355 if (0 == m_dwSize) { 356 m_pStr = NULL; 357 } else { 358 m_pStr = (LPWSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (m_dwSize+1), sizeof(WCHAR) ); 359 env->GetStringRegion(text, 0, m_dwSize, reinterpret_cast<jchar *>(m_pStr)); 360 m_pStr[m_dwSize] = 0; 361 } 362 } 363 364 365 ~JavaStringBuffer() { 366 free(m_pStr); 367 } 368 369 void Resize(jsize cbTCharCount) { 370 m_dwSize = cbTCharCount; 371 //It is ok to have non-null terminated string here. 372 //The function is used only for space reservation in staff buffer for 373 //followed data copying process. And that is the reason why we ignore 374 //the special case m_dwSize==0 here. 375 m_pStr = (LPWSTR)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_pStr, m_dwSize+1, sizeof(WCHAR) ); 376 } 377 //we are in UNICODE now, so LPWSTR:=:LPTSTR 378 operator LPWSTR() { return getNonEmptyString(); } 379 operator LPARAM() { return (LPARAM)getNonEmptyString(); } 380 void *GetData() { return (void *)getNonEmptyString(); } 381 jsize GetSize() { return m_dwSize; } 382 }; 383 384 385 #endif /* _AWT_H_ */