1/* 2 * Copyright (c) 2011, 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#import "JNIUtilities.h" 27#import <JavaRuntimeSupport/JavaRuntimeSupport.h> 28 29#import "apple_laf_JRSUIControl.h" 30#import "apple_laf_JRSUIConstants_DoubleValue.h" 31#import "apple_laf_JRSUIConstants_Hit.h" 32 33#import "JRSUIConstantSync.h" 34 35 36static JRSUIRendererRef gRenderer; 37 38/* 39 * Class: apple_laf_JRSUIControl 40 * Method: initNativeJRSUI 41 * Signature: ()I 42 */ 43JNIEXPORT jint JNICALL Java_apple_laf_JRSUIControl_initNativeJRSUI 44(JNIEnv *env, jclass clazz) 45{ 46 BOOL coherent = _InitializeJRSProperties(); 47 if (!coherent) return apple_laf_JRSUIControl_INCOHERENT; 48 49 gRenderer = JRSUIRendererCreate(); 50 if (gRenderer == NULL) return apple_laf_JRSUIControl_NULL_PTR; 51 52 return apple_laf_JRSUIControl_SUCCESS; 53} 54 55/* 56 * Class: apple_laf_JRSUIControl 57 * Method: getPtrOfBuffer 58 * Signature: (Ljava/nio/ByteBuffer;)J 59 */ 60JNIEXPORT jlong JNICALL Java_apple_laf_JRSUIControl_getPtrOfBuffer 61(JNIEnv *env, jclass clazz, jobject byteBuffer) 62{ 63 char *byteBufferPtr = (*env)->GetDirectBufferAddress(env, byteBuffer); 64 if (byteBufferPtr == NULL) return 0L; 65 return ptr_to_jlong(byteBufferPtr); // GC 66} 67 68/* 69 * Class: apple_laf_JRSUIControl 70 * Method: getCFDictionary 71 * Signature: (Z)J 72 */ 73JNIEXPORT jlong JNICALL Java_apple_laf_JRSUIControl_getCFDictionary 74(JNIEnv *env, jclass clazz, jboolean isFlipped) 75{ 76 return ptr_to_jlong(JRSUIControlCreate(isFlipped)); 77} 78 79/* 80 * Class: apple_laf_JRSUIControl 81 * Method: disposeCFDictionary 82 * Signature: (J)V 83 */ 84JNIEXPORT void JNICALL Java_apple_laf_JRSUIControl_disposeCFDictionary 85(JNIEnv *env, jclass clazz, jlong controlPtr) 86{ 87 void *ptr = jlong_to_ptr(controlPtr); 88 if (!ptr) return; 89 JRSUIControlRelease((JRSUIControlRef)ptr); 90} 91 92 93static inline void *getValueFor 94(jbyte code, UInt8 *changeBuffer, size_t *dataSizePtr) 95{ 96 switch (code) 97 { 98 case apple_laf_JRSUIConstants_DoubleValue_TYPE_CODE: 99 *dataSizePtr = sizeof(jdouble); 100 jdouble doubleValue = (*(jdouble *)changeBuffer); 101 return (void *)CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &doubleValue); 102 } 103 104 return NULL; 105} 106 107static inline jint syncChangesToControl 108(JRSUIControlRef control, UInt8 *changeBuffer) 109{ 110 UInt8 *endOfBuffer = changeBuffer + apple_laf_JRSUIControl_NIO_BUFFER_SIZE; 111 112 while (changeBuffer < endOfBuffer) 113 { 114 // dereference the pointer to the constant that was stored as a jlong in the byte buffer 115 CFStringRef key = (CFStringRef)jlong_to_ptr(*((jlong *)changeBuffer)); 116 if (key == NULL) return apple_laf_JRSUIControl_SUCCESS; 117 changeBuffer += sizeof(jlong); 118 119 jbyte code = *((jbyte *)changeBuffer); 120 changeBuffer += sizeof(jbyte); 121 122 size_t dataSize; 123 void *value = (void *)getValueFor(code, changeBuffer, &dataSize); 124 if (value == NULL) { 125 NSLog(@"null pointer for %@ for value %d", key, (int)code); 126 127 return apple_laf_JRSUIControl_NULL_PTR; 128 } 129 130 changeBuffer += dataSize; 131 JRSUIControlSetValueByKey(control, key, value); 132 CFRelease(value); 133 } 134 135 return apple_laf_JRSUIControl_SUCCESS; 136} 137 138static inline jint doSyncChanges 139(JNIEnv *env, jlong controlPtr, jlong byteBufferPtr) 140{ 141 JRSUIControlRef control = (JRSUIControlRef)jlong_to_ptr(controlPtr); 142 UInt8 *changeBuffer = (UInt8 *)jlong_to_ptr(byteBufferPtr); 143 144 return syncChangesToControl(control, changeBuffer); 145} 146 147/* 148 * Class: apple_laf_JRSUIControl 149 * Method: syncChanges 150 * Signature: (JJ)I 151 */ 152JNIEXPORT jint JNICALL Java_apple_laf_JRSUIControl_syncChanges 153(JNIEnv *env, jclass clazz, jlong controlPtr, jlong byteBufferPtr) 154{ 155 return doSyncChanges(env, controlPtr, byteBufferPtr); 156} 157 158static inline jint doPaintCGContext(CGContextRef cgRef, jlong controlPtr, jlong oldProperties, jlong newProperties, jdouble x, jdouble y, jdouble w, jdouble h) 159{ 160 JRSUIControlRef control = (JRSUIControlRef)jlong_to_ptr(controlPtr); 161 _SyncEncodedProperties(control, oldProperties, newProperties); 162 CGRect bounds = CGRectMake(x, y, w, h); 163 JRSUIControlDraw(gRenderer, control, cgRef, bounds); 164 return 0; 165} 166 167/* 168 * Class: apple_laf_JRSUIControl 169 * Method: paintToCGContext 170 * Signature: (JJJJDDDD)I 171 */ 172JNIEXPORT jint JNICALL Java_apple_laf_JRSUIControl_paintToCGContext 173(JNIEnv *env, jclass clazz, jlong cgContextPtr, jlong controlPtr, jlong oldProperties, jlong newProperties, jdouble x, jdouble y, jdouble w, jdouble h) 174{ 175 return doPaintCGContext((CGContextRef)jlong_to_ptr(cgContextPtr), controlPtr, oldProperties, newProperties, x, y, w, h); 176} 177 178/* 179 * Class: apple_laf_JRSUIControl 180 * Method: paintChangesToCGContext 181 * Signature: (JJJJDDDDJ)I 182 */ 183JNIEXPORT jint JNICALL Java_apple_laf_JRSUIControl_paintChangesToCGContext 184(JNIEnv *env, jclass clazz, jlong cgContextPtr, jlong controlPtr, jlong oldProperties, jlong newProperties, jdouble x, jdouble y, jdouble w, jdouble h, jlong changes) 185{ 186 int syncStatus = doSyncChanges(env, controlPtr, changes); 187 if (syncStatus != apple_laf_JRSUIControl_SUCCESS) return syncStatus; 188 189 return doPaintCGContext((CGContextRef)jlong_to_ptr(cgContextPtr), controlPtr, oldProperties, newProperties, x, y, w, h); 190} 191 192static inline jint doPaintImage 193(JNIEnv *env, jlong controlPtr, jlong oldProperties, jlong newProperties, jintArray data, jint imgW, jint imgH, jdouble x, jdouble y, jdouble w, jdouble h) 194{ 195 jboolean isCopy = JNI_FALSE; 196 void *rawPixelData = (*env)->GetPrimitiveArrayCritical(env, data, &isCopy); 197 if (!rawPixelData) return apple_laf_JRSUIControl_NULL_PTR; 198 199 CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); 200 CGContextRef cgRef = CGBitmapContextCreate(rawPixelData, imgW, imgH, 8, imgW * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); 201 CGColorSpaceRelease(colorspace); 202 CGContextScaleCTM(cgRef, imgW/(w + x + x) , imgH/(h + y + y)); 203 204 jint status = doPaintCGContext(cgRef, controlPtr, oldProperties, newProperties, x, y, w, h); 205 CGContextRelease(cgRef); 206 207 (*env)->ReleasePrimitiveArrayCritical(env, data, rawPixelData, 0); 208 209 return status == noErr ? apple_laf_JRSUIControl_SUCCESS : status; 210} 211 212/* 213 * Class: apple_laf_JRSUIControl 214 * Method: paintImage 215 * Signature: ([IIIJJJDDDD)I 216 */ 217JNIEXPORT jint JNICALL Java_apple_laf_JRSUIControl_paintImage 218(JNIEnv *env, jclass clazz, jintArray data, jint imgW, jint imgH, jlong controlPtr, jlong oldProperties, jlong newProperties, jdouble x, jdouble y, jdouble w, jdouble h) 219{ 220 return doPaintImage(env, controlPtr, oldProperties, newProperties, data, imgW, imgH, x, y, w, h); 221} 222 223/* 224 * Class: apple_laf_JRSUIControl 225 * Method: paintChangesImage 226 * Signature: ([IIIJJJDDDDJ)I 227 */ 228JNIEXPORT jint JNICALL Java_apple_laf_JRSUIControl_paintChangesImage 229(JNIEnv *env, jclass clazz, jintArray data, jint imgW, jint imgH, jlong controlPtr, jlong oldProperties, jlong newProperties, jdouble x, jdouble y, jdouble w, jdouble h, jlong changes) 230{ 231 int syncStatus = doSyncChanges(env, controlPtr, changes); 232 if (syncStatus != apple_laf_JRSUIControl_SUCCESS) return syncStatus; 233 234 return doPaintImage(env, controlPtr, oldProperties, newProperties, data, imgW, imgH, x, y, w, h); 235} 236 237/* 238 * Class: apple_laf_JRSUIControl 239 * Method: getNativeHitPart 240 * Signature: (JJJDDDDDD)I 241 */ 242JNIEXPORT jint JNICALL Java_apple_laf_JRSUIControl_getNativeHitPart 243(JNIEnv *env, jclass clazz, jlong controlPtr, jlong oldProperties, jlong newProperties, jdouble x, jdouble y, jdouble w, jdouble h, jdouble pointX, jdouble pointY) 244{ 245 JRSUIControlRef control = (JRSUIControlRef)jlong_to_ptr(controlPtr); 246 _SyncEncodedProperties(control, oldProperties, newProperties); 247 248 CGRect bounds = CGRectMake(x, y, w, h); 249 CGPoint point = CGPointMake(pointX, pointY); 250 251 return JRSUIControlGetHitPart(gRenderer, control, bounds, point); 252} 253 254/* 255 * Class: apple_laf_JRSUIUtils_ScrollBar 256 * Method: shouldUseScrollToClick 257 * Signature: ()Z 258 */ 259JNIEXPORT jboolean JNICALL Java_apple_laf_JRSUIUtils_00024ScrollBar_shouldUseScrollToClick 260(JNIEnv *env, jclass clazz) 261{ 262 return JRSUIControlShouldScrollToClick(); 263} 264 265/* 266 * Class: apple_laf_JRSUIControl 267 * Method: getNativePartBounds 268 * Signature: ([DJJJDDDDI)V 269 */ 270JNIEXPORT void JNICALL Java_apple_laf_JRSUIControl_getNativePartBounds 271(JNIEnv *env, jclass clazz, jdoubleArray rectArray, jlong controlPtr, jlong oldProperties, jlong newProperties, jdouble x, jdouble y, jdouble w, jdouble h, jint part) 272{ 273 JRSUIControlRef control = (JRSUIControlRef)jlong_to_ptr(controlPtr); 274 _SyncEncodedProperties(control, oldProperties, newProperties); 275 276 CGRect frame = CGRectMake(x, y, w, h); 277 CGRect partBounds = JRSUIControlGetScrollBarPartBounds(control, frame, part); 278 279 jdouble *rect = (*env)->GetPrimitiveArrayCritical(env, rectArray, NULL); 280 rect[0] = partBounds.origin.x; 281 rect[1] = partBounds.origin.y; 282 rect[2] = partBounds.size.width; 283 rect[3] = partBounds.size.height; 284 (*env)->ReleasePrimitiveArrayCritical(env, rectArray, rect, 0); 285} 286 287/* 288 * Class: apple_laf_JRSUIControl 289 * Method: getNativeScrollBarOffsetChange 290 * Signature: (JJJDDDDIII)D 291 */ 292JNIEXPORT jdouble JNICALL Java_apple_laf_JRSUIControl_getNativeScrollBarOffsetChange 293(JNIEnv *env, jclass clazz, jlong controlPtr, jlong oldProperties, jlong newProperties, jdouble x, jdouble y, jdouble w, jdouble h, jint offset, jint visibleAmount, jint extent) 294{ 295 JRSUIControlRef control = (JRSUIControlRef)jlong_to_ptr(controlPtr); 296 _SyncEncodedProperties(control, oldProperties, newProperties); 297 298 CGRect frame = CGRectMake(x, y, w, h); 299 return (jdouble)JRSUIControlGetScrollBarOffsetFor(control, frame, offset, visibleAmount, extent); 300} 301