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#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 37static 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 58static 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 68static void setCursorOnAppKitThread(NSCursor *cursor) { 69 [cursor set]; 70} 71 72JNIEXPORT void JNICALL 73Java_sun_lwawt_macosx_CCursorManager_nativeSetBuiltInCursor 74(JNIEnv *env, jclass class, jint type, jstring name) 75{ 76JNF_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 93JNF_COCOA_EXIT(env); 94} 95 96JNIEXPORT void JNICALL 97Java_sun_lwawt_macosx_CCursorManager_nativeSetCustomCursor 98(JNIEnv *env, jclass class, jlong imgPtr, jdouble x, jdouble y) 99{ 100JNF_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 110JNF_COCOA_EXIT(env); 111} 112 113JNIEXPORT jobject JNICALL 114Java_sun_lwawt_macosx_CCursorManager_nativeGetCursorPosition 115(JNIEnv *env, jclass class) 116{ 117 jobject jpt = NULL; 118 119JNF_COCOA_ENTER(env); 120 121 CGEventRef event = CGEventCreate(NULL); 122 CGPoint globalPos = CGEventGetLocation(event); 123 CFRelease(event); 124 125 jpt = NSToJavaPoint(env, globalPos); 126 127JNF_COCOA_EXIT(env); 128 129 return jpt; 130} 131 132 133JNIEXPORT void JNICALL 134Java_sun_lwawt_macosx_CCursorManager_nativeSetAllowsCursorSetInBackground 135(JNIEnv *env, jclass class, jboolean allows) 136{ 137JNF_COCOA_ENTER(env); 138 139 SEL allowsSetInBackground_SEL = @selector(javaSetAllowsCursorSetInBackground:); 140 if ([[NSCursor class] respondsToSelector:allowsSetInBackground_SEL]) { 141 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ 142 NSMethodSignature *allowsSetInBackground_sig = 143 [[NSCursor class] methodSignatureForSelector:allowsSetInBackground_SEL]; 144 NSInvocation *invocation = 145 [NSInvocation invocationWithMethodSignature:allowsSetInBackground_sig]; 146 BOOL arg = (BOOL)allows; 147 [invocation setSelector:allowsSetInBackground_SEL]; 148 [invocation setArgument:&arg atIndex:2]; 149 [invocation invokeWithTarget:[NSCursor class]]; 150 }]; 151 } 152 153JNF_COCOA_EXIT(env); 154 155} 156