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