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 #import "sun_lwawt_macosx_CDropTargetContextPeer.h" 27 28 #import <JavaNativeFoundation/JavaNativeFoundation.h> 29 30 #import "CDataTransferer.h" 31 #import "CDropTarget.h" 32 #import "DnDUtilities.h" 33 #import "ThreadUtilities.h" 34 35 JNF_CLASS_CACHE(jc_CDropTargetContextPeer, "sun/lwawt/macosx/CDropTargetContextPeer"); 36 37 38 static void TransferFailed(JNIEnv *env, jobject jthis, jlong jdroptarget, jlong jdroptransfer, jlong jformat) { 39 AWT_ASSERT_NOT_APPKIT_THREAD; 40 JNF_MEMBER_CACHE(transferFailedMethod, jc_CDropTargetContextPeer, "transferFailed", "(J)V"); 41 JNFCallVoidMethod(env, jthis, transferFailedMethod, jformat); // AWT_THREADING Safe (!appKit) 42 } 43 44 static CDropTarget* GetCDropTarget(jlong jdroptarget) { 45 CDropTarget* dropTarget = (CDropTarget*) jlong_to_ptr(jdroptarget); 46 47 // Make sure the drop target is of the right kind: 48 if ([dropTarget isKindOfClass:[CDropTarget class]]) { 49 return dropTarget; 50 } 51 52 return nil; 53 } 54 55 56 /* 57 * Class: sun_lwawt_macosx_CDropTargetContextPeer 58 * Method: startTransfer 59 * Signature: (JJ)J 60 */ 61 JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDropTargetContextPeer_startTransfer 62 (JNIEnv *env, jobject jthis, jlong jdroptarget, jlong jformat) 63 { 64 AWT_ASSERT_NOT_APPKIT_THREAD; 65 66 jlong result = (jlong) 0L; 67 68 // Currently startTransfer and endTransfer are synchronous since [CDropTarget copyDraggingDataForFormat] 69 // works off a data copy and doesn't have to go to the native event thread to get the data. 70 // We can have endTransfer just call startTransfer. 71 72 JNF_COCOA_ENTER(env); 73 // Get the drop target native object: 74 CDropTarget* dropTarget = GetCDropTarget(jdroptarget); 75 if (dropTarget == nil) { 76 DLog2(@"[CDropTargetContextPeer startTransfer]: GetCDropTarget failed for %d.\n", (NSInteger) jdroptarget); 77 TransferFailed(env, jthis, jdroptarget, (jlong) 0L, jformat); 78 return result; 79 } 80 81 JNF_MEMBER_CACHE(newDataMethod, jc_CDropTargetContextPeer, "newData", "(J[B)V"); 82 if ((*env)->ExceptionOccurred(env) || !newDataMethod) { 83 DLog2(@"[CDropTargetContextPeer startTransfer]: couldn't get newData method for %d.\n", (NSInteger) jdroptarget); 84 TransferFailed(env, jthis, jdroptarget, (jlong) 0L, jformat); 85 return result; 86 } 87 88 // Get data from drop target: 89 jobject jdropdata = [dropTarget copyDraggingDataForFormat:jformat]; 90 if (!jdropdata) { 91 DLog2(@"[CDropTargetContextPeer startTransfer]: copyDraggingDataForFormat failed for %d.\n", (NSInteger) jdroptarget); 92 TransferFailed(env, jthis, jdroptarget, (jlong) 0L, jformat); 93 return result; 94 } 95 96 // Pass the data to drop target: 97 @try { 98 JNFCallVoidMethod(env, jthis, newDataMethod, jformat, jdropdata); // AWT_THREADING Safe (!appKit) 99 } @catch (NSException *ex) { 100 DLog2(@"[CDropTargetContextPeer startTransfer]: exception in newData() for %d.\n", (NSInteger) jdroptarget); 101 JNFDeleteGlobalRef(env, jdropdata); 102 TransferFailed(env, jthis, jdroptarget, (jlong) 0L, jformat); 103 return result; 104 } 105 106 // if no error return dropTarget's draggingSequence 107 result = [dropTarget getDraggingSequenceNumber]; 108 JNF_COCOA_EXIT(env); 109 110 return result; 111 } 112 113 /* 114 * Class: sun_lwawt_macosx_CDropTargetContextPeer 115 * Method: addTransfer 116 * Signature: (JJJ)V 117 */ 118 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDropTargetContextPeer_addTransfer 119 (JNIEnv *env, jobject jthis, jlong jdroptarget, jlong jdroptransfer, jlong jformat) 120 { 121 // Currently startTransfer and endTransfer are synchronous since [CDropTarget copyDraggingDataForFormat] 122 // works off a data copy and doesn't have to go to the native event thread to get the data. 123 // We can have endTransfer just call startTransfer. 124 125 Java_sun_lwawt_macosx_CDropTargetContextPeer_startTransfer(env, jthis, jdroptarget, jformat); 126 127 return; 128 } 129 130 /* 131 * Class: sun_lwawt_macosx_CDropTargetContextPeer 132 * Method: dropDone 133 * Signature: (JJZZI)V 134 */ 135 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDropTargetContextPeer_dropDone 136 (JNIEnv *env, jobject jthis, jlong jdroptarget, jlong jdroptransfer, jboolean jislocal, jboolean jsuccess, jint jdropaction) 137 { 138 // Get the drop target native object: 139 JNF_COCOA_ENTER(env); 140 CDropTarget* dropTarget = GetCDropTarget(jdroptarget); 141 if (dropTarget == nil) { 142 DLog2(@"[CDropTargetContextPeer dropDone]: GetCDropTarget failed for %d.\n", (NSInteger) jdroptarget); 143 return; 144 } 145 146 // Notify drop target Java is all done with this dragging sequence: 147 [dropTarget javaDraggingEnded:(jlong)jdroptransfer success:jsuccess action:jdropaction]; 148 JNF_COCOA_EXIT(env); 149 150 return; 151 }