1 /* 2 * Copyright (c) 2011, 2015, 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 "common.h" 27 #import "com_sun_glass_ui_Cursor.h" 28 #import "com_sun_glass_ui_mac_MacCursor.h" 29 30 #import <Cocoa/Cocoa.h> 31 32 #import "GlassMacros.h" 33 #import "GlassHelper.h" 34 35 //#define VERBOSE 36 #ifndef VERBOSE 37 #define LOG(MSG, ...) 38 #else 39 #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__); 40 #endif 41 42 #define CURSOR_BEST_SIZE 32 43 44 static NSArray *cursorCache; 45 46 #pragma mark --- Java NSCursor 47 48 @interface NSCursor (Java) 49 50 + (NSCursor*)performJavaSelector:(SEL)aSelector; 51 52 @end 53 54 @implementation NSCursor (Java) 55 56 + (NSCursor*)performJavaSelector:(SEL)aSelector 57 { 58 NSCursor *cursor = nil; 59 if ([GlassHelper InvokeSelectorIfAvailable:aSelector forClass:[NSCursor class] withArgument:NULL withReturnValue:(void**)&cursor] == NO) 60 { 61 cursor = [NSCursor arrowCursor]; 62 } 63 return cursor; 64 } 65 66 @end 67 68 #pragma mark --- com_sun_glass_ui_mac_MacCursor 69 70 /* 71 * Class: com_sun_glass_ui_mac_MacCursor 72 * Method: _initIDs 73 * Signature: ()V 74 */ 75 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacCursor__1initIDs 76 (JNIEnv *env, jclass jCursorClass) 77 { 78 LOG("Java_com_sun_glass_ui_mac_MacCursor__1initIDs"); 79 80 if (jSizeInit == NULL) 81 { 82 jclass cls = [GlassHelper ClassForName:"com.sun.glass.ui.Size" withEnv:env]; 83 if (!cls) { 84 return; 85 } 86 jSizeInit = (*env)->GetMethodID(env, cls, "<init>", "(II)V"); 87 } 88 89 NSString *base = @"/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/Resources/cursors"; 90 NSString *nwse = @"resizenorthwestsoutheast"; 91 NSString *nesw = @"resizenortheastsouthwest"; 92 NSString *nwsePath = [base stringByAppendingPathComponent:nwse]; 93 NSString *neswPath = [base stringByAppendingPathComponent:nesw]; 94 NSString *nwseFile = [nwsePath stringByAppendingPathComponent:@"cursor.pdf"]; 95 NSString *neswFile = [neswPath stringByAppendingPathComponent:@"cursor.pdf"]; 96 NSString *nwseInfo = [nwsePath stringByAppendingPathComponent:@"info.plist"]; 97 NSString *neswInfo = [neswPath stringByAppendingPathComponent:@"info.plist"]; 98 NSImage *nwseImage = [[NSImage alloc] initByReferencingFile:nwseFile]; 99 NSImage *neswImage = [[NSImage alloc] initByReferencingFile:neswFile]; 100 NSDictionary *nwseDict = [NSDictionary dictionaryWithContentsOfFile:nwseInfo]; 101 NSDictionary *neswDict = [NSDictionary dictionaryWithContentsOfFile:neswInfo]; 102 NSPoint nwsePoint = NSMakePoint([[nwseDict valueForKey:@"hotx"] doubleValue], 103 [[nwseDict valueForKey:@"hoty"] doubleValue]); 104 NSPoint neswPoint = NSMakePoint([[neswDict valueForKey:@"hotx"] doubleValue], 105 [[neswDict valueForKey:@"hoty"] doubleValue]); 106 107 108 cursorCache = [NSArray arrayWithObjects: 109 /* CURSOR_CUSTOM */ [NSCursor arrowCursor], // not handed out in set 110 /* CURSOR_DEFAULT */ [NSCursor arrowCursor], 111 /* CURSOR_TEXT */ [NSCursor IBeamCursor], 112 /* CURSOR_CROSSHAIR */ [NSCursor crosshairCursor], 113 /* CURSOR_CLOSED_HAND */ [NSCursor closedHandCursor], 114 /* CURSOR_OPEN_HAND */ [NSCursor openHandCursor], 115 /* CURSOR_POINTING_HAND */ [NSCursor pointingHandCursor], 116 /* CURSOR_RESIZE_LEFT: */ [NSCursor resizeLeftCursor], 117 /* CURSOR_RESIZE_RIGHT */ [NSCursor resizeRightCursor], 118 /* CURSOR_RESIZE_UP */ [NSCursor resizeUpCursor], 119 /* CURSOR_RESIZE_DOWN */ [NSCursor resizeDownCursor], 120 /* CURSOR_RESIZE_LEFTRIGHT */ [NSCursor resizeLeftRightCursor], 121 /* CURSOR_RESIZE_UPDOWN */ [NSCursor resizeUpDownCursor], 122 /* CURSOR_DISAPPEAR */ [NSCursor disappearingItemCursor], 123 /* CURSOR_WAIT */ [NSCursor performJavaSelector:@selector(javaBusyButClickableCursor)], 124 /* CURSOR_RESIZE_SOUTHWEST */ [[NSCursor alloc] initWithImage:neswImage hotSpot:neswPoint], 125 /* CURSOR_RESIZE_SOUTHEAST */ [[NSCursor alloc] initWithImage:nwseImage hotSpot:nwsePoint], 126 /* CURSOR_RESIZE_NORTHWEST */ [[NSCursor alloc] initWithImage:nwseImage hotSpot:nwsePoint], 127 /* CURSOR_RESIZE_NORTHEAST */ [[NSCursor alloc] initWithImage:neswImage hotSpot:neswPoint], 128 /* CURSOR_MOVE */ [NSCursor performJavaSelector:@selector(javaMoveCursor)], 129 /* NS_REQUIRES_NIL_TERM */ nil 130 ]; 131 [cursorCache retain]; 132 133 assert([cursorCache count] == (com_sun_glass_ui_Cursor_CURSOR_MAX + 1)); 134 } 135 136 /* 137 * Class: com_sun_glass_ui_mac_MacCursor 138 * Method: _createCursor 139 * Signature: (IILcom/sun/glass/ui/Pixels;)J 140 */ 141 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacCursor__1createCursor 142 (JNIEnv *env, jclass jCursorClass, jint x, jint y, jobject jPixels) 143 { 144 LOG("Java_com_sun_glass_ui_mac_MacCursor__1createCursor"); 145 jlong jcursor = 0; 146 147 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 148 GLASS_POOL_ENTER; 149 { 150 NSImage *image = NULL; 151 (*env)->CallVoidMethod(env, jPixels, jPixelsAttachData, ptr_to_jlong(&image)); 152 if (image != NULL) 153 { 154 NSCursor *cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(x, y)]; 155 jcursor = ptr_to_jlong(cursor); 156 [image release]; 157 } 158 } 159 GLASS_POOL_EXIT; 160 GLASS_CHECK_EXCEPTION(env); 161 162 return jcursor; 163 } 164 165 /* 166 * Class: com_sun_glass_ui_mac_MacCursor 167 * Method: _set 168 * Signature: (I)V 169 */ 170 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacCursor__1set 171 (JNIEnv *env, jclass jCursorClass, jint jtype) 172 { 173 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 174 GLASS_POOL_ENTER; 175 { 176 LOG("Java_com_sun_glass_ui_mac_MacCursor__1set: %d", jtype); 177 assert(jtype > 0 && jtype <= com_sun_glass_ui_Cursor_CURSOR_MAX); 178 179 NSCursor *cursor = [cursorCache objectAtIndex: jtype]; 180 181 [cursor set]; 182 } 183 GLASS_POOL_EXIT; 184 GLASS_CHECK_EXCEPTION(env); 185 } 186 187 /* 188 * Class: com_sun_glass_ui_mac_MacCursor 189 * Method: _setCustom 190 * Signature: (J)V 191 */ 192 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacCursor__1setCustom 193 (JNIEnv *env, jclass jCursorClass, jlong cursorPtr) 194 { 195 LOG("Java_com_sun_glass_ui_mac_MacCursor__1setCustom"); 196 197 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 198 GLASS_POOL_ENTER; 199 { 200 NSCursor *cursor = (NSCursor*)jlong_to_ptr(cursorPtr); 201 [cursor set]; 202 } 203 GLASS_POOL_EXIT; 204 GLASS_CHECK_EXCEPTION(env); 205 } 206 207 /* 208 * Class: com_sun_glass_ui_mac_MacCursor 209 * Method: _setVisible 210 * Signature: (Z)V 211 */ 212 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacCursor__1setVisible 213 (JNIEnv *env, jclass jCursorClass, jboolean visible) 214 { 215 LOG("Java_com_sun_glass_ui_mac_MacCursor__1setVisible"); 216 217 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 218 GLASS_POOL_ENTER; 219 { 220 if (visible == JNI_TRUE) 221 { 222 [NSCursor unhide]; 223 } 224 else 225 { 226 [NSCursor hide]; 227 } 228 } 229 GLASS_POOL_EXIT; 230 GLASS_CHECK_EXCEPTION(env); 231 } 232 233 /* 234 * Class: com_sun_glass_ui_mac_MacCursor 235 * Method: _getBestSize 236 * Signature: (II)Lcom.sun.glass.ui.Size; 237 */ 238 JNIEXPORT jobject JNICALL Java_com_sun_glass_ui_mac_MacCursor__1getBestSize 239 (JNIEnv *env, jclass jCursorClass, jint width, jint height) 240 { 241 LOG("Java_com_sun_glass_ui_mac_MacCursor__1getBestSize"); 242 243 jobject jsize = NULL; 244 245 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 246 GLASS_POOL_ENTER; 247 { 248 jint widthBest = width; 249 jint heightBest = height; 250 251 NSImage *image = [[[NSCursor arrowCursor] image] retain]; 252 253 if (widthBest <= 0) 254 { 255 if (image != nil) 256 { 257 widthBest = (jint)[image size].width; 258 } 259 else 260 { 261 widthBest = CURSOR_BEST_SIZE; 262 } 263 } 264 265 if (heightBest <= 0) 266 { 267 if (image != nil) 268 { 269 heightBest = (jint)[image size].height; 270 } 271 else 272 { 273 heightBest = CURSOR_BEST_SIZE; 274 } 275 } 276 277 [image release]; 278 jclass sizeClass = [GlassHelper ClassForName:"com.sun.glass.ui.Size" withEnv:env]; 279 if (sizeClass) { 280 return NULL; 281 } 282 jsize = (*env)->NewObject(env, sizeClass, jSizeInit, widthBest, heightBest); 283 } 284 GLASS_POOL_EXIT; 285 GLASS_CHECK_EXCEPTION(env); 286 287 return jsize; 288 }