1 /* 2 * Copyright (c) 2011, 2013, 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 65 jlong result = (jlong) 0L; 66 67 // Currently startTransfer and endTransfer are synchronous since [CDropTarget copyDraggingDataForFormat] 68 // works off a data copy and doesn't have to go to the native event thread to get the data. 69 // We can have endTransfer just call startTransfer. 70 71 JNF_COCOA_ENTER(env); 72 // Get the drop target native object: 73 CDropTarget* dropTarget = GetCDropTarget(jdroptarget); 74 if (dropTarget == nil) { 75 DLog2(@"[CDropTargetContextPeer startTransfer]: GetCDropTarget failed for %d.\n", (NSInteger) jdroptarget); 76 TransferFailed(env, jthis, jdroptarget, (jlong) 0L, jformat); 77 return result; 78 } 79 80 JNF_MEMBER_CACHE(newDataMethod, jc_CDropTargetContextPeer, "newData", "(J[B)V"); 81 if ((*env)->ExceptionOccurred(env) || !newDataMethod) { 82 DLog2(@"[CDropTargetContextPeer startTransfer]: couldn't get newData method for %d.\n", (NSInteger) jdroptarget); 83 TransferFailed(env, jthis, jdroptarget, (jlong) 0L, jformat); 84 return result; 85 } 86 87 // Get data from drop target: 88 jobject jdropdata = [dropTarget copyDraggingDataForFormat:jformat]; 89 if (!jdropdata) { 90 DLog2(@"[CDropTargetContextPeer startTransfer]: copyDraggingDataForFormat failed for %d.\n", (NSInteger) jdroptarget); 91 TransferFailed(env, jthis, jdroptarget, (jlong) 0L, jformat); 92 return result; 93 } 94 95 // Pass the data to drop target: 96 @try { 97 JNFCallVoidMethod(env, jthis, newDataMethod, jformat, jdropdata); // AWT_THREADING Safe (!appKit) 98 } @catch (NSException *ex) { 99 DLog2(@"[CDropTargetContextPeer startTransfer]: exception in newData() for %d.\n", (NSInteger) jdroptarget); 100 JNFDeleteGlobalRef(env, jdropdata); 101 TransferFailed(env, jthis, jdroptarget, (jlong) 0L, jformat); 102 return result; 103 } 104 105 // if no error return dropTarget's draggingSequence 106 result = [dropTarget getDraggingSequenceNumber]; 107 JNF_COCOA_EXIT(env); 108 109 return result; 110 } 111 112 /* 113 * Class: sun_lwawt_macosx_CDropTargetContextPeer 114 * Method: addTransfer 115 * Signature: (JJJ)V 116 */ 117 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDropTargetContextPeer_addTransfer 118 (JNIEnv *env, jobject jthis, jlong jdroptarget, jlong jdroptransfer, jlong jformat) 119 { 120 // Currently startTransfer and endTransfer are synchronous since [CDropTarget copyDraggingDataForFormat] 121 // works off a data copy and doesn't have to go to the native event thread to get the data. 122 // We can have endTransfer just call startTransfer. 123 124 Java_sun_lwawt_macosx_CDropTargetContextPeer_startTransfer(env, jthis, jdroptarget, jformat); 125 126 return; 127 } 128 129 /* 130 * Class: sun_lwawt_macosx_CDropTargetContextPeer 131 * Method: dropDone 132 * Signature: (JJZZI)V 133 */ 134 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDropTargetContextPeer_dropDone 135 (JNIEnv *env, jobject jthis, jlong jdroptarget, jlong jdroptransfer, jboolean jislocal, jboolean jsuccess, jint jdropaction) 136 { 137 // Get the drop target native object: 138 JNF_COCOA_ENTER(env); 139 CDropTarget* dropTarget = GetCDropTarget(jdroptarget); 140 if (dropTarget == nil) { 141 DLog2(@"[CDropTargetContextPeer dropDone]: GetCDropTarget failed for %d.\n", (NSInteger) jdroptarget); 142 return; 143 } 144 145 // Notify drop target Java is all done with this dragging sequence: 146 [dropTarget javaDraggingEnded:(jlong)jdroptransfer success:jsuccess action:jdropaction]; 147 JNF_COCOA_EXIT(env); 148 149 return; 150 }