1 /* 2 * Copyright (c) 2011, 2013, 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 <JavaNativeFoundation/JavaNativeFoundation.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 36 static JRSUIRendererRef gRenderer; 37 38 /* 39 * Class: apple_laf_JRSUIControl 40 * Method: initNativeJRSUI 41 * Signature: ()I 42 */ 43 JNIEXPORT 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 */ 60 JNIEXPORT 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 */ 73 JNIEXPORT 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 */ 84 JNIEXPORT 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 93 static 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 107 static 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 138 static 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 */ 152 JNIEXPORT 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 158 static 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 */ 172 JNIEXPORT 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 */ 183 JNIEXPORT 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 192 static 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 , imgH/h); 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 */ 217 JNIEXPORT 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 */ 228 JNIEXPORT 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 */ 242 JNIEXPORT 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 */ 259 JNIEXPORT 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 */ 270 JNIEXPORT 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 */ 292 JNIEXPORT 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 }