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