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 45extern COLORREF DesktopColor2RGB(int colorIndex); 46 47class AwtObject; 48typedef 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 179extern 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) 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 244struct 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 279template <class T> 280class JLocalRef { 281 JNIEnv* m_env; 282 T m_localJRef; 283 284public: 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 312typedef JLocalRef<jobject> JLObject; 313typedef JLocalRef<jstring> JLString; 314typedef 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 */ 320class JavaStringBuffer 321{ 322protected: 323 LPWSTR m_pStr; 324 jsize m_dwSize; 325 LPWSTR getNonEmptyString() { 326 return (NULL==m_pStr) 327 ? L"" 328 : m_pStr; 329 } 330 331public: 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_ */ 374