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 #define IS_WIN8 ( \ 179 (IS_WINVISTA && (HIBYTE(LOWORD(::GetVersion())) >= 2)) || \ 180 (LOBYTE(LOWORD(::GetVersion())) > 6)) 181 182 #define IS_WINVER_ATLEAST(maj, min) \ 183 ((maj) < LOBYTE(LOWORD(::GetVersion())) || \ 184 (maj) == LOBYTE(LOWORD(::GetVersion())) && \ 185 (min) <= HIBYTE(LOWORD(::GetVersion()))) 186 187 /* 188 * macros to crack a LPARAM into two ints -- used for signed coordinates, 189 * such as with mouse messages. 190 */ 191 #define LO_INT(l) ((int)(short)(l)) 192 #define HI_INT(l) ((int)(short)(((DWORD)(l) >> 16) & 0xFFFF)) 193 194 extern JavaVM *jvm; 195 196 // Platform encoding is Unicode (UTF-16), re-define JNU_ functions 197 // to proper JNI functions. 198 #define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast<const jchar*>(x), static_cast<jsize>(_tcslen(x))) 199 #define JNU_GetStringPlatformChars(env, x, y) reinterpret_cast<LPCWSTR>(env->GetStringChars(x, y)) 200 #define JNU_ReleaseStringPlatformChars(env, x, y) env->ReleaseStringChars(x, reinterpret_cast<const jchar*>(y)) 201 202 /* 203 * Itanium symbols needed for 64-bit compilation. 204 * These are defined in winuser.h in the August 2001 MSDN update. 205 */ 206 #ifndef GCLP_HBRBACKGROUND 207 #ifdef _WIN64 208 #error Macros for GetClassLongPtr, etc. are for 32-bit windows only 209 #endif /* !_WIN64 */ 210 #define GetClassLongPtr GetClassLong 211 #define SetClassLongPtr SetClassLong 212 #define GCLP_HBRBACKGROUND GCL_HBRBACKGROUND 213 #define GCLP_HCURSOR GCL_HCURSOR 214 #define GCLP_HICON GCL_HICON 215 #define GCLP_HICONSM GCL_HICONSM 216 #define GCLP_HMODULE GCL_HMODULE 217 #define GCLP_MENUNAME GCL_MENUNAME 218 #define GCLP_WNDPROC GCL_WNDPROC 219 #define GetWindowLongPtr GetWindowLong 220 #define SetWindowLongPtr SetWindowLong 221 #define GWLP_WNDPROC GWL_WNDPROC 222 #define GWLP_HINSTANCE GWL_HINSTANCE 223 #define GWLP_HWNDPARENT GWL_HWNDPARENT 224 #define GWLP_ID GWL_ID 225 #define GWLP_USERDATA GWL_USERDATA 226 #define DWLP_DLGPROC DWL_DLGPROC 227 #define DWLP_MSGRESULT DWL_MSGRESULT 228 #define DWLP_USER DWL_USER 229 #endif /* !GCLP_HBRBACKGROUND */ 230 231 /* 232 * macros for saving and restoring FPU control word 233 * NOTE: float.h must be defined if using these macros 234 */ 235 #define SAVE_CONTROLWORD \ 236 unsigned int fpu_cw = _control87(0, 0); 237 238 #define RESTORE_CONTROLWORD \ 239 if (_control87(0, 0) != fpu_cw) { \ 240 _control87(fpu_cw, 0xffffffff); \ 241 } 242 243 /* 244 * checks if the current thread is/isn't the toolkit thread 245 */ 246 #if defined(DEBUG) 247 #define CHECK_IS_TOOLKIT_THREAD() \ 248 if (GetCurrentThreadId() != AwtToolkit::MainThread()) \ 249 { JNU_ThrowInternalError(env,"Operation is not permitted on non-toolkit thread!\n"); } 250 #define CHECK_ISNOT_TOOLKIT_THREAD() \ 251 if (GetCurrentThreadId() == AwtToolkit::MainThread()) \ 252 { JNU_ThrowInternalError(env,"Operation is not permitted on toolkit thread!\n"); } 253 #else 254 #define CHECK_IS_TOOLKIT_THREAD() 255 #define CHECK_ISNOT_TOOLKIT_THREAD() 256 #endif 257 258 259 struct EnvHolder 260 { 261 JavaVM *m_pVM; 262 JNIEnv *m_env; 263 bool m_isOwner; 264 EnvHolder( 265 JavaVM *pVM, 266 LPCSTR name = "COM holder", 267 jint ver = JNI_VERSION_1_2) m_pVMEnvHolder268 : m_pVM(pVM), 269 m_env((JNIEnv *)JNU_GetEnv(pVM, ver)), 270 m_isOwner(false) 271 { 272 if (NULL == m_env) { 273 JavaVMAttachArgs attachArgs; 274 attachArgs.version = ver; 275 attachArgs.name = const_cast<char *>(name); 276 attachArgs.group = NULL; 277 jint status = m_pVM->AttachCurrentThread( 278 (void**)&m_env, 279 &attachArgs); 280 m_isOwner = (NULL!=m_env); 281 } 282 } ~EnvHolderEnvHolder283 ~EnvHolder() { 284 if (m_isOwner) { 285 m_pVM->DetachCurrentThread(); 286 } 287 } 288 operator bool() const { return NULL!=m_env; } 289 bool operator !() const { return NULL==m_env; } 290 operator JNIEnv*() const { return m_env; } 291 JNIEnv* operator ->() const { return m_env; } 292 }; 293 294 template <class T> 295 class JLocalRef { 296 JNIEnv* m_env; 297 T m_localJRef; 298 299 public: 300 JLocalRef(JNIEnv* env, T localJRef = NULL) m_env(env)301 : m_env(env), 302 m_localJRef(localJRef) 303 {} Detach()304 T Detach() { 305 T ret = m_localJRef; 306 m_localJRef = NULL; 307 return ret; 308 } Attach(T newValue)309 void Attach(T newValue) { 310 if (m_localJRef) { 311 m_env->DeleteLocalRef((jobject)m_localJRef); 312 } 313 m_localJRef = newValue; 314 } 315 T()316 operator T() { return m_localJRef; } 317 operator bool() { return NULL!=m_localJRef; } 318 bool operator !() { return NULL==m_localJRef; } 319 ~JLocalRef()320 ~JLocalRef() { 321 if (m_localJRef) { 322 m_env->DeleteLocalRef((jobject)m_localJRef); 323 } 324 } 325 }; 326 327 typedef JLocalRef<jobject> JLObject; 328 typedef JLocalRef<jstring> JLString; 329 typedef JLocalRef<jclass> JLClass; 330 331 /* 332 * Class to encapsulate the extraction of the java string contents 333 * into a buffer and the cleanup of the buffer 334 */ 335 class JavaStringBuffer 336 { 337 protected: 338 LPWSTR m_pStr; 339 jsize m_dwSize; getNonEmptyString()340 LPWSTR getNonEmptyString() { 341 return (NULL==m_pStr) 342 ? L"" 343 : m_pStr; 344 } 345 346 public: JavaStringBuffer(jsize cbTCharCount)347 JavaStringBuffer(jsize cbTCharCount) { 348 m_dwSize = cbTCharCount; 349 m_pStr = (0 == m_dwSize) 350 ? NULL 351 : (LPWSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (m_dwSize+1), sizeof(WCHAR) ); 352 } 353 JavaStringBuffer(JNIEnv * env,jstring text)354 JavaStringBuffer(JNIEnv *env, jstring text) { 355 m_dwSize = (NULL == text) 356 ? 0 357 : env->GetStringLength(text); 358 if (0 == m_dwSize) { 359 m_pStr = NULL; 360 } else { 361 m_pStr = (LPWSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (m_dwSize+1), sizeof(WCHAR) ); 362 env->GetStringRegion(text, 0, m_dwSize, reinterpret_cast<jchar *>(m_pStr)); 363 m_pStr[m_dwSize] = 0; 364 } 365 } 366 367 ~JavaStringBuffer()368 ~JavaStringBuffer() { 369 free(m_pStr); 370 } 371 Resize(jsize cbTCharCount)372 void Resize(jsize cbTCharCount) { 373 m_dwSize = cbTCharCount; 374 //It is ok to have non-null terminated string here. 375 //The function is used only for space reservation in staff buffer for 376 //followed data copying process. And that is the reason why we ignore 377 //the special case m_dwSize==0 here. 378 m_pStr = (LPWSTR)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_pStr, m_dwSize+1, sizeof(WCHAR) ); 379 } 380 //we are in UNICODE now, so LPWSTR:=:LPTSTR LPWSTR()381 operator LPWSTR() { return getNonEmptyString(); } LPARAM()382 operator LPARAM() { return (LPARAM)getNonEmptyString(); } GetData()383 void *GetData() { return (void *)getNonEmptyString(); } GetSize()384 jsize GetSize() { return m_dwSize; } 385 }; 386 387 388 #endif /* _AWT_H_ */ 389