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 78 NSString *cursorName = JNFJavaToNSString(env, name); 79 SEL cursorSelector = (type == sun_lwawt_macosx_CCursorManager_NAMED_CURSOR) ? lookupCursorSelectorForName(cursorName) : lookupCursorSelectorForType(type); 80 if (cursorSelector == nil) { 81 NSString *reason = [NSString stringWithFormat:@"unimplemented built-in cursor type: %d / %@", type, cursorName]; 82 [JNFException raise:env as:kIllegalArgumentException reason:[reason UTF8String]]; 83 } 84 85 if (![[NSCursor class] respondsToSelector:cursorSelector]) { 86 [JNFException raise:env as:kNoSuchMethodException reason:"missing NSCursor selector"]; 87 } 88 89 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 90 setCursorOnAppKitThread([[NSCursor class] performSelector:cursorSelector]); 91 }]; 92 93 JNF_COCOA_EXIT(env); 94 } 95 96 JNIEXPORT void JNICALL 97 Java_sun_lwawt_macosx_CCursorManager_nativeSetCustomCursor 98 (JNIEnv *env, jclass class, jlong imgPtr, jdouble x, jdouble y) 99 { 100 JNF_COCOA_ENTER(env); 101 NSImage *image = (NSImage *)jlong_to_ptr(imgPtr); 102 103 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 104 NSCursor *cursor = [[NSCursor alloc] initWithImage:image 105 hotSpot:(NSPoint){ x, y }]; 106 setCursorOnAppKitThread(cursor); 107 [cursor release]; 108 }]; 109 110 JNF_COCOA_EXIT(env); 111 } 112 113 JNIEXPORT jobject JNICALL 114 Java_sun_lwawt_macosx_CCursorManager_nativeGetCursorPosition 115 (JNIEnv *env, jclass class) 116 { 117 jobject jpt = NULL; 118 119 JNF_COCOA_ENTER(env); 120 121 __block NSPoint pt = NSZeroPoint; 122 123 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ 124 pt = ConvertNSScreenPoint(env, [NSEvent mouseLocation]); 125 }]; 126 127 jpt = NSToJavaPoint(env, pt); 128 129 JNF_COCOA_EXIT(env); 130 131 return jpt; 132 } 133 134 135 JNIEXPORT void JNICALL 136 Java_sun_lwawt_macosx_CCursorManager_nativeSetAllowsCursorSetInBackground 137 (JNIEnv *env, jclass class, jboolean allows) 138 { 139 JNF_COCOA_ENTER(env); 140 141 SEL allowsSetInBackground_SEL = @selector(javaSetAllowsCursorSetInBackground:); 142 if ([[NSCursor class] respondsToSelector:allowsSetInBackground_SEL]) { 143 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ 144 NSMethodSignature *allowsSetInBackground_sig = 145 [[NSCursor class] methodSignatureForSelector:allowsSetInBackground_SEL]; 146 NSInvocation *invocation = 147 [NSInvocation invocationWithMethodSignature:allowsSetInBackground_sig]; 148 BOOL arg = (BOOL)allows; 149 [invocation setSelector:allowsSetInBackground_SEL]; 150 [invocation setArgument:&arg atIndex:2]; 151 [invocation invokeWithTarget:[NSCursor class]]; 152 }]; 153 } 154 155 JNF_COCOA_EXIT(env); 156 157 }