1 /* 2 * Copyright (c) 2011, 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 #include "sun_lwawt_macosx_CCursorManager.h" 27 28 #include <Cocoa/Cocoa.h> 29 #include <JavaNativeFoundation/JavaNativeFoundation.h> 30 31 #include "GeomUtilities.h" 32 #include "ThreadUtilities.h" 33 34 #include "java_awt_Cursor.h" 35 36 37 static SEL lookupCursorSelectorForType(jint type) { 38 switch (type) { 39 case java_awt_Cursor_DEFAULT_CURSOR: return @selector(arrowCursor); 40 case java_awt_Cursor_CROSSHAIR_CURSOR: return @selector(crosshairCursor); 41 case java_awt_Cursor_TEXT_CURSOR: return @selector(IBeamCursor); 42 case java_awt_Cursor_WAIT_CURSOR: return @selector(javaBusyButClickableCursor); 43 case java_awt_Cursor_SW_RESIZE_CURSOR: return @selector(javaResizeSWCursor); 44 case java_awt_Cursor_SE_RESIZE_CURSOR: return @selector(javaResizeSECursor); 45 case java_awt_Cursor_NW_RESIZE_CURSOR: return @selector(javaResizeNWCursor); 46 case java_awt_Cursor_NE_RESIZE_CURSOR: return @selector(javaResizeNECursor); 47 case java_awt_Cursor_N_RESIZE_CURSOR: return @selector(resizeUpDownCursor); 48 case java_awt_Cursor_S_RESIZE_CURSOR: return @selector(resizeUpDownCursor); 49 case java_awt_Cursor_W_RESIZE_CURSOR: return @selector(resizeLeftRightCursor); 50 case java_awt_Cursor_E_RESIZE_CURSOR: return @selector(resizeLeftRightCursor); 51 case java_awt_Cursor_HAND_CURSOR: return @selector(pointingHandCursor); 52 case java_awt_Cursor_MOVE_CURSOR: return @selector(javaMoveCursor); 53 } 54 55 return nil; 56 } 57 58 static SEL lookupCursorSelectorForName(NSString *name) { 59 if ([@"DnD.Cursor.CopyDrop" isEqual:name]) return @selector(dragCopyCursor); 60 if ([@"DnD.Cursor.LinkDrop" isEqual:name]) return @selector(dragLinkCursor); 61 if ([@"DnD.Cursor.MoveDrop" isEqual:name]) return @selector(_genericDragCursor); 62 if ([@"DnD.Cursor.CopyNoDrop" isEqual:name]) return @selector(operationNotAllowedCursor); 63 if ([@"DnD.Cursor.LinkNoDrop" isEqual:name]) return @selector(operationNotAllowedCursor); 64 if ([@"DnD.Cursor.MoveNoDrop" isEqual:name]) return @selector(operationNotAllowedCursor); 65 return nil; 66 } 67 68 static void setCursorOnAppKitThread(NSCursor *cursor) { 69 [cursor set]; 70 } 71 72 JNIEXPORT void JNICALL 73 Java_sun_lwawt_macosx_CCursorManager_nativeSetBuiltInCursor 74 (JNIEnv *env, jclass class, jint type, jstring name) 75 { 76 JNF_COCOA_ENTER(env); 77 AWT_ASSERT_NOT_APPKIT_THREAD; 78 79 NSString *cursorName = JNFJavaToNSString(env, name); 80 SEL cursorSelector = (type == sun_lwawt_macosx_CCursorManager_NAMED_CURSOR) ? lookupCursorSelectorForName(cursorName) : lookupCursorSelectorForType(type); 81 if (cursorSelector == nil) { 82 NSString *reason = [NSString stringWithFormat:@"unimplemented built-in cursor type: %d / %@", type, cursorName]; 83 [JNFException raise:env as:kIllegalArgumentException reason:[reason UTF8String]]; 84 } 85 86 if (![[NSCursor class] respondsToSelector:cursorSelector]) { 87 [JNFException raise:env as:kNoSuchMethodException reason:"missing NSCursor selector"]; 88 } 89 90 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){ 91 AWT_ASSERT_APPKIT_THREAD; 92 93 setCursorOnAppKitThread([[NSCursor class] performSelector:cursorSelector]); 94 }]; 95 96 JNF_COCOA_EXIT(env); 97 } 98 99 JNIEXPORT void JNICALL 100 Java_sun_lwawt_macosx_CCursorManager_nativeSetCustomCursor 101 (JNIEnv *env, jclass class, jlong imgPtr, jdouble x, jdouble y) 102 { 103 JNF_COCOA_ENTER(env); 104 AWT_ASSERT_NOT_APPKIT_THREAD; 105 NSImage *image = (NSImage *)jlong_to_ptr(imgPtr); 106 107 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){ 108 AWT_ASSERT_APPKIT_THREAD; 109 110 NSCursor *cursor = [[NSCursor alloc] initWithImage:image 111 hotSpot:(NSPoint){ x, y }]; 112 setCursorOnAppKitThread(cursor); 113 [cursor release]; 114 }]; 115 116 JNF_COCOA_EXIT(env); 117 } 118 119 JNIEXPORT jobject JNICALL 120 Java_sun_lwawt_macosx_CCursorManager_nativeGetCursorPosition 121 (JNIEnv *env, jclass class) 122 { 123 jobject jpt = NULL; 124 125 JNF_COCOA_ENTER(env); 126 AWT_ASSERT_NOT_APPKIT_THREAD; 127 128 __block NSPoint pt = NSZeroPoint; 129 [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ 130 AWT_ASSERT_APPKIT_THREAD; 131 132 pt = ConvertNSScreenPoint(env, [NSEvent mouseLocation]); 133 }]; 134 jpt = NSToJavaPoint(env, pt); 135 136 JNF_COCOA_EXIT(env); 137 138 return jpt; 139 } 140 141 142 JNIEXPORT void JNICALL 143 Java_sun_lwawt_macosx_CCursorManager_nativeSetAllowsCursorSetInBackground 144 (JNIEnv *env, jclass class, jboolean allows) 145 { 146 147 JNF_COCOA_ENTER(env); 148 AWT_ASSERT_NOT_APPKIT_THREAD; 149 150 SEL allowsSetInBackground_SEL = @selector(javaSetAllowsCursorSetInBackground:); 151 if ([[NSCursor class] respondsToSelector:allowsSetInBackground_SEL]) { 152 [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ 153 NSMethodSignature *allowsSetInBackground_sig = 154 [[NSCursor class] methodSignatureForSelector:allowsSetInBackground_SEL]; 155 NSInvocation *invocation = 156 [NSInvocation invocationWithMethodSignature:allowsSetInBackground_sig]; 157 BOOL arg = (BOOL)allows; 158 [invocation setSelector:allowsSetInBackground_SEL]; 159 [invocation setArgument:&arg atIndex:2]; 160 [invocation invokeWithTarget:[NSCursor class]]; 161 }]; 162 } 163 164 JNF_COCOA_EXIT(env); 165 166 }