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